@cedarjs/auth-dbauth-api 7.0.0-canary.3073 → 7.0.0-canary.3075

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.
@@ -1,6 +1,7 @@
1
1
  import type { AuthenticationResponseJSON, RegistrationResponseJSON } from '@simplewebauthn/server';
2
2
  import type { APIGatewayProxyEvent, Context as LambdaContext } from 'aws-lambda';
3
3
  import type { CorsConfig, CorsContext, PartialRequest } from '@cedarjs/api';
4
+ import type { DbAuthCookieConfig } from './session.js';
4
5
  interface SignupFlowOptions<TUserAttributes = Record<string, unknown>> {
5
6
  /**
6
7
  * Allow users to sign up. Defaults to true.
@@ -170,33 +171,7 @@ export interface DbAuthHandlerOptions<TUser = UserType, TUserAttributes = Record
170
171
  /**
171
172
  * Object containing cookie config options
172
173
  */
173
- cookie?: {
174
- /** @deprecated set this option in `cookie.attributes` */
175
- Path?: string;
176
- /** @deprecated set this option in `cookie.attributes` */
177
- HttpOnly?: boolean;
178
- /** @deprecated set this option in `cookie.attributes` */
179
- Secure?: boolean;
180
- /** @deprecated set this option in `cookie.attributes` */
181
- SameSite?: string;
182
- /** @deprecated set this option in `cookie.attributes` */
183
- Domain?: string;
184
- attributes?: {
185
- Path?: string;
186
- HttpOnly?: boolean;
187
- Secure?: boolean;
188
- SameSite?: string;
189
- Domain?: string;
190
- };
191
- /**
192
- * The name of the cookie that dbAuth sets
193
- *
194
- * %port% will be replaced with the port the api server is running on.
195
- * If you have multiple RW apps running on the same host, you'll need to
196
- * make sure they all use unique cookie names
197
- */
198
- name?: string;
199
- };
174
+ cookie?: DbAuthCookieConfig;
200
175
  /**
201
176
  * Object containing forgot password options
202
177
  */
@@ -231,6 +206,17 @@ export interface DbAuthHandlerOptions<TUser = UserType, TUserAttributes = Record
231
206
  * CORS settings, same as in createGraphqlHandler
232
207
  */
233
208
  cors?: CorsConfig;
209
+ /**
210
+ * Extra origins that are trusted for state-changing (non-GET) requests,
211
+ * on top of the request's own host and any origins already listed in
212
+ * `cors.origin`.
213
+ *
214
+ * Needed when the web side and API are on different origins and
215
+ * `cors.origin` isn't set to those origins, or when `cors.origin` is set
216
+ * to `true` -- reflecting any request origin is never treated as trust,
217
+ * so that combination requires listing trusted origins here explicitly.
218
+ */
219
+ trustedOrigins?: string | string[];
234
220
  }
235
221
  export interface SignupHandlerOptions<TUserAttributes> {
236
222
  username: string;
@@ -312,6 +298,8 @@ export declare class DbAuthHandler<TUser extends UserType, TUserAttributes = Rec
312
298
  body?: string | undefined;
313
299
  statusCode: number;
314
300
  }>;
301
+ _requestHost(): string | null;
302
+ _requestProtocol(): string | null;
315
303
  forgotPassword(): Promise<AuthMethodOutput>;
316
304
  getToken(): Promise<AuthMethodOutput>;
317
305
  login(): Promise<AuthMethodOutput>;
@@ -326,15 +314,14 @@ export declare class DbAuthHandler<TUser extends UserType, TUserAttributes = Rec
326
314
  _validateOptions(): void;
327
315
  _saveChallenge(userId: string | number, value: string | null): Promise<void>;
328
316
  _webAuthnCookie(id: string, expires: string): string;
329
- _sanitizeUser(user: Record<string, unknown>): any;
317
+ _sanitizeUser(user: Record<string, unknown>): Record<string, unknown>;
330
318
  _decodeEvent(): void;
331
319
  _cookieAttributes({ expires, options, }: {
332
320
  expires?: 'now' | string;
333
321
  options?: DbAuthHandlerOptions['cookie'];
334
- }): (string | null)[];
322
+ }): string[];
335
323
  _createAuthProviderCookieString(): string;
336
324
  _createSessionCookieString<TIdType = any>(data: DbAuthSession<TIdType>, csrfToken: string): string;
337
- _validateCsrf(): Promise<boolean>;
338
325
  _findUserByToken(token: string): Promise<any>;
339
326
  _clearResetToken(user: Record<string, unknown>): Promise<void>;
340
327
  _verifyUser(username: string | undefined, password: string | undefined): Promise<any>;
@@ -343,9 +330,7 @@ export declare class DbAuthHandler<TUser extends UserType, TUserAttributes = Rec
343
330
  _createUser(): Promise<any>;
344
331
  _getAuthMethod(): Promise<AuthMethodNames>;
345
332
  _validateField(name: string, value: string | undefined): value is string;
346
- _loginResponse(user: Record<string, any>, statusCode?: number): [{
347
- id: string;
348
- }, Headers, {
333
+ _loginResponse(user: Record<string, any>, statusCode?: number): [Record<string, any>, Headers, {
349
334
  statusCode: number;
350
335
  }];
351
336
  _logoutResponse(response?: Record<string, unknown>): AuthMethodOutput;
@@ -364,6 +349,11 @@ export declare class DbAuthHandler<TUser extends UserType, TUserAttributes = Rec
364
349
  body: string;
365
350
  headers: Headers;
366
351
  };
352
+ _forbidden(message: string): {
353
+ statusCode: number;
354
+ body: string;
355
+ headers: Headers;
356
+ };
367
357
  _getUserMatchCriteriaOptions(username: string, usernameMatchFlowOption: string | undefined): {
368
358
  [x: string]: string;
369
359
  } | {
@@ -1 +1 @@
1
- {"version":3,"file":"DbAuthHandler.d.ts","sourceRoot":"","sources":["../src/DbAuthHandler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DbAuthHandler.d.ts","sourceRoot":"","sources":["../src/DbAuthHandler.ts"],"names":[],"mappings":"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"}
@@ -6,9 +6,25 @@ import {
6
6
  normalizeRequest
7
7
  } from "@cedarjs/api";
8
8
  import * as DbAuthError from "./errors.js";
9
+ import {
10
+ isProxiedRequest,
11
+ isRequestOriginTrusted,
12
+ requiresOriginValidation,
13
+ resolveRequestHost,
14
+ resolveRequestProtocol
15
+ } from "./originValidation.js";
16
+ import {
17
+ buildCookieAttributes,
18
+ createAuthProviderCookieString,
19
+ createCsrfToken,
20
+ createExpiresAtDate,
21
+ createLoginResponse,
22
+ createSessionCookieString,
23
+ DEFAULT_ALLOWED_USER_FIELDS,
24
+ sanitizeUser
25
+ } from "./session.js";
9
26
  import {
10
27
  decryptSession,
11
- encryptSession,
12
28
  extractCookie,
13
29
  extractHashingOptions,
14
30
  generateCookieName,
@@ -20,7 +36,6 @@ import {
20
36
  legacyHashPassword,
21
37
  webAuthnSession
22
38
  } from "./shared.js";
23
- const DEFAULT_ALLOWED_USER_FIELDS = ["id", "email"];
24
39
  class DbAuthHandler {
25
40
  event;
26
41
  _normalizedRequest;
@@ -85,7 +100,7 @@ class DbAuthHandler {
85
100
  }
86
101
  // generate a new token (standard UUID)
87
102
  static get CSRF_TOKEN() {
88
- return uuidv4();
103
+ return createCsrfToken();
89
104
  }
90
105
  static get AVAILABLE_WEBAUTHN_TRANSPORTS() {
91
106
  return ["usb", "ble", "nfc", "internal"];
@@ -128,11 +143,9 @@ class DbAuthHandler {
128
143
  this.dbCredentialAccessor = this.options.credentialModelAccessor ? this.db[this.options.credentialModelAccessor] : null;
129
144
  this.hasInvalidSession = false;
130
145
  this.allowedUserFields = this.options.allowedUserFields || DEFAULT_ALLOWED_USER_FIELDS;
131
- const sessionExpiresAt = /* @__PURE__ */ new Date();
132
- sessionExpiresAt.setSeconds(
133
- sessionExpiresAt.getSeconds() + this.options.login.expires
146
+ this.sessionExpiresDate = createExpiresAtDate(
147
+ this.options.login.expires
134
148
  );
135
- this.sessionExpiresDate = sessionExpiresAt.toUTCString();
136
149
  const webAuthnExpiresAt = /* @__PURE__ */ new Date();
137
150
  webAuthnExpiresAt.setSeconds(
138
151
  webAuthnExpiresAt.getSeconds() + (this.options?.webAuthn?.expires || 0)
@@ -188,11 +201,28 @@ class DbAuthHandler {
188
201
  if (this.httpMethod !== DbAuthHandler.VERBS[method]) {
189
202
  return this.createResponse(this._notFound(), corsHeaders);
190
203
  }
204
+ if (requiresOriginValidation(this.httpMethod) && !isRequestOriginTrusted(
205
+ {
206
+ method: this.httpMethod,
207
+ headers: this.normalizedRequest.headers,
208
+ host: this._requestHost(),
209
+ protocol: this._requestProtocol(),
210
+ proxied: isProxiedRequest(this.normalizedRequest.headers)
211
+ },
212
+ {
213
+ trustedOrigins: this.options.trustedOrigins,
214
+ corsOrigin: this.options.cors?.origin
215
+ }
216
+ )) {
217
+ throw new DbAuthError.UntrustedOriginError();
218
+ }
191
219
  const [body, headers, options = { statusCode: 200 }] = await this[method]();
192
220
  return this.createResponse(this._ok(body, headers, options), corsHeaders);
193
221
  } catch (e) {
194
222
  if (e instanceof DbAuthError.WrongVerbError) {
195
223
  return this.createResponse(this._notFound(), corsHeaders);
224
+ } else if (e instanceof DbAuthError.UntrustedOriginError) {
225
+ return this.createResponse(this._forbidden(e.message), corsHeaders);
196
226
  } else {
197
227
  return this.createResponse(
198
228
  this._badRequest(e.message || e),
@@ -201,6 +231,25 @@ class DbAuthHandler {
201
231
  }
202
232
  }
203
233
  }
234
+ // best-effort host the request was sent to, used by origin validation to
235
+ // allow same-origin requests through with no extra configuration. Prefers
236
+ // `X-Forwarded-Host` over the connection-level host/URL -- see
237
+ // `resolveRequestHost` for why that's safe behind a proxy
238
+ _requestHost() {
239
+ return resolveRequestHost(
240
+ this.normalizedRequest.headers,
241
+ isFetchApiRequest(this.event) ? this.event.url : void 0
242
+ );
243
+ }
244
+ // best-effort scheme the request arrived over, used alongside
245
+ // `_requestHost` for origin validation. See `resolveRequestProtocol` for
246
+ // when it can and can't be determined reliably
247
+ _requestProtocol() {
248
+ return resolveRequestProtocol(
249
+ this.normalizedRequest.headers,
250
+ isFetchApiRequest(this.event) ? this.event.url : void 0
251
+ );
252
+ }
204
253
  async forgotPassword() {
205
254
  const { enabled = true } = this.options.forgotPassword;
206
255
  if (!enabled) {
@@ -626,13 +675,7 @@ class DbAuthHandler {
626
675
  // removes any fields not explicitly allowed to be sent to the client before
627
676
  // sending a response over the wire
628
677
  _sanitizeUser(user) {
629
- const sanitized = JSON.parse(JSON.stringify(user));
630
- Object.keys(sanitized).forEach((key) => {
631
- if (!this.allowedUserFields.includes(key)) {
632
- delete sanitized[key];
633
- }
634
- });
635
- return sanitized;
678
+ return sanitizeUser(user, this.allowedUserFields);
636
679
  }
637
680
  // Converts LambdaEvent or FetchRequest to
638
681
  _decodeEvent() {
@@ -645,49 +688,27 @@ class DbAuthHandler {
645
688
  expires = "now",
646
689
  options = {}
647
690
  }) {
648
- const userCookieAttributes = this.options.cookie?.attributes ? { ...this.options.cookie?.attributes } : { ...this.options.cookie };
649
- if (!this.options.cookie?.attributes) {
650
- delete userCookieAttributes.name;
651
- }
652
- const cookieOptions = { ...userCookieAttributes, ...options };
653
- const meta = Object.keys(cookieOptions).map((key) => {
654
- const optionValue = cookieOptions[key];
655
- if (optionValue === true) {
656
- return key;
657
- } else if (optionValue === false) {
658
- return null;
659
- } else {
660
- return `${key}=${optionValue}`;
661
- }
662
- }).filter((v) => v);
663
- const expiresAt = expires === "now" ? DbAuthHandler.PAST_EXPIRES_DATE : expires;
664
- meta.push(`Expires=${expiresAt}`);
665
- return meta;
691
+ return buildCookieAttributes({
692
+ cookieConfig: this.options.cookie,
693
+ expires,
694
+ overrideAttributes: options
695
+ });
666
696
  }
667
697
  _createAuthProviderCookieString() {
668
- return [
669
- `auth-provider=dbAuth`,
670
- ...this._cookieAttributes({ expires: this.sessionExpiresDate })
671
- ].join(";");
698
+ return createAuthProviderCookieString({
699
+ cookieConfig: this.options.cookie,
700
+ expiresAt: this.sessionExpiresDate
701
+ });
672
702
  }
673
703
  // returns the set-cookie header to be returned in the request (effectively
674
704
  // creates the session)
675
705
  _createSessionCookieString(data, csrfToken) {
676
- const session = JSON.stringify(data) + ";" + csrfToken;
677
- const encrypted = encryptSession(session);
678
- const sessionCookieString = [
679
- `${generateCookieName(this.options.cookie?.name)}=${encrypted}`,
680
- ...this._cookieAttributes({ expires: this.sessionExpiresDate })
681
- ].join(";");
682
- return sessionCookieString;
683
- }
684
- // checks the CSRF token in the header against the CSRF token in the session
685
- // and throw an error if they are not the same (not used yet)
686
- async _validateCsrf() {
687
- if (this.sessionCsrfToken !== this.normalizedRequest.headers.get("csrf-token")) {
688
- throw new DbAuthError.CsrfTokenMismatchError();
689
- }
690
- return true;
706
+ return createSessionCookieString({
707
+ data,
708
+ csrfToken,
709
+ cookieConfig: this.options.cookie,
710
+ expiresAt: this.sessionExpiresDate
711
+ });
691
712
  }
692
713
  async _findUserByToken(token) {
693
714
  const tokenExpires = /* @__PURE__ */ new Date();
@@ -870,16 +891,12 @@ class DbAuthHandler {
870
891
  }
871
892
  }
872
893
  _loginResponse(user, statusCode = 200) {
873
- const sessionData = this._sanitizeUser(user);
874
- const csrfToken = DbAuthHandler.CSRF_TOKEN;
875
- const headers = new Headers();
876
- headers.append("csrf-token", csrfToken);
877
- headers.append("set-cookie", this._createAuthProviderCookieString());
878
- headers.append(
879
- "set-cookie",
880
- this._createSessionCookieString(sessionData, csrfToken)
881
- );
882
- return [sessionData, headers, { statusCode }];
894
+ return createLoginResponse(user, {
895
+ cookie: this.options.cookie,
896
+ allowedUserFields: this.allowedUserFields,
897
+ expiresAt: this.sessionExpiresDate,
898
+ statusCode
899
+ });
883
900
  }
884
901
  _logoutResponse(response) {
885
902
  return [response ? JSON.stringify(response) : "", this._deleteSessionHeader];
@@ -904,6 +921,13 @@ class DbAuthHandler {
904
921
  headers: new Headers({ "content-type": "application/json" })
905
922
  };
906
923
  }
924
+ _forbidden(message) {
925
+ return {
926
+ statusCode: 403,
927
+ body: JSON.stringify({ error: message }),
928
+ headers: new Headers({ "content-type": "application/json" })
929
+ };
930
+ }
907
931
  _getUserMatchCriteriaOptions(username, usernameMatchFlowOption) {
908
932
  const findUniqueUserMatchCriteriaOptions = !usernameMatchFlowOption ? { [this.options.authFields.username]: username } : {
909
933
  [this.options.authFields.username]: {
package/dist/errors.d.ts CHANGED
@@ -49,8 +49,8 @@ export declare class DuplicateUsernameError extends Error {
49
49
  export declare class IncorrectPasswordError extends Error {
50
50
  constructor(username: string, message?: string | undefined);
51
51
  }
52
- export declare class CsrfTokenMismatchError extends Error {
53
- constructor();
52
+ export declare class UntrustedOriginError extends Error {
53
+ constructor(message?: string);
54
54
  }
55
55
  export declare class SessionDecryptionError extends Error {
56
56
  constructor();
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,oBAAqB,SAAQ,KAAK;;CAO9C;AAED,qBAAa,wBAAyB,SAAQ,KAAK;;CAKlD;AAED,qBAAa,mBAAoB,SAAQ,KAAK;;CAK7C;AAED,qBAAa,oBAAqB,SAAQ,KAAK;;CAK9C;AAED,qBAAa,4BAA6B,SAAQ,KAAK;;CAKtD;AAED,qBAAa,2BAA4B,SAAQ,KAAK;;CAKrD;AAED,qBAAa,qBAAsB,SAAQ,KAAK;;CAO/C;AAED,qBAAa,0BAA2B,SAAQ,KAAK;;CAOpD;AAED,qBAAa,sBAAuB,SAAQ,KAAK;gBACnC,IAAI,EAAE,MAAM;CAIzB;AAED,qBAAa,cAAe,SAAQ,KAAK;gBAC3B,UAAU,EAAE,MAAM;CAI/B;AAED,qBAAa,gBAAiB,SAAQ,KAAK;;CAK1C;AAED,qBAAa,iBAAkB,SAAQ,KAAK;gBAExC,QAAQ,GAAE,MAAM,GAAG,SAAqB,EACxC,OAAO,GAAE,MAAM,GAAG,SAA4C;CAUjE;AAED,qBAAa,gCAAiC,SAAQ,KAAK;gBAEvD,OAAO,GAAE,MAAM,GAAG,SAAqD;CAK1E;AAED,qBAAa,aAAc,SAAQ,KAAK;;CAOvC;AAED,qBAAa,kBAAmB,SAAQ,KAAK;gBAEzC,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,MAAM,GAAG,SAAkC;CAKvD;AAED,qBAAa,sBAAuB,SAAQ,KAAK;gBAE7C,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,MAAM,GAAG,SAAmD;CAKxE;AAED,qBAAa,sBAAuB,SAAQ,KAAK;gBAE7C,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,MAAM,GAAG,SAAgD;CAKrE;AAED,qBAAa,sBAAuB,SAAQ,KAAK;;CAKhD;AAED,qBAAa,sBAAuB,SAAQ,KAAK;;CAKhD;AAED,qBAAa,mBAAoB,SAAQ,KAAK;gBAChC,OAAO,SAAwB;CAI5C;AAED,qBAAa,qBAAsB,SAAQ,KAAK;gBAClC,OAAO,SAAyB;CAI7C;AAED,qBAAa,qBAAsB,SAAQ,KAAK;gBAClC,OAAO,SAAyB;CAI7C;AAED,qBAAa,qBAAsB,SAAQ,KAAK;gBAClC,OAAO,SAAuB;CAI3C;AAED,qBAAa,sBAAuB,SAAQ,KAAK;gBACnC,OAAO,SAA0B;CAI9C;AAED,qBAAa,sBAAuB,SAAQ,KAAK;gBACnC,OAAO,SAA0B;CAI9C;AAED,qBAAa,uBAAwB,SAAQ,KAAK;gBACpC,OAAO,SAA2B;CAI/C;AAED,qBAAa,mBAAoB,SAAQ,KAAK;gBAChC,OAAO,SAA+B;CAInD;AAED,qBAAa,uBAAwB,SAAQ,KAAK;gBACpC,OAAO,SAAwB;CAI5C;AAED,qBAAa,YAAa,SAAQ,KAAK;gBACzB,OAAO,SAA2B;CAI/C;AAED,qBAAa,aAAc,SAAQ,KAAK;gBAC1B,OAAO,SAAmB;CAIvC;AAED,qBAAa,sBAAuB,SAAQ,aAAa;gBAErD,OAAO,SAAyD;CAKnE"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,oBAAqB,SAAQ,KAAK;;CAO9C;AAED,qBAAa,wBAAyB,SAAQ,KAAK;;CAKlD;AAED,qBAAa,mBAAoB,SAAQ,KAAK;;CAK7C;AAED,qBAAa,oBAAqB,SAAQ,KAAK;;CAK9C;AAED,qBAAa,4BAA6B,SAAQ,KAAK;;CAKtD;AAED,qBAAa,2BAA4B,SAAQ,KAAK;;CAKrD;AAED,qBAAa,qBAAsB,SAAQ,KAAK;;CAO/C;AAED,qBAAa,0BAA2B,SAAQ,KAAK;;CAOpD;AAED,qBAAa,sBAAuB,SAAQ,KAAK;gBACnC,IAAI,EAAE,MAAM;CAIzB;AAED,qBAAa,cAAe,SAAQ,KAAK;gBAC3B,UAAU,EAAE,MAAM;CAI/B;AAED,qBAAa,gBAAiB,SAAQ,KAAK;;CAK1C;AAED,qBAAa,iBAAkB,SAAQ,KAAK;gBAExC,QAAQ,GAAE,MAAM,GAAG,SAAqB,EACxC,OAAO,GAAE,MAAM,GAAG,SAA4C;CAUjE;AAED,qBAAa,gCAAiC,SAAQ,KAAK;gBAEvD,OAAO,GAAE,MAAM,GAAG,SAAqD;CAK1E;AAED,qBAAa,aAAc,SAAQ,KAAK;;CAOvC;AAED,qBAAa,kBAAmB,SAAQ,KAAK;gBAEzC,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,MAAM,GAAG,SAAkC;CAKvD;AAED,qBAAa,sBAAuB,SAAQ,KAAK;gBAE7C,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,MAAM,GAAG,SAAmD;CAKxE;AAED,qBAAa,sBAAuB,SAAQ,KAAK;gBAE7C,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,MAAM,GAAG,SAAgD;CAKrE;AAED,qBAAa,oBAAqB,SAAQ,KAAK;gBACjC,OAAO,SAAkC;CAItD;AAED,qBAAa,sBAAuB,SAAQ,KAAK;;CAKhD;AAED,qBAAa,mBAAoB,SAAQ,KAAK;gBAChC,OAAO,SAAwB;CAI5C;AAED,qBAAa,qBAAsB,SAAQ,KAAK;gBAClC,OAAO,SAAyB;CAI7C;AAED,qBAAa,qBAAsB,SAAQ,KAAK;gBAClC,OAAO,SAAyB;CAI7C;AAED,qBAAa,qBAAsB,SAAQ,KAAK;gBAClC,OAAO,SAAuB;CAI3C;AAED,qBAAa,sBAAuB,SAAQ,KAAK;gBACnC,OAAO,SAA0B;CAI9C;AAED,qBAAa,sBAAuB,SAAQ,KAAK;gBACnC,OAAO,SAA0B;CAI9C;AAED,qBAAa,uBAAwB,SAAQ,KAAK;gBACpC,OAAO,SAA2B;CAI/C;AAED,qBAAa,mBAAoB,SAAQ,KAAK;gBAChC,OAAO,SAA+B;CAInD;AAED,qBAAa,uBAAwB,SAAQ,KAAK;gBACpC,OAAO,SAAwB;CAI5C;AAED,qBAAa,YAAa,SAAQ,KAAK;gBACzB,OAAO,SAA2B;CAI/C;AAED,qBAAa,aAAc,SAAQ,KAAK;gBAC1B,OAAO,SAAmB;CAIvC;AAED,qBAAa,sBAAuB,SAAQ,aAAa;gBAErD,OAAO,SAAyD;CAKnE"}
package/dist/errors.js CHANGED
@@ -112,10 +112,10 @@ class IncorrectPasswordError extends Error {
112
112
  this.name = "IncorrectPasswordError";
113
113
  }
114
114
  }
115
- class CsrfTokenMismatchError extends Error {
116
- constructor() {
117
- super(`CSRF token mismatch`);
118
- this.name = "CsrfTokenMismatchError";
115
+ class UntrustedOriginError extends Error {
116
+ constructor(message = "Request origin is not trusted") {
117
+ super(message);
118
+ this.name = "UntrustedOriginError";
119
119
  }
120
120
  }
121
121
  class SessionDecryptionError extends Error {
@@ -197,7 +197,6 @@ class NoWebAuthnSessionError extends WebAuthnError {
197
197
  }
198
198
  }
199
199
  export {
200
- CsrfTokenMismatchError,
201
200
  DuplicateUsernameError,
202
201
  FieldRequiredError,
203
202
  FlowNotEnabledError,
@@ -222,6 +221,7 @@ export {
222
221
  ReusedPasswordError,
223
222
  SessionDecryptionError,
224
223
  UnknownAuthMethodError,
224
+ UntrustedOriginError,
225
225
  UserNotFoundError,
226
226
  UsernameAndPasswordRequiredError,
227
227
  UsernameNotFoundError,
package/dist/index.d.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  export * from './DbAuthHandler.js';
2
2
  export { PasswordValidationError } from './errors.js';
3
+ export * from './session.js';
3
4
  export * from './shared.js';
4
5
  export { authDecoder, createAuthDecoder } from './decoder.js';
6
+ export * from './originValidation.js';
5
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAA;AAClC,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AACrD,cAAc,aAAa,CAAA;AAC3B,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAA;AAClC,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AACrD,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAC7D,cAAc,uBAAuB,CAAA"}
package/dist/index.js CHANGED
@@ -1,7 +1,9 @@
1
1
  export * from "./DbAuthHandler.js";
2
2
  import { PasswordValidationError } from "./errors.js";
3
+ export * from "./session.js";
3
4
  export * from "./shared.js";
4
5
  import { authDecoder, createAuthDecoder } from "./decoder.js";
6
+ export * from "./originValidation.js";
5
7
  export {
6
8
  PasswordValidationError,
7
9
  authDecoder,
@@ -0,0 +1,131 @@
1
+ import type { CorsConfig } from '@cedarjs/api';
2
+ /**
3
+ * Minimal, transport-agnostic shape of an incoming request needed to decide
4
+ * whether its `Origin` header should be trusted for a state-changing
5
+ * request. Deliberately decoupled from any specific request/event type (no
6
+ * `DbAuthHandler` coupling) so this helper can be reused by other handler
7
+ * packages.
8
+ */
9
+ export interface OriginValidationRequest {
10
+ /**
11
+ * HTTP method of the request, e.g. `GET`, `POST`. Used by
12
+ * {@link requiresOriginValidation} to decide whether a request needs to be
13
+ * checked at all.
14
+ */
15
+ method: string;
16
+ /**
17
+ * Request headers, including `origin` if the browser sent one.
18
+ */
19
+ headers: Headers;
20
+ /**
21
+ * Host (and port, if non-default) the request was sent to, resolved with
22
+ * {@link resolveRequestHost}. Used to allow same-origin requests through
23
+ * with no extra configuration, which covers the standard Cedar setup
24
+ * where the web side proxies API requests through its own origin. Pass
25
+ * `null` when the host can't be determined.
26
+ */
27
+ host?: string | null;
28
+ /**
29
+ * Scheme (`http`/`https`) the request is considered to have arrived
30
+ * over, resolved with {@link resolveRequestProtocol}, when it can be
31
+ * determined reliably. Used as an extra check alongside `host` when
32
+ * deciding whether the `Origin` header matches the request's own
33
+ * origin. Pass `null`/`undefined` when it can't be determined -- in that
34
+ * case only the host is compared, unless `proxied` narrows that further
35
+ * (see {@link isProxiedRequest}).
36
+ */
37
+ protocol?: string | null;
38
+ /**
39
+ * Whether the request declares itself as arriving through a forwarding
40
+ * proxy, resolved with {@link isProxiedRequest}. Scopes the
41
+ * unknown-scheme same-host restriction to requests a proxy actually
42
+ * touched -- see `isSameOrigin`.
43
+ */
44
+ proxied?: boolean;
45
+ }
46
+ export interface OriginValidationConfig {
47
+ /**
48
+ * Extra origins that are always trusted for state-changing requests, on
49
+ * top of the request's own host and any origins already listed in
50
+ * `cors.origin`.
51
+ */
52
+ trustedOrigins?: string | string[];
53
+ /**
54
+ * The `origin` value from a handler's `cors` config (same shape as passed
55
+ * to `createCorsContext`). String and array values are treated as
56
+ * trusted origins.
57
+ *
58
+ * `true` (reflect any request origin back in
59
+ * `Access-Control-Allow-Origin`) is intentionally NOT treated as trust --
60
+ * combined with `credentials: true` that is the exact misconfiguration
61
+ * this check protects against. Apps that need to accept requests from an
62
+ * arbitrary set of origins must list them explicitly in `trustedOrigins`
63
+ * instead.
64
+ */
65
+ corsOrigin?: CorsConfig['origin'];
66
+ }
67
+ /**
68
+ * HTTP methods that can change server-side state and therefore need their
69
+ * `Origin` validated. `GET` and `HEAD` requests are read-only and are never
70
+ * checked.
71
+ */
72
+ export declare function requiresOriginValidation(method: string): boolean;
73
+ /**
74
+ * Resolves the host a request should be considered as having arrived at,
75
+ * preferring a forwarding proxy's advertised host over the connection-level
76
+ * one.
77
+ *
78
+ * A proxy in front of the api side (this framework's own `cedar serve
79
+ * --ud`, or an external nginx/CDN) terminates the browser's connection and
80
+ * opens a new one to the api server, so the request's own URL/`Host` header
81
+ * reflects that internal hop rather than the origin-facing host the
82
+ * browser actually targeted. `X-Forwarded-Host` carries the origin-facing
83
+ * host instead.
84
+ *
85
+ * Trusting `X-Forwarded-Host` here is safe for CSRF purposes: a cross-site
86
+ * HTML form can't set arbitrary request headers, and a cross-origin
87
+ * `fetch()` that sets a custom header triggers a CORS preflight, so an
88
+ * attacker can't forge it without already having crossed the browser's
89
+ * CORS checks.
90
+ *
91
+ * @param url - The request's own URL (Fetch API requests only), used as a
92
+ * fallback when neither `X-Forwarded-Host` nor `Host` is present.
93
+ */
94
+ export declare function resolveRequestHost(headers: Headers, url?: string | null): string | null;
95
+ /**
96
+ * Resolves the scheme (`http`/`https`) a request should be considered as
97
+ * having arrived over, mirroring {@link resolveRequestHost}.
98
+ *
99
+ * The request's own URL is only used as a fallback when no
100
+ * `X-Forwarded-Host` is present -- once a proxy has declared itself by
101
+ * setting that header, the request's own URL reflects the internal hop to
102
+ * the proxy, and its scheme can't be assumed to match what the browser
103
+ * actually used unless the proxy also set `X-Forwarded-Proto`.
104
+ *
105
+ * @param url - The request's own URL (Fetch API requests only).
106
+ */
107
+ export declare function resolveRequestProtocol(headers: Headers, url?: string | null): string | null;
108
+ /**
109
+ * Whether a request declares itself as arriving through a forwarding
110
+ * proxy, i.e. carries an `X-Forwarded-Host` header.
111
+ *
112
+ * Used to scope the unknown-scheme same-host restriction (see
113
+ * `isSameOrigin`) to requests a proxy actually touched. A request with no
114
+ * forwarding headers at all is a direct connection -- the normal case for
115
+ * dev servers, classic `cedar serve`, and most self-hosts -- not evidence
116
+ * of a proxy.
117
+ */
118
+ export declare function isProxiedRequest(headers: Headers): boolean;
119
+ /**
120
+ * Decides whether a request's `Origin` header should be trusted.
121
+ *
122
+ * Requests with no `Origin` header are always trusted: non-browser clients
123
+ * (server-to-server calls, CLIs, mobile apps) don't send one and don't carry
124
+ * ambient browser cookies, so they aren't CSRF vectors.
125
+ *
126
+ * When an `Origin` header is present, it's trusted when it matches the
127
+ * request's own host, is listed in `trustedOrigins`, or is listed in
128
+ * `corsOrigin`. Everything else is untrusted.
129
+ */
130
+ export declare function isRequestOriginTrusted(request: OriginValidationRequest, config: OriginValidationConfig): boolean;
131
+ //# sourceMappingURL=originValidation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"originValidation.d.ts","sourceRoot":"","sources":["../src/originValidation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAE9C;;;;;;GAMG;AACH,MAAM,WAAW,uBAAuB;IACtC;;;;OAIG;IACH,MAAM,EAAE,MAAM,CAAA;IACd;;OAEG;IACH,OAAO,EAAE,OAAO,CAAA;IAChB;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB;;;;;;;;OAQG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,MAAM,WAAW,sBAAsB;IACrC;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IAClC;;;;;;;;;;;OAWG;IACH,UAAU,CAAC,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAA;CAClC;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAGhE;AAgBD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,OAAO,EAChB,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,GAClB,MAAM,GAAG,IAAI,CAoBf;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,OAAO,EAChB,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,GAClB,MAAM,GAAG,IAAI,CAef;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAE1D;AA+CD;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,uBAAuB,EAChC,MAAM,EAAE,sBAAsB,GAC7B,OAAO,CA6BT"}
@@ -0,0 +1,92 @@
1
+ function requiresOriginValidation(method) {
2
+ const upperMethod = method.toUpperCase();
3
+ return upperMethod !== "GET" && upperMethod !== "HEAD";
4
+ }
5
+ function toOriginList(value) {
6
+ if (!value) {
7
+ return [];
8
+ }
9
+ return Array.isArray(value) ? value : [value];
10
+ }
11
+ function firstForwardedValue(headerValue) {
12
+ return headerValue.split(",")[0].trim();
13
+ }
14
+ function resolveRequestHost(headers, url) {
15
+ const forwardedHost = headers.get("x-forwarded-host");
16
+ if (forwardedHost) {
17
+ return firstForwardedValue(forwardedHost);
18
+ }
19
+ const host = headers.get("host");
20
+ if (host) {
21
+ return host;
22
+ }
23
+ if (url) {
24
+ try {
25
+ return new URL(url).host;
26
+ } catch {
27
+ return null;
28
+ }
29
+ }
30
+ return null;
31
+ }
32
+ function resolveRequestProtocol(headers, url) {
33
+ const forwardedProto = headers.get("x-forwarded-proto");
34
+ if (forwardedProto) {
35
+ return firstForwardedValue(forwardedProto).toLowerCase();
36
+ }
37
+ if (!headers.get("x-forwarded-host") && url) {
38
+ try {
39
+ return new URL(url).protocol.replace(":", "");
40
+ } catch {
41
+ return null;
42
+ }
43
+ }
44
+ return null;
45
+ }
46
+ function isProxiedRequest(headers) {
47
+ return headers.get("x-forwarded-host") !== null;
48
+ }
49
+ function isSameOrigin(origin, host, protocol, proxied) {
50
+ try {
51
+ const originUrl = new URL(origin);
52
+ if (originUrl.host !== host) {
53
+ return false;
54
+ }
55
+ if (protocol) {
56
+ return originUrl.protocol === `${protocol}:`;
57
+ }
58
+ if (proxied) {
59
+ return originUrl.protocol === "https:";
60
+ }
61
+ return true;
62
+ } catch {
63
+ return false;
64
+ }
65
+ }
66
+ function isRequestOriginTrusted(request, config) {
67
+ const origin = request.headers.get("origin");
68
+ if (!origin) {
69
+ return true;
70
+ }
71
+ if (request.host && isSameOrigin(origin, request.host, request.protocol, request.proxied)) {
72
+ return true;
73
+ }
74
+ const trustedOrigins = toOriginList(config.trustedOrigins);
75
+ if (trustedOrigins.includes(origin)) {
76
+ return true;
77
+ }
78
+ const corsOrigins = toOriginList(
79
+ typeof config.corsOrigin === "string" || Array.isArray(config.corsOrigin) ? config.corsOrigin : void 0
80
+ );
81
+ if (corsOrigins.includes(origin)) {
82
+ return true;
83
+ }
84
+ return false;
85
+ }
86
+ export {
87
+ isProxiedRequest,
88
+ isRequestOriginTrusted,
89
+ requiresOriginValidation,
90
+ resolveRequestHost,
91
+ resolveRequestProtocol
92
+ };
@@ -0,0 +1,114 @@
1
+ /**
2
+ * Cookie attributes that can be set on a dbAuth cookie, either as
3
+ * `cookie.attributes` or (deprecated) directly on `cookie`.
4
+ */
5
+ export interface DbAuthCookieAttributes {
6
+ Path?: string;
7
+ HttpOnly?: boolean;
8
+ Secure?: boolean;
9
+ SameSite?: string;
10
+ Domain?: string;
11
+ }
12
+ /**
13
+ * Configuration for the cookies dbAuth sets: the session cookie's name, and
14
+ * the attributes applied to every cookie dbAuth writes (the session cookie
15
+ * and the `auth-provider` cookie).
16
+ */
17
+ export interface DbAuthCookieConfig extends DbAuthCookieAttributes {
18
+ attributes?: DbAuthCookieAttributes;
19
+ /**
20
+ * The name of the cookie that dbAuth sets
21
+ *
22
+ * %port% will be replaced with the port the api server is running on.
23
+ * If you have multiple RW apps running on the same host, you'll need to
24
+ * make sure they all use unique cookie names
25
+ */
26
+ name?: string;
27
+ }
28
+ /**
29
+ * Returns a UTC date string `expiresInSeconds` seconds in the future. Used as
30
+ * the `Expires` cookie attribute for a session that should stay valid for
31
+ * that long from now.
32
+ */
33
+ export declare function createExpiresAtDate(expiresInSeconds: number): string;
34
+ /**
35
+ * Generates a new CSRF token (a standard UUID) to pair with a session.
36
+ */
37
+ export declare function createCsrfToken(): string;
38
+ /**
39
+ * Removes any fields not explicitly allowed to be sent to the client before
40
+ * sending a user record over the wire.
41
+ */
42
+ export declare function sanitizeUser(user: Record<string, unknown>, allowedUserFields: string[]): Record<string, unknown>;
43
+ /**
44
+ * Builds the Set-Cookie attribute strings (`Path`, `HttpOnly`, `SameSite`,
45
+ * `Secure`, `Domain`, `Expires`) for a dbAuth cookie.
46
+ *
47
+ * Pass `expires: 'now'` (the default) to get the attributes needed to expire
48
+ * the cookie, or a UTC date string (e.g. from `createExpiresAtDate`) to set a
49
+ * future expiration.
50
+ */
51
+ export declare function buildCookieAttributes({ cookieConfig, expires, overrideAttributes, }: {
52
+ cookieConfig?: DbAuthCookieConfig;
53
+ expires?: 'now' | string;
54
+ overrideAttributes?: DbAuthCookieAttributes;
55
+ }): string[];
56
+ /**
57
+ * Builds the Set-Cookie header string for the `auth-provider` cookie dbAuth
58
+ * sets alongside the session cookie.
59
+ */
60
+ export declare function createAuthProviderCookieString({ cookieConfig, expiresAt, }: {
61
+ cookieConfig?: DbAuthCookieConfig;
62
+ expiresAt: string;
63
+ }): string;
64
+ /**
65
+ * Builds the Set-Cookie header string for the dbAuth session cookie: the
66
+ * `data;csrfToken` payload, encrypted, under the configured cookie name and
67
+ * attributes.
68
+ */
69
+ export declare function createSessionCookieString<TIdType = unknown>({ data, csrfToken, cookieConfig, expiresAt, }: {
70
+ data: Record<string, TIdType>;
71
+ csrfToken: string;
72
+ cookieConfig?: DbAuthCookieConfig;
73
+ expiresAt: string;
74
+ }): string;
75
+ /** Fields returned from the user record when none are explicitly allowed */
76
+ export declare const DEFAULT_ALLOWED_USER_FIELDS: string[];
77
+ export interface CreateLoginResponseOptions {
78
+ /**
79
+ * Object containing cookie config options: the cookie name (with %port%
80
+ * support) and the attributes applied to it (`Path`, `HttpOnly`,
81
+ * `SameSite`, `Secure`, `Domain`).
82
+ */
83
+ cookie?: DbAuthCookieConfig;
84
+ /**
85
+ * The fields that are allowed to be returned from the user record.
86
+ * Defaults to `id` and `email`.
87
+ */
88
+ allowedUserFields?: string[];
89
+ /**
90
+ * The `Expires` cookie attribute value for the session and `auth-provider`
91
+ * cookies: a UTC date string in the future. Build one with
92
+ * `createExpiresAtDate(expiresInSeconds)`.
93
+ */
94
+ expiresAt: string;
95
+ /**
96
+ * The HTTP status code to return in the response tuple. Defaults to 200.
97
+ */
98
+ statusCode?: number;
99
+ }
100
+ /**
101
+ * Mints a dbAuth session for the given user: a CSRF token, a session cookie
102
+ * (the sanitized user data paired with the CSRF token, encrypted), and the
103
+ * `auth-provider` cookie, in the same `[body, headers, { statusCode }]` shape
104
+ * every dbAuth auth method returns.
105
+ *
106
+ * Callable without a `DbAuthHandler` instance, so any code that has already
107
+ * verified a user's identity — a WebAuthn assertion, an OAuth callback, a
108
+ * magic link — can issue a session the same way the built-in login flow
109
+ * does.
110
+ */
111
+ export declare function createLoginResponse(user: Record<string, unknown>, options: CreateLoginResponseOptions): [Record<string, unknown>, Headers, {
112
+ statusCode: number;
113
+ }];
114
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED;;;;GAIG;AACH,MAAM,WAAW,kBAAmB,SAAQ,sBAAsB;IAChE,UAAU,CAAC,EAAE,sBAAsB,CAAA;IACnC;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAOD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,gBAAgB,EAAE,MAAM,GAAG,MAAM,CAKpE;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,iBAAiB,EAAE,MAAM,EAAE,GAC1B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAUzB;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,YAAY,EACZ,OAAe,EACf,kBAAuB,GACxB,EAAE;IACD,YAAY,CAAC,EAAE,kBAAkB,CAAA;IACjC,OAAO,CAAC,EAAE,KAAK,GAAG,MAAM,CAAA;IACxB,kBAAkB,CAAC,EAAE,sBAAsB,CAAA;CAC5C,GAAG,MAAM,EAAE,CAiCX;AAED;;;GAGG;AACH,wBAAgB,8BAA8B,CAAC,EAC7C,YAAY,EACZ,SAAS,GACV,EAAE;IACD,YAAY,CAAC,EAAE,kBAAkB,CAAA;IACjC,SAAS,EAAE,MAAM,CAAA;CAClB,GAAG,MAAM,CAKT;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,GAAG,OAAO,EAAE,EAC3D,IAAI,EACJ,SAAS,EACT,YAAY,EACZ,SAAS,GACV,EAAE;IACD,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC7B,SAAS,EAAE,MAAM,CAAA;IACjB,YAAY,CAAC,EAAE,kBAAkB,CAAA;IACjC,SAAS,EAAE,MAAM,CAAA;CAClB,GAAG,MAAM,CAQT;AAED,4EAA4E;AAC5E,eAAO,MAAM,2BAA2B,UAAkB,CAAA;AAE1D,MAAM,WAAW,0BAA0B;IACzC;;;;OAIG;IACH,MAAM,CAAC,EAAE,kBAAkB,CAAA;IAC3B;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC5B;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAA;IACjB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,EAAE,0BAA0B,GAClC,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE;IAAE,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,CA+B5D"}
@@ -0,0 +1,103 @@
1
+ import { v4 as uuidv4 } from "uuid";
2
+ import { encryptSession, generateCookieName } from "./shared.js";
3
+ const PAST_EXPIRES_DATE = (/* @__PURE__ */ new Date(
4
+ "1970-01-01T00:00:00.000+00:00"
5
+ )).toUTCString();
6
+ function createExpiresAtDate(expiresInSeconds) {
7
+ const expiresAt = /* @__PURE__ */ new Date();
8
+ expiresAt.setSeconds(expiresAt.getSeconds() + expiresInSeconds);
9
+ return expiresAt.toUTCString();
10
+ }
11
+ function createCsrfToken() {
12
+ return uuidv4();
13
+ }
14
+ function sanitizeUser(user, allowedUserFields) {
15
+ const sanitized = JSON.parse(JSON.stringify(user));
16
+ Object.keys(sanitized).forEach((key) => {
17
+ if (!allowedUserFields.includes(key)) {
18
+ delete sanitized[key];
19
+ }
20
+ });
21
+ return sanitized;
22
+ }
23
+ function buildCookieAttributes({
24
+ cookieConfig,
25
+ expires = "now",
26
+ overrideAttributes = {}
27
+ }) {
28
+ const userCookieAttributes = cookieConfig?.attributes ? { ...cookieConfig.attributes } : { ...cookieConfig };
29
+ if (!cookieConfig?.attributes) {
30
+ delete userCookieAttributes.name;
31
+ }
32
+ const cookieOptions = { ...userCookieAttributes, ...overrideAttributes };
33
+ const meta = Object.keys(cookieOptions).map((key) => {
34
+ const optionValue = cookieOptions[key];
35
+ if (optionValue === true) {
36
+ return key;
37
+ } else if (optionValue === false) {
38
+ return null;
39
+ } else {
40
+ return `${key}=${optionValue}`;
41
+ }
42
+ }).filter((v) => v !== null);
43
+ const expiresAt = expires === "now" ? PAST_EXPIRES_DATE : expires;
44
+ meta.push(`Expires=${expiresAt}`);
45
+ return meta;
46
+ }
47
+ function createAuthProviderCookieString({
48
+ cookieConfig,
49
+ expiresAt
50
+ }) {
51
+ return [
52
+ `auth-provider=dbAuth`,
53
+ ...buildCookieAttributes({ cookieConfig, expires: expiresAt })
54
+ ].join(";");
55
+ }
56
+ function createSessionCookieString({
57
+ data,
58
+ csrfToken,
59
+ cookieConfig,
60
+ expiresAt
61
+ }) {
62
+ const session = JSON.stringify(data) + ";" + csrfToken;
63
+ const encrypted = encryptSession(session);
64
+ return [
65
+ `${generateCookieName(cookieConfig?.name)}=${encrypted}`,
66
+ ...buildCookieAttributes({ cookieConfig, expires: expiresAt })
67
+ ].join(";");
68
+ }
69
+ const DEFAULT_ALLOWED_USER_FIELDS = ["id", "email"];
70
+ function createLoginResponse(user, options) {
71
+ const allowedUserFields = options.allowedUserFields ?? DEFAULT_ALLOWED_USER_FIELDS;
72
+ const sessionData = sanitizeUser(user, allowedUserFields);
73
+ const csrfToken = createCsrfToken();
74
+ const headers = new Headers();
75
+ headers.append("csrf-token", csrfToken);
76
+ headers.append(
77
+ "set-cookie",
78
+ createAuthProviderCookieString({
79
+ cookieConfig: options.cookie,
80
+ expiresAt: options.expiresAt
81
+ })
82
+ );
83
+ headers.append(
84
+ "set-cookie",
85
+ createSessionCookieString({
86
+ data: sessionData,
87
+ csrfToken,
88
+ cookieConfig: options.cookie,
89
+ expiresAt: options.expiresAt
90
+ })
91
+ );
92
+ return [sessionData, headers, { statusCode: options.statusCode ?? 200 }];
93
+ }
94
+ export {
95
+ DEFAULT_ALLOWED_USER_FIELDS,
96
+ buildCookieAttributes,
97
+ createAuthProviderCookieString,
98
+ createCsrfToken,
99
+ createExpiresAtDate,
100
+ createLoginResponse,
101
+ createSessionCookieString,
102
+ sanitizeUser
103
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cedarjs/auth-dbauth-api",
3
- "version": "7.0.0-canary.3073",
3
+ "version": "7.0.0-canary.3075",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/cedarjs/cedar.git",
@@ -57,13 +57,13 @@
57
57
  "test:watch": "vitest watch"
58
58
  },
59
59
  "dependencies": {
60
- "@cedarjs/project-config": "7.0.0-canary.3073",
60
+ "@cedarjs/project-config": "7.0.0-canary.3075",
61
61
  "md5": "2.3.0",
62
62
  "uuid": "11.1.0"
63
63
  },
64
64
  "devDependencies": {
65
- "@cedarjs/api": "7.0.0-canary.3073",
66
- "@cedarjs/framework-tools": "7.0.0-canary.3073",
65
+ "@cedarjs/api": "7.0.0-canary.3075",
66
+ "@cedarjs/framework-tools": "7.0.0-canary.3075",
67
67
  "@simplewebauthn/server": "13.3.3",
68
68
  "@types/aws-lambda": "8.10.162",
69
69
  "@types/md5": "2.3.6",