From 8ae57d95079f1e8f93a400cf0a9fa8d0dd9aace4 Mon Sep 17 00:00:00 2001 From: Sara Vieira Date: Sat, 25 Jun 2022 16:42:34 +0200 Subject: [PATCH 01/20] add alerts in the case of errors --- app/routes/auth/dev.tsx | 24 ++++++++++---- app/routes/auth/github.tsx | 30 ++++++++++++----- app/routes/auth/google.tsx | 28 +++++++++++----- app/routes/login/index.tsx | 2 ++ app/services/auth.server.ts | 6 ++-- app/shared/session/useLoginErrors.ts | 49 ++++++++++++++++++++++++++++ prisma/schema.prisma | 10 +++++- yarn.lock | 8 ++--- 8 files changed, 126 insertions(+), 31 deletions(-) create mode 100644 app/shared/session/useLoginErrors.ts diff --git a/app/routes/auth/dev.tsx b/app/routes/auth/dev.tsx index 32cbe47da1..2e20c451e1 100644 --- a/app/routes/auth/dev.tsx +++ b/app/routes/auth/dev.tsx @@ -1,14 +1,26 @@ -import { ActionFunction } from "@remix-run/node"; +import { ActionFunction, redirect } from "@remix-run/node"; import config from "~/config"; import { authenticator } from "~/services/auth.server"; +import { LOGIN_ERROR_CODES } from "~/shared/session/useLoginErrors"; export default function Dev() { return null; } -export const action: ActionFunction = ({ request }) => { - return authenticator.authenticate("dev", request, { - successRedirect: config.dashboardPath, - failureRedirect: config.loginPath, - }); +export const action: ActionFunction = async ({ request }) => { + try { + return await authenticator.authenticate("dev", request, { + successRedirect: config.dashboardPath, + throwOnError: true, + }); + } catch (error: any) { + // all redirects are basically errors and in that case we don't want to catch it + if (error instanceof Response) return error; + console.log(error); + return redirect( + `${config.loginPath}?error=${LOGIN_ERROR_CODES.LOGIN_DEV}&message=${ + error?.message || "" + }` + ); + } }; diff --git a/app/routes/auth/github.tsx b/app/routes/auth/github.tsx index eb1ef90951..f6537a7aca 100644 --- a/app/routes/auth/github.tsx +++ b/app/routes/auth/github.tsx @@ -1,19 +1,31 @@ -import { ActionFunction } from "@remix-run/node"; +import { ActionFunction, redirect } from "@remix-run/node"; import config from "~/config"; import { authenticator } from "~/services/auth.server"; import { ensureUserCookie } from "~/shared/session"; +import { LOGIN_ERROR_CODES } from "~/shared/session/useLoginErrors"; export default function GH() { return null; } export const action: ActionFunction = async ({ request }) => { - const { userId } = await ensureUserCookie(request); - return authenticator.authenticate("github", request, { - context: { - userId, - }, - successRedirect: config.dashboardPath, - failureRedirect: config.loginPath, - }); + try { + const { userId } = await ensureUserCookie(request); + return await authenticator.authenticate("github", request, { + context: { + userId, + }, + successRedirect: config.dashboardPath, + throwOnError: true, + }); + } catch (error: any) { + // all redirects are basically errors and in that case we don't want to catch it + if (error instanceof Response) return error; + console.log(error); + return redirect( + `${config.loginPath}?error=${LOGIN_ERROR_CODES.LOGIN_GITHUB}&message=${ + error?.message || "" + }` + ); + } }; diff --git a/app/routes/auth/google.tsx b/app/routes/auth/google.tsx index 06c06a589d..985b6afd82 100644 --- a/app/routes/auth/google.tsx +++ b/app/routes/auth/google.tsx @@ -2,6 +2,7 @@ import { ActionFunction, LoaderFunction, redirect } from "@remix-run/node"; import config from "~/config"; import { authenticator } from "~/services/auth.server"; import { ensureUserCookie } from "~/shared/session"; +import { LOGIN_ERROR_CODES } from "~/shared/session/useLoginErrors"; export default function Google() { return null; @@ -10,12 +11,23 @@ export default function Google() { export const loader: LoaderFunction = () => redirect("/login"); export const action: ActionFunction = async ({ request }) => { - const { userId } = await ensureUserCookie(request); - return authenticator.authenticate("google", request, { - context: { - userId, - }, - successRedirect: config.dashboardPath, - failureRedirect: config.loginPath, - }); + try { + const { userId } = await ensureUserCookie(request); + return await authenticator.authenticate("google", request, { + context: { + userId, + }, + successRedirect: config.dashboardPath, + throwOnError: true, + }); + } catch (error: any) { + // all redirects are basically errors and in that case we don't want to catch it + if (error instanceof Response) return error; + console.log(error); + return redirect( + `${config.loginPath}?error=${LOGIN_ERROR_CODES.LOGIN_GOOGLE}&message=${ + error?.message || "" + }` + ); + } }; diff --git a/app/routes/login/index.tsx b/app/routes/login/index.tsx index 091979a839..697ccd044d 100644 --- a/app/routes/login/index.tsx +++ b/app/routes/login/index.tsx @@ -4,6 +4,7 @@ import { authenticator } from "~/services/auth.server"; import config from "~/config"; import { Login, links } from "~/auth/"; +import { useLoginErrors } from "~/shared/session/useLoginErrors"; export { links }; @@ -17,6 +18,7 @@ export const loader: LoaderFunction = async ({ request }) => { }; const LoginRoute = () => { + useLoginErrors(); return ; }; diff --git a/app/services/auth.server.ts b/app/services/auth.server.ts index eaa9389177..d7f7aaa6cc 100644 --- a/app/services/auth.server.ts +++ b/app/services/auth.server.ts @@ -48,8 +48,8 @@ const google = new GoogleStrategy( export const authenticator = new Authenticator(sessionStorage); if (process.env.GH_CLIENT_ID && process.env.GH_CLIENT_SECRET) { authenticator.use(github, "github"); - authenticator.use(google, "google"); } +authenticator.use(google, "google"); if (process.env.DEV_LOGIN === "true") { authenticator.use( @@ -60,8 +60,8 @@ if (process.env.DEV_LOGIN === "true") { try { const user = await createOrLoginWithDev(secret); return user; - } catch (e) { - console.log(e); + } catch (error: any) { + throw new Error(error); } } diff --git a/app/shared/session/useLoginErrors.ts b/app/shared/session/useLoginErrors.ts new file mode 100644 index 0000000000..93b9d0f227 --- /dev/null +++ b/app/shared/session/useLoginErrors.ts @@ -0,0 +1,49 @@ +import { useEffect } from "react"; +import { useSearchParams } from "react-router-dom"; + +export const LOGIN_ERROR_CODES = { + LOGIN_DEV: "login_dev", + LOGIN_GITHUB: "login_github", + LOGIN_GOOGLE: "login_google", +}; + +export const LOGIN_ERROR_MESSAGES = { + [LOGIN_ERROR_CODES.LOGIN_DEV]: + "There has been an issue logging you in with dev", + [LOGIN_ERROR_CODES.LOGIN_GITHUB]: + "There has been an issue logging you in with Github", + [LOGIN_ERROR_CODES.LOGIN_GOOGLE]: + "There has been an issue logging you in with Google", +}; + +export const useLoginErrors = () => { + const [searchParams, setSearchParams] = useSearchParams(); + const error = searchParams.get("error"); + const message = searchParams.get("message"); + useEffect(() => { + if (error !== null && !!message) { + console.log(message); + alert(message); + + setSearchParams({}); + return; + } + + switch (error) { + case LOGIN_ERROR_CODES.LOGIN_DEV: + alert(LOGIN_ERROR_MESSAGES[LOGIN_ERROR_CODES.LOGIN_DEV]); + break; + case LOGIN_ERROR_CODES.LOGIN_GITHUB: + alert(LOGIN_ERROR_MESSAGES[LOGIN_ERROR_CODES.LOGIN_GITHUB]); + break; + case LOGIN_ERROR_CODES.LOGIN_GOOGLE: + alert(LOGIN_ERROR_MESSAGES[LOGIN_ERROR_CODES.LOGIN_GOOGLE]); + break; + + default: + break; + } + + setSearchParams({}); + }, [error, message, searchParams, setSearchParams]); +}; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 926f331193..c7a5edb888 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -10,6 +10,12 @@ datasource db { url = env("DATABASE_URL") } +model Team { + id String @id @default(uuid()) + users User[] + +} + model User { id String @id @default(uuid()) email String? @unique @@ -17,18 +23,20 @@ model User { image String? username String? createdAt DateTime @default(now()) + Team Team? @relation(fields: [teamId], references: [id]) + teamId String? projects Project[] } model Project { id String @id @default(uuid()) - userId String title String domain String @unique prodTreeId String? // exists when published devTreeId String prodTreeIdHistory String @default("[]") User User? @relation(fields: [userId], references: [id]) + userId String? } model Tree { diff --git a/yarn.lock b/yarn.lock index ada3e74e10..e572c9589a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4374,10 +4374,10 @@ "@webassemblyjs/wast-parser" "1.9.0" "@xtuc/long" "4.2.2" -"@webstudio-is/sdk@0.3.2": - version "0.3.2" - resolved "https://registry.yarnpkg.com/@webstudio-is/sdk/-/sdk-0.3.2.tgz#abb9d9be162511232202125d03bb4b23e551b608" - integrity sha512-+q+PYzCKWq7Me/JQNjBveUHY4vm1rr364pW5FCA1HN00heEQolQJwgg3ION9MKjYfSSaUjny7dPRtb/dV5ETGw== +"@webstudio-is/sdk@0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@webstudio-is/sdk/-/sdk-0.4.0.tgz#dd8f17e2663f6373fcde5c11999f1b3566c40a75" + integrity sha512-Im6vc5v6SIpd8663Y0BWIJLoIm9zxGj4WVo3cDaC5tNJbPuBRMMm5eLIYaFmNApfGimftQqNDasELOViQsEMag== dependencies: "@prisma/client" "^3.10.0" "@stitches/core" "^1.2.7" From 9476f9570170d464fce71394c68f209f30228534 Mon Sep 17 00:00:00 2001 From: Sara Vieira Date: Sat, 25 Jun 2022 16:48:07 +0200 Subject: [PATCH 02/20] fix prisma warnings --- app/auth/login.tsx | 2 +- app/shared/db/prisma.server.ts | 26 ++++++++++++-------------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/app/auth/login.tsx b/app/auth/login.tsx index 1427155342..a3528afe0b 100644 --- a/app/auth/login.tsx +++ b/app/auth/login.tsx @@ -67,7 +67,7 @@ export const Login = () => { minLength={2} required autoFocus - placeholder="Place your AUTH_SECRET" + placeholder="Place your auth secret here" /> ) : ( diff --git a/app/shared/db/prisma.server.ts b/app/shared/db/prisma.server.ts index 97307d82cb..045640bef6 100644 --- a/app/shared/db/prisma.server.ts +++ b/app/shared/db/prisma.server.ts @@ -1,16 +1,14 @@ -import { - PrismaClient, - Prisma, - PrismaClientKnownRequestError, -} from "@webstudio-is/sdk/lib/prisma.server"; +import { PrismaClient, Prisma } from "@prisma/client"; +import { PrismaClientKnownRequestError } from "@prisma/client/runtime"; + +declare global { + // allow global `var` declarations + // eslint-disable-next-line no-var + var prisma: PrismaClient | undefined; +} + +export const prisma = global.prisma || new PrismaClient(); + +if (process.env.NODE_ENV !== "production") global.prisma = prisma; -export const prisma = new PrismaClient(); export { Prisma, PrismaClientKnownRequestError }; - -const main = async () => { - await prisma.$connect(); -}; - -main().catch((error) => { - throw error; -}); From aed24fcc7c45f9ed80a289164852ff26355bef3b Mon Sep 17 00:00:00 2001 From: Sara Vieira Date: Sat, 25 Jun 2022 16:54:07 +0200 Subject: [PATCH 03/20] fix ts --- app/routes/auth/dev.tsx | 15 ++++++++------- app/routes/auth/github.tsx | 16 +++++++++------- app/routes/auth/google.tsx | 16 +++++++++------- app/services/auth.server.ts | 6 ++++-- 4 files changed, 30 insertions(+), 23 deletions(-) diff --git a/app/routes/auth/dev.tsx b/app/routes/auth/dev.tsx index 2e20c451e1..b35442f343 100644 --- a/app/routes/auth/dev.tsx +++ b/app/routes/auth/dev.tsx @@ -13,14 +13,15 @@ export const action: ActionFunction = async ({ request }) => { successRedirect: config.dashboardPath, throwOnError: true, }); - } catch (error: any) { + } catch (error: unknown) { // all redirects are basically errors and in that case we don't want to catch it if (error instanceof Response) return error; - console.log(error); - return redirect( - `${config.loginPath}?error=${LOGIN_ERROR_CODES.LOGIN_DEV}&message=${ - error?.message || "" - }` - ); + if (error instanceof Error) { + return redirect( + `${config.loginPath}?error=${LOGIN_ERROR_CODES.LOGIN_DEV}&message=${ + error?.message || "" + }` + ); + } } }; diff --git a/app/routes/auth/github.tsx b/app/routes/auth/github.tsx index f6537a7aca..7b8486e8f0 100644 --- a/app/routes/auth/github.tsx +++ b/app/routes/auth/github.tsx @@ -18,14 +18,16 @@ export const action: ActionFunction = async ({ request }) => { successRedirect: config.dashboardPath, throwOnError: true, }); - } catch (error: any) { + } catch (error: unknown) { // all redirects are basically errors and in that case we don't want to catch it if (error instanceof Response) return error; - console.log(error); - return redirect( - `${config.loginPath}?error=${LOGIN_ERROR_CODES.LOGIN_GITHUB}&message=${ - error?.message || "" - }` - ); + if (error instanceof Error) { + console.log(error); + return redirect( + `${config.loginPath}?error=${LOGIN_ERROR_CODES.LOGIN_GITHUB}&message=${ + error?.message || "" + }` + ); + } } }; diff --git a/app/routes/auth/google.tsx b/app/routes/auth/google.tsx index 985b6afd82..ccabf94682 100644 --- a/app/routes/auth/google.tsx +++ b/app/routes/auth/google.tsx @@ -20,14 +20,16 @@ export const action: ActionFunction = async ({ request }) => { successRedirect: config.dashboardPath, throwOnError: true, }); - } catch (error: any) { + } catch (error: unknown) { // all redirects are basically errors and in that case we don't want to catch it if (error instanceof Response) return error; - console.log(error); - return redirect( - `${config.loginPath}?error=${LOGIN_ERROR_CODES.LOGIN_GOOGLE}&message=${ - error?.message || "" - }` - ); + if (error instanceof Error) { + console.log(error); + return redirect( + `${config.loginPath}?error=${LOGIN_ERROR_CODES.LOGIN_GOOGLE}&message=${ + error?.message || "" + }` + ); + } } }; diff --git a/app/services/auth.server.ts b/app/services/auth.server.ts index d7f7aaa6cc..57294f428d 100644 --- a/app/services/auth.server.ts +++ b/app/services/auth.server.ts @@ -60,8 +60,10 @@ if (process.env.DEV_LOGIN === "true") { try { const user = await createOrLoginWithDev(secret); return user; - } catch (error: any) { - throw new Error(error); + } catch (error) { + if (error instanceof Error) { + throw new Error(error?.message); + } } } From 5b6ee08a14f70eb40fe812333e2baefdc0904e46 Mon Sep 17 00:00:00 2001 From: Sara Vieira Date: Sat, 25 Jun 2022 16:58:40 +0200 Subject: [PATCH 04/20] add test cases --- docs/test-cases.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/test-cases.md b/docs/test-cases.md index 76fccecf2d..108444c5a7 100644 --- a/docs/test-cases.md +++ b/docs/test-cases.md @@ -57,3 +57,13 @@ - Click on the canvas closes breakpoints selector - Styles added on each breakpoint are only applied to each breakpoint, verify that by resizing the canvas in preview mode - Resizing canvas width in preview mode doesn't limit resize slider to each breakpoint + +1. Auth + - Make sure user is redirected from the dashboard to the login page if not logged in + - Make sure if logged in user is redirected from login to the dashboard + - Ensure login is not required when viewing a built site + - Ensure login is not required when viewing a forked site + - Test dev login with correct auth secret and make sure user is authenticated + - Test dev login with incorrect auth secret to make sure an error is returned + - Test github login and make sure all is working + - Test google login and make sure all is working From 34eb450f3eccd9ed286dc0940c0e3ebbf372aef5 Mon Sep 17 00:00:00 2001 From: Sara Vieira Date: Sat, 25 Jun 2022 17:02:14 +0200 Subject: [PATCH 05/20] make sure to redirect user on github error --- app/routes/auth/github/callback.tsx | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/app/routes/auth/github/callback.tsx b/app/routes/auth/github/callback.tsx index fbbfa77838..4cb72c2afc 100644 --- a/app/routes/auth/github/callback.tsx +++ b/app/routes/auth/github/callback.tsx @@ -1,10 +1,21 @@ -import { LoaderFunction } from "@remix-run/node"; +import { LoaderFunction, redirect } from "@remix-run/node"; import config from "~/config"; import { authenticator } from "~/services/auth.server"; import { ensureUserCookie } from "~/shared/session"; +import { LOGIN_ERROR_CODES } from "~/shared/session/useLoginErrors"; 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"); + if (error) { + return redirect( + `${config.loginPath}?error=${LOGIN_ERROR_CODES.LOGIN_GITHUB}&message=${ + error_description || error + }` + ); + } return authenticator.authenticate("github", request, { context: { userId, From 70d47501a95d933370cd2a2f7f38f0c3f8f4b60b Mon Sep 17 00:00:00 2001 From: Sara Vieira Date: Sat, 25 Jun 2022 19:51:19 +0200 Subject: [PATCH 06/20] add dev login to env example --- .env.example | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.env.example b/.env.example index f170dc77ec..346a8f74da 100644 --- a/.env.example +++ b/.env.example @@ -1,4 +1,5 @@ DATABASE_URL=postgresql://user:pass@localhost/webstudio AUTH_SECRET="# Linux: `openssl rand -hex 32` or go to https://generate-secret.now.sh/32" GH_CLIENT_SECRET= -GH_CLIENT_ID= \ No newline at end of file +GH_CLIENT_ID= +DEV_LOGIN=true \ No newline at end of file From f590e5236735291b7fee242c8729745335ec1b5f Mon Sep 17 00:00:00 2001 From: Sara Vieira Date: Sun, 26 Jun 2022 00:05:41 +0200 Subject: [PATCH 07/20] MR fixes --- app/routes/auth/github/callback.tsx | 4 ++-- app/shared/session/useLoginErrors.ts | 23 +++++++++++------------ 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/app/routes/auth/github/callback.tsx b/app/routes/auth/github/callback.tsx index 4cb72c2afc..5d26e4d19c 100644 --- a/app/routes/auth/github/callback.tsx +++ b/app/routes/auth/github/callback.tsx @@ -2,7 +2,7 @@ import { LoaderFunction, redirect } from "@remix-run/node"; import config from "~/config"; import { authenticator } from "~/services/auth.server"; import { ensureUserCookie } from "~/shared/session"; -import { LOGIN_ERROR_CODES } from "~/shared/session/useLoginErrors"; +import { AUTH_PROVIDERS } from "~/shared/session/useLoginErrors"; export const loader: LoaderFunction = async ({ request }) => { const { userId } = await ensureUserCookie(request); @@ -11,7 +11,7 @@ export const loader: LoaderFunction = async ({ request }) => { const error_description = url.searchParams.get("error_description"); if (error) { return redirect( - `${config.loginPath}?error=${LOGIN_ERROR_CODES.LOGIN_GITHUB}&message=${ + `${config.loginPath}?error=${AUTH_PROVIDERS.LOGIN_GITHUB}&message=${ error_description || error }` ); diff --git a/app/shared/session/useLoginErrors.ts b/app/shared/session/useLoginErrors.ts index 93b9d0f227..e636946546 100644 --- a/app/shared/session/useLoginErrors.ts +++ b/app/shared/session/useLoginErrors.ts @@ -1,18 +1,17 @@ import { useEffect } from "react"; import { useSearchParams } from "react-router-dom"; -export const LOGIN_ERROR_CODES = { +export const AUTH_PROVIDERS = { LOGIN_DEV: "login_dev", LOGIN_GITHUB: "login_github", LOGIN_GOOGLE: "login_google", }; export const LOGIN_ERROR_MESSAGES = { - [LOGIN_ERROR_CODES.LOGIN_DEV]: - "There has been an issue logging you in with dev", - [LOGIN_ERROR_CODES.LOGIN_GITHUB]: + [AUTH_PROVIDERS.LOGIN_DEV]: "There has been an issue logging you in with dev", + [AUTH_PROVIDERS.LOGIN_GITHUB]: "There has been an issue logging you in with Github", - [LOGIN_ERROR_CODES.LOGIN_GOOGLE]: + [AUTH_PROVIDERS.LOGIN_GOOGLE]: "There has been an issue logging you in with Google", }; @@ -21,7 +20,7 @@ export const useLoginErrors = () => { const error = searchParams.get("error"); const message = searchParams.get("message"); useEffect(() => { - if (error !== null && !!message) { + if (error !== null && Boolean(message)) { console.log(message); alert(message); @@ -30,14 +29,14 @@ export const useLoginErrors = () => { } switch (error) { - case LOGIN_ERROR_CODES.LOGIN_DEV: - alert(LOGIN_ERROR_MESSAGES[LOGIN_ERROR_CODES.LOGIN_DEV]); + case AUTH_PROVIDERS.LOGIN_DEV: + alert(LOGIN_ERROR_MESSAGES[AUTH_PROVIDERS.LOGIN_DEV]); break; - case LOGIN_ERROR_CODES.LOGIN_GITHUB: - alert(LOGIN_ERROR_MESSAGES[LOGIN_ERROR_CODES.LOGIN_GITHUB]); + case AUTH_PROVIDERS.LOGIN_GITHUB: + alert(LOGIN_ERROR_MESSAGES[AUTH_PROVIDERS.LOGIN_GITHUB]); break; - case LOGIN_ERROR_CODES.LOGIN_GOOGLE: - alert(LOGIN_ERROR_MESSAGES[LOGIN_ERROR_CODES.LOGIN_GOOGLE]); + case AUTH_PROVIDERS.LOGIN_GOOGLE: + alert(LOGIN_ERROR_MESSAGES[AUTH_PROVIDERS.LOGIN_GOOGLE]); break; default: From 9ced96e609e5fd6b19e26faa2a294798d47eb74a Mon Sep 17 00:00:00 2001 From: Sara Vieira Date: Sun, 26 Jun 2022 01:10:12 +0200 Subject: [PATCH 08/20] fix imports --- app/routes/auth/dev.tsx | 4 ++-- app/routes/auth/github.tsx | 4 ++-- app/routes/auth/google.tsx | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/routes/auth/dev.tsx b/app/routes/auth/dev.tsx index b35442f343..fe018768c4 100644 --- a/app/routes/auth/dev.tsx +++ b/app/routes/auth/dev.tsx @@ -1,7 +1,7 @@ import { ActionFunction, redirect } from "@remix-run/node"; import config from "~/config"; import { authenticator } from "~/services/auth.server"; -import { LOGIN_ERROR_CODES } from "~/shared/session/useLoginErrors"; +import { AUTH_PROVIDERS } from "~/shared/session/useLoginErrors"; export default function Dev() { return null; @@ -18,7 +18,7 @@ export const action: ActionFunction = async ({ request }) => { if (error instanceof Response) return error; if (error instanceof Error) { return redirect( - `${config.loginPath}?error=${LOGIN_ERROR_CODES.LOGIN_DEV}&message=${ + `${config.loginPath}?error=${AUTH_PROVIDERS.LOGIN_DEV}&message=${ error?.message || "" }` ); diff --git a/app/routes/auth/github.tsx b/app/routes/auth/github.tsx index 7b8486e8f0..f49cbdbed7 100644 --- a/app/routes/auth/github.tsx +++ b/app/routes/auth/github.tsx @@ -2,7 +2,7 @@ import { ActionFunction, redirect } from "@remix-run/node"; import config from "~/config"; import { authenticator } from "~/services/auth.server"; import { ensureUserCookie } from "~/shared/session"; -import { LOGIN_ERROR_CODES } from "~/shared/session/useLoginErrors"; +import { AUTH_PROVIDERS } from "~/shared/session/useLoginErrors"; export default function GH() { return null; @@ -24,7 +24,7 @@ export const action: ActionFunction = async ({ request }) => { if (error instanceof Error) { console.log(error); return redirect( - `${config.loginPath}?error=${LOGIN_ERROR_CODES.LOGIN_GITHUB}&message=${ + `${config.loginPath}?error=${AUTH_PROVIDERS.LOGIN_GITHUB}&message=${ error?.message || "" }` ); diff --git a/app/routes/auth/google.tsx b/app/routes/auth/google.tsx index ccabf94682..f6ef060045 100644 --- a/app/routes/auth/google.tsx +++ b/app/routes/auth/google.tsx @@ -2,7 +2,7 @@ import { ActionFunction, LoaderFunction, redirect } from "@remix-run/node"; import config from "~/config"; import { authenticator } from "~/services/auth.server"; import { ensureUserCookie } from "~/shared/session"; -import { LOGIN_ERROR_CODES } from "~/shared/session/useLoginErrors"; +import { AUTH_PROVIDERS } from "~/shared/session/useLoginErrors"; export default function Google() { return null; @@ -26,7 +26,7 @@ export const action: ActionFunction = async ({ request }) => { if (error instanceof Error) { console.log(error); return redirect( - `${config.loginPath}?error=${LOGIN_ERROR_CODES.LOGIN_GOOGLE}&message=${ + `${config.loginPath}?error=${AUTH_PROVIDERS.LOGIN_GOOGLE}&message=${ error?.message || "" }` ); From f3846eecaf2973a62112616685a231aa62f09a96 Mon Sep 17 00:00:00 2001 From: Sara Vieira Date: Sun, 26 Jun 2022 13:56:30 +0200 Subject: [PATCH 09/20] add comment explaning prisma changes --- app/shared/db/prisma.server.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/shared/db/prisma.server.ts b/app/shared/db/prisma.server.ts index 045640bef6..e56bcdb8cf 100644 --- a/app/shared/db/prisma.server.ts +++ b/app/shared/db/prisma.server.ts @@ -7,6 +7,9 @@ declare global { var prisma: PrismaClient | undefined; } +// this fixes the issue with `warn(prisma-client) There are already 10 instances of Prisma Client actively running.` +// explanation here +// https://www.prisma.io/docs/guides/database/troubleshooting-orm/help-articles/nextjs-prisma-client-dev-practices export const prisma = global.prisma || new PrismaClient(); if (process.env.NODE_ENV !== "production") global.prisma = prisma; From 13ca606ec31223eb3785af6a13fafe6a37a05254 Mon Sep 17 00:00:00 2001 From: Sara Vieira Date: Sun, 26 Jun 2022 14:21:00 +0200 Subject: [PATCH 10/20] better error message --- app/services/auth.server.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/auth.server.ts b/app/services/auth.server.ts index 57294f428d..fbe53f571e 100644 --- a/app/services/auth.server.ts +++ b/app/services/auth.server.ts @@ -67,7 +67,7 @@ if (process.env.DEV_LOGIN === "true") { } } - throw new Error("Wrong code"); + throw new Error("The dev login code is incorrect"); }), "dev" ); From c19406ff5628ba4d178f581b21dae2947b7bc59e Mon Sep 17 00:00:00 2001 From: Sara Vieira Date: Sun, 26 Jun 2022 14:25:49 +0200 Subject: [PATCH 11/20] better testing cases --- docs/test-cases.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/test-cases.md b/docs/test-cases.md index 108444c5a7..dc320b84fe 100644 --- a/docs/test-cases.md +++ b/docs/test-cases.md @@ -59,11 +59,11 @@ - Resizing canvas width in preview mode doesn't limit resize slider to each breakpoint 1. Auth - - Make sure user is redirected from the dashboard to the login page if not logged in - - Make sure if logged in user is redirected from login to the dashboard - - Ensure login is not required when viewing a built site - - Ensure login is not required when viewing a forked site - - Test dev login with correct auth secret and make sure user is authenticated - - Test dev login with incorrect auth secret to make sure an error is returned - - Test github login and make sure all is working - - Test google login and make sure all is working + - Try to access the dashboard when not logged in to make sure you will be redirected to the login page + - Open the login page when logged in to make sure you are redirected to the dashboard + - Ensure you can view a built site in an incognito tab + - Ensure you can view a forked site in an incognito tab + - Click on dev login, add the AUTH_SECRET value in the `.env` value and make sure user is authenticated and redirected to the dashboard + - Click on dev login and write a wrong value to make sure you get an error message and stay in the login page. + - Click on login with GitHub and make sure that you are redirected to the dashboard + - Click on login with Google and make sure that you are redirected to the dashboard From c0e603740d643e9d23204840a58d5fbb52a1661a Mon Sep 17 00:00:00 2001 From: Sara Vieira Date: Sun, 26 Jun 2022 14:32:20 +0200 Subject: [PATCH 12/20] don"t catch error and let it go through --- app/services/auth.server.ts | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/app/services/auth.server.ts b/app/services/auth.server.ts index fbe53f571e..09fd2c9ce6 100644 --- a/app/services/auth.server.ts +++ b/app/services/auth.server.ts @@ -57,14 +57,8 @@ if (process.env.DEV_LOGIN === "true") { const secret = form.get("secret"); if (secret === process.env.AUTH_SECRET) { - try { - const user = await createOrLoginWithDev(secret); - return user; - } catch (error) { - if (error instanceof Error) { - throw new Error(error?.message); - } - } + const user = await createOrLoginWithDev(secret); + return user; } throw new Error("The dev login code is incorrect"); From 4892c1257963812239c60596d8ca9fbe65045b4c Mon Sep 17 00:00:00 2001 From: Sara Vieira Date: Tue, 28 Jun 2022 18:59:45 +0200 Subject: [PATCH 13/20] return sentry errors --- app/routes/auth/github.tsx | 8 +++++++- app/routes/auth/google.tsx | 8 +++++++- app/shared/session/useLoginErrors.ts | 5 ++++- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/app/routes/auth/github.tsx b/app/routes/auth/github.tsx index f49cbdbed7..90687739eb 100644 --- a/app/routes/auth/github.tsx +++ b/app/routes/auth/github.tsx @@ -1,6 +1,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 } from "~/shared/session"; import { AUTH_PROVIDERS } from "~/shared/session/useLoginErrors"; @@ -22,7 +23,12 @@ export const action: ActionFunction = async ({ request }) => { // all redirects are basically errors and in that case we don't want to catch it if (error instanceof Response) return error; if (error instanceof Error) { - console.log(error); + sentryException({ + message: error.message, + extra: { + loginMethod: "github", + }, + }); return redirect( `${config.loginPath}?error=${AUTH_PROVIDERS.LOGIN_GITHUB}&message=${ error?.message || "" diff --git a/app/routes/auth/google.tsx b/app/routes/auth/google.tsx index f6ef060045..566bc653c6 100644 --- a/app/routes/auth/google.tsx +++ b/app/routes/auth/google.tsx @@ -1,6 +1,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 } from "~/shared/session"; import { AUTH_PROVIDERS } from "~/shared/session/useLoginErrors"; @@ -24,7 +25,12 @@ export const action: ActionFunction = async ({ request }) => { // all redirects are basically errors and in that case we don't want to catch it if (error instanceof Response) return error; if (error instanceof Error) { - console.log(error); + sentryException({ + message: error.message, + extra: { + loginMethod: "google", + }, + }); return redirect( `${config.loginPath}?error=${AUTH_PROVIDERS.LOGIN_GOOGLE}&message=${ error?.message || "" diff --git a/app/shared/session/useLoginErrors.ts b/app/shared/session/useLoginErrors.ts index e636946546..7cd9042e89 100644 --- a/app/shared/session/useLoginErrors.ts +++ b/app/shared/session/useLoginErrors.ts @@ -1,5 +1,6 @@ import { useEffect } from "react"; import { useSearchParams } from "react-router-dom"; +import { sentryException } from "../sentry"; export const AUTH_PROVIDERS = { LOGIN_DEV: "login_dev", @@ -21,7 +22,9 @@ export const useLoginErrors = () => { const message = searchParams.get("message"); useEffect(() => { if (error !== null && Boolean(message)) { - console.log(message); + sentryException({ + message, + }); alert(message); setSearchParams({}); From 9ff29d23eb6666fa32b98de357e1e746c9a7d1b5 Mon Sep 17 00:00:00 2001 From: Sara Vieira Date: Tue, 28 Jun 2022 19:11:14 +0200 Subject: [PATCH 14/20] show message instead of alert --- app/auth/login.tsx | 19 +++++++++++++++---- app/routes/login/index.tsx | 4 ++-- app/shared/session/useLoginErrors.ts | 19 +++++++++++-------- 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/app/auth/login.tsx b/app/auth/login.tsx index a3528afe0b..853b9f3d73 100644 --- a/app/auth/login.tsx +++ b/app/auth/login.tsx @@ -1,7 +1,14 @@ import { LinksFunction, MetaFunction } from "@remix-run/node"; import { Form, useLoaderData } from "@remix-run/react"; import { useState } from "react"; -import { Button, Card, Flex, Heading, TextField } from "~/shared/design-system"; +import { + Button, + Card, + Flex, + Heading, + Text, + TextField, +} from "~/shared/design-system"; import interStyles from "~/shared/font-faces/inter.css"; import { GoogleIcon, GithubIcon, CommitIcon } from "~/shared/icons"; @@ -24,7 +31,7 @@ export const meta: MetaFunction = () => { return { title: "Webstudio Login" }; }; -export const Login = () => { +export const Login = ({ errorMessage }: { errorMessage: string | null }) => { const [isDevLogin, setIsDevLogin] = useState(false); const loaderData = useLoaderData(); @@ -35,10 +42,14 @@ export const Login = () => { align="center" justify="center" > - + Login - + {errorMessage && ( + + {errorMessage} + + )}