@auth0/auth0-server-js 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2025 Auth0, Inc. <support@auth0.com> (http://auth0.com)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -10,7 +10,7 @@ Using this SDK as-is in your application may not be trivial, as it is designed t
10
10
 
11
11
  ## Documentation
12
12
 
13
- - [Examples](https://github.com/auth0/auth0-server-js/blob/main/packages/auth0-server-js/EXAMPLES.md) - examples for your different use cases.
13
+ - [Examples](https://github.com/auth0/auth0-auth-js/blob/main/packages/auth0-server-js/EXAMPLES.md) - examples for your different use cases.
14
14
  - [Docs Site](https://auth0.com/docs) - explore our docs site and learn more about Auth0.
15
15
 
16
16
  ## Getting Started
@@ -53,7 +53,7 @@ The `AUTH0_REDIRECT_URI` is needed to tell Auth0 what URL to redirect back to af
53
53
 
54
54
  ### 3. Configuring the Store
55
55
 
56
- The `auth0-server-js` SDK does not come with a built-in store for both transaction and state data, **it's required to provide a persistent solution** that fits your use-case.
56
+ The `auth0-server-js` SDK comes with a built-in store for both transaction and state data, however **it's required to provide it a CookieHandler implementation** that fits your use-case.
57
57
  The goal of `auth0-server-js` is to provide a flexible API that allows you to use any storage mechanism you prefer, but is mostly designed to work with cookie and session-based storage kept in mind.
58
58
 
59
59
  The SDK methods accept an optional `storeOptions` object that can be used to pass additional options to the storage methods, such as Request / Response objects, allowing to control cookies in the storage layer.
@@ -72,7 +72,7 @@ import { FastifyReply, FastifyRequest } from 'fastify';
72
72
  import { CookieSerializeOptions } from '@fastify/cookie';
73
73
  import {
74
74
  AbstractStateStore,
75
- TransactionStore,
75
+ AbstractTransactionStore,
76
76
  ServerClient,
77
77
  StateData,
78
78
  TransactionData
@@ -83,105 +83,37 @@ export interface StoreOptions {
83
83
  reply: FastifyReply;
84
84
  }
85
85
 
86
- const auth0 = new ServerClient<StoreOptions>({
87
- transactionStore: new StatelessTransactionStore({ secret: options.secret }),
88
- stateStore: new StatelessStateStore({ secret: options.secret }),
89
- });
90
-
91
- export class StatelessTransactionStore implements TransactionStore<StoreOptions> {
92
- async set(identifier: string, transactionData: TransactionData, removeIfExists?: boolean, options?: StoreOptions): Promise<void> {
93
- // We can not handle cookies in Fastify when the `StoreOptions` are not provided.
94
- if (!options) {
95
- throw new Error();
96
- }
97
-
98
- // Note that `removeIfExists` is not used in Stateless storage, but it's kept for compatibility with Stateful storage.
99
-
100
- const maxAge = 60 * 60;
101
- const cookieOpts: CookieSerializeOptions = { httpOnly: true, sameSite: 'lax', path: '/', maxAge };
102
-
103
- options.reply.setCookie(identifier, JSON.stringify(transactionData), cookieOpts);
104
- }
105
-
106
- async get(identifier: string, options?: StoreOptions): Promise<TransactionData | undefined> {
107
- // We can not handle cookies in Fastify when the `StoreOptions` are not provided.
108
- if (!options) {
109
- throw new Error();
110
- }
111
-
112
- const cookieValue = options.request.cookies[identifier];
113
-
114
- if (cookieValue) {
115
- return JSON.parse(cookieValue) as TransactionData;
116
- }
117
- }
118
-
119
- async delete(identifier: string, options?: StoreOptions | undefined): Promise<void> {
120
- // We can not handle cookies in Fastify when the `StoreOptions` are not provided.
121
- if (!options) {
122
- throw new Error();
123
- }
124
-
125
- options?.reply.clearCookie(identifier);
86
+ export class FastifyCookieHandler implements CookieHandler<StoreOptions> {
87
+ setCookie(
88
+ name: string,
89
+ value: string,
90
+ options?: CookieSerializeOptions,
91
+ storeOptions?: StoreOptions
92
+ ): void {
93
+ // Handle storeOptions being undefined if needed.
94
+ storeOptions!.reply.setCookie(name, value, options || {});
126
95
  }
127
- }
128
96
 
129
- export class StatelessStateStore extends AbstractStateStore<StoreOptions> {
130
- async set(
131
- identifier: string,
132
- stateData: StateData,
133
- removeIfExists?: boolean,
134
- options?: StoreOptions | undefined
135
- ): Promise<void> {
136
- // We can not handle cookies in Fastify when the `StoreOptions` are not provided.
137
- if (!options) {
138
- throw new Error();
139
- }
140
-
141
- // Note that `removeIfExists` is not used in Stateless storage, but it's kept for compatibility with Stateful storage.
142
-
143
- const maxAge = ?; // Set the max age of the cookie
144
- const cookieOpts: CookieSerializeOptions = {
145
- httpOnly: true,
146
- sameSite: 'lax',
147
- path: '/',
148
- secure: 'auto',
149
- maxAge,
150
- };
151
- const expiration = Math.floor(Date.now() / 1000 + maxAge);
152
- const encryptedStateData = await this.encrypt(identifier, stateData, expiration);
153
-
154
- options.reply.setCookie(identifier, encryptedStateData, cookieOpts);
97
+ getCookie(name: string, storeOptions?: StoreOptions): string | undefined {
98
+ // Handle storeOptions being undefined if needed.
99
+ return storeOptions!.request.cookies?.[name];
155
100
  }
156
101
 
157
- async get(identifier: string, options?: StoreOptions | undefined): Promise<StateData | undefined> {
158
- // We can not handle cookies in Fastify when the `StoreOptions` are not provided.
159
- if (!options) {
160
- throw new Error();
161
- }
162
-
163
- const encryptedStateData = options.request.cookies[identifier];
164
-
165
- if (encryptedStateData) {
166
- return (await this.decrypt(identifier, encryptedStateData)) as StateData;
167
- }
102
+ getCookies(storeOptions?: StoreOptions): Record<string, string> {
103
+ // Handle storeOptions being undefined if needed.
104
+ return storeOptions!.request.cookies as Record<string, string>;
168
105
  }
169
106
 
170
- async delete(identifier: string, options?: StoreOptions | undefined): Promise<void> {
171
- // We can not handle cookies in Fastify when the `StoreOptions` are not provided.
172
- if (!options) {
173
- throw new Error();
174
- }
175
-
176
- options?.reply.clearCookie(identifier);
177
- }
178
-
179
- deleteByLogoutToken(): Promise<void> {
180
- throw new Error(
181
- 'Backchannel logout is not available when using Stateless Storage. Use Stateful Storage instead.'
182
- );
107
+ deleteCookie(name: string, storeOptions?: StoreOptions): void {
108
+ // Handle storeOptions being undefined if needed.
109
+ storeOptions!.reply.clearCookie(name);
183
110
  }
184
111
  }
112
+
113
+ const auth0 = new ServerClient<StoreOptions>({
114
+ transactionStore: new CookieTransactionStore({ secret: options.secret }, new FastifyCookieHandler()),
115
+ stateStore: new StatelessStateStore({ secret: options.secret }, new FastifyCookieHandler()),
116
+ });
185
117
  ```
186
118
 
187
119
  #### Stateful Store
@@ -207,113 +139,41 @@ export interface StoreOptions {
207
139
  reply: FastifyReply;
208
140
  }
209
141
 
210
- const auth0 = new ServerClient<StoreOptions>({
211
- transactionStore: new StatelessTransactionStore({ secret: '<secret>' }),
212
- stateStore: new StatefulStateStore({ secret: '<secret>' }),
213
- });
214
-
215
- export class StatefulStateStore extends AbstractSessionStore {
216
- async set(
217
- identifier: string,
218
- stateData: StateData,
219
- removeIfExists?: boolean,
220
- options?: StoreOptions | undefined
221
- ): Promise<void> {
222
- // We can not handle cookies in Fastify when the `StoreOptions` are not provided.
223
- if (!options) {
224
- throw new Error();
225
- }
226
-
227
- let sessionId = await this.getSessionId(identifier, options);
228
-
229
- // If this is a new session created by a new login we need to remove the old session
230
- // from the store and regenerate the session ID to prevent session fixation.
231
- if (sessionId && removeIfExists) {
232
- // Delete the session from the store by the sessionId.
233
- // await yourDeleteSessionLogic(sessionId);
234
- sessionId = generateId();
235
- }
236
-
237
- if (!sessionId) {
238
- sessionId = generateId();
239
- }
240
-
241
- const maxAge = ?; // Set the max age of the cookie
242
- const cookieOpts: CookieSerializeOptions = {
243
- httpOnly: true,
244
- sameSite: 'lax',
245
- path: '/',
246
- secure: 'auto',
247
- maxAge,
248
- };
249
- const expiration = Date.now() / 1000 + maxAge;
250
- const encryptedStateData = await this.encrypt<{ id: string }>(
251
- identifier,
252
- {
253
- id: sessionId,
254
- },
255
- expiration
256
- );
257
-
258
- // Save the stateData in the store, identified by the sessionId.
259
- // await yourSaveSessionLogic(sessionId, stateData);
260
-
261
- options.reply.setCookie(identifier, encryptedStateData, cookieOpts);
262
- }
263
-
264
- async get(identifier: string, options?: StoreOptions | undefined): Promise<StateData | undefined> {
265
- // We can not handle cookies in Fastify when the `StoreOptions` are not provided.
266
- if (!options) {
267
- throw new Error();
268
- }
269
-
270
- const sessionId = await this.getSessionId(identifier, options);
271
-
272
- if (sessionId) {
273
- // Retrieve the stateData from the store, identified by the sessionId.
274
- // const stateData = await yourGetSessionLogic(sessionId);
275
-
276
- // If we have a session cookie, but no `stateData`, we should remove the cookie.
277
- if (!stateData) {
278
- options?.reply.clearCookie(identifier);
279
- }
280
-
281
- return stateData;
282
- }
142
+ export class FastifyCookieHandler implements CookieHandler<StoreOptions> {
143
+ setCookie(
144
+ name: string,
145
+ value: string,
146
+ options?: CookieSerializeOptions,
147
+ storeOptions?: StoreOptions,
148
+ ): void {
149
+ // Handle storeOptions being undefined if needed.
150
+ storeOptions!.reply.setCookie(name, value, options || {});
283
151
  }
284
152
 
285
- async delete(identifier: string, options?: StoreOptions | undefined): Promise<void> {
286
- // We can not handle cookies in Fastify when the `StoreOptions` are not provided.
287
- if (!options) {
288
- throw new Error();
289
- }
290
-
291
- const sessionId = await this.getSessionId(identifier, options);
292
-
293
- if (sessionId) {
294
- // Delete the session from the store by the sessionId.
295
- // await yourDeleteSessionLogic(sessionId);
296
- }
297
-
298
- options?.reply.clearCookie(identifier);
153
+ getCookie(name: string, storeOptions?: StoreOptions): string | undefined {
154
+ // Handle storeOptions being undefined if needed.
155
+ return storeOptions!.request.cookies?.[name];
299
156
  }
300
157
 
301
- private async getSessionId(identifier: string, options: StoreOptions) {
302
- const cookieValue = options.request.cookies[identifier];
303
- if (cookieValue) {
304
- const sessionCookie = await this.decrypt<{ id: string }>(identifier, cookieValue);
305
- return sessionCookie.id;
306
- }
158
+ getCookies(storeOptions?: StoreOptions): Record<string, string> {
159
+ // Handle storeOptions being undefined if needed.
160
+ return storeOptions!.request.cookies as Record<string, string>;
307
161
  }
308
162
 
309
- deleteByLogoutToken(claims: LogoutTokenClaims, options?: StoreOptions | undefined): Promise<void> {
310
- // Delete the session from the store by the LogoutTokenClaims (sub and sid)
311
- // await yourDeleteSessionByLogoutTokenLogic(sessionId);
163
+ deleteCookie(name: string, storeOptions?: StoreOptions): void {
164
+ // Handle storeOptions being undefined if needed.
165
+ storeOptions!.reply.clearCookie(name);
312
166
  }
313
167
  }
168
+
169
+ const auth0 = new ServerClient<StoreOptions>({
170
+ transactionStore: new CookieTransactionStore({ secret: options.secret }, new FastifyCookieHandler()),
171
+ stateStore: new StatefulStateStore({ secret: options.secret }, new FastifyCookieHandler()),
172
+ });
173
+
314
174
  ```
315
175
 
316
- Note that `storeOptions` is optional, but required when wanting to interact with the framework to set cookies. Here's how to pass the `storeOptions` to `startInteractiveLogin()` in a Fastify application:
176
+ Note that `storeOptions` is optional in the SDK's methods, but required when wanting to interact with the framework to set cookies. Here's how to pass the `storeOptions` to `startInteractiveLogin()` in a Fastify application:
317
177
 
318
178
  ```ts
319
179
  fastify.get('/auth/login', async (request, reply) => {
@@ -324,7 +184,7 @@ fastify.get('/auth/login', async (request, reply) => {
324
184
  });
325
185
  ```
326
186
 
327
- Because storage systems in Web Applications are mostly cookie-based, the `storeOptions` object is used to pass the `request` and `reply` objects to the storage methods, allowing to control cookies in the storage layer. It's expected to pass this to every interaction with the SDK.
187
+ Because storage systems in Web Applications are mostly cookie-based, the `storeOptions` object is used to pass the `request` and `reply` (in the case of Fastify, as per the example) objects to the storage methods, allowing to control cookies in the storage layer. It's expected to pass this to every interaction with the SDK.
328
188
 
329
189
  ### 4. Add login to your Application (interactive)
330
190
 
@@ -400,12 +260,12 @@ fastify.get('/auth/logout', async (request, reply) => {
400
260
  We appreciate feedback and contribution to this repo! Before you get started, please read the following:
401
261
 
402
262
  - [Auth0's general contribution guidelines](https://github.com/auth0/open-source-template/blob/master/GENERAL-CONTRIBUTING.md)
403
- - [Auth0's code of conduct guidelines](https://github.com/auth0/auth0-server-js/blob/main/CODE-OF-CONDUCT.md)
404
- - [This repo's contribution guide](./../../CONTRIBUTING.md)
263
+ - [Auth0's code of conduct guidelines](https://github.com/auth0/open-source-template/blob/master/CODE-OF-CONDUCT.md)
264
+ - [This repo's contribution guide](https://github.com/auth0/auth0-auth-js/blob/main/CONTRIBUTING.md)
405
265
 
406
266
  ### Raise an issue
407
267
 
408
- To provide feedback or report a bug, please [raise an issue on our issue tracker](https://github.com/auth0/auth0-server-js/issues).
268
+ To provide feedback or report a bug, please [raise an issue on our issue tracker](https://github.com/auth0/auth0-auth-js/issues).
409
269
 
410
270
  ## Vulnerability Reporting
411
271
 
@@ -424,5 +284,5 @@ Please do not report security vulnerabilities on the public GitHub issue tracker
424
284
  Auth0 is an easy to implement, adaptable authentication and authorization platform. To learn more checkout <a href="https://auth0.com/why-auth0">Why Auth0?</a>
425
285
  </p>
426
286
  <p align="center">
427
- This project is licensed under the MIT license. See the <a href="https://github.com/auth0/auth0-server-js/blob/main/packages/auth0-auth-js/LICENSE"> LICENSE</a> file for more info.
287
+ This project is licensed under the MIT license. See the <a href="https://github.com/auth0/auth0-auth-js/blob/main/packages/auth0-server-js/LICENSE"> LICENSE</a> file for more info.
428
288
  </p>
package/dist/index.cjs CHANGED
@@ -23,11 +23,14 @@ __export(index_exports, {
23
23
  AbstractStateStore: () => AbstractStateStore,
24
24
  AbstractTransactionStore: () => AbstractTransactionStore,
25
25
  BackchannelLogoutError: () => BackchannelLogoutError,
26
+ CookieTransactionStore: () => CookieTransactionStore,
26
27
  MissingRequiredArgumentError: () => MissingRequiredArgumentError,
27
28
  MissingSessionError: () => MissingSessionError,
28
29
  MissingTransactionError: () => MissingTransactionError,
29
30
  ServerClient: () => ServerClient,
30
- StartLinkUserError: () => StartLinkUserError
31
+ StartLinkUserError: () => StartLinkUserError,
32
+ StatefulStateStore: () => StatefulStateStore,
33
+ StatelessStateStore: () => StatelessStateStore
31
34
  });
32
35
  module.exports = __toCommonJS(index_exports);
33
36
 
@@ -544,15 +547,198 @@ var AbstractTransactionStore = class extends AbstractStore {
544
547
  super(options);
545
548
  }
546
549
  };
550
+
551
+ // src/store/cookie-transaction-store.ts
552
+ var CookieTransactionStore = class extends AbstractTransactionStore {
553
+ #cookieHandler;
554
+ constructor(options, cookieHandler) {
555
+ super(options);
556
+ this.#cookieHandler = cookieHandler;
557
+ }
558
+ async set(identifier, transactionData, removeIfExists, options) {
559
+ const maxAge = 60 * 60;
560
+ const cookieOpts = { httpOnly: true, sameSite: "lax", path: "/", maxAge };
561
+ const expiration = Math.floor(Date.now() / 1e3 + maxAge);
562
+ const encryptedStateData = await this.encrypt(identifier, transactionData, expiration);
563
+ this.#cookieHandler.setCookie(identifier, encryptedStateData, cookieOpts, options);
564
+ }
565
+ async get(identifier, options) {
566
+ const cookieValue = this.#cookieHandler.getCookie(identifier, options);
567
+ if (cookieValue) {
568
+ return await this.decrypt(identifier, cookieValue);
569
+ }
570
+ }
571
+ async delete(identifier, options) {
572
+ this.#cookieHandler.deleteCookie(identifier, options);
573
+ }
574
+ };
575
+
576
+ // src/store/abstract-session-store.ts
577
+ var AbstractSessionStore = class extends AbstractStateStore {
578
+ #rolling;
579
+ #absoluteDuration;
580
+ #inactivityDuration;
581
+ constructor(options) {
582
+ super(options);
583
+ this.#rolling = options.rolling ?? true;
584
+ this.#absoluteDuration = options.absoluteDuration ?? 60 * 60 * 24 * 3;
585
+ this.#inactivityDuration = options.inactivityDuration ?? 60 * 60 * 24 * 1;
586
+ }
587
+ /**
588
+ * calculateMaxAge calculates the max age of the session based on createdAt and the rolling and absolute durations.
589
+ */
590
+ calculateMaxAge(createdAt) {
591
+ if (!this.#rolling) {
592
+ return this.#absoluteDuration;
593
+ }
594
+ const now = Date.now() / 1e3 | 0;
595
+ const expiresAt = Math.min(now + this.#inactivityDuration, createdAt + this.#absoluteDuration);
596
+ const maxAge = expiresAt - now;
597
+ return maxAge > 0 ? maxAge : 0;
598
+ }
599
+ };
600
+
601
+ // src/store/stateful-state-store.ts
602
+ var generateId = () => {
603
+ const bytes = new Uint8Array(16);
604
+ crypto.getRandomValues(bytes);
605
+ return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
606
+ };
607
+ var StatefulStateStore = class extends AbstractSessionStore {
608
+ #store;
609
+ #cookieOptions;
610
+ #cookieHandler;
611
+ constructor(options, cookieHandler) {
612
+ super(options);
613
+ this.#store = options.store;
614
+ this.#cookieOptions = options.cookie;
615
+ this.#cookieHandler = cookieHandler;
616
+ }
617
+ async set(identifier, stateData, removeIfExists, options) {
618
+ let sessionId = await this.getSessionId(identifier, options);
619
+ if (sessionId && removeIfExists) {
620
+ await this.#store.delete(sessionId);
621
+ sessionId = generateId();
622
+ }
623
+ sessionId ??= generateId();
624
+ const maxAge = this.calculateMaxAge(stateData.internal.createdAt);
625
+ const cookieOpts = {
626
+ httpOnly: true,
627
+ sameSite: this.#cookieOptions?.sameSite ?? "lax",
628
+ path: "/",
629
+ secure: this.#cookieOptions?.secure,
630
+ maxAge
631
+ };
632
+ const expiration = Date.now() / 1e3 + maxAge;
633
+ const encryptedStateData = await this.encrypt(
634
+ identifier,
635
+ {
636
+ id: sessionId
637
+ },
638
+ expiration
639
+ );
640
+ await this.#store.set(sessionId, stateData);
641
+ this.#cookieHandler.setCookie(identifier, encryptedStateData, cookieOpts, options);
642
+ }
643
+ async get(identifier, options) {
644
+ const sessionId = await this.getSessionId(identifier, options);
645
+ if (sessionId) {
646
+ const stateData = await this.#store.get(sessionId);
647
+ if (!stateData) {
648
+ this.#cookieHandler.deleteCookie(identifier, options);
649
+ }
650
+ return stateData;
651
+ }
652
+ }
653
+ async delete(identifier, options) {
654
+ const sessionId = await this.getSessionId(identifier, options);
655
+ if (sessionId) {
656
+ await this.#store.delete(sessionId);
657
+ }
658
+ this.#cookieHandler.deleteCookie(identifier, options);
659
+ }
660
+ async getSessionId(identifier, options) {
661
+ const cookieValue = this.#cookieHandler.getCookie(identifier, options);
662
+ if (cookieValue) {
663
+ const sessionCookie = await this.decrypt(identifier, cookieValue);
664
+ return sessionCookie.id;
665
+ }
666
+ }
667
+ deleteByLogoutToken(claims, options) {
668
+ return this.#store.deleteByLogoutToken(claims, options);
669
+ }
670
+ };
671
+
672
+ // src/store/stateless-state-store.ts
673
+ var StatelessStateStore = class extends AbstractSessionStore {
674
+ #cookieHandler;
675
+ constructor(options, cookieHandler) {
676
+ super(options);
677
+ this.#cookieHandler = cookieHandler;
678
+ }
679
+ async set(identifier, stateData, removeIfExists, options) {
680
+ const maxAge = this.calculateMaxAge(stateData.internal.createdAt);
681
+ const cookieOpts = {
682
+ httpOnly: true,
683
+ sameSite: "lax",
684
+ path: "/",
685
+ secure: true,
686
+ maxAge
687
+ };
688
+ const expiration = Math.floor(Date.now() / 1e3 + maxAge);
689
+ const encryptedStateData = await this.encrypt(identifier, stateData, expiration);
690
+ const chunkSize = 3072;
691
+ const chunkCount = Math.ceil(encryptedStateData.length / chunkSize);
692
+ const chunks = [...Array(chunkCount).keys()].map((i) => ({
693
+ value: encryptedStateData.substring(i * chunkSize, (i + 1) * chunkSize),
694
+ name: `${identifier}.${i}`
695
+ }));
696
+ chunks.forEach((chunk) => {
697
+ this.#cookieHandler.setCookie(chunk.name, chunk.value, cookieOpts, options);
698
+ });
699
+ const existingCookieKeys = this.getCookieKeys(identifier, options);
700
+ const cookieKeysToRemove = existingCookieKeys.filter((key) => !chunks.some((chunk) => chunk.name === key));
701
+ cookieKeysToRemove.forEach((key) => {
702
+ this.#cookieHandler.deleteCookie(key, options);
703
+ });
704
+ }
705
+ async get(identifier, options) {
706
+ const cookieKeys = this.getCookieKeys(identifier, options);
707
+ const encryptedStateData = cookieKeys.map((key) => ({
708
+ index: parseInt(key.split(".")[1], 10),
709
+ value: this.#cookieHandler.getCookie(key, options)
710
+ })).sort((a, b) => a.index - b.index).map((item) => item.value).join("");
711
+ if (encryptedStateData) {
712
+ return await this.decrypt(identifier, encryptedStateData);
713
+ }
714
+ }
715
+ async delete(identifier, options) {
716
+ const cookieKeys = this.getCookieKeys(identifier, options);
717
+ for (const key of cookieKeys) {
718
+ this.#cookieHandler.deleteCookie(key, options);
719
+ }
720
+ }
721
+ deleteByLogoutToken() {
722
+ throw new Error(
723
+ "Backchannel logout is not available when using Stateless Storage. Use Stateful Storage by providing a `sessionStore`"
724
+ );
725
+ }
726
+ getCookieKeys(identifier, options) {
727
+ return Object.keys(this.#cookieHandler.getCookies(options)).filter((key) => key.startsWith(identifier));
728
+ }
729
+ };
547
730
  // Annotate the CommonJS export names for ESM import in node:
548
731
  0 && (module.exports = {
549
732
  AbstractStateStore,
550
733
  AbstractTransactionStore,
551
734
  BackchannelLogoutError,
735
+ CookieTransactionStore,
552
736
  MissingRequiredArgumentError,
553
737
  MissingSessionError,
554
738
  MissingTransactionError,
555
739
  ServerClient,
556
- StartLinkUserError
740
+ StartLinkUserError,
741
+ StatefulStateStore,
742
+ StatelessStateStore
557
743
  });
558
744
  //# sourceMappingURL=index.cjs.map