2021-07-31 15:57:43 +00:00
|
|
|
import { resolver, SecurePassword, AuthenticationError } from "blitz";
|
2021-07-31 14:33:18 +00:00
|
|
|
|
2021-08-05 17:07:15 +00:00
|
|
|
import db, { GlobalRole } from "../../../db";
|
2021-07-31 15:57:43 +00:00
|
|
|
import { Login } from "../validations";
|
2021-07-31 14:33:18 +00:00
|
|
|
|
|
|
|
export const authenticateUser = async (rawEmail: string, rawPassword: string) => {
|
2021-07-31 15:57:43 +00:00
|
|
|
const email = rawEmail.toLowerCase().trim();
|
|
|
|
const password = rawPassword.trim();
|
2021-08-08 05:34:51 +00:00
|
|
|
const user = await db.user.findFirst({
|
|
|
|
where: { email },
|
|
|
|
include: {
|
|
|
|
memberships: {
|
|
|
|
include: {
|
|
|
|
organization: {
|
|
|
|
include: { phoneNumbers: true },
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
});
|
2021-07-31 15:57:43 +00:00
|
|
|
if (!user) throw new AuthenticationError();
|
2021-07-31 14:33:18 +00:00
|
|
|
|
2021-07-31 15:57:43 +00:00
|
|
|
const result = await SecurePassword.verify(user.hashedPassword, password);
|
2021-07-31 14:33:18 +00:00
|
|
|
|
|
|
|
if (result === SecurePassword.VALID_NEEDS_REHASH) {
|
|
|
|
// Upgrade hashed password with a more secure hash
|
2021-07-31 15:57:43 +00:00
|
|
|
const improvedHash = await SecurePassword.hash(password);
|
2021-08-08 05:34:51 +00:00
|
|
|
await db.user.update({
|
|
|
|
where: { id: user.id },
|
|
|
|
data: { hashedPassword: improvedHash },
|
|
|
|
});
|
2021-07-31 14:33:18 +00:00
|
|
|
}
|
|
|
|
|
2021-07-31 15:57:43 +00:00
|
|
|
const { hashedPassword, ...rest } = user;
|
|
|
|
return rest;
|
|
|
|
};
|
2021-07-31 14:33:18 +00:00
|
|
|
|
|
|
|
export default resolver.pipe(resolver.zod(Login), async ({ email, password }, ctx) => {
|
|
|
|
// This throws an error if credentials are invalid
|
2021-07-31 15:57:43 +00:00
|
|
|
const user = await authenticateUser(email, password);
|
2021-07-31 14:33:18 +00:00
|
|
|
|
2021-08-08 05:34:51 +00:00
|
|
|
const organization = user.memberships[0]!.organization;
|
|
|
|
const hasCompletedOnboarding =
|
|
|
|
Boolean(organization.twilioAccountSid) &&
|
|
|
|
Boolean(organization.twilioAuthToken) &&
|
|
|
|
Boolean(organization.twilioApiKey) &&
|
|
|
|
Boolean(organization.twilioApiSecret) &&
|
|
|
|
Boolean(organization.phoneNumbers.length > 1);
|
2021-08-05 17:07:15 +00:00
|
|
|
await ctx.session.$create({
|
|
|
|
userId: user.id,
|
2021-08-08 05:34:51 +00:00
|
|
|
roles: [user.role, user.memberships[0]!.role],
|
|
|
|
hasCompletedOnboarding: hasCompletedOnboarding || undefined,
|
|
|
|
orgId: organization.id,
|
2021-08-05 17:07:15 +00:00
|
|
|
});
|
2021-07-31 14:33:18 +00:00
|
|
|
|
2021-07-31 15:57:43 +00:00
|
|
|
return user;
|
|
|
|
});
|