You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
125 lines
3.1 KiB
125 lines
3.1 KiB
import * as Sentry from '@sentry/node';
|
|
import crypto from 'crypto';
|
|
import { Token, IToken, IUser } from '../models';
|
|
import { createOrganization } from './organization';
|
|
import { addMembershipsOrg } from './membershipOrg';
|
|
import { createWorkspace } from './workspace';
|
|
import { addMemberships } from './membership';
|
|
import { OWNER, ADMIN, ACCEPTED, GRANTED } from '../variables';
|
|
import { sendMail } from '../helpers/nodemailer';
|
|
|
|
/**
|
|
* Send magic link to verify email to [email]
|
|
* for user and workspace.
|
|
* @param {Object} obj
|
|
* @param {String} obj.email - email
|
|
* @returns {Boolean} success - whether or not operation was successful
|
|
*
|
|
*/
|
|
const sendEmailVerification = async ({ email }: { email: string }) => {
|
|
try {
|
|
const token = String(crypto.randomInt(Math.pow(10, 5), Math.pow(10, 6) - 1));
|
|
|
|
await Token.findOneAndUpdate(
|
|
{ email },
|
|
{
|
|
email,
|
|
token,
|
|
createdAt: new Date()
|
|
},
|
|
{ upsert: true, new: true }
|
|
);
|
|
|
|
// send mail
|
|
await sendMail({
|
|
template: 'emailVerification.handlebars',
|
|
subjectLine: 'Infisical workspace invitation',
|
|
recipients: [email],
|
|
substitutions: {
|
|
code: token
|
|
}
|
|
});
|
|
} catch (err) {
|
|
Sentry.setUser(null);
|
|
Sentry.captureException(err);
|
|
throw new Error(
|
|
"Ouch. We weren't able to send your email verification code"
|
|
);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Validate [code] sent to [email]
|
|
* @param {Object} obj
|
|
* @param {String} obj.email - emai
|
|
* @param {String} obj.code - code that was sent to [email]
|
|
*/
|
|
const checkEmailVerification = async ({
|
|
email,
|
|
code
|
|
}: {
|
|
email: string;
|
|
code: string;
|
|
}) => {
|
|
try {
|
|
const token = await Token.findOneAndDelete({
|
|
email,
|
|
token: code
|
|
});
|
|
|
|
if (!token) throw new Error('Failed to find email verification token');
|
|
} catch (err) {
|
|
Sentry.setUser(null);
|
|
Sentry.captureException(err);
|
|
throw new Error("Oops. We weren't able to verify");
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Initialize default organization named [organizationName] with workspace
|
|
* for user [user]
|
|
* @param {Object} obj
|
|
* @param {String} obj.organizationName - name of organization to initialize
|
|
* @param {IUser} obj.user - user who we are initializing for
|
|
*/
|
|
const initializeDefaultOrg = async ({
|
|
organizationName,
|
|
user
|
|
}: {
|
|
organizationName: string;
|
|
user: IUser;
|
|
}) => {
|
|
try {
|
|
// create organization with user as owner and initialize a free
|
|
// subscription
|
|
const organization = await createOrganization({
|
|
email: user.email,
|
|
name: organizationName
|
|
});
|
|
|
|
await addMembershipsOrg({
|
|
userIds: [user._id.toString()],
|
|
organizationId: organization._id.toString(),
|
|
roles: [OWNER],
|
|
statuses: [ACCEPTED]
|
|
});
|
|
|
|
// initialize a default workspace inside the new organization
|
|
const workspace = await createWorkspace({
|
|
name: `${user.firstName}'s Project`,
|
|
organizationId: organization._id.toString()
|
|
});
|
|
|
|
await addMemberships({
|
|
userIds: [user._id.toString()],
|
|
workspaceId: workspace._id.toString(),
|
|
roles: [ADMIN],
|
|
statuses: [GRANTED]
|
|
});
|
|
} catch (err) {
|
|
throw new Error('Failed to initialize default organization and workspace');
|
|
}
|
|
};
|
|
|
|
export { sendEmailVerification, checkEmailVerification, initializeDefaultOrg };
|