added phone, email

This commit is contained in:
heyethereum
2024-08-14 23:28:45 +08:00
parent b176e5c54f
commit 624bfdc2f9
7 changed files with 74 additions and 48 deletions

View File

@@ -50,11 +50,6 @@ public class QRCodeTypeController {
return ResponseEntity.ok(qrCodeTypeService.scanQRCode(userId, payload));
}
@PostMapping(API_URL_QRCODE_DETECT)
public ResponseEntity<String> detectType(@RequestBody QRCodePayload payload) {
return ResponseEntity.ok(qrCodeTypeService.detectType(payload).block());
}
@PostMapping(value = API_URL_QRCODE_VERIFY_URL, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<BaseScanResponse> verifyURL(@RequestBody QRCodePayload payload,
@RequestHeader(required = false, name = HEADER_USER_ID) String userId) {

View File

@@ -27,6 +27,8 @@ public final class EmailModel extends QRCodeModel<EmailEntity> {
@Override
public void setDetails() {
details = EmailEntity.builder().qrCodeId(data.getId()).build();
emailVerificationService.parseEmailString(details, data.getContents());
// Insert into email table
emailVerificationService.insertDB(details);
}

View File

@@ -27,6 +27,8 @@ public final class PhoneModel extends QRCodeModel<PhoneEntity> {
@Override
public void setDetails() {
details = PhoneEntity.builder().qrCodeId(data.getId()).build();
phoneVerificationService.parsePhoneString(details, data.getContents());
// Insert into phone table
phoneVerificationService.insertDB(details);
}

View File

@@ -25,7 +25,8 @@ public class QRCodeFactoryProvider {
case QR_CODE_TYPE_EMAIL -> applicationContext.getBean(EmailFactory.class).create(scannedQRCodeEntity);
case QR_CODE_TYPE_WIFI -> applicationContext.getBean(WifiFactory.class).create(scannedQRCodeEntity);
case DEFAULT_QR_CODE_TYPE -> applicationContext.getBean(TextFactory.class).create(scannedQRCodeEntity);
default -> throw new IllegalArgumentException("Unsupported QR code type: " + scannedQRCodeEntity.getInfo().getType());
//default -> throw new IllegalArgumentException("Unsupported QR code type: " + scannedQRCodeEntity.getInfo().getType());
default -> applicationContext.getBean(TextFactory.class).create(scannedQRCodeEntity);
};
}
}

View File

@@ -1,5 +1,6 @@
package com.safeqr.app.qrcode.service;
import com.safeqr.app.exceptions.InvalidFormatExceptions;
import com.safeqr.app.exceptions.ResourceNotFoundExceptions;
import com.safeqr.app.qrcode.entity.EmailEntity;
import com.safeqr.app.qrcode.repository.EmailRepository;
@@ -8,7 +9,11 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import java.util.stream.Collectors;
@Service
public class EmailVerificationService {
@@ -28,4 +33,35 @@ public class EmailVerificationService {
emailRepository.save(emailEntity);
}
public void parseEmailString(EmailEntity emailEntity, String emailString) {
Optional.ofNullable(emailString)
.filter(s -> !s.isEmpty())
.filter(s -> s.startsWith("MAILTO:"))
.map(s -> s.substring(7))
.map(s -> s.split("\\?", 2))
.filter(parts -> parts.length > 0)
.ifPresentOrElse(
parts -> {
String email = parts[0];
Map<String, String> params = (parts.length == 2)
? Arrays.stream(parts[1].split("&"))
.map(param -> param.split("=", 2))
.filter(keyValue -> keyValue.length == 2)
.collect(Collectors.toMap(
keyValue -> keyValue[0],
keyValue -> keyValue[1],
(v1, v2) -> v1
))
: Map.of();
emailEntity.setEmail(email);
emailEntity.setTitle(params.getOrDefault("subject", ""));
emailEntity.setMessage(params.getOrDefault("body", ""));
},
() -> {
throw new InvalidFormatExceptions("Invalid email format. Expected format: MAILTO:<email>?subject=<title>&body=<message>");
}
);
}
}

View File

@@ -1,5 +1,6 @@
package com.safeqr.app.qrcode.service;
import com.safeqr.app.exceptions.InvalidFormatExceptions;
import com.safeqr.app.exceptions.ResourceNotFoundExceptions;
import com.safeqr.app.qrcode.entity.PhoneEntity;
import com.safeqr.app.qrcode.repository.PhoneRepository;
@@ -28,4 +29,23 @@ public class PhoneVerificationService {
phoneRepository.save(phoneEntity);
}
public void parsePhoneString(PhoneEntity phoneEntity, String phoneString) {
// Validate the string format
if (phoneString == null || phoneString.isEmpty()) {
throw new InvalidFormatExceptions("Phone string cannot be null or empty.");
}
// Remove the "TEL:" prefix
String phoneNumber = phoneString.substring(4);
// Further validation for phone number can be done here (optional)
if (phoneNumber.matches("\\+?[0-9]*")) {
// Populate the PhoneEntity object
phoneEntity.setPhone(phoneNumber);
} else {
throw new InvalidFormatExceptions("Invalid phone number format.");
}
}
}

View File

@@ -88,41 +88,33 @@ public class QRCodeTypeService {
String data = payload.getData();
logger.info("scanQRCode: userId={}, data={}", userId, data);
// Get the QR Code Type
QRCodeTypeEntity qrType = getQRCodeType(data);
// Insert the QR Code into main qrcode table
QRCodeEntity scannedQR = qrCodeRepository.save(QRCodeEntity.builder()
.userId(userId)
.contents(data)
.info(qrType)
.createdAt(LocalDateTime.now())
.build());
QRCodeModel<?> qrCodeModel = scanAndClassify(userId, data);
UUID qrId = qrCodeModel.getData().getId();
// Insert into Scan History table if userId is not null
logger.info("scanQRCode: scannedQR new ID={}", scannedQR.getId());
logger.info("scanQRCode: scannedQR new ID={}", qrId);
if (userId != null) {
scanHistoryRepository.save(ScanHistoryEntity.builder()
.qrCodeId(scannedQR.getId())
.qrCodeId(qrId)
.userId(userId)
.scanStatus(ScanHistoryEntity.ScanStatus.ACTIVE)
.build());
}
// Create the QR Code Instance based on the QR Code Type & insert into the respective table
QRCodeModel<?> qrCodeModel = qrCodeFactoryProvider.createQRCodeInstance(scannedQR);
qrCodeModel.setDetails();
// Get classifications based on verifications
scannedQR.setResult(qrCodeModel.retrieveClassification());
// update result category in qrcode table
qrCodeRepository.save(scannedQR);
return BaseScanResponse.builder().qrcode(qrCodeModel).build();
}
// Scan decoded contents from email message
@Transactional
public QRCodeModel<?> scanGmailDecodedContents(String userId, String data) {
logger.info("Scan Gmail content: userId={}, data={}", userId, data);
return scanAndClassify(userId, data);
}
// ScanAndClassify
private QRCodeModel<?> scanAndClassify(String userId, String data) {
// Get the QR Code Type
QRCodeTypeEntity qrType = getQRCodeType(data);
@@ -143,6 +135,7 @@ public class QRCodeTypeService {
return qrCodeModel;
}
// Returns Default type as text if it does not fit into any of the category
private QRCodeTypeEntity getQRCodeType(String data) {
return configs.stream()
@@ -150,27 +143,4 @@ public class QRCodeTypeService {
.findFirst()
.orElse(defaultQRCodeTypeEntity);
}
public Mono<String> detectType(QRCodePayload payload) {
String data = payload.getData();
for (QRCodeTypeEntity config : configs) {
if (data.startsWith(config.getPrefix())) {
if ("URL".equals(config.getType())) {
try
{
return safeBrowsingService.isSafeUrl(data)
.map(isSafe -> isSafe ? "Safe URL" : "Unsafe URL");
} catch (NoSuchAlgorithmException e)
{
// TODO Auto-generated catch block
return Mono.just("Error checking URL safety: " + e.getMessage());
}
}
return Mono.just(config.getType());
}
}
return Mono.just("Unknown");
}
}