@enterprisestandard/core 0.0.9 → 0.0.11
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
|
@@ -89,6 +89,22 @@ interface UserListOptions {
|
|
|
89
89
|
/** Sort order (applied in array order). */
|
|
90
90
|
sort?: UserSortOptions[];
|
|
91
91
|
}
|
|
92
|
+
/** Allowed sort fields for tenants (no config). */
|
|
93
|
+
type TenantSortField = "tenantId" | "companyId" | "companyName" | "environmentType" | "email" | "webhookUrl" | "callbackUrl" | "tenantUrl" | "status" | "error" | "createdAt" | "updatedAt";
|
|
94
|
+
/** Single sort option for tenant list. */
|
|
95
|
+
interface TenantSortOptions {
|
|
96
|
+
field: TenantSortField;
|
|
97
|
+
direction: SortDirection;
|
|
98
|
+
}
|
|
99
|
+
/** Options for TenantStore.list() and getByCompanyId(). */
|
|
100
|
+
interface TenantListOptions {
|
|
101
|
+
/** 0-based index of first item. Default 0. */
|
|
102
|
+
start?: number;
|
|
103
|
+
/** Max items to return. Omitted = implementation-defined (InMemory: no limit). */
|
|
104
|
+
limit?: number;
|
|
105
|
+
/** Sort order (applied in array order). */
|
|
106
|
+
sort?: TenantSortOptions[];
|
|
107
|
+
}
|
|
92
108
|
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
93
109
|
/**
|
|
94
110
|
* SCIM 2.0 User Resource
|
|
@@ -2540,14 +2556,30 @@ type UpsertTenantResponse = {
|
|
|
2540
2556
|
tenantUrl?: string;
|
|
2541
2557
|
status: Exclude<TenantStatus, "action_required">;
|
|
2542
2558
|
error?: string;
|
|
2559
|
+
refs?: RefUrls[];
|
|
2543
2560
|
} | {
|
|
2544
2561
|
status: "action_required";
|
|
2545
2562
|
actionUrl: string;
|
|
2546
2563
|
requestToken: string;
|
|
2547
2564
|
expiresAt: string;
|
|
2565
|
+
refs?: RefUrls[];
|
|
2548
2566
|
};
|
|
2549
2567
|
type CreateTenantRequest = UpsertTenantRequest;
|
|
2550
2568
|
type CreateTenantResponse = UpsertTenantResponse;
|
|
2569
|
+
/**
|
|
2570
|
+
* The audience of the reference URL.
|
|
2571
|
+
* - 'human' for human-readable documentation such as user guides, documentation, etc.
|
|
2572
|
+
* - 'ai' for AI-generated reference such as llms.txt, AI-optimized markdown, etc.
|
|
2573
|
+
* - 'spec' for specifications and code-gen ready docs such as OpenAPI, GraphQL, etc.
|
|
2574
|
+
*/
|
|
2575
|
+
type Audience = "human" | "ai" | "spec";
|
|
2576
|
+
interface RefUrls {
|
|
2577
|
+
audience: Audience;
|
|
2578
|
+
url: string;
|
|
2579
|
+
description: string;
|
|
2580
|
+
createdAt: Date;
|
|
2581
|
+
updatedAt: Date;
|
|
2582
|
+
}
|
|
2551
2583
|
interface TenantWebhookPayload {
|
|
2552
2584
|
tenantId: string;
|
|
2553
2585
|
companyId: string;
|
|
@@ -2647,12 +2679,14 @@ type StoredTenant<TExtended extends object = Record<string, never>> = {
|
|
|
2647
2679
|
} & TExtended;
|
|
2648
2680
|
interface TenantStore<TExtended extends object = Record<string, never>> {
|
|
2649
2681
|
get(tenantId: string): Promise<StoredTenant<TExtended> | null>;
|
|
2682
|
+
list(options?: TenantListOptions): Promise<ListResult<StoredTenant<TExtended>>>;
|
|
2650
2683
|
upsert(tenant: Omit<StoredTenant<TExtended>, "config" | "status" | "createdAt" | "updatedAt"> & Partial<Pick<StoredTenant<TExtended>, "status" | "createdAt" | "updatedAt">>): Promise<StoredTenant<TExtended>>;
|
|
2651
2684
|
delete(tenantId: string): Promise<void>;
|
|
2652
2685
|
}
|
|
2653
2686
|
declare class InMemoryTenantStore<TExtended extends object = Record<string, never>> implements TenantStore<TExtended> {
|
|
2654
2687
|
private tenants;
|
|
2655
2688
|
get(tenantId: string): Promise<StoredTenant<TExtended> | null>;
|
|
2689
|
+
list(options?: TenantListOptions): Promise<ListResult<StoredTenant<TExtended>>>;
|
|
2656
2690
|
upsert(tenant: Omit<StoredTenant<TExtended>, "config" | "status" | "createdAt" | "updatedAt"> & Partial<Pick<StoredTenant<TExtended>, "status" | "createdAt" | "updatedAt">>): Promise<StoredTenant<TExtended>>;
|
|
2657
2691
|
delete(tenantId: string): Promise<void>;
|
|
2658
2692
|
}
|
|
@@ -2857,4 +2891,4 @@ declare function parseJsonc<T>(content: string): T;
|
|
|
2857
2891
|
* @returns A promise that resolves when the service is ready.
|
|
2858
2892
|
*/
|
|
2859
2893
|
declare function waitOn(url: string, pingInterval?: number, warnInterval?: number, timeout?: number): Promise<void>;
|
|
2860
|
-
export { workloadTokenResponseSchema, withValidate, waitOn, version, validationFailureResponse, userSchema, tokenResponseSchema, stripJsonComments, silentLogger, setActiveSession, serializeESConfig, sendTenantWebhook, parseJsonc, oidcCallbackSchema, must, mergeConfig, list, jwtAssertionClaimsSchema, infoLogger, idTokenClaimsSchema, groupResourceSchema, getActiveSession, findTenantFromStateParam, defaultLogger, decodeUser, debugLogger, consoleLogger, claimsToUser, X509Certificate, WorkloadValidators, WorkloadTokenStore, WorkloadTokenResponse, WorkloadIncomingOutgoing, WorkloadIdentity, WorkloadConfigMap, WorkloadConfig, WorkloadClient, Workload, VaultSecretsConfig, ValidateResult, UsersInboundHandlerConfig, UserStore, UserSortOptions, UserSortField, UserListOptions, User2 as User, UpsertTenantResponse, UpsertTenantRequest, TokenValidationResult, TokenResponse, TenantWebhookPayload, TenantValidators, TenantStore, TenantStatus, TenantSecretsConfig, TenantRequestError, TenantConfigEnv, StoredUser, 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, MetaData, MagicLinkStore, MagicLink, LoginConfig, Logger, ListResult, LfvSecretsConfig, JwtBearerWorkloadConfig, JWTAssertionClaims, 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, CreateUserOptions, CreateTenantResponse, CreateTenantRequest, CreateGroupOptions, ConfigSourceType, ConfigSource, ClientCredentialsWorkloadConfig, CachedWorkloadToken, CIAMValidators, CIAMConfigFromCode, CIAMConfig, CIAM, BaseUser, AzureSecretsConfig, AwsSecretsConfig, AwsAuthMethod, Address };
|
|
2894
|
+
export { workloadTokenResponseSchema, withValidate, waitOn, version, validationFailureResponse, userSchema, tokenResponseSchema, stripJsonComments, silentLogger, setActiveSession, serializeESConfig, sendTenantWebhook, parseJsonc, oidcCallbackSchema, must, mergeConfig, list, jwtAssertionClaimsSchema, infoLogger, idTokenClaimsSchema, groupResourceSchema, getActiveSession, findTenantFromStateParam, defaultLogger, decodeUser, debugLogger, consoleLogger, claimsToUser, X509Certificate, WorkloadValidators, WorkloadTokenStore, WorkloadTokenResponse, WorkloadIncomingOutgoing, WorkloadIdentity, WorkloadConfigMap, WorkloadConfig, WorkloadClient, Workload, VaultSecretsConfig, ValidateResult, UsersInboundHandlerConfig, UserStore, UserSortOptions, UserSortField, UserListOptions, User2 as User, UpsertTenantResponse, UpsertTenantRequest, TokenValidationResult, TokenResponse, TenantWebhookPayload, TenantValidators, TenantStore, TenantStatus, TenantSortOptions, TenantSortField, TenantSecretsConfig, TenantRequestError, TenantListOptions, TenantConfigEnv, StoredUser, 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, MetaData, MagicLinkStore, MagicLink, LoginConfig, Logger, ListResult, LfvSecretsConfig, JwtBearerWorkloadConfig, JWTAssertionClaims, 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, CreateUserOptions, CreateTenantResponse, CreateTenantRequest, CreateGroupOptions, ConfigSourceType, ConfigSource, ClientCredentialsWorkloadConfig, CachedWorkloadToken, CIAMValidators, CIAMConfigFromCode, CIAMConfig, CIAM, BaseUser, AzureSecretsConfig, AwsSecretsConfig, AwsAuthMethod, Address };
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as j,b as S,c as P,d as p,e as g,f as b,g as h,h as m,i as d,j as o,k as n,l as v,m as r,n as l,o as t,p as i,q as u,t as a,u as s,v as e}from"./shared/core-q2xp5jrk.js";var W="0.0.9";var B=["sessionStore","userStore","groupStore","tokenStore","magicLinkStore"];function _(H){if(H===null||typeof H!=="object")return H;let C={};for(let[D,x]of Object.entries(H)){if(B.includes(D)||D==="validators")continue;C[D]=x!==null&&typeof x==="object"&&!Array.isArray(x)&&Object.getPrototypeOf(x)===Object.prototype?_(x):x}return C}function E(H){return _(H)}function I(H,C,D,x){let J=C.length,$=x??H,Q=$>0?Math.floor(D/$)+1:1,Z=$>0?Math.ceil(H/$):0;return{total:H,count:J,items:C,size:$,page:Q,pages:Z}}class Y extends Error{constructor(H,C){super(H,C);this.name="TenantRequestError",Object.setPrototypeOf(this,Y.prototype)}}class M{tenants=new Map;async get(H){return this.tenants.get(H)??null}async upsert(H){let C=new Date,D=this.tenants.get(H.tenantId),x={...D??{},...H,status:H.status??D?.status??"completed",createdAt:H.createdAt??D?.createdAt??C,updatedAt:H.updatedAt??C};return this.tenants.set(x.tenantId,x),x}async delete(H){this.tenants.delete(H)}}function K(H,C,D){return(async()=>{try{let x=await fetch(H,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(C)});if(!x.ok)D.error(`Failed to send webhook update: ${x.status} ${x.statusText}`)}catch(x){D.error("Failed to send webhook update:",x)}})()}async function R(H,C,D){return K(H,C,D)}function X(H,C,D,x,J){if(H===void 0||H===null){if(D)x.push({message:`${C} is required`,path:J});return}if(typeof H!=="string"){x.push({message:`${C} must be a string`,path:J});return}return H}function L(H,C,D,x){if(H===void 0||H===null)return;if(typeof H!=="boolean"){D.push({message:`${C} must be a boolean`,path:x});return}return H}function z(H,C,D){if(H===void 0||H===null)return;if(typeof H!=="object"||H===null){C.push({message:"name must be an object",path:D});return}let x=H,J={};return J.formatted=X(x.formatted,"formatted",!1,C,[...D,"formatted"]),J.familyName=X(x.familyName,"familyName",!1,C,[...D,"familyName"]),J.givenName=X(x.givenName,"givenName",!1,C,[...D,"givenName"]),J.middleName=X(x.middleName,"middleName",!1,C,[...D,"middleName"]),J.honorificPrefix=X(x.honorificPrefix,"honorificPrefix",!1,C,[...D,"honorificPrefix"]),J.honorificSuffix=X(x.honorificSuffix,"honorificSuffix",!1,C,[...D,"honorificSuffix"]),J}function U(H,C,D){if(H===void 0||H===null)return;if(!Array.isArray(H)){C.push({message:"emails must be an array",path:D});return}let x=[];for(let J=0;J<H.length;J++){let $=H[J],Q=[...D,J];if(typeof $!=="object"||$===null){C.push({message:"email must be an object",path:Q});continue}let Z=$,A=X(Z.value,"value",!0,C,[...Q,"value"]);if(A)x.push({value:A,display:X(Z.display,"display",!1,C,[...Q,"display"]),type:X(Z.type,"type",!1,C,[...Q,"type"]),primary:L(Z.primary,"primary",C,[...Q,"primary"])})}return x.length>0?x:void 0}function q(H,C,D){if(H===void 0||H===null)return;if(!Array.isArray(H)){C.push({message:"phoneNumbers must be an array",path:D});return}let x=[];for(let J=0;J<H.length;J++){let $=H[J],Q=[...D,J];if(typeof $!=="object"||$===null){C.push({message:"phoneNumber must be an object",path:Q});continue}let Z=$,A=X(Z.value,"value",!0,C,[...Q,"value"]);if(A)x.push({value:A,display:X(Z.display,"display",!1,C,[...Q,"display"]),type:X(Z.type,"type",!1,C,[...Q,"type"]),primary:L(Z.primary,"primary",C,[...Q,"primary"])})}return x.length>0?x:void 0}function w(H,C,D){if(H===void 0||H===null)return;if(!Array.isArray(H)){C.push({message:"addresses must be an array",path:D});return}let x=[];for(let J=0;J<H.length;J++){let $=H[J],Q=[...D,J];if(typeof $!=="object"||$===null){C.push({message:"address must be an object",path:Q});continue}let Z=$;x.push({formatted:X(Z.formatted,"formatted",!1,C,[...Q,"formatted"]),streetAddress:X(Z.streetAddress,"streetAddress",!1,C,[...Q,"streetAddress"]),locality:X(Z.locality,"locality",!1,C,[...Q,"locality"]),region:X(Z.region,"region",!1,C,[...Q,"region"]),postalCode:X(Z.postalCode,"postalCode",!1,C,[...Q,"postalCode"]),country:X(Z.country,"country",!1,C,[...Q,"country"]),type:X(Z.type,"type",!1,C,[...Q,"type"]),primary:L(Z.primary,"primary",C,[...Q,"primary"])})}return x.length>0?x:void 0}function T(H,C,D){if(H===void 0||H===null)return;if(!Array.isArray(H)){C.push({message:"groups must be an array",path:D});return}let x=[];for(let J=0;J<H.length;J++){let $=H[J],Q=[...D,J];if(typeof $!=="object"||$===null){C.push({message:"group must be an object",path:Q});continue}let Z=$,A=X(Z.value,"value",!0,C,[...Q,"value"]);if(A)x.push({value:A,$ref:X(Z.$ref,"$ref",!1,C,[...Q,"$ref"]),display:X(Z.display,"display",!1,C,[...Q,"display"]),type:X(Z.type,"type",!1,C,[...Q,"type"])})}return x.length>0?x:void 0}function V(H,C,D){if(H===void 0||H===null)return;if(!Array.isArray(H)){C.push({message:"roles must be an array",path:D});return}let x=[];for(let J=0;J<H.length;J++){let $=H[J],Q=[...D,J];if(typeof $!=="object"||$===null){C.push({message:"role must be an object",path:Q});continue}let Z=$,A=X(Z.value,"value",!0,C,[...Q,"value"]);if(A)x.push({value:A,display:X(Z.display,"display",!1,C,[...Q,"display"]),type:X(Z.type,"type",!1,C,[...Q,"type"]),primary:L(Z.primary,"primary",C,[...Q,"primary"])})}return x.length>0?x:void 0}function k(H,C,D){if(H===void 0||H===null)return;if(typeof H!=="object"||H===null){C.push({message:"Enterprise User extension must be an object",path:D});return}let x=H,J={};if(J.employeeNumber=X(x.employeeNumber,"employeeNumber",!1,C,[...D,"employeeNumber"]),J.costCenter=X(x.costCenter,"costCenter",!1,C,[...D,"costCenter"]),J.organization=X(x.organization,"organization",!1,C,[...D,"organization"]),J.division=X(x.division,"division",!1,C,[...D,"division"]),J.department=X(x.department,"department",!1,C,[...D,"department"]),x.manager!==void 0&&x.manager!==null)if(typeof x.manager!=="object"||x.manager===null)C.push({message:"manager must be an object",path:[...D,"manager"]});else{let $=x.manager;J.manager={value:X($.value,"value",!1,C,[...D,"manager","value"]),$ref:X($.$ref,"$ref",!1,C,[...D,"manager","$ref"]),displayName:X($.displayName,"displayName",!1,C,[...D,"manager","displayName"])}}return J}function y(H){return{"~standard":{version:1,vendor:H,validate:(C)=>{if(typeof C!=="object"||C===null)return{issues:[{message:"Expected an object"}]};let D=C,x=[],J={},$=X(D.userName,"userName",!0,x,["userName"]);if(!$)return{issues:x};J.userName=$,J.id=X(D.id,"id",!1,x,["id"]),J.externalId=X(D.externalId,"externalId",!1,x,["externalId"]),J.displayName=X(D.displayName,"displayName",!1,x,["displayName"]),J.nickName=X(D.nickName,"nickName",!1,x,["nickName"]),J.profileUrl=X(D.profileUrl,"profileUrl",!1,x,["profileUrl"]),J.title=X(D.title,"title",!1,x,["title"]),J.userType=X(D.userType,"userType",!1,x,["userType"]),J.preferredLanguage=X(D.preferredLanguage,"preferredLanguage",!1,x,["preferredLanguage"]),J.locale=X(D.locale,"locale",!1,x,["locale"]),J.timezone=X(D.timezone,"timezone",!1,x,["timezone"]),J.password=X(D.password,"password",!1,x,["password"]),J.active=L(D.active,"active",x,["active"]),J.name=z(D.name,x,["name"]),J.emails=U(D.emails,x,["emails"]),J.phoneNumbers=q(D.phoneNumbers,x,["phoneNumbers"]),J.addresses=w(D.addresses,x,["addresses"]),J.groups=T(D.groups,x,["groups"]),J.roles=V(D.roles,x,["roles"]);let Q="urn:ietf:params:scim:schemas:extension:enterprise:2.0:User";if(D[Q]!==void 0)J[Q]=k(D[Q],x,[Q]);if(D.schemas!==void 0)if(Array.isArray(D.schemas))J.schemas=D.schemas.filter((Z)=>typeof Z==="string");else x.push({message:"schemas must be an array",path:["schemas"]});if(D.meta!==void 0)if(typeof D.meta==="object"&&D.meta!==null){let Z=D.meta;J.meta={resourceType:typeof Z.resourceType==="string"?Z.resourceType:void 0,created:typeof Z.created==="string"?Z.created:void 0,lastModified:typeof Z.lastModified==="string"?Z.lastModified:void 0,location:typeof Z.location==="string"?Z.location:void 0,version:typeof Z.version==="string"?Z.version:void 0}}else x.push({message:"meta must be an object",path:["meta"]});if(x.length>0)return{issues:x};return{value:J}}}}}function N(H,C,D){if(H===void 0||H===null)return;if(!Array.isArray(H)){C.push({message:"members must be an array",path:D});return}let x=[];for(let J=0;J<H.length;J++){let $=H[J],Q=[...D,J];if(typeof $!=="object"||$===null){C.push({message:"member must be an object",path:Q});continue}let Z=$,A=X(Z.value,"value",!0,C,[...Q,"value"]);if(A){let G=X(Z.type,"type",!1,C,[...Q,"type"]);x.push({value:A,$ref:X(Z.$ref,"$ref",!1,C,[...Q,"$ref"]),display:X(Z.display,"display",!1,C,[...Q,"display"]),type:G==="User"||G==="Group"?G:void 0})}}return x.length>0?x:void 0}function c(H){return{"~standard":{version:1,vendor:H,validate:(C)=>{if(typeof C!=="object"||C===null)return{issues:[{message:"Expected an object"}]};let D=C,x=[],J={},$=X(D.displayName,"displayName",!0,x,["displayName"]);if(!$)return{issues:x};if(J.displayName=$,J.id=X(D.id,"id",!1,x,["id"]),J.externalId=X(D.externalId,"externalId",!1,x,["externalId"]),J.members=N(D.members,x,["members"]),D.schemas!==void 0)if(Array.isArray(D.schemas))J.schemas=D.schemas.filter((Q)=>typeof Q==="string");else x.push({message:"schemas must be an array",path:["schemas"]});if(D.meta!==void 0)if(typeof D.meta==="object"&&D.meta!==null){let Q=D.meta;J.meta={resourceType:typeof Q.resourceType==="string"?Q.resourceType:void 0,created:typeof Q.created==="string"?Q.created:void 0,lastModified:typeof Q.lastModified==="string"?Q.lastModified:void 0,location:typeof Q.location==="string"?Q.location:void 0,version:typeof Q.version==="string"?Q.version:void 0}}else x.push({message:"meta must be an object",path:["meta"]});if(x.length>0)return{issues:x};return{value:J}}}}}function f(H){return{"~standard":{version:1,vendor:H,validate:(C)=>{if(typeof C!=="object"||C===null)return{issues:[{message:"Expected an object"}]};let D=C,x=[],J={...D},$=["iss","sub"];for(let A of $)if(A in D){if(typeof D[A]!=="string")x.push({message:`${A} must be a string`,path:[A]})}else x.push({message:`${A} is required`,path:[A]});if("aud"in D&&D.aud!==void 0){let A=D.aud;if(typeof A!=="string"&&!Array.isArray(A))x.push({message:"aud must be a string or array of strings",path:["aud"]});else if(Array.isArray(A)&&!A.every((G)=>typeof G==="string"))x.push({message:"aud array must contain only strings",path:["aud"]})}let Q=["jti","scope"];for(let A of Q)if(A in D&&D[A]!==void 0){if(typeof D[A]!=="string")x.push({message:`${A} must be a string`,path:[A]})}let Z=["exp","iat"];for(let A of Z)if(A in D){if(typeof D[A]!=="number")x.push({message:`${A} must be a number`,path:[A]})}else x.push({message:`${A} is required`,path:[A]});if(x.length>0)return{issues:x};return{value:J}}}}}function O(H){return{"~standard":{version:1,vendor:H,validate:(C)=>{if(typeof C!=="object"||C===null)return{issues:[{message:"Expected an object"}]};let D=C,x=[],J={};if("access_token"in D)if(typeof D.access_token==="string")J.access_token=D.access_token;else x.push({message:"access_token must be a string",path:["access_token"]});else x.push({message:"access_token is required",path:["access_token"]});if("token_type"in D)if(typeof D.token_type==="string")J.token_type=D.token_type;else x.push({message:"token_type must be a string",path:["token_type"]});else x.push({message:"token_type is required",path:["token_type"]});if("scope"in D)if(typeof D.scope==="string"||D.scope===void 0)J.scope=D.scope;else x.push({message:"scope must be a string",path:["scope"]});if("refresh_token"in D)if(typeof D.refresh_token==="string"||D.refresh_token===void 0)J.refresh_token=D.refresh_token;else x.push({message:"refresh_token must be a string",path:["refresh_token"]});if("expires"in D)if(typeof D.expires==="string"||D.expires===void 0)J.expires=D.expires;else x.push({message:"expires must be a string",path:["expires"]});if("expires_in"in D)if(typeof D.expires_in==="number"||D.expires_in===void 0)J.expires_in=D.expires_in;else x.push({message:"expires_in must be a number",path:["expires_in"]});if(x.length>0)return{issues:x};return{value:J}}}}}export{O as workloadTokenResponseSchema,p as withValidate,o as waitOn,W as version,b as validationFailureResponse,y as userSchema,S as tokenResponseSchema,m as stripJsonComments,l as silentLogger,s as setActiveSession,E as serializeESConfig,R as sendTenantWebhook,d as parseJsonc,j as oidcCallbackSchema,g as must,h as mergeConfig,I as list,f as jwtAssertionClaimsSchema,t as infoLogger,P as idTokenClaimsSchema,c as groupResourceSchema,a as getActiveSession,e as findTenantFromStateParam,r as defaultLogger,v as decodeUser,i as debugLogger,u as consoleLogger,n as claimsToUser,Y as TenantRequestError,M as InMemoryTenantStore};
|
|
1
|
+
import{a as m,b,c as d,d as v,e as n,f as o,g as r,h as l,i as t,j as u,k as i,l as a,m as s,n as e,o as D0,p as x0,q as C0,t as H0,u as J0,v as Q0}from"./shared/core-3rxwxw02.js";var E="0.0.11";var q=["sessionStore","userStore","groupStore","tokenStore","magicLinkStore"];function W(H){if(H===null||typeof H!=="object")return H;let C={};for(let[D,x]of Object.entries(H)){if(q.includes(D)||D==="validators")continue;C[D]=x!==null&&typeof x==="object"&&!Array.isArray(x)&&Object.getPrototypeOf(x)===Object.prototype?W(x):x}return C}function w(H){return W(H)}function _(H,C,D,x){let J=C.length,$=x??H,Q=$>0?Math.floor(D/$)+1:1,Z=$>0?Math.ceil(H/$):0;return{total:H,count:J,items:C,size:$,page:Q,pages:Z}}class M extends Error{constructor(H,C){super(H,C);this.name="TenantRequestError",Object.setPrototypeOf(this,M.prototype)}}class B{tenants=new Map;async get(H){return this.tenants.get(H)??null}async list(H){let C=Array.from(this.tenants.values()),D=Math.max(0,H?.start??0),x=H?.limit,J=H?.sort;if(J?.length)C=[...C].sort((A,G)=>{for(let{field:F,direction:I}of J){let K=A[F],R=G[F],Y=T(K,R);if(Y!==0)return I==="desc"?-Y:Y}return 0});let $=C.length,Q=x!=null?D+x:void 0,Z=C.slice(D,Q);return _($,Z,D,x)}async upsert(H){let C=new Date,D=this.tenants.get(H.tenantId),x={...D??{},...H,status:H.status??D?.status??"completed",createdAt:H.createdAt??D?.createdAt??C,updatedAt:H.updatedAt??C};return this.tenants.set(x.tenantId,x),x}async delete(H){this.tenants.delete(H)}}function T(H,C){let D=H===void 0||H===null,x=C===void 0||C===null;if(D&&x)return 0;if(D)return 1;if(x)return-1;if(H instanceof Date&&C instanceof Date)return H.getTime()-C.getTime();let J=String(H),$=String(C);return J.localeCompare($)}function U(H,C,D){return(async()=>{try{let x=await fetch(H,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(C)});if(!x.ok)D.error(`Failed to send webhook update: ${x.status} ${x.statusText}`)}catch(x){D.error("Failed to send webhook update:",x)}})()}async function V(H,C,D){return U(H,C,D)}function X(H,C,D,x,J){if(H===void 0||H===null){if(D)x.push({message:`${C} is required`,path:J});return}if(typeof H!=="string"){x.push({message:`${C} must be a string`,path:J});return}return H}function L(H,C,D,x){if(H===void 0||H===null)return;if(typeof H!=="boolean"){D.push({message:`${C} must be a boolean`,path:x});return}return H}function k(H,C,D){if(H===void 0||H===null)return;if(typeof H!=="object"||H===null){C.push({message:"name must be an object",path:D});return}let x=H,J={};return J.formatted=X(x.formatted,"formatted",!1,C,[...D,"formatted"]),J.familyName=X(x.familyName,"familyName",!1,C,[...D,"familyName"]),J.givenName=X(x.givenName,"givenName",!1,C,[...D,"givenName"]),J.middleName=X(x.middleName,"middleName",!1,C,[...D,"middleName"]),J.honorificPrefix=X(x.honorificPrefix,"honorificPrefix",!1,C,[...D,"honorificPrefix"]),J.honorificSuffix=X(x.honorificSuffix,"honorificSuffix",!1,C,[...D,"honorificSuffix"]),J}function y(H,C,D){if(H===void 0||H===null)return;if(!Array.isArray(H)){C.push({message:"emails must be an array",path:D});return}let x=[];for(let J=0;J<H.length;J++){let $=H[J],Q=[...D,J];if(typeof $!=="object"||$===null){C.push({message:"email must be an object",path:Q});continue}let Z=$,A=X(Z.value,"value",!0,C,[...Q,"value"]);if(A)x.push({value:A,display:X(Z.display,"display",!1,C,[...Q,"display"]),type:X(Z.type,"type",!1,C,[...Q,"type"]),primary:L(Z.primary,"primary",C,[...Q,"primary"])})}return x.length>0?x:void 0}function N(H,C,D){if(H===void 0||H===null)return;if(!Array.isArray(H)){C.push({message:"phoneNumbers must be an array",path:D});return}let x=[];for(let J=0;J<H.length;J++){let $=H[J],Q=[...D,J];if(typeof $!=="object"||$===null){C.push({message:"phoneNumber must be an object",path:Q});continue}let Z=$,A=X(Z.value,"value",!0,C,[...Q,"value"]);if(A)x.push({value:A,display:X(Z.display,"display",!1,C,[...Q,"display"]),type:X(Z.type,"type",!1,C,[...Q,"type"]),primary:L(Z.primary,"primary",C,[...Q,"primary"])})}return x.length>0?x:void 0}function c(H,C,D){if(H===void 0||H===null)return;if(!Array.isArray(H)){C.push({message:"addresses must be an array",path:D});return}let x=[];for(let J=0;J<H.length;J++){let $=H[J],Q=[...D,J];if(typeof $!=="object"||$===null){C.push({message:"address must be an object",path:Q});continue}let Z=$;x.push({formatted:X(Z.formatted,"formatted",!1,C,[...Q,"formatted"]),streetAddress:X(Z.streetAddress,"streetAddress",!1,C,[...Q,"streetAddress"]),locality:X(Z.locality,"locality",!1,C,[...Q,"locality"]),region:X(Z.region,"region",!1,C,[...Q,"region"]),postalCode:X(Z.postalCode,"postalCode",!1,C,[...Q,"postalCode"]),country:X(Z.country,"country",!1,C,[...Q,"country"]),type:X(Z.type,"type",!1,C,[...Q,"type"]),primary:L(Z.primary,"primary",C,[...Q,"primary"])})}return x.length>0?x:void 0}function f(H,C,D){if(H===void 0||H===null)return;if(!Array.isArray(H)){C.push({message:"groups must be an array",path:D});return}let x=[];for(let J=0;J<H.length;J++){let $=H[J],Q=[...D,J];if(typeof $!=="object"||$===null){C.push({message:"group must be an object",path:Q});continue}let Z=$,A=X(Z.value,"value",!0,C,[...Q,"value"]);if(A)x.push({value:A,$ref:X(Z.$ref,"$ref",!1,C,[...Q,"$ref"]),display:X(Z.display,"display",!1,C,[...Q,"display"]),type:X(Z.type,"type",!1,C,[...Q,"type"])})}return x.length>0?x:void 0}function O(H,C,D){if(H===void 0||H===null)return;if(!Array.isArray(H)){C.push({message:"roles must be an array",path:D});return}let x=[];for(let J=0;J<H.length;J++){let $=H[J],Q=[...D,J];if(typeof $!=="object"||$===null){C.push({message:"role must be an object",path:Q});continue}let Z=$,A=X(Z.value,"value",!0,C,[...Q,"value"]);if(A)x.push({value:A,display:X(Z.display,"display",!1,C,[...Q,"display"]),type:X(Z.type,"type",!1,C,[...Q,"type"]),primary:L(Z.primary,"primary",C,[...Q,"primary"])})}return x.length>0?x:void 0}function j(H,C,D){if(H===void 0||H===null)return;if(typeof H!=="object"||H===null){C.push({message:"Enterprise User extension must be an object",path:D});return}let x=H,J={};if(J.employeeNumber=X(x.employeeNumber,"employeeNumber",!1,C,[...D,"employeeNumber"]),J.costCenter=X(x.costCenter,"costCenter",!1,C,[...D,"costCenter"]),J.organization=X(x.organization,"organization",!1,C,[...D,"organization"]),J.division=X(x.division,"division",!1,C,[...D,"division"]),J.department=X(x.department,"department",!1,C,[...D,"department"]),x.manager!==void 0&&x.manager!==null)if(typeof x.manager!=="object"||x.manager===null)C.push({message:"manager must be an object",path:[...D,"manager"]});else{let $=x.manager;J.manager={value:X($.value,"value",!1,C,[...D,"manager","value"]),$ref:X($.$ref,"$ref",!1,C,[...D,"manager","$ref"]),displayName:X($.displayName,"displayName",!1,C,[...D,"manager","displayName"])}}return J}function S(H){return{"~standard":{version:1,vendor:H,validate:(C)=>{if(typeof C!=="object"||C===null)return{issues:[{message:"Expected an object"}]};let D=C,x=[],J={},$=X(D.userName,"userName",!0,x,["userName"]);if(!$)return{issues:x};J.userName=$,J.id=X(D.id,"id",!1,x,["id"]),J.externalId=X(D.externalId,"externalId",!1,x,["externalId"]),J.displayName=X(D.displayName,"displayName",!1,x,["displayName"]),J.nickName=X(D.nickName,"nickName",!1,x,["nickName"]),J.profileUrl=X(D.profileUrl,"profileUrl",!1,x,["profileUrl"]),J.title=X(D.title,"title",!1,x,["title"]),J.userType=X(D.userType,"userType",!1,x,["userType"]),J.preferredLanguage=X(D.preferredLanguage,"preferredLanguage",!1,x,["preferredLanguage"]),J.locale=X(D.locale,"locale",!1,x,["locale"]),J.timezone=X(D.timezone,"timezone",!1,x,["timezone"]),J.password=X(D.password,"password",!1,x,["password"]),J.active=L(D.active,"active",x,["active"]),J.name=k(D.name,x,["name"]),J.emails=y(D.emails,x,["emails"]),J.phoneNumbers=N(D.phoneNumbers,x,["phoneNumbers"]),J.addresses=c(D.addresses,x,["addresses"]),J.groups=f(D.groups,x,["groups"]),J.roles=O(D.roles,x,["roles"]);let Q="urn:ietf:params:scim:schemas:extension:enterprise:2.0:User";if(D[Q]!==void 0)J[Q]=j(D[Q],x,[Q]);if(D.schemas!==void 0)if(Array.isArray(D.schemas))J.schemas=D.schemas.filter((Z)=>typeof Z==="string");else x.push({message:"schemas must be an array",path:["schemas"]});if(D.meta!==void 0)if(typeof D.meta==="object"&&D.meta!==null){let Z=D.meta;J.meta={resourceType:typeof Z.resourceType==="string"?Z.resourceType:void 0,created:typeof Z.created==="string"?Z.created:void 0,lastModified:typeof Z.lastModified==="string"?Z.lastModified:void 0,location:typeof Z.location==="string"?Z.location:void 0,version:typeof Z.version==="string"?Z.version:void 0}}else x.push({message:"meta must be an object",path:["meta"]});if(x.length>0)return{issues:x};return{value:J}}}}}function P(H,C,D){if(H===void 0||H===null)return;if(!Array.isArray(H)){C.push({message:"members must be an array",path:D});return}let x=[];for(let J=0;J<H.length;J++){let $=H[J],Q=[...D,J];if(typeof $!=="object"||$===null){C.push({message:"member must be an object",path:Q});continue}let Z=$,A=X(Z.value,"value",!0,C,[...Q,"value"]);if(A){let G=X(Z.type,"type",!1,C,[...Q,"type"]);x.push({value:A,$ref:X(Z.$ref,"$ref",!1,C,[...Q,"$ref"]),display:X(Z.display,"display",!1,C,[...Q,"display"]),type:G==="User"||G==="Group"?G:void 0})}}return x.length>0?x:void 0}function g(H){return{"~standard":{version:1,vendor:H,validate:(C)=>{if(typeof C!=="object"||C===null)return{issues:[{message:"Expected an object"}]};let D=C,x=[],J={},$=X(D.displayName,"displayName",!0,x,["displayName"]);if(!$)return{issues:x};if(J.displayName=$,J.id=X(D.id,"id",!1,x,["id"]),J.externalId=X(D.externalId,"externalId",!1,x,["externalId"]),J.members=P(D.members,x,["members"]),D.schemas!==void 0)if(Array.isArray(D.schemas))J.schemas=D.schemas.filter((Q)=>typeof Q==="string");else x.push({message:"schemas must be an array",path:["schemas"]});if(D.meta!==void 0)if(typeof D.meta==="object"&&D.meta!==null){let Q=D.meta;J.meta={resourceType:typeof Q.resourceType==="string"?Q.resourceType:void 0,created:typeof Q.created==="string"?Q.created:void 0,lastModified:typeof Q.lastModified==="string"?Q.lastModified:void 0,location:typeof Q.location==="string"?Q.location:void 0,version:typeof Q.version==="string"?Q.version:void 0}}else x.push({message:"meta must be an object",path:["meta"]});if(x.length>0)return{issues:x};return{value:J}}}}}function p(H){return{"~standard":{version:1,vendor:H,validate:(C)=>{if(typeof C!=="object"||C===null)return{issues:[{message:"Expected an object"}]};let D=C,x=[],J={...D},$=["iss","sub"];for(let A of $)if(A in D){if(typeof D[A]!=="string")x.push({message:`${A} must be a string`,path:[A]})}else x.push({message:`${A} is required`,path:[A]});if("aud"in D&&D.aud!==void 0){let A=D.aud;if(typeof A!=="string"&&!Array.isArray(A))x.push({message:"aud must be a string or array of strings",path:["aud"]});else if(Array.isArray(A)&&!A.every((G)=>typeof G==="string"))x.push({message:"aud array must contain only strings",path:["aud"]})}let Q=["jti","scope"];for(let A of Q)if(A in D&&D[A]!==void 0){if(typeof D[A]!=="string")x.push({message:`${A} must be a string`,path:[A]})}let Z=["exp","iat"];for(let A of Z)if(A in D){if(typeof D[A]!=="number")x.push({message:`${A} must be a number`,path:[A]})}else x.push({message:`${A} is required`,path:[A]});if(x.length>0)return{issues:x};return{value:J}}}}}function h(H){return{"~standard":{version:1,vendor:H,validate:(C)=>{if(typeof C!=="object"||C===null)return{issues:[{message:"Expected an object"}]};let D=C,x=[],J={};if("access_token"in D)if(typeof D.access_token==="string")J.access_token=D.access_token;else x.push({message:"access_token must be a string",path:["access_token"]});else x.push({message:"access_token is required",path:["access_token"]});if("token_type"in D)if(typeof D.token_type==="string")J.token_type=D.token_type;else x.push({message:"token_type must be a string",path:["token_type"]});else x.push({message:"token_type is required",path:["token_type"]});if("scope"in D)if(typeof D.scope==="string"||D.scope===void 0)J.scope=D.scope;else x.push({message:"scope must be a string",path:["scope"]});if("refresh_token"in D)if(typeof D.refresh_token==="string"||D.refresh_token===void 0)J.refresh_token=D.refresh_token;else x.push({message:"refresh_token must be a string",path:["refresh_token"]});if("expires"in D)if(typeof D.expires==="string"||D.expires===void 0)J.expires=D.expires;else x.push({message:"expires must be a string",path:["expires"]});if("expires_in"in D)if(typeof D.expires_in==="number"||D.expires_in===void 0)J.expires_in=D.expires_in;else x.push({message:"expires_in must be a number",path:["expires_in"]});if(x.length>0)return{issues:x};return{value:J}}}}}export{h as workloadTokenResponseSchema,v as withValidate,u as waitOn,E as version,o as validationFailureResponse,S as userSchema,b as tokenResponseSchema,l as stripJsonComments,e as silentLogger,J0 as setActiveSession,w as serializeESConfig,V as sendTenantWebhook,t as parseJsonc,m as oidcCallbackSchema,n as must,r as mergeConfig,_ as list,p as jwtAssertionClaimsSchema,D0 as infoLogger,d as idTokenClaimsSchema,g as groupResourceSchema,H0 as getActiveSession,Q0 as findTenantFromStateParam,s as defaultLogger,a as decodeUser,x0 as debugLogger,C0 as consoleLogger,i as claimsToUser,M as TenantRequestError,B as InMemoryTenantStore};
|
package/dist/server.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{A as JM,B as LM,C as DM,D as jM,c as XM,d as YM,e,k as ZM,r as $M,s as HM,w as NM,x as VM,y as _M,z as GM}from"./shared/core-q2xp5jrk.js";function zM(O,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)),W=`${X}.${Z}`,_=await x(),S=await crypto.subtle.sign("HMAC",_,new TextEncoder().encode(W)),I=l(new Uint8Array(S));return`${W}.${I}`}async function k(M){let A=M.split(".");if(A.length!==3)throw Error("Invalid JWT");let[X,Z,W]=A,_=`${X}.${Z}`,S=await x(),I=new Uint8Array(t(W).split("").map((T)=>T.charCodeAt(0)));if(!await crypto.subtle.verify("HMAC",S,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 W=`${Y.cookiesPrefix}.${M}`,_=Z.split(";").find((C)=>C.trim().startsWith(`${W}=`));if(!_)return null;let S=_.indexOf("="),I=_.substring(S+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 '${W}':`,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 S=v(M);if(S){let I=await k(S.access);if(I.sid)await g().delete(I.sid)}}catch(S){console.warn("Failed to delete CIAM session:",S)}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 W=M.headers.get("accept");if(W?.includes("application/json")||W?.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(),W=new URLSearchParams(X).get("logout_token");if(!W)return new Response("Missing logout_token parameter",{status:400});let S=(await k(W)).sid;if(!S)return new Response("Invalid logout_token: missing sid claim",{status:400});return await g().delete(S),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 K(M){return M.id||M.email||`ciam-${M.userName}`}function V(M,A,X){return{sub:K(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 F(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"),S=_?parseInt(_,10):Y.magicLinkTtl??3600;if(Number.isNaN(S)||S<=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()+S*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 H(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 W=new Date(Date.now()+(Y.sessionTtl??86400)*1000),_=i(32),S=K(Z.user),I=V(Z.user,_,W),C=Q(S,_,W),u=z(I);try{let L={sid:_,sub:S,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,s=await Y.userStore.get(L);if(s||Y.enableJitUserProvisioning){let FM={...s??{},...u,id:L,createdAt:s?.createdAt??r,updatedAt:r,userType:s?.userType??"customer"};await Y.userStore.upsert(FM)}}}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,W)]})}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",W=Y.logoutBackChannelUrl||"/auth/logout/backchannel",_=new URL(M.url).pathname,S=(T)=>{if(!T)return;try{return new URL(T).pathname}catch{return T.startsWith("/")?T:`/${T}`}};if(S(A)===_&&M.method==="POST")return F(M);if(S(X)===_&&M.method==="GET")return H(M);if(S(Z)===_&&M.method==="GET")return p(M);if(S(W)===_&&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(O,D){return e(D,"EnterpriseStandard instance is required. Create one with enterpriseStandard(source, config) and pass it to this function."),D.ciam?.getUser(O)}function N(O,D,j){return new Response(JSON.stringify({schemas:["urn:ietf:params:scim:api:messages:2.0:Error"],status:String(O),scimType:j,detail:D}),{status:O,headers:{"Content-Type":"application/scim+json"}})}function MM(O,D){let j=D?.totalResults??O.length,h=D?.startIndex??1,q=D?.itemsPerPage??O.length;return new Response(JSON.stringify({schemas:["urn:ietf:params:scim:api:messages:2.0:ListResponse"],totalResults:j,startIndex:h,itemsPerPage:q,Resources:O}),{status:200,headers:{"Content-Type":"application/scim+json"}})}function d(O,D=200){return new Response(JSON.stringify(O),{status:D,headers:{"Content-Type":"application/scim+json"}})}function o(O){return{schemas:["urn:ietf:params:scim:schemas:core:2.0:Group"],id:O.id,externalId:O.externalId,displayName:O.displayName,members:O.members,meta:{resourceType:"Group",created:O.createdAt.toISOString(),lastModified:O.updatedAt.toISOString()}}}function AM(){return crypto.randomUUID()}function KM(O,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((K)=>K.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,O.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,O.group)}};let x;if(Y.groupStore){let B=Y.groupStore,G=async(K)=>{let V=U(),Q=K.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(K,V)=>{if(!await G(K))return N(401,"Authorization required");let z=new URL(K.url),F=V?.basePath??"/Groups",H=z.pathname;if(H.startsWith(F))H=H.substring(F.length);let M=H.match(/^\/([^/]+)$/)?.[1],A=K.method;try{if(M)switch(A){case"GET":return await v(M);case"PUT":return await b(K,M);case"PATCH":return await p(K,M);case"DELETE":return await y(M);default:return N(405,"Method not allowed")}else if(H===""||H==="/")switch(A){case"GET":return await P(K);case"POST":return await w(K);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(K)=>{let V=new URL(K.url),Q=V.searchParams.get("startIndex"),z=V.searchParams.get("count"),F=Q!=null?parseInt(Q,10):void 0,H=z!=null?parseInt(z,10):void 0,$=F!=null&&!Number.isNaN(F)?Math.max(0,F-1):0,M=H!=null&&!Number.isNaN(H)?H:void 0,A=await B.list({start:$,limit:M}),X=A.items.map(o);return MM(X,{totalResults:A.total,startIndex:$+1,itemsPerPage:A.count})},v=async(K)=>{let V=await B.get(K);if(!V)return N(404,`Group ${K} not found`,"invalidValue");return d(o(V))},w=async(K)=>{let V=await K.json(),Q=await O.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 F=new Date,H={id:AM(),displayName:z.displayName,externalId:z.externalId,members:z.members,createdAt:F,updatedAt:F};return await B.upsert(H),d(o(H),201)},b=async(K,V)=>{let Q=await B.get(V);if(!Q)return N(404,`Group ${V} not found`,"invalidValue");let z=await K.json(),F=await O.group["~standard"].validate(z);if(F.issues)return console.error("Group replacement validation failed:",F.issues),N(400,`Request validation failed: ${F.issues.map((M)=>M.message).join("; ")}`,"invalidValue");let H=F.value,$={...Q,displayName:H.displayName??Q.displayName,externalId:H.externalId,members:H.members,updatedAt:new Date};return await B.upsert($),d(o($))},p=async(K,V)=>{let Q=await B.get(V);if(!Q)return N(404,`Group ${V} not found`,"invalidValue");let F=(await K.json()).Operations??[],H={...Q};for(let $ of F)if($.op==="replace"&&$.path&&$.value!==void 0){if($.path==="displayName")H.displayName=$.value}else if($.op==="add"&&$.path&&$.value!==void 0){if($.path==="members"){let M=$.value;H.members=[...H.members??[],...M]}}else if($.op==="remove"&&$.path){if($.path.startsWith("members[")){let M=$.path.match(/members\[value eq "([^"]+)"\]/);if(M)H.members=(H.members??[]).filter((A)=>A.value!==M[1])}}return H.updatedAt=new Date,await B.upsert(H),d(o(H))},y=async(K)=>{if(!await B.get(K))return N(404,`Group ${K} not found`,"invalidValue");return await B.delete(K),new Response(null,{status:204})};x={handler:J}}let f;if(Y.userStore){let B=Y.userStore,G=async(Q)=>{let z=U(),F=Q.headers.get("Authorization");if(!F||!F.startsWith("Bearer "))return!1;try{let H=F.substring(7);return(await z.validateToken(H)).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,F=Q.emails?.find((A)=>A.primary)?.value||Q.emails?.[0]?.value,H=Q.name?`${Q.name.givenName||""} ${Q.name.familyName||""}`.trim():Q.displayName,$=Q.id||AM(),M=Q.userName||F||$;return{id:$,userName:M,name:H||Q.displayName||M,email:F||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:F||M,email_verified:!0,name:H||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 H=new URL(Q.url),$=z?.basePath??"/Users",M=H.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 K(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(W){return console.error("Users inbound handler error:",W),N(500,W instanceof Error?W.message:"Internal server error")}},w=async(Q)=>{let z=new URL(Q.url),F=z.searchParams.get("startIndex"),H=z.searchParams.get("count"),$=F!=null?parseInt(F,10):void 0,M=H!=null?parseInt(H,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}),W=Z.items.map(J);return MM(W,{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(),F=await O.user["~standard"].validate(z);if(F.issues)return console.error("User creation validation failed:",F.issues),N(400,`Request validation failed: ${F.issues.map((M)=>M.message).join("; ")}`,"invalidValue");let H=F.value;if(!H.userName&&!H.emails?.[0]?.value)return N(400,"userName or email is required","invalidValue");let $=P(H);return await B.upsert($),d(J($),201)},y=async(Q,z)=>{let F=await B.get(z);if(!F)return N(404,`User ${z} not found`,"invalidValue");let H=await Q.json(),$=await O.user["~standard"].validate(H);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=F.createdAt,A.updatedAt=new Date,await B.upsert(A),d(J(A))},K=async(Q,z)=>{let F=await B.get(z);if(!F)return N(404,`User ${z} not found`,"invalidValue");let $=(await Q.json()).Operations??[],M={...F};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((W)=>W.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((W)=>W.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 WM="@enterprisestandard/core",OM=YM(XM(WM));function QM(O){let D=O.replace(/-/g,"+").replace(/_/g,"/");return atob(D)}async function SM(O,D){let j=O.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 HM(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 OM.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{SM as verifyUser,NM as sso,jM as logoutBackChannel,DM as logout,JM as initiateLogin,KM as iam,_M as getSSOorCIAMUser,VM as getSSOUser,GM as getRequiredSSOorCIAMUser,BM as getCIAMUser,zM as ciam,LM as callback};
|
|
1
|
+
import{A as JM,B as LM,C as DM,D as jM,c as XM,d as YM,e,k as ZM,r as $M,s as HM,w as NM,x as VM,y as _M,z as GM}from"./shared/core-3rxwxw02.js";function zM(O,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)),W=`${X}.${Z}`,_=await x(),S=await crypto.subtle.sign("HMAC",_,new TextEncoder().encode(W)),I=l(new Uint8Array(S));return`${W}.${I}`}async function k(M){let A=M.split(".");if(A.length!==3)throw Error("Invalid JWT");let[X,Z,W]=A,_=`${X}.${Z}`,S=await x(),I=new Uint8Array(t(W).split("").map((T)=>T.charCodeAt(0)));if(!await crypto.subtle.verify("HMAC",S,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 W=`${Y.cookiesPrefix}.${M}`,_=Z.split(";").find((C)=>C.trim().startsWith(`${W}=`));if(!_)return null;let S=_.indexOf("="),I=_.substring(S+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 '${W}':`,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 S=v(M);if(S){let I=await k(S.access);if(I.sid)await g().delete(I.sid)}}catch(S){console.warn("Failed to delete CIAM session:",S)}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 W=M.headers.get("accept");if(W?.includes("application/json")||W?.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(),W=new URLSearchParams(X).get("logout_token");if(!W)return new Response("Missing logout_token parameter",{status:400});let S=(await k(W)).sid;if(!S)return new Response("Invalid logout_token: missing sid claim",{status:400});return await g().delete(S),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 K(M){return M.id||M.email||`ciam-${M.userName}`}function V(M,A,X){return{sub:K(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 F(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"),S=_?parseInt(_,10):Y.magicLinkTtl??3600;if(Number.isNaN(S)||S<=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()+S*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 H(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 W=new Date(Date.now()+(Y.sessionTtl??86400)*1000),_=i(32),S=K(Z.user),I=V(Z.user,_,W),C=Q(S,_,W),u=z(I);try{let L={sid:_,sub:S,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,s=await Y.userStore.get(L);if(s||Y.enableJitUserProvisioning){let FM={...s??{},...u,id:L,createdAt:s?.createdAt??r,updatedAt:r,userType:s?.userType??"customer"};await Y.userStore.upsert(FM)}}}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,W)]})}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",W=Y.logoutBackChannelUrl||"/auth/logout/backchannel",_=new URL(M.url).pathname,S=(T)=>{if(!T)return;try{return new URL(T).pathname}catch{return T.startsWith("/")?T:`/${T}`}};if(S(A)===_&&M.method==="POST")return F(M);if(S(X)===_&&M.method==="GET")return H(M);if(S(Z)===_&&M.method==="GET")return p(M);if(S(W)===_&&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(O,D){return e(D,"EnterpriseStandard instance is required. Create one with enterpriseStandard(source, config) and pass it to this function."),D.ciam?.getUser(O)}function N(O,D,j){return new Response(JSON.stringify({schemas:["urn:ietf:params:scim:api:messages:2.0:Error"],status:String(O),scimType:j,detail:D}),{status:O,headers:{"Content-Type":"application/scim+json"}})}function MM(O,D){let j=D?.totalResults??O.length,h=D?.startIndex??1,q=D?.itemsPerPage??O.length;return new Response(JSON.stringify({schemas:["urn:ietf:params:scim:api:messages:2.0:ListResponse"],totalResults:j,startIndex:h,itemsPerPage:q,Resources:O}),{status:200,headers:{"Content-Type":"application/scim+json"}})}function d(O,D=200){return new Response(JSON.stringify(O),{status:D,headers:{"Content-Type":"application/scim+json"}})}function o(O){return{schemas:["urn:ietf:params:scim:schemas:core:2.0:Group"],id:O.id,externalId:O.externalId,displayName:O.displayName,members:O.members,meta:{resourceType:"Group",created:O.createdAt.toISOString(),lastModified:O.updatedAt.toISOString()}}}function AM(){return crypto.randomUUID()}function KM(O,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((K)=>K.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,O.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,O.group)}};let x;if(Y.groupStore){let B=Y.groupStore,G=async(K)=>{let V=U(),Q=K.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(K,V)=>{if(!await G(K))return N(401,"Authorization required");let z=new URL(K.url),F=V?.basePath??"/Groups",H=z.pathname;if(H.startsWith(F))H=H.substring(F.length);let M=H.match(/^\/([^/]+)$/)?.[1],A=K.method;try{if(M)switch(A){case"GET":return await v(M);case"PUT":return await b(K,M);case"PATCH":return await p(K,M);case"DELETE":return await y(M);default:return N(405,"Method not allowed")}else if(H===""||H==="/")switch(A){case"GET":return await P(K);case"POST":return await w(K);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(K)=>{let V=new URL(K.url),Q=V.searchParams.get("startIndex"),z=V.searchParams.get("count"),F=Q!=null?parseInt(Q,10):void 0,H=z!=null?parseInt(z,10):void 0,$=F!=null&&!Number.isNaN(F)?Math.max(0,F-1):0,M=H!=null&&!Number.isNaN(H)?H:void 0,A=await B.list({start:$,limit:M}),X=A.items.map(o);return MM(X,{totalResults:A.total,startIndex:$+1,itemsPerPage:A.count})},v=async(K)=>{let V=await B.get(K);if(!V)return N(404,`Group ${K} not found`,"invalidValue");return d(o(V))},w=async(K)=>{let V=await K.json(),Q=await O.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 F=new Date,H={id:AM(),displayName:z.displayName,externalId:z.externalId,members:z.members,createdAt:F,updatedAt:F};return await B.upsert(H),d(o(H),201)},b=async(K,V)=>{let Q=await B.get(V);if(!Q)return N(404,`Group ${V} not found`,"invalidValue");let z=await K.json(),F=await O.group["~standard"].validate(z);if(F.issues)return console.error("Group replacement validation failed:",F.issues),N(400,`Request validation failed: ${F.issues.map((M)=>M.message).join("; ")}`,"invalidValue");let H=F.value,$={...Q,displayName:H.displayName??Q.displayName,externalId:H.externalId,members:H.members,updatedAt:new Date};return await B.upsert($),d(o($))},p=async(K,V)=>{let Q=await B.get(V);if(!Q)return N(404,`Group ${V} not found`,"invalidValue");let F=(await K.json()).Operations??[],H={...Q};for(let $ of F)if($.op==="replace"&&$.path&&$.value!==void 0){if($.path==="displayName")H.displayName=$.value}else if($.op==="add"&&$.path&&$.value!==void 0){if($.path==="members"){let M=$.value;H.members=[...H.members??[],...M]}}else if($.op==="remove"&&$.path){if($.path.startsWith("members[")){let M=$.path.match(/members\[value eq "([^"]+)"\]/);if(M)H.members=(H.members??[]).filter((A)=>A.value!==M[1])}}return H.updatedAt=new Date,await B.upsert(H),d(o(H))},y=async(K)=>{if(!await B.get(K))return N(404,`Group ${K} not found`,"invalidValue");return await B.delete(K),new Response(null,{status:204})};x={handler:J}}let f;if(Y.userStore){let B=Y.userStore,G=async(Q)=>{let z=U(),F=Q.headers.get("Authorization");if(!F||!F.startsWith("Bearer "))return!1;try{let H=F.substring(7);return(await z.validateToken(H)).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,F=Q.emails?.find((A)=>A.primary)?.value||Q.emails?.[0]?.value,H=Q.name?`${Q.name.givenName||""} ${Q.name.familyName||""}`.trim():Q.displayName,$=Q.id||AM(),M=Q.userName||F||$;return{id:$,userName:M,name:H||Q.displayName||M,email:F||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:F||M,email_verified:!0,name:H||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 H=new URL(Q.url),$=z?.basePath??"/Users",M=H.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 K(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(W){return console.error("Users inbound handler error:",W),N(500,W instanceof Error?W.message:"Internal server error")}},w=async(Q)=>{let z=new URL(Q.url),F=z.searchParams.get("startIndex"),H=z.searchParams.get("count"),$=F!=null?parseInt(F,10):void 0,M=H!=null?parseInt(H,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}),W=Z.items.map(J);return MM(W,{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(),F=await O.user["~standard"].validate(z);if(F.issues)return console.error("User creation validation failed:",F.issues),N(400,`Request validation failed: ${F.issues.map((M)=>M.message).join("; ")}`,"invalidValue");let H=F.value;if(!H.userName&&!H.emails?.[0]?.value)return N(400,"userName or email is required","invalidValue");let $=P(H);return await B.upsert($),d(J($),201)},y=async(Q,z)=>{let F=await B.get(z);if(!F)return N(404,`User ${z} not found`,"invalidValue");let H=await Q.json(),$=await O.user["~standard"].validate(H);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=F.createdAt,A.updatedAt=new Date,await B.upsert(A),d(J(A))},K=async(Q,z)=>{let F=await B.get(z);if(!F)return N(404,`User ${z} not found`,"invalidValue");let $=(await Q.json()).Operations??[],M={...F};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((W)=>W.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((W)=>W.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 WM="@enterprisestandard/core",OM=YM(XM(WM));function QM(O){let D=O.replace(/-/g,"+").replace(/_/g,"/");return atob(D)}async function SM(O,D){let j=O.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 HM(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 OM.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{SM as verifyUser,NM as sso,jM as logoutBackChannel,DM as logout,JM as initiateLogin,KM as iam,_M as getSSOorCIAMUser,VM as getSSOUser,GM as getRequiredSSOorCIAMUser,BM as getCIAMUser,zM as ciam,LM as callback};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
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,A=[],N={};if("code"in X)if(typeof X.code==="string")N.code=X.code;else A.push({message:"code must be a string",path:["code"]});else if(!("error"in X))A.push({message:"code is required",path:["code"]});if("state"in X)if(typeof X.state==="string"||X.state===void 0)N.state=X.state;else A.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)N.session_state=X.session_state;else A.push({message:"session_state must be a string",path:["session_state"]});if("error"in X){if(typeof X.error==="string")N.error=X.error;else A.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)N.error_description=X.error_description;else A.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)N.error_uri=X.error_uri;else A.push({message:"error_uri must be a string",path:["error_uri"]})}if("iss"in X)if(typeof X.iss==="string"||X.iss===void 0)N.iss=X.iss;else A.push({message:"iss must be a string",path:["iss"]});if(A.length>0)return{issues:A};return{value:N}}}}}function FX(Y){return{"~standard":{version:1,vendor:Y,validate:(Z)=>{if(typeof Z!=="object"||Z===null)return{issues:[{message:"Expected an object"}]};let X=Z,A=[],N={};if("access_token"in X)if(typeof X.access_token==="string")N.access_token=X.access_token;else A.push({message:"access_token must be a string",path:["access_token"]});else A.push({message:"access_token is required",path:["access_token"]});if("id_token"in X)if(typeof X.id_token==="string")N.id_token=X.id_token;else A.push({message:"id_token must be a string",path:["id_token"]});else A.push({message:"id_token is required",path:["id_token"]});if("token_type"in X)if(typeof X.token_type==="string")N.token_type=X.token_type;else A.push({message:"token_type must be a string",path:["token_type"]});else A.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)N.refresh_token=X.refresh_token;else A.push({message:"refresh_token must be a string",path:["refresh_token"]});if("scope"in X)if(typeof X.scope==="string"||X.scope===void 0)N.scope=X.scope;else A.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)N.session_state=X.session_state;else A.push({message:"session_state must be a string",path:["session_state"]});if("expires"in X)if(typeof X.expires==="string"||X.expires===void 0)N.expires=X.expires;else A.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)N.expires_in=X.expires_in;else A.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)N.refresh_expires_in=X.refresh_expires_in;else A.push({message:"refresh_expires_in must be a number",path:["refresh_expires_in"]});if(A.length>0)return{issues:A};return{value:N}}}}}function n(Y){return{"~standard":{version:1,vendor:Y,validate:(Z)=>{if(typeof Z!=="object"||Z===null)return{issues:[{message:"Expected an object"}]};let X=Z,A=[],N={...X},M=["iss","aud","sub","sid","name","email","preferred_username","picture"];for(let H of M)if(H in X&&X[H]!==void 0){if(typeof X[H]!=="string")A.push({message:`${H} must be a string`,path:[H]})}let $=["exp","iat"];for(let H of $)if(H in X&&X[H]!==void 0){if(typeof X[H]!=="number")A.push({message:`${H} must be a number`,path:[H]})}if(A.length>0)return{issues:A};return{value:N}}}}}function t(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 i(Y,Z){return Response.json({error:"validation_failed",message:Z,issues:Y},{status:400,headers:{"Content-Type":"application/json"}})}function jX(Y,Z,X=[]){let A={...Y,...Z};for(let N of X)A[N]=Y?.[N]??Z?.[N];return A}function QX(Y){let Z="",X=0,A=Y.length;while(X<A){let N=Y[X];if(N==='"'||N==="'"){let M=N;Z+=N,X++;while(X<A){let $=Y[X];if($==="\\"){if(Z+=$,X+1<A)Z+=Y[X+1],X+=2;else X++;continue}if($===M){Z+=$,X++;break}Z+=$,X++}continue}if(N==="/"&&X+1<A){let M=Y[X+1];if(M==="/"){X+=2;while(X<A&&Y[X]!==`
|
|
2
2
|
`)X++;if(X<A)Z+=`
|
|
3
|
-
`;X++;continue}if(M==="*"){X+=2;while(X+1<A&&!(Y[X]==="*"&&Y[X+1]==="/"))X++;X+=2;continue}}Z+=N,X++}return Z}function DX(Y){let Z=QX(Y);return JSON.parse(Z)}async function EX(Y,Z=1000,X=1e4,A){let N=Date.now(),M="Awaiting Ping";return new Promise(($,H)=>{let
|
|
3
|
+
`;X++;continue}if(M==="*"){X+=2;while(X+1<A&&!(Y[X]==="*"&&Y[X+1]==="/"))X++;X+=2;continue}}Z+=N,X++}return Z}function DX(Y){let Z=QX(Y);return JSON.parse(Z)}async function EX(Y,Z=1000,X=1e4,A){let N=Date.now(),M="Awaiting Ping";return new Promise(($,H)=>{let z=null,w=null,C=async()=>{try{let P=await fetch(Y);if(P.ok){if(z)clearInterval(z);if(w)clearInterval(w);$()}else try{let v=await P.json();M=`Response error: ${P.status}: ${P.statusText} - ${Y}: ${JSON.stringify(v)}`}catch(v){M=`Response error: ${P.status}: ${P.statusText} - ${Y}`}}catch(P){M=`${P instanceof Error?P.message:String(P)} - ${Y}`}};if(C(),z=setInterval(C,Z),X>0)w=setInterval(()=>{console.warn(`${M}: ${Date.now()-N}ms`)},X);if(A)setTimeout(()=>{if(z)clearInterval(z);if(w)clearInterval(w);H(Error(`Timeout: ${A}ms: ${M}`))},A)})}var BX="@enterprisestandard/core",WX=t(n(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 LX(Y){let Z=Y.replace(/-/g,"+").replace(/_/g,"/");return atob(Z)}async function _X(Y){let Z=Y.split(".");if(Z.length!==3)throw Error("Invalid JWT");let X=LX(Z[1]),A=JSON.parse(X),N=await WX.validate(A);if(N.issues)throw Error(`ID token claims validation failed: ${N.issues.map((M)=>M.message).join("; ")}`);if(N.value)return MX(N.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)},a={debug:()=>{},info:()=>{},warn(Y,...Z){I("warn",Y,...Z)},error(Y,...Z){I("error",Y,...Z)}},IX={debug:()=>{},info:()=>{},warn:()=>{},error:()=>{}},TX={debug:()=>{},info:I.bind(console,"info"),warn:I.bind(console,"warn"),error:I.bind(console,"error")},o=(Y,...Z)=>{if(Z.length>0)console.log("[DEBUG]",Y,...Z);else console.log("[DEBUG]",Y)},wX={debug:o,info:I.bind(console,"info"),warn:I.bind(console,"warn"),error:I.bind(console,"error")},yX={debug:o,info:I.bind(console,"info"),warn:I.bind(console,"warn"),error:I.bind(console,"error")};var r=new Map;async function g(Y,Z=3,X=1000,A=30000){let N=Error("Placeholder Error");for(let M=0;M<=Z;M++)try{return await Y()}catch($){if(N=$ instanceof Error?$:Error(String($)),$ instanceof Error&&$.message.includes("400"))throw $;if(M===Z)throw N;let H=Math.min(X*2**M,A),z=Math.random()*0.1*H;await new Promise((w)=>setTimeout(w,H+z)),console.warn(`Retry attempt ${M+1} after ${H+z}ms delay`)}throw N}async function s(Y){let Z=r.get(Y);if(Z)return Z;return g(async()=>{let X=await fetch(Y);if(!X.ok)throw Error("Failed to fetch JWKS");let A=await X.json();return r.set(Y,A),A})}async function e(Y,Z){let X=Y.keys.find((A)=>A.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 UX(Y,Z={}){let X=Z.cookieName??"es.active_session",A=Y.headers.get("cookie");if(!A)return;return YX(A)[X]}function hX(Y,Z={}){let X=Z.cookieName??"es.active_session",A=Z.path??"/",N=Z.secure??!1,M=Z.sameSite??"Lax",$=Z.maxAge,H=[`${X}=${Y}`,`Path=${A}`,"HttpOnly",`SameSite=${M}`];if(N)H.push("Secure");if(typeof $==="number")H.push(`Max-Age=${$}`);return H.join("; ")}function fX(Y,Z){if(!Y)return;let X=YX(Y);for(let[A,N]of Object.entries(X)){if(!A.startsWith("es.sso.")||!A.endsWith(".state"))continue;try{let M=JSON.parse(atob(N));if(M?.state===Z)return{clientId:A.slice(7,-6),stateCookie:M}}catch{}}return}function kX(Y,Z,X,A){if(!X&&!A)return;let N={...X,...A},M=!!(N.authority&&N.tokenUrl&&N.authorizationUrl&&N.clientId&&N.redirectUri&&N.scope),$={...N,authority:M?D(N.authority,"Missing 'authority' from SSO Config"):N.authority,tokenUrl:M?D(N.tokenUrl,"Missing 'tokenUrl' from SSO Config"):N.tokenUrl,authorizationUrl:M?D(N.authorizationUrl,"Missing 'authorizationUrl' from SSO Config"):N.authorizationUrl,clientId:M?D(N.clientId,"Missing 'clientId' from SSO Config"):N.clientId,redirectUri:M?D(N.redirectUri,"Missing 'redirectUri' from SSO Config"):N.redirectUri,scope:M?D(N.scope,"Missing 'scope' from SSO Config"):N.scope,responseType:N.responseType??"code",cookiesSecure:N.cookiesSecure!==void 0?N.cookiesSecure:!0,cookiesSameSite:N.cookiesSameSite!==void 0?N.cookiesSameSite:"Strict",cookiesPrefix:N.cookiesPrefix??(N.clientId?`es.sso.${N.clientId}`:"es.sso"),cookiesPath:N.cookiesPath??"/"};function H(){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 z(K){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");try{let{tokens:G}=await f(K);if(!G)return;return await U(G)}catch(G){console.error("Error parsing user from cookies:",G);return}}async function w(K){let G=await z(K);if(G)return G;throw new Response("Unauthorized",{status:401,statusText:"Unauthorized"})}async function C({landingUrl:K,errorUrl:G},B){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");H();let L=l(),W=l(64),Q=$.redirectUri;try{new URL(Q)}catch{if(B)try{let V=new URL(B),T=Q.startsWith("//")?Q.slice(1):Q.startsWith("/")?Q:`/${Q}`;Q=new URL(T,V.origin).toString()}catch{try{let V=new URL($.authorizationUrl),T=Q.startsWith("//")?Q.slice(1):Q.startsWith("/")?Q:`/${Q}`;Q=new URL(T,V.origin).toString()}catch{throw Error(`Invalid redirectUri: "${$.redirectUri}". It must be a valid absolute URL.`)}}}let O=new URL($.authorizationUrl);O.searchParams.append("client_id",$.clientId),O.searchParams.append("redirect_uri",Q),O.searchParams.append("response_type","code"),O.searchParams.append("scope",$.scope),O.searchParams.append("state",L);let J=await NX(W);O.searchParams.append("code_challenge",J),O.searchParams.append("code_challenge_method","S256");let j={state:L,codeVerifier:W,landingUrl:K,errorUrl:G};return new Response("Redirecting to SSO Provider",{status:302,headers:{Location:O.toString(),"Set-Cookie":h("state",j,86400)}})}async function P(K,G){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");try{let J=y("refresh",K);if(J)await $X(J)}catch(J){console.warn("Failed to revoke token:",J)}if($.sessionStore)try{let J=await z(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",R("access")],["Set-Cookie",R("id")],["Set-Cookie",R("refresh")],["Set-Cookie",R("control")],["Set-Cookie",R("state")]],W=new URL(K.url).searchParams.get("redirect");if(W)return new Response("Logged out",{status:302,headers:[["Location",W],...B]});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"],...B]});else return new Response(`
|
|
4
4
|
<!DOCTYPE html><html lang="en"><body>
|
|
5
5
|
<h1>Logout Complete</h1>
|
|
6
6
|
<div style="display: none">
|
|
@@ -8,5 +8,5 @@ function JX(Y){return{"~standard":{version:1,vendor:Y,validate:(Z)=>{if(typeof Z
|
|
|
8
8
|
Check the <a href="https://EnterpriseStandard.com/sso#logout">Enterprise Standard Packages</a> for more information.
|
|
9
9
|
</div>
|
|
10
10
|
</body></html>
|
|
11
|
-
`,{status:200,headers:[["Content-Type","text/html"],...B]})}async function g(K){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");if(!$.sessionStore)throw Error("Back-Channel Logout requires sessionStore configuration");try{let G=K.headers.get("content-type");if(!G||!G.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 O=(await c(W)).sid;if(!O)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(O),console.log(`Back-Channel Logout: successfully deleted session ${O}`),new Response("OK",{status:200})}catch(G){return console.error("Error during back-channel logout:",G),new Response("Internal Server Error",{status:500})}}async function m(K){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");let G=new URL(K.url),B=new URLSearchParams(G.search),L=Object.fromEntries(B.entries()),W=await Y.callbackParams["~standard"].validate(L);if(W.issues)return i(W.issues,"OIDC callback parameters validation failed");let{code:Q,state:O}=W.value;try{let J=y("state",K,!0),{codeVerifier:j,state:V,landingUrl:T}=J??{};if(D(j,'OIDC "codeVerifier" was not present in cookies, ensure that the SSO login was initiated correctly'),D(V,'OIDC "stateVerifier" was not present in cookies, ensure that the SSO login was initiated correctly'),D(T,'OIDC "landingUrl" was not present in cookies'),O!==V)throw Error('SSO State Verifier failed, the "state" request parameter does not equal the "state" in the SSO cookie');let z=await ZX(Q,j,K.url),E=await v(z);if($.sessionStore)try{let F=E.sso.profile.sid,S=E.id;if(F&&S){let _={sid:F,sub:S,createdAt:new Date,lastActivityAt:new Date};await $.sessionStore.create(_)}else console.warn("Session creation skipped: missing sid or sub in ID token claims")}catch(F){console.warn("Failed to create session:",F)}if($.userStore)try{let F=E.id;if(F){let S=new Date,_=await $.userStore.get(F);if(_||$.enableJitUserProvisioning){let k={..._??{},...E,id:F,createdAt:_?.createdAt??S,updatedAt:S};await $.userStore.upsert(k)}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(F){console.warn("Failed to store user:",F)}return new Response("Authentication successful, redirecting",{status:302,headers:[["Location",T],["Set-Cookie",R("state")],...f(z,E.sso.expires)]})}catch(J){console.error("Error during sign-in callback:",J);try{let j=y("state",K,!0),{errorUrl:V}=j??{};if(V)return new Response("Redirecting to error url",{status:302,headers:[["Location",V]]})}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 v(K){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");let G=await c(K.id_token),B=Number(K.refresh_expires_in??K.expires_in??3600),L=K.expires?new Date(K.expires):new Date(Date.now()+B*1000);return{id:G.sub,userName:G.preferred_username||"",name:G.name||"",email:G.email||"",emails:[{value:G.email||"",primary:!0}],avatar:G.picture,sso:{profile:{...G,iss:G.iss||$.authority,aud:G.aud||$.clientId},tenant:{id:G.idp||G.iss||$.authority||"",name:G.iss||$.authority||""},scope:K.scope,tokenType:K.token_type,sessionState:K.session_state,expires:L}}}async function ZX(K,G,B){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");H();let{tokenUrl:L,redirectUri:W}=$;try{new URL(W)}catch{if(B)try{let O=new URL(B),J=W.startsWith("//")?W.slice(1):W.startsWith("/")?W:`/${W}`;W=new URL(J,O.origin).toString()}catch{try{let O=new URL(L),J=W.startsWith("//")?W.slice(1):W.startsWith("/")?W:`/${W}`;W=new URL(J,O.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",G);try{let O=await fetch(L,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:Q.toString()}),J=await O.json();if(!O.ok){console.error("Token exchange error:",J);let V=J;throw Error(`Token exchange failed: ${V.error||O.statusText} - ${V.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(O){throw console.error("Error during token exchange:",O),O}}async function d(K){return p(async()=>{if(!$)throw Error("Enterprise Standard SSO Manager not initialized");H();let G=$.tokenUrl,B=new URLSearchParams;B.append("grant_type","refresh_token"),B.append("refresh_token",K),B.append("client_id",$.clientId);let L=await fetch(G,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:B.toString()}),W=await L.json();if(!L.ok){console.error("Token refresh error:",W);let Q=W;throw Error(`Token refresh failed: ${Q.error||L.statusText} - ${Q.error_description||""}`.trim())}return W})}async function $X(K){try{if(!$)throw Error("Enterprise Standard SSO Manager not initialized");if(!$.revocationEndpoint)return;let G=new URLSearchParams;G.append("token",K),G.append("token_type_hint","refresh_token"),G.append("client_id",$.clientId);let B=await fetch($.revocationEndpoint,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:G.toString()});if(!B.ok)console.warn("Token revocation failed:",B.status,B.statusText);else console.log("Token revoked successfully")}catch(G){console.warn("Error revoking token:",G)}}async function u(){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 s(K)}async function c(K){try{let G=K.split(".");if(G.length!==3)throw Error("Invalid JWT");let B=JSON.parse(atob(G[0].replace(/-/g,"+").replace(/_/g,"/"))),L=JSON.parse(atob(G[1].replace(/-/g,"+").replace(/_/g,"/"))),W=G[2].replace(/-/g,"+").replace(/_/g,"/"),Q=await KX(B.kid),J=new TextEncoder().encode(`${G[0]}.${G[1]}`);if(!await crypto.subtle.verify("RSASSA-PKCS1-v1_5",Q,Uint8Array.from(atob(W),(T)=>T.charCodeAt(0)),J))throw Error("Invalid JWT signature");let V=await Y.idTokenClaims["~standard"].validate(L);if(V.issues)throw console.error("ID token claims validation failed:",V.issues),Error(`ID token claims validation failed: ${V.issues}`);return V.value}catch(G){throw console.error("Error verifying JWT:",G),G}}function l(K=32){let G=new Uint8Array(K);return crypto.getRandomValues(G),Array.from(G,(B)=>B.toString(16).padStart(2,"0")).join("").substring(0,K)}async function NX(K){let B=new TextEncoder().encode(K),L=await crypto.subtle.digest("SHA-256",B),W=Array.from(new Uint8Array(L));return btoa(String.fromCharCode(...W)).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}async function KX(K){let G=await u();return e(G,K)}function f(K,G){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:G.toISOString()};return[["Set-Cookie",U("access",K.access_token,G)],["Set-Cookie",U("id",K.id_token,G)],["Set-Cookie",U("refresh",K.refresh_token??"",G)],["Set-Cookie",U("control",B,G)]]}async function h(K){let G=y("access",K),B=y("id",K),L=y("refresh",K),W=y("control",K,!0);if(!G||!B||!L||!W)return{tokens:void 0,refreshHeaders:[]};let Q={access_token:G,id_token:B,refresh_token:L,...W};if(W.expires&&L&&Date.now()>new Date(W.expires).getTime()){Q=await d(L);let O=await v(Q),J=f(Q,O.sso.expires);return{tokens:Q,refreshHeaders:J}}return{tokens:Q,refreshHeaders:[]}}async function AX(K){let{tokens:G}=await h(K);if(!G)return;return G.access_token}function U(K,G,B){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");if(K=`${$.cookiesPrefix}.${K}`,typeof G!=="string")G=btoa(JSON.stringify(G));let L;if(B instanceof Date)L=`Expires=${B.toUTCString()}`;else if(typeof B==="number")L=`Max-Age=${B}`;else throw Error("Invalid expires type",B);if(G.length>4000)throw Error(`Error setting cookie: ${K}. Cookie length is: ${G.length}`);return`${K}=${G}; ${L}; Path=${$.cookiesPath}; HttpOnly;${$.cookiesSecure?" Secure;":""} SameSite=${$.cookiesSameSite};`}function R(K){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");return`${$.cookiesPrefix}.${K}=; Max-Age=0; Path=${$.cookiesPath}; HttpOnly;${$.cookiesSecure?" Secure;":""} SameSite=${$.cookiesSameSite};`}function y(K,G,B=!1){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");let L=G.headers.get("cookie");if(!L)return null;let W=L.split(";").find((J)=>J.trim().startsWith(`${$.cookiesPrefix}.${K}=`));if(!W)return null;let Q=W.split("=")[1].trim();if(!B)return Q;let O=atob(Q);return JSON.parse(O)}async function GX(K,G){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");let{loginUrl:B,userUrl:L,errorUrl:W,landingUrl:Q,tokenUrl:O,refreshUrl:J,logoutUrl:j,logoutBackChannelUrl:V,jwksUrl:T,redirectUri:z}={...$,...G},E=new URL(K.url).pathname;if(z){let F;try{F=new URL(z).pathname}catch{try{let S=new URL(K.url),_=z.startsWith("//")?z.slice(1):z;F=new URL(_,S.origin).pathname}catch{F=z.startsWith("/")?z:`/${z}`}}if(F===E)return m(K)}if(B===E)return C({landingUrl:Q||"/",errorUrl:W},K.url);if(L===E){let{tokens:F,refreshHeaders:S}=await h(K);if(!F)return new Response("User not logged in",{status:401});let _=await v(F);return new Response(JSON.stringify(_),{headers:[["Content-Type","application/json"],...S]})}if(O===E){let{tokens:F,refreshHeaders:S}=await h(K);if(!F)return new Response("User not logged in",{status:401});return new Response(JSON.stringify({token:F.access_token,expires:F.expires}),{headers:[["Content-Type","application/json"],...S]})}if(J===E){let F=y("refresh",K);if(!F)return new Response("User not logged in",{status:401});let S=await d(F),_=await v(S),k=f(S,_.sso.expires);return new Response("Refresh Complete",{status:200,headers:k})}if(j===E)return I(K,{landingUrl:Q||"/"});if(V===E)return g(K);if(T===E){let F=await u();return new Response(JSON.stringify(F),{headers:[["Content-Type","application/json"]]})}return new Response("Not Found",{status:404})}return{...$,getUser:P,getRequiredUser:w,getJwt:AX,initiateLogin:C,logout:I,logoutBackChannel:g,callbackHandler:m,handler:GX}}function YX(Y){let Z={},X=Y.split(";");for(let A of X){let N=A.trim();if(!N)continue;let M=N.indexOf("=");if(M===-1)continue;let $=N.slice(0,M).trim(),H=N.slice(M+1).trim();Z[$]=H}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 XX(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 OX(Y,Z){let X=new Headers;for(let[A,N]of Y.headers)if(A.toLowerCase()!=="set-cookie")X.set(A,N);for(let A of Z)X.append("Set-Cookie",A);return new Response(Y.body,{status:Y.status,statusText:Y.statusText,headers:X})}var b="EnterpriseStandard instance is required. Create one with enterpriseStandard(source, config) and pass it to this function.";async function pX(Y,Z){return D(Z,b),Z.sso?.getUser(Y)}async function HX(Y,Z){D(Z,b);let X=Z.logger??a;X.debug?.("getUser called",{hasInstance:!0,hasSso:!!Z.sso,hasCiam:!!Z.ciam});let A=await Z.sso?.getUser(Y);if(A)return X.debug?.("Found SSO user",{email:A.email}),A;X.debug?.("No SSO user, trying CIAM");let N=await Z.ciam?.getUser(Y);return X.debug?.("CIAM user result",{email:N?.email??void 0}),N}async function gX(Y,Z){let X=await HX(Y,Z);if(X)return X;throw new Response("Unauthorized",{status:401,statusText:"Unauthorized"})}async function mX(Y,Z){D(Z,b);let X=Z.sso;if(!X)return q();return X.initiateLogin(Y)}async function dX(Y,Z){D(Z,b);let X=Z.sso;if(!X)return q();return X.callbackHandler(Y)}async function uX(Y,Z){D(Z,b);let{sso:X,ciam:A}=Z;if(!X&&!A)return q("Logout Unavailable");let N=X?await X.logout(Y,{landingUrl:"/"}):void 0,M=A?await A.logout(Y):void 0,$=N??M;if(!$)return q("Logout Unavailable");let H=[...XX(N),...XX(M)];return OX($,H)}async function cX(Y,Z){D(Z,b);let{sso:X,ciam:A}=Z;if(!X&&!A)return q("Back-Channel Logout Unavailable");let N=Y.clone(),M=Y.clone(),$=X?await X.logoutBackChannel(N):void 0;if($?.status===200)return $;let H=A?await A.logoutBackChannel(M):void 0;if(H)return H;return $??q("Back-Channel Logout Unavailable")}
|
|
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 G=K.headers.get("content-type");if(!G||!G.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 O=(await c(W)).sid;if(!O)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(O),console.log(`Back-Channel Logout: successfully deleted session ${O}`),new Response("OK",{status:200})}catch(G){return console.error("Error during back-channel logout:",G),new Response("Internal Server Error",{status:500})}}async function m(K){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");let G=new URL(K.url),B=new URLSearchParams(G.search),L=Object.fromEntries(B.entries()),W=await Y.callbackParams["~standard"].validate(L);if(W.issues)return i(W.issues,"OIDC callback parameters validation failed");let{code:Q,state:O}=W.value;try{let J=y("state",K,!0),{codeVerifier:j,state:V,landingUrl:T}=J??{};if(D(j,'OIDC "codeVerifier" was not present in cookies, ensure that the SSO login was initiated correctly'),D(V,'OIDC "stateVerifier" was not present in cookies, ensure that the SSO login was initiated correctly'),D(T,'OIDC "landingUrl" was not present in cookies'),O!==V)throw Error('SSO State Verifier failed, the "state" request parameter does not equal the "state" in the SSO cookie');let _=await ZX(Q,j,K.url),E=await U(_);if($.sessionStore)try{let F=E.sso.profile.sid,S=E.id;if(F&&S){let x={sid:F,sub:S,createdAt:new Date,lastActivityAt:new Date};await $.sessionStore.create(x)}else console.warn("Session creation skipped: missing sid or sub in ID token claims")}catch(F){console.warn("Failed to create session:",F)}if($.userStore)try{let F=E.id;if(F){let S=new Date,x=await $.userStore.get(F);if(x||$.enableJitUserProvisioning){let p={...x??{},...E,id:F,createdAt:x?.createdAt??S,updatedAt:S};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(F){console.warn("Failed to store user:",F)}return new Response("Authentication successful, redirecting",{status:302,headers:[["Location",T],["Set-Cookie",R("state")],...k(_,E.sso.expires)]})}catch(J){console.error("Error during sign-in callback:",J);try{let j=y("state",K,!0),{errorUrl:V}=j??{};if(V)return new Response("Redirecting to error url",{status:302,headers:[["Location",V]]})}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 G=await c(K.id_token),B=Number(K.refresh_expires_in??K.expires_in??3600),L=K.expires?new Date(K.expires):new Date(Date.now()+B*1000);return{id:G.sub,userName:G.preferred_username||"",name:G.name||"",email:G.email||"",emails:[{value:G.email||"",primary:!0}],avatar:G.picture,sso:{profile:{...G,iss:G.iss||$.authority,aud:G.aud||$.clientId},tenant:{id:G.idp||G.iss||$.authority||"",name:G.iss||$.authority||""},scope:K.scope,tokenType:K.token_type,sessionState:K.session_state,expires:L}}}async function ZX(K,G,B){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");H();let{tokenUrl:L,redirectUri:W}=$;try{new URL(W)}catch{if(B)try{let O=new URL(B),J=W.startsWith("//")?W.slice(1):W.startsWith("/")?W:`/${W}`;W=new URL(J,O.origin).toString()}catch{try{let O=new URL(L),J=W.startsWith("//")?W.slice(1):W.startsWith("/")?W:`/${W}`;W=new URL(J,O.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",G);try{let O=await fetch(L,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:Q.toString()}),J=await O.json();if(!O.ok){console.error("Token exchange error:",J);let V=J;throw Error(`Token exchange failed: ${V.error||O.statusText} - ${V.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(O){throw console.error("Error during token exchange:",O),O}}async function d(K){return g(async()=>{if(!$)throw Error("Enterprise Standard SSO Manager not initialized");H();let G=$.tokenUrl,B=new URLSearchParams;B.append("grant_type","refresh_token"),B.append("refresh_token",K),B.append("client_id",$.clientId);let L=await fetch(G,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:B.toString()}),W=await L.json();if(!L.ok){console.error("Token refresh error:",W);let Q=W;throw Error(`Token refresh failed: ${Q.error||L.statusText} - ${Q.error_description||""}`.trim())}return W})}async function $X(K){try{if(!$)throw Error("Enterprise Standard SSO Manager not initialized");if(!$.revocationEndpoint)return;let G=new URLSearchParams;G.append("token",K),G.append("token_type_hint","refresh_token"),G.append("client_id",$.clientId);let B=await fetch($.revocationEndpoint,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:G.toString()});if(!B.ok)console.warn("Token revocation failed:",B.status,B.statusText);else console.log("Token revoked successfully")}catch(G){console.warn("Error revoking token:",G)}}async function u(){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 s(K)}async function c(K){try{let G=K.split(".");if(G.length!==3)throw Error("Invalid JWT");let B=JSON.parse(atob(G[0].replace(/-/g,"+").replace(/_/g,"/"))),L=JSON.parse(atob(G[1].replace(/-/g,"+").replace(/_/g,"/"))),W=G[2].replace(/-/g,"+").replace(/_/g,"/"),Q=await KX(B.kid),J=new TextEncoder().encode(`${G[0]}.${G[1]}`);if(!await crypto.subtle.verify("RSASSA-PKCS1-v1_5",Q,Uint8Array.from(atob(W),(T)=>T.charCodeAt(0)),J))throw Error("Invalid JWT signature");let V=await Y.idTokenClaims["~standard"].validate(L);if(V.issues)throw console.error("ID token claims validation failed:",V.issues),Error(`ID token claims validation failed: ${V.issues}`);return V.value}catch(G){throw console.error("Error verifying JWT:",G),G}}function l(K=32){let G=new Uint8Array(K);return crypto.getRandomValues(G),Array.from(G,(B)=>B.toString(16).padStart(2,"0")).join("").substring(0,K)}async function NX(K){let B=new TextEncoder().encode(K),L=await crypto.subtle.digest("SHA-256",B),W=Array.from(new Uint8Array(L));return btoa(String.fromCharCode(...W)).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}async function KX(K){let G=await u();return e(G,K)}function k(K,G){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:G.toISOString()};return[["Set-Cookie",h("access",K.access_token,G)],["Set-Cookie",h("id",K.id_token,G)],["Set-Cookie",h("refresh",K.refresh_token??"",G)],["Set-Cookie",h("control",B,G)]]}async function f(K){let G=y("access",K),B=y("id",K),L=y("refresh",K),W=y("control",K,!0);if(!G||!B||!L||!W)return{tokens:void 0,refreshHeaders:[]};let Q={access_token:G,id_token:B,refresh_token:L,...W};if(W.expires&&L&&Date.now()>new Date(W.expires).getTime()){Q=await d(L);let O=await U(Q),J=k(Q,O.sso.expires);return{tokens:Q,refreshHeaders:J}}return{tokens:Q,refreshHeaders:[]}}async function AX(K){let{tokens:G}=await f(K);if(!G)return;return G.access_token}function h(K,G,B){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");if(K=`${$.cookiesPrefix}.${K}`,typeof G!=="string")G=btoa(JSON.stringify(G));let L;if(B instanceof Date)L=`Expires=${B.toUTCString()}`;else if(typeof B==="number")L=`Max-Age=${B}`;else throw Error("Invalid expires type",B);if(G.length>4000)throw Error(`Error setting cookie: ${K}. Cookie length is: ${G.length}`);return`${K}=${G}; ${L}; Path=${$.cookiesPath}; HttpOnly;${$.cookiesSecure?" Secure;":""} SameSite=${$.cookiesSameSite};`}function R(K){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");return`${$.cookiesPrefix}.${K}=; Max-Age=0; Path=${$.cookiesPath}; HttpOnly;${$.cookiesSecure?" Secure;":""} SameSite=${$.cookiesSameSite};`}function y(K,G,B=!1){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");let L=G.headers.get("cookie");if(!L)return null;let W=L.split(";").find((J)=>J.trim().startsWith(`${$.cookiesPrefix}.${K}=`));if(!W)return null;let Q=W.split("=")[1].trim();if(!B)return Q;let O=atob(Q);return JSON.parse(O)}async function GX(K,G){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");let{loginUrl:B,userUrl:L,errorUrl:W,landingUrl:Q,tokenUrl:O,refreshUrl:J,logoutUrl:j,logoutBackChannelUrl:V,jwksUrl:T,redirectUri:_}={...$,...G},E=new URL(K.url).pathname;if(_){let F;try{F=new URL(_).pathname}catch{try{let S=new URL(K.url),x=_.startsWith("//")?_.slice(1):_;F=new URL(x,S.origin).pathname}catch{F=_.startsWith("/")?_:`/${_}`}}if(F===E)return m(K)}if(B===E)return C({landingUrl:Q||"/",errorUrl:W},K.url);if(L===E){let{tokens:F,refreshHeaders:S}=await f(K);if(!F)return new Response("User not logged in",{status:401});let x=await U(F);return new Response(JSON.stringify(x),{headers:[["Content-Type","application/json"],...S]})}if(O===E){let{tokens:F,refreshHeaders:S}=await f(K);if(!F)return new Response("User not logged in",{status:401});return new Response(JSON.stringify({token:F.access_token,expires:F.expires}),{headers:[["Content-Type","application/json"],...S]})}if(J===E){let F=y("refresh",K);if(!F)return new Response("User not logged in",{status:401});let S=await d(F),x=await U(S),p=k(S,x.sso.expires);return new Response("Refresh Complete",{status:200,headers:p})}if(j===E)return P(K,{landingUrl:Q||"/"});if(V===E)return v(K);if(T===E){let F=await u();return new Response(JSON.stringify(F),{headers:[["Content-Type","application/json"]]})}return new Response("Not Found",{status:404})}return{...$,getUser:z,getRequiredUser:w,getJwt:AX,initiateLogin:C,logout:P,logoutBackChannel:v,callbackHandler:m,handler:GX}}function YX(Y){let Z={},X=Y.split(";");for(let A of X){let N=A.trim();if(!N)continue;let M=N.indexOf("=");if(M===-1)continue;let $=N.slice(0,M).trim(),H=N.slice(M+1).trim();Z[$]=H}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 XX(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 OX(Y,Z){let X=new Headers;Y.headers.forEach((A,N)=>{if(N.toLowerCase()!=="set-cookie")X.set(N,A)});for(let A of Z)X.append("Set-Cookie",A);return new Response(Y.body,{status:Y.status,statusText:Y.statusText,headers:X})}var b="EnterpriseStandard instance is required. Create one with enterpriseStandard(source, config) and pass it to this function.";async function pX(Y,Z){return D(Z,b),Z.sso?.getUser(Y)}async function HX(Y,Z){D(Z,b);let X=Z.logger??a;X.debug?.("getUser called",{hasInstance:!0,hasSso:!!Z.sso,hasCiam:!!Z.ciam});let A=await Z.sso?.getUser(Y);if(A)return X.debug?.("Found SSO user",{email:A.email}),A;X.debug?.("No SSO user, trying CIAM");let N=await Z.ciam?.getUser(Y);return X.debug?.("CIAM user result",{email:N?.email??void 0}),N}async function gX(Y,Z){let X=await HX(Y,Z);if(X)return X;throw new Response("Unauthorized",{status:401,statusText:"Unauthorized"})}async function mX(Y,Z){D(Z,b);let X=Z.sso;if(!X)return q();return X.initiateLogin(Y)}async function dX(Y,Z){D(Z,b);let X=Z.sso;if(!X)return q();return X.callbackHandler(Y)}async function uX(Y,Z){D(Z,b);let{sso:X,ciam:A}=Z;if(!X&&!A)return q("Logout Unavailable");let N=X?await X.logout(Y,{landingUrl:"/"}):void 0,M=A?await A.logout(Y):void 0,$=N??M;if(!$)return q("Logout Unavailable");let H=[...XX(N),...XX(M)];return OX($,H)}async function cX(Y,Z){D(Z,b);let{sso:X,ciam:A}=Z;if(!X&&!A)return q("Back-Channel Logout Unavailable");let N=Y.clone(),M=Y.clone(),$=X?await X.logoutBackChannel(N):void 0;if($?.status===200)return $;let H=A?await A.logoutBackChannel(M):void 0;if(H)return H;return $??q("Back-Channel Logout Unavailable")}
|
|
12
12
|
export{JX as a,FX as b,n as c,t as d,D as e,i as f,jX as g,QX as h,DX as i,EX as j,MX as k,_X as l,a as m,IX as n,TX as o,wX as p,yX as q,s as r,e as s,UX as t,hX as u,fX as v,kX as w,pX as x,HX as y,gX as z,mX as A,dX as B,uX as C,cX as D};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@enterprisestandard/core",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.11",
|
|
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.
|
|
31
|
-
"@enterprisestandard/valibot": "^0.0.
|
|
30
|
+
"@enterprisestandard/zod": "^0.0.11",
|
|
31
|
+
"@enterprisestandard/valibot": "^0.0.11"
|
|
32
32
|
}
|
|
33
33
|
}
|