Skip to content
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

feat(passport): custom domain #2330

Merged
merged 1 commit into from
Jun 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions apps/passport/app/auth.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,17 @@ import {
import { TwitterStrategy } from 'remix-auth-twitter'

import { AppleStrategy } from '~/utils/applestrategy.server'
import { getCookieDomain } from './utils/cookie'

// OAuth state

export const createAuthenticatorSessionStorage = (env: Env) => {
export const createAuthenticatorSessionStorage = (
request: Request,
env: Env
) => {
return createCookieSessionStorage({
cookie: {
domain: env.COOKIE_DOMAIN,
domain: getCookieDomain(request, env),
httpOnly: true,
name: 'external_oauth_login',
path: '/',
Expand All @@ -40,7 +44,7 @@ export const injectAuthnParamsIntoSession = async (
request: Request,
env: Env
) => {
const authenticatorStorage = createAuthenticatorSessionStorage(env)
const authenticatorStorage = createAuthenticatorSessionStorage(request, env)
const session = await authenticatorStorage.getSession(
request.headers.get('Cookie')
)
Expand Down
6 changes: 5 additions & 1 deletion apps/passport/app/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,11 @@ export const loader: LoaderFunction = getRollupReqFunctionErrorWrapper(
},
{
headers: {
'Set-Cookie': await commitFlashSession(context.env, flashSession),
'Set-Cookie': await commitFlashSession(
request,
context.env,
flashSession
),
},
}
)
Expand Down
2 changes: 2 additions & 0 deletions apps/passport/app/routes/authorize.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ export const loader: LoaderFunction = getRollupReqFunctionErrorWrapper(
}

await createAuthzParamsCookieAndAuthenticate(
request,
context.authzQueryParams,
context.env
)
Expand All @@ -136,6 +137,7 @@ export const loader: LoaderFunction = getRollupReqFunctionErrorWrapper(
if (lastCP) {
if (!authzParamsMatch(lastCP, context.authzQueryParams)) {
await createAuthzParamsCookieAndAuthenticate(
request,
context.authzQueryParams,
context.env
)
Expand Down
5 changes: 4 additions & 1 deletion apps/passport/app/routes/connect/apple/callback.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ export const loader: LoaderFunction = getRollupReqFunctionErrorWrapper(

const appData = await getAuthzCookieParams(request, context.env)

const authenticatorStorage = createAuthenticatorSessionStorage(context.env)
const authenticatorStorage = createAuthenticatorSessionStorage(
request,
context.env
)
const authenticator = new Authenticator(authenticatorStorage)
authenticator.use(getAppleStrategy(context.env))

Expand Down
5 changes: 4 additions & 1 deletion apps/passport/app/routes/connect/discord/callback.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ export const loader: LoaderFunction = getRollupReqFunctionErrorWrapper(

const appData = await getAuthzCookieParams(request, context.env)

const authenticatorStorage = createAuthenticatorSessionStorage(context.env)
const authenticatorStorage = createAuthenticatorSessionStorage(
request,
context.env
)
const authenticator = new Authenticator(authenticatorStorage)
authenticator.use(getDiscordStrategy(context.env))

Expand Down
5 changes: 4 additions & 1 deletion apps/passport/app/routes/connect/github/callback.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ export const loader: LoaderFunction = getRollupReqFunctionErrorWrapper(

const appData = await getAuthzCookieParams(request, context.env)

const authenticatorSession = createAuthenticatorSessionStorage(context.env)
const authenticatorSession = createAuthenticatorSessionStorage(
request,
context.env
)
const authenticator = new Authenticator(authenticatorSession)
authenticator.use(getGithubAuthenticator(context.env))

Expand Down
5 changes: 4 additions & 1 deletion apps/passport/app/routes/connect/google/callback.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ export const loader: LoaderFunction = getRollupReqFunctionErrorWrapper(

const appData = await getAuthzCookieParams(request, context.env)

const authenticatorStorage = createAuthenticatorSessionStorage(context.env)
const authenticatorStorage = createAuthenticatorSessionStorage(
request,
context.env
)
const authenticator = new Authenticator(authenticatorStorage)
authenticator.use(getGoogleAuthenticator(context.env))

Expand Down
5 changes: 4 additions & 1 deletion apps/passport/app/routes/connect/microsoft/callback.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ export const loader: LoaderFunction = getRollupReqFunctionErrorWrapper(

const appData = await getAuthzCookieParams(request, context.env)

const authenticatorStorage = createAuthenticatorSessionStorage(context.env)
const authenticatorStorage = createAuthenticatorSessionStorage(
request,
context.env
)
const authenticator = new Authenticator(authenticatorStorage)
authenticator.use(getMicrosoftStrategy(context.env))

Expand Down
5 changes: 4 additions & 1 deletion apps/passport/app/routes/connect/twitter/callback.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ export const loader: LoaderFunction = getRollupReqFunctionErrorWrapper(

const appData = await getAuthzCookieParams(request, context.env)

const authenticatorStorage = createAuthenticatorSessionStorage(context.env)
const authenticatorStorage = createAuthenticatorSessionStorage(
request,
context.env
)
const authenticator = new Authenticator(authenticatorStorage)
authenticator.use(getTwitterStrategy(context.env))

Expand Down
7 changes: 6 additions & 1 deletion apps/passport/app/routes/settings.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Outlet, useLoaderData } from '@remix-run/react'

import { json } from '@remix-run/cloudflare'
import { json, redirect } from '@remix-run/cloudflare'
import {
getDefaultAuthzParams,
getValidatedSessionContext,
Expand Down Expand Up @@ -46,6 +46,11 @@ export const links: LinksFunction = () => [

export const loader: LoaderFunction = getRollupReqFunctionErrorWrapper(
async ({ request, context }) => {
const host = request.headers.get('host') as string
if (!context.env.DEFAULT_HOSTS.includes(host)) {
throw redirect('/not-found')
}

const passportDefaultAuthzParams = getDefaultAuthzParams(request)

const { jwt, accountUrn } = await getValidatedSessionContext(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export const action: ActionFunction = getRollupReqFunctionErrorWrapper(

return redirect('/settings/applications', {
headers: {
'Set-Cookie': await commitFlashSession(context.env, session),
'Set-Cookie': await commitFlashSession(request, context.env, session),
},
})
}
Expand Down
2 changes: 1 addition & 1 deletion apps/passport/app/routes/settings/applications/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export const loader: LoaderFunction = getRollupReqFunctionErrorWrapper(
},
{
headers: {
'Set-Cookie': await commitFlashSession(context.env, session),
'Set-Cookie': await commitFlashSession(request, context.env, session),
},
}
)
Expand Down
55 changes: 38 additions & 17 deletions apps/passport/app/session.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,18 @@ import { AccountURNSpace } from '@proofzero/urns/account'
import type { AccountURN } from '@proofzero/urns/account'

import { FLASH_MESSAGE, FLASH_MESSAGE_KEY } from './utils/flashMessage.server'
import { getCookieDomain } from './utils/cookie'

export const InvalidSessionAccountError = new UnauthorizedError({
message: 'Session account is not valid',
})

// FLASH SESSION

const getFlashSessionStorage = (env: Env) => {
const getFlashSessionStorage = (request: Request, env: Env) => {
return createCookieSessionStorage({
cookie: {
domain: env.COOKIE_DOMAIN,
domain: getCookieDomain(request, env),
name: '_rollup_flash',
path: '/',
sameSite: 'lax',
Expand All @@ -46,18 +47,23 @@ const getFlashSessionStorage = (env: Env) => {
}

export function getFlashSession(request: Request, env: Env) {
const storage = getFlashSessionStorage(env)
const storage = getFlashSessionStorage(request, env)
return storage.getSession(request.headers.get('Cookie'))
}

export function commitFlashSession(env: Env, session: Session) {
const storage = getFlashSessionStorage(env)
export function commitFlashSession(
request: Request,
env: Env,
session: Session
) {
const storage = getFlashSessionStorage(request, env)
return storage.commitSession(session)
}

// USER PARAMS

const getUserSessionStorage = (
request: Request,
env: Env,
clientId?: string,
MAX_AGE = 7776000 /*60 * 60 * 24 * 90*/
Expand All @@ -68,7 +74,7 @@ const getUserSessionStorage = (
}

return createCookie(cookieName, {
domain: env.COOKIE_DOMAIN,
domain: getCookieDomain(request, env),
path: '/',
sameSite: 'lax',
secure: process.env.NODE_ENV == 'production',
Expand All @@ -78,12 +84,13 @@ const getUserSessionStorage = (
}

export async function createUserSession(
request: Request,
jwt: string,
redirectTo: string,
env: Env,
clientId?: string
) {
const cookie = getUserSessionStorage(env, clientId)
const cookie = getUserSessionStorage(request, env, clientId)
return redirect(redirectTo, {
headers: {
'Set-Cookie': await cookie.serialize(
Expand All @@ -98,7 +105,7 @@ export async function getUserSession(
env: Env,
clientId?: string
) {
const cookie = getUserSessionStorage(env, clientId)
const cookie = getUserSessionStorage(request, env, clientId)
const data = await cookie.parse(request.headers.get('Cookie'))
if (!data) return ''

Expand All @@ -122,13 +129,13 @@ export async function destroyUserSession(
) {
const headers = new Headers()

const cookie = await getUserSessionStorage(env, clientId)
const cookie = await getUserSessionStorage(request, env, clientId)
headers.append(
'Set-Cookie',
await cookie.serialize('', { expires: new Date(0) })
)

const flashStorage = getFlashSessionStorage(env)
const flashStorage = getFlashSessionStorage(request, env)
const flashSession = await flashStorage.getSession()
flashSession.flash(FLASH_MESSAGE_KEY, flashMessage)
headers.append('Set-Cookie', await flashStorage.commitSession(flashSession))
Expand All @@ -137,6 +144,7 @@ export async function destroyUserSession(
}

const getAuthzCookieParamsSessionStorage = (
request: Request,
env: Env,
clientId: string = 'last',
// https://developer.chrome.com/blog/cookie-max-age-expires/
Expand All @@ -146,7 +154,7 @@ const getAuthzCookieParamsSessionStorage = (
) => {
return createCookieSessionStorage({
cookie: {
domain: env.COOKIE_DOMAIN,
domain: getCookieDomain(request, env),
name: `_rollup_authz_params_${clientId}`,
path: '/',
sameSite: 'lax',
Expand All @@ -162,6 +170,7 @@ const getAuthzCookieParamsSessionStorage = (
* and redirects to the authentication route
*/
export async function createAuthzParamsCookieAndAuthenticate(
request: Request,
authzQueryParams: AuthzParams,
env: Env,
qp: URLSearchParams = new URLSearchParams()
Expand All @@ -185,13 +194,15 @@ export async function createAuthzParamsCookieAndAuthenticate(

throw redirect(redirectURL, {
headers: await createAuthorizationParamsCookieHeaders(
request,
authzQueryParams,
env
),
})
}

export async function createAuthorizationParamsCookieHeaders(
request: Request,
authzParams: AuthzParams,
env: Env
) {
Expand All @@ -204,22 +215,28 @@ export async function createAuthorizationParamsCookieHeaders(
const headers = new Headers()
headers.append(
'Set-Cookie',
await setAuthzCookieParamsSession(authzParams, env, authzParams.clientId)
await setAuthzCookieParamsSession(
request,
authzParams,
env,
authzParams.clientId
)
)
headers.append(
'Set-Cookie',
await setAuthzCookieParamsSession(authzParams, env)
await setAuthzCookieParamsSession(request, authzParams, env)
)

return headers
}

export async function setAuthzCookieParamsSession(
request: Request,
authzParams: AuthzParams,
env: Env,
clientId?: string
) {
const storage = getAuthzCookieParamsSessionStorage(env, clientId)
const storage = getAuthzCookieParamsSessionStorage(request, env, clientId)
const session = await storage.getSession()

//Convert string array scope to space-delimited scope before setting cookie value
Expand All @@ -235,7 +252,7 @@ export async function getAuthzCookieParamsSession(
env: Env,
clientId?: string
) {
const storage = getAuthzCookieParamsSessionStorage(env, clientId)
const storage = getAuthzCookieParamsSessionStorage(request, env, clientId)
return storage.getSession(request.headers.get('Cookie'))
}

Expand All @@ -245,7 +262,7 @@ export async function destroyAuthzCookieParamsSession(
clientId?: string
) {
const gps = await getAuthzCookieParamsSession(request, env, clientId)
const storage = getAuthzCookieParamsSessionStorage(env, clientId)
const storage = getAuthzCookieParamsSessionStorage(request, env, clientId)
return storage.destroySession(gps)
}

Expand Down Expand Up @@ -318,7 +335,11 @@ export async function getValidatedSessionContext(
const redirectTo = `/authenticate/${authzParams?.clientId}`
if (error === InvalidTokenError)
if (authzParams.clientId)
throw await createAuthzParamsCookieAndAuthenticate(authzParams, env)
throw await createAuthzParamsCookieAndAuthenticate(
request,
authzParams,
env
)
else throw redirect(redirectTo)
else if (
error === ExpiredTokenError ||
Expand Down
6 changes: 5 additions & 1 deletion apps/passport/app/utils/authenticate.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ export const authenticateAddress = async (
await provisionProfile(accessToken, env, traceSpan, address)

return createUserSession(
request,
accessToken,
getAuthzRedirectURL(appData),
env,
Expand Down Expand Up @@ -189,7 +190,10 @@ export const checkOAuthError = async (request: Request, env: Env) => {
console.error({ error, uri, description })

const authzParams = await getAuthzCookieParamsSession(request, env)
const authenticatorStorage = await createAuthenticatorSessionStorage(env)
const authenticatorStorage = await createAuthenticatorSessionStorage(
request,
env
)
const session = await authenticatorStorage.getSession(
request.headers.get('Cookie')
)
Expand Down
Loading