diff --git a/PasswordKeeper.BusinessLogic/Users.cs b/PasswordKeeper.BusinessLogic/Users.cs
index 8e30c14..dabfda5 100644
--- a/PasswordKeeper.BusinessLogic/Users.cs
+++ b/PasswordKeeper.BusinessLogic/Users.cs
@@ -10,7 +10,7 @@ namespace PasswordKeeper.BusinessLogic;
public class Users(PasswordKeeper.DataAccess.Users users)
{
///
- public async Task UpsertUser(UserDto userDto)
+ public async Task UpsertUser(UserDto userDto)
{
return await users.UpsertUser(userDto);
}
diff --git a/PasswordKeeper.DataAccess/Users.cs b/PasswordKeeper.DataAccess/Users.cs
index a1de3cb..17c749b 100644
--- a/PasswordKeeper.DataAccess/Users.cs
+++ b/PasswordKeeper.DataAccess/Users.cs
@@ -30,8 +30,8 @@ public class Users(IDbContextFactory dbContextFactory, IMapper mapper)
/// Upserts a user. If the user doesn't exist, inserts it, otherwise updates it.
///
/// The user to upsert.
- /// true if the user was upserted successfully, otherwise false.
- public async Task UpsertUser(UserDto userDto)
+ /// The upserted user data or null if the operation failed.
+ public async Task UpsertUser(UserDto userDto)
{
await using var context = await dbContextFactory.CreateDbContextAsync();
@@ -49,6 +49,6 @@ public async Task UpsertUser(UserDto userDto)
await context.SaveChangesAsync();
- return true;
+ return mapper.Map(user);
}
}
\ No newline at end of file
diff --git a/PasswordKeeperServer/Controllers/AuthenticationController.cs b/PasswordKeeperServer/Controllers/AuthenticationController.cs
index fbbe293..e2b9bca 100644
--- a/PasswordKeeperServer/Controllers/AuthenticationController.cs
+++ b/PasswordKeeperServer/Controllers/AuthenticationController.cs
@@ -1,4 +1,5 @@
using System.IdentityModel.Tokens.Jwt;
+using System.Security.Authentication;
using System.Security.Claims;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
@@ -47,9 +48,9 @@ public async Task Login([FromBody] UserLogin user)
PasswordSalt = Convert.ToBase64String(salt!),
};
- await users.UpsertUser(userDto);
+ userDto = await users.UpsertUser(userDto);
- var token = GenerateJwtToken(user.Username);
+ var token = GenerateJwtToken(user.Username, userDto.Id);
return Ok(new { token, });
}
@@ -59,7 +60,7 @@ public async Task Login([FromBody] UserLogin user)
if (Users.VerifyPassword(user.Password, userDto.PasswordHash,
Convert.FromBase64String(userDto.PasswordSalt)))
{
- var token = GenerateJwtToken(user.Username);
+ var token = GenerateJwtToken(user.Username, userDto.Id);
return Ok(new { token, });
}
}
@@ -77,17 +78,35 @@ public IActionResult TestUnauthorized()
return Ok();
}
+ ///
+ /// Gets the logged-in user's ID.
+ ///
+ /// The logged-in user's ID, or -1 if the claim containing the user ID is not found.
+ long GetLoggedUserId()
+ {
+ var claim = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier && long.TryParse(c.Value, out _));
+
+ if (long.TryParse(claim?.Value, out var result))
+ {
+ return result;
+ }
+
+ return -1;
+ }
+
///
/// Generates a JWT token for the given username.
///
/// The username to generate the JWT token for.
+ /// The user ID to generate the JWT token for.
/// The JWT token.
- private string GenerateJwtToken(string username)
+ private string GenerateJwtToken(string username, long userId)
{
var claims = new[]
{
new Claim(JwtRegisteredClaimNames.Sub, username),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
+ new Claim(JwtRegisteredClaimNames.NameId, userId.ToString()),
};
var key = new SymmetricSecurityKey(Program.JwtKey);
diff --git a/PasswordKeeperServer/Program.cs b/PasswordKeeperServer/Program.cs
index 388ca05..0bebffe 100644
--- a/PasswordKeeperServer/Program.cs
+++ b/PasswordKeeperServer/Program.cs
@@ -3,6 +3,7 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
+using Microsoft.OpenApi;
using MySql.Data.MySqlClient;
using PasswordKeeper.BusinessLogic;
using PasswordKeeper.DAO;
@@ -70,7 +71,11 @@ public static void Main(string[] args)
builder.Services.AddAutoMapper(typeof(AutoMapperProfile));
// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi
- builder.Services.AddOpenApi();
+ builder.Services.AddOpenApi("v3",options =>
+ {
+ options.ShouldInclude = operation => operation.HttpMethod != null;
+ options.OpenApiVersion = OpenApiSpecVersion.OpenApi3_0;
+ });
var app = builder.Build();