d56b2eded5
* Initial commit and WIP new login page * added wrapper to fix layout * Improved the layout and style of the page * Added a new extra-large button style (and added it to storybook) * Moved the cusom onboarding style tooltip to the Tooltip component * Populated the bento grid with items * Imrpoved the quote styling * Tooltip doesn’t stay if you mouse over it * Added more content including a list of quote that cycle on page load * New quote mark positioning * Added the rest of the content to the tooltips * Made the bento grid responsive * Moved the login page layout to a seaparte component * Login pages now use the new layout component * Extra large button style tweak * Match the large input style with the large button style * Cleaned up imports and made the Ts & Cs text the same for magic links * Layout fix * Quotes don’t push content off the screen as much * Added openai integration to the grid * Make the quote fit if the screen height is narrower * Style update to the magic link sent state * Icon colour updates * fixed text centering on mobile * Icons are more responsive * removed unnecessary w-fulls * Added 2 onboarding questions * Revalidate form on submit, not input * Typo fixes * Name field focuses by default * Added conform to the employees question * Update pnpm lock file * Implement referral source and company size on managed cloud * Fixed some type errors --------- Co-authored-by: James Ritchie <james@jamesritchie.co.uk>
188 lines
4.2 KiB
TypeScript
188 lines
4.2 KiB
TypeScript
import type { Prisma, User } from "@trigger.dev/database";
|
|
import type { GitHubProfile } from "remix-auth-github";
|
|
import { prisma } from "~/db.server";
|
|
import { env } from "~/env.server";
|
|
export type { User } from "@trigger.dev/database";
|
|
|
|
type FindOrCreateMagicLink = {
|
|
authenticationMethod: "MAGIC_LINK";
|
|
email: string;
|
|
};
|
|
|
|
type FindOrCreateGithub = {
|
|
authenticationMethod: "GITHUB";
|
|
email: User["email"];
|
|
authenticationProfile: GitHubProfile;
|
|
authenticationExtraParams: Record<string, unknown>;
|
|
};
|
|
|
|
type FindOrCreateUser = FindOrCreateMagicLink | FindOrCreateGithub;
|
|
|
|
type LoggedInUser = {
|
|
user: User;
|
|
isNewUser: boolean;
|
|
};
|
|
|
|
export async function findOrCreateUser(input: FindOrCreateUser): Promise<LoggedInUser> {
|
|
switch (input.authenticationMethod) {
|
|
case "GITHUB": {
|
|
return findOrCreateGithubUser(input);
|
|
}
|
|
case "MAGIC_LINK": {
|
|
return findOrCreateMagicLinkUser(input);
|
|
}
|
|
}
|
|
}
|
|
|
|
export async function findOrCreateMagicLinkUser(
|
|
input: FindOrCreateMagicLink
|
|
): Promise<LoggedInUser> {
|
|
if (env.WHITELISTED_EMAILS && !new RegExp(env.WHITELISTED_EMAILS).test(input.email)) {
|
|
throw new Error("This email is unauthorized");
|
|
}
|
|
|
|
const existingUser = await prisma.user.findFirst({
|
|
where: {
|
|
email: input.email,
|
|
},
|
|
});
|
|
|
|
const user = await prisma.user.upsert({
|
|
where: {
|
|
email: input.email,
|
|
},
|
|
update: { email: input.email },
|
|
create: { email: input.email, authenticationMethod: "MAGIC_LINK" },
|
|
});
|
|
|
|
return {
|
|
user,
|
|
isNewUser: !existingUser,
|
|
};
|
|
}
|
|
|
|
export async function findOrCreateGithubUser({
|
|
email,
|
|
authenticationProfile,
|
|
authenticationExtraParams,
|
|
}: FindOrCreateGithub): Promise<LoggedInUser> {
|
|
const name = authenticationProfile._json.name;
|
|
let avatarUrl: string | undefined = undefined;
|
|
if (authenticationProfile.photos[0]) {
|
|
avatarUrl = authenticationProfile.photos[0].value;
|
|
}
|
|
const displayName = authenticationProfile.displayName;
|
|
const authProfile = authenticationProfile
|
|
? (authenticationProfile as unknown as Prisma.JsonObject)
|
|
: undefined;
|
|
const authExtraParams = authenticationExtraParams
|
|
? (authenticationExtraParams as unknown as Prisma.JsonObject)
|
|
: undefined;
|
|
|
|
const authIdentifier = `github:${authenticationProfile.id}`;
|
|
|
|
const existingUser = await prisma.user.findUnique({
|
|
where: {
|
|
authIdentifier,
|
|
},
|
|
});
|
|
|
|
const existingEmailUser = await prisma.user.findUnique({
|
|
where: {
|
|
email,
|
|
},
|
|
});
|
|
|
|
if (existingEmailUser && !existingUser) {
|
|
const user = await prisma.user.update({
|
|
where: {
|
|
email,
|
|
},
|
|
data: {
|
|
authenticationProfile: authProfile,
|
|
authenticationExtraParams: authExtraParams,
|
|
avatarUrl,
|
|
authIdentifier,
|
|
},
|
|
});
|
|
|
|
return {
|
|
user,
|
|
isNewUser: false,
|
|
};
|
|
}
|
|
|
|
if (existingEmailUser && existingUser) {
|
|
const user = await prisma.user.update({
|
|
where: {
|
|
id: existingUser.id,
|
|
},
|
|
data: {},
|
|
});
|
|
|
|
return {
|
|
user,
|
|
isNewUser: false,
|
|
};
|
|
}
|
|
|
|
const user = await prisma.user.upsert({
|
|
where: {
|
|
authIdentifier,
|
|
},
|
|
update: {},
|
|
create: {
|
|
authenticationProfile: authProfile,
|
|
authenticationExtraParams: authExtraParams,
|
|
name,
|
|
avatarUrl,
|
|
displayName,
|
|
authIdentifier,
|
|
email,
|
|
authenticationMethod: "GITHUB",
|
|
},
|
|
});
|
|
|
|
return {
|
|
user,
|
|
isNewUser: !existingUser,
|
|
};
|
|
}
|
|
|
|
export async function getUserById(id: User["id"]) {
|
|
return prisma.user.findUnique({ where: { id } });
|
|
}
|
|
|
|
export async function getUserByEmail(email: User["email"]) {
|
|
return prisma.user.findUnique({ where: { email } });
|
|
}
|
|
|
|
export function updateUser({
|
|
id,
|
|
name,
|
|
email,
|
|
marketingEmails,
|
|
referralSource,
|
|
}: Pick<User, "id" | "name" | "email"> & {
|
|
marketingEmails?: boolean;
|
|
referralSource?: string;
|
|
}) {
|
|
return prisma.user.update({
|
|
where: { id },
|
|
data: { name, email, marketingEmails, referralSource, confirmedBasicDetails: true },
|
|
});
|
|
}
|
|
|
|
export async function grantUserCloudAccess({ id, inviteCode }: { id: string; inviteCode: string }) {
|
|
return prisma.user.update({
|
|
where: { id },
|
|
data: {
|
|
invitationCode: {
|
|
connect: {
|
|
code: inviteCode,
|
|
},
|
|
},
|
|
},
|
|
});
|
|
}
|