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 ICurrentUserService _currentUserService; private readonly ICompreFaceClient _compreFaceClient; private readonly IConfiguration _configuration; 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 == UserID); var faceMatches = await VerifySelfieAsync(selfieImage, identificationDocument); var isMatchSuccess = faceMatches.Any(); if (isMatchSuccess) { var signatory = _notaryoDBContext.TransactionSignatories.First(x => x.UserID == UserID); signatory.Status = nameof(SignatoryStatus.FaceMatch); _notaryoDBContext.Update(signatory); var selfieEntity = CreateOrUpdateSelfie(selfieImage); if (_notaryoDBContext.Entry(selfieEntity).State == EntityState.Detached) { _notaryoDBContext.Add(selfieEntity); } else { _notaryoDBContext.Update(selfieEntity); } _notaryoDBContext.SaveChanges(); } return isMatchSuccess; } private Transaction _transactionEntity; private int TransactionID { get { if (_transactionEntity == null) { _transactionEntity = _notaryoDBContext.Transactions.AsNoTracking().First(x => x.Transaction_UID == Transaction_UID); } return _transactionEntity?.TransactionID ?? 0; } } private User _user; private int UserID { get { if (_user == null) { _user = _notaryoDBContext.Users.AsNoTracking().First(x => x.User_UID == _currentUserService.GetUser_UID()); } return _user?.UserID ?? 0; } } 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 = [] }; var result = await client.VerifyAsync(faceVerificationRequest); var faceMatches = result.Result.SelectMany(x => x.FaceMatches); return faceMatches; } 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 = UserID, TransactionID = 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; } [BindProperty(SupportsGet = true)] public Guid Transaction_UID { get; set; } [BindProperty] public string SelfieBase64Image { get; set; } [BindProperty(SupportsGet = true)] public Guid TransactionSelfie_UID { get; set; } } }