mirror of
https://github.com/BidingCC/BuildingAI.git
synced 2026-08-31 02:03:00 +08:00
feat: 完善、优化登录控制逻辑
This commit is contained in:
@@ -524,46 +524,4 @@ export class AuthService extends BaseService<User> {
|
||||
throw HttpExceptionFactory.internal("退出登录失败", BusinessCode.OPERATION_FAILED);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置多端登录开关
|
||||
*
|
||||
* @param enabled 是否启用
|
||||
* @returns 设置结果
|
||||
*/
|
||||
async setMultiLoginEnabled(enabled: boolean): Promise<{ success: boolean; message: string }> {
|
||||
try {
|
||||
const result = await this.userTokenService.setMultiLoginEnabled(enabled);
|
||||
|
||||
return {
|
||||
success: result,
|
||||
message: result ? "设置成功" : "设置失败",
|
||||
};
|
||||
} catch (error) {
|
||||
this.logger.error(`设置多端登录开关失败: ${error.message}`);
|
||||
throw HttpExceptionFactory.internal("设置失败", BusinessCode.OPERATION_FAILED);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置单终端登录开关
|
||||
*
|
||||
* @param enabled 是否启用
|
||||
* @returns 设置结果
|
||||
*/
|
||||
async setSingleTerminalLoginEnabled(
|
||||
enabled: boolean,
|
||||
): Promise<{ success: boolean; message: string }> {
|
||||
try {
|
||||
const result = await this.userTokenService.setSingleTerminalLoginEnabled(enabled);
|
||||
|
||||
return {
|
||||
success: result,
|
||||
message: result ? "设置成功" : "设置失败",
|
||||
};
|
||||
} catch (error) {
|
||||
this.logger.error(`设置单终端登录开关失败: ${error.message}`);
|
||||
throw HttpExceptionFactory.internal("设置失败", BusinessCode.OPERATION_FAILED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,16 +25,6 @@ export class UserTokenService extends BaseService<UserToken> {
|
||||
*/
|
||||
private readonly TOKEN_CONFIG_KEY = "token";
|
||||
|
||||
/**
|
||||
* 多端登录配置键
|
||||
*/
|
||||
private readonly MULTI_LOGIN_CONFIG_KEY = "multi_login";
|
||||
|
||||
/**
|
||||
* 单终端登录配置键
|
||||
*/
|
||||
private readonly SINGLE_TERMINAL_LOGIN_CONFIG_KEY = "single_terminal_login";
|
||||
|
||||
/**
|
||||
* 令牌缓存前缀
|
||||
*/
|
||||
@@ -77,11 +67,11 @@ export class UserTokenService extends BaseService<UserToken> {
|
||||
// 获取令牌配置
|
||||
const tokenConfig = await this.getTokenConfig();
|
||||
|
||||
// 获取单终端登录配置
|
||||
const isSingleTerminalLoginEnabled = await this.isSingleTerminalLoginEnabled();
|
||||
// 获取登录设置配置
|
||||
const loginSettings = await this.getLoginSettings();
|
||||
|
||||
// 如果启用单终端登录,则撤销该用户在同一终端的所有其他令牌
|
||||
if (isSingleTerminalLoginEnabled) {
|
||||
// 如果不允许多处登录,则撤销该用户在同一终端的所有其他令牌
|
||||
if (!loginSettings.allowMultipleLogin) {
|
||||
await this.revokeTokensByTerminal(userId, terminal);
|
||||
}
|
||||
|
||||
@@ -403,74 +393,22 @@ export class UserTokenService extends BaseService<UserToken> {
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否启用多端登录
|
||||
* 获取登录设置配置
|
||||
*
|
||||
* @returns 是否启用多端登录
|
||||
* @returns 登录设置配置
|
||||
*/
|
||||
async isMultiLoginEnabled(): Promise<boolean> {
|
||||
private async getLoginSettings(): Promise<{ allowMultipleLogin: boolean }> {
|
||||
try {
|
||||
return await this.dictService.get<boolean>(this.MULTI_LOGIN_CONFIG_KEY, false, "auth");
|
||||
} catch (error) {
|
||||
this.logger.warn(`获取多端登录配置失败,使用默认配置: ${error.message}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置是否启用多端登录
|
||||
*
|
||||
* @param enabled 是否启用
|
||||
* @returns 设置结果
|
||||
*/
|
||||
async setMultiLoginEnabled(enabled: boolean): Promise<boolean> {
|
||||
try {
|
||||
await this.dictService.set(this.MULTI_LOGIN_CONFIG_KEY, enabled, {
|
||||
group: "auth", // 明确指定分组为 auth
|
||||
description: "是否允许用户在同一终端多处登录",
|
||||
});
|
||||
|
||||
return true;
|
||||
} catch (error) {
|
||||
this.logger.error(`设置多端登录配置失败: ${error.message}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否启用单终端登录
|
||||
*
|
||||
* @returns 是否启用单终端登录
|
||||
*/
|
||||
async isSingleTerminalLoginEnabled(): Promise<boolean> {
|
||||
try {
|
||||
return await this.dictService.get<boolean>(
|
||||
this.SINGLE_TERMINAL_LOGIN_CONFIG_KEY,
|
||||
true,
|
||||
const config = await this.dictService.get<{ allowMultipleLogin: boolean }>(
|
||||
"login_settings",
|
||||
{ allowMultipleLogin: false }, // 默认不允许多处登录
|
||||
"auth",
|
||||
);
|
||||
} catch (error) {
|
||||
this.logger.warn(`获取单终端登录配置失败,使用默认配置: ${error.message}`);
|
||||
return true; // 默认启用单终端登录
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置是否启用单终端登录
|
||||
*
|
||||
* @param enabled 是否启用
|
||||
* @returns 设置结果
|
||||
*/
|
||||
async setSingleTerminalLoginEnabled(enabled: boolean): Promise<boolean> {
|
||||
try {
|
||||
await this.dictService.set(this.SINGLE_TERMINAL_LOGIN_CONFIG_KEY, enabled, {
|
||||
group: "auth", // 明确指定分组为 auth
|
||||
description: "是否启用单终端登录(同一类型终端登录时挤掉对方)",
|
||||
});
|
||||
|
||||
return true;
|
||||
return config;
|
||||
} catch (error) {
|
||||
this.logger.error(`设置单终端登录配置失败: ${error.message}`);
|
||||
return false;
|
||||
this.logger.warn(`获取登录设置配置失败,使用默认配置: ${error.message}`);
|
||||
return { allowMultipleLogin: false }; // 默认不允许多处登录
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -434,8 +434,8 @@ export class UserController extends BaseController {
|
||||
*/
|
||||
private getDefaultLoginSettings(): LoginSettingsConfig {
|
||||
return {
|
||||
allowedLoginMethods: [LOGIN_TYPE.ACCOUNT, LOGIN_TYPE.PHONE, LOGIN_TYPE.WECHAT],
|
||||
allowedRegisterMethods: [LOGIN_TYPE.ACCOUNT, LOGIN_TYPE.PHONE],
|
||||
allowedLoginMethods: [LOGIN_TYPE.ACCOUNT, LOGIN_TYPE.WECHAT],
|
||||
allowedRegisterMethods: [LOGIN_TYPE.ACCOUNT, LOGIN_TYPE.WECHAT],
|
||||
defaultLoginMethod: LOGIN_TYPE.ACCOUNT,
|
||||
allowMultipleLogin: false,
|
||||
showPolicyAgreement: true,
|
||||
|
||||
@@ -127,31 +127,6 @@ export class AuthController extends BaseController {
|
||||
return this.authService.logout(token);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置多端登录开关
|
||||
*
|
||||
* @param enabled 是否启用
|
||||
* @returns 设置结果
|
||||
*/
|
||||
@Post("multi-login")
|
||||
async setMultiLoginEnabled(@Body("enabled") enabled: boolean) {
|
||||
return this.authService.setMultiLoginEnabled(enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取多端登录开关状态
|
||||
*
|
||||
* @returns 多端登录开关状态
|
||||
*/
|
||||
@Get("multi-login")
|
||||
async getMultiLoginStatus() {
|
||||
// 从用户令牌服务中获取多端登录状态
|
||||
const isEnabled = await this.authService.userTokenService.isMultiLoginEnabled();
|
||||
|
||||
return {
|
||||
enabled: isEnabled,
|
||||
};
|
||||
}
|
||||
/**
|
||||
* 获取微信二维码
|
||||
*
|
||||
|
||||
@@ -336,8 +336,8 @@ export class UserController extends BaseController {
|
||||
*/
|
||||
private getDefaultLoginSettings() {
|
||||
return {
|
||||
allowedLoginMethods: [LOGIN_TYPE.ACCOUNT, LOGIN_TYPE.PHONE, LOGIN_TYPE.WECHAT],
|
||||
allowedRegisterMethods: [LOGIN_TYPE.ACCOUNT, LOGIN_TYPE.PHONE],
|
||||
allowedLoginMethods: [LOGIN_TYPE.ACCOUNT, LOGIN_TYPE.WECHAT],
|
||||
allowedRegisterMethods: [LOGIN_TYPE.ACCOUNT, LOGIN_TYPE.WECHAT],
|
||||
defaultLoginMethod: LOGIN_TYPE.ACCOUNT,
|
||||
allowMultipleLogin: false,
|
||||
showPolicyAgreement: true,
|
||||
|
||||
Vendored
-1
@@ -9,7 +9,6 @@ export declare const LOGIN_TYPE: {
|
||||
/** 账号登录 */
|
||||
readonly ACCOUNT: 1;
|
||||
/** 手机号登录 */
|
||||
readonly PHONE: 2;
|
||||
/** 微信登录 */
|
||||
readonly WECHAT: 3;
|
||||
};
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,eAAO,MAAM,UAAU;IACnB,WAAW;;IAEX,YAAY;;IAEZ,WAAW;;CAEL,CAAC;AACX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,OAAO,UAAU,CAAC,CAAC"}
|
||||
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,eAAO,MAAM,UAAU;IACnB,WAAW;;IAEX,YAAY;IAEZ,WAAW;;CAEL,CAAC;AACX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,OAAO,UAAU,CAAC,CAAC"}
|
||||
@@ -9,7 +9,7 @@ export const LOGIN_TYPE = {
|
||||
/** 账号登录 */
|
||||
ACCOUNT: 1,
|
||||
/** 手机号登录 */
|
||||
PHONE: 2,
|
||||
// PHONE: 2,
|
||||
/** 微信登录 */
|
||||
WECHAT: 3,
|
||||
};
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG;IACtB,WAAW;IACX,OAAO,EAAE,CAAC;IACV,YAAY;IACZ,KAAK,EAAE,CAAC;IACR,WAAW;IACX,MAAM,EAAE,CAAC;CACH,CAAC"}
|
||||
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG;IACtB,WAAW;IACX,OAAO,EAAE,CAAC;IACV,YAAY;IACZ,YAAY;IACZ,WAAW;IACX,MAAM,EAAE,CAAC;CACH,CAAC"}
|
||||
Vendored
-1
@@ -9,7 +9,6 @@ export declare const LOGIN_TYPE: {
|
||||
/** 账号登录 */
|
||||
readonly ACCOUNT: 1;
|
||||
/** 手机号登录 */
|
||||
readonly PHONE: 2;
|
||||
/** 微信登录 */
|
||||
readonly WECHAT: 3;
|
||||
};
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/auth.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,eAAO,MAAM,UAAU;IACnB,WAAW;;IAEX,YAAY;;IAEZ,WAAW;;CAEL,CAAC;AACX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,OAAO,UAAU,CAAC,CAAC"}
|
||||
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/auth.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,eAAO,MAAM,UAAU;IACnB,WAAW;;IAEX,YAAY;IAEZ,WAAW;;CAEL,CAAC;AACX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,OAAO,UAAU,CAAC,CAAC"}
|
||||
@@ -12,7 +12,7 @@ exports.LOGIN_TYPE = {
|
||||
/** 账号登录 */
|
||||
ACCOUNT: 1,
|
||||
/** 手机号登录 */
|
||||
PHONE: 2,
|
||||
// PHONE: 2,
|
||||
/** 微信登录 */
|
||||
WECHAT: 3,
|
||||
};
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/auth.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH;;GAEG;AACU,QAAA,UAAU,GAAG;IACtB,WAAW;IACX,OAAO,EAAE,CAAC;IACV,YAAY;IACZ,KAAK,EAAE,CAAC;IACR,WAAW;IACX,MAAM,EAAE,CAAC;CACH,CAAC"}
|
||||
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/auth.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH;;GAEG;AACU,QAAA,UAAU,GAAG;IACtB,WAAW;IACX,OAAO,EAAE,CAAC;IACV,YAAY;IACZ,YAAY;IACZ,WAAW;IACX,MAAM,EAAE,CAAC;CACH,CAAC"}
|
||||
@@ -10,7 +10,7 @@ export const LOGIN_TYPE = {
|
||||
/** 账号登录 */
|
||||
ACCOUNT: 1,
|
||||
/** 手机号登录 */
|
||||
PHONE: 2,
|
||||
// PHONE: 2,
|
||||
/** 微信登录 */
|
||||
WECHAT: 3,
|
||||
} as const;
|
||||
|
||||
Reference in New Issue
Block a user