fix: simplify account password flow
This commit is contained in:
1 parent
203bfb3246
commit
df65e9f517
9 files changed
+118
-131
No files matched your search
+14
-33
@@ -51,19 +51,18 @@ export function aiServiceConnected(databaseIsReady: boolean, probe: Record<strin
|
||||
|
||||
const loginSchema = z.object({
|
||||
username: z.string().min(1).max(160),
|
||||
password: z.string().min(1).max(512)
|
||||
password: z.string().min(1)
|
||||
});
|
||||
|
||||
const changePasswordSchema = z.object({
|
||||
current_password: z.string().min(1).max(512),
|
||||
new_password: z.string().min(12).max(512)
|
||||
current_password: z.string().min(1),
|
||||
new_password: z.string().min(1)
|
||||
});
|
||||
|
||||
const accountCreateSchema = z.object({
|
||||
username: z.string().min(1).max(160),
|
||||
password: z.string().min(12).max(512),
|
||||
password: z.string().min(1),
|
||||
role: z.enum(['admin', 'team_lead', 'user']).default('user'),
|
||||
must_change_password: z.boolean().default(true),
|
||||
business_route_ids: z.array(
|
||||
z.string().trim().refine((routeId) => Boolean(businessRouteById(routeId)), '业务类型不存在。')
|
||||
).max(BUSINESS_ROUTES.length).default([])
|
||||
@@ -78,8 +77,7 @@ const accountUpdateSchema = z.object({
|
||||
});
|
||||
|
||||
const accountPasswordResetSchema = z.object({
|
||||
password: z.string().min(12).max(512),
|
||||
must_change_password: z.boolean().default(true)
|
||||
password: z.string().min(1)
|
||||
});
|
||||
|
||||
const accountBusinessAuthorizationsSchema = z.object({
|
||||
@@ -363,8 +361,7 @@ function publicUser(session: ActiveSession) {
|
||||
return {
|
||||
id: session.user.id,
|
||||
username: session.user.username,
|
||||
role: session.user.role,
|
||||
must_change_password: session.user.mustChangePassword
|
||||
role: session.user.role
|
||||
};
|
||||
}
|
||||
|
||||
@@ -516,14 +513,6 @@ export async function buildServer({
|
||||
return session;
|
||||
};
|
||||
|
||||
const getReadySession = async (request: FastifyRequest): Promise<ActiveSession> => {
|
||||
const session = await getSession(request);
|
||||
if (session.user.mustChangePassword) {
|
||||
throw new AuthError('password_change_required', '首次登录或密码重置后必须先修改密码。', 403);
|
||||
}
|
||||
return session;
|
||||
};
|
||||
|
||||
const requireAdmin = (session: ActiveSession): ActiveSession => {
|
||||
if (session.user.role !== 'admin') throw new AuthError('admin_required', '需要管理员权限。', 403);
|
||||
return session;
|
||||
@@ -554,16 +543,10 @@ export async function buildServer({
|
||||
return session;
|
||||
};
|
||||
|
||||
const requireMutationSession = async (request: FastifyRequest): Promise<ActiveSession> => {
|
||||
const session = await requireAuthenticatedMutationSession(request);
|
||||
if (session.user.mustChangePassword) {
|
||||
throw new AuthError('password_change_required', '首次登录或密码重置后必须先修改密码。', 403);
|
||||
}
|
||||
return session;
|
||||
};
|
||||
const requireMutationSession = requireAuthenticatedMutationSession;
|
||||
|
||||
const requireAdminSession = async (request: FastifyRequest): Promise<ActiveSession> => (
|
||||
requireAdmin(await getReadySession(request))
|
||||
requireAdmin(await getSession(request))
|
||||
);
|
||||
|
||||
const requireAdminMutationSession = async (request: FastifyRequest): Promise<ActiveSession> => (
|
||||
@@ -571,7 +554,7 @@ export async function buildServer({
|
||||
);
|
||||
|
||||
const requireLeadershipSession = async (request: FastifyRequest): Promise<ActiveSession> => (
|
||||
requireLeadership(await getReadySession(request))
|
||||
requireLeadership(await getSession(request))
|
||||
);
|
||||
|
||||
async function persistParseOutcome(
|
||||
@@ -980,7 +963,6 @@ export async function buildServer({
|
||||
username: body.username,
|
||||
password: body.password,
|
||||
role: body.role,
|
||||
mustChangePassword: body.must_change_password,
|
||||
businessRouteIds: body.business_route_ids
|
||||
}, requestId(request));
|
||||
return { ok: true, account };
|
||||
@@ -1022,7 +1004,6 @@ export async function buildServer({
|
||||
session.user,
|
||||
userId,
|
||||
body.password,
|
||||
body.must_change_password,
|
||||
requestId(request)
|
||||
);
|
||||
return { ok: true, password_reset: true, sessions_revoked: true };
|
||||
@@ -1172,7 +1153,7 @@ export async function buildServer({
|
||||
});
|
||||
|
||||
app.get('/api/tasks', async (request) => {
|
||||
const session = await getReadySession(request);
|
||||
const session = await getSession(request);
|
||||
const query = listTasksQuerySchema.parse(request.query || {});
|
||||
const page = await tasks.listTasksPage(session.user.organizationId, {
|
||||
status: query.status || undefined,
|
||||
@@ -1224,19 +1205,19 @@ export async function buildServer({
|
||||
});
|
||||
|
||||
app.get('/api/tasks/:taskId', async (request) => {
|
||||
const session = await getReadySession(request);
|
||||
const session = await getSession(request);
|
||||
const params = request.params as { taskId: string };
|
||||
return { ok: true, task: await tasks.getTask(session.user.organizationId, params.taskId, contextFor(session, request)) };
|
||||
});
|
||||
|
||||
app.get('/api/tasks/:taskId/input-history', async (request) => {
|
||||
const session = await getReadySession(request);
|
||||
const session = await getSession(request);
|
||||
const params = request.params as { taskId: string };
|
||||
return { ok: true, ...(await tasks.getTaskInputHistory(contextFor(session, request), params.taskId)) };
|
||||
});
|
||||
|
||||
app.get('/api/tasks/:taskId/artifacts/:artifactId', async (request, reply) => {
|
||||
const session = await getReadySession(request);
|
||||
const session = await getSession(request);
|
||||
const params = request.params as { taskId: string; artifactId: string };
|
||||
const artifactId = z.string().uuid().safeParse(params.artifactId);
|
||||
if (!artifactId.success) throw new TaskError('artifact_not_found', '附件不存在或无权访问。', 404);
|
||||
@@ -1403,7 +1384,7 @@ export async function buildServer({
|
||||
});
|
||||
|
||||
app.get('/api/events', async (request, reply) => {
|
||||
const session = await getReadySession(request);
|
||||
const session = await getSession(request);
|
||||
const query = (request.query || {}) as Record<string, unknown>;
|
||||
const querySince = Number(query.since || 0);
|
||||
const reconnectSince = Number(request.headers['last-event-id'] || 0);
|
||||
|
||||
Reference in new issue
Block a user