Added components, authentication and authorization
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
using MongoDB.Bson;
|
||||
using MongoDB.Driver;
|
||||
|
||||
namespace Htmx.ApiDemo.Data;
|
||||
|
||||
/// <summary>
|
||||
/// Scoped service wrapping the AppUser MongoDB collection.
|
||||
/// All operations use MongoDB's native async API — no EF, no LINQ-to-SQL
|
||||
/// translation, no RelationalModel, fully NativeAOT safe.
|
||||
/// </summary>
|
||||
public sealed class MongoDbService
|
||||
{
|
||||
private readonly IMongoCollection<AppUser> _users;
|
||||
|
||||
public MongoDbService(IMongoClient client, IConfiguration configuration)
|
||||
{
|
||||
var db = client.GetDatabase(configuration["MongoDbName"] ?? "HtmxAppDb");
|
||||
_users = db.GetCollection<AppUser>("users");
|
||||
}
|
||||
|
||||
/// <summary>Ensures the unique index on NormalizedEmail exists (idempotent).</summary>
|
||||
public async Task EnsureIndexesAsync(CancellationToken ct = default)
|
||||
{
|
||||
var indexKeys = Builders<AppUser>.IndexKeys.Ascending(u => u.NormalizedEmail);
|
||||
var indexOptions = new CreateIndexOptions { Unique = true, Name = "uq_normalizedEmail" };
|
||||
var model = new CreateIndexModel<AppUser>(indexKeys, indexOptions);
|
||||
await _users.Indexes.CreateOneAsync(model, cancellationToken: ct);
|
||||
}
|
||||
|
||||
/// <summary>Returns true if a user with the given normalised email already exists.</summary>
|
||||
public async Task<bool> EmailExistsAsync(string normalizedEmail, CancellationToken ct = default)
|
||||
{
|
||||
var filter = Builders<AppUser>.Filter.Eq(u => u.NormalizedEmail, normalizedEmail);
|
||||
return await _users.Find(filter).AnyAsync(ct);
|
||||
}
|
||||
|
||||
/// <summary>Returns the user matching the normalised email, or null.</summary>
|
||||
public async Task<AppUser?> FindByNormalizedEmailAsync(string normalizedEmail, CancellationToken ct = default)
|
||||
{
|
||||
var filter = Builders<AppUser>.Filter.Eq(u => u.NormalizedEmail, normalizedEmail);
|
||||
return await _users.Find(filter).FirstOrDefaultAsync(ct);
|
||||
}
|
||||
|
||||
/// <summary>Inserts a new user document.</summary>
|
||||
public Task InsertAsync(AppUser user, CancellationToken ct = default) =>
|
||||
_users.InsertOneAsync(user, cancellationToken: ct);
|
||||
}
|
||||
Reference in New Issue
Block a user