Files
webstudio/apps/builder/app/shared/db/user.server.ts
T
Ivan Starkov 3105b5cec0 feat: Make it easy for a self-hosted version to set the plan features (#3475)
## Description

closes #3400 


`+` on dev login its now possible to add any email
like 
`{code}:hello@world.xx` to login as other user


## Steps for reproduction

Login on main with `{code}:ice@yandex.ru`
- See no plan
<img width="213" alt="image"
src="https://github.com/webstudio-is/webstudio/assets/5077042/65f79295-63b3-4d4f-b5d2-ed854f8462e3">

---

Login on main as usual
- See user has plan
<img width="265" alt="image"
src="https://github.com/webstudio-is/webstudio/assets/5077042/db9e1c3e-a8d7-4cde-bbd5-1f39ce7442b8">

---

Login locally
See user has plan

<img width="231" alt="image"
src="https://github.com/webstudio-is/webstudio/assets/5077042/c1187bce-2c7e-49f3-a3ac-bfa15560ccce">




## Code Review

- [ ] hi @kof, I need you to do
  - conceptual review (architecture, feature-correctness)
  - detailed review (read every line)
  - test it on preview

## Before requesting a review

- [ ] made a self-review
- [ ] added inline comments where things may be not obvious (the "why",
not "what")

## Before merging

- [ ] tested locally and on preview environment (preview dev login:
5de6)
- [ ] updated [test
cases](https://github.com/webstudio-is/webstudio/blob/main/apps/builder/docs/test-cases.md)
document
- [ ] added tests
- [ ] if any new env variables are added, added them to `.env.example`
and the `builder/env-check.js` if mandatory
2024-06-02 14:54:19 +03:00

93 lines
1.9 KiB
TypeScript

import type { GitHubProfile } from "remix-auth-github";
import type { GoogleProfile } from "remix-auth-google";
import { prisma } from "@webstudio-is/prisma-client";
import { z } from "zod";
const User = z.object({
id: z.string(),
email: z.string().nullable(),
image: z.string().nullable(),
username: z.string().nullable(),
createdAt: z.date().transform((date) => date.toISOString()),
teamId: z.string().nullable(),
});
export type User = z.infer<typeof User>;
export const getUserById = async (id: User["id"]) => {
const dbUser = await prisma.user.findUnique({
where: { id },
});
return User.parse(dbUser);
};
const genericCreateAccount = async (userData: {
email: string;
username: string;
image: string;
provider: string;
}): Promise<User> => {
const dbUser = await prisma.user.findUnique({
where: {
email: userData.email,
},
});
if (dbUser) {
const user = User.parse(dbUser);
if (user.teamId) {
return user;
}
await prisma.team.create({
data: {
users: {
connect: {
id: user.id,
},
},
},
});
return user;
}
const newTeam = await prisma.team.create({
data: {
users: {
create: userData,
},
},
include: {
users: true,
},
});
return User.parse(newTeam.users[0]);
};
export const createOrLoginWithOAuth = async (
profile: GoogleProfile | GitHubProfile
): Promise<User> => {
const userData = {
email: (profile.emails ?? [])[0]?.value,
username: profile.displayName,
image: (profile.photos ?? [])[0]?.value,
provider: profile.provider,
};
const newUser = await genericCreateAccount(userData);
return newUser;
};
export const createOrLoginWithDev = async (email: string): Promise<User> => {
const userData = {
email,
username: "admin",
image: "",
provider: "dev",
};
const newUser = await genericCreateAccount(userData);
return newUser;
};