mirror of
https://github.com/documenso/documenso.git
synced 2025-11-13 08:13:56 +10:00
feat: add two factor auth (#643)
Add two factor authentication for users who wish to enhance the security of their accounts.
This commit is contained in:
105
packages/trpc/server/two-factor-authentication-router/router.ts
Normal file
105
packages/trpc/server/two-factor-authentication-router/router.ts
Normal file
@ -0,0 +1,105 @@
|
||||
import { TRPCError } from '@trpc/server';
|
||||
|
||||
import { ErrorCode } from '@documenso/lib/next-auth/error-codes';
|
||||
import { disableTwoFactorAuthentication } from '@documenso/lib/server-only/2fa/disable-2fa';
|
||||
import { enableTwoFactorAuthentication } from '@documenso/lib/server-only/2fa/enable-2fa';
|
||||
import { getBackupCodes } from '@documenso/lib/server-only/2fa/get-backup-code';
|
||||
import { setupTwoFactorAuthentication } from '@documenso/lib/server-only/2fa/setup-2fa';
|
||||
import { compareSync } from '@documenso/lib/server-only/auth/hash';
|
||||
|
||||
import { authenticatedProcedure, router } from '../trpc';
|
||||
import {
|
||||
ZDisableTwoFactorAuthenticationMutationSchema,
|
||||
ZEnableTwoFactorAuthenticationMutationSchema,
|
||||
ZSetupTwoFactorAuthenticationMutationSchema,
|
||||
ZViewRecoveryCodesMutationSchema,
|
||||
} from './schema';
|
||||
|
||||
export const twoFactorAuthenticationRouter = router({
|
||||
setup: authenticatedProcedure
|
||||
.input(ZSetupTwoFactorAuthenticationMutationSchema)
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
const user = ctx.user;
|
||||
|
||||
const { password } = input;
|
||||
|
||||
return await setupTwoFactorAuthentication({ user, password });
|
||||
}),
|
||||
|
||||
enable: authenticatedProcedure
|
||||
.input(ZEnableTwoFactorAuthenticationMutationSchema)
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
try {
|
||||
const user = ctx.user;
|
||||
|
||||
const { code } = input;
|
||||
|
||||
return await enableTwoFactorAuthentication({ user, code });
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw new TRPCError({
|
||||
code: 'BAD_REQUEST',
|
||||
message: 'We were unable to enable two-factor authentication. Please try again later.',
|
||||
});
|
||||
}
|
||||
}),
|
||||
|
||||
disable: authenticatedProcedure
|
||||
.input(ZDisableTwoFactorAuthenticationMutationSchema)
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
try {
|
||||
const user = ctx.user;
|
||||
|
||||
const { password, backupCode } = input;
|
||||
|
||||
return await disableTwoFactorAuthentication({ user, password, backupCode });
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw new TRPCError({
|
||||
code: 'BAD_REQUEST',
|
||||
message: 'We were unable to disable two-factor authentication. Please try again later.',
|
||||
});
|
||||
}
|
||||
}),
|
||||
|
||||
viewRecoveryCodes: authenticatedProcedure
|
||||
.input(ZViewRecoveryCodesMutationSchema)
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
try {
|
||||
const user = ctx.user;
|
||||
|
||||
const { password } = input;
|
||||
|
||||
if (!user.twoFactorEnabled) {
|
||||
throw new TRPCError({
|
||||
code: 'BAD_REQUEST',
|
||||
message: ErrorCode.TWO_FACTOR_SETUP_REQUIRED,
|
||||
});
|
||||
}
|
||||
|
||||
if (!user.password || !compareSync(password, user.password)) {
|
||||
throw new TRPCError({
|
||||
code: 'UNAUTHORIZED',
|
||||
message: ErrorCode.INCORRECT_PASSWORD,
|
||||
});
|
||||
}
|
||||
|
||||
const recoveryCodes = await getBackupCodes({ user });
|
||||
|
||||
return { recoveryCodes };
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
if (err instanceof TRPCError) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
throw new TRPCError({
|
||||
code: 'BAD_REQUEST',
|
||||
message: 'We were unable to view your recovery codes. Please try again later.',
|
||||
});
|
||||
}
|
||||
}),
|
||||
});
|
||||
Reference in New Issue
Block a user