From e589e377092858e4e6aa72c517a82dc2a2f3e8ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?So=CC=88nmez=20Kartal?= Date: Thu, 25 May 2023 22:39:16 +0300 Subject: [PATCH] feat(passport): custom domain --- apps/passport/app/auth.server.ts | 10 ++- apps/passport/app/root.tsx | 6 +- apps/passport/app/routes/authorize.tsx | 2 + .../app/routes/connect/apple/callback.ts | 5 +- .../app/routes/connect/discord/callback.ts | 5 +- .../app/routes/connect/github/callback.ts | 5 +- .../app/routes/connect/google/callback.ts | 5 +- .../app/routes/connect/microsoft/callback.ts | 5 +- .../app/routes/connect/twitter/callback.ts | 5 +- .../applications/$clientId/revoke.tsx | 2 +- .../routes/settings/applications/index.tsx | 2 +- apps/passport/app/session.server.ts | 55 +++++++++---- .../passport/app/utils/authenticate.server.ts | 6 +- apps/passport/app/utils/authorize.server.ts | 6 +- apps/passport/app/utils/cookie.ts | 14 ++++ apps/passport/bindings.d.ts | 3 +- apps/passport/server.ts | 82 +++++++++++++------ apps/passport/wrangler.toml | 12 ++- .../src/jsonrpc/methods/getAppPublicProps.ts | 9 ++ .../starbase/src/jsonrpc/validators/app.ts | 6 ++ 20 files changed, 184 insertions(+), 61 deletions(-) create mode 100644 apps/passport/app/utils/cookie.ts diff --git a/apps/passport/app/auth.server.ts b/apps/passport/app/auth.server.ts index 760fdb0c97..cc9652b877 100644 --- a/apps/passport/app/auth.server.ts +++ b/apps/passport/app/auth.server.ts @@ -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: '/', @@ -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') ) diff --git a/apps/passport/app/root.tsx b/apps/passport/app/root.tsx index ddecec874e..7674038313 100644 --- a/apps/passport/app/root.tsx +++ b/apps/passport/app/root.tsx @@ -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 + ), }, } ) diff --git a/apps/passport/app/routes/authorize.tsx b/apps/passport/app/routes/authorize.tsx index aedf00b5ec..c5d31bab7c 100644 --- a/apps/passport/app/routes/authorize.tsx +++ b/apps/passport/app/routes/authorize.tsx @@ -127,6 +127,7 @@ export const loader: LoaderFunction = getRollupReqFunctionErrorWrapper( } await createAuthzParamsCookieAndAuthenticate( + request, context.authzQueryParams, context.env ) @@ -136,6 +137,7 @@ export const loader: LoaderFunction = getRollupReqFunctionErrorWrapper( if (lastCP) { if (!authzParamsMatch(lastCP, context.authzQueryParams)) { await createAuthzParamsCookieAndAuthenticate( + request, context.authzQueryParams, context.env ) diff --git a/apps/passport/app/routes/connect/apple/callback.ts b/apps/passport/app/routes/connect/apple/callback.ts index bd613ddc42..b5c2a12689 100644 --- a/apps/passport/app/routes/connect/apple/callback.ts +++ b/apps/passport/app/routes/connect/apple/callback.ts @@ -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)) diff --git a/apps/passport/app/routes/connect/discord/callback.ts b/apps/passport/app/routes/connect/discord/callback.ts index 549e792f63..8f1c1fb44d 100644 --- a/apps/passport/app/routes/connect/discord/callback.ts +++ b/apps/passport/app/routes/connect/discord/callback.ts @@ -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)) diff --git a/apps/passport/app/routes/connect/github/callback.ts b/apps/passport/app/routes/connect/github/callback.ts index 8bc3212f08..671dbcc383 100644 --- a/apps/passport/app/routes/connect/github/callback.ts +++ b/apps/passport/app/routes/connect/github/callback.ts @@ -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)) diff --git a/apps/passport/app/routes/connect/google/callback.ts b/apps/passport/app/routes/connect/google/callback.ts index b09170a3d7..97f963bbdb 100644 --- a/apps/passport/app/routes/connect/google/callback.ts +++ b/apps/passport/app/routes/connect/google/callback.ts @@ -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)) diff --git a/apps/passport/app/routes/connect/microsoft/callback.ts b/apps/passport/app/routes/connect/microsoft/callback.ts index 9a59690965..ff2429b491 100644 --- a/apps/passport/app/routes/connect/microsoft/callback.ts +++ b/apps/passport/app/routes/connect/microsoft/callback.ts @@ -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)) diff --git a/apps/passport/app/routes/connect/twitter/callback.ts b/apps/passport/app/routes/connect/twitter/callback.ts index a919286356..3078cfca0e 100644 --- a/apps/passport/app/routes/connect/twitter/callback.ts +++ b/apps/passport/app/routes/connect/twitter/callback.ts @@ -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)) diff --git a/apps/passport/app/routes/settings/applications/$clientId/revoke.tsx b/apps/passport/app/routes/settings/applications/$clientId/revoke.tsx index 117c68fff8..30ab894077 100644 --- a/apps/passport/app/routes/settings/applications/$clientId/revoke.tsx +++ b/apps/passport/app/routes/settings/applications/$clientId/revoke.tsx @@ -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), }, }) } diff --git a/apps/passport/app/routes/settings/applications/index.tsx b/apps/passport/app/routes/settings/applications/index.tsx index f4c57a4ba9..70551905a1 100644 --- a/apps/passport/app/routes/settings/applications/index.tsx +++ b/apps/passport/app/routes/settings/applications/index.tsx @@ -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), }, } ) diff --git a/apps/passport/app/session.server.ts b/apps/passport/app/session.server.ts index 510d75d053..d62b9cc356 100644 --- a/apps/passport/app/session.server.ts +++ b/apps/passport/app/session.server.ts @@ -23,6 +23,7 @@ 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', @@ -30,10 +31,10 @@ export const InvalidSessionAccountError = new UnauthorizedError({ // 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', @@ -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*/ @@ -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', @@ -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( @@ -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 '' @@ -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)) @@ -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/ @@ -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', @@ -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() @@ -185,6 +194,7 @@ export async function createAuthzParamsCookieAndAuthenticate( throw redirect(redirectURL, { headers: await createAuthorizationParamsCookieHeaders( + request, authzQueryParams, env ), @@ -192,6 +202,7 @@ export async function createAuthzParamsCookieAndAuthenticate( } export async function createAuthorizationParamsCookieHeaders( + request: Request, authzParams: AuthzParams, env: Env ) { @@ -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 @@ -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')) } @@ -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) } @@ -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 || diff --git a/apps/passport/app/utils/authenticate.server.ts b/apps/passport/app/utils/authenticate.server.ts index b4c1af5dae..3172c4c394 100644 --- a/apps/passport/app/utils/authenticate.server.ts +++ b/apps/passport/app/utils/authenticate.server.ts @@ -79,6 +79,7 @@ export const authenticateAddress = async ( await provisionProfile(accessToken, env, traceSpan, address) return createUserSession( + request, accessToken, getAuthzRedirectURL(appData), env, @@ -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') ) diff --git a/apps/passport/app/utils/authorize.server.ts b/apps/passport/app/utils/authorize.server.ts index f2885961b8..4d97215085 100644 --- a/apps/passport/app/utils/authorize.server.ts +++ b/apps/passport/app/utils/authorize.server.ts @@ -163,6 +163,10 @@ export async function createAuthzParamCookieAndCreate( throw new BadRequestError({ message: 'Invalid create_type' }) } throw redirect(redirectURL, { - headers: await createAuthorizationParamsCookieHeaders(authzParams, env), + headers: await createAuthorizationParamsCookieHeaders( + request, + authzParams, + env + ), }) } diff --git a/apps/passport/app/utils/cookie.ts b/apps/passport/app/utils/cookie.ts new file mode 100644 index 0000000000..0527e0ed71 --- /dev/null +++ b/apps/passport/app/utils/cookie.ts @@ -0,0 +1,14 @@ +import type { Request as CfRequest } from '@cloudflare/workers-types' + +type CfHostMetadata = { + clientId: string +} + +export const getCookieDomain = (request: Request, env: Env): string => { + const host = request.headers.get('host') as string + if (host == env.DEFAULT_HOST) return env.COOKIE_DOMAIN + const cfRequest = request as unknown as CfRequest + const clientId = cfRequest.cf?.hostMetadata.clientId + if (clientId) return host + return env.COOKIE_DOMAIN +} diff --git a/apps/passport/bindings.d.ts b/apps/passport/bindings.d.ts index 5426254a93..a9f96bde43 100644 --- a/apps/passport/bindings.d.ts +++ b/apps/passport/bindings.d.ts @@ -11,9 +11,10 @@ declare global { Starbase: Fetcher Images: Fetcher + DEFAULT_HOST: string + COOKIE_DOMAIN: string SECRET_SESSION_KEY: string SECRET_SESSION_SALT: string - COOKIE_DOMAIN: string PROFILE_APP_URL: string CONSOLE_APP_URL: string PASSPORT_REDIRECT_URL: string diff --git a/apps/passport/server.ts b/apps/passport/server.ts index 4afde0ec8a..318f3f6b25 100644 --- a/apps/passport/server.ts +++ b/apps/passport/server.ts @@ -1,13 +1,21 @@ -import { - generateTraceSpan, - TraceableFetchEvent, -} from '@proofzero/platform-middleware/trace' +import type { Request as CfRequest } from '@cloudflare/workers-types' import { createRequestHandler, handleAsset, } from '@remix-run/cloudflare-workers' import * as build from '@remix-run/dev/server-build' +import createStarbaseClient from '@proofzero/platform-clients/starbase' +import { + generateTraceContextHeaders, + generateTraceSpan, +} from '@proofzero/platform-middleware/trace' +import type { TraceableFetchEvent } from '@proofzero/platform-middleware/trace' + +type CfHostMetadata = { + clientId: string +} + export function parseParams(request: Request) { const url = new URL(request.url) const clientId = url.searchParams.get('client_id') || '' @@ -42,10 +50,12 @@ const requestHandler = createRequestHandler({ build, mode: process.env.NODE_ENV, getLoadContext: (event) => { + const authzQueryParams = parseParams(event.request) + const env = globalThis as unknown as Env const traceSpan = (event as TraceableFetchEvent).traceSpan return { - authzQueryParams: parseParams(event.request), - env: globalThis as unknown as Env, + authzQueryParams, + env, traceSpan, } }, @@ -53,33 +63,55 @@ const requestHandler = createRequestHandler({ const handleEvent = async (event: FetchEvent) => { let response = await handleAsset(event, build) + if (response) return response - if (!response) { - //Create a new trace span with no parent - const newTraceSpan = generateTraceSpan() + //Create a new trace span with no parent + const newTraceSpan = generateTraceSpan() - const reqURL = new URL(event.request.url) - //Have to force injection of new field so it is available in the context setup above - const newEvent = Object.assign(event, { traceSpan: newTraceSpan }) + const reqURL = new URL(event.request.url) + //Have to force injection of new field so it is available in the context setup above + const newEvent = Object.assign(event, { traceSpan: newTraceSpan }) - console.debug( - `Started HTTP handler for ${reqURL.pathname}/${reqURL.searchParams}`, - newTraceSpan.toString() + console.debug( + `Started HTTP handler for ${reqURL.pathname}/${reqURL.searchParams}`, + newTraceSpan.toString() + ) + + const env = globalThis as unknown as Env + const request = event.request as unknown as CfRequest + const host = request.headers.get('host') + if (host != env.DEFAULT_HOST) { + const clientId = request.cf?.hostMetadata?.clientId + if (!clientId) return new Response(null, { status: 404 }) + const starbaseClient = createStarbaseClient( + env.Starbase, + generateTraceContextHeaders(newTraceSpan) ) + try { - response = await requestHandler(newEvent) - } finally { - console.debug( - `Completed HTTP handler ${ - response?.status && response?.status >= 400 && response?.status <= 599 - ? 'with errors ' - : '' - }for ${reqURL.pathname}/${reqURL.searchParams}`, - newTraceSpan.toString() - ) + const app = await starbaseClient.getAppPublicProps.query({ clientId }) + const { customDomain } = app + if (!customDomain) return new Response(null, { status: 404 }) + if (!customDomain.isActive || host !== customDomain?.hostname) + return new Response(null, { status: 404 }) + } catch (error) { + return new Response(null, { status: 500 }) } } + try { + response = await requestHandler(newEvent) + } finally { + console.debug( + `Completed HTTP handler ${ + response?.status && response?.status >= 400 && response?.status <= 599 + ? 'with errors ' + : '' + }for ${reqURL.pathname}/${reqURL.searchParams}`, + newTraceSpan.toString() + ) + } + return response } diff --git a/apps/passport/wrangler.toml b/apps/passport/wrangler.toml index 19e6b66568..5159bb1e25 100644 --- a/apps/passport/wrangler.toml +++ b/apps/passport/wrangler.toml @@ -27,10 +27,11 @@ inspector_port = 11001 local_protocol = "http" [vars] +DEFAULT_HOST = "localhost:10001" +COOKIE_DOMAIN = "localhost" PROFILE_APP_URL = "http://localhost:10003" CONSOLE_APP_URL = "http://localhost:10002" PASSPORT_REDIRECT_URL = "http://localhost:10001/connect/token" -COOKIE_DOMAIN = "localhost" INTERNAL_GOOGLE_OAUTH_CALLBACK_URL = "http://localhost:10001/connect/google/callback" INTERNAL_GITHUB_OAUTH_CALLBACK_URL = "http://localhost:10001/connect/github/callback" INTERNAL_TWITTER_OAUTH_CALLBACK_URL = "http://localhost:10001/connect/twitter/callback" @@ -56,10 +57,11 @@ services = [ ] [env.dev.vars] +DEFAULT_HOST = "passport-dev.rollup.id" +COOKIE_DOMAIN = "rollup.id" PROFILE_APP_URL = "https://my-dev.rollup.id" CONSOLE_APP_URL = "https://console-dev.rollup.id" PASSPORT_REDIRECT_URL = "https://passport-dev.rollup.id/connect/token" -COOKIE_DOMAIN = "rollup.id" INTERNAL_GOOGLE_OAUTH_CALLBACK_URL = "https://passport-dev.rollup.id/connect/google/callback" INTERNAL_GITHUB_OAUTH_CALLBACK_URL = "https://passport-dev.rollup.id/connect/github/callback" INTERNAL_TWITTER_OAUTH_CALLBACK_URL = "https://passport-dev.rollup.id/connect/twitter/callback" @@ -83,10 +85,11 @@ services = [ ] [env.next.vars] +DEFAULT_HOST = "passport-next.rollup.id" +COOKIE_DOMAIN = "rollup.id" PROFILE_APP_URL = "https://my-next.rollup.id" CONSOLE_APP_URL = "https://console-next.rollup.id" PASSPORT_REDIRECT_URL = "https://passport-next.rollup.id/connect/token" -COOKIE_DOMAIN = "rollup.id" INTERNAL_GOOGLE_OAUTH_CALLBACK_URL = "https://passport-next.rollup.id/connect/google/callback" INTERNAL_GITHUB_OAUTH_CALLBACK_URL = "https://passport-next.rollup.id/connect/github/callback" INTERNAL_TWITTER_OAUTH_CALLBACK_URL = "https://passport-next.rollup.id/connect/twitter/callback" @@ -113,10 +116,11 @@ services = [ ] [env.current.vars] +DEFAULT_HOST = "passport.rollup.id" +COOKIE_DOMAIN = "rollup.id" PROFILE_APP_URL = "https://my.rollup.id" CONSOLE_APP_URL = "https://console.rollup.id" PASSPORT_REDIRECT_URL = "https://passport.rollup.id/connect/token" -COOKIE_DOMAIN = "rollup.id" INTERNAL_GOOGLE_OAUTH_CALLBACK_URL = "https://passport.rollup.id/connect/google/callback" INTERNAL_GITHUB_OAUTH_CALLBACK_URL = "https://passport.rollup.id/connect/github/callback" INTERNAL_TWITTER_OAUTH_CALLBACK_URL = "https://passport.rollup.id/connect/twitter/callback" diff --git a/platform/starbase/src/jsonrpc/methods/getAppPublicProps.ts b/platform/starbase/src/jsonrpc/methods/getAppPublicProps.ts index 05a5986237..46681512d6 100644 --- a/platform/starbase/src/jsonrpc/methods/getAppPublicProps.ts +++ b/platform/starbase/src/jsonrpc/methods/getAppPublicProps.ts @@ -2,6 +2,7 @@ import { z } from 'zod' import { Context } from '../context' import { getApplicationNodeByClientId } from '../../nodes/application' import { AppClientIdParamSchema, AppPublicPropsSchema } from '../validators/app' +import type { CustomDomain } from '../../types' export const GetAppPublicPropsInput = AppClientIdParamSchema export const GetAppPublicPropsOutput = AppPublicPropsSchema @@ -21,6 +22,7 @@ export const getAppPublicProps = async ({ ) const appDetails = await appDO.class.getDetails() const appTheme = await appDO.class.getTheme() + const customDomain = await appDO.storage.get('customDomain') if (appDetails && appDetails.app && appDetails.published) { return { @@ -33,6 +35,13 @@ export const getAppPublicProps = async ({ privacyURL: appDetails.app.privacyURL, websiteURL: appDetails.app.websiteURL, appTheme, + customDomain: { + hostname: customDomain?.hostname ?? '', + isActive: + Boolean(customDomain?.hostname) && + customDomain?.status === 'active' && + customDomain?.ssl.status === 'active', + }, } } else { throw new Error( diff --git a/platform/starbase/src/jsonrpc/validators/app.ts b/platform/starbase/src/jsonrpc/validators/app.ts index 5b079d2b10..d41233f10f 100644 --- a/platform/starbase/src/jsonrpc/validators/app.ts +++ b/platform/starbase/src/jsonrpc/validators/app.ts @@ -80,6 +80,12 @@ export const AppPublicPropsSchema = z.object({ privacyURL: z.string().optional(), websiteURL: z.string().optional(), appTheme: AppThemeSchema.optional(), + customDomain: z + .object({ + hostname: z.string(), + isActive: z.boolean(), + }) + .optional(), }) export type AppPublicProps = z.infer