@enterprisestandard/react 0.0.3-beta.3 → 0.0.5-beta.20251125.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,356 @@
1
+ import type { StandardSchemaV1 } from './standard-schema';
2
+ /**
3
+ * SCIM 2.0 User Resource
4
+ * @see https://datatracker.ietf.org/doc/html/rfc7643#section-4.1
5
+ */
6
+ /**
7
+ * SCIM Name sub-attribute
8
+ */
9
+ export interface Name {
10
+ /**
11
+ * The full name, including all middle names, titles, and suffixes as appropriate
12
+ */
13
+ formatted?: string;
14
+ /**
15
+ * The family name of the User, or last name
16
+ */
17
+ familyName?: string;
18
+ /**
19
+ * The given name of the User, or first name
20
+ */
21
+ givenName?: string;
22
+ /**
23
+ * The middle name(s) of the User
24
+ */
25
+ middleName?: string;
26
+ /**
27
+ * The honorific prefix(es) of the User, or title
28
+ */
29
+ honorificPrefix?: string;
30
+ /**
31
+ * The honorific suffix(es) of the User, or suffix
32
+ */
33
+ honorificSuffix?: string;
34
+ }
35
+ /**
36
+ * SCIM Email sub-attribute
37
+ */
38
+ export interface Email {
39
+ /**
40
+ * The email address value
41
+ */
42
+ value: string;
43
+ /**
44
+ * A human-readable name, primarily used for display purposes
45
+ */
46
+ display?: string;
47
+ /**
48
+ * A label indicating the attribute's function (e.g., "work" or "home")
49
+ */
50
+ type?: string;
51
+ /**
52
+ * A Boolean value indicating the 'primary' or preferred attribute value
53
+ */
54
+ primary?: boolean;
55
+ }
56
+ /**
57
+ * SCIM Phone Number sub-attribute
58
+ */
59
+ export interface PhoneNumber {
60
+ /**
61
+ * The phone number value
62
+ */
63
+ value: string;
64
+ /**
65
+ * A human-readable name, primarily used for display purposes
66
+ */
67
+ display?: string;
68
+ /**
69
+ * A label indicating the attribute's function (e.g., "work", "home", "mobile")
70
+ */
71
+ type?: string;
72
+ /**
73
+ * A Boolean value indicating the 'primary' or preferred attribute value
74
+ */
75
+ primary?: boolean;
76
+ }
77
+ /**
78
+ * SCIM Address sub-attribute
79
+ */
80
+ export interface Address {
81
+ /**
82
+ * The full mailing address, formatted for display
83
+ */
84
+ formatted?: string;
85
+ /**
86
+ * The full street address component
87
+ */
88
+ streetAddress?: string;
89
+ /**
90
+ * The city or locality component
91
+ */
92
+ locality?: string;
93
+ /**
94
+ * The state or region component
95
+ */
96
+ region?: string;
97
+ /**
98
+ * The zip code or postal code component
99
+ */
100
+ postalCode?: string;
101
+ /**
102
+ * The country name component
103
+ */
104
+ country?: string;
105
+ /**
106
+ * A label indicating the attribute's function (e.g., "work" or "home")
107
+ */
108
+ type?: string;
109
+ /**
110
+ * A Boolean value indicating the 'primary' or preferred attribute value
111
+ */
112
+ primary?: boolean;
113
+ }
114
+ /**
115
+ * SCIM Group reference
116
+ */
117
+ export interface Group {
118
+ /**
119
+ * The identifier of the User's group
120
+ */
121
+ value: string;
122
+ /**
123
+ * The URI of the corresponding 'Group' resource
124
+ */
125
+ $ref?: string;
126
+ /**
127
+ * A human-readable name, primarily used for display purposes
128
+ */
129
+ display?: string;
130
+ /**
131
+ * A label indicating the attribute's function (e.g., "direct" or "indirect")
132
+ */
133
+ type?: string;
134
+ }
135
+ /**
136
+ * SCIM Role
137
+ */
138
+ export interface Role {
139
+ /**
140
+ * The value of the role
141
+ */
142
+ value: string;
143
+ /**
144
+ * A human-readable name, primarily used for display purposes
145
+ */
146
+ display?: string;
147
+ /**
148
+ * A label indicating the attribute's function
149
+ */
150
+ type?: string;
151
+ /**
152
+ * A Boolean value indicating the 'primary' or preferred attribute value
153
+ */
154
+ primary?: boolean;
155
+ }
156
+ /**
157
+ * SCIM X509 Certificate
158
+ */
159
+ export interface X509Certificate {
160
+ /**
161
+ * The value of the X.509 certificate
162
+ */
163
+ value: string;
164
+ /**
165
+ * A human-readable name, primarily used for display purposes
166
+ */
167
+ display?: string;
168
+ /**
169
+ * A label indicating the attribute's function
170
+ */
171
+ type?: string;
172
+ /**
173
+ * A Boolean value indicating the 'primary' or preferred attribute value
174
+ */
175
+ primary?: boolean;
176
+ }
177
+ /**
178
+ * SCIM Enterprise User Extension
179
+ * @see https://datatracker.ietf.org/doc/html/rfc7643#section-4.3
180
+ */
181
+ export interface EnterpriseUser {
182
+ /**
183
+ * Numeric or alphanumeric identifier assigned to a person
184
+ */
185
+ employeeNumber?: string;
186
+ /**
187
+ * Identifies the name of a cost center
188
+ */
189
+ costCenter?: string;
190
+ /**
191
+ * Identifies the name of an organization
192
+ */
193
+ organization?: string;
194
+ /**
195
+ * Identifies the name of a division
196
+ */
197
+ division?: string;
198
+ /**
199
+ * Identifies the name of a department
200
+ */
201
+ department?: string;
202
+ /**
203
+ * The user's manager
204
+ */
205
+ manager?: {
206
+ /**
207
+ * The "id" of the SCIM resource representing the User's manager
208
+ */
209
+ value?: string;
210
+ /**
211
+ * The URI of the SCIM resource representing the User's manager
212
+ */
213
+ $ref?: string;
214
+ /**
215
+ * The displayName of the User's manager
216
+ */
217
+ displayName?: string;
218
+ };
219
+ }
220
+ /**
221
+ * SCIM User Resource
222
+ */
223
+ export interface User {
224
+ /**
225
+ * REQUIRED. Unique identifier for the User, typically from the provider
226
+ */
227
+ id?: string;
228
+ /**
229
+ * REQUIRED. A unique identifier for a SCIM resource as defined by the service provider
230
+ */
231
+ externalId?: string;
232
+ /**
233
+ * Resource metadata
234
+ */
235
+ meta?: {
236
+ resourceType?: string;
237
+ created?: string;
238
+ lastModified?: string;
239
+ location?: string;
240
+ version?: string;
241
+ };
242
+ /**
243
+ * REQUIRED. Unique identifier for the User, typically used for login
244
+ */
245
+ userName: string;
246
+ /**
247
+ * The components of the user's name
248
+ */
249
+ name?: Name;
250
+ /**
251
+ * The name of the User, suitable for display to end-users
252
+ */
253
+ displayName?: string;
254
+ /**
255
+ * The casual way to address the user
256
+ */
257
+ nickName?: string;
258
+ /**
259
+ * A fully qualified URL pointing to a page representing the User's online profile
260
+ */
261
+ profileUrl?: string;
262
+ /**
263
+ * The user's title, such as "Vice President"
264
+ */
265
+ title?: string;
266
+ /**
267
+ * Used to identify the relationship between the organization and the user
268
+ */
269
+ userType?: string;
270
+ /**
271
+ * Indicates the User's preferred written or spoken language
272
+ */
273
+ preferredLanguage?: string;
274
+ /**
275
+ * Used to indicate the User's default location for purposes of localizing items such as currency
276
+ */
277
+ locale?: string;
278
+ /**
279
+ * The User's time zone in the "Olson" time zone database format
280
+ */
281
+ timezone?: string;
282
+ /**
283
+ * A Boolean value indicating the User's administrative status
284
+ */
285
+ active?: boolean;
286
+ /**
287
+ * The User's cleartext password
288
+ */
289
+ password?: string;
290
+ /**
291
+ * Email addresses for the user
292
+ */
293
+ emails?: Email[];
294
+ /**
295
+ * Phone numbers for the User
296
+ */
297
+ phoneNumbers?: PhoneNumber[];
298
+ /**
299
+ * Instant messaging addresses for the User
300
+ */
301
+ ims?: Array<{
302
+ value: string;
303
+ display?: string;
304
+ type?: string;
305
+ primary?: boolean;
306
+ }>;
307
+ /**
308
+ * URLs of photos of the User
309
+ */
310
+ photos?: Array<{
311
+ value: string;
312
+ display?: string;
313
+ type?: string;
314
+ primary?: boolean;
315
+ }>;
316
+ /**
317
+ * Physical mailing addresses for this User
318
+ */
319
+ addresses?: Address[];
320
+ /**
321
+ * A list of groups to which the user belongs
322
+ */
323
+ groups?: Group[];
324
+ /**
325
+ * A list of entitlements for the User
326
+ */
327
+ entitlements?: Array<{
328
+ value: string;
329
+ display?: string;
330
+ type?: string;
331
+ primary?: boolean;
332
+ }>;
333
+ /**
334
+ * A list of roles for the User
335
+ */
336
+ roles?: Role[];
337
+ /**
338
+ * A list of certificates issued to the User
339
+ */
340
+ x509Certificates?: X509Certificate[];
341
+ /**
342
+ * Enterprise User Extension
343
+ */
344
+ 'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User'?: EnterpriseUser;
345
+ /**
346
+ * REQUIRED. The schemas attribute is an array of Strings which allows introspection of the supported schema version
347
+ */
348
+ schemas?: string[];
349
+ }
350
+ /**
351
+ * Creates a StandardSchemaV1 for validating SCIM User resources.
352
+ * @param vendor - The name of the vendor creating this schema
353
+ * @returns A StandardSchemaV1 instance for SCIM User resources
354
+ */
355
+ export declare function userSchema(vendor: string): StandardSchemaV1<Record<string, unknown>, User>;
356
+ //# sourceMappingURL=scim-schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scim-schema.d.ts","sourceRoot":"","sources":["../src/scim-schema.ts"],"names":[],"mappings":"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"}
package/dist/server.d.ts CHANGED
@@ -4,3 +4,4 @@ export declare function getRequiredUser(request: Request, config?: ESConfig): Pr
4
4
  export declare function initiateLogin(config: LoginConfig): Promise<Response>;
5
5
  export declare function callback(request: Request, config?: ESConfig): Promise<Response>;
6
6
  export declare function handler(request: Request, config?: SSOHandlerConfig): Promise<Response>;
7
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAC;AAoBrE,wBAAsB,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,QAAQ,mEAEhE;AAED,wBAAsB,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,QAAQ,uDAIxE;AAED,wBAAsB,aAAa,CAAC,MAAM,EAAE,WAAW,qBAItD;AAED,wBAAsB,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,QAAQ,qBAIjE;AAED,wBAAsB,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,gBAAgB,qBAIxE"}
@@ -0,0 +1,179 @@
1
+ /**
2
+ * Session management for tracking user sessions and enabling backchannel logout.
3
+ *
4
+ * Session stores are optional - the package works with JWT cookies alone.
5
+ * Sessions are only required for backchannel logout functionality.
6
+ *
7
+ * ## Session Validation Strategies
8
+ *
9
+ * When using a session store, you can configure when sessions are validated:
10
+ *
11
+ * ### 'always' (default)
12
+ * Validates session on every authenticated request.
13
+ * - **Security**: Maximum - immediate session revocation
14
+ * - **Performance**: InMemory ~0.00005ms, Redis ~1-2ms per request
15
+ * - **Backchannel Logout**: Takes effect immediately
16
+ * - **Use when**: Security is paramount, using InMemory or Redis backend
17
+ *
18
+ * ### 'refresh-only'
19
+ * Validates session only during token refresh (typically every 5-15 minutes).
20
+ * - **Security**: Good - 5-15 minute revocation window
21
+ * - **Performance**: 99% reduction in session lookups
22
+ * - **Backchannel Logout**: Takes effect within token TTL (5-15 min)
23
+ * - **Use when**: Performance is critical AND delayed revocation is acceptable
24
+ * - **WARNING**: Compromised sessions remain valid until next refresh
25
+ *
26
+ * ### 'disabled'
27
+ * Never validates sessions against the store.
28
+ * - **Security**: None - backchannel logout doesn't work
29
+ * - **Performance**: No overhead
30
+ * - **Use when**: Cookie-only mode without session store
31
+ * - **WARNING**: Do not use with session_store configured
32
+ *
33
+ * ## Performance Characteristics
34
+ *
35
+ * | Backend | Lookup Time | Impact on Request | Recommendation |
36
+ * |--------------|-------------|-------------------|------------------------|
37
+ * | InMemory | <0.00005ms | Negligible | Use 'always' |
38
+ * | Redis | 1-2ms | 2-4% increase | Use 'always' or test |
39
+ * | Database | 5-20ms | 10-40% increase | Use Redis cache layer |
40
+ *
41
+ * ## Example Usage
42
+ *
43
+ * ```typescript
44
+ * import { sso, InMemorySessionStore } from '@enterprisestandard/react/server';
45
+ *
46
+ * // Maximum security (default)
47
+ * const secure = sso({
48
+ * // ... other config
49
+ * session_store: new InMemorySessionStore(),
50
+ * session_validation: 'always', // Immediate revocation
51
+ * });
52
+ *
53
+ * // High performance
54
+ * const fast = sso({
55
+ * // ... other config
56
+ * session_store: new InMemorySessionStore(),
57
+ * session_validation: {
58
+ * strategy: 'refresh-only' // 5-15 min revocation delay
59
+ * }
60
+ * });
61
+ * ```
62
+ */
63
+ /**
64
+ * Core session data tracked for each authenticated user session.
65
+ *
66
+ * @template TExtended - Type-safe custom data that consumers can add to sessions
67
+ */
68
+ export type Session<TExtended = Record<string, never>> = {
69
+ /**
70
+ * Session ID from the Identity Provider (from `sid` claim in ID token).
71
+ * This is the unique identifier for the session.
72
+ */
73
+ sid: string;
74
+ /**
75
+ * Subject identifier (user ID) from the Identity Provider.
76
+ * From the `sub` claim in the ID token.
77
+ */
78
+ sub: string;
79
+ /**
80
+ * Timestamp when the session was created.
81
+ */
82
+ createdAt: Date;
83
+ /**
84
+ * Timestamp of the last activity in this session.
85
+ * Can be updated to track session activity.
86
+ */
87
+ lastActivityAt: Date;
88
+ /**
89
+ * Allow consumers to add runtime data to sessions.
90
+ */
91
+ [key: string]: unknown;
92
+ } & TExtended;
93
+ /**
94
+ * Abstract interface for session storage backends.
95
+ *
96
+ * Consumers can implement this interface to use different storage backends:
97
+ * - Redis
98
+ * - Database (PostgreSQL, MySQL, etc.)
99
+ * - Distributed cache
100
+ * - Custom solutions
101
+ *
102
+ * @template TExtended - Type-safe custom data that consumers can add to sessions
103
+ *
104
+ * @example
105
+ * ```typescript
106
+ * // Custom session data
107
+ * type MySessionData = {
108
+ * ipAddress: string;
109
+ * userAgent: string;
110
+ * };
111
+ *
112
+ * // Implement custom store
113
+ * class RedisSessionStore implements SessionStore<MySessionData> {
114
+ * async create(session: Session<MySessionData>): Promise<void> {
115
+ * await redis.set(`session:${session.sid}`, JSON.stringify(session));
116
+ * }
117
+ * // ... other methods
118
+ * }
119
+ * ```
120
+ */
121
+ export interface SessionStore<TExtended = Record<string, never>> {
122
+ /**
123
+ * Create a new session in the store.
124
+ *
125
+ * @param session - The session data to store
126
+ * @throws Error if session with same sid already exists
127
+ */
128
+ create(session: Session<TExtended>): Promise<void>;
129
+ /**
130
+ * Retrieve a session by its IdP session ID (sid).
131
+ *
132
+ * @param sid - The session.sid from the Identity Provider
133
+ * @returns The session if found, null otherwise
134
+ */
135
+ get(sid: string): Promise<Session<TExtended> | null>;
136
+ /**
137
+ * Update an existing session with partial data.
138
+ *
139
+ * Commonly used to update lastActivityAt or add custom fields.
140
+ *
141
+ * @param sid - The session.sid to update
142
+ * @param data - Partial session data to merge
143
+ * @throws Error if session not found
144
+ */
145
+ update(sid: string, data: Partial<Session<TExtended>>): Promise<void>;
146
+ /**
147
+ * Delete a session by its IdP session ID (sid).
148
+ *
149
+ * Used for both normal logout and backchannel logout flows.
150
+ *
151
+ * @param sid - The session.sid to delete
152
+ */
153
+ delete(sid: string): Promise<void>;
154
+ }
155
+ /**
156
+ * In-memory session store implementation using Maps.
157
+ *
158
+ * Suitable for:
159
+ * - Development and testing
160
+ * - Single-server deployments
161
+ * - Applications without high availability requirements
162
+ *
163
+ * NOT suitable for:
164
+ * - Multi-server deployments (sessions not shared)
165
+ * - High availability scenarios (sessions lost on restart)
166
+ * - Production applications with distributed architecture
167
+ *
168
+ * For production, implement SessionStore with Redis or a database.
169
+ *
170
+ * @template TExtended - Type-safe custom data that consumers can add to sessions
171
+ */
172
+ export declare class InMemorySessionStore<TExtended = Record<string, never>> implements SessionStore<TExtended> {
173
+ private sessions;
174
+ create(session: Session<TExtended>): Promise<void>;
175
+ get(sid: string): Promise<Session<TExtended> | null>;
176
+ update(sid: string, data: Partial<Session<TExtended>>): Promise<void>;
177
+ delete(sid: string): Promise<void>;
178
+ }
179
+ //# sourceMappingURL=session-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-store.d.ts","sourceRoot":"","sources":["../src/session-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6DG;AAEH;;;;GAIG;AACH,MAAM,MAAM,OAAO,CAAC,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI;IACvD;;;OAGG;IACH,GAAG,EAAE,MAAM,CAAC;IAEZ;;;OAGG;IACH,GAAG,EAAE,MAAM,CAAC;IAEZ;;OAEG;IACH,SAAS,EAAE,IAAI,CAAC;IAEhB;;;OAGG;IACH,cAAc,EAAE,IAAI,CAAC;IAErB;;OAEG;IACH,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,GAAG,SAAS,CAAC;AAEd;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,WAAW,YAAY,CAAC,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC;IAC7D;;;;;OAKG;IACH,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnD;;;;;OAKG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,CAAC;IAErD;;;;;;;;OAQG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtE;;;;;;OAMG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACpC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,oBAAoB,CAAC,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAE,YAAW,YAAY,CAAC,SAAS,CAAC;IACrG,OAAO,CAAC,QAAQ,CAAyC;IAEnD,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAQlD,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC;IAIpD,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAWrE,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAGzC"}
package/dist/sso.d.ts CHANGED
@@ -1,19 +1,24 @@
1
1
  import type { EnterpriseStandard, EnterpriseUser } from '.';
2
- export type SSOConfig = {
3
- authority: string;
4
- token_url: string;
5
- authorization_url: string;
6
- client_id: string;
7
- redirect_uri: string;
8
- response_type: string;
9
- scope: string;
10
- post_logout_redirect_uri?: string;
2
+ import type { IdTokenClaims, OidcCallbackParams, TokenResponse } from './oidc-schema';
3
+ import type { StandardSchemaV1 } from './standard-schema';
4
+ import type { SessionStore } from './session-store';
5
+ export type SSOConfig<TSessionData = Record<string, never>> = {
6
+ authority?: string;
7
+ token_url?: string;
8
+ authorization_url?: string;
9
+ client_id?: string;
10
+ redirect_uri?: string;
11
+ response_type?: 'code';
12
+ scope?: string;
11
13
  silent_redirect_uri?: string;
12
14
  jwks_uri?: string;
13
- cookiePrefix?: string;
14
- cookiePath?: string;
15
- sameSite?: 'Strict' | 'Lax';
16
- secure?: boolean;
15
+ cookies_prefix?: string;
16
+ cookies_path?: string;
17
+ cookies_secure?: boolean;
18
+ cookies_same_site?: 'Strict' | 'Lax';
19
+ end_session_endpoint?: string;
20
+ revocation_endpoint?: string;
21
+ session_store?: SessionStore<TSessionData>;
17
22
  };
18
23
  export type ESConfig = {
19
24
  es?: EnterpriseStandard;
@@ -29,13 +34,23 @@ export type SSOHandlerConfig = {
29
34
  landingUrl?: string;
30
35
  tokenUrl?: string;
31
36
  refreshUrl?: string;
37
+ jwksUrl?: string;
38
+ logoutUrl?: string;
39
+ logoutBackChannelUrl?: string;
40
+ validation?: {
41
+ callbackParams?: StandardSchemaV1<unknown, OidcCallbackParams>;
42
+ idTokenClaims?: StandardSchemaV1<unknown, IdTokenClaims>;
43
+ tokenResponse?: StandardSchemaV1<unknown, TokenResponse>;
44
+ };
32
45
  } & ESConfig;
33
- export type SSO = {
46
+ export type SSO<_TSessionData = Record<string, never>> = {
34
47
  getUser: (request: Request) => Promise<EnterpriseUser | undefined>;
35
48
  getRequiredUser: (request: Request) => Promise<EnterpriseUser>;
36
49
  getJwt: (request: Request) => Promise<string | undefined>;
37
50
  initiateLogin: (config: LoginConfig) => Promise<Response>;
51
+ logout: (request: Request, config?: LoginConfig) => Promise<Response>;
38
52
  callbackHandler: (request: Request) => Promise<Response>;
39
53
  handler: (request: Request, handlerConfig?: SSOHandlerConfig) => Promise<Response>;
40
54
  };
41
- export declare function sso(config: SSOConfig): SSO;
55
+ export declare function sso<TSessionData = Record<string, never>>(config: SSOConfig<TSessionData>): SSO<TSessionData>;
56
+ //# sourceMappingURL=sso.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sso.d.ts","sourceRoot":"","sources":["../src/sso.ts"],"names":[],"mappings":"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"}
@@ -53,3 +53,4 @@ export declare namespace StandardSchemaV1 {
53
53
  /** Infers the output type of a Standard Schema. */
54
54
  type InferOutput<Schema extends StandardSchemaV1> = NonNullable<Schema['~standard']['types']>['output'];
55
55
  }
56
+ //# sourceMappingURL=standard-schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"standard-schema.d.ts","sourceRoot":"","sources":["../src/standard-schema.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,MAAM,WAAW,gBAAgB,CAAC,KAAK,GAAG,OAAO,EAAE,MAAM,GAAG,KAAK;IAC/D,sCAAsC;IACtC,QAAQ,CAAC,WAAW,EAAE,gBAAgB,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;CAC7D;AAED,MAAM,CAAC,OAAO,WAAW,gBAAgB,CAAC;IACxC,gDAAgD;IAChD,UAAiB,KAAK,CAAC,KAAK,GAAG,OAAO,EAAE,MAAM,GAAG,KAAK;QACpD,0CAA0C;QAC1C,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;QACpB,6CAA6C;QAC7C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,sCAAsC;QACtC,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,MAAM,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;QAChF,iDAAiD;QACjD,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;KACnD;IAED,qDAAqD;IACrD,KAAY,MAAM,CAAC,MAAM,IAAI,aAAa,CAAC,MAAM,CAAC,GAAG,aAAa,CAAC;IAEnE,mDAAmD;IACnD,UAAiB,aAAa,CAAC,MAAM;QACnC,8BAA8B;QAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,+BAA+B;QAC/B,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC;KAC7B;IAED,gDAAgD;IAChD,UAAiB,aAAa;QAC5B,uCAAuC;QACvC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC;KACvC;IAED,iDAAiD;IACjD,UAAiB,KAAK;QACpB,sCAAsC;QACtC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,qCAAqC;QACrC,QAAQ,CAAC,IAAI,CAAC,EAAE,aAAa,CAAC,WAAW,GAAG,WAAW,CAAC,GAAG,SAAS,CAAC;KACtE;IAED,+CAA+C;IAC/C,UAAiB,WAAW;QAC1B,2CAA2C;QAC3C,QAAQ,CAAC,GAAG,EAAE,WAAW,CAAC;KAC3B;IAED,2CAA2C;IAC3C,UAAiB,KAAK,CAAC,KAAK,GAAG,OAAO,EAAE,MAAM,GAAG,KAAK;QACpD,oCAAoC;QACpC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;QACtB,qCAAqC;QACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;KACzB;IAED,kDAAkD;IAClD,KAAY,UAAU,CAAC,MAAM,SAAS,gBAAgB,IAAI,WAAW,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAE7G,mDAAmD;IACnD,KAAY,WAAW,CAAC,MAAM,SAAS,gBAAgB,IAAI,WAAW,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;CAChH"}
@@ -2,3 +2,4 @@ import type { PropsWithChildren } from 'react';
2
2
  export declare function SignInLoading({ complete, children }: {
3
3
  complete?: boolean;
4
4
  } & PropsWithChildren): import("react/jsx-runtime").JSX.Element | null;
5
+ //# sourceMappingURL=sign-in-loading.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sign-in-loading.d.ts","sourceRoot":"","sources":["../../src/ui/sign-in-loading.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAG/C,wBAAgB,aAAa,CAAC,EAAE,QAAgB,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,iBAAiB,kDAKvG"}
@@ -1,2 +1,3 @@
1
1
  import type { PropsWithChildren } from 'react';
2
2
  export declare function SignedIn({ children }: PropsWithChildren): import("react/jsx-runtime").JSX.Element | null;
3
+ //# sourceMappingURL=signed-in.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signed-in.d.ts","sourceRoot":"","sources":["../../src/ui/signed-in.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAG/C,wBAAgB,QAAQ,CAAC,EAAE,QAAQ,EAAE,EAAE,iBAAiB,kDAKvD"}
@@ -1,2 +1,3 @@
1
1
  import type { PropsWithChildren } from 'react';
2
2
  export declare function SignedOut({ children }: PropsWithChildren): import("react/jsx-runtime").JSX.Element | null;
3
+ //# sourceMappingURL=signed-out.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signed-out.d.ts","sourceRoot":"","sources":["../../src/ui/signed-out.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAG/C,wBAAgB,SAAS,CAAC,EAAE,QAAQ,EAAE,EAAE,iBAAiB,kDAKxD"}
@@ -27,4 +27,9 @@ interface UseTokenReturn {
27
27
  refresh: () => Promise<void>;
28
28
  }
29
29
  export declare function useToken(): UseTokenReturn;
30
+ export declare function logout(logoutUrl: string): Promise<{
31
+ success: boolean;
32
+ error?: string;
33
+ }>;
30
34
  export {};
35
+ //# sourceMappingURL=sso-provider.d.ts.map