auth-vir 2.3.5 → 2.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auth-client/backend-auth.client.d.ts +1 -1
- package/dist/auth-client/backend-auth.client.js +4 -3
- package/dist/auth-client/frontend-auth.client.d.ts +10 -3
- package/dist/auth-client/frontend-auth.client.js +14 -9
- package/package.json +2 -1
- package/src/auth-client/backend-auth.client.ts +6 -4
- package/src/auth-client/frontend-auth.client.ts +16 -7
|
@@ -99,7 +99,7 @@ export type BackendAuthClientConfig<DatabaseUser extends AnyObject, UserId exten
|
|
|
99
99
|
* How long before a user's session times out when we should start trying to refresh their
|
|
100
100
|
* session.
|
|
101
101
|
*
|
|
102
|
-
* @default {minutes:
|
|
102
|
+
* @default {minutes: 10}
|
|
103
103
|
*/
|
|
104
104
|
sessionRefreshThreshold: Readonly<AnyDuration>;
|
|
105
105
|
overrides: PartialWithUndefined<{
|
|
@@ -7,6 +7,9 @@ import { parseJwtKeys } from '../jwt/jwt-keys.js';
|
|
|
7
7
|
const defaultSessionIdleTimeout = {
|
|
8
8
|
minutes: 20,
|
|
9
9
|
};
|
|
10
|
+
const defaultSessionRefreshThreshold = {
|
|
11
|
+
minutes: 10,
|
|
12
|
+
};
|
|
10
13
|
/**
|
|
11
14
|
* An auth client for creating and validating JWTs embedded in cookies. This should only be used in
|
|
12
15
|
* a backend environment as it accesses native Node packages.
|
|
@@ -72,9 +75,7 @@ export class BackendAuthClient {
|
|
|
72
75
|
* - Z = JWT expiration outside the refresh threshold: {@link isRefreshReady} = false.
|
|
73
76
|
*/
|
|
74
77
|
const isRefreshReady = isDateAfter({
|
|
75
|
-
fullDate: calculateRelativeDate(now, this.config.sessionRefreshThreshold ||
|
|
76
|
-
minutes: 5,
|
|
77
|
-
}),
|
|
78
|
+
fullDate: calculateRelativeDate(now, this.config.sessionRefreshThreshold || defaultSessionRefreshThreshold),
|
|
78
79
|
relativeTo: userIdResult.jwtExpiration,
|
|
79
80
|
});
|
|
80
81
|
if (isRefreshReady) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createBlockingInterval, type JsonCompatibleObject, type MaybePromise, type PartialWithUndefined, type SelectFrom } from '@augment-vir/common';
|
|
1
|
+
import { type createBlockingInterval, type JsonCompatibleObject, type MaybePromise, type PartialWithUndefined, type SelectFrom } from '@augment-vir/common';
|
|
2
2
|
import { type AnyDuration } from 'date-vir';
|
|
3
3
|
import { type EmptyObject } from 'type-fest';
|
|
4
4
|
/**
|
|
@@ -26,12 +26,19 @@ export type FrontendAuthClientConfig = PartialWithUndefined<{
|
|
|
26
26
|
*
|
|
27
27
|
* If the user is not currently authorized, this should return `undefined` to prevent
|
|
28
28
|
* unnecessary network traffic.
|
|
29
|
+
*
|
|
30
|
+
* This will be called any time the user interacts with the page, debounced by the adjacent
|
|
31
|
+
* `debounce` property.
|
|
29
32
|
*/
|
|
30
33
|
performCheck: () => MaybePromise<SelectFrom<Response, {
|
|
31
34
|
status: true;
|
|
32
35
|
}> | undefined>;
|
|
33
|
-
/**
|
|
34
|
-
|
|
36
|
+
/**
|
|
37
|
+
* Debounce for firing `performCheck`.
|
|
38
|
+
*
|
|
39
|
+
* @default {minutes: 1}
|
|
40
|
+
*/
|
|
41
|
+
debounce?: AnyDuration | undefined;
|
|
35
42
|
};
|
|
36
43
|
overrides: PartialWithUndefined<{
|
|
37
44
|
localStorage: Pick<Storage, 'setItem' | 'removeItem' | 'getItem'>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { HttpStatus, } from '@augment-vir/common';
|
|
2
|
+
import { listenToActivity } from 'detect-activity';
|
|
2
3
|
import { CsrfTokenFailureReason, extractCsrfTokenHeader, getCurrentCsrfToken, storeCsrfToken, wipeCurrentCsrfToken, } from '../csrf-token.js';
|
|
3
4
|
import { AuthHeaderName } from '../headers.js';
|
|
4
5
|
/**
|
|
@@ -14,14 +15,18 @@ export class FrontendAuthClient {
|
|
|
14
15
|
constructor(config = {}) {
|
|
15
16
|
this.config = config;
|
|
16
17
|
if (config.checkUser) {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
18
|
+
listenToActivity({
|
|
19
|
+
listener: async () => {
|
|
20
|
+
const response = await config.checkUser?.performCheck();
|
|
21
|
+
if (response) {
|
|
22
|
+
await this.verifyResponseAuth({
|
|
23
|
+
status: response.status,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
debounce: config.checkUser.debounce || { minutes: 5 },
|
|
28
|
+
fireImmediately: false,
|
|
29
|
+
});
|
|
25
30
|
}
|
|
26
31
|
}
|
|
27
32
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "auth-vir",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.7",
|
|
4
4
|
"description": "Auth made easy and secure via JWT cookies, CSRF tokens, and password hashing helpers.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"auth",
|
|
@@ -45,6 +45,7 @@
|
|
|
45
45
|
"@augment-vir/assert": "^31.47.0",
|
|
46
46
|
"@augment-vir/common": "^31.47.0",
|
|
47
47
|
"date-vir": "^8.0.0",
|
|
48
|
+
"detect-activity": "^0.0.1",
|
|
48
49
|
"hash-wasm": "^4.12.0",
|
|
49
50
|
"jose": "^6.1.0",
|
|
50
51
|
"object-shape-tester": "^6.9.3",
|
|
@@ -123,7 +123,7 @@ export type BackendAuthClientConfig<
|
|
|
123
123
|
* How long before a user's session times out when we should start trying to refresh their
|
|
124
124
|
* session.
|
|
125
125
|
*
|
|
126
|
-
* @default {minutes:
|
|
126
|
+
* @default {minutes: 10}
|
|
127
127
|
*/
|
|
128
128
|
sessionRefreshThreshold: Readonly<AnyDuration>;
|
|
129
129
|
overrides: PartialWithUndefined<{
|
|
@@ -137,6 +137,10 @@ const defaultSessionIdleTimeout: Readonly<AnyDuration> = {
|
|
|
137
137
|
minutes: 20,
|
|
138
138
|
};
|
|
139
139
|
|
|
140
|
+
const defaultSessionRefreshThreshold: Readonly<AnyDuration> = {
|
|
141
|
+
minutes: 10,
|
|
142
|
+
};
|
|
143
|
+
|
|
140
144
|
/**
|
|
141
145
|
* An auth client for creating and validating JWTs embedded in cookies. This should only be used in
|
|
142
146
|
* a backend environment as it accesses native Node packages.
|
|
@@ -245,9 +249,7 @@ export class BackendAuthClient<
|
|
|
245
249
|
const isRefreshReady = isDateAfter({
|
|
246
250
|
fullDate: calculateRelativeDate(
|
|
247
251
|
now,
|
|
248
|
-
this.config.sessionRefreshThreshold ||
|
|
249
|
-
minutes: 5,
|
|
250
|
-
},
|
|
252
|
+
this.config.sessionRefreshThreshold || defaultSessionRefreshThreshold,
|
|
251
253
|
),
|
|
252
254
|
relativeTo: userIdResult.jwtExpiration,
|
|
253
255
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
-
createBlockingInterval,
|
|
2
|
+
type createBlockingInterval,
|
|
3
3
|
HttpStatus,
|
|
4
4
|
type JsonCompatibleObject,
|
|
5
5
|
type MaybePromise,
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
type SelectFrom,
|
|
8
8
|
} from '@augment-vir/common';
|
|
9
9
|
import {type AnyDuration} from 'date-vir';
|
|
10
|
+
import {listenToActivity} from 'detect-activity';
|
|
10
11
|
import {type EmptyObject} from 'type-fest';
|
|
11
12
|
import {
|
|
12
13
|
CsrfTokenFailureReason,
|
|
@@ -43,6 +44,9 @@ export type FrontendAuthClientConfig = PartialWithUndefined<{
|
|
|
43
44
|
*
|
|
44
45
|
* If the user is not currently authorized, this should return `undefined` to prevent
|
|
45
46
|
* unnecessary network traffic.
|
|
47
|
+
*
|
|
48
|
+
* This will be called any time the user interacts with the page, debounced by the adjacent
|
|
49
|
+
* `debounce` property.
|
|
46
50
|
*/
|
|
47
51
|
performCheck: () => MaybePromise<
|
|
48
52
|
| SelectFrom<
|
|
@@ -53,8 +57,12 @@ export type FrontendAuthClientConfig = PartialWithUndefined<{
|
|
|
53
57
|
>
|
|
54
58
|
| undefined
|
|
55
59
|
>;
|
|
56
|
-
/**
|
|
57
|
-
|
|
60
|
+
/**
|
|
61
|
+
* Debounce for firing `performCheck`.
|
|
62
|
+
*
|
|
63
|
+
* @default {minutes: 1}
|
|
64
|
+
*/
|
|
65
|
+
debounce?: AnyDuration | undefined;
|
|
58
66
|
};
|
|
59
67
|
|
|
60
68
|
overrides: PartialWithUndefined<{
|
|
@@ -76,8 +84,8 @@ export class FrontendAuthClient<AssumedUserParams extends JsonCompatibleObject =
|
|
|
76
84
|
|
|
77
85
|
constructor(protected readonly config: FrontendAuthClientConfig = {}) {
|
|
78
86
|
if (config.checkUser) {
|
|
79
|
-
|
|
80
|
-
async () => {
|
|
87
|
+
listenToActivity({
|
|
88
|
+
listener: async () => {
|
|
81
89
|
const response = await config.checkUser?.performCheck();
|
|
82
90
|
|
|
83
91
|
if (response) {
|
|
@@ -86,8 +94,9 @@ export class FrontendAuthClient<AssumedUserParams extends JsonCompatibleObject =
|
|
|
86
94
|
});
|
|
87
95
|
}
|
|
88
96
|
},
|
|
89
|
-
config.checkUser.
|
|
90
|
-
|
|
97
|
+
debounce: config.checkUser.debounce || {minutes: 5},
|
|
98
|
+
fireImmediately: false,
|
|
99
|
+
});
|
|
91
100
|
}
|
|
92
101
|
}
|
|
93
102
|
|