import type {
    AuthAccessRequestItem,
    AuthAllowedClientItem,
    AuthApplicationPageItem,
    AuthAuthorizationPageItem,
    PagedListWarp,
    AuthTokenPageItem,
    AdminMfaPayload,
    AdminMfaVerificationResult,
} from "../models/AuthModels";
import { ApiHttpClient } from "./ApiHttpClient";

export interface PageQuery {
    page: number;
    limit: number;
}

export interface ApplicationQuery extends PageQuery {
    keyword?: string;
}

export interface ApplicationFormPayload {
    id?: string;
    clientId: string;
    clientSecret?: string;
    displayName: string;
    logo?: string;
    applicationType?: string;
    clientType: string;
    redirectUris: string[];
    postLogoutRedirectUri?: string;
    permissions: string[];
    mfa?: AdminMfaPayload;
}

export interface AuthorizationQuery extends PageQuery {
    applicationId?: string;
    status?: string;
    type?: string;
    keyword?: string;
}

export interface TokenQuery extends PageQuery {
    userId?: string;
    clientId?: string;
}

export interface AccessRequestQuery extends PageQuery {
    account?: string;
    clientId?: string;
}

export interface GrantQuery extends PageQuery {
    account?: string;
    appId?: string;
}

export class AdminApiService {
    private readonly http = new ApiHttpClient();

    applications(query: ApplicationQuery) {
        return this.getPage<AuthApplicationPageItem>("/api/admin/applications", query);
    }

    applicationDetail(id: string) {
        return this.http.get<AuthApplicationPageItem>(
            `/api/admin/applications/${encodeURIComponent(id)}`,
        );
    }

    createApplication(payload: ApplicationFormPayload) {
        return this.http.post<AdminMfaVerificationResult>(
            "/api/admin/applications",
            this.toApplicationBody(payload),
        );
    }

    updateApplication(payload: ApplicationFormPayload) {
        return this.http.put<AdminMfaVerificationResult>(
            `/api/admin/applications/${encodeURIComponent(payload.id ?? "")}`,
            this.toApplicationBody(payload),
        );
    }

    authorizations(query: AuthorizationQuery) {
        return this.getPage<AuthAuthorizationPageItem>("/api/admin/authorizations", query);
    }

    tokens(query: TokenQuery) {
        return this.getPage<AuthTokenPageItem>("/api/admin/tokens", query);
    }

    accessRequests(query: AccessRequestQuery) {
        return this.getPage<AuthAccessRequestItem>("/api/admin/access-requests", query);
    }

    grants(query: GrantQuery) {
        return this.getPage<AuthAllowedClientItem>("/api/admin/grants", query);
    }

    deleteApplication(id: string, mfa?: AdminMfaPayload) {
        return this.http.delete<AdminMfaVerificationResult>(
            `/api/admin/applications/${encodeURIComponent(id)}`,
            mfa ?? {},
        );
    }

    revokeAuthorization(item: AuthAuthorizationPageItem, mfa?: AdminMfaPayload) {
        return this.http.post<AdminMfaVerificationResult>("/api/admin/authorizations/revoke", {
            applicationId: item.applicationId,
            status: item.status ?? "",
            type: item.type ?? "",
            ...(mfa ?? {}),
        });
    }

    revokeTokenByUser(userId: string, mfa?: AdminMfaPayload) {
        return this.http.post<AdminMfaVerificationResult>("/api/admin/tokens/revoke-by-user", {
            userId,
            ...(mfa ?? {}),
        });
    }

    revokeTokenByClient(clientId: string, mfa?: AdminMfaPayload) {
        return this.http.post<AdminMfaVerificationResult>("/api/admin/tokens/revoke-by-client", {
            clientId,
            ...(mfa ?? {}),
        });
    }

    handleAccessRequest(id: string, status: number, remark: string) {
        return this.http.patch(`/api/admin/access-requests/${encodeURIComponent(id)}`, {
            status,
            remark,
        });
    }

    grantAllowedClient(account: string, appId: string) {
        return this.http.post("/api/admin/grants", { account, appId });
    }

    revokeAllowedClient(id: string) {
        return this.http.delete(`/api/admin/grants/${encodeURIComponent(id)}`);
    }

    private getPage<T>(url: string, query: object) {
        const requestUrl = `${url}?${this.toSearchParams(query).toString()}`;
        return this.http.get<PagedListWarp<T>>(requestUrl);
    }

    private toApplicationBody(payload: ApplicationFormPayload) {
        return {
            clientId: payload.clientId,
            clientSecret: payload.clientSecret,
            displayName: payload.displayName,
            logo: payload.logo,
            applicationType: payload.applicationType,
            clientType: payload.clientType,
            redirectUris: payload.redirectUris,
            postLogoutRedirectUri: payload.postLogoutRedirectUri,
            permissions: payload.permissions,
            ...(payload.mfa ?? {}),
        };
    }

    private toSearchParams(query: object) {
        const params = new URLSearchParams();
        for (const [key, value] of Object.entries(query)) {
            if (value === undefined || value === null || value === "") {
                continue;
            }
            params.append(key, String(value));
        }
        return params;
    }
}
⚠⚠    以下内容为AI分析的结果,请根据实际情况进行判断。

代码解释

这是一个 TypeScript 编写的后台管理 API 服务类,用于处理认证授权系统的管理功能。

主要组成部分

1. 接口定义 (Interface Definitions)

定义了多个查询和表单数据的类型接口:

  • PageQuery: 基础分页查询(页码、每页条数)
  • ApplicationQuery: 应用查询(继承分页 + 关键词搜索)
  • ApplicationFormPayload: 应用表单数据(包含客户端ID、密钥、显示名称、重定向URI、权限、MFA配置等)
  • AuthorizationQuery: 授权查询(按应用ID、状态、类型、关键词筛选)
  • TokenQuery: Token查询(按用户ID或客户端ID筛选)
  • AccessRequestQuery: 访问请求查询
  • GrantQuery: 授权许可查询

2. 核心服务类 AdminApiService

这是一个封装了所有管理端API调用的服务类:

应用管理 (Application Management)

applications()        // 获取应用列表(分页)
applicationDetail()   // 获取应用详情
createApplication()   // 创建应用(支持MFA验证)
updateApplication()   // 更新应用(支持MFA验证)
deleteApplication()   // 删除应用(支持MFA验证)

授权管理 (Authorization Management)

authorizations()      // 获取授权列表
revokeAuthorization() // 撤销授权(支持MFA验证)

Token管理 (Token Management)

tokens()              // 获取Token列表
revokeTokenByUser()   // 按用户撤销Token
revokeTokenByClient() // 按客户端撤销Token

访问请求管理 (Access Request Management)

accessRequests()      // 获取访问请求列表
handleAccessRequest() // 处理访问请求(批准/拒绝)

客户端授权管理 (Client Grant Management)

grants()              // 获取授权客户端列表
grantAllowedClient()  // 授予客户端访问权限
revokeAllowedClient() // 撤销客户端访问权限

3. 私有辅助方法

  • getPage<T>(): 通用分页数据获取方法,构建查询URL并发起GET请求
  • toApplicationBody(): 将应用表单数据转换为API请求体(合并MFA参数)
  • toSearchParams(): 将查询对象转换为URL查询参数,自动过滤空值

关键设计特点

  1. 泛型支持: 使用泛型 <T> 实现类型安全的分页数据返回
  2. MFA集成: 多个敏感操作(创建/更新/删除应用、撤销授权/Token)支持多因素认证
  3. 参数清洗: toSearchParams 方法自动过滤 undefinednull、空字符串
  4. URL编码: 使用 encodeURIComponent 防止URL注入
  5. RESTful规范: 使用标准HTTP方法(GET/POST/PUT/PATCH/DELETE)

使用场景

这是一个OAuth2.0/OIDC认证授权系统的后台管理API客户端,用于:

  • 管理OAuth应用(注册、配置、删除)
  • 监控和管理用户授权
  • 处理访问申请
  • 管理访问令牌生命周期
评论加载中...