mirror of
https://github.com/movie-web/backend.git
synced 2025-09-13 13:03:26 +00:00
Extract challenge verification logic to service
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { ChallengeCode, formatChallengeCode } from '@/db/models/ChallengeCode';
|
import { ChallengeCode } from '@/db/models/ChallengeCode';
|
||||||
import { formatSession } from '@/db/models/Session';
|
import { formatSession } from '@/db/models/Session';
|
||||||
import { User, formatUser } from '@/db/models/User';
|
import { User, formatUser } from '@/db/models/User';
|
||||||
import { getMetrics } from '@/modules/metrics';
|
import { getMetrics } from '@/modules/metrics';
|
||||||
@@ -7,10 +7,7 @@ import { handle } from '@/services/handler';
|
|||||||
import { makeRouter } from '@/services/router';
|
import { makeRouter } from '@/services/router';
|
||||||
import { makeSession, makeSessionToken } from '@/services/session';
|
import { makeSession, makeSessionToken } from '@/services/session';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import { nanoid } from 'nanoid';
|
import { assertChallengeCode } from '@/services/challenge';
|
||||||
import forge from 'node-forge';
|
|
||||||
import { StatusError } from '@/services/error';
|
|
||||||
import { t } from '@mikro-orm/core';
|
|
||||||
|
|
||||||
const startSchema = z.object({
|
const startSchema = z.object({
|
||||||
captchaToken: z.string().optional(),
|
captchaToken: z.string().optional(),
|
||||||
@@ -54,32 +51,12 @@ export const manageAuthRouter = makeRouter((app) => {
|
|||||||
'/auth/register/complete',
|
'/auth/register/complete',
|
||||||
{ schema: { body: completeSchema } },
|
{ schema: { body: completeSchema } },
|
||||||
handle(async ({ em, body, req }) => {
|
handle(async ({ em, body, req }) => {
|
||||||
const now = Date.now();
|
await assertChallengeCode(
|
||||||
|
em,
|
||||||
const challenge = await em.findOne(ChallengeCode, {
|
body.challenge.code,
|
||||||
code: body.challenge.code,
|
body.publicKey,
|
||||||
});
|
body.challenge.signature,
|
||||||
|
);
|
||||||
if (!challenge) throw new StatusError('Challenge Code Invalid', 401);
|
|
||||||
|
|
||||||
if (challenge.expiresAt.getTime() <= now)
|
|
||||||
throw new StatusError('Challenge Code Expired', 401);
|
|
||||||
|
|
||||||
const verifiedChallenge = forge.pki.ed25519.verify({
|
|
||||||
publicKey: new forge.util.ByteStringBuffer(
|
|
||||||
Buffer.from(body.publicKey, 'base64url'),
|
|
||||||
),
|
|
||||||
encoding: 'utf8',
|
|
||||||
signature: new forge.util.ByteStringBuffer(
|
|
||||||
Buffer.from(body.challenge.signature, 'base64url'),
|
|
||||||
),
|
|
||||||
message: body.challenge.code,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!verifiedChallenge)
|
|
||||||
throw new StatusError('Challenge Code Signature Invalid', 401);
|
|
||||||
|
|
||||||
em.remove(challenge);
|
|
||||||
|
|
||||||
const user = new User();
|
const user = new User();
|
||||||
user.namespace = body.namespace;
|
user.namespace = body.namespace;
|
||||||
|
38
src/services/challenge.ts
Normal file
38
src/services/challenge.ts
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import { ChallengeCode } from '@/db/models/ChallengeCode';
|
||||||
|
import { StatusError } from '@/services/error';
|
||||||
|
import { EntityManager } from '@mikro-orm/core';
|
||||||
|
import forge from 'node-forge';
|
||||||
|
|
||||||
|
export async function assertChallengeCode(
|
||||||
|
em: EntityManager,
|
||||||
|
code: string,
|
||||||
|
publicKey: string,
|
||||||
|
signature: string,
|
||||||
|
) {
|
||||||
|
const now = Date.now();
|
||||||
|
|
||||||
|
const challenge = await em.findOne(ChallengeCode, {
|
||||||
|
code,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!challenge) throw new StatusError('Challenge Code Invalid', 401);
|
||||||
|
|
||||||
|
if (challenge.expiresAt.getTime() <= now)
|
||||||
|
throw new StatusError('Challenge Code Expired', 401);
|
||||||
|
|
||||||
|
const verifiedChallenge = forge.pki.ed25519.verify({
|
||||||
|
publicKey: new forge.util.ByteStringBuffer(
|
||||||
|
Buffer.from(publicKey, 'base64url'),
|
||||||
|
),
|
||||||
|
encoding: 'utf8',
|
||||||
|
signature: new forge.util.ByteStringBuffer(
|
||||||
|
Buffer.from(signature, 'base64url'),
|
||||||
|
),
|
||||||
|
message: code,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!verifiedChallenge)
|
||||||
|
throw new StatusError('Challenge Code Signature Invalid', 401);
|
||||||
|
|
||||||
|
em.remove(challenge);
|
||||||
|
}
|
Reference in New Issue
Block a user