@schemavaults/auth-client-sdk 0.5.6 → 0.7.5

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.
Files changed (28) hide show
  1. package/dist/auth-client.d.ts +1 -1
  2. package/dist/auth-client.js +65 -502
  3. package/dist/auth-client.js.map +1 -1
  4. package/dist/index.d.ts +2 -1
  5. package/dist/index.js +1 -0
  6. package/dist/index.js.map +1 -1
  7. package/dist/lib/assert-http-only-refresh-token-has-accompanying-expiry-marker.d.ts +2 -0
  8. package/dist/lib/assert-http-only-refresh-token-has-accompanying-expiry-marker.js +9 -0
  9. package/dist/lib/assert-http-only-refresh-token-has-accompanying-expiry-marker.js.map +1 -0
  10. package/dist/lib/authenticate-url-encoder.js +12 -1
  11. package/dist/lib/authenticate-url-encoder.js.map +1 -1
  12. package/dist/lib/authenticate-with-redirect.d.ts +13 -0
  13. package/dist/lib/authenticate-with-redirect.js +108 -0
  14. package/dist/lib/authenticate-with-redirect.js.map +1 -0
  15. package/dist/lib/check-if-authenticated-with-server.d.ts +8 -0
  16. package/dist/lib/check-if-authenticated-with-server.js +37 -0
  17. package/dist/lib/check-if-authenticated-with-server.js.map +1 -0
  18. package/dist/lib/exchange-auth-tokens.d.ts +16 -0
  19. package/dist/lib/exchange-auth-tokens.js +121 -0
  20. package/dist/lib/exchange-auth-tokens.js.map +1 -0
  21. package/dist/lib/handle-successful-authentication.d.ts +21 -0
  22. package/dist/lib/handle-successful-authentication.js +259 -0
  23. package/dist/lib/handle-successful-authentication.js.map +1 -0
  24. package/dist/lib/send-authenticate-request.js +15 -7
  25. package/dist/lib/send-authenticate-request.js.map +1 -1
  26. package/dist/types/ISchemaVaultsAuthClient.d.ts +9 -0
  27. package/dist/types/ISchemaVaultsAuthClientAdapter.d.ts +2 -6
  28. package/package.json +3 -3
@@ -113,7 +113,6 @@ export declare class SchemaVaultsAuthClient extends EventTarget implements ISche
113
113
  * @returns `UserData` | `null`
114
114
  */
115
115
  get currentUser(): UserData | null;
116
- private assertHttpOnlyRefreshTokenCookieHasAccompanyingMarkerCookie;
117
116
  private handleSuccessfulExchangeAuthTokensResponse;
118
117
  private exchangeAuthTokens;
119
118
  private uuid;
@@ -126,4 +125,5 @@ export declare class SchemaVaultsAuthClient extends EventTarget implements ISche
126
125
  */
127
126
  get successful_logout_redirect_uri(): string | undefined;
128
127
  supports(feature_name: string): boolean;
128
+ checkIfAuthenticatedWithServer(): Promise<UserData | null>;
129
129
  }
@@ -1,9 +1,13 @@
1
- import AuthenticateURLEncoder from "./lib/authenticate-url-encoder";
2
- import { PKCE_ProofKeyManager, requestTokensResultSchema, authorizationCodePOSTbody, refreshTokenPOSTbody, audienceSchema, } from "@schemavaults/auth-common";
1
+ // auth-client.ts
2
+ // @schemavaults/auth-client-sdk
3
+ import { PKCE_ProofKeyManager, requestTokensResultSchema, audienceSchema, } from "@schemavaults/auth-common";
3
4
  import { sendAuthenticateRequest } from "./lib/send-authenticate-request";
4
5
  import { appIdSchema, SCHEMAVAULTS_AUTH_APP_DEFINITION, schemaVaultsAppEnvironmentSchema, } from "@schemavaults/app-definitions";
5
- import debugPrintTokensAsTable from "./lib/debugPrintTokensAsTable";
6
- import debugPrintUserDataAsTable from "./lib/debugPrintUserDataAsTable";
6
+ import authenticateWithRedirect from "./lib/authenticate-with-redirect";
7
+ import checkIfAuthenticatedWithServer from "./lib/check-if-authenticated-with-server";
8
+ import exchangeAuthTokens from "./lib/exchange-auth-tokens";
9
+ import assertHttpOnlyRefreshTokenCookieHasAccompanyingMarkerCookie from "./lib/assert-http-only-refresh-token-has-accompanying-expiry-marker";
10
+ import handleSuccessfulAuthentication from "./lib/handle-successful-authentication";
7
11
  /**
8
12
  * The SchemaVaultsAuthClient is a client SDK for the SchemaVaults Auth Server
9
13
  * It is used to authenticate users, store tokens, and manage user data
@@ -238,105 +242,26 @@ export class SchemaVaultsAuthClient extends EventTarget {
238
242
  return code_challenge;
239
243
  }
240
244
  async authenticateWithRedirect(type) {
241
- if (this.DEBUG) {
242
- console.log(`[SchemaVaultsAuthClient] Authenticating with redirect (type "${type}")...`);
243
- }
244
- // This should be kept securely within the SDK
245
- let code_verifier;
246
- try {
247
- code_verifier = PKCE_ProofKeyManager.createCodeVerifier();
248
- }
249
- catch (e) {
250
- console.error("Failed to create code verifier to initialize PKCE challenge process: ", e);
251
- throw new Error("Failed to create code verifier to initialize PKCE challenge process");
252
- }
253
- // Do some validation
254
- if (typeof code_verifier !== "object" || !code_verifier) {
255
- throw new TypeError("Expected generated 'code_verifier' to be an object!");
256
- }
257
- else if (typeof code_verifier.challenge_time !== "number") {
258
- throw new TypeError("Expected generated 'code_verifier.challenge_time' to be a number!");
259
- }
260
- else if (typeof code_verifier.code_verifier !== "string") {
261
- throw new TypeError("Expected generated 'code_verifier.code_verifier' to be a string!");
262
- }
263
- // This is sent to the auth server-- it's a hash of the code verifier
264
- // https://datatracker.ietf.org/doc/html/rfc7636#section-4.2
265
- let code_challenge;
266
- try {
267
- const new_code_challenge = await PKCE_ProofKeyManager.createCodeChallenge(code_verifier);
268
- code_challenge = new_code_challenge;
269
- }
270
- catch (e) {
271
- console.error("Auth client failed to create code challenge from code verifier object: ", e);
272
- const errMsg = e instanceof Error && typeof e.message === "string"
273
- ? e.message
274
- : "Auth client encountered an unknown error while creating code challenge";
275
- throw new Error(`Auth client failed to create code challenge from code verifier object (error: ${errMsg})`);
276
- }
277
- // Validate code challenge a bit
278
- if (typeof code_challenge.challenge_time !== "number") {
279
- throw new Error("Expected challenge_time to be set (from input code_verifier)");
280
- }
281
- else if (typeof code_challenge.code_challenge_method !== "string" ||
282
- code_challenge.code_challenge_method !== "S256") {
283
- throw new Error("Expected code_challenge_method to be set to S256");
284
- }
285
- else if (typeof code_challenge.code_challenge !== "string") {
286
- throw new Error("Expected code_challenge to be set");
287
- }
288
- // Store the code verifier in a secure location
289
- try {
290
- this.storeCodeVerifier(code_verifier.code_verifier, code_challenge.challenge_time);
291
- }
292
- catch (e) {
293
- console.error("Failed to store code verifier: ", e);
294
- throw new Error("Failed to store code verifier!");
295
- }
296
- // If the authentication is successful, the auth server will redirect the user back to the client
297
- // and the code_verifier will be used to prove that the client initiating the flow is the same as the client that the authorization server issued the code to
298
- const app_id = this.app_id;
299
- if (!app_id) {
300
- console.error("App ID not set, but required for PKCE flow");
301
- throw new Error("App ID not set, but required for PKCE flow");
302
- }
303
- // The user is about to be redirected to auth server. Where should they be redirected back to this app? (for PKCE flow)
304
- const redirect_uri = this.authorize_uri;
305
- if (typeof redirect_uri !== "string") {
306
- throw new Error("A URL to redirect to when authentication is successful was not provided. Required for PKCE flow.");
307
- }
308
- if (this.DEBUG) {
309
- console.log("[SchemaVaultsAuthClient] Attempting to build URL to open from client in order to start OAuth 2.0 PKCE flow with SchemaVaults Auth Server...");
310
- }
311
- // Redirect the user to the auth server
312
- let authenticate_url;
313
- try {
314
- authenticate_url = AuthenticateURLEncoder.encode({
315
- type,
316
- code_challenge: code_challenge,
317
- redirect_uri,
318
- app_id,
319
- auth_server_uri: this._authServerUri,
320
- app_env: this.environment,
321
- });
322
- }
323
- catch (e) {
324
- console.error("Failed to build authenticate URL: ", e);
325
- throw new Error("Failed to build authenticate URL (i.e. where to login/register url not found)");
326
- }
327
- if (this.DEBUG) {
328
- console.log("[SchemaVaultsAuthClient] Redirecting to authenticate URL: ", authenticate_url);
329
- }
330
- try {
331
- await this.adapter.redirect(authenticate_url);
332
- return;
333
- }
334
- catch (e) {
335
- console.error("Failed to redirect to authentication server using client adapter: ", e);
336
- throw new Error("Failed to redirect to authentication server");
337
- }
245
+ if (!this.authorize_uri ||
246
+ typeof this.authorize_uri !== "string" ||
247
+ this.authorize_uri.length === 0) {
248
+ throw new TypeError("Failed to resolve 'authorize_uri'!");
249
+ }
250
+ return await authenticateWithRedirect({
251
+ type,
252
+ adapter: this.adapter,
253
+ auth_server_uri: this._authServerUri,
254
+ client_app_id: this._app_id,
255
+ storeCodeVerifier: this.storeCodeVerifier.bind(this),
256
+ environment: this.environment,
257
+ authorize_uri: this.authorize_uri,
258
+ debug: this.debug,
259
+ });
338
260
  }
339
261
  async login() {
262
+ if (this.isClientForAuthServer) {
263
+ return await this.adapter.redirect("/auth/login");
264
+ }
340
265
  if (this.DEBUG) {
341
266
  console.log("[SchemaVaultsAuthClient] Attempting to sign in with redirect...");
342
267
  }
@@ -351,6 +276,9 @@ export class SchemaVaultsAuthClient extends EventTarget {
351
276
  }
352
277
  } // login()
353
278
  async register() {
279
+ if (this.isClientForAuthServer) {
280
+ return await this.adapter.redirect("/auth/register");
281
+ }
354
282
  if (this.DEBUG) {
355
283
  console.log("[SchemaVaultsAuthClient] Attempting to register with redirect...");
356
284
  }
@@ -436,257 +364,22 @@ export class SchemaVaultsAuthClient extends EventTarget {
436
364
  return codeVerifiers;
437
365
  } // loadSavedAuthorizationCodeVerifiers()
438
366
  async handleSuccessfulAuthentication(authorization_code, challenge_time, code_verifier) {
439
- const debug = this.DEBUG;
440
- if (debug) {
441
- console.log("[SchemaVaultsAuthClient::handleSuccessfulAuthentication]" +
442
- " " +
443
- "Handling successful authentication...");
444
- }
445
- if (!authorization_code) {
446
- throw new Error("Missing authorization code");
447
- }
448
- else if (typeof authorization_code !== "string" ||
449
- authorization_code.length === 0) {
450
- throw new TypeError("Expected 'authorization_code' to be a non-empty string!");
451
- }
452
- if (!challenge_time || typeof challenge_time !== "number") {
453
- throw new Error("Invalid challenge_time");
454
- }
455
- const time_elapsed_since_challenge_time = Date.now() - challenge_time;
456
- if (time_elapsed_since_challenge_time <= 0) {
457
- throw new Error("Expected challenge time to be in the past");
458
- }
459
- if (time_elapsed_since_challenge_time > PKCE_ProofKeyManager.max_age) {
460
- console.error("[SchemaVaultsAuthClient::handleSuccessfulAuthentication] Code verifier has expired based on challenge time");
461
- if (this.debug) {
462
- try {
463
- console.table({
464
- challenge_time,
465
- current_time: Date.now(),
466
- time_elapsed: time_elapsed_since_challenge_time,
467
- max_age: PKCE_ProofKeyManager.max_age,
468
- });
469
- }
470
- catch (e) {
471
- void e; /** no-op */
472
- }
473
- }
474
- throw new Error("Code verifier has expired");
475
- }
476
- // The auth server will redirect the user back to the client
477
- // The client will have a code in the query parameters
478
- // The client will use the code to get an access token
479
- // PKCE: The client will use the code_verifier to prove that it is the same client
480
- if (debug) {
481
- console.log("[SchemaVaultsAuthClient] " +
482
- "Attempting to load code verifier to prove authorization code validity...");
483
- }
484
- const cached_code_verifier = code_verifier ?? this.loadCodeVerifier(challenge_time);
485
- if (!cached_code_verifier) {
486
- const errorMessage = `[SchemaVaultsAuthClient] Failed to load code_verifier at challenge_time=${challenge_time}`;
487
- console.error(errorMessage);
488
- throw new Error(errorMessage);
489
- }
490
- cached_code_verifier;
491
- const shouldClearCodeVerifierAfterLoad = this.environment !== "development";
492
- if (shouldClearCodeVerifierAfterLoad) {
493
- // Clear the code verifier from storage
494
- try {
495
- if (debug) {
496
- console.log("[SchemaVaultsAuthClient] " +
497
- "Code verifier was retrieved from storage, now clearing code verifier at challenge time: ", challenge_time);
498
- }
499
- this.adapter.clearCodeVerifier(challenge_time);
500
- if (debug) {
501
- console.log("[SchemaVaultsAuthClient] Cleared code verifiers from storage");
502
- }
503
- }
504
- catch (e) {
505
- console.error("[SchemaVaultsAuthClient] Failed to clear code verifiers: ", e);
506
- if (debug) {
507
- throw new Error("Failed to clear code verifiers");
508
- }
509
- }
510
- }
511
- else {
512
- if (debug) {
513
- console.log("[SchemaVaultsAuthClient] Not attempting to clear code verifiers in this app environment...");
514
- }
515
- }
516
- // Get the endpoint to exchange the authorization code for an access token
517
- // https://datatracker.ietf.org/doc/html/rfc7636#section-4.5
518
- const token_endpoint = `${this.auth_server_uri}/api/auth/token/authorization_code`;
519
- if (debug) {
520
- console.log("[SchemaVaultsAuthClient::handleSuccessfulAuthentication()] Token Endpoint: ", token_endpoint);
521
- }
522
- const client_app_id = this.app_id;
523
- if (debug) {
524
- console.log("[SchemaVaultsAuthClient::handleSuccessfulAuthentication()] Client App ID: ", client_app_id);
525
- }
526
- let audience = this.defaultTokenAudiences;
527
- if (debug) {
528
- console.log("[SchemaVaultsAuthClient::handleSuccessfulAuthentication()] Initial access token audience(s): ", audience);
529
- }
530
- if (!audience || (Array.isArray(audience) && audience.length === 0)) {
531
- console.warn("[SchemaVaultsAuthClient::handleSuccessfulAuthentication()] No access token audience(s) set");
532
- audience = [];
533
- }
534
- // Exchange the authorization code for an access token
535
- let request_body;
536
- try {
537
- const parsed = await authorizationCodePOSTbody.safeParseAsync({
538
- grant_type: "authorization_code",
539
- code: authorization_code,
540
- code_verifier: cached_code_verifier,
541
- client_app_id,
542
- audience,
543
- challenge_time,
544
- });
545
- if (!parsed.success)
546
- throw parsed.error;
547
- request_body = parsed.data;
548
- }
549
- catch (e) {
550
- console.error(e);
551
- throw new Error("Failed to prepare request body for authorization grant request");
552
- }
553
- // Send the request to the auth server
554
- // The auth server will hash the code_verifier and compare it to the code_challenge
555
- let response;
556
- try {
557
- if (this.debug) {
558
- console.log(`[SchemaVaultsAuthClient] Exchanging authorization code for access token; sending req body to token endpoint: "${token_endpoint}"`, request_body);
559
- }
560
- response = await this.adapter.sendPOSTRequest(token_endpoint, request_body, {});
561
- if (this.debug) {
562
- console.log("[SchemaVaultsAuthClient] Received response in attempt to exchange authorization code for access token: ", response);
563
- }
564
- }
565
- catch (e) {
566
- console.error("Failed to exchange authorization code for access token:", e);
567
- throw new Error("Failed to exchange authorization code for access token");
568
- }
569
- if (!response || !response.ok || response.status !== 200) {
570
- const errorMsg = `Failed to exchange authorization code for access token (status code: ${response.status})`;
571
- console.error(errorMsg);
572
- throw new Error(errorMsg);
573
- }
574
- if (this.DEBUG) {
575
- console.log("[SchemaVaultsAuthClient::handleSuccessfulAuthentication()] " +
576
- "Successfully exchanged authorization code for token(s)");
577
- }
578
- let access_tokens;
579
- let refresh_token;
580
- let user;
581
- try {
582
- const tokens_data = await requestTokensResultSchema.safeParseAsync(response.data);
583
- if (!tokens_data.success) {
584
- console.error("[SchemaVaultsAuthClient::handleSuccessfulAuthentication()] " +
585
- "Failed to parse tokens from auth server response:", tokens_data.error);
586
- throw new Error("Failed to parse tokens from auth server response");
587
- }
588
- else if (!tokens_data.data.success) {
589
- throw new Error(tokens_data.data.message);
590
- }
591
- if (this.DEBUG) {
592
- console.log("[SchemaVaultsAuthClient::handleSuccessfulAuthentication()] Success response data: ", tokens_data.data);
593
- }
594
- const { tokens, userData } = tokens_data.data;
595
- if (!tokens) {
596
- console.error("Did not receive tokens in response from auth server");
597
- throw new Error("Did not receive tokens in response from auth server");
598
- }
599
- if (!tokens.access) {
600
- console.error("Did not receive any access tokens in response from auth server");
601
- throw new Error("Did not receive any access tokens in response from auth server");
602
- }
603
- if (!tokens.refresh ||
604
- (typeof tokens.refresh !== "object" &&
605
- typeof tokens.refresh !== "string")) {
606
- console.error("Did not receive (valid) refresh token in response from auth server.", `Type: ${typeof tokens.refresh}`, tokens.refresh);
607
- throw new Error("Did not receive refresh token in response from auth server");
608
- }
609
- if (this.debug) {
610
- debugPrintTokensAsTable(tokens);
611
- }
612
- access_tokens = tokens.access;
613
- refresh_token = tokens.refresh;
614
- if (!userData) {
615
- console.error("Did not receive user data in response from auth server");
616
- throw new Error("Did not receive user data in response from auth server");
617
- }
618
- else {
619
- if (this.debug) {
620
- debugPrintUserDataAsTable(userData);
621
- }
622
- }
623
- user = userData;
624
- }
625
- catch (e) {
626
- let errorMessage = "Unknown error";
627
- if (e instanceof Error) {
628
- errorMessage = e.message;
629
- }
630
- console.error("Failed to parse tokens response: ", errorMessage);
631
- throw new Error(`Failed to parse tokens response: ${errorMessage}`);
632
- }
633
- // Store refresh token
634
- const doStoreReceivedRefreshToken = () => {
635
- if (typeof refresh_token === "object" &&
636
- refresh_token.type === "refresh") {
637
- try {
638
- if (debug) {
639
- console.log("[SchemaVaultsAuthClient] Storing refresh token...");
640
- }
641
- this.storeRefreshToken(refresh_token);
642
- if (debug) {
643
- console.log("[SchemaVaultsAuthClient] Stored refresh token!");
644
- }
645
- }
646
- catch (e) {
647
- console.error(e);
648
- throw new Error("Failed to store refresh token");
649
- }
650
- }
651
- else if (typeof refresh_token === "string" &&
652
- refresh_token === "AS_HTTP_ONLY_COOKIE") {
653
- this.assertHttpOnlyRefreshTokenCookieHasAccompanyingMarkerCookie();
654
- if (debug) {
655
- console.log("[SchemaVaultsAuthClient] Detected HTTP-only cookie refresh token (accompanying-cookie).");
656
- }
657
- return;
658
- }
659
- else {
660
- throw new TypeError("Invalid type for refresh token!");
661
- }
662
- };
663
- doStoreReceivedRefreshToken();
664
- // Store access tokens
665
- this.storeMultipleAccessTokens(access_tokens);
666
- try {
667
- if (debug) {
668
- console.log("[SchemaVaultsAuthClient] Storing user data...");
669
- }
670
- this.storeUserData(user);
671
- if (debug) {
672
- console.log("[SchemaVaultsAuthClient] Stored user data.");
673
- }
674
- }
675
- catch (e) {
676
- console.error("Failed to store user data: ", e);
677
- throw new Error("Failed to store user data");
678
- }
679
- if (debug) {
680
- console.log("[SchemaVaultsAuthClient] Triggering auth state changed!");
681
- }
682
- this.triggerAuthStateChanged();
683
- if (debug) {
684
- console.log("[SchemaVaultsAuthClient] Finished triggering auth state change.");
685
- }
686
- if (debug) {
687
- console.log("[SchemaVaultsAuthClient] handleSuccessfulAuthentication success!");
688
- }
689
- return;
367
+ return await handleSuccessfulAuthentication({
368
+ authorization_code,
369
+ challenge_time,
370
+ code_verifier,
371
+ loadCodeVerifier: this.loadCodeVerifier.bind(this),
372
+ auth_server_uri: this.auth_server_uri,
373
+ client_app_id: this.app_id,
374
+ adapter: this.adapter,
375
+ storeUserData: this.storeUserData.bind(this),
376
+ storeRefreshToken: this.storeRefreshToken.bind(this),
377
+ storeMultipleAccessTokens: this.storeMultipleAccessTokens.bind(this),
378
+ environment: this.environment,
379
+ debug: this.DEBUG,
380
+ triggerAuthStateChanged: this.triggerAuthStateChanged.bind(this),
381
+ defaultTokenAudiences: this.defaultTokenAudiences,
382
+ });
690
383
  } // handleSuccessfulAuthentication()
691
384
  async logout() {
692
385
  if (this.debug) {
@@ -895,31 +588,7 @@ export class SchemaVaultsAuthClient extends EventTarget {
895
588
  * @description Getter that returns true/false based on whether a user is currently signed into their account
896
589
  */
897
590
  get isAuthenticated() {
898
- if (this.DEBUG) {
899
- console.log("[SchemaVaultsAuthClient::isAuthenticated] Checking whether auth client has a refresh token to see if authenticated...");
900
- }
901
- const refreshToken = this.getRefreshTokenFromCache();
902
- if (refreshToken) {
903
- if (this.DEBUG) {
904
- console.log("[SchemaVaultsAuthClient::isAuthenticated] There is a refresh token stored, checking if it is expired...");
905
- }
906
- const refreshTokenExpiryTime = refreshToken.exp;
907
- const now = this.getCurrentTimestamp();
908
- if (now < refreshTokenExpiryTime) {
909
- return true;
910
- }
911
- else {
912
- if (this.DEBUG) {
913
- console.warn("[SchemaVaultsAuthClient::isAuthenticated] There is a refresh token stored, but it appears to be expired!");
914
- }
915
- }
916
- }
917
- else {
918
- if (this.DEBUG) {
919
- console.warn("[SchemaVaultsAuthClient::isAuthenticated] No refresh token found from cache!");
920
- }
921
- }
922
- return false;
591
+ return this.adapter.hasRefreshToken();
923
592
  }
924
593
  /**
925
594
  * @name sendAuthenticateRequest
@@ -950,14 +619,6 @@ export class SchemaVaultsAuthClient extends EventTarget {
950
619
  const userData = this.getUserData();
951
620
  return userData;
952
621
  }
953
- assertHttpOnlyRefreshTokenCookieHasAccompanyingMarkerCookie() {
954
- if (typeof this.adapter.hasHttpOnlyRefreshToken === "function" &&
955
- !this.adapter.hasHttpOnlyRefreshToken()) {
956
- throw new Error("Adapter does not indicate having an HTTP-only refresh token after exchange," +
957
- " " +
958
- "despite response of AS_HTTP_ONLY_COOKIE!");
959
- }
960
- }
961
622
  async handleSuccessfulExchangeAuthTokensResponse(tokens_response) {
962
623
  const parsed_tokens_data = await requestTokensResultSchema.safeParseAsync(tokens_response);
963
624
  if (!parsed_tokens_data.success) {
@@ -991,7 +652,7 @@ export class SchemaVaultsAuthClient extends EventTarget {
991
652
  }
992
653
  else if (typeof tokens.refresh === "string" &&
993
654
  tokens.refresh === "AS_HTTP_ONLY_COOKIE") {
994
- this.assertHttpOnlyRefreshTokenCookieHasAccompanyingMarkerCookie();
655
+ assertHttpOnlyRefreshTokenCookieHasAccompanyingMarkerCookie(this.adapter);
995
656
  if (this.debug) {
996
657
  console.log("[SchemaVaultsAuthClient] Detected HTTP-only cookie refresh token from exchange response.");
997
658
  }
@@ -1003,122 +664,17 @@ export class SchemaVaultsAuthClient extends EventTarget {
1003
664
  return tokens;
1004
665
  }
1005
666
  async exchangeAuthTokens(refreshToken, audience, replaceRefreshToo) {
1006
- if (this.DEBUG) {
1007
- console.log("[SchemaVaultsAuthClient] Attempting to send request to exchange refresh token for access token...");
1008
- }
1009
- const token_endpoint = `${this.auth_server_uri}/api/auth/token/refresh_token`;
1010
- const client_app_id = this.app_id;
1011
- if (!audience && !replaceRefreshToo) {
1012
- throw new Error("Type of token to acquire not specified");
1013
- }
1014
- // Exchange the authorization code for an access token
1015
- let request_body;
1016
- try {
1017
- const parsed = await refreshTokenPOSTbody.safeParseAsync({
1018
- grant_type: "refresh_token",
1019
- client_app_id,
1020
- audience: audience ?? this.defaultTokenAudiences,
1021
- replaceRefreshToo: replaceRefreshToo ?? false,
1022
- });
1023
- if (!parsed.success) {
1024
- console.error(parsed.error);
1025
- throw new Error("Failed to parse tokens from exchange auth tokens POST request!");
1026
- }
1027
- request_body = parsed.data;
1028
- }
1029
- catch (e) {
1030
- if (this.DEBUG) {
1031
- console.error("Failed to prepare request body for authorization grant request: ", e);
1032
- }
1033
- throw new Error("Failed to prepare request body for authorization grant request");
1034
- }
1035
- const exchangeAuthTokensReqHeaders = {};
1036
- if (!refreshToken) {
1037
- throw new Error("Did not receive a refresh token to exchange for access token!");
1038
- }
1039
- if (typeof refreshToken === "object" && refreshToken.type === "refresh") {
1040
- if (typeof refreshToken.token !== "string" ||
1041
- refreshToken.token.length === 0) {
1042
- throw new TypeError("Expected 'token' to be a non-empty string!");
1043
- }
1044
- exchangeAuthTokensReqHeaders["Authorization"] =
1045
- `Bearer ${refreshToken.token}`;
1046
- }
1047
- else if (typeof refreshToken === "string" &&
1048
- refreshToken === "AS_HTTP_ONLY_COOKIE") {
1049
- const doesSupportHttpOnlyRefreshToken = this.adapter.doesSupportHttpOnlyRefreshToken;
1050
- if (typeof doesSupportHttpOnlyRefreshToken !== "function" ||
1051
- !doesSupportHttpOnlyRefreshToken()) {
1052
- throw new Error("Adapter does not support HTTP-only refresh tokens!");
1053
- }
1054
- }
1055
- else {
1056
- throw new Error("Did not receive a valid refresh token (or valid method of acquiring refresh token)");
1057
- }
1058
- if (this.DEBUG) {
1059
- console.log("[SchemaVaultsAuthClient::exchangeAuthTokens()] " +
1060
- `Sending POST request to "${token_endpoint}" with body & headers:`, request_body, exchangeAuthTokensReqHeaders);
1061
- }
1062
- let tokens_response_data;
1063
- try {
1064
- if (this.DEBUG) {
1065
- console.log(`POST => ${token_endpoint}`);
1066
- }
1067
- const response = await this.adapter.sendPOSTRequest(token_endpoint,
1068
- // body
1069
- request_body,
1070
- // headers
1071
- exchangeAuthTokensReqHeaders);
1072
- if (!response ||
1073
- typeof response !== "object" ||
1074
- response.status !== 200) {
1075
- if (response.status === 403 || response.status === 401) {
1076
- console.error("401/403 error response from exchange token attempt, client is not logged in!");
1077
- await this.logout();
1078
- }
1079
- throw new Error("HTTP request failed to exchange refresh token for access token(s) object");
1080
- }
1081
- const parsed_failed_tokens_result = await requestTokensResultSchema.safeParseAsync(response.data);
1082
- if (!parsed_failed_tokens_result.success) {
1083
- console.error("Failed to parse tokens response from server: ", parsed_failed_tokens_result.error);
1084
- throw new Error("Failed to parse tokens response from server!");
1085
- }
1086
- tokens_response_data = parsed_failed_tokens_result.data;
1087
- }
1088
- catch (e) {
1089
- if (this.DEBUG) {
1090
- console.error("[this.adapter.sendPOSTRequest] FAILED: ", e);
1091
- throw new Error("Failed to ");
1092
- }
1093
- if (e instanceof Error) {
1094
- const errMsg = e.message;
1095
- const eMsg = errMsg.toLowerCase();
1096
- if (eMsg.includes("expired") ||
1097
- eMsg.includes("jwtexpired") ||
1098
- eMsg.includes("err_jwt_expired")) {
1099
- console.error("Refresh token appears to have expired!");
1100
- throw new Error("Refresh token has expired!");
1101
- }
1102
- }
1103
- if (this.DEBUG) {
1104
- console.error("Failed to exchange refresh token for access token: ", e);
1105
- }
1106
- throw new Error("Failed to exchange refresh token for access token");
1107
- } // end of this.adapter.sendPOSTRequest catch block
1108
- try {
1109
- // Parse tokens from response JSON body
1110
- return await this.handleSuccessfulExchangeAuthTokensResponse(tokens_response_data);
1111
- }
1112
- catch (e) {
1113
- if (this.DEBUG) {
1114
- console.log("typeof e === ", typeof e);
1115
- if (e instanceof Error) {
1116
- console.error("Parse tokens error message: ", e.message);
1117
- }
1118
- console.error("Failed to parse authentication tokens from exchange tokens POST request: ", e);
1119
- }
1120
- throw new Error("Failed to parse authentication tokens from exchange tokens POST request!");
1121
- }
667
+ return await exchangeAuthTokens({
668
+ refreshToken,
669
+ replaceRefreshToo,
670
+ audience: audience ?? this.defaultTokenAudiences,
671
+ logout: this.logout.bind(this),
672
+ debug: this.DEBUG,
673
+ handleSuccessfulExchangeAuthTokensResponse: this.handleSuccessfulExchangeAuthTokensResponse.bind(this),
674
+ client_app_id: this.app_id,
675
+ adapter: this.adapter,
676
+ auth_server_uri: this.auth_server_uri,
677
+ });
1122
678
  } // exchangeAuthTokens()
1123
679
  uuid() {
1124
680
  let id;
@@ -1189,5 +745,12 @@ export class SchemaVaultsAuthClient extends EventTarget {
1189
745
  }
1190
746
  return false;
1191
747
  }
748
+ async checkIfAuthenticatedWithServer() {
749
+ return await checkIfAuthenticatedWithServer({
750
+ adapter: this.adapter,
751
+ auth_server_uri: this.auth_server_uri,
752
+ client_app_id: this.app_id,
753
+ });
754
+ }
1192
755
  }
1193
756
  //# sourceMappingURL=auth-client.js.map