feat: 支持租户伪装登录与管理员重置链接
This commit is contained in:
@@ -5,6 +5,7 @@ using System.ComponentModel.DataAnnotations;
|
||||
using TakeoutSaaS.Application.App.Tenants.Commands;
|
||||
using TakeoutSaaS.Application.App.Tenants.Dto;
|
||||
using TakeoutSaaS.Application.App.Tenants.Queries;
|
||||
using TakeoutSaaS.Application.Identity.Contracts;
|
||||
using TakeoutSaaS.Module.Authorization.Attributes;
|
||||
using TakeoutSaaS.Shared.Abstractions.Results;
|
||||
using TakeoutSaaS.Shared.Web.Api;
|
||||
@@ -318,6 +319,49 @@ public sealed class TenantsController(IMediator mediator) : BaseApiController
|
||||
return ApiResponse<PagedResult<TenantAuditLogDto>>.Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 伪装登录租户(仅平台超级管理员可用)。
|
||||
/// </summary>
|
||||
/// <returns>目标租户主管理员的令牌对。</returns>
|
||||
[HttpPost("{tenantId:long}/impersonate")]
|
||||
[PermissionAuthorize("tenant:read")]
|
||||
[ProducesResponseType(typeof(ApiResponse<TokenResponse>), StatusCodes.Status200OK)]
|
||||
public async Task<ApiResponse<TokenResponse>> Impersonate(long tenantId, CancellationToken cancellationToken)
|
||||
{
|
||||
// 1. 执行伪装登录
|
||||
var result = await mediator.Send(new ImpersonateTenantCommand { TenantId = tenantId }, cancellationToken);
|
||||
|
||||
// 2. 返回令牌
|
||||
return ApiResponse<TokenResponse>.Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成租户主管理员重置密码链接(仅平台超级管理员可用)。
|
||||
/// </summary>
|
||||
/// <remarks>链接默认 24 小时有效且仅可使用一次。</remarks>
|
||||
/// <returns>重置密码链接。</returns>
|
||||
[HttpPost("{tenantId:long}/admin/reset-link")]
|
||||
[PermissionAuthorize("tenant:read")]
|
||||
[ProducesResponseType(typeof(ApiResponse<string>), StatusCodes.Status200OK)]
|
||||
public async Task<ApiResponse<string>> CreateAdminResetLink(long tenantId, CancellationToken cancellationToken)
|
||||
{
|
||||
// 1. 生成一次性令牌
|
||||
var token = await mediator.Send(new CreateTenantAdminResetLinkTokenCommand { TenantId = tenantId }, cancellationToken);
|
||||
|
||||
// 2. (空行后) 解析前端来源(优先 Origin,避免拼成 AdminApi 域名)
|
||||
var origin = Request.Headers.Origin.ToString();
|
||||
if (string.IsNullOrWhiteSpace(origin))
|
||||
{
|
||||
origin = $"{Request.Scheme}://{Request.Host}";
|
||||
}
|
||||
|
||||
origin = origin.TrimEnd('/');
|
||||
var resetUrl = $"{origin}/#/auth/reset-password?token={Uri.EscapeDataString(token)}";
|
||||
|
||||
// 3. (空行后) 返回链接
|
||||
return ApiResponse<string>.Ok(resetUrl);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 配额校验并占用额度(门店/账号/短信/配送)。
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user