mirror of
https://github.com/documenso/documenso.git
synced 2025-11-13 08:13:56 +10:00
chore: refactor code
This commit is contained in:
@ -13,7 +13,7 @@ import { IdentityProvider, UserSecurityAuditLogType } from '@documenso/prisma/cl
|
|||||||
|
|
||||||
import { isTwoFactorAuthenticationEnabled } from '../server-only/2fa/is-2fa-availble';
|
import { isTwoFactorAuthenticationEnabled } from '../server-only/2fa/is-2fa-availble';
|
||||||
import { validateTwoFactorAuthentication } from '../server-only/2fa/validate-2fa';
|
import { validateTwoFactorAuthentication } from '../server-only/2fa/validate-2fa';
|
||||||
import { getLastVerificationToken } from '../server-only/user/get-last-verification-token';
|
import { getMostRecentVerificationTokenByUserId } from '../server-only/user/get-most-recent-verification-token-by-user-id';
|
||||||
import { getUserByEmail } from '../server-only/user/get-user-by-email';
|
import { getUserByEmail } from '../server-only/user/get-user-by-email';
|
||||||
import { sendConfirmationToken } from '../server-only/user/send-confirmation-token';
|
import { sendConfirmationToken } from '../server-only/user/send-confirmation-token';
|
||||||
import { extractNextAuthRequestMetadata } from '../universal/extract-request-metadata';
|
import { extractNextAuthRequestMetadata } from '../universal/extract-request-metadata';
|
||||||
@ -93,19 +93,15 @@ export const NEXT_AUTH_OPTIONS: AuthOptions = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!user.emailVerified) {
|
if (!user.emailVerified) {
|
||||||
const [lastUserVerificationToken] = await getLastVerificationToken({ userId: user.id });
|
const mostRecentToken = await getMostRecentVerificationTokenByUserId({
|
||||||
|
userId: user.id,
|
||||||
|
});
|
||||||
|
|
||||||
if (!lastUserVerificationToken) {
|
if (
|
||||||
await sendConfirmationToken({ email });
|
!mostRecentToken ||
|
||||||
throw new Error(ErrorCode.UNVERIFIED_EMAIL);
|
mostRecentToken.expires.valueOf() <= Date.now() ||
|
||||||
}
|
DateTime.fromJSDate(mostRecentToken.createdAt).diffNow('minutes').minutes > -5
|
||||||
|
) {
|
||||||
const expiredToken =
|
|
||||||
DateTime.fromJSDate(lastUserVerificationToken.expires) <= DateTime.now();
|
|
||||||
const lastSentToken = DateTime.fromJSDate(lastUserVerificationToken.createdAt);
|
|
||||||
const sentWithinLastHour = DateTime.now().minus({ hours: 1 }) <= lastSentToken;
|
|
||||||
|
|
||||||
if (expiredToken || !sentWithinLastHour) {
|
|
||||||
await sendConfirmationToken({ email });
|
await sendConfirmationToken({ email });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,27 +0,0 @@
|
|||||||
import { prisma } from '@documenso/prisma';
|
|
||||||
|
|
||||||
export interface GetLastVerificationTokenOptions {
|
|
||||||
userId: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getLastVerificationToken = async ({ userId }: GetLastVerificationTokenOptions) => {
|
|
||||||
const user = await prisma.user.findFirstOrThrow({
|
|
||||||
where: {
|
|
||||||
id: userId,
|
|
||||||
},
|
|
||||||
include: {
|
|
||||||
VerificationToken: {
|
|
||||||
select: {
|
|
||||||
expires: true,
|
|
||||||
createdAt: true,
|
|
||||||
},
|
|
||||||
orderBy: {
|
|
||||||
createdAt: 'desc',
|
|
||||||
},
|
|
||||||
take: 1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
return user.VerificationToken;
|
|
||||||
};
|
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
import { prisma } from '@documenso/prisma';
|
||||||
|
|
||||||
|
export type GetMostRecentVerificationTokenByUserIdOptions = {
|
||||||
|
userId: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getMostRecentVerificationTokenByUserId = async ({
|
||||||
|
userId,
|
||||||
|
}: GetMostRecentVerificationTokenByUserIdOptions) => {
|
||||||
|
return await prisma.verificationToken.findFirst({
|
||||||
|
where: {
|
||||||
|
userId,
|
||||||
|
},
|
||||||
|
orderBy: {
|
||||||
|
createdAt: 'desc',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
@ -1,13 +1,20 @@
|
|||||||
import crypto from 'crypto';
|
import crypto from 'crypto';
|
||||||
|
import { DateTime } from 'luxon';
|
||||||
|
|
||||||
import { prisma } from '@documenso/prisma';
|
import { prisma } from '@documenso/prisma';
|
||||||
|
|
||||||
import { ONE_HOUR } from '../../constants/time';
|
import { ONE_HOUR } from '../../constants/time';
|
||||||
import { sendConfirmationEmail } from '../auth/send-confirmation-email';
|
import { sendConfirmationEmail } from '../auth/send-confirmation-email';
|
||||||
|
import { getMostRecentVerificationTokenByUserId } from './get-most-recent-verification-token-by-user-id';
|
||||||
|
|
||||||
const IDENTIFIER = 'confirmation-email';
|
const IDENTIFIER = 'confirmation-email';
|
||||||
|
|
||||||
export const sendConfirmationToken = async ({ email }: { email: string }) => {
|
type SendConfirmationTokenOptions = { email: string; force?: boolean };
|
||||||
|
|
||||||
|
export const sendConfirmationToken = async ({
|
||||||
|
email,
|
||||||
|
force = false,
|
||||||
|
}: SendConfirmationTokenOptions) => {
|
||||||
const token = crypto.randomBytes(20).toString('hex');
|
const token = crypto.randomBytes(20).toString('hex');
|
||||||
|
|
||||||
const user = await prisma.user.findFirst({
|
const user = await prisma.user.findFirst({
|
||||||
@ -24,6 +31,17 @@ export const sendConfirmationToken = async ({ email }: { email: string }) => {
|
|||||||
throw new Error('Email verified');
|
throw new Error('Email verified');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const mostRecentToken = await getMostRecentVerificationTokenByUserId({ userId: user.id });
|
||||||
|
|
||||||
|
// If we've sent a token in the last 5 minutes, don't send another one
|
||||||
|
if (
|
||||||
|
!force &&
|
||||||
|
mostRecentToken?.createdAt &&
|
||||||
|
DateTime.fromJSDate(mostRecentToken.createdAt).diffNow('minutes').minutes > -5
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const createdToken = await prisma.verificationToken.create({
|
const createdToken = await prisma.verificationToken.create({
|
||||||
data: {
|
data: {
|
||||||
identifier: IDENTIFIER,
|
identifier: IDENTIFIER,
|
||||||
|
|||||||
Reference in New Issue
Block a user