feat: add disableUserRegister and disableGuestLogin

pull/90/head
moonrailgun
parent 44ec0599e2
commit dedeaa805f

@ -25,6 +25,16 @@ export interface GlobalConfig {
* *
*/ */
serverEntryImage?: string; serverEntryImage?: string;
/**
*
*/
disableUserRegister?: boolean;
/**
*
*/
disableGuestLogin?: boolean;
} }
export function getGlobalConfig(): GlobalConfig { export function getGlobalConfig(): GlobalConfig {

@ -21,4 +21,6 @@ export const SYSTEM_USERID = '000000000000000000000000';
export const defaultGlobalConfig: GlobalConfig = { export const defaultGlobalConfig: GlobalConfig = {
uploadFileLimit: 1 * 1024 * 1024, uploadFileLimit: 1 * 1024 * 1024,
emailVerification: false, emailVerification: false,
disableUserRegister: false,
disableGuestLogin: false,
}; };

@ -50,7 +50,12 @@ export const LoginView: React.FC = React.memo(() => {
const navigate = useNavigate(); const navigate = useNavigate();
const navRedirect = useSearchParam('redirect'); const navRedirect = useSearchParam('redirect');
const { pathname } = useLocation(); const { pathname } = useLocation();
const serverName = useGlobalConfigStore((state) => state.serverName); const { serverName, disableGuestLogin, disableUserRegister } =
useGlobalConfigStore((state) => ({
serverName: state.serverName,
disableGuestLogin: state.disableGuestLogin,
disableUserRegister: state.disableUserRegister,
}));
useEffect(() => { useEffect(() => {
tryAutoLogin() tryAutoLogin()
@ -132,21 +137,25 @@ export const LoginView: React.FC = React.memo(() => {
{t('登录')} {t('登录')}
</PrimaryBtn> </PrimaryBtn>
<SecondaryBtn {!disableUserRegister && (
disabled={loading} <SecondaryBtn
onClick={() => navToView('/entry/register')} disabled={loading}
> onClick={() => navToView('/entry/register')}
{t('注册账号')} >
<Icon icon="mdi:arrow-right" className="ml-1 inline" /> {t('注册账号')}
</SecondaryBtn> <Icon icon="mdi:arrow-right" className="ml-1 inline" />
</SecondaryBtn>
<SecondaryBtn )}
disabled={loading}
onClick={() => navToView('/entry/guest')} {!disableGuestLogin && (
> <SecondaryBtn
{t('游客访问')} disabled={loading}
<Icon icon="mdi:arrow-right" className="ml-1 inline" /> onClick={() => navToView('/entry/guest')}
</SecondaryBtn> >
{t('游客访问')}
<Icon icon="mdi:arrow-right" className="ml-1 inline" />
</SecondaryBtn>
)}
</div> </div>
<div className="absolute bottom-4 left-0 space-x-2"> <div className="absolute bottom-4 left-0 space-x-2">

@ -19,6 +19,7 @@
"k45c8d1bf": "Claimed user does not exist", "k45c8d1bf": "Claimed user does not exist",
"k4fd701fe": "Email does not exist", "k4fd701fe": "Email does not exist",
"k590cb8b6": "Account does not exist", "k590cb8b6": "Account does not exist",
"k5f7a33eb": "The server does not allow guests to login",
"k64a3c830": "User does not exist", "k64a3c830": "User does not exist",
"k65a070a1": "Not group admin cannot edit", "k65a070a1": "Not group admin cannot edit",
"k674f3f65": "Email verification failed, please enter correct email OTP", "k674f3f65": "Email verification failed, please enter correct email OTP",
@ -54,5 +55,6 @@
"ke99cd649": "No access to converse information permission", "ke99cd649": "No access to converse information permission",
"ke9fabda8": "Token Invalid", "ke9fabda8": "Token Invalid",
"kea5b4254": "This channel has opened a call", "kea5b4254": "This channel has opened a call",
"kebcb959": "The server does not allow new user register",
"kef3676e1": "The invitation code has expired" "kef3676e1": "The invitation code has expired"
} }

@ -19,6 +19,7 @@
"k45c8d1bf": "认领用户不存在", "k45c8d1bf": "认领用户不存在",
"k4fd701fe": "邮箱不存在", "k4fd701fe": "邮箱不存在",
"k590cb8b6": "账号不存在", "k590cb8b6": "账号不存在",
"k5f7a33eb": "服务器不允许游客登录",
"k64a3c830": "用户不存在", "k64a3c830": "用户不存在",
"k65a070a1": "不是群组管理员无法编辑", "k65a070a1": "不是群组管理员无法编辑",
"k674f3f65": "邮箱校验失败, 请输入正确的邮箱OTP", "k674f3f65": "邮箱校验失败, 请输入正确的邮箱OTP",
@ -54,5 +55,6 @@
"ke99cd649": "没有获取会话信息权限", "ke99cd649": "没有获取会话信息权限",
"ke9fabda8": "Token不合规", "ke9fabda8": "Token不合规",
"kea5b4254": "本频道开启了通话", "kea5b4254": "本频道开启了通话",
"kebcb959": "服务器不允许新用户注册",
"kef3676e1": "该邀请码已过期" "kef3676e1": "该邀请码已过期"
} }

@ -48,6 +48,8 @@ export const config = {
feature: { feature: {
disableFileCheck: checkEnvTrusty(process.env.DISABLE_FILE_CHECK), disableFileCheck: checkEnvTrusty(process.env.DISABLE_FILE_CHECK),
disableLogger: checkEnvTrusty(process.env.DISABLE_LOGGER), // 是否关闭日志 disableLogger: checkEnvTrusty(process.env.DISABLE_LOGGER), // 是否关闭日志
disableUserRegister: checkEnvTrusty(process.env.DISABLE_USER_REGISTER), // 是否关闭用户注册功能
disableGuestLogin: checkEnvTrusty(process.env.DISABLE_GUEST_LOGIN), // 是否关闭用户游客登录功能
}, },
}; };

@ -76,6 +76,8 @@ class ConfigService extends TcService {
return { return {
uploadFileLimit: config.storage.limit, uploadFileLimit: config.storage.limit,
emailVerification: config.emailVerification, emailVerification: config.emailVerification,
disableUserRegister: config.feature.disableUserRegister,
disableGuestLogin: config.feature.disableGuestLogin,
...persistConfig, ...persistConfig,
}; };
} }

@ -394,6 +394,10 @@ class UserService extends TcService {
await this.validateRegisterParams(params, t); await this.validateRegisterParams(params, t);
if (config.feature.disableUserRegister) {
throw new Error(t('服务器不允许新用户注册'));
}
const nickname = params.username ?? getEmailAddress(params.email); const nickname = params.username ?? getEmailAddress(params.email);
const discriminator = await this.adapter.model.generateDiscriminator( const discriminator = await this.adapter.model.generateDiscriminator(
nickname nickname
@ -468,6 +472,12 @@ class UserService extends TcService {
*/ */
async createTemporaryUser(ctx: TcPureContext<{ nickname: string }>) { async createTemporaryUser(ctx: TcPureContext<{ nickname: string }>) {
const nickname = ctx.params.nickname; const nickname = ctx.params.nickname;
const t = ctx.meta.t;
if (config.feature.disableGuestLogin) {
throw new Error(t('服务器不允许游客登录'));
}
const discriminator = await this.adapter.model.generateDiscriminator( const discriminator = await this.adapter.model.generateDiscriminator(
nickname nickname
); );

Loading…
Cancel
Save