added phone, email
This commit is contained in:
@@ -50,11 +50,6 @@ public class QRCodeTypeController {
|
|||||||
return ResponseEntity.ok(qrCodeTypeService.scanQRCode(userId, payload));
|
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)
|
@PostMapping(value = API_URL_QRCODE_VERIFY_URL, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||||
public ResponseEntity<BaseScanResponse> verifyURL(@RequestBody QRCodePayload payload,
|
public ResponseEntity<BaseScanResponse> verifyURL(@RequestBody QRCodePayload payload,
|
||||||
@RequestHeader(required = false, name = HEADER_USER_ID) String userId) {
|
@RequestHeader(required = false, name = HEADER_USER_ID) String userId) {
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ public final class EmailModel extends QRCodeModel<EmailEntity> {
|
|||||||
@Override
|
@Override
|
||||||
public void setDetails() {
|
public void setDetails() {
|
||||||
details = EmailEntity.builder().qrCodeId(data.getId()).build();
|
details = EmailEntity.builder().qrCodeId(data.getId()).build();
|
||||||
|
|
||||||
|
emailVerificationService.parseEmailString(details, data.getContents());
|
||||||
// Insert into email table
|
// Insert into email table
|
||||||
emailVerificationService.insertDB(details);
|
emailVerificationService.insertDB(details);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ public final class PhoneModel extends QRCodeModel<PhoneEntity> {
|
|||||||
@Override
|
@Override
|
||||||
public void setDetails() {
|
public void setDetails() {
|
||||||
details = PhoneEntity.builder().qrCodeId(data.getId()).build();
|
details = PhoneEntity.builder().qrCodeId(data.getId()).build();
|
||||||
|
|
||||||
|
phoneVerificationService.parsePhoneString(details, data.getContents());
|
||||||
// Insert into phone table
|
// Insert into phone table
|
||||||
phoneVerificationService.insertDB(details);
|
phoneVerificationService.insertDB(details);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,8 @@ public class QRCodeFactoryProvider {
|
|||||||
case QR_CODE_TYPE_EMAIL -> applicationContext.getBean(EmailFactory.class).create(scannedQRCodeEntity);
|
case QR_CODE_TYPE_EMAIL -> applicationContext.getBean(EmailFactory.class).create(scannedQRCodeEntity);
|
||||||
case QR_CODE_TYPE_WIFI -> applicationContext.getBean(WifiFactory.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);
|
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);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.safeqr.app.qrcode.service;
|
package com.safeqr.app.qrcode.service;
|
||||||
|
|
||||||
|
import com.safeqr.app.exceptions.InvalidFormatExceptions;
|
||||||
import com.safeqr.app.exceptions.ResourceNotFoundExceptions;
|
import com.safeqr.app.exceptions.ResourceNotFoundExceptions;
|
||||||
import com.safeqr.app.qrcode.entity.EmailEntity;
|
import com.safeqr.app.qrcode.entity.EmailEntity;
|
||||||
import com.safeqr.app.qrcode.repository.EmailRepository;
|
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.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class EmailVerificationService {
|
public class EmailVerificationService {
|
||||||
@@ -28,4 +33,35 @@ public class EmailVerificationService {
|
|||||||
emailRepository.save(emailEntity);
|
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>");
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.safeqr.app.qrcode.service;
|
package com.safeqr.app.qrcode.service;
|
||||||
|
|
||||||
|
import com.safeqr.app.exceptions.InvalidFormatExceptions;
|
||||||
import com.safeqr.app.exceptions.ResourceNotFoundExceptions;
|
import com.safeqr.app.exceptions.ResourceNotFoundExceptions;
|
||||||
import com.safeqr.app.qrcode.entity.PhoneEntity;
|
import com.safeqr.app.qrcode.entity.PhoneEntity;
|
||||||
import com.safeqr.app.qrcode.repository.PhoneRepository;
|
import com.safeqr.app.qrcode.repository.PhoneRepository;
|
||||||
@@ -28,4 +29,23 @@ public class PhoneVerificationService {
|
|||||||
phoneRepository.save(phoneEntity);
|
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.");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -88,41 +88,33 @@ public class QRCodeTypeService {
|
|||||||
String data = payload.getData();
|
String data = payload.getData();
|
||||||
logger.info("scanQRCode: userId={}, data={}", userId, data);
|
logger.info("scanQRCode: userId={}, data={}", userId, data);
|
||||||
|
|
||||||
// Get the QR Code Type
|
QRCodeModel<?> qrCodeModel = scanAndClassify(userId, data);
|
||||||
QRCodeTypeEntity qrType = getQRCodeType(data);
|
UUID qrId = qrCodeModel.getData().getId();
|
||||||
|
|
||||||
// Insert the QR Code into main qrcode table
|
|
||||||
QRCodeEntity scannedQR = qrCodeRepository.save(QRCodeEntity.builder()
|
|
||||||
.userId(userId)
|
|
||||||
.contents(data)
|
|
||||||
.info(qrType)
|
|
||||||
.createdAt(LocalDateTime.now())
|
|
||||||
.build());
|
|
||||||
|
|
||||||
// Insert into Scan History table if userId is not null
|
// 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) {
|
if (userId != null) {
|
||||||
scanHistoryRepository.save(ScanHistoryEntity.builder()
|
scanHistoryRepository.save(ScanHistoryEntity.builder()
|
||||||
.qrCodeId(scannedQR.getId())
|
.qrCodeId(qrId)
|
||||||
.userId(userId)
|
.userId(userId)
|
||||||
.scanStatus(ScanHistoryEntity.ScanStatus.ACTIVE)
|
.scanStatus(ScanHistoryEntity.ScanStatus.ACTIVE)
|
||||||
.build());
|
.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();
|
return BaseScanResponse.builder().qrcode(qrCodeModel).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Scan decoded contents from email message
|
||||||
@Transactional
|
@Transactional
|
||||||
public QRCodeModel<?> scanGmailDecodedContents(String userId, String data) {
|
public QRCodeModel<?> scanGmailDecodedContents(String userId, String data) {
|
||||||
logger.info("Scan Gmail content: userId={}, data={}", userId, 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
|
// Get the QR Code Type
|
||||||
QRCodeTypeEntity qrType = getQRCodeType(data);
|
QRCodeTypeEntity qrType = getQRCodeType(data);
|
||||||
|
|
||||||
@@ -143,6 +135,7 @@ public class QRCodeTypeService {
|
|||||||
|
|
||||||
return qrCodeModel;
|
return qrCodeModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns Default type as text if it does not fit into any of the category
|
// Returns Default type as text if it does not fit into any of the category
|
||||||
private QRCodeTypeEntity getQRCodeType(String data) {
|
private QRCodeTypeEntity getQRCodeType(String data) {
|
||||||
return configs.stream()
|
return configs.stream()
|
||||||
@@ -150,27 +143,4 @@ public class QRCodeTypeService {
|
|||||||
.findFirst()
|
.findFirst()
|
||||||
.orElse(defaultQRCodeTypeEntity);
|
.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");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user