Implement identity verification feature with image upload and token management
All checks were successful
Build And Push Dev Docker Image / docker (push) Successful in 2m2s
All checks were successful
Build And Push Dev Docker Image / docker (push) Successful in 2m2s
This commit is contained in:
@@ -111,7 +111,10 @@ namespace FoodsharingSiegen.Server.Data.Service
|
||||
{
|
||||
try
|
||||
{
|
||||
var prospectsQuery = Context.Prospects!.AsNoTracking().Include(x => x.Interactions.OrderBy(i => i.Date)).ThenInclude(x => x.User).OrderBy(x => x.Name).AsQueryable();
|
||||
var prospectsQuery = Context.Prospects!.AsNoTracking()
|
||||
.Include(x => x.Images)
|
||||
.Include(x => x.Interactions.OrderBy(i => i.Date)).ThenInclude(x => x.User)
|
||||
.OrderBy(x => x.Name).AsQueryable();
|
||||
|
||||
if(parameter.MustHaveInteractions != null && parameter.MustHaveInteractions.Any())
|
||||
prospectsQuery = prospectsQuery.Where(x => x.Interactions.Any(i => parameter.MustHaveInteractions.Contains(i.Type)));
|
||||
@@ -206,5 +209,138 @@ namespace FoodsharingSiegen.Server.Data.Service
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Image Upload Features
|
||||
|
||||
public async Task<OperationResult<Guid>> GenerateVerificationTokenAsync(Guid prospectId)
|
||||
{
|
||||
try
|
||||
{
|
||||
var prospect = await Context.Prospects!
|
||||
.Include(x => x.Interactions)
|
||||
.FirstOrDefaultAsync(x => x.Id == prospectId);
|
||||
|
||||
if (prospect == null) return new(new Exception("Prospect not found"));
|
||||
|
||||
if (prospect.Interactions.Any(x => x.Type == InteractionType.Verify))
|
||||
return new(new Exception("Die Identitätsprüfung wurde bereits abgeschlossen. Es kann kein neuer Token generiert werden."));
|
||||
|
||||
prospect.VerificationToken = Guid.NewGuid();
|
||||
prospect.Modified = DateTime.UtcNow;
|
||||
|
||||
await Context.SaveChangesAsync();
|
||||
return new(prospect.VerificationToken.Value);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return new(e);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<OperationResult<Prospect>> GetProspectByVerificationTokenAsync(Guid token)
|
||||
{
|
||||
try
|
||||
{
|
||||
var prospect = await Context.Prospects!
|
||||
.Include(x => x.Interactions)
|
||||
.AsNoTracking()
|
||||
.FirstOrDefaultAsync(x => x.VerificationToken == token);
|
||||
|
||||
if (prospect == null) return new(new Exception("Ungültiger oder abgelaufener Token."));
|
||||
|
||||
if (prospect.Interactions.Any(x => x.Type == InteractionType.Verify))
|
||||
return new(new Exception("Die Identitätsprüfung wurde bereits abgeschlossen. Ein Hochladen weiterer Bilder ist nicht mehr möglich."));
|
||||
|
||||
return new(prospect);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return new(e);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<OperationResult> AddVerificationImageAsync(Guid prospectId, byte[] imageData, string contentType)
|
||||
{
|
||||
try
|
||||
{
|
||||
var prospect = await Context.Prospects!
|
||||
.Include(x => x.Interactions)
|
||||
.AsNoTracking()
|
||||
.FirstOrDefaultAsync(x => x.Id == prospectId);
|
||||
|
||||
if (prospect == null) return new(new Exception("Foodsaver nicht gefunden."));
|
||||
|
||||
if (prospect.Interactions.Any(x => x.Type == InteractionType.Verify))
|
||||
return new(new Exception("Die Identitätsprüfung wurde bereits abgeschlossen. Ein Hochladen weiterer Bilder ist nicht mehr möglich."));
|
||||
|
||||
// Verify max 5 images
|
||||
var imgCount = await Context.ProspectImages!.CountAsync(x => x.ProspectId == prospectId);
|
||||
if (imgCount >= 5) return new(new Exception("Maximum 5 images allowed"));
|
||||
|
||||
var image = new ProspectImage
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
ProspectId = prospectId,
|
||||
ImageData = imageData,
|
||||
ContentType = contentType,
|
||||
Created = DateTime.UtcNow
|
||||
};
|
||||
|
||||
await Context.ProspectImages!.AddAsync(image);
|
||||
await Context.SaveChangesAsync();
|
||||
|
||||
return new();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return new(e);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<OperationResult<List<ProspectImage>>> GetVerificationImagesAsync(Guid prospectId)
|
||||
{
|
||||
try
|
||||
{
|
||||
var images = await Context.ProspectImages!
|
||||
.AsNoTracking()
|
||||
.Where(x => x.ProspectId == prospectId)
|
||||
.OrderBy(x => x.Created)
|
||||
.ToListAsync();
|
||||
|
||||
return new(images);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return new(e);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<OperationResult> DeleteVerificationImagesAsync(Guid prospectId)
|
||||
{
|
||||
try
|
||||
{
|
||||
var images = await Context.ProspectImages!.Where(x => x.ProspectId == prospectId).ToListAsync();
|
||||
if (images.Any())
|
||||
{
|
||||
Context.ProspectImages!.RemoveRange(images);
|
||||
|
||||
var prospect = await Context.Prospects!.FirstOrDefaultAsync(x => x.Id == prospectId);
|
||||
if (prospect != null)
|
||||
{
|
||||
prospect.VerificationToken = null; // Clear token when images are deleted
|
||||
}
|
||||
|
||||
await Context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
return new();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return new(e);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user