@enterprisestandard/core 0.0.11 → 0.0.12
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 +276 -154
- package/dist/index.js +1 -1
- package/dist/server.d.ts +73 -4
- package/dist/server.js +1 -1
- package/dist/shared/core-gqcvxn3w.js +12 -0
- package/package.json +3 -3
- package/dist/shared/core-3rxwxw02.js +0 -12
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { version } from "../package.json";
|
|
2
|
-
import { StandardSchemaV1 as
|
|
2
|
+
import { StandardSchemaV1 as StandardSchemaV18 } from "@standard-schema/spec";
|
|
3
3
|
import { StandardSchemaV1 as StandardSchemaV15 } from "@standard-schema/spec";
|
|
4
4
|
/**
|
|
5
5
|
* Minimal logger interface compatible with common patterns (console, pino, winston, etc.)
|
|
@@ -812,6 +812,11 @@ type StoredUser<TExtended = object> = User2 & {
|
|
|
812
812
|
*/
|
|
813
813
|
id: string;
|
|
814
814
|
/**
|
|
815
|
+
* Optional Enterprise Standard tenant identifier for tenant-aware apps.
|
|
816
|
+
* Built-in user stores can use this when registering HRD mappings.
|
|
817
|
+
*/
|
|
818
|
+
tenantId?: string;
|
|
819
|
+
/**
|
|
815
820
|
* Timestamp when the user was first stored.
|
|
816
821
|
*/
|
|
817
822
|
createdAt: Date;
|
|
@@ -1804,6 +1809,10 @@ type CookieOptions = {
|
|
|
1804
1809
|
};
|
|
1805
1810
|
declare function getActiveSession(request: Request, options?: CookieOptions): string | undefined;
|
|
1806
1811
|
declare function setActiveSession(clientId: string, options?: CookieOptions): string;
|
|
1812
|
+
declare function clearActiveSession(options?: CookieOptions): string;
|
|
1813
|
+
declare function listSsoClientIdsFromCookies(requestOrCookieHeader: Request | string | null | undefined, options?: {
|
|
1814
|
+
cookiePrefix?: string;
|
|
1815
|
+
}): string[];
|
|
1807
1816
|
declare function findTenantFromStateParam(cookieHeader: string | null | undefined, stateParam: string): {
|
|
1808
1817
|
clientId: string;
|
|
1809
1818
|
stateCookie: StateCookie;
|
|
@@ -1841,6 +1850,7 @@ type SSO<
|
|
|
1841
1850
|
callbackHandler: (request: Request) => Promise<Response>;
|
|
1842
1851
|
handler: (request: Request) => Promise<Response>;
|
|
1843
1852
|
};
|
|
1853
|
+
import { StandardSchemaV1 as StandardSchemaV17 } from "@standard-schema/spec";
|
|
1844
1854
|
type Secret<T> = {
|
|
1845
1855
|
data: T;
|
|
1846
1856
|
metadata: MetaData;
|
|
@@ -2111,6 +2121,237 @@ type AzureSecretsConfig = {
|
|
|
2111
2121
|
*/
|
|
2112
2122
|
ttl?: number;
|
|
2113
2123
|
};
|
|
2124
|
+
type EnvironmentType = "POC" | "DEV" | "QA" | "PROD";
|
|
2125
|
+
type TenantStatus = "pending" | "processing" | "completed" | "failed" | "action_required";
|
|
2126
|
+
interface UpsertTenantRequest {
|
|
2127
|
+
tenantId: string;
|
|
2128
|
+
companyId: string;
|
|
2129
|
+
companyName: string;
|
|
2130
|
+
environmentType: EnvironmentType;
|
|
2131
|
+
email?: string;
|
|
2132
|
+
webhookUrl?: string;
|
|
2133
|
+
callbackUrl?: string;
|
|
2134
|
+
tenantUrl: string;
|
|
2135
|
+
configSource: TenantSecretsConfig;
|
|
2136
|
+
}
|
|
2137
|
+
type UpsertTenantResponse = {
|
|
2138
|
+
tenantUrl?: string;
|
|
2139
|
+
status: Exclude<TenantStatus, "action_required">;
|
|
2140
|
+
error?: string;
|
|
2141
|
+
refs?: RefUrls[];
|
|
2142
|
+
} | {
|
|
2143
|
+
status: "action_required";
|
|
2144
|
+
actionUrl: string;
|
|
2145
|
+
requestToken: string;
|
|
2146
|
+
expiresAt: string;
|
|
2147
|
+
refs?: RefUrls[];
|
|
2148
|
+
};
|
|
2149
|
+
type CreateTenantRequest = UpsertTenantRequest;
|
|
2150
|
+
type CreateTenantResponse = UpsertTenantResponse;
|
|
2151
|
+
/**
|
|
2152
|
+
* The audience of the reference URL.
|
|
2153
|
+
* - 'human' for human-readable documentation such as user guides, documentation, etc.
|
|
2154
|
+
* - 'ai' for AI-generated reference such as llms.txt, AI-optimized markdown, etc.
|
|
2155
|
+
* - 'spec' for specifications and code-gen ready docs such as OpenAPI, GraphQL, etc.
|
|
2156
|
+
*/
|
|
2157
|
+
type Audience = "human" | "ai" | "spec";
|
|
2158
|
+
interface RefUrls {
|
|
2159
|
+
audience: Audience;
|
|
2160
|
+
url: string;
|
|
2161
|
+
description: string;
|
|
2162
|
+
createdAt: Date;
|
|
2163
|
+
updatedAt: Date;
|
|
2164
|
+
}
|
|
2165
|
+
interface TenantWebhookPayload {
|
|
2166
|
+
tenantId: string;
|
|
2167
|
+
companyId: string;
|
|
2168
|
+
status: TenantStatus;
|
|
2169
|
+
tenantUrl?: string;
|
|
2170
|
+
actionUrl?: string;
|
|
2171
|
+
requestToken?: string;
|
|
2172
|
+
expiresAt?: string;
|
|
2173
|
+
error?: string;
|
|
2174
|
+
}
|
|
2175
|
+
declare class TenantRequestError extends Error {
|
|
2176
|
+
constructor(message: string, options?: ErrorOptions);
|
|
2177
|
+
}
|
|
2178
|
+
declare class MultipleTenantsForUserError extends Error {
|
|
2179
|
+
readonly userId: string;
|
|
2180
|
+
readonly tenantIds: string[];
|
|
2181
|
+
constructor(userId: string, tenantIds: string[], options?: ErrorOptions);
|
|
2182
|
+
}
|
|
2183
|
+
type UserMode = "singleTenantOnly" | "multipleTenantsPerUser";
|
|
2184
|
+
type TenantValidators = {
|
|
2185
|
+
upsertTenantRequest: StandardSchemaV17<unknown, UpsertTenantRequest>;
|
|
2186
|
+
upsertTenantResponse?: StandardSchemaV17<unknown, UpsertTenantResponse>;
|
|
2187
|
+
createTenantRequest?: StandardSchemaV17<unknown, UpsertTenantRequest>;
|
|
2188
|
+
createTenantResponse?: StandardSchemaV17<unknown, UpsertTenantResponse>;
|
|
2189
|
+
};
|
|
2190
|
+
/**
|
|
2191
|
+
* Env-like tenant config variables used to build a ConfigSource at runtime.
|
|
2192
|
+
* These mirror the ES_* variables read by envConfig().
|
|
2193
|
+
*/
|
|
2194
|
+
type TenantConfigEnv = {
|
|
2195
|
+
ES_CONFIG_TYPE?: ConfigSourceType;
|
|
2196
|
+
ES_APP_ID?: string;
|
|
2197
|
+
ES_CONFIG_PATH?: string;
|
|
2198
|
+
ES_IONITE_URL?: string;
|
|
2199
|
+
ES_LFV_PATH?: string;
|
|
2200
|
+
ES_LFV_SERVER_URL?: string;
|
|
2201
|
+
ES_LFV_CLIENT_ID?: string;
|
|
2202
|
+
ES_LFV_SIGNATURE?: string;
|
|
2203
|
+
ES_LFV_DELIVERY_ENDPOINT?: string;
|
|
2204
|
+
ES_LFV_VERIFY_PUBLIC_KEY?: string;
|
|
2205
|
+
ES_LFV_EVENTS_ENDPOINT?: string;
|
|
2206
|
+
ES_LFV_DELIVERY_TIMEOUT?: string;
|
|
2207
|
+
ES_LFV_RETRY_INTERVAL?: string;
|
|
2208
|
+
ES_LFV_WARN_INTERVAL?: string;
|
|
2209
|
+
ES_FILE_PATH?: string;
|
|
2210
|
+
ES_FILE_WATCH?: string;
|
|
2211
|
+
ES_FILE_TTL?: string;
|
|
2212
|
+
ES_VAULT_URL?: string;
|
|
2213
|
+
ES_VAULT_TOKEN?: string;
|
|
2214
|
+
ES_VAULT_PATH?: string;
|
|
2215
|
+
ES_VAULT_TTL?: string;
|
|
2216
|
+
ES_AZURE_API_VERSION?: string;
|
|
2217
|
+
ES_AZURE_SCOPE?: string;
|
|
2218
|
+
ES_AZURE_SECRET_NAME_PREFIX?: string;
|
|
2219
|
+
ES_AZURE_AUTH_METHOD?: AwsAuthMethod;
|
|
2220
|
+
ES_AZURE_TENANT_ID?: string;
|
|
2221
|
+
ES_AZURE_CLIENT_ID?: string;
|
|
2222
|
+
ES_AZURE_CLIENT_SECRET?: string;
|
|
2223
|
+
ES_AZURE_FEDERATED_TOKEN_FILE?: string;
|
|
2224
|
+
ES_AZURE_MANAGED_IDENTITY_CLIENT_ID?: string;
|
|
2225
|
+
ES_AZURE_IMDS_API_VERSION?: string;
|
|
2226
|
+
ES_AZURE_VAULT_URL?: string;
|
|
2227
|
+
ES_AZURE_VAULT_NAME?: string;
|
|
2228
|
+
ES_AZURE_TTL?: string;
|
|
2229
|
+
ES_AWS_WEBHOOK_URL?: string;
|
|
2230
|
+
ES_AWS_TTL?: string;
|
|
2231
|
+
ES_GCP_TTL?: string;
|
|
2232
|
+
};
|
|
2233
|
+
type TenantSecretsConfig = LfvSecretsConfig | (VaultSecretsConfig & {
|
|
2234
|
+
path: string;
|
|
2235
|
+
retryInterval?: number;
|
|
2236
|
+
}) | (DevSecretsConfig & {
|
|
2237
|
+
path?: string;
|
|
2238
|
+
appId?: string;
|
|
2239
|
+
}) | (AwsSecretsConfig & {
|
|
2240
|
+
ttl?: number;
|
|
2241
|
+
}) | AzureSecretsConfig | (GcpSecretsConfig & {
|
|
2242
|
+
ttl?: number;
|
|
2243
|
+
}) | {
|
|
2244
|
+
type: "localFile";
|
|
2245
|
+
path?: string;
|
|
2246
|
+
watch?: boolean;
|
|
2247
|
+
ttl?: number;
|
|
2248
|
+
};
|
|
2249
|
+
type TenantConfigSourceInput = TenantSecretsConfig | ConfigSource;
|
|
2250
|
+
type TenantBaseRecord = {
|
|
2251
|
+
tenantId: string;
|
|
2252
|
+
companyId: string;
|
|
2253
|
+
companyName: string;
|
|
2254
|
+
environmentType: EnvironmentType;
|
|
2255
|
+
email?: string;
|
|
2256
|
+
webhookUrl?: string;
|
|
2257
|
+
callbackUrl?: string;
|
|
2258
|
+
tenantUrl?: string;
|
|
2259
|
+
status: TenantStatus;
|
|
2260
|
+
error?: string;
|
|
2261
|
+
actionUrl?: string;
|
|
2262
|
+
requestToken?: string;
|
|
2263
|
+
expiresAt?: string;
|
|
2264
|
+
createdAt: Date;
|
|
2265
|
+
updatedAt: Date;
|
|
2266
|
+
/** Persisted tenant config metadata, or a runtime ConfigSource for internal-only tenants. */
|
|
2267
|
+
configSource: TenantConfigSourceInput;
|
|
2268
|
+
/** Runtime helper that returns a ConfigSource for this tenant. */
|
|
2269
|
+
config: () => ConfigSource;
|
|
2270
|
+
};
|
|
2271
|
+
type StoredTenant<TExtended extends object = Record<string, never>> = TenantBaseRecord & TExtended;
|
|
2272
|
+
type StoredTenantRecord<TExtended extends object = Record<string, never>> = Omit<StoredTenant<TExtended>, "config">;
|
|
2273
|
+
type TenantEsFactory<TExtended extends object = Record<string, never>> = (tenant: StoredTenant<TExtended>) => EnterpriseStandard;
|
|
2274
|
+
type TenantStoreWithESOptions<TExtended extends object = Record<string, never>> = {
|
|
2275
|
+
/**
|
|
2276
|
+
* TTL for cached per-tenant EnterpriseStandard instances, in milliseconds.
|
|
2277
|
+
* Default is forever; set to 0 to recreate ES on every getEs() call.
|
|
2278
|
+
*/
|
|
2279
|
+
ttl?: number;
|
|
2280
|
+
/**
|
|
2281
|
+
* Optional factory used to create an ES instance for a tenant.
|
|
2282
|
+
* If omitted, getEs() throws.
|
|
2283
|
+
*/
|
|
2284
|
+
createEs?: TenantEsFactory<TExtended>;
|
|
2285
|
+
};
|
|
2286
|
+
type TenantMetadataRecord = Omit<TenantBaseRecord, "tenantId" | "config" | "configSource" | "status" | "createdAt" | "updatedAt">;
|
|
2287
|
+
type TenantExtendedUpsertFields<TExtended extends object> = string extends keyof TExtended ? unknown : Partial<TExtended>;
|
|
2288
|
+
type TenantStoreUpsertRecord<TExtended extends object = Record<string, never>> = Pick<TenantBaseRecord, "tenantId" | "configSource"> & Partial<TenantMetadataRecord> & Partial<Pick<TenantBaseRecord, "status" | "createdAt" | "updatedAt">> & TenantExtendedUpsertFields<TExtended>;
|
|
2289
|
+
type TenantUserRegistration<TMode extends UserMode = UserMode> = {
|
|
2290
|
+
userMode: TMode;
|
|
2291
|
+
registerUserTenantId?(userId: string, tenantId: string | null | undefined): void | Promise<void>;
|
|
2292
|
+
};
|
|
2293
|
+
type TenantStoreBase<
|
|
2294
|
+
TMode extends UserMode = "singleTenantOnly",
|
|
2295
|
+
TExtended extends object = Record<string, never>
|
|
2296
|
+
> = TenantUserRegistration<TMode> & {
|
|
2297
|
+
get(tenantId: string): Promise<StoredTenant<TExtended> | null>;
|
|
2298
|
+
list(options?: TenantListOptions): Promise<ListResult<StoredTenant<TExtended>>>;
|
|
2299
|
+
upsert(tenant: TenantStoreUpsertRecord<TExtended>): Promise<StoredTenant<TExtended>>;
|
|
2300
|
+
delete(tenantId: string): Promise<void>;
|
|
2301
|
+
};
|
|
2302
|
+
type TenantLookupMethods<
|
|
2303
|
+
TMode extends UserMode,
|
|
2304
|
+
TExtended extends object
|
|
2305
|
+
> = TMode extends "singleTenantOnly" ? {
|
|
2306
|
+
findTenantByUserId(userId: string): Promise<StoredTenant<TExtended> | null>;
|
|
2307
|
+
findTenantsByUserId?: never;
|
|
2308
|
+
} : {
|
|
2309
|
+
findTenantByUserId?: never;
|
|
2310
|
+
findTenantsByUserId(userId: string): Promise<StoredTenant<TExtended>[]>;
|
|
2311
|
+
};
|
|
2312
|
+
type TenantStore<
|
|
2313
|
+
TMode extends UserMode = "singleTenantOnly",
|
|
2314
|
+
TExtended extends object = Record<string, never>
|
|
2315
|
+
> = TenantStoreBase<TMode, TExtended> & TenantLookupMethods<TMode, TExtended>;
|
|
2316
|
+
type TenantStoreWithES<
|
|
2317
|
+
TMode extends UserMode = "singleTenantOnly",
|
|
2318
|
+
TExtended extends object = Record<string, never>
|
|
2319
|
+
> = TenantStore<TMode, TExtended> & {
|
|
2320
|
+
ttl: number;
|
|
2321
|
+
getEs(tenantId: string): Promise<EnterpriseStandard | null>;
|
|
2322
|
+
getCachedTenantIds(): string[];
|
|
2323
|
+
};
|
|
2324
|
+
type InMemoryTenantStoreOptions<
|
|
2325
|
+
TMode extends UserMode = "singleTenantOnly",
|
|
2326
|
+
TExtended extends object = Record<string, never>
|
|
2327
|
+
> = TenantStoreWithESOptions<TExtended> & {
|
|
2328
|
+
userMode: TMode;
|
|
2329
|
+
};
|
|
2330
|
+
declare class InMemoryTenantStore<
|
|
2331
|
+
TMode extends UserMode = "singleTenantOnly",
|
|
2332
|
+
TExtended extends object = Record<string, never>
|
|
2333
|
+
> {
|
|
2334
|
+
private tenants;
|
|
2335
|
+
private tenantEsMap;
|
|
2336
|
+
private userTenantIds;
|
|
2337
|
+
readonly ttl: number;
|
|
2338
|
+
readonly userMode: TMode;
|
|
2339
|
+
private readonly createEs?;
|
|
2340
|
+
readonly findTenantByUserId: TMode extends "singleTenantOnly" ? (userId: string) => Promise<StoredTenant<TExtended> | null> : never;
|
|
2341
|
+
readonly findTenantsByUserId: TMode extends "multipleTenantsPerUser" ? (userId: string) => Promise<StoredTenant<TExtended>[]> : never;
|
|
2342
|
+
constructor(options: InMemoryTenantStoreOptions<TMode, TExtended>);
|
|
2343
|
+
get(tenantId: string): Promise<StoredTenant<TExtended> | null>;
|
|
2344
|
+
list(options?: TenantListOptions): Promise<ListResult<StoredTenant<TExtended>>>;
|
|
2345
|
+
upsert(tenant: TenantStoreUpsertRecord<TExtended>): Promise<StoredTenant<TExtended>>;
|
|
2346
|
+
delete(tenantId: string): Promise<void>;
|
|
2347
|
+
getEs(tenantId: string): Promise<EnterpriseStandard>;
|
|
2348
|
+
getCachedTenantIds(): string[];
|
|
2349
|
+
registerUserTenantId(userId: string, tenantId: string | null | undefined): Promise<void>;
|
|
2350
|
+
private findSingleTenantByUserId;
|
|
2351
|
+
private findMultipleTenantsByUserId;
|
|
2352
|
+
private resolveTenantsByUserId;
|
|
2353
|
+
}
|
|
2354
|
+
declare function sendTenantWebhook(webhookUrl: string, payload: TenantWebhookPayload, log: Logger): Promise<void>;
|
|
2114
2355
|
type ConfigSourceType = "vault" | "lfv" | "azure" | "aws" | "gcp" | "dev" | "localFile";
|
|
2115
2356
|
type ESValidators = {
|
|
2116
2357
|
sso: SSOValidators;
|
|
@@ -2119,6 +2360,9 @@ type ESValidators = {
|
|
|
2119
2360
|
ciam: CIAMValidators;
|
|
2120
2361
|
secrets?: SecretsValidators;
|
|
2121
2362
|
};
|
|
2363
|
+
type ApplicationValidators = ESValidators & {
|
|
2364
|
+
tenant: TenantValidators;
|
|
2365
|
+
};
|
|
2122
2366
|
/**
|
|
2123
2367
|
* Configuration supplied by the framework/application when creating an Enterprise Standard instance.
|
|
2124
2368
|
* Merged with RemoteConfig from the ConfigSource (framework config wins). Pass as the second
|
|
@@ -2399,8 +2643,8 @@ interface MagicLinkStore<TExtended = object> {
|
|
|
2399
2643
|
* baseUser includes a top-level .validate() for a cleaner API (see withValidate).
|
|
2400
2644
|
*/
|
|
2401
2645
|
type CIAMValidators = {
|
|
2402
|
-
baseUser:
|
|
2403
|
-
validate(value: unknown): Promise<
|
|
2646
|
+
baseUser: StandardSchemaV18<unknown, BaseUser> & {
|
|
2647
|
+
validate(value: unknown): Promise<StandardSchemaV18.Result<BaseUser>>;
|
|
2404
2648
|
};
|
|
2405
2649
|
};
|
|
2406
2650
|
type CIAMConfig<
|
|
@@ -2538,159 +2782,37 @@ declare function decodeUser(jwt: string): Promise<User2>;
|
|
|
2538
2782
|
* When limit is omitted, size is set to total (one logical page), page and pages are 1.
|
|
2539
2783
|
*/
|
|
2540
2784
|
declare function list<T>(total: number, items: T[], start: number, limit: number | undefined): ListResult<T>;
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
interface UpsertTenantRequest {
|
|
2545
|
-
tenantId: string;
|
|
2546
|
-
companyId: string;
|
|
2547
|
-
companyName: string;
|
|
2548
|
-
environmentType: EnvironmentType;
|
|
2549
|
-
email: string;
|
|
2550
|
-
webhookUrl: string;
|
|
2551
|
-
callbackUrl: string;
|
|
2552
|
-
tenantUrl?: string;
|
|
2553
|
-
configSource: TenantSecretsConfig;
|
|
2554
|
-
}
|
|
2555
|
-
type UpsertTenantResponse = {
|
|
2556
|
-
tenantUrl?: string;
|
|
2557
|
-
status: Exclude<TenantStatus, "action_required">;
|
|
2558
|
-
error?: string;
|
|
2559
|
-
refs?: RefUrls[];
|
|
2560
|
-
} | {
|
|
2561
|
-
status: "action_required";
|
|
2562
|
-
actionUrl: string;
|
|
2563
|
-
requestToken: string;
|
|
2564
|
-
expiresAt: string;
|
|
2565
|
-
refs?: RefUrls[];
|
|
2785
|
+
type TenantPathNamespace = {
|
|
2786
|
+
beforeTenantSegments?: string[];
|
|
2787
|
+
afterTenantSegments?: string[];
|
|
2566
2788
|
};
|
|
2567
|
-
type
|
|
2568
|
-
type
|
|
2569
|
-
|
|
2570
|
-
|
|
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
|
-
}
|
|
2583
|
-
interface TenantWebhookPayload {
|
|
2584
|
-
tenantId: string;
|
|
2585
|
-
companyId: string;
|
|
2586
|
-
status: TenantStatus;
|
|
2587
|
-
tenantUrl?: string;
|
|
2588
|
-
actionUrl?: string;
|
|
2589
|
-
requestToken?: string;
|
|
2590
|
-
expiresAt?: string;
|
|
2591
|
-
error?: string;
|
|
2592
|
-
}
|
|
2593
|
-
declare class TenantRequestError extends Error {
|
|
2594
|
-
constructor(message: string, options?: ErrorOptions);
|
|
2595
|
-
}
|
|
2596
|
-
type TenantValidators = {
|
|
2597
|
-
upsertTenantRequest: StandardSchemaV18<unknown, UpsertTenantRequest>;
|
|
2598
|
-
upsertTenantResponse?: StandardSchemaV18<unknown, UpsertTenantResponse>;
|
|
2789
|
+
type TenantPathRoutingStrategy = {
|
|
2790
|
+
type?: "path";
|
|
2791
|
+
ui?: TenantPathNamespace;
|
|
2792
|
+
api?: TenantPathNamespace;
|
|
2599
2793
|
};
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
ES_LFV_PATH?: string;
|
|
2610
|
-
ES_LFV_SERVER_URL?: string;
|
|
2611
|
-
ES_LFV_CLIENT_ID?: string;
|
|
2612
|
-
ES_LFV_SIGNATURE?: string;
|
|
2613
|
-
ES_LFV_DELIVERY_ENDPOINT?: string;
|
|
2614
|
-
ES_LFV_VERIFY_PUBLIC_KEY?: string;
|
|
2615
|
-
ES_LFV_EVENTS_ENDPOINT?: string;
|
|
2616
|
-
ES_LFV_DELIVERY_TIMEOUT?: string;
|
|
2617
|
-
ES_LFV_RETRY_INTERVAL?: string;
|
|
2618
|
-
ES_LFV_WARN_INTERVAL?: string;
|
|
2619
|
-
ES_FILE_PATH?: string;
|
|
2620
|
-
ES_FILE_WATCH?: string;
|
|
2621
|
-
ES_FILE_TTL?: string;
|
|
2622
|
-
ES_VAULT_URL?: string;
|
|
2623
|
-
ES_VAULT_TOKEN?: string;
|
|
2624
|
-
ES_VAULT_PATH?: string;
|
|
2625
|
-
ES_VAULT_TTL?: string;
|
|
2626
|
-
ES_AZURE_API_VERSION?: string;
|
|
2627
|
-
ES_AZURE_SCOPE?: string;
|
|
2628
|
-
ES_AZURE_SECRET_NAME_PREFIX?: string;
|
|
2629
|
-
ES_AZURE_AUTH_METHOD?: AwsAuthMethod;
|
|
2630
|
-
ES_AZURE_TENANT_ID?: string;
|
|
2631
|
-
ES_AZURE_CLIENT_ID?: string;
|
|
2632
|
-
ES_AZURE_CLIENT_SECRET?: string;
|
|
2633
|
-
ES_AZURE_FEDERATED_TOKEN_FILE?: string;
|
|
2634
|
-
ES_AZURE_MANAGED_IDENTITY_CLIENT_ID?: string;
|
|
2635
|
-
ES_AZURE_IMDS_API_VERSION?: string;
|
|
2636
|
-
ES_AZURE_VAULT_URL?: string;
|
|
2637
|
-
ES_AZURE_VAULT_NAME?: string;
|
|
2638
|
-
ES_AZURE_TTL?: string;
|
|
2639
|
-
ES_AWS_WEBHOOK_URL?: string;
|
|
2640
|
-
ES_AWS_TTL?: string;
|
|
2641
|
-
ES_GCP_TTL?: string;
|
|
2642
|
-
};
|
|
2643
|
-
type TenantSecretsConfig = LfvSecretsConfig | (VaultSecretsConfig & {
|
|
2644
|
-
path: string;
|
|
2645
|
-
retryInterval?: number;
|
|
2646
|
-
}) | (DevSecretsConfig & {
|
|
2647
|
-
path?: string;
|
|
2648
|
-
appId?: string;
|
|
2649
|
-
}) | (AwsSecretsConfig & {
|
|
2650
|
-
ttl?: number;
|
|
2651
|
-
}) | AzureSecretsConfig | (GcpSecretsConfig & {
|
|
2652
|
-
ttl?: number;
|
|
2653
|
-
}) | {
|
|
2654
|
-
type: "localFile";
|
|
2655
|
-
path?: string;
|
|
2656
|
-
watch?: boolean;
|
|
2657
|
-
ttl?: number;
|
|
2794
|
+
type TenantJwtRoutingStrategy = {
|
|
2795
|
+
type: "jwt";
|
|
2796
|
+
claim: string | string[];
|
|
2797
|
+
ui?: {
|
|
2798
|
+
segments?: string[];
|
|
2799
|
+
};
|
|
2800
|
+
api?: {
|
|
2801
|
+
segments?: string[];
|
|
2802
|
+
};
|
|
2658
2803
|
};
|
|
2659
|
-
type
|
|
2804
|
+
type TenantRoutingStrategy = TenantPathRoutingStrategy | TenantJwtRoutingStrategy;
|
|
2805
|
+
type TenantPathMatch = {
|
|
2660
2806
|
tenantId: string;
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
actionUrl?: string;
|
|
2671
|
-
requestToken?: string;
|
|
2672
|
-
expiresAt?: string;
|
|
2673
|
-
createdAt: Date;
|
|
2674
|
-
updatedAt: Date;
|
|
2675
|
-
/** Persisted typed config used to construct a ConfigSource at runtime. */
|
|
2676
|
-
configSource: TenantSecretsConfig;
|
|
2677
|
-
/** Runtime helper that returns a ConfigSource for this tenant. */
|
|
2678
|
-
config: () => ConfigSource;
|
|
2679
|
-
} & TExtended;
|
|
2680
|
-
interface TenantStore<TExtended extends object = Record<string, never>> {
|
|
2681
|
-
get(tenantId: string): Promise<StoredTenant<TExtended> | null>;
|
|
2682
|
-
list(options?: TenantListOptions): Promise<ListResult<StoredTenant<TExtended>>>;
|
|
2683
|
-
upsert(tenant: Omit<StoredTenant<TExtended>, "config" | "status" | "createdAt" | "updatedAt"> & Partial<Pick<StoredTenant<TExtended>, "status" | "createdAt" | "updatedAt">>): Promise<StoredTenant<TExtended>>;
|
|
2684
|
-
delete(tenantId: string): Promise<void>;
|
|
2685
|
-
}
|
|
2686
|
-
declare class InMemoryTenantStore<TExtended extends object = Record<string, never>> implements TenantStore<TExtended> {
|
|
2687
|
-
private tenants;
|
|
2688
|
-
get(tenantId: string): Promise<StoredTenant<TExtended> | null>;
|
|
2689
|
-
list(options?: TenantListOptions): Promise<ListResult<StoredTenant<TExtended>>>;
|
|
2690
|
-
upsert(tenant: Omit<StoredTenant<TExtended>, "config" | "status" | "createdAt" | "updatedAt"> & Partial<Pick<StoredTenant<TExtended>, "status" | "createdAt" | "updatedAt">>): Promise<StoredTenant<TExtended>>;
|
|
2691
|
-
delete(tenantId: string): Promise<void>;
|
|
2692
|
-
}
|
|
2693
|
-
declare function sendTenantWebhook(webhookUrl: string, payload: TenantWebhookPayload, log: Logger): Promise<void>;
|
|
2807
|
+
restSegments: string[];
|
|
2808
|
+
restPath: string;
|
|
2809
|
+
};
|
|
2810
|
+
declare const DEFAULT_TENANT_UI_NAMESPACE: TenantPathNamespace;
|
|
2811
|
+
declare const DEFAULT_TENANT_API_NAMESPACE: TenantPathNamespace;
|
|
2812
|
+
declare function normalizeTenantPathNamespace(namespace?: TenantPathNamespace): TenantPathNamespace;
|
|
2813
|
+
declare function normalizeTenantRoutingStrategy(strategy?: TenantRoutingStrategy): TenantRoutingStrategy;
|
|
2814
|
+
declare function matchTenantPath(pathname: string, namespace?: TenantPathNamespace): TenantPathMatch | null;
|
|
2815
|
+
declare function buildTenantPath(tenantId: string, restPath?: string, namespace?: TenantPathNamespace): string;
|
|
2694
2816
|
/**
|
|
2695
2817
|
* Enterprise user with SCIM attributes.
|
|
2696
2818
|
* Extends BaseUser (simple fields) with optional complex SCIM fields.
|
|
@@ -2890,5 +3012,5 @@ declare function parseJsonc<T>(content: string): T;
|
|
|
2890
3012
|
* @param timeout - The timeout in milliseconds to reject the promise.
|
|
2891
3013
|
* @returns A promise that resolves when the service is ready.
|
|
2892
3014
|
*/
|
|
2893
|
-
declare function waitOn(url: string, pingInterval?: number, warnInterval?: number, timeout?: number): Promise<void>;
|
|
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 };
|
|
3015
|
+
declare function waitOn(url: string, test?: (resp: Response) => boolean | Promise<boolean>, pingInterval?: number, warnInterval?: number, timeout?: number): Promise<void>;
|
|
3016
|
+
export { workloadTokenResponseSchema, withValidate, waitOn, version, validationFailureResponse, userSchema, tokenResponseSchema, stripJsonComments, silentLogger, setActiveSession, serializeESConfig, sendTenantWebhook, parseJsonc, oidcCallbackSchema, normalizeTenantRoutingStrategy, normalizeTenantPathNamespace, must, mergeConfig, matchTenantPath, listSsoClientIdsFromCookies, list, jwtAssertionClaimsSchema, infoLogger, idTokenClaimsSchema, groupResourceSchema, getActiveSession, findTenantFromStateParam, defaultLogger, decodeUser, debugLogger, consoleLogger, clearActiveSession, claimsToUser, buildTenantPath, X509Certificate, WorkloadValidators, WorkloadTokenStore, WorkloadTokenResponse, WorkloadIncomingOutgoing, WorkloadIdentity, WorkloadConfigMap, WorkloadConfig, WorkloadClient, Workload, VaultSecretsConfig, ValidateResult, UsersInboundHandlerConfig, UserStore, UserSortOptions, UserSortField, UserMode, UserListOptions, User2 as User, UpsertTenantResponse, UpsertTenantRequest, TokenValidationResult, TokenResponse, TenantWebhookPayload, TenantValidators, TenantUserRegistration, TenantStoreWithESOptions, TenantStoreWithES, TenantStoreUpsertRecord, TenantStore, TenantStatus, TenantSortOptions, TenantSortField, TenantSecretsConfig, TenantRoutingStrategy, TenantRequestError, TenantPathRoutingStrategy, TenantPathNamespace, TenantPathMatch, TenantListOptions, TenantJwtRoutingStrategy, TenantEsFactory, TenantConfigSourceInput, TenantConfigEnv, StoredUser, StoredTenantRecord, StoredTenant, StoredGroup, StateCookie, StandardSchemaWithValidate, SortDirection, SessionStore, Session, ServerOnlyWorkloadConfig, SecretsValidators, SecretsSourceType, SecretsSourceMap, SecretsSourceConfig, SecretsSource, SecretsOperationOptions, SecretsModuleConfig, Secrets, SecretRequestSeverity, SecretLifecycleRequest, Secret, User as ScimUser, ScimResult, ScimListResponse, ScimError, SSOValidators, SSOHandlerConfig, SSOConfig, SSO, Role, ResolvedLfvSecretsConfig, RemoteConfig, Photo, PhoneNumber, OidcCallbackParams, Name, MultipleTenantsForUserError, MetaData, MagicLinkStore, MagicLink, LoginConfig, Logger, ListResult, LfvSecretsConfig, JwtBearerWorkloadConfig, JWTAssertionClaims, InMemoryTenantStoreOptions, InMemoryTenantStore, IdTokenClaims, IAMValidators, IAMUsersInbound, IAMHandlerConfig, IAMGroupsOutbound, IAMGroupsInbound, IAMConfig, IAM, GroupsInboundHandlerConfig, GroupStore, GroupSortOptions, GroupSortField, GroupResource, GroupMember, GroupListOptions, Group, GcpSecretsConfig, FrameworkWorkloadIncomingOutgoing, FrameworkWorkloadConfig, FrameworkSecretsSourceConfig, FrameworkSecretsModuleConfig, FrameworkConfig, EnvironmentType, EnterpriseUser, EnterpriseStandardFromConfig, EnterpriseStandardBase, EnterpriseStandard, EnterpriseExtension, Email, ESValidators, ESRoutingOptions, ESRouteModule, ESRouteFilterResult, ESResolvedRoute, ESModuleFromConfig, ESConfigChangeResult, ESConfigChangeOptions, ESConfigChangeCallback, ESConfig, DevSecretsConfig, DEFAULT_TENANT_UI_NAMESPACE, DEFAULT_TENANT_API_NAMESPACE, CreateUserOptions, CreateTenantResponse, CreateTenantRequest, CreateGroupOptions, ConfigSourceType, ConfigSource, ClientCredentialsWorkloadConfig, CachedWorkloadToken, CIAMValidators, CIAMConfigFromCode, CIAMConfig, CIAM, BaseUser, AzureSecretsConfig, AwsSecretsConfig, AwsAuthMethod, ApplicationValidators, Address };
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
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};
|
|
1
|
+
import{I as B,a as D0,b as T0,c as $0,d as f0,e as x0,f as A0,g as Q0,h as X0,i as Z0,j as G0,k as R0,l as Y0,m as c0,n as y0,o as z0,p as B0,q as H0,t as N0,u as W0,v as C0,w as M0,x as _0}from"./shared/core-gqcvxn3w.js";var k="0.0.12";var V=["sessionStore","userStore","groupStore","tokenStore","magicLinkStore"];function C(L){if(L===null||typeof L!=="object")return L;let T={};for(let[J,D]of Object.entries(L)){if(V.includes(J)||J==="validators")continue;T[J]=D!==null&&typeof D==="object"&&!Array.isArray(D)&&Object.getPrototypeOf(D)===Object.prototype?C(D):D}return T}function E(L){return C(L)}function z(L,T,J,D){let $=T.length,A=D??L,f=A>0?Math.floor(J/A)+1:1,x=A>0?Math.ceil(L/A):0;return{total:L,count:$,items:T,size:A,page:f,pages:x}}class N extends Error{constructor(L,T){super(L,T);this.name="TenantRequestError",Object.setPrototypeOf(this,N.prototype)}}class c extends Error{userId;tenantIds;constructor(L,T,J){super(`Multiple tenants found for user id "${L}"`,J);this.name="MultipleTenantsForUserError",this.userId=L,this.tenantIds=T,Object.setPrototypeOf(this,c.prototype)}}var H=Number.POSITIVE_INFINITY;class M{tenants=new Map;tenantEsMap=new Map;userTenantIds=new Map;ttl;userMode;createEs;findTenantByUserId;findTenantsByUserId;constructor(L){if(this.ttl=O(L.ttl),this.userMode=L.userMode,this.createEs=L.createEs,this.userMode==="singleTenantOnly"){this.findTenantByUserId=this.findSingleTenantByUserId.bind(this),this.findTenantsByUserId=void 0;return}this.findTenantByUserId=void 0,this.findTenantsByUserId=this.findMultipleTenantsByUserId.bind(this)}async get(L){return this.tenants.get(L)??null}async list(L){let T=Array.from(this.tenants.values()),J=Math.max(0,L?.start??0),D=L?.limit,$=L?.sort;if($?.length)T=[...T].sort((X,G)=>{for(let{field:Z,direction:q}of $){let F=X[Z],U=G[Z],y=j(F,U);if(y!==0)return q==="desc"?-y:y}return 0});let A=T.length,f=D!=null?J+D:void 0,x=T.slice(J,f);return z(A,x,J,D)}async upsert(L){let T=new Date,J=this.tenants.get(L.tenantId),D={...J??{},...L,companyId:L.companyId??J?.companyId??"",companyName:L.companyName??J?.companyName??"",environmentType:L.environmentType??J?.environmentType??"DEV",email:L.email??J?.email,webhookUrl:L.webhookUrl??J?.webhookUrl,callbackUrl:L.callbackUrl??J?.callbackUrl,tenantUrl:L.tenantUrl??J?.tenantUrl,status:L.status??J?.status??"completed",createdAt:L.createdAt??J?.createdAt??T,updatedAt:L.updatedAt??T};return this.tenants.set(D.tenantId,D),this.tenantEsMap.delete(D.tenantId),D}async delete(L){this.tenantEsMap.delete(L),this.tenants.delete(L)}async getEs(L){let T=await this.get(L);if(!T)throw Error(`Tenant "${L}" not found`);if(!this.createEs)throw Error("InMemoryTenantStore requires options.createEs to use getEs()");if(this.ttl===0)return this.createEs(B(T));let J=Date.now(),D=this.tenantEsMap.get(L);if(D&&D.expiresAt>J)return D.es;if(D)this.tenantEsMap.delete(L);let $=this.createEs(B(T));return this.tenantEsMap.set(L,{es:$,expiresAt:g(J,this.ttl)}),$}getCachedTenantIds(){if(this.ttl===0)return[];let L=Date.now();for(let[T,J]of this.tenantEsMap.entries())if(J.expiresAt<=L)this.tenantEsMap.delete(T);return Array.from(this.tenantEsMap.keys())}async registerUserTenantId(L,T){if(!L)return;let J=S(T);if(this.userMode==="singleTenantOnly"){this.userTenantIds.set(L,new Set([J]));return}let D=this.userTenantIds.get(L);if(D){D.add(J);return}this.userTenantIds.set(L,new Set([J]))}async findSingleTenantByUserId(L){let T=await this.resolveTenantsByUserId(L);if(T.length>1)throw new c(L,T.map((J)=>J.tenantId));return T[0]??null}async findMultipleTenantsByUserId(L){return this.resolveTenantsByUserId(L)}async resolveTenantsByUserId(L){let T=this.userTenantIds.get(L);if(!T||T.size===0)return[];let J=T.has(null),D=Array.from(T).filter((f)=>f!=null);if(D.length===0)return[];let $=await Promise.all(D.map(async(f)=>({tenantId:f,tenant:await this.get(f)}))),A=$.filter((f)=>f.tenant!=null).map((f)=>f.tenantId);if(A.length===0){if(J)this.userTenantIds.set(L,new Set([null]));else this.userTenantIds.delete(L);return[]}if(A.length!==D.length){let f=J?[null,...A]:A;this.userTenantIds.set(L,new Set(f))}return $.map((f)=>f.tenant).filter((f)=>f!=null)}}function j(L,T){let J=L===void 0||L===null,D=T===void 0||T===null;if(J&&D)return 0;if(J)return 1;if(D)return-1;if(L instanceof Date&&T instanceof Date)return L.getTime()-T.getTime();let $=String(L),A=String(T);return $.localeCompare(A)}function S(L){if(typeof L!=="string")return null;return L.trim()||null}function O(L){if(L===void 0)return H;if(L<=0)return L===0?0:H;return L}function g(L,T){if(!Number.isFinite(T))return H;return L+T}function I(L,T,J){return(async()=>{try{let D=await fetch(L,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(T)});if(!D.ok)J.error(`Failed to send webhook update: ${D.status} ${D.statusText}`)}catch(D){J.error("Failed to send webhook update:",D)}})()}async function P(L,T,J){return I(L,T,J)}var p={beforeTenantSegments:["ui"]},m={beforeTenantSegments:["api"]};function _(L){return{segments:W(L?.segments)}}function W(L){return(L??[]).map((T)=>T.trim()).filter(Boolean)}function h(L){let T=L.trim();if(!T)return"/";let J=T.replace(/\\/g,"/").replace(/\/+/g,"/");return J.startsWith("/")?J:`/${J}`}function K(L){return h(L).split("/").filter(Boolean)}function R(L){return{beforeTenantSegments:W(L?.beforeTenantSegments),afterTenantSegments:W(L?.afterTenantSegments)}}function b(L){if(!L||L.type===void 0||L.type==="path"){let J=L;return{type:"path",ui:R(J?.ui),api:R(J?.api)}}let T=L;return{...T,ui:_(T.ui),api:_(T.api)}}function o(L,T){let J=R(T),D=J.beforeTenantSegments??[],$=J.afterTenantSegments??[],A=K(L),f=D.length+1+$.length;if(A.length<f)return null;for(let Z=0;Z<D.length;Z++)if(A[Z]!==D[Z])return null;let x=D.length,X=A[x];if(!X)return null;for(let Z=0;Z<$.length;Z++)if(A[x+1+Z]!==$[Z])return null;let G=A.slice(x+1+$.length);return{tenantId:decodeURIComponent(X),restSegments:G,restPath:G.length>0?`/${G.join("/")}`:"/"}}function n(L,T="/",J){let D=R(J),$=D.beforeTenantSegments??[],A=D.afterTenantSegments??[],f=K(T),x=[...$,encodeURIComponent(L),...A,...f];return x.length>0?`/${x.join("/")}`:"/"}function Q(L,T,J,D,$){if(L===void 0||L===null){if(J)D.push({message:`${T} is required`,path:$});return}if(typeof L!=="string"){D.push({message:`${T} must be a string`,path:$});return}return L}function Y(L,T,J,D){if(L===void 0||L===null)return;if(typeof L!=="boolean"){J.push({message:`${T} must be a boolean`,path:D});return}return L}function v(L,T,J){if(L===void 0||L===null)return;if(typeof L!=="object"||L===null){T.push({message:"name must be an object",path:J});return}let D=L,$={};return $.formatted=Q(D.formatted,"formatted",!1,T,[...J,"formatted"]),$.familyName=Q(D.familyName,"familyName",!1,T,[...J,"familyName"]),$.givenName=Q(D.givenName,"givenName",!1,T,[...J,"givenName"]),$.middleName=Q(D.middleName,"middleName",!1,T,[...J,"middleName"]),$.honorificPrefix=Q(D.honorificPrefix,"honorificPrefix",!1,T,[...J,"honorificPrefix"]),$.honorificSuffix=Q(D.honorificSuffix,"honorificSuffix",!1,T,[...J,"honorificSuffix"]),$}function d(L,T,J){if(L===void 0||L===null)return;if(!Array.isArray(L)){T.push({message:"emails must be an array",path:J});return}let D=[];for(let $=0;$<L.length;$++){let A=L[$],f=[...J,$];if(typeof A!=="object"||A===null){T.push({message:"email must be an object",path:f});continue}let x=A,X=Q(x.value,"value",!0,T,[...f,"value"]);if(X)D.push({value:X,display:Q(x.display,"display",!1,T,[...f,"display"]),type:Q(x.type,"type",!1,T,[...f,"type"]),primary:Y(x.primary,"primary",T,[...f,"primary"])})}return D.length>0?D:void 0}function r(L,T,J){if(L===void 0||L===null)return;if(!Array.isArray(L)){T.push({message:"phoneNumbers must be an array",path:J});return}let D=[];for(let $=0;$<L.length;$++){let A=L[$],f=[...J,$];if(typeof A!=="object"||A===null){T.push({message:"phoneNumber must be an object",path:f});continue}let x=A,X=Q(x.value,"value",!0,T,[...f,"value"]);if(X)D.push({value:X,display:Q(x.display,"display",!1,T,[...f,"display"]),type:Q(x.type,"type",!1,T,[...f,"type"]),primary:Y(x.primary,"primary",T,[...f,"primary"])})}return D.length>0?D:void 0}function l(L,T,J){if(L===void 0||L===null)return;if(!Array.isArray(L)){T.push({message:"addresses must be an array",path:J});return}let D=[];for(let $=0;$<L.length;$++){let A=L[$],f=[...J,$];if(typeof A!=="object"||A===null){T.push({message:"address must be an object",path:f});continue}let x=A;D.push({formatted:Q(x.formatted,"formatted",!1,T,[...f,"formatted"]),streetAddress:Q(x.streetAddress,"streetAddress",!1,T,[...f,"streetAddress"]),locality:Q(x.locality,"locality",!1,T,[...f,"locality"]),region:Q(x.region,"region",!1,T,[...f,"region"]),postalCode:Q(x.postalCode,"postalCode",!1,T,[...f,"postalCode"]),country:Q(x.country,"country",!1,T,[...f,"country"]),type:Q(x.type,"type",!1,T,[...f,"type"]),primary:Y(x.primary,"primary",T,[...f,"primary"])})}return D.length>0?D:void 0}function t(L,T,J){if(L===void 0||L===null)return;if(!Array.isArray(L)){T.push({message:"groups must be an array",path:J});return}let D=[];for(let $=0;$<L.length;$++){let A=L[$],f=[...J,$];if(typeof A!=="object"||A===null){T.push({message:"group must be an object",path:f});continue}let x=A,X=Q(x.value,"value",!0,T,[...f,"value"]);if(X)D.push({value:X,$ref:Q(x.$ref,"$ref",!1,T,[...f,"$ref"]),display:Q(x.display,"display",!1,T,[...f,"display"]),type:Q(x.type,"type",!1,T,[...f,"type"])})}return D.length>0?D:void 0}function i(L,T,J){if(L===void 0||L===null)return;if(!Array.isArray(L)){T.push({message:"roles must be an array",path:J});return}let D=[];for(let $=0;$<L.length;$++){let A=L[$],f=[...J,$];if(typeof A!=="object"||A===null){T.push({message:"role must be an object",path:f});continue}let x=A,X=Q(x.value,"value",!0,T,[...f,"value"]);if(X)D.push({value:X,display:Q(x.display,"display",!1,T,[...f,"display"]),type:Q(x.type,"type",!1,T,[...f,"type"]),primary:Y(x.primary,"primary",T,[...f,"primary"])})}return D.length>0?D:void 0}function u(L,T,J){if(L===void 0||L===null)return;if(typeof L!=="object"||L===null){T.push({message:"Enterprise User extension must be an object",path:J});return}let D=L,$={};if($.employeeNumber=Q(D.employeeNumber,"employeeNumber",!1,T,[...J,"employeeNumber"]),$.costCenter=Q(D.costCenter,"costCenter",!1,T,[...J,"costCenter"]),$.organization=Q(D.organization,"organization",!1,T,[...J,"organization"]),$.division=Q(D.division,"division",!1,T,[...J,"division"]),$.department=Q(D.department,"department",!1,T,[...J,"department"]),D.manager!==void 0&&D.manager!==null)if(typeof D.manager!=="object"||D.manager===null)T.push({message:"manager must be an object",path:[...J,"manager"]});else{let A=D.manager;$.manager={value:Q(A.value,"value",!1,T,[...J,"manager","value"]),$ref:Q(A.$ref,"$ref",!1,T,[...J,"manager","$ref"]),displayName:Q(A.displayName,"displayName",!1,T,[...J,"manager","displayName"])}}return $}function a(L){return{"~standard":{version:1,vendor:L,validate:(T)=>{if(typeof T!=="object"||T===null)return{issues:[{message:"Expected an object"}]};let J=T,D=[],$={},A=Q(J.userName,"userName",!0,D,["userName"]);if(!A)return{issues:D};$.userName=A,$.id=Q(J.id,"id",!1,D,["id"]),$.externalId=Q(J.externalId,"externalId",!1,D,["externalId"]),$.displayName=Q(J.displayName,"displayName",!1,D,["displayName"]),$.nickName=Q(J.nickName,"nickName",!1,D,["nickName"]),$.profileUrl=Q(J.profileUrl,"profileUrl",!1,D,["profileUrl"]),$.title=Q(J.title,"title",!1,D,["title"]),$.userType=Q(J.userType,"userType",!1,D,["userType"]),$.preferredLanguage=Q(J.preferredLanguage,"preferredLanguage",!1,D,["preferredLanguage"]),$.locale=Q(J.locale,"locale",!1,D,["locale"]),$.timezone=Q(J.timezone,"timezone",!1,D,["timezone"]),$.password=Q(J.password,"password",!1,D,["password"]),$.active=Y(J.active,"active",D,["active"]),$.name=v(J.name,D,["name"]),$.emails=d(J.emails,D,["emails"]),$.phoneNumbers=r(J.phoneNumbers,D,["phoneNumbers"]),$.addresses=l(J.addresses,D,["addresses"]),$.groups=t(J.groups,D,["groups"]),$.roles=i(J.roles,D,["roles"]);let f="urn:ietf:params:scim:schemas:extension:enterprise:2.0:User";if(J[f]!==void 0)$[f]=u(J[f],D,[f]);if(J.schemas!==void 0)if(Array.isArray(J.schemas))$.schemas=J.schemas.filter((x)=>typeof x==="string");else D.push({message:"schemas must be an array",path:["schemas"]});if(J.meta!==void 0)if(typeof J.meta==="object"&&J.meta!==null){let x=J.meta;$.meta={resourceType:typeof x.resourceType==="string"?x.resourceType:void 0,created:typeof x.created==="string"?x.created:void 0,lastModified:typeof x.lastModified==="string"?x.lastModified:void 0,location:typeof x.location==="string"?x.location:void 0,version:typeof x.version==="string"?x.version:void 0}}else D.push({message:"meta must be an object",path:["meta"]});if(D.length>0)return{issues:D};return{value:$}}}}}function e(L,T,J){if(L===void 0||L===null)return;if(!Array.isArray(L)){T.push({message:"members must be an array",path:J});return}let D=[];for(let $=0;$<L.length;$++){let A=L[$],f=[...J,$];if(typeof A!=="object"||A===null){T.push({message:"member must be an object",path:f});continue}let x=A,X=Q(x.value,"value",!0,T,[...f,"value"]);if(X){let G=Q(x.type,"type",!1,T,[...f,"type"]);D.push({value:X,$ref:Q(x.$ref,"$ref",!1,T,[...f,"$ref"]),display:Q(x.display,"display",!1,T,[...f,"display"]),type:G==="User"||G==="Group"?G:void 0})}}return D.length>0?D:void 0}function s(L){return{"~standard":{version:1,vendor:L,validate:(T)=>{if(typeof T!=="object"||T===null)return{issues:[{message:"Expected an object"}]};let J=T,D=[],$={},A=Q(J.displayName,"displayName",!0,D,["displayName"]);if(!A)return{issues:D};if($.displayName=A,$.id=Q(J.id,"id",!1,D,["id"]),$.externalId=Q(J.externalId,"externalId",!1,D,["externalId"]),$.members=e(J.members,D,["members"]),J.schemas!==void 0)if(Array.isArray(J.schemas))$.schemas=J.schemas.filter((f)=>typeof f==="string");else D.push({message:"schemas must be an array",path:["schemas"]});if(J.meta!==void 0)if(typeof J.meta==="object"&&J.meta!==null){let f=J.meta;$.meta={resourceType:typeof f.resourceType==="string"?f.resourceType:void 0,created:typeof f.created==="string"?f.created:void 0,lastModified:typeof f.lastModified==="string"?f.lastModified:void 0,location:typeof f.location==="string"?f.location:void 0,version:typeof f.version==="string"?f.version:void 0}}else D.push({message:"meta must be an object",path:["meta"]});if(D.length>0)return{issues:D};return{value:$}}}}}function J0(L){return{"~standard":{version:1,vendor:L,validate:(T)=>{if(typeof T!=="object"||T===null)return{issues:[{message:"Expected an object"}]};let J=T,D=[],$={...J},A=["iss","sub"];for(let X of A)if(X in J){if(typeof J[X]!=="string")D.push({message:`${X} must be a string`,path:[X]})}else D.push({message:`${X} is required`,path:[X]});if("aud"in J&&J.aud!==void 0){let X=J.aud;if(typeof X!=="string"&&!Array.isArray(X))D.push({message:"aud must be a string or array of strings",path:["aud"]});else if(Array.isArray(X)&&!X.every((G)=>typeof G==="string"))D.push({message:"aud array must contain only strings",path:["aud"]})}let f=["jti","scope"];for(let X of f)if(X in J&&J[X]!==void 0){if(typeof J[X]!=="string")D.push({message:`${X} must be a string`,path:[X]})}let x=["exp","iat"];for(let X of x)if(X in J){if(typeof J[X]!=="number")D.push({message:`${X} must be a number`,path:[X]})}else D.push({message:`${X} is required`,path:[X]});if(D.length>0)return{issues:D};return{value:$}}}}}function L0(L){return{"~standard":{version:1,vendor:L,validate:(T)=>{if(typeof T!=="object"||T===null)return{issues:[{message:"Expected an object"}]};let J=T,D=[],$={};if("access_token"in J)if(typeof J.access_token==="string")$.access_token=J.access_token;else D.push({message:"access_token must be a string",path:["access_token"]});else D.push({message:"access_token is required",path:["access_token"]});if("token_type"in J)if(typeof J.token_type==="string")$.token_type=J.token_type;else D.push({message:"token_type must be a string",path:["token_type"]});else D.push({message:"token_type is required",path:["token_type"]});if("scope"in J)if(typeof J.scope==="string"||J.scope===void 0)$.scope=J.scope;else D.push({message:"scope must be a string",path:["scope"]});if("refresh_token"in J)if(typeof J.refresh_token==="string"||J.refresh_token===void 0)$.refresh_token=J.refresh_token;else D.push({message:"refresh_token must be a string",path:["refresh_token"]});if("expires"in J)if(typeof J.expires==="string"||J.expires===void 0)$.expires=J.expires;else D.push({message:"expires must be a string",path:["expires"]});if("expires_in"in J)if(typeof J.expires_in==="number"||J.expires_in===void 0)$.expires_in=J.expires_in;else D.push({message:"expires_in must be a number",path:["expires_in"]});if(D.length>0)return{issues:D};return{value:$}}}}}export{L0 as workloadTokenResponseSchema,f0 as withValidate,G0 as waitOn,k as version,A0 as validationFailureResponse,a as userSchema,T0 as tokenResponseSchema,X0 as stripJsonComments,y0 as silentLogger,W0 as setActiveSession,E as serializeESConfig,P as sendTenantWebhook,Z0 as parseJsonc,D0 as oidcCallbackSchema,b as normalizeTenantRoutingStrategy,R as normalizeTenantPathNamespace,x0 as must,Q0 as mergeConfig,o as matchTenantPath,M0 as listSsoClientIdsFromCookies,z as list,J0 as jwtAssertionClaimsSchema,z0 as infoLogger,$0 as idTokenClaimsSchema,s as groupResourceSchema,N0 as getActiveSession,_0 as findTenantFromStateParam,c0 as defaultLogger,Y0 as decodeUser,B0 as debugLogger,H0 as consoleLogger,C0 as clearActiveSession,R0 as claimsToUser,n as buildTenantPath,N as TenantRequestError,c as MultipleTenantsForUserError,M as InMemoryTenantStore,p as DEFAULT_TENANT_UI_NAMESPACE,m as DEFAULT_TENANT_API_NAMESPACE};
|
package/dist/server.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { StandardSchemaV1 as
|
|
1
|
+
import { StandardSchemaV1 as StandardSchemaV18 } from "@standard-schema/spec";
|
|
2
2
|
import { StandardSchemaV1 as StandardSchemaV15 } from "@standard-schema/spec";
|
|
3
3
|
/**
|
|
4
4
|
* Minimal logger interface compatible with common patterns (console, pino, winston, etc.)
|
|
@@ -726,6 +726,11 @@ type StoredUser<TExtended = object> = User2 & {
|
|
|
726
726
|
*/
|
|
727
727
|
id: string;
|
|
728
728
|
/**
|
|
729
|
+
* Optional Enterprise Standard tenant identifier for tenant-aware apps.
|
|
730
|
+
* Built-in user stores can use this when registering HRD mappings.
|
|
731
|
+
*/
|
|
732
|
+
tenantId?: string;
|
|
733
|
+
/**
|
|
729
734
|
* Timestamp when the user was first stored.
|
|
730
735
|
*/
|
|
731
736
|
createdAt: Date;
|
|
@@ -2011,6 +2016,47 @@ type AzureSecretsConfig = {
|
|
|
2011
2016
|
*/
|
|
2012
2017
|
ttl?: number;
|
|
2013
2018
|
};
|
|
2019
|
+
type EnvironmentType = "POC" | "DEV" | "QA" | "PROD";
|
|
2020
|
+
type TenantStatus = "pending" | "processing" | "completed" | "failed" | "action_required";
|
|
2021
|
+
type TenantSecretsConfig = LfvSecretsConfig | (VaultSecretsConfig & {
|
|
2022
|
+
path: string;
|
|
2023
|
+
retryInterval?: number;
|
|
2024
|
+
}) | (DevSecretsConfig & {
|
|
2025
|
+
path?: string;
|
|
2026
|
+
appId?: string;
|
|
2027
|
+
}) | (AwsSecretsConfig & {
|
|
2028
|
+
ttl?: number;
|
|
2029
|
+
}) | AzureSecretsConfig | (GcpSecretsConfig & {
|
|
2030
|
+
ttl?: number;
|
|
2031
|
+
}) | {
|
|
2032
|
+
type: "localFile";
|
|
2033
|
+
path?: string;
|
|
2034
|
+
watch?: boolean;
|
|
2035
|
+
ttl?: number;
|
|
2036
|
+
};
|
|
2037
|
+
type TenantConfigSourceInput = TenantSecretsConfig | ConfigSource;
|
|
2038
|
+
type TenantBaseRecord = {
|
|
2039
|
+
tenantId: string;
|
|
2040
|
+
companyId: string;
|
|
2041
|
+
companyName: string;
|
|
2042
|
+
environmentType: EnvironmentType;
|
|
2043
|
+
email?: string;
|
|
2044
|
+
webhookUrl?: string;
|
|
2045
|
+
callbackUrl?: string;
|
|
2046
|
+
tenantUrl?: string;
|
|
2047
|
+
status: TenantStatus;
|
|
2048
|
+
error?: string;
|
|
2049
|
+
actionUrl?: string;
|
|
2050
|
+
requestToken?: string;
|
|
2051
|
+
expiresAt?: string;
|
|
2052
|
+
createdAt: Date;
|
|
2053
|
+
updatedAt: Date;
|
|
2054
|
+
/** Persisted tenant config metadata, or a runtime ConfigSource for internal-only tenants. */
|
|
2055
|
+
configSource: TenantConfigSourceInput;
|
|
2056
|
+
/** Runtime helper that returns a ConfigSource for this tenant. */
|
|
2057
|
+
config: () => ConfigSource;
|
|
2058
|
+
};
|
|
2059
|
+
type StoredTenant<TExtended extends object = Record<string, never>> = TenantBaseRecord & TExtended;
|
|
2014
2060
|
type ESValidators = {
|
|
2015
2061
|
sso: SSOValidators;
|
|
2016
2062
|
iam: IAMValidators;
|
|
@@ -2054,6 +2100,25 @@ type RemoteConfig = {
|
|
|
2054
2100
|
secrets?: SecretsModuleConfig;
|
|
2055
2101
|
ciam?: CIAMConfig;
|
|
2056
2102
|
};
|
|
2103
|
+
type ConfigSource = {
|
|
2104
|
+
load(): Promise<RemoteConfig>;
|
|
2105
|
+
/**
|
|
2106
|
+
* Called when the config changes.
|
|
2107
|
+
* @param onConfig - The callback to call when the config changes.
|
|
2108
|
+
* @return an unsubscribe/cleanup function.
|
|
2109
|
+
*/
|
|
2110
|
+
subscribe(onConfig: (config: RemoteConfig) => void): undefined | (() => void);
|
|
2111
|
+
/**
|
|
2112
|
+
* Optional. If not set by the creator, the framework may set this before calling load/subscribe
|
|
2113
|
+
* so the source can use the same logger.
|
|
2114
|
+
*/
|
|
2115
|
+
logger?: Logger;
|
|
2116
|
+
/**
|
|
2117
|
+
* Optional. If not set by the creator, the framework may set this before calling load/subscribe
|
|
2118
|
+
* so the source can use the same validators.
|
|
2119
|
+
*/
|
|
2120
|
+
validators?: ESValidators;
|
|
2121
|
+
};
|
|
2057
2122
|
type AggregateWorkload = Omit<Workload, "getToken"> & {
|
|
2058
2123
|
getToken: (client: string, scope?: string) => Promise<string>;
|
|
2059
2124
|
getServerToken: (scope?: string) => Promise<string>;
|
|
@@ -2180,8 +2245,8 @@ interface MagicLinkStore<TExtended = object> {
|
|
|
2180
2245
|
* baseUser includes a top-level .validate() for a cleaner API (see withValidate).
|
|
2181
2246
|
*/
|
|
2182
2247
|
type CIAMValidators = {
|
|
2183
|
-
baseUser:
|
|
2184
|
-
validate(value: unknown): Promise<
|
|
2248
|
+
baseUser: StandardSchemaV18<unknown, BaseUser> & {
|
|
2249
|
+
validate(value: unknown): Promise<StandardSchemaV18.Result<BaseUser>>;
|
|
2185
2250
|
};
|
|
2186
2251
|
};
|
|
2187
2252
|
type CIAMConfig<
|
|
@@ -2305,6 +2370,10 @@ declare function ciam<
|
|
|
2305
2370
|
* Only checks CIAM; does not check SSO.
|
|
2306
2371
|
*/
|
|
2307
2372
|
declare function getCIAMUser(request: Request, es: EnterpriseStandard): Promise<User2 | undefined>;
|
|
2373
|
+
type TenantConfigSourceFactory = (config: TenantSecretsConfig) => ConfigSource;
|
|
2374
|
+
declare function registerTenantConfigSourceFactory(factory: TenantConfigSourceFactory): void;
|
|
2375
|
+
declare function tenantConfigSource(tenant: Pick<StoredTenant, "configSource">): ConfigSource;
|
|
2376
|
+
declare function withTenantConfigMethod<TExtended extends object>(tenant: Omit<StoredTenant<TExtended>, "config">): StoredTenant<TExtended>;
|
|
2308
2377
|
/**
|
|
2309
2378
|
* Verifies the JWT signature using the given JWKS URI (cached), then decodes and
|
|
2310
2379
|
* returns the User. Throws on invalid or expired token.
|
|
@@ -2315,4 +2384,4 @@ declare function getCIAMUser(request: Request, es: EnterpriseStandard): Promise<
|
|
|
2315
2384
|
* @throws If the JWT is invalid, signature verification fails, or the token is expired.
|
|
2316
2385
|
*/
|
|
2317
2386
|
declare function verifyUser(jwt: string, jwksUri: string): Promise<User2>;
|
|
2318
|
-
export { verifyUser, sso, logoutBackChannel2 as logoutBackChannel, logout, initiateLogin, iam, getSSOorCIAMUser, getSSOUser, getRequiredSSOorCIAMUser, getCIAMUser, ciam, callback, UsersInboundHandlerConfig, StateCookie, ScimResult, ScimListResponse, ScimError, SSOValidators, SSOHandlerConfig, SSOConfig, SSO, LoginConfig, IAMValidators, IAMUsersInbound, IAMHandlerConfig, IAMGroupsOutbound, IAMGroupsInbound, IAMConfig, IAM, GroupsInboundHandlerConfig, CreateUserOptions, CreateGroupOptions, CIAMValidators, CIAMConfigFromCode, CIAMConfig, CIAM };
|
|
2387
|
+
export { withTenantConfigMethod, verifyUser, tenantConfigSource, sso, registerTenantConfigSourceFactory, logoutBackChannel2 as logoutBackChannel, logout, initiateLogin, iam, getSSOorCIAMUser, getSSOUser, getRequiredSSOorCIAMUser, getCIAMUser, ciam, callback, UsersInboundHandlerConfig, TenantConfigSourceFactory, StateCookie, ScimResult, ScimListResponse, ScimError, SSOValidators, SSOHandlerConfig, SSOConfig, SSO, LoginConfig, IAMValidators, IAMUsersInbound, IAMHandlerConfig, IAMGroupsOutbound, IAMGroupsInbound, IAMConfig, IAM, GroupsInboundHandlerConfig, CreateUserOptions, CreateGroupOptions, CIAMValidators, CIAMConfigFromCode, CIAMConfig, CIAM };
|
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-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
|
+
import{A as _M,B as GM,C as JM,D as LM,E as DM,F as jM,G as IM,H as EM,I as PM,c as XM,d as YM,e,k as ZM,r as $M,s as FM,y as NM,z as VM}from"./shared/core-gqcvxn3w.js";function zM(W,D,j,h,q){if(!j&&!h)return;let E={...j,...h},Y={...E,signingKey:j?.signingKey,magicLinkTtl:E.magicLinkTtl??3600,sessionTtl:E.sessionTtl??86400,cookiesSecure:E.cookiesSecure!==void 0?E.cookiesSecure:!0,cookiesSameSite:E.cookiesSameSite!==void 0?E.cookiesSameSite:"Strict",cookiesPrefix:E.cookiesPrefix??(E.ciamId?`es.ciam.${E.ciamId}`:"es.ciam"),cookiesPath:E.cookiesPath??"/",sessionValidation:E.sessionValidation??"always"};function U(){if(!Y.signingKey)throw Error("Missing CIAM configuration field: signingKey. CIAM signingKey is required for JWT token signing and must be provided via Vault (ciam.signingKey).")}function g(){if(!Y.sessionStore)throw Error("Missing CIAM configuration field: sessionStore. CIAM sessionStore is required for server-side session tracking and backchannel logout.");return Y.sessionStore}function m(){U(),g()}function i(M=32){let A=new Uint8Array(M);return crypto.getRandomValues(A),Array.from(A,(X)=>X.toString(16).padStart(2,"0")).join("").substring(0,M)}function l(M){let A=typeof M==="string"?new TextEncoder().encode(M):M,X="";return A.forEach((Z)=>{X+=String.fromCharCode(Z)}),btoa(X).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function t(M){let A=M.replace(/-/g,"+").replace(/_/g,"/"),X=A.padEnd(A.length+(4-A.length%4)%4,"=");return atob(X)}async function x(){U();let M=new TextEncoder().encode(Y.signingKey??"");return crypto.subtle.importKey("raw",M,{name:"HMAC",hash:"SHA-256"},!1,["sign","verify"])}async function f(M){let X=l(JSON.stringify({alg:"HS256",typ:"JWT"})),Z=l(JSON.stringify(M)),K=`${X}.${Z}`,_=await x(),O=await crypto.subtle.sign("HMAC",_,new TextEncoder().encode(K)),I=l(new Uint8Array(O));return`${K}.${I}`}async function k(M){let A=M.split(".");if(A.length!==3)throw Error("Invalid JWT");let[X,Z,K]=A,_=`${X}.${Z}`,O=await x(),I=new Uint8Array(t(K).split("").map((T)=>T.charCodeAt(0)));if(!await crypto.subtle.verify("HMAC",O,I,new TextEncoder().encode(_)))throw Error("Invalid JWT signature");let u=t(Z),c=JSON.parse(u);if(typeof c.exp==="number"&&c.exp<Math.floor(Date.now()/1000))throw Error("Token expired");return c}function B(M,A,X){if(!Y)throw Error("Enterprise Standard CIAM Manager not initialized");if(M=`${Y.cookiesPrefix}.${M}`,typeof A!=="string")A=btoa(JSON.stringify(A));let Z;if(X instanceof Date)Z=`Expires=${X.toUTCString()}`;else if(typeof X==="number")Z=`Max-Age=${X}`;else throw Error("Invalid expires type",X);if(A.length>4000)throw Error(`Error setting cookie: ${M}. Cookie length is: ${A.length}`);return`${M}=${A}; ${Z}; Path=${Y.cookiesPath}; HttpOnly;${Y.cookiesSecure?" Secure;":""} SameSite=${Y.cookiesSameSite};`}function G(M){if(!Y)throw Error("Enterprise Standard CIAM Manager not initialized");return`${Y.cookiesPrefix}.${M}=; Max-Age=0; Path=${Y.cookiesPath}; HttpOnly;${Y.cookiesSecure?" Secure;":""} SameSite=${Y.cookiesSameSite};`}function J(M,A,X=!1){if(!Y)throw Error("Enterprise Standard CIAM Manager not initialized");let Z=A.headers.get("cookie");if(!Z)return null;let K=`${Y.cookiesPrefix}.${M}`,_=Z.split(";").find((C)=>C.trim().startsWith(`${K}=`));if(!_)return null;let O=_.indexOf("="),I=_.substring(O+1).trim();if(!X)return I;try{let C=atob(I);return JSON.parse(C)}catch(C){return console.error(`[CIAM] Failed to parse cookie '${K}':`,C),null}}function P(M,A,X){let Z={expires_in:Y.sessionTtl??86400,token_type:"Bearer",expires:X.toISOString()};return[["Set-Cookie",B("access",M,X)],["Set-Cookie",B("id",A,X)],["Set-Cookie",B("control",Z,X)]]}function v(M){let A=J("access",M),X=J("id",M),Z=J("control",M,!0);if(!A||!X||!Z)return;if(Z.expires&&Date.now()>new Date(Z.expires).getTime())return;return{access:A,id:X,control:Z}}async function w(M){if(!Y)throw Error("Enterprise Standard CIAM Manager not initialized");m();try{let A=v(M);if(!A)return;let X=await k(A.access),Z=await k(A.id);if(!X.sid||!Z.sub)return;if(Y.sessionValidation!=="disabled"){if(!await g().get(X.sid))return}return z(Z)}catch(A){return}}async function b(M){let A=await w(M);if(A)return A;throw new Response("Unauthorized",{status:401,statusText:"Unauthorized"})}async function p(M){if(!Y)throw Error("Enterprise Standard CIAM Manager not initialized");m();try{let O=v(M);if(O){let I=await k(O.access);if(I.sid)await g().delete(I.sid)}}catch(O){console.warn("Failed to delete CIAM session:",O)}let A=[["Set-Cookie",G("access")],["Set-Cookie",G("id")],["Set-Cookie",G("control")]],Z=new URL(M.url).searchParams.get("redirect");if(Z)return new Response("Logged out",{status:302,headers:[["Location",Z],...A]});let K=M.headers.get("accept");if(K?.includes("application/json")||K?.includes("text/javascript"))return new Response(JSON.stringify({success:!0,message:"Logged out"}),{status:200,headers:[["Content-Type","application/json"],...A]});return new Response("Logout Complete",{status:200,headers:[["Content-Type","text/plain"],...A]})}async function y(M){if(!Y)throw Error("Enterprise Standard CIAM Manager not initialized");m();try{let A=M.headers.get("content-type");if(!A||!A.includes("application/x-www-form-urlencoded"))return new Response("Invalid Content-Type, expected application/x-www-form-urlencoded",{status:400});let X=await M.text(),K=new URLSearchParams(X).get("logout_token");if(!K)return new Response("Missing logout_token parameter",{status:400});let O=(await k(K)).sid;if(!O)return new Response("Invalid logout_token: missing sid claim",{status:400});return await g().delete(O),new Response("OK",{status:200})}catch(A){return console.error("Error during CIAM back-channel logout:",A),new Response("Internal Server Error",{status:500})}}function S(M){return M.id||M.email||`ciam-${M.userName}`}function V(M,A,X){return{sub:S(M),iss:"ciam",aud:"ciam",exp:Math.floor(X.getTime()/1000),iat:Math.floor(Date.now()/1000),email:M.email,name:M.name,preferred_username:M.userName,picture:M.avatar,sid:A}}function Q(M,A,X){return{sub:M,iss:"ciam",aud:"ciam",exp:Math.floor(X.getTime()/1000),iat:Math.floor(Date.now()/1000),sid:A,scope:"openid profile email"}}function z(M){let A=M.exp?new Date(M.exp*1000):new Date;return{id:M.sub,userName:M.preferred_username??"",name:M.name??"",email:M.email??"",avatar:M.picture,userType:"customer",sso:{profile:M,tenant:{id:"ciam",name:"CIAM"},scope:"openid profile email",tokenType:"Bearer",expires:A}}}async function H(M){if(!Y)throw Error("Enterprise Standard CIAM Manager not initialized");if(!q)return new Response(JSON.stringify({error:"Workload authentication required"}),{status:401,headers:{"Content-Type":"application/json"}});if(!await q.getWorkloadIdentity(M))return new Response(JSON.stringify({error:"Unauthorized: Valid workload token required"}),{status:401,headers:{"Content-Type":"application/json"}});let X,Z;try{let n=M.headers.get("content-type");if(!n||!n.includes("application/json"))return new Response(JSON.stringify({error:"Content-Type must be application/json"}),{status:400,headers:{"Content-Type":"application/json"}});let a=await M.text(),R=JSON.parse(a);if(Z=typeof R?.redirect==="string"&&R.redirect.length>0?R.redirect:void 0,X={userName:R.userName,name:R.name,email:R.email,avatar:R.avatar},!X.userName||!X.name||!X.email)return new Response(JSON.stringify({error:"Missing required fields: userName, name, email"}),{status:400,headers:{"Content-Type":"application/json"}})}catch(n){return new Response(JSON.stringify({error:"Invalid JSON in request body"}),{status:400,headers:{"Content-Type":"application/json"}})}let _=new URL(M.url).searchParams.get("ttl"),O=_?parseInt(_,10):Y.magicLinkTtl??3600;if(Number.isNaN(O)||O<=0)return new Response(JSON.stringify({error:"Invalid TTL parameter"}),{status:400,headers:{"Content-Type":"application/json"}});let I=i(32),C=new Date(Date.now()+O*1000);if(!Y.magicLinkStore)return new Response(JSON.stringify({error:"Magic link store not configured"}),{status:500,headers:{"Content-Type":"application/json"}});try{await Y.magicLinkStore.create(I,X,C)}catch(n){return console.error("Error creating magic link:",n),new Response(JSON.stringify({error:"Failed to create magic link"}),{status:500,headers:{"Content-Type":"application/json"}})}let u=new URL(M.url),c=Y.magicLinkLoginUrl||"/magic-link/login",T=new URL(c,u.origin);if(T.searchParams.set("token",I),Z)T.searchParams.set("redirect",Z);return new Response(JSON.stringify({magicLink:T.toString(),expiresAt:C.toISOString()}),{status:200,headers:{"Content-Type":"application/json"}})}async function F(M){if(!Y)throw Error("Enterprise Standard CIAM Manager not initialized");m();let A=new URL(M.url),X=A.searchParams.get("token");if(!X){let L=Y.errorUrl||"/";return new Response("Redirecting to error URL",{status:302,headers:{Location:L}})}if(!Y.magicLinkStore){let L=Y.errorUrl||"/";return new Response("Redirecting to error URL",{status:302,headers:{Location:L}})}let Z=await Y.magicLinkStore.get(X);if(!Z){let L=Y.errorUrl||"/";return new Response("Redirecting to error URL",{status:302,headers:{Location:L}})}let K=new Date(Date.now()+(Y.sessionTtl??86400)*1000),_=i(32),O=S(Z.user),I=V(Z.user,_,K),C=Q(O,_,K),u=z(I);try{let L={sid:_,sub:O,createdAt:new Date,lastActivityAt:new Date};await g().create(L)}catch(L){console.warn("Failed to create session:",L)}if(Y.userStore)try{let L=u.id;if(L){let r=new Date,o=await Y.userStore.get(L);if(o||Y.enableJitUserProvisioning){let HM={...o??{},...u,id:L,tenantId:o?.tenantId,createdAt:o?.createdAt??r,updatedAt:r,userType:o?.userType??"customer"};await Y.userStore.upsert(HM)}}}catch(L){console.warn("Failed to store user:",L)}try{await Y.magicLinkStore.delete(X)}catch(L){console.warn("Failed to delete magic link:",L)}let c=await f(C),T=await f(I),n=Y.landingUrl||"/",a=A.searchParams.get("redirect"),R=n;if(a)if(a.startsWith("/"))R=a;else try{if(new URL(a).origin===new URL(M.url).origin)R=a}catch{}return new Response("Authentication successful, redirecting",{status:302,headers:[["Location",R],...P(c,T,K)]})}async function $(M){if(!Y)throw Error("Enterprise Standard CIAM Manager not initialized");m();let A=Y.magicLinkUrl||"/magic-link",X=Y.magicLinkLoginUrl||"/magic-link/login",Z=Y.logoutUrl||"/auth/logout",K=Y.logoutBackChannelUrl||"/auth/logout/backchannel",_=new URL(M.url).pathname,O=(T)=>{if(!T)return;try{return new URL(T).pathname}catch{return T.startsWith("/")?T:`/${T}`}};if(O(A)===_&&M.method==="POST")return H(M);if(O(X)===_&&M.method==="GET")return F(M);if(O(Z)===_&&M.method==="GET")return p(M);if(O(K)===_&&M.method==="POST")return y(M);return new Response("Not Found",{status:404})}return{...Y,getUser:w,getRequiredUser:b,logout:p,logoutBackChannel:y,handler:$}}async function BM(W,D){return e(D,"EnterpriseStandard instance is required. Create one with enterpriseStandard(source, config) and pass it to this function."),D.ciam?.getUser(W)}function N(W,D,j){return new Response(JSON.stringify({schemas:["urn:ietf:params:scim:api:messages:2.0:Error"],status:String(W),scimType:j,detail:D}),{status:W,headers:{"Content-Type":"application/scim+json"}})}function MM(W,D){let j=D?.totalResults??W.length,h=D?.startIndex??1,q=D?.itemsPerPage??W.length;return new Response(JSON.stringify({schemas:["urn:ietf:params:scim:api:messages:2.0:ListResponse"],totalResults:j,startIndex:h,itemsPerPage:q,Resources:W}),{status:200,headers:{"Content-Type":"application/scim+json"}})}function d(W,D=200){return new Response(JSON.stringify(W),{status:D,headers:{"Content-Type":"application/scim+json"}})}function s(W){return{schemas:["urn:ietf:params:scim:schemas:core:2.0:Group"],id:W.id,externalId:W.externalId,displayName:W.displayName,members:W.members,meta:{resourceType:"Group",created:W.createdAt.toISOString(),lastModified:W.updatedAt.toISOString()}}}function AM(){return crypto.randomUUID()}function SM(W,D,j,h,q){if(!h&&!q)return;let Y={...h,...q};function U(){if(!j)throw D.error?.("IAM requires workload configuration before use"),Error("IAM requires workload configuration");return j}async function g(){let B=U(),G=typeof B.getServerToken==="function"?await B.getServerToken():await B.getToken();return new Headers({"Content-Type":"application/scim+json",Accept:"application/scim+json",Authorization:`Bearer ${G}`})}async function m(B,G,J,P){if(!Y.url)throw Error("IAM URL not configured for outgoing requests");let v=`${Y.url}${G}`;try{let w=await g(),b=await fetch(v,{method:B,headers:w,body:J?JSON.stringify(J):void 0}),p=await b.json();if(!b.ok)return{success:!1,error:p,status:b.status};let y=await P["~standard"].validate(p);if(y.issues)return console.error("SCIM response validation failed:",y.issues),{success:!1,error:{schemas:["urn:ietf:params:scim:api:messages:2.0:Error"],status:"400",scimType:"invalidValue",detail:`Response validation failed: ${y.issues.map((S)=>S.message).join("; ")}`},status:400};return{success:!0,data:y.value,status:b.status}}catch(w){return{success:!1,error:{schemas:["urn:ietf:params:scim:api:messages:2.0:Error"],status:"500",detail:w instanceof Error?w.message:"Unknown error occurred"},status:500}}}function i(){return Y.url}let l,t;if(Y.url)t=async(G,J)=>{let P={...G,schemas:G.schemas??["urn:ietf:params:scim:schemas:core:2.0:User","urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"]};return m("POST","/Users",P,W.user)},l={createGroup:async(G,J)=>{let P={schemas:["urn:ietf:params:scim:schemas:core:2.0:Group"],displayName:G,externalId:J?.externalId,members:J?.members};return m("POST","/Groups",P,W.group)}};let x;if(Y.groupStore){let B=Y.groupStore,G=async(S)=>{let V=U(),Q=S.headers.get("Authorization");if(!Q||!Q.startsWith("Bearer "))return!1;try{let z=Q.substring(7);return(await V.validateToken(z)).valid}catch{return!1}},J=async(S,V)=>{if(!await G(S))return N(401,"Authorization required");let z=new URL(S.url),H=V?.basePath??"/Groups",F=z.pathname;if(F.startsWith(H))F=F.substring(H.length);let M=F.match(/^\/([^/]+)$/)?.[1],A=S.method;try{if(M)switch(A){case"GET":return await v(M);case"PUT":return await b(S,M);case"PATCH":return await p(S,M);case"DELETE":return await y(M);default:return N(405,"Method not allowed")}else if(F===""||F==="/")switch(A){case"GET":return await P(S);case"POST":return await w(S);default:return N(405,"Method not allowed")}return N(404,"Resource not found")}catch(X){return console.error("Groups inbound handler error:",X),N(500,X instanceof Error?X.message:"Internal server error")}},P=async(S)=>{let V=new URL(S.url),Q=V.searchParams.get("startIndex"),z=V.searchParams.get("count"),H=Q!=null?parseInt(Q,10):void 0,F=z!=null?parseInt(z,10):void 0,$=H!=null&&!Number.isNaN(H)?Math.max(0,H-1):0,M=F!=null&&!Number.isNaN(F)?F:void 0,A=await B.list({start:$,limit:M}),X=A.items.map(s);return MM(X,{totalResults:A.total,startIndex:$+1,itemsPerPage:A.count})},v=async(S)=>{let V=await B.get(S);if(!V)return N(404,`Group ${S} not found`,"invalidValue");return d(s(V))},w=async(S)=>{let V=await S.json(),Q=await W.group["~standard"].validate(V);if(Q.issues)return console.error("Group creation validation failed:",Q.issues),N(400,`Request validation failed: ${Q.issues.map(($)=>$.message).join("; ")}`,"invalidValue");let z=Q.value;if(!z.displayName)return N(400,"displayName is required","invalidValue");let H=new Date,F={id:AM(),displayName:z.displayName,externalId:z.externalId,members:z.members,createdAt:H,updatedAt:H};return await B.upsert(F),d(s(F),201)},b=async(S,V)=>{let Q=await B.get(V);if(!Q)return N(404,`Group ${V} not found`,"invalidValue");let z=await S.json(),H=await W.group["~standard"].validate(z);if(H.issues)return console.error("Group replacement validation failed:",H.issues),N(400,`Request validation failed: ${H.issues.map((M)=>M.message).join("; ")}`,"invalidValue");let F=H.value,$={...Q,displayName:F.displayName??Q.displayName,externalId:F.externalId,members:F.members,updatedAt:new Date};return await B.upsert($),d(s($))},p=async(S,V)=>{let Q=await B.get(V);if(!Q)return N(404,`Group ${V} not found`,"invalidValue");let H=(await S.json()).Operations??[],F={...Q};for(let $ of H)if($.op==="replace"&&$.path&&$.value!==void 0){if($.path==="displayName")F.displayName=$.value}else if($.op==="add"&&$.path&&$.value!==void 0){if($.path==="members"){let M=$.value;F.members=[...F.members??[],...M]}}else if($.op==="remove"&&$.path){if($.path.startsWith("members[")){let M=$.path.match(/members\[value eq "([^"]+)"\]/);if(M)F.members=(F.members??[]).filter((A)=>A.value!==M[1])}}return F.updatedAt=new Date,await B.upsert(F),d(s(F))},y=async(S)=>{if(!await B.get(S))return N(404,`Group ${S} not found`,"invalidValue");return await B.delete(S),new Response(null,{status:204})};x={handler:J}}let f;if(Y.userStore){let B=Y.userStore,G=async(Q)=>{let z=U(),H=Q.headers.get("Authorization");if(!H||!H.startsWith("Bearer "))return!1;try{let F=H.substring(7);return(await z.validateToken(F)).valid}catch{return!1}},J=(Q)=>{return{schemas:["urn:ietf:params:scim:schemas:core:2.0:User","urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"],id:Q.id,userName:Q.userName||Q.email||Q.id,displayName:Q.name||Q.userName||Q.email,name:Q.name?{givenName:Q.name.split(" ")[0],familyName:Q.name.split(" ").slice(1).join(" ")||void 0}:void 0,emails:Q.email?[{value:Q.email,primary:!0}]:[],active:!0,...Q.userType!=null&&{userType:Q.userType},meta:{resourceType:"User",created:Q.createdAt.toISOString(),lastModified:Q.updatedAt.toISOString()}}},P=(Q)=>{let z=new Date,H=Q.emails?.find((A)=>A.primary)?.value||Q.emails?.[0]?.value,F=Q.name?`${Q.name.givenName||""} ${Q.name.familyName||""}`.trim():Q.displayName,$=Q.id||AM(),M=Q.userName||H||$;return{id:$,userName:M,name:F||Q.displayName||M,email:H||M,avatar:Q.profileUrl,sso:{profile:{sub:$,iss:"iam-provisioned",aud:"iam-provisioned",exp:Math.floor(Date.now()/1000)+3600,iat:Math.floor(Date.now()/1000),email:H||M,email_verified:!0,name:F||Q.displayName||M,preferred_username:M},tenant:{id:"iam-provisioned",name:"IAM Provisioned"},scope:"openid profile email",tokenType:"Bearer",expires:new Date(Date.now()+3600000)},createdAt:Q.meta?.created?new Date(Q.meta.created):z,updatedAt:Q.meta?.lastModified?new Date(Q.meta.lastModified):z,...Q.userType!=null&&{userType:Q.userType}}},v=async(Q,z)=>{if(!await G(Q))return N(401,"Authorization required");let F=new URL(Q.url),$=z?.basePath??"/Users",M=F.pathname;if(M.startsWith($))M=M.substring($.length);let X=M.match(/^\/([^/]+)$/)?.[1],Z=Q.method;try{if(X)switch(Z){case"GET":return await b(X);case"PUT":return await y(Q,X);case"PATCH":return await S(Q,X);case"DELETE":return await V(X);default:return N(405,"Method not allowed")}else if(M===""||M==="/")switch(Z){case"GET":return await w(Q);case"POST":return await p(Q);default:return N(405,"Method not allowed")}return N(404,"Resource not found")}catch(K){return console.error("Users inbound handler error:",K),N(500,K instanceof Error?K.message:"Internal server error")}},w=async(Q)=>{let z=new URL(Q.url),H=z.searchParams.get("startIndex"),F=z.searchParams.get("count"),$=H!=null?parseInt(H,10):void 0,M=F!=null?parseInt(F,10):void 0,A=$!=null&&!Number.isNaN($)?Math.max(0,$-1):0,X=M!=null&&!Number.isNaN(M)?M:void 0,Z=await B.list({start:A,limit:X}),K=Z.items.map(J);return MM(K,{totalResults:Z.total,startIndex:A+1,itemsPerPage:Z.count})},b=async(Q)=>{let z=await B.get(Q);if(!z)return N(404,`User ${Q} not found`,"invalidValue");return d(J(z))},p=async(Q)=>{let z=await Q.json(),H=await W.user["~standard"].validate(z);if(H.issues)return console.error("User creation validation failed:",H.issues),N(400,`Request validation failed: ${H.issues.map((M)=>M.message).join("; ")}`,"invalidValue");let F=H.value;if(!F.userName&&!F.emails?.[0]?.value)return N(400,"userName or email is required","invalidValue");let $=P(F);return await B.upsert($),d(J($),201)},y=async(Q,z)=>{let H=await B.get(z);if(!H)return N(404,`User ${z} not found`,"invalidValue");let F=await Q.json(),$=await W.user["~standard"].validate(F);if($.issues)return console.error("User replacement validation failed:",$.issues),N(400,`Request validation failed: ${$.issues.map((X)=>X.message).join("; ")}`,"invalidValue");let M=$.value,A=P({...M,id:z});return A.createdAt=H.createdAt,A.updatedAt=new Date,await B.upsert(A),d(J(A))},S=async(Q,z)=>{let H=await B.get(z);if(!H)return N(404,`User ${z} not found`,"invalidValue");let $=(await Q.json()).Operations??[],M={...H};for(let A of $)if(A.op==="replace"&&A.path&&A.value!==void 0){if(A.path==="displayName")M.name=A.value;else if(A.path==="userName")M.userName=A.value;else if(A.path.startsWith("name.")){let X=A.path.split(".")[1];if(!M.name)M.name="";if(X==="givenName")M.name=`${A.value} ${M.name.split(" ").slice(1).join(" ")}`.trim();else if(X==="familyName")M.name=`${M.name.split(" ")[0]} ${A.value}`.trim()}else if(A.path==="emails"){let X=A.value,Z=X?.find((K)=>K.primary)?.value||X?.[0]?.value;if(Z)M.email=Z}}else if(A.op==="add"&&A.path&&A.value!==void 0){if(A.path==="emails"){let X=A.value,Z=X?.find((K)=>K.primary)?.value||X?.[0]?.value;if(Z)M.email=Z}}else if(A.op==="remove"&&A.path){if(A.path==="displayName")M.name=""}return M.updatedAt=new Date,await B.upsert(M),d(J(M))},V=async(Q)=>{if(!await B.get(Q))return N(404,`User ${Q} not found`,"invalidValue");return await B.delete(Q),new Response(null,{status:204})};f={handler:v}}async function k(B,G){U();let P=new URL(B.url).pathname,v=G?.usersUrl??Y.usersUrl??"/api/iam/Users",w=G?.groupsUrl??Y.groupsUrl??"/api/iam/Groups";if(P.startsWith(v)&&f)return f.handler(B,{basePath:v});if(P.startsWith(w)&&x)return x.handler(B,{basePath:w});return N(404,"Resource not found")}return{...Y,createUser:t,getBaseUrl:i,groups_outbound:l,groups_inbound:x,users_inbound:f,handler:k}}var KM="@enterprisestandard/core",WM=YM(XM(KM));function QM(W){let D=W.replace(/-/g,"+").replace(/_/g,"/");return atob(D)}async function OM(W,D){let j=W.split(".");if(j.length!==3)throw Error("Invalid JWT");let h=JSON.parse(QM(j[0])),q=JSON.parse(QM(j[1])),E=j[2].replace(/-/g,"+").replace(/_/g,"/"),Y=h.kid;if(!Y)throw Error("JWT header missing kid");let U=await $M(D),g=await FM(U,Y),i=new TextEncoder().encode(`${j[0]}.${j[1]}`),l=Uint8Array.from(atob(E),(B)=>B.charCodeAt(0));if(!await crypto.subtle.verify("RSASSA-PKCS1-v1_5",g,l,i))throw Error("Invalid JWT signature");let x=await WM.validate(q);if(x.issues)throw Error(`ID token claims validation failed: ${x.issues.map((B)=>B.message).join("; ")}`);let f=x.value;if(f===void 0)throw Error("ID token claims missing");let k=f;if(typeof k.exp==="number"&&k.exp<Math.floor(Date.now()/1000))throw Error("Token expired");return ZM(k)}export{PM as withTenantConfigMethod,OM as verifyUser,EM as tenantConfigSource,NM as sso,IM as registerTenantConfigSourceFactory,jM as logoutBackChannel,DM as logout,JM as initiateLogin,SM as iam,_M as getSSOorCIAMUser,VM as getSSOUser,GM as getRequiredSSOorCIAMUser,BM as getCIAMUser,zM as ciam,LM as callback};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
function jX(Y){return{"~standard":{version:1,vendor:Y,validate:(Z)=>{if(typeof Z!=="object"||Z===null)return{issues:[{message:"Expected an object"}]};let X=Z,N=[],S={};if("code"in X)if(typeof X.code==="string")S.code=X.code;else N.push({message:"code must be a string",path:["code"]});else if(!("error"in X))N.push({message:"code is required",path:["code"]});if("state"in X)if(typeof X.state==="string"||X.state===void 0)S.state=X.state;else N.push({message:"state must be a string",path:["state"]});if("session_state"in X)if(typeof X.session_state==="string"||X.session_state===void 0)S.session_state=X.session_state;else N.push({message:"session_state must be a string",path:["session_state"]});if("error"in X){if(typeof X.error==="string")S.error=X.error;else N.push({message:"error must be a string",path:["error"]});if("error_description"in X)if(typeof X.error_description==="string"||X.error_description===void 0)S.error_description=X.error_description;else N.push({message:"error_description must be a string",path:["error_description"]});if("error_uri"in X)if(typeof X.error_uri==="string"||X.error_uri===void 0)S.error_uri=X.error_uri;else N.push({message:"error_uri must be a string",path:["error_uri"]})}if("iss"in X)if(typeof X.iss==="string"||X.iss===void 0)S.iss=X.iss;else N.push({message:"iss must be a string",path:["iss"]});if(N.length>0)return{issues:N};return{value:S}}}}}function VX(Y){return{"~standard":{version:1,vendor:Y,validate:(Z)=>{if(typeof Z!=="object"||Z===null)return{issues:[{message:"Expected an object"}]};let X=Z,N=[],S={};if("access_token"in X)if(typeof X.access_token==="string")S.access_token=X.access_token;else N.push({message:"access_token must be a string",path:["access_token"]});else N.push({message:"access_token is required",path:["access_token"]});if("id_token"in X)if(typeof X.id_token==="string")S.id_token=X.id_token;else N.push({message:"id_token must be a string",path:["id_token"]});else N.push({message:"id_token is required",path:["id_token"]});if("token_type"in X)if(typeof X.token_type==="string")S.token_type=X.token_type;else N.push({message:"token_type must be a string",path:["token_type"]});else N.push({message:"token_type is required",path:["token_type"]});if("refresh_token"in X)if(typeof X.refresh_token==="string"||X.refresh_token===void 0)S.refresh_token=X.refresh_token;else N.push({message:"refresh_token must be a string",path:["refresh_token"]});if("scope"in X)if(typeof X.scope==="string"||X.scope===void 0)S.scope=X.scope;else N.push({message:"scope must be a string",path:["scope"]});if("session_state"in X)if(typeof X.session_state==="string"||X.session_state===void 0)S.session_state=X.session_state;else N.push({message:"session_state must be a string",path:["session_state"]});if("expires"in X)if(typeof X.expires==="string"||X.expires===void 0)S.expires=X.expires;else N.push({message:"expires must be a string",path:["expires"]});if("expires_in"in X)if(typeof X.expires_in==="number"||X.expires_in===void 0)S.expires_in=X.expires_in;else N.push({message:"expires_in must be a number",path:["expires_in"]});if("refresh_expires_in"in X)if(typeof X.refresh_expires_in==="number"||X.refresh_expires_in===void 0)S.refresh_expires_in=X.refresh_expires_in;else N.push({message:"refresh_expires_in must be a number",path:["refresh_expires_in"]});if(N.length>0)return{issues:N};return{value:S}}}}}function i(Y){return{"~standard":{version:1,vendor:Y,validate:(Z)=>{if(typeof Z!=="object"||Z===null)return{issues:[{message:"Expected an object"}]};let X=Z,N=[],S={...X},Q=["iss","aud","sub","sid","name","email","preferred_username","picture"];for(let M of Q)if(M in X&&X[M]!==void 0){if(typeof X[M]!=="string")N.push({message:`${M} must be a string`,path:[M]})}let $=["exp","iat"];for(let M of $)if(M in X&&X[M]!==void 0){if(typeof X[M]!=="number")N.push({message:`${M} must be a number`,path:[M]})}if(N.length>0)return{issues:N};return{value:S}}}}}function a(Y){let Z=Y["~standard"];return Object.assign({},Y,{validate(X){return Promise.resolve(Z.validate(X))}})}function D(Y,Z="Assertion failed. Required value is null or undefined."){if(Y===void 0||Y===null)throw Error(Z);return Y}function o(Y,Z){return Response.json({error:"validation_failed",message:Z,issues:Y},{status:400,headers:{"Content-Type":"application/json"}})}function HX(Y,Z,X=[]){let N={...Y,...Z};for(let S of X)N[S]=Y?.[S]??Z?.[S];return N}function QX(Y){let Z="",X=0,N=Y.length;while(X<N){let S=Y[X];if(S==='"'||S==="'"){let Q=S;Z+=S,X++;while(X<N){let $=Y[X];if($==="\\"){if(Z+=$,X+1<N)Z+=Y[X+1],X+=2;else X++;continue}if($===Q){Z+=$,X++;break}Z+=$,X++}continue}if(S==="/"&&X+1<N){let Q=Y[X+1];if(Q==="/"){X+=2;while(X<N&&Y[X]!==`
|
|
2
|
+
`)X++;if(X<N)Z+=`
|
|
3
|
+
`;X++;continue}if(Q==="*"){X+=2;while(X+1<N&&!(Y[X]==="*"&&Y[X+1]==="/"))X++;X+=2;continue}}Z+=S,X++}return Z}function PX(Y){let Z=QX(Y);return JSON.parse(Z)}async function TX(Y,Z=async(Q)=>Q.status===200,X=1000,N=1e4,S){let Q=Date.now(),$="Awaiting Ping";return new Promise((M,_)=>{let T=null,y=null,v=async()=>{try{let V=await fetch(Y);if(V.ok)if(await Z(V)){if(T)clearInterval(T);if(y)clearInterval(y);M()}else $=`Response test failed: ${V.status}: ${V.statusText} - ${Y}`;else try{let h=await V.json();$=`Response error: ${V.status}: ${V.statusText} - ${Y}: ${JSON.stringify(h)}`}catch(h){$=`Response error: ${V.status}: ${V.statusText} - ${Y}`}}catch(V){$=`${V instanceof Error?V.message:String(V)} - ${Y}`}};if(v(),T=setInterval(v,X),N>0)y=setInterval(()=>{console.warn(`${$}: ${Date.now()-Q}ms`)},N);if(S)setTimeout(()=>{if(T)clearInterval(T);if(y)clearInterval(y);_(Error(`Timeout: ${S}ms: ${$}`))},S)})}var BX="@enterprisestandard/core",WX=a(i(BX));function MX(Y){let Z=Y.exp!=null?new Date(Y.exp*1000):new Date,X=Y.iss??"";return{id:Y.sub??"",userName:Y.preferred_username??"",name:Y.name??"",email:Y.email??"",avatar:Y.picture,sso:{profile:{...Y,iss:Y.iss??X,aud:Y.aud},tenant:{id:Y.idp??X,name:X},tokenType:"Bearer",expires:Z}}}function FX(Y){let Z=Y.replace(/-/g,"+").replace(/_/g,"/");return atob(Z)}async function IX(Y){let Z=Y.split(".");if(Z.length!==3)throw Error("Invalid JWT");let X=FX(Z[1]),N=JSON.parse(X),S=await WX.validate(N);if(S.issues)throw Error(`ID token claims validation failed: ${S.issues.map((Q)=>Q.message).join("; ")}`);if(S.value)return MX(S.value);throw Error("ID token claims validation failed")}var I=(Y,Z,...X)=>{if(X.length>0)console[Y](`[${Y.toUpperCase()}]`,Z,...X);else console[Y](`[${Y.toUpperCase()}]`,Z)},r={debug:()=>{},info:()=>{},warn(Y,...Z){I("warn",Y,...Z)},error(Y,...Z){I("error",Y,...Z)}},yX={debug:()=>{},info:()=>{},warn:()=>{},error:()=>{}},RX={debug:()=>{},info:I.bind(console,"info"),warn:I.bind(console,"warn"),error:I.bind(console,"error")},s=(Y,...Z)=>{if(Z.length>0)console.log("[DEBUG]",Y,...Z);else console.log("[DEBUG]",Y)},bX={debug:s,info:I.bind(console,"info"),warn:I.bind(console,"warn"),error:I.bind(console,"error")},CX={debug:s,info:I.bind(console,"info"),warn:I.bind(console,"warn"),error:I.bind(console,"error")};var e=new Map;async function m(Y,Z=3,X=1000,N=30000){let S=Error("Placeholder Error");for(let Q=0;Q<=Z;Q++)try{return await Y()}catch($){if(S=$ instanceof Error?$:Error(String($)),$ instanceof Error&&$.message.includes("400"))throw $;if(Q===Z)throw S;let M=Math.min(X*2**Q,N),_=Math.random()*0.1*M;await new Promise((T)=>setTimeout(T,M+_)),console.warn(`Retry attempt ${Q+1} after ${M+_}ms delay`)}throw S}async function XX(Y){let Z=e.get(Y);if(Z)return Z;return m(async()=>{let X=await fetch(Y);if(!X.ok)throw Error("Failed to fetch JWKS");let N=await X.json();return e.set(Y,N),N})}async function YX(Y,Z){let X=Y.keys.find((N)=>N.kid===Z);if(!X)throw Error("Public key not found");return crypto.subtle.importKey("jwk",{kty:X.kty,n:X.n,e:X.e},{name:"RSASSA-PKCS1-v1_5",hash:"SHA-256"},!1,["verify"])}function kX(Y,Z={}){let X=Z.cookieName??"es.active_session",N=Y.headers.get("cookie");if(!N)return;return d(N)[X]}function gX(Y,Z={}){let X=Z.cookieName??"es.active_session",N=Z.path??"/",S=Z.secure??!1,Q=Z.sameSite??"Lax",$=Z.maxAge,M=[`${X}=${Y}`,`Path=${N}`,"HttpOnly",`SameSite=${Q}`];if(S)M.push("Secure");if(typeof $==="number")M.push(`Max-Age=${$}`);return M.join("; ")}function pX(Y={}){let Z=Y.cookieName??"es.active_session",X=Y.path??"/",N=Y.secure??!1,S=Y.sameSite??"Lax",Q=[`${Z}=`,"Max-Age=0",`Path=${X}`,"HttpOnly",`SameSite=${S}`];if(N)Q.push("Secure");return Q.join("; ")}function mX(Y,Z={}){let X=typeof Y==="string"?Y:Y?.headers.get("cookie")??void 0;if(!X)return[];let S=`${Z.cookiePrefix??"es.sso"}.`,Q=new Set;for(let $ of Object.keys(d(X))){if(!$.startsWith(S))continue;let M=$.slice(S.length),_=M.lastIndexOf(".");if(_<=0)continue;let T=M.slice(0,_).trim();if(T)Q.add(T)}return Array.from(Q)}function dX(Y,Z){if(!Y)return;let X=d(Y);for(let[N,S]of Object.entries(X)){if(!N.startsWith("es.sso.")||!N.endsWith(".state"))continue;try{let Q=JSON.parse(atob(S));if(Q?.state===Z)return{clientId:N.slice(7,-6),stateCookie:Q}}catch{}}return}function cX(Y,Z,X,N){if(!X&&!N)return;let S={...X,...N},Q=!!(S.authority&&S.tokenUrl&&S.authorizationUrl&&S.clientId&&S.redirectUri&&S.scope),$={...S,authority:Q?D(S.authority,"Missing 'authority' from SSO Config"):S.authority,tokenUrl:Q?D(S.tokenUrl,"Missing 'tokenUrl' from SSO Config"):S.tokenUrl,authorizationUrl:Q?D(S.authorizationUrl,"Missing 'authorizationUrl' from SSO Config"):S.authorizationUrl,clientId:Q?D(S.clientId,"Missing 'clientId' from SSO Config"):S.clientId,redirectUri:Q?D(S.redirectUri,"Missing 'redirectUri' from SSO Config"):S.redirectUri,scope:Q?D(S.scope,"Missing 'scope' from SSO Config"):S.scope,responseType:S.responseType??"code",cookiesSecure:S.cookiesSecure!==void 0?S.cookiesSecure:!0,cookiesSameSite:S.cookiesSameSite!==void 0?S.cookiesSameSite:"Strict",cookiesPrefix:S.cookiesPrefix??(S.clientId?`es.sso.${S.clientId}`:"es.sso"),cookiesPath:S.cookiesPath??"/"};function M(){let K=[];if(!$.authority)K.push("authority");if(!$.tokenUrl)K.push("tokenUrl");if(!$.authorizationUrl)K.push("authorizationUrl");if(!$.clientId)K.push("clientId");if(!$.redirectUri)K.push("redirectUri");if(!$.scope)K.push("scope");if(K.length>0)throw Error(`Missing OIDC configuration fields: ${K.join(", ")}. OIDC configuration is required for SSO operations. Please provide these fields either in your vault configuration or in the SSO config when initializing enterpriseStandard.`)}async function _(K){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");try{let{tokens:A}=await k(K);if(!A)return;return await U(A)}catch(A){console.error("Error parsing user from cookies:",A);return}}async function T(K){let A=await _(K);if(A)return A;throw new Response("Unauthorized",{status:401,statusText:"Unauthorized"})}async function y({landingUrl:K,errorUrl:A},B){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");M();let F=t(),W=t(64),G=$.redirectUri;try{new URL(G)}catch{if(B)try{let O=new URL(B),w=G.startsWith("//")?G.slice(1):G.startsWith("/")?G:`/${G}`;G=new URL(w,O.origin).toString()}catch{try{let O=new URL($.authorizationUrl),w=G.startsWith("//")?G.slice(1):G.startsWith("/")?G:`/${G}`;G=new URL(w,O.origin).toString()}catch{throw Error(`Invalid redirectUri: "${$.redirectUri}". It must be a valid absolute URL.`)}}}let L=new URL($.authorizationUrl);L.searchParams.append("client_id",$.clientId),L.searchParams.append("redirect_uri",G),L.searchParams.append("response_type","code"),L.searchParams.append("scope",$.scope),L.searchParams.append("state",F);let J=await KX(W);L.searchParams.append("code_challenge",J),L.searchParams.append("code_challenge_method","S256");let j={state:F,codeVerifier:W,landingUrl:K,errorUrl:A};return new Response("Redirecting to SSO Provider",{status:302,headers:{Location:L.toString(),"Set-Cookie":f("state",j,86400)}})}async function v(K,A){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");try{let J=R("refresh",K);if(J)await SX(J)}catch(J){console.warn("Failed to revoke token:",J)}if($.sessionStore)try{let J=await _(K);if(J?.sso?.profile.sid){let j=J.sso.profile.sid;await $.sessionStore.delete(j)}}catch(J){console.warn("Failed to delete session:",J)}let B=[["Set-Cookie",b("access")],["Set-Cookie",b("id")],["Set-Cookie",b("refresh")],["Set-Cookie",b("control")],["Set-Cookie",b("state")]],W=new URL(K.url).searchParams.get("redirect");if(W)return new Response("Logged out",{status:302,headers:[["Location",W],...B]});let G=K.headers.get("accept");if(G?.includes("application/json")||G?.includes("text/javascript"))return new Response(JSON.stringify({success:!0,message:"Logged out"}),{status:200,headers:[["Content-Type","application/json"],...B]});else return new Response(`
|
|
4
|
+
<!DOCTYPE html><html lang="en"><body>
|
|
5
|
+
<h1>Logout Complete</h1>
|
|
6
|
+
<div style="display: none">
|
|
7
|
+
It is not recommended to show the default logout page. Include '?redirect=/someHomePage' or logout asynchronously.
|
|
8
|
+
Check the <a href="https://EnterpriseStandard.com/sso#logout">Enterprise Standard Packages</a> for more information.
|
|
9
|
+
</div>
|
|
10
|
+
</body></html>
|
|
11
|
+
`,{status:200,headers:[["Content-Type","text/html"],...B]})}async function V(K){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");if(!$.sessionStore)throw Error("Back-Channel Logout requires sessionStore configuration");try{let A=K.headers.get("content-type");if(!A||!A.includes("application/x-www-form-urlencoded"))return new Response("Invalid Content-Type, expected application/x-www-form-urlencoded",{status:400});let B=await K.text(),W=new URLSearchParams(B).get("logout_token");if(!W)return new Response("Missing logout_token parameter",{status:400});let L=(await n(W)).sid;if(!L)return console.warn("Back-Channel Logout: logout_token missing sid claim"),new Response("Invalid logout_token: missing sid claim",{status:400});return await $.sessionStore.delete(L),console.log(`Back-Channel Logout: successfully deleted session ${L}`),new Response("OK",{status:200})}catch(A){return console.error("Error during back-channel logout:",A),new Response("Internal Server Error",{status:500})}}async function h(K){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");let A=new URL(K.url),B=new URLSearchParams(A.search),F=Object.fromEntries(B.entries()),W=await Y.callbackParams["~standard"].validate(F);if(W.issues)return o(W.issues,"OIDC callback parameters validation failed");let{code:G,state:L}=W.value;try{let J=R("state",K,!0),{codeVerifier:j,state:O,landingUrl:w}=J??{};if(D(j,'OIDC "codeVerifier" was not present in cookies, ensure that the SSO login was initiated correctly'),D(O,'OIDC "stateVerifier" was not present in cookies, ensure that the SSO login was initiated correctly'),D(w,'OIDC "landingUrl" was not present in cookies'),L!==O)throw Error('SSO State Verifier failed, the "state" request parameter does not equal the "state" in the SSO cookie');let x=await $X(G,j,K.url),H=await U(x);if($.sessionStore)try{let E=H.sso.profile.sid,P=H.id;if(E&&P){let z={sid:E,sub:P,createdAt:new Date,lastActivityAt:new Date};await $.sessionStore.create(z)}else console.warn("Session creation skipped: missing sid or sub in ID token claims")}catch(E){console.warn("Failed to create session:",E)}if($.userStore)try{let E=H.id;if(E){let P=new Date,z=await $.userStore.get(E);if(z||$.enableJitUserProvisioning){let p={...z??{},...H,id:E,tenantId:z?.tenantId,createdAt:z?.createdAt??P,updatedAt:P};await $.userStore.upsert(p)}else console.warn("JIT user provisioning disabled: user not found in store and will not be created")}else console.warn("User storage skipped: missing sub in ID token claims")}catch(E){console.warn("Failed to store user:",E)}return new Response("Authentication successful, redirecting",{status:302,headers:[["Location",w],["Set-Cookie",b("state")],...g(x,H.sso.expires)]})}catch(J){console.error("Error during sign-in callback:",J);try{let j=R("state",K,!0),{errorUrl:O}=j??{};if(O)return new Response("Redirecting to error url",{status:302,headers:[["Location",O]]})}catch(j){console.warn("Error parsing the errorUrl from the OIDC cookie")}return console.warn("No error page was found in the cookies. The user will be shown a default error page."),new Response("An error occurred during authentication, please return to the application homepage and try again.",{status:500})}}async function U(K){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");let A=await n(K.id_token),B=Number(K.refresh_expires_in??K.expires_in??3600),F=K.expires?new Date(K.expires):new Date(Date.now()+B*1000);return{id:A.sub,userName:A.preferred_username||"",name:A.name||"",email:A.email||"",emails:[{value:A.email||"",primary:!0}],avatar:A.picture,sso:{profile:{...A,iss:A.iss||$.authority,aud:A.aud||$.clientId},tenant:{id:A.idp||A.iss||$.authority||"",name:A.iss||$.authority||""},scope:K.scope,tokenType:K.token_type,sessionState:K.session_state,expires:F}}}async function $X(K,A,B){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");M();let{tokenUrl:F,redirectUri:W}=$;try{new URL(W)}catch{if(B)try{let L=new URL(B),J=W.startsWith("//")?W.slice(1):W.startsWith("/")?W:`/${W}`;W=new URL(J,L.origin).toString()}catch{try{let L=new URL(F),J=W.startsWith("//")?W.slice(1):W.startsWith("/")?W:`/${W}`;W=new URL(J,L.origin).toString()}catch{throw Error(`Invalid redirectUri: "${$.redirectUri}". It must be a valid absolute URL.`)}}}let G=new URLSearchParams;if(G.append("grant_type","authorization_code"),G.append("code",K),G.append("redirect_uri",W),G.append("client_id",$.clientId),$.clientSecret)G.append("client_secret",$.clientSecret);G.append("code_verifier",A);try{let L=await fetch(F,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:G.toString()}),J=await L.json();if(!L.ok){console.error("Token exchange error:",J);let O=J;throw Error(`Token exchange failed: ${O.error||L.statusText} - ${O.error_description||""}`.trim())}let j=await Y.tokenResponse["~standard"].validate(J);if(j.issues)throw console.error("Token response validation failed:",j.issues),Error(`Token response validation failed: ${j.issues}`);return j.value}catch(L){throw console.error("Error during token exchange:",L),L}}async function u(K){return m(async()=>{if(!$)throw Error("Enterprise Standard SSO Manager not initialized");M();let A=$.tokenUrl,B=new URLSearchParams;B.append("grant_type","refresh_token"),B.append("refresh_token",K),B.append("client_id",$.clientId);let F=await fetch(A,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:B.toString()}),W=await F.json();if(!F.ok){console.error("Token refresh error:",W);let G=W;throw Error(`Token refresh failed: ${G.error||F.statusText} - ${G.error_description||""}`.trim())}return W})}async function SX(K){try{if(!$)throw Error("Enterprise Standard SSO Manager not initialized");if(!$.revocationEndpoint)return;let A=new URLSearchParams;A.append("token",K),A.append("token_type_hint","refresh_token"),A.append("client_id",$.clientId);let B=await fetch($.revocationEndpoint,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:A.toString()});if(!B.ok)console.warn("Token revocation failed:",B.status,B.statusText);else console.log("Token revoked successfully")}catch(A){console.warn("Error revoking token:",A)}}async function l(){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");if(!$.jwksUri&&!$.authority)throw Error("Missing 'jwksUri' or 'authority' from SSO Config. OIDC configuration is required for this operation.");let K=$.jwksUri||`${$.authority}/protocol/openid-connect/certs`;return XX(K)}async function n(K){try{let A=K.split(".");if(A.length!==3)throw Error("Invalid JWT");let B=JSON.parse(atob(A[0].replace(/-/g,"+").replace(/_/g,"/"))),F=JSON.parse(atob(A[1].replace(/-/g,"+").replace(/_/g,"/"))),W=A[2].replace(/-/g,"+").replace(/_/g,"/"),G=await NX(B.kid),J=new TextEncoder().encode(`${A[0]}.${A[1]}`);if(!await crypto.subtle.verify("RSASSA-PKCS1-v1_5",G,Uint8Array.from(atob(W),(w)=>w.charCodeAt(0)),J))throw Error("Invalid JWT signature");let O=await Y.idTokenClaims["~standard"].validate(F);if(O.issues)throw console.error("ID token claims validation failed:",O.issues),Error(`ID token claims validation failed: ${O.issues}`);return O.value}catch(A){throw console.error("Error verifying JWT:",A),A}}function t(K=32){let A=new Uint8Array(K);return crypto.getRandomValues(A),Array.from(A,(B)=>B.toString(16).padStart(2,"0")).join("").substring(0,K)}async function KX(K){let B=new TextEncoder().encode(K),F=await crypto.subtle.digest("SHA-256",B),W=Array.from(new Uint8Array(F));return btoa(String.fromCharCode(...W)).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}async function NX(K){let A=await l();return YX(A,K)}function g(K,A){let B={expires_in:K.expires_in,refresh_expires_in:K.refresh_expires_in,scope:K.scope,session_state:K.session_state,token_type:K.token_type,expires:A.toISOString()};return[["Set-Cookie",f("access",K.access_token,A)],["Set-Cookie",f("id",K.id_token,A)],["Set-Cookie",f("refresh",K.refresh_token??"",A)],["Set-Cookie",f("control",B,A)]]}async function k(K){let A=R("access",K),B=R("id",K),F=R("refresh",K),W=R("control",K,!0);if(!A||!B||!F||!W)return{tokens:void 0,refreshHeaders:[]};let G={access_token:A,id_token:B,refresh_token:F,...W};if(W.expires&&F&&Date.now()>new Date(W.expires).getTime()){G=await u(F);let L=await U(G),J=g(G,L.sso.expires);return{tokens:G,refreshHeaders:J}}return{tokens:G,refreshHeaders:[]}}async function AX(K){let{tokens:A}=await k(K);if(!A)return;return A.access_token}function f(K,A,B){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");if(K=`${$.cookiesPrefix}.${K}`,typeof A!=="string")A=btoa(JSON.stringify(A));let F;if(B instanceof Date)F=`Expires=${B.toUTCString()}`;else if(typeof B==="number")F=`Max-Age=${B}`;else throw Error("Invalid expires type",B);if(A.length>4000)throw Error(`Error setting cookie: ${K}. Cookie length is: ${A.length}`);return`${K}=${A}; ${F}; Path=${$.cookiesPath}; HttpOnly;${$.cookiesSecure?" Secure;":""} SameSite=${$.cookiesSameSite};`}function b(K){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");return`${$.cookiesPrefix}.${K}=; Max-Age=0; Path=${$.cookiesPath}; HttpOnly;${$.cookiesSecure?" Secure;":""} SameSite=${$.cookiesSameSite};`}function R(K,A,B=!1){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");let F=A.headers.get("cookie");if(!F)return null;let W=F.split(";").find((J)=>J.trim().startsWith(`${$.cookiesPrefix}.${K}=`));if(!W)return null;let G=W.split("=")[1].trim();if(!B)return G;let L=atob(G);return JSON.parse(L)}async function GX(K,A){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");let{loginUrl:B,userUrl:F,errorUrl:W,landingUrl:G,tokenUrl:L,refreshUrl:J,logoutUrl:j,logoutBackChannelUrl:O,jwksUrl:w,redirectUri:x}={...$,...A},H=new URL(K.url).pathname;if(x){let E;try{E=new URL(x).pathname}catch{try{let P=new URL(K.url),z=x.startsWith("//")?x.slice(1):x;E=new URL(z,P.origin).pathname}catch{E=x.startsWith("/")?x:`/${x}`}}if(E===H)return h(K)}if(B===H)return y({landingUrl:G||"/",errorUrl:W},K.url);if(F===H){let{tokens:E,refreshHeaders:P}=await k(K);if(!E)return new Response("User not logged in",{status:401});let z=await U(E);return new Response(JSON.stringify(z),{headers:[["Content-Type","application/json"],...P]})}if(L===H){let{tokens:E,refreshHeaders:P}=await k(K);if(!E)return new Response("User not logged in",{status:401});return new Response(JSON.stringify({token:E.access_token,expires:E.expires}),{headers:[["Content-Type","application/json"],...P]})}if(J===H){let E=R("refresh",K);if(!E)return new Response("User not logged in",{status:401});let P=await u(E),z=await U(P),p=g(P,z.sso.expires);return new Response("Refresh Complete",{status:200,headers:p})}if(j===H)return v(K,{landingUrl:G||"/"});if(O===H)return V(K);if(w===H){let E=await l();return new Response(JSON.stringify(E),{headers:[["Content-Type","application/json"]]})}return new Response("Not Found",{status:404})}return{...$,getUser:_,getRequiredUser:T,getJwt:AX,initiateLogin:y,logout:v,logoutBackChannel:V,callbackHandler:h,handler:GX}}function d(Y){let Z={},X=Y.split(";");for(let N of X){let S=N.trim();if(!S)continue;let Q=S.indexOf("=");if(Q===-1)continue;let $=S.slice(0,Q).trim(),M=S.slice(Q+1).trim();Z[$]=M}return Z}function C(Y){return Y=Y??"SSO Unavailable",new Response(JSON.stringify({error:Y}),{status:503,statusText:Y,headers:{"Content-Type":"application/json"}})}function ZX(Y){if(!Y)return[];let Z=Y.headers;if(Z.getSetCookie)return Z.getSetCookie();let X=Y.headers.get("set-cookie");return X?[X]:[]}function LX(Y,Z){let X=new Headers;Y.headers.forEach((N,S)=>{if(S.toLowerCase()!=="set-cookie")X.set(S,N)});for(let N of Z)X.append("Set-Cookie",N);return new Response(Y.body,{status:Y.status,statusText:Y.statusText,headers:X})}var q="EnterpriseStandard instance is required. Create one with enterpriseStandard(source, config) and pass it to this function.";async function uX(Y,Z){return D(Z,q),Z.sso?.getUser(Y)}async function JX(Y,Z){D(Z,q);let X=Z.logger??r;X.debug?.("getUser called",{hasInstance:!0,hasSso:!!Z.sso,hasCiam:!!Z.ciam});let N=await Z.sso?.getUser(Y);if(N)return X.debug?.("Found SSO user",{email:N.email}),N;X.debug?.("No SSO user, trying CIAM");let S=await Z.ciam?.getUser(Y);return X.debug?.("CIAM user result",{email:S?.email??void 0}),S}async function lX(Y,Z){let X=await JX(Y,Z);if(X)return X;throw new Response("Unauthorized",{status:401,statusText:"Unauthorized"})}async function nX(Y,Z){D(Z,q);let X=Z.sso;if(!X)return C();return X.initiateLogin(Y)}async function tX(Y,Z){D(Z,q);let X=Z.sso;if(!X)return C();return X.callbackHandler(Y)}async function iX(Y,Z){D(Z,q);let{sso:X,ciam:N}=Z;if(!X&&!N)return C("Logout Unavailable");let S=X?await X.logout(Y,{landingUrl:"/"}):void 0,Q=N?await N.logout(Y):void 0,$=S??Q;if(!$)return C("Logout Unavailable");let M=[...ZX(S),...ZX(Q)];return LX($,M)}async function aX(Y,Z){D(Z,q);let{sso:X,ciam:N}=Z;if(!X&&!N)return C("Back-Channel Logout Unavailable");let S=Y.clone(),Q=Y.clone(),$=X?await X.logoutBackChannel(S):void 0;if($?.status===200)return $;let M=N?await N.logoutBackChannel(Q):void 0;if(M)return M;return $??C("Back-Channel Logout Unavailable")}var c;function rX(Y){c=Y}function EX(Y){if(OX(Y.configSource))return Y.configSource;if(!c)throw Error("Tenant config hydration is not registered. Import @enterprisestandard/server before using tenant.config().");return c(Y.configSource)}function sX(Y){let Z=Y.configSource;return{...Y,config:()=>EX({configSource:Z})}}function OX(Y){let Z=Y;return typeof Y==="object"&&Y!==null&&typeof Z.load==="function"&&typeof Z.subscribe==="function"}
|
|
12
|
+
export{jX as a,VX as b,i as c,a as d,D as e,o as f,HX as g,QX as h,PX as i,TX as j,MX as k,IX as l,r as m,yX as n,RX as o,bX as p,CX as q,XX as r,YX as s,kX as t,gX as u,pX as v,mX as w,dX as x,cX as y,uX as z,JX as A,lX as B,nX as C,tX as D,iX as E,aX as F,rX as G,EX as H,sX as I};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@enterprisestandard/core",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.12",
|
|
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.12",
|
|
31
|
+
"@enterprisestandard/valibot": "^0.0.12"
|
|
32
32
|
}
|
|
33
33
|
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
function JX(Y){return{"~standard":{version:1,vendor:Y,validate:(Z)=>{if(typeof Z!=="object"||Z===null)return{issues:[{message:"Expected an object"}]};let X=Z,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
|
-
`)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 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
|
-
<!DOCTYPE html><html lang="en"><body>
|
|
5
|
-
<h1>Logout Complete</h1>
|
|
6
|
-
<div style="display: none">
|
|
7
|
-
It is not recommended to show the default logout page. Include '?redirect=/someHomePage' or logout asynchronously.
|
|
8
|
-
Check the <a href="https://EnterpriseStandard.com/sso#logout">Enterprise Standard Packages</a> for more information.
|
|
9
|
-
</div>
|
|
10
|
-
</body></html>
|
|
11
|
-
`,{status:200,headers:[["Content-Type","text/html"],...B]})}async function v(K){if(!$)throw Error("Enterprise Standard SSO Manager not initialized");if(!$.sessionStore)throw Error("Back-Channel Logout requires sessionStore configuration");try{let 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
|
-
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};
|