mirror of
https://github.com/labring/FastGPT.git
synced 2026-05-05 01:02:59 +08:00
fix: login secret (#6635)
* fix: login secret * lock * env template * fix: ts * fix: ts * fix: ts
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
import type { OpenAPIPath } from '../../../type';
|
||||
import { LoginPath } from './login';
|
||||
import { RegisterPath } from './register';
|
||||
import { PasswordPath } from './password';
|
||||
|
||||
export const UserAccountPath: OpenAPIPath = {
|
||||
...LoginPath,
|
||||
...RegisterPath,
|
||||
...PasswordPath
|
||||
};
|
||||
@@ -0,0 +1,110 @@
|
||||
import { z } from 'zod';
|
||||
import { OAuthEnum } from '../../../../../support/user/constant';
|
||||
import { TrackRegisterParamsSchema } from '../../../../../support/marketing/type';
|
||||
import { LanguageSchema } from '../../../../../common/i18n/type';
|
||||
|
||||
export const LoginSuccessResponseSchema = z.object({
|
||||
user: z.any().meta({
|
||||
description: '用户详情'
|
||||
}),
|
||||
token: z.string().meta({
|
||||
example: 'eyJhbGciOiJIUzI1NiIs...',
|
||||
description: '登录令牌'
|
||||
})
|
||||
});
|
||||
export type LoginSuccessResponseType = z.infer<typeof LoginSuccessResponseSchema>;
|
||||
|
||||
// ===== Pre login - get login verification code =====
|
||||
export const PreLoginQuerySchema = z.object({
|
||||
username: z.string().meta({
|
||||
example: 'admin',
|
||||
description: '用户名'
|
||||
})
|
||||
});
|
||||
export type PreLoginQueryType = z.infer<typeof PreLoginQuerySchema>;
|
||||
|
||||
export const PreLoginResponseSchema = z
|
||||
.object({
|
||||
code: z.string().meta({
|
||||
example: 'a1b2c3',
|
||||
description: '预登录验证码'
|
||||
})
|
||||
})
|
||||
.meta({
|
||||
example: {
|
||||
code: 'a1b2c3'
|
||||
}
|
||||
});
|
||||
export type PreLoginResponseType = z.infer<typeof PreLoginResponseSchema>;
|
||||
|
||||
// ===== Login by password =====
|
||||
export const LoginByPasswordBodySchema = z
|
||||
.object({
|
||||
username: z.string().meta({
|
||||
example: 'admin',
|
||||
description: '用户名'
|
||||
}),
|
||||
password: z.string().meta({
|
||||
example: 'hashed_password',
|
||||
description: '密码'
|
||||
}),
|
||||
code: z.string().meta({
|
||||
example: '123456',
|
||||
description: '预登录验证码'
|
||||
}),
|
||||
language: LanguageSchema.optional().default('zh-CN').meta({
|
||||
example: 'zh-CN',
|
||||
description: '用户语言偏好'
|
||||
})
|
||||
})
|
||||
.meta({
|
||||
example: {
|
||||
username: 'admin',
|
||||
password: 'hashed_password',
|
||||
code: '123456',
|
||||
language: 'zh-CN'
|
||||
}
|
||||
});
|
||||
export type LoginByPasswordBodyType = z.infer<typeof LoginByPasswordBodySchema>;
|
||||
|
||||
/* ===== Wecom Login ===== */
|
||||
export const WecomGetRedirectURLBodySchema = z.object({
|
||||
redirectUri: z.string(),
|
||||
state: z.string(),
|
||||
isWecomWorkTerminal: z.boolean()
|
||||
});
|
||||
export const WecomGetRedirectURLResponseSchema = z.string();
|
||||
export type WecomGetRedirectURLBodyType = z.infer<typeof WecomGetRedirectURLBodySchema>;
|
||||
export type WecomGetRedirectURLResponseType = z.infer<typeof WecomGetRedirectURLResponseSchema>;
|
||||
|
||||
// ===== OAuth Login =====
|
||||
export const OauthLoginBodySchema = TrackRegisterParamsSchema.extend({
|
||||
type: z.enum(OAuthEnum).meta({ description: 'OAuth 登录类型' }),
|
||||
callbackUrl: z.string().meta({ description: '回调 URL' }),
|
||||
props: z.record(z.string(), z.string()).meta({ description: '附加属性' }),
|
||||
language: LanguageSchema.optional().meta({ description: '语言' })
|
||||
});
|
||||
export type OauthLoginBodyType = z.infer<typeof OauthLoginBodySchema>;
|
||||
|
||||
// ===== Fast Login =====
|
||||
export const FastLoginBodySchema = z.object({
|
||||
token: z.string().meta({ description: 'Token' }),
|
||||
code: z.string().meta({ description: 'Code' })
|
||||
});
|
||||
export type FastLoginBodyType = z.infer<typeof FastLoginBodySchema>;
|
||||
|
||||
// ===== WeChat Login Result =====
|
||||
export const WxLoginBodySchema = z.object({
|
||||
inviterId: z.string().optional().meta({ description: '邀请人 ID' }),
|
||||
code: z.string().meta({ description: '微信登录 Code' }),
|
||||
bd_vid: z.string().optional(),
|
||||
msclkid: z.string().optional(),
|
||||
fastgpt_sem: z.string().optional(),
|
||||
sourceDomain: z.string().optional()
|
||||
});
|
||||
export type WxLoginBodyType = z.infer<typeof WxLoginBodySchema>;
|
||||
export const GetWXLoginQRResponseSchema = z.object({
|
||||
code: z.string().meta({ description: '微信登录 Code' }),
|
||||
codeUrl: z.string().meta({ description: '微信登录二维码 URL' })
|
||||
});
|
||||
export type GetWXLoginQRResponseType = z.infer<typeof GetWXLoginQRResponseSchema>;
|
||||
@@ -0,0 +1,178 @@
|
||||
import type { OpenAPIPath } from '../../../../type';
|
||||
import { TagsMap } from '../../../../tag';
|
||||
import {
|
||||
LoginByPasswordBodySchema,
|
||||
PreLoginQuerySchema,
|
||||
PreLoginResponseSchema,
|
||||
OauthLoginBodySchema,
|
||||
FastLoginBodySchema,
|
||||
WxLoginBodySchema,
|
||||
GetWXLoginQRResponseSchema,
|
||||
LoginSuccessResponseSchema
|
||||
} from './api';
|
||||
import { UserSchema } from '../../../../../support/user/type';
|
||||
|
||||
export const LoginPath: OpenAPIPath = {
|
||||
'/support/user/account/tokenLogin': {
|
||||
get: {
|
||||
summary: 'Token 登录',
|
||||
description: '通过已有的登录令牌获取用户信息',
|
||||
tags: [TagsMap.userLogin],
|
||||
responses: {
|
||||
200: {
|
||||
description: '成功获取用户信息',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: UserSchema
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
'/support/user/account/preLogin': {
|
||||
get: {
|
||||
summary: '预登录获取验证码',
|
||||
description: '通过用户名获取预登录验证码,用于密码登录时的验证',
|
||||
tags: [TagsMap.userLogin],
|
||||
requestParams: {
|
||||
query: PreLoginQuerySchema
|
||||
},
|
||||
responses: {
|
||||
200: {
|
||||
description: '成功获取预登录验证码',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: PreLoginResponseSchema
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
'/support/user/account/loginByPassword': {
|
||||
post: {
|
||||
summary: '用户密码登录',
|
||||
description: '通过用户名和密码进行登录,需要先获取预登录验证码',
|
||||
tags: [TagsMap.userLogin],
|
||||
requestBody: {
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: LoginByPasswordBodySchema
|
||||
}
|
||||
}
|
||||
},
|
||||
responses: {
|
||||
200: {
|
||||
description: '登录成功,返回用户信息和令牌',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: LoginSuccessResponseSchema
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
'/proApi/support/user/account/login/oauth': {
|
||||
post: {
|
||||
summary: 'OAuth 登录',
|
||||
description: '使用第三方 OAuth 授权登录',
|
||||
tags: [TagsMap.userLogin],
|
||||
requestBody: {
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: OauthLoginBodySchema
|
||||
}
|
||||
}
|
||||
},
|
||||
responses: {
|
||||
200: {
|
||||
description: '登录成功',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: LoginSuccessResponseSchema
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
'/proApi/support/user/account/login/fastLogin': {
|
||||
post: {
|
||||
summary: '快捷登录',
|
||||
description: '使用 Token 和 Code 进行快捷登录',
|
||||
tags: [TagsMap.userLogin],
|
||||
requestBody: {
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: FastLoginBodySchema
|
||||
}
|
||||
}
|
||||
},
|
||||
responses: {
|
||||
200: {
|
||||
description: '登录成功',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: LoginSuccessResponseSchema
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
'/proApi/support/user/account/login/wx/getQR': {
|
||||
get: {
|
||||
summary: '获取微信登录二维码',
|
||||
description: '获取微信登录二维码',
|
||||
tags: [TagsMap.userLogin],
|
||||
responses: {
|
||||
200: {
|
||||
description: '获取微信登录二维码成功',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: GetWXLoginQRResponseSchema
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
'/proApi/support/user/account/login/wx/getResult': {
|
||||
post: {
|
||||
summary: '获取微信登录结果',
|
||||
description: '提交微信登录 Code 以获取登录结果',
|
||||
tags: [TagsMap.userLogin],
|
||||
requestBody: {
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: WxLoginBodySchema
|
||||
}
|
||||
}
|
||||
},
|
||||
responses: {
|
||||
200: {
|
||||
description: '登录成功',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: LoginSuccessResponseSchema
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
'/support/user/account/loginout': {
|
||||
get: {
|
||||
summary: '退出登录',
|
||||
description: '退出当前用户的所有会话并清除登录凭证',
|
||||
tags: [TagsMap.userLogin],
|
||||
responses: {
|
||||
200: {
|
||||
description: '退出登录成功'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,12 +0,0 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
export const WecomGetRedirectURLBodySchema = z.object({
|
||||
redirectUri: z.string(),
|
||||
state: z.string(),
|
||||
isWecomWorkTerminal: z.boolean()
|
||||
});
|
||||
|
||||
export const WecomGetRedirectURLResponseSchema = z.string();
|
||||
|
||||
export type WecomGetRedirectURLBodyType = z.infer<typeof WecomGetRedirectURLBodySchema>;
|
||||
export type WecomGetRedirectURLResponseType = z.infer<typeof WecomGetRedirectURLResponseSchema>;
|
||||
@@ -0,0 +1,62 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
// ===== Update password by old password =====
|
||||
export const UpdatePasswordByOldBodySchema = z
|
||||
.object({
|
||||
oldPsw: z.string().trim().min(1).meta({
|
||||
example: 'hashed_old_password',
|
||||
description: '旧密码(已加密)'
|
||||
}),
|
||||
newPsw: z.string().trim().min(1).meta({
|
||||
example: 'hashed_new_password',
|
||||
description: '新密码(已加密)'
|
||||
})
|
||||
})
|
||||
.meta({
|
||||
example: {
|
||||
oldPsw: 'hashed_old_password',
|
||||
newPsw: 'hashed_new_password'
|
||||
}
|
||||
});
|
||||
export type UpdatePasswordByOldBodyType = z.infer<typeof UpdatePasswordByOldBodySchema>;
|
||||
export const UpdatePasswordByOldResponseSchema = z.any().meta({
|
||||
description: '用户信息'
|
||||
});
|
||||
export type UpdatePasswordByOldResponseType = z.infer<typeof UpdatePasswordByOldResponseSchema>;
|
||||
|
||||
// ===== Check password expired =====
|
||||
export const CheckPswExpiredResponseSchema = z.boolean().meta({
|
||||
example: false,
|
||||
description: '密码是否已过期'
|
||||
});
|
||||
export type CheckPswExpiredResponseType = z.infer<typeof CheckPswExpiredResponseSchema>;
|
||||
|
||||
// ===== Reset expired password =====
|
||||
export const ResetExpiredPswBodySchema = z
|
||||
.object({
|
||||
newPsw: z.string().trim().min(1).meta({
|
||||
example: 'hashed_new_password',
|
||||
description: '新密码(已加密)'
|
||||
})
|
||||
})
|
||||
.meta({
|
||||
example: {
|
||||
newPsw: 'hashed_new_password'
|
||||
}
|
||||
});
|
||||
export type ResetExpiredPswBodyType = z.infer<typeof ResetExpiredPswBodySchema>;
|
||||
|
||||
export const ResetExpiredPswResponseSchema = z.object({}).meta({
|
||||
description: '重置成功'
|
||||
});
|
||||
export type ResetExpiredPswResponseType = z.infer<typeof ResetExpiredPswResponseSchema>;
|
||||
|
||||
// ===== Find Password (update by code) =====
|
||||
export const UpdatePasswordByCodeBodySchema = z.object({
|
||||
username: z.string().trim().min(1).meta({ description: '用户名' }),
|
||||
code: z.string().meta({ description: '验证码' }),
|
||||
password: z.string().trim().min(1).meta({ description: '新密码' }),
|
||||
tmbId: z.string().optional().meta({ description: '团队成员 ID(可选)' })
|
||||
});
|
||||
|
||||
export type UpdatePasswordByCodeBodyType = z.infer<typeof UpdatePasswordByCodeBodySchema>;
|
||||
@@ -0,0 +1,102 @@
|
||||
import type { OpenAPIPath } from '../../../../type';
|
||||
import { TagsMap } from '../../../../tag';
|
||||
import {
|
||||
UpdatePasswordByOldBodySchema,
|
||||
UpdatePasswordByOldResponseSchema,
|
||||
CheckPswExpiredResponseSchema,
|
||||
ResetExpiredPswBodySchema,
|
||||
ResetExpiredPswResponseSchema,
|
||||
UpdatePasswordByCodeBodySchema
|
||||
} from './api';
|
||||
|
||||
export const PasswordPath: OpenAPIPath = {
|
||||
'/support/user/account/updatePasswordByOld': {
|
||||
post: {
|
||||
summary: '通过旧密码修改密码',
|
||||
description: '使用旧密码验证后修改为新密码,修改成功后其他会话将被注销',
|
||||
tags: [TagsMap.userLogin],
|
||||
requestBody: {
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: UpdatePasswordByOldBodySchema
|
||||
}
|
||||
}
|
||||
},
|
||||
responses: {
|
||||
200: {
|
||||
description: '密码修改成功',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: UpdatePasswordByOldResponseSchema
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
'/support/user/account/checkPswExpired': {
|
||||
get: {
|
||||
summary: '检查密码是否过期',
|
||||
description: '检查当前用户的密码是否已过期,需要强制修改',
|
||||
tags: [TagsMap.userLogin],
|
||||
responses: {
|
||||
200: {
|
||||
description: '返回密码是否过期',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: CheckPswExpiredResponseSchema
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
'/support/user/account/resetExpiredPsw': {
|
||||
post: {
|
||||
summary: '重置过期密码',
|
||||
description: '当密码过期时,使用此接口重置密码,重置后其他会话将被注销',
|
||||
tags: [TagsMap.userLogin],
|
||||
requestBody: {
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: ResetExpiredPswBodySchema
|
||||
}
|
||||
}
|
||||
},
|
||||
responses: {
|
||||
200: {
|
||||
description: '密码重置成功',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: ResetExpiredPswResponseSchema
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
'/support/user/account/password/updateByCode': {
|
||||
post: {
|
||||
summary: '通过验证码找回/修改密码',
|
||||
description: '通过邮箱/手机验证码找回或修改密码',
|
||||
tags: [TagsMap.userLogin],
|
||||
requestBody: {
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: UpdatePasswordByCodeBodySchema
|
||||
}
|
||||
}
|
||||
},
|
||||
responses: {
|
||||
200: {
|
||||
description: '修改成功',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,13 @@
|
||||
import { z } from 'zod';
|
||||
import { TrackRegisterParamsSchema } from '../../../../../support/marketing/type';
|
||||
import { LanguageSchema } from '../../../../../common/i18n/type';
|
||||
|
||||
// ===== Register by email or phone =====
|
||||
export const AccountRegisterBodySchema = TrackRegisterParamsSchema.extend({
|
||||
username: z.string().meta({ description: '用户名(邮箱或手机号)' }),
|
||||
code: z.string().meta({ description: '验证码' }),
|
||||
password: z.string().meta({ description: '密码(已加密)' }),
|
||||
language: LanguageSchema.optional().meta({ description: '语言' })
|
||||
});
|
||||
|
||||
export type AccountRegisterBodyType = z.infer<typeof AccountRegisterBodySchema>;
|
||||
@@ -0,0 +1,30 @@
|
||||
import type { OpenAPIPath } from '../../../../type';
|
||||
import { TagsMap } from '../../../../tag';
|
||||
import { AccountRegisterBodySchema } from './api';
|
||||
|
||||
export const RegisterPath: OpenAPIPath = {
|
||||
'/support/user/account/register/emailAndPhone': {
|
||||
post: {
|
||||
summary: '邮箱/手机号注册',
|
||||
description: '使用邮箱或手机号验证码注册新账号',
|
||||
tags: [TagsMap.userLogin],
|
||||
requestBody: {
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: AccountRegisterBodySchema
|
||||
}
|
||||
}
|
||||
},
|
||||
responses: {
|
||||
200: {
|
||||
description: '注册成功',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,6 +1,8 @@
|
||||
import { UserInformPath } from './inform';
|
||||
import type { OpenAPIPath } from '../../type';
|
||||
import { UserAccountPath } from './account';
|
||||
|
||||
export const UserPath: OpenAPIPath = {
|
||||
...UserInformPath
|
||||
...UserInformPath,
|
||||
...UserAccountPath
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user