add role api
This commit is contained in:
+57
-2
@@ -38,6 +38,7 @@ Errors: `404` unknown function, `400` (`KeyNotFoundException`/`InvalidOperationE
|
|||||||
| `/api/loginUser` | POST | UserManager | forced `loginUser` |
|
| `/api/loginUser` | POST | UserManager | forced `loginUser` |
|
||||||
| `/api/forgotPassword` | POST | RecoveryManager | forced `forgotPassword` |
|
| `/api/forgotPassword` | POST | RecoveryManager | forced `forgotPassword` |
|
||||||
| `/api/alt` | POST | AltOptionManager | from body |
|
| `/api/alt` | POST | AltOptionManager | from body |
|
||||||
|
| `/api/role` | POST | RoleManager | from body |
|
||||||
|
|
||||||
### GET /api/status
|
### GET /api/status
|
||||||
Response:
|
Response:
|
||||||
@@ -63,9 +64,12 @@ Payload:
|
|||||||
"roleId": "guid (required)",
|
"roleId": "guid (required)",
|
||||||
"userTypeId": "guid (required)",
|
"userTypeId": "guid (required)",
|
||||||
"chkUser": "bool? (if true, checks for existing conflicting user)",
|
"chkUser": "bool? (if true, checks for existing conflicting user)",
|
||||||
"password": "string? (auto-generated if empty)"
|
"password": "string? (auto-generated if empty)",
|
||||||
|
"sendCredentialsEmail": "bool? (default true; emails `email` the username + password when set)"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
The generated/supplied password is now persisted (hashed) against the user record (previously a bug left it unset). When `email` is present and `sendCredentialsEmail` is not `false`, an email with the username and password is sent best-effort after the user is committed (failures do not roll back registration).
|
||||||
|
|
||||||
Data:
|
Data:
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -129,6 +133,13 @@ Data:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### listUserTypes
|
||||||
|
No payload.
|
||||||
|
Data: array of
|
||||||
|
```json
|
||||||
|
{ "userTypeId": "guid", "code": "", "description": "" }
|
||||||
|
```
|
||||||
|
|
||||||
### getUserSessions
|
### getUserSessions
|
||||||
_Requires auth (userId from claims). No payload needed._
|
_Requires auth (userId from claims). No payload needed._
|
||||||
Data: array of
|
Data: array of
|
||||||
@@ -323,8 +334,52 @@ Data:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## /api/role — RoleManager functions
|
||||||
|
|
||||||
|
> **Null-tolerant fields (fixed 2026-07-18):** `isSystemRole` is read via `data["isSystemRole"].ValueKind != JsonValueKind.Null`
|
||||||
|
> before calling `GetBoolean()` in both `createRole` and `updateRole` — an explicit JSON `null` (as opposed to the key being
|
||||||
|
> absent) previously threw an unhandled `InvalidOperationException`, surfaced to ERPCore callers as a generic `500`/`AUTH_UPSTREAM_ERROR`.
|
||||||
|
|
||||||
|
### createRole
|
||||||
|
Payload:
|
||||||
|
```json
|
||||||
|
{ "code": "string (required)", "name": "string? (defaults to code)", "isSystemRole": "bool? (default false)" }
|
||||||
|
```
|
||||||
|
Data:
|
||||||
|
```json
|
||||||
|
{ "roleId": "guid", "code": "", "name": "", "isSystemRole": false, "createdAt": "" }
|
||||||
|
```
|
||||||
|
|
||||||
|
### getRole
|
||||||
|
Payload:
|
||||||
|
```json
|
||||||
|
{ "roleId": "guid (required)" }
|
||||||
|
```
|
||||||
|
Data: same shape as `createRole`.
|
||||||
|
|
||||||
|
### listRoles
|
||||||
|
No payload.
|
||||||
|
Data: array of `createRole`-shaped objects.
|
||||||
|
|
||||||
|
### updateRole
|
||||||
|
Payload (all fields optional except `roleId`):
|
||||||
|
```json
|
||||||
|
{ "roleId": "guid (required)", "code": "string?", "name": "string?", "isSystemRole": "bool?" }
|
||||||
|
```
|
||||||
|
Data: same shape as `createRole`.
|
||||||
|
|
||||||
|
### deleteRole
|
||||||
|
Payload:
|
||||||
|
```json
|
||||||
|
{ "roleId": "guid (required)" }
|
||||||
|
```
|
||||||
|
Blocked with a `400` (`"ROLE_IN_USE: role is assigned to one or more users"`) if any `User.RoleId` references it (FK is `Restrict`).
|
||||||
|
Data: `{ "message": "Role deleted successfully" }`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
- All timestamps are UTC.
|
- All timestamps are UTC.
|
||||||
- `deviceName`, `Browser`, `OS`, `IPAddress` are captured per session from request headers for session tracking (`getUserSessions`).
|
- `deviceName`, `Browser`, `OS`, `IPAddress` are captured per session from request headers for session tracking (`getUserSessions`).
|
||||||
- Password login validation (`PasswordHasher.Verify`) is currently commented out in `loginUser` — passwords are not checked on login as of this version.
|
- Password login validation (`PasswordHasher.Verify`) is performed in `loginUser` — invalid/missing password hashes are rejected.
|
||||||
- JWT access tokens issued with `expiresIn: 3600` (1 hour); refresh tokens/sessions expire after 30 days.
|
- JWT access tokens issued with `expiresIn: 3600` (1 hour); refresh tokens/sessions expire after 30 days.
|
||||||
|
|||||||
@@ -10,11 +10,12 @@ namespace AuthHex.Controllers
|
|||||||
[ApiController]
|
[ApiController]
|
||||||
[Route("api")]
|
[Route("api")]
|
||||||
[EnableCors("AllowAll")]
|
[EnableCors("AllowAll")]
|
||||||
public class APIController(UserManager userManager, RecoveryManager recoveryManager, AltOptionManager altOptionManager) : ControllerBase
|
public class APIController(UserManager userManager, RecoveryManager recoveryManager, AltOptionManager altOptionManager, RoleManager roleManager) : ControllerBase
|
||||||
{
|
{
|
||||||
private readonly UserManager _userManager = userManager;
|
private readonly UserManager _userManager = userManager;
|
||||||
private readonly RecoveryManager _recoveryManager = recoveryManager;
|
private readonly RecoveryManager _recoveryManager = recoveryManager;
|
||||||
private readonly AltOptionManager _altOptionManager = altOptionManager;
|
private readonly AltOptionManager _altOptionManager = altOptionManager;
|
||||||
|
private readonly RoleManager _roleManager = roleManager;
|
||||||
|
|
||||||
[HttpGet("status")]
|
[HttpGet("status")]
|
||||||
[AllowAnonymous]
|
[AllowAnonymous]
|
||||||
@@ -70,10 +71,18 @@ namespace AuthHex.Controllers
|
|||||||
[AllowAnonymous]
|
[AllowAnonymous]
|
||||||
public async Task<IActionResult> IsAvailable([FromBody] ApiRequest request)
|
public async Task<IActionResult> IsAvailable([FromBody] ApiRequest request)
|
||||||
{
|
{
|
||||||
|
|
||||||
var response = await _altOptionManager.Execute(request, HttpContext);
|
var response = await _altOptionManager.Execute(request, HttpContext);
|
||||||
return StatusCode(response.StatusCode, response);
|
return StatusCode(response.StatusCode, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpPost("role")]
|
||||||
|
[AllowAnonymous]
|
||||||
|
public async Task<IActionResult> RoleExecute([FromBody] ApiRequest request)
|
||||||
|
{
|
||||||
|
var response = await _roleManager.Execute(request, HttpContext);
|
||||||
|
return StatusCode(response.StatusCode, response);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
using AuthHex.Models;
|
||||||
|
|
||||||
|
namespace AuthHex.Interfaces
|
||||||
|
{
|
||||||
|
public interface IRoleManageRepository
|
||||||
|
{
|
||||||
|
Task<Role> AddRoleAsync(Role role, CancellationToken ct = default);
|
||||||
|
Task<Role?> GetRoleByIdAsync(Guid roleId, CancellationToken ct = default);
|
||||||
|
Task<List<Role>> ListRolesAsync(CancellationToken ct = default);
|
||||||
|
Task<bool> RoleInUseAsync(Guid roleId, CancellationToken ct = default);
|
||||||
|
Task DeleteRoleAsync(Role role, CancellationToken ct = default);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -57,15 +57,18 @@ builder.Services.AddScoped<IUnitOfWork, EFUnitOfWork>();
|
|||||||
builder.Services.AddScoped<IUserManageRepository, UserManageRepository>();
|
builder.Services.AddScoped<IUserManageRepository, UserManageRepository>();
|
||||||
builder.Services.AddScoped<IRecoveryManagerRepository, RecoveryManagerRepository>();
|
builder.Services.AddScoped<IRecoveryManagerRepository, RecoveryManagerRepository>();
|
||||||
builder.Services.AddScoped<IAltOptionManagerRepository, AltOptionManagerRepository>();
|
builder.Services.AddScoped<IAltOptionManagerRepository, AltOptionManagerRepository>();
|
||||||
|
builder.Services.AddScoped<IRoleManageRepository, RoleManageRepository>();
|
||||||
builder.Services.AddScoped<UserHelper>();
|
builder.Services.AddScoped<UserHelper>();
|
||||||
builder.Services.AddScoped<UserManagerService>();
|
builder.Services.AddScoped<UserManagerService>();
|
||||||
builder.Services.AddScoped<RecoveryManagerService>();
|
builder.Services.AddScoped<RecoveryManagerService>();
|
||||||
builder.Services.AddScoped<AuthHex.Services.AltOptionManager.AltOptionManagerService>();
|
builder.Services.AddScoped<AuthHex.Services.AltOptionManager.AltOptionManagerService>();
|
||||||
|
builder.Services.AddScoped<AuthHex.Services.RoleManager.RoleManagerService>();
|
||||||
builder.Services.AddHttpClient<ThirdPartyService>();
|
builder.Services.AddHttpClient<ThirdPartyService>();
|
||||||
builder.Services.AddScoped<JwtTokenHelper>();
|
builder.Services.AddScoped<JwtTokenHelper>();
|
||||||
builder.Services.AddScoped<AuthHex.Services.FunctionHandler.UserManager>();
|
builder.Services.AddScoped<AuthHex.Services.FunctionHandler.UserManager>();
|
||||||
builder.Services.AddScoped<AuthHex.Services.FunctionHandler.RecoveryManager>();
|
builder.Services.AddScoped<AuthHex.Services.FunctionHandler.RecoveryManager>();
|
||||||
builder.Services.AddScoped<AuthHex.Services.FunctionHandler.AltOptionManager>();
|
builder.Services.AddScoped<AuthHex.Services.FunctionHandler.AltOptionManager>();
|
||||||
|
builder.Services.AddScoped<AuthHex.Services.FunctionHandler.RoleManager>();
|
||||||
|
|
||||||
var configuredOrigins = builder.Configuration.GetSection("Cors:AllowedOrigins").Get<string[]>() ?? Array.Empty<string>();
|
var configuredOrigins = builder.Configuration.GetSection("Cors:AllowedOrigins").Get<string[]>() ?? Array.Empty<string>();
|
||||||
var allowedOrigins = configuredOrigins
|
var allowedOrigins = configuredOrigins
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
using AuthHex.Interfaces;
|
||||||
|
using AuthHex.Models;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace AuthHex.Repos
|
||||||
|
{
|
||||||
|
public class RoleManageRepository : IRoleManageRepository
|
||||||
|
{
|
||||||
|
private readonly AppDBContext _dbContext;
|
||||||
|
|
||||||
|
public RoleManageRepository(AppDBContext dbContext)
|
||||||
|
{
|
||||||
|
_dbContext = dbContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<Role> AddRoleAsync(Role role, CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
_dbContext.Roles.Add(role);
|
||||||
|
return Task.FromResult(role);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Role?> GetRoleByIdAsync(Guid roleId, CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
return await _dbContext.Roles.FirstOrDefaultAsync(r => r.RoleId == roleId, ct);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<List<Role>> ListRolesAsync(CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
return await _dbContext.Roles.OrderBy(r => r.Code).ToListAsync(ct);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<bool> RoleInUseAsync(Guid roleId, CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
return await _dbContext.Users.AnyAsync(u => u.RoleId == roleId, ct);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task DeleteRoleAsync(Role role, CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
_dbContext.Roles.Remove(role);
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
using AuthHex.Models.IOs;
|
||||||
|
using AuthHex.Services.RoleManager;
|
||||||
|
|
||||||
|
namespace AuthHex.Services.FunctionHandler
|
||||||
|
{
|
||||||
|
public class RoleManager
|
||||||
|
{
|
||||||
|
public readonly Dictionary<string, Func<object, HttpContext, Task<object>>> _functionHandler;
|
||||||
|
|
||||||
|
public RoleManager(RoleManagerService roleManagerService)
|
||||||
|
{
|
||||||
|
_functionHandler = new()
|
||||||
|
{
|
||||||
|
{ "createRole", roleManagerService.CreateRole },
|
||||||
|
{ "getRole", roleManagerService.GetRole },
|
||||||
|
{ "listRoles", async (payload, context) => await roleManagerService.ListRoles(context) },
|
||||||
|
{ "updateRole", roleManagerService.UpdateRole },
|
||||||
|
{ "deleteRole", roleManagerService.DeleteRole }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ApiResponse> Execute(ApiRequest request, HttpContext httpContext)
|
||||||
|
{
|
||||||
|
if (!_functionHandler.TryGetValue(request.FunctionName, out var handler))
|
||||||
|
{
|
||||||
|
return new ApiResponse
|
||||||
|
{
|
||||||
|
StatusCode = 404,
|
||||||
|
Message = $"Function '{request.FunctionName}' not found.",
|
||||||
|
Data = null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var results = await handler(request.Payload, httpContext);
|
||||||
|
return new ApiResponse
|
||||||
|
{
|
||||||
|
StatusCode = 200,
|
||||||
|
Message = "success",
|
||||||
|
Data = results
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch (KeyNotFoundException ex)
|
||||||
|
{
|
||||||
|
return new ApiResponse
|
||||||
|
{
|
||||||
|
StatusCode = 400,
|
||||||
|
Message = ex.Message,
|
||||||
|
Data = null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch (InvalidOperationException ex)
|
||||||
|
{
|
||||||
|
return new ApiResponse
|
||||||
|
{
|
||||||
|
StatusCode = 400,
|
||||||
|
Message = ex.Message,
|
||||||
|
Data = null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch (ArgumentException ex)
|
||||||
|
{
|
||||||
|
return new ApiResponse
|
||||||
|
{
|
||||||
|
StatusCode = 500,
|
||||||
|
Message = ex.Message,
|
||||||
|
Data = null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,6 +18,7 @@ namespace AuthHex.Services.FunctionHandler
|
|||||||
{ "refreshToken", UserManagerService.RefreshToken },
|
{ "refreshToken", UserManagerService.RefreshToken },
|
||||||
{ "getUserDetails", UserManagerService.GetUserDetails },
|
{ "getUserDetails", UserManagerService.GetUserDetails },
|
||||||
{ "getUserSessions", async (payload, context) => await UserManagerService.GetUserSessions(context) },
|
{ "getUserSessions", async (payload, context) => await UserManagerService.GetUserSessions(context) },
|
||||||
|
{ "listUserTypes", async (payload, context) => await UserManagerService.ListUserTypes(context) },
|
||||||
{ "ChangeUserStatus", UserManagerService.ChangeUserStatus},
|
{ "ChangeUserStatus", UserManagerService.ChangeUserStatus},
|
||||||
{"LockUserAccount" , UserManagerService.LockUserAccount },
|
{"LockUserAccount" , UserManagerService.LockUserAccount },
|
||||||
{"ChangeUserPassword" , UserManagerService.ChangeUserPassword },
|
{"ChangeUserPassword" , UserManagerService.ChangeUserPassword },
|
||||||
|
|||||||
@@ -0,0 +1,151 @@
|
|||||||
|
using System.Text.Json;
|
||||||
|
using AuthHex.Infra.UoW;
|
||||||
|
using AuthHex.Interfaces;
|
||||||
|
using AuthHex.Models;
|
||||||
|
using Core_Archi.Helpers;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
||||||
|
namespace AuthHex.Services.RoleManager;
|
||||||
|
|
||||||
|
public class RoleManagerService
|
||||||
|
{
|
||||||
|
private readonly IRoleManageRepository _repository;
|
||||||
|
private readonly IUnitOfWork _uow;
|
||||||
|
|
||||||
|
public RoleManagerService(IRoleManageRepository repository, IUnitOfWork uow)
|
||||||
|
{
|
||||||
|
_repository = repository;
|
||||||
|
_uow = uow;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<object> CreateRole(object payload, HttpContext httpContext)
|
||||||
|
{
|
||||||
|
await _uow.BeginAsync();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var data = DeserializePayload.Deserialize(payload);
|
||||||
|
|
||||||
|
var code = data.ContainsKey("code") ? data["code"].GetString() : null;
|
||||||
|
var name = data.ContainsKey("name") ? data["name"].GetString() : null;
|
||||||
|
var isSystemRole = data.ContainsKey("isSystemRole")
|
||||||
|
&& data["isSystemRole"].ValueKind != JsonValueKind.Null
|
||||||
|
&& data["isSystemRole"].GetBoolean();
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(code))
|
||||||
|
throw new ArgumentException("code is required");
|
||||||
|
|
||||||
|
var role = new Role
|
||||||
|
{
|
||||||
|
RoleId = Guid.NewGuid(),
|
||||||
|
Code = code,
|
||||||
|
Name = string.IsNullOrWhiteSpace(name) ? code : name,
|
||||||
|
IsSystemRole = isSystemRole,
|
||||||
|
CreatedAt = DateTime.UtcNow
|
||||||
|
};
|
||||||
|
|
||||||
|
await _repository.AddRoleAsync(role);
|
||||||
|
await _uow.CommitAsync();
|
||||||
|
|
||||||
|
return ToDto(role);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
await _uow.RollbackAsync();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<object> GetRole(object payload, HttpContext httpContext)
|
||||||
|
{
|
||||||
|
var data = DeserializePayload.Deserialize(payload);
|
||||||
|
|
||||||
|
if (!data.ContainsKey("roleId") || !Guid.TryParse(data["roleId"].GetString(), out var roleId))
|
||||||
|
throw new ArgumentException("Invalid roleId");
|
||||||
|
|
||||||
|
var role = await _repository.GetRoleByIdAsync(roleId)
|
||||||
|
?? throw new KeyNotFoundException("Role not found");
|
||||||
|
|
||||||
|
return ToDto(role);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<object> ListRoles(HttpContext httpContext)
|
||||||
|
{
|
||||||
|
var roles = await _repository.ListRolesAsync();
|
||||||
|
return roles.Select(ToDto).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<object> UpdateRole(object payload, HttpContext httpContext)
|
||||||
|
{
|
||||||
|
await _uow.BeginAsync();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var data = DeserializePayload.Deserialize(payload);
|
||||||
|
|
||||||
|
if (!data.ContainsKey("roleId") || !Guid.TryParse(data["roleId"].GetString(), out var roleId))
|
||||||
|
throw new ArgumentException("Invalid roleId");
|
||||||
|
|
||||||
|
var role = await _repository.GetRoleByIdAsync(roleId)
|
||||||
|
?? throw new KeyNotFoundException("Role not found");
|
||||||
|
|
||||||
|
if (data.ContainsKey("code"))
|
||||||
|
{
|
||||||
|
var code = data["code"].GetString();
|
||||||
|
if (string.IsNullOrWhiteSpace(code))
|
||||||
|
throw new ArgumentException("code cannot be empty");
|
||||||
|
role.Code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.ContainsKey("name"))
|
||||||
|
role.Name = data["name"].GetString();
|
||||||
|
|
||||||
|
if (data.ContainsKey("isSystemRole") && data["isSystemRole"].ValueKind != JsonValueKind.Null)
|
||||||
|
role.IsSystemRole = data["isSystemRole"].GetBoolean();
|
||||||
|
|
||||||
|
await _uow.CommitAsync();
|
||||||
|
|
||||||
|
return ToDto(role);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
await _uow.RollbackAsync();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<object> DeleteRole(object payload, HttpContext httpContext)
|
||||||
|
{
|
||||||
|
await _uow.BeginAsync();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var data = DeserializePayload.Deserialize(payload);
|
||||||
|
|
||||||
|
if (!data.ContainsKey("roleId") || !Guid.TryParse(data["roleId"].GetString(), out var roleId))
|
||||||
|
throw new ArgumentException("Invalid roleId");
|
||||||
|
|
||||||
|
var role = await _repository.GetRoleByIdAsync(roleId)
|
||||||
|
?? throw new KeyNotFoundException("Role not found");
|
||||||
|
|
||||||
|
if (await _repository.RoleInUseAsync(roleId))
|
||||||
|
throw new InvalidOperationException("ROLE_IN_USE: role is assigned to one or more users");
|
||||||
|
|
||||||
|
await _repository.DeleteRoleAsync(role);
|
||||||
|
await _uow.CommitAsync();
|
||||||
|
|
||||||
|
return new { message = "Role deleted successfully" };
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
await _uow.RollbackAsync();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static object ToDto(Role role) => new
|
||||||
|
{
|
||||||
|
role.RoleId,
|
||||||
|
role.Code,
|
||||||
|
role.Name,
|
||||||
|
role.IsSystemRole,
|
||||||
|
role.CreatedAt
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -94,8 +94,10 @@ public class UserManagerService
|
|||||||
data["password"] = JsonDocument.Parse($"\"{Guid.NewGuid().ToString().Substring(0, 8)}\"").RootElement;
|
data["password"] = JsonDocument.Parse($"\"{Guid.NewGuid().ToString().Substring(0, 8)}\"").RootElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
var PasswordHash = data.ContainsKey("password") ? PasswordHasher.Hash(data["password"].GetString()!) : null;
|
var RawPassword = data["password"].GetString()!;
|
||||||
|
var PasswordHash = PasswordHasher.Hash(RawPassword);
|
||||||
|
|
||||||
|
var sendCredentialsEmail = !data.ContainsKey("sendCredentialsEmail") || data["sendCredentialsEmail"].GetBoolean();
|
||||||
|
|
||||||
// Create User object
|
// Create User object
|
||||||
User user = new User
|
User user = new User
|
||||||
@@ -113,7 +115,7 @@ public class UserManagerService
|
|||||||
IsLocked = false,
|
IsLocked = false,
|
||||||
EmailVerified = false,
|
EmailVerified = false,
|
||||||
MobileNumberVerified = false,
|
MobileNumberVerified = false,
|
||||||
//PasswordHash = PasswordHash
|
PasswordHash = PasswordHash
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -151,6 +153,30 @@ public class UserManagerService
|
|||||||
|
|
||||||
await _uow.CommitAsync();
|
await _uow.CommitAsync();
|
||||||
|
|
||||||
|
if (sendCredentialsEmail && !string.IsNullOrWhiteSpace(Email))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _thirdPartyService.EmailConfiguration(
|
||||||
|
Email,
|
||||||
|
RawPassword,
|
||||||
|
"Your ERP System Account",
|
||||||
|
$@"
|
||||||
|
<html>
|
||||||
|
<body style='font-family: Arial, sans-serif;'>
|
||||||
|
<h2>Your ERP System account has been created</h2>
|
||||||
|
<p>Username: <strong>{WebUtility.HtmlEncode(UserName ?? Email)}</strong></p>
|
||||||
|
<p>Temporary password: <strong>{{code}}</strong></p>
|
||||||
|
<p>Please log in and change your password as soon as possible.</p>
|
||||||
|
</body>
|
||||||
|
</html>");
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// Best-effort: account creation already committed; do not fail the request on email delivery issues.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return new
|
return new
|
||||||
{
|
{
|
||||||
AccessToken = jwtToken,
|
AccessToken = jwtToken,
|
||||||
@@ -544,6 +570,17 @@ public class UserManagerService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<object> ListUserTypes(HttpContext httpContext)
|
||||||
|
{
|
||||||
|
var userTypes = await _dbContext.UserType.OrderBy(t => t.Code).ToListAsync();
|
||||||
|
return userTypes.Select(t => new
|
||||||
|
{
|
||||||
|
t.UserTypeId,
|
||||||
|
t.Code,
|
||||||
|
t.Description
|
||||||
|
}).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<object> GetUserSessions(HttpContext httpContext)
|
public async Task<object> GetUserSessions(HttpContext httpContext)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|||||||
+2
-2
@@ -8,8 +8,8 @@
|
|||||||
"ConnectionStrings": {
|
"ConnectionStrings": {
|
||||||
|
|
||||||
//"DefaultConnection": "server=187.127.102.190;port=3306;database=hexafitnessauth;user=dbuser;password=dbpass"
|
//"DefaultConnection": "server=187.127.102.190;port=3306;database=hexafitnessauth;user=dbuser;password=dbpass"
|
||||||
"DefaultConnection": "server=localhost;port=3306;database=authhex;user=root;password="
|
//"DefaultConnection": "server=localhost;port=3306;database=authhex;user=root;password="
|
||||||
//"DefaultConnection": "server=187.127.102.190;port=3306;database=omsauth;user=poojathmi;password=poojathmi@hexdive.com"
|
"DefaultConnection": "server=187.127.102.190;port=3306;database=erpauth;user=poojathmi;password=poojathmi@hexdive.com"
|
||||||
},
|
},
|
||||||
"AllowedHosts": "*",
|
"AllowedHosts": "*",
|
||||||
"AppSettings": {
|
"AppSettings": {
|
||||||
|
|||||||
Reference in New Issue
Block a user