-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3 from itsmegood/vite
Vite
- Loading branch information
Showing
45 changed files
with
1,152 additions
and
1,255 deletions.
There are no files selected for viewing
This file contains 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 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 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 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 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 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 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,158 @@ | ||
import { invariant } from '@epic-web/invariant' | ||
import { redirect } from '@remix-run/node' | ||
import { safeRedirect } from 'remix-utils/safe-redirect' | ||
import { twoFAVerificationType } from '#app/routes/settings+/profile.two-factor.tsx' | ||
import { getUserId, sessionKey } from '#app/utils/auth.server.ts' | ||
import { prisma } from '#app/utils/db.server.ts' | ||
import { combineResponseInits } from '#app/utils/misc.tsx' | ||
import { authSessionStorage } from '#app/utils/session.server.ts' | ||
import { redirectWithToast } from '#app/utils/toast.server.ts' | ||
import { verifySessionStorage } from '#app/utils/verification.server.ts' | ||
import { getRedirectToUrl, type VerifyFunctionArgs } from './verify.server.ts' | ||
|
||
const verifiedTimeKey = 'verified-time' | ||
const unverifiedSessionIdKey = 'unverified-session-id' | ||
const rememberKey = 'remember' | ||
|
||
export async function handleNewSession( | ||
{ | ||
request, | ||
session, | ||
redirectTo, | ||
remember, | ||
}: { | ||
request: Request | ||
session: { userId: string; id: string; expirationDate: Date } | ||
redirectTo?: string | ||
remember: boolean | ||
}, | ||
responseInit?: ResponseInit, | ||
) { | ||
const verification = await prisma.verification.findUnique({ | ||
select: { id: true }, | ||
where: { | ||
target_type: { target: session.userId, type: twoFAVerificationType }, | ||
}, | ||
}) | ||
const userHasTwoFactor = Boolean(verification) | ||
|
||
if (userHasTwoFactor) { | ||
const verifySession = await verifySessionStorage.getSession() | ||
verifySession.set(unverifiedSessionIdKey, session.id) | ||
verifySession.set(rememberKey, remember) | ||
const redirectUrl = getRedirectToUrl({ | ||
request, | ||
type: twoFAVerificationType, | ||
target: session.userId, | ||
redirectTo, | ||
}) | ||
return redirect( | ||
`${redirectUrl.pathname}?${redirectUrl.searchParams}`, | ||
combineResponseInits( | ||
{ | ||
headers: { | ||
'set-cookie': | ||
await verifySessionStorage.commitSession(verifySession), | ||
}, | ||
}, | ||
responseInit, | ||
), | ||
) | ||
} else { | ||
const authSession = await authSessionStorage.getSession( | ||
request.headers.get('cookie'), | ||
) | ||
authSession.set(sessionKey, session.id) | ||
|
||
return redirect( | ||
safeRedirect(redirectTo), | ||
combineResponseInits( | ||
{ | ||
headers: { | ||
'set-cookie': await authSessionStorage.commitSession(authSession, { | ||
expires: remember ? session.expirationDate : undefined, | ||
}), | ||
}, | ||
}, | ||
responseInit, | ||
), | ||
) | ||
} | ||
} | ||
|
||
export async function handleVerification({ | ||
request, | ||
submission, | ||
}: VerifyFunctionArgs) { | ||
invariant( | ||
submission.status === 'success', | ||
'Submission should be successful by now', | ||
) | ||
const authSession = await authSessionStorage.getSession( | ||
request.headers.get('cookie'), | ||
) | ||
const verifySession = await verifySessionStorage.getSession( | ||
request.headers.get('cookie'), | ||
) | ||
|
||
const remember = verifySession.get(rememberKey) | ||
const { redirectTo } = submission.value | ||
const headers = new Headers() | ||
authSession.set(verifiedTimeKey, Date.now()) | ||
|
||
const unverifiedSessionId = verifySession.get(unverifiedSessionIdKey) | ||
if (unverifiedSessionId) { | ||
const session = await prisma.session.findUnique({ | ||
select: { expirationDate: true }, | ||
where: { id: unverifiedSessionId }, | ||
}) | ||
if (!session) { | ||
throw await redirectWithToast('/login', { | ||
type: 'error', | ||
title: 'Invalid session', | ||
description: 'Could not find session to verify. Please try again.', | ||
}) | ||
} | ||
authSession.set(sessionKey, unverifiedSessionId) | ||
|
||
headers.append( | ||
'set-cookie', | ||
await authSessionStorage.commitSession(authSession, { | ||
expires: remember ? session.expirationDate : undefined, | ||
}), | ||
) | ||
} else { | ||
headers.append( | ||
'set-cookie', | ||
await authSessionStorage.commitSession(authSession), | ||
) | ||
} | ||
|
||
headers.append( | ||
'set-cookie', | ||
await verifySessionStorage.destroySession(verifySession), | ||
) | ||
|
||
return redirect(safeRedirect(redirectTo), { headers }) | ||
} | ||
|
||
export async function shouldRequestTwoFA(request: Request) { | ||
const authSession = await authSessionStorage.getSession( | ||
request.headers.get('cookie'), | ||
) | ||
const verifySession = await verifySessionStorage.getSession( | ||
request.headers.get('cookie'), | ||
) | ||
if (verifySession.has(unverifiedSessionIdKey)) return true | ||
const userId = await getUserId(request) | ||
if (!userId) return false | ||
// if it's over two hours since they last verified, we should request 2FA again | ||
const userHasTwoFA = await prisma.verification.findUnique({ | ||
select: { id: true }, | ||
where: { target_type: { target: userId, type: twoFAVerificationType } }, | ||
}) | ||
if (!userHasTwoFA) return false | ||
const verifiedTime = authSession.get(verifiedTimeKey) ?? new Date(0) | ||
const twoHours = 1000 * 60 * 2 | ||
return Date.now() - verifiedTime > twoHours | ||
} |
Oops, something went wrong.