workspaces to dashboards, imap email sync, ffmpeg tool, tts fix, file browser refresh, automation sidebar reorder
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -5,6 +5,7 @@ import { sign, verify } from '@@/jwt';
|
||||
import argon2 from 'argon2';
|
||||
import * as errors from '@@/custom-errors';
|
||||
import { validatePassword } from './validate-password';
|
||||
import { validateUsername } from './validate-username';
|
||||
|
||||
export const bootstrapHandler: Handler = async function (ctx) {
|
||||
const body = ctx.get('body');
|
||||
@@ -42,7 +43,7 @@ export const bootstrapHandler: Handler = async function (ctx) {
|
||||
const confirmPassword = body.confirmPassword as string;
|
||||
|
||||
if (!name || !name.trim()) throw errors.BAD_REQUEST('Name is required');
|
||||
if (!username || !username.trim()) throw errors.BAD_REQUEST('Username is required');
|
||||
const validUsername = validateUsername(username);
|
||||
validatePassword(password);
|
||||
if (password !== confirmPassword) throw errors.BAD_REQUEST('Passwords do not match');
|
||||
|
||||
@@ -52,7 +53,7 @@ export const bootstrapHandler: Handler = async function (ctx) {
|
||||
email: payload.email,
|
||||
password: passwordHash,
|
||||
name: name.trim(),
|
||||
username: username.trim(),
|
||||
username: validUsername,
|
||||
role: 'Super Admin',
|
||||
status: 'Active',
|
||||
});
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import * as errors from '@@/custom-errors';
|
||||
|
||||
export function validateUsername(username: string | undefined): string {
|
||||
if (!username || !username.trim()) {
|
||||
throw errors.BAD_REQUEST('Username is required');
|
||||
}
|
||||
|
||||
const trimmed = username.trim();
|
||||
|
||||
if (trimmed.includes('@')) {
|
||||
throw errors.BAD_REQUEST('Username cannot be an email address');
|
||||
}
|
||||
|
||||
if (trimmed.length < 2 || trimmed.length > 32) {
|
||||
throw errors.BAD_REQUEST('Username must be between 2 and 32 characters');
|
||||
}
|
||||
|
||||
if (!/^[a-zA-Z0-9._-]+$/.test(trimmed)) {
|
||||
throw errors.BAD_REQUEST('Username can only contain letters, numbers, dots, hyphens, and underscores');
|
||||
}
|
||||
|
||||
return trimmed;
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import { verify as verifyJwt, sign } from '@@/jwt';
|
||||
import argon2 from 'argon2';
|
||||
import * as errors from '@@/custom-errors';
|
||||
import { validatePassword } from './validate-password';
|
||||
import { validateUsername } from './validate-username';
|
||||
|
||||
export const verifyHandler: Handler = async function (ctx) {
|
||||
const { verificationCode, name, username, password, confirmPassword } = ctx.get('body');
|
||||
@@ -24,7 +25,7 @@ export const verifyHandler: Handler = async function (ctx) {
|
||||
}
|
||||
|
||||
if (username && typeof username === 'string' && username.trim()) {
|
||||
updates.username = username.trim();
|
||||
updates.username = validateUsername(username);
|
||||
}
|
||||
|
||||
if (password) {
|
||||
|
||||
Reference in New Issue
Block a user