mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-08 00:26:37 +08:00
oauth
This commit is contained in:
@@ -1,13 +1,16 @@
|
||||
import { BaseService } from '../core/base.service';
|
||||
import {BaseService} from '../core/base.service';
|
||||
import type {
|
||||
SystemConfig,
|
||||
AuthSource,
|
||||
AuthSourceRequest,
|
||||
CreateSystemConfigRequest,
|
||||
UpdateSystemConfigRequest,
|
||||
TaskMeta,
|
||||
TaskTypeResponse,
|
||||
DispatchTaskRequest,
|
||||
ListUsersRequest,
|
||||
ListUsersResponse,
|
||||
SystemConfig,
|
||||
TaskMeta,
|
||||
TaskTypeResponse,
|
||||
ToggleAuthSourceRequest,
|
||||
UpdateSystemConfigRequest,
|
||||
UpdateUserStatusRequest,
|
||||
} from './types';
|
||||
|
||||
@@ -16,7 +19,7 @@ export type { AdminUser } from './types';
|
||||
/**
|
||||
* 管理员服务
|
||||
* 处理系统配置和用户积分配置管理相关的 API 请求
|
||||
*
|
||||
*
|
||||
* @remarks
|
||||
* 所有接口都需要管理员权限
|
||||
*/
|
||||
@@ -32,7 +35,7 @@ export class AdminService extends BaseService {
|
||||
* @throws {UnauthorizedError} 当未登录时
|
||||
* @throws {ForbiddenError} 当无管理员权限时
|
||||
* @throws {ValidationError} 当参数验证失败或配置键已存在时
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* await AdminService.createSystemConfig({
|
||||
@@ -53,7 +56,7 @@ export class AdminService extends BaseService {
|
||||
* @returns 系统配置列表
|
||||
* @throws {UnauthorizedError} 当未登录时
|
||||
* @throws {ForbiddenError} 当无管理员权限时
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const configs = await AdminService.listSystemConfigs();
|
||||
@@ -72,7 +75,7 @@ export class AdminService extends BaseService {
|
||||
* @throws {UnauthorizedError} 当未登录时
|
||||
* @throws {ForbiddenError} 当无管理员权限时
|
||||
* @throws {NotFoundError} 当配置不存在时
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const config = await AdminService.getSystemConfig('app.version');
|
||||
@@ -92,7 +95,7 @@ export class AdminService extends BaseService {
|
||||
* @throws {ForbiddenError} 当无管理员权限时
|
||||
* @throws {NotFoundError} 当配置不存在时
|
||||
* @throws {ValidationError} 当参数验证失败时
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* await AdminService.updateSystemConfig('app.version', {
|
||||
@@ -115,7 +118,7 @@ export class AdminService extends BaseService {
|
||||
* @throws {UnauthorizedError} 当未登录时
|
||||
* @throws {ForbiddenError} 当无管理员权限时
|
||||
* @throws {NotFoundError} 当配置不存在时
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* await AdminService.deleteSystemConfig('app.version');
|
||||
@@ -125,6 +128,28 @@ export class AdminService extends BaseService {
|
||||
return this.delete<void>(`/system-configs/${ key }`);
|
||||
}
|
||||
|
||||
// ==================== 认证源管理 ====================
|
||||
|
||||
static async listAuthSources(): Promise<AuthSource[]> {
|
||||
return this.get<AuthSource[]>('/auth-sources');
|
||||
}
|
||||
|
||||
static async createAuthSource(request: AuthSourceRequest): Promise<AuthSource> {
|
||||
return this.post<AuthSource>('/auth-sources', request);
|
||||
}
|
||||
|
||||
static async updateAuthSource(id: string, request: AuthSourceRequest): Promise<AuthSource> {
|
||||
return this.put<AuthSource>(`/auth-sources/${ id }`, request);
|
||||
}
|
||||
|
||||
static async toggleAuthSource(id: string, request: ToggleAuthSourceRequest): Promise<void> {
|
||||
return this.put<void>(`/auth-sources/${ id }/toggle`, request);
|
||||
}
|
||||
|
||||
static async deleteAuthSource(id: string): Promise<void> {
|
||||
return this.delete<void>(`/auth-sources/${ id }`);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ==================== 任务管理 ====================
|
||||
@@ -134,7 +159,7 @@ export class AdminService extends BaseService {
|
||||
* @returns 任务类型列表
|
||||
* @throws {UnauthorizedError} 当未登录时
|
||||
* @throws {ForbiddenError} 当无管理员权限时
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const taskTypes = await AdminService.getTaskTypes();
|
||||
@@ -162,7 +187,7 @@ export class AdminService extends BaseService {
|
||||
* @throws {UnauthorizedError} 当未登录时
|
||||
* @throws {ForbiddenError} 当无管理员权限时
|
||||
* @throws {ValidationError} 当参数验证失败时
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* // 下发订单同步任务(带时间范围)
|
||||
@@ -171,19 +196,19 @@ export class AdminService extends BaseService {
|
||||
* start_time: '2025-12-01T00:00:00Z',
|
||||
* end_time: '2025-12-27T23:59:59Z'
|
||||
* });
|
||||
*
|
||||
*
|
||||
* // 下发用户积分更新任务
|
||||
* await AdminService.dispatchTask({
|
||||
* task_type: 'user_gamification',
|
||||
* user_id: 123
|
||||
* });
|
||||
*
|
||||
*
|
||||
* // 下发争议自动退款任务
|
||||
* await AdminService.dispatchTask({
|
||||
* task_type: 'dispute_auto_refund'
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
*
|
||||
* @remarks
|
||||
* - 不同任务类型需要不同的参数
|
||||
* - order_sync 支持 start_time 和 end_time 参数
|
||||
@@ -203,7 +228,7 @@ export class AdminService extends BaseService {
|
||||
* @throws {UnauthorizedError} 当未登录时
|
||||
* @throws {ForbiddenError} 当无管理员权限时
|
||||
* @throws {ValidationError} 当参数验证失败时
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const result = await AdminService.listUsers({
|
||||
@@ -215,7 +240,7 @@ export class AdminService extends BaseService {
|
||||
* console.log('用户总数:', result.total);
|
||||
* console.log('用户列表:', result.users);
|
||||
* ```
|
||||
*
|
||||
*
|
||||
* @remarks
|
||||
* - page 从 1 开始
|
||||
* - page_size 范围 1-100
|
||||
@@ -234,16 +259,16 @@ export class AdminService extends BaseService {
|
||||
* @throws {UnauthorizedError} 当未登录时
|
||||
* @throws {ForbiddenError} 当无管理员权限或禁用管理员用户时
|
||||
* @throws {NotFoundError} 当用户不存在时
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* // 禁用用户
|
||||
* await AdminService.updateUserStatus(123, { is_active: false });
|
||||
*
|
||||
*
|
||||
* // 启用用户
|
||||
* await AdminService.updateUserStatus(123, { is_active: true });
|
||||
* ```
|
||||
*
|
||||
*
|
||||
* @remarks
|
||||
* - 不能禁用管理员用户
|
||||
*/
|
||||
|
||||
@@ -24,6 +24,9 @@ export type {
|
||||
SystemConfig,
|
||||
CreateSystemConfigRequest,
|
||||
UpdateSystemConfigRequest,
|
||||
AuthSource,
|
||||
AuthSourceRequest,
|
||||
ToggleAuthSourceRequest,
|
||||
TaskMeta,
|
||||
DispatchTaskRequest,
|
||||
AdminUser,
|
||||
|
||||
@@ -171,3 +171,38 @@ export interface UpdateUserStatusRequest {
|
||||
/** 是否激活 */
|
||||
is_active: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* 认证源信息
|
||||
*/
|
||||
export interface AuthSource {
|
||||
id: string;
|
||||
name: string;
|
||||
type: 'oidc';
|
||||
display_name: string;
|
||||
is_active: boolean;
|
||||
client_id: string;
|
||||
client_secret?: string;
|
||||
client_secret_configured?: boolean;
|
||||
openid_discovery_url: string;
|
||||
scopes: string;
|
||||
icon_url: string;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
export interface AuthSourceRequest {
|
||||
name: string;
|
||||
type: 'oidc';
|
||||
display_name: string;
|
||||
is_active: boolean;
|
||||
client_id: string;
|
||||
client_secret: string;
|
||||
openid_discovery_url: string;
|
||||
scopes: string;
|
||||
icon_url: string;
|
||||
}
|
||||
|
||||
export interface ToggleAuthSourceRequest {
|
||||
is_active: boolean;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
import { BaseService } from '../core/base.service';
|
||||
import {BaseService} from '../core/base.service';
|
||||
import type {
|
||||
OAuthLoginUrlResponse,
|
||||
AuthSource,
|
||||
ExternalAccountBinding,
|
||||
LoginRequest,
|
||||
OAuthAuthorizeResponse,
|
||||
OAuthCallbackRequest,
|
||||
OAuthCallbackResult,
|
||||
OAuthLoginUrlResponse,
|
||||
RegisterRequest,
|
||||
User,
|
||||
} from './types';
|
||||
|
||||
@@ -10,13 +16,13 @@ import type {
|
||||
* 处理 OAuth 认证、用户信息获取、登出等
|
||||
*/
|
||||
export class AuthService extends BaseService {
|
||||
protected static readonly basePath = '/api/v1/oauth';
|
||||
protected static readonly basePath = '/api/v1';
|
||||
|
||||
/**
|
||||
* 获取 OAuth 登录 URL
|
||||
* @returns OAuth 授权 URL
|
||||
* @throws {ApiErrorBase} 当获取失败时
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const url = await AuthService.getLoginUrl();
|
||||
@@ -24,7 +30,15 @@ export class AuthService extends BaseService {
|
||||
* ```
|
||||
*/
|
||||
static async getLoginUrl(): Promise<OAuthLoginUrlResponse> {
|
||||
return this.get<OAuthLoginUrlResponse>('/login');
|
||||
return this.get<OAuthLoginUrlResponse>('/oauth/login');
|
||||
}
|
||||
|
||||
static async getAuthSources(): Promise<AuthSource[]> {
|
||||
return this.get<AuthSource[]>('/oauth/sources');
|
||||
}
|
||||
|
||||
static async getAuthorizeUrl(source: string, purpose: 'login' | 'bind' = 'login'): Promise<OAuthAuthorizeResponse> {
|
||||
return this.get<OAuthAuthorizeResponse>(`/oauth/${encodeURIComponent(source)}/authorize?purpose=${purpose}`);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -32,14 +46,14 @@ export class AuthService extends BaseService {
|
||||
* @param request - OAuth 回调参数(state 和 code)
|
||||
* @throws {ApiErrorBase} 当回调处理失败时
|
||||
* @throws {ValidationError} 当 state 无效时
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* // 在回调页面获取 URL 参数
|
||||
* const params = new URLSearchParams(window.location.search);
|
||||
* const state = params.get('state');
|
||||
* const code = params.get('code');
|
||||
*
|
||||
*
|
||||
* if (state && code) {
|
||||
* await AuthService.handleCallback({ state, code });
|
||||
* // 登录成功,跳转到首页
|
||||
@@ -47,15 +61,15 @@ export class AuthService extends BaseService {
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
static async handleCallback(request: OAuthCallbackRequest): Promise<void> {
|
||||
return this.post<void>('/callback', request);
|
||||
static async handleCallback(request: OAuthCallbackRequest): Promise<OAuthCallbackResult> {
|
||||
return this.post<OAuthCallbackResult>('/oauth/callback', request);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前登录用户信息
|
||||
* @returns 用户信息
|
||||
* @throws {UnauthorizedError} 当未登录时
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* try {
|
||||
@@ -76,7 +90,7 @@ export class AuthService extends BaseService {
|
||||
/**
|
||||
* 用户登出
|
||||
* @throws {ApiErrorBase} 当登出失败时
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* await AuthService.logout();
|
||||
@@ -85,33 +99,22 @@ export class AuthService extends BaseService {
|
||||
* ```
|
||||
*/
|
||||
static async logout(): Promise<void> {
|
||||
await this.get<void>('/logout');
|
||||
await this.get<void>('/oauth/logout');
|
||||
}
|
||||
|
||||
/**
|
||||
* 发起登录流程
|
||||
* 直接获取登录 URL 并重定向
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* // 在登录按钮点击时调用
|
||||
* await AuthService.initiateLogin();
|
||||
* ```
|
||||
*/
|
||||
static async initiateLogin(): Promise<void> {
|
||||
if (typeof window !== 'undefined') {
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
const callbackUrl = params.get('callbackUrl');
|
||||
static async login(request: LoginRequest): Promise<User> {
|
||||
return this.post<User>('/user/login', request);
|
||||
}
|
||||
|
||||
if (callbackUrl) {
|
||||
sessionStorage.setItem('redirect_after_login', callbackUrl);
|
||||
}
|
||||
}
|
||||
static async register(request: RegisterRequest): Promise<User> {
|
||||
return this.post<User>('/user/register', request);
|
||||
}
|
||||
|
||||
const url = await this.getLoginUrl();
|
||||
if (typeof window !== 'undefined' && url) {
|
||||
window.location.href = url;
|
||||
}
|
||||
static async getExternalAccountBindings(): Promise<ExternalAccountBinding[]> {
|
||||
return this.get<ExternalAccountBinding[]>('/oauth/external-accounts');
|
||||
}
|
||||
|
||||
static async deleteExternalAccountBinding(id: string): Promise<void> {
|
||||
return this.delete<void>(`/oauth/external-accounts/${encodeURIComponent(id)}/delete`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,5 +31,10 @@ export type {
|
||||
User,
|
||||
OAuthLoginUrlResponse,
|
||||
OAuthCallbackRequest,
|
||||
LoginRequest,
|
||||
RegisterRequest,
|
||||
OAuthAuthorizeResponse,
|
||||
OAuthCallbackResult,
|
||||
AuthSource,
|
||||
ExternalAccountBinding,
|
||||
} from './types';
|
||||
|
||||
|
||||
@@ -81,3 +81,44 @@ export interface OAuthCallbackRequest {
|
||||
/** 授权码 */
|
||||
code: string;
|
||||
}
|
||||
|
||||
export interface LoginRequest {
|
||||
username: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
export interface RegisterRequest {
|
||||
username: string;
|
||||
password: string;
|
||||
nickname?: string;
|
||||
}
|
||||
|
||||
export interface OAuthAuthorizeResponse {
|
||||
authorize_url: string;
|
||||
}
|
||||
|
||||
export interface OAuthCallbackResult {
|
||||
status: 'logged_in' | 'bound';
|
||||
user?: User;
|
||||
}
|
||||
|
||||
export interface AuthSource {
|
||||
id: string;
|
||||
name: string;
|
||||
type: 'oidc';
|
||||
display_name: string;
|
||||
is_active: boolean;
|
||||
icon_url: string;
|
||||
client_secret_configured: boolean;
|
||||
}
|
||||
|
||||
export interface ExternalAccountBinding {
|
||||
id: string;
|
||||
auth_source_id: string;
|
||||
auth_source_name: string;
|
||||
auth_source_type: string;
|
||||
auth_source_label: string;
|
||||
external_username: string;
|
||||
email: string;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
@@ -6,8 +6,14 @@ export interface PublicConfigResponse {
|
||||
upload_allowed_extensions: string;
|
||||
/** 站点名称 */
|
||||
site_name: string;
|
||||
/** 是否允许密码登录 */
|
||||
password_login_enabled: boolean;
|
||||
/** 是否允许注册 */
|
||||
registration_enabled: boolean;
|
||||
/** 是否允许密码注册 */
|
||||
password_register_enabled: boolean;
|
||||
/** 是否允许 OIDC 登录 */
|
||||
oidc_login_enabled: boolean;
|
||||
/** 每个用户最大 API Key 数量 */
|
||||
max_api_keys_per_user: number;
|
||||
}
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* ```
|
||||
*/
|
||||
|
||||
import { AuthService } from './auth';
|
||||
import { AdminService } from './admin';
|
||||
import { UserService } from './user';
|
||||
import { ConfigService } from './config';
|
||||
import { UploadService } from './upload';
|
||||
import {AuthService} from './auth';
|
||||
import {AdminService} from './admin';
|
||||
import {UserService} from './user';
|
||||
import {ConfigService} from './config';
|
||||
import {UploadService} from './upload';
|
||||
|
||||
/**
|
||||
* 服务对象
|
||||
@@ -82,7 +82,7 @@ export type {
|
||||
|
||||
// 认证服务
|
||||
export { AuthService, TrustLevel } from './auth';
|
||||
export type { User, OAuthLoginUrlResponse, OAuthCallbackRequest } from './auth';
|
||||
export type { User, OAuthLoginUrlResponse, OAuthCallbackRequest, AuthSource, ExternalAccountBinding } from './auth';
|
||||
|
||||
// 配置服务
|
||||
export { ConfigService } from './config';
|
||||
|
||||
Reference in New Issue
Block a user