auth-vir 2.4.1 → 2.5.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.
|
@@ -58,6 +58,13 @@ export type BackendAuthClientConfig<DatabaseUser extends AnyObject, UserId exten
|
|
|
58
58
|
*/
|
|
59
59
|
isDev: boolean;
|
|
60
60
|
} & PartialWithUndefined<{
|
|
61
|
+
/**
|
|
62
|
+
* Optionally generate a service origin from request headers. The generated origin is used
|
|
63
|
+
* for set-cookie headers.
|
|
64
|
+
*/
|
|
65
|
+
generateServiceOrigin(params: {
|
|
66
|
+
requestHeaders: Readonly<IncomingHttpHeaders>;
|
|
67
|
+
}): MaybePromise<undefined | string>;
|
|
61
68
|
/**
|
|
62
69
|
* Set this to allow specific users (determined by `canAssumeUser`) to assume the identity
|
|
63
70
|
* of other users. This should only be used for admins so that they can troubleshoot user
|
|
@@ -119,7 +126,7 @@ export declare class BackendAuthClient<DatabaseUser extends AnyObject, UserId ex
|
|
|
119
126
|
protected cachedParsedJwtKeys: Record<string, Readonly<JwtKeys>>;
|
|
120
127
|
constructor(config: BackendAuthClientConfig<DatabaseUser, UserId, AssumedUserParams, CsrfHeaderName>);
|
|
121
128
|
/** Get all the parameters used for cookie generation. */
|
|
122
|
-
protected getCookieParams({ isSignUpCookie,
|
|
129
|
+
protected getCookieParams({ isSignUpCookie, requestHeaders, }: {
|
|
123
130
|
/**
|
|
124
131
|
* Set this to `true` when we are setting the initial cookie right after a user signs up.
|
|
125
132
|
* This allows them to auto-authorize when they verify their email address.
|
|
@@ -127,8 +134,7 @@ export declare class BackendAuthClient<DatabaseUser extends AnyObject, UserId ex
|
|
|
127
134
|
* This should only be set to `true` when a new user is signing up.
|
|
128
135
|
*/
|
|
129
136
|
isSignUpCookie: boolean;
|
|
130
|
-
|
|
131
|
-
serviceOrigin: string | undefined;
|
|
137
|
+
requestHeaders: Readonly<IncomingHttpHeaders> | undefined;
|
|
132
138
|
}): Promise<Readonly<CookieParams>>;
|
|
133
139
|
/** Calls the provided `getUserFromDatabase` config. */
|
|
134
140
|
protected getDatabaseUser({ isSignUpCookie, userId, assumingUser, }: {
|
|
@@ -137,8 +143,9 @@ export declare class BackendAuthClient<DatabaseUser extends AnyObject, UserId ex
|
|
|
137
143
|
isSignUpCookie: boolean;
|
|
138
144
|
}): Promise<undefined | DatabaseUser>;
|
|
139
145
|
/** Creates a `'cookie-set'` header to refresh the user's session cookie. */
|
|
140
|
-
protected createCookieRefreshHeaders({ userIdResult, }: {
|
|
146
|
+
protected createCookieRefreshHeaders({ userIdResult, requestHeaders, }: {
|
|
141
147
|
userIdResult: Readonly<UserIdResult<UserId>>;
|
|
148
|
+
requestHeaders: IncomingHttpHeaders;
|
|
142
149
|
}): Promise<OutgoingHttpHeaders | undefined>;
|
|
143
150
|
/** Reads the user's assumed user headers and, if configured, gets the assumed user. */
|
|
144
151
|
protected getAssumedUser({ headers, user, }: {
|
|
@@ -172,12 +179,10 @@ export declare class BackendAuthClient<DatabaseUser extends AnyObject, UserId ex
|
|
|
172
179
|
'set-cookie': string[];
|
|
173
180
|
}>;
|
|
174
181
|
/** Use these headers to log a user in. */
|
|
175
|
-
createLoginHeaders({ userId, requestHeaders, isSignUpCookie,
|
|
182
|
+
createLoginHeaders({ userId, requestHeaders, isSignUpCookie, }: {
|
|
176
183
|
userId: UserId;
|
|
177
184
|
requestHeaders: IncomingHttpHeaders;
|
|
178
185
|
isSignUpCookie: boolean;
|
|
179
|
-
/** Overrides the client's already established `serviceOrigin`. */
|
|
180
|
-
serviceOrigin?: string | undefined;
|
|
181
186
|
}): Promise<OutgoingHttpHeaders>;
|
|
182
187
|
/** Combines `.getInsecureUser()` and `.getSecureUser()` into one method. */
|
|
183
188
|
getInsecureOrSecureUser(params: {
|
|
@@ -189,6 +194,8 @@ export declare class BackendAuthClient<DatabaseUser extends AnyObject, UserId ex
|
|
|
189
194
|
* with the frontend auth client's `checkUser.performCheck` callback.
|
|
190
195
|
*/
|
|
191
196
|
allowUserAuthRefresh: boolean;
|
|
197
|
+
/** Overrides the client's already established `serviceOrigin`. */
|
|
198
|
+
serviceOrigin?: string | undefined;
|
|
192
199
|
}): Promise<RequireOneOrNone<{
|
|
193
200
|
secureUser: GetUserResult<DatabaseUser>;
|
|
194
201
|
/**
|
|
@@ -24,7 +24,10 @@ export class BackendAuthClient {
|
|
|
24
24
|
this.config = config;
|
|
25
25
|
}
|
|
26
26
|
/** Get all the parameters used for cookie generation. */
|
|
27
|
-
async getCookieParams({ isSignUpCookie,
|
|
27
|
+
async getCookieParams({ isSignUpCookie, requestHeaders, }) {
|
|
28
|
+
const serviceOrigin = requestHeaders
|
|
29
|
+
? await this.config.generateServiceOrigin?.({ requestHeaders })
|
|
30
|
+
: undefined;
|
|
28
31
|
return {
|
|
29
32
|
cookieDuration: this.config.userSessionIdleTimeout || defaultSessionIdleTimeout,
|
|
30
33
|
hostOrigin: serviceOrigin || this.config.serviceOrigin,
|
|
@@ -49,7 +52,7 @@ export class BackendAuthClient {
|
|
|
49
52
|
return authenticatedUser;
|
|
50
53
|
}
|
|
51
54
|
/** Creates a `'cookie-set'` header to refresh the user's session cookie. */
|
|
52
|
-
async createCookieRefreshHeaders({ userIdResult, }) {
|
|
55
|
+
async createCookieRefreshHeaders({ userIdResult, requestHeaders, }) {
|
|
53
56
|
const now = getNowInUtcTimezone();
|
|
54
57
|
/** Double check that the JWT hasn't already expired. */
|
|
55
58
|
const isExpiredAlready = isDateAfter({
|
|
@@ -80,7 +83,7 @@ export class BackendAuthClient {
|
|
|
80
83
|
});
|
|
81
84
|
if (isRefreshReady) {
|
|
82
85
|
return this.createLoginHeaders({
|
|
83
|
-
requestHeaders
|
|
86
|
+
requestHeaders,
|
|
84
87
|
userId: userIdResult.userId,
|
|
85
88
|
isSignUpCookie: userIdResult.cookieName === AuthCookieName.SignUp,
|
|
86
89
|
});
|
|
@@ -129,6 +132,7 @@ export class BackendAuthClient {
|
|
|
129
132
|
});
|
|
130
133
|
const cookieRefreshHeaders = (await this.createCookieRefreshHeaders({
|
|
131
134
|
userIdResult,
|
|
135
|
+
requestHeaders,
|
|
132
136
|
})) || {};
|
|
133
137
|
return {
|
|
134
138
|
user: assumedUser || user,
|
|
@@ -160,13 +164,13 @@ export class BackendAuthClient {
|
|
|
160
164
|
const signUpCookieHeaders = params.allCookies || params.isSignUpCookie
|
|
161
165
|
? generateLogoutHeaders(await this.getCookieParams({
|
|
162
166
|
isSignUpCookie: true,
|
|
163
|
-
|
|
167
|
+
requestHeaders: undefined,
|
|
164
168
|
}), this.config.overrides)
|
|
165
169
|
: undefined;
|
|
166
170
|
const authCookieHeaders = params.allCookies || !params.isSignUpCookie
|
|
167
171
|
? generateLogoutHeaders(await this.getCookieParams({
|
|
168
172
|
isSignUpCookie: false,
|
|
169
|
-
|
|
173
|
+
requestHeaders: undefined,
|
|
170
174
|
}), this.config.overrides)
|
|
171
175
|
: undefined;
|
|
172
176
|
const setCookieHeader = {
|
|
@@ -182,18 +186,18 @@ export class BackendAuthClient {
|
|
|
182
186
|
};
|
|
183
187
|
}
|
|
184
188
|
/** Use these headers to log a user in. */
|
|
185
|
-
async createLoginHeaders({ userId, requestHeaders, isSignUpCookie,
|
|
189
|
+
async createLoginHeaders({ userId, requestHeaders, isSignUpCookie, }) {
|
|
186
190
|
const oppositeCookieName = isSignUpCookie ? AuthCookieName.Auth : AuthCookieName.SignUp;
|
|
187
191
|
const hasExistingOppositeCookie = requestHeaders.cookie?.includes(`${oppositeCookieName}=`);
|
|
188
192
|
const discardOppositeCookieHeaders = hasExistingOppositeCookie
|
|
189
193
|
? generateLogoutHeaders(await this.getCookieParams({
|
|
190
194
|
isSignUpCookie: !isSignUpCookie,
|
|
191
|
-
|
|
195
|
+
requestHeaders,
|
|
192
196
|
}), this.config.overrides)
|
|
193
197
|
: undefined;
|
|
194
198
|
const newCookieHeaders = await generateSuccessfulLoginHeaders(userId, await this.getCookieParams({
|
|
195
199
|
isSignUpCookie,
|
|
196
|
-
|
|
200
|
+
requestHeaders,
|
|
197
201
|
}), this.config.overrides);
|
|
198
202
|
return {
|
|
199
203
|
...newCookieHeaders,
|
|
@@ -237,6 +241,7 @@ export class BackendAuthClient {
|
|
|
237
241
|
const refreshHeaders = allowUserAuthRefresh &&
|
|
238
242
|
(await this.createCookieRefreshHeaders({
|
|
239
243
|
userIdResult,
|
|
244
|
+
requestHeaders,
|
|
240
245
|
}));
|
|
241
246
|
return {
|
|
242
247
|
user,
|
package/package.json
CHANGED
|
@@ -78,6 +78,13 @@ export type BackendAuthClientConfig<
|
|
|
78
78
|
*/
|
|
79
79
|
isDev: boolean;
|
|
80
80
|
} & PartialWithUndefined<{
|
|
81
|
+
/**
|
|
82
|
+
* Optionally generate a service origin from request headers. The generated origin is used
|
|
83
|
+
* for set-cookie headers.
|
|
84
|
+
*/
|
|
85
|
+
generateServiceOrigin(params: {
|
|
86
|
+
requestHeaders: Readonly<IncomingHttpHeaders>;
|
|
87
|
+
}): MaybePromise<undefined | string>;
|
|
81
88
|
/**
|
|
82
89
|
* Set this to allow specific users (determined by `canAssumeUser`) to assume the identity
|
|
83
90
|
* of other users. This should only be used for admins so that they can troubleshoot user
|
|
@@ -168,7 +175,7 @@ export class BackendAuthClient<
|
|
|
168
175
|
/** Get all the parameters used for cookie generation. */
|
|
169
176
|
protected async getCookieParams({
|
|
170
177
|
isSignUpCookie,
|
|
171
|
-
|
|
178
|
+
requestHeaders,
|
|
172
179
|
}: {
|
|
173
180
|
/**
|
|
174
181
|
* Set this to `true` when we are setting the initial cookie right after a user signs up.
|
|
@@ -177,9 +184,12 @@ export class BackendAuthClient<
|
|
|
177
184
|
* This should only be set to `true` when a new user is signing up.
|
|
178
185
|
*/
|
|
179
186
|
isSignUpCookie: boolean;
|
|
180
|
-
|
|
181
|
-
serviceOrigin: string | undefined;
|
|
187
|
+
requestHeaders: Readonly<IncomingHttpHeaders> | undefined;
|
|
182
188
|
}): Promise<Readonly<CookieParams>> {
|
|
189
|
+
const serviceOrigin = requestHeaders
|
|
190
|
+
? await this.config.generateServiceOrigin?.({requestHeaders})
|
|
191
|
+
: undefined;
|
|
192
|
+
|
|
183
193
|
return {
|
|
184
194
|
cookieDuration: this.config.userSessionIdleTimeout || defaultSessionIdleTimeout,
|
|
185
195
|
hostOrigin: serviceOrigin || this.config.serviceOrigin,
|
|
@@ -219,8 +229,10 @@ export class BackendAuthClient<
|
|
|
219
229
|
/** Creates a `'cookie-set'` header to refresh the user's session cookie. */
|
|
220
230
|
protected async createCookieRefreshHeaders({
|
|
221
231
|
userIdResult,
|
|
232
|
+
requestHeaders,
|
|
222
233
|
}: {
|
|
223
234
|
userIdResult: Readonly<UserIdResult<UserId>>;
|
|
235
|
+
requestHeaders: IncomingHttpHeaders;
|
|
224
236
|
}): Promise<OutgoingHttpHeaders | undefined> {
|
|
225
237
|
const now = getNowInUtcTimezone();
|
|
226
238
|
|
|
@@ -259,7 +271,7 @@ export class BackendAuthClient<
|
|
|
259
271
|
|
|
260
272
|
if (isRefreshReady) {
|
|
261
273
|
return this.createLoginHeaders({
|
|
262
|
-
requestHeaders
|
|
274
|
+
requestHeaders,
|
|
263
275
|
userId: userIdResult.userId,
|
|
264
276
|
isSignUpCookie: userIdResult.cookieName === AuthCookieName.SignUp,
|
|
265
277
|
});
|
|
@@ -347,6 +359,7 @@ export class BackendAuthClient<
|
|
|
347
359
|
const cookieRefreshHeaders =
|
|
348
360
|
(await this.createCookieRefreshHeaders({
|
|
349
361
|
userIdResult,
|
|
362
|
+
requestHeaders,
|
|
350
363
|
})) || {};
|
|
351
364
|
|
|
352
365
|
return {
|
|
@@ -400,7 +413,7 @@ export class BackendAuthClient<
|
|
|
400
413
|
? (generateLogoutHeaders(
|
|
401
414
|
await this.getCookieParams({
|
|
402
415
|
isSignUpCookie: true,
|
|
403
|
-
|
|
416
|
+
requestHeaders: undefined,
|
|
404
417
|
}),
|
|
405
418
|
this.config.overrides,
|
|
406
419
|
) satisfies Record<CsrfHeaderName, string>)
|
|
@@ -410,7 +423,7 @@ export class BackendAuthClient<
|
|
|
410
423
|
? (generateLogoutHeaders(
|
|
411
424
|
await this.getCookieParams({
|
|
412
425
|
isSignUpCookie: false,
|
|
413
|
-
|
|
426
|
+
requestHeaders: undefined,
|
|
414
427
|
}),
|
|
415
428
|
this.config.overrides,
|
|
416
429
|
) satisfies Record<CsrfHeaderName, string>)
|
|
@@ -440,13 +453,10 @@ export class BackendAuthClient<
|
|
|
440
453
|
userId,
|
|
441
454
|
requestHeaders,
|
|
442
455
|
isSignUpCookie,
|
|
443
|
-
serviceOrigin,
|
|
444
456
|
}: {
|
|
445
457
|
userId: UserId;
|
|
446
458
|
requestHeaders: IncomingHttpHeaders;
|
|
447
459
|
isSignUpCookie: boolean;
|
|
448
|
-
/** Overrides the client's already established `serviceOrigin`. */
|
|
449
|
-
serviceOrigin?: string | undefined;
|
|
450
460
|
}): Promise<OutgoingHttpHeaders> {
|
|
451
461
|
const oppositeCookieName = isSignUpCookie ? AuthCookieName.Auth : AuthCookieName.SignUp;
|
|
452
462
|
const hasExistingOppositeCookie = requestHeaders.cookie?.includes(`${oppositeCookieName}=`);
|
|
@@ -455,7 +465,7 @@ export class BackendAuthClient<
|
|
|
455
465
|
? generateLogoutHeaders(
|
|
456
466
|
await this.getCookieParams({
|
|
457
467
|
isSignUpCookie: !isSignUpCookie,
|
|
458
|
-
|
|
468
|
+
requestHeaders,
|
|
459
469
|
}),
|
|
460
470
|
this.config.overrides,
|
|
461
471
|
)
|
|
@@ -465,7 +475,7 @@ export class BackendAuthClient<
|
|
|
465
475
|
userId,
|
|
466
476
|
await this.getCookieParams({
|
|
467
477
|
isSignUpCookie,
|
|
468
|
-
|
|
478
|
+
requestHeaders,
|
|
469
479
|
}),
|
|
470
480
|
this.config.overrides,
|
|
471
481
|
);
|
|
@@ -494,6 +504,8 @@ export class BackendAuthClient<
|
|
|
494
504
|
* with the frontend auth client's `checkUser.performCheck` callback.
|
|
495
505
|
*/
|
|
496
506
|
allowUserAuthRefresh: boolean;
|
|
507
|
+
/** Overrides the client's already established `serviceOrigin`. */
|
|
508
|
+
serviceOrigin?: string | undefined;
|
|
497
509
|
}): Promise<
|
|
498
510
|
RequireOneOrNone<{
|
|
499
511
|
secureUser: GetUserResult<DatabaseUser>;
|
|
@@ -560,6 +572,7 @@ export class BackendAuthClient<
|
|
|
560
572
|
allowUserAuthRefresh &&
|
|
561
573
|
(await this.createCookieRefreshHeaders({
|
|
562
574
|
userIdResult,
|
|
575
|
+
requestHeaders,
|
|
563
576
|
}));
|
|
564
577
|
|
|
565
578
|
return {
|