@enterprisestandard/react 0.0.5-beta.20251125.1 → 0.0.5-beta.20260114.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.
Files changed (48) hide show
  1. package/dist/group-store.d.ts +164 -0
  2. package/dist/group-store.d.ts.map +1 -0
  3. package/dist/iam.d.ts +205 -5
  4. package/dist/iam.d.ts.map +1 -1
  5. package/dist/index.d.ts +41 -13
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +2837 -555
  8. package/dist/index.js.map +17 -9
  9. package/dist/server.d.ts +6 -4
  10. package/dist/server.d.ts.map +1 -1
  11. package/dist/session-store.d.ts +3 -3
  12. package/dist/session-store.d.ts.map +1 -1
  13. package/dist/sso.d.ts +58 -10
  14. package/dist/sso.d.ts.map +1 -1
  15. package/dist/tenant-server.d.ts +8 -0
  16. package/dist/tenant-server.d.ts.map +1 -0
  17. package/dist/tenant.d.ts +280 -0
  18. package/dist/tenant.d.ts.map +1 -0
  19. package/dist/types/base-user.d.ts +27 -0
  20. package/dist/types/base-user.d.ts.map +1 -0
  21. package/dist/types/enterprise-user.d.ts +158 -0
  22. package/dist/types/enterprise-user.d.ts.map +1 -0
  23. package/dist/types/oidc-schema.d.ts.map +1 -0
  24. package/dist/{scim-schema.d.ts → types/scim-schema.d.ts} +66 -3
  25. package/dist/types/scim-schema.d.ts.map +1 -0
  26. package/dist/types/standard-schema.d.ts.map +1 -0
  27. package/dist/types/user.d.ts +41 -0
  28. package/dist/types/user.d.ts.map +1 -0
  29. package/dist/types/workload-schema.d.ts +106 -0
  30. package/dist/types/workload-schema.d.ts.map +1 -0
  31. package/dist/ui/sso-provider.d.ts +3 -3
  32. package/dist/ui/sso-provider.d.ts.map +1 -1
  33. package/dist/user-store.d.ts +161 -0
  34. package/dist/user-store.d.ts.map +1 -0
  35. package/dist/workload-server.d.ts +126 -0
  36. package/dist/workload-server.d.ts.map +1 -0
  37. package/dist/workload-token-store.d.ts +187 -0
  38. package/dist/workload-token-store.d.ts.map +1 -0
  39. package/dist/workload.d.ts +227 -0
  40. package/dist/workload.d.ts.map +1 -0
  41. package/package.json +1 -2
  42. package/dist/enterprise-user.d.ts +0 -126
  43. package/dist/enterprise-user.d.ts.map +0 -1
  44. package/dist/oidc-schema.d.ts.map +0 -1
  45. package/dist/scim-schema.d.ts.map +0 -1
  46. package/dist/standard-schema.d.ts.map +0 -1
  47. /package/dist/{oidc-schema.d.ts → types/oidc-schema.d.ts} +0 -0
  48. /package/dist/{standard-schema.d.ts → types/standard-schema.d.ts} +0 -0
package/dist/index.js.map CHANGED
@@ -1,21 +1,29 @@
1
1
  {
2
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"],
3
+ "sources": ["../src/types/scim-schema.ts", "../src/iam.ts", "../src/types/oidc-schema.ts", "../src/utils.ts", "../src/sso.ts", "../src/vault.ts", "../src/types/workload-schema.ts", "../src/workload-token-store.ts", "../src/workload.ts", "../src/group-store.ts", "../src/tenant.ts", "../src/workload-server.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/user-store.ts", "../src/index.ts"],
4
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",
5
+ "import type { StandardSchemaV1 } from './standard-schema';\n\n/**\n * SCIM 2.0 User Resource\n * @see https://datatracker.ietf.org/doc/html/rfc7643#section-4.1\n */\n\n/**\n * SCIM Name sub-attribute\n */\nexport interface Name {\n /**\n * The full name, including all middle names, titles, and suffixes as appropriate\n */\n formatted?: string;\n /**\n * The family name of the User, or last name\n */\n familyName?: string;\n /**\n * The given name of the User, or first name\n */\n givenName?: string;\n /**\n * The middle name(s) of the User\n */\n middleName?: string;\n /**\n * The honorific prefix(es) of the User, or title\n */\n honorificPrefix?: string;\n /**\n * The honorific suffix(es) of the User, or suffix\n */\n honorificSuffix?: string;\n}\n\n/**\n * SCIM Email sub-attribute\n */\nexport interface Email {\n /**\n * The email address value\n */\n value: string;\n /**\n * A human-readable name, primarily used for display purposes\n */\n display?: string;\n /**\n * A label indicating the attribute's function (e.g., \"work\" or \"home\")\n */\n type?: string;\n /**\n * A Boolean value indicating the 'primary' or preferred attribute value\n */\n primary?: boolean;\n}\n\n/**\n * SCIM Phone Number sub-attribute\n */\nexport interface PhoneNumber {\n /**\n * The phone number value\n */\n value: string;\n /**\n * A human-readable name, primarily used for display purposes\n */\n display?: string;\n /**\n * A label indicating the attribute's function (e.g., \"work\", \"home\", \"mobile\")\n */\n type?: string;\n /**\n * A Boolean value indicating the 'primary' or preferred attribute value\n */\n primary?: boolean;\n}\n\n/**\n * SCIM Address sub-attribute\n */\nexport interface Address {\n /**\n * The full mailing address, formatted for display\n */\n formatted?: string;\n /**\n * The full street address component\n */\n streetAddress?: string;\n /**\n * The city or locality component\n */\n locality?: string;\n /**\n * The state or region component\n */\n region?: string;\n /**\n * The zip code or postal code component\n */\n postalCode?: string;\n /**\n * The country name component\n */\n country?: string;\n /**\n * A label indicating the attribute's function (e.g., \"work\" or \"home\")\n */\n type?: string;\n /**\n * A Boolean value indicating the 'primary' or preferred attribute value\n */\n primary?: boolean;\n}\n\n/**\n * SCIM Group reference (used within User resources)\n */\nexport interface Group {\n /**\n * The identifier of the User's group\n */\n value: string;\n /**\n * The URI of the corresponding 'Group' resource\n */\n $ref?: string;\n /**\n * A human-readable name, primarily used for display purposes\n */\n display?: string;\n /**\n * A label indicating the attribute's function (e.g., \"direct\" or \"indirect\")\n */\n type?: string;\n}\n\n/**\n * SCIM Group Member reference\n */\nexport interface GroupMember {\n /**\n * The identifier of the member (User or Group)\n */\n value: string;\n /**\n * The URI of the corresponding member resource\n */\n $ref?: string;\n /**\n * A human-readable name of the member\n */\n display?: string;\n /**\n * The type of the member (e.g., \"User\" or \"Group\")\n */\n type?: 'User' | 'Group';\n}\n\n/**\n * SCIM 2.0 Group Resource\n * @see https://datatracker.ietf.org/doc/html/rfc7643#section-4.2\n */\nexport interface GroupResource {\n /**\n * REQUIRED. The schemas attribute\n */\n schemas?: string[];\n /**\n * Unique identifier for the Group, assigned by the service provider\n */\n id?: string;\n /**\n * External identifier from the provisioning client\n */\n externalId?: string;\n /**\n * Resource metadata\n */\n meta?: {\n resourceType?: string;\n created?: string;\n lastModified?: string;\n location?: string;\n version?: string;\n };\n /**\n * REQUIRED. A human-readable name for the Group\n */\n displayName: string;\n /**\n * A list of members of the Group\n */\n members?: GroupMember[];\n}\n\n/**\n * SCIM Role\n */\nexport interface Role {\n /**\n * The value of the role\n */\n value: string;\n /**\n * A human-readable name, primarily used for display purposes\n */\n display?: string;\n /**\n * A label indicating the attribute's function\n */\n type?: string;\n /**\n * A Boolean value indicating the 'primary' or preferred attribute value\n */\n primary?: boolean;\n}\n\n/**\n * SCIM X509 Certificate\n */\nexport interface X509Certificate {\n /**\n * The value of the X.509 certificate\n */\n value: string;\n /**\n * A human-readable name, primarily used for display purposes\n */\n display?: string;\n /**\n * A label indicating the attribute's function\n */\n type?: string;\n /**\n * A Boolean value indicating the 'primary' or preferred attribute value\n */\n primary?: boolean;\n}\n\n/**\n * SCIM Enterprise User Extension\n * @see https://datatracker.ietf.org/doc/html/rfc7643#section-4.3\n */\nexport interface EnterpriseExtension {\n /**\n * Numeric or alphanumeric identifier assigned to a person\n */\n employeeNumber?: string;\n /**\n * Identifies the name of a cost center\n */\n costCenter?: string;\n /**\n * Identifies the name of an organization\n */\n organization?: string;\n /**\n * Identifies the name of a division\n */\n division?: string;\n /**\n * Identifies the name of a department\n */\n department?: string;\n /**\n * The user's manager\n */\n manager?: {\n /**\n * The \"id\" of the SCIM resource representing the User's manager\n */\n value?: string;\n /**\n * The URI of the SCIM resource representing the User's manager\n */\n $ref?: string;\n /**\n * The displayName of the User's manager\n */\n displayName?: string;\n };\n}\n\n/**\n * SCIM User Resource\n */\nexport interface User {\n /**\n * REQUIRED. Unique identifier for the User, typically from the provider\n */\n id?: string;\n /**\n * REQUIRED. A unique identifier for a SCIM resource as defined by the service provider\n */\n externalId?: string;\n /**\n * Resource metadata\n */\n meta?: {\n resourceType?: string;\n created?: string;\n lastModified?: string;\n location?: string;\n version?: string;\n };\n /**\n * REQUIRED. Unique identifier for the User, typically used for login\n */\n userName: string;\n /**\n * The components of the user's name\n */\n name?: Name;\n /**\n * The name of the User, suitable for display to end-users\n */\n displayName?: string;\n /**\n * The casual way to address the user\n */\n nickName?: string;\n /**\n * A fully qualified URL pointing to a page representing the User's online profile\n */\n profileUrl?: string;\n /**\n * The user's title, such as \"Vice President\"\n */\n title?: string;\n /**\n * Used to identify the relationship between the organization and the user\n */\n userType?: string;\n /**\n * Indicates the User's preferred written or spoken language\n */\n preferredLanguage?: string;\n /**\n * Used to indicate the User's default location for purposes of localizing items such as currency\n */\n locale?: string;\n /**\n * The User's time zone in the \"Olson\" time zone database format\n */\n timezone?: string;\n /**\n * A Boolean value indicating the User's administrative status\n */\n active?: boolean;\n /**\n * The User's cleartext password\n */\n password?: string;\n /**\n * Email addresses for the user\n */\n emails?: Email[];\n /**\n * Phone numbers for the User\n */\n phoneNumbers?: PhoneNumber[];\n /**\n * Instant messaging addresses for the User\n */\n ims?: Array<{\n value: string;\n display?: string;\n type?: string;\n primary?: boolean;\n }>;\n /**\n * URLs of photos of the User\n */\n photos?: Array<{\n value: string;\n display?: string;\n type?: string;\n primary?: boolean;\n }>;\n /**\n * Physical mailing addresses for this User\n */\n addresses?: Address[];\n /**\n * A list of groups to which the user belongs\n */\n groups?: Group[];\n /**\n * A list of entitlements for the User\n */\n entitlements?: Array<{\n value: string;\n display?: string;\n type?: string;\n primary?: boolean;\n }>;\n /**\n * A list of roles for the User\n */\n roles?: Role[];\n /**\n * A list of certificates issued to the User\n */\n x509Certificates?: X509Certificate[];\n /**\n * Enterprise User Extension\n */\n 'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User'?: EnterpriseExtension;\n /**\n * REQUIRED. The schemas attribute is an array of Strings which allows introspection of the supported schema version\n */\n schemas?: string[];\n}\n\n/**\n * Validates a string field\n */\nfunction validateString(\n value: unknown,\n fieldName: string,\n required: boolean,\n issues: StandardSchemaV1.Issue[],\n path: PropertyKey[],\n): string | undefined {\n if (value === undefined || value === null) {\n if (required) {\n issues.push({\n message: `${fieldName} is required`,\n path,\n });\n }\n return undefined;\n }\n\n if (typeof value !== 'string') {\n issues.push({\n message: `${fieldName} must be a string`,\n path,\n });\n return undefined;\n }\n\n return value;\n}\n\n/**\n * Validates a boolean field\n */\nfunction validateBoolean(\n value: unknown,\n fieldName: string,\n issues: StandardSchemaV1.Issue[],\n path: PropertyKey[],\n): boolean | undefined {\n if (value === undefined || value === null) {\n return undefined;\n }\n\n if (typeof value !== 'boolean') {\n issues.push({\n message: `${fieldName} must be a boolean`,\n path,\n });\n return undefined;\n }\n\n return value;\n}\n\n/**\n * Validates a SCIM Name object\n */\nfunction validateName(value: unknown, issues: StandardSchemaV1.Issue[], basePath: PropertyKey[]): Name | undefined {\n if (value === undefined || value === null) {\n return undefined;\n }\n\n if (typeof value !== 'object' || value === null) {\n issues.push({\n message: 'name must be an object',\n path: basePath,\n });\n return undefined;\n }\n\n const name = value as Record<string, unknown>;\n const result: Name = {};\n\n result.formatted = validateString(name.formatted, 'formatted', false, issues, [...basePath, 'formatted']);\n result.familyName = validateString(name.familyName, 'familyName', false, issues, [...basePath, 'familyName']);\n result.givenName = validateString(name.givenName, 'givenName', false, issues, [...basePath, 'givenName']);\n result.middleName = validateString(name.middleName, 'middleName', false, issues, [...basePath, 'middleName']);\n result.honorificPrefix = validateString(name.honorificPrefix, 'honorificPrefix', false, issues, [\n ...basePath,\n 'honorificPrefix',\n ]);\n result.honorificSuffix = validateString(name.honorificSuffix, 'honorificSuffix', false, issues, [\n ...basePath,\n 'honorificSuffix',\n ]);\n\n return result;\n}\n\n/**\n * Validates a SCIM Email array\n */\nfunction validateEmails(\n value: unknown,\n issues: StandardSchemaV1.Issue[],\n basePath: PropertyKey[],\n): Email[] | undefined {\n if (value === undefined || value === null) {\n return undefined;\n }\n\n if (!Array.isArray(value)) {\n issues.push({\n message: 'emails must be an array',\n path: basePath,\n });\n return undefined;\n }\n\n const emails: Email[] = [];\n\n for (let i = 0; i < value.length; i++) {\n const email = value[i];\n const emailPath = [...basePath, i];\n\n if (typeof email !== 'object' || email === null) {\n issues.push({\n message: 'email must be an object',\n path: emailPath,\n });\n continue;\n }\n\n const emailObj = email as Record<string, unknown>;\n const emailValue = validateString(emailObj.value, 'value', true, issues, [...emailPath, 'value']);\n\n if (emailValue) {\n emails.push({\n value: emailValue,\n display: validateString(emailObj.display, 'display', false, issues, [...emailPath, 'display']),\n type: validateString(emailObj.type, 'type', false, issues, [...emailPath, 'type']),\n primary: validateBoolean(emailObj.primary, 'primary', issues, [...emailPath, 'primary']),\n });\n }\n }\n\n return emails.length > 0 ? emails : undefined;\n}\n\n/**\n * Validates a SCIM PhoneNumber array\n */\nfunction validatePhoneNumbers(\n value: unknown,\n issues: StandardSchemaV1.Issue[],\n basePath: PropertyKey[],\n): PhoneNumber[] | undefined {\n if (value === undefined || value === null) {\n return undefined;\n }\n\n if (!Array.isArray(value)) {\n issues.push({\n message: 'phoneNumbers must be an array',\n path: basePath,\n });\n return undefined;\n }\n\n const phoneNumbers: PhoneNumber[] = [];\n\n for (let i = 0; i < value.length; i++) {\n const phone = value[i];\n const phonePath = [...basePath, i];\n\n if (typeof phone !== 'object' || phone === null) {\n issues.push({\n message: 'phoneNumber must be an object',\n path: phonePath,\n });\n continue;\n }\n\n const phoneObj = phone as Record<string, unknown>;\n const phoneValue = validateString(phoneObj.value, 'value', true, issues, [...phonePath, 'value']);\n\n if (phoneValue) {\n phoneNumbers.push({\n value: phoneValue,\n display: validateString(phoneObj.display, 'display', false, issues, [...phonePath, 'display']),\n type: validateString(phoneObj.type, 'type', false, issues, [...phonePath, 'type']),\n primary: validateBoolean(phoneObj.primary, 'primary', issues, [...phonePath, 'primary']),\n });\n }\n }\n\n return phoneNumbers.length > 0 ? phoneNumbers : undefined;\n}\n\n/**\n * Validates a SCIM Address array\n */\nfunction validateAddresses(\n value: unknown,\n issues: StandardSchemaV1.Issue[],\n basePath: PropertyKey[],\n): Address[] | undefined {\n if (value === undefined || value === null) {\n return undefined;\n }\n\n if (!Array.isArray(value)) {\n issues.push({\n message: 'addresses must be an array',\n path: basePath,\n });\n return undefined;\n }\n\n const addresses: Address[] = [];\n\n for (let i = 0; i < value.length; i++) {\n const address = value[i];\n const addressPath = [...basePath, i];\n\n if (typeof address !== 'object' || address === null) {\n issues.push({\n message: 'address must be an object',\n path: addressPath,\n });\n continue;\n }\n\n const addressObj = address as Record<string, unknown>;\n\n addresses.push({\n formatted: validateString(addressObj.formatted, 'formatted', false, issues, [...addressPath, 'formatted']),\n streetAddress: validateString(addressObj.streetAddress, 'streetAddress', false, issues, [\n ...addressPath,\n 'streetAddress',\n ]),\n locality: validateString(addressObj.locality, 'locality', false, issues, [...addressPath, 'locality']),\n region: validateString(addressObj.region, 'region', false, issues, [...addressPath, 'region']),\n postalCode: validateString(addressObj.postalCode, 'postalCode', false, issues, [...addressPath, 'postalCode']),\n country: validateString(addressObj.country, 'country', false, issues, [...addressPath, 'country']),\n type: validateString(addressObj.type, 'type', false, issues, [...addressPath, 'type']),\n primary: validateBoolean(addressObj.primary, 'primary', issues, [...addressPath, 'primary']),\n });\n }\n\n return addresses.length > 0 ? addresses : undefined;\n}\n\n/**\n * Validates a SCIM Group array\n */\nfunction validateGroups(\n value: unknown,\n issues: StandardSchemaV1.Issue[],\n basePath: PropertyKey[],\n): Group[] | undefined {\n if (value === undefined || value === null) {\n return undefined;\n }\n\n if (!Array.isArray(value)) {\n issues.push({\n message: 'groups must be an array',\n path: basePath,\n });\n return undefined;\n }\n\n const groups: Group[] = [];\n\n for (let i = 0; i < value.length; i++) {\n const group = value[i];\n const groupPath = [...basePath, i];\n\n if (typeof group !== 'object' || group === null) {\n issues.push({\n message: 'group must be an object',\n path: groupPath,\n });\n continue;\n }\n\n const groupObj = group as Record<string, unknown>;\n const groupValue = validateString(groupObj.value, 'value', true, issues, [...groupPath, 'value']);\n\n if (groupValue) {\n groups.push({\n value: groupValue,\n $ref: validateString(groupObj.$ref, '$ref', false, issues, [...groupPath, '$ref']),\n display: validateString(groupObj.display, 'display', false, issues, [...groupPath, 'display']),\n type: validateString(groupObj.type, 'type', false, issues, [...groupPath, 'type']),\n });\n }\n }\n\n return groups.length > 0 ? groups : undefined;\n}\n\n/**\n * Validates a SCIM Role array\n */\nfunction validateRoles(value: unknown, issues: StandardSchemaV1.Issue[], basePath: PropertyKey[]): Role[] | undefined {\n if (value === undefined || value === null) {\n return undefined;\n }\n\n if (!Array.isArray(value)) {\n issues.push({\n message: 'roles must be an array',\n path: basePath,\n });\n return undefined;\n }\n\n const roles: Role[] = [];\n\n for (let i = 0; i < value.length; i++) {\n const role = value[i];\n const rolePath = [...basePath, i];\n\n if (typeof role !== 'object' || role === null) {\n issues.push({\n message: 'role must be an object',\n path: rolePath,\n });\n continue;\n }\n\n const roleObj = role as Record<string, unknown>;\n const roleValue = validateString(roleObj.value, 'value', true, issues, [...rolePath, 'value']);\n\n if (roleValue) {\n roles.push({\n value: roleValue,\n display: validateString(roleObj.display, 'display', false, issues, [...rolePath, 'display']),\n type: validateString(roleObj.type, 'type', false, issues, [...rolePath, 'type']),\n primary: validateBoolean(roleObj.primary, 'primary', issues, [...rolePath, 'primary']),\n });\n }\n }\n\n return roles.length > 0 ? roles : undefined;\n}\n\n/**\n * Validates a SCIM Enterprise User extension\n */\nfunction validateEnterpriseUser(\n value: unknown,\n issues: StandardSchemaV1.Issue[],\n basePath: PropertyKey[],\n): EnterpriseExtension | undefined {\n if (value === undefined || value === null) {\n return undefined;\n }\n\n if (typeof value !== 'object' || value === null) {\n issues.push({\n message: 'Enterprise User extension must be an object',\n path: basePath,\n });\n return undefined;\n }\n\n const enterprise = value as Record<string, unknown>;\n const result: EnterpriseExtension = {};\n\n result.employeeNumber = validateString(enterprise.employeeNumber, 'employeeNumber', false, issues, [\n ...basePath,\n 'employeeNumber',\n ]);\n result.costCenter = validateString(enterprise.costCenter, 'costCenter', false, issues, [...basePath, 'costCenter']);\n result.organization = validateString(enterprise.organization, 'organization', false, issues, [\n ...basePath,\n 'organization',\n ]);\n result.division = validateString(enterprise.division, 'division', false, issues, [...basePath, 'division']);\n result.department = validateString(enterprise.department, 'department', false, issues, [...basePath, 'department']);\n\n if (enterprise.manager !== undefined && enterprise.manager !== null) {\n if (typeof enterprise.manager !== 'object' || enterprise.manager === null) {\n issues.push({\n message: 'manager must be an object',\n path: [...basePath, 'manager'],\n });\n } else {\n const manager = enterprise.manager as Record<string, unknown>;\n result.manager = {\n value: validateString(manager.value, 'value', false, issues, [...basePath, 'manager', 'value']),\n $ref: validateString(manager.$ref, '$ref', false, issues, [...basePath, 'manager', '$ref']),\n displayName: validateString(manager.displayName, 'displayName', false, issues, [\n ...basePath,\n 'manager',\n 'displayName',\n ]),\n };\n }\n }\n\n return result;\n}\n\n/**\n * Creates a StandardSchemaV1 for validating SCIM User resources.\n * @param vendor - The name of the vendor creating this schema\n * @returns A StandardSchemaV1 instance for SCIM User resources\n */\nexport function userSchema(vendor: string): StandardSchemaV1<Record<string, unknown>, User> {\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 user = value as Record<string, unknown>;\n const issues: StandardSchemaV1.Issue[] = [];\n const result: Partial<User> = {};\n\n // userName is REQUIRED\n const userName = validateString(user.userName, 'userName', true, issues, ['userName']);\n if (!userName) {\n return { issues };\n }\n result.userName = userName;\n\n // Optional string fields\n result.id = validateString(user.id, 'id', false, issues, ['id']);\n result.externalId = validateString(user.externalId, 'externalId', false, issues, ['externalId']);\n result.displayName = validateString(user.displayName, 'displayName', false, issues, ['displayName']);\n result.nickName = validateString(user.nickName, 'nickName', false, issues, ['nickName']);\n result.profileUrl = validateString(user.profileUrl, 'profileUrl', false, issues, ['profileUrl']);\n result.title = validateString(user.title, 'title', false, issues, ['title']);\n result.userType = validateString(user.userType, 'userType', false, issues, ['userType']);\n result.preferredLanguage = validateString(user.preferredLanguage, 'preferredLanguage', false, issues, [\n 'preferredLanguage',\n ]);\n result.locale = validateString(user.locale, 'locale', false, issues, ['locale']);\n result.timezone = validateString(user.timezone, 'timezone', false, issues, ['timezone']);\n result.password = validateString(user.password, 'password', false, issues, ['password']);\n\n // Boolean field\n result.active = validateBoolean(user.active, 'active', issues, ['active']);\n\n // Complex sub-attributes\n result.name = validateName(user.name, issues, ['name']);\n result.emails = validateEmails(user.emails, issues, ['emails']);\n result.phoneNumbers = validatePhoneNumbers(user.phoneNumbers, issues, ['phoneNumbers']);\n result.addresses = validateAddresses(user.addresses, issues, ['addresses']);\n result.groups = validateGroups(user.groups, issues, ['groups']);\n result.roles = validateRoles(user.roles, issues, ['roles']);\n\n // Enterprise User Extension\n const enterpriseKey = 'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User';\n if (user[enterpriseKey] !== undefined) {\n result[enterpriseKey] = validateEnterpriseUser(user[enterpriseKey], issues, [enterpriseKey]);\n }\n\n // Schemas array\n if (user.schemas !== undefined) {\n if (Array.isArray(user.schemas)) {\n result.schemas = user.schemas.filter((s): s is string => typeof s === 'string');\n } else {\n issues.push({\n message: 'schemas must be an array',\n path: ['schemas'],\n });\n }\n }\n\n // Meta object (basic validation)\n if (user.meta !== undefined) {\n if (typeof user.meta === 'object' && user.meta !== null) {\n const meta = user.meta as Record<string, unknown>;\n result.meta = {\n resourceType: typeof meta.resourceType === 'string' ? meta.resourceType : undefined,\n created: typeof meta.created === 'string' ? meta.created : undefined,\n lastModified: typeof meta.lastModified === 'string' ? meta.lastModified : undefined,\n location: typeof meta.location === 'string' ? meta.location : undefined,\n version: typeof meta.version === 'string' ? meta.version : undefined,\n };\n } else {\n issues.push({\n message: 'meta must be an object',\n path: ['meta'],\n });\n }\n }\n\n if (issues.length > 0) {\n return { issues };\n }\n\n return { value: result as User };\n },\n },\n };\n}\n\n/**\n * Validates a SCIM GroupMember array\n */\nfunction validateMembers(\n value: unknown,\n issues: StandardSchemaV1.Issue[],\n basePath: PropertyKey[],\n): GroupMember[] | undefined {\n if (value === undefined || value === null) {\n return undefined;\n }\n\n if (!Array.isArray(value)) {\n issues.push({\n message: 'members must be an array',\n path: basePath,\n });\n return undefined;\n }\n\n const members: GroupMember[] = [];\n\n for (let i = 0; i < value.length; i++) {\n const member = value[i];\n const memberPath = [...basePath, i];\n\n if (typeof member !== 'object' || member === null) {\n issues.push({\n message: 'member must be an object',\n path: memberPath,\n });\n continue;\n }\n\n const memberObj = member as Record<string, unknown>;\n const memberValue = validateString(memberObj.value, 'value', true, issues, [...memberPath, 'value']);\n\n if (memberValue) {\n const memberType = validateString(memberObj.type, 'type', false, issues, [...memberPath, 'type']);\n members.push({\n value: memberValue,\n $ref: validateString(memberObj.$ref, '$ref', false, issues, [...memberPath, '$ref']),\n display: validateString(memberObj.display, 'display', false, issues, [...memberPath, 'display']),\n type: memberType === 'User' || memberType === 'Group' ? memberType : undefined,\n });\n }\n }\n\n return members.length > 0 ? members : undefined;\n}\n\n/**\n * Creates a StandardSchemaV1 for validating SCIM Group resources.\n * @param vendor - The name of the vendor creating this schema\n * @returns A StandardSchemaV1 instance for SCIM Group resources\n */\nexport function groupResourceSchema(vendor: string): StandardSchemaV1<Record<string, unknown>, GroupResource> {\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 group = value as Record<string, unknown>;\n const issues: StandardSchemaV1.Issue[] = [];\n const result: Partial<GroupResource> = {};\n\n // displayName is REQUIRED\n const displayName = validateString(group.displayName, 'displayName', true, issues, ['displayName']);\n if (!displayName) {\n return { issues };\n }\n result.displayName = displayName;\n\n // Optional string fields\n result.id = validateString(group.id, 'id', false, issues, ['id']);\n result.externalId = validateString(group.externalId, 'externalId', false, issues, ['externalId']);\n\n // Members array\n result.members = validateMembers(group.members, issues, ['members']);\n\n // Schemas array\n if (group.schemas !== undefined) {\n if (Array.isArray(group.schemas)) {\n result.schemas = group.schemas.filter((s): s is string => typeof s === 'string');\n } else {\n issues.push({\n message: 'schemas must be an array',\n path: ['schemas'],\n });\n }\n }\n\n // Meta object (basic validation)\n if (group.meta !== undefined) {\n if (typeof group.meta === 'object' && group.meta !== null) {\n const meta = group.meta as Record<string, unknown>;\n result.meta = {\n resourceType: typeof meta.resourceType === 'string' ? meta.resourceType : undefined,\n created: typeof meta.created === 'string' ? meta.created : undefined,\n lastModified: typeof meta.lastModified === 'string' ? meta.lastModified : undefined,\n location: typeof meta.location === 'string' ? meta.location : undefined,\n version: typeof meta.version === 'string' ? meta.version : undefined,\n };\n } else {\n issues.push({\n message: 'meta must be an object',\n path: ['meta'],\n });\n }\n }\n\n if (issues.length > 0) {\n return { issues };\n }\n\n return { value: result as GroupResource };\n },\n },\n };\n}\n",
6
+ "import type { GroupStore, StoredGroup } from './group-store';\nimport type { GroupMember, GroupResource, User } from './types/scim-schema';\nimport { groupResourceSchema, userSchema } from './types/scim-schema';\nimport type { StandardSchemaV1 } from './types/standard-schema';\nimport type { UserStore } from './user-store';\nimport type { Workload } from './workload';\n\n/**\n * SCIM Error response structure\n */\nexport interface ScimError {\n schemas: string[];\n status: string;\n scimType?: string;\n detail?: string;\n}\n\n/**\n * SCIM List Response for bulk operations\n */\nexport interface ScimListResponse<T> {\n schemas: string[];\n totalResults: number;\n startIndex?: number;\n itemsPerPage?: number;\n Resources: T[];\n}\n\n/**\n * Result of a SCIM operation\n */\nexport interface ScimResult<T> {\n success: boolean;\n data?: T;\n error?: ScimError;\n status: number;\n}\n\n/**\n * Handler configuration for IAM\n */\nexport interface IAMHandlerConfig {\n /**\n * Base path for the SCIM Users endpoints (e.g., '/api/iam/Users')\n */\n usersUrl?: string;\n\n /**\n * Base path for the SCIM Groups endpoints (e.g., '/api/iam/Groups')\n */\n groupsUrl?: string;\n}\n\n/**\n * IAM configuration\n *\n * - If `url` is provided, groups_outbound is enabled (app calls external IAM)\n * - If `group_store` is provided, groups_inbound is enabled (external IAM calls app)\n * - If `user_store` is provided, users_inbound is enabled (external IAM calls app)\n */\nexport type IAMConfig = {\n /**\n * Base URL of the external SCIM endpoint (e.g., https://sailpoint.example.com/scim/v2)\n * If provided, enables outbound SCIM operations (app -> external IAM)\n */\n url?: string;\n\n /**\n * Store for inbound user provisioning from external IAM providers.\n * When configured, the app can receive user CRUD operations via SCIM.\n */\n user_store?: UserStore;\n\n /**\n * Store for inbound group provisioning from external IAM providers.\n * When configured, enables groups_inbound (external IAM -> app).\n */\n group_store?: GroupStore;\n\n /**\n * Optional handler defaults. These are merged with per-call overrides in\n * `iam.handler`, with per-call values taking precedence.\n */\n usersUrl?: string;\n groupsUrl?: string;\n};\n\n/**\n * Options for creating a group\n */\nexport interface CreateGroupOptions {\n /**\n * External identifier for the group\n */\n externalId?: string;\n /**\n * Initial members to add to the group\n */\n members?: GroupMember[];\n /**\n * Custom validation schema for the response\n */\n validation?: StandardSchemaV1<unknown, GroupResource>;\n}\n\n/**\n * Options for creating a user\n */\nexport interface CreateUserOptions {\n /**\n * Custom validation schema for the response\n */\n validation?: StandardSchemaV1<unknown, User>;\n}\n\n/**\n * Handler configuration for groups_inbound\n */\nexport interface GroupsInboundHandlerConfig {\n /**\n * Base path for the SCIM Groups endpoints (e.g., '/api/iam/Groups')\n */\n basePath?: string;\n}\n\n/**\n * Handler configuration for users_inbound\n */\nexport interface UsersInboundHandlerConfig {\n /**\n * Base path for the SCIM Users endpoints (e.g., '/api/iam/Users')\n */\n basePath?: string;\n}\n\n/**\n * Groups Outbound extension - for creating groups in external IAM providers.\n * Enabled when `url` is configured in IAMConfig.\n */\nexport type IAMGroupsOutbound = {\n /**\n * Create a new group in the external IAM provider\n * @param displayName - The display name for the group\n * @param options - Optional configuration for the group creation\n * @returns The created group resource from the provider\n */\n createGroup: (displayName: string, options?: CreateGroupOptions) => Promise<ScimResult<GroupResource>>;\n};\n\n/**\n * Groups Inbound extension - for receiving group provisioning from external IAM providers.\n * Enabled when `group_store` is configured in IAMConfig.\n */\nexport type IAMGroupsInbound = {\n /**\n * Handle inbound SCIM requests for group management.\n * Routes: GET/POST /Groups, GET/PUT/PATCH/DELETE /Groups/:id\n */\n handler: (request: Request, config?: GroupsInboundHandlerConfig) => Promise<Response>;\n};\n\n/**\n * Users Inbound extension - for receiving user provisioning from external IAM providers.\n * Enabled when `user_store` is configured in IAMConfig.\n */\nexport type IAMUsersInbound = {\n /**\n * Handle inbound SCIM requests for user management.\n * Routes: GET/POST /Users, GET/PUT/PATCH/DELETE /Users/:id\n */\n handler: (request: Request, config?: UsersInboundHandlerConfig) => Promise<Response>;\n};\n\n/**\n * Core IAM service interface.\n *\n * - Core functions are user-related (outbound to external IAM)\n * - `groups_outbound` is available when `url` is configured\n * - `groups_inbound` is available when `group_store` is configured\n * - `users_inbound` is available when `user_store` is configured\n */\nexport type IAM = IAMConfig & {\n /**\n * Create a new user/account in the external IAM provider\n * Only available when `url` is configured.\n */\n createUser?: (user: User, options?: CreateUserOptions) => Promise<ScimResult<User>>;\n\n /**\n * Get the configured external SCIM base URL\n */\n getBaseUrl: () => string | undefined;\n\n /**\n * Groups Outbound extension - create groups in external IAM provider.\n * Available when `url` is configured in IAMConfig.\n */\n groups_outbound?: IAMGroupsOutbound;\n\n /**\n * Groups Inbound extension - receive group provisioning from external IAM.\n * Available when `group_store` is configured in IAMConfig.\n */\n groups_inbound?: IAMGroupsInbound;\n\n /**\n * Users Inbound extension - receive user provisioning from external IAM.\n * Available when `user_store` is configured in IAMConfig.\n */\n users_inbound?: IAMUsersInbound;\n\n /**\n * Framework-agnostic request handler for IAM endpoints.\n * Routes to users_inbound or groups_inbound handlers based on the request path.\n */\n handler: (request: Request, config?: IAMHandlerConfig) => Promise<Response>;\n};\n\nconst SCIM_CONTENT_TYPE = 'application/scim+json';\n\n/**\n * Send SCIM error response\n */\nfunction scimErrorResponse(status: number, detail: string, scimType?: string): Response {\n return new Response(\n JSON.stringify({\n schemas: ['urn:ietf:params:scim:api:messages:2.0:Error'],\n status: String(status),\n scimType,\n detail,\n }),\n {\n status,\n headers: { 'Content-Type': SCIM_CONTENT_TYPE },\n },\n );\n}\n\n/**\n * Send SCIM list response\n */\nfunction scimListResponse<T>(resources: T[]): Response {\n return new Response(\n JSON.stringify({\n schemas: ['urn:ietf:params:scim:api:messages:2.0:ListResponse'],\n totalResults: resources.length,\n startIndex: 1,\n itemsPerPage: resources.length,\n Resources: resources,\n }),\n {\n status: 200,\n headers: { 'Content-Type': SCIM_CONTENT_TYPE },\n },\n );\n}\n\n/**\n * Send SCIM resource response\n */\nfunction scimResourceResponse<T>(resource: T, status = 200): Response {\n return new Response(JSON.stringify(resource), {\n status,\n headers: { 'Content-Type': SCIM_CONTENT_TYPE },\n });\n}\n\n/**\n * Convert StoredGroup to GroupResource for SCIM response\n */\nfunction storedGroupToResource(group: StoredGroup): GroupResource {\n return {\n schemas: ['urn:ietf:params:scim:schemas:core:2.0:Group'],\n id: group.id,\n externalId: group.externalId,\n displayName: group.displayName,\n members: group.members,\n meta: {\n resourceType: 'Group',\n created: group.createdAt.toISOString(),\n lastModified: group.updatedAt.toISOString(),\n },\n };\n}\n\n/**\n * Generate a UUID for new resources\n */\nfunction generateId(): string {\n return crypto.randomUUID();\n}\n\n/**\n * Creates an IAM service instance.\n *\n * - If `url` is configured, enables outbound SCIM operations to external IAM\n * - If `group_store` is configured, enables inbound SCIM operations from external IAM\n *\n * @param config - IAM configuration\n * @param workload - Workload instance for authentication\n * @returns IAM service instance\n */\nexport function iam(config: IAMConfig, workload: Workload): IAM {\n const { url, group_store } = config;\n\n /**\n * Build headers for outgoing SCIM request using workload auth\n */\n async function buildHeaders(): Promise<Headers> {\n const token = await workload.getToken();\n\n return new Headers({\n 'Content-Type': SCIM_CONTENT_TYPE,\n Accept: SCIM_CONTENT_TYPE,\n Authorization: `Bearer ${token}`,\n });\n }\n\n /**\n * Make an outgoing SCIM request to external IAM\n */\n async function scimRequest<T>(\n method: string,\n endpoint: string,\n body?: unknown,\n validator?: StandardSchemaV1<unknown, T>,\n ): Promise<ScimResult<T>> {\n if (!url) {\n return {\n success: false,\n error: {\n schemas: ['urn:ietf:params:scim:api:messages:2.0:Error'],\n status: '500',\n detail: 'IAM URL not configured for outgoing requests',\n },\n status: 500,\n };\n }\n\n const requestUrl = `${url}${endpoint}`;\n\n try {\n const headers = await buildHeaders();\n const response = await fetch(requestUrl, {\n method,\n headers,\n body: body ? JSON.stringify(body) : undefined,\n });\n\n const responseData = await response.json();\n\n if (!response.ok) {\n return {\n success: false,\n error: responseData as ScimError,\n status: response.status,\n };\n }\n\n // Validate response if validator provided\n if (validator) {\n const validationResult = await validator['~standard'].validate(responseData);\n if ('issues' in validationResult) {\n return {\n success: false,\n error: {\n schemas: ['urn:ietf:params:scim:api:messages:2.0:Error'],\n status: '400',\n scimType: 'invalidValue',\n detail: `Response validation failed: ${validationResult.issues?.map((i) => i.message).join('; ')}`,\n },\n status: 400,\n };\n }\n return {\n success: true,\n data: validationResult.value,\n status: response.status,\n };\n }\n\n return {\n success: true,\n data: responseData as T,\n status: response.status,\n };\n } catch (error) {\n return {\n success: false,\n error: {\n schemas: ['urn:ietf:params:scim:api:messages:2.0:Error'],\n status: '500',\n detail: error instanceof Error ? error.message : 'Unknown error occurred',\n },\n status: 500,\n };\n }\n }\n\n /**\n * Get the configured SCIM base URL\n */\n function getBaseUrl(): string | undefined {\n return url;\n }\n\n // Build groups_outbound if url is configured\n let groups_outbound: IAMGroupsOutbound | undefined;\n let createUser: ((user: User, options?: CreateUserOptions) => Promise<ScimResult<User>>) | undefined;\n\n if (url) {\n /**\n * Create a new user/account in the external IAM provider\n */\n createUser = async (user: User, options?: CreateUserOptions): Promise<ScimResult<User>> => {\n const userPayload: User = {\n ...user,\n schemas: user.schemas ?? [\n 'urn:ietf:params:scim:schemas:core:2.0:User',\n 'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User',\n ],\n };\n\n const validator = options?.validation ?? userSchema('es-iam');\n return scimRequest<User>('POST', '/Users', userPayload, validator);\n };\n\n /**\n * Create a new group in the external IAM provider\n */\n async function createGroup(displayName: string, options?: CreateGroupOptions): Promise<ScimResult<GroupResource>> {\n const groupPayload: GroupResource = {\n schemas: ['urn:ietf:params:scim:schemas:core:2.0:Group'],\n displayName,\n externalId: options?.externalId,\n members: options?.members,\n };\n\n const validator = options?.validation ?? groupResourceSchema('es-iam');\n return scimRequest<GroupResource>('POST', '/Groups', groupPayload, validator);\n }\n\n groups_outbound = {\n createGroup,\n };\n }\n\n // Build groups_inbound if group_store is configured\n let groups_inbound: IAMGroupsInbound | undefined;\n\n if (group_store) {\n // Capture reference to avoid undefined checks in nested functions\n const store = group_store;\n\n /**\n * Validate authorization header for inbound requests\n */\n const validateAuth = async (request: Request): Promise<boolean> => {\n const auth = request.headers.get('Authorization');\n if (!auth || !auth.startsWith('Bearer ')) {\n return false;\n }\n\n // Validate the token using workload\n try {\n const token = auth.substring(7);\n const result = await workload.validateToken(token);\n return result.valid;\n } catch {\n return false;\n }\n };\n\n /**\n * Handle inbound SCIM requests for group management\n */\n const handler = async (request: Request, handlerConfig?: GroupsInboundHandlerConfig): Promise<Response> => {\n // Validate auth\n const isAuthorized = await validateAuth(request);\n if (!isAuthorized) {\n return scimErrorResponse(401, 'Authorization required');\n }\n\n const urlObj = new URL(request.url);\n const basePath = handlerConfig?.basePath ?? '/Groups';\n let path = urlObj.pathname;\n\n // Remove base path to get the resource path\n if (path.startsWith(basePath)) {\n path = path.substring(basePath.length);\n }\n\n // Parse group ID from path\n const groupIdMatch = path.match(/^\\/([^/]+)$/);\n const groupId = groupIdMatch?.[1];\n\n const method = request.method;\n\n try {\n // Route to appropriate handler\n if (groupId) {\n // Operations on specific group\n switch (method) {\n case 'GET':\n return await handleGetGroup(groupId);\n case 'PUT':\n return await handleReplaceGroup(request, groupId);\n case 'PATCH':\n return await handlePatchGroup(request, groupId);\n case 'DELETE':\n return await handleDeleteGroup(groupId);\n default:\n return scimErrorResponse(405, 'Method not allowed');\n }\n } else if (path === '' || path === '/') {\n // Operations on groups collection\n switch (method) {\n case 'GET':\n return await handleListGroups();\n case 'POST':\n return await handleCreateGroup(request);\n default:\n return scimErrorResponse(405, 'Method not allowed');\n }\n }\n\n return scimErrorResponse(404, 'Resource not found');\n } catch (error) {\n console.error('Groups inbound handler error:', error);\n return scimErrorResponse(500, error instanceof Error ? error.message : 'Internal server error');\n }\n };\n\n /**\n * List all groups\n */\n const handleListGroups = async (): Promise<Response> => {\n const groups = await store.list();\n const resources = groups.map(storedGroupToResource);\n return scimListResponse(resources);\n };\n\n /**\n * Get a group by ID\n */\n const handleGetGroup = async (id: string): Promise<Response> => {\n const group = await store.get(id);\n if (!group) {\n return scimErrorResponse(404, `Group ${id} not found`, 'invalidValue');\n }\n return scimResourceResponse(storedGroupToResource(group));\n };\n\n /**\n * Create a new group\n */\n const handleCreateGroup = async (request: Request): Promise<Response> => {\n const body = (await request.json()) as Partial<GroupResource>;\n\n if (!body.displayName) {\n return scimErrorResponse(400, 'displayName is required', 'invalidValue');\n }\n\n const now = new Date();\n const storedGroup: StoredGroup<Record<string, unknown>> = {\n id: generateId(),\n displayName: body.displayName,\n externalId: body.externalId,\n members: body.members,\n createdAt: now,\n updatedAt: now,\n };\n\n await store.upsert(storedGroup as StoredGroup);\n return scimResourceResponse(storedGroupToResource(storedGroup as StoredGroup), 201);\n };\n\n /**\n * Replace a group (PUT)\n */\n const handleReplaceGroup = async (request: Request, id: string): Promise<Response> => {\n const existing = await store.get(id);\n if (!existing) {\n return scimErrorResponse(404, `Group ${id} not found`, 'invalidValue');\n }\n\n const body = (await request.json()) as Partial<GroupResource>;\n\n const updatedGroup: StoredGroup<Record<string, unknown>> = {\n ...existing,\n displayName: body.displayName ?? existing.displayName,\n externalId: body.externalId,\n members: body.members,\n updatedAt: new Date(),\n };\n\n await store.upsert(updatedGroup as StoredGroup);\n return scimResourceResponse(storedGroupToResource(updatedGroup as StoredGroup));\n };\n\n /**\n * Patch a group (PATCH)\n */\n const handlePatchGroup = async (request: Request, id: string): Promise<Response> => {\n const existing = await store.get(id);\n if (!existing) {\n return scimErrorResponse(404, `Group ${id} not found`, 'invalidValue');\n }\n\n const body = (await request.json()) as {\n Operations?: Array<{ op: string; path?: string; value?: unknown }>;\n };\n const operations = body.Operations ?? [];\n\n const updated = { ...existing };\n\n for (const op of operations) {\n if (op.op === 'replace' && op.path && op.value !== undefined) {\n if (op.path === 'displayName') {\n updated.displayName = op.value as string;\n }\n } else if (op.op === 'add' && op.path && op.value !== undefined) {\n if (op.path === 'members') {\n const newMembers = op.value as GroupMember[];\n updated.members = [...(updated.members ?? []), ...newMembers];\n }\n } else if (op.op === 'remove' && op.path) {\n if (op.path.startsWith('members[')) {\n // Parse member filter like members[value eq \"user-id\"]\n const match = op.path.match(/members\\[value eq \"([^\"]+)\"\\]/);\n if (match) {\n updated.members = (updated.members ?? []).filter((m) => m.value !== match[1]);\n }\n }\n }\n }\n\n updated.updatedAt = new Date();\n await store.upsert(updated);\n return scimResourceResponse(storedGroupToResource(updated));\n };\n\n /**\n * Delete a group\n */\n const handleDeleteGroup = async (id: string): Promise<Response> => {\n const existing = await store.get(id);\n if (!existing) {\n return scimErrorResponse(404, `Group ${id} not found`, 'invalidValue');\n }\n\n await store.delete(id);\n return new Response(null, { status: 204 });\n }\n\n groups_inbound = {\n handler,\n };\n }\n\n // Build users_inbound if user_store is configured\n let users_inbound: IAMUsersInbound | undefined;\n\n if (config.user_store) {\n // Capture reference to avoid undefined checks in nested functions\n const store = config.user_store;\n\n /**\n * Validate authorization header for inbound requests\n */\n async function validateAuth(request: Request): Promise<boolean> {\n const auth = request.headers.get('Authorization');\n if (!auth || !auth.startsWith('Bearer ')) {\n return false;\n }\n\n // Validate the token using workload\n try {\n const token = auth.substring(7);\n const result = await workload.validateToken(token);\n return result.valid;\n } catch {\n return false;\n }\n }\n\n /**\n * Convert StoredUser to SCIM User for response\n */\n const storedUserToScimUser = (storedUser: import('./user-store').StoredUser): User => {\n return {\n schemas: [\n 'urn:ietf:params:scim:schemas:core:2.0:User',\n 'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User',\n ],\n id: storedUser.id,\n userName: storedUser.userName || storedUser.email || storedUser.id,\n displayName: storedUser.name || storedUser.userName || storedUser.email,\n name: storedUser.name\n ? {\n givenName: storedUser.name.split(' ')[0],\n familyName: storedUser.name.split(' ').slice(1).join(' ') || undefined,\n }\n : undefined,\n emails: storedUser.email ? [{ value: storedUser.email, primary: true }] : [],\n active: true,\n meta: {\n resourceType: 'User',\n created: storedUser.createdAt.toISOString(),\n lastModified: storedUser.updatedAt.toISOString(),\n },\n };\n };\n\n /**\n * Convert SCIM User to StoredUser for storage\n */\n const scimUserToStoredUser = (scimUser: User): import('./user-store').StoredUser => {\n const now = new Date();\n const primaryEmail = scimUser.emails?.find((e) => e.primary)?.value || scimUser.emails?.[0]?.value;\n const name = scimUser.name\n ? `${scimUser.name.givenName || ''} ${scimUser.name.familyName || ''}`.trim()\n : scimUser.displayName;\n\n // Create minimal SSO data for IAM-provisioned users\n const userId = scimUser.id || generateId();\n const userName = scimUser.userName || primaryEmail || userId;\n \n return {\n id: userId,\n userName,\n name: name || scimUser.displayName || userName,\n email: primaryEmail || userName,\n avatarUrl: scimUser.profileUrl,\n sso: {\n profile: {\n sub: userId,\n iss: 'iam-provisioned',\n aud: 'iam-provisioned',\n exp: Math.floor(Date.now() / 1000) + 3600,\n iat: Math.floor(Date.now() / 1000),\n email: primaryEmail || userName,\n email_verified: true,\n name: name || scimUser.displayName || userName,\n preferred_username: userName,\n },\n tenant: {\n id: 'iam-provisioned',\n name: 'IAM Provisioned',\n },\n scope: 'openid profile email',\n tokenType: 'Bearer',\n expires: new Date(Date.now() + 3600 * 1000),\n },\n createdAt: scimUser.meta?.created ? new Date(scimUser.meta.created) : now,\n updatedAt: scimUser.meta?.lastModified ? new Date(scimUser.meta.lastModified) : now,\n } as import('./user-store').StoredUser;\n };\n\n /**\n * Handle inbound SCIM requests for user management\n */\n const handler = async (request: Request, handlerConfig?: UsersInboundHandlerConfig): Promise<Response> => {\n // Validate auth\n const isAuthorized = await validateAuth(request);\n if (!isAuthorized) {\n return scimErrorResponse(401, 'Authorization required');\n }\n\n const urlObj = new URL(request.url);\n const basePath = handlerConfig?.basePath ?? '/Users';\n let path = urlObj.pathname;\n\n // Remove base path to get the resource path\n if (path.startsWith(basePath)) {\n path = path.substring(basePath.length);\n }\n\n // Parse user ID from path\n const userIdMatch = path.match(/^\\/([^/]+)$/);\n const userId = userIdMatch?.[1];\n\n const method = request.method;\n\n try {\n // Route to appropriate handler\n if (userId) {\n // Operations on specific user\n switch (method) {\n case 'GET':\n return await handleGetUser(userId);\n case 'PUT':\n return await handleReplaceUser(request, userId);\n case 'PATCH':\n return await handlePatchUser(request, userId);\n case 'DELETE':\n return await handleDeleteUser(userId);\n default:\n return scimErrorResponse(405, 'Method not allowed');\n }\n } else if (path === '' || path === '/') {\n // Operations on users collection\n switch (method) {\n case 'GET':\n return await handleListUsers();\n case 'POST':\n return await handleCreateUser(request);\n default:\n return scimErrorResponse(405, 'Method not allowed');\n }\n }\n\n return scimErrorResponse(404, 'Resource not found');\n } catch (error) {\n console.error('Users inbound handler error:', error);\n return scimErrorResponse(500, error instanceof Error ? error.message : 'Internal server error');\n }\n }\n\n /**\n * List all users\n */\n const handleListUsers = async (): Promise<Response> => {\n // Note: UserStore doesn't have a list method, so we'd need to implement it\n // For now, return empty list - this would need to be enhanced based on UserStore interface\n return scimListResponse([]);\n };\n\n /**\n * Get a user by ID\n */\n const handleGetUser = async (id: string): Promise<Response> => {\n const user = await store.get(id);\n if (!user) {\n return scimErrorResponse(404, `User ${id} not found`, 'invalidValue');\n }\n return scimResourceResponse(storedUserToScimUser(user));\n };\n\n /**\n * Create a new user\n */\n const handleCreateUser = async (request: Request): Promise<Response> => {\n const body = (await request.json()) as Partial<User>;\n\n if (!body.userName && !body.emails?.[0]?.value) {\n return scimErrorResponse(400, 'userName or email is required', 'invalidValue');\n }\n\n const storedUser = scimUserToStoredUser(body as User);\n await store.upsert(storedUser);\n return scimResourceResponse(storedUserToScimUser(storedUser), 201);\n };\n\n /**\n * Replace a user (PUT)\n */\n const handleReplaceUser = async (request: Request, id: string): Promise<Response> => {\n const existing = await store.get(id);\n if (!existing) {\n return scimErrorResponse(404, `User ${id} not found`, 'invalidValue');\n }\n\n const body = (await request.json()) as Partial<User>;\n const updatedUser = scimUserToStoredUser({ ...body, id } as User);\n updatedUser.createdAt = existing.createdAt;\n updatedUser.updatedAt = new Date();\n\n await store.upsert(updatedUser);\n return scimResourceResponse(storedUserToScimUser(updatedUser));\n };\n\n /**\n * Patch a user (PATCH)\n */\n const handlePatchUser = async (request: Request, id: string): Promise<Response> => {\n const existing = await store.get(id);\n if (!existing) {\n return scimErrorResponse(404, `User ${id} not found`, 'invalidValue');\n }\n\n const body = (await request.json()) as {\n Operations?: Array<{ op: string; path?: string; value?: unknown }>;\n };\n const operations = body.Operations ?? [];\n\n const updated = { ...existing };\n\n for (const op of operations) {\n if (op.op === 'replace' && op.path && op.value !== undefined) {\n if (op.path === 'displayName') {\n updated.name = op.value as string;\n } else if (op.path === 'userName') {\n updated.userName = op.value as string;\n } else if (op.path.startsWith('name.')) {\n const namePart = op.path.split('.')[1] as 'givenName' | 'familyName';\n if (!updated.name) updated.name = '';\n // Simple name handling - in production you'd want more sophisticated parsing\n if (namePart === 'givenName') {\n updated.name = `${op.value as string} ${updated.name.split(' ').slice(1).join(' ')}`.trim();\n } else if (namePart === 'familyName') {\n updated.name = `${updated.name.split(' ')[0]} ${op.value as string}`.trim();\n }\n } else if (op.path === 'emails') {\n // Note: StoredUser doesn't have emails array, only email string\n // We'll extract the primary email and update the email field\n const emails = op.value as Array<{ value: string; primary?: boolean }>;\n const primaryEmail = emails?.find((e) => e.primary)?.value || emails?.[0]?.value;\n if (primaryEmail) updated.email = primaryEmail;\n }\n } else if (op.op === 'add' && op.path && op.value !== undefined) {\n if (op.path === 'emails') {\n // Note: StoredUser doesn't have emails array, only email string\n // We'll extract the primary email and update the email field\n const newEmails = op.value as Array<{ value: string; primary?: boolean }>;\n const primaryEmail = newEmails?.find((e) => e.primary)?.value || newEmails?.[0]?.value;\n if (primaryEmail) updated.email = primaryEmail;\n }\n } else if (op.op === 'remove' && op.path) {\n if (op.path === 'displayName') {\n updated.name = '';\n }\n }\n }\n\n updated.updatedAt = new Date();\n await store.upsert(updated);\n return scimResourceResponse(storedUserToScimUser(updated));\n };\n\n /**\n * Delete a user\n */\n const handleDeleteUser = async (id: string): Promise<Response> => {\n const existing = await store.get(id);\n if (!existing) {\n return scimErrorResponse(404, `User ${id} not found`, 'invalidValue');\n }\n\n await store.delete(id);\n return new Response(null, { status: 204 });\n }\n\n users_inbound = {\n handler,\n };\n }\n\n /**\n * Top-level handler that routes to users_inbound or groups_inbound based on path\n */\n async function topLevelHandler(request: Request, handlerConfig?: IAMHandlerConfig): Promise<Response> {\n const urlObj = new URL(request.url);\n const path = urlObj.pathname;\n\n const usersUrl = handlerConfig?.usersUrl ?? config.usersUrl ?? '/api/iam/Users';\n const groupsUrl = handlerConfig?.groupsUrl ?? config.groupsUrl ?? '/api/iam/Groups';\n\n // Route to users handler if path matches usersUrl\n if (path.startsWith(usersUrl) && users_inbound) {\n return users_inbound.handler(request, { basePath: usersUrl });\n }\n\n // Route to groups handler if path matches groupsUrl\n if (path.startsWith(groupsUrl) && groups_inbound) {\n return groups_inbound.handler(request, { basePath: groupsUrl });\n }\n\n // If neither matches, return 404\n return scimErrorResponse(404, 'Resource not found');\n }\n\n return {\n ...config,\n createUser,\n getBaseUrl,\n groups_outbound,\n groups_inbound,\n users_inbound,\n handler: topLevelHandler,\n } as IAM;\n}\n",
6
7
  "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
8
  "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
+ "import type { EnterpriseStandard } from '.';\nimport type { Session, SessionStore } from './session-store';\nimport type { IdTokenClaims, OidcCallbackParams, TokenResponse } from './types/oidc-schema';\nimport { idTokenClaimsSchema, oidcCallbackSchema, tokenResponseSchema } from './types/oidc-schema';\nimport type { StandardSchemaV1 } from './types/standard-schema';\nimport type { User } from './types/user';\nimport type { StoredUser, UserStore } from './user-store';\nimport { must } from './utils';\n\nexport type SSOConfig<TSessionData = {}, TUserData = {}> = {\n authority?: string;\n token_url?: string;\n authorization_url?: string;\n client_id?: string;\n client_secret?: 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 * Optional handler defaults. These are merged with per-call overrides in\n * `sso.handler`, with per-call values taking precedence.\n */\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 /**\n * Optional user store for persisting user profiles from SSO authentication.\n * When configured, users are automatically stored/updated on each login.\n */\n user_store?: UserStore<TUserData>;\n /**\n * Enable Just-In-Time (JIT) user provisioning.\n * When enabled, new users are automatically created in the user_store on their first login.\n * When disabled (default), only existing users in the user_store are updated on login.\n * Requires user_store to be configured.\n * @default false\n */\n enable_jit_user_provisioning?: boolean;\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 = {}, TUserData = {}> = SSOConfig<\n TSessionData,\n TUserData\n> & {\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 = {}, TUserData = {}> = \n SSOConfigWithDefaults<TSessionData, TUserData> & {\n getUser: (request: Request) => Promise<User | undefined>;\n getRequiredUser: (request: Request) => Promise<User>;\n getJwt: (request: Request) => Promise<string | undefined>;\n initiateLogin: (config: LoginConfig, requestUrl?: string) => Promise<Response>;\n logout: (request: Request, config?: LoginConfig) => Promise<Response>;\n callbackHandler: (request: Request) => Promise<Response>;\n handler: (request: Request) => Promise<Response>;\n };\n\nconst jwksCache = new Map<string, JWKS>();\n\nexport function sso<TSessionData = {}, TUserData = {}>(\n config?: SSOConfig<TSessionData, TUserData>,\n): SSO<TSessionData, TUserData> {\n let configWithDefaults: SSOConfigWithDefaults<TSessionData, TUserData> | undefined;\n\n const handlerDefaults = {\n loginUrl: config?.loginUrl,\n userUrl: config?.userUrl,\n errorUrl: config?.errorUrl,\n landingUrl: config?.landingUrl,\n tokenUrl: config?.tokenUrl,\n refreshUrl: config?.refreshUrl,\n jwksUrl: config?.jwksUrl,\n logoutUrl: config?.logoutUrl,\n logoutBackChannelUrl: config?.logoutBackChannelUrl,\n validation: config?.validation,\n };\n\n configWithDefaults = !config\n ? undefined\n : {\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<User | undefined> {\n if (!configWithDefaults) {\n throw new Error('Enterprise Standard SSO Manager not initialized');\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<User> {\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, requestUrl?: string) {\n if (!configWithDefaults) {\n throw new Error('Enterprise Standard SSO Manager not initialized');\n }\n\n const state = generateRandomString();\n const codeVerifier = generateRandomString(64);\n\n // Normalize redirect_uri - use request URL if available, otherwise use the stored value\n let normalizedRedirectUri = configWithDefaults.redirect_uri;\n try {\n new URL(normalizedRedirectUri);\n } catch {\n // If redirect_uri is not a valid URL, try to construct it from request URL\n if (requestUrl) {\n try {\n const baseUrl = new URL(requestUrl);\n const path = normalizedRedirectUri.startsWith('//') \n ? normalizedRedirectUri.slice(1) \n : normalizedRedirectUri.startsWith('/')\n ? normalizedRedirectUri\n : `/${normalizedRedirectUri}`;\n normalizedRedirectUri = new URL(path, baseUrl.origin).toString();\n } catch {\n // If we can't construct it, use authorization_url's origin as fallback\n try {\n const authUrl = new URL(configWithDefaults.authorization_url);\n const path = normalizedRedirectUri.startsWith('//') \n ? normalizedRedirectUri.slice(1) \n : normalizedRedirectUri.startsWith('/')\n ? normalizedRedirectUri\n : `/${normalizedRedirectUri}`;\n normalizedRedirectUri = new URL(path, authUrl.origin).toString();\n } catch {\n throw new Error(`Invalid redirect_uri: \"${configWithDefaults.redirect_uri}\". It must be a valid absolute URL.`);\n }\n }\n }\n }\n\n const url = new URL(configWithDefaults.authorization_url);\n url.searchParams.append('client_id', configWithDefaults.client_id);\n url.searchParams.append('redirect_uri', normalizedRedirectUri);\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 if (!configWithDefaults) {\n throw new Error('Enterprise Standard SSO Manager not initialized');\n }\n\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 (configWithDefaults.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 configWithDefaults.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) {\n throw new Error('Enterprise Standard SSO Manager not initialized');\n }\n if (!configWithDefaults.session_store) {\n throw new Error('Back-Channel Logout requires session_store configuration');\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(request: Request, validation?: SSOHandlerConfig['validation']) {\n if (!configWithDefaults) {\n throw new Error('Enterprise Standard SSO Manager not initialized');\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, request.url);\n const user = await parseUser(tokenResponse, validation);\n\n // Create session if session_store is configured\n if (configWithDefaults.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 configWithDefaults.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 // Store/update user if user_store is configured\n if (configWithDefaults.user_store) {\n try {\n const sub = user.id;\n\n if (sub) {\n const now = new Date();\n const existingUser = await configWithDefaults.user_store.get(sub);\n\n // Only create new users if JIT provisioning is enabled\n // Always update existing users\n if (existingUser || configWithDefaults.enable_jit_user_provisioning) {\n // Merge existing custom data with updated user info\n // This preserves TUserData fields that were previously set\n const storedUser = {\n ...(existingUser ?? {}),\n ...user,\n id: sub,\n createdAt: existingUser?.createdAt ?? now,\n updatedAt: now,\n } as unknown as StoredUser<TUserData>;\n\n await configWithDefaults.user_store.upsert(storedUser);\n } else {\n console.warn('JIT user provisioning disabled: user not found in store and will not be created');\n }\n } else {\n console.warn('User storage skipped: missing sub in ID token claims');\n }\n } catch (error) {\n console.warn('Failed to store user:', error);\n // Don't fail the login if user storage 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) {\n throw new Error('Enterprise Standard SSO Manager not initialized');\n }\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 requestUrl?: string,\n ): Promise<TokenResponse> {\n if (!configWithDefaults) {\n throw new Error('Enterprise Standard SSO Manager not initialized');\n }\n const tokenUrl = configWithDefaults.token_url;\n\n // Normalize redirect_uri - use the same logic as in initiateLogin\n let normalizedRedirectUri = configWithDefaults.redirect_uri;\n try {\n new URL(normalizedRedirectUri);\n } catch {\n // If redirect_uri is not a valid URL, try to construct it from request URL\n if (requestUrl) {\n try {\n const baseUrl = new URL(requestUrl);\n const path = normalizedRedirectUri.startsWith('//') \n ? normalizedRedirectUri.slice(1) \n : normalizedRedirectUri.startsWith('/')\n ? normalizedRedirectUri\n : `/${normalizedRedirectUri}`;\n normalizedRedirectUri = new URL(path, baseUrl.origin).toString();\n } catch {\n // If we can't construct it, use token_url's origin as fallback\n try {\n const tokenUrlObj = new URL(tokenUrl);\n const path = normalizedRedirectUri.startsWith('//') \n ? normalizedRedirectUri.slice(1) \n : normalizedRedirectUri.startsWith('/')\n ? normalizedRedirectUri\n : `/${normalizedRedirectUri}`;\n normalizedRedirectUri = new URL(path, tokenUrlObj.origin).toString();\n } catch {\n throw new Error(`Invalid redirect_uri: \"${configWithDefaults.redirect_uri}\". It must be a valid absolute URL.`);\n }\n }\n }\n }\n\n const body = new URLSearchParams();\n body.append('grant_type', 'authorization_code');\n body.append('code', code);\n body.append('redirect_uri', normalizedRedirectUri);\n body.append('client_id', configWithDefaults.client_id);\n if (configWithDefaults.client_secret) {\n body.append('client_secret', configWithDefaults.client_secret);\n }\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(`Token response validation failed: ${tokenResult.issues?.map((i) => i.message).join('; ')}`);\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) {\n throw new Error('Enterprise Standard SSO Manager not initialized');\n }\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) {\n throw new Error('Enterprise Standard SSO Manager not initialized');\n }\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 if (!configWithDefaults) {\n throw new Error('Enterprise Standard SSO Manager not initialized');\n }\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(`ID token claims validation failed: ${claimsResult.issues?.map((i) => i.message).join('; ')}`);\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 if (!configWithDefaults) {\n throw new Error('Enterprise Standard SSO Manager not initialized');\n }\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 if (!configWithDefaults) {\n throw new Error('Enterprise Standard SSO Manager not initialized');\n }\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 if (!configWithDefaults) {\n throw new Error('Enterprise Standard SSO Manager not initialized');\n }\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 {\n loginUrl,\n userUrl,\n errorUrl,\n landingUrl,\n tokenUrl,\n refreshUrl,\n logoutUrl,\n logoutBackChannelUrl,\n jwksUrl,\n validation,\n } = { ...handlerDefaults, ...handlerConfig };\n\n if (!configWithDefaults) {\n throw new Error('Enterprise Standard SSO Manager not initialized');\n }\n\n if (!loginUrl) {\n console.error('loginUrl is required');\n }\n\n const path = new URL(request.url).pathname;\n // Handle both absolute URLs and relative paths for redirect_uri\n let redirectUriPath: string;\n try {\n // Try to parse as absolute URL first\n redirectUriPath = new URL(configWithDefaults.redirect_uri).pathname;\n } catch {\n // If it's not a valid URL, try to construct from request URL\n try {\n const requestUrl = new URL(request.url);\n // If redirect_uri starts with //, it's a protocol-relative URL, treat as path\n const redirectUri = configWithDefaults.redirect_uri.startsWith('//')\n ? configWithDefaults.redirect_uri.slice(1)\n : configWithDefaults.redirect_uri;\n // Construct full URL from request origin + redirect_uri path\n redirectUriPath = new URL(redirectUri, requestUrl.origin).pathname;\n } catch {\n // Fallback: treat as path directly\n redirectUriPath = configWithDefaults.redirect_uri.startsWith('/')\n ? configWithDefaults.redirect_uri\n : `/${configWithDefaults.redirect_uri}`;\n }\n }\n if (redirectUriPath === path) {\n return callbackHandler(request, validation);\n }\n\n if (loginUrl === path) {\n return initiateLogin({\n landingUrl: landingUrl || '/',\n errorUrl,\n }, request.url);\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 if (!configWithDefaults) {\n throw new Error('Enterprise Standard SSO Manager not initialized');\n }\n\n return {\n ...configWithDefaults,\n getUser,\n getRequiredUser,\n getJwt,\n initiateLogin,\n logout,\n callbackHandler,\n handler,\n };\n}\n",
9
10
  "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",
11
+ "import type { StandardSchemaV1 } from './standard-schema';\n\n/**\n * JWT Assertion Claims for OAuth2 JWT Bearer Grant (RFC 7523) and OAuth2 Access Tokens\n * @see https://datatracker.ietf.org/doc/html/rfc7523\n * @see https://datatracker.ietf.org/doc/html/rfc9068\n */\nexport interface JWTAssertionClaims {\n /**\n * REQUIRED. Issuer - the workload identity (e.g., SPIFFE ID) or authorization server\n */\n iss: string;\n\n /**\n * REQUIRED. Subject - the workload identity or service account\n */\n sub: string;\n\n /**\n * OPTIONAL. Audience - may be a string or array of strings\n * Note: Required for JWT assertions, but may be absent in OAuth2 access tokens\n */\n aud?: string | string[];\n\n /**\n * REQUIRED. Expiration time (Unix timestamp)\n */\n exp: number;\n\n /**\n * REQUIRED. Issued at time (Unix timestamp)\n */\n iat: number;\n\n /**\n * OPTIONAL. JWT ID - unique identifier for this token\n * Note: Required for JWT assertions, optional for access tokens\n */\n jti?: string;\n\n /**\n * OPTIONAL. Requested OAuth scopes (space-delimited)\n */\n scope?: string;\n\n /**\n * Allow additional claims for extensibility\n */\n [key: string]: unknown;\n}\n\n/**\n * Creates a StandardSchemaV1 for validating JWT Assertion Claims.\n * @param vendor - The name of the vendor creating this schema\n * @returns A StandardSchemaV1 instance for JWT Assertion Claims validation\n */\nexport function jwtAssertionClaimsSchema(\n vendor: string,\n): StandardSchemaV1<Record<string, unknown>, JWTAssertionClaims> {\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: JWTAssertionClaims = { ...claims } as JWTAssertionClaims;\n\n // Validate required string fields\n const requiredStringFields = ['iss', 'sub'];\n for (const field of requiredStringFields) {\n if (field in claims) {\n if (typeof claims[field] !== 'string') {\n issues.push({\n message: `${field} must be a string`,\n path: [field],\n });\n }\n } else {\n issues.push({\n message: `${field} is required`,\n path: [field],\n });\n }\n }\n\n // Validate optional aud field (can be string or array of strings)\n if ('aud' in claims && claims.aud !== undefined) {\n const aud = claims.aud;\n if (typeof aud !== 'string' && !Array.isArray(aud)) {\n issues.push({\n message: 'aud must be a string or array of strings',\n path: ['aud'],\n });\n } else if (Array.isArray(aud) && !aud.every((a) => typeof a === 'string')) {\n issues.push({\n message: 'aud array must contain only strings',\n path: ['aud'],\n });\n }\n }\n\n // Validate optional string fields\n const optionalStringFields = ['jti', 'scope'];\n for (const field of optionalStringFields) {\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 required number fields\n const requiredNumberFields = ['exp', 'iat'];\n for (const field of requiredNumberFields) {\n if (field in claims) {\n if (typeof claims[field] !== 'number') {\n issues.push({\n message: `${field} must be a number`,\n path: [field],\n });\n }\n } else {\n issues.push({\n message: `${field} is required`,\n path: [field],\n });\n }\n }\n\n if (issues.length > 0) {\n return { issues };\n }\n\n return { value: result };\n },\n },\n };\n}\n\n/**\n * Workload Token Response from OAuth2 token endpoint\n * @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.1\n */\nexport interface WorkloadTokenResponse {\n /**\n * REQUIRED. The access token issued by the authorization server.\n */\n access_token: string;\n\n /**\n * REQUIRED. The type of the token (typically \"Bearer\").\n */\n token_type: string;\n\n /**\n * RECOMMENDED. The lifetime in seconds of the access token.\n */\n expires_in?: number;\n\n /**\n * OPTIONAL. The scope of the access token.\n */\n scope?: string;\n\n /**\n * OPTIONAL. The refresh token (rarely used for workload identities).\n */\n refresh_token?: string;\n\n /**\n * OPTIONAL. The expiration time as an ISO 8601 string.\n */\n expires?: string;\n}\n\n/**\n * Creates a StandardSchemaV1 for validating Workload Token Responses.\n * @param vendor - The name of the vendor creating this schema\n * @returns A StandardSchemaV1 instance for Workload Token Response validation\n */\nexport function workloadTokenResponseSchema(\n vendor: string,\n): StandardSchemaV1<Record<string, unknown>, WorkloadTokenResponse> {\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<WorkloadTokenResponse> = {};\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 '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 ('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 ('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 ('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 field\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 (issues.length > 0) {\n return { issues };\n }\n\n return { value: result as WorkloadTokenResponse };\n },\n },\n };\n}\n\n/**\n * Token Validation Result\n */\nexport interface TokenValidationResult {\n /**\n * Whether the token is valid\n */\n valid: boolean;\n\n /**\n * The decoded and validated claims (if valid)\n */\n claims?: JWTAssertionClaims;\n\n /**\n * Error message (if invalid)\n */\n error?: string;\n\n /**\n * Token expiration time (if valid)\n */\n expiresAt?: Date;\n}\n",
12
+ "/**\n * Token caching for workload identity authentication.\n *\n * Token stores are optional but recommended for performance - they enable:\n * - Token caching to avoid repeated token acquisition\n * - Automatic token refresh before expiration\n * - Reduced load on authorization servers\n *\n * ## Token Caching Strategy\n *\n * Unlike session stores for user authentication, workload token stores cache\n * short-lived access tokens (typically 5 minutes) for service-to-service calls.\n *\n * **Default Behavior:**\n * - Tokens cached with 5-minute TTL\n * - Auto-refresh 60 seconds before expiration\n * - Expired tokens automatically removed\n *\n * ## Performance Characteristics\n *\n * | Backend | Lookup Time | Use Case |\n * |--------------|-------------|----------------------------|\n * | InMemory | <0.00005ms | Single-server deployments |\n * | Redis | 1-2ms | Multi-server deployments |\n * | Database | 5-20ms | Persistent token storage |\n *\n * ## Example Usage\n *\n * ```typescript\n * import { workload, InMemoryWorkloadTokenStore } from '@enterprisestandard/react/server';\n *\n * // With token caching\n * const workloadAuth = workload({\n * // ... other config\n * token_store: new InMemoryWorkloadTokenStore(),\n * auto_refresh: true, // Refresh before expiry\n * });\n *\n * // Without token caching (fetch new token each time)\n * const workloadAuth = workload({\n * // ... config without token_store\n * });\n * ```\n */\n\n/**\n * Cached workload token data.\n *\n * @template TExtended - Type-safe custom data that consumers can add to cached tokens\n */\nexport type CachedWorkloadToken<TExtended = object> = {\n /**\n * Workload identifier (typically SPIFFE ID).\n * Used as the primary key for token lookup.\n */\n workload_id: string;\n\n /**\n * OAuth2 access token (Bearer token)\n */\n access_token: string;\n\n /**\n * Token type (always \"Bearer\" for OAuth2)\n */\n token_type: string;\n\n /**\n * OAuth2 scopes granted for this token\n */\n scope?: string;\n\n /**\n * Timestamp when the token expires.\n * Used for automatic cleanup and refresh logic.\n */\n expires_at: Date;\n\n /**\n * Timestamp when the token was created/cached.\n */\n created_at: Date;\n\n /**\n * Optional refresh token (rarely used for workload identities)\n */\n refresh_token?: string;\n} & TExtended;\n\n/**\n * Abstract interface for workload token storage backends.\n *\n * Consumers can implement this interface to use different storage backends:\n * - Redis (recommended for multi-server deployments)\n * - Database (PostgreSQL, MySQL, etc. for persistence)\n * - Distributed cache (Memcached, etc.)\n * - Custom solutions\n *\n * @template TExtended - Type-safe custom data that consumers can add to cached tokens\n *\n * @example\n * ```typescript\n * // Custom token cache data\n * type MyTokenData = {\n * environment: string;\n * region: string;\n * };\n *\n * // Implement custom store with Redis\n * class RedisWorkloadTokenStore implements WorkloadTokenStore<MyTokenData> {\n * async set(token: CachedWorkloadToken<MyTokenData>): Promise<void> {\n * const ttl = Math.floor((token.expires_at.getTime() - Date.now()) / 1000);\n * await redis.setex(\n * `workload:token:${token.workload_id}`,\n * ttl,\n * JSON.stringify(token)\n * );\n * }\n *\n * async get(workload_id: string): Promise<CachedWorkloadToken<MyTokenData> | null> {\n * const data = await redis.get(`workload:token:${workload_id}`);\n * if (!data) return null;\n * const token = JSON.parse(data);\n * // Convert date strings back to Date objects\n * token.expires_at = new Date(token.expires_at);\n * token.created_at = new Date(token.created_at);\n * return token;\n * }\n *\n * // ... other methods\n * }\n * ```\n */\nexport interface WorkloadTokenStore<TExtended = object> {\n /**\n * Store or update a workload token in the cache.\n *\n * @param token - The token data to cache\n */\n set(token: CachedWorkloadToken<TExtended>): Promise<void>;\n\n /**\n * Retrieve a cached token by workload ID.\n *\n * @param workload_id - The workload identifier (e.g., SPIFFE ID)\n * @returns The cached token if found and not expired, null otherwise\n */\n get(workload_id: string): Promise<CachedWorkloadToken<TExtended> | null>;\n\n /**\n * Delete a cached token by workload ID.\n *\n * Used when explicitly revoking tokens or clearing cache.\n *\n * @param workload_id - The workload identifier to remove\n */\n delete(workload_id: string): Promise<void>;\n\n /**\n * Check if a valid (non-expired) token exists for a workload.\n *\n * @param workload_id - The workload identifier to check\n * @returns true if a valid token exists, false otherwise\n */\n isValid(workload_id: string): Promise<boolean>;\n\n /**\n * Remove all expired tokens from the cache.\n *\n * Should be called periodically to prevent memory leaks.\n */\n cleanup(): Promise<void>;\n}\n\n/**\n * In-memory workload token 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 (tokens not shared across instances)\n * - High availability scenarios (tokens lost on restart)\n * - Production applications with distributed architecture\n *\n * For production multi-server deployments, implement WorkloadTokenStore with Redis.\n *\n * @template TExtended - Type-safe custom data that consumers can add to cached tokens\n */\nexport class InMemoryWorkloadTokenStore<TExtended = object> implements WorkloadTokenStore<TExtended> {\n private tokens = new Map<string, CachedWorkloadToken<TExtended>>();\n\n async set(token: CachedWorkloadToken<TExtended>): Promise<void> {\n this.tokens.set(token.workload_id, token);\n }\n\n async get(workload_id: string): Promise<CachedWorkloadToken<TExtended> | null> {\n const token = this.tokens.get(workload_id);\n if (!token) return null;\n\n // Check if token is expired\n if (Date.now() > token.expires_at.getTime()) {\n this.tokens.delete(workload_id);\n return null;\n }\n\n return token;\n }\n\n async delete(workload_id: string): Promise<void> {\n this.tokens.delete(workload_id);\n }\n\n async isValid(workload_id: string): Promise<boolean> {\n const token = await this.get(workload_id);\n return token !== null;\n }\n\n async cleanup(): Promise<void> {\n const now = Date.now();\n for (const [workload_id, token] of this.tokens.entries()) {\n if (now > token.expires_at.getTime()) {\n this.tokens.delete(workload_id);\n }\n }\n }\n}\n",
13
+ "import type { EnterpriseStandard } from '.';\nimport type { StandardSchemaV1 } from './types/standard-schema';\nimport type { JWTAssertionClaims, TokenValidationResult, WorkloadTokenResponse } from './types/workload-schema';\nimport { jwtAssertionClaimsSchema, workloadTokenResponseSchema } from './types/workload-schema';\nimport { must } from './utils';\nimport { InMemoryWorkloadTokenStore, type WorkloadTokenStore } from './workload-token-store';\n\n/**\n * Common fields shared across all workload authentication modes\n */\ntype WorkloadConfigBase = {\n /**\n * OAuth2 token endpoint URL\n * REQUIRED for client role (token acquisition)\n */\n token_url?: string;\n\n /**\n * JWKS endpoint URL for public key retrieval\n * REQUIRED for server role (token validation)\n */\n jwks_uri?: string;\n\n /**\n * Expected token issuer URL for validation\n * RECOMMENDED for server role (token validation)\n */\n issuer?: string;\n\n /**\n * Target audience for tokens\n */\n audience?: string;\n\n /**\n * Default OAuth2 scopes (space-delimited)\n */\n scope?: string;\n\n /**\n * JWT assertion/token lifetime in seconds\n * @default 300 (5 minutes)\n */\n token_lifetime?: number;\n\n /**\n * Refresh threshold in seconds (refresh token this many seconds before expiry)\n * @default 60\n */\n refresh_threshold?: number;\n\n /**\n * Optional token store for caching access tokens\n */\n token_store?: WorkloadTokenStore;\n\n /**\n * Automatically refresh tokens before expiration\n * @default true\n */\n auto_refresh?: boolean;\n\n /**\n * Optional RFC 7009 token revocation endpoint\n */\n revocation_endpoint?: string;\n /**\n * Optional handler defaults (merged with per-call overrides in `handler`)\n */\n tokenUrl?: string;\n validateUrl?: string;\n jwksUrl?: string;\n refreshUrl?: string;\n validation?: {\n jwtAssertionClaims?: StandardSchemaV1<unknown, JWTAssertionClaims>;\n tokenResponse?: StandardSchemaV1<unknown, WorkloadTokenResponse>;\n };\n};\n\n/**\n * JWT Bearer Grant (RFC 7523) Configuration\n *\n * Used for SPIFFE-style workload identities where services have their own\n * cryptographic identity and sign their own JWT assertions.\n *\n * @example\n * ```json\n * {\n * \"token_url\": \"https://auth.example.com/oauth/token\",\n * \"jwks_uri\": \"https://auth.example.com/.well-known/jwks.json\",\n * \"workload_id\": \"spiffe://trust-domain/ns/service\",\n * \"audience\": \"https://auth.example.com/oauth/token\",\n * \"private_key\": \"-----BEGIN PRIVATE KEY-----...\",\n * \"algorithm\": \"RS256\"\n * }\n * ```\n */\nexport type JwtBearerWorkloadConfig = WorkloadConfigBase & {\n /**\n * Workload identifier (e.g., SPIFFE ID: spiffe://trust-domain/namespace/service)\n * REQUIRED for JWT Bearer Grant mode\n */\n workload_id?: string;\n\n /**\n * PEM-encoded private key for signing JWT assertions\n * REQUIRED for client role in JWT Bearer Grant mode\n */\n private_key?: string;\n\n /**\n * Key ID (kid) to include in JWT header for key rotation support\n */\n key_id?: string;\n\n /**\n * JWT signing algorithm\n * @default 'RS256'\n */\n algorithm?: 'RS256' | 'RS384' | 'RS512' | 'ES256' | 'ES384' | 'ES512';\n};\n\n/**\n * OAuth2 Client Credentials Configuration\n *\n * Standard OAuth2 Client Credentials Grant (RFC 6749 Section 4.4).\n * Used with identity providers like Keycloak for service-to-service authentication.\n *\n * @example\n * ```json\n * {\n * \"token_url\": \"https://sso.example.com/realms/myrealm/protocol/openid-connect/token\",\n * \"jwks_uri\": \"https://sso.example.com/realms/myrealm/protocol/openid-connect/certs\",\n * \"client_id\": \"my-service\",\n * \"client_secret\": \"secret-from-idp\",\n * \"issuer\": \"https://sso.example.com/realms/myrealm\",\n * \"scope\": \"api:read api:write\"\n * }\n * ```\n */\nexport type ClientCredentialsWorkloadConfig = WorkloadConfigBase & {\n /**\n * OAuth2 client identifier registered with the authorization server\n * REQUIRED for Client Credentials mode\n */\n client_id?: string;\n\n /**\n * OAuth2 client secret\n * REQUIRED for Client Credentials mode\n */\n client_secret?: string;\n};\n\n/**\n * Server-Only Workload Configuration\n *\n * Used when a service only needs to validate incoming workload tokens,\n * not acquire tokens for outbound calls. Requires only jwks_uri for\n * public key retrieval.\n *\n * @example\n * ```json\n * {\n * \"jwks_uri\": \"https://sso.example.com/realms/myrealm/protocol/openid-connect/certs\",\n * \"issuer\": \"https://sso.example.com/realms/myrealm\"\n * }\n * ```\n */\nexport type ServerOnlyWorkloadConfig = WorkloadConfigBase;\n\n/**\n * Workload Identity Authentication Configuration\n *\n * Union type supporting multiple authentication modes. The mode is automatically\n * detected based on which fields are present:\n *\n * - **JWT Bearer Grant**: Requires `workload_id` + `private_key`\n * - **Client Credentials**: Requires `client_id` + `client_secret`\n * - **Server-Only**: Only `jwks_uri` (and optionally `issuer`) for token validation\n *\n * The developer uses the same API regardless of mode - the library handles the details.\n */\nexport type WorkloadConfig = JwtBearerWorkloadConfig | ClientCredentialsWorkloadConfig | ServerOnlyWorkloadConfig;\n\ntype JwtBearerConfigWithDefaults = JwtBearerWorkloadConfig & {\n token_url: string;\n workload_id: string;\n audience: string;\n scope: string;\n algorithm: 'RS256' | 'RS384' | 'RS512' | 'ES256' | 'ES384' | 'ES512';\n token_lifetime: number;\n refresh_threshold: number;\n auto_refresh: boolean;\n token_store: WorkloadTokenStore;\n};\n\ntype ClientCredentialsConfigWithDefaults = ClientCredentialsWorkloadConfig & {\n token_url: string;\n client_id: string;\n client_secret: string;\n scope: string;\n token_lifetime: number;\n refresh_threshold: number;\n auto_refresh: boolean;\n token_store: WorkloadTokenStore;\n};\n\ntype WorkloadConfigWithDefaults = JwtBearerConfigWithDefaults | ClientCredentialsConfigWithDefaults;\n\nexport type ESConfig = {\n es?: EnterpriseStandard;\n};\n\n/**\n * Workload Identity extracted from validated tokens\n */\nexport type WorkloadIdentity = {\n /**\n * Workload identifier (for JWT Bearer Grant tokens)\n */\n workload_id?: string;\n\n /**\n * Client identifier (for OAuth2 Client Credentials tokens)\n */\n client_id?: string;\n\n /**\n * Granted scopes\n */\n scope?: string;\n\n /**\n * Full JWT claims from the token\n */\n claims: JWTAssertionClaims;\n};\n\n/**\n * Workload Identity Authentication Interface\n */\nexport type Workload = WorkloadConfig & {\n // Client Role - Acquiring tokens for outbound API calls\n getToken: (scope?: string) => Promise<string>;\n refreshToken: () => Promise<WorkloadTokenResponse>;\n generateJWTAssertion: (scope?: string) => Promise<string>;\n revokeToken: (token: string) => Promise<void>;\n\n // Server Role - Validating incoming tokens from other workloads\n validateToken: (token: string, validation?: WorkloadConfig['validation']) => Promise<TokenValidationResult>;\n getWorkload: (request: Request) => Promise<WorkloadIdentity | undefined>;\n parseJWT: (token: string, validation?: WorkloadConfig['validation']) => Promise<JWTAssertionClaims>;\n\n // Framework-agnostic request handler\n handler: (request: Request) => Promise<Response>;\n};\n\ntype JWK = {\n kty: string;\n kid: string;\n use?: string;\n alg?: string;\n n?: string;\n e?: string;\n crv?: string;\n x?: string;\n y?: string;\n [key: string]: unknown;\n};\n\ntype JWKS = {\n keys: JWK[];\n};\n\nconst jwksCache = new Map<string, JWKS>();\n\n/**\n * Type guard to check if config is for JWT Bearer Grant mode\n */\nfunction isJwtBearerConfig(config: WorkloadConfig): config is JwtBearerWorkloadConfig {\n return 'workload_id' in config || 'private_key' in config;\n}\n\n/**\n * Type guard to check if config is for OAuth2 Client Credentials mode\n */\nfunction isClientCredentialsConfig(config: WorkloadConfig): config is ClientCredentialsWorkloadConfig {\n return 'client_id' in config || 'client_secret' in config;\n}\n\n/**\n * Type guard to check if config is for server-only mode (token validation only)\n */\nfunction isServerOnlyConfig(config: WorkloadConfig): boolean {\n return 'jwks_uri' in config && !('workload_id' in config) && !('client_id' in config);\n}\n\n/**\n * Validates that the config has the required fields for at least one mode:\n * - JWT Bearer Grant (client role): workload_id + private_key\n * - Client Credentials (client role): client_id + client_secret\n * - Server-only (validation role): jwks_uri only\n */\nfunction validateWorkloadConfig(config: WorkloadConfig): void {\n const hasJwtBearer = 'workload_id' in config && 'private_key' in config;\n const hasClientCreds = 'client_id' in config && 'client_secret' in config;\n const hasServerOnly = 'jwks_uri' in config;\n\n if (!hasJwtBearer && !hasClientCreds && !hasServerOnly) {\n throw new Error(\n 'Invalid WorkloadConfig: must provide either (workload_id + private_key) for JWT Bearer Grant, ' +\n '(client_id + client_secret) for OAuth2 Client Credentials, or (jwks_uri) for server-only token validation',\n );\n }\n}\n\n/**\n * Create a workload identity authentication instance\n *\n * @param config - Workload authentication configuration\n * @returns Workload authentication interface\n *\n * @example\n * ```typescript\n * import { workload } from '@enterprisestandard/react';\n *\n * const workloadAuth = workload({\n * token_url: 'https://auth.example.com/oauth/token',\n * jwks_uri: 'https://auth.example.com/.well-known/jwks.json',\n * workload_id: 'spiffe://trust-domain/ns/service',\n * audience: 'https://auth.example.com/oauth/token',\n * private_key: '-----BEGIN PRIVATE KEY-----...',\n * algorithm: 'RS256',\n * });\n *\n * // Get access token\n * const token = await workloadAuth.getToken('api:read api:write');\n * ```\n */\nexport function workload(config: WorkloadConfig): Workload {\n // Validate config has required fields for at least one mode\n validateWorkloadConfig(config);\n\n // Apply defaults based on config type\n // For server-only mode, we use a minimal config that only supports token validation\n let configWithDefaults: WorkloadConfigWithDefaults | WorkloadConfig;\n\n if (isJwtBearerConfig(config)) {\n configWithDefaults = {\n ...config,\n token_url: must(config.token_url, \"Missing 'token_url' from Workload Config\"),\n workload_id: must(config.workload_id, \"Missing 'workload_id' from Workload Config\"),\n audience: must(config.audience, \"Missing 'audience' from Workload Config\"),\n scope: config.scope ?? '',\n algorithm: config.algorithm ?? 'RS256',\n token_lifetime: config.token_lifetime ?? 300,\n refresh_threshold: config.refresh_threshold ?? 60,\n auto_refresh: config.auto_refresh !== undefined ? config.auto_refresh : true,\n token_store: config.token_store ?? new InMemoryWorkloadTokenStore(),\n } as JwtBearerConfigWithDefaults;\n } else if (isClientCredentialsConfig(config)) {\n // Client Credentials mode\n configWithDefaults = {\n ...config,\n token_url: must(config.token_url, \"Missing 'token_url' from Workload Config\"),\n client_id: must(config.client_id, \"Missing 'client_id' from Workload Config\"),\n client_secret: must(config.client_secret, \"Missing 'client_secret' from Workload Config\"),\n scope: config.scope ?? '',\n token_lifetime: config.token_lifetime ?? 300,\n refresh_threshold: config.refresh_threshold ?? 60,\n auto_refresh: config.auto_refresh !== undefined ? config.auto_refresh : true,\n token_store: config.token_store ?? new InMemoryWorkloadTokenStore(),\n } as ClientCredentialsConfigWithDefaults;\n } else {\n // Server-only mode - only token validation, no token acquisition\n configWithDefaults = config;\n }\n\n const initialized = true;\n\n function ensureInitialized() {\n if (!initialized) {\n throw new Error('Enterprise Standard Workload Manager not initialized');\n }\n }\n\n // ========== Utility Functions ==========\n\n function generateJTI(): string {\n const array = new Uint8Array(16);\n crypto.getRandomValues(array);\n return Array.from(array, (byte) => byte.toString(16).padStart(2, '0')).join('');\n }\n\n function base64UrlEncode(data: string | Uint8Array): string {\n let base64: string;\n if (typeof data === 'string') {\n base64 = btoa(data);\n } else {\n base64 = btoa(String.fromCharCode(...data));\n }\n return base64.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n }\n\n function base64UrlDecode(base64url: string): string {\n let base64 = base64url.replace(/-/g, '+').replace(/_/g, '/');\n // Add padding if needed (atob requires padding)\n while (base64.length % 4) {\n base64 += '=';\n }\n return atob(base64);\n }\n\n function getAlgorithmParams(\n alg: string,\n ): { name: 'RSASSA-PKCS1-v1_5'; hash: string } | { name: 'ECDSA'; namedCurve: string; hash: string } {\n if (alg.startsWith('RS')) {\n const hash = alg === 'RS256' ? 'SHA-256' : alg === 'RS384' ? 'SHA-384' : 'SHA-512';\n return { name: 'RSASSA-PKCS1-v1_5', hash };\n } else if (alg.startsWith('ES')) {\n const namedCurve = alg === 'ES256' ? 'P-256' : alg === 'ES384' ? 'P-384' : 'P-521';\n const hash = alg === 'ES256' ? 'SHA-256' : alg === 'ES384' ? 'SHA-384' : 'SHA-512';\n return { name: 'ECDSA', namedCurve, hash };\n }\n throw new Error(`Unsupported algorithm: ${alg}`);\n }\n\n async function importPrivateKey(pemKey: string, algorithm: string): Promise<CryptoKey> {\n // Strip PEM header/footer and whitespace\n const pemContents = pemKey\n .replace(/-----BEGIN PRIVATE KEY-----/, '')\n .replace(/-----END PRIVATE KEY-----/, '')\n .replace(/\\s/g, '');\n\n // Decode base64 to binary\n const binaryDer = Uint8Array.from(atob(pemContents), (c) => c.charCodeAt(0));\n\n const algorithmParams = getAlgorithmParams(algorithm);\n\n return crypto.subtle.importKey('pkcs8', binaryDer, algorithmParams, false, ['sign']);\n }\n\n async function signJWT(data: string, privateKeyPEM: string, algorithm: string): Promise<string> {\n const privateKey = await importPrivateKey(privateKeyPEM, algorithm);\n const encoder = new TextEncoder();\n const dataBuffer = encoder.encode(data);\n\n const algorithmParams = getAlgorithmParams(algorithm);\n const signatureBuffer = await crypto.subtle.sign(algorithmParams, privateKey, dataBuffer);\n\n return base64UrlEncode(new Uint8Array(signatureBuffer));\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)\n if (\n lastError.message.includes('400') ||\n lastError.message.includes('401') ||\n lastError.message.includes('403') ||\n lastError.message.includes('404')\n ) {\n throw lastError;\n }\n\n if (attempt < maxRetries) {\n // Exponential backoff with jitter\n const delay = Math.min(baseDelay * 2 ** attempt, maxDelay);\n const jitter = Math.random() * delay * 0.1;\n await new Promise((resolve) => setTimeout(resolve, delay + jitter));\n }\n }\n }\n\n throw lastError;\n }\n\n // ========== Client Methods ==========\n\n async function generateJWTAssertion(scope?: string): Promise<string> {\n ensureInitialized();\n if (!isJwtBearerConfig(config)) {\n throw new Error('generateJWTAssertion is only available in JWT Bearer Grant mode');\n }\n const cfg = configWithDefaults as JwtBearerConfigWithDefaults;\n\n const now = Math.floor(Date.now() / 1000);\n\n // Build JWT claims\n const claims: JWTAssertionClaims = {\n iss: cfg.workload_id,\n sub: cfg.workload_id,\n aud: cfg.audience ?? '',\n exp: now + cfg.token_lifetime,\n iat: now,\n jti: generateJTI(),\n scope: scope ?? cfg.scope,\n };\n\n // Build JWT header\n const header = {\n alg: cfg.algorithm,\n typ: 'JWT',\n kid: cfg.key_id,\n };\n\n // Encode header and payload\n const encodedHeader = base64UrlEncode(JSON.stringify(header));\n const encodedPayload = base64UrlEncode(JSON.stringify(claims));\n const signatureInput = `${encodedHeader}.${encodedPayload}`;\n\n // Sign the JWT (private_key is guaranteed by isJwtBearerConfig check above)\n // biome-ignore lint/style/noNonNullAssertion: private_key guaranteed by type guard\n const signature = await signJWT(signatureInput, cfg.private_key!, cfg.algorithm);\n\n return `${signatureInput}.${signature}`;\n }\n\n async function acquireTokenJwtBearer(\n scope: string,\n validation?: WorkloadConfig['validation'],\n ): Promise<WorkloadTokenResponse> {\n const cfg = configWithDefaults as JwtBearerConfigWithDefaults;\n return retryWithBackoff(async () => {\n const tokenUrl = cfg.token_url;\n\n // Generate JWT assertion\n const assertion = await generateJWTAssertion(scope);\n\n // Build request body\n const body = new URLSearchParams();\n body.append('grant_type', 'urn:ietf:params:oauth:grant-type:jwt-bearer');\n body.append('assertion', assertion);\n if (scope) body.append('scope', scope);\n\n // POST to token endpoint\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 acquisition error:', data);\n throw new Error(\n `Token acquisition failed: ${data.error || response.statusText} - ${data.error_description || ''}`.trim(),\n );\n }\n\n // Validate response using StandardSchema\n const validator = validation?.tokenResponse ?? workloadTokenResponseSchema('builtin');\n const result = await validator['~standard'].validate(data);\n\n if ('issues' in result) {\n console.error('Token response validation failed:', result.issues);\n throw new Error(`Token response validation failed: ${result.issues?.map((i) => i.message).join('; ')}`);\n }\n\n // Cache token if store configured\n if (cfg.token_store) {\n const expiresAt = new Date(Date.now() + (result.value.expires_in ?? 300) * 1000);\n const cachedToken = {\n workload_id: cfg.workload_id,\n access_token: result.value.access_token,\n token_type: result.value.token_type,\n scope: result.value.scope,\n expires_at: expiresAt,\n created_at: new Date(),\n refresh_token: result.value.refresh_token,\n };\n await cfg.token_store.set(cachedToken);\n }\n\n return result.value;\n });\n }\n\n async function acquireTokenClientCredentials(\n scope: string,\n validation?: WorkloadConfig['validation'],\n ): Promise<WorkloadTokenResponse> {\n const cfg = configWithDefaults as ClientCredentialsConfigWithDefaults;\n return retryWithBackoff(async () => {\n const tokenUrl = cfg.token_url;\n\n // Build request body for OAuth2 Client Credentials\n const body = new URLSearchParams();\n body.append('grant_type', 'client_credentials');\n body.append('client_id', cfg.client_id);\n body.append('client_secret', cfg.client_secret);\n if (scope) body.append('scope', scope);\n\n // POST to token endpoint\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 acquisition error:', data);\n throw new Error(\n `Token acquisition failed: ${data.error || response.statusText} - ${data.error_description || ''}`.trim(),\n );\n }\n\n // Validate response using StandardSchema\n const validator = validation?.tokenResponse ?? workloadTokenResponseSchema('builtin');\n const result = await validator['~standard'].validate(data);\n\n if ('issues' in result) {\n console.error('Token response validation failed:', result.issues);\n throw new Error(`Token response validation failed: ${result.issues?.map((i) => i.message).join('; ')}`);\n }\n\n // Cache token if store configured\n if (cfg.token_store) {\n const expiresAt = new Date(Date.now() + (result.value.expires_in ?? 300) * 1000);\n const cachedToken = {\n workload_id: cfg.client_id,\n access_token: result.value.access_token,\n token_type: result.value.token_type,\n scope: result.value.scope,\n expires_at: expiresAt,\n created_at: new Date(),\n refresh_token: result.value.refresh_token,\n };\n await cfg.token_store.set(cachedToken);\n }\n\n return result.value;\n });\n }\n\n async function getToken(scope?: string): Promise<string> {\n ensureInitialized();\n // Check if in server-only mode (no client credentials configured)\n if (isServerOnlyConfig(config)) {\n throw new Error(\n 'Cannot acquire tokens: Workload is configured in server-only mode (validation only). ' +\n 'To acquire tokens, configure client_id + client_secret for OAuth2 Client Credentials, ' +\n 'or workload_id + private_key for JWT Bearer Grant.',\n );\n }\n\n // Validate client role requirements\n if (!configWithDefaults.token_url) {\n throw new Error(\n 'Cannot acquire tokens: Missing token_url in WorkloadConfig. ' +\n 'Client role requires token_url to be configured in vault.',\n );\n }\n\n if (isJwtBearerConfig(configWithDefaults)) {\n if (!configWithDefaults.private_key) {\n throw new Error(\n 'Cannot acquire tokens: Missing private_key in WorkloadConfig. ' +\n 'JWT Bearer Grant client role requires private_key to be configured in vault.',\n );\n }\n } else if (isClientCredentialsConfig(configWithDefaults)) {\n if (!configWithDefaults.client_secret) {\n throw new Error(\n 'Cannot acquire tokens: Missing client_secret in WorkloadConfig. ' +\n 'OAuth2 Client Credentials client role requires client_secret to be configured in vault.',\n );\n }\n }\n\n const requestedScope = scope ?? (configWithDefaults as WorkloadConfigWithDefaults).scope ?? '';\n\n // Determine cache key based on config type\n let cacheKey: string;\n if (isJwtBearerConfig(configWithDefaults)) {\n cacheKey = (configWithDefaults as JwtBearerConfigWithDefaults).workload_id;\n } else if (isClientCredentialsConfig(configWithDefaults)) {\n cacheKey = (configWithDefaults as ClientCredentialsConfigWithDefaults).client_id;\n } else {\n throw new Error('Invalid WorkloadConfig');\n }\n\n // Check cache if token store is configured\n const cfg = configWithDefaults as WorkloadConfigWithDefaults;\n if (cfg.token_store) {\n const cachedToken = await cfg.token_store.get(cacheKey);\n\n if (cachedToken) {\n const now = Date.now();\n const expiresAt = cachedToken.expires_at.getTime();\n const refreshThreshold = cfg.refresh_threshold * 1000;\n\n // If token is not approaching expiry, return it\n if (now + refreshThreshold < expiresAt) {\n return cachedToken.access_token;\n }\n\n // If auto-refresh is enabled and approaching expiry, refresh proactively\n if (cfg.auto_refresh) {\n try {\n const newToken = isJwtBearerConfig(config)\n ? await acquireTokenJwtBearer(requestedScope)\n : await acquireTokenClientCredentials(requestedScope);\n return newToken.access_token;\n } catch (error) {\n // If refresh fails but token still valid, use cached token\n if (now < expiresAt) {\n console.warn('Token refresh failed, using cached token:', error);\n return cachedToken.access_token;\n }\n throw error;\n }\n }\n }\n }\n\n // No cache or expired - acquire new token based on mode\n const tokenResponse = isJwtBearerConfig(config)\n ? await acquireTokenJwtBearer(requestedScope)\n : await acquireTokenClientCredentials(requestedScope);\n return tokenResponse.access_token;\n }\n\n async function refreshToken(): Promise<WorkloadTokenResponse> {\n ensureInitialized();\n if (isServerOnlyConfig(config)) {\n throw new Error('Cannot refresh tokens: Workload is configured in server-only mode (validation only).');\n }\n const cfg = configWithDefaults as WorkloadConfigWithDefaults;\n return isJwtBearerConfig(cfg)\n ? await acquireTokenJwtBearer(cfg.scope)\n : await acquireTokenClientCredentials(cfg.scope);\n }\n\n async function revokeToken(token: string): Promise<void> {\n ensureInitialized();\n try {\n // Only attempt revocation if endpoint is configured\n if (!config.revocation_endpoint) {\n return;\n }\n\n const body = new URLSearchParams();\n body.append('token', token);\n body.append('token_type_hint', 'access_token');\n\n // Use appropriate client identifier based on mode\n if (isJwtBearerConfig(config)) {\n const cfg = configWithDefaults as JwtBearerConfigWithDefaults;\n body.append('client_id', cfg.workload_id);\n } else if (isClientCredentialsConfig(config)) {\n const cfg = configWithDefaults as ClientCredentialsConfigWithDefaults;\n body.append('client_id', cfg.client_id);\n body.append('client_secret', cfg.client_secret);\n }\n\n const response = await fetch(config.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\n // Also delete from cache if using token store\n if (config.token_store) {\n let cacheKey: string;\n if (isJwtBearerConfig(config)) {\n cacheKey = (configWithDefaults as JwtBearerConfigWithDefaults).workload_id;\n } else if (isClientCredentialsConfig(config)) {\n cacheKey = (configWithDefaults as ClientCredentialsConfigWithDefaults).client_id;\n } else {\n return; // Server-only mode, no cache\n }\n await config.token_store.delete(cacheKey);\n }\n } catch (error) {\n console.warn('Error revoking token:', error);\n // Don't throw - revocation is best-effort\n }\n }\n\n // ========== Server Methods ==========\n\n async function fetchJwks(): Promise<JWKS> {\n ensureInitialized();\n // config is the merged config from enterpriseStandard, which should include jwks_uri from vault\n const url = config.jwks_uri;\n if (!url) {\n throw new Error(\n 'Cannot validate tokens: Missing jwks_uri in WorkloadConfig. ' +\n 'Server role requires jwks_uri to be configured in vault to fetch public keys for token validation.',\n );\n }\n\n const cached = jwksCache.get(url);\n if (cached) return cached;\n\n return retryWithBackoff(async () => {\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 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\n // Use algorithm from JWK or default to RS256\n const defaultAlg = isJwtBearerConfig(config)\n ? (configWithDefaults as JwtBearerConfigWithDefaults).algorithm\n : 'RS256';\n const algorithmParams = getAlgorithmParams(key.alg || defaultAlg);\n\n return crypto.subtle.importKey('jwk', key, algorithmParams, false, ['verify']);\n }\n\n async function parseJWT(\n token: string,\n validation?: WorkloadConfig['validation'],\n ): Promise<JWTAssertionClaims> {\n ensureInitialized();\n try {\n const parts = token.split('.');\n if (parts.length !== 3) throw new Error('Invalid JWT');\n\n // Decode header and payload\n const header = JSON.parse(base64UrlDecode(parts[0]));\n const payload = JSON.parse(base64UrlDecode(parts[1]));\n\n // Get public key\n const publicKey = await getPublicKey(header.kid);\n\n // Verify signature\n const signature = parts[2];\n const encoder = new TextEncoder();\n const data = encoder.encode(`${parts[0]}.${parts[1]}`);\n const signatureBytes = Uint8Array.from(base64UrlDecode(signature), (c) => c.charCodeAt(0));\n\n const algorithmParams = getAlgorithmParams(header.alg);\n const isValid = await crypto.subtle.verify(algorithmParams, publicKey, signatureBytes, data);\n\n if (!isValid) throw new Error('Invalid JWT signature');\n\n // Validate claims using StandardSchema\n const validator = validation?.jwtAssertionClaims ?? jwtAssertionClaimsSchema('builtin');\n const result = await validator['~standard'].validate(payload);\n\n if ('issues' in result) {\n console.error('JWT claims validation failed:', result.issues);\n throw new Error(`JWT claims validation failed: ${result.issues?.map((i) => i.message).join('; ')}`);\n }\n\n return result.value;\n } catch (error) {\n console.error('Error verifying JWT:', error);\n throw error;\n }\n }\n\n async function validateToken(\n token: string,\n validation?: WorkloadConfig['validation'],\n ): Promise<TokenValidationResult> {\n ensureInitialized();\n try {\n const claims = await parseJWT(token, validation);\n\n // Check expiration\n const now = Math.floor(Date.now() / 1000);\n if (claims.exp && claims.exp < now) {\n return { valid: false, error: 'Token expired' };\n }\n\n // Validate based on mode using type guards\n if (isJwtBearerConfig(config)) {\n // JWT Bearer Grant validation\n if (config.audience && claims.aud !== config.audience) {\n return { valid: false, error: 'Invalid audience' };\n }\n } else if (isClientCredentialsConfig(config)) {\n // OAuth2 Client Credentials validation\n if (config.issuer && claims.iss !== config.issuer) {\n return { valid: false, error: 'Invalid issuer' };\n }\n if (config.audience && claims.aud !== config.audience) {\n return { valid: false, error: 'Invalid audience' };\n }\n } else {\n // Server-only mode - validate issuer if configured\n const serverConfig = config as WorkloadConfigBase;\n if (serverConfig.issuer && claims.iss !== serverConfig.issuer) {\n return { valid: false, error: 'Invalid issuer' };\n }\n }\n\n return {\n valid: true,\n claims,\n expiresAt: claims.exp ? new Date(claims.exp * 1000) : undefined,\n };\n } catch (error) {\n return {\n valid: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n }\n\n async function getWorkload(request: Request): Promise<WorkloadIdentity | undefined> {\n ensureInitialized();\n // Validate server role requirements\n if (!config.jwks_uri) {\n throw new Error(\n 'Cannot validate tokens: Missing jwks_uri in WorkloadConfig. ' +\n 'Server role requires jwks_uri to be configured in vault to fetch public keys for token validation.',\n );\n }\n\n // Extract Bearer token from Authorization header\n const authHeader = request.headers.get('Authorization');\n if (!authHeader || !authHeader.startsWith('Bearer ')) {\n return undefined;\n }\n\n const token = authHeader.substring(7);\n const result = await validateToken(token, configWithDefaults.validation);\n\n if (!result.valid || !result.claims) {\n return undefined;\n }\n\n return {\n workload_id: result.claims.sub, // Subject is the workload identity\n client_id: typeof result.claims.client_id === 'string' ? result.claims.client_id : undefined, // May be present in OAuth2 tokens\n scope: result.claims.scope,\n claims: result.claims,\n };\n }\n\n // ========== Framework-Agnostic Handler ==========\n\n async function handler(request: Request): Promise<Response> {\n ensureInitialized();\n // Read handler URLs and validation directly from config (which is now part of the instance)\n const tokenUrl = configWithDefaults.tokenUrl;\n const validateUrl = configWithDefaults.validateUrl;\n const jwksUrl = configWithDefaults.jwksUrl;\n const refreshUrl = configWithDefaults.refreshUrl;\n const validation = configWithDefaults.validation;\n\n const path = new URL(request.url).pathname;\n\n // GET /api/workload/token?scope=api:read\n if (tokenUrl === path && request.method === 'GET') {\n const url = new URL(request.url);\n const scope = url.searchParams.get('scope') || undefined;\n const token = await getToken(scope);\n return new Response(JSON.stringify({ access_token: token, token_type: 'Bearer' }), {\n headers: [['Content-Type', 'application/json']],\n });\n }\n\n // POST /api/workload/validate with Authorization: Bearer <token>\n if (validateUrl === path && request.method === 'POST') {\n const authHeader = request.headers.get('Authorization');\n if (!authHeader || !authHeader.startsWith('Bearer ')) {\n return new Response(JSON.stringify({ valid: false, error: 'Missing Authorization header' }), {\n status: 401,\n headers: [['Content-Type', 'application/json']],\n });\n }\n const token = authHeader.substring(7);\n const result = await validateToken(token, validation);\n return new Response(JSON.stringify(result), {\n status: result.valid ? 200 : 401,\n headers: [['Content-Type', 'application/json']],\n });\n }\n\n // GET /api/workload/jwks\n if (jwksUrl === path && request.method === 'GET') {\n const jwks = await fetchJwks();\n return new Response(JSON.stringify(jwks), {\n headers: [['Content-Type', 'application/json']],\n });\n }\n\n // POST /api/workload/refresh\n if (refreshUrl === path && request.method === 'POST') {\n const tokenResponse = await refreshToken();\n return new Response(JSON.stringify(tokenResponse), {\n headers: [['Content-Type', 'application/json']],\n });\n }\n\n return new Response('Not Found', { status: 404 });\n }\n\n // ========== Return Interface ==========\n\n return {\n ...configWithDefaults,\n getToken,\n refreshToken,\n generateJWTAssertion,\n revokeToken,\n validateToken,\n getWorkload,\n parseJWT,\n handler,\n } as Workload;\n}\n",
14
+ "/**\n * Group storage for persisting group data.\n *\n * Group stores are an optional extension for the IAM Groups functionality.\n * They enable:\n * - Caching group data locally for fast lookups\n * - Receiving group provisioning from external IAM providers (SCIM server)\n * - Storing groups close to your application (in-memory, Redis, database)\n *\n * ## Example Usage\n *\n * ```typescript\n * import { InMemoryGroupStore } from '@enterprisestandard/react';\n *\n * const groupStore = new InMemoryGroupStore();\n *\n * // Store a group\n * await groupStore.upsert({\n * id: 'group-123',\n * displayName: 'Administrators',\n * createdAt: new Date(),\n * updatedAt: new Date(),\n * });\n *\n * // Look up groups\n * const group = await groupStore.get('group-123');\n * const allGroups = await groupStore.list();\n * ```\n */\n\nimport type { GroupMember } from './types/scim-schema';\n\n/**\n * Stored group data with required id and tracking metadata.\n *\n * @template TExtended - Type-safe custom data that consumers can add to groups\n */\nexport type StoredGroup<TExtended = {}> = {\n /**\n * Required unique identifier for the group.\n * This is the primary key for group storage.\n */\n id: string;\n\n /**\n * Required human-readable name for the group.\n */\n displayName: string;\n\n /**\n * Optional external identifier from provisioning client.\n */\n externalId?: string;\n\n /**\n * List of members in the group.\n */\n members?: GroupMember[];\n\n /**\n * Timestamp when the group was first stored.\n */\n createdAt: Date;\n\n /**\n * Timestamp when the group was last updated.\n */\n updatedAt: Date;\n} & TExtended;\n\n/**\n * Abstract interface for group storage backends.\n *\n * Consumers can implement this interface to use different storage backends:\n * - In-memory (for development/testing)\n * - Redis (for production with fast lookups)\n * - Database (PostgreSQL, MySQL, etc.)\n *\n * @template TExtended - Type-safe custom data that consumers can add to groups\n */\nexport interface GroupStore<TExtended = {}> {\n /**\n * Retrieve a group by its unique identifier.\n *\n * @param id - The group's unique identifier\n * @returns The group if found, null otherwise\n */\n get(id: string): Promise<StoredGroup<TExtended> | null>;\n\n /**\n * Retrieve a group by its external identifier.\n *\n * @param externalId - The external identifier from the provisioning client\n * @returns The group if found, null otherwise\n */\n getByExternalId(externalId: string): Promise<StoredGroup<TExtended> | null>;\n\n /**\n * Retrieve a group by its display name.\n *\n * @param displayName - The group's display name\n * @returns The group if found, null otherwise\n */\n getByDisplayName(displayName: string): Promise<StoredGroup<TExtended> | null>;\n\n /**\n * List all groups in the store.\n *\n * @returns Array of all stored groups\n */\n list(): Promise<StoredGroup<TExtended>[]>;\n\n /**\n * Create or update a group in the store.\n *\n * If a group with the same `id` exists, it will be updated.\n * Otherwise, a new group will be created.\n *\n * @param group - The group data to store\n */\n upsert(group: StoredGroup<TExtended>): Promise<void>;\n\n /**\n * Delete a group by its unique identifier.\n *\n * @param id - The group's unique identifier to delete\n */\n delete(id: string): Promise<void>;\n\n /**\n * Add a member to a group.\n *\n * @param groupId - The group's unique identifier\n * @param member - The member to add\n */\n addMember(groupId: string, member: GroupMember): Promise<void>;\n\n /**\n * Remove a member from a group.\n *\n * @param groupId - The group's unique identifier\n * @param memberId - The member's value/id to remove\n */\n removeMember(groupId: string, memberId: string): Promise<void>;\n}\n\n/**\n * In-memory group 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 (groups not shared)\n * - High availability scenarios (groups lost on restart)\n * - Production applications with distributed architecture\n *\n * For production, implement GroupStore with Redis or a database.\n *\n * @template TExtended - Type-safe custom data that consumers can add to groups\n */\nexport class InMemoryGroupStore<TExtended = {}> implements GroupStore<TExtended> {\n /** Primary storage: id -> group */\n private groups = new Map<string, StoredGroup<TExtended>>();\n\n /** Secondary index: externalId -> id */\n private externalIdIndex = new Map<string, string>();\n\n /** Secondary index: displayName (lowercase) -> id */\n private displayNameIndex = new Map<string, string>();\n\n async get(id: string): Promise<StoredGroup<TExtended> | null> {\n return this.groups.get(id) ?? null;\n }\n\n async getByExternalId(externalId: string): Promise<StoredGroup<TExtended> | null> {\n const id = this.externalIdIndex.get(externalId);\n if (!id) return null;\n return this.groups.get(id) ?? null;\n }\n\n async getByDisplayName(displayName: string): Promise<StoredGroup<TExtended> | null> {\n const id = this.displayNameIndex.get(displayName.toLowerCase());\n if (!id) return null;\n return this.groups.get(id) ?? null;\n }\n\n async list(): Promise<StoredGroup<TExtended>[]> {\n return Array.from(this.groups.values());\n }\n\n async upsert(group: StoredGroup<TExtended>): Promise<void> {\n const existing = this.groups.get(group.id);\n\n // Clean up old indexes if externalId or displayName changed\n if (existing) {\n if (existing.externalId && existing.externalId !== group.externalId) {\n this.externalIdIndex.delete(existing.externalId);\n }\n if (existing.displayName.toLowerCase() !== group.displayName.toLowerCase()) {\n this.displayNameIndex.delete(existing.displayName.toLowerCase());\n }\n }\n\n // Store the group\n this.groups.set(group.id, group);\n\n // Update indexes\n if (group.externalId) {\n this.externalIdIndex.set(group.externalId, group.id);\n }\n this.displayNameIndex.set(group.displayName.toLowerCase(), group.id);\n }\n\n async delete(id: string): Promise<void> {\n const group = this.groups.get(id);\n if (group) {\n // Clean up indexes\n if (group.externalId) {\n this.externalIdIndex.delete(group.externalId);\n }\n this.displayNameIndex.delete(group.displayName.toLowerCase());\n }\n this.groups.delete(id);\n }\n\n async addMember(groupId: string, member: GroupMember): Promise<void> {\n const group = this.groups.get(groupId);\n if (!group) {\n throw new Error(`Group ${groupId} not found`);\n }\n\n const members = group.members ?? [];\n\n // Check if member already exists\n if (!members.some((m) => m.value === member.value)) {\n members.push(member);\n group.members = members;\n group.updatedAt = new Date();\n }\n }\n\n async removeMember(groupId: string, memberId: string): Promise<void> {\n const group = this.groups.get(groupId);\n if (!group) {\n throw new Error(`Group ${groupId} not found`);\n }\n\n if (group.members) {\n group.members = group.members.filter((m) => m.value !== memberId);\n group.updatedAt = new Date();\n }\n }\n}\n",
15
+ "/**\n * Tenant Management SDK\n *\n * Provides helper functions for applications to implement tenant creation endpoints\n * that ESVS can test. Supports both synchronous (201) and asynchronous (202)\n * tenant creation with webhook-based status updates.\n */\n\nimport { EnterpriseStandard } from \".\";\n\n/**\n * Environment type for tenant creation\n */\nexport type EnvironmentType = 'POC' | 'DEV' | 'QA' | 'PROD';\n\n/**\n * Status of tenant creation process\n */\nexport type TenantStatus = 'pending' | 'processing' | 'completed' | 'failed';\n\n/**\n * Request payload from ESVS for creating a tenant\n */\nexport interface CreateTenantRequest {\n /**\n * Required app identifier to use when initializing EnterpriseStandard for this tenant.\n * This is the primary identifier for tenant management. A company can have multiple\n * applications (e.g., one instance on the east coast, one on the west coast).\n */\n appId: string;\n /**\n * Company ID (used for reporting purposes only, not for tenant identification)\n */\n companyId: string;\n\n /**\n * Company Name\n */\n companyName: string;\n\n /**\n * Environment Type (POC, DEV, QA, PROD)\n */\n environmentType: EnvironmentType;\n\n /**\n * Email (The email or distribution list used to communicate to the team)\n */\n email: string;\n\n /**\n * Webhook URL where the application can send updates around the creation of the tenant\n */\n webhookUrl: string;\n}\n\n/**\n * Response payload for tenant creation\n */\nexport interface CreateTenantResponse {\n /**\n * URL that the tenant will be available at\n */\n tenantUrl: string;\n\n /**\n * Current status of tenant creation\n */\n status: TenantStatus;\n}\n\n/**\n * Payload sent to webhook URL for status updates\n */\nexport interface TenantWebhookPayload {\n /**\n * Company ID\n */\n companyId: string;\n\n /**\n * Current status of tenant creation\n */\n status: TenantStatus;\n\n /**\n * URL that the tenant will be available at (provided once creation completes)\n */\n tenantUrl?: string;\n\n /**\n * Error message (only present if status is \"failed\")\n */\n error?: string;\n}\n\n/**\n * Error thrown when tenant request validation fails\n */\nexport class TenantRequestError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'TenantRequestError';\n }\n}\n\n/**\n * Serializes an ESConfig or EnterpriseStandard instance to a JSON-serializable format\n * by removing non-serializable properties like stores, validators, and functions.\n *\n * Since EnterpriseStandard now extends ESConfig, the config (including handler URLs)\n * is accessible directly from the instance.\n *\n * @param configOrES - The ESConfig object or EnterpriseStandard instance to serialize\n * @returns A JSON-serializable version of the config\n */\nexport function serializeESConfig(configOrES: any): any {\n // EnterpriseStandard now extends ESConfig, so we can access config directly\n // Extract the config properties (sso, iam, workload, validation, defaultInstance)\n // and exclude the service instances (vault, sso instance, iam instance, workload instance)\n if (configOrES && typeof configOrES === 'object' && 'sso' in configOrES && 'workload' in configOrES && 'iam' in configOrES) {\n // It's an EnterpriseStandard instance\n // Extract config from the service instances (they now extend their configs)\n const config: any = {\n defaultInstance: configOrES.defaultInstance,\n sso: configOrES.sso ? serializeESConfig(configOrES.sso) : undefined,\n iam: configOrES.iam ? serializeESConfig(configOrES.iam) : undefined,\n workload: configOrES.workload ? serializeESConfig(configOrES.workload) : undefined,\n validation: configOrES.validation,\n };\n return config;\n }\n \n // Otherwise, treat it as an ESConfig or service config\n const config = configOrES;\n if (config === null || config === undefined) {\n return config;\n }\n\n // Handle primitives\n if (typeof config !== 'object') {\n return config;\n }\n\n // Handle arrays\n if (Array.isArray(config)) {\n return config.map((item) => serializeESConfig(item));\n }\n\n // Check if it's a store instance (has methods like get, set, create, delete, etc.)\n const isStore =\n typeof config.get === 'function' ||\n typeof config.set === 'function' ||\n typeof config.create === 'function' ||\n typeof config.delete === 'function' ||\n typeof config.upsert === 'function' ||\n typeof config.list === 'function';\n\n // Check if it's a StandardSchemaV1 validator (has '~standard' property)\n const isValidator = config['~standard'] !== undefined;\n\n // Check if it's a function\n if (typeof config === 'function' || isStore || isValidator) {\n return undefined;\n }\n\n // Handle Date objects\n if (config instanceof Date) {\n return config.toISOString();\n }\n\n // Recursively serialize object properties\n const serialized: any = {};\n for (const key in config) {\n if (Object.prototype.hasOwnProperty.call(config, key)) {\n // Skip non-serializable properties\n if (\n key === 'session_store' ||\n key === 'user_store' ||\n key === 'token_store' ||\n key === 'group_store' ||\n key === 'validation' ||\n key === 'vault' || // Skip vault instance\n // Skip method properties from service instances\n key === 'getUser' ||\n key === 'getRequiredUser' ||\n key === 'getJwt' ||\n key === 'initiateLogin' ||\n key === 'logout' ||\n key === 'callbackHandler' ||\n key === 'handler' ||\n key === 'getToken' ||\n key === 'refreshToken' ||\n key === 'generateJWTAssertion' ||\n key === 'revokeToken' ||\n key === 'validateToken' ||\n key === 'getWorkload' ||\n key === 'parseJWT' ||\n key === 'createUser' ||\n key === 'getBaseUrl' ||\n key === 'groups_outbound' ||\n key === 'groups_inbound'\n ) {\n continue;\n }\n\n const value = serializeESConfig(config[key]);\n // Only include defined values\n if (value !== undefined) {\n serialized[key] = value;\n }\n }\n }\n\n return serialized;\n}\n\n/**\n * Parse and validate a tenant creation request from an HTTP request.\n *\n * @param request - The HTTP request containing the tenant creation data\n * @returns The validated tenant creation request\n * @throws {TenantRequestError} If the request is invalid or missing required fields\n *\n * @example\n * ```typescript\n * app.post('/api/tenant', async (c) => {\n * try {\n * const tenantRequest = await parseTenantRequest(c.req.raw);\n * // Create tenant...\n * } catch (error) {\n * if (error instanceof TenantRequestError) {\n * return c.json({ error: error.message }, 400);\n * }\n * throw error;\n * }\n * });\n * ```\n */\nexport async function parseTenantRequest(request: Request): Promise<CreateTenantRequest> {\n if (request.method !== 'POST') {\n throw new TenantRequestError('Only POST method is supported');\n }\n\n let body: unknown;\n try {\n body = await request.json();\n } catch (_error) {\n throw new TenantRequestError('Invalid JSON in request body');\n }\n\n if (typeof body !== 'object' || body === null) {\n throw new TenantRequestError('Request body must be an object');\n }\n\n const tenantRequest = body as Partial<CreateTenantRequest>;\n\n // Validate required fields\n if (!tenantRequest.appId) {\n throw new TenantRequestError('Missing required field: appId');\n }\n if (!tenantRequest.companyId) {\n throw new TenantRequestError('Missing required field: companyId');\n }\n if (!tenantRequest.companyName) {\n throw new TenantRequestError('Missing required field: companyName');\n }\n if (!tenantRequest.environmentType) {\n throw new TenantRequestError('Missing required field: environmentType');\n }\n if (!tenantRequest.email) {\n throw new TenantRequestError('Missing required field: email');\n }\n if (!tenantRequest.webhookUrl) {\n throw new TenantRequestError('Missing required field: webhookUrl');\n }\n\n // Validate environmentType enum\n const validEnvironmentTypes: EnvironmentType[] = ['POC', 'DEV', 'QA', 'PROD'];\n if (!validEnvironmentTypes.includes(tenantRequest.environmentType)) {\n throw new TenantRequestError(\n `Invalid environmentType: ${tenantRequest.environmentType}. Must be one of: ${validEnvironmentTypes.join(', ')}`,\n );\n }\n\n // Validate webhookUrl is a valid URL\n try {\n new URL(tenantRequest.webhookUrl);\n } catch {\n throw new TenantRequestError('Invalid webhookUrl: must be a valid URL');\n }\n\n // At this point, all required fields are validated and non-null\n // Extract them to satisfy TypeScript's type narrowing\n const appId = tenantRequest.appId!;\n const companyId = tenantRequest.companyId!;\n const companyName = tenantRequest.companyName!;\n const environmentType = tenantRequest.environmentType!;\n const email = tenantRequest.email!;\n const webhookUrl = tenantRequest.webhookUrl!;\n\n return {\n appId,\n companyId,\n companyName,\n environmentType,\n email,\n webhookUrl,\n };\n}\n\n/**\n * Send a webhook update to ESVS with tenant creation status.\n *\n * @param webhookUrl - The webhook URL provided in the tenant creation request\n * @param payload - The webhook payload with status and tenant information\n * @throws Never throws - errors are logged but not propagated to avoid breaking tenant creation\n *\n * @example\n * ```typescript\n * // Send initial status\n * await sendTenantWebhook(tenantRequest.webhookUrl, {\n * companyId: tenantRequest.companyId,\n * status: 'processing',\n * });\n *\n * // Send completion status\n * await sendTenantWebhook(tenantRequest.webhookUrl, {\n * companyId: tenantRequest.companyId,\n * status: 'completed',\n * tenantUrl: 'https://app.example.com/tenants/tenant-123',\n * });\n * ```\n */\nexport async function sendTenantWebhook(webhookUrl: string, payload: TenantWebhookPayload): Promise<void> {\n try {\n const response = await fetch(webhookUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n console.error(`Failed to send webhook update: ${response.status} ${response.statusText}`);\n }\n } catch (error) {\n console.error('Failed to send webhook update:', error);\n // Don't throw - webhook failures shouldn't break tenant creation\n }\n}\n\n/**\n * Stored tenant data with required appId and tracking metadata.\n *\n * @template TExtended - Type-safe custom data that consumers can add to tenants\n */\nexport type StoredTenant<TExtended = {}> = {\n /**\n * Required app identifier used to initialize EnterpriseStandard for this tenant.\n * This is the primary key for tenant storage. A company can have multiple\n * applications (e.g., one instance on the east coast, one on the west coast).\n */\n appId: string;\n\n /**\n * Company ID (used for reporting purposes only, not for tenant identification)\n */\n companyId: string;\n\n /**\n * Company Name\n */\n companyName: string;\n\n /**\n * Environment Type (POC, DEV, QA, PROD)\n */\n environmentType: EnvironmentType;\n\n /**\n * Email (The email or distribution list used to communicate to the team)\n */\n email: string;\n\n /**\n * Webhook URL where the application can send updates around the creation of the tenant\n */\n webhookUrl: string;\n\n /**\n * URL that the tenant will be available at\n */\n tenantUrl?: string;\n\n /**\n * Current status of tenant creation\n */\n status: TenantStatus;\n\n /**\n * Error message (only present if status is \"failed\")\n */\n error?: string;\n\n /**\n * Timestamp when the tenant was first stored.\n */\n createdAt: Date;\n\n /**\n * Timestamp when the tenant was last updated.\n */\n updatedAt: Date;\n\n /**\n * Serialized Enterprise Standard configuration.\n * This is a JSON-serializable version of the ESConfig with non-serializable items excluded.\n */\n config?: any;\n} & TExtended;\n\n/**\n * Abstract interface for tenant storage backends.\n *\n * Consumers can implement this interface to use different storage backends:\n * - In-memory (for development/testing)\n * - Redis (for production with fast lookups)\n * - Database (PostgreSQL, MySQL, etc.)\n *\n * @template TExtended - Type-safe custom data that consumers can add to tenants\n */\nexport interface TenantStore<TExtended = {}> {\n /**\n * Retrieve a tenant by its app identifier.\n *\n * @param appId - The tenant's app identifier (primary key)\n * @returns The tenant if found, null otherwise\n */\n get(appId: string): Promise<StoredTenant<TExtended> | null>;\n\n /**\n * Retrieve all tenants for a company ID.\n * Since a company can have multiple applications, this returns an array.\n *\n * @param companyId - The company ID (used for reporting, not primary identification)\n * @returns Array of tenants for the company, empty array if none found\n */\n getByCompanyId(companyId: string): Promise<StoredTenant<TExtended>[]>;\n\n /**\n * List all tenants in the store.\n *\n * @returns Array of all stored tenants\n */\n list(): Promise<StoredTenant<TExtended>[]>;\n\n /**\n * Create or update a tenant in the store.\n *\n * If a tenant with the same `appId` exists, it will be updated.\n * Otherwise, a new tenant will be created.\n *\n * @param tenant - The tenant data to store\n * @returns The stored tenant\n */\n upsert(tenant: StoredTenant<TExtended>): Promise<StoredTenant<TExtended>>;\n\n /**\n * Delete a tenant by its app identifier.\n *\n * @param appId - The tenant's app identifier to delete\n */\n delete(appId: string): Promise<void>;\n}\n\n/**\n * In-memory tenant 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 (tenants not shared)\n * - High availability scenarios (tenants lost on restart)\n * - Production applications with distributed architecture\n *\n * For production, implement TenantStore with Redis or a database.\n *\n * @template TExtended - Type-safe custom data that consumers can add to tenants\n */\nexport class InMemoryTenantStore<TExtended = {}> implements TenantStore<TExtended> {\n /** Primary storage: appId -> tenant */\n private tenants = new Map<string, StoredTenant<TExtended>>();\n\n /** Secondary index: companyId -> Set of appIds (since one company can have multiple apps) */\n private companyIdIndex = new Map<string, Set<string>>();\n\n async get(appId: string): Promise<StoredTenant<TExtended> | null> {\n return this.tenants.get(appId) ?? null;\n }\n\n async getByCompanyId(companyId: string): Promise<StoredTenant<TExtended>[]> {\n const appIds = this.companyIdIndex.get(companyId);\n if (!appIds || appIds.size === 0) return [];\n \n const tenants: StoredTenant<TExtended>[] = [];\n for (const appId of appIds) {\n const tenant = this.tenants.get(appId);\n if (tenant) {\n tenants.push(tenant);\n }\n }\n return tenants;\n }\n\n async list(): Promise<StoredTenant<TExtended>[]> {\n return Array.from(this.tenants.values());\n }\n\n async upsert(tenant: StoredTenant<TExtended>): Promise<StoredTenant<TExtended>> {\n const existing = this.tenants.get(tenant.appId);\n\n // Clean up old index if companyId changed\n if (existing && existing.companyId !== tenant.companyId) {\n const oldAppIds = this.companyIdIndex.get(existing.companyId);\n if (oldAppIds) {\n oldAppIds.delete(tenant.appId);\n if (oldAppIds.size === 0) {\n this.companyIdIndex.delete(existing.companyId);\n }\n }\n }\n\n // Store the tenant\n this.tenants.set(tenant.appId, tenant);\n\n // Update index (companyId -> Set of appIds)\n let appIds = this.companyIdIndex.get(tenant.companyId);\n if (!appIds) {\n appIds = new Set<string>();\n this.companyIdIndex.set(tenant.companyId, appIds);\n }\n appIds.add(tenant.appId);\n \n return tenant;\n }\n\n async delete(appId: string): Promise<void> {\n const tenant = this.tenants.get(appId);\n if (tenant) {\n // Clean up index\n const appIds = this.companyIdIndex.get(tenant.companyId);\n if (appIds) {\n appIds.delete(appId);\n if (appIds.size === 0) {\n this.companyIdIndex.delete(tenant.companyId);\n }\n }\n }\n this.tenants.delete(appId);\n }\n}\n",
16
+ "import type { TokenValidationResult } from './types/workload-schema';\nimport { getES } from './utils';\nimport type { ESConfig, WorkloadIdentity } from './workload';\n\nfunction getWorkloadInstance(config?: ESConfig) {\n const es = getES(config?.es);\n if (!es.workload) {\n console.error('Workload authentication not configured in EnterpriseStandard');\n return undefined;\n }\n return es.workload;\n}\n\nfunction unavailable() {\n return new Response(JSON.stringify({ error: 'Workload authentication unavailable' }), {\n status: 503,\n statusText: 'Workload authentication unavailable',\n headers: { 'Content-Type': 'application/json' },\n });\n}\n\n/**\n * Get the workload identity from an incoming request.\n * Returns undefined if no valid workload token is present.\n *\n * @param request - Request with Authorization header\n * @param config - Optional EnterpriseStandard configuration\n * @returns WorkloadIdentity or undefined\n *\n * @example\n * ```typescript\n * import { getWorkload } from '@enterprisestandard/react';\n *\n * export async function handler(request: Request) {\n * const workload = await getWorkload(request);\n *\n * if (!workload) {\n * return new Response('Unauthorized', { status: 401 });\n * }\n *\n * console.log('Request from workload:', workload.workload_id);\n * // ... process authenticated request\n * }\n * ```\n */\nexport async function getWorkload(request: Request, config?: ESConfig): Promise<WorkloadIdentity | undefined> {\n const workloadAuth = getWorkloadInstance(config);\n if (!workloadAuth) {\n return undefined;\n }\n return workloadAuth.getWorkload(request);\n}\n\n/**\n * Get an access token for the configured workload identity.\n *\n * @param scope - Optional OAuth2 scopes (space-delimited)\n * @param config - Optional EnterpriseStandard configuration\n * @returns Access token string\n *\n * @example\n * ```typescript\n * import { getWorkloadToken } from '@enterprisestandard/react/server';\n *\n * // Get token for API calls\n * const token = await getWorkloadToken('api:read api:write');\n *\n * // Use in outbound requests\n * const response = await fetch('https://api.example.com/data', {\n * headers: { 'Authorization': `Bearer ${token}` },\n * });\n * ```\n */\nexport async function getWorkloadToken(scope?: string, config?: ESConfig): Promise<string> {\n const workloadAuth = getWorkloadInstance(config);\n if (!workloadAuth) throw unavailable();\n return workloadAuth.getToken(scope);\n}\n\n/**\n * Validate a workload token from an incoming request.\n *\n * @param request - Request with Authorization header\n * @param config - Optional EnterpriseStandard configuration\n * @returns Token validation result\n *\n * @example\n * ```typescript\n * import { validateWorkloadToken } from '@enterprisestandard/react/server';\n *\n * export async function handler(request: Request) {\n * const result = await validateWorkloadToken(request);\n *\n * if (!result.valid) {\n * return new Response(\n * JSON.stringify({ error: result.error }),\n * { status: 401 }\n * );\n * }\n *\n * const workloadId = result.claims?.iss;\n * // ... process authenticated request\n * }\n * ```\n */\nexport async function validateWorkloadToken(request: Request, config?: ESConfig): Promise<TokenValidationResult> {\n const workloadAuth = getWorkloadInstance(config);\n if (!workloadAuth) {\n return { valid: false, error: 'Workload authentication unavailable' };\n }\n\n const authHeader = request.headers.get('Authorization');\n if (!authHeader || !authHeader.startsWith('Bearer ')) {\n return { valid: false, error: 'Missing or invalid Authorization header' };\n }\n\n const token = authHeader.substring(7);\n return workloadAuth.validateToken(token);\n}\n\n/**\n * Revoke a workload access token.\n *\n * @param token - The access token to revoke\n * @param config - Optional EnterpriseStandard configuration\n *\n * @example\n * ```typescript\n * import { revokeWorkloadToken } from '@enterprisestandard/react/server';\n *\n * // Revoke token when workload is decommissioned\n * await revokeWorkloadToken(accessToken);\n * ```\n */\nexport async function revokeWorkloadToken(token: string, config?: ESConfig): Promise<void> {\n const workloadAuth = getWorkloadInstance(config);\n if (!workloadAuth) throw unavailable();\n return workloadAuth.revokeToken(token);\n}\n\n/**\n * Framework-agnostic handler for workload authentication routes.\n *\n * The handler reads configuration (handler URLs, validation) directly from the\n * EnterpriseStandard instance, so no config parameter is needed.\n *\n * @param request - Incoming request\n * @param config - Optional ESConfig to specify which EnterpriseStandard instance to use\n * @returns Response\n *\n * @example\n * ```typescript\n * import { workloadHandler } from '@enterprisestandard/react/server';\n *\n * // TanStack Start example\n * export const Route = createFileRoute('/api/workload/$')({\n * server: {\n * handlers: ({ createHandlers }) =>\n * createHandlers({\n * GET: {\n * handler: async ({ request }) => {\n * return workloadHandler(request);\n * },\n * },\n * POST: {\n * handler: async ({ request }) => {\n * return workloadHandler(request);\n * },\n * },\n * }),\n * },\n * });\n * ```\n */\nexport async function workloadHandler(request: Request, config?: ESConfig): Promise<Response> {\n const workloadAuth = getWorkloadInstance(config);\n if (!workloadAuth) throw unavailable();\n return workloadAuth.handler(request);\n}\n",
17
+ "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?: ESConfig) {\n const sso = getSSO(config);\n if (!sso) throw unavailable();\n return sso.handler(request);\n}\n\n// Tenant server helpers\nexport * from './tenant-server';\n// Workload server helpers\nexport * from './workload-server';\n",
18
+ "/**\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 = {}> = {\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 = {}> {\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 = {}> 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
19
  "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
20
  "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
21
  "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"
22
+ "import { createContext, type ReactNode, useCallback, useContext, useEffect, useState } from 'react';\nimport type { User } from '../types/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: User | null;\n setUser: (user: User | 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<User | 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: User | null): boolean => {\n if (!user || !tenantId) return true;\n return user.sso?.tenant?.id === tenantId;\n },\n [tenantId],\n );\n\n const loadUserFromStorage = useCallback((): User | 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 User;\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: User | 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: User | 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 User;\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 User;\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",
23
+ "/**\n * User storage for persisting user profiles from SSO authentication.\n *\n * User stores are optional - the package works with JWT cookies alone.\n * User stores are useful when you want to:\n * - Cache user profiles for fast lookup\n * - Store users close to your application (in-memory, Redis, etc.)\n * - Avoid custom IAM/SCIM integration for simple use cases\n *\n * ## When to Use UserStore vs IAM\n *\n * **Use UserStore when:**\n * - You just need fast user lookups without external systems\n * - Users are managed by an external IdP and you just cache them locally\n * - You want simple in-memory or Redis storage\n *\n * **Use IAM (SCIM) when:**\n * - You need to provision users to an external identity provider\n * - You need custom user attributes beyond what SSO provides\n * - You need to sync users with enterprise directories\n *\n * ## Example Usage\n *\n * ```typescript\n * import { sso, InMemoryUserStore } from '@enterprisestandard/react/server';\n *\n * const userStore = new InMemoryUserStore();\n *\n * const auth = sso({\n * // ... other config\n * user_store: userStore,\n * });\n *\n * // Later, look up users\n * const user = await userStore.get('user-sub-id');\n * const userByEmail = await userStore.getByEmail('user@example.com');\n * ```\n */\n\nimport type { User } from './types/user';\n\n/**\n * Stored user data with required id and tracking metadata.\n *\n * Extends the SSO User type with:\n * - Required `id` (the `sub` claim from the IdP)\n * - Timestamps for tracking when users were first seen and last updated\n * - Optional custom extended data\n *\n * @template TExtended - Type-safe custom data that consumers can add to users\n */\nexport type StoredUser<TExtended = {}> = User & {\n /**\n * Required unique identifier (the `sub` claim from the IdP).\n * This is the primary key for user storage.\n */\n id: string;\n\n /**\n * Timestamp when the user was first stored.\n */\n createdAt: Date;\n\n /**\n * Timestamp when the user was last updated (e.g., on re-login).\n */\n updatedAt: Date;\n} & TExtended;\n\n/**\n * Abstract interface for user storage backends.\n *\n * Consumers can implement this interface to use different storage backends:\n * - In-memory (for development/testing)\n * - Redis (for production with fast lookups)\n * - Database (PostgreSQL, MySQL, etc.)\n *\n * @template TExtended - Type-safe custom data that consumers can add to users\n *\n * @example\n * ```typescript\n * // Custom user data\n * type MyUserData = {\n * department: string;\n * roles: string[];\n * };\n *\n * // Implement custom store\n * class RedisUserStore implements UserStore<MyUserData> {\n * async get(sub: string): Promise<StoredUser<MyUserData> | null> {\n * const data = await redis.get(`user:${sub}`);\n * return data ? JSON.parse(data) : null;\n * }\n * // ... other methods\n * }\n * ```\n */\nexport interface UserStore<TExtended = {}> {\n /**\n * Retrieve a user by their subject identifier (sub).\n *\n * @param sub - The user's unique identifier from the IdP\n * @returns The user if found, null otherwise\n */\n get(sub: string): Promise<StoredUser<TExtended> | null>;\n\n /**\n * Retrieve a user by their email address.\n *\n * @param email - The user's email address\n * @returns The user if found, null otherwise\n */\n getByEmail(email: string): Promise<StoredUser<TExtended> | null>;\n\n /**\n * Retrieve a user by their username.\n *\n * @param userName - The user's username\n * @returns The user if found, null otherwise\n */\n getByUserName(userName: string): Promise<StoredUser<TExtended> | null>;\n\n /**\n * Create or update a user in the store.\n *\n * If a user with the same `id` (sub) exists, it will be updated.\n * Otherwise, a new user will be created.\n *\n * @param user - The user data to store\n */\n upsert(user: StoredUser<TExtended>): Promise<void>;\n\n /**\n * Delete a user by their subject identifier (sub).\n *\n * @param sub - The user's unique identifier to delete\n */\n delete(sub: string): Promise<void>;\n}\n\n/**\n * In-memory user 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 (users not shared)\n * - High availability scenarios (users lost on restart)\n * - Production applications with distributed architecture\n *\n * For production, implement UserStore with Redis or a database.\n *\n * @template TExtended - Type-safe custom data that consumers can add to users\n */\nexport class InMemoryUserStore<TExtended = {}> implements UserStore<TExtended> {\n /** Primary storage: sub -> user */\n private users = new Map<string, StoredUser<TExtended>>();\n\n /** Secondary index: email -> sub */\n private emailIndex = new Map<string, string>();\n\n /** Secondary index: userName -> sub */\n private userNameIndex = new Map<string, string>();\n\n async get(sub: string): Promise<StoredUser<TExtended> | null> {\n return this.users.get(sub) ?? null;\n }\n\n async getByEmail(email: string): Promise<StoredUser<TExtended> | null> {\n const sub = this.emailIndex.get(email.toLowerCase());\n if (!sub) return null;\n return this.users.get(sub) ?? null;\n }\n\n async getByUserName(userName: string): Promise<StoredUser<TExtended> | null> {\n const sub = this.userNameIndex.get(userName.toLowerCase());\n if (!sub) return null;\n return this.users.get(sub) ?? null;\n }\n\n async upsert(user: StoredUser<TExtended>): Promise<void> {\n const existing = this.users.get(user.id);\n\n // Clean up old indexes if email or userName changed\n if (existing) {\n if (existing.email && existing.email.toLowerCase() !== user.email?.toLowerCase()) {\n this.emailIndex.delete(existing.email.toLowerCase());\n }\n if (existing.userName && existing.userName.toLowerCase() !== user.userName?.toLowerCase()) {\n this.userNameIndex.delete(existing.userName.toLowerCase());\n }\n }\n\n // Store the user\n this.users.set(user.id, user);\n\n // Update indexes\n if (user.email) {\n this.emailIndex.set(user.email.toLowerCase(), user.id);\n }\n if (user.userName) {\n this.userNameIndex.set(user.userName.toLowerCase(), user.id);\n }\n }\n\n async delete(sub: string): Promise<void> {\n const user = this.users.get(sub);\n if (user) {\n // Clean up indexes\n if (user.email) {\n this.emailIndex.delete(user.email.toLowerCase());\n }\n if (user.userName) {\n this.userNameIndex.delete(user.userName.toLowerCase());\n }\n }\n this.users.delete(sub);\n }\n}\n",
24
+ "import { type IAM, type IAMConfig, iam } from './iam';\nimport { type SSO, type SSOConfig, type SSOHandlerConfig, sso } from './sso';\nimport { getDefaultInstance, setDefaultInstance } from './utils';\nimport { type Vault, vault } from './vault';\nimport { type Workload, type WorkloadConfig, workload } from './workload';\n\nexport type EnterpriseStandard = ESConfig & {\n defaultInstance: boolean;\n vault: Vault;\n sso: SSO;\n iam: IAM;\n workload: Workload;\n};\n\ntype ESConfig = {\n defaultInstance?: boolean;\n sso?: SSOConfig;\n iam?: IAMConfig;\n workload?: WorkloadConfig;\n validation?:\n | {\n sso?: SSOHandlerConfig['validation'];\n workload?: WorkloadConfig['validation'];\n }\n | SSOHandlerConfig['validation']\n | WorkloadConfig['validation'];\n};\n\ntype VaultSecret = {\n path: string;\n token: string;\n};\n\ntype VaultData = {\n sso?: SSOConfig;\n iam?: IAMConfig;\n workload?: WorkloadConfig;\n};\n\nfunction extractSsoValidation(validation?: ESConfig['validation']): SSOHandlerConfig['validation'] | undefined {\n if (!validation) return undefined;\n const val: any = validation;\n if (val.callbackParams || val.idTokenClaims || val.tokenResponse) {\n return val as SSOHandlerConfig['validation'];\n }\n if (typeof val === 'object' && 'sso' in val) {\n return (val as { sso?: SSOHandlerConfig['validation'] }).sso;\n }\n return undefined;\n}\n\nfunction extractWorkloadValidation(\n validation?: ESConfig['validation'],\n): WorkloadConfig['validation'] | undefined {\n if (!validation) return undefined;\n const val: any = validation;\n if (val.jwtAssertionClaims || val.tokenResponse) {\n return val as WorkloadConfig['validation'];\n }\n if (typeof val === 'object' && 'workload' in val) {\n return (val as { workload?: WorkloadConfig['validation'] }).workload;\n }\n return undefined;\n}\n\nexport async function enterpriseStandard(appId?: string, initConfig?: ESConfig): Promise<EnterpriseStandard> {\n const ioniteUrl = process.env.IONITE_URL ?? 'https://ionite.com';\n let vaultUrl = process.env.ES_VAULT_URL;\n const vaultToken = process.env.ES_VAULT_TOKEN;\n const vaultPath = process.env.ES_VAULT_PATH;\n let secret: VaultSecret | undefined;\n\n // Use environment variables if set (for testing), otherwise use demo vault for demo apps\n if (appId?.startsWith('IONITE_PUBLIC_DEMO_') && !vaultUrl) {\n vaultUrl = 'https://vault-ionite.ionite.dev/v1/secret/data';\n secret = {\n path: `public/${appId}`,\n token: 'hvs.VGhD2hmXDH9PmZjTacZx0G5K',\n };\n } else if (vaultUrl && vaultToken && vaultPath) {\n // Use environment variables (for testing or custom vault)\n secret = {\n path: vaultPath,\n token: vaultToken,\n };\n } else if (!vaultUrl || !vaultToken || !vaultPath) {\n const cmd = `${process.versions.bun ? 'bun' : 'npm'} ionite login --app ${appId}`;\n throw new Error(\n `@enterprisestandard configuration missing.\\n For development, login with the ionite CLI using \"${cmd}\" or visit ${ioniteUrl}/api/applications/apiKeys/create?appId=${appId}. If this is a non-development environment, ensure that you are deployed with the correct tenant pattern.`,\n );\n }\n\n const defaultInstance = getDefaultInstance();\n const vaultClient = vault(vaultUrl);\n const ssoValidation = extractSsoValidation(initConfig?.validation);\n const workloadValidation = extractWorkloadValidation(initConfig?.validation);\n\n // Fetch the es config from vault containing sso, iam, and workload configs, etc\n let vaultData: VaultData = {};\n if (secret) {\n vaultData = await vaultClient.getSecret<VaultData>(secret.path, secret.token);\n }\n\n // Create workload first since other services depend on it for authentication\n // Merge pattern: vault (base) -> initConfig (override) -> defaults (validation)\n // Note: initConfig only overrides properties it explicitly provides\n const workloadConfig: WorkloadConfig = {\n ...vaultData.workload, // Base from vault (includes jwks_uri, token_url, etc.)\n ...initConfig?.workload, // Override with initConfig (if provided) - only overrides explicit properties\n // Ensure critical vault fields are preserved if not overridden\n jwks_uri: initConfig?.workload?.jwks_uri ?? vaultData.workload?.jwks_uri,\n token_url: initConfig?.workload?.token_url ?? vaultData.workload?.token_url,\n validation: initConfig?.workload?.validation ?? workloadValidation, // Apply validation defaults\n };\n const workloadInstance = workload(workloadConfig);\n\n // Build merged SSO config\n const ssoConfig = {\n ...vaultData.sso, // Base from vault\n ...initConfig?.sso, // Override with initConfig (if provided)\n validation: initConfig?.sso?.validation ?? ssoValidation, // Apply validation defaults\n };\n const ssoInstance = sso(ssoConfig);\n\n // Build merged IAM config\n const iamConfig = {\n ...vaultData.iam, // Base from vault\n ...initConfig?.iam, // Override with initConfig (if provided)\n };\n const iamInstance = iam(iamConfig, workloadInstance);\n\n // Build merged ESConfig for EnterpriseStandard\n const mergedConfig: ESConfig = {\n defaultInstance: initConfig?.defaultInstance,\n sso: ssoConfig,\n iam: iamConfig,\n workload: workloadConfig,\n validation: initConfig?.validation,\n };\n\n const result: EnterpriseStandard = {\n ...mergedConfig,\n defaultInstance: initConfig?.defaultInstance || (initConfig?.defaultInstance !== false && !defaultInstance),\n vault: vaultClient,\n sso: ssoInstance,\n iam: iamInstance,\n workload: workloadInstance,\n };\n\n if (result.defaultInstance) {\n if (defaultInstance) {\n defaultInstance.defaultInstance = false;\n }\n setDefaultInstance(result);\n }\n\n return result;\n}\n\n// Group store (for IAM Groups extension)\nexport type { GroupStore, StoredGroup } from './group-store';\nexport { InMemoryGroupStore } from './group-store';\n// IAM\nexport type {\n CreateGroupOptions,\n CreateUserOptions,\n GroupsInboundHandlerConfig,\n IAM,\n IAMConfig,\n IAMGroupsInbound,\n IAMGroupsOutbound,\n IAMHandlerConfig,\n IAMUsersInbound,\n ScimError,\n ScimListResponse,\n ScimResult,\n UsersInboundHandlerConfig,\n} from './iam';\n// IAM (export function)\nexport { iam } from './iam';\n// Server and session\nexport * from './server';\nexport type { SessionStore } from './session-store';\nexport { InMemorySessionStore } from './session-store';\n// SSO\nexport type { SSO, SSOConfig, SSOHandlerConfig } from './sso';\n// SSO (export function)\nexport { sso } from './sso';\n// Tenant Management\nexport type {\n CreateTenantRequest,\n CreateTenantResponse,\n EnvironmentType,\n StoredTenant,\n TenantStatus,\n TenantStore,\n TenantWebhookPayload,\n} from './tenant';\nexport {\n InMemoryTenantStore,\n parseTenantRequest,\n sendTenantWebhook,\n serializeESConfig,\n TenantRequestError,\n} from './tenant';\n// Primary user types\nexport type { BaseUser } from './types/base-user';\nexport type { EnterpriseUser } from './types/enterprise-user';\nexport type { IdTokenClaims, OidcCallbackParams, TokenResponse } from './types/oidc-schema';\n// OIDC/SSO schemas\nexport { idTokenClaimsSchema, oidcCallbackSchema, tokenResponseSchema } from './types/oidc-schema';\nexport type {\n Address,\n Email,\n EnterpriseExtension,\n Group,\n GroupMember,\n GroupResource,\n Name,\n PhoneNumber,\n Role,\n User as ScimUser,\n X509Certificate,\n} from './types/scim-schema';\n// SCIM types (for IAM/provisioning)\nexport { groupResourceSchema, userSchema } from './types/scim-schema';\n// Standard Schema\nexport type { StandardSchemaV1 } from './types/standard-schema';\nexport type { User } from './types/user';\nexport type {\n JWTAssertionClaims,\n TokenValidationResult,\n WorkloadTokenResponse,\n} from './types/workload-schema';\nexport { jwtAssertionClaimsSchema, workloadTokenResponseSchema } from './types/workload-schema';\n// UI Components\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// User store\nexport type { StoredUser, UserStore } from './user-store';\nexport { InMemoryUserStore } from './user-store';\n// Utils (for accessing default instance)\nexport { getDefaultInstance, getES } from './utils';\nexport type { Vault } from './vault';\n// Vault\nexport { vault } from './vault';\n// Workload Identity\nexport type {\n ClientCredentialsWorkloadConfig,\n JwtBearerWorkloadConfig,\n ServerOnlyWorkloadConfig,\n Workload,\n WorkloadConfig,\n WorkloadIdentity,\n} from './workload';\nexport { workload } from './workload';\nexport type { CachedWorkloadToken, WorkloadTokenStore } from './workload-token-store';\nexport { InMemoryWorkloadTokenStore } from './workload-token-store';\n"
17
25
  ],
18
- "mappings": "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",
19
- "debugId": "11B14D9E3E6DAB9F64756E2164756E21",
26
+ "mappings": "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",
27
+ "debugId": "BB2BA44916C99DF364756E2164756E21",
20
28
  "names": []
21
29
  }