auth-vir 2.0.2 → 2.0.4
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 +10 -13
- package/dist/auth-client/backend-auth.client.js +14 -27
- package/dist/auth-client/frontend-auth.client.d.ts +6 -2
- package/dist/auth-client/frontend-auth.client.js +12 -2
- package/package.json +1 -1
- package/src/auth-client/backend-auth.client.ts +22 -37
- package/src/auth-client/frontend-auth.client.ts +18 -6
|
@@ -44,7 +44,7 @@ export type BackendAuthClientConfig<DatabaseUser extends AnyObject, UserId exten
|
|
|
44
44
|
* If this is set, we're attempting to load a database user for the purpose of assuming
|
|
45
45
|
* their user identity. Otherwise, this is `undefined`.
|
|
46
46
|
*/
|
|
47
|
-
|
|
47
|
+
assumingUser: AssumedUserParams | undefined;
|
|
48
48
|
}) => MaybePromise<DatabaseUser | undefined | null>;
|
|
49
49
|
/**
|
|
50
50
|
* Get JWT keys produced by {@link generateNewJwtKeys}. Make sure that each time this is
|
|
@@ -67,11 +67,11 @@ export type BackendAuthClientConfig<DatabaseUser extends AnyObject, UserId exten
|
|
|
67
67
|
*/
|
|
68
68
|
assumeUser: {
|
|
69
69
|
/**
|
|
70
|
-
*
|
|
70
|
+
* Parse the assumed user header value.
|
|
71
71
|
*
|
|
72
72
|
* @see {@link AuthHeaderName}
|
|
73
73
|
*/
|
|
74
|
-
|
|
74
|
+
parseAssumedUserHeaderValue: (
|
|
75
75
|
/**
|
|
76
76
|
* The assumed user header value.
|
|
77
77
|
*
|
|
@@ -82,15 +82,12 @@ export type BackendAuthClientConfig<DatabaseUser extends AnyObject, UserId exten
|
|
|
82
82
|
userId: UserId;
|
|
83
83
|
} | undefined>;
|
|
84
84
|
/**
|
|
85
|
-
* Return `true` to allow the current user
|
|
86
|
-
*
|
|
87
|
-
* admin users.
|
|
85
|
+
* Return `true` to allow the current/original user to assume identities of other users.
|
|
86
|
+
* Return `false` to block it. It is recommended to only return `true` for admin users.
|
|
88
87
|
*
|
|
89
88
|
* @see {@link AuthHeaderName}
|
|
90
89
|
*/
|
|
91
|
-
canAssumeUser: (
|
|
92
|
-
userId: UserId;
|
|
93
|
-
}) => MaybePromise<boolean>;
|
|
90
|
+
canAssumeUser: (originalUser: DatabaseUser) => MaybePromise<boolean>;
|
|
94
91
|
};
|
|
95
92
|
/**
|
|
96
93
|
* This determines how long a cookie will be valid until it needs to be refreshed.
|
|
@@ -132,9 +129,9 @@ export declare class BackendAuthClient<DatabaseUser extends AnyObject, UserId ex
|
|
|
132
129
|
isSignUpCookie?: boolean | undefined;
|
|
133
130
|
}): Promise<Readonly<CookieParams>>;
|
|
134
131
|
/** Calls the provided `getUserFromDatabase` config. */
|
|
135
|
-
protected getDatabaseUser({ isSignUpCookie, userId,
|
|
132
|
+
protected getDatabaseUser({ isSignUpCookie, userId, assumingUser, }: {
|
|
136
133
|
userId: UserId | undefined;
|
|
137
|
-
|
|
134
|
+
assumingUser: AssumedUserParams | undefined;
|
|
138
135
|
isSignUpCookie: boolean;
|
|
139
136
|
}): Promise<undefined | DatabaseUser>;
|
|
140
137
|
/** Creates a `'cookie-set'` header to refresh the user's session cookie. */
|
|
@@ -142,8 +139,8 @@ export declare class BackendAuthClient<DatabaseUser extends AnyObject, UserId ex
|
|
|
142
139
|
userIdResult: Readonly<UserIdResult<UserId>>;
|
|
143
140
|
}): Promise<OutgoingHttpHeaders | undefined>;
|
|
144
141
|
/** Reads the user's assumed user headers and, if configured, gets the assumed user. */
|
|
145
|
-
protected getAssumedUser({ headers,
|
|
146
|
-
|
|
142
|
+
protected getAssumedUser({ headers, user, }: {
|
|
143
|
+
user: DatabaseUser;
|
|
147
144
|
headers: IncomingHttpHeaders;
|
|
148
145
|
}): Promise<DatabaseUser | undefined>;
|
|
149
146
|
/** Securely extract a user from their request headers. */
|
|
@@ -31,12 +31,12 @@ export class BackendAuthClient {
|
|
|
31
31
|
};
|
|
32
32
|
}
|
|
33
33
|
/** Calls the provided `getUserFromDatabase` config. */
|
|
34
|
-
async getDatabaseUser({ isSignUpCookie, userId,
|
|
34
|
+
async getDatabaseUser({ isSignUpCookie, userId, assumingUser, }) {
|
|
35
35
|
if (!userId) {
|
|
36
36
|
return undefined;
|
|
37
37
|
}
|
|
38
38
|
const authenticatedUser = await this.config.getUserFromDatabase({
|
|
39
|
-
|
|
39
|
+
assumingUser,
|
|
40
40
|
userId,
|
|
41
41
|
isSignUpCookie,
|
|
42
42
|
});
|
|
@@ -89,26 +89,22 @@ export class BackendAuthClient {
|
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
91
|
/** Reads the user's assumed user headers and, if configured, gets the assumed user. */
|
|
92
|
-
async getAssumedUser({ headers,
|
|
93
|
-
if (!
|
|
94
|
-
!this.config.assumeUser ||
|
|
95
|
-
!(await this.config.assumeUser.canAssumeUser({
|
|
96
|
-
userId: originalUserId,
|
|
97
|
-
}))) {
|
|
92
|
+
async getAssumedUser({ headers, user, }) {
|
|
93
|
+
if (!this.config.assumeUser || !(await this.config.assumeUser.canAssumeUser(user))) {
|
|
98
94
|
return undefined;
|
|
99
95
|
}
|
|
100
96
|
const assumedUserHeader = ensureArray(headers[this.config.overrides?.assumedUserHeaderName || AuthHeaderName.AssumedUser])[0];
|
|
101
97
|
if (!assumedUserHeader) {
|
|
102
98
|
return undefined;
|
|
103
99
|
}
|
|
104
|
-
const parsedAssumedUserData = await this.config.assumeUser.
|
|
100
|
+
const parsedAssumedUserData = await this.config.assumeUser.parseAssumedUserHeaderValue(assumedUserHeader);
|
|
105
101
|
if (!parsedAssumedUserData || !parsedAssumedUserData.userId) {
|
|
106
102
|
return undefined;
|
|
107
103
|
}
|
|
108
104
|
const assumedUser = await this.getDatabaseUser({
|
|
109
105
|
isSignUpCookie: false,
|
|
110
106
|
userId: parsedAssumedUserData.userId,
|
|
111
|
-
|
|
107
|
+
assumingUser: parsedAssumedUserData.assumedUserParams,
|
|
112
108
|
});
|
|
113
109
|
return assumedUser;
|
|
114
110
|
}
|
|
@@ -120,7 +116,7 @@ export class BackendAuthClient {
|
|
|
120
116
|
}
|
|
121
117
|
const user = await this.getDatabaseUser({
|
|
122
118
|
userId: userIdResult.userId,
|
|
123
|
-
|
|
119
|
+
assumingUser: undefined,
|
|
124
120
|
isSignUpCookie: !!isSignUpCookie,
|
|
125
121
|
});
|
|
126
122
|
if (!user) {
|
|
@@ -128,25 +124,16 @@ export class BackendAuthClient {
|
|
|
128
124
|
}
|
|
129
125
|
const assumedUser = await this.getAssumedUser({
|
|
130
126
|
headers: requestHeaders,
|
|
131
|
-
|
|
127
|
+
user,
|
|
132
128
|
});
|
|
133
129
|
const cookieRefreshHeaders = (await this.createCookieRefreshHeaders({
|
|
134
130
|
userIdResult,
|
|
135
131
|
})) || {};
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
else {
|
|
144
|
-
return {
|
|
145
|
-
user,
|
|
146
|
-
isAssumed: false,
|
|
147
|
-
responseHeaders: cookieRefreshHeaders,
|
|
148
|
-
};
|
|
149
|
-
}
|
|
132
|
+
return {
|
|
133
|
+
user: assumedUser || user,
|
|
134
|
+
isAssumed: !!assumedUser,
|
|
135
|
+
responseHeaders: cookieRefreshHeaders,
|
|
136
|
+
};
|
|
150
137
|
}
|
|
151
138
|
/**
|
|
152
139
|
* Get all the JWT params used when creating the auth cookie, in case you need them for
|
|
@@ -216,7 +203,7 @@ export class BackendAuthClient {
|
|
|
216
203
|
const user = await this.getDatabaseUser({
|
|
217
204
|
isSignUpCookie: false,
|
|
218
205
|
userId: userIdResult.userId,
|
|
219
|
-
|
|
206
|
+
assumingUser: undefined,
|
|
220
207
|
});
|
|
221
208
|
if (!user) {
|
|
222
209
|
return undefined;
|
|
@@ -31,8 +31,12 @@ export declare class FrontendAuthClient<AssumedUserParams extends JsonCompatible
|
|
|
31
31
|
constructor(config?: FrontendAuthClientConfig);
|
|
32
32
|
/** Wraps {@link getCurrentCsrfToken} to automatically handle wiping an invalid CSRF token. */
|
|
33
33
|
getCurrentCsrfToken(): Promise<string | undefined>;
|
|
34
|
-
/**
|
|
35
|
-
|
|
34
|
+
/**
|
|
35
|
+
* Assume the given user. Pass `undefined` to wipe the currently assumed user.
|
|
36
|
+
*
|
|
37
|
+
* @returns Whether the assumed user setting or clearing succeeded or not.
|
|
38
|
+
*/
|
|
39
|
+
assumeUser(assumedUserParams: Readonly<AssumedUserParams> | undefined): Promise<boolean>;
|
|
36
40
|
/** Gets the assumed user params stored in local storage, if any. */
|
|
37
41
|
getAssumedUser(): AssumedUserParams | undefined;
|
|
38
42
|
/**
|
|
@@ -25,12 +25,22 @@ export class FrontendAuthClient {
|
|
|
25
25
|
return csrfTokenResult.csrfToken?.token;
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
|
-
/**
|
|
28
|
+
/**
|
|
29
|
+
* Assume the given user. Pass `undefined` to wipe the currently assumed user.
|
|
30
|
+
*
|
|
31
|
+
* @returns Whether the assumed user setting or clearing succeeded or not.
|
|
32
|
+
*/
|
|
29
33
|
async assumeUser(assumedUserParams) {
|
|
34
|
+
const localStorage = this.config.overrides?.localStorage || globalThis.localStorage;
|
|
35
|
+
const storageKey = this.config.overrides?.assumedUserHeaderName || AuthHeaderName.AssumedUser;
|
|
36
|
+
if (!assumedUserParams) {
|
|
37
|
+
localStorage.removeItem(storageKey);
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
30
40
|
if (!(await this.config.canAssumeUser?.())) {
|
|
31
41
|
return false;
|
|
32
42
|
}
|
|
33
|
-
|
|
43
|
+
localStorage.setItem(storageKey, JSON.stringify(assumedUserParams));
|
|
34
44
|
return true;
|
|
35
45
|
}
|
|
36
46
|
/** Gets the assumed user params stored in local storage, if any. */
|
package/package.json
CHANGED
|
@@ -65,7 +65,7 @@ export type BackendAuthClientConfig<
|
|
|
65
65
|
* If this is set, we're attempting to load a database user for the purpose of assuming
|
|
66
66
|
* their user identity. Otherwise, this is `undefined`.
|
|
67
67
|
*/
|
|
68
|
-
|
|
68
|
+
assumingUser: AssumedUserParams | undefined;
|
|
69
69
|
}) => MaybePromise<DatabaseUser | undefined | null>;
|
|
70
70
|
/**
|
|
71
71
|
* Get JWT keys produced by {@link generateNewJwtKeys}. Make sure that each time this is
|
|
@@ -88,11 +88,11 @@ export type BackendAuthClientConfig<
|
|
|
88
88
|
*/
|
|
89
89
|
assumeUser: {
|
|
90
90
|
/**
|
|
91
|
-
*
|
|
91
|
+
* Parse the assumed user header value.
|
|
92
92
|
*
|
|
93
93
|
* @see {@link AuthHeaderName}
|
|
94
94
|
*/
|
|
95
|
-
|
|
95
|
+
parseAssumedUserHeaderValue: (
|
|
96
96
|
/**
|
|
97
97
|
* The assumed user header value.
|
|
98
98
|
*
|
|
@@ -107,13 +107,12 @@ export type BackendAuthClientConfig<
|
|
|
107
107
|
| undefined
|
|
108
108
|
>;
|
|
109
109
|
/**
|
|
110
|
-
* Return `true` to allow the current user
|
|
111
|
-
*
|
|
112
|
-
* admin users.
|
|
110
|
+
* Return `true` to allow the current/original user to assume identities of other users.
|
|
111
|
+
* Return `false` to block it. It is recommended to only return `true` for admin users.
|
|
113
112
|
*
|
|
114
113
|
* @see {@link AuthHeaderName}
|
|
115
114
|
*/
|
|
116
|
-
canAssumeUser: (
|
|
115
|
+
canAssumeUser: (originalUser: DatabaseUser) => MaybePromise<boolean>;
|
|
117
116
|
};
|
|
118
117
|
/**
|
|
119
118
|
* This determines how long a cookie will be valid until it needs to be refreshed.
|
|
@@ -188,10 +187,10 @@ export class BackendAuthClient<
|
|
|
188
187
|
protected async getDatabaseUser({
|
|
189
188
|
isSignUpCookie,
|
|
190
189
|
userId,
|
|
191
|
-
|
|
190
|
+
assumingUser,
|
|
192
191
|
}: {
|
|
193
192
|
userId: UserId | undefined;
|
|
194
|
-
|
|
193
|
+
assumingUser: AssumedUserParams | undefined;
|
|
195
194
|
isSignUpCookie: boolean;
|
|
196
195
|
}): Promise<undefined | DatabaseUser> {
|
|
197
196
|
if (!userId) {
|
|
@@ -199,7 +198,7 @@ export class BackendAuthClient<
|
|
|
199
198
|
}
|
|
200
199
|
|
|
201
200
|
const authenticatedUser = await this.config.getUserFromDatabase({
|
|
202
|
-
|
|
201
|
+
assumingUser,
|
|
203
202
|
userId,
|
|
204
203
|
isSignUpCookie,
|
|
205
204
|
});
|
|
@@ -268,18 +267,12 @@ export class BackendAuthClient<
|
|
|
268
267
|
/** Reads the user's assumed user headers and, if configured, gets the assumed user. */
|
|
269
268
|
protected async getAssumedUser({
|
|
270
269
|
headers,
|
|
271
|
-
|
|
270
|
+
user,
|
|
272
271
|
}: {
|
|
273
|
-
|
|
272
|
+
user: DatabaseUser;
|
|
274
273
|
headers: IncomingHttpHeaders;
|
|
275
274
|
}): Promise<DatabaseUser | undefined> {
|
|
276
|
-
if (
|
|
277
|
-
!originalUserId ||
|
|
278
|
-
!this.config.assumeUser ||
|
|
279
|
-
!(await this.config.assumeUser.canAssumeUser({
|
|
280
|
-
userId: originalUserId,
|
|
281
|
-
}))
|
|
282
|
-
) {
|
|
275
|
+
if (!this.config.assumeUser || !(await this.config.assumeUser.canAssumeUser(user))) {
|
|
283
276
|
return undefined;
|
|
284
277
|
}
|
|
285
278
|
|
|
@@ -292,7 +285,7 @@ export class BackendAuthClient<
|
|
|
292
285
|
}
|
|
293
286
|
|
|
294
287
|
const parsedAssumedUserData =
|
|
295
|
-
await this.config.assumeUser.
|
|
288
|
+
await this.config.assumeUser.parseAssumedUserHeaderValue(assumedUserHeader);
|
|
296
289
|
|
|
297
290
|
if (!parsedAssumedUserData || !parsedAssumedUserData.userId) {
|
|
298
291
|
return undefined;
|
|
@@ -301,7 +294,7 @@ export class BackendAuthClient<
|
|
|
301
294
|
const assumedUser = await this.getDatabaseUser({
|
|
302
295
|
isSignUpCookie: false,
|
|
303
296
|
userId: parsedAssumedUserData.userId,
|
|
304
|
-
|
|
297
|
+
assumingUser: parsedAssumedUserData.assumedUserParams,
|
|
305
298
|
});
|
|
306
299
|
|
|
307
300
|
return assumedUser;
|
|
@@ -327,7 +320,7 @@ export class BackendAuthClient<
|
|
|
327
320
|
|
|
328
321
|
const user = await this.getDatabaseUser({
|
|
329
322
|
userId: userIdResult.userId,
|
|
330
|
-
|
|
323
|
+
assumingUser: undefined,
|
|
331
324
|
isSignUpCookie: !!isSignUpCookie,
|
|
332
325
|
});
|
|
333
326
|
|
|
@@ -337,7 +330,7 @@ export class BackendAuthClient<
|
|
|
337
330
|
|
|
338
331
|
const assumedUser = await this.getAssumedUser({
|
|
339
332
|
headers: requestHeaders,
|
|
340
|
-
|
|
333
|
+
user,
|
|
341
334
|
});
|
|
342
335
|
|
|
343
336
|
const cookieRefreshHeaders =
|
|
@@ -345,19 +338,11 @@ export class BackendAuthClient<
|
|
|
345
338
|
userIdResult,
|
|
346
339
|
})) || {};
|
|
347
340
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
};
|
|
354
|
-
} else {
|
|
355
|
-
return {
|
|
356
|
-
user,
|
|
357
|
-
isAssumed: false,
|
|
358
|
-
responseHeaders: cookieRefreshHeaders,
|
|
359
|
-
};
|
|
360
|
-
}
|
|
341
|
+
return {
|
|
342
|
+
user: assumedUser || user,
|
|
343
|
+
isAssumed: !!assumedUser,
|
|
344
|
+
responseHeaders: cookieRefreshHeaders,
|
|
345
|
+
};
|
|
361
346
|
}
|
|
362
347
|
|
|
363
348
|
/**
|
|
@@ -481,7 +466,7 @@ export class BackendAuthClient<
|
|
|
481
466
|
const user = await this.getDatabaseUser({
|
|
482
467
|
isSignUpCookie: false,
|
|
483
468
|
userId: userIdResult.userId,
|
|
484
|
-
|
|
469
|
+
assumingUser: undefined,
|
|
485
470
|
});
|
|
486
471
|
|
|
487
472
|
if (!user) {
|
|
@@ -60,16 +60,28 @@ export class FrontendAuthClient<AssumedUserParams extends JsonCompatibleObject =
|
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
/**
|
|
64
|
-
|
|
63
|
+
/**
|
|
64
|
+
* Assume the given user. Pass `undefined` to wipe the currently assumed user.
|
|
65
|
+
*
|
|
66
|
+
* @returns Whether the assumed user setting or clearing succeeded or not.
|
|
67
|
+
*/
|
|
68
|
+
public async assumeUser(
|
|
69
|
+
assumedUserParams: Readonly<AssumedUserParams> | undefined,
|
|
70
|
+
): Promise<boolean> {
|
|
71
|
+
const localStorage = this.config.overrides?.localStorage || globalThis.localStorage;
|
|
72
|
+
const storageKey =
|
|
73
|
+
this.config.overrides?.assumedUserHeaderName || AuthHeaderName.AssumedUser;
|
|
74
|
+
|
|
75
|
+
if (!assumedUserParams) {
|
|
76
|
+
localStorage.removeItem(storageKey);
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
|
|
65
80
|
if (!(await this.config.canAssumeUser?.())) {
|
|
66
81
|
return false;
|
|
67
82
|
}
|
|
68
83
|
|
|
69
|
-
(
|
|
70
|
-
this.config.overrides?.assumedUserHeaderName || AuthHeaderName.AssumedUser,
|
|
71
|
-
JSON.stringify(assumedUserParams),
|
|
72
|
-
);
|
|
84
|
+
localStorage.setItem(storageKey, JSON.stringify(assumedUserParams));
|
|
73
85
|
|
|
74
86
|
return true;
|
|
75
87
|
}
|