auth-vir 1.3.2 → 2.0.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.
- package/README.md +27 -18
- package/dist/auth-client/backend-auth.client.d.ts +177 -0
- package/dist/auth-client/backend-auth.client.js +232 -0
- package/dist/auth-client/frontend-auth.client.d.ts +65 -0
- package/dist/auth-client/frontend-auth.client.js +108 -0
- package/dist/auth.d.ts +32 -46
- package/dist/auth.js +36 -36
- package/dist/cookie.d.ts +15 -4
- package/dist/cookie.js +16 -4
- package/dist/csrf-token.d.ts +113 -3
- package/dist/csrf-token.js +101 -5
- package/dist/generated/browser.d.ts +9 -0
- package/dist/generated/browser.js +16 -0
- package/dist/generated/client.d.ts +26 -0
- package/dist/generated/client.js +31 -0
- package/dist/generated/commonInputTypes.d.ts +122 -0
- package/dist/generated/commonInputTypes.js +1 -0
- package/dist/generated/enums.d.ts +1 -0
- package/dist/generated/enums.js +9 -0
- package/dist/generated/internal/class.d.ts +126 -0
- package/dist/generated/internal/class.js +84 -0
- package/dist/generated/internal/prismaNamespace.d.ts +544 -0
- package/dist/generated/internal/prismaNamespace.js +101 -0
- package/dist/generated/internal/prismaNamespaceBrowser.d.ts +75 -0
- package/dist/generated/internal/prismaNamespaceBrowser.js +69 -0
- package/dist/generated/models/User.d.ts +983 -0
- package/dist/generated/models/User.js +1 -0
- package/dist/generated/models.d.ts +2 -0
- package/dist/generated/models.js +1 -0
- package/dist/generated/shapes.gen.d.ts +8 -0
- package/dist/generated/shapes.gen.js +11 -0
- package/dist/headers.d.ts +20 -0
- package/dist/headers.js +33 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/jwt/jwt.d.ts +11 -2
- package/dist/jwt/jwt.js +14 -3
- package/dist/jwt/user-jwt.d.ts +8 -8
- package/dist/jwt/user-jwt.js +12 -9
- package/package.json +12 -7
- package/src/auth-client/backend-auth.client.ts +500 -0
- package/src/auth-client/frontend-auth.client.ts +183 -0
- package/src/auth.ts +99 -77
- package/src/cookie.ts +20 -8
- package/src/csrf-token.ts +196 -5
- package/src/generated/browser.ts +23 -0
- package/src/generated/client.ts +47 -0
- package/src/generated/commonInputTypes.ts +147 -0
- package/src/generated/enums.ts +14 -0
- package/src/generated/internal/class.ts +236 -0
- package/src/generated/internal/prismaNamespace.ts +761 -0
- package/src/generated/internal/prismaNamespaceBrowser.ts +102 -0
- package/src/generated/models/User.ts +1135 -0
- package/src/generated/models.ts +11 -0
- package/src/generated/shapes.gen.ts +15 -0
- package/src/headers.ts +35 -0
- package/src/index.ts +3 -0
- package/src/jwt/jwt.ts +34 -5
- package/src/jwt/user-jwt.ts +21 -12
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { HttpStatus, } from '@augment-vir/common';
|
|
2
|
+
import { CsrfTokenFailureReason, extractCsrfTokenHeader, getCurrentCsrfToken, storeCsrfToken, wipeCurrentCsrfToken, } from '../csrf-token.js';
|
|
3
|
+
import { AuthHeaderName } from '../headers.js';
|
|
4
|
+
/**
|
|
5
|
+
* An auth client for sending and validating client requests to a backend. This should only be used
|
|
6
|
+
* in a frontend environment as it accesses native browser APIs.
|
|
7
|
+
*
|
|
8
|
+
* @category Auth : Client
|
|
9
|
+
* @category Client
|
|
10
|
+
*/
|
|
11
|
+
export class FrontendAuthClient {
|
|
12
|
+
config;
|
|
13
|
+
constructor(config = {}) {
|
|
14
|
+
this.config = config;
|
|
15
|
+
}
|
|
16
|
+
/** Wraps {@link getCurrentCsrfToken} to automatically handle wiping an invalid CSRF token. */
|
|
17
|
+
async getCurrentCsrfToken() {
|
|
18
|
+
const csrfTokenResult = getCurrentCsrfToken(this.config.overrides);
|
|
19
|
+
if (csrfTokenResult.failure &&
|
|
20
|
+
csrfTokenResult.failure !== CsrfTokenFailureReason.DoesNotExist) {
|
|
21
|
+
await this.logout();
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
return csrfTokenResult.csrfToken?.token;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/** @returns Whether the user assuming succeeded or not. */
|
|
29
|
+
async assumeUser(assumedUserParams) {
|
|
30
|
+
if (!(await this.config.canAssumeUser?.())) {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
(this.config.overrides?.localStorage || globalThis.localStorage).setItem(this.config.overrides?.assumedUserHeaderName || AuthHeaderName.AssumedUser, JSON.stringify(assumedUserParams));
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
/** Gets the assumed user params stored in local storage, if any. */
|
|
37
|
+
getAssumedUser() {
|
|
38
|
+
const rawValue = (this.config.overrides?.localStorage || globalThis.localStorage).getItem(this.config.overrides?.assumedUserHeaderName || AuthHeaderName.AssumedUser);
|
|
39
|
+
if (!rawValue) {
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
try {
|
|
43
|
+
return JSON.parse(rawValue);
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Creates a `RequestInit` object for the `fetch` API. If you have other request init options,
|
|
51
|
+
* use [`mergeDeep` from
|
|
52
|
+
* `@augment-vir/common`](https://electrovir.github.io/augment-vir/functions/mergeDeep.html) to
|
|
53
|
+
* combine them with these.
|
|
54
|
+
*/
|
|
55
|
+
async createAuthenticatedRequestInit() {
|
|
56
|
+
const csrfToken = await this.getCurrentCsrfToken();
|
|
57
|
+
const assumedUser = this.getAssumedUser();
|
|
58
|
+
const headers = {
|
|
59
|
+
...(csrfToken
|
|
60
|
+
? {
|
|
61
|
+
[AuthHeaderName.CsrfToken]: csrfToken,
|
|
62
|
+
}
|
|
63
|
+
: {}),
|
|
64
|
+
...(assumedUser
|
|
65
|
+
? {
|
|
66
|
+
[this.config.overrides?.assumedUserHeaderName || AuthHeaderName.AssumedUser]: JSON.stringify(assumedUser),
|
|
67
|
+
}
|
|
68
|
+
: {}),
|
|
69
|
+
};
|
|
70
|
+
return {
|
|
71
|
+
headers,
|
|
72
|
+
credentials: 'include',
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
/** Wipes the current user auth. */
|
|
76
|
+
async logout() {
|
|
77
|
+
await this.config.authClearedCallback?.();
|
|
78
|
+
wipeCurrentCsrfToken(this.config.overrides);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Use to handle a login response. Automatically stores the CSRF token.
|
|
82
|
+
*
|
|
83
|
+
* @throws Error if the login response failed.
|
|
84
|
+
* @throws Error if the login response has an invalid CSRF token.
|
|
85
|
+
*/
|
|
86
|
+
async handleLoginResponse(response) {
|
|
87
|
+
if (!response.ok) {
|
|
88
|
+
await this.logout();
|
|
89
|
+
throw new Error('Login response failed.');
|
|
90
|
+
}
|
|
91
|
+
const { csrfToken } = extractCsrfTokenHeader(response, this.config.overrides);
|
|
92
|
+
if (!csrfToken) {
|
|
93
|
+
await this.logout();
|
|
94
|
+
throw new Error('Did not receive any CSRF token.');
|
|
95
|
+
}
|
|
96
|
+
storeCsrfToken(csrfToken, this.config.overrides);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Use to verify _all_ responses received from the backend. Immediately logs the user out once
|
|
100
|
+
* an unauthorized response is detected.
|
|
101
|
+
*/
|
|
102
|
+
async verifyResponseAuth(response) {
|
|
103
|
+
if (response.status === HttpStatus.Unauthorized &&
|
|
104
|
+
!response.headers.get(AuthHeaderName.IsSignUpAuth)) {
|
|
105
|
+
await this.logout();
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
package/dist/auth.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { type PartialWithUndefined } from '@augment-vir/common';
|
|
2
|
+
import { type FullDate, type UtcTimezone } from 'date-vir';
|
|
3
|
+
import { type CookieParams } from './cookie.js';
|
|
4
|
+
import { AuthHeaderName } from './headers.js';
|
|
2
5
|
import { type ParseJwtParams } from './jwt/jwt.js';
|
|
3
6
|
/**
|
|
4
7
|
* All possible headers container types supported by {@link extractUserIdFromRequestHeaders}.
|
|
@@ -6,6 +9,16 @@ import { type ParseJwtParams } from './jwt/jwt.js';
|
|
|
6
9
|
* @category Internal
|
|
7
10
|
*/
|
|
8
11
|
export type HeaderContainer = Record<string, string[] | undefined | string | number> | Headers;
|
|
12
|
+
/**
|
|
13
|
+
* Output from {@link extractUserIdFromRequestHeaders}.
|
|
14
|
+
*
|
|
15
|
+
* @category Internal
|
|
16
|
+
*/
|
|
17
|
+
export type UserIdResult<UserId extends string | number> = {
|
|
18
|
+
userId: UserId;
|
|
19
|
+
jwtExpiration: FullDate<UtcTimezone>;
|
|
20
|
+
cookieName: string;
|
|
21
|
+
};
|
|
9
22
|
/**
|
|
10
23
|
* Extract the user id from a request by checking both the request cookie and CSRF token. This is
|
|
11
24
|
* used by host (backend) code to help verify a request. After extracting the user id using this,
|
|
@@ -14,36 +27,41 @@ export type HeaderContainer = Record<string, string[] | undefined | string | num
|
|
|
14
27
|
* @category Auth : Host
|
|
15
28
|
* @returns The extracted user id or `undefined` if no valid auth headers exist.
|
|
16
29
|
*/
|
|
17
|
-
export declare function extractUserIdFromRequestHeaders(headers: HeaderContainer, jwtParams: Readonly<ParseJwtParams>, cookieName?: string
|
|
30
|
+
export declare function extractUserIdFromRequestHeaders<UserId extends string | number>(headers: HeaderContainer, jwtParams: Readonly<ParseJwtParams>, cookieName?: string, overrides?: PartialWithUndefined<{
|
|
31
|
+
csrfHeaderName: string;
|
|
32
|
+
}>): Promise<Readonly<UserIdResult<UserId>> | undefined>;
|
|
18
33
|
/**
|
|
19
34
|
* Extract a user id from just the cookie, without CSRF token validation. This is _less secure_ than
|
|
20
35
|
* {@link extractUserIdFromRequestHeaders} as a result. This should only be used in rare
|
|
21
36
|
* circumstances where you cannot rely on client-side JavaScript to insert the CSRF token.
|
|
22
37
|
*
|
|
23
38
|
* @deprecated Prefer {@link extractUserIdFromRequestHeaders} instead: it is more secure.
|
|
39
|
+
* @category Auth : Host
|
|
24
40
|
*/
|
|
25
|
-
export declare function
|
|
41
|
+
export declare function insecureExtractUserIdFromCookieAlone<UserId extends string | number>(headers: HeaderContainer, jwtParams: Readonly<ParseJwtParams>, cookieName?: string): Promise<Readonly<UserIdResult<UserId>> | undefined>;
|
|
26
42
|
/**
|
|
27
43
|
* Used by host (backend) code to set headers on a response object.
|
|
28
44
|
*
|
|
29
45
|
* @category Auth : Host
|
|
30
46
|
*/
|
|
31
|
-
export declare function generateSuccessfulLoginHeaders(
|
|
47
|
+
export declare function generateSuccessfulLoginHeaders<CsrfHeaderName extends string = AuthHeaderName.CsrfToken>(
|
|
32
48
|
/** The id from your database of the user you're authenticating. */
|
|
33
|
-
userId: string, cookieConfig: Readonly<CookieParams
|
|
49
|
+
userId: string | number, cookieConfig: Readonly<CookieParams>, overrides?: PartialWithUndefined<{
|
|
50
|
+
csrfHeaderName: CsrfHeaderName;
|
|
51
|
+
}>): Promise<{
|
|
34
52
|
'set-cookie': string;
|
|
35
|
-
|
|
36
|
-
}>;
|
|
53
|
+
} & Record<CsrfHeaderName, string>>;
|
|
37
54
|
/**
|
|
38
55
|
* Used by host (backend) code to set headers on a response object when the user has logged out or
|
|
39
56
|
* failed to authorize.
|
|
40
57
|
*
|
|
41
58
|
* @category Auth : Host
|
|
42
59
|
*/
|
|
43
|
-
export declare function generateLogoutHeaders(
|
|
60
|
+
export declare function generateLogoutHeaders<CsrfHeaderName extends string = AuthHeaderName.CsrfToken>(cookieConfig: Readonly<Pick<CookieParams, 'cookieName' | 'hostOrigin' | 'isDev'>>, overrides?: PartialWithUndefined<{
|
|
61
|
+
csrfHeaderName: CsrfHeaderName;
|
|
62
|
+
}>): {
|
|
44
63
|
'set-cookie': string;
|
|
45
|
-
|
|
46
|
-
};
|
|
64
|
+
} & Record<CsrfHeaderName, string>;
|
|
47
65
|
/**
|
|
48
66
|
* Store auth data on a client (frontend) after receiving an auth response from the host (backend).
|
|
49
67
|
* Specifically, this stores the CSRF token into local storage (which doesn't need to be a secret).
|
|
@@ -53,45 +71,13 @@ export declare function generateLogoutHeaders(...params: Parameters<typeof clear
|
|
|
53
71
|
* @category Auth : Client
|
|
54
72
|
* @throws Error if no CSRF token header is found.
|
|
55
73
|
*/
|
|
56
|
-
export declare function handleAuthResponse(response: Readonly<Pick<Response, 'ok' | 'headers'>>, overrides?: {
|
|
57
|
-
/**
|
|
58
|
-
* Allows mocking or overriding the global `localStorage`.
|
|
59
|
-
*
|
|
60
|
-
* @default globalThis.localStorage
|
|
61
|
-
*/
|
|
62
|
-
localStorage?: Pick<Storage, 'setItem' | 'removeItem'>;
|
|
63
|
-
/** Override the default CSRF token header name. */
|
|
64
|
-
csrfHeaderName?: string;
|
|
65
|
-
}): void;
|
|
66
|
-
/**
|
|
67
|
-
* Used in client (frontend) code to retrieve the current CSRF token in order to send it with
|
|
68
|
-
* requests to the host (backend).
|
|
69
|
-
*
|
|
70
|
-
* @category Auth : Client
|
|
71
|
-
*/
|
|
72
|
-
export declare function getCurrentCsrfToken(overrides?: {
|
|
73
|
-
/**
|
|
74
|
-
* Allows mocking or overriding the global `localStorage`.
|
|
75
|
-
*
|
|
76
|
-
* @default globalThis.localStorage
|
|
77
|
-
*/
|
|
78
|
-
localStorage?: Pick<Storage, 'getItem'>;
|
|
79
|
-
/** Override the default CSRF token header name. */
|
|
80
|
-
csrfHeaderName?: string;
|
|
81
|
-
}): string | undefined;
|
|
82
|
-
/**
|
|
83
|
-
* Wipes the current stored CSRF token. This should be used by client (frontend) code to logout a
|
|
84
|
-
* user or react to a session timeout.
|
|
85
|
-
*
|
|
86
|
-
* @category Auth : Client
|
|
87
|
-
*/
|
|
88
|
-
export declare function wipeCurrentCsrfToken(overrides?: {
|
|
74
|
+
export declare function handleAuthResponse(response: Readonly<Pick<Response, 'ok' | 'headers'>>, overrides?: PartialWithUndefined<{
|
|
89
75
|
/**
|
|
90
76
|
* Allows mocking or overriding the global `localStorage`.
|
|
91
77
|
*
|
|
92
78
|
* @default globalThis.localStorage
|
|
93
79
|
*/
|
|
94
|
-
localStorage
|
|
80
|
+
localStorage: Pick<Storage, 'setItem' | 'removeItem'>;
|
|
95
81
|
/** Override the default CSRF token header name. */
|
|
96
|
-
csrfHeaderName
|
|
97
|
-
}): void;
|
|
82
|
+
csrfHeaderName: string;
|
|
83
|
+
}>): void;
|
package/dist/auth.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { clearAuthCookie, extractCookieJwt, generateAuthCookie, } from './cookie.js';
|
|
2
|
-
import {
|
|
1
|
+
import { AuthCookieName, clearAuthCookie, extractCookieJwt, generateAuthCookie, } from './cookie.js';
|
|
2
|
+
import { extractCsrfTokenHeader, generateCsrfToken, parseCsrfToken, storeCsrfToken, wipeCurrentCsrfToken, } from './csrf-token.js';
|
|
3
|
+
import { AuthHeaderName } from './headers.js';
|
|
3
4
|
function readHeader(headers, headerName) {
|
|
4
5
|
if (headers instanceof Headers) {
|
|
5
6
|
return headers.get(headerName) || undefined;
|
|
@@ -17,6 +18,13 @@ function readHeader(headers, headerName) {
|
|
|
17
18
|
}
|
|
18
19
|
}
|
|
19
20
|
}
|
|
21
|
+
function readCsrfTokenHeader(headers, overrides) {
|
|
22
|
+
const rawCsrfToken = readHeader(headers, overrides.csrfHeaderName || AuthHeaderName.CsrfToken);
|
|
23
|
+
if (!rawCsrfToken) {
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
return parseCsrfToken(rawCsrfToken).csrfToken?.token || rawCsrfToken;
|
|
27
|
+
}
|
|
20
28
|
/**
|
|
21
29
|
* Extract the user id from a request by checking both the request cookie and CSRF token. This is
|
|
22
30
|
* used by host (backend) code to help verify a request. After extracting the user id using this,
|
|
@@ -25,18 +33,22 @@ function readHeader(headers, headerName) {
|
|
|
25
33
|
* @category Auth : Host
|
|
26
34
|
* @returns The extracted user id or `undefined` if no valid auth headers exist.
|
|
27
35
|
*/
|
|
28
|
-
export async function extractUserIdFromRequestHeaders(headers, jwtParams, cookieName) {
|
|
36
|
+
export async function extractUserIdFromRequestHeaders(headers, jwtParams, cookieName = AuthCookieName.Auth, overrides = {}) {
|
|
29
37
|
try {
|
|
30
|
-
const csrfToken =
|
|
38
|
+
const csrfToken = readCsrfTokenHeader(headers, overrides);
|
|
31
39
|
const cookie = readHeader(headers, 'cookie');
|
|
32
40
|
if (!cookie || !csrfToken) {
|
|
33
41
|
return undefined;
|
|
34
42
|
}
|
|
35
43
|
const jwt = await extractCookieJwt(cookie, jwtParams, cookieName);
|
|
36
|
-
if (!jwt || jwt.csrfToken !== csrfToken) {
|
|
44
|
+
if (!jwt || jwt.data.csrfToken !== csrfToken) {
|
|
37
45
|
return undefined;
|
|
38
46
|
}
|
|
39
|
-
return
|
|
47
|
+
return {
|
|
48
|
+
userId: jwt.data.userId,
|
|
49
|
+
jwtExpiration: jwt.jwtExpiration,
|
|
50
|
+
cookieName,
|
|
51
|
+
};
|
|
40
52
|
}
|
|
41
53
|
catch {
|
|
42
54
|
return undefined;
|
|
@@ -48,8 +60,9 @@ export async function extractUserIdFromRequestHeaders(headers, jwtParams, cookie
|
|
|
48
60
|
* circumstances where you cannot rely on client-side JavaScript to insert the CSRF token.
|
|
49
61
|
*
|
|
50
62
|
* @deprecated Prefer {@link extractUserIdFromRequestHeaders} instead: it is more secure.
|
|
63
|
+
* @category Auth : Host
|
|
51
64
|
*/
|
|
52
|
-
export async function
|
|
65
|
+
export async function insecureExtractUserIdFromCookieAlone(headers, jwtParams, cookieName = AuthCookieName.Auth) {
|
|
53
66
|
try {
|
|
54
67
|
const cookie = readHeader(headers, 'cookie');
|
|
55
68
|
if (!cookie) {
|
|
@@ -59,7 +72,11 @@ export async function extractUserIdFromCookieAlone(headers, jwtParams, cookieNam
|
|
|
59
72
|
if (!jwt) {
|
|
60
73
|
return undefined;
|
|
61
74
|
}
|
|
62
|
-
return
|
|
75
|
+
return {
|
|
76
|
+
userId: jwt.data.userId,
|
|
77
|
+
jwtExpiration: jwt.jwtExpiration,
|
|
78
|
+
cookieName,
|
|
79
|
+
};
|
|
63
80
|
}
|
|
64
81
|
catch {
|
|
65
82
|
return undefined;
|
|
@@ -72,14 +89,15 @@ export async function extractUserIdFromCookieAlone(headers, jwtParams, cookieNam
|
|
|
72
89
|
*/
|
|
73
90
|
export async function generateSuccessfulLoginHeaders(
|
|
74
91
|
/** The id from your database of the user you're authenticating. */
|
|
75
|
-
userId, cookieConfig) {
|
|
76
|
-
const csrfToken = generateCsrfToken();
|
|
92
|
+
userId, cookieConfig, overrides = {}) {
|
|
93
|
+
const csrfToken = generateCsrfToken(cookieConfig.cookieDuration);
|
|
94
|
+
const csrfHeaderName = (overrides.csrfHeaderName || AuthHeaderName.CsrfToken);
|
|
77
95
|
return {
|
|
78
96
|
'set-cookie': await generateAuthCookie({
|
|
79
|
-
csrfToken,
|
|
97
|
+
csrfToken: csrfToken.token,
|
|
80
98
|
userId,
|
|
81
99
|
}, cookieConfig),
|
|
82
|
-
[
|
|
100
|
+
[csrfHeaderName]: JSON.stringify(csrfToken),
|
|
83
101
|
};
|
|
84
102
|
}
|
|
85
103
|
/**
|
|
@@ -88,10 +106,11 @@ userId, cookieConfig) {
|
|
|
88
106
|
*
|
|
89
107
|
* @category Auth : Host
|
|
90
108
|
*/
|
|
91
|
-
export function generateLogoutHeaders(
|
|
109
|
+
export function generateLogoutHeaders(cookieConfig, overrides = {}) {
|
|
110
|
+
const csrfHeaderName = (overrides.csrfHeaderName || AuthHeaderName.CsrfToken);
|
|
92
111
|
return {
|
|
93
|
-
'set-cookie': clearAuthCookie(
|
|
94
|
-
[
|
|
112
|
+
'set-cookie': clearAuthCookie(cookieConfig),
|
|
113
|
+
[csrfHeaderName]: 'redacted',
|
|
95
114
|
};
|
|
96
115
|
}
|
|
97
116
|
/**
|
|
@@ -108,29 +127,10 @@ export function handleAuthResponse(response, overrides = {}) {
|
|
|
108
127
|
wipeCurrentCsrfToken(overrides);
|
|
109
128
|
return;
|
|
110
129
|
}
|
|
111
|
-
const
|
|
112
|
-
const csrfToken = response.headers.get(headerName);
|
|
130
|
+
const { csrfToken } = extractCsrfTokenHeader(response, overrides);
|
|
113
131
|
if (!csrfToken) {
|
|
114
132
|
wipeCurrentCsrfToken(overrides);
|
|
115
133
|
throw new Error('Did not receive any CSRF token.');
|
|
116
134
|
}
|
|
117
|
-
(
|
|
118
|
-
}
|
|
119
|
-
/**
|
|
120
|
-
* Used in client (frontend) code to retrieve the current CSRF token in order to send it with
|
|
121
|
-
* requests to the host (backend).
|
|
122
|
-
*
|
|
123
|
-
* @category Auth : Client
|
|
124
|
-
*/
|
|
125
|
-
export function getCurrentCsrfToken(overrides = {}) {
|
|
126
|
-
return ((overrides.localStorage || globalThis.localStorage).getItem(overrides.csrfHeaderName || csrfTokenHeaderName) || undefined);
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* Wipes the current stored CSRF token. This should be used by client (frontend) code to logout a
|
|
130
|
-
* user or react to a session timeout.
|
|
131
|
-
*
|
|
132
|
-
* @category Auth : Client
|
|
133
|
-
*/
|
|
134
|
-
export function wipeCurrentCsrfToken(overrides = {}) {
|
|
135
|
-
return (overrides.localStorage || globalThis.localStorage).removeItem(overrides.csrfHeaderName || csrfTokenHeaderName);
|
|
135
|
+
storeCsrfToken(csrfToken, overrides);
|
|
136
136
|
}
|
package/dist/cookie.d.ts
CHANGED
|
@@ -1,8 +1,19 @@
|
|
|
1
1
|
import { type PartialWithUndefined } from '@augment-vir/common';
|
|
2
2
|
import { type AnyDuration } from 'date-vir';
|
|
3
3
|
import { type Primitive } from 'type-fest';
|
|
4
|
-
import { type CreateJwtParams, type ParseJwtParams } from './jwt/jwt.js';
|
|
5
|
-
import { type
|
|
4
|
+
import { type CreateJwtParams, type ParseJwtParams, type ParsedJwt } from './jwt/jwt.js';
|
|
5
|
+
import { type JwtUserData } from './jwt/user-jwt.js';
|
|
6
|
+
/**
|
|
7
|
+
* Cookie header names supported by default.
|
|
8
|
+
*
|
|
9
|
+
* @category Internal
|
|
10
|
+
*/
|
|
11
|
+
export declare enum AuthCookieName {
|
|
12
|
+
/** Used for a full user login auth. */
|
|
13
|
+
Auth = "auth",
|
|
14
|
+
/** Use for a temporary "just signed up" auth. */
|
|
15
|
+
SignUp = "sign-up"
|
|
16
|
+
}
|
|
6
17
|
/**
|
|
7
18
|
* Parameters for {@link generateAuthCookie}.
|
|
8
19
|
*
|
|
@@ -42,7 +53,7 @@ export type CookieParams = {
|
|
|
42
53
|
*
|
|
43
54
|
* @category Internal
|
|
44
55
|
*/
|
|
45
|
-
export declare function generateAuthCookie(userJwtData: Readonly<
|
|
56
|
+
export declare function generateAuthCookie(userJwtData: Readonly<JwtUserData>, cookieConfig: Readonly<CookieParams>): Promise<string>;
|
|
46
57
|
/**
|
|
47
58
|
* Generate a cookie value that will clear the previous auth cookie. Use this when signing out.
|
|
48
59
|
*
|
|
@@ -61,4 +72,4 @@ export declare function generateCookie(params: Readonly<Record<string, Exclude<P
|
|
|
61
72
|
* @category Internal
|
|
62
73
|
* @returns The extracted auth Cookie JWT data or `undefined` if no valid auth JWT data was found.
|
|
63
74
|
*/
|
|
64
|
-
export declare function extractCookieJwt(rawCookie: string, jwtParams: Readonly<ParseJwtParams>, cookieName?: string): Promise<undefined |
|
|
75
|
+
export declare function extractCookieJwt(rawCookie: string, jwtParams: Readonly<ParseJwtParams>, cookieName?: string): Promise<undefined | ParsedJwt<JwtUserData>>;
|
package/dist/cookie.js
CHANGED
|
@@ -3,6 +3,18 @@ import { safeMatch } from '@augment-vir/common';
|
|
|
3
3
|
import { convertDuration } from 'date-vir';
|
|
4
4
|
import { parseUrl } from 'url-vir';
|
|
5
5
|
import { createUserJwt, parseUserJwt } from './jwt/user-jwt.js';
|
|
6
|
+
/**
|
|
7
|
+
* Cookie header names supported by default.
|
|
8
|
+
*
|
|
9
|
+
* @category Internal
|
|
10
|
+
*/
|
|
11
|
+
export var AuthCookieName;
|
|
12
|
+
(function (AuthCookieName) {
|
|
13
|
+
/** Used for a full user login auth. */
|
|
14
|
+
AuthCookieName["Auth"] = "auth";
|
|
15
|
+
/** Use for a temporary "just signed up" auth. */
|
|
16
|
+
AuthCookieName["SignUp"] = "sign-up";
|
|
17
|
+
})(AuthCookieName || (AuthCookieName = {}));
|
|
6
18
|
/**
|
|
7
19
|
* Generate a secure cookie that stores the user JWT data. Used in host (backend) code.
|
|
8
20
|
*
|
|
@@ -65,13 +77,13 @@ export function generateCookie(params) {
|
|
|
65
77
|
* @category Internal
|
|
66
78
|
* @returns The extracted auth Cookie JWT data or `undefined` if no valid auth JWT data was found.
|
|
67
79
|
*/
|
|
68
|
-
export async function extractCookieJwt(rawCookie, jwtParams, cookieName =
|
|
80
|
+
export async function extractCookieJwt(rawCookie, jwtParams, cookieName = AuthCookieName.Auth) {
|
|
69
81
|
const cookieRegExp = new RegExp(`${cookieName}=[^;]+(?:;|$)`);
|
|
70
|
-
const [
|
|
71
|
-
if (!
|
|
82
|
+
const [cookieValue] = safeMatch(rawCookie, cookieRegExp);
|
|
83
|
+
if (!cookieValue) {
|
|
72
84
|
return undefined;
|
|
73
85
|
}
|
|
74
|
-
const rawJwt =
|
|
86
|
+
const rawJwt = cookieValue.replace(`${cookieName}=`, '').replace(';', '');
|
|
75
87
|
const jwt = await parseUserJwt(rawJwt, jwtParams);
|
|
76
88
|
return jwt;
|
|
77
89
|
}
|
package/dist/csrf-token.d.ts
CHANGED
|
@@ -1,12 +1,122 @@
|
|
|
1
|
+
import { type PartialWithUndefined, type SelectFrom } from '@augment-vir/common';
|
|
2
|
+
import { type AnyDuration } from 'date-vir';
|
|
3
|
+
import { type RequireExactlyOne } from 'type-fest';
|
|
1
4
|
/**
|
|
2
|
-
*
|
|
5
|
+
* Shape definition for {@link CsrfToken}.
|
|
3
6
|
*
|
|
4
7
|
* @category Internal
|
|
5
8
|
*/
|
|
6
|
-
export declare const
|
|
9
|
+
export declare const csrfTokenShape: import("object-shape-tester").Shape<{
|
|
10
|
+
token: string;
|
|
11
|
+
expiration: import("object-shape-tester").Shape<import("object-shape-tester").Shape<import("@sinclair/typebox").TUnsafe<{
|
|
12
|
+
hour: import("date-vir").Hour;
|
|
13
|
+
minute: import("date-vir").Minute;
|
|
14
|
+
second: import("date-vir").Minute;
|
|
15
|
+
millisecond: number;
|
|
16
|
+
timezone: "Africa/Abidjan" | "Africa/Accra" | "Africa/Addis_Ababa" | "Africa/Algiers" | "Africa/Asmara" | "Africa/Bamako" | "Africa/Bangui" | "Africa/Banjul" | "Africa/Bissau" | "Africa/Blantyre" | "Africa/Brazzaville" | "Africa/Bujumbura" | "Africa/Cairo" | "Africa/Casablanca" | "Africa/Ceuta" | "Africa/Conakry" | "Africa/Dakar" | "Africa/Dar_es_Salaam" | "Africa/Djibouti" | "Africa/Douala" | "Africa/El_Aaiun" | "Africa/Freetown" | "Africa/Gaborone" | "Africa/Harare" | "Africa/Johannesburg" | "Africa/Juba" | "Africa/Kampala" | "Africa/Khartoum" | "Africa/Kigali" | "Africa/Kinshasa" | "Africa/Lagos" | "Africa/Libreville" | "Africa/Lome" | "Africa/Luanda" | "Africa/Lubumbashi" | "Africa/Lusaka" | "Africa/Malabo" | "Africa/Maputo" | "Africa/Maseru" | "Africa/Mbabane" | "Africa/Mogadishu" | "Africa/Monrovia" | "Africa/Nairobi" | "Africa/Ndjamena" | "Africa/Niamey" | "Africa/Nouakchott" | "Africa/Ouagadougou" | "Africa/Porto-Novo" | "Africa/Sao_Tome" | "Africa/Timbuktu" | "Africa/Tripoli" | "Africa/Tunis" | "Africa/Windhoek" | "America/Adak" | "America/Anchorage" | "America/Anguilla" | "America/Antigua" | "America/Araguaina" | "America/Argentina/Buenos_Aires" | "America/Argentina/Catamarca" | "America/Argentina/ComodRivadavia" | "America/Argentina/Cordoba" | "America/Argentina/Jujuy" | "America/Argentina/La_Rioja" | "America/Argentina/Mendoza" | "America/Argentina/Rio_Gallegos" | "America/Argentina/Salta" | "America/Argentina/San_Juan" | "America/Argentina/San_Luis" | "America/Argentina/Tucuman" | "America/Argentina/Ushuaia" | "America/Aruba" | "America/Asuncion" | "America/Atikokan" | "America/Bahia" | "America/Bahia_Banderas" | "America/Barbados" | "America/Belem" | "America/Belize" | "America/Blanc-Sablon" | "America/Boa_Vista" | "America/Bogota" | "America/Boise" | "America/Cambridge_Bay" | "America/Campo_Grande" | "America/Cancun" | "America/Caracas" | "America/Cayenne" | "America/Cayman" | "America/Chicago" | "America/Chihuahua" | "America/Coral_Harbour" | "America/Costa_Rica" | "America/Creston" | "America/Cuiaba" | "America/Curacao" | "America/Danmarkshavn" | "America/Dawson" | "America/Dawson_Creek" | "America/Denver" | "America/Detroit" | "America/Dominica" | "America/Edmonton" | "America/Eirunepe" | "America/El_Salvador" | "America/Ensenada" | "America/Fort_Nelson" | "America/Fortaleza" | "America/Glace_Bay" | "America/Goose_Bay" | "America/Grand_Turk" | "America/Grenada" | "America/Guadeloupe" | "America/Guatemala" | "America/Guayaquil" | "America/Guyana" | "America/Halifax" | "America/Havana" | "America/Hermosillo" | "America/Indiana/Indianapolis" | "America/Indiana/Knox" | "America/Indiana/Marengo" | "America/Indiana/Petersburg" | "America/Indiana/Tell_City" | "America/Indiana/Vevay" | "America/Indiana/Vincennes" | "America/Indiana/Winamac" | "America/Inuvik" | "America/Iqaluit" | "America/Jamaica" | "America/Juneau" | "America/Kentucky/Louisville" | "America/Kentucky/Monticello" | "America/La_Paz" | "America/Lima" | "America/Los_Angeles" | "America/Maceio" | "America/Managua" | "America/Manaus" | "America/Martinique" | "America/Matamoros" | "America/Mazatlan" | "America/Menominee" | "America/Merida" | "America/Metlakatla" | "America/Mexico_City" | "America/Miquelon" | "America/Moncton" | "America/Monterrey" | "America/Montevideo" | "America/Montreal" | "America/Montserrat" | "America/Nassau" | "America/New_York" | "America/Nipigon" | "America/Nome" | "America/Noronha" | "America/North_Dakota/Beulah" | "America/North_Dakota/Center" | "America/North_Dakota/New_Salem" | "America/Nuuk" | "America/Ojinaga" | "America/Panama" | "America/Pangnirtung" | "America/Paramaribo" | "America/Phoenix" | "America/Port-au-Prince" | "America/Port_of_Spain" | "America/Porto_Velho" | "America/Puerto_Rico" | "America/Punta_Arenas" | "America/Rainy_River" | "America/Rankin_Inlet" | "America/Recife" | "America/Regina" | "America/Resolute" | "America/Rio_Branco" | "America/Rosario" | "America/Santarem" | "America/Santiago" | "America/Santo_Domingo" | "America/Sao_Paulo" | "America/Scoresbysund" | "America/Sitka" | "America/St_Johns" | "America/St_Kitts" | "America/St_Lucia" | "America/St_Thomas" | "America/St_Vincent" | "America/Swift_Current" | "America/Tegucigalpa" | "America/Thule" | "America/Thunder_Bay" | "America/Tijuana" | "America/Toronto" | "America/Tortola" | "America/Vancouver" | "America/Whitehorse" | "America/Winnipeg" | "America/Yakutat" | "America/Yellowknife" | "Antarctica/Casey" | "Antarctica/Davis" | "Antarctica/DumontDUrville" | "Antarctica/Macquarie" | "Antarctica/Mawson" | "Antarctica/McMurdo" | "Antarctica/Palmer" | "Antarctica/Rothera" | "Antarctica/Syowa" | "Antarctica/Troll" | "Antarctica/Vostok" | "Asia/Aden" | "Asia/Almaty" | "Asia/Amman" | "Asia/Anadyr" | "Asia/Aqtau" | "Asia/Aqtobe" | "Asia/Ashgabat" | "Asia/Atyrau" | "Asia/Baghdad" | "Asia/Bahrain" | "Asia/Baku" | "Asia/Bangkok" | "Asia/Barnaul" | "Asia/Beirut" | "Asia/Bishkek" | "Asia/Brunei" | "Asia/Chita" | "Asia/Choibalsan" | "Asia/Chongqing" | "Asia/Colombo" | "Asia/Damascus" | "Asia/Dhaka" | "Asia/Dili" | "Asia/Dubai" | "Asia/Dushanbe" | "Asia/Famagusta" | "Asia/Gaza" | "Asia/Harbin" | "Asia/Hebron" | "Asia/Ho_Chi_Minh" | "Asia/Hong_Kong" | "Asia/Hovd" | "Asia/Irkutsk" | "Asia/Jakarta" | "Asia/Jayapura" | "Asia/Jerusalem" | "Asia/Kabul" | "Asia/Kamchatka" | "Asia/Karachi" | "Asia/Kashgar" | "Asia/Kathmandu" | "Asia/Khandyga" | "Asia/Kolkata" | "Asia/Krasnoyarsk" | "Asia/Kuala_Lumpur" | "Asia/Kuching" | "Asia/Kuwait" | "Asia/Macau" | "Asia/Magadan" | "Asia/Makassar" | "Asia/Manila" | "Asia/Muscat" | "Asia/Nicosia" | "Asia/Novokuznetsk" | "Asia/Novosibirsk" | "Asia/Omsk" | "Asia/Oral" | "Asia/Phnom_Penh" | "Asia/Pontianak" | "Asia/Pyongyang" | "Asia/Qatar" | "Asia/Qostanay" | "Asia/Qyzylorda" | "Asia/Riyadh" | "Asia/Sakhalin" | "Asia/Samarkand" | "Asia/Seoul" | "Asia/Shanghai" | "Asia/Singapore" | "Asia/Srednekolymsk" | "Asia/Taipei" | "Asia/Tashkent" | "Asia/Tbilisi" | "Asia/Tehran" | "Asia/Tel_Aviv" | "Asia/Thimphu" | "Asia/Tokyo" | "Asia/Tomsk" | "Asia/Ulaanbaatar" | "Asia/Urumqi" | "Asia/Ust-Nera" | "Asia/Vientiane" | "Asia/Vladivostok" | "Asia/Yakutsk" | "Asia/Yangon" | "Asia/Yekaterinburg" | "Asia/Yerevan" | "Atlantic/Azores" | "Atlantic/Bermuda" | "Atlantic/Canary" | "Atlantic/Cape_Verde" | "Atlantic/Faroe" | "Atlantic/Jan_Mayen" | "Atlantic/Madeira" | "Atlantic/Reykjavik" | "Atlantic/South_Georgia" | "Atlantic/St_Helena" | "Atlantic/Stanley" | "Australia/Adelaide" | "Australia/Brisbane" | "Australia/Broken_Hill" | "Australia/Currie" | "Australia/Darwin" | "Australia/Eucla" | "Australia/Hobart" | "Australia/Lindeman" | "Australia/Lord_Howe" | "Australia/Melbourne" | "Australia/Perth" | "Australia/Sydney" | "CET" | "CST6CDT" | "EET" | "EST" | "EST5EDT" | "Etc/GMT+1" | "Etc/GMT+10" | "Etc/GMT+11" | "Etc/GMT+12" | "Etc/GMT+2" | "Etc/GMT+3" | "Etc/GMT+4" | "Etc/GMT+5" | "Etc/GMT+6" | "Etc/GMT+7" | "Etc/GMT+8" | "Etc/GMT+9" | "Etc/GMT-1" | "Etc/GMT-10" | "Etc/GMT-11" | "Etc/GMT-12" | "Etc/GMT-13" | "Etc/GMT-14" | "Etc/GMT-2" | "Etc/GMT-3" | "Etc/GMT-4" | "Etc/GMT-5" | "Etc/GMT-6" | "Etc/GMT-7" | "Etc/GMT-8" | "Etc/GMT-9" | "Europe/Amsterdam" | "Europe/Andorra" | "Europe/Astrakhan" | "Europe/Athens" | "Europe/Belfast" | "Europe/Belgrade" | "Europe/Berlin" | "Europe/Brussels" | "Europe/Bucharest" | "Europe/Budapest" | "Europe/Chisinau" | "Europe/Copenhagen" | "Europe/Dublin" | "Europe/Gibraltar" | "Europe/Guernsey" | "Europe/Helsinki" | "Europe/Isle_of_Man" | "Europe/Istanbul" | "Europe/Jersey" | "Europe/Kaliningrad" | "Europe/Kirov" | "Europe/Kyiv" | "Europe/Lisbon" | "Europe/Ljubljana" | "Europe/London" | "Europe/Luxembourg" | "Europe/Madrid" | "Europe/Malta" | "Europe/Minsk" | "Europe/Monaco" | "Europe/Moscow" | "Europe/Oslo" | "Europe/Paris" | "Europe/Prague" | "Europe/Riga" | "Europe/Rome" | "Europe/Samara" | "Europe/Sarajevo" | "Europe/Saratov" | "Europe/Simferopol" | "Europe/Skopje" | "Europe/Sofia" | "Europe/Stockholm" | "Europe/Tallinn" | "Europe/Tirane" | "Europe/Tiraspol" | "Europe/Ulyanovsk" | "Europe/Uzhgorod" | "Europe/Vaduz" | "Europe/Vienna" | "Europe/Vilnius" | "Europe/Volgograd" | "Europe/Warsaw" | "Europe/Zagreb" | "Europe/Zaporozhye" | "Europe/Zurich" | "HST" | "Indian/Antananarivo" | "Indian/Chagos" | "Indian/Christmas" | "Indian/Cocos" | "Indian/Comoro" | "Indian/Kerguelen" | "Indian/Mahe" | "Indian/Maldives" | "Indian/Mauritius" | "Indian/Mayotte" | "Indian/Reunion" | "MET" | "MST" | "MST7MDT" | "PST8PDT" | "Pacific/Apia" | "Pacific/Auckland" | "Pacific/Bougainville" | "Pacific/Chatham" | "Pacific/Chuuk" | "Pacific/Easter" | "Pacific/Efate" | "Pacific/Enderbury" | "Pacific/Fakaofo" | "Pacific/Fiji" | "Pacific/Funafuti" | "Pacific/Galapagos" | "Pacific/Gambier" | "Pacific/Guadalcanal" | "Pacific/Guam" | "Pacific/Honolulu" | "Pacific/Johnston" | "Pacific/Kanton" | "Pacific/Kiritimati" | "Pacific/Kosrae" | "Pacific/Kwajalein" | "Pacific/Majuro" | "Pacific/Marquesas" | "Pacific/Midway" | "Pacific/Nauru" | "Pacific/Niue" | "Pacific/Norfolk" | "Pacific/Noumea" | "Pacific/Pago_Pago" | "Pacific/Palau" | "Pacific/Pitcairn" | "Pacific/Pohnpei" | "Pacific/Port_Moresby" | "Pacific/Rarotonga" | "Pacific/Saipan" | "Pacific/Tahiti" | "Pacific/Tarawa" | "Pacific/Tongatapu" | "Pacific/Wake" | "Pacific/Wallis" | "UTC" | "WET";
|
|
17
|
+
} & {
|
|
18
|
+
year: number;
|
|
19
|
+
month: import("date-vir").MonthNumber;
|
|
20
|
+
day: import("date-vir").DayOfMonth;
|
|
21
|
+
timezone: "Africa/Abidjan" | "Africa/Accra" | "Africa/Addis_Ababa" | "Africa/Algiers" | "Africa/Asmara" | "Africa/Bamako" | "Africa/Bangui" | "Africa/Banjul" | "Africa/Bissau" | "Africa/Blantyre" | "Africa/Brazzaville" | "Africa/Bujumbura" | "Africa/Cairo" | "Africa/Casablanca" | "Africa/Ceuta" | "Africa/Conakry" | "Africa/Dakar" | "Africa/Dar_es_Salaam" | "Africa/Djibouti" | "Africa/Douala" | "Africa/El_Aaiun" | "Africa/Freetown" | "Africa/Gaborone" | "Africa/Harare" | "Africa/Johannesburg" | "Africa/Juba" | "Africa/Kampala" | "Africa/Khartoum" | "Africa/Kigali" | "Africa/Kinshasa" | "Africa/Lagos" | "Africa/Libreville" | "Africa/Lome" | "Africa/Luanda" | "Africa/Lubumbashi" | "Africa/Lusaka" | "Africa/Malabo" | "Africa/Maputo" | "Africa/Maseru" | "Africa/Mbabane" | "Africa/Mogadishu" | "Africa/Monrovia" | "Africa/Nairobi" | "Africa/Ndjamena" | "Africa/Niamey" | "Africa/Nouakchott" | "Africa/Ouagadougou" | "Africa/Porto-Novo" | "Africa/Sao_Tome" | "Africa/Timbuktu" | "Africa/Tripoli" | "Africa/Tunis" | "Africa/Windhoek" | "America/Adak" | "America/Anchorage" | "America/Anguilla" | "America/Antigua" | "America/Araguaina" | "America/Argentina/Buenos_Aires" | "America/Argentina/Catamarca" | "America/Argentina/ComodRivadavia" | "America/Argentina/Cordoba" | "America/Argentina/Jujuy" | "America/Argentina/La_Rioja" | "America/Argentina/Mendoza" | "America/Argentina/Rio_Gallegos" | "America/Argentina/Salta" | "America/Argentina/San_Juan" | "America/Argentina/San_Luis" | "America/Argentina/Tucuman" | "America/Argentina/Ushuaia" | "America/Aruba" | "America/Asuncion" | "America/Atikokan" | "America/Bahia" | "America/Bahia_Banderas" | "America/Barbados" | "America/Belem" | "America/Belize" | "America/Blanc-Sablon" | "America/Boa_Vista" | "America/Bogota" | "America/Boise" | "America/Cambridge_Bay" | "America/Campo_Grande" | "America/Cancun" | "America/Caracas" | "America/Cayenne" | "America/Cayman" | "America/Chicago" | "America/Chihuahua" | "America/Coral_Harbour" | "America/Costa_Rica" | "America/Creston" | "America/Cuiaba" | "America/Curacao" | "America/Danmarkshavn" | "America/Dawson" | "America/Dawson_Creek" | "America/Denver" | "America/Detroit" | "America/Dominica" | "America/Edmonton" | "America/Eirunepe" | "America/El_Salvador" | "America/Ensenada" | "America/Fort_Nelson" | "America/Fortaleza" | "America/Glace_Bay" | "America/Goose_Bay" | "America/Grand_Turk" | "America/Grenada" | "America/Guadeloupe" | "America/Guatemala" | "America/Guayaquil" | "America/Guyana" | "America/Halifax" | "America/Havana" | "America/Hermosillo" | "America/Indiana/Indianapolis" | "America/Indiana/Knox" | "America/Indiana/Marengo" | "America/Indiana/Petersburg" | "America/Indiana/Tell_City" | "America/Indiana/Vevay" | "America/Indiana/Vincennes" | "America/Indiana/Winamac" | "America/Inuvik" | "America/Iqaluit" | "America/Jamaica" | "America/Juneau" | "America/Kentucky/Louisville" | "America/Kentucky/Monticello" | "America/La_Paz" | "America/Lima" | "America/Los_Angeles" | "America/Maceio" | "America/Managua" | "America/Manaus" | "America/Martinique" | "America/Matamoros" | "America/Mazatlan" | "America/Menominee" | "America/Merida" | "America/Metlakatla" | "America/Mexico_City" | "America/Miquelon" | "America/Moncton" | "America/Monterrey" | "America/Montevideo" | "America/Montreal" | "America/Montserrat" | "America/Nassau" | "America/New_York" | "America/Nipigon" | "America/Nome" | "America/Noronha" | "America/North_Dakota/Beulah" | "America/North_Dakota/Center" | "America/North_Dakota/New_Salem" | "America/Nuuk" | "America/Ojinaga" | "America/Panama" | "America/Pangnirtung" | "America/Paramaribo" | "America/Phoenix" | "America/Port-au-Prince" | "America/Port_of_Spain" | "America/Porto_Velho" | "America/Puerto_Rico" | "America/Punta_Arenas" | "America/Rainy_River" | "America/Rankin_Inlet" | "America/Recife" | "America/Regina" | "America/Resolute" | "America/Rio_Branco" | "America/Rosario" | "America/Santarem" | "America/Santiago" | "America/Santo_Domingo" | "America/Sao_Paulo" | "America/Scoresbysund" | "America/Sitka" | "America/St_Johns" | "America/St_Kitts" | "America/St_Lucia" | "America/St_Thomas" | "America/St_Vincent" | "America/Swift_Current" | "America/Tegucigalpa" | "America/Thule" | "America/Thunder_Bay" | "America/Tijuana" | "America/Toronto" | "America/Tortola" | "America/Vancouver" | "America/Whitehorse" | "America/Winnipeg" | "America/Yakutat" | "America/Yellowknife" | "Antarctica/Casey" | "Antarctica/Davis" | "Antarctica/DumontDUrville" | "Antarctica/Macquarie" | "Antarctica/Mawson" | "Antarctica/McMurdo" | "Antarctica/Palmer" | "Antarctica/Rothera" | "Antarctica/Syowa" | "Antarctica/Troll" | "Antarctica/Vostok" | "Asia/Aden" | "Asia/Almaty" | "Asia/Amman" | "Asia/Anadyr" | "Asia/Aqtau" | "Asia/Aqtobe" | "Asia/Ashgabat" | "Asia/Atyrau" | "Asia/Baghdad" | "Asia/Bahrain" | "Asia/Baku" | "Asia/Bangkok" | "Asia/Barnaul" | "Asia/Beirut" | "Asia/Bishkek" | "Asia/Brunei" | "Asia/Chita" | "Asia/Choibalsan" | "Asia/Chongqing" | "Asia/Colombo" | "Asia/Damascus" | "Asia/Dhaka" | "Asia/Dili" | "Asia/Dubai" | "Asia/Dushanbe" | "Asia/Famagusta" | "Asia/Gaza" | "Asia/Harbin" | "Asia/Hebron" | "Asia/Ho_Chi_Minh" | "Asia/Hong_Kong" | "Asia/Hovd" | "Asia/Irkutsk" | "Asia/Jakarta" | "Asia/Jayapura" | "Asia/Jerusalem" | "Asia/Kabul" | "Asia/Kamchatka" | "Asia/Karachi" | "Asia/Kashgar" | "Asia/Kathmandu" | "Asia/Khandyga" | "Asia/Kolkata" | "Asia/Krasnoyarsk" | "Asia/Kuala_Lumpur" | "Asia/Kuching" | "Asia/Kuwait" | "Asia/Macau" | "Asia/Magadan" | "Asia/Makassar" | "Asia/Manila" | "Asia/Muscat" | "Asia/Nicosia" | "Asia/Novokuznetsk" | "Asia/Novosibirsk" | "Asia/Omsk" | "Asia/Oral" | "Asia/Phnom_Penh" | "Asia/Pontianak" | "Asia/Pyongyang" | "Asia/Qatar" | "Asia/Qostanay" | "Asia/Qyzylorda" | "Asia/Riyadh" | "Asia/Sakhalin" | "Asia/Samarkand" | "Asia/Seoul" | "Asia/Shanghai" | "Asia/Singapore" | "Asia/Srednekolymsk" | "Asia/Taipei" | "Asia/Tashkent" | "Asia/Tbilisi" | "Asia/Tehran" | "Asia/Tel_Aviv" | "Asia/Thimphu" | "Asia/Tokyo" | "Asia/Tomsk" | "Asia/Ulaanbaatar" | "Asia/Urumqi" | "Asia/Ust-Nera" | "Asia/Vientiane" | "Asia/Vladivostok" | "Asia/Yakutsk" | "Asia/Yangon" | "Asia/Yekaterinburg" | "Asia/Yerevan" | "Atlantic/Azores" | "Atlantic/Bermuda" | "Atlantic/Canary" | "Atlantic/Cape_Verde" | "Atlantic/Faroe" | "Atlantic/Jan_Mayen" | "Atlantic/Madeira" | "Atlantic/Reykjavik" | "Atlantic/South_Georgia" | "Atlantic/St_Helena" | "Atlantic/Stanley" | "Australia/Adelaide" | "Australia/Brisbane" | "Australia/Broken_Hill" | "Australia/Currie" | "Australia/Darwin" | "Australia/Eucla" | "Australia/Hobart" | "Australia/Lindeman" | "Australia/Lord_Howe" | "Australia/Melbourne" | "Australia/Perth" | "Australia/Sydney" | "CET" | "CST6CDT" | "EET" | "EST" | "EST5EDT" | "Etc/GMT+1" | "Etc/GMT+10" | "Etc/GMT+11" | "Etc/GMT+12" | "Etc/GMT+2" | "Etc/GMT+3" | "Etc/GMT+4" | "Etc/GMT+5" | "Etc/GMT+6" | "Etc/GMT+7" | "Etc/GMT+8" | "Etc/GMT+9" | "Etc/GMT-1" | "Etc/GMT-10" | "Etc/GMT-11" | "Etc/GMT-12" | "Etc/GMT-13" | "Etc/GMT-14" | "Etc/GMT-2" | "Etc/GMT-3" | "Etc/GMT-4" | "Etc/GMT-5" | "Etc/GMT-6" | "Etc/GMT-7" | "Etc/GMT-8" | "Etc/GMT-9" | "Europe/Amsterdam" | "Europe/Andorra" | "Europe/Astrakhan" | "Europe/Athens" | "Europe/Belfast" | "Europe/Belgrade" | "Europe/Berlin" | "Europe/Brussels" | "Europe/Bucharest" | "Europe/Budapest" | "Europe/Chisinau" | "Europe/Copenhagen" | "Europe/Dublin" | "Europe/Gibraltar" | "Europe/Guernsey" | "Europe/Helsinki" | "Europe/Isle_of_Man" | "Europe/Istanbul" | "Europe/Jersey" | "Europe/Kaliningrad" | "Europe/Kirov" | "Europe/Kyiv" | "Europe/Lisbon" | "Europe/Ljubljana" | "Europe/London" | "Europe/Luxembourg" | "Europe/Madrid" | "Europe/Malta" | "Europe/Minsk" | "Europe/Monaco" | "Europe/Moscow" | "Europe/Oslo" | "Europe/Paris" | "Europe/Prague" | "Europe/Riga" | "Europe/Rome" | "Europe/Samara" | "Europe/Sarajevo" | "Europe/Saratov" | "Europe/Simferopol" | "Europe/Skopje" | "Europe/Sofia" | "Europe/Stockholm" | "Europe/Tallinn" | "Europe/Tirane" | "Europe/Tiraspol" | "Europe/Ulyanovsk" | "Europe/Uzhgorod" | "Europe/Vaduz" | "Europe/Vienna" | "Europe/Vilnius" | "Europe/Volgograd" | "Europe/Warsaw" | "Europe/Zagreb" | "Europe/Zaporozhye" | "Europe/Zurich" | "HST" | "Indian/Antananarivo" | "Indian/Chagos" | "Indian/Christmas" | "Indian/Cocos" | "Indian/Comoro" | "Indian/Kerguelen" | "Indian/Mahe" | "Indian/Maldives" | "Indian/Mauritius" | "Indian/Mayotte" | "Indian/Reunion" | "MET" | "MST" | "MST7MDT" | "PST8PDT" | "Pacific/Apia" | "Pacific/Auckland" | "Pacific/Bougainville" | "Pacific/Chatham" | "Pacific/Chuuk" | "Pacific/Easter" | "Pacific/Efate" | "Pacific/Enderbury" | "Pacific/Fakaofo" | "Pacific/Fiji" | "Pacific/Funafuti" | "Pacific/Galapagos" | "Pacific/Gambier" | "Pacific/Guadalcanal" | "Pacific/Guam" | "Pacific/Honolulu" | "Pacific/Johnston" | "Pacific/Kanton" | "Pacific/Kiritimati" | "Pacific/Kosrae" | "Pacific/Kwajalein" | "Pacific/Majuro" | "Pacific/Marquesas" | "Pacific/Midway" | "Pacific/Nauru" | "Pacific/Niue" | "Pacific/Norfolk" | "Pacific/Noumea" | "Pacific/Pago_Pago" | "Pacific/Palau" | "Pacific/Pitcairn" | "Pacific/Pohnpei" | "Pacific/Port_Moresby" | "Pacific/Rarotonga" | "Pacific/Saipan" | "Pacific/Tahiti" | "Pacific/Tarawa" | "Pacific/Tongatapu" | "Pacific/Wake" | "Pacific/Wallis" | "UTC" | "WET";
|
|
22
|
+
}>>>;
|
|
23
|
+
}>;
|
|
24
|
+
/**
|
|
25
|
+
* A cryptographically CSRF token with expiration date.
|
|
26
|
+
*
|
|
27
|
+
* @category Internal
|
|
28
|
+
*/
|
|
29
|
+
export type CsrfToken = typeof csrfTokenShape.runtimeType;
|
|
7
30
|
/**
|
|
8
31
|
* Generates a random, cryptographically secure CSRF token.
|
|
9
32
|
*
|
|
10
33
|
* @category Internal
|
|
11
34
|
*/
|
|
12
|
-
export declare function generateCsrfToken(
|
|
35
|
+
export declare function generateCsrfToken(
|
|
36
|
+
/** How long the CSRF token is valid for. */
|
|
37
|
+
duration: Readonly<AnyDuration>): CsrfToken;
|
|
38
|
+
/**
|
|
39
|
+
* CSRF token failure reasons for {@link GetCsrfTokenResult}.
|
|
40
|
+
*
|
|
41
|
+
* @category Internal
|
|
42
|
+
*/
|
|
43
|
+
export declare enum CsrfTokenFailureReason {
|
|
44
|
+
/** No CSRF token was found. */
|
|
45
|
+
DoesNotExist = "does-not-exist",
|
|
46
|
+
/** A CSRF token was found but parsing it failed. */
|
|
47
|
+
ParseFailed = "parse-failed",
|
|
48
|
+
/** A CSRF token was found and parsed but is expired. */
|
|
49
|
+
Expired = "expired"
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Output from {@link getCurrentCsrfToken}.
|
|
53
|
+
*
|
|
54
|
+
* @category Internal
|
|
55
|
+
*/
|
|
56
|
+
export type GetCsrfTokenResult = RequireExactlyOne<{
|
|
57
|
+
csrfToken: Readonly<CsrfToken>;
|
|
58
|
+
failure: CsrfTokenFailureReason;
|
|
59
|
+
}>;
|
|
60
|
+
/**
|
|
61
|
+
* Extract the CSRF token header from a response.
|
|
62
|
+
*
|
|
63
|
+
* @category Auth : Client
|
|
64
|
+
*/
|
|
65
|
+
export declare function extractCsrfTokenHeader(response: Readonly<SelectFrom<Response, {
|
|
66
|
+
headers: true;
|
|
67
|
+
}>>, overrides?: PartialWithUndefined<{
|
|
68
|
+
csrfHeaderName: string;
|
|
69
|
+
}>): Readonly<GetCsrfTokenResult>;
|
|
70
|
+
/**
|
|
71
|
+
* Stores the given CSRF token into local storage.
|
|
72
|
+
*
|
|
73
|
+
* @category Auth : Client
|
|
74
|
+
*/
|
|
75
|
+
export declare function storeCsrfToken(csrfToken: Readonly<CsrfToken>, overrides?: PartialWithUndefined<{
|
|
76
|
+
/**
|
|
77
|
+
* Allows mocking or overriding the global `localStorage`.
|
|
78
|
+
*
|
|
79
|
+
* @default globalThis.localStorage
|
|
80
|
+
*/
|
|
81
|
+
localStorage: Pick<Storage, 'setItem' | 'removeItem'>;
|
|
82
|
+
/** Override the default CSRF token header name. */
|
|
83
|
+
csrfHeaderName: string;
|
|
84
|
+
}>): void;
|
|
85
|
+
/**
|
|
86
|
+
* Parse a raw CSRF token JSON string.
|
|
87
|
+
*
|
|
88
|
+
* @category Internal
|
|
89
|
+
*/
|
|
90
|
+
export declare function parseCsrfToken(value: string | undefined | null): Readonly<GetCsrfTokenResult>;
|
|
91
|
+
/**
|
|
92
|
+
* Used in client (frontend) code to retrieve the current CSRF token in order to send it with
|
|
93
|
+
* requests to the host (backend).
|
|
94
|
+
*
|
|
95
|
+
* @category Auth : Client
|
|
96
|
+
*/
|
|
97
|
+
export declare function getCurrentCsrfToken(overrides?: PartialWithUndefined<{
|
|
98
|
+
/**
|
|
99
|
+
* Allows mocking or overriding the global `localStorage`.
|
|
100
|
+
*
|
|
101
|
+
* @default globalThis.localStorage
|
|
102
|
+
*/
|
|
103
|
+
localStorage: Pick<Storage, 'getItem'>;
|
|
104
|
+
/** Override the default CSRF token header name. */
|
|
105
|
+
csrfHeaderName: string;
|
|
106
|
+
}>): Readonly<GetCsrfTokenResult>;
|
|
107
|
+
/**
|
|
108
|
+
* Wipes the current stored CSRF token. This should be used by client (frontend) code to logout a
|
|
109
|
+
* user or react to a session timeout.
|
|
110
|
+
*
|
|
111
|
+
* @category Auth : Client
|
|
112
|
+
*/
|
|
113
|
+
export declare function wipeCurrentCsrfToken(overrides?: PartialWithUndefined<{
|
|
114
|
+
/**
|
|
115
|
+
* Allows mocking or overriding the global `localStorage`.
|
|
116
|
+
*
|
|
117
|
+
* @default globalThis.localStorage
|
|
118
|
+
*/
|
|
119
|
+
localStorage: Pick<Storage, 'removeItem'>;
|
|
120
|
+
/** Override the default CSRF token header name. */
|
|
121
|
+
csrfHeaderName: string;
|
|
122
|
+
}>): void;
|