-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
feat(dashboard): login with google and "last used" indicator #2746
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 1 commit
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
c95b0f5
feat(dashboard): login with google and "last used" indicator
ericallam 5523569
a few tweaks via CodeRabbit
ericallam 1bcfd32
Changed login buttons to secondary style
samejr 6deed23
Nicer styling/layout for the last used badge
samejr 9fc1dd8
Moved google svg logo to new component
samejr ddecae4
update existing google user details like email when they already exis…
ericallam 7e50b54
Improved the last used badge position on small screens
samejr 3e1b5e0
handle the case where the google auth conflicts with an existing user…
ericallam 6944207
Add auth info when upserting a user
ericallam 9f84f97
better check for existing emails in the profile info
ericallam File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| import type { LoaderFunction } from "@remix-run/node"; | ||
| import { redirect } from "@remix-run/node"; | ||
| import { prisma } from "~/db.server"; | ||
| import { getSession, redirectWithErrorMessage } from "~/models/message.server"; | ||
| import { authenticator } from "~/services/auth.server"; | ||
| import { setLastAuthMethodHeader } from "~/services/lastAuthMethod.server"; | ||
| import { commitSession } from "~/services/sessionStorage.server"; | ||
| import { redirectCookie } from "./auth.google"; | ||
| import { sanitizeRedirectPath } from "~/utils"; | ||
|
|
||
| export let loader: LoaderFunction = async ({ request }) => { | ||
| const cookie = request.headers.get("Cookie"); | ||
| const redirectValue = await redirectCookie.parse(cookie); | ||
| const redirectTo = sanitizeRedirectPath(redirectValue); | ||
|
|
||
| const auth = await authenticator.authenticate("google", request, { | ||
| failureRedirect: "/login", // If auth fails, the failureRedirect will be thrown as a Response | ||
| }); | ||
|
|
||
| // manually get the session | ||
| const session = await getSession(request.headers.get("cookie")); | ||
|
|
||
| const userRecord = await prisma.user.findFirst({ | ||
| where: { | ||
| id: auth.userId, | ||
| }, | ||
| select: { | ||
| id: true, | ||
| mfaEnabledAt: true, | ||
| }, | ||
| }); | ||
|
|
||
| if (!userRecord) { | ||
| return redirectWithErrorMessage( | ||
| "/login", | ||
| request, | ||
| "Could not find your account. Please contact support." | ||
| ); | ||
| } | ||
|
|
||
| if (userRecord.mfaEnabledAt) { | ||
| session.set("pending-mfa-user-id", userRecord.id); | ||
| session.set("pending-mfa-redirect-to", redirectTo); | ||
|
|
||
| const headers = new Headers(); | ||
| headers.append("Set-Cookie", await commitSession(session)); | ||
| headers.append("Set-Cookie", await setLastAuthMethodHeader("google")); | ||
|
|
||
| return redirect("/login/mfa", { headers }); | ||
| } | ||
|
|
||
| // and store the user data | ||
| session.set(authenticator.sessionKey, auth); | ||
|
|
||
| const headers = new Headers(); | ||
| headers.append("Set-Cookie", await commitSession(session)); | ||
| headers.append("Set-Cookie", await setLastAuthMethodHeader("google")); | ||
|
|
||
| return redirect(redirectTo, { headers }); | ||
| }; | ||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| import { type ActionFunction, type LoaderFunction, redirect, createCookie } from "@remix-run/node"; | ||
| import { authenticator } from "~/services/auth.server"; | ||
|
|
||
| export let loader: LoaderFunction = () => redirect("/login"); | ||
|
|
||
| export let action: ActionFunction = async ({ request }) => { | ||
| const url = new URL(request.url); | ||
| const redirectTo = url.searchParams.get("redirectTo"); | ||
|
|
||
| try { | ||
| // call authenticate as usual, in successRedirect use returnTo or a fallback | ||
| return await authenticator.authenticate("google", request, { | ||
| successRedirect: redirectTo ?? "/", | ||
| failureRedirect: "/login", | ||
| }); | ||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } catch (error) { | ||
| // here we catch anything authenticator.authenticate throw, this will | ||
| // include redirects | ||
| // if the error is a Response and is a redirect | ||
| if (error instanceof Response) { | ||
| // we need to append a Set-Cookie header with a cookie storing the | ||
| // returnTo value | ||
| error.headers.append("Set-Cookie", await redirectCookie.serialize(redirectTo)); | ||
| } | ||
| throw error; | ||
| } | ||
| }; | ||
|
|
||
| export const redirectCookie = createCookie("google-redirect-to", { | ||
| maxAge: 60 * 60, // 1 hour | ||
| httpOnly: true, | ||
| }); | ||
ericallam marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.