auth-vir 2.0.1 → 2.0.3

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.
@@ -31,7 +31,7 @@ export type GetUserResult<DatabaseUser extends AnyObject> = {
31
31
  *
32
32
  * @category Internal
33
33
  */
34
- export type BackendAuthClientConfig<DatabaseUser extends AnyObject, UserId extends string | number, CsrfHeaderName extends string = AuthHeaderName.CsrfToken, AssumedUserParams extends JsonCompatibleObject = EmptyObject> = Readonly<{
34
+ export type BackendAuthClientConfig<DatabaseUser extends AnyObject, UserId extends string | number, AssumedUserParams extends JsonCompatibleObject = EmptyObject, CsrfHeaderName extends string = AuthHeaderName.CsrfToken> = Readonly<{
35
35
  /** The origin of your backend that is offering auth cookies. */
36
36
  serviceOrigin: string;
37
37
  /** Finds the relevant user from your own database. */
@@ -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
- assumedUserParams: AssumedUserParams | undefined;
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
- * Handles assumed user header value.
70
+ * Parse the assumed user header value.
71
71
  *
72
72
  * @see {@link AuthHeaderName}
73
73
  */
74
- handleAssumedUserData: (
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 (by the given id) to assume identities of
86
- * other users. Return `false` to block it. It is recommended to only return `true` for
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: (params: {
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.
@@ -117,10 +114,10 @@ export type BackendAuthClientConfig<DatabaseUser extends AnyObject, UserId exten
117
114
  * @category Auth : Host
118
115
  * @category Client
119
116
  */
120
- export declare class BackendAuthClient<DatabaseUser extends AnyObject, UserId extends string | number, CsrfHeaderName extends string = AuthHeaderName.CsrfToken, AssumedUserParams extends AnyObject = EmptyObject> {
121
- protected readonly config: BackendAuthClientConfig<DatabaseUser, UserId, CsrfHeaderName, AssumedUserParams>;
117
+ export declare class BackendAuthClient<DatabaseUser extends AnyObject, UserId extends string | number, AssumedUserParams extends AnyObject = EmptyObject, CsrfHeaderName extends string = AuthHeaderName.CsrfToken> {
118
+ protected readonly config: BackendAuthClientConfig<DatabaseUser, UserId, AssumedUserParams, CsrfHeaderName>;
122
119
  protected cachedParsedJwtKeys: Record<string, Readonly<JwtKeys>>;
123
- constructor(config: BackendAuthClientConfig<DatabaseUser, UserId, CsrfHeaderName, AssumedUserParams>);
120
+ constructor(config: BackendAuthClientConfig<DatabaseUser, UserId, AssumedUserParams, CsrfHeaderName>);
124
121
  /** Get all the parameters used for cookie generation. */
125
122
  protected getCookieParams({ isSignUpCookie, }: {
126
123
  /**
@@ -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, assumedUserParams, }: {
132
+ protected getDatabaseUser({ isSignUpCookie, userId, assumingUser, }: {
136
133
  userId: UserId | undefined;
137
- assumedUserParams: AssumedUserParams | undefined;
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, originalUserId, }: {
146
- originalUserId: UserId | undefined;
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, assumedUserParams, }) {
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
- assumedUserParams,
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, originalUserId, }) {
93
- if (!originalUserId ||
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.handleAssumedUserData(assumedUserHeader);
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
- assumedUserParams: parsedAssumedUserData.assumedUserParams,
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
- assumedUserParams: undefined,
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
- originalUserId: userIdResult.userId,
127
+ user,
132
128
  });
133
129
  const cookieRefreshHeaders = (await this.createCookieRefreshHeaders({
134
130
  userIdResult,
135
131
  })) || {};
136
- if (assumedUser) {
137
- return {
138
- user: assumedUser,
139
- isAssumed: true,
140
- responseHeaders: cookieRefreshHeaders,
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
- assumedUserParams: undefined,
206
+ assumingUser: undefined,
220
207
  });
221
208
  if (!user) {
222
209
  return undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "auth-vir",
3
- "version": "2.0.1",
3
+ "version": "2.0.3",
4
4
  "description": "Auth made easy and secure via JWT cookies, CSRF tokens, and password hashing helpers.",
5
5
  "keywords": [
6
6
  "auth",
@@ -49,8 +49,8 @@ export type GetUserResult<DatabaseUser extends AnyObject> = {
49
49
  export type BackendAuthClientConfig<
50
50
  DatabaseUser extends AnyObject,
51
51
  UserId extends string | number,
52
- CsrfHeaderName extends string = AuthHeaderName.CsrfToken,
53
52
  AssumedUserParams extends JsonCompatibleObject = EmptyObject,
53
+ CsrfHeaderName extends string = AuthHeaderName.CsrfToken,
54
54
  > = Readonly<
55
55
  {
56
56
  /** The origin of your backend that is offering auth cookies. */
@@ -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
- assumedUserParams: AssumedUserParams | undefined;
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
- * Handles assumed user header value.
91
+ * Parse the assumed user header value.
92
92
  *
93
93
  * @see {@link AuthHeaderName}
94
94
  */
95
- handleAssumedUserData: (
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 (by the given id) to assume identities of
111
- * other users. Return `false` to block it. It is recommended to only return `true` for
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: (params: {userId: UserId}) => MaybePromise<boolean>;
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.
@@ -149,8 +148,8 @@ const defaultSessionIdleTimeout: Readonly<AnyDuration> = {
149
148
  export class BackendAuthClient<
150
149
  DatabaseUser extends AnyObject,
151
150
  UserId extends string | number,
152
- CsrfHeaderName extends string = AuthHeaderName.CsrfToken,
153
151
  AssumedUserParams extends AnyObject = EmptyObject,
152
+ CsrfHeaderName extends string = AuthHeaderName.CsrfToken,
154
153
  > {
155
154
  protected cachedParsedJwtKeys: Record<string, Readonly<JwtKeys>> = {};
156
155
 
@@ -158,8 +157,8 @@ export class BackendAuthClient<
158
157
  protected readonly config: BackendAuthClientConfig<
159
158
  DatabaseUser,
160
159
  UserId,
161
- CsrfHeaderName,
162
- AssumedUserParams
160
+ AssumedUserParams,
161
+ CsrfHeaderName
163
162
  >,
164
163
  ) {}
165
164
 
@@ -188,10 +187,10 @@ export class BackendAuthClient<
188
187
  protected async getDatabaseUser({
189
188
  isSignUpCookie,
190
189
  userId,
191
- assumedUserParams,
190
+ assumingUser,
192
191
  }: {
193
192
  userId: UserId | undefined;
194
- assumedUserParams: AssumedUserParams | undefined;
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
- assumedUserParams,
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
- originalUserId,
270
+ user,
272
271
  }: {
273
- originalUserId: UserId | undefined;
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.handleAssumedUserData(assumedUserHeader);
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
- assumedUserParams: parsedAssumedUserData.assumedUserParams,
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
- assumedUserParams: undefined,
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
- originalUserId: userIdResult.userId,
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
- if (assumedUser) {
349
- return {
350
- user: assumedUser,
351
- isAssumed: true,
352
- responseHeaders: cookieRefreshHeaders,
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
- assumedUserParams: undefined,
469
+ assumingUser: undefined,
485
470
  });
486
471
 
487
472
  if (!user) {