feat: migrate nextjs to rr7

This commit is contained in:
David Nguyen
2025-01-02 15:33:37 +11:00
parent 9183f668d3
commit 383b5f78f0
898 changed files with 31175 additions and 24615 deletions

View File

@ -1,13 +1,17 @@
import type { User } from '@prisma/client';
import { UserSecurityAuditLogType } from '@prisma/client';
import { prisma } from '@documenso/prisma';
import type { User } from '@documenso/prisma/client';
import { UserSecurityAuditLogType } from '@documenso/prisma/client';
import { AppError, AppErrorCode } from '../../errors/app-error';
import type { RequestMetadata } from '../../universal/extract-request-metadata';
import { validateTwoFactorAuthentication } from './validate-2fa';
type DisableTwoFactorAuthenticationOptions = {
user: User;
user: Pick<
User,
'id' | 'email' | 'twoFactorEnabled' | 'twoFactorSecret' | 'twoFactorBackupCodes'
>;
totpCode?: string;
backupCode?: string;
requestMetadata?: RequestMetadata;

View File

@ -1,5 +1,6 @@
import { type User, UserSecurityAuditLogType } from '@prisma/client';
import { prisma } from '@documenso/prisma';
import { type User, UserSecurityAuditLogType } from '@documenso/prisma/client';
import { AppError } from '../../errors/app-error';
import type { RequestMetadata } from '../../universal/extract-request-metadata';
@ -7,7 +8,7 @@ import { getBackupCodes } from './get-backup-code';
import { verifyTwoFactorAuthenticationToken } from './verify-2fa-token';
type EnableTwoFactorAuthenticationOptions = {
user: User;
user: Pick<User, 'id' | 'email' | 'twoFactorEnabled' | 'twoFactorSecret'>;
code: string;
requestMetadata?: RequestMetadata;
};

View File

@ -1,12 +1,11 @@
import type { User } from '@prisma/client';
import { z } from 'zod';
import { User } from '@documenso/prisma/client';
import { DOCUMENSO_ENCRYPTION_KEY } from '../../constants/crypto';
import { symmetricDecrypt } from '../../universal/crypto';
interface GetBackupCodesOptions {
user: User;
user: Pick<User, 'id' | 'twoFactorEnabled' | 'twoFactorBackupCodes'>;
}
const ZBackupCodeSchema = z.array(z.string());
@ -14,6 +13,10 @@ const ZBackupCodeSchema = z.array(z.string());
export const getBackupCodes = ({ user }: GetBackupCodesOptions) => {
const key = DOCUMENSO_ENCRYPTION_KEY;
if (!key) {
throw new Error('Missing DOCUMENSO_ENCRYPTION_KEY');
}
if (!user.twoFactorEnabled) {
throw new Error('User has not enabled 2FA');
}

View File

@ -1,4 +1,4 @@
import type { User } from '@documenso/prisma/client';
import type { User } from '@prisma/client';
import { DOCUMENSO_ENCRYPTION_KEY } from '../../constants/crypto';

View File

@ -1,16 +1,15 @@
import { type User } from '@prisma/client';
import { base32 } from '@scure/base';
import crypto from 'crypto';
import { createTOTPKeyURI } from 'oslo/otp';
import { ErrorCode } from '@documenso/lib/next-auth/error-codes';
import { prisma } from '@documenso/prisma';
import { type User } from '@documenso/prisma/client';
import { DOCUMENSO_ENCRYPTION_KEY } from '../../constants/crypto';
import { symmetricEncrypt } from '../../universal/crypto';
type SetupTwoFactorAuthenticationOptions = {
user: User;
user: Pick<User, 'id' | 'email'>;
};
const ISSUER = 'Documenso';
@ -21,7 +20,7 @@ export const setupTwoFactorAuthentication = async ({
const key = DOCUMENSO_ENCRYPTION_KEY;
if (!key) {
throw new Error(ErrorCode.MISSING_ENCRYPTION_KEY);
throw new Error('MISSING_ENCRYPTION_KEY');
}
const secret = crypto.randomBytes(10);

View File

@ -1,13 +1,16 @@
import type { User } from '@documenso/prisma/client';
import type { User } from '@prisma/client';
import { ErrorCode } from '../../next-auth/error-codes';
import { AppError } from '../../errors/app-error';
import { verifyTwoFactorAuthenticationToken } from './verify-2fa-token';
import { verifyBackupCode } from './verify-backup-code';
type ValidateTwoFactorAuthenticationOptions = {
totpCode?: string;
backupCode?: string;
user: User;
user: Pick<
User,
'id' | 'email' | 'twoFactorEnabled' | 'twoFactorSecret' | 'twoFactorBackupCodes'
>;
};
export const validateTwoFactorAuthentication = async ({
@ -16,11 +19,11 @@ export const validateTwoFactorAuthentication = async ({
user,
}: ValidateTwoFactorAuthenticationOptions) => {
if (!user.twoFactorEnabled) {
throw new Error(ErrorCode.TWO_FACTOR_SETUP_REQUIRED);
throw new AppError('TWO_FACTOR_SETUP_REQUIRED');
}
if (!user.twoFactorSecret) {
throw new Error(ErrorCode.TWO_FACTOR_MISSING_SECRET);
throw new AppError('TWO_FACTOR_MISSING_SECRET');
}
if (totpCode) {
@ -28,8 +31,8 @@ export const validateTwoFactorAuthentication = async ({
}
if (backupCode) {
return await verifyBackupCode({ user, backupCode });
return verifyBackupCode({ user, backupCode });
}
throw new Error(ErrorCode.TWO_FACTOR_MISSING_CREDENTIALS);
throw new AppError('TWO_FACTOR_MISSING_CREDENTIALS');
};

View File

@ -1,13 +1,12 @@
import type { User } from '@prisma/client';
import { base32 } from '@scure/base';
import { generateHOTP } from 'oslo/otp';
import type { User } from '@documenso/prisma/client';
import { DOCUMENSO_ENCRYPTION_KEY } from '../../constants/crypto';
import { symmetricDecrypt } from '../../universal/crypto';
type VerifyTwoFactorAuthenticationTokenOptions = {
user: User;
user: Pick<User, 'id' | 'twoFactorSecret'>;
totpCode: string;
// The number of windows to look back
window?: number;
@ -23,6 +22,10 @@ export const verifyTwoFactorAuthenticationToken = async ({
}: VerifyTwoFactorAuthenticationTokenOptions) => {
const key = DOCUMENSO_ENCRYPTION_KEY;
if (!key) {
throw new Error('Missing DOCUMENSO_ENCRYPTION_KEY');
}
if (!user.twoFactorSecret) {
throw new Error('user missing 2fa secret');
}

View File

@ -1,14 +1,14 @@
import { User } from '@documenso/prisma/client';
import type { User } from '@prisma/client';
import { getBackupCodes } from './get-backup-code';
type VerifyBackupCodeParams = {
user: User;
user: Pick<User, 'id' | 'twoFactorEnabled' | 'twoFactorBackupCodes'>;
backupCode: string;
};
export const verifyBackupCode = async ({ user, backupCode }: VerifyBackupCodeParams) => {
const userBackupCodes = await getBackupCodes({ user });
export const verifyBackupCode = ({ user, backupCode }: VerifyBackupCodeParams) => {
const userBackupCodes = getBackupCodes({ user });
if (!userBackupCodes) {
throw new Error('User has no backup codes');

View File

@ -1,11 +1,14 @@
import type { User } from '@documenso/prisma/client';
import type { User } from '@prisma/client';
import { AppError } from '../../errors/app-error';
import { getBackupCodes } from './get-backup-code';
import { validateTwoFactorAuthentication } from './validate-2fa';
type ViewBackupCodesOptions = {
user: User;
user: Pick<
User,
'id' | 'email' | 'twoFactorEnabled' | 'twoFactorSecret' | 'twoFactorBackupCodes'
>;
token: string;
};