mirror of
https://github.com/webstudio-is/webstudio.git
synced 2026-11-08 13:05:08 +09:00
Merge pull request #115 from webstudio-is/fix-login-no-user
Fix error on clone project
This commit is contained in:
10 files changed
+63
-90
No files matched your search
@@ -2,6 +2,7 @@ import { useCallback, useMemo, useState } from "react";
|
||||
import { DndProvider } from "react-dnd";
|
||||
import { TouchBackend } from "react-dnd-touch-backend";
|
||||
import store from "immerhin";
|
||||
import * as db from "~/shared/db";
|
||||
import {
|
||||
type OnChangeChildren,
|
||||
type Data,
|
||||
@@ -41,7 +42,6 @@ import {
|
||||
useHandleBreakpoints,
|
||||
useInitializeBreakpoints,
|
||||
} from "./shared/breakpoints";
|
||||
import type { Project } from "~/shared/db/project.server";
|
||||
import {
|
||||
rootInstanceContainer,
|
||||
useBreakpoints,
|
||||
@@ -102,7 +102,7 @@ const PreviewMode = () => {
|
||||
|
||||
type DesignModeProps = {
|
||||
treeId: Tree["id"];
|
||||
project: Project;
|
||||
project: db.project.Project;
|
||||
};
|
||||
|
||||
const dndOptions = { enableMouseEvents: true };
|
||||
@@ -141,7 +141,7 @@ const DesignMode = ({ treeId, project }: DesignModeProps) => {
|
||||
};
|
||||
|
||||
type CanvasProps = {
|
||||
data: Data & { project: Project };
|
||||
data: Data & { project: db.project.Project };
|
||||
};
|
||||
|
||||
export const Canvas = ({ data }: CanvasProps): JSX.Element | null => {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import useInterval from "react-use/lib/useInterval";
|
||||
import { sync } from "immerhin";
|
||||
import { enqueue } from "./queue";
|
||||
import type { Project } from "~/shared/db/project.server";
|
||||
import * as db from "~/shared/db";
|
||||
|
||||
export const useSync = ({ project }: { project: Project }) => {
|
||||
export const useSync = ({ project }: { project: db.project.Project }) => {
|
||||
useInterval(() => {
|
||||
const entries = sync();
|
||||
if (entries.length === 0) return;
|
||||
|
||||
@@ -2,7 +2,7 @@ import { ActionFunction, redirect } from "@remix-run/node";
|
||||
import config from "~/config";
|
||||
import { authenticator } from "~/services/auth.server";
|
||||
import { sentryException } from "~/shared/sentry";
|
||||
import { ensureUserCookie, AUTH_PROVIDERS } from "~/shared/session";
|
||||
import { AUTH_PROVIDERS } from "~/shared/session";
|
||||
|
||||
export default function GH() {
|
||||
return null;
|
||||
@@ -10,11 +10,7 @@ export default function GH() {
|
||||
|
||||
export const action: ActionFunction = async ({ request }) => {
|
||||
try {
|
||||
const { userId } = await ensureUserCookie(request);
|
||||
return await authenticator.authenticate("github", request, {
|
||||
context: {
|
||||
userId,
|
||||
},
|
||||
successRedirect: config.dashboardPath,
|
||||
throwOnError: true,
|
||||
});
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import { LoaderFunction, redirect } from "@remix-run/node";
|
||||
import config from "~/config";
|
||||
import { authenticator } from "~/services/auth.server";
|
||||
import { ensureUserCookie, AUTH_PROVIDERS } from "~/shared/session";
|
||||
import { AUTH_PROVIDERS } from "~/shared/session";
|
||||
|
||||
export const loader: LoaderFunction = async ({ request }) => {
|
||||
const { userId } = await ensureUserCookie(request);
|
||||
const url = new URL(request.url);
|
||||
const error = url.searchParams.get("error");
|
||||
const error_description = url.searchParams.get("error_description");
|
||||
@@ -16,9 +15,6 @@ export const loader: LoaderFunction = async ({ request }) => {
|
||||
);
|
||||
}
|
||||
return authenticator.authenticate("github", request, {
|
||||
context: {
|
||||
userId,
|
||||
},
|
||||
successRedirect: config.dashboardPath,
|
||||
failureRedirect: config.loginPath,
|
||||
});
|
||||
|
||||
@@ -2,7 +2,7 @@ import { ActionFunction, LoaderFunction, redirect } from "@remix-run/node";
|
||||
import config from "~/config";
|
||||
import { authenticator } from "~/services/auth.server";
|
||||
import { sentryException } from "~/shared/sentry";
|
||||
import { ensureUserCookie, AUTH_PROVIDERS } from "~/shared/session";
|
||||
import { AUTH_PROVIDERS } from "~/shared/session";
|
||||
|
||||
export default function Google() {
|
||||
return null;
|
||||
@@ -12,11 +12,7 @@ export const loader: LoaderFunction = () => redirect("/login");
|
||||
|
||||
export const action: ActionFunction = async ({ request }) => {
|
||||
try {
|
||||
const { userId } = await ensureUserCookie(request);
|
||||
return await authenticator.authenticate("google", request, {
|
||||
context: {
|
||||
userId,
|
||||
},
|
||||
successRedirect: config.dashboardPath,
|
||||
throwOnError: true,
|
||||
});
|
||||
|
||||
@@ -1,15 +1,10 @@
|
||||
import { LoaderFunction } from "@remix-run/node";
|
||||
import config from "~/config";
|
||||
import { authenticator } from "~/services/auth.server";
|
||||
import { ensureUserCookie } from "~/shared/session";
|
||||
|
||||
export const loader: LoaderFunction = async ({ request }) => {
|
||||
const { userId } = await ensureUserCookie(request);
|
||||
return authenticator.authenticate("google", request, {
|
||||
successRedirect: config.dashboardPath,
|
||||
failureRedirect: config.loginPath,
|
||||
context: {
|
||||
userId,
|
||||
},
|
||||
});
|
||||
};
|
||||
@@ -3,7 +3,7 @@ import type { User } from "@webstudio-is/sdk";
|
||||
import * as db from "~/shared/db";
|
||||
import { ensureUserCookie } from "~/shared/session";
|
||||
import config from "~/config";
|
||||
import type { Project } from "~/shared/db/project.server";
|
||||
import { authenticator } from "~/services/auth.server";
|
||||
|
||||
const ensureProject = async ({
|
||||
userId,
|
||||
@@ -11,7 +11,7 @@ const ensureProject = async ({
|
||||
}: {
|
||||
userId: User["id"];
|
||||
domain: string;
|
||||
}): Promise<Project> => {
|
||||
}): Promise<db.project.Project> => {
|
||||
const projects = await db.project.loadManyByUserId(userId);
|
||||
if (projects.length !== 0) return projects[0];
|
||||
|
||||
@@ -28,9 +28,16 @@ const ensureProject = async ({
|
||||
*/
|
||||
export const loader: LoaderFunction = async ({ request, params }) => {
|
||||
if (params.domain === undefined) return { errors: "Domain required" };
|
||||
const { headers, userId } = await ensureUserCookie(request);
|
||||
const user = await authenticator.isAuthenticated(request);
|
||||
const { headers, userId: generatedUserId } = await ensureUserCookie(request);
|
||||
try {
|
||||
const project = await ensureProject({ userId, domain: params.domain });
|
||||
const userId = await db.user.ensureUser({
|
||||
userId: user ? user.id : generatedUserId,
|
||||
});
|
||||
const project = await ensureProject({
|
||||
userId,
|
||||
domain: params.domain,
|
||||
});
|
||||
return redirect(`${config.designerPath}/${project?.id}`, { headers });
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
|
||||
@@ -4,12 +4,8 @@ import { FormStrategy } from "remix-auth-form";
|
||||
import { GitHubStrategy } from "remix-auth-github";
|
||||
import { GoogleStrategy } from "remix-auth-google";
|
||||
import config from "~/config";
|
||||
import * as db from "~/shared/db";
|
||||
import { sessionStorage } from "~/services/session.server";
|
||||
import {
|
||||
createOrLoginWithDev,
|
||||
createOrLoginWithGithub,
|
||||
createOrLoginWithGoogle,
|
||||
} from "~/shared/db/user.server";
|
||||
import { sentryException } from "~/shared/sentry";
|
||||
import { AUTH_PROVIDERS } from "~/shared/session";
|
||||
|
||||
@@ -25,8 +21,8 @@ const github = new GitHubStrategy(
|
||||
clientSecret: process.env.GH_CLIENT_SECRET as string,
|
||||
callbackURL: `${url}${config.githubCallbackPath}`,
|
||||
},
|
||||
async ({ profile, context }) => {
|
||||
const user = await createOrLoginWithGithub(profile, context?.userId);
|
||||
async ({ profile }) => {
|
||||
const user = await db.user.createOrLoginWithGithub(profile);
|
||||
|
||||
return user;
|
||||
}
|
||||
@@ -38,8 +34,8 @@ const google = new GoogleStrategy(
|
||||
clientSecret: process.env.GOOGLE_CLIENT_SECRET as string,
|
||||
callbackURL: `${url}${config.googleCallbackPath}`,
|
||||
},
|
||||
async ({ profile, context }) => {
|
||||
const user = await createOrLoginWithGoogle(profile, context?.userId);
|
||||
async ({ profile }) => {
|
||||
const user = await db.user.createOrLoginWithGoogle(profile);
|
||||
|
||||
return user;
|
||||
}
|
||||
@@ -61,7 +57,7 @@ if (process.env.DEV_LOGIN === "true") {
|
||||
|
||||
if (secret === process.env.AUTH_SECRET) {
|
||||
try {
|
||||
const user = await createOrLoginWithDev(secret);
|
||||
const user = await db.user.createOrLoginWithDev();
|
||||
return user;
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
|
||||
@@ -2,5 +2,6 @@ export * as tree from "./tree.server";
|
||||
export * as project from "./project.server";
|
||||
export * as props from "./props.server";
|
||||
export * as misc from "./misc.server";
|
||||
export * as user from "./user.server";
|
||||
export * from "./canvas.server";
|
||||
export * as breakpoints from "./breakpoints.server";
|
||||
@@ -3,45 +3,40 @@ import { GitHubProfile } from "remix-auth-github";
|
||||
import { GoogleProfile } from "remix-auth-google";
|
||||
import { prisma } from "./prisma.server";
|
||||
|
||||
const genericCreateAccount = async (
|
||||
userData: {
|
||||
email: string;
|
||||
username: string;
|
||||
image: string;
|
||||
provider: string;
|
||||
},
|
||||
userId: string
|
||||
): Promise<User> => {
|
||||
const existingUserWithId = await prisma.user.findUnique({
|
||||
where: {
|
||||
id: userId,
|
||||
},
|
||||
});
|
||||
if (existingUserWithId) {
|
||||
const connectedUser = await prisma.user.update({
|
||||
where: {
|
||||
id: userId,
|
||||
},
|
||||
data: userData,
|
||||
});
|
||||
|
||||
if (connectedUser.teamId) {
|
||||
return connectedUser;
|
||||
}
|
||||
|
||||
await prisma.team.create({
|
||||
data: {
|
||||
users: {
|
||||
connect: {
|
||||
id: connectedUser.id,
|
||||
},
|
||||
export const createDemoUser = async (userId: string) => {
|
||||
await prisma.team.create({
|
||||
data: {
|
||||
users: {
|
||||
create: {
|
||||
id: userId,
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
return connectedUser;
|
||||
export const ensureUser = async ({ userId }: { userId: string }) => {
|
||||
// Always check if the account userId exists because account could have been deleted
|
||||
// or we could be in a demo mode with a generated user
|
||||
const isUserCreated = Boolean(
|
||||
await prisma.user.findUnique({
|
||||
where: { id: userId },
|
||||
})
|
||||
);
|
||||
if (isUserCreated) {
|
||||
return userId;
|
||||
}
|
||||
await createDemoUser(userId);
|
||||
|
||||
return userId;
|
||||
};
|
||||
|
||||
const genericCreateAccount = async (userData: {
|
||||
email: string;
|
||||
username: string;
|
||||
image: string;
|
||||
provider: string;
|
||||
}): Promise<User> => {
|
||||
const existingUserWithEmail = await prisma.user.findUnique({
|
||||
where: {
|
||||
email: userData.email,
|
||||
@@ -68,18 +63,11 @@ const genericCreateAccount = async (
|
||||
const newTeam = await prisma.team.create({
|
||||
data: {
|
||||
users: {
|
||||
create: {
|
||||
id: userId,
|
||||
...userData,
|
||||
},
|
||||
create: userData,
|
||||
},
|
||||
},
|
||||
include: {
|
||||
users: {
|
||||
where: {
|
||||
id: userId,
|
||||
},
|
||||
},
|
||||
users: true,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -87,8 +75,7 @@ const genericCreateAccount = async (
|
||||
};
|
||||
|
||||
export const createOrLoginWithGithub = async (
|
||||
profile: GitHubProfile,
|
||||
userId: string
|
||||
profile: GitHubProfile
|
||||
): Promise<User> => {
|
||||
const userData = {
|
||||
email: profile._json.email,
|
||||
@@ -96,13 +83,12 @@ export const createOrLoginWithGithub = async (
|
||||
image: profile._json.avatar_url,
|
||||
provider: profile.provider,
|
||||
};
|
||||
const newUser = await genericCreateAccount(userData, userId);
|
||||
const newUser = await genericCreateAccount(userData);
|
||||
return newUser;
|
||||
};
|
||||
|
||||
export const createOrLoginWithGoogle = async (
|
||||
profile: GoogleProfile,
|
||||
userId: string
|
||||
profile: GoogleProfile
|
||||
): Promise<User> => {
|
||||
const userData = {
|
||||
email: profile._json.email,
|
||||
@@ -110,11 +96,11 @@ export const createOrLoginWithGoogle = async (
|
||||
image: profile._json.picture,
|
||||
provider: profile.provider,
|
||||
};
|
||||
const newUser = await genericCreateAccount(userData, userId);
|
||||
const newUser = await genericCreateAccount(userData);
|
||||
return newUser;
|
||||
};
|
||||
|
||||
export const createOrLoginWithDev = async (userId: string): Promise<User> => {
|
||||
export const createOrLoginWithDev = async (): Promise<User> => {
|
||||
const userData = {
|
||||
email: "hello@webstudio.is",
|
||||
username: "admin",
|
||||
@@ -122,6 +108,6 @@ export const createOrLoginWithDev = async (userId: string): Promise<User> => {
|
||||
provider: "dev",
|
||||
};
|
||||
|
||||
const newUser = await genericCreateAccount(userData, userId);
|
||||
const newUser = await genericCreateAccount(userData);
|
||||
return newUser;
|
||||
};
|
||||
Reference in new issue
Block a user