@enterprisestandard/react 0.0.3-beta.3 → 0.0.5-beta.20251125.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/enterprise-user.d.ts +2 -0
- package/dist/enterprise-user.d.ts.map +1 -0
- package/dist/iam.d.ts +5 -11
- package/dist/iam.d.ts.map +1 -0
- package/dist/index.d.ts +10 -5
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +599 -160
- package/dist/index.js.map +21 -0
- package/dist/oidc-schema.d.ts +43 -0
- package/dist/oidc-schema.d.ts.map +1 -0
- package/dist/scim-schema.d.ts +356 -0
- package/dist/scim-schema.d.ts.map +1 -0
- package/dist/server.d.ts +1 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/session-store.d.ts +179 -0
- package/dist/session-store.d.ts.map +1 -0
- package/dist/sso.d.ts +30 -15
- package/dist/sso.d.ts.map +1 -0
- package/dist/standard-schema.d.ts +1 -0
- package/dist/standard-schema.d.ts.map +1 -0
- package/dist/ui/sign-in-loading.d.ts +1 -0
- package/dist/ui/sign-in-loading.d.ts.map +1 -0
- package/dist/ui/signed-in.d.ts +1 -0
- package/dist/ui/signed-in.d.ts.map +1 -0
- package/dist/ui/signed-out.d.ts +1 -0
- package/dist/ui/signed-out.d.ts.map +1 -0
- package/dist/ui/sso-provider.d.ts +5 -0
- package/dist/ui/sso-provider.d.ts.map +1 -0
- package/dist/utils.d.ts +1 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/vault.d.ts +4 -3
- package/dist/vault.d.ts.map +1 -0
- package/package.json +14 -7
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/iam.ts", "../src/oidc-schema.ts", "../src/utils.ts", "../src/sso.ts", "../src/vault.ts", "../src/server.ts", "../src/session-store.ts", "../src/ui/sign-in-loading.tsx", "../src/ui/signed-in.tsx", "../src/ui/signed-out.tsx", "../src/ui/sso-provider.tsx", "../src/index.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import type { User } from './scim-schema';\n\nexport type {\n User,\n Name,\n Email,\n PhoneNumber,\n Address,\n Group,\n Role,\n X509Certificate,\n EnterpriseUser,\n} from './scim-schema';\n\nexport { userSchema } from './scim-schema';\n\ntype IAMConfig = {\n // TODO\n};\n\nexport type IAM = {\n // TODO\n};\n\nexport async function iam(config: IAMConfig): Promise<IAM> {\n // TODO configure IAM\n\n return {\n // TODO\n };\n}\n",
|
|
6
|
+
"import type { StandardSchemaV1 } from './standard-schema';\n\n/**\n * OIDC Code Flow Callback URL Parameters\n * @see https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth\n */\nexport interface OidcCallbackParams {\n /**\n * REQUIRED. The authorization code returned from the authorization server.\n */\n code: string;\n\n /**\n * REQUIRED if the \"state\" parameter was present in the client authorization request.\n * The exact value received from the client.\n */\n state?: string;\n\n /**\n * RECOMMENDED. The session state value. Clients should use this to verify the session state.\n */\n session_state?: string;\n\n /**\n * OAuth 2.0 error code if the authorization request failed.\n */\n error?: string;\n\n /**\n * Human-readable ASCII text providing additional information for the error.\n */\n error_description?: string;\n\n /**\n * A URI identifying a human-readable web page with information about the error.\n */\n error_uri?: string;\n\n /**\n * The \"iss\" (issuer) parameter identifies the principal that issued the response.\n * This is typically used in the implicit flow.\n */\n iss?: string;\n}\n\n/**\n * Creates a StandardSchemaV1 for validating OIDC callback URL parameters.\n * @param vendor - The name of the vendor creating this schema\n * @returns A StandardSchemaV1 instance for OIDC callback parameters\n */\nexport function oidcCallbackSchema(vendor: string): StandardSchemaV1<Record<string, unknown>, OidcCallbackParams> {\n return {\n '~standard': {\n version: 1,\n vendor,\n validate: (value: unknown) => {\n if (typeof value !== 'object' || value === null) {\n return {\n issues: [\n {\n message: 'Expected an object',\n },\n ],\n };\n }\n\n const params = value as Record<string, unknown>;\n const issues: StandardSchemaV1.Issue[] = [];\n const result: Partial<OidcCallbackParams> = {};\n\n // Check required 'code' parameter\n if ('code' in params) {\n if (typeof params.code === 'string') {\n result.code = params.code;\n } else {\n issues.push({\n message: 'code must be a string',\n path: ['code'],\n });\n }\n } else if (!('error' in params)) {\n // 'code' is required unless there's an error\n issues.push({\n message: 'code is required',\n path: ['code'],\n });\n }\n\n // Validate state if present\n if ('state' in params) {\n if (typeof params.state === 'string' || params.state === undefined) {\n result.state = params.state as string | undefined;\n } else {\n issues.push({\n message: 'state must be a string',\n path: ['state'],\n });\n }\n }\n\n // Validate session_state if present\n if ('session_state' in params) {\n if (typeof params.session_state === 'string' || params.session_state === undefined) {\n result.session_state = params.session_state as string | undefined;\n } else {\n issues.push({\n message: 'session_state must be a string',\n path: ['session_state'],\n });\n }\n }\n\n // Validate error related fields if present\n if ('error' in params) {\n if (typeof params.error === 'string') {\n result.error = params.error;\n } else {\n issues.push({\n message: 'error must be a string',\n path: ['error'],\n });\n }\n\n if ('error_description' in params) {\n if (typeof params.error_description === 'string' || params.error_description === undefined) {\n result.error_description = params.error_description as string | undefined;\n } else {\n issues.push({\n message: 'error_description must be a string',\n path: ['error_description'],\n });\n }\n }\n\n if ('error_uri' in params) {\n if (typeof params.error_uri === 'string' || params.error_uri === undefined) {\n result.error_uri = params.error_uri as string | undefined;\n } else {\n issues.push({\n message: 'error_uri must be a string',\n path: ['error_uri'],\n });\n }\n }\n }\n\n // Validate iss if present\n if ('iss' in params) {\n if (typeof params.iss === 'string' || params.iss === undefined) {\n result.iss = params.iss as string | undefined;\n } else {\n issues.push({\n message: 'iss must be a string',\n path: ['iss'],\n });\n }\n }\n\n if (issues.length > 0) {\n return { issues };\n }\n\n return { value: result as OidcCallbackParams };\n },\n },\n };\n}\n\n/**\n * Token Response from IdP\n */\nexport interface TokenResponse {\n access_token: string;\n id_token: string;\n refresh_token?: string;\n token_type: string;\n expires_in?: number;\n scope?: string;\n refresh_expires_in?: number;\n session_state?: string;\n expires?: string;\n}\n\n/**\n * Creates a StandardSchemaV1 for validating OIDC Token Responses.\n * @param vendor - The name of the vendor creating this schema\n * @returns A StandardSchemaV1 instance for Token Response validation\n */\nexport function tokenResponseSchema(vendor: string): StandardSchemaV1<Record<string, unknown>, TokenResponse> {\n return {\n '~standard': {\n version: 1,\n vendor,\n validate: (value: unknown) => {\n if (typeof value !== 'object' || value === null) {\n return {\n issues: [\n {\n message: 'Expected an object',\n },\n ],\n };\n }\n\n const response = value as Record<string, unknown>;\n const issues: StandardSchemaV1.Issue[] = [];\n const result: Partial<TokenResponse> = {};\n\n // Check required 'access_token' parameter\n if ('access_token' in response) {\n if (typeof response.access_token === 'string') {\n result.access_token = response.access_token;\n } else {\n issues.push({\n message: 'access_token must be a string',\n path: ['access_token'],\n });\n }\n } else {\n issues.push({\n message: 'access_token is required',\n path: ['access_token'],\n });\n }\n\n // Check required 'id_token' parameter\n if ('id_token' in response) {\n if (typeof response.id_token === 'string') {\n result.id_token = response.id_token;\n } else {\n issues.push({\n message: 'id_token must be a string',\n path: ['id_token'],\n });\n }\n } else {\n issues.push({\n message: 'id_token is required',\n path: ['id_token'],\n });\n }\n\n // Check required 'token_type' parameter\n if ('token_type' in response) {\n if (typeof response.token_type === 'string') {\n result.token_type = response.token_type;\n } else {\n issues.push({\n message: 'token_type must be a string',\n path: ['token_type'],\n });\n }\n } else {\n issues.push({\n message: 'token_type is required',\n path: ['token_type'],\n });\n }\n\n // Optional string fields\n if ('refresh_token' in response) {\n if (typeof response.refresh_token === 'string' || response.refresh_token === undefined) {\n result.refresh_token = response.refresh_token as string | undefined;\n } else {\n issues.push({\n message: 'refresh_token must be a string',\n path: ['refresh_token'],\n });\n }\n }\n\n if ('scope' in response) {\n if (typeof response.scope === 'string' || response.scope === undefined) {\n result.scope = response.scope as string | undefined;\n } else {\n issues.push({\n message: 'scope must be a string',\n path: ['scope'],\n });\n }\n }\n\n if ('session_state' in response) {\n if (typeof response.session_state === 'string' || response.session_state === undefined) {\n result.session_state = response.session_state as string | undefined;\n } else {\n issues.push({\n message: 'session_state must be a string',\n path: ['session_state'],\n });\n }\n }\n\n if ('expires' in response) {\n if (typeof response.expires === 'string' || response.expires === undefined) {\n result.expires = response.expires as string | undefined;\n } else {\n issues.push({\n message: 'expires must be a string',\n path: ['expires'],\n });\n }\n }\n\n // Optional number fields\n if ('expires_in' in response) {\n if (typeof response.expires_in === 'number' || response.expires_in === undefined) {\n result.expires_in = response.expires_in as number | undefined;\n } else {\n issues.push({\n message: 'expires_in must be a number',\n path: ['expires_in'],\n });\n }\n }\n\n if ('refresh_expires_in' in response) {\n if (typeof response.refresh_expires_in === 'number' || response.refresh_expires_in === undefined) {\n result.refresh_expires_in = response.refresh_expires_in as number | undefined;\n } else {\n issues.push({\n message: 'refresh_expires_in must be a number',\n path: ['refresh_expires_in'],\n });\n }\n }\n\n if (issues.length > 0) {\n return { issues };\n }\n\n return { value: result as TokenResponse };\n },\n },\n };\n}\n\n/**\n * ID Token Claims\n */\nexport interface IdTokenClaims {\n iss?: string;\n aud?: string;\n exp?: number;\n iat?: number;\n sub?: string;\n sid?: string;\n name?: string;\n email?: string;\n preferred_username?: string;\n picture?: string;\n [key: string]: unknown;\n}\n\n/**\n * Creates a StandardSchemaV1 for validating ID Token Claims.\n * @param vendor - The name of the vendor creating this schema\n * @returns A StandardSchemaV1 instance for ID Token Claims validation\n */\nexport function idTokenClaimsSchema(vendor: string): StandardSchemaV1<Record<string, unknown>, IdTokenClaims> {\n return {\n '~standard': {\n version: 1,\n vendor,\n validate: (value: unknown) => {\n if (typeof value !== 'object' || value === null) {\n return {\n issues: [\n {\n message: 'Expected an object',\n },\n ],\n };\n }\n\n const claims = value as Record<string, unknown>;\n const issues: StandardSchemaV1.Issue[] = [];\n const result: IdTokenClaims = { ...claims };\n\n // Validate optional string fields\n const stringFields = ['iss', 'aud', 'sub', 'sid', 'name', 'email', 'preferred_username', 'picture'];\n for (const field of stringFields) {\n if (field in claims && claims[field] !== undefined) {\n if (typeof claims[field] !== 'string') {\n issues.push({\n message: `${field} must be a string`,\n path: [field],\n });\n }\n }\n }\n\n // Validate optional number fields\n const numberFields = ['exp', 'iat'];\n for (const field of numberFields) {\n if (field in claims && claims[field] !== undefined) {\n if (typeof claims[field] !== 'number') {\n issues.push({\n message: `${field} must be a number`,\n path: [field],\n });\n }\n }\n }\n\n if (issues.length > 0) {\n return { issues };\n }\n\n return { value: result };\n },\n },\n };\n}\n",
|
|
7
|
+
"import type { EnterpriseStandard } from '.';\n\nlet defaultInstance: EnterpriseStandard | undefined;\n\nexport function must<T>(\n value: T | undefined | null,\n message = 'Assertion failed. Required value is null or undefined.',\n): T {\n if (value === undefined || value === null) {\n throw new Error(message);\n }\n return value;\n}\n\nexport function setDefaultInstance(es: EnterpriseStandard) {\n defaultInstance = es;\n}\n\nexport function getDefaultInstance() {\n return defaultInstance;\n}\n\n/**\n * If an es is defined, then return it, otherwise return the defaultEnterpriseStandard\n */\nexport function getES(es?: EnterpriseStandard) {\n if (es) return es;\n if (defaultInstance) return defaultInstance;\n throw new Error(`TODO standardize the error message when there isn't a default EntepriseStandard`);\n}\n",
|
|
8
|
+
"import type { EnterpriseStandard, EnterpriseUser } from '.';\nimport type { IdTokenClaims, OidcCallbackParams, TokenResponse } from './oidc-schema';\nimport { oidcCallbackSchema, tokenResponseSchema, idTokenClaimsSchema } from './oidc-schema';\nimport type { StandardSchemaV1 } from './standard-schema';\nimport type { Session, SessionStore } from './session-store';\nimport { must } from './utils';\n\nexport type SSOConfig<TSessionData = Record<string, never>> = {\n authority?: string;\n token_url?: string;\n authorization_url?: string;\n client_id?: string;\n redirect_uri?: string;\n response_type?: 'code'; // Future possiblities: 'code' | 'code id_token' | 'code id_token token'\n scope?: string;\n silent_redirect_uri?: string;\n jwks_uri?: string;\n cookies_prefix?: string;\n cookies_path?: string;\n cookies_secure?: boolean;\n cookies_same_site?: 'Strict' | 'Lax';\n end_session_endpoint?: string;\n revocation_endpoint?: string;\n session_store?: SessionStore<TSessionData>;\n};\n\n// TokenResponse now imported from oidc-schema.ts\n\ntype TokenControlFields = {\n token_type: string;\n expires_in?: number;\n scope?: string;\n refresh_expires_in?: number;\n session_state?: string;\n expires?: string;\n};\n\ntype JWK = {\n kty: string;\n kid: string;\n use?: string;\n n?: string;\n e?: string;\n [key: string]: unknown;\n};\n\ntype JWKS = {\n keys: JWK[];\n};\n\ntype SSOConfigWithDefaults<TSessionData = Record<string, never>> = SSOConfig<TSessionData> & {\n authority: string;\n token_url: string;\n authorization_url: string;\n client_id: string;\n redirect_uri: string;\n response_type: 'code'; // Future possiblities: 'code' | 'code id_token' | 'code id_token token'\n scope: string;\n cookies_secure: boolean;\n cookies_same_site: string;\n cookies_prefix: string;\n cookies_path: string;\n};\n\nexport type ESConfig = {\n es?: EnterpriseStandard;\n};\n\nexport type LoginConfig = {\n landingUrl: string;\n errorUrl?: string;\n} & ESConfig;\n\nexport type SSOHandlerConfig = {\n loginUrl?: string;\n userUrl?: string;\n errorUrl?: string;\n landingUrl?: string;\n tokenUrl?: string;\n refreshUrl?: string;\n jwksUrl?: string;\n logoutUrl?: string;\n logoutBackChannelUrl?: string;\n validation?: {\n callbackParams?: StandardSchemaV1<unknown, OidcCallbackParams>;\n idTokenClaims?: StandardSchemaV1<unknown, IdTokenClaims>;\n tokenResponse?: StandardSchemaV1<unknown, TokenResponse>;\n };\n} & ESConfig;\n\nexport type SSO<_TSessionData = Record<string, never>> = {\n getUser: (request: Request) => Promise<EnterpriseUser | undefined>;\n getRequiredUser: (request: Request) => Promise<EnterpriseUser>;\n getJwt: (request: Request) => Promise<string | undefined>;\n initiateLogin: (config: LoginConfig) => Promise<Response>;\n logout: (request: Request, config?: LoginConfig) => Promise<Response>;\n callbackHandler: (request: Request) => Promise<Response>;\n handler: (request: Request, handlerConfig?: SSOHandlerConfig) => Promise<Response>;\n};\n\nconst jwksCache = new Map<string, JWKS>();\n\nexport function sso<TSessionData = Record<string, never>>(config: SSOConfig<TSessionData>): SSO<TSessionData> {\n const configWithDefaults: SSOConfigWithDefaults<TSessionData> = {\n ...config,\n authority: must(config.authority, \"Missing 'authority' from SSO Config\"),\n token_url: must(config.token_url, \"Missing 'token_url' from SSO Config\"),\n authorization_url: must(config.authorization_url, \"Missing 'authorization_url' from SSO Config\"),\n client_id: must(config.client_id, \"Missing 'client_id' from SSO Config\"),\n redirect_uri: must(config.redirect_uri, \"Missing 'redirect_uri' from SSO Config\"),\n scope: must(config.scope, \"Missing 'scope' from SSO Config\"),\n response_type: config.response_type ?? 'code',\n cookies_secure: config.cookies_secure !== undefined ? config.cookies_secure : true,\n cookies_same_site: config.cookies_same_site !== undefined ? config.cookies_same_site : 'Strict',\n cookies_prefix: config.cookies_prefix ?? `es.sso.${config.client_id}`,\n cookies_path: config.cookies_path ?? '/',\n };\n\n async function getUser(request: Request): Promise<EnterpriseUser | undefined> {\n if (!configWithDefaults) {\n console.error('SSO Manager not initialized');\n return undefined;\n }\n\n try {\n const { tokens } = await getTokenFromCookies(request);\n if (!tokens) return undefined;\n return await parseUser(tokens);\n } catch (error) {\n console.error('Error parsing user from cookies:', error);\n return undefined;\n }\n }\n\n async function getRequiredUser(request: Request): Promise<EnterpriseUser> {\n const user = await getUser(request);\n if (user) return user;\n\n throw new Response('Unauthorized', {\n status: 401,\n statusText: 'Unauthorized',\n });\n }\n\n async function initiateLogin({ landingUrl, errorUrl }: LoginConfig) {\n if (!configWithDefaults) {\n console.error('SSO Manager not initialized');\n return Promise.resolve(new Response('SSO Manager not initialized', { status: 503 }));\n }\n\n const state = generateRandomString();\n const codeVerifier = generateRandomString(64);\n\n const url = new URL(configWithDefaults.authorization_url);\n url.searchParams.append('client_id', configWithDefaults.client_id);\n url.searchParams.append('redirect_uri', configWithDefaults.redirect_uri);\n url.searchParams.append('response_type', 'code');\n url.searchParams.append('scope', configWithDefaults.scope);\n url.searchParams.append('state', state);\n\n const codeChallenge = await pkceChallengeFromVerifier(codeVerifier);\n url.searchParams.append('code_challenge', codeChallenge);\n url.searchParams.append('code_challenge_method', 'S256');\n\n const val = {\n state,\n codeVerifier,\n landingUrl,\n errorUrl,\n };\n\n return new Response('Redirecting to SSO Provider', {\n status: 302,\n headers: {\n Location: url.toString(),\n 'Set-Cookie': createCookie('state', val, 86400),\n },\n });\n }\n\n async function logout(request: Request, _config?: LoginConfig) {\n // Try to revoke the refresh token on the server\n try {\n const refreshToken = getCookie('refresh', request);\n if (refreshToken) {\n await revokeToken(refreshToken);\n }\n } catch (error) {\n console.warn('Failed to revoke token:', error);\n }\n\n // Delete session from session store if configured\n if (config.session_store) {\n try {\n const user = await getUser(request);\n if (user?.sso?.profile.sid) {\n const sid = user.sso.profile.sid;\n await config.session_store.delete(sid);\n console.log(`Session ${sid} deleted from store`);\n }\n } catch (error) {\n console.warn('Failed to delete session:', error);\n // Don't fail logout if session deletion fails\n }\n }\n\n // Clear cookies\n const clearHeaders: [string, string][] = [\n ['Set-Cookie', clearCookie('access')],\n ['Set-Cookie', clearCookie('id')],\n ['Set-Cookie', clearCookie('refresh')],\n ['Set-Cookie', clearCookie('control')],\n ['Set-Cookie', clearCookie('state')],\n ];\n\n // Check for redirect query parameter\n const url = new URL(request.url);\n const redirectTo = url.searchParams.get('redirect');\n\n if (redirectTo) {\n return new Response('Logged out', {\n status: 302,\n headers: [['Location', redirectTo], ...clearHeaders],\n });\n }\n\n // Check if this is an AJAX request (expects JSON response)\n const accept = request.headers.get('accept');\n const isAjax = accept?.includes('application/json') || accept?.includes('text/javascript');\n\n if (isAjax) {\n return new Response(JSON.stringify({ success: true, message: 'Logged out' }), {\n status: 200,\n headers: [['Content-Type', 'application/json'], ...clearHeaders],\n });\n } else {\n return new Response(\n `\n <!DOCTYPE html><html lang=\"en\"><body>\n <h1>Logout Complete</h1>\n <div style=\"display: none\">\n It is not recommended to show the default logout page. Include '?redirect=/someHomePage' or logout asynchronously.\n Check the <a href=\"https://EnterpriseStandard.com/sso#logout\">Enterprise Standard Packages</a> for more information.\n </div>\n </body></html>\n `,\n {\n status: 200,\n headers: [['Content-Type', 'text/html'], ...clearHeaders],\n },\n );\n }\n }\n\n async function logoutBackChannel(request: Request) {\n if (!configWithDefaults.session_store) {\n return new Response('Back-Channel Logout requires session_store configuration', {\n status: 400,\n statusText: 'Bad Request',\n });\n }\n\n try {\n // Parse the logout token from the request body\n const contentType = request.headers.get('content-type');\n if (!contentType || !contentType.includes('application/x-www-form-urlencoded')) {\n return new Response('Invalid Content-Type, expected application/x-www-form-urlencoded', {\n status: 400,\n });\n }\n\n const body = await request.text();\n const params = new URLSearchParams(body);\n const logoutToken = params.get('logout_token');\n\n if (!logoutToken) {\n return new Response('Missing logout_token parameter', { status: 400 });\n }\n\n // Parse and verify the logout token JWT\n const claims = await parseJwt(logoutToken);\n\n // Extract sid (session ID) from the logout token\n const sid = claims.sid;\n\n if (!sid) {\n console.warn('Back-Channel Logout: logout_token missing sid claim');\n return new Response('Invalid logout_token: missing sid claim', { status: 400 });\n }\n\n // Delete the session from the store\n await configWithDefaults.session_store.delete(sid);\n\n console.log(`Back-Channel Logout: successfully deleted session ${sid}`);\n\n return new Response('OK', { status: 200 });\n } catch (error) {\n console.error('Error during back-channel logout:', error);\n return new Response('Internal Server Error', { status: 500 });\n }\n }\n\n async function callbackHandler(\n request: Request,\n validation?: SSOHandlerConfig['validation'],\n ) {\n if (!configWithDefaults) {\n console.error('SSO Manager not initialized');\n return Promise.resolve(new Response('SSO Manager not initialized', { status: 503 }));\n }\n\n const url = new URL(request.url);\n const params = new URLSearchParams(url.search);\n\n // Validate callback parameters using StandardSchema\n const callbackParamsValidator = validation?.callbackParams ?? oidcCallbackSchema('builtin');\n const paramsObject = Object.fromEntries(params.entries());\n const paramsResult = await callbackParamsValidator['~standard'].validate(paramsObject);\n\n if ('issues' in paramsResult) {\n return new Response(\n JSON.stringify({\n error: 'validation_failed',\n message: 'OIDC callback parameters validation failed',\n issues: paramsResult.issues?.map((i) => ({\n path: i.path?.join('.'),\n message: i.message,\n })),\n }),\n {\n status: 400,\n headers: { 'Content-Type': 'application/json' },\n },\n );\n }\n\n const { code: codeFromUrl, state: stateFromUrl } = paramsResult.value;\n\n try {\n const cookie = getCookie('state', request, true);\n const { codeVerifier, state, landingUrl } = cookie ?? {};\n\n must(\n codeVerifier,\n 'OIDC \"codeVerifier\" was not present in cookies, ensure that the SSO login was initiated correctly',\n );\n must(state, 'OIDC \"stateVerifier\" was not present in cookies, ensure that the SSO login was initiated correctly');\n must(landingUrl, 'OIDC \"landingUrl\" was not present in cookies');\n\n if (stateFromUrl !== state) {\n throw new Error(\n 'SSO State Verifier failed, the \"state\" request parameter does not equal the \"state\" in the SSO cookie',\n );\n }\n\n const tokenResponse = await exchangeCodeForToken(codeFromUrl, codeVerifier, validation);\n const user = await parseUser(tokenResponse, validation);\n\n // Create session if session_store is configured\n if (config.session_store) {\n try {\n const sid = user.sso.profile.sid;\n const sub = user.id;\n\n if (sid && sub) {\n const session: Session<TSessionData> = {\n sid,\n sub,\n createdAt: new Date(),\n lastActivityAt: new Date(),\n } as Session<TSessionData>;\n\n await config.session_store.create(session);\n } else {\n console.warn('Session creation skipped: missing sid or sub in ID token claims');\n }\n } catch (error) {\n console.warn('Failed to create session:', error);\n // Don't fail the login if session creation fails\n }\n }\n\n return new Response('Authentication successful, redirecting', {\n status: 302,\n headers: [\n ['Location', landingUrl],\n ['Set-Cookie', clearCookie('state')],\n ...createJwtCookies(tokenResponse, user.sso.expires),\n ],\n });\n } catch (error) {\n console.error('Error during sign-in callback:', error);\n\n try {\n const cookie = getCookie('state', request, true);\n const { errorUrl } = cookie ?? {};\n if (errorUrl) {\n return new Response('Redirecting to error url', {\n status: 302,\n headers: [['Location', errorUrl]],\n });\n }\n } catch (_err) {\n console.warn('Error parsing the errorUrl from the OIDC cookie');\n }\n\n console.warn('No error page was found in the cookies. The user will be shown a default error page.');\n return new Response(\n 'An error occurred during authentication, please return to the application homepage and try again.',\n {\n status: 500,\n },\n );\n }\n }\n\n async function parseUser(token: TokenResponse, validation?: SSOHandlerConfig['validation']) {\n if (!configWithDefaults) throw new Error('SSO Manager not initialized');\n\n const idToken = await parseJwt(token.id_token, validation);\n const expiresIn = Number(token.refresh_expires_in ?? token.expires_in ?? 3600);\n const expires = token.expires ? new Date(token.expires) : new Date(Date.now() + expiresIn * 1000);\n\n return {\n id: idToken.sub,\n userName: idToken.preferred_username || '',\n name: idToken.name || '',\n email: idToken.email || '',\n emails: [\n {\n value: idToken.email || '',\n primary: true,\n },\n ],\n avatarUrl: idToken.picture,\n sso: {\n profile: {\n ...idToken,\n iss: idToken.iss || configWithDefaults.authority,\n aud: idToken.aud || configWithDefaults.client_id,\n },\n tenant: {\n id: (idToken.idp as string | undefined) || idToken.iss || configWithDefaults.authority,\n name: idToken.iss || configWithDefaults.authority,\n },\n scope: token.scope,\n tokenType: token.token_type,\n sessionState: token.session_state,\n expires,\n },\n };\n }\n\n async function exchangeCodeForToken(\n code: string,\n codeVerifier: string,\n validation?: SSOHandlerConfig['validation'],\n ): Promise<TokenResponse> {\n if (!configWithDefaults) throw new Error('SSO Manager not initialized');\n const tokenUrl = configWithDefaults.token_url;\n\n const body = new URLSearchParams();\n body.append('grant_type', 'authorization_code');\n body.append('code', code);\n body.append('redirect_uri', configWithDefaults.redirect_uri);\n body.append('client_id', configWithDefaults.client_id);\n body.append('code_verifier', codeVerifier);\n\n try {\n const response = await fetch(tokenUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n Accept: 'application/json',\n },\n body: body.toString(),\n });\n\n const data = await response.json();\n\n if (!response.ok) {\n console.error('Token exchange error:', data);\n throw new Error(\n `Token exchange failed: ${data.error || response.statusText} - ${data.error_description || ''}`.trim(),\n );\n }\n\n // Validate token response using StandardSchema\n const tokenResponseValidator = validation?.tokenResponse ?? tokenResponseSchema('builtin');\n const tokenResult = await tokenResponseValidator['~standard'].validate(data);\n\n if ('issues' in tokenResult) {\n console.error('Token response validation failed:', tokenResult.issues);\n throw new Error(\n `Token response validation failed: ${tokenResult.issues?.map((i) => i.message).join('; ')}`,\n );\n }\n\n return tokenResult.value;\n } catch (error) {\n console.error('Error during token exchange:', error);\n throw error;\n }\n }\n\n async function refreshToken(refreshToken: string): Promise<TokenResponse> {\n return retryWithBackoff(async () => {\n if (!configWithDefaults) throw new Error('SSO Manager not initialized');\n const tokenUrl = configWithDefaults.token_url;\n\n const body = new URLSearchParams();\n body.append('grant_type', 'refresh_token');\n body.append('refresh_token', refreshToken);\n body.append('client_id', configWithDefaults.client_id);\n\n const response = await fetch(tokenUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n Accept: 'application/json',\n },\n body: body.toString(),\n });\n\n const data = await response.json();\n\n if (!response.ok) {\n console.error('Token refresh error:', data);\n throw new Error(\n `Token refresh failed: ${data.error || response.statusText} - ${data.error_description || ''}`.trim(),\n );\n }\n\n return data;\n });\n }\n\n async function revokeToken(token: string): Promise<void> {\n try {\n if (!configWithDefaults) throw new Error('SSO Manager not initialized');\n\n // Only attempt revocation if a revocation endpoint is explicitly configured\n if (!configWithDefaults.revocation_endpoint) {\n return;\n }\n\n const body = new URLSearchParams();\n body.append('token', token);\n body.append('token_type_hint', 'refresh_token');\n body.append('client_id', configWithDefaults.client_id);\n\n const response = await fetch(configWithDefaults.revocation_endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n body: body.toString(),\n });\n\n if (!response.ok) {\n console.warn('Token revocation failed:', response.status, response.statusText);\n } else {\n console.log('Token revoked successfully');\n }\n } catch (error) {\n console.warn('Error revoking token:', error);\n }\n }\n\n async function fetchJwks(): Promise<JWKS> {\n const url = configWithDefaults.jwks_uri || `${configWithDefaults.authority}/protocol/openid-connect/certs`;\n const cached = jwksCache.get(url);\n if (cached) return cached;\n return retryWithBackoff(async () => {\n if (!configWithDefaults) throw new Error('SSO Manager not initialized');\n const response = await fetch(url);\n if (!response.ok) throw new Error('Failed to fetch JWKS');\n const jwks = await response.json();\n jwksCache.set(url, jwks);\n return jwks;\n });\n }\n\n async function retryWithBackoff<T>(\n operation: () => Promise<T>,\n maxRetries: number = 3,\n baseDelay: number = 1000,\n maxDelay: number = 30000,\n ): Promise<T> {\n let lastError = new Error('Placeholder Error');\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n return await operation();\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n\n // Don't retry on authentication errors (4xx) or client errors\n if (error instanceof Error && error.message.includes('400')) {\n throw error;\n }\n\n if (attempt === maxRetries) {\n throw lastError;\n }\n\n // Exponential backoff with jitter\n const delay = Math.min(baseDelay * 2 ** attempt, maxDelay);\n const jitter = Math.random() * 0.1 * delay;\n await new Promise((resolve) => setTimeout(resolve, delay + jitter));\n\n console.warn(`Retry attempt ${attempt + 1} after ${delay + jitter}ms delay`);\n }\n }\n\n throw lastError;\n }\n\n async function parseJwt(token: string, validation?: SSOHandlerConfig['validation']): Promise<IdTokenClaims> {\n try {\n const parts = token.split('.');\n if (parts.length !== 3) throw new Error('Invalid JWT');\n\n const header = JSON.parse(atob(parts[0].replace(/-/g, '+').replace(/_/g, '/')));\n const payload = JSON.parse(atob(parts[1].replace(/-/g, '+').replace(/_/g, '/')));\n const signature = parts[2].replace(/-/g, '+').replace(/_/g, '/');\n const publicKey = await getPublicKey(header.kid);\n const encoder = new TextEncoder();\n const data = encoder.encode(`${parts[0]}.${parts[1]}`);\n const isValid = await crypto.subtle.verify(\n 'RSASSA-PKCS1-v1_5',\n publicKey,\n Uint8Array.from(atob(signature), (c) => c.charCodeAt(0)),\n data,\n );\n if (!isValid) throw new Error('Invalid JWT signature');\n\n // Validate ID token claims using StandardSchema\n const idTokenClaimsValidator = validation?.idTokenClaims ?? idTokenClaimsSchema('builtin');\n const claimsResult = await idTokenClaimsValidator['~standard'].validate(payload);\n\n if ('issues' in claimsResult) {\n console.error('ID token claims validation failed:', claimsResult.issues);\n throw new Error(\n `ID token claims validation failed: ${claimsResult.issues?.map((i) => i.message).join('; ')}`,\n );\n }\n\n return claimsResult.value;\n } catch (e) {\n console.error('Error verifying JWT:', e);\n throw e;\n }\n }\n\n function generateRandomString(length = 32): string {\n const array = new Uint8Array(length);\n crypto.getRandomValues(array);\n return Array.from(array, (byte) => byte.toString(16).padStart(2, '0'))\n .join('')\n .substring(0, length);\n }\n\n async function pkceChallengeFromVerifier(verifier: string): Promise<string> {\n const encoder = new TextEncoder();\n const data = encoder.encode(verifier);\n const hashBuffer = await crypto.subtle.digest('SHA-256', data);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n const hashBase64 = btoa(String.fromCharCode(...hashArray))\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_')\n .replace(/=+$/, '');\n return hashBase64;\n }\n\n async function getPublicKey(kid: string): Promise<CryptoKey> {\n const jwks = await fetchJwks();\n const key = jwks.keys.find((k: JWK) => k.kid === kid);\n if (!key) throw new Error('Public key not found');\n const publicKey = await crypto.subtle.importKey(\n 'jwk',\n {\n kty: key.kty,\n n: key.n,\n e: key.e,\n },\n { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA-256' },\n false,\n ['verify'],\n );\n return publicKey;\n }\n\n function createJwtCookies(token: TokenResponse, expires: Date): [string, string][] {\n const control: TokenControlFields = {\n expires_in: token.expires_in,\n refresh_expires_in: token.refresh_expires_in,\n scope: token.scope,\n session_state: token.session_state,\n token_type: token.token_type,\n expires: expires.toISOString(),\n };\n return [\n ['Set-Cookie', createCookie('access', token.access_token, expires)],\n ['Set-Cookie', createCookie('id', token.id_token, expires)],\n ['Set-Cookie', createCookie('refresh', token.refresh_token ?? '', expires)],\n ['Set-Cookie', createCookie('control', control, expires)],\n ];\n }\n\n async function getTokenFromCookies(req: Request): Promise<{\n tokens: TokenResponse | undefined;\n refreshHeaders: [string, string][];\n }> {\n const access_token = getCookie('access', req);\n const id_token = getCookie('id', req);\n const refresh_token = getCookie('refresh', req);\n const control: TokenControlFields = getCookie('control', req, true);\n\n if (!access_token || !id_token || !refresh_token || !control) {\n return { tokens: undefined, refreshHeaders: [] };\n }\n\n let tokenResponse: TokenResponse = {\n access_token,\n id_token,\n refresh_token,\n ...control,\n };\n\n // Check if access token is expired\n if (control.expires && refresh_token && Date.now() > new Date(control.expires).getTime()) {\n tokenResponse = await refreshToken(refresh_token);\n\n // Create new cookies with refreshed tokens\n const user = await parseUser(tokenResponse);\n const refreshHeaders = createJwtCookies(tokenResponse, user.sso.expires);\n\n return { tokens: tokenResponse, refreshHeaders };\n }\n\n return { tokens: tokenResponse, refreshHeaders: [] };\n }\n\n async function getJwt(request: Request): Promise<string | undefined> {\n const { tokens } = await getTokenFromCookies(request);\n if (!tokens) return undefined;\n return tokens.access_token;\n }\n\n function createCookie(name: string, value: Record<string, unknown> | string, expires: Date | number) {\n name = `${configWithDefaults.cookies_prefix}.${name}`;\n if (typeof value !== 'string') {\n value = btoa(JSON.stringify(value));\n }\n\n let exp: string;\n if (expires instanceof Date) {\n exp = `Expires=${expires.toUTCString()}`;\n } else if (typeof expires === 'number') {\n exp = `Max-Age=${expires}`;\n } else {\n throw new Error('Invalid expires type', expires);\n }\n\n if (value.length > 4000) {\n throw new Error(`Error setting cookie: ${name}. Cookie length is: ${value.length}`);\n }\n\n return `${name}=${value}; ${exp}; Path=${configWithDefaults.cookies_path}; HttpOnly;${configWithDefaults.cookies_secure ? ' Secure;' : ''} SameSite=${configWithDefaults.cookies_same_site};`;\n }\n\n function clearCookie(name: string) {\n return `${configWithDefaults.cookies_prefix}.${name}=; Max-Age=0; Path=${configWithDefaults.cookies_path}; HttpOnly;${configWithDefaults.cookies_secure ? ' Secure;' : ''} SameSite=${configWithDefaults.cookies_same_site};`;\n }\n\n function getCookie(name: string, req: Request, parse = false) {\n const header = req.headers.get('cookie');\n if (!header) return null;\n\n const cookie = header\n .split(';')\n .find((row) => row.trim().startsWith(`${configWithDefaults.cookies_prefix}.${name}=`));\n if (!cookie) return null;\n\n const val = cookie.split('=')[1].trim();\n if (!parse) return val;\n const str = atob(val);\n return JSON.parse(str);\n }\n\n async function handler(request: Request, handlerConfig?: SSOHandlerConfig) {\n const { loginUrl, userUrl, errorUrl, landingUrl, tokenUrl, refreshUrl, logoutUrl, logoutBackChannelUrl, jwksUrl, validation } =\n handlerConfig ?? {};\n if (!loginUrl) {\n console.error('loginUrl is required');\n }\n\n const path = new URL(request.url).pathname;\n if (new URL(configWithDefaults.redirect_uri).pathname === path) {\n return callbackHandler(request, validation);\n }\n\n if (loginUrl === path) {\n return initiateLogin({\n landingUrl: landingUrl || '/',\n errorUrl,\n });\n }\n\n if (userUrl === path) {\n const { tokens, refreshHeaders } = await getTokenFromCookies(request);\n if (!tokens) {\n return new Response('User not logged in', { status: 401 });\n }\n const user = await parseUser(tokens);\n return new Response(JSON.stringify(user), {\n headers: [['Content-Type', 'application/json'], ...refreshHeaders],\n });\n }\n\n if (tokenUrl === path) {\n const { tokens, refreshHeaders } = await getTokenFromCookies(request);\n if (!tokens) {\n return new Response('User not logged in', { status: 401 });\n }\n return new Response(\n JSON.stringify({\n token: tokens.access_token,\n expires: tokens.expires,\n }),\n {\n headers: [['Content-Type', 'application/json'], ...refreshHeaders],\n },\n );\n }\n\n if (refreshUrl === path) {\n const refresh_token = getCookie('refresh', request);\n if (!refresh_token) {\n return new Response('User not logged in', { status: 401 });\n }\n\n // Force a token refresh\n const newTokenResponse = await refreshToken(refresh_token);\n const user = await parseUser(newTokenResponse);\n const refreshHeaders = createJwtCookies(newTokenResponse, user.sso.expires);\n\n return new Response('Refresh Complete', {\n status: 200,\n headers: refreshHeaders,\n });\n }\n\n if (logoutUrl === path) {\n return logout(request, { landingUrl: landingUrl || '/' });\n }\n\n if (logoutBackChannelUrl === path) {\n return logoutBackChannel(request);\n }\n\n if (jwksUrl === path) {\n const jwks = await fetchJwks();\n return new Response(JSON.stringify(jwks), {\n headers: [['Content-Type', 'application/json']],\n });\n }\n\n return new Response('Not Found', { status: 404 });\n }\n\n return {\n getUser,\n getRequiredUser,\n getJwt,\n initiateLogin,\n logout,\n callbackHandler,\n handler,\n };\n}\n",
|
|
9
|
+
"type Secret<T> = {\n data: T;\n metadata: MetaData;\n};\n\ntype MetaData = {\n created_time: string;\n deletion_time: string;\n destroyed: boolean;\n version: number;\n};\n\nexport type Vault = {\n url: string;\n getFullSecret: <T>(path: string, token: string) => Promise<Secret<T>>;\n getSecret: <T>(path: string, token: string) => Promise<T>;\n};\n\nexport function vault(url: string): Vault {\n async function getFullSecret<T>(path: string, token: string): Promise<Secret<T>> {\n const resp = await fetch(`${url}/${path}`, { headers: { 'X-Vault-Token': token } });\n if (resp.status !== 200) {\n throw new Error(`Vault returned invalid status, ${resp.status}: '${resp.statusText}' from URL: ${url}`);\n }\n try {\n const secret = await resp.json();\n return secret.data as Secret<T>;\n } catch (cause) {\n throw new Error('Error retrieving secret', { cause });\n }\n }\n\n return {\n url,\n getFullSecret,\n getSecret: async <T>(path: string, token: string): Promise<T> => {\n return (await getFullSecret(path, token)).data as T;\n },\n };\n}\n",
|
|
10
|
+
"import type { ESConfig, LoginConfig, SSOHandlerConfig } from './sso';\nimport { getES } from './utils';\n\nfunction getSSO(config?: ESConfig) {\n const es = getES(config?.es);\n if (!es.sso) {\n console.error('TODO tell them how to connect SSO');\n return undefined;\n }\n return es.sso;\n}\n\nfunction unavailable() {\n new Response(JSON.stringify({ error: 'SSO Unavailable' }), {\n status: 503,\n statusText: 'SSO Unavailable',\n headers: { 'Content-Type': 'application/json' },\n });\n}\n\nexport async function getUser(request: Request, config?: ESConfig) {\n return getSSO(config)?.getUser(request);\n}\n\nexport async function getRequiredUser(request: Request, config?: ESConfig) {\n const sso = getSSO(config);\n if (!sso) throw unavailable();\n return sso.getRequiredUser(request);\n}\n\nexport async function initiateLogin(config: LoginConfig) {\n const sso = getSSO(config);\n if (!sso) throw unavailable();\n return sso.initiateLogin(config);\n}\n\nexport async function callback(request: Request, config?: ESConfig) {\n const sso = getSSO(config);\n if (!sso) throw unavailable();\n return sso.callbackHandler(request);\n}\n\nexport async function handler(request: Request, config?: SSOHandlerConfig) {\n const sso = getSSO(config);\n if (!sso) throw unavailable();\n return sso.handler(request, config);\n}\n",
|
|
11
|
+
"/**\n * Session management for tracking user sessions and enabling backchannel logout.\n *\n * Session stores are optional - the package works with JWT cookies alone.\n * Sessions are only required for backchannel logout functionality.\n *\n * ## Session Validation Strategies\n *\n * When using a session store, you can configure when sessions are validated:\n *\n * ### 'always' (default)\n * Validates session on every authenticated request.\n * - **Security**: Maximum - immediate session revocation\n * - **Performance**: InMemory ~0.00005ms, Redis ~1-2ms per request\n * - **Backchannel Logout**: Takes effect immediately\n * - **Use when**: Security is paramount, using InMemory or Redis backend\n *\n * ### 'refresh-only'\n * Validates session only during token refresh (typically every 5-15 minutes).\n * - **Security**: Good - 5-15 minute revocation window\n * - **Performance**: 99% reduction in session lookups\n * - **Backchannel Logout**: Takes effect within token TTL (5-15 min)\n * - **Use when**: Performance is critical AND delayed revocation is acceptable\n * - **WARNING**: Compromised sessions remain valid until next refresh\n *\n * ### 'disabled'\n * Never validates sessions against the store.\n * - **Security**: None - backchannel logout doesn't work\n * - **Performance**: No overhead\n * - **Use when**: Cookie-only mode without session store\n * - **WARNING**: Do not use with session_store configured\n *\n * ## Performance Characteristics\n *\n * | Backend | Lookup Time | Impact on Request | Recommendation |\n * |--------------|-------------|-------------------|------------------------|\n * | InMemory | <0.00005ms | Negligible | Use 'always' |\n * | Redis | 1-2ms | 2-4% increase | Use 'always' or test |\n * | Database | 5-20ms | 10-40% increase | Use Redis cache layer |\n *\n * ## Example Usage\n *\n * ```typescript\n * import { sso, InMemorySessionStore } from '@enterprisestandard/react/server';\n *\n * // Maximum security (default)\n * const secure = sso({\n * // ... other config\n * session_store: new InMemorySessionStore(),\n * session_validation: 'always', // Immediate revocation\n * });\n *\n * // High performance\n * const fast = sso({\n * // ... other config\n * session_store: new InMemorySessionStore(),\n * session_validation: {\n * strategy: 'refresh-only' // 5-15 min revocation delay\n * }\n * });\n * ```\n */\n\n/**\n * Core session data tracked for each authenticated user session.\n *\n * @template TExtended - Type-safe custom data that consumers can add to sessions\n */\nexport type Session<TExtended = Record<string, never>> = {\n /**\n * Session ID from the Identity Provider (from `sid` claim in ID token).\n * This is the unique identifier for the session.\n */\n sid: string;\n\n /**\n * Subject identifier (user ID) from the Identity Provider.\n * From the `sub` claim in the ID token.\n */\n sub: string;\n\n /**\n * Timestamp when the session was created.\n */\n createdAt: Date;\n\n /**\n * Timestamp of the last activity in this session.\n * Can be updated to track session activity.\n */\n lastActivityAt: Date;\n\n /**\n * Allow consumers to add runtime data to sessions.\n */\n [key: string]: unknown;\n} & TExtended;\n\n/**\n * Abstract interface for session storage backends.\n *\n * Consumers can implement this interface to use different storage backends:\n * - Redis\n * - Database (PostgreSQL, MySQL, etc.)\n * - Distributed cache\n * - Custom solutions\n *\n * @template TExtended - Type-safe custom data that consumers can add to sessions\n *\n * @example\n * ```typescript\n * // Custom session data\n * type MySessionData = {\n * ipAddress: string;\n * userAgent: string;\n * };\n *\n * // Implement custom store\n * class RedisSessionStore implements SessionStore<MySessionData> {\n * async create(session: Session<MySessionData>): Promise<void> {\n * await redis.set(`session:${session.sid}`, JSON.stringify(session));\n * }\n * // ... other methods\n * }\n * ```\n */\nexport interface SessionStore<TExtended = Record<string, never>> {\n /**\n * Create a new session in the store.\n *\n * @param session - The session data to store\n * @throws Error if session with same sid already exists\n */\n create(session: Session<TExtended>): Promise<void>;\n\n /**\n * Retrieve a session by its IdP session ID (sid).\n *\n * @param sid - The session.sid from the Identity Provider\n * @returns The session if found, null otherwise\n */\n get(sid: string): Promise<Session<TExtended> | null>;\n\n /**\n * Update an existing session with partial data.\n *\n * Commonly used to update lastActivityAt or add custom fields.\n *\n * @param sid - The session.sid to update\n * @param data - Partial session data to merge\n * @throws Error if session not found\n */\n update(sid: string, data: Partial<Session<TExtended>>): Promise<void>;\n\n /**\n * Delete a session by its IdP session ID (sid).\n *\n * Used for both normal logout and backchannel logout flows.\n *\n * @param sid - The session.sid to delete\n */\n delete(sid: string): Promise<void>;\n}\n\n/**\n * In-memory session store implementation using Maps.\n *\n * Suitable for:\n * - Development and testing\n * - Single-server deployments\n * - Applications without high availability requirements\n *\n * NOT suitable for:\n * - Multi-server deployments (sessions not shared)\n * - High availability scenarios (sessions lost on restart)\n * - Production applications with distributed architecture\n *\n * For production, implement SessionStore with Redis or a database.\n *\n * @template TExtended - Type-safe custom data that consumers can add to sessions\n */\nexport class InMemorySessionStore<TExtended = Record<string, never>> implements SessionStore<TExtended> {\n private sessions = new Map<string, Session<TExtended>>();\n\n async create(session: Session<TExtended>): Promise<void> {\n if (this.sessions.has(session.sid)) {\n throw new Error(`Session with sid ${session.sid} already exists`);\n }\n\n this.sessions.set(session.sid, session);\n }\n\n async get(sid: string): Promise<Session<TExtended> | null> {\n return this.sessions.get(sid) ?? null;\n }\n\n async update(sid: string, data: Partial<Session<TExtended>>): Promise<void> {\n const session = this.sessions.get(sid);\n if (!session) {\n throw new Error(`Session with sid ${sid} not found`);\n }\n\n // Merge the update data\n const updated = { ...session, ...data };\n this.sessions.set(sid, updated);\n }\n\n async delete(sid: string): Promise<void> {\n this.sessions.delete(sid);\n }\n}\n",
|
|
12
|
+
"import type { PropsWithChildren } from 'react';\nimport { useUser } from '..';\n\nexport function SignInLoading({ complete = false, children }: { complete?: boolean } & PropsWithChildren) {\n const { isLoading } = useUser();\n\n if (isLoading && !complete) return <>{children}</>;\n return null;\n}\n",
|
|
13
|
+
"import type { PropsWithChildren } from 'react';\nimport { useUser } from '..';\n\nexport function SignedIn({ children }: PropsWithChildren) {\n const { user } = useUser();\n\n if (user) return <>{children}</>;\n return null;\n}\n",
|
|
14
|
+
"import type { PropsWithChildren } from 'react';\nimport { useUser } from '..';\n\nexport function SignedOut({ children }: PropsWithChildren) {\n const { user, isLoading } = useUser();\n\n if (user || isLoading) return null;\n return <>{children}</>;\n}\n",
|
|
15
|
+
"import { createContext, type ReactNode, useCallback, useContext, useEffect, useState } from 'react';\nimport type { EnterpriseUser } from '../enterprise-user';\n\ntype StorageType = 'local' | 'session' | 'memory';\n\ninterface SSOProviderProps {\n tenantId?: string;\n storage?: StorageType;\n storageKey?: string;\n userUrl?: string;\n tokenUrl?: string;\n refreshUrl?: string;\n disableListener?: boolean;\n children: ReactNode;\n}\n\ninterface SSOContext {\n user: EnterpriseUser | null;\n setUser: (user: EnterpriseUser | null) => void;\n isLoading: boolean;\n tokenUrl?: string;\n refreshUrl?: string;\n}\n\nconst CTX = createContext<SSOContext | undefined>(undefined);\n\nconst generateStorageKey = (tenantId: string): string => {\n return `es-sso-user-${tenantId\n .replace(/[^a-zA-Z0-9]/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '')}`;\n};\n\nexport function SSOProvider({\n tenantId,\n storage = 'memory',\n storageKey,\n userUrl,\n tokenUrl,\n refreshUrl,\n disableListener = false,\n children,\n}: SSOProviderProps) {\n const [user, setUserState] = useState<EnterpriseUser | null>(null);\n const [isLoading, setIsLoading] = useState<boolean>(!!userUrl);\n\n const actualStorageKey = storageKey || (tenantId ? generateStorageKey(tenantId) : 'es-sso-user');\n\n const isValidUser = useCallback(\n (user: EnterpriseUser | null): boolean => {\n if (!user || !tenantId) return true;\n return user.sso?.tenant?.id === tenantId;\n },\n [tenantId],\n );\n\n const loadUserFromStorage = useCallback((): EnterpriseUser | null => {\n if (storage === 'memory' || typeof window === 'undefined') return null;\n\n try {\n const storageObject = storage === 'local' ? localStorage : sessionStorage;\n const userData = storageObject.getItem(actualStorageKey);\n if (!userData) return null;\n\n const parsedUser = JSON.parse(userData) as EnterpriseUser;\n\n if (parsedUser.sso?.expires) {\n parsedUser.sso.expires = new Date(parsedUser.sso.expires);\n }\n\n return isValidUser(parsedUser) ? parsedUser : null;\n } catch (error) {\n console.error('Error loading user from storage:', error);\n return null;\n }\n }, [storage, actualStorageKey, isValidUser]);\n\n const saveUserToStorage = useCallback(\n (user: EnterpriseUser | null) => {\n if (storage === 'memory' || typeof window === 'undefined') return;\n\n try {\n const storageObject = storage === 'local' ? localStorage : sessionStorage;\n if (user === null) {\n storageObject.removeItem(actualStorageKey);\n } else {\n storageObject.setItem(actualStorageKey, JSON.stringify(user));\n }\n } catch (error) {\n console.error('Error saving user to storage:', error);\n }\n },\n [storage, actualStorageKey],\n );\n\n const setUser = useCallback(\n (newUser: EnterpriseUser | null) => {\n if (newUser && !isValidUser(newUser)) return;\n\n setUserState(newUser);\n saveUserToStorage(newUser);\n },\n [isValidUser, saveUserToStorage],\n );\n\n const fetchUserFromUrl = useCallback(async () => {\n if (!userUrl) return;\n\n setIsLoading(true);\n try {\n const response = await fetch(userUrl);\n\n if (response.status === 401) {\n setUserState(null);\n saveUserToStorage(null);\n setIsLoading(false);\n return;\n }\n\n if (!response.ok) {\n throw new Error(`Failed to fetch user: ${response.status} ${response.statusText}`);\n }\n\n const userData = (await response.json()) as EnterpriseUser;\n\n if (userData.sso?.expires && typeof userData.sso.expires === 'string') {\n userData.sso.expires = new Date(userData.sso.expires);\n }\n\n if (isValidUser(userData)) {\n setUserState(userData);\n saveUserToStorage(userData);\n }\n } catch (error) {\n console.error('Error fetching user from URL:', error);\n } finally {\n setIsLoading(false);\n }\n }, [userUrl, isValidUser, saveUserToStorage]);\n\n useEffect(() => {\n const storedUser = loadUserFromStorage();\n if (storedUser) {\n setUserState(storedUser);\n }\n\n if (userUrl) {\n fetchUserFromUrl();\n } else {\n setIsLoading(false);\n }\n }, [loadUserFromStorage, userUrl, fetchUserFromUrl]);\n\n useEffect(() => {\n if (disableListener || storage === 'memory') return;\n\n const handleStorageChange = (event: StorageEvent) => {\n if (event.key !== actualStorageKey) return;\n\n if (event.newValue === null) {\n setUserState(null);\n } else {\n try {\n const parsedUser = JSON.parse(event.newValue) as EnterpriseUser;\n\n if (parsedUser.sso?.expires) {\n parsedUser.sso.expires = new Date(parsedUser.sso.expires);\n }\n\n if (isValidUser(parsedUser)) {\n setUserState(parsedUser);\n }\n } catch (error) {\n console.error('Error parsing user from storage event:', error);\n }\n }\n };\n\n const handleLogout = () => {\n setUserState(null);\n };\n\n window.addEventListener('storage', handleStorageChange);\n window.addEventListener('es-sso-logout', handleLogout);\n\n return () => {\n window.removeEventListener('storage', handleStorageChange);\n window.removeEventListener('es-sso-logout', handleLogout);\n };\n }, [disableListener, storage, actualStorageKey, isValidUser]);\n\n const contextValue: SSOContext = {\n user,\n setUser,\n isLoading,\n tokenUrl,\n refreshUrl,\n };\n\n return <CTX.Provider value={contextValue}>{children}</CTX.Provider>;\n}\n\nexport function useUser(): SSOContext {\n const context = useContext(CTX);\n if (context === undefined) {\n throw new Error('useUser must be used within a SSOProvider');\n }\n return context;\n}\n\ninterface JwtData {\n token: string;\n expires: string;\n}\n\ninterface UseTokenReturn {\n token: string | null;\n isLoading: boolean;\n error: Error | null;\n refresh: () => Promise<void>;\n}\n\nexport function useToken(): UseTokenReturn {\n const context = useContext(CTX);\n if (context === undefined) {\n throw new Error('useToken must be used within a SSOProvider');\n }\n\n const { tokenUrl, refreshUrl } = context;\n if (!tokenUrl || !refreshUrl) {\n throw new Error('useToken requires that a \"tokenUrl\" and \"refreshUrl\" be set in the SSOProvider');\n }\n\n const [token, setToken] = useState<string | null>(null);\n const [expires, setExpires] = useState<Date | null>(null);\n const [isLoading, setIsLoading] = useState<boolean>(!!tokenUrl);\n const [error, setError] = useState<Error | null>(null);\n\n const fetchJwt = useCallback(\n async (url: string) => {\n setIsLoading(true);\n setError(null);\n try {\n const response = await fetch(url);\n\n if (response.status === 401) {\n context.setUser(null);\n setToken(null);\n setExpires(null);\n setIsLoading(false);\n return;\n }\n\n if (!response.ok) {\n throw new Error(`Failed to fetch JWT: ${response.status} ${response.statusText}`);\n }\n\n const data = (await response.json()) as JwtData;\n setToken(data.token);\n setExpires(new Date(data.expires));\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n setToken(null);\n setExpires(null);\n console.error('Error fetching JWT:', error);\n } finally {\n setIsLoading(false);\n }\n },\n [context],\n );\n\n const refresh = useCallback(async () => {\n const url = refreshUrl || tokenUrl;\n if (!url) {\n console.warn('No tokenUrl or refreshUrl provided');\n return;\n }\n await fetchJwt(url);\n }, [refreshUrl, tokenUrl, fetchJwt]);\n\n useEffect(() => {\n if (!tokenUrl) {\n setIsLoading(false);\n return;\n }\n\n fetchJwt(tokenUrl);\n }, [tokenUrl, fetchJwt]);\n\n useEffect(() => {\n if (!expires || !refreshUrl) return;\n\n const checkExpiration = () => {\n const now = new Date();\n const timeUntilExpiry = expires.getTime() - now.getTime();\n\n // Refresh 1 minute before expiration\n if (timeUntilExpiry <= 60000 && timeUntilExpiry > 0) {\n refresh();\n }\n };\n\n // Check immediately\n checkExpiration();\n\n // Check every 30 seconds\n const interval = setInterval(checkExpiration, 30000);\n\n return () => clearInterval(interval);\n }, [expires, refreshUrl, refresh]);\n\n return {\n token,\n isLoading,\n error,\n refresh,\n };\n}\n\nexport async function logout(logoutUrl: string): Promise<{ success: boolean; error?: string }> {\n try {\n // Make AJAX logout call\n const response = await fetch(logoutUrl, {\n headers: { Accept: 'application/json' },\n });\n\n if (!response.ok) {\n return { success: false, error: `HTTP ${response.status}` };\n }\n\n const data = await response.json();\n if (!data.success) {\n return { success: false, error: data.message || 'Logout failed' };\n }\n\n // Clear managed storage keys (all es-sso-user-* keys)\n if (typeof window !== 'undefined') {\n // Clear localStorage\n for (let i = localStorage.length - 1; i >= 0; i--) {\n const key = localStorage.key(i);\n if (key?.startsWith('es-sso-user')) {\n localStorage.removeItem(key);\n }\n }\n\n // Clear sessionStorage\n for (let i = sessionStorage.length - 1; i >= 0; i--) {\n const key = sessionStorage.key(i);\n if (key?.startsWith('es-sso-user')) {\n sessionStorage.removeItem(key);\n }\n }\n\n // Dispatch custom event for same-tab state updates\n window.dispatchEvent(new CustomEvent('es-sso-logout'));\n }\n\n return { success: true };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Network error',\n };\n }\n}\n",
|
|
16
|
+
"import { type IAM, iam } from './iam';\nimport { type SSO, type SSOConfig, sso } from './sso';\nimport { getDefaultInstance, setDefaultInstance } from './utils';\nimport { type Vault, vault } from './vault';\n\nexport type EnterpriseStandard = {\n ioniteUrl: string;\n defaultInstance: boolean;\n vault: Vault;\n sso?: SSO;\n iam?: IAM;\n};\n\ntype ESConfig = {\n ioniteUrl?: string;\n defaultInstance?: boolean;\n sso?: SSOConfig;\n};\n\ntype VaultSecret = {\n path: string;\n token: string;\n};\n\nexport async function enterpriseStandard(appKey?: string, initConfig?: ESConfig): Promise<EnterpriseStandard> {\n let vaultUrl: string | undefined;\n let vaultToken: string | undefined;\n let secrets: { sso?: VaultSecret; iam?: VaultSecret };\n const ioniteUrl = initConfig?.ioniteUrl ?? 'https://ionite.com';\n\n if (appKey?.startsWith('IONITE_PUBLIC_DEMO_')) {\n vaultUrl = 'https://vault-ionite.ionite.dev/v1/secret/data';\n const port = appKey.slice('IONITE_PUBLIC_DEMO_'.length);\n secrets = {\n sso: {\n path: `public/IONITE_PUBLIC_DEMO_SSO_${port}`,\n token: 'hvs.VGhD2hmXDH9PmZjTacZx0G5K',\n },\n };\n } else if (appKey) {\n // TODO Connect to ionite and get the vault url/token as well as the paths\n if (!vaultUrl || !vaultToken) {\n throw new Error('TODO something is wrong with the ionite config, handle this error');\n }\n secrets = {};\n } else {\n throw new Error('TODO tell them how to connect to ionite');\n }\n\n const defaultInstance = getDefaultInstance();\n const vaultClient = vault(vaultUrl);\n\n const result = {\n ioniteUrl,\n defaultInstance: initConfig?.defaultInstance || (initConfig?.defaultInstance !== false && !defaultInstance),\n vault: vaultClient,\n sso: secrets.sso\n ? sso({\n ...(await vaultClient.getSecret<SSOConfig>(secrets.sso.path, secrets.sso.token)),\n ...initConfig,\n })\n : undefined,\n iam: secrets.iam ? await iam(await vaultClient.getSecret(secrets.iam.path, secrets.iam.token)) : undefined,\n };\n\n if (result.defaultInstance) {\n if (defaultInstance) {\n defaultInstance.defaultInstance = false;\n }\n setDefaultInstance(result);\n }\n\n return result;\n}\n\nexport type * from './enterprise-user';\nexport { oidcCallbackSchema, tokenResponseSchema, idTokenClaimsSchema } from './oidc-schema';\nexport type { OidcCallbackParams, TokenResponse, IdTokenClaims } from './oidc-schema';\nexport type { StandardSchemaV1 } from './standard-schema';\nexport * from './server';\nexport type { SessionStore } from './session-store';\nexport { InMemorySessionStore } from './session-store';\nexport type { SSOConfig, SSOHandlerConfig } from './sso';\nexport { SignInLoading } from './ui/sign-in-loading';\nexport { SignedIn } from './ui/signed-in';\nexport { SignedOut } from './ui/signed-out';\nexport * from './ui/sso-provider';\n"
|
|
17
|
+
],
|
|
18
|
+
"mappings": "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",
|
|
19
|
+
"debugId": "11B14D9E3E6DAB9F64756E2164756E21",
|
|
20
|
+
"names": []
|
|
21
|
+
}
|
package/dist/oidc-schema.d.ts
CHANGED
|
@@ -41,3 +41,46 @@ export interface OidcCallbackParams {
|
|
|
41
41
|
* @returns A StandardSchemaV1 instance for OIDC callback parameters
|
|
42
42
|
*/
|
|
43
43
|
export declare function oidcCallbackSchema(vendor: string): StandardSchemaV1<Record<string, unknown>, OidcCallbackParams>;
|
|
44
|
+
/**
|
|
45
|
+
* Token Response from IdP
|
|
46
|
+
*/
|
|
47
|
+
export interface TokenResponse {
|
|
48
|
+
access_token: string;
|
|
49
|
+
id_token: string;
|
|
50
|
+
refresh_token?: string;
|
|
51
|
+
token_type: string;
|
|
52
|
+
expires_in?: number;
|
|
53
|
+
scope?: string;
|
|
54
|
+
refresh_expires_in?: number;
|
|
55
|
+
session_state?: string;
|
|
56
|
+
expires?: string;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Creates a StandardSchemaV1 for validating OIDC Token Responses.
|
|
60
|
+
* @param vendor - The name of the vendor creating this schema
|
|
61
|
+
* @returns A StandardSchemaV1 instance for Token Response validation
|
|
62
|
+
*/
|
|
63
|
+
export declare function tokenResponseSchema(vendor: string): StandardSchemaV1<Record<string, unknown>, TokenResponse>;
|
|
64
|
+
/**
|
|
65
|
+
* ID Token Claims
|
|
66
|
+
*/
|
|
67
|
+
export interface IdTokenClaims {
|
|
68
|
+
iss?: string;
|
|
69
|
+
aud?: string;
|
|
70
|
+
exp?: number;
|
|
71
|
+
iat?: number;
|
|
72
|
+
sub?: string;
|
|
73
|
+
sid?: string;
|
|
74
|
+
name?: string;
|
|
75
|
+
email?: string;
|
|
76
|
+
preferred_username?: string;
|
|
77
|
+
picture?: string;
|
|
78
|
+
[key: string]: unknown;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Creates a StandardSchemaV1 for validating ID Token Claims.
|
|
82
|
+
* @param vendor - The name of the vendor creating this schema
|
|
83
|
+
* @returns A StandardSchemaV1 instance for ID Token Claims validation
|
|
84
|
+
*/
|
|
85
|
+
export declare function idTokenClaimsSchema(vendor: string): StandardSchemaV1<Record<string, unknown>, IdTokenClaims>;
|
|
86
|
+
//# sourceMappingURL=oidc-schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oidc-schema.d.ts","sourceRoot":"","sources":["../src/oidc-schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE1D;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,kBAAkB,CAAC,CAoHhH;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,CAAC,CAmJ5G;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,CAAC,CAsD5G"}
|