using EnotaryoPH.Data; using EnotaryoPH.Data.Entities; using Exadel.Compreface.Clients.CompreFaceClient; using Exadel.Compreface.DTOs.FaceVerificationDTOs.FaceVerification; using Exadel.Compreface.Services; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; namespace EnotaryoPH.Web.Pages { public class BaseTakeSelfiePageModel : PageModel { protected readonly NotaryoDBContext _notaryoDBContext; private readonly ICompreFaceClient _compreFaceClient; private readonly IConfiguration _configuration; private readonly ICurrentUserService _currentUserService; private Transaction _transactionEntity; private User _user; public BaseTakeSelfiePageModel(NotaryoDBContext notaryoDBContext, ICurrentUserService currentUserService, ICompreFaceClient compreFaceClient, IConfiguration configuration) { _notaryoDBContext = notaryoDBContext; _currentUserService = currentUserService; _compreFaceClient = compreFaceClient; _configuration = configuration; } protected async Task PostAsync() { var selfieImage = Convert.FromBase64String(SelfieBase64Image.Split(",")[1]) ?? []; var identificationDocument = _notaryoDBContext.IdentificationDocuments.First(e => e.UserID == CurrentUser.UserID); var faceMatches = await VerifySelfieAsync(selfieImage, identificationDocument); var isMatchSuccess = faceMatches.Any(); if (isMatchSuccess) { var signatory = _notaryoDBContext.TransactionSignatories.Include(ts => ts.Transaction).FirstOrDefault(x => x.UserID == CurrentUser.UserID); if (signatory != null) { signatory.Status = nameof(SignatoryStatus.FaceMatch); _notaryoDBContext.Update(signatory); _transactionEntity = signatory.Transaction; Transaction_UID = _transactionEntity.Transaction_UID.Value; } else if (!CurrentUser.Role.IsInList(nameof(UserType.Principal), nameof(UserType.SuperUser), nameof(UserType.Administrator))) { return false; } if (CurrentTransaction.TransactionID == 0) { var newTransaction = new Transaction { Transaction_UID = Guid.CreateVersion7(DateTime.UtcNow), CreatedOn = DateTime.UtcNow, TransactionDate = DateTime.UtcNow, Status = nameof(TransactionState.New), PrincipalID = CurrentUser.UserID }; _notaryoDBContext.Add(CurrentTransaction); } var selfieEntity = CreateOrUpdateSelfie(selfieImage); selfieEntity.Transaction = CurrentTransaction; selfieEntity.IdentificationDocumentID = identificationDocument.IdentificationDocumentID; _notaryoDBContext.UpdateOrCreate(selfieEntity); _notaryoDBContext.SaveChanges(); } return isMatchSuccess; } private TransactionSelfie CreateOrUpdateSelfie(byte[] selfieImage) { TransactionSelfie selfieEntity; if (TransactionSelfie_UID == Guid.Empty) { selfieEntity = new TransactionSelfie { CreatedOn = DateTime.UtcNow, TransactionSelfie_UID = Guid.CreateVersion7(DateTime.UtcNow), UserID = CurrentUser.UserID, TransactionID = CurrentTransaction.TransactionID, }; TransactionSelfie_UID = selfieEntity.TransactionSelfie_UID.Value; } else { selfieEntity = _notaryoDBContext.TransactionSelfies.FirstOrDefault(e => e.TransactionSelfie_UID == TransactionSelfie_UID); } selfieEntity.File = Convert.FromBase64String(SelfieBase64Image.Split(",")[1]); return selfieEntity; } private async Task> VerifySelfieAsync(byte[] selfieImage, IdentificationDocument identificationDocument) { var selfiePath = Path.Combine(Path.GetTempPath(), "Selfies"); if (!Directory.Exists(selfiePath)) { Directory.CreateDirectory(selfiePath); } var identificationDocumentPath = Path.Combine(selfiePath, $"{identificationDocument.IdentificationDocument_UID}.jpg"); var apiKey = _configuration.GetValue("CompreFaceConfig:APIKey"); var client = _compreFaceClient.GetCompreFaceService(apiKey); var faceVerificationRequest = new FaceVerificationRequestByBytes() { SourceImageInBytes = selfieImage, TargetImageInBytes = identificationDocument.File, DetProbThreshold = 0.81m, Limit = 1, Status = false, FacePlugins = [] }; try { var result = await client.VerifyAsync(faceVerificationRequest); var faceMatches = result.Result.SelectMany(x => x.FaceMatches); return faceMatches; } catch (Exception) { return Enumerable.Empty(); } } [BindProperty] public string SelfieBase64Image { get; set; } [BindProperty(SupportsGet = true)] public Guid Transaction_UID { get; set; } [BindProperty(SupportsGet = true)] public Guid TransactionSelfie_UID { get; set; } protected User CurrentUser => _user ??= _notaryoDBContext.Users.AsNoTracking().First(x => x.User_UID == _currentUserService.GetUser_UID()); protected Transaction CurrentTransaction => _transactionEntity ??= _notaryoDBContext.Transactions.AsNoTracking().FirstOrDefault(x => x.Transaction_UID == Transaction_UID) ?? new Transaction { Transaction_UID = Guid.CreateVersion7(DateTime.UtcNow), CreatedOn = DateTime.UtcNow, TransactionDate = DateTime.UtcNow, Status = nameof(TransactionState.New), PrincipalID = CurrentUser.UserID }; } }