mirror of
https://github.com/documenso/documenso.git
synced 2025-11-13 08:13:56 +10:00
Allow organisations to manage an SSO OIDC compliant portal. This method is intended to streamline the onboarding process and paves the way to allow organisations to manage their members in a more strict way.
115 lines
2.5 KiB
TypeScript
115 lines
2.5 KiB
TypeScript
import { DateTime } from 'luxon';
|
|
|
|
import { prisma } from '@documenso/prisma';
|
|
|
|
import {
|
|
EMAIL_VERIFICATION_STATE,
|
|
USER_SIGNUP_VERIFICATION_TOKEN_IDENTIFIER,
|
|
} from '../../constants/email';
|
|
import { jobsClient } from '../../jobs/client';
|
|
|
|
export type VerifyEmailProps = {
|
|
token: string;
|
|
};
|
|
|
|
export const verifyEmail = async ({ token }: VerifyEmailProps) => {
|
|
const verificationToken = await prisma.verificationToken.findFirst({
|
|
include: {
|
|
user: {
|
|
select: {
|
|
id: true,
|
|
email: true,
|
|
name: true,
|
|
},
|
|
},
|
|
},
|
|
where: {
|
|
token,
|
|
identifier: USER_SIGNUP_VERIFICATION_TOKEN_IDENTIFIER,
|
|
},
|
|
});
|
|
|
|
if (!verificationToken) {
|
|
return {
|
|
state: EMAIL_VERIFICATION_STATE.NOT_FOUND,
|
|
userId: null,
|
|
};
|
|
}
|
|
|
|
// check if the token is valid or expired
|
|
const valid = verificationToken.expires > new Date();
|
|
|
|
if (!valid) {
|
|
const mostRecentToken = await prisma.verificationToken.findFirst({
|
|
where: {
|
|
userId: verificationToken.userId,
|
|
},
|
|
orderBy: {
|
|
createdAt: 'desc',
|
|
},
|
|
});
|
|
|
|
// If there isn't a recent token or it's older than 1 hour, send a new token
|
|
if (
|
|
!mostRecentToken ||
|
|
DateTime.now().minus({ hours: 1 }).toJSDate() > mostRecentToken.createdAt
|
|
) {
|
|
await jobsClient.triggerJob({
|
|
name: 'send.signup.confirmation.email',
|
|
payload: {
|
|
email: verificationToken.user.email,
|
|
},
|
|
});
|
|
}
|
|
|
|
return {
|
|
state: EMAIL_VERIFICATION_STATE.EXPIRED,
|
|
userId: null,
|
|
};
|
|
}
|
|
|
|
if (verificationToken.completed) {
|
|
return {
|
|
state: EMAIL_VERIFICATION_STATE.ALREADY_VERIFIED,
|
|
userId: null,
|
|
};
|
|
}
|
|
|
|
const [updatedUser] = await prisma.$transaction([
|
|
prisma.user.update({
|
|
where: {
|
|
id: verificationToken.userId,
|
|
},
|
|
data: {
|
|
emailVerified: new Date(),
|
|
},
|
|
}),
|
|
prisma.verificationToken.updateMany({
|
|
where: {
|
|
userId: verificationToken.userId,
|
|
},
|
|
data: {
|
|
completed: true,
|
|
},
|
|
}),
|
|
// Tidy up old expired tokens
|
|
prisma.verificationToken.deleteMany({
|
|
where: {
|
|
userId: verificationToken.userId,
|
|
expires: {
|
|
lt: new Date(),
|
|
},
|
|
},
|
|
}),
|
|
]);
|
|
|
|
if (!updatedUser) {
|
|
throw new Error('Something went wrong while verifying your email. Please try again.');
|
|
}
|
|
|
|
return {
|
|
state: EMAIL_VERIFICATION_STATE.VERIFIED,
|
|
userId: updatedUser.id,
|
|
};
|
|
};
|