chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 13:32:57 +08:00
commit cd420f9332
4811 changed files with 884702 additions and 0 deletions
+418
View File
@@ -0,0 +1,418 @@
import type { Prisma, User } from "@trigger.dev/database";
import type { GitHubProfile } from "remix-auth-github";
import type { GoogleProfile } from "remix-auth-google";
import { prisma } from "~/db.server";
import { env } from "~/env.server";
import type { DashboardPreferences } from "~/services/dashboardPreferences.server";
import { getDashboardPreferences } from "~/services/dashboardPreferences.server";
export type { User } from "@trigger.dev/database";
import { assertEmailAllowed } from "~/utils/email";
import { emailMatchesPattern } from "~/utils/emailPattern";
import { logger } from "~/services/logger.server";
type FindOrCreateMagicLink = {
authenticationMethod: "MAGIC_LINK";
email: string;
};
type FindOrCreateGithub = {
authenticationMethod: "GITHUB";
email: User["email"];
authenticationProfile: GitHubProfile;
authenticationExtraParams: Record<string, unknown>;
};
type FindOrCreateGoogle = {
authenticationMethod: "GOOGLE";
email: User["email"];
authenticationProfile: GoogleProfile;
authenticationExtraParams: Record<string, unknown>;
};
type FindOrCreateSso = {
authenticationMethod: "SSO";
email: User["email"];
firstName: string | null;
lastName: string | null;
};
type FindOrCreateUser =
| FindOrCreateMagicLink
| FindOrCreateGithub
| FindOrCreateGoogle
| FindOrCreateSso;
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);
}
case "GOOGLE": {
return findOrCreateGoogleUser(input);
}
case "SSO": {
return findOrCreateSsoUser(input);
}
}
}
export async function findOrCreateMagicLinkUser({
email,
}: FindOrCreateMagicLink): Promise<LoggedInUser> {
assertEmailAllowed(email);
const existingUser = await prisma.user.findFirst({
where: {
email,
},
});
const makeAdmin = env.ADMIN_EMAILS ? emailMatchesPattern(env.ADMIN_EMAILS, email) : false;
const user = await prisma.user.upsert({
where: {
email,
},
update: {
email,
},
create: {
email,
authenticationMethod: "MAGIC_LINK",
admin: makeAdmin, // only on create, to prevent automatically removing existing admins
},
});
return {
user,
isNewUser: !existingUser,
};
}
export async function findOrCreateGithubUser({
email,
authenticationProfile,
authenticationExtraParams,
}: FindOrCreateGithub): Promise<LoggedInUser> {
assertEmailAllowed(email);
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 findOrCreateGoogleUser({
email,
authenticationProfile,
authenticationExtraParams,
}: FindOrCreateGoogle): Promise<LoggedInUser> {
assertEmailAllowed(email);
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 = `google:${authenticationProfile.id}`;
const existingUser = await prisma.user.findUnique({
where: {
authIdentifier,
},
});
const existingEmailUser = await prisma.user.findUnique({
where: {
email,
},
});
if (existingEmailUser && !existingUser) {
// Link existing email account to Google auth, preserving original authenticationMethod
const user = await prisma.user.update({
where: {
email,
},
data: {
authenticationProfile: authProfile,
authenticationExtraParams: authExtraParams,
avatarUrl,
authIdentifier,
},
});
return {
user,
isNewUser: false,
};
}
if (existingEmailUser && existingUser) {
// Check if email user and auth user are the same
if (existingEmailUser.id !== existingUser.id) {
// Different users: email is taken by one user, Google auth belongs to another
logger.warn(
`Google auth conflict: Google ID ${authenticationProfile.id} belongs to user ${existingUser.id} but email ${email} is taken by user ${existingEmailUser.id}`,
{
email,
existingEmailUserId: existingEmailUser.id,
existingAuthUserId: existingUser.id,
authIdentifier,
}
);
return {
user: existingUser,
isNewUser: false,
};
}
// Same user: update all profile fields
const user = await prisma.user.update({
where: {
id: existingUser.id,
},
data: {
email,
displayName,
name,
avatarUrl,
authenticationProfile: authProfile,
authenticationExtraParams: authExtraParams,
},
});
return {
user,
isNewUser: false,
};
}
// When the IDP user (Google) already exists, the "update" path will be taken and the email will be updated
// It's not possible that the email is already taken by a different user because that would have been handled
// by one of the if statements above.
const user = await prisma.user.upsert({
where: {
authIdentifier,
},
update: {
email,
displayName,
name,
avatarUrl,
authenticationProfile: authProfile,
authenticationExtraParams: authExtraParams,
},
create: {
authenticationProfile: authProfile,
authenticationExtraParams: authExtraParams,
name,
avatarUrl,
displayName,
authIdentifier,
email,
authenticationMethod: "GOOGLE",
},
});
return {
user,
isNewUser: !existingUser,
};
}
// Find an existing user by email (lowercased) or create a new one with the
// SSO authentication method. Mirrors the magic-link upsert shape; the
// callback route is responsible for normalising email before calling.
// Plugin writes (linking the IdP identity row) happen via the SSO plugin
// after this returns.
export async function findOrCreateSsoUser({
email,
firstName,
lastName,
}: FindOrCreateSso): Promise<LoggedInUser> {
// Validate the canonical value we actually look up and persist below —
// validating raw `email` would let case/whitespace variants slip past
// (or misapply) the allow-list policy.
const normalised = email.toLowerCase().trim();
assertEmailAllowed(normalised);
const existingUser = await prisma.user.findFirst({ where: { email: normalised } });
const fullName = [firstName, lastName].filter(Boolean).join(" ").trim() || null;
const user = await prisma.user.upsert({
where: { email: normalised },
update: {
// Existing magic-link / OAuth users keep their original
// authenticationMethod; we only refresh name/displayName when the
// user has nothing set yet so we don't clobber a customised display
// name on every SSO login.
...(existingUser?.name ? {} : { name: fullName }),
...(existingUser?.displayName ? {} : { displayName: fullName }),
},
create: {
email: normalised,
name: fullName,
displayName: fullName,
authenticationMethod: "SSO",
},
});
return { user, isNewUser: !existingUser };
}
export type UserWithDashboardPreferences = User & {
dashboardPreferences: DashboardPreferences;
};
export async function getUserById(id: User["id"]) {
const user = await prisma.user.findUnique({ where: { id } });
if (!user) {
return null;
}
const dashboardPreferences = getDashboardPreferences(user.dashboardPreferences);
return {
...user,
dashboardPreferences,
};
}
export async function getUserByEmail(email: User["email"]) {
return prisma.user.findUnique({ where: { email } });
}
export function updateUser({
id,
name,
email,
marketingEmails,
referralSource,
onboardingData,
}: Pick<User, "id" | "name" | "email"> & {
marketingEmails?: boolean;
referralSource?: string;
onboardingData?: Prisma.InputJsonValue;
}) {
return prisma.user.update({
where: { id },
data: {
name,
email,
marketingEmails,
referralSource,
onboardingData,
confirmedBasicDetails: true,
},
});
}
export async function grantUserCloudAccess({ id, inviteCode }: { id: string; inviteCode: string }) {
return prisma.user.update({
where: { id },
data: {
invitationCode: {
connect: {
code: inviteCode,
},
},
},
});
}