mirror of
https://github.com/movie-web/backend.git
synced 2025-09-13 18:13:26 +00:00
80 lines
2.1 KiB
TypeScript
80 lines
2.1 KiB
TypeScript
import { ChallengeCode } from '@/db/models/ChallengeCode';
|
|
import { formatSession } from '@/db/models/Session';
|
|
import { User, formatUser } from '@/db/models/User';
|
|
import { getMetrics } from '@/modules/metrics';
|
|
import { assertCaptcha } from '@/services/captcha';
|
|
import { handle } from '@/services/handler';
|
|
import { makeRouter } from '@/services/router';
|
|
import { makeSession, makeSessionToken } from '@/services/session';
|
|
import { z } from 'zod';
|
|
import { assertChallengeCode } from '@/services/challenge';
|
|
|
|
const startSchema = z.object({
|
|
captchaToken: z.string().optional(),
|
|
});
|
|
|
|
const completeSchema = z.object({
|
|
publicKey: z.string(),
|
|
challenge: z.object({
|
|
code: z.string(),
|
|
signature: z.string(),
|
|
}),
|
|
namespace: z.string().min(1),
|
|
device: z.string().max(500).min(1),
|
|
profile: z.object({
|
|
colorA: z.string(),
|
|
colorB: z.string(),
|
|
icon: z.string(),
|
|
}),
|
|
});
|
|
|
|
export const manageAuthRouter = makeRouter((app) => {
|
|
app.post(
|
|
'/auth/register/start',
|
|
{ schema: { body: startSchema } },
|
|
handle(async ({ em, body }) => {
|
|
await assertCaptcha(body.captchaToken);
|
|
|
|
const challenge = new ChallengeCode();
|
|
challenge.authType = 'mnemonic';
|
|
challenge.stage = 'registration';
|
|
|
|
await em.persistAndFlush(challenge);
|
|
|
|
return {
|
|
challenge: challenge.code,
|
|
};
|
|
}),
|
|
);
|
|
|
|
app.post(
|
|
'/auth/register/complete',
|
|
{ schema: { body: completeSchema } },
|
|
handle(async ({ em, body, req }) => {
|
|
await assertChallengeCode(
|
|
em,
|
|
body.challenge.code,
|
|
body.publicKey,
|
|
body.challenge.signature,
|
|
);
|
|
|
|
const user = new User();
|
|
user.namespace = body.namespace;
|
|
user.publicKey = body.publicKey;
|
|
user.profile = body.profile;
|
|
const session = makeSession(
|
|
user.id,
|
|
body.device,
|
|
req.headers['user-agent'],
|
|
);
|
|
await em.persistAndFlush([user, session]);
|
|
getMetrics().user.inc({ namespace: body.namespace }, 1);
|
|
return {
|
|
user: formatUser(user),
|
|
session: formatSession(session),
|
|
token: makeSessionToken(session),
|
|
};
|
|
}),
|
|
);
|
|
});
|