@enterprisestandard/core 0.0.13 → 0.0.14-beta.20260331.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -2352,6 +2352,95 @@ declare class InMemoryTenantStore<
2352
2352
  private resolveTenantsByUserId;
2353
2353
  }
2354
2354
  declare function sendTenantWebhook(webhookUrl: string, payload: TenantWebhookPayload, log: Logger): Promise<void>;
2355
+ /**
2356
+ * Magic link data stored in the store.
2357
+ *
2358
+ * @template TExtended - Type-safe custom data that consumers can add to magic links
2359
+ */
2360
+ type MagicLink<TExtended = object> = {
2361
+ /**
2362
+ * The magic link token (unique identifier)
2363
+ */
2364
+ token: string;
2365
+ /**
2366
+ * User information associated with this magic link
2367
+ */
2368
+ user: BaseUser;
2369
+ /**
2370
+ * Timestamp when the magic link was created
2371
+ */
2372
+ createdAt: Date;
2373
+ /**
2374
+ * Timestamp when the magic link expires
2375
+ */
2376
+ expiresAt: Date;
2377
+ /**
2378
+ * Allow consumers to add runtime data to magic links
2379
+ */
2380
+ [key: string]: unknown;
2381
+ } & TExtended;
2382
+ /**
2383
+ * Abstract interface for magic link storage backends.
2384
+ *
2385
+ * Consumers can implement this interface to use different storage backends:
2386
+ * - In-memory (for development/testing)
2387
+ * - Redis (for production with fast lookups and automatic expiration)
2388
+ * - Database (PostgreSQL, MySQL, etc.)
2389
+ *
2390
+ * @template TExtended - Type-safe custom data that consumers can add to magic links
2391
+ *
2392
+ * @example
2393
+ * ```typescript
2394
+ * // Custom magic link data
2395
+ * type MyMagicLinkData = {
2396
+ * source: string;
2397
+ * metadata: Record<string, unknown>;
2398
+ * };
2399
+ *
2400
+ * // Implement custom store
2401
+ * class RedisMagicLinkStore implements MagicLinkStore<MyMagicLinkData> {
2402
+ * async create(token: string, user: BaseUser, expiresAt: Date): Promise<void> {
2403
+ * const magicLink: MagicLink<MyMagicLinkData> = {
2404
+ * token,
2405
+ * user,
2406
+ * createdAt: new Date(),
2407
+ * expiresAt,
2408
+ * source: 'api',
2409
+ * metadata: {},
2410
+ * };
2411
+ * const ttl = Math.floor((expiresAt.getTime() - Date.now()) / 1000);
2412
+ * await redis.setex(`magic-link:${token}`, ttl, JSON.stringify(magicLink));
2413
+ * }
2414
+ * // ... other methods
2415
+ * }
2416
+ * ```
2417
+ */
2418
+ interface MagicLinkStore<TExtended = object> {
2419
+ /**
2420
+ * Create a new magic link in the store.
2421
+ *
2422
+ * @param token - The magic link token (unique identifier)
2423
+ * @param user - The user information to associate with this magic link
2424
+ * @param expiresAt - When the magic link expires
2425
+ * @throws Error if magic link with same token already exists
2426
+ */
2427
+ create(token: string, user: BaseUser, expiresAt: Date): Promise<void>;
2428
+ /**
2429
+ * Retrieve a magic link by its token.
2430
+ *
2431
+ * @param token - The magic link token
2432
+ * @returns The magic link if found and not expired, null otherwise
2433
+ */
2434
+ get(token: string): Promise<MagicLink<TExtended> | null>;
2435
+ /**
2436
+ * Delete a magic link by its token.
2437
+ *
2438
+ * Used after a magic link has been consumed (one-time use).
2439
+ *
2440
+ * @param token - The magic link token to delete
2441
+ */
2442
+ delete(token: string): Promise<void>;
2443
+ }
2355
2444
  type ConfigSourceType = "vault" | "lfv" | "azure" | "aws" | "gcp" | "dev" | "localFile";
2356
2445
  type ESValidators = {
2357
2446
  sso: SSOValidators;
@@ -2405,13 +2494,26 @@ type RemoteConfig = {
2405
2494
  secrets?: SecretsModuleConfig;
2406
2495
  ciam?: CIAMConfig;
2407
2496
  };
2497
+ /**
2498
+ * Stores supplied by the framework/application when creating an Enterprise Standard instance.
2499
+ */
2500
+ type FrameworkStores = {
2501
+ sessionStore?: SessionStore<unknown>;
2502
+ userStore?: UserStore<unknown>;
2503
+ groupStore?: GroupStore<unknown>;
2504
+ magicLinkStore?: MagicLinkStore<unknown>;
2505
+ workloadTokenStore?: WorkloadTokenStore;
2506
+ };
2507
+ type ModifiableFrameworkConfig = FrameworkConfig & {
2508
+ setStores(stores: FrameworkStores): void;
2509
+ };
2408
2510
  /** Return type from the beforeChange hook passed to enterpriseStandard(). */
2409
2511
  type ESConfigChangeResult = {
2410
2512
  config?: RemoteConfig;
2411
2513
  frameworkConfig?: FrameworkConfig;
2412
2514
  };
2413
2515
  /** beforeChange callback invoked on every config application (initial load and updates). */
2414
- type ESConfigChangeCallback = (config: RemoteConfig, frameworkConfig: FrameworkConfig, oldConfig: RemoteConfig | undefined) => ESConfigChangeResult | void;
2516
+ type ESConfigChangeCallback = (config: RemoteConfig, frameworkConfig: ModifiableFrameworkConfig, oldConfig: RemoteConfig | undefined) => ESConfigChangeResult | void;
2415
2517
  type ConfigSource = {
2416
2518
  load(): Promise<RemoteConfig>;
2417
2519
  /**
@@ -2542,102 +2644,13 @@ type ESRoutingOptions = {
2542
2644
  */
2543
2645
  type ESConfigChangeOptions = {
2544
2646
  beforeChange?: ESConfigChangeCallback;
2545
- afterChange?: (es: EnterpriseStandard, config: RemoteConfig, frameworkConfig: FrameworkConfig, oldConfig: RemoteConfig | undefined) => void;
2647
+ afterChange?: (es: EnterpriseStandard, config: RemoteConfig, frameworkConfig: ModifiableFrameworkConfig, oldConfig: RemoteConfig | undefined) => void;
2546
2648
  /**
2547
2649
  * Optional runtime routing customization for `es.handler(request)`.
2548
2650
  */
2549
2651
  routing?: ESRoutingOptions;
2550
2652
  };
2551
2653
  /**
2552
- * Magic link data stored in the store.
2553
- *
2554
- * @template TExtended - Type-safe custom data that consumers can add to magic links
2555
- */
2556
- type MagicLink<TExtended = object> = {
2557
- /**
2558
- * The magic link token (unique identifier)
2559
- */
2560
- token: string;
2561
- /**
2562
- * User information associated with this magic link
2563
- */
2564
- user: BaseUser;
2565
- /**
2566
- * Timestamp when the magic link was created
2567
- */
2568
- createdAt: Date;
2569
- /**
2570
- * Timestamp when the magic link expires
2571
- */
2572
- expiresAt: Date;
2573
- /**
2574
- * Allow consumers to add runtime data to magic links
2575
- */
2576
- [key: string]: unknown;
2577
- } & TExtended;
2578
- /**
2579
- * Abstract interface for magic link storage backends.
2580
- *
2581
- * Consumers can implement this interface to use different storage backends:
2582
- * - In-memory (for development/testing)
2583
- * - Redis (for production with fast lookups and automatic expiration)
2584
- * - Database (PostgreSQL, MySQL, etc.)
2585
- *
2586
- * @template TExtended - Type-safe custom data that consumers can add to magic links
2587
- *
2588
- * @example
2589
- * ```typescript
2590
- * // Custom magic link data
2591
- * type MyMagicLinkData = {
2592
- * source: string;
2593
- * metadata: Record<string, unknown>;
2594
- * };
2595
- *
2596
- * // Implement custom store
2597
- * class RedisMagicLinkStore implements MagicLinkStore<MyMagicLinkData> {
2598
- * async create(token: string, user: BaseUser, expiresAt: Date): Promise<void> {
2599
- * const magicLink: MagicLink<MyMagicLinkData> = {
2600
- * token,
2601
- * user,
2602
- * createdAt: new Date(),
2603
- * expiresAt,
2604
- * source: 'api',
2605
- * metadata: {},
2606
- * };
2607
- * const ttl = Math.floor((expiresAt.getTime() - Date.now()) / 1000);
2608
- * await redis.setex(`magic-link:${token}`, ttl, JSON.stringify(magicLink));
2609
- * }
2610
- * // ... other methods
2611
- * }
2612
- * ```
2613
- */
2614
- interface MagicLinkStore<TExtended = object> {
2615
- /**
2616
- * Create a new magic link in the store.
2617
- *
2618
- * @param token - The magic link token (unique identifier)
2619
- * @param user - The user information to associate with this magic link
2620
- * @param expiresAt - When the magic link expires
2621
- * @throws Error if magic link with same token already exists
2622
- */
2623
- create(token: string, user: BaseUser, expiresAt: Date): Promise<void>;
2624
- /**
2625
- * Retrieve a magic link by its token.
2626
- *
2627
- * @param token - The magic link token
2628
- * @returns The magic link if found and not expired, null otherwise
2629
- */
2630
- get(token: string): Promise<MagicLink<TExtended> | null>;
2631
- /**
2632
- * Delete a magic link by its token.
2633
- *
2634
- * Used after a magic link has been consumed (one-time use).
2635
- *
2636
- * @param token - The magic link token to delete
2637
- */
2638
- delete(token: string): Promise<void>;
2639
- }
2640
- /**
2641
2654
  * Validators for CIAM (magic link) request bodies.
2642
2655
  * Used to validate the POST body for magic link generation (BaseUser).
2643
2656
  * baseUser includes a top-level .validate() for a cleaner API (see withValidate).
@@ -3053,4 +3066,4 @@ declare function parseJsonc<T>(content: string): T;
3053
3066
  * @returns A promise that resolves when the service is ready.
3054
3067
  */
3055
3068
  declare function waitOn(url: string, test?: (resp: Response) => boolean | Promise<boolean>, pingInterval?: number, warnInterval?: number, timeout?: number): Promise<void>;
3056
- export { workloadTokenResponseSchema, withValidate, waitOn, version, validationFailureResponse, userSchema, tokenResponseSchema, stripJsonComments, silentLogger, setActiveSession, serializeESConfig, sendTenantWebhook, parseJsonc, oidcCallbackSchema, normalizeTenantRoutingStrategy, normalizeTenantPathNamespace, must, mergeConfig, matchTenantPath, listSsoClientIdsFromCookies, list, jwtAssertionClaimsSchema, infoLogger, idTokenClaimsSchema, groupResourceSchema, getActiveSession, findTenantFromStateParam, defaultLogger, decodeUser, debugLogger, consoleLogger, clearActiveSession, claimsToUser, buildTenantPath, X509Certificate, WorkloadValidators, WorkloadTokenStore, WorkloadTokenResponse, WorkloadIncomingOutgoing, WorkloadIdentity, WorkloadConfigMap, WorkloadConfig, WorkloadClient, Workload, VaultSecretsConfig, ValidateResult, UsersInboundHandlerConfig, UserStore, UserSortOptions, UserSortField, UserMode, UserListOptions, User2 as User, UpsertTenantResponse, UpsertTenantRequest, TokenValidationResult, TokenResponse, TenantWebhookPayload, TenantValidators, TenantUserRegistration, TenantStoreWithESOptions, TenantStoreWithES, TenantStoreUpsertRecord, TenantStore, TenantStatus, TenantSortOptions, TenantSortField, TenantSecretsConfig, TenantRoutingStrategy, TenantRequestError, TenantPathRoutingStrategy, TenantPathNamespace, TenantPathMatch, TenantListOptions, TenantJwtRoutingStrategy, TenantEsFactory, TenantDirectoryTenant, TenantDirectoryResponse, TenantDirectoryAccount, TenantConfigSourceInput, TenantConfigEnv, StoredUser, StoredTenantRecord, StoredTenant, StoredGroup, StateCookie, StandardSchemaWithValidate, SortDirection, SessionStore, Session, ServerOnlyWorkloadConfig, SecretsValidators, SecretsSourceType, SecretsSourceMap, SecretsSourceConfig, SecretsSource, SecretsOperationOptions, SecretsModuleConfig, Secrets, SecretRequestSeverity, SecretLifecycleRequest, Secret, User as ScimUser, ScimResult, ScimListResponse, ScimError, SSOValidators, SSOHandlerConfig, SSOConfig, SSO, Role, ResolvedLfvSecretsConfig, RemoteConfig, Photo, PhoneNumber, OidcCallbackParams, Name, MultipleTenantsForUserError, MetaData, MagicLinkStore, MagicLink, LoginConfig, Logger, ListResult, LfvSecretsConfig, JwtBearerWorkloadConfig, JWTAssertionClaims, InMemoryTenantStoreOptions, InMemoryTenantStore, IdTokenClaims, IAMValidators, IAMUsersInbound, IAMHandlerConfig, IAMGroupsOutbound, IAMGroupsInbound, IAMConfig, IAM, GroupsInboundHandlerConfig, GroupStore, GroupSortOptions, GroupSortField, GroupResource, GroupMember, GroupListOptions, Group, GcpSecretsConfig, FrameworkWorkloadIncomingOutgoing, FrameworkWorkloadConfig, FrameworkSecretsSourceConfig, FrameworkSecretsModuleConfig, FrameworkConfig, EnvironmentType, EnterpriseUser, EnterpriseStandardFromConfig, EnterpriseStandardBase, EnterpriseStandard, EnterpriseExtension, Email, ESValidators, ESRoutingOptions, ESRouteModule, ESRouteFilterResult, ESResolvedRoute, ESModuleFromConfig, ESConfigChangeResult, ESConfigChangeOptions, ESConfigChangeCallback, ESConfig, DevSecretsConfig, DEFAULT_TENANT_UI_NAMESPACE, DEFAULT_TENANT_API_NAMESPACE, CreateUserOptions, CreateTenantResponse, CreateTenantRequest, CreateGroupOptions, ConfigSourceType, ConfigSource, ClientCredentialsWorkloadConfig, CachedWorkloadToken, CIAMValidators, CIAMConfigFromCode, CIAMConfig, CIAM, BaseUser, AzureSecretsConfig, AwsSecretsConfig, AwsAuthMethod, ApplicationValidators, Address };
3069
+ export { workloadTokenResponseSchema, withValidate, waitOn, version, validationFailureResponse, userSchema, tokenResponseSchema, stripJsonComments, silentLogger, setActiveSession, serializeESConfig, sendTenantWebhook, parseJsonc, oidcCallbackSchema, normalizeTenantRoutingStrategy, normalizeTenantPathNamespace, must, mergeConfig, matchTenantPath, listSsoClientIdsFromCookies, list, jwtAssertionClaimsSchema, infoLogger, idTokenClaimsSchema, groupResourceSchema, getActiveSession, findTenantFromStateParam, defaultLogger, decodeUser, debugLogger, consoleLogger, clearActiveSession, claimsToUser, buildTenantPath, X509Certificate, WorkloadValidators, WorkloadTokenStore, WorkloadTokenResponse, WorkloadIncomingOutgoing, WorkloadIdentity, WorkloadConfigMap, WorkloadConfig, WorkloadClient, Workload, VaultSecretsConfig, ValidateResult, UsersInboundHandlerConfig, UserStore, UserSortOptions, UserSortField, UserMode, UserListOptions, User2 as User, UpsertTenantResponse, UpsertTenantRequest, TokenValidationResult, TokenResponse, TenantWebhookPayload, TenantValidators, TenantUserRegistration, TenantStoreWithESOptions, TenantStoreWithES, TenantStoreUpsertRecord, TenantStore, TenantStatus, TenantSortOptions, TenantSortField, TenantSecretsConfig, TenantRoutingStrategy, TenantRequestError, TenantPathRoutingStrategy, TenantPathNamespace, TenantPathMatch, TenantListOptions, TenantJwtRoutingStrategy, TenantEsFactory, TenantDirectoryTenant, TenantDirectoryResponse, TenantDirectoryAccount, TenantConfigSourceInput, TenantConfigEnv, StoredUser, StoredTenantRecord, StoredTenant, StoredGroup, StateCookie, StandardSchemaWithValidate, SortDirection, SessionStore, Session, ServerOnlyWorkloadConfig, SecretsValidators, SecretsSourceType, SecretsSourceMap, SecretsSourceConfig, SecretsSource, SecretsOperationOptions, SecretsModuleConfig, Secrets, SecretRequestSeverity, SecretLifecycleRequest, Secret, User as ScimUser, ScimResult, ScimListResponse, ScimError, SSOValidators, SSOHandlerConfig, SSOConfig, SSO, Role, ResolvedLfvSecretsConfig, RemoteConfig, Photo, PhoneNumber, OidcCallbackParams, Name, MultipleTenantsForUserError, ModifiableFrameworkConfig, MetaData, MagicLinkStore, MagicLink, LoginConfig, Logger, ListResult, LfvSecretsConfig, JwtBearerWorkloadConfig, JWTAssertionClaims, InMemoryTenantStoreOptions, InMemoryTenantStore, IdTokenClaims, IAMValidators, IAMUsersInbound, IAMHandlerConfig, IAMGroupsOutbound, IAMGroupsInbound, IAMConfig, IAM, GroupsInboundHandlerConfig, GroupStore, GroupSortOptions, GroupSortField, GroupResource, GroupMember, GroupListOptions, Group, GcpSecretsConfig, FrameworkWorkloadIncomingOutgoing, FrameworkWorkloadConfig, FrameworkStores, FrameworkSecretsSourceConfig, FrameworkSecretsModuleConfig, FrameworkConfig, EnvironmentType, EnterpriseUser, EnterpriseStandardFromConfig, EnterpriseStandardBase, EnterpriseStandard, EnterpriseExtension, Email, ESValidators, ESRoutingOptions, ESRouteModule, ESRouteFilterResult, ESResolvedRoute, ESModuleFromConfig, ESConfigChangeResult, ESConfigChangeOptions, ESConfigChangeCallback, ESConfig, DevSecretsConfig, DEFAULT_TENANT_UI_NAMESPACE, DEFAULT_TENANT_API_NAMESPACE, CreateUserOptions, CreateTenantResponse, CreateTenantRequest, CreateGroupOptions, ConfigSourceType, ConfigSource, ClientCredentialsWorkloadConfig, CachedWorkloadToken, CIAMValidators, CIAMConfigFromCode, CIAMConfig, CIAM, BaseUser, AzureSecretsConfig, AwsSecretsConfig, AwsAuthMethod, ApplicationValidators, Address };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{I as B,a as D0,b as T0,c as $0,d as f0,e as x0,f as A0,g as Q0,h as X0,i as Z0,j as G0,k as R0,l as Y0,m as c0,n as y0,o as z0,p as B0,q as H0,t as N0,u as W0,v as C0,w as M0,x as _0}from"./shared/core-gqcvxn3w.js";var k="0.0.13";var V=["sessionStore","userStore","groupStore","tokenStore","magicLinkStore"];function C(L){if(L===null||typeof L!=="object")return L;let T={};for(let[J,D]of Object.entries(L)){if(V.includes(J)||J==="validators")continue;T[J]=D!==null&&typeof D==="object"&&!Array.isArray(D)&&Object.getPrototypeOf(D)===Object.prototype?C(D):D}return T}function E(L){return C(L)}function z(L,T,J,D){let $=T.length,A=D??L,f=A>0?Math.floor(J/A)+1:1,x=A>0?Math.ceil(L/A):0;return{total:L,count:$,items:T,size:A,page:f,pages:x}}class N extends Error{constructor(L,T){super(L,T);this.name="TenantRequestError",Object.setPrototypeOf(this,N.prototype)}}class c extends Error{userId;tenantIds;constructor(L,T,J){super(`Multiple tenants found for user id "${L}"`,J);this.name="MultipleTenantsForUserError",this.userId=L,this.tenantIds=T,Object.setPrototypeOf(this,c.prototype)}}var H=Number.POSITIVE_INFINITY;class M{tenants=new Map;tenantEsMap=new Map;userTenantIds=new Map;ttl;userMode;createEs;findTenantByUserId;findTenantsByUserId;constructor(L){if(this.ttl=O(L.ttl),this.userMode=L.userMode,this.createEs=L.createEs,this.userMode==="singleTenantOnly"){this.findTenantByUserId=this.findSingleTenantByUserId.bind(this),this.findTenantsByUserId=void 0;return}this.findTenantByUserId=void 0,this.findTenantsByUserId=this.findMultipleTenantsByUserId.bind(this)}async get(L){return this.tenants.get(L)??null}async list(L){let T=Array.from(this.tenants.values()),J=Math.max(0,L?.start??0),D=L?.limit,$=L?.sort;if($?.length)T=[...T].sort((X,G)=>{for(let{field:Z,direction:q}of $){let F=X[Z],U=G[Z],y=j(F,U);if(y!==0)return q==="desc"?-y:y}return 0});let A=T.length,f=D!=null?J+D:void 0,x=T.slice(J,f);return z(A,x,J,D)}async upsert(L){let T=new Date,J=this.tenants.get(L.tenantId),D={...J??{},...L,companyId:L.companyId??J?.companyId??"",companyName:L.companyName??J?.companyName??"",environmentType:L.environmentType??J?.environmentType??"DEV",email:L.email??J?.email,webhookUrl:L.webhookUrl??J?.webhookUrl,callbackUrl:L.callbackUrl??J?.callbackUrl,tenantUrl:L.tenantUrl??J?.tenantUrl,status:L.status??J?.status??"completed",createdAt:L.createdAt??J?.createdAt??T,updatedAt:L.updatedAt??T};return this.tenants.set(D.tenantId,D),this.tenantEsMap.delete(D.tenantId),D}async delete(L){this.tenantEsMap.delete(L),this.tenants.delete(L)}async getEs(L){let T=await this.get(L);if(!T)throw Error(`Tenant "${L}" not found`);if(!this.createEs)throw Error("InMemoryTenantStore requires options.createEs to use getEs()");if(this.ttl===0)return this.createEs(B(T));let J=Date.now(),D=this.tenantEsMap.get(L);if(D&&D.expiresAt>J)return D.es;if(D)this.tenantEsMap.delete(L);let $=this.createEs(B(T));return this.tenantEsMap.set(L,{es:$,expiresAt:g(J,this.ttl)}),$}getCachedTenantIds(){if(this.ttl===0)return[];let L=Date.now();for(let[T,J]of this.tenantEsMap.entries())if(J.expiresAt<=L)this.tenantEsMap.delete(T);return Array.from(this.tenantEsMap.keys())}async registerUserTenantId(L,T){if(!L)return;let J=S(T);if(this.userMode==="singleTenantOnly"){this.userTenantIds.set(L,new Set([J]));return}let D=this.userTenantIds.get(L);if(D){D.add(J);return}this.userTenantIds.set(L,new Set([J]))}async findSingleTenantByUserId(L){let T=await this.resolveTenantsByUserId(L);if(T.length>1)throw new c(L,T.map((J)=>J.tenantId));return T[0]??null}async findMultipleTenantsByUserId(L){return this.resolveTenantsByUserId(L)}async resolveTenantsByUserId(L){let T=this.userTenantIds.get(L);if(!T||T.size===0)return[];let J=T.has(null),D=Array.from(T).filter((f)=>f!=null);if(D.length===0)return[];let $=await Promise.all(D.map(async(f)=>({tenantId:f,tenant:await this.get(f)}))),A=$.filter((f)=>f.tenant!=null).map((f)=>f.tenantId);if(A.length===0){if(J)this.userTenantIds.set(L,new Set([null]));else this.userTenantIds.delete(L);return[]}if(A.length!==D.length){let f=J?[null,...A]:A;this.userTenantIds.set(L,new Set(f))}return $.map((f)=>f.tenant).filter((f)=>f!=null)}}function j(L,T){let J=L===void 0||L===null,D=T===void 0||T===null;if(J&&D)return 0;if(J)return 1;if(D)return-1;if(L instanceof Date&&T instanceof Date)return L.getTime()-T.getTime();let $=String(L),A=String(T);return $.localeCompare(A)}function S(L){if(typeof L!=="string")return null;return L.trim()||null}function O(L){if(L===void 0)return H;if(L<=0)return L===0?0:H;return L}function g(L,T){if(!Number.isFinite(T))return H;return L+T}function I(L,T,J){return(async()=>{try{let D=await fetch(L,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(T)});if(!D.ok)J.error(`Failed to send webhook update: ${D.status} ${D.statusText}`)}catch(D){J.error("Failed to send webhook update:",D)}})()}async function P(L,T,J){return I(L,T,J)}var p={beforeTenantSegments:["ui"]},m={beforeTenantSegments:["api"]};function _(L){return{segments:W(L?.segments)}}function W(L){return(L??[]).map((T)=>T.trim()).filter(Boolean)}function h(L){let T=L.trim();if(!T)return"/";let J=T.replace(/\\/g,"/").replace(/\/+/g,"/");return J.startsWith("/")?J:`/${J}`}function K(L){return h(L).split("/").filter(Boolean)}function R(L){return{beforeTenantSegments:W(L?.beforeTenantSegments),afterTenantSegments:W(L?.afterTenantSegments)}}function b(L){if(!L||L.type===void 0||L.type==="path"){let J=L;return{type:"path",ui:R(J?.ui),api:R(J?.api)}}let T=L;return{...T,ui:_(T.ui),api:_(T.api)}}function o(L,T){let J=R(T),D=J.beforeTenantSegments??[],$=J.afterTenantSegments??[],A=K(L),f=D.length+1+$.length;if(A.length<f)return null;for(let Z=0;Z<D.length;Z++)if(A[Z]!==D[Z])return null;let x=D.length,X=A[x];if(!X)return null;for(let Z=0;Z<$.length;Z++)if(A[x+1+Z]!==$[Z])return null;let G=A.slice(x+1+$.length);return{tenantId:decodeURIComponent(X),restSegments:G,restPath:G.length>0?`/${G.join("/")}`:"/"}}function n(L,T="/",J){let D=R(J),$=D.beforeTenantSegments??[],A=D.afterTenantSegments??[],f=K(T),x=[...$,encodeURIComponent(L),...A,...f];return x.length>0?`/${x.join("/")}`:"/"}function Q(L,T,J,D,$){if(L===void 0||L===null){if(J)D.push({message:`${T} is required`,path:$});return}if(typeof L!=="string"){D.push({message:`${T} must be a string`,path:$});return}return L}function Y(L,T,J,D){if(L===void 0||L===null)return;if(typeof L!=="boolean"){J.push({message:`${T} must be a boolean`,path:D});return}return L}function v(L,T,J){if(L===void 0||L===null)return;if(typeof L!=="object"||L===null){T.push({message:"name must be an object",path:J});return}let D=L,$={};return $.formatted=Q(D.formatted,"formatted",!1,T,[...J,"formatted"]),$.familyName=Q(D.familyName,"familyName",!1,T,[...J,"familyName"]),$.givenName=Q(D.givenName,"givenName",!1,T,[...J,"givenName"]),$.middleName=Q(D.middleName,"middleName",!1,T,[...J,"middleName"]),$.honorificPrefix=Q(D.honorificPrefix,"honorificPrefix",!1,T,[...J,"honorificPrefix"]),$.honorificSuffix=Q(D.honorificSuffix,"honorificSuffix",!1,T,[...J,"honorificSuffix"]),$}function d(L,T,J){if(L===void 0||L===null)return;if(!Array.isArray(L)){T.push({message:"emails must be an array",path:J});return}let D=[];for(let $=0;$<L.length;$++){let A=L[$],f=[...J,$];if(typeof A!=="object"||A===null){T.push({message:"email must be an object",path:f});continue}let x=A,X=Q(x.value,"value",!0,T,[...f,"value"]);if(X)D.push({value:X,display:Q(x.display,"display",!1,T,[...f,"display"]),type:Q(x.type,"type",!1,T,[...f,"type"]),primary:Y(x.primary,"primary",T,[...f,"primary"])})}return D.length>0?D:void 0}function r(L,T,J){if(L===void 0||L===null)return;if(!Array.isArray(L)){T.push({message:"phoneNumbers must be an array",path:J});return}let D=[];for(let $=0;$<L.length;$++){let A=L[$],f=[...J,$];if(typeof A!=="object"||A===null){T.push({message:"phoneNumber must be an object",path:f});continue}let x=A,X=Q(x.value,"value",!0,T,[...f,"value"]);if(X)D.push({value:X,display:Q(x.display,"display",!1,T,[...f,"display"]),type:Q(x.type,"type",!1,T,[...f,"type"]),primary:Y(x.primary,"primary",T,[...f,"primary"])})}return D.length>0?D:void 0}function l(L,T,J){if(L===void 0||L===null)return;if(!Array.isArray(L)){T.push({message:"addresses must be an array",path:J});return}let D=[];for(let $=0;$<L.length;$++){let A=L[$],f=[...J,$];if(typeof A!=="object"||A===null){T.push({message:"address must be an object",path:f});continue}let x=A;D.push({formatted:Q(x.formatted,"formatted",!1,T,[...f,"formatted"]),streetAddress:Q(x.streetAddress,"streetAddress",!1,T,[...f,"streetAddress"]),locality:Q(x.locality,"locality",!1,T,[...f,"locality"]),region:Q(x.region,"region",!1,T,[...f,"region"]),postalCode:Q(x.postalCode,"postalCode",!1,T,[...f,"postalCode"]),country:Q(x.country,"country",!1,T,[...f,"country"]),type:Q(x.type,"type",!1,T,[...f,"type"]),primary:Y(x.primary,"primary",T,[...f,"primary"])})}return D.length>0?D:void 0}function t(L,T,J){if(L===void 0||L===null)return;if(!Array.isArray(L)){T.push({message:"groups must be an array",path:J});return}let D=[];for(let $=0;$<L.length;$++){let A=L[$],f=[...J,$];if(typeof A!=="object"||A===null){T.push({message:"group must be an object",path:f});continue}let x=A,X=Q(x.value,"value",!0,T,[...f,"value"]);if(X)D.push({value:X,$ref:Q(x.$ref,"$ref",!1,T,[...f,"$ref"]),display:Q(x.display,"display",!1,T,[...f,"display"]),type:Q(x.type,"type",!1,T,[...f,"type"])})}return D.length>0?D:void 0}function i(L,T,J){if(L===void 0||L===null)return;if(!Array.isArray(L)){T.push({message:"roles must be an array",path:J});return}let D=[];for(let $=0;$<L.length;$++){let A=L[$],f=[...J,$];if(typeof A!=="object"||A===null){T.push({message:"role must be an object",path:f});continue}let x=A,X=Q(x.value,"value",!0,T,[...f,"value"]);if(X)D.push({value:X,display:Q(x.display,"display",!1,T,[...f,"display"]),type:Q(x.type,"type",!1,T,[...f,"type"]),primary:Y(x.primary,"primary",T,[...f,"primary"])})}return D.length>0?D:void 0}function u(L,T,J){if(L===void 0||L===null)return;if(typeof L!=="object"||L===null){T.push({message:"Enterprise User extension must be an object",path:J});return}let D=L,$={};if($.employeeNumber=Q(D.employeeNumber,"employeeNumber",!1,T,[...J,"employeeNumber"]),$.costCenter=Q(D.costCenter,"costCenter",!1,T,[...J,"costCenter"]),$.organization=Q(D.organization,"organization",!1,T,[...J,"organization"]),$.division=Q(D.division,"division",!1,T,[...J,"division"]),$.department=Q(D.department,"department",!1,T,[...J,"department"]),D.manager!==void 0&&D.manager!==null)if(typeof D.manager!=="object"||D.manager===null)T.push({message:"manager must be an object",path:[...J,"manager"]});else{let A=D.manager;$.manager={value:Q(A.value,"value",!1,T,[...J,"manager","value"]),$ref:Q(A.$ref,"$ref",!1,T,[...J,"manager","$ref"]),displayName:Q(A.displayName,"displayName",!1,T,[...J,"manager","displayName"])}}return $}function a(L){return{"~standard":{version:1,vendor:L,validate:(T)=>{if(typeof T!=="object"||T===null)return{issues:[{message:"Expected an object"}]};let J=T,D=[],$={},A=Q(J.userName,"userName",!0,D,["userName"]);if(!A)return{issues:D};$.userName=A,$.id=Q(J.id,"id",!1,D,["id"]),$.externalId=Q(J.externalId,"externalId",!1,D,["externalId"]),$.displayName=Q(J.displayName,"displayName",!1,D,["displayName"]),$.nickName=Q(J.nickName,"nickName",!1,D,["nickName"]),$.profileUrl=Q(J.profileUrl,"profileUrl",!1,D,["profileUrl"]),$.title=Q(J.title,"title",!1,D,["title"]),$.userType=Q(J.userType,"userType",!1,D,["userType"]),$.preferredLanguage=Q(J.preferredLanguage,"preferredLanguage",!1,D,["preferredLanguage"]),$.locale=Q(J.locale,"locale",!1,D,["locale"]),$.timezone=Q(J.timezone,"timezone",!1,D,["timezone"]),$.password=Q(J.password,"password",!1,D,["password"]),$.active=Y(J.active,"active",D,["active"]),$.name=v(J.name,D,["name"]),$.emails=d(J.emails,D,["emails"]),$.phoneNumbers=r(J.phoneNumbers,D,["phoneNumbers"]),$.addresses=l(J.addresses,D,["addresses"]),$.groups=t(J.groups,D,["groups"]),$.roles=i(J.roles,D,["roles"]);let f="urn:ietf:params:scim:schemas:extension:enterprise:2.0:User";if(J[f]!==void 0)$[f]=u(J[f],D,[f]);if(J.schemas!==void 0)if(Array.isArray(J.schemas))$.schemas=J.schemas.filter((x)=>typeof x==="string");else D.push({message:"schemas must be an array",path:["schemas"]});if(J.meta!==void 0)if(typeof J.meta==="object"&&J.meta!==null){let x=J.meta;$.meta={resourceType:typeof x.resourceType==="string"?x.resourceType:void 0,created:typeof x.created==="string"?x.created:void 0,lastModified:typeof x.lastModified==="string"?x.lastModified:void 0,location:typeof x.location==="string"?x.location:void 0,version:typeof x.version==="string"?x.version:void 0}}else D.push({message:"meta must be an object",path:["meta"]});if(D.length>0)return{issues:D};return{value:$}}}}}function e(L,T,J){if(L===void 0||L===null)return;if(!Array.isArray(L)){T.push({message:"members must be an array",path:J});return}let D=[];for(let $=0;$<L.length;$++){let A=L[$],f=[...J,$];if(typeof A!=="object"||A===null){T.push({message:"member must be an object",path:f});continue}let x=A,X=Q(x.value,"value",!0,T,[...f,"value"]);if(X){let G=Q(x.type,"type",!1,T,[...f,"type"]);D.push({value:X,$ref:Q(x.$ref,"$ref",!1,T,[...f,"$ref"]),display:Q(x.display,"display",!1,T,[...f,"display"]),type:G==="User"||G==="Group"?G:void 0})}}return D.length>0?D:void 0}function s(L){return{"~standard":{version:1,vendor:L,validate:(T)=>{if(typeof T!=="object"||T===null)return{issues:[{message:"Expected an object"}]};let J=T,D=[],$={},A=Q(J.displayName,"displayName",!0,D,["displayName"]);if(!A)return{issues:D};if($.displayName=A,$.id=Q(J.id,"id",!1,D,["id"]),$.externalId=Q(J.externalId,"externalId",!1,D,["externalId"]),$.members=e(J.members,D,["members"]),J.schemas!==void 0)if(Array.isArray(J.schemas))$.schemas=J.schemas.filter((f)=>typeof f==="string");else D.push({message:"schemas must be an array",path:["schemas"]});if(J.meta!==void 0)if(typeof J.meta==="object"&&J.meta!==null){let f=J.meta;$.meta={resourceType:typeof f.resourceType==="string"?f.resourceType:void 0,created:typeof f.created==="string"?f.created:void 0,lastModified:typeof f.lastModified==="string"?f.lastModified:void 0,location:typeof f.location==="string"?f.location:void 0,version:typeof f.version==="string"?f.version:void 0}}else D.push({message:"meta must be an object",path:["meta"]});if(D.length>0)return{issues:D};return{value:$}}}}}function J0(L){return{"~standard":{version:1,vendor:L,validate:(T)=>{if(typeof T!=="object"||T===null)return{issues:[{message:"Expected an object"}]};let J=T,D=[],$={...J},A=["iss","sub"];for(let X of A)if(X in J){if(typeof J[X]!=="string")D.push({message:`${X} must be a string`,path:[X]})}else D.push({message:`${X} is required`,path:[X]});if("aud"in J&&J.aud!==void 0){let X=J.aud;if(typeof X!=="string"&&!Array.isArray(X))D.push({message:"aud must be a string or array of strings",path:["aud"]});else if(Array.isArray(X)&&!X.every((G)=>typeof G==="string"))D.push({message:"aud array must contain only strings",path:["aud"]})}let f=["jti","scope"];for(let X of f)if(X in J&&J[X]!==void 0){if(typeof J[X]!=="string")D.push({message:`${X} must be a string`,path:[X]})}let x=["exp","iat"];for(let X of x)if(X in J){if(typeof J[X]!=="number")D.push({message:`${X} must be a number`,path:[X]})}else D.push({message:`${X} is required`,path:[X]});if(D.length>0)return{issues:D};return{value:$}}}}}function L0(L){return{"~standard":{version:1,vendor:L,validate:(T)=>{if(typeof T!=="object"||T===null)return{issues:[{message:"Expected an object"}]};let J=T,D=[],$={};if("access_token"in J)if(typeof J.access_token==="string")$.access_token=J.access_token;else D.push({message:"access_token must be a string",path:["access_token"]});else D.push({message:"access_token is required",path:["access_token"]});if("token_type"in J)if(typeof J.token_type==="string")$.token_type=J.token_type;else D.push({message:"token_type must be a string",path:["token_type"]});else D.push({message:"token_type is required",path:["token_type"]});if("scope"in J)if(typeof J.scope==="string"||J.scope===void 0)$.scope=J.scope;else D.push({message:"scope must be a string",path:["scope"]});if("refresh_token"in J)if(typeof J.refresh_token==="string"||J.refresh_token===void 0)$.refresh_token=J.refresh_token;else D.push({message:"refresh_token must be a string",path:["refresh_token"]});if("expires"in J)if(typeof J.expires==="string"||J.expires===void 0)$.expires=J.expires;else D.push({message:"expires must be a string",path:["expires"]});if("expires_in"in J)if(typeof J.expires_in==="number"||J.expires_in===void 0)$.expires_in=J.expires_in;else D.push({message:"expires_in must be a number",path:["expires_in"]});if(D.length>0)return{issues:D};return{value:$}}}}}export{L0 as workloadTokenResponseSchema,f0 as withValidate,G0 as waitOn,k as version,A0 as validationFailureResponse,a as userSchema,T0 as tokenResponseSchema,X0 as stripJsonComments,y0 as silentLogger,W0 as setActiveSession,E as serializeESConfig,P as sendTenantWebhook,Z0 as parseJsonc,D0 as oidcCallbackSchema,b as normalizeTenantRoutingStrategy,R as normalizeTenantPathNamespace,x0 as must,Q0 as mergeConfig,o as matchTenantPath,M0 as listSsoClientIdsFromCookies,z as list,J0 as jwtAssertionClaimsSchema,z0 as infoLogger,$0 as idTokenClaimsSchema,s as groupResourceSchema,N0 as getActiveSession,_0 as findTenantFromStateParam,c0 as defaultLogger,Y0 as decodeUser,B0 as debugLogger,H0 as consoleLogger,C0 as clearActiveSession,R0 as claimsToUser,n as buildTenantPath,N as TenantRequestError,c as MultipleTenantsForUserError,M as InMemoryTenantStore,p as DEFAULT_TENANT_UI_NAMESPACE,m as DEFAULT_TENANT_API_NAMESPACE};
1
+ import{I as B,a as D0,b as T0,c as $0,d as f0,e as x0,f as A0,g as Q0,h as X0,i as Z0,j as G0,k as R0,l as Y0,m as c0,n as y0,o as z0,p as B0,q as H0,t as N0,u as W0,v as C0,w as M0,x as _0}from"./shared/core-tyde8csq.js";var k="0.0.14-beta.20260331.2";var V=["sessionStore","userStore","groupStore","tokenStore","magicLinkStore"];function C(L){if(L===null||typeof L!=="object")return L;let T={};for(let[J,D]of Object.entries(L)){if(V.includes(J)||J==="validators"||J==="setStores")continue;T[J]=D!==null&&typeof D==="object"&&!Array.isArray(D)&&Object.getPrototypeOf(D)===Object.prototype?C(D):D}return T}function E(L){return C(L)}function z(L,T,J,D){let $=T.length,A=D??L,f=A>0?Math.floor(J/A)+1:1,x=A>0?Math.ceil(L/A):0;return{total:L,count:$,items:T,size:A,page:f,pages:x}}class N extends Error{constructor(L,T){super(L,T);this.name="TenantRequestError",Object.setPrototypeOf(this,N.prototype)}}class c extends Error{userId;tenantIds;constructor(L,T,J){super(`Multiple tenants found for user id "${L}"`,J);this.name="MultipleTenantsForUserError",this.userId=L,this.tenantIds=T,Object.setPrototypeOf(this,c.prototype)}}var H=Number.POSITIVE_INFINITY;class M{tenants=new Map;tenantEsMap=new Map;userTenantIds=new Map;ttl;userMode;createEs;findTenantByUserId;findTenantsByUserId;constructor(L){if(this.ttl=O(L.ttl),this.userMode=L.userMode,this.createEs=L.createEs,this.userMode==="singleTenantOnly"){this.findTenantByUserId=this.findSingleTenantByUserId.bind(this),this.findTenantsByUserId=void 0;return}this.findTenantByUserId=void 0,this.findTenantsByUserId=this.findMultipleTenantsByUserId.bind(this)}async get(L){return this.tenants.get(L)??null}async list(L){let T=Array.from(this.tenants.values()),J=Math.max(0,L?.start??0),D=L?.limit,$=L?.sort;if($?.length)T=[...T].sort((X,G)=>{for(let{field:Z,direction:q}of $){let F=X[Z],U=G[Z],y=j(F,U);if(y!==0)return q==="desc"?-y:y}return 0});let A=T.length,f=D!=null?J+D:void 0,x=T.slice(J,f);return z(A,x,J,D)}async upsert(L){let T=new Date,J=this.tenants.get(L.tenantId),D={...J??{},...L,companyId:L.companyId??J?.companyId??"",companyName:L.companyName??J?.companyName??"",environmentType:L.environmentType??J?.environmentType??"DEV",email:L.email??J?.email,webhookUrl:L.webhookUrl??J?.webhookUrl,callbackUrl:L.callbackUrl??J?.callbackUrl,tenantUrl:L.tenantUrl??J?.tenantUrl,status:L.status??J?.status??"completed",createdAt:L.createdAt??J?.createdAt??T,updatedAt:L.updatedAt??T};return this.tenants.set(D.tenantId,D),this.tenantEsMap.delete(D.tenantId),D}async delete(L){this.tenantEsMap.delete(L),this.tenants.delete(L)}async getEs(L){let T=await this.get(L);if(!T)throw Error(`Tenant "${L}" not found`);if(!this.createEs)throw Error("InMemoryTenantStore requires options.createEs to use getEs()");if(this.ttl===0)return this.createEs(B(T));let J=Date.now(),D=this.tenantEsMap.get(L);if(D&&D.expiresAt>J)return D.es;if(D)this.tenantEsMap.delete(L);let $=this.createEs(B(T));return this.tenantEsMap.set(L,{es:$,expiresAt:g(J,this.ttl)}),$}getCachedTenantIds(){if(this.ttl===0)return[];let L=Date.now();for(let[T,J]of this.tenantEsMap.entries())if(J.expiresAt<=L)this.tenantEsMap.delete(T);return Array.from(this.tenantEsMap.keys())}async registerUserTenantId(L,T){if(!L)return;let J=S(T);if(this.userMode==="singleTenantOnly"){this.userTenantIds.set(L,new Set([J]));return}let D=this.userTenantIds.get(L);if(D){D.add(J);return}this.userTenantIds.set(L,new Set([J]))}async findSingleTenantByUserId(L){let T=await this.resolveTenantsByUserId(L);if(T.length>1)throw new c(L,T.map((J)=>J.tenantId));return T[0]??null}async findMultipleTenantsByUserId(L){return this.resolveTenantsByUserId(L)}async resolveTenantsByUserId(L){let T=this.userTenantIds.get(L);if(!T||T.size===0)return[];let J=T.has(null),D=Array.from(T).filter((f)=>f!=null);if(D.length===0)return[];let $=await Promise.all(D.map(async(f)=>({tenantId:f,tenant:await this.get(f)}))),A=$.filter((f)=>f.tenant!=null).map((f)=>f.tenantId);if(A.length===0){if(J)this.userTenantIds.set(L,new Set([null]));else this.userTenantIds.delete(L);return[]}if(A.length!==D.length){let f=J?[null,...A]:A;this.userTenantIds.set(L,new Set(f))}return $.map((f)=>f.tenant).filter((f)=>f!=null)}}function j(L,T){let J=L===void 0||L===null,D=T===void 0||T===null;if(J&&D)return 0;if(J)return 1;if(D)return-1;if(L instanceof Date&&T instanceof Date)return L.getTime()-T.getTime();let $=String(L),A=String(T);return $.localeCompare(A)}function S(L){if(typeof L!=="string")return null;return L.trim()||null}function O(L){if(L===void 0)return H;if(L<=0)return L===0?0:H;return L}function g(L,T){if(!Number.isFinite(T))return H;return L+T}function I(L,T,J){return(async()=>{try{let D=await fetch(L,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(T)});if(!D.ok)J.error(`Failed to send webhook update: ${D.status} ${D.statusText}`)}catch(D){J.error("Failed to send webhook update:",D)}})()}async function P(L,T,J){return I(L,T,J)}var p={beforeTenantSegments:["ui"]},m={beforeTenantSegments:["api"]};function _(L){return{segments:W(L?.segments)}}function W(L){return(L??[]).map((T)=>T.trim()).filter(Boolean)}function h(L){let T=L.trim();if(!T)return"/";let J=T.replace(/\\/g,"/").replace(/\/+/g,"/");return J.startsWith("/")?J:`/${J}`}function K(L){return h(L).split("/").filter(Boolean)}function R(L){return{beforeTenantSegments:W(L?.beforeTenantSegments),afterTenantSegments:W(L?.afterTenantSegments)}}function b(L){if(!L||L.type===void 0||L.type==="path"){let J=L;return{type:"path",ui:R(J?.ui),api:R(J?.api)}}let T=L;return{...T,ui:_(T.ui),api:_(T.api)}}function o(L,T){let J=R(T),D=J.beforeTenantSegments??[],$=J.afterTenantSegments??[],A=K(L),f=D.length+1+$.length;if(A.length<f)return null;for(let Z=0;Z<D.length;Z++)if(A[Z]!==D[Z])return null;let x=D.length,X=A[x];if(!X)return null;for(let Z=0;Z<$.length;Z++)if(A[x+1+Z]!==$[Z])return null;let G=A.slice(x+1+$.length);return{tenantId:decodeURIComponent(X),restSegments:G,restPath:G.length>0?`/${G.join("/")}`:"/"}}function n(L,T="/",J){let D=R(J),$=D.beforeTenantSegments??[],A=D.afterTenantSegments??[],f=K(T),x=[...$,encodeURIComponent(L),...A,...f];return x.length>0?`/${x.join("/")}`:"/"}function Q(L,T,J,D,$){if(L===void 0||L===null){if(J)D.push({message:`${T} is required`,path:$});return}if(typeof L!=="string"){D.push({message:`${T} must be a string`,path:$});return}return L}function Y(L,T,J,D){if(L===void 0||L===null)return;if(typeof L!=="boolean"){J.push({message:`${T} must be a boolean`,path:D});return}return L}function v(L,T,J){if(L===void 0||L===null)return;if(typeof L!=="object"||L===null){T.push({message:"name must be an object",path:J});return}let D=L,$={};return $.formatted=Q(D.formatted,"formatted",!1,T,[...J,"formatted"]),$.familyName=Q(D.familyName,"familyName",!1,T,[...J,"familyName"]),$.givenName=Q(D.givenName,"givenName",!1,T,[...J,"givenName"]),$.middleName=Q(D.middleName,"middleName",!1,T,[...J,"middleName"]),$.honorificPrefix=Q(D.honorificPrefix,"honorificPrefix",!1,T,[...J,"honorificPrefix"]),$.honorificSuffix=Q(D.honorificSuffix,"honorificSuffix",!1,T,[...J,"honorificSuffix"]),$}function d(L,T,J){if(L===void 0||L===null)return;if(!Array.isArray(L)){T.push({message:"emails must be an array",path:J});return}let D=[];for(let $=0;$<L.length;$++){let A=L[$],f=[...J,$];if(typeof A!=="object"||A===null){T.push({message:"email must be an object",path:f});continue}let x=A,X=Q(x.value,"value",!0,T,[...f,"value"]);if(X)D.push({value:X,display:Q(x.display,"display",!1,T,[...f,"display"]),type:Q(x.type,"type",!1,T,[...f,"type"]),primary:Y(x.primary,"primary",T,[...f,"primary"])})}return D.length>0?D:void 0}function r(L,T,J){if(L===void 0||L===null)return;if(!Array.isArray(L)){T.push({message:"phoneNumbers must be an array",path:J});return}let D=[];for(let $=0;$<L.length;$++){let A=L[$],f=[...J,$];if(typeof A!=="object"||A===null){T.push({message:"phoneNumber must be an object",path:f});continue}let x=A,X=Q(x.value,"value",!0,T,[...f,"value"]);if(X)D.push({value:X,display:Q(x.display,"display",!1,T,[...f,"display"]),type:Q(x.type,"type",!1,T,[...f,"type"]),primary:Y(x.primary,"primary",T,[...f,"primary"])})}return D.length>0?D:void 0}function l(L,T,J){if(L===void 0||L===null)return;if(!Array.isArray(L)){T.push({message:"addresses must be an array",path:J});return}let D=[];for(let $=0;$<L.length;$++){let A=L[$],f=[...J,$];if(typeof A!=="object"||A===null){T.push({message:"address must be an object",path:f});continue}let x=A;D.push({formatted:Q(x.formatted,"formatted",!1,T,[...f,"formatted"]),streetAddress:Q(x.streetAddress,"streetAddress",!1,T,[...f,"streetAddress"]),locality:Q(x.locality,"locality",!1,T,[...f,"locality"]),region:Q(x.region,"region",!1,T,[...f,"region"]),postalCode:Q(x.postalCode,"postalCode",!1,T,[...f,"postalCode"]),country:Q(x.country,"country",!1,T,[...f,"country"]),type:Q(x.type,"type",!1,T,[...f,"type"]),primary:Y(x.primary,"primary",T,[...f,"primary"])})}return D.length>0?D:void 0}function t(L,T,J){if(L===void 0||L===null)return;if(!Array.isArray(L)){T.push({message:"groups must be an array",path:J});return}let D=[];for(let $=0;$<L.length;$++){let A=L[$],f=[...J,$];if(typeof A!=="object"||A===null){T.push({message:"group must be an object",path:f});continue}let x=A,X=Q(x.value,"value",!0,T,[...f,"value"]);if(X)D.push({value:X,$ref:Q(x.$ref,"$ref",!1,T,[...f,"$ref"]),display:Q(x.display,"display",!1,T,[...f,"display"]),type:Q(x.type,"type",!1,T,[...f,"type"])})}return D.length>0?D:void 0}function i(L,T,J){if(L===void 0||L===null)return;if(!Array.isArray(L)){T.push({message:"roles must be an array",path:J});return}let D=[];for(let $=0;$<L.length;$++){let A=L[$],f=[...J,$];if(typeof A!=="object"||A===null){T.push({message:"role must be an object",path:f});continue}let x=A,X=Q(x.value,"value",!0,T,[...f,"value"]);if(X)D.push({value:X,display:Q(x.display,"display",!1,T,[...f,"display"]),type:Q(x.type,"type",!1,T,[...f,"type"]),primary:Y(x.primary,"primary",T,[...f,"primary"])})}return D.length>0?D:void 0}function u(L,T,J){if(L===void 0||L===null)return;if(typeof L!=="object"||L===null){T.push({message:"Enterprise User extension must be an object",path:J});return}let D=L,$={};if($.employeeNumber=Q(D.employeeNumber,"employeeNumber",!1,T,[...J,"employeeNumber"]),$.costCenter=Q(D.costCenter,"costCenter",!1,T,[...J,"costCenter"]),$.organization=Q(D.organization,"organization",!1,T,[...J,"organization"]),$.division=Q(D.division,"division",!1,T,[...J,"division"]),$.department=Q(D.department,"department",!1,T,[...J,"department"]),D.manager!==void 0&&D.manager!==null)if(typeof D.manager!=="object"||D.manager===null)T.push({message:"manager must be an object",path:[...J,"manager"]});else{let A=D.manager;$.manager={value:Q(A.value,"value",!1,T,[...J,"manager","value"]),$ref:Q(A.$ref,"$ref",!1,T,[...J,"manager","$ref"]),displayName:Q(A.displayName,"displayName",!1,T,[...J,"manager","displayName"])}}return $}function a(L){return{"~standard":{version:1,vendor:L,validate:(T)=>{if(typeof T!=="object"||T===null)return{issues:[{message:"Expected an object"}]};let J=T,D=[],$={},A=Q(J.userName,"userName",!0,D,["userName"]);if(!A)return{issues:D};$.userName=A,$.id=Q(J.id,"id",!1,D,["id"]),$.externalId=Q(J.externalId,"externalId",!1,D,["externalId"]),$.displayName=Q(J.displayName,"displayName",!1,D,["displayName"]),$.nickName=Q(J.nickName,"nickName",!1,D,["nickName"]),$.profileUrl=Q(J.profileUrl,"profileUrl",!1,D,["profileUrl"]),$.title=Q(J.title,"title",!1,D,["title"]),$.userType=Q(J.userType,"userType",!1,D,["userType"]),$.preferredLanguage=Q(J.preferredLanguage,"preferredLanguage",!1,D,["preferredLanguage"]),$.locale=Q(J.locale,"locale",!1,D,["locale"]),$.timezone=Q(J.timezone,"timezone",!1,D,["timezone"]),$.password=Q(J.password,"password",!1,D,["password"]),$.active=Y(J.active,"active",D,["active"]),$.name=v(J.name,D,["name"]),$.emails=d(J.emails,D,["emails"]),$.phoneNumbers=r(J.phoneNumbers,D,["phoneNumbers"]),$.addresses=l(J.addresses,D,["addresses"]),$.groups=t(J.groups,D,["groups"]),$.roles=i(J.roles,D,["roles"]);let f="urn:ietf:params:scim:schemas:extension:enterprise:2.0:User";if(J[f]!==void 0)$[f]=u(J[f],D,[f]);if(J.schemas!==void 0)if(Array.isArray(J.schemas))$.schemas=J.schemas.filter((x)=>typeof x==="string");else D.push({message:"schemas must be an array",path:["schemas"]});if(J.meta!==void 0)if(typeof J.meta==="object"&&J.meta!==null){let x=J.meta;$.meta={resourceType:typeof x.resourceType==="string"?x.resourceType:void 0,created:typeof x.created==="string"?x.created:void 0,lastModified:typeof x.lastModified==="string"?x.lastModified:void 0,location:typeof x.location==="string"?x.location:void 0,version:typeof x.version==="string"?x.version:void 0}}else D.push({message:"meta must be an object",path:["meta"]});if(D.length>0)return{issues:D};return{value:$}}}}}function e(L,T,J){if(L===void 0||L===null)return;if(!Array.isArray(L)){T.push({message:"members must be an array",path:J});return}let D=[];for(let $=0;$<L.length;$++){let A=L[$],f=[...J,$];if(typeof A!=="object"||A===null){T.push({message:"member must be an object",path:f});continue}let x=A,X=Q(x.value,"value",!0,T,[...f,"value"]);if(X){let G=Q(x.type,"type",!1,T,[...f,"type"]);D.push({value:X,$ref:Q(x.$ref,"$ref",!1,T,[...f,"$ref"]),display:Q(x.display,"display",!1,T,[...f,"display"]),type:G==="User"||G==="Group"?G:void 0})}}return D.length>0?D:void 0}function s(L){return{"~standard":{version:1,vendor:L,validate:(T)=>{if(typeof T!=="object"||T===null)return{issues:[{message:"Expected an object"}]};let J=T,D=[],$={},A=Q(J.displayName,"displayName",!0,D,["displayName"]);if(!A)return{issues:D};if($.displayName=A,$.id=Q(J.id,"id",!1,D,["id"]),$.externalId=Q(J.externalId,"externalId",!1,D,["externalId"]),$.members=e(J.members,D,["members"]),J.schemas!==void 0)if(Array.isArray(J.schemas))$.schemas=J.schemas.filter((f)=>typeof f==="string");else D.push({message:"schemas must be an array",path:["schemas"]});if(J.meta!==void 0)if(typeof J.meta==="object"&&J.meta!==null){let f=J.meta;$.meta={resourceType:typeof f.resourceType==="string"?f.resourceType:void 0,created:typeof f.created==="string"?f.created:void 0,lastModified:typeof f.lastModified==="string"?f.lastModified:void 0,location:typeof f.location==="string"?f.location:void 0,version:typeof f.version==="string"?f.version:void 0}}else D.push({message:"meta must be an object",path:["meta"]});if(D.length>0)return{issues:D};return{value:$}}}}}function J0(L){return{"~standard":{version:1,vendor:L,validate:(T)=>{if(typeof T!=="object"||T===null)return{issues:[{message:"Expected an object"}]};let J=T,D=[],$={...J},A=["iss","sub"];for(let X of A)if(X in J){if(typeof J[X]!=="string")D.push({message:`${X} must be a string`,path:[X]})}else D.push({message:`${X} is required`,path:[X]});if("aud"in J&&J.aud!==void 0){let X=J.aud;if(typeof X!=="string"&&!Array.isArray(X))D.push({message:"aud must be a string or array of strings",path:["aud"]});else if(Array.isArray(X)&&!X.every((G)=>typeof G==="string"))D.push({message:"aud array must contain only strings",path:["aud"]})}let f=["jti","scope"];for(let X of f)if(X in J&&J[X]!==void 0){if(typeof J[X]!=="string")D.push({message:`${X} must be a string`,path:[X]})}let x=["exp","iat"];for(let X of x)if(X in J){if(typeof J[X]!=="number")D.push({message:`${X} must be a number`,path:[X]})}else D.push({message:`${X} is required`,path:[X]});if(D.length>0)return{issues:D};return{value:$}}}}}function L0(L){return{"~standard":{version:1,vendor:L,validate:(T)=>{if(typeof T!=="object"||T===null)return{issues:[{message:"Expected an object"}]};let J=T,D=[],$={};if("access_token"in J)if(typeof J.access_token==="string")$.access_token=J.access_token;else D.push({message:"access_token must be a string",path:["access_token"]});else D.push({message:"access_token is required",path:["access_token"]});if("token_type"in J)if(typeof J.token_type==="string")$.token_type=J.token_type;else D.push({message:"token_type must be a string",path:["token_type"]});else D.push({message:"token_type is required",path:["token_type"]});if("scope"in J)if(typeof J.scope==="string"||J.scope===void 0)$.scope=J.scope;else D.push({message:"scope must be a string",path:["scope"]});if("refresh_token"in J)if(typeof J.refresh_token==="string"||J.refresh_token===void 0)$.refresh_token=J.refresh_token;else D.push({message:"refresh_token must be a string",path:["refresh_token"]});if("expires"in J)if(typeof J.expires==="string"||J.expires===void 0)$.expires=J.expires;else D.push({message:"expires must be a string",path:["expires"]});if("expires_in"in J)if(typeof J.expires_in==="number"||J.expires_in===void 0)$.expires_in=J.expires_in;else D.push({message:"expires_in must be a number",path:["expires_in"]});if(D.length>0)return{issues:D};return{value:$}}}}}export{L0 as workloadTokenResponseSchema,f0 as withValidate,G0 as waitOn,k as version,A0 as validationFailureResponse,a as userSchema,T0 as tokenResponseSchema,X0 as stripJsonComments,y0 as silentLogger,W0 as setActiveSession,E as serializeESConfig,P as sendTenantWebhook,Z0 as parseJsonc,D0 as oidcCallbackSchema,b as normalizeTenantRoutingStrategy,R as normalizeTenantPathNamespace,x0 as must,Q0 as mergeConfig,o as matchTenantPath,M0 as listSsoClientIdsFromCookies,z as list,J0 as jwtAssertionClaimsSchema,z0 as infoLogger,$0 as idTokenClaimsSchema,s as groupResourceSchema,N0 as getActiveSession,_0 as findTenantFromStateParam,c0 as defaultLogger,Y0 as decodeUser,B0 as debugLogger,H0 as consoleLogger,C0 as clearActiveSession,R0 as claimsToUser,n as buildTenantPath,N as TenantRequestError,c as MultipleTenantsForUserError,M as InMemoryTenantStore,p as DEFAULT_TENANT_UI_NAMESPACE,m as DEFAULT_TENANT_API_NAMESPACE};
package/dist/server.d.ts CHANGED
@@ -2057,6 +2057,95 @@ type TenantBaseRecord = {
2057
2057
  config: () => ConfigSource;
2058
2058
  };
2059
2059
  type StoredTenant<TExtended extends object = Record<string, never>> = TenantBaseRecord & TExtended;
2060
+ /**
2061
+ * Magic link data stored in the store.
2062
+ *
2063
+ * @template TExtended - Type-safe custom data that consumers can add to magic links
2064
+ */
2065
+ type MagicLink<TExtended = object> = {
2066
+ /**
2067
+ * The magic link token (unique identifier)
2068
+ */
2069
+ token: string;
2070
+ /**
2071
+ * User information associated with this magic link
2072
+ */
2073
+ user: BaseUser;
2074
+ /**
2075
+ * Timestamp when the magic link was created
2076
+ */
2077
+ createdAt: Date;
2078
+ /**
2079
+ * Timestamp when the magic link expires
2080
+ */
2081
+ expiresAt: Date;
2082
+ /**
2083
+ * Allow consumers to add runtime data to magic links
2084
+ */
2085
+ [key: string]: unknown;
2086
+ } & TExtended;
2087
+ /**
2088
+ * Abstract interface for magic link storage backends.
2089
+ *
2090
+ * Consumers can implement this interface to use different storage backends:
2091
+ * - In-memory (for development/testing)
2092
+ * - Redis (for production with fast lookups and automatic expiration)
2093
+ * - Database (PostgreSQL, MySQL, etc.)
2094
+ *
2095
+ * @template TExtended - Type-safe custom data that consumers can add to magic links
2096
+ *
2097
+ * @example
2098
+ * ```typescript
2099
+ * // Custom magic link data
2100
+ * type MyMagicLinkData = {
2101
+ * source: string;
2102
+ * metadata: Record<string, unknown>;
2103
+ * };
2104
+ *
2105
+ * // Implement custom store
2106
+ * class RedisMagicLinkStore implements MagicLinkStore<MyMagicLinkData> {
2107
+ * async create(token: string, user: BaseUser, expiresAt: Date): Promise<void> {
2108
+ * const magicLink: MagicLink<MyMagicLinkData> = {
2109
+ * token,
2110
+ * user,
2111
+ * createdAt: new Date(),
2112
+ * expiresAt,
2113
+ * source: 'api',
2114
+ * metadata: {},
2115
+ * };
2116
+ * const ttl = Math.floor((expiresAt.getTime() - Date.now()) / 1000);
2117
+ * await redis.setex(`magic-link:${token}`, ttl, JSON.stringify(magicLink));
2118
+ * }
2119
+ * // ... other methods
2120
+ * }
2121
+ * ```
2122
+ */
2123
+ interface MagicLinkStore<TExtended = object> {
2124
+ /**
2125
+ * Create a new magic link in the store.
2126
+ *
2127
+ * @param token - The magic link token (unique identifier)
2128
+ * @param user - The user information to associate with this magic link
2129
+ * @param expiresAt - When the magic link expires
2130
+ * @throws Error if magic link with same token already exists
2131
+ */
2132
+ create(token: string, user: BaseUser, expiresAt: Date): Promise<void>;
2133
+ /**
2134
+ * Retrieve a magic link by its token.
2135
+ *
2136
+ * @param token - The magic link token
2137
+ * @returns The magic link if found and not expired, null otherwise
2138
+ */
2139
+ get(token: string): Promise<MagicLink<TExtended> | null>;
2140
+ /**
2141
+ * Delete a magic link by its token.
2142
+ *
2143
+ * Used after a magic link has been consumed (one-time use).
2144
+ *
2145
+ * @param token - The magic link token to delete
2146
+ */
2147
+ delete(token: string): Promise<void>;
2148
+ }
2060
2149
  type ESValidators = {
2061
2150
  sso: SSOValidators;
2062
2151
  iam: IAMValidators;
@@ -2151,95 +2240,6 @@ type EnterpriseStandardBase = {
2151
2240
  };
2152
2241
  type EnterpriseStandard = EnterpriseStandardBase;
2153
2242
  /**
2154
- * Magic link data stored in the store.
2155
- *
2156
- * @template TExtended - Type-safe custom data that consumers can add to magic links
2157
- */
2158
- type MagicLink<TExtended = object> = {
2159
- /**
2160
- * The magic link token (unique identifier)
2161
- */
2162
- token: string;
2163
- /**
2164
- * User information associated with this magic link
2165
- */
2166
- user: BaseUser;
2167
- /**
2168
- * Timestamp when the magic link was created
2169
- */
2170
- createdAt: Date;
2171
- /**
2172
- * Timestamp when the magic link expires
2173
- */
2174
- expiresAt: Date;
2175
- /**
2176
- * Allow consumers to add runtime data to magic links
2177
- */
2178
- [key: string]: unknown;
2179
- } & TExtended;
2180
- /**
2181
- * Abstract interface for magic link storage backends.
2182
- *
2183
- * Consumers can implement this interface to use different storage backends:
2184
- * - In-memory (for development/testing)
2185
- * - Redis (for production with fast lookups and automatic expiration)
2186
- * - Database (PostgreSQL, MySQL, etc.)
2187
- *
2188
- * @template TExtended - Type-safe custom data that consumers can add to magic links
2189
- *
2190
- * @example
2191
- * ```typescript
2192
- * // Custom magic link data
2193
- * type MyMagicLinkData = {
2194
- * source: string;
2195
- * metadata: Record<string, unknown>;
2196
- * };
2197
- *
2198
- * // Implement custom store
2199
- * class RedisMagicLinkStore implements MagicLinkStore<MyMagicLinkData> {
2200
- * async create(token: string, user: BaseUser, expiresAt: Date): Promise<void> {
2201
- * const magicLink: MagicLink<MyMagicLinkData> = {
2202
- * token,
2203
- * user,
2204
- * createdAt: new Date(),
2205
- * expiresAt,
2206
- * source: 'api',
2207
- * metadata: {},
2208
- * };
2209
- * const ttl = Math.floor((expiresAt.getTime() - Date.now()) / 1000);
2210
- * await redis.setex(`magic-link:${token}`, ttl, JSON.stringify(magicLink));
2211
- * }
2212
- * // ... other methods
2213
- * }
2214
- * ```
2215
- */
2216
- interface MagicLinkStore<TExtended = object> {
2217
- /**
2218
- * Create a new magic link in the store.
2219
- *
2220
- * @param token - The magic link token (unique identifier)
2221
- * @param user - The user information to associate with this magic link
2222
- * @param expiresAt - When the magic link expires
2223
- * @throws Error if magic link with same token already exists
2224
- */
2225
- create(token: string, user: BaseUser, expiresAt: Date): Promise<void>;
2226
- /**
2227
- * Retrieve a magic link by its token.
2228
- *
2229
- * @param token - The magic link token
2230
- * @returns The magic link if found and not expired, null otherwise
2231
- */
2232
- get(token: string): Promise<MagicLink<TExtended> | null>;
2233
- /**
2234
- * Delete a magic link by its token.
2235
- *
2236
- * Used after a magic link has been consumed (one-time use).
2237
- *
2238
- * @param token - The magic link token to delete
2239
- */
2240
- delete(token: string): Promise<void>;
2241
- }
2242
- /**
2243
2243
  * Validators for CIAM (magic link) request bodies.
2244
2244
  * Used to validate the POST body for magic link generation (BaseUser).
2245
2245
  * baseUser includes a top-level .validate() for a cleaner API (see withValidate).
package/dist/server.js CHANGED
@@ -1 +1 @@
1
- import{A as _M,B as GM,C as JM,D as LM,E as DM,F as jM,G as IM,H as EM,I as PM,c as XM,d as YM,e,k as ZM,r as $M,s as FM,y as NM,z as VM}from"./shared/core-gqcvxn3w.js";function zM(W,D,j,h,q){if(!j&&!h)return;let E={...j,...h},Y={...E,signingKey:j?.signingKey,magicLinkTtl:E.magicLinkTtl??3600,sessionTtl:E.sessionTtl??86400,cookiesSecure:E.cookiesSecure!==void 0?E.cookiesSecure:!0,cookiesSameSite:E.cookiesSameSite!==void 0?E.cookiesSameSite:"Strict",cookiesPrefix:E.cookiesPrefix??(E.ciamId?`es.ciam.${E.ciamId}`:"es.ciam"),cookiesPath:E.cookiesPath??"/",sessionValidation:E.sessionValidation??"always"};function U(){if(!Y.signingKey)throw Error("Missing CIAM configuration field: signingKey. CIAM signingKey is required for JWT token signing and must be provided via Vault (ciam.signingKey).")}function g(){if(!Y.sessionStore)throw Error("Missing CIAM configuration field: sessionStore. CIAM sessionStore is required for server-side session tracking and backchannel logout.");return Y.sessionStore}function m(){U(),g()}function i(M=32){let A=new Uint8Array(M);return crypto.getRandomValues(A),Array.from(A,(X)=>X.toString(16).padStart(2,"0")).join("").substring(0,M)}function l(M){let A=typeof M==="string"?new TextEncoder().encode(M):M,X="";return A.forEach((Z)=>{X+=String.fromCharCode(Z)}),btoa(X).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function t(M){let A=M.replace(/-/g,"+").replace(/_/g,"/"),X=A.padEnd(A.length+(4-A.length%4)%4,"=");return atob(X)}async function x(){U();let M=new TextEncoder().encode(Y.signingKey??"");return crypto.subtle.importKey("raw",M,{name:"HMAC",hash:"SHA-256"},!1,["sign","verify"])}async function f(M){let X=l(JSON.stringify({alg:"HS256",typ:"JWT"})),Z=l(JSON.stringify(M)),K=`${X}.${Z}`,_=await x(),O=await crypto.subtle.sign("HMAC",_,new TextEncoder().encode(K)),I=l(new Uint8Array(O));return`${K}.${I}`}async function k(M){let A=M.split(".");if(A.length!==3)throw Error("Invalid JWT");let[X,Z,K]=A,_=`${X}.${Z}`,O=await x(),I=new Uint8Array(t(K).split("").map((T)=>T.charCodeAt(0)));if(!await crypto.subtle.verify("HMAC",O,I,new TextEncoder().encode(_)))throw Error("Invalid JWT signature");let u=t(Z),c=JSON.parse(u);if(typeof c.exp==="number"&&c.exp<Math.floor(Date.now()/1000))throw Error("Token expired");return c}function B(M,A,X){if(!Y)throw Error("Enterprise Standard CIAM Manager not initialized");if(M=`${Y.cookiesPrefix}.${M}`,typeof A!=="string")A=btoa(JSON.stringify(A));let Z;if(X instanceof Date)Z=`Expires=${X.toUTCString()}`;else if(typeof X==="number")Z=`Max-Age=${X}`;else throw Error("Invalid expires type",X);if(A.length>4000)throw Error(`Error setting cookie: ${M}. Cookie length is: ${A.length}`);return`${M}=${A}; ${Z}; Path=${Y.cookiesPath}; HttpOnly;${Y.cookiesSecure?" Secure;":""} SameSite=${Y.cookiesSameSite};`}function G(M){if(!Y)throw Error("Enterprise Standard CIAM Manager not initialized");return`${Y.cookiesPrefix}.${M}=; Max-Age=0; Path=${Y.cookiesPath}; HttpOnly;${Y.cookiesSecure?" Secure;":""} SameSite=${Y.cookiesSameSite};`}function J(M,A,X=!1){if(!Y)throw Error("Enterprise Standard CIAM Manager not initialized");let Z=A.headers.get("cookie");if(!Z)return null;let K=`${Y.cookiesPrefix}.${M}`,_=Z.split(";").find((C)=>C.trim().startsWith(`${K}=`));if(!_)return null;let O=_.indexOf("="),I=_.substring(O+1).trim();if(!X)return I;try{let C=atob(I);return JSON.parse(C)}catch(C){return console.error(`[CIAM] Failed to parse cookie '${K}':`,C),null}}function P(M,A,X){let Z={expires_in:Y.sessionTtl??86400,token_type:"Bearer",expires:X.toISOString()};return[["Set-Cookie",B("access",M,X)],["Set-Cookie",B("id",A,X)],["Set-Cookie",B("control",Z,X)]]}function v(M){let A=J("access",M),X=J("id",M),Z=J("control",M,!0);if(!A||!X||!Z)return;if(Z.expires&&Date.now()>new Date(Z.expires).getTime())return;return{access:A,id:X,control:Z}}async function w(M){if(!Y)throw Error("Enterprise Standard CIAM Manager not initialized");m();try{let A=v(M);if(!A)return;let X=await k(A.access),Z=await k(A.id);if(!X.sid||!Z.sub)return;if(Y.sessionValidation!=="disabled"){if(!await g().get(X.sid))return}return z(Z)}catch(A){return}}async function b(M){let A=await w(M);if(A)return A;throw new Response("Unauthorized",{status:401,statusText:"Unauthorized"})}async function p(M){if(!Y)throw Error("Enterprise Standard CIAM Manager not initialized");m();try{let O=v(M);if(O){let I=await k(O.access);if(I.sid)await g().delete(I.sid)}}catch(O){console.warn("Failed to delete CIAM session:",O)}let A=[["Set-Cookie",G("access")],["Set-Cookie",G("id")],["Set-Cookie",G("control")]],Z=new URL(M.url).searchParams.get("redirect");if(Z)return new Response("Logged out",{status:302,headers:[["Location",Z],...A]});let K=M.headers.get("accept");if(K?.includes("application/json")||K?.includes("text/javascript"))return new Response(JSON.stringify({success:!0,message:"Logged out"}),{status:200,headers:[["Content-Type","application/json"],...A]});return new Response("Logout Complete",{status:200,headers:[["Content-Type","text/plain"],...A]})}async function y(M){if(!Y)throw Error("Enterprise Standard CIAM Manager not initialized");m();try{let A=M.headers.get("content-type");if(!A||!A.includes("application/x-www-form-urlencoded"))return new Response("Invalid Content-Type, expected application/x-www-form-urlencoded",{status:400});let X=await M.text(),K=new URLSearchParams(X).get("logout_token");if(!K)return new Response("Missing logout_token parameter",{status:400});let O=(await k(K)).sid;if(!O)return new Response("Invalid logout_token: missing sid claim",{status:400});return await g().delete(O),new Response("OK",{status:200})}catch(A){return console.error("Error during CIAM back-channel logout:",A),new Response("Internal Server Error",{status:500})}}function S(M){return M.id||M.email||`ciam-${M.userName}`}function V(M,A,X){return{sub:S(M),iss:"ciam",aud:"ciam",exp:Math.floor(X.getTime()/1000),iat:Math.floor(Date.now()/1000),email:M.email,name:M.name,preferred_username:M.userName,picture:M.avatar,sid:A}}function Q(M,A,X){return{sub:M,iss:"ciam",aud:"ciam",exp:Math.floor(X.getTime()/1000),iat:Math.floor(Date.now()/1000),sid:A,scope:"openid profile email"}}function z(M){let A=M.exp?new Date(M.exp*1000):new Date;return{id:M.sub,userName:M.preferred_username??"",name:M.name??"",email:M.email??"",avatar:M.picture,userType:"customer",sso:{profile:M,tenant:{id:"ciam",name:"CIAM"},scope:"openid profile email",tokenType:"Bearer",expires:A}}}async function H(M){if(!Y)throw Error("Enterprise Standard CIAM Manager not initialized");if(!q)return new Response(JSON.stringify({error:"Workload authentication required"}),{status:401,headers:{"Content-Type":"application/json"}});if(!await q.getWorkloadIdentity(M))return new Response(JSON.stringify({error:"Unauthorized: Valid workload token required"}),{status:401,headers:{"Content-Type":"application/json"}});let X,Z;try{let n=M.headers.get("content-type");if(!n||!n.includes("application/json"))return new Response(JSON.stringify({error:"Content-Type must be application/json"}),{status:400,headers:{"Content-Type":"application/json"}});let a=await M.text(),R=JSON.parse(a);if(Z=typeof R?.redirect==="string"&&R.redirect.length>0?R.redirect:void 0,X={userName:R.userName,name:R.name,email:R.email,avatar:R.avatar},!X.userName||!X.name||!X.email)return new Response(JSON.stringify({error:"Missing required fields: userName, name, email"}),{status:400,headers:{"Content-Type":"application/json"}})}catch(n){return new Response(JSON.stringify({error:"Invalid JSON in request body"}),{status:400,headers:{"Content-Type":"application/json"}})}let _=new URL(M.url).searchParams.get("ttl"),O=_?parseInt(_,10):Y.magicLinkTtl??3600;if(Number.isNaN(O)||O<=0)return new Response(JSON.stringify({error:"Invalid TTL parameter"}),{status:400,headers:{"Content-Type":"application/json"}});let I=i(32),C=new Date(Date.now()+O*1000);if(!Y.magicLinkStore)return new Response(JSON.stringify({error:"Magic link store not configured"}),{status:500,headers:{"Content-Type":"application/json"}});try{await Y.magicLinkStore.create(I,X,C)}catch(n){return console.error("Error creating magic link:",n),new Response(JSON.stringify({error:"Failed to create magic link"}),{status:500,headers:{"Content-Type":"application/json"}})}let u=new URL(M.url),c=Y.magicLinkLoginUrl||"/magic-link/login",T=new URL(c,u.origin);if(T.searchParams.set("token",I),Z)T.searchParams.set("redirect",Z);return new Response(JSON.stringify({magicLink:T.toString(),expiresAt:C.toISOString()}),{status:200,headers:{"Content-Type":"application/json"}})}async function F(M){if(!Y)throw Error("Enterprise Standard CIAM Manager not initialized");m();let A=new URL(M.url),X=A.searchParams.get("token");if(!X){let L=Y.errorUrl||"/";return new Response("Redirecting to error URL",{status:302,headers:{Location:L}})}if(!Y.magicLinkStore){let L=Y.errorUrl||"/";return new Response("Redirecting to error URL",{status:302,headers:{Location:L}})}let Z=await Y.magicLinkStore.get(X);if(!Z){let L=Y.errorUrl||"/";return new Response("Redirecting to error URL",{status:302,headers:{Location:L}})}let K=new Date(Date.now()+(Y.sessionTtl??86400)*1000),_=i(32),O=S(Z.user),I=V(Z.user,_,K),C=Q(O,_,K),u=z(I);try{let L={sid:_,sub:O,createdAt:new Date,lastActivityAt:new Date};await g().create(L)}catch(L){console.warn("Failed to create session:",L)}if(Y.userStore)try{let L=u.id;if(L){let r=new Date,o=await Y.userStore.get(L);if(o||Y.enableJitUserProvisioning){let HM={...o??{},...u,id:L,tenantId:o?.tenantId,createdAt:o?.createdAt??r,updatedAt:r,userType:o?.userType??"customer"};await Y.userStore.upsert(HM)}}}catch(L){console.warn("Failed to store user:",L)}try{await Y.magicLinkStore.delete(X)}catch(L){console.warn("Failed to delete magic link:",L)}let c=await f(C),T=await f(I),n=Y.landingUrl||"/",a=A.searchParams.get("redirect"),R=n;if(a)if(a.startsWith("/"))R=a;else try{if(new URL(a).origin===new URL(M.url).origin)R=a}catch{}return new Response("Authentication successful, redirecting",{status:302,headers:[["Location",R],...P(c,T,K)]})}async function $(M){if(!Y)throw Error("Enterprise Standard CIAM Manager not initialized");m();let A=Y.magicLinkUrl||"/magic-link",X=Y.magicLinkLoginUrl||"/magic-link/login",Z=Y.logoutUrl||"/auth/logout",K=Y.logoutBackChannelUrl||"/auth/logout/backchannel",_=new URL(M.url).pathname,O=(T)=>{if(!T)return;try{return new URL(T).pathname}catch{return T.startsWith("/")?T:`/${T}`}};if(O(A)===_&&M.method==="POST")return H(M);if(O(X)===_&&M.method==="GET")return F(M);if(O(Z)===_&&M.method==="GET")return p(M);if(O(K)===_&&M.method==="POST")return y(M);return new Response("Not Found",{status:404})}return{...Y,getUser:w,getRequiredUser:b,logout:p,logoutBackChannel:y,handler:$}}async function BM(W,D){return e(D,"EnterpriseStandard instance is required. Create one with enterpriseStandard(source, config) and pass it to this function."),D.ciam?.getUser(W)}function N(W,D,j){return new Response(JSON.stringify({schemas:["urn:ietf:params:scim:api:messages:2.0:Error"],status:String(W),scimType:j,detail:D}),{status:W,headers:{"Content-Type":"application/scim+json"}})}function MM(W,D){let j=D?.totalResults??W.length,h=D?.startIndex??1,q=D?.itemsPerPage??W.length;return new Response(JSON.stringify({schemas:["urn:ietf:params:scim:api:messages:2.0:ListResponse"],totalResults:j,startIndex:h,itemsPerPage:q,Resources:W}),{status:200,headers:{"Content-Type":"application/scim+json"}})}function d(W,D=200){return new Response(JSON.stringify(W),{status:D,headers:{"Content-Type":"application/scim+json"}})}function s(W){return{schemas:["urn:ietf:params:scim:schemas:core:2.0:Group"],id:W.id,externalId:W.externalId,displayName:W.displayName,members:W.members,meta:{resourceType:"Group",created:W.createdAt.toISOString(),lastModified:W.updatedAt.toISOString()}}}function AM(){return crypto.randomUUID()}function SM(W,D,j,h,q){if(!h&&!q)return;let Y={...h,...q};function U(){if(!j)throw D.error?.("IAM requires workload configuration before use"),Error("IAM requires workload configuration");return j}async function g(){let B=U(),G=typeof B.getServerToken==="function"?await B.getServerToken():await B.getToken();return new Headers({"Content-Type":"application/scim+json",Accept:"application/scim+json",Authorization:`Bearer ${G}`})}async function m(B,G,J,P){if(!Y.url)throw Error("IAM URL not configured for outgoing requests");let v=`${Y.url}${G}`;try{let w=await g(),b=await fetch(v,{method:B,headers:w,body:J?JSON.stringify(J):void 0}),p=await b.json();if(!b.ok)return{success:!1,error:p,status:b.status};let y=await P["~standard"].validate(p);if(y.issues)return console.error("SCIM response validation failed:",y.issues),{success:!1,error:{schemas:["urn:ietf:params:scim:api:messages:2.0:Error"],status:"400",scimType:"invalidValue",detail:`Response validation failed: ${y.issues.map((S)=>S.message).join("; ")}`},status:400};return{success:!0,data:y.value,status:b.status}}catch(w){return{success:!1,error:{schemas:["urn:ietf:params:scim:api:messages:2.0:Error"],status:"500",detail:w instanceof Error?w.message:"Unknown error occurred"},status:500}}}function i(){return Y.url}let l,t;if(Y.url)t=async(G,J)=>{let P={...G,schemas:G.schemas??["urn:ietf:params:scim:schemas:core:2.0:User","urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"]};return m("POST","/Users",P,W.user)},l={createGroup:async(G,J)=>{let P={schemas:["urn:ietf:params:scim:schemas:core:2.0:Group"],displayName:G,externalId:J?.externalId,members:J?.members};return m("POST","/Groups",P,W.group)}};let x;if(Y.groupStore){let B=Y.groupStore,G=async(S)=>{let V=U(),Q=S.headers.get("Authorization");if(!Q||!Q.startsWith("Bearer "))return!1;try{let z=Q.substring(7);return(await V.validateToken(z)).valid}catch{return!1}},J=async(S,V)=>{if(!await G(S))return N(401,"Authorization required");let z=new URL(S.url),H=V?.basePath??"/Groups",F=z.pathname;if(F.startsWith(H))F=F.substring(H.length);let M=F.match(/^\/([^/]+)$/)?.[1],A=S.method;try{if(M)switch(A){case"GET":return await v(M);case"PUT":return await b(S,M);case"PATCH":return await p(S,M);case"DELETE":return await y(M);default:return N(405,"Method not allowed")}else if(F===""||F==="/")switch(A){case"GET":return await P(S);case"POST":return await w(S);default:return N(405,"Method not allowed")}return N(404,"Resource not found")}catch(X){return console.error("Groups inbound handler error:",X),N(500,X instanceof Error?X.message:"Internal server error")}},P=async(S)=>{let V=new URL(S.url),Q=V.searchParams.get("startIndex"),z=V.searchParams.get("count"),H=Q!=null?parseInt(Q,10):void 0,F=z!=null?parseInt(z,10):void 0,$=H!=null&&!Number.isNaN(H)?Math.max(0,H-1):0,M=F!=null&&!Number.isNaN(F)?F:void 0,A=await B.list({start:$,limit:M}),X=A.items.map(s);return MM(X,{totalResults:A.total,startIndex:$+1,itemsPerPage:A.count})},v=async(S)=>{let V=await B.get(S);if(!V)return N(404,`Group ${S} not found`,"invalidValue");return d(s(V))},w=async(S)=>{let V=await S.json(),Q=await W.group["~standard"].validate(V);if(Q.issues)return console.error("Group creation validation failed:",Q.issues),N(400,`Request validation failed: ${Q.issues.map(($)=>$.message).join("; ")}`,"invalidValue");let z=Q.value;if(!z.displayName)return N(400,"displayName is required","invalidValue");let H=new Date,F={id:AM(),displayName:z.displayName,externalId:z.externalId,members:z.members,createdAt:H,updatedAt:H};return await B.upsert(F),d(s(F),201)},b=async(S,V)=>{let Q=await B.get(V);if(!Q)return N(404,`Group ${V} not found`,"invalidValue");let z=await S.json(),H=await W.group["~standard"].validate(z);if(H.issues)return console.error("Group replacement validation failed:",H.issues),N(400,`Request validation failed: ${H.issues.map((M)=>M.message).join("; ")}`,"invalidValue");let F=H.value,$={...Q,displayName:F.displayName??Q.displayName,externalId:F.externalId,members:F.members,updatedAt:new Date};return await B.upsert($),d(s($))},p=async(S,V)=>{let Q=await B.get(V);if(!Q)return N(404,`Group ${V} not found`,"invalidValue");let H=(await S.json()).Operations??[],F={...Q};for(let $ of H)if($.op==="replace"&&$.path&&$.value!==void 0){if($.path==="displayName")F.displayName=$.value}else if($.op==="add"&&$.path&&$.value!==void 0){if($.path==="members"){let M=$.value;F.members=[...F.members??[],...M]}}else if($.op==="remove"&&$.path){if($.path.startsWith("members[")){let M=$.path.match(/members\[value eq "([^"]+)"\]/);if(M)F.members=(F.members??[]).filter((A)=>A.value!==M[1])}}return F.updatedAt=new Date,await B.upsert(F),d(s(F))},y=async(S)=>{if(!await B.get(S))return N(404,`Group ${S} not found`,"invalidValue");return await B.delete(S),new Response(null,{status:204})};x={handler:J}}let f;if(Y.userStore){let B=Y.userStore,G=async(Q)=>{let z=U(),H=Q.headers.get("Authorization");if(!H||!H.startsWith("Bearer "))return!1;try{let F=H.substring(7);return(await z.validateToken(F)).valid}catch{return!1}},J=(Q)=>{return{schemas:["urn:ietf:params:scim:schemas:core:2.0:User","urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"],id:Q.id,userName:Q.userName||Q.email||Q.id,displayName:Q.name||Q.userName||Q.email,name:Q.name?{givenName:Q.name.split(" ")[0],familyName:Q.name.split(" ").slice(1).join(" ")||void 0}:void 0,emails:Q.email?[{value:Q.email,primary:!0}]:[],active:!0,...Q.userType!=null&&{userType:Q.userType},meta:{resourceType:"User",created:Q.createdAt.toISOString(),lastModified:Q.updatedAt.toISOString()}}},P=(Q)=>{let z=new Date,H=Q.emails?.find((A)=>A.primary)?.value||Q.emails?.[0]?.value,F=Q.name?`${Q.name.givenName||""} ${Q.name.familyName||""}`.trim():Q.displayName,$=Q.id||AM(),M=Q.userName||H||$;return{id:$,userName:M,name:F||Q.displayName||M,email:H||M,avatar:Q.profileUrl,sso:{profile:{sub:$,iss:"iam-provisioned",aud:"iam-provisioned",exp:Math.floor(Date.now()/1000)+3600,iat:Math.floor(Date.now()/1000),email:H||M,email_verified:!0,name:F||Q.displayName||M,preferred_username:M},tenant:{id:"iam-provisioned",name:"IAM Provisioned"},scope:"openid profile email",tokenType:"Bearer",expires:new Date(Date.now()+3600000)},createdAt:Q.meta?.created?new Date(Q.meta.created):z,updatedAt:Q.meta?.lastModified?new Date(Q.meta.lastModified):z,...Q.userType!=null&&{userType:Q.userType}}},v=async(Q,z)=>{if(!await G(Q))return N(401,"Authorization required");let F=new URL(Q.url),$=z?.basePath??"/Users",M=F.pathname;if(M.startsWith($))M=M.substring($.length);let X=M.match(/^\/([^/]+)$/)?.[1],Z=Q.method;try{if(X)switch(Z){case"GET":return await b(X);case"PUT":return await y(Q,X);case"PATCH":return await S(Q,X);case"DELETE":return await V(X);default:return N(405,"Method not allowed")}else if(M===""||M==="/")switch(Z){case"GET":return await w(Q);case"POST":return await p(Q);default:return N(405,"Method not allowed")}return N(404,"Resource not found")}catch(K){return console.error("Users inbound handler error:",K),N(500,K instanceof Error?K.message:"Internal server error")}},w=async(Q)=>{let z=new URL(Q.url),H=z.searchParams.get("startIndex"),F=z.searchParams.get("count"),$=H!=null?parseInt(H,10):void 0,M=F!=null?parseInt(F,10):void 0,A=$!=null&&!Number.isNaN($)?Math.max(0,$-1):0,X=M!=null&&!Number.isNaN(M)?M:void 0,Z=await B.list({start:A,limit:X}),K=Z.items.map(J);return MM(K,{totalResults:Z.total,startIndex:A+1,itemsPerPage:Z.count})},b=async(Q)=>{let z=await B.get(Q);if(!z)return N(404,`User ${Q} not found`,"invalidValue");return d(J(z))},p=async(Q)=>{let z=await Q.json(),H=await W.user["~standard"].validate(z);if(H.issues)return console.error("User creation validation failed:",H.issues),N(400,`Request validation failed: ${H.issues.map((M)=>M.message).join("; ")}`,"invalidValue");let F=H.value;if(!F.userName&&!F.emails?.[0]?.value)return N(400,"userName or email is required","invalidValue");let $=P(F);return await B.upsert($),d(J($),201)},y=async(Q,z)=>{let H=await B.get(z);if(!H)return N(404,`User ${z} not found`,"invalidValue");let F=await Q.json(),$=await W.user["~standard"].validate(F);if($.issues)return console.error("User replacement validation failed:",$.issues),N(400,`Request validation failed: ${$.issues.map((X)=>X.message).join("; ")}`,"invalidValue");let M=$.value,A=P({...M,id:z});return A.createdAt=H.createdAt,A.updatedAt=new Date,await B.upsert(A),d(J(A))},S=async(Q,z)=>{let H=await B.get(z);if(!H)return N(404,`User ${z} not found`,"invalidValue");let $=(await Q.json()).Operations??[],M={...H};for(let A of $)if(A.op==="replace"&&A.path&&A.value!==void 0){if(A.path==="displayName")M.name=A.value;else if(A.path==="userName")M.userName=A.value;else if(A.path.startsWith("name.")){let X=A.path.split(".")[1];if(!M.name)M.name="";if(X==="givenName")M.name=`${A.value} ${M.name.split(" ").slice(1).join(" ")}`.trim();else if(X==="familyName")M.name=`${M.name.split(" ")[0]} ${A.value}`.trim()}else if(A.path==="emails"){let X=A.value,Z=X?.find((K)=>K.primary)?.value||X?.[0]?.value;if(Z)M.email=Z}}else if(A.op==="add"&&A.path&&A.value!==void 0){if(A.path==="emails"){let X=A.value,Z=X?.find((K)=>K.primary)?.value||X?.[0]?.value;if(Z)M.email=Z}}else if(A.op==="remove"&&A.path){if(A.path==="displayName")M.name=""}return M.updatedAt=new Date,await B.upsert(M),d(J(M))},V=async(Q)=>{if(!await B.get(Q))return N(404,`User ${Q} not found`,"invalidValue");return await B.delete(Q),new Response(null,{status:204})};f={handler:v}}async function k(B,G){U();let P=new URL(B.url).pathname,v=G?.usersUrl??Y.usersUrl??"/api/iam/Users",w=G?.groupsUrl??Y.groupsUrl??"/api/iam/Groups";if(P.startsWith(v)&&f)return f.handler(B,{basePath:v});if(P.startsWith(w)&&x)return x.handler(B,{basePath:w});return N(404,"Resource not found")}return{...Y,createUser:t,getBaseUrl:i,groups_outbound:l,groups_inbound:x,users_inbound:f,handler:k}}var KM="@enterprisestandard/core",WM=YM(XM(KM));function QM(W){let D=W.replace(/-/g,"+").replace(/_/g,"/");return atob(D)}async function OM(W,D){let j=W.split(".");if(j.length!==3)throw Error("Invalid JWT");let h=JSON.parse(QM(j[0])),q=JSON.parse(QM(j[1])),E=j[2].replace(/-/g,"+").replace(/_/g,"/"),Y=h.kid;if(!Y)throw Error("JWT header missing kid");let U=await $M(D),g=await FM(U,Y),i=new TextEncoder().encode(`${j[0]}.${j[1]}`),l=Uint8Array.from(atob(E),(B)=>B.charCodeAt(0));if(!await crypto.subtle.verify("RSASSA-PKCS1-v1_5",g,l,i))throw Error("Invalid JWT signature");let x=await WM.validate(q);if(x.issues)throw Error(`ID token claims validation failed: ${x.issues.map((B)=>B.message).join("; ")}`);let f=x.value;if(f===void 0)throw Error("ID token claims missing");let k=f;if(typeof k.exp==="number"&&k.exp<Math.floor(Date.now()/1000))throw Error("Token expired");return ZM(k)}export{PM as withTenantConfigMethod,OM as verifyUser,EM as tenantConfigSource,NM as sso,IM as registerTenantConfigSourceFactory,jM as logoutBackChannel,DM as logout,JM as initiateLogin,SM as iam,_M as getSSOorCIAMUser,VM as getSSOUser,GM as getRequiredSSOorCIAMUser,BM as getCIAMUser,zM as ciam,LM as callback};
1
+ import{A as _M,B as GM,C as JM,D as LM,E as DM,F as jM,G as IM,H as EM,I as PM,c as XM,d as YM,e,k as ZM,r as $M,s as FM,y as NM,z as VM}from"./shared/core-tyde8csq.js";function zM(W,D,j,h,q){if(!j&&!h)return;let E={...j,...h},Y={...E,signingKey:j?.signingKey,magicLinkTtl:E.magicLinkTtl??3600,sessionTtl:E.sessionTtl??86400,cookiesSecure:E.cookiesSecure!==void 0?E.cookiesSecure:!0,cookiesSameSite:E.cookiesSameSite!==void 0?E.cookiesSameSite:"Strict",cookiesPrefix:E.cookiesPrefix??(E.ciamId?`es.ciam.${E.ciamId}`:"es.ciam"),cookiesPath:E.cookiesPath??"/",sessionValidation:E.sessionValidation??"always"};function U(){if(!Y.signingKey)throw Error("Missing CIAM configuration field: signingKey. CIAM signingKey is required for JWT token signing and must be provided via Vault (ciam.signingKey).")}function g(){if(!Y.sessionStore)throw Error("Missing CIAM configuration field: sessionStore. CIAM sessionStore is required for server-side session tracking and backchannel logout.");return Y.sessionStore}function m(){U(),g()}function i(M=32){let A=new Uint8Array(M);return crypto.getRandomValues(A),Array.from(A,(X)=>X.toString(16).padStart(2,"0")).join("").substring(0,M)}function l(M){let A=typeof M==="string"?new TextEncoder().encode(M):M,X="";return A.forEach((Z)=>{X+=String.fromCharCode(Z)}),btoa(X).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function t(M){let A=M.replace(/-/g,"+").replace(/_/g,"/"),X=A.padEnd(A.length+(4-A.length%4)%4,"=");return atob(X)}async function x(){U();let M=new TextEncoder().encode(Y.signingKey??"");return crypto.subtle.importKey("raw",M,{name:"HMAC",hash:"SHA-256"},!1,["sign","verify"])}async function f(M){let X=l(JSON.stringify({alg:"HS256",typ:"JWT"})),Z=l(JSON.stringify(M)),K=`${X}.${Z}`,_=await x(),O=await crypto.subtle.sign("HMAC",_,new TextEncoder().encode(K)),I=l(new Uint8Array(O));return`${K}.${I}`}async function k(M){let A=M.split(".");if(A.length!==3)throw Error("Invalid JWT");let[X,Z,K]=A,_=`${X}.${Z}`,O=await x(),I=new Uint8Array(t(K).split("").map((T)=>T.charCodeAt(0)));if(!await crypto.subtle.verify("HMAC",O,I,new TextEncoder().encode(_)))throw Error("Invalid JWT signature");let u=t(Z),c=JSON.parse(u);if(typeof c.exp==="number"&&c.exp<Math.floor(Date.now()/1000))throw Error("Token expired");return c}function B(M,A,X){if(!Y)throw Error("Enterprise Standard CIAM Manager not initialized");if(M=`${Y.cookiesPrefix}.${M}`,typeof A!=="string")A=btoa(JSON.stringify(A));let Z;if(X instanceof Date)Z=`Expires=${X.toUTCString()}`;else if(typeof X==="number")Z=`Max-Age=${X}`;else throw Error("Invalid expires type",X);if(A.length>4000)throw Error(`Error setting cookie: ${M}. Cookie length is: ${A.length}`);return`${M}=${A}; ${Z}; Path=${Y.cookiesPath}; HttpOnly;${Y.cookiesSecure?" Secure;":""} SameSite=${Y.cookiesSameSite};`}function G(M){if(!Y)throw Error("Enterprise Standard CIAM Manager not initialized");return`${Y.cookiesPrefix}.${M}=; Max-Age=0; Path=${Y.cookiesPath}; HttpOnly;${Y.cookiesSecure?" Secure;":""} SameSite=${Y.cookiesSameSite};`}function J(M,A,X=!1){if(!Y)throw Error("Enterprise Standard CIAM Manager not initialized");let Z=A.headers.get("cookie");if(!Z)return null;let K=`${Y.cookiesPrefix}.${M}`,_=Z.split(";").find((C)=>C.trim().startsWith(`${K}=`));if(!_)return null;let O=_.indexOf("="),I=_.substring(O+1).trim();if(!X)return I;try{let C=atob(I);return JSON.parse(C)}catch(C){return console.error(`[CIAM] Failed to parse cookie '${K}':`,C),null}}function P(M,A,X){let Z={expires_in:Y.sessionTtl??86400,token_type:"Bearer",expires:X.toISOString()};return[["Set-Cookie",B("access",M,X)],["Set-Cookie",B("id",A,X)],["Set-Cookie",B("control",Z,X)]]}function v(M){let A=J("access",M),X=J("id",M),Z=J("control",M,!0);if(!A||!X||!Z)return;if(Z.expires&&Date.now()>new Date(Z.expires).getTime())return;return{access:A,id:X,control:Z}}async function w(M){if(!Y)throw Error("Enterprise Standard CIAM Manager not initialized");m();try{let A=v(M);if(!A)return;let X=await k(A.access),Z=await k(A.id);if(!X.sid||!Z.sub)return;if(Y.sessionValidation!=="disabled"){if(!await g().get(X.sid))return}return z(Z)}catch(A){return}}async function b(M){let A=await w(M);if(A)return A;throw new Response("Unauthorized",{status:401,statusText:"Unauthorized"})}async function p(M){if(!Y)throw Error("Enterprise Standard CIAM Manager not initialized");m();try{let O=v(M);if(O){let I=await k(O.access);if(I.sid)await g().delete(I.sid)}}catch(O){console.warn("Failed to delete CIAM session:",O)}let A=[["Set-Cookie",G("access")],["Set-Cookie",G("id")],["Set-Cookie",G("control")]],Z=new URL(M.url).searchParams.get("redirect");if(Z)return new Response("Logged out",{status:302,headers:[["Location",Z],...A]});let K=M.headers.get("accept");if(K?.includes("application/json")||K?.includes("text/javascript"))return new Response(JSON.stringify({success:!0,message:"Logged out"}),{status:200,headers:[["Content-Type","application/json"],...A]});return new Response("Logout Complete",{status:200,headers:[["Content-Type","text/plain"],...A]})}async function y(M){if(!Y)throw Error("Enterprise Standard CIAM Manager not initialized");m();try{let A=M.headers.get("content-type");if(!A||!A.includes("application/x-www-form-urlencoded"))return new Response("Invalid Content-Type, expected application/x-www-form-urlencoded",{status:400});let X=await M.text(),K=new URLSearchParams(X).get("logout_token");if(!K)return new Response("Missing logout_token parameter",{status:400});let O=(await k(K)).sid;if(!O)return new Response("Invalid logout_token: missing sid claim",{status:400});return await g().delete(O),new Response("OK",{status:200})}catch(A){return console.error("Error during CIAM back-channel logout:",A),new Response("Internal Server Error",{status:500})}}function S(M){return M.id||M.email||`ciam-${M.userName}`}function V(M,A,X){return{sub:S(M),iss:"ciam",aud:"ciam",exp:Math.floor(X.getTime()/1000),iat:Math.floor(Date.now()/1000),email:M.email,name:M.name,preferred_username:M.userName,picture:M.avatar,sid:A}}function Q(M,A,X){return{sub:M,iss:"ciam",aud:"ciam",exp:Math.floor(X.getTime()/1000),iat:Math.floor(Date.now()/1000),sid:A,scope:"openid profile email"}}function z(M){let A=M.exp?new Date(M.exp*1000):new Date;return{id:M.sub,userName:M.preferred_username??"",name:M.name??"",email:M.email??"",avatar:M.picture,userType:"customer",sso:{profile:M,tenant:{id:"ciam",name:"CIAM"},scope:"openid profile email",tokenType:"Bearer",expires:A}}}async function H(M){if(!Y)throw Error("Enterprise Standard CIAM Manager not initialized");if(!q)return new Response(JSON.stringify({error:"Workload authentication required"}),{status:401,headers:{"Content-Type":"application/json"}});if(!await q.getWorkloadIdentity(M))return new Response(JSON.stringify({error:"Unauthorized: Valid workload token required"}),{status:401,headers:{"Content-Type":"application/json"}});let X,Z;try{let n=M.headers.get("content-type");if(!n||!n.includes("application/json"))return new Response(JSON.stringify({error:"Content-Type must be application/json"}),{status:400,headers:{"Content-Type":"application/json"}});let a=await M.text(),R=JSON.parse(a);if(Z=typeof R?.redirect==="string"&&R.redirect.length>0?R.redirect:void 0,X={userName:R.userName,name:R.name,email:R.email,avatar:R.avatar},!X.userName||!X.name||!X.email)return new Response(JSON.stringify({error:"Missing required fields: userName, name, email"}),{status:400,headers:{"Content-Type":"application/json"}})}catch(n){return new Response(JSON.stringify({error:"Invalid JSON in request body"}),{status:400,headers:{"Content-Type":"application/json"}})}let _=new URL(M.url).searchParams.get("ttl"),O=_?parseInt(_,10):Y.magicLinkTtl??3600;if(Number.isNaN(O)||O<=0)return new Response(JSON.stringify({error:"Invalid TTL parameter"}),{status:400,headers:{"Content-Type":"application/json"}});let I=i(32),C=new Date(Date.now()+O*1000);if(!Y.magicLinkStore)return new Response(JSON.stringify({error:"Magic link store not configured"}),{status:500,headers:{"Content-Type":"application/json"}});try{await Y.magicLinkStore.create(I,X,C)}catch(n){return console.error("Error creating magic link:",n),new Response(JSON.stringify({error:"Failed to create magic link"}),{status:500,headers:{"Content-Type":"application/json"}})}let u=new URL(M.url),c=Y.magicLinkLoginUrl||"/magic-link/login",T=new URL(c,u.origin);if(T.searchParams.set("token",I),Z)T.searchParams.set("redirect",Z);return new Response(JSON.stringify({magicLink:T.toString(),expiresAt:C.toISOString()}),{status:200,headers:{"Content-Type":"application/json"}})}async function F(M){if(!Y)throw Error("Enterprise Standard CIAM Manager not initialized");m();let A=new URL(M.url),X=A.searchParams.get("token");if(!X){let L=Y.errorUrl||"/";return new Response("Redirecting to error URL",{status:302,headers:{Location:L}})}if(!Y.magicLinkStore){let L=Y.errorUrl||"/";return new Response("Redirecting to error URL",{status:302,headers:{Location:L}})}let Z=await Y.magicLinkStore.get(X);if(!Z){let L=Y.errorUrl||"/";return new Response("Redirecting to error URL",{status:302,headers:{Location:L}})}let K=new Date(Date.now()+(Y.sessionTtl??86400)*1000),_=i(32),O=S(Z.user),I=V(Z.user,_,K),C=Q(O,_,K),u=z(I);try{let L={sid:_,sub:O,createdAt:new Date,lastActivityAt:new Date};await g().create(L)}catch(L){console.warn("Failed to create session:",L)}if(Y.userStore)try{let L=u.id;if(L){let r=new Date,o=await Y.userStore.get(L);if(o||Y.enableJitUserProvisioning){let HM={...o??{},...u,id:L,tenantId:o?.tenantId,createdAt:o?.createdAt??r,updatedAt:r,userType:o?.userType??"customer"};await Y.userStore.upsert(HM)}}}catch(L){console.warn("Failed to store user:",L)}try{await Y.magicLinkStore.delete(X)}catch(L){console.warn("Failed to delete magic link:",L)}let c=await f(C),T=await f(I),n=Y.landingUrl||"/",a=A.searchParams.get("redirect"),R=n;if(a)if(a.startsWith("/"))R=a;else try{if(new URL(a).origin===new URL(M.url).origin)R=a}catch{}return new Response("Authentication successful, redirecting",{status:302,headers:[["Location",R],...P(c,T,K)]})}async function $(M){if(!Y)throw Error("Enterprise Standard CIAM Manager not initialized");m();let A=Y.magicLinkUrl||"/magic-link",X=Y.magicLinkLoginUrl||"/magic-link/login",Z=Y.logoutUrl||"/auth/logout",K=Y.logoutBackChannelUrl||"/auth/logout/backchannel",_=new URL(M.url).pathname,O=(T)=>{if(!T)return;try{return new URL(T).pathname}catch{return T.startsWith("/")?T:`/${T}`}};if(O(A)===_&&M.method==="POST")return H(M);if(O(X)===_&&M.method==="GET")return F(M);if(O(Z)===_&&M.method==="GET")return p(M);if(O(K)===_&&M.method==="POST")return y(M);return new Response("Not Found",{status:404})}return{...Y,getUser:w,getRequiredUser:b,logout:p,logoutBackChannel:y,handler:$}}async function BM(W,D){return e(D,"EnterpriseStandard instance is required. Create one with enterpriseStandard(source, config) and pass it to this function."),D.ciam?.getUser(W)}function N(W,D,j){return new Response(JSON.stringify({schemas:["urn:ietf:params:scim:api:messages:2.0:Error"],status:String(W),scimType:j,detail:D}),{status:W,headers:{"Content-Type":"application/scim+json"}})}function MM(W,D){let j=D?.totalResults??W.length,h=D?.startIndex??1,q=D?.itemsPerPage??W.length;return new Response(JSON.stringify({schemas:["urn:ietf:params:scim:api:messages:2.0:ListResponse"],totalResults:j,startIndex:h,itemsPerPage:q,Resources:W}),{status:200,headers:{"Content-Type":"application/scim+json"}})}function d(W,D=200){return new Response(JSON.stringify(W),{status:D,headers:{"Content-Type":"application/scim+json"}})}function s(W){return{schemas:["urn:ietf:params:scim:schemas:core:2.0:Group"],id:W.id,externalId:W.externalId,displayName:W.displayName,members:W.members,meta:{resourceType:"Group",created:W.createdAt.toISOString(),lastModified:W.updatedAt.toISOString()}}}function AM(){return crypto.randomUUID()}function SM(W,D,j,h,q){if(!h&&!q)return;let Y={...h,...q};function U(){if(!j)throw D.error?.("IAM requires workload configuration before use"),Error("IAM requires workload configuration");return j}async function g(){let B=U(),G=typeof B.getServerToken==="function"?await B.getServerToken():await B.getToken();return new Headers({"Content-Type":"application/scim+json",Accept:"application/scim+json",Authorization:`Bearer ${G}`})}async function m(B,G,J,P){if(!Y.url)throw Error("IAM URL not configured for outgoing requests");let v=`${Y.url}${G}`;try{let w=await g(),b=await fetch(v,{method:B,headers:w,body:J?JSON.stringify(J):void 0}),p=await b.json();if(!b.ok)return{success:!1,error:p,status:b.status};let y=await P["~standard"].validate(p);if(y.issues)return console.error("SCIM response validation failed:",y.issues),{success:!1,error:{schemas:["urn:ietf:params:scim:api:messages:2.0:Error"],status:"400",scimType:"invalidValue",detail:`Response validation failed: ${y.issues.map((S)=>S.message).join("; ")}`},status:400};return{success:!0,data:y.value,status:b.status}}catch(w){return{success:!1,error:{schemas:["urn:ietf:params:scim:api:messages:2.0:Error"],status:"500",detail:w instanceof Error?w.message:"Unknown error occurred"},status:500}}}function i(){return Y.url}let l,t;if(Y.url)t=async(G,J)=>{let P={...G,schemas:G.schemas??["urn:ietf:params:scim:schemas:core:2.0:User","urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"]};return m("POST","/Users",P,W.user)},l={createGroup:async(G,J)=>{let P={schemas:["urn:ietf:params:scim:schemas:core:2.0:Group"],displayName:G,externalId:J?.externalId,members:J?.members};return m("POST","/Groups",P,W.group)}};let x;if(Y.groupStore){let B=Y.groupStore,G=async(S)=>{let V=U(),Q=S.headers.get("Authorization");if(!Q||!Q.startsWith("Bearer "))return!1;try{let z=Q.substring(7);return(await V.validateToken(z)).valid}catch{return!1}},J=async(S,V)=>{if(!await G(S))return N(401,"Authorization required");let z=new URL(S.url),H=V?.basePath??"/Groups",F=z.pathname;if(F.startsWith(H))F=F.substring(H.length);let M=F.match(/^\/([^/]+)$/)?.[1],A=S.method;try{if(M)switch(A){case"GET":return await v(M);case"PUT":return await b(S,M);case"PATCH":return await p(S,M);case"DELETE":return await y(M);default:return N(405,"Method not allowed")}else if(F===""||F==="/")switch(A){case"GET":return await P(S);case"POST":return await w(S);default:return N(405,"Method not allowed")}return N(404,"Resource not found")}catch(X){return console.error("Groups inbound handler error:",X),N(500,X instanceof Error?X.message:"Internal server error")}},P=async(S)=>{let V=new URL(S.url),Q=V.searchParams.get("startIndex"),z=V.searchParams.get("count"),H=Q!=null?parseInt(Q,10):void 0,F=z!=null?parseInt(z,10):void 0,$=H!=null&&!Number.isNaN(H)?Math.max(0,H-1):0,M=F!=null&&!Number.isNaN(F)?F:void 0,A=await B.list({start:$,limit:M}),X=A.items.map(s);return MM(X,{totalResults:A.total,startIndex:$+1,itemsPerPage:A.count})},v=async(S)=>{let V=await B.get(S);if(!V)return N(404,`Group ${S} not found`,"invalidValue");return d(s(V))},w=async(S)=>{let V=await S.json(),Q=await W.group["~standard"].validate(V);if(Q.issues)return console.error("Group creation validation failed:",Q.issues),N(400,`Request validation failed: ${Q.issues.map(($)=>$.message).join("; ")}`,"invalidValue");let z=Q.value;if(!z.displayName)return N(400,"displayName is required","invalidValue");let H=new Date,F={id:AM(),displayName:z.displayName,externalId:z.externalId,members:z.members,createdAt:H,updatedAt:H};return await B.upsert(F),d(s(F),201)},b=async(S,V)=>{let Q=await B.get(V);if(!Q)return N(404,`Group ${V} not found`,"invalidValue");let z=await S.json(),H=await W.group["~standard"].validate(z);if(H.issues)return console.error("Group replacement validation failed:",H.issues),N(400,`Request validation failed: ${H.issues.map((M)=>M.message).join("; ")}`,"invalidValue");let F=H.value,$={...Q,displayName:F.displayName??Q.displayName,externalId:F.externalId,members:F.members,updatedAt:new Date};return await B.upsert($),d(s($))},p=async(S,V)=>{let Q=await B.get(V);if(!Q)return N(404,`Group ${V} not found`,"invalidValue");let H=(await S.json()).Operations??[],F={...Q};for(let $ of H)if($.op==="replace"&&$.path&&$.value!==void 0){if($.path==="displayName")F.displayName=$.value}else if($.op==="add"&&$.path&&$.value!==void 0){if($.path==="members"){let M=$.value;F.members=[...F.members??[],...M]}}else if($.op==="remove"&&$.path){if($.path.startsWith("members[")){let M=$.path.match(/members\[value eq "([^"]+)"\]/);if(M)F.members=(F.members??[]).filter((A)=>A.value!==M[1])}}return F.updatedAt=new Date,await B.upsert(F),d(s(F))},y=async(S)=>{if(!await B.get(S))return N(404,`Group ${S} not found`,"invalidValue");return await B.delete(S),new Response(null,{status:204})};x={handler:J}}let f;if(Y.userStore){let B=Y.userStore,G=async(Q)=>{let z=U(),H=Q.headers.get("Authorization");if(!H||!H.startsWith("Bearer "))return!1;try{let F=H.substring(7);return(await z.validateToken(F)).valid}catch{return!1}},J=(Q)=>{return{schemas:["urn:ietf:params:scim:schemas:core:2.0:User","urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"],id:Q.id,userName:Q.userName||Q.email||Q.id,displayName:Q.name||Q.userName||Q.email,name:Q.name?{givenName:Q.name.split(" ")[0],familyName:Q.name.split(" ").slice(1).join(" ")||void 0}:void 0,emails:Q.email?[{value:Q.email,primary:!0}]:[],active:!0,...Q.userType!=null&&{userType:Q.userType},meta:{resourceType:"User",created:Q.createdAt.toISOString(),lastModified:Q.updatedAt.toISOString()}}},P=(Q)=>{let z=new Date,H=Q.emails?.find((A)=>A.primary)?.value||Q.emails?.[0]?.value,F=Q.name?`${Q.name.givenName||""} ${Q.name.familyName||""}`.trim():Q.displayName,$=Q.id||AM(),M=Q.userName||H||$;return{id:$,userName:M,name:F||Q.displayName||M,email:H||M,avatar:Q.profileUrl,sso:{profile:{sub:$,iss:"iam-provisioned",aud:"iam-provisioned",exp:Math.floor(Date.now()/1000)+3600,iat:Math.floor(Date.now()/1000),email:H||M,email_verified:!0,name:F||Q.displayName||M,preferred_username:M},tenant:{id:"iam-provisioned",name:"IAM Provisioned"},scope:"openid profile email",tokenType:"Bearer",expires:new Date(Date.now()+3600000)},createdAt:Q.meta?.created?new Date(Q.meta.created):z,updatedAt:Q.meta?.lastModified?new Date(Q.meta.lastModified):z,...Q.userType!=null&&{userType:Q.userType}}},v=async(Q,z)=>{if(!await G(Q))return N(401,"Authorization required");let F=new URL(Q.url),$=z?.basePath??"/Users",M=F.pathname;if(M.startsWith($))M=M.substring($.length);let X=M.match(/^\/([^/]+)$/)?.[1],Z=Q.method;try{if(X)switch(Z){case"GET":return await b(X);case"PUT":return await y(Q,X);case"PATCH":return await S(Q,X);case"DELETE":return await V(X);default:return N(405,"Method not allowed")}else if(M===""||M==="/")switch(Z){case"GET":return await w(Q);case"POST":return await p(Q);default:return N(405,"Method not allowed")}return N(404,"Resource not found")}catch(K){return console.error("Users inbound handler error:",K),N(500,K instanceof Error?K.message:"Internal server error")}},w=async(Q)=>{let z=new URL(Q.url),H=z.searchParams.get("startIndex"),F=z.searchParams.get("count"),$=H!=null?parseInt(H,10):void 0,M=F!=null?parseInt(F,10):void 0,A=$!=null&&!Number.isNaN($)?Math.max(0,$-1):0,X=M!=null&&!Number.isNaN(M)?M:void 0,Z=await B.list({start:A,limit:X}),K=Z.items.map(J);return MM(K,{totalResults:Z.total,startIndex:A+1,itemsPerPage:Z.count})},b=async(Q)=>{let z=await B.get(Q);if(!z)return N(404,`User ${Q} not found`,"invalidValue");return d(J(z))},p=async(Q)=>{let z=await Q.json(),H=await W.user["~standard"].validate(z);if(H.issues)return console.error("User creation validation failed:",H.issues),N(400,`Request validation failed: ${H.issues.map((M)=>M.message).join("; ")}`,"invalidValue");let F=H.value;if(!F.userName&&!F.emails?.[0]?.value)return N(400,"userName or email is required","invalidValue");let $=P(F);return await B.upsert($),d(J($),201)},y=async(Q,z)=>{let H=await B.get(z);if(!H)return N(404,`User ${z} not found`,"invalidValue");let F=await Q.json(),$=await W.user["~standard"].validate(F);if($.issues)return console.error("User replacement validation failed:",$.issues),N(400,`Request validation failed: ${$.issues.map((X)=>X.message).join("; ")}`,"invalidValue");let M=$.value,A=P({...M,id:z});return A.createdAt=H.createdAt,A.updatedAt=new Date,await B.upsert(A),d(J(A))},S=async(Q,z)=>{let H=await B.get(z);if(!H)return N(404,`User ${z} not found`,"invalidValue");let $=(await Q.json()).Operations??[],M={...H};for(let A of $)if(A.op==="replace"&&A.path&&A.value!==void 0){if(A.path==="displayName")M.name=A.value;else if(A.path==="userName")M.userName=A.value;else if(A.path.startsWith("name.")){let X=A.path.split(".")[1];if(!M.name)M.name="";if(X==="givenName")M.name=`${A.value} ${M.name.split(" ").slice(1).join(" ")}`.trim();else if(X==="familyName")M.name=`${M.name.split(" ")[0]} ${A.value}`.trim()}else if(A.path==="emails"){let X=A.value,Z=X?.find((K)=>K.primary)?.value||X?.[0]?.value;if(Z)M.email=Z}}else if(A.op==="add"&&A.path&&A.value!==void 0){if(A.path==="emails"){let X=A.value,Z=X?.find((K)=>K.primary)?.value||X?.[0]?.value;if(Z)M.email=Z}}else if(A.op==="remove"&&A.path){if(A.path==="displayName")M.name=""}return M.updatedAt=new Date,await B.upsert(M),d(J(M))},V=async(Q)=>{if(!await B.get(Q))return N(404,`User ${Q} not found`,"invalidValue");return await B.delete(Q),new Response(null,{status:204})};f={handler:v}}async function k(B,G){U();let P=new URL(B.url).pathname,v=G?.usersUrl??Y.usersUrl??"/api/iam/Users",w=G?.groupsUrl??Y.groupsUrl??"/api/iam/Groups";if(P.startsWith(v)&&f)return f.handler(B,{basePath:v});if(P.startsWith(w)&&x)return x.handler(B,{basePath:w});return N(404,"Resource not found")}return{...Y,createUser:t,getBaseUrl:i,groups_outbound:l,groups_inbound:x,users_inbound:f,handler:k}}var KM="@enterprisestandard/core",WM=YM(XM(KM));function QM(W){let D=W.replace(/-/g,"+").replace(/_/g,"/");return atob(D)}async function OM(W,D){let j=W.split(".");if(j.length!==3)throw Error("Invalid JWT");let h=JSON.parse(QM(j[0])),q=JSON.parse(QM(j[1])),E=j[2].replace(/-/g,"+").replace(/_/g,"/"),Y=h.kid;if(!Y)throw Error("JWT header missing kid");let U=await $M(D),g=await FM(U,Y),i=new TextEncoder().encode(`${j[0]}.${j[1]}`),l=Uint8Array.from(atob(E),(B)=>B.charCodeAt(0));if(!await crypto.subtle.verify("RSASSA-PKCS1-v1_5",g,l,i))throw Error("Invalid JWT signature");let x=await WM.validate(q);if(x.issues)throw Error(`ID token claims validation failed: ${x.issues.map((B)=>B.message).join("; ")}`);let f=x.value;if(f===void 0)throw Error("ID token claims missing");let k=f;if(typeof k.exp==="number"&&k.exp<Math.floor(Date.now()/1000))throw Error("Token expired");return ZM(k)}export{PM as withTenantConfigMethod,OM as verifyUser,EM as tenantConfigSource,NM as sso,IM as registerTenantConfigSourceFactory,jM as logoutBackChannel,DM as logout,JM as initiateLogin,SM as iam,_M as getSSOorCIAMUser,VM as getSSOUser,GM as getRequiredSSOorCIAMUser,BM as getCIAMUser,zM as ciam,LM as callback};
@@ -0,0 +1,12 @@
1
+ function DX(Y){return{"~standard":{version:1,vendor:Y,validate:(Z)=>{if(typeof Z!=="object"||Z===null)return{issues:[{message:"Expected an object"}]};let X=Z,N=[],S={};if("code"in X)if(typeof X.code==="string")S.code=X.code;else N.push({message:"code must be a string",path:["code"]});else if(!("error"in X))N.push({message:"code is required",path:["code"]});if("state"in X)if(typeof X.state==="string"||X.state===void 0)S.state=X.state;else N.push({message:"state must be a string",path:["state"]});if("session_state"in X)if(typeof X.session_state==="string"||X.session_state===void 0)S.session_state=X.session_state;else N.push({message:"session_state must be a string",path:["session_state"]});if("error"in X){if(typeof X.error==="string")S.error=X.error;else N.push({message:"error must be a string",path:["error"]});if("error_description"in X)if(typeof X.error_description==="string"||X.error_description===void 0)S.error_description=X.error_description;else N.push({message:"error_description must be a string",path:["error_description"]});if("error_uri"in X)if(typeof X.error_uri==="string"||X.error_uri===void 0)S.error_uri=X.error_uri;else N.push({message:"error_uri must be a string",path:["error_uri"]})}if("iss"in X)if(typeof X.iss==="string"||X.iss===void 0)S.iss=X.iss;else N.push({message:"iss must be a string",path:["iss"]});if(N.length>0)return{issues:N};return{value:S}}}}}function EX(Y){return{"~standard":{version:1,vendor:Y,validate:(Z)=>{if(typeof Z!=="object"||Z===null)return{issues:[{message:"Expected an object"}]};let X=Z,N=[],S={};if("access_token"in X)if(typeof X.access_token==="string")S.access_token=X.access_token;else N.push({message:"access_token must be a string",path:["access_token"]});else N.push({message:"access_token is required",path:["access_token"]});if("id_token"in X)if(typeof X.id_token==="string")S.id_token=X.id_token;else N.push({message:"id_token must be a string",path:["id_token"]});else N.push({message:"id_token is required",path:["id_token"]});if("token_type"in X)if(typeof X.token_type==="string")S.token_type=X.token_type;else N.push({message:"token_type must be a string",path:["token_type"]});else N.push({message:"token_type is required",path:["token_type"]});if("refresh_token"in X)if(typeof X.refresh_token==="string"||X.refresh_token===void 0)S.refresh_token=X.refresh_token;else N.push({message:"refresh_token must be a string",path:["refresh_token"]});if("scope"in X)if(typeof X.scope==="string"||X.scope===void 0)S.scope=X.scope;else N.push({message:"scope must be a string",path:["scope"]});if("session_state"in X)if(typeof X.session_state==="string"||X.session_state===void 0)S.session_state=X.session_state;else N.push({message:"session_state must be a string",path:["session_state"]});if("expires"in X)if(typeof X.expires==="string"||X.expires===void 0)S.expires=X.expires;else N.push({message:"expires must be a string",path:["expires"]});if("expires_in"in X)if(typeof X.expires_in==="number"||X.expires_in===void 0)S.expires_in=X.expires_in;else N.push({message:"expires_in must be a number",path:["expires_in"]});if("refresh_expires_in"in X)if(typeof X.refresh_expires_in==="number"||X.refresh_expires_in===void 0)S.refresh_expires_in=X.refresh_expires_in;else N.push({message:"refresh_expires_in must be a number",path:["refresh_expires_in"]});if(N.length>0)return{issues:N};return{value:S}}}}}function i(Y){return{"~standard":{version:1,vendor:Y,validate:(Z)=>{if(typeof Z!=="object"||Z===null)return{issues:[{message:"Expected an object"}]};let X=Z,N=[],S={...X},B=["iss","aud","sub","sid","name","email","preferred_username","picture"];for(let M of B)if(M in X&&X[M]!==void 0){if(typeof X[M]!=="string")N.push({message:`${M} must be a string`,path:[M]})}let $=["exp","iat"];for(let M of $)if(M in X&&X[M]!==void 0){if(typeof X[M]!=="number")N.push({message:`${M} must be a number`,path:[M]})}if(N.length>0)return{issues:N};return{value:S}}}}}function a(Y){let Z=Y["~standard"];return Object.assign({},Y,{validate(X){return Promise.resolve(Z.validate(X))}})}function H(Y,Z="Assertion failed. Required value is null or undefined."){if(Y===void 0||Y===null)throw Error(Z);return Y}function o(Y,Z){return Response.json({error:"validation_failed",message:Z,issues:Y},{status:400,headers:{"Content-Type":"application/json"}})}function PX(Y,Z,X=[]){let N={...Y,...Z};for(let S of X)N[S]=Y?.[S]??Z?.[S];return N}function BX(Y){let Z="",X=0,N=Y.length;while(X<N){let S=Y[X];if(S==='"'||S==="'"){let B=S;Z+=S,X++;while(X<N){let $=Y[X];if($==="\\"){if(Z+=$,X+1<N)Z+=Y[X+1],X+=2;else X++;continue}if($===B){Z+=$,X++;break}Z+=$,X++}continue}if(S==="/"&&X+1<N){let B=Y[X+1];if(B==="/"){X+=2;while(X<N&&Y[X]!==`
2
+ `)X++;if(X<N)Z+=`
3
+ `;X++;continue}if(B==="*"){X+=2;while(X+1<N&&!(Y[X]==="*"&&Y[X+1]==="/"))X++;X+=2;continue}}Z+=S,X++}return Z}function TX(Y){let Z=BX(Y);return JSON.parse(Z)}async function zX(Y,Z=async(B)=>B.status===200,X=1000,N=1e4,S){let B=Date.now(),$="Awaiting Ping";return new Promise((M,T)=>{let P=null,y=null,h=async()=>{try{let E=await fetch(Y);if(E.ok)if(await Z(E)){if(P)clearInterval(P);if(y)clearInterval(y);M()}else $=`Response test failed: ${E.status}: ${E.statusText} - ${Y}`;else try{let U=await E.json();$=`Response error: ${E.status}: ${E.statusText} - ${Y}: ${JSON.stringify(U)}`}catch(U){$=`Response error: ${E.status}: ${E.statusText} - ${Y}`}}catch(E){$=`${E instanceof Error?E.message:String(E)} - ${Y}`}};if(h(),P=setInterval(h,X),N>0)y=setInterval(()=>{console.warn(`${$}: ${Date.now()-B}ms`)},N);if(S)setTimeout(()=>{if(P)clearInterval(P);if(y)clearInterval(y);T(Error(`Timeout: ${S}ms: ${$}`))},S)})}var WX="@enterprisestandard/core",MX=a(i(WX));function FX(Y){let Z=Y.exp!=null?new Date(Y.exp*1000):new Date,X=Y.iss??"";return{id:Y.sub??"",userName:Y.preferred_username??"",name:Y.name??"",email:Y.email??"",avatar:Y.picture,sso:{profile:{...Y,iss:Y.iss??X,aud:Y.aud},tenant:{id:Y.idp??X,name:X},tokenType:"Bearer",expires:Z}}}function LX(Y){let Z=Y.replace(/-/g,"+").replace(/_/g,"/");return atob(Z)}async function wX(Y){let Z=Y.split(".");if(Z.length!==3)throw Error("Invalid JWT");let X=LX(Z[1]),N=JSON.parse(X),S=await MX.validate(N);if(S.issues)throw Error(`ID token claims validation failed: ${S.issues.map((B)=>B.message).join("; ")}`);if(S.value)return FX(S.value);throw Error("ID token claims validation failed")}var x=(Y,Z,...X)=>{if(X.length>0)console[Y](`[${Y.toUpperCase()}]`,Z,...X);else console[Y](`[${Y.toUpperCase()}]`,Z)},r={debug:()=>{},info:()=>{},warn(Y,...Z){x("warn",Y,...Z)},error(Y,...Z){x("error",Y,...Z)}},RX={debug:()=>{},info:()=>{},warn:()=>{},error:()=>{}},bX={debug:()=>{},info:x.bind(console,"info"),warn:x.bind(console,"warn"),error:x.bind(console,"error")},s=(Y,...Z)=>{if(Z.length>0)console.log("[DEBUG]",Y,...Z);else console.log("[DEBUG]",Y)},CX={debug:s,info:x.bind(console,"info"),warn:x.bind(console,"warn"),error:x.bind(console,"error")},qX={debug:s,info:x.bind(console,"info"),warn:x.bind(console,"warn"),error:x.bind(console,"error")};var e=new Map;async function m(Y,Z=3,X=1000,N=30000){let S=Error("Placeholder Error");for(let B=0;B<=Z;B++)try{return await Y()}catch($){if(S=$ instanceof Error?$:Error(String($)),$ instanceof Error&&$.message.includes("400"))throw $;if(B===Z)throw S;let M=Math.min(X*2**B,N),T=Math.random()*0.1*M;await new Promise((P)=>setTimeout(P,M+T)),console.warn(`Retry attempt ${B+1} after ${M+T}ms delay`)}throw S}async function XX(Y){let Z=e.get(Y);if(Z)return Z;return m(async()=>{let X=await fetch(Y);if(!X.ok)throw Error("Failed to fetch JWKS");let N=await X.json();return e.set(Y,N),N})}async function YX(Y,Z){let X=Y.keys.find((N)=>N.kid===Z);if(!X)throw Error("Public key not found");return crypto.subtle.importKey("jwk",{kty:X.kty,n:X.n,e:X.e},{name:"RSASSA-PKCS1-v1_5",hash:"SHA-256"},!1,["verify"])}function gX(Y,Z={}){let X=Z.cookieName??"es.active_session",N=Y.headers.get("cookie");if(!N)return;return d(N)[X]}function pX(Y,Z={}){let X=Z.cookieName??"es.active_session",N=Z.path??"/",S=Z.secure??!1,B=Z.sameSite??"Lax",$=Z.maxAge,M=[`${X}=${Y}`,`Path=${N}`,"HttpOnly",`SameSite=${B}`];if(S)M.push("Secure");if(typeof $==="number")M.push(`Max-Age=${$}`);return M.join("; ")}function mX(Y={}){let Z=Y.cookieName??"es.active_session",X=Y.path??"/",N=Y.secure??!1,S=Y.sameSite??"Lax",B=[`${Z}=`,"Max-Age=0",`Path=${X}`,"HttpOnly",`SameSite=${S}`];if(N)B.push("Secure");return B.join("; ")}function dX(Y,Z={}){let X=typeof Y==="string"?Y:Y?.headers.get("cookie")??void 0;if(!X)return[];let S=`${Z.cookiePrefix??"es.sso"}.`,B=new Set;for(let $ of Object.keys(d(X))){if(!$.startsWith(S))continue;let M=$.slice(S.length),T=M.lastIndexOf(".");if(T<=0)continue;let P=M.slice(0,T).trim();if(P)B.add(P)}return Array.from(B)}function cX(Y,Z){if(!Y)return;let X=d(Y);for(let[N,S]of Object.entries(X)){if(!N.startsWith("es.sso.")||!N.endsWith(".state"))continue;try{let B=JSON.parse(atob(S));if(B?.state===Z)return{clientId:N.slice(7,-6),stateCookie:B}}catch{}}return}function uX(Y,Z,X,N){if(!X&&!N)return;let S={...X,...N},B=!!(S.authority&&S.tokenUrl&&S.authorizationUrl&&S.clientId&&S.redirectUri&&S.scope),$={...S,authority:B?H(S.authority,"Missing 'authority' from SSO Config"):S.authority,tokenUrl:B?H(S.tokenUrl,"Missing 'tokenUrl' from SSO Config"):S.tokenUrl,authorizationUrl:B?H(S.authorizationUrl,"Missing 'authorizationUrl' from SSO Config"):S.authorizationUrl,clientId:B?H(S.clientId,"Missing 'clientId' from SSO Config"):S.clientId,redirectUri:B?H(S.redirectUri,"Missing 'redirectUri' from SSO Config"):S.redirectUri,scope:B?H(S.scope,"Missing 'scope' from SSO Config"):S.scope,responseType:S.responseType??"code",cookiesSecure:S.cookiesSecure!==void 0?S.cookiesSecure:!0,cookiesSameSite:S.cookiesSameSite!==void 0?S.cookiesSameSite:"Strict",cookiesPrefix:S.cookiesPrefix??(S.clientId?`es.sso.${S.clientId}`:"es.sso"),cookiesPath:S.cookiesPath??"/"};function M(){let K=[];if(!$.authority)K.push("authority");if(!$.tokenUrl)K.push("tokenUrl");if(!$.authorizationUrl)K.push("authorizationUrl");if(!$.clientId)K.push("clientId");if(!$.redirectUri)K.push("redirectUri");if(!$.scope)K.push("scope");if(K.length>0)throw Error(`Missing OIDC configuration fields: ${K.join(", ")}. OIDC configuration is required for SSO operations. Please provide these fields either in your vault configuration or in the SSO config when initializing enterpriseStandard.`)}async function T(K){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");try{let{tokens:A}=await g(K);if(!A)return;return await f(A)}catch(A){console.error("Error parsing user from cookies:",A);return}}async function P(K){let A=await T(K);if(A)return A;throw new Response("Unauthorized",{status:401,statusText:"Unauthorized"})}async function y({landingUrl:K,errorUrl:A},G){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");M();let F=t(),W=t(64),Q=$.redirectUri;try{new URL(Q)}catch{if(G)try{let j=new URL(G),I=Q.startsWith("//")?Q.slice(1):Q.startsWith("/")?Q:`/${Q}`;Q=new URL(I,j.origin).toString()}catch{try{let j=new URL($.authorizationUrl),I=Q.startsWith("//")?Q.slice(1):Q.startsWith("/")?Q:`/${Q}`;Q=new URL(I,j.origin).toString()}catch{throw Error(`Invalid redirectUri: "${$.redirectUri}". It must be a valid absolute URL.`)}}}let L=new URL($.authorizationUrl);L.searchParams.append("client_id",$.clientId),L.searchParams.append("redirect_uri",Q),L.searchParams.append("response_type","code"),L.searchParams.append("scope",$.scope),L.searchParams.append("state",F);let J=await KX(W);L.searchParams.append("code_challenge",J),L.searchParams.append("code_challenge_method","S256");let D={state:F,codeVerifier:W,landingUrl:K,errorUrl:A};return new Response("Redirecting to SSO Provider",{status:302,headers:{Location:L.toString(),"Set-Cookie":k("state",D,86400)}})}async function h(K,A){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");try{let J=R("refresh",K);if(J)await SX(J)}catch(J){console.warn("Failed to revoke token:",J)}if($.sessionStore)try{let J=await T(K);if(J?.sso?.profile.sid){let D=J.sso.profile.sid;await $.sessionStore.delete(D)}}catch(J){console.warn("Failed to delete session:",J)}let G=[["Set-Cookie",C("access")],["Set-Cookie",C("id")],["Set-Cookie",C("refresh")],["Set-Cookie",C("control")],["Set-Cookie",C("state")]],W=new URL(K.url).searchParams.get("redirect");if(W)return new Response("Logged out",{status:302,headers:[["Location",W],...G]});let Q=K.headers.get("accept");if(Q?.includes("application/json")||Q?.includes("text/javascript"))return new Response(JSON.stringify({success:!0,message:"Logged out"}),{status:200,headers:[["Content-Type","application/json"],...G]});else return new Response(`
4
+ <!DOCTYPE html><html lang="en"><body>
5
+ <h1>Logout Complete</h1>
6
+ <div style="display: none">
7
+ It is not recommended to show the default logout page. Include '?redirect=/someHomePage' or logout asynchronously.
8
+ Check the <a href="https://EnterpriseStandard.com/sso#logout">Enterprise Standard Packages</a> for more information.
9
+ </div>
10
+ </body></html>
11
+ `,{status:200,headers:[["Content-Type","text/html"],...G]})}async function E(K){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");if(!$.sessionStore)throw Error("Back-Channel Logout requires sessionStore configuration");try{let A=K.headers.get("content-type");if(!A||!A.includes("application/x-www-form-urlencoded"))return new Response("Invalid Content-Type, expected application/x-www-form-urlencoded",{status:400});let G=await K.text(),W=new URLSearchParams(G).get("logout_token");if(!W)return new Response("Missing logout_token parameter",{status:400});let L=(await n(W)).sid;if(!L)return console.warn("Back-Channel Logout: logout_token missing sid claim"),new Response("Invalid logout_token: missing sid claim",{status:400});return await $.sessionStore.delete(L),console.log(`Back-Channel Logout: successfully deleted session ${L}`),new Response("OK",{status:200})}catch(A){return console.error("Error during back-channel logout:",A),new Response("Internal Server Error",{status:500})}}async function U(K){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");let A=new URL(K.url),G=new URLSearchParams(A.search),F=Object.fromEntries(G.entries()),W=await Y.callbackParams["~standard"].validate(F);if(W.issues)return o(W.issues,"OIDC callback parameters validation failed");let{code:Q,state:L}=W.value;try{let J=R("state",K,!0),{codeVerifier:D,state:j,landingUrl:I}=J??{};if(H(D,'OIDC "codeVerifier" was not present in cookies, ensure that the SSO login was initiated correctly'),H(j,'OIDC "stateVerifier" was not present in cookies, ensure that the SSO login was initiated correctly'),H(I,'OIDC "landingUrl" was not present in cookies'),L!==j)throw Error('SSO State Verifier failed, the "state" request parameter does not equal the "state" in the SSO cookie');let w=$.cookiesSecure?K.url.replace(/^http:\/\//,"https://"):K.url,z=await $X(Q,D,w),O=await f(z);if($.sessionStore)try{let V=O.sso.profile.sid,_=O.id;if(V&&_){let b={sid:V,sub:_,createdAt:new Date,lastActivityAt:new Date};await $.sessionStore.create(b)}else console.warn("Session creation skipped: missing sid or sub in ID token claims")}catch(V){console.warn("Failed to create session:",V)}if($.userStore)try{let V=O.id;if(V){let _=new Date,b=await $.userStore.get(V);if(b||$.enableJitUserProvisioning){let QX={...b??{},...O,id:V,tenantId:b?.tenantId,createdAt:b?.createdAt??_,updatedAt:_};await $.userStore.upsert(QX)}else console.warn("JIT user provisioning disabled: user not found in store and will not be created")}else console.warn("User storage skipped: missing sub in ID token claims")}catch(V){console.warn("Failed to store user:",V)}return new Response("Authentication successful, redirecting",{status:302,headers:[["Location",I],["Set-Cookie",C("state")],...p(z,O.sso.expires)]})}catch(J){console.error("Error during sign-in callback:",J);try{let D=R("state",K,!0),{errorUrl:j}=D??{};if(j)return new Response("Redirecting to error url",{status:302,headers:[["Location",j]]})}catch(D){console.warn("Error parsing the errorUrl from the OIDC cookie")}return console.warn("No error page was found in the cookies. The user will be shown a default error page."),new Response("An error occurred during authentication, please return to the application homepage and try again.",{status:500})}}async function f(K){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");let A=await n(K.id_token),G=Number(K.refresh_expires_in??K.expires_in??3600),F=K.expires?new Date(K.expires):new Date(Date.now()+G*1000);return{id:A.sub,userName:A.preferred_username||"",name:A.name||"",email:A.email||"",emails:[{value:A.email||"",primary:!0}],avatar:A.picture,sso:{profile:{...A,iss:A.iss||$.authority,aud:A.aud||$.clientId},tenant:{id:A.idp||A.iss||$.authority||"",name:A.iss||$.authority||""},scope:K.scope,tokenType:K.token_type,sessionState:K.session_state,expires:F}}}async function $X(K,A,G){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");M();let{tokenUrl:F,redirectUri:W}=$;try{new URL(W)}catch{if(G)try{let L=new URL(G),J=W.startsWith("//")?W.slice(1):W.startsWith("/")?W:`/${W}`;W=new URL(J,L.origin).toString()}catch{try{let L=new URL(F),J=W.startsWith("//")?W.slice(1):W.startsWith("/")?W:`/${W}`;W=new URL(J,L.origin).toString()}catch{throw Error(`Invalid redirectUri: "${$.redirectUri}". It must be a valid absolute URL.`)}}}let Q=new URLSearchParams;if(Q.append("grant_type","authorization_code"),Q.append("code",K),Q.append("redirect_uri",W),Q.append("client_id",$.clientId),$.clientSecret)Q.append("client_secret",$.clientSecret);Q.append("code_verifier",A);try{let L=await fetch(F,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:Q.toString()}),J=await L.json();if(!L.ok){console.error("Token exchange error:",J);let j=J;throw Error(`Token exchange failed: ${j.error||L.statusText} - ${j.error_description||""}`.trim())}let D=await Y.tokenResponse["~standard"].validate(J);if(D.issues)throw console.error("Token response validation failed:",D.issues),Error(`Token response validation failed: ${D.issues}`);return D.value}catch(L){throw console.error("Error during token exchange:",L),L}}async function u(K){return m(async()=>{if(!$)throw Error("Enterprise Standard SSO Manager not initialized");M();let A=$.tokenUrl,G=new URLSearchParams;G.append("grant_type","refresh_token"),G.append("refresh_token",K),G.append("client_id",$.clientId);let F=await fetch(A,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:G.toString()}),W=await F.json();if(!F.ok){console.error("Token refresh error:",W);let Q=W;throw Error(`Token refresh failed: ${Q.error||F.statusText} - ${Q.error_description||""}`.trim())}return W})}async function SX(K){try{if(!$)throw Error("Enterprise Standard SSO Manager not initialized");if(!$.revocationEndpoint)return;let A=new URLSearchParams;A.append("token",K),A.append("token_type_hint","refresh_token"),A.append("client_id",$.clientId);let G=await fetch($.revocationEndpoint,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:A.toString()});if(!G.ok)console.warn("Token revocation failed:",G.status,G.statusText);else console.log("Token revoked successfully")}catch(A){console.warn("Error revoking token:",A)}}async function l(){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");if(!$.jwksUri&&!$.authority)throw Error("Missing 'jwksUri' or 'authority' from SSO Config. OIDC configuration is required for this operation.");let K=$.jwksUri||`${$.authority}/protocol/openid-connect/certs`;return XX(K)}async function n(K){try{let A=K.split(".");if(A.length!==3)throw Error("Invalid JWT");let G=JSON.parse(atob(A[0].replace(/-/g,"+").replace(/_/g,"/"))),F=JSON.parse(atob(A[1].replace(/-/g,"+").replace(/_/g,"/"))),W=A[2].replace(/-/g,"+").replace(/_/g,"/"),Q=await NX(G.kid),J=new TextEncoder().encode(`${A[0]}.${A[1]}`);if(!await crypto.subtle.verify("RSASSA-PKCS1-v1_5",Q,Uint8Array.from(atob(W),(I)=>I.charCodeAt(0)),J))throw Error("Invalid JWT signature");let j=await Y.idTokenClaims["~standard"].validate(F);if(j.issues)throw console.error("ID token claims validation failed:",j.issues),Error(`ID token claims validation failed: ${j.issues}`);return j.value}catch(A){throw console.error("Error verifying JWT:",A),A}}function t(K=32){let A=new Uint8Array(K);return crypto.getRandomValues(A),Array.from(A,(G)=>G.toString(16).padStart(2,"0")).join("").substring(0,K)}async function KX(K){let G=new TextEncoder().encode(K),F=await crypto.subtle.digest("SHA-256",G),W=Array.from(new Uint8Array(F));return btoa(String.fromCharCode(...W)).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}async function NX(K){let A=await l();return YX(A,K)}function p(K,A){let G=A instanceof Date?A:new Date(A);if(Number.isNaN(G.getTime()))throw Error(`Invalid SSO token expiry: ${String(A)}`);let F={expires_in:K.expires_in,refresh_expires_in:K.refresh_expires_in,scope:K.scope,session_state:K.session_state,token_type:K.token_type,expires:G.toISOString()};return[["Set-Cookie",k("access",K.access_token,G)],["Set-Cookie",k("id",K.id_token,G)],["Set-Cookie",k("refresh",K.refresh_token??"",G)],["Set-Cookie",k("control",F,G)]]}async function g(K){let A=R("access",K),G=R("id",K),F=R("refresh",K),W=R("control",K,!0);if(!A||!G||!F||!W)return{tokens:void 0,refreshHeaders:[]};let Q={access_token:A,id_token:G,refresh_token:F,...W};if(W.expires&&F&&Date.now()>new Date(W.expires).getTime()){Q=await u(F);let L=await f(Q),J=p(Q,L.sso.expires);return{tokens:Q,refreshHeaders:J}}return{tokens:Q,refreshHeaders:[]}}async function AX(K){let{tokens:A}=await g(K);if(!A)return;return A.access_token}function k(K,A,G){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");if(K=`${$.cookiesPrefix}.${K}`,typeof A!=="string")A=btoa(JSON.stringify(A));let F;if(G instanceof Date)F=`Expires=${G.toUTCString()}`;else if(typeof G==="number")F=`Max-Age=${G}`;else throw Error("Invalid expires type",G);if(A.length>4000)throw Error(`Error setting cookie: ${K}. Cookie length is: ${A.length}`);return`${K}=${A}; ${F}; Path=${$.cookiesPath}; HttpOnly;${$.cookiesSecure?" Secure;":""} SameSite=${$.cookiesSameSite};`}function C(K){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");return`${$.cookiesPrefix}.${K}=; Max-Age=0; Path=${$.cookiesPath}; HttpOnly;${$.cookiesSecure?" Secure;":""} SameSite=${$.cookiesSameSite};`}function R(K,A,G=!1){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");let F=A.headers.get("cookie");if(!F)return null;let W=F.split(";").find((J)=>J.trim().startsWith(`${$.cookiesPrefix}.${K}=`));if(!W)return null;let Q=W.split("=")[1].trim();if(!G)return Q;let L=atob(Q);return JSON.parse(L)}async function GX(K,A){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");let{loginUrl:G,userUrl:F,errorUrl:W,landingUrl:Q,tokenUrl:L,refreshUrl:J,logoutUrl:D,logoutBackChannelUrl:j,jwksUrl:I,redirectUri:w}={...$,...A},z=new URL(K.url).pathname;if(w){let O;try{O=new URL(w).pathname}catch{try{let V=new URL(K.url),_=w.startsWith("//")?w.slice(1):w;O=new URL(_,V.origin).pathname}catch{O=w.startsWith("/")?w:`/${w}`}}if(O===z)return U(K)}if(G===z){let O=$.cookiesSecure?K.url.replace(/^http:\/\//,"https://"):K.url;return y({landingUrl:Q||"/",errorUrl:W},O)}if(F===z){let{tokens:O,refreshHeaders:V}=await g(K);if(!O)return new Response("User not logged in",{status:401});let _=await f(O);return new Response(JSON.stringify(_),{headers:[["Content-Type","application/json"],...V]})}if(L===z){let{tokens:O,refreshHeaders:V}=await g(K);if(!O)return new Response("User not logged in",{status:401});return new Response(JSON.stringify({token:O.access_token,expires:O.expires}),{headers:[["Content-Type","application/json"],...V]})}if(J===z){let O=R("refresh",K);if(!O)return new Response("User not logged in",{status:401});let V=await u(O),_=await f(V),b=p(V,_.sso.expires);return new Response("Refresh Complete",{status:200,headers:b})}if(D===z)return h(K,{landingUrl:Q||"/"});if(j===z)return E(K);if(I===z){let O=await l();return new Response(JSON.stringify(O),{headers:[["Content-Type","application/json"]]})}return new Response("Not Found",{status:404})}return{...$,getUser:T,getRequiredUser:P,getJwt:AX,initiateLogin:y,logout:h,logoutBackChannel:E,callbackHandler:U,handler:GX}}function d(Y){let Z={},X=Y.split(";");for(let N of X){let S=N.trim();if(!S)continue;let B=S.indexOf("=");if(B===-1)continue;let $=S.slice(0,B).trim(),M=S.slice(B+1).trim();Z[$]=M}return Z}function q(Y){return Y=Y??"SSO Unavailable",new Response(JSON.stringify({error:Y}),{status:503,statusText:Y,headers:{"Content-Type":"application/json"}})}function ZX(Y){if(!Y)return[];let Z=Y.headers;if(Z.getSetCookie)return Z.getSetCookie();let X=Y.headers.get("set-cookie");return X?[X]:[]}function JX(Y,Z){let X=new Headers;Y.headers.forEach((N,S)=>{if(S.toLowerCase()!=="set-cookie")X.set(S,N)});for(let N of Z)X.append("Set-Cookie",N);return new Response(Y.body,{status:Y.status,statusText:Y.statusText,headers:X})}var v="EnterpriseStandard instance is required. Create one with enterpriseStandard(source, config) and pass it to this function.";async function lX(Y,Z){return H(Z,v),Z.sso?.getUser(Y)}async function OX(Y,Z){H(Z,v);let X=Z.logger??r;X.debug?.("getUser called",{hasInstance:!0,hasSso:!!Z.sso,hasCiam:!!Z.ciam});let N=await Z.sso?.getUser(Y);if(N)return X.debug?.("Found SSO user",{email:N.email}),N;X.debug?.("No SSO user, trying CIAM");let S=await Z.ciam?.getUser(Y);return X.debug?.("CIAM user result",{email:S?.email??void 0}),S}async function nX(Y,Z){let X=await OX(Y,Z);if(X)return X;throw new Response("Unauthorized",{status:401,statusText:"Unauthorized"})}async function tX(Y,Z){H(Z,v);let X=Z.sso;if(!X)return q();return X.initiateLogin(Y)}async function iX(Y,Z){H(Z,v);let X=Z.sso;if(!X)return q();return X.callbackHandler(Y)}async function aX(Y,Z){H(Z,v);let{sso:X,ciam:N}=Z;if(!X&&!N)return q("Logout Unavailable");let S=X?await X.logout(Y,{landingUrl:"/"}):void 0,B=N?await N.logout(Y):void 0,$=S??B;if(!$)return q("Logout Unavailable");let M=[...ZX(S),...ZX(B)];return JX($,M)}async function oX(Y,Z){H(Z,v);let{sso:X,ciam:N}=Z;if(!X&&!N)return q("Back-Channel Logout Unavailable");let S=Y.clone(),B=Y.clone(),$=X?await X.logoutBackChannel(S):void 0;if($?.status===200)return $;let M=N?await N.logoutBackChannel(B):void 0;if(M)return M;return $??q("Back-Channel Logout Unavailable")}var c;function sX(Y){c=Y}function jX(Y){if(VX(Y.configSource))return Y.configSource;if(!c)throw Error("Tenant config hydration is not registered. Import @enterprisestandard/server before using tenant.config().");return c(Y.configSource)}function eX(Y){let Z=Y.configSource;return{...Y,config:()=>jX({configSource:Z})}}function VX(Y){let Z=Y;return typeof Y==="object"&&Y!==null&&typeof Z.load==="function"&&typeof Z.subscribe==="function"}
12
+ export{DX as a,EX as b,i as c,a as d,H as e,o as f,PX as g,BX as h,TX as i,zX as j,FX as k,wX as l,r as m,RX as n,bX as o,CX as p,qX as q,XX as r,YX as s,gX as t,pX as u,mX as v,dX as w,cX as x,uX as y,lX as z,OX as A,nX as B,tX as C,iX as D,aX as E,oX as F,sX as G,jX as H,eX as I};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@enterprisestandard/core",
3
- "version": "0.0.13",
3
+ "version": "0.0.14-beta.20260331.2",
4
4
  "description": "Enterprise Standard Core (Server-only)",
5
5
  "private": false,
6
6
  "author": "enterprisestandard",
@@ -27,7 +27,7 @@
27
27
  }
28
28
  },
29
29
  "peerDependencies": {
30
- "@enterprisestandard/zod": "^0.0.13",
31
- "@enterprisestandard/valibot": "^0.0.13"
30
+ "@enterprisestandard/zod": "0.0.14-beta.20260331.2",
31
+ "@enterprisestandard/valibot": "0.0.14-beta.20260331.2"
32
32
  }
33
33
  }
@@ -1,12 +0,0 @@
1
- function jX(Y){return{"~standard":{version:1,vendor:Y,validate:(Z)=>{if(typeof Z!=="object"||Z===null)return{issues:[{message:"Expected an object"}]};let X=Z,N=[],S={};if("code"in X)if(typeof X.code==="string")S.code=X.code;else N.push({message:"code must be a string",path:["code"]});else if(!("error"in X))N.push({message:"code is required",path:["code"]});if("state"in X)if(typeof X.state==="string"||X.state===void 0)S.state=X.state;else N.push({message:"state must be a string",path:["state"]});if("session_state"in X)if(typeof X.session_state==="string"||X.session_state===void 0)S.session_state=X.session_state;else N.push({message:"session_state must be a string",path:["session_state"]});if("error"in X){if(typeof X.error==="string")S.error=X.error;else N.push({message:"error must be a string",path:["error"]});if("error_description"in X)if(typeof X.error_description==="string"||X.error_description===void 0)S.error_description=X.error_description;else N.push({message:"error_description must be a string",path:["error_description"]});if("error_uri"in X)if(typeof X.error_uri==="string"||X.error_uri===void 0)S.error_uri=X.error_uri;else N.push({message:"error_uri must be a string",path:["error_uri"]})}if("iss"in X)if(typeof X.iss==="string"||X.iss===void 0)S.iss=X.iss;else N.push({message:"iss must be a string",path:["iss"]});if(N.length>0)return{issues:N};return{value:S}}}}}function VX(Y){return{"~standard":{version:1,vendor:Y,validate:(Z)=>{if(typeof Z!=="object"||Z===null)return{issues:[{message:"Expected an object"}]};let X=Z,N=[],S={};if("access_token"in X)if(typeof X.access_token==="string")S.access_token=X.access_token;else N.push({message:"access_token must be a string",path:["access_token"]});else N.push({message:"access_token is required",path:["access_token"]});if("id_token"in X)if(typeof X.id_token==="string")S.id_token=X.id_token;else N.push({message:"id_token must be a string",path:["id_token"]});else N.push({message:"id_token is required",path:["id_token"]});if("token_type"in X)if(typeof X.token_type==="string")S.token_type=X.token_type;else N.push({message:"token_type must be a string",path:["token_type"]});else N.push({message:"token_type is required",path:["token_type"]});if("refresh_token"in X)if(typeof X.refresh_token==="string"||X.refresh_token===void 0)S.refresh_token=X.refresh_token;else N.push({message:"refresh_token must be a string",path:["refresh_token"]});if("scope"in X)if(typeof X.scope==="string"||X.scope===void 0)S.scope=X.scope;else N.push({message:"scope must be a string",path:["scope"]});if("session_state"in X)if(typeof X.session_state==="string"||X.session_state===void 0)S.session_state=X.session_state;else N.push({message:"session_state must be a string",path:["session_state"]});if("expires"in X)if(typeof X.expires==="string"||X.expires===void 0)S.expires=X.expires;else N.push({message:"expires must be a string",path:["expires"]});if("expires_in"in X)if(typeof X.expires_in==="number"||X.expires_in===void 0)S.expires_in=X.expires_in;else N.push({message:"expires_in must be a number",path:["expires_in"]});if("refresh_expires_in"in X)if(typeof X.refresh_expires_in==="number"||X.refresh_expires_in===void 0)S.refresh_expires_in=X.refresh_expires_in;else N.push({message:"refresh_expires_in must be a number",path:["refresh_expires_in"]});if(N.length>0)return{issues:N};return{value:S}}}}}function i(Y){return{"~standard":{version:1,vendor:Y,validate:(Z)=>{if(typeof Z!=="object"||Z===null)return{issues:[{message:"Expected an object"}]};let X=Z,N=[],S={...X},Q=["iss","aud","sub","sid","name","email","preferred_username","picture"];for(let M of Q)if(M in X&&X[M]!==void 0){if(typeof X[M]!=="string")N.push({message:`${M} must be a string`,path:[M]})}let $=["exp","iat"];for(let M of $)if(M in X&&X[M]!==void 0){if(typeof X[M]!=="number")N.push({message:`${M} must be a number`,path:[M]})}if(N.length>0)return{issues:N};return{value:S}}}}}function a(Y){let Z=Y["~standard"];return Object.assign({},Y,{validate(X){return Promise.resolve(Z.validate(X))}})}function D(Y,Z="Assertion failed. Required value is null or undefined."){if(Y===void 0||Y===null)throw Error(Z);return Y}function o(Y,Z){return Response.json({error:"validation_failed",message:Z,issues:Y},{status:400,headers:{"Content-Type":"application/json"}})}function HX(Y,Z,X=[]){let N={...Y,...Z};for(let S of X)N[S]=Y?.[S]??Z?.[S];return N}function QX(Y){let Z="",X=0,N=Y.length;while(X<N){let S=Y[X];if(S==='"'||S==="'"){let Q=S;Z+=S,X++;while(X<N){let $=Y[X];if($==="\\"){if(Z+=$,X+1<N)Z+=Y[X+1],X+=2;else X++;continue}if($===Q){Z+=$,X++;break}Z+=$,X++}continue}if(S==="/"&&X+1<N){let Q=Y[X+1];if(Q==="/"){X+=2;while(X<N&&Y[X]!==`
2
- `)X++;if(X<N)Z+=`
3
- `;X++;continue}if(Q==="*"){X+=2;while(X+1<N&&!(Y[X]==="*"&&Y[X+1]==="/"))X++;X+=2;continue}}Z+=S,X++}return Z}function PX(Y){let Z=QX(Y);return JSON.parse(Z)}async function TX(Y,Z=async(Q)=>Q.status===200,X=1000,N=1e4,S){let Q=Date.now(),$="Awaiting Ping";return new Promise((M,_)=>{let T=null,y=null,v=async()=>{try{let V=await fetch(Y);if(V.ok)if(await Z(V)){if(T)clearInterval(T);if(y)clearInterval(y);M()}else $=`Response test failed: ${V.status}: ${V.statusText} - ${Y}`;else try{let h=await V.json();$=`Response error: ${V.status}: ${V.statusText} - ${Y}: ${JSON.stringify(h)}`}catch(h){$=`Response error: ${V.status}: ${V.statusText} - ${Y}`}}catch(V){$=`${V instanceof Error?V.message:String(V)} - ${Y}`}};if(v(),T=setInterval(v,X),N>0)y=setInterval(()=>{console.warn(`${$}: ${Date.now()-Q}ms`)},N);if(S)setTimeout(()=>{if(T)clearInterval(T);if(y)clearInterval(y);_(Error(`Timeout: ${S}ms: ${$}`))},S)})}var BX="@enterprisestandard/core",WX=a(i(BX));function MX(Y){let Z=Y.exp!=null?new Date(Y.exp*1000):new Date,X=Y.iss??"";return{id:Y.sub??"",userName:Y.preferred_username??"",name:Y.name??"",email:Y.email??"",avatar:Y.picture,sso:{profile:{...Y,iss:Y.iss??X,aud:Y.aud},tenant:{id:Y.idp??X,name:X},tokenType:"Bearer",expires:Z}}}function FX(Y){let Z=Y.replace(/-/g,"+").replace(/_/g,"/");return atob(Z)}async function IX(Y){let Z=Y.split(".");if(Z.length!==3)throw Error("Invalid JWT");let X=FX(Z[1]),N=JSON.parse(X),S=await WX.validate(N);if(S.issues)throw Error(`ID token claims validation failed: ${S.issues.map((Q)=>Q.message).join("; ")}`);if(S.value)return MX(S.value);throw Error("ID token claims validation failed")}var I=(Y,Z,...X)=>{if(X.length>0)console[Y](`[${Y.toUpperCase()}]`,Z,...X);else console[Y](`[${Y.toUpperCase()}]`,Z)},r={debug:()=>{},info:()=>{},warn(Y,...Z){I("warn",Y,...Z)},error(Y,...Z){I("error",Y,...Z)}},yX={debug:()=>{},info:()=>{},warn:()=>{},error:()=>{}},RX={debug:()=>{},info:I.bind(console,"info"),warn:I.bind(console,"warn"),error:I.bind(console,"error")},s=(Y,...Z)=>{if(Z.length>0)console.log("[DEBUG]",Y,...Z);else console.log("[DEBUG]",Y)},bX={debug:s,info:I.bind(console,"info"),warn:I.bind(console,"warn"),error:I.bind(console,"error")},CX={debug:s,info:I.bind(console,"info"),warn:I.bind(console,"warn"),error:I.bind(console,"error")};var e=new Map;async function m(Y,Z=3,X=1000,N=30000){let S=Error("Placeholder Error");for(let Q=0;Q<=Z;Q++)try{return await Y()}catch($){if(S=$ instanceof Error?$:Error(String($)),$ instanceof Error&&$.message.includes("400"))throw $;if(Q===Z)throw S;let M=Math.min(X*2**Q,N),_=Math.random()*0.1*M;await new Promise((T)=>setTimeout(T,M+_)),console.warn(`Retry attempt ${Q+1} after ${M+_}ms delay`)}throw S}async function XX(Y){let Z=e.get(Y);if(Z)return Z;return m(async()=>{let X=await fetch(Y);if(!X.ok)throw Error("Failed to fetch JWKS");let N=await X.json();return e.set(Y,N),N})}async function YX(Y,Z){let X=Y.keys.find((N)=>N.kid===Z);if(!X)throw Error("Public key not found");return crypto.subtle.importKey("jwk",{kty:X.kty,n:X.n,e:X.e},{name:"RSASSA-PKCS1-v1_5",hash:"SHA-256"},!1,["verify"])}function kX(Y,Z={}){let X=Z.cookieName??"es.active_session",N=Y.headers.get("cookie");if(!N)return;return d(N)[X]}function gX(Y,Z={}){let X=Z.cookieName??"es.active_session",N=Z.path??"/",S=Z.secure??!1,Q=Z.sameSite??"Lax",$=Z.maxAge,M=[`${X}=${Y}`,`Path=${N}`,"HttpOnly",`SameSite=${Q}`];if(S)M.push("Secure");if(typeof $==="number")M.push(`Max-Age=${$}`);return M.join("; ")}function pX(Y={}){let Z=Y.cookieName??"es.active_session",X=Y.path??"/",N=Y.secure??!1,S=Y.sameSite??"Lax",Q=[`${Z}=`,"Max-Age=0",`Path=${X}`,"HttpOnly",`SameSite=${S}`];if(N)Q.push("Secure");return Q.join("; ")}function mX(Y,Z={}){let X=typeof Y==="string"?Y:Y?.headers.get("cookie")??void 0;if(!X)return[];let S=`${Z.cookiePrefix??"es.sso"}.`,Q=new Set;for(let $ of Object.keys(d(X))){if(!$.startsWith(S))continue;let M=$.slice(S.length),_=M.lastIndexOf(".");if(_<=0)continue;let T=M.slice(0,_).trim();if(T)Q.add(T)}return Array.from(Q)}function dX(Y,Z){if(!Y)return;let X=d(Y);for(let[N,S]of Object.entries(X)){if(!N.startsWith("es.sso.")||!N.endsWith(".state"))continue;try{let Q=JSON.parse(atob(S));if(Q?.state===Z)return{clientId:N.slice(7,-6),stateCookie:Q}}catch{}}return}function cX(Y,Z,X,N){if(!X&&!N)return;let S={...X,...N},Q=!!(S.authority&&S.tokenUrl&&S.authorizationUrl&&S.clientId&&S.redirectUri&&S.scope),$={...S,authority:Q?D(S.authority,"Missing 'authority' from SSO Config"):S.authority,tokenUrl:Q?D(S.tokenUrl,"Missing 'tokenUrl' from SSO Config"):S.tokenUrl,authorizationUrl:Q?D(S.authorizationUrl,"Missing 'authorizationUrl' from SSO Config"):S.authorizationUrl,clientId:Q?D(S.clientId,"Missing 'clientId' from SSO Config"):S.clientId,redirectUri:Q?D(S.redirectUri,"Missing 'redirectUri' from SSO Config"):S.redirectUri,scope:Q?D(S.scope,"Missing 'scope' from SSO Config"):S.scope,responseType:S.responseType??"code",cookiesSecure:S.cookiesSecure!==void 0?S.cookiesSecure:!0,cookiesSameSite:S.cookiesSameSite!==void 0?S.cookiesSameSite:"Strict",cookiesPrefix:S.cookiesPrefix??(S.clientId?`es.sso.${S.clientId}`:"es.sso"),cookiesPath:S.cookiesPath??"/"};function M(){let K=[];if(!$.authority)K.push("authority");if(!$.tokenUrl)K.push("tokenUrl");if(!$.authorizationUrl)K.push("authorizationUrl");if(!$.clientId)K.push("clientId");if(!$.redirectUri)K.push("redirectUri");if(!$.scope)K.push("scope");if(K.length>0)throw Error(`Missing OIDC configuration fields: ${K.join(", ")}. OIDC configuration is required for SSO operations. Please provide these fields either in your vault configuration or in the SSO config when initializing enterpriseStandard.`)}async function _(K){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");try{let{tokens:A}=await k(K);if(!A)return;return await U(A)}catch(A){console.error("Error parsing user from cookies:",A);return}}async function T(K){let A=await _(K);if(A)return A;throw new Response("Unauthorized",{status:401,statusText:"Unauthorized"})}async function y({landingUrl:K,errorUrl:A},B){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");M();let F=t(),W=t(64),G=$.redirectUri;try{new URL(G)}catch{if(B)try{let O=new URL(B),w=G.startsWith("//")?G.slice(1):G.startsWith("/")?G:`/${G}`;G=new URL(w,O.origin).toString()}catch{try{let O=new URL($.authorizationUrl),w=G.startsWith("//")?G.slice(1):G.startsWith("/")?G:`/${G}`;G=new URL(w,O.origin).toString()}catch{throw Error(`Invalid redirectUri: "${$.redirectUri}". It must be a valid absolute URL.`)}}}let L=new URL($.authorizationUrl);L.searchParams.append("client_id",$.clientId),L.searchParams.append("redirect_uri",G),L.searchParams.append("response_type","code"),L.searchParams.append("scope",$.scope),L.searchParams.append("state",F);let J=await KX(W);L.searchParams.append("code_challenge",J),L.searchParams.append("code_challenge_method","S256");let j={state:F,codeVerifier:W,landingUrl:K,errorUrl:A};return new Response("Redirecting to SSO Provider",{status:302,headers:{Location:L.toString(),"Set-Cookie":f("state",j,86400)}})}async function v(K,A){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");try{let J=R("refresh",K);if(J)await SX(J)}catch(J){console.warn("Failed to revoke token:",J)}if($.sessionStore)try{let J=await _(K);if(J?.sso?.profile.sid){let j=J.sso.profile.sid;await $.sessionStore.delete(j)}}catch(J){console.warn("Failed to delete session:",J)}let B=[["Set-Cookie",b("access")],["Set-Cookie",b("id")],["Set-Cookie",b("refresh")],["Set-Cookie",b("control")],["Set-Cookie",b("state")]],W=new URL(K.url).searchParams.get("redirect");if(W)return new Response("Logged out",{status:302,headers:[["Location",W],...B]});let G=K.headers.get("accept");if(G?.includes("application/json")||G?.includes("text/javascript"))return new Response(JSON.stringify({success:!0,message:"Logged out"}),{status:200,headers:[["Content-Type","application/json"],...B]});else return new Response(`
4
- <!DOCTYPE html><html lang="en"><body>
5
- <h1>Logout Complete</h1>
6
- <div style="display: none">
7
- It is not recommended to show the default logout page. Include '?redirect=/someHomePage' or logout asynchronously.
8
- Check the <a href="https://EnterpriseStandard.com/sso#logout">Enterprise Standard Packages</a> for more information.
9
- </div>
10
- </body></html>
11
- `,{status:200,headers:[["Content-Type","text/html"],...B]})}async function V(K){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");if(!$.sessionStore)throw Error("Back-Channel Logout requires sessionStore configuration");try{let A=K.headers.get("content-type");if(!A||!A.includes("application/x-www-form-urlencoded"))return new Response("Invalid Content-Type, expected application/x-www-form-urlencoded",{status:400});let B=await K.text(),W=new URLSearchParams(B).get("logout_token");if(!W)return new Response("Missing logout_token parameter",{status:400});let L=(await n(W)).sid;if(!L)return console.warn("Back-Channel Logout: logout_token missing sid claim"),new Response("Invalid logout_token: missing sid claim",{status:400});return await $.sessionStore.delete(L),console.log(`Back-Channel Logout: successfully deleted session ${L}`),new Response("OK",{status:200})}catch(A){return console.error("Error during back-channel logout:",A),new Response("Internal Server Error",{status:500})}}async function h(K){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");let A=new URL(K.url),B=new URLSearchParams(A.search),F=Object.fromEntries(B.entries()),W=await Y.callbackParams["~standard"].validate(F);if(W.issues)return o(W.issues,"OIDC callback parameters validation failed");let{code:G,state:L}=W.value;try{let J=R("state",K,!0),{codeVerifier:j,state:O,landingUrl:w}=J??{};if(D(j,'OIDC "codeVerifier" was not present in cookies, ensure that the SSO login was initiated correctly'),D(O,'OIDC "stateVerifier" was not present in cookies, ensure that the SSO login was initiated correctly'),D(w,'OIDC "landingUrl" was not present in cookies'),L!==O)throw Error('SSO State Verifier failed, the "state" request parameter does not equal the "state" in the SSO cookie');let x=await $X(G,j,K.url),H=await U(x);if($.sessionStore)try{let E=H.sso.profile.sid,P=H.id;if(E&&P){let z={sid:E,sub:P,createdAt:new Date,lastActivityAt:new Date};await $.sessionStore.create(z)}else console.warn("Session creation skipped: missing sid or sub in ID token claims")}catch(E){console.warn("Failed to create session:",E)}if($.userStore)try{let E=H.id;if(E){let P=new Date,z=await $.userStore.get(E);if(z||$.enableJitUserProvisioning){let p={...z??{},...H,id:E,tenantId:z?.tenantId,createdAt:z?.createdAt??P,updatedAt:P};await $.userStore.upsert(p)}else console.warn("JIT user provisioning disabled: user not found in store and will not be created")}else console.warn("User storage skipped: missing sub in ID token claims")}catch(E){console.warn("Failed to store user:",E)}return new Response("Authentication successful, redirecting",{status:302,headers:[["Location",w],["Set-Cookie",b("state")],...g(x,H.sso.expires)]})}catch(J){console.error("Error during sign-in callback:",J);try{let j=R("state",K,!0),{errorUrl:O}=j??{};if(O)return new Response("Redirecting to error url",{status:302,headers:[["Location",O]]})}catch(j){console.warn("Error parsing the errorUrl from the OIDC cookie")}return console.warn("No error page was found in the cookies. The user will be shown a default error page."),new Response("An error occurred during authentication, please return to the application homepage and try again.",{status:500})}}async function U(K){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");let A=await n(K.id_token),B=Number(K.refresh_expires_in??K.expires_in??3600),F=K.expires?new Date(K.expires):new Date(Date.now()+B*1000);return{id:A.sub,userName:A.preferred_username||"",name:A.name||"",email:A.email||"",emails:[{value:A.email||"",primary:!0}],avatar:A.picture,sso:{profile:{...A,iss:A.iss||$.authority,aud:A.aud||$.clientId},tenant:{id:A.idp||A.iss||$.authority||"",name:A.iss||$.authority||""},scope:K.scope,tokenType:K.token_type,sessionState:K.session_state,expires:F}}}async function $X(K,A,B){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");M();let{tokenUrl:F,redirectUri:W}=$;try{new URL(W)}catch{if(B)try{let L=new URL(B),J=W.startsWith("//")?W.slice(1):W.startsWith("/")?W:`/${W}`;W=new URL(J,L.origin).toString()}catch{try{let L=new URL(F),J=W.startsWith("//")?W.slice(1):W.startsWith("/")?W:`/${W}`;W=new URL(J,L.origin).toString()}catch{throw Error(`Invalid redirectUri: "${$.redirectUri}". It must be a valid absolute URL.`)}}}let G=new URLSearchParams;if(G.append("grant_type","authorization_code"),G.append("code",K),G.append("redirect_uri",W),G.append("client_id",$.clientId),$.clientSecret)G.append("client_secret",$.clientSecret);G.append("code_verifier",A);try{let L=await fetch(F,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:G.toString()}),J=await L.json();if(!L.ok){console.error("Token exchange error:",J);let O=J;throw Error(`Token exchange failed: ${O.error||L.statusText} - ${O.error_description||""}`.trim())}let j=await Y.tokenResponse["~standard"].validate(J);if(j.issues)throw console.error("Token response validation failed:",j.issues),Error(`Token response validation failed: ${j.issues}`);return j.value}catch(L){throw console.error("Error during token exchange:",L),L}}async function u(K){return m(async()=>{if(!$)throw Error("Enterprise Standard SSO Manager not initialized");M();let A=$.tokenUrl,B=new URLSearchParams;B.append("grant_type","refresh_token"),B.append("refresh_token",K),B.append("client_id",$.clientId);let F=await fetch(A,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:B.toString()}),W=await F.json();if(!F.ok){console.error("Token refresh error:",W);let G=W;throw Error(`Token refresh failed: ${G.error||F.statusText} - ${G.error_description||""}`.trim())}return W})}async function SX(K){try{if(!$)throw Error("Enterprise Standard SSO Manager not initialized");if(!$.revocationEndpoint)return;let A=new URLSearchParams;A.append("token",K),A.append("token_type_hint","refresh_token"),A.append("client_id",$.clientId);let B=await fetch($.revocationEndpoint,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:A.toString()});if(!B.ok)console.warn("Token revocation failed:",B.status,B.statusText);else console.log("Token revoked successfully")}catch(A){console.warn("Error revoking token:",A)}}async function l(){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");if(!$.jwksUri&&!$.authority)throw Error("Missing 'jwksUri' or 'authority' from SSO Config. OIDC configuration is required for this operation.");let K=$.jwksUri||`${$.authority}/protocol/openid-connect/certs`;return XX(K)}async function n(K){try{let A=K.split(".");if(A.length!==3)throw Error("Invalid JWT");let B=JSON.parse(atob(A[0].replace(/-/g,"+").replace(/_/g,"/"))),F=JSON.parse(atob(A[1].replace(/-/g,"+").replace(/_/g,"/"))),W=A[2].replace(/-/g,"+").replace(/_/g,"/"),G=await NX(B.kid),J=new TextEncoder().encode(`${A[0]}.${A[1]}`);if(!await crypto.subtle.verify("RSASSA-PKCS1-v1_5",G,Uint8Array.from(atob(W),(w)=>w.charCodeAt(0)),J))throw Error("Invalid JWT signature");let O=await Y.idTokenClaims["~standard"].validate(F);if(O.issues)throw console.error("ID token claims validation failed:",O.issues),Error(`ID token claims validation failed: ${O.issues}`);return O.value}catch(A){throw console.error("Error verifying JWT:",A),A}}function t(K=32){let A=new Uint8Array(K);return crypto.getRandomValues(A),Array.from(A,(B)=>B.toString(16).padStart(2,"0")).join("").substring(0,K)}async function KX(K){let B=new TextEncoder().encode(K),F=await crypto.subtle.digest("SHA-256",B),W=Array.from(new Uint8Array(F));return btoa(String.fromCharCode(...W)).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}async function NX(K){let A=await l();return YX(A,K)}function g(K,A){let B={expires_in:K.expires_in,refresh_expires_in:K.refresh_expires_in,scope:K.scope,session_state:K.session_state,token_type:K.token_type,expires:A.toISOString()};return[["Set-Cookie",f("access",K.access_token,A)],["Set-Cookie",f("id",K.id_token,A)],["Set-Cookie",f("refresh",K.refresh_token??"",A)],["Set-Cookie",f("control",B,A)]]}async function k(K){let A=R("access",K),B=R("id",K),F=R("refresh",K),W=R("control",K,!0);if(!A||!B||!F||!W)return{tokens:void 0,refreshHeaders:[]};let G={access_token:A,id_token:B,refresh_token:F,...W};if(W.expires&&F&&Date.now()>new Date(W.expires).getTime()){G=await u(F);let L=await U(G),J=g(G,L.sso.expires);return{tokens:G,refreshHeaders:J}}return{tokens:G,refreshHeaders:[]}}async function AX(K){let{tokens:A}=await k(K);if(!A)return;return A.access_token}function f(K,A,B){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");if(K=`${$.cookiesPrefix}.${K}`,typeof A!=="string")A=btoa(JSON.stringify(A));let F;if(B instanceof Date)F=`Expires=${B.toUTCString()}`;else if(typeof B==="number")F=`Max-Age=${B}`;else throw Error("Invalid expires type",B);if(A.length>4000)throw Error(`Error setting cookie: ${K}. Cookie length is: ${A.length}`);return`${K}=${A}; ${F}; Path=${$.cookiesPath}; HttpOnly;${$.cookiesSecure?" Secure;":""} SameSite=${$.cookiesSameSite};`}function b(K){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");return`${$.cookiesPrefix}.${K}=; Max-Age=0; Path=${$.cookiesPath}; HttpOnly;${$.cookiesSecure?" Secure;":""} SameSite=${$.cookiesSameSite};`}function R(K,A,B=!1){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");let F=A.headers.get("cookie");if(!F)return null;let W=F.split(";").find((J)=>J.trim().startsWith(`${$.cookiesPrefix}.${K}=`));if(!W)return null;let G=W.split("=")[1].trim();if(!B)return G;let L=atob(G);return JSON.parse(L)}async function GX(K,A){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");let{loginUrl:B,userUrl:F,errorUrl:W,landingUrl:G,tokenUrl:L,refreshUrl:J,logoutUrl:j,logoutBackChannelUrl:O,jwksUrl:w,redirectUri:x}={...$,...A},H=new URL(K.url).pathname;if(x){let E;try{E=new URL(x).pathname}catch{try{let P=new URL(K.url),z=x.startsWith("//")?x.slice(1):x;E=new URL(z,P.origin).pathname}catch{E=x.startsWith("/")?x:`/${x}`}}if(E===H)return h(K)}if(B===H)return y({landingUrl:G||"/",errorUrl:W},K.url);if(F===H){let{tokens:E,refreshHeaders:P}=await k(K);if(!E)return new Response("User not logged in",{status:401});let z=await U(E);return new Response(JSON.stringify(z),{headers:[["Content-Type","application/json"],...P]})}if(L===H){let{tokens:E,refreshHeaders:P}=await k(K);if(!E)return new Response("User not logged in",{status:401});return new Response(JSON.stringify({token:E.access_token,expires:E.expires}),{headers:[["Content-Type","application/json"],...P]})}if(J===H){let E=R("refresh",K);if(!E)return new Response("User not logged in",{status:401});let P=await u(E),z=await U(P),p=g(P,z.sso.expires);return new Response("Refresh Complete",{status:200,headers:p})}if(j===H)return v(K,{landingUrl:G||"/"});if(O===H)return V(K);if(w===H){let E=await l();return new Response(JSON.stringify(E),{headers:[["Content-Type","application/json"]]})}return new Response("Not Found",{status:404})}return{...$,getUser:_,getRequiredUser:T,getJwt:AX,initiateLogin:y,logout:v,logoutBackChannel:V,callbackHandler:h,handler:GX}}function d(Y){let Z={},X=Y.split(";");for(let N of X){let S=N.trim();if(!S)continue;let Q=S.indexOf("=");if(Q===-1)continue;let $=S.slice(0,Q).trim(),M=S.slice(Q+1).trim();Z[$]=M}return Z}function C(Y){return Y=Y??"SSO Unavailable",new Response(JSON.stringify({error:Y}),{status:503,statusText:Y,headers:{"Content-Type":"application/json"}})}function ZX(Y){if(!Y)return[];let Z=Y.headers;if(Z.getSetCookie)return Z.getSetCookie();let X=Y.headers.get("set-cookie");return X?[X]:[]}function LX(Y,Z){let X=new Headers;Y.headers.forEach((N,S)=>{if(S.toLowerCase()!=="set-cookie")X.set(S,N)});for(let N of Z)X.append("Set-Cookie",N);return new Response(Y.body,{status:Y.status,statusText:Y.statusText,headers:X})}var q="EnterpriseStandard instance is required. Create one with enterpriseStandard(source, config) and pass it to this function.";async function uX(Y,Z){return D(Z,q),Z.sso?.getUser(Y)}async function JX(Y,Z){D(Z,q);let X=Z.logger??r;X.debug?.("getUser called",{hasInstance:!0,hasSso:!!Z.sso,hasCiam:!!Z.ciam});let N=await Z.sso?.getUser(Y);if(N)return X.debug?.("Found SSO user",{email:N.email}),N;X.debug?.("No SSO user, trying CIAM");let S=await Z.ciam?.getUser(Y);return X.debug?.("CIAM user result",{email:S?.email??void 0}),S}async function lX(Y,Z){let X=await JX(Y,Z);if(X)return X;throw new Response("Unauthorized",{status:401,statusText:"Unauthorized"})}async function nX(Y,Z){D(Z,q);let X=Z.sso;if(!X)return C();return X.initiateLogin(Y)}async function tX(Y,Z){D(Z,q);let X=Z.sso;if(!X)return C();return X.callbackHandler(Y)}async function iX(Y,Z){D(Z,q);let{sso:X,ciam:N}=Z;if(!X&&!N)return C("Logout Unavailable");let S=X?await X.logout(Y,{landingUrl:"/"}):void 0,Q=N?await N.logout(Y):void 0,$=S??Q;if(!$)return C("Logout Unavailable");let M=[...ZX(S),...ZX(Q)];return LX($,M)}async function aX(Y,Z){D(Z,q);let{sso:X,ciam:N}=Z;if(!X&&!N)return C("Back-Channel Logout Unavailable");let S=Y.clone(),Q=Y.clone(),$=X?await X.logoutBackChannel(S):void 0;if($?.status===200)return $;let M=N?await N.logoutBackChannel(Q):void 0;if(M)return M;return $??C("Back-Channel Logout Unavailable")}var c;function rX(Y){c=Y}function EX(Y){if(OX(Y.configSource))return Y.configSource;if(!c)throw Error("Tenant config hydration is not registered. Import @enterprisestandard/server before using tenant.config().");return c(Y.configSource)}function sX(Y){let Z=Y.configSource;return{...Y,config:()=>EX({configSource:Z})}}function OX(Y){let Z=Y;return typeof Y==="object"&&Y!==null&&typeof Z.load==="function"&&typeof Z.subscribe==="function"}
12
- export{jX as a,VX as b,i as c,a as d,D as e,o as f,HX as g,QX as h,PX as i,TX as j,MX as k,IX as l,r as m,yX as n,RX as o,bX as p,CX as q,XX as r,YX as s,kX as t,gX as u,pX as v,mX as w,dX as x,cX as y,uX as z,JX as A,lX as B,nX as C,tX as D,iX as E,aX as F,rX as G,EX as H,sX as I};