auth-vir 3.1.2 → 5.0.0

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/src/cookie.ts CHANGED
@@ -1,13 +1,11 @@
1
1
  import {check} from '@augment-vir/assert';
2
- import {escapeStringForRegExp, safeMatch, type PartialWithUndefined} from '@augment-vir/common';
3
2
  import {
4
- calculateRelativeDate,
5
- convertDuration,
6
- getNowInUtcTimezone,
7
- type AnyDuration,
8
- type FullDate,
9
- type UtcTimezone,
10
- } from 'date-vir';
3
+ escapeStringForRegExp,
4
+ safeMatch,
5
+ type PartialWithUndefined,
6
+ type SelectFrom,
7
+ } from '@augment-vir/common';
8
+ import {convertDuration, type AnyDuration} from 'date-vir';
11
9
  import {type Primitive} from 'type-fest';
12
10
  import {parseUrl} from 'url-vir';
13
11
  import {type CreateJwtParams, type ParseJwtParams, type ParsedJwt} from './jwt/jwt.js';
@@ -18,11 +16,13 @@ import {createUserJwt, parseUserJwt, type JwtUserData} from './jwt/user-jwt.js';
18
16
  *
19
17
  * @category Internal
20
18
  */
21
- export enum AuthCookieName {
19
+ export enum AuthCookie {
22
20
  /** Used for a full user login auth. */
23
21
  Auth = 'auth',
24
22
  /** Use for a temporary "just signed up" auth. */
25
23
  SignUp = 'sign-up',
24
+ /** Used for storing the CSRF token. Not `HttpOnly` so that frontend JS can read it. */
25
+ Csrf = 'auth-vir-csrf',
26
26
  }
27
27
 
28
28
  /**
@@ -49,8 +49,13 @@ export type CookieParams = {
49
49
  * client, etc.
50
50
  */
51
51
  jwtParams: Readonly<CreateJwtParams>;
52
- cookieName?: string;
53
52
  } & PartialWithUndefined<{
53
+ /**
54
+ * Which auth cookie name to use.
55
+ *
56
+ * @default AuthCookie.Auth
57
+ */
58
+ authCookie: AuthCookie;
54
59
  /**
55
60
  * Is set to `true` (which should only be done in development environments), the cookie will be
56
61
  * allowed in insecure requests (non HTTPS requests).
@@ -60,15 +65,32 @@ export type CookieParams = {
60
65
  isDev: boolean;
61
66
  }>;
62
67
 
63
- /**
64
- * Output from {@link generateAuthCookie}.
65
- *
66
- * @category Internal
67
- */
68
- export type GenerateAuthCookieResult = {
69
- cookie: string;
70
- expiration: FullDate<UtcTimezone>;
71
- };
68
+ function generateSetCookie({
69
+ name,
70
+ value,
71
+ httpOnly,
72
+ cookieConfig,
73
+ }: {
74
+ name: string;
75
+ value: string;
76
+ httpOnly: boolean;
77
+ cookieConfig: Readonly<SelectFrom<CookieParams, {hostOrigin: true; isDev: true}>> &
78
+ PartialWithUndefined<SelectFrom<CookieParams, {cookieDuration: true}>>;
79
+ }): string {
80
+ return generateCookie({
81
+ [name]: value,
82
+ Domain: parseUrl(cookieConfig.hostOrigin).hostname,
83
+ HttpOnly: httpOnly,
84
+ Path: '/',
85
+ SameSite: 'Strict',
86
+ 'MAX-AGE': cookieConfig.cookieDuration
87
+ ? convertDuration(cookieConfig.cookieDuration, {
88
+ seconds: true,
89
+ }).seconds
90
+ : 0,
91
+ Secure: !cookieConfig.isDev,
92
+ });
93
+ }
72
94
 
73
95
  /**
74
96
  * Generate a secure cookie that stores the user JWT data. Used in host (backend) code.
@@ -78,26 +100,41 @@ export type GenerateAuthCookieResult = {
78
100
  export async function generateAuthCookie(
79
101
  userJwtData: Readonly<JwtUserData>,
80
102
  cookieConfig: Readonly<CookieParams>,
81
- ): Promise<GenerateAuthCookieResult> {
82
- const expiration = calculateRelativeDate(getNowInUtcTimezone(), cookieConfig.cookieDuration);
103
+ ): Promise<string> {
104
+ return generateSetCookie({
105
+ name: cookieConfig.authCookie || AuthCookie.Auth,
106
+ value: await createUserJwt(userJwtData, cookieConfig.jwtParams),
107
+ httpOnly: true,
108
+ cookieConfig,
109
+ });
110
+ }
83
111
 
84
- return {
85
- cookie: generateCookie({
86
- [cookieConfig.cookieName || 'auth']: await createUserJwt(
87
- userJwtData,
88
- cookieConfig.jwtParams,
89
- ),
90
- Domain: parseUrl(cookieConfig.hostOrigin).hostname,
91
- HttpOnly: true,
92
- Path: '/',
93
- SameSite: 'Strict',
94
- 'MAX-AGE': convertDuration(cookieConfig.cookieDuration, {
95
- seconds: true,
96
- }).seconds,
97
- Secure: !cookieConfig.isDev,
98
- }),
99
- expiration,
100
- };
112
+ /**
113
+ * Generate a CSRF token cookie. This cookie is intentionally not `HttpOnly` so that frontend
114
+ * JavaScript can read it and inject the value as a request header for double-submit verification.
115
+ *
116
+ * The CSRF cookie uses a fixed 400-day MAX-AGE rather than matching the auth cookie duration. 400
117
+ * days is the cross-browser safe maximum (Chrome caps cookie lifetimes at 400 days; other browsers
118
+ * accept it as-is). The CSRF token is only meaningful when paired with a valid JWT, so it doesn't
119
+ * need its own expiration management. It gets regenerated on every fresh login.
120
+ *
121
+ * @category Internal
122
+ */
123
+ export function generateCsrfCookie(
124
+ csrfToken: string,
125
+ cookieConfig: Readonly<SelectFrom<CookieParams, {hostOrigin: true; isDev: true}>>,
126
+ ): string {
127
+ return generateSetCookie({
128
+ name: AuthCookie.Csrf,
129
+ value: csrfToken,
130
+ httpOnly: false,
131
+ cookieConfig: {
132
+ ...cookieConfig,
133
+ cookieDuration: {
134
+ days: 400,
135
+ },
136
+ },
137
+ });
101
138
  }
102
139
 
103
140
  /**
@@ -106,16 +143,30 @@ export async function generateAuthCookie(
106
143
  * @category Internal
107
144
  */
108
145
  export function clearAuthCookie(
109
- cookieConfig: Readonly<Pick<CookieParams, 'cookieName' | 'hostOrigin' | 'isDev'>>,
146
+ cookieConfig: Readonly<SelectFrom<CookieParams, {hostOrigin: true; isDev: true}>> &
147
+ PartialWithUndefined<{authCookie: AuthCookie}>,
110
148
  ) {
111
- return generateCookie({
112
- [cookieConfig.cookieName || 'auth']: 'redacted',
113
- Domain: parseUrl(cookieConfig.hostOrigin).hostname,
114
- HttpOnly: true,
115
- Path: '/',
116
- SameSite: 'Strict',
117
- 'MAX-AGE': 0,
118
- Secure: !cookieConfig.isDev,
149
+ return generateSetCookie({
150
+ name: cookieConfig.authCookie || AuthCookie.Auth,
151
+ value: 'redacted',
152
+ httpOnly: true,
153
+ cookieConfig,
154
+ });
155
+ }
156
+
157
+ /**
158
+ * Generate a cookie value that will clear the CSRF token cookie. Use this when signing out.
159
+ *
160
+ * @category Internal
161
+ */
162
+ export function clearCsrfCookie(
163
+ cookieConfig: Readonly<SelectFrom<CookieParams, {hostOrigin: true; isDev: true}>>,
164
+ ) {
165
+ return generateSetCookie({
166
+ name: AuthCookie.Csrf,
167
+ value: 'redacted',
168
+ httpOnly: false,
169
+ cookieConfig,
119
170
  });
120
171
  }
121
172
 
@@ -158,7 +209,7 @@ export function generateCookie(
158
209
  export async function extractCookieJwt(
159
210
  rawCookie: string,
160
211
  jwtParams: Readonly<ParseJwtParams>,
161
- cookieName: string = AuthCookieName.Auth,
212
+ cookieName: AuthCookie,
162
213
  ): Promise<undefined | ParsedJwt<JwtUserData>> {
163
214
  const cookieRegExp = new RegExp(`${escapeStringForRegExp(cookieName)}=[^;]+(?:;|$)`);
164
215
 
package/src/csrf-token.ts CHANGED
@@ -1,75 +1,15 @@
1
- import {
2
- randomString,
3
- wrapInTry,
4
- type PartialWithUndefined,
5
- type SelectFrom,
6
- } from '@augment-vir/common';
7
- import {
8
- calculateRelativeDate,
9
- fullDateShape,
10
- getNowInUtcTimezone,
11
- isDateAfter,
12
- type AnyDuration,
13
- } from 'date-vir';
14
- import {defineShape, parseJsonWithShape} from 'object-shape-tester';
1
+ import {check} from '@augment-vir/assert';
2
+ import {escapeStringForRegExp, randomString, safeMatch} from '@augment-vir/common';
15
3
  import {type RequireExactlyOne} from 'type-fest';
16
- import {getDefaultCsrfTokenStore, type CsrfTokenStore} from './csrf-token-store.js';
4
+ import {AuthCookie} from './cookie.js';
17
5
 
18
6
  /**
19
- * Shape definition for {@link CsrfToken}.
7
+ * Generates a random, cryptographically secure CSRF token string.
20
8
  *
21
9
  * @category Internal
22
10
  */
23
- export const csrfTokenShape = defineShape({
24
- token: '',
25
- expiration: fullDateShape,
26
- });
27
-
28
- /**
29
- * A cryptographically CSRF token with expiration date.
30
- *
31
- * @category Internal
32
- */
33
- export type CsrfToken = typeof csrfTokenShape.runtimeType;
34
-
35
- /**
36
- * Default allowed clock skew for CSRF token expiration checks. Accounts for differences between
37
- * server and client clocks when checking token expiration.
38
- *
39
- * @category Internal
40
- * @default {minutes: 5}
41
- */
42
- export const defaultAllowedClockSkew: Readonly<AnyDuration> = {
43
- minutes: 5,
44
- };
45
-
46
- /**
47
- * Generates a random, cryptographically secure CSRF token.
48
- *
49
- * @category Internal
50
- */
51
- export function generateCsrfToken(
52
- /** How long the CSRF token is valid for. */
53
- duration: Readonly<AnyDuration>,
54
- ): CsrfToken {
55
- return {
56
- token: randomString(256),
57
- expiration: calculateRelativeDate(getNowInUtcTimezone(), duration),
58
- };
59
- }
60
-
61
- /**
62
- * CSRF token failure reasons for {@link GetCsrfTokenResult}.
63
- *
64
- * @category Internal
65
- */
66
- export enum CsrfTokenFailureReason {
67
- /** No CSRF token was found. */
68
- DoesNotExist = 'does-not-exist',
69
- /** A CSRF token was found but parsing it failed. */
70
- ParseFailed = 'parse-failed',
71
- /** A CSRF token was found and parsed but is expired. */
72
- Expired = 'expired',
11
+ export function generateCsrfToken(): string {
12
+ return randomString(256);
73
13
  }
74
14
 
75
15
  /**
@@ -91,181 +31,31 @@ export type CsrfHeaderNameOption = RequireExactlyOne<{
91
31
  * @category Auth : Client
92
32
  * @category Auth : Host
93
33
  */
94
- export function resolveCsrfHeaderName(option: Readonly<CsrfHeaderNameOption>): string {
95
- if ('csrfHeaderName' in option && option.csrfHeaderName) {
96
- return option.csrfHeaderName;
34
+ export function resolveCsrfHeaderName(options: Readonly<CsrfHeaderNameOption>): string {
35
+ if ('csrfHeaderName' in options && options.csrfHeaderName) {
36
+ return options.csrfHeaderName;
97
37
  } else {
98
38
  return [
99
- option.csrfHeaderPrefix,
39
+ options.csrfHeaderPrefix,
100
40
  'auth-vir',
101
41
  'csrf-token',
102
- ].join('-');
103
- }
104
- }
105
-
106
- /**
107
- * Output from {@link getCurrentCsrfToken}.
108
- *
109
- * @category Internal
110
- */
111
- export type GetCsrfTokenResult = RequireExactlyOne<{
112
- csrfToken: Readonly<CsrfToken>;
113
- failure: CsrfTokenFailureReason;
114
- }>;
115
-
116
- /**
117
- * Extract the CSRF token header from a response.
118
- *
119
- * @category Auth : Client
120
- */
121
- export function extractCsrfTokenHeader(
122
- response: Readonly<PartialWithUndefined<SelectFrom<Response, {headers: true}>>>,
123
- csrfHeaderNameOption: Readonly<CsrfHeaderNameOption>,
124
- options?: PartialWithUndefined<{
125
- /**
126
- * Allowed clock skew tolerance for CSRF token expiration checks.
127
- *
128
- * @default {minutes: 5}
129
- */
130
- allowedClockSkew: Readonly<AnyDuration>;
131
- }>,
132
- ): Readonly<GetCsrfTokenResult> {
133
- const csrfTokenHeaderName = resolveCsrfHeaderName(csrfHeaderNameOption);
134
-
135
- const rawCsrfToken = response.headers?.get(csrfTokenHeaderName);
136
-
137
- return parseCsrfToken(rawCsrfToken, options);
138
- }
139
-
140
- /**
141
- * Stores the given CSRF token into IndexedDB.
142
- *
143
- * @category Auth : Client
144
- */
145
- export async function storeCsrfToken(
146
- csrfToken: Readonly<CsrfToken>,
147
- options: Readonly<CsrfHeaderNameOption> &
148
- PartialWithUndefined<{
149
- /**
150
- * Allows mocking or overriding the default CSRF token store.
151
- *
152
- * @default getDefaultCsrfTokenStore()
153
- */
154
- csrfTokenStore: CsrfTokenStore;
155
- }>,
156
- ): Promise<void> {
157
- await (options.csrfTokenStore || (await getDefaultCsrfTokenStore())).setCsrfToken(
158
- JSON.stringify(csrfToken),
159
- );
160
- }
161
-
162
- /**
163
- * Parse a raw CSRF token JSON string.
164
- *
165
- * @category Internal
166
- */
167
- export function parseCsrfToken(
168
- value: string | undefined | null,
169
- options?: PartialWithUndefined<{
170
- /**
171
- * Allowed clock skew tolerance for CSRF token expiration checks. Accounts for differences
172
- * between server and client clocks.
173
- *
174
- * @default {minutes: 5}
175
- */
176
- allowedClockSkew: Readonly<AnyDuration>;
177
- }>,
178
- ): Readonly<GetCsrfTokenResult> {
179
- if (!value) {
180
- return {
181
- failure: CsrfTokenFailureReason.DoesNotExist,
182
- };
183
- }
184
-
185
- const csrfToken: CsrfToken | undefined = wrapInTry(
186
- () =>
187
- parseJsonWithShape(value, csrfTokenShape, {
188
- /** For forwards / backwards compatibility. */
189
- allowExtraKeys: true,
190
- }),
191
- {
192
- fallbackValue: undefined,
193
- },
194
- );
195
-
196
- if (!csrfToken) {
197
- return {
198
- failure: CsrfTokenFailureReason.ParseFailed,
199
- };
42
+ ]
43
+ .filter(check.isTruthy)
44
+ .join('-');
200
45
  }
201
-
202
- const effectiveExpiration = calculateRelativeDate(
203
- csrfToken.expiration,
204
- options?.allowedClockSkew || defaultAllowedClockSkew,
205
- );
206
-
207
- if (
208
- isDateAfter({
209
- fullDate: getNowInUtcTimezone(),
210
- relativeTo: effectiveExpiration,
211
- })
212
- ) {
213
- return {
214
- failure: CsrfTokenFailureReason.Expired,
215
- };
216
- }
217
-
218
- return {
219
- csrfToken,
220
- };
221
- }
222
-
223
- /**
224
- * Used in client (frontend) code to retrieve the current CSRF token in order to send it with
225
- * requests to the host (backend).
226
- *
227
- * @category Auth : Client
228
- */
229
- export async function getCurrentCsrfToken(
230
- options: Readonly<CsrfHeaderNameOption> &
231
- PartialWithUndefined<{
232
- /**
233
- * Allows mocking or overriding the default CSRF token store.
234
- *
235
- * @default getDefaultCsrfTokenStore()
236
- */
237
- csrfTokenStore: CsrfTokenStore;
238
- /**
239
- * Allowed clock skew tolerance for CSRF token expiration checks.
240
- *
241
- * @default {minutes: 5}
242
- */
243
- allowedClockSkew: Readonly<AnyDuration>;
244
- }>,
245
- ): Promise<Readonly<GetCsrfTokenResult>> {
246
- const rawCsrfToken: string | undefined =
247
- (await (options.csrfTokenStore || (await getDefaultCsrfTokenStore())).getCsrfToken()) ||
248
- undefined;
249
-
250
- return parseCsrfToken(rawCsrfToken, options);
251
46
  }
252
47
 
253
48
  /**
254
- * Wipes the current stored CSRF token. This should be used by client (frontend) code to react to a
255
- * session timeout.
49
+ * Used in client (frontend) code to retrieve the current CSRF token from the browser cookie in
50
+ * order to send it with requests to the host (backend).
256
51
  *
257
52
  * @category Auth : Client
258
53
  */
259
- export async function wipeCurrentCsrfToken(
260
- options: Readonly<CsrfHeaderNameOption> &
261
- PartialWithUndefined<{
262
- /**
263
- * Allows mocking or overriding the default CSRF token store.
264
- *
265
- * @default getDefaultCsrfTokenStore()
266
- */
267
- csrfTokenStore: CsrfTokenStore;
268
- }>,
269
- ): Promise<void> {
270
- await (options.csrfTokenStore || (await getDefaultCsrfTokenStore())).deleteCsrfToken();
54
+ export function getCurrentCsrfToken(): string | undefined {
55
+ const cookieRegExp = new RegExp(`${escapeStringForRegExp(AuthCookie.Csrf)}=([^;]+)`);
56
+ const [
57
+ ,
58
+ value,
59
+ ] = safeMatch(globalThis.document.cookie, cookieRegExp);
60
+ return value || undefined;
271
61
  }
package/src/index.ts CHANGED
@@ -3,11 +3,9 @@ export * from './auth-client/frontend-auth.client.js';
3
3
  export * from './auth-client/is-session-refresh-ready.js';
4
4
  export * from './auth.js';
5
5
  export * from './cookie.js';
6
- export * from './csrf-token-store.js';
7
6
  export * from './csrf-token.js';
8
7
  export * from './hash.js';
9
8
  export * from './headers.js';
10
9
  export * from './jwt/jwt-keys.js';
11
10
  export * from './jwt/jwt.js';
12
11
  export * from './jwt/user-jwt.js';
13
- export * from './mock-csrf-token-store.js';
package/src/jwt/jwt.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import {assertWrap, check} from '@augment-vir/assert';
2
- import {type AnyObject, type PartialWithUndefined} from '@augment-vir/common';
2
+ import {type AnyObject, type PartialWithUndefined, type SelectFrom} from '@augment-vir/common';
3
3
  import {
4
4
  type AnyDuration,
5
5
  calculateRelativeDate,
@@ -13,7 +13,6 @@ import {
13
13
  type UtcTimezone,
14
14
  } from 'date-vir';
15
15
  import {EncryptJWT, jwtDecrypt, jwtVerify, SignJWT} from 'jose';
16
- import {defaultAllowedClockSkew} from '../csrf-token.js';
17
16
  import {type JwtKeys} from './jwt-keys.js';
18
17
 
19
18
  const encryptionProtectedHeader = {
@@ -24,6 +23,17 @@ const signingProtectedHeader = {
24
23
  alg: 'HS512',
25
24
  };
26
25
 
26
+ /**
27
+ * Default allowed clock skew for JWT expiration checks. Accounts for differences between server and
28
+ * client clocks.
29
+ *
30
+ * @category Internal
31
+ * @default {minutes: 5}
32
+ */
33
+ export const defaultAllowedClockSkew: Readonly<AnyDuration> = {
34
+ minutes: 5,
35
+ };
36
+
27
37
  /**
28
38
  * Params for {@link createJwt}.
29
39
  *
@@ -148,7 +158,9 @@ export async function createJwt<JwtData extends AnyObject = AnyObject>(
148
158
  *
149
159
  * @category Internal
150
160
  */
151
- export type ParseJwtParams = Readonly<Pick<CreateJwtParams, 'issuer' | 'audience' | 'jwtKeys'>> &
161
+ export type ParseJwtParams = Readonly<
162
+ SelectFrom<CreateJwtParams, {issuer: true; audience: true; jwtKeys: true}>
163
+ > &
152
164
  PartialWithUndefined<{
153
165
  /**
154
166
  * Allowed clock skew tolerance for JWT expiration and timestamp checks. Accounts for
@@ -1,21 +0,0 @@
1
- /**
2
- * The interface used for overriding the default CSRF token store in storage functions.
3
- *
4
- * @category Internal
5
- */
6
- export type CsrfTokenStore = {
7
- /** Retrieves the stored CSRF token, if any. */
8
- getCsrfToken(): Promise<string | undefined>;
9
- /** Stores a CSRF token. */
10
- setCsrfToken(value: string): Promise<void>;
11
- /** Deletes the stored CSRF token. */
12
- deleteCsrfToken(): Promise<void>;
13
- };
14
- /**
15
- * The default {@link LocalDbClient} instance used for storing CSRF tokens. This uses a dedicated
16
- * store name to avoid collisions with other storage. Lazily initialized to avoid crashes in Node.js
17
- * environments where IndexedDB is not available.
18
- *
19
- * @category Internal
20
- */
21
- export declare function getDefaultCsrfTokenStore(): Promise<CsrfTokenStore>;
@@ -1,35 +0,0 @@
1
- import { LocalDbClient } from 'local-db-client';
2
- import { defineShape } from 'object-shape-tester';
3
- const csrfTokenDbShapes = {
4
- csrfToken: defineShape(''),
5
- };
6
- async function createDefaultCsrfTokenStore() {
7
- const client = await LocalDbClient.createClient(csrfTokenDbShapes, {
8
- storeName: 'auth-vir-csrf',
9
- });
10
- return {
11
- async getCsrfToken() {
12
- return (await client.load.csrfToken()) || undefined;
13
- },
14
- async setCsrfToken(value) {
15
- await client.set.csrfToken(value);
16
- },
17
- async deleteCsrfToken() {
18
- await client.delete.csrfToken();
19
- },
20
- };
21
- }
22
- /**
23
- * The default {@link LocalDbClient} instance used for storing CSRF tokens. This uses a dedicated
24
- * store name to avoid collisions with other storage. Lazily initialized to avoid crashes in Node.js
25
- * environments where IndexedDB is not available.
26
- *
27
- * @category Internal
28
- */
29
- export async function getDefaultCsrfTokenStore() {
30
- if (!cachedStorePromise) {
31
- cachedStorePromise = createDefaultCsrfTokenStore();
32
- }
33
- return cachedStorePromise;
34
- }
35
- let cachedStorePromise;
@@ -1,64 +0,0 @@
1
- import { type CsrfTokenStore } from './csrf-token-store.js';
2
- /**
3
- * `accessRecord` type for {@link createMockLocalStorage}'s output.
4
- *
5
- * @category Internal
6
- */
7
- export type MockLocalStorageAccessRecord = {
8
- getItem: string[];
9
- removeItem: string[];
10
- setItem: {
11
- key: string;
12
- value: string;
13
- }[];
14
- key: number[];
15
- };
16
- /**
17
- * Create an empty `accessRecord` object, this is to be used in conjunction with
18
- * {@link createMockLocalStorage}.
19
- *
20
- * @category Mock
21
- */
22
- export declare function createEmptyMockLocalStorageAccessRecord(): MockLocalStorageAccessRecord;
23
- /**
24
- * Create a LocalStorage mock.
25
- *
26
- * @category Mock
27
- */
28
- export declare function createMockLocalStorage(
29
- /** Set values in here to initialize the mocked localStorage data store contents. */
30
- init?: Record<string, string>): {
31
- localStorage: Storage;
32
- store: Record<string, string>;
33
- accessRecord: MockLocalStorageAccessRecord;
34
- };
35
- /**
36
- * `accessRecord` type for {@link createMockCsrfTokenStore}'s output.
37
- *
38
- * @category Internal
39
- */
40
- export type MockCsrfTokenStoreAccessRecord = {
41
- getCsrfToken: number;
42
- setCsrfToken: string[];
43
- deleteCsrfToken: number;
44
- };
45
- /**
46
- * Create an empty `accessRecord` object, this is to be used in conjunction with
47
- * {@link createMockCsrfTokenStore}.
48
- *
49
- * @category Mock
50
- */
51
- export declare function createEmptyMockCsrfTokenStoreAccessRecord(): MockCsrfTokenStoreAccessRecord;
52
- /**
53
- * Create a mock {@link CsrfTokenStore} backed by a simple in-memory object, for use in tests.
54
- *
55
- * @category Mock
56
- */
57
- export declare function createMockCsrfTokenStore(
58
- /** Set an initial value to initialize the mocked store contents. */
59
- init?: string | undefined): {
60
- csrfTokenStore: CsrfTokenStore;
61
- /** The current value held in the mock store. */
62
- readonly storedValue: string | undefined;
63
- accessRecord: MockCsrfTokenStoreAccessRecord;
64
- };