@inrupt/solid-client-authn-browser 1.11.9-alpha.1 → 1.11.9-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.es.js CHANGED
@@ -1,6 +1,7 @@
1
- import { StorageUtility, determineSigningAlg, PREFERRED_SIGNING_ALG, getWebidFromTokenPayload, createDpopHeader, OidcProviderError, InvalidResponseError, generateDpopKeyPair, EVENTS, ConfigurationError, handleRegistration, isSupportedTokenType, loadOidcContextFromStorage, buildAuthenticatedFetch, AggregateHandler, InMemoryStorage, SOLID_CLIENT_AUTHN_KEY_PREFIX } from '@inrupt/solid-client-authn-core';
1
+ import { StorageUtility, EVENTS, ConfigurationError, handleRegistration, isSupportedTokenType, loadOidcContextFromStorage, buildAuthenticatedFetch, AggregateHandler, InMemoryStorage, SOLID_CLIENT_AUTHN_KEY_PREFIX } from '@inrupt/solid-client-authn-core';
2
2
  export { ConfigurationError, InMemoryStorage, NotImplementedError } from '@inrupt/solid-client-authn-core';
3
- import { OidcClient, WebStorageStateStore } from '@inrupt/oidc-client';
3
+ import { v4 } from 'uuid';
4
+ import { removeOidcQueryParam, OidcClient, clearOidcPersistentStorage, getDpopToken, getBearerToken, registerClient, refresh } from '@inrupt/oidc-client-ext';
4
5
 
5
6
  var domain;
6
7
 
@@ -474,362 +475,12 @@ function unwrapListeners(arr) {
474
475
  return ret;
475
476
  }
476
477
 
477
- // Unique ID creation requires a high quality random # generator. In the browser we therefore
478
- // require the crypto API and do not support built-in fallback to lower quality random number
479
- // generators (like Math.random()).
480
- var getRandomValues;
481
- var rnds8 = new Uint8Array(16);
482
- function rng() {
483
- // lazy load so that environments that need to polyfill have a chance to do so
484
- if (!getRandomValues) {
485
- // getRandomValues needs to be invoked in a context where "this" is a Crypto implementation. Also,
486
- // find the complete implementation of crypto (msCrypto) on IE11.
487
- getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto) || typeof msCrypto !== 'undefined' && typeof msCrypto.getRandomValues === 'function' && msCrypto.getRandomValues.bind(msCrypto);
488
-
489
- if (!getRandomValues) {
490
- throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported');
491
- }
492
- }
493
-
494
- return getRandomValues(rnds8);
495
- }
496
-
497
- var REGEX = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;
498
-
499
- function validate(uuid) {
500
- return typeof uuid === 'string' && REGEX.test(uuid);
501
- }
502
-
503
- /**
504
- * Convert array of 16 byte values to UUID string format of the form:
505
- * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
506
- */
507
-
508
- var byteToHex = [];
509
-
510
- for (var i = 0; i < 256; ++i) {
511
- byteToHex.push((i + 0x100).toString(16).substr(1));
512
- }
513
-
514
- function stringify(arr) {
515
- var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
516
- // Note: Be careful editing this code! It's been tuned for performance
517
- // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434
518
- var uuid = (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); // Consistency check for valid UUID. If this throws, it's likely due to one
519
- // of the following:
520
- // - One or more input array values don't map to a hex octet (leading to
521
- // "undefined" in the uuid)
522
- // - Invalid input values for the RFC `version` or `variant` fields
523
-
524
- if (!validate(uuid)) {
525
- throw TypeError('Stringified UUID is invalid');
526
- }
527
-
528
- return uuid;
529
- }
530
-
531
- function v4(options, buf, offset) {
532
- options = options || {};
533
- var rnds = options.random || (options.rng || rng)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
534
-
535
- rnds[6] = rnds[6] & 0x0f | 0x40;
536
- rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided
537
-
538
- if (buf) {
539
- offset = offset || 0;
540
-
541
- for (var i = 0; i < 16; ++i) {
542
- buf[offset + i] = rnds[i];
543
- }
544
-
545
- return buf;
546
- }
547
-
548
- return stringify(rnds);
549
- }
550
-
551
478
  class StorageUtilityBrowser extends StorageUtility {
552
479
  constructor(secureStorage, insecureStorage) {
553
480
  super(secureStorage, insecureStorage);
554
481
  }
555
482
  }
556
483
 
557
- function processErrorResponse(responseBody, options) {
558
- var _a, _b, _c, _d;
559
- if (responseBody.error === "invalid_redirect_uri") {
560
- throw new Error(`Dynamic client registration failed: the provided redirect uri [${(_a = options.redirectUrl) === null || _a === void 0 ? void 0 : _a.toString()}] is invalid - ${(_b = responseBody.error_description) !== null && _b !== void 0 ? _b : ""}`);
561
- }
562
- if (responseBody.error === "invalid_client_metadata") {
563
- throw new Error(`Dynamic client registration failed: the provided client metadata ${JSON.stringify(options)} is invalid - ${(_c = responseBody.error_description) !== null && _c !== void 0 ? _c : ""}`);
564
- }
565
- throw new Error(`Dynamic client registration failed: ${responseBody.error} - ${(_d = responseBody.error_description) !== null && _d !== void 0 ? _d : ""}`);
566
- }
567
- function validateRegistrationResponse(responseBody, options) {
568
- if (responseBody.client_id === undefined) {
569
- throw new Error(`Dynamic client registration failed: no client_id has been found on ${JSON.stringify(responseBody)}`);
570
- }
571
- if (options.redirectUrl &&
572
- (responseBody.redirect_uris === undefined ||
573
- responseBody.redirect_uris[0] !== options.redirectUrl.toString())) {
574
- throw new Error(`Dynamic client registration failed: the returned redirect URIs ${JSON.stringify(responseBody.redirect_uris)} don't match the provided ${JSON.stringify([
575
- options.redirectUrl.toString(),
576
- ])}`);
577
- }
578
- }
579
- async function registerClient(options, issuerConfig) {
580
- var _a;
581
- if (!issuerConfig.registrationEndpoint) {
582
- throw new Error("Dynamic Registration could not be completed because the issuer has no registration endpoint.");
583
- }
584
- if (!Array.isArray(issuerConfig.idTokenSigningAlgValuesSupported)) {
585
- throw new Error("The OIDC issuer discovery profile is missing the 'id_token_signing_alg_values_supported' value, which is mandatory.");
586
- }
587
- const signingAlg = determineSigningAlg(issuerConfig.idTokenSigningAlgValuesSupported, PREFERRED_SIGNING_ALG);
588
- const config = {
589
- client_name: options.clientName,
590
- application_type: "web",
591
- redirect_uris: [(_a = options.redirectUrl) === null || _a === void 0 ? void 0 : _a.toString()],
592
- subject_type: "public",
593
- token_endpoint_auth_method: "client_secret_basic",
594
- id_token_signed_response_alg: signingAlg,
595
- grant_types: ["authorization_code", "refresh_token"],
596
- };
597
- const headers = {
598
- "Content-Type": "application/json",
599
- };
600
- if (options.registrationAccessToken) {
601
- headers.Authorization = `Bearer ${options.registrationAccessToken}`;
602
- }
603
- const registerResponse = await fetch(issuerConfig.registrationEndpoint.toString(), {
604
- method: "POST",
605
- headers,
606
- body: JSON.stringify(config),
607
- });
608
- if (registerResponse.ok) {
609
- const responseBody = await registerResponse.json();
610
- validateRegistrationResponse(responseBody, options);
611
- return {
612
- clientId: responseBody.client_id,
613
- clientSecret: responseBody.client_secret,
614
- idTokenSignedResponseAlg: responseBody.id_token_signed_response_alg,
615
- clientType: "dynamic",
616
- };
617
- }
618
- if (registerResponse.status === 400) {
619
- processErrorResponse(await registerResponse.json(), options);
620
- }
621
- throw new Error(`Dynamic client registration failed: the server returned ${registerResponse.status} ${registerResponse.statusText} - ${await registerResponse.text()}`);
622
- }
623
-
624
- function hasError(value) {
625
- return value.error !== undefined && typeof value.error === "string";
626
- }
627
- function hasErrorDescription(value) {
628
- return (value.error_description !== undefined &&
629
- typeof value.error_description === "string");
630
- }
631
- function hasErrorUri(value) {
632
- return value.error_uri !== undefined && typeof value.error_uri === "string";
633
- }
634
- function hasAccessToken(value) {
635
- return (value.access_token !== undefined && typeof value.access_token === "string");
636
- }
637
- function hasIdToken(value) {
638
- return value.id_token !== undefined && typeof value.id_token === "string";
639
- }
640
- function hasRefreshToken(value) {
641
- return (value.refresh_token !== undefined && typeof value.refresh_token === "string");
642
- }
643
- function hasTokenType(value) {
644
- return value.token_type !== undefined && typeof value.token_type === "string";
645
- }
646
- function hasExpiresIn(value) {
647
- return value.expires_in === undefined || typeof value.expires_in === "number";
648
- }
649
- function validatePreconditions(issuer, data) {
650
- if (data.grantType &&
651
- (!issuer.grantTypesSupported ||
652
- !issuer.grantTypesSupported.includes(data.grantType))) {
653
- throw new Error(`The issuer [${issuer.issuer}] does not support the [${data.grantType}] grant`);
654
- }
655
- if (!issuer.tokenEndpoint) {
656
- throw new Error(`This issuer [${issuer.issuer}] does not have a token endpoint`);
657
- }
658
- }
659
- function validateTokenEndpointResponse(tokenResponse, dpop) {
660
- if (hasError(tokenResponse)) {
661
- throw new OidcProviderError(`Token endpoint returned error [${tokenResponse.error}]${hasErrorDescription(tokenResponse)
662
- ? `: ${tokenResponse.error_description}`
663
- : ""}${hasErrorUri(tokenResponse) ? ` (see ${tokenResponse.error_uri})` : ""}`, tokenResponse.error, hasErrorDescription(tokenResponse)
664
- ? tokenResponse.error_description
665
- : undefined);
666
- }
667
- if (!hasAccessToken(tokenResponse)) {
668
- throw new InvalidResponseError(["access_token"]);
669
- }
670
- if (!hasIdToken(tokenResponse)) {
671
- throw new InvalidResponseError(["id_token"]);
672
- }
673
- if (!hasTokenType(tokenResponse)) {
674
- throw new InvalidResponseError(["token_type"]);
675
- }
676
- if (!hasExpiresIn(tokenResponse)) {
677
- throw new InvalidResponseError(["expires_in"]);
678
- }
679
- if (!dpop && tokenResponse.token_type.toLowerCase() !== "bearer") {
680
- throw new Error(`Invalid token endpoint response: requested a [Bearer] token, but got a 'token_type' value of [${tokenResponse.token_type}].`);
681
- }
682
- return tokenResponse;
683
- }
684
- async function getTokens(issuer, client, data, dpop) {
685
- validatePreconditions(issuer, data);
686
- const headers = {
687
- "content-type": "application/x-www-form-urlencoded",
688
- };
689
- let dpopKey;
690
- if (dpop) {
691
- dpopKey = await generateDpopKeyPair();
692
- headers.DPoP = await createDpopHeader(issuer.tokenEndpoint, "POST", dpopKey);
693
- }
694
- if (client.clientSecret) {
695
- headers.Authorization = `Basic ${btoa(`${client.clientId}:${client.clientSecret}`)}`;
696
- }
697
- const requestBody = {
698
- grant_type: data.grantType,
699
- redirect_uri: data.redirectUrl,
700
- code: data.code,
701
- code_verifier: data.codeVerifier,
702
- client_id: client.clientId,
703
- };
704
- const tokenRequestInit = {
705
- method: "POST",
706
- headers,
707
- body: new URLSearchParams(requestBody).toString(),
708
- };
709
- const rawTokenResponse = await await fetch(issuer.tokenEndpoint, tokenRequestInit);
710
- const jsonTokenResponse = (await rawTokenResponse.json());
711
- const tokenResponse = validateTokenEndpointResponse(jsonTokenResponse, dpop);
712
- const webId = await getWebidFromTokenPayload(tokenResponse.id_token, issuer.jwksUri, issuer.issuer, client.clientId);
713
- return {
714
- accessToken: tokenResponse.access_token,
715
- idToken: tokenResponse.id_token,
716
- refreshToken: hasRefreshToken(tokenResponse)
717
- ? tokenResponse.refresh_token
718
- : undefined,
719
- webId,
720
- dpopKey,
721
- expiresIn: tokenResponse.expires_in,
722
- };
723
- }
724
- async function getBearerToken(redirectUrl) {
725
- let signinResponse;
726
- try {
727
- const client = new OidcClient({
728
- response_mode: "query",
729
- loadUserInfo: false,
730
- });
731
- signinResponse = await client.processSigninResponse(redirectUrl);
732
- if (client.settings.metadata === undefined) {
733
- throw new Error("Cannot retrieve issuer metadata from client information in storage.");
734
- }
735
- if (client.settings.metadata.jwks_uri === undefined) {
736
- throw new Error("Missing some issuer metadata from client information in storage: 'jwks_uri' is undefined");
737
- }
738
- if (client.settings.metadata.issuer === undefined) {
739
- throw new Error("Missing some issuer metadata from client information in storage: 'issuer' is undefined");
740
- }
741
- if (client.settings.client_id === undefined) {
742
- throw new Error("Missing some client information in storage: 'client_id' is undefined");
743
- }
744
- const webId = await getWebidFromTokenPayload(signinResponse.id_token, client.settings.metadata.jwks_uri, client.settings.metadata.issuer, client.settings.client_id);
745
- return {
746
- accessToken: signinResponse.access_token,
747
- idToken: signinResponse.id_token,
748
- webId,
749
- refreshToken: signinResponse.refresh_token,
750
- };
751
- }
752
- catch (err) {
753
- throw new Error(`Problem handling Auth Code Grant (Flow) redirect - URL [${redirectUrl}]: ${err}`);
754
- }
755
- }
756
- async function getDpopToken(issuer, client, data) {
757
- return getTokens(issuer, client, data, true);
758
- }
759
-
760
- async function refresh(refreshToken, issuer, client, dpopKey) {
761
- const requestBody = {
762
- grant_type: "refresh_token",
763
- refresh_token: refreshToken,
764
- scope: "openid offline_access",
765
- };
766
- let dpopHeader = {};
767
- if (dpopKey !== undefined) {
768
- dpopHeader = {
769
- DPoP: await createDpopHeader(issuer.tokenEndpoint, "POST", dpopKey),
770
- };
771
- }
772
- let authHeader = {};
773
- if (client.clientSecret !== undefined) {
774
- authHeader = {
775
- Authorization: `Basic ${btoa(`${client.clientId}:${client.clientSecret}`)}`,
776
- };
777
- }
778
- const rawResponse = await fetch(issuer.tokenEndpoint, {
779
- method: "POST",
780
- body: new URLSearchParams(requestBody).toString(),
781
- headers: {
782
- ...dpopHeader,
783
- ...authHeader,
784
- "Content-Type": "application/x-www-form-urlencoded",
785
- },
786
- });
787
- let response;
788
- try {
789
- response = await rawResponse.json();
790
- }
791
- catch (e) {
792
- throw new Error(`The token endpoint of issuer ${issuer.issuer} returned a malformed response.`);
793
- }
794
- const validatedResponse = validateTokenEndpointResponse(response, dpopKey !== undefined);
795
- const webId = await getWebidFromTokenPayload(validatedResponse.id_token, issuer.jwksUri, issuer.issuer, client.clientId);
796
- return {
797
- accessToken: validatedResponse.access_token,
798
- idToken: validatedResponse.id_token,
799
- refreshToken: typeof validatedResponse.refresh_token === "string"
800
- ? validatedResponse.refresh_token
801
- : undefined,
802
- webId,
803
- dpopKey,
804
- expiresIn: validatedResponse.expires_in,
805
- };
806
- }
807
-
808
- function removeOidcQueryParam(redirectUrl) {
809
- const cleanedUrl = new URL(redirectUrl);
810
- cleanedUrl.searchParams.delete("code");
811
- cleanedUrl.searchParams.delete("state");
812
- cleanedUrl.hash = "";
813
- return cleanedUrl.toString();
814
- }
815
- async function clearOidcPersistentStorage() {
816
- const client = new OidcClient({
817
- response_mode: "query",
818
- });
819
- await client.clearStaleState(new WebStorageStateStore({}));
820
- const myStorage = window.localStorage;
821
- const itemsToRemove = [];
822
- for (let i = 0; i <= myStorage.length; i += 1) {
823
- const key = myStorage.key(i);
824
- if (key &&
825
- (key.match(/^oidc\..+$/) ||
826
- key.match(/^solidClientAuthenticationUser:.+$/))) {
827
- itemsToRemove.push(key);
828
- }
829
- }
830
- itemsToRemove.forEach((key) => myStorage.removeItem(key));
831
- }
832
-
833
484
  const globalFetch = (request, init) => window.fetch(request, init);
834
485
  class ClientAuthentication {
835
486
  constructor(loginHandler, redirectHandler, logoutHandler, sessionInfoManager, issuerConfigFetcher) {
package/dist/index.js CHANGED
@@ -3,7 +3,8 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var solidClientAuthnCore = require('@inrupt/solid-client-authn-core');
6
- var oidcClient = require('@inrupt/oidc-client');
6
+ var uuid = require('uuid');
7
+ var oidcClientExt = require('@inrupt/oidc-client-ext');
7
8
 
8
9
  var domain;
9
10
 
@@ -477,362 +478,12 @@ function unwrapListeners(arr) {
477
478
  return ret;
478
479
  }
479
480
 
480
- // Unique ID creation requires a high quality random # generator. In the browser we therefore
481
- // require the crypto API and do not support built-in fallback to lower quality random number
482
- // generators (like Math.random()).
483
- var getRandomValues;
484
- var rnds8 = new Uint8Array(16);
485
- function rng() {
486
- // lazy load so that environments that need to polyfill have a chance to do so
487
- if (!getRandomValues) {
488
- // getRandomValues needs to be invoked in a context where "this" is a Crypto implementation. Also,
489
- // find the complete implementation of crypto (msCrypto) on IE11.
490
- getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto) || typeof msCrypto !== 'undefined' && typeof msCrypto.getRandomValues === 'function' && msCrypto.getRandomValues.bind(msCrypto);
491
-
492
- if (!getRandomValues) {
493
- throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported');
494
- }
495
- }
496
-
497
- return getRandomValues(rnds8);
498
- }
499
-
500
- var REGEX = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;
501
-
502
- function validate(uuid) {
503
- return typeof uuid === 'string' && REGEX.test(uuid);
504
- }
505
-
506
- /**
507
- * Convert array of 16 byte values to UUID string format of the form:
508
- * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
509
- */
510
-
511
- var byteToHex = [];
512
-
513
- for (var i = 0; i < 256; ++i) {
514
- byteToHex.push((i + 0x100).toString(16).substr(1));
515
- }
516
-
517
- function stringify(arr) {
518
- var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
519
- // Note: Be careful editing this code! It's been tuned for performance
520
- // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434
521
- var uuid = (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); // Consistency check for valid UUID. If this throws, it's likely due to one
522
- // of the following:
523
- // - One or more input array values don't map to a hex octet (leading to
524
- // "undefined" in the uuid)
525
- // - Invalid input values for the RFC `version` or `variant` fields
526
-
527
- if (!validate(uuid)) {
528
- throw TypeError('Stringified UUID is invalid');
529
- }
530
-
531
- return uuid;
532
- }
533
-
534
- function v4(options, buf, offset) {
535
- options = options || {};
536
- var rnds = options.random || (options.rng || rng)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
537
-
538
- rnds[6] = rnds[6] & 0x0f | 0x40;
539
- rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided
540
-
541
- if (buf) {
542
- offset = offset || 0;
543
-
544
- for (var i = 0; i < 16; ++i) {
545
- buf[offset + i] = rnds[i];
546
- }
547
-
548
- return buf;
549
- }
550
-
551
- return stringify(rnds);
552
- }
553
-
554
481
  class StorageUtilityBrowser extends solidClientAuthnCore.StorageUtility {
555
482
  constructor(secureStorage, insecureStorage) {
556
483
  super(secureStorage, insecureStorage);
557
484
  }
558
485
  }
559
486
 
560
- function processErrorResponse(responseBody, options) {
561
- var _a, _b, _c, _d;
562
- if (responseBody.error === "invalid_redirect_uri") {
563
- throw new Error(`Dynamic client registration failed: the provided redirect uri [${(_a = options.redirectUrl) === null || _a === void 0 ? void 0 : _a.toString()}] is invalid - ${(_b = responseBody.error_description) !== null && _b !== void 0 ? _b : ""}`);
564
- }
565
- if (responseBody.error === "invalid_client_metadata") {
566
- throw new Error(`Dynamic client registration failed: the provided client metadata ${JSON.stringify(options)} is invalid - ${(_c = responseBody.error_description) !== null && _c !== void 0 ? _c : ""}`);
567
- }
568
- throw new Error(`Dynamic client registration failed: ${responseBody.error} - ${(_d = responseBody.error_description) !== null && _d !== void 0 ? _d : ""}`);
569
- }
570
- function validateRegistrationResponse(responseBody, options) {
571
- if (responseBody.client_id === undefined) {
572
- throw new Error(`Dynamic client registration failed: no client_id has been found on ${JSON.stringify(responseBody)}`);
573
- }
574
- if (options.redirectUrl &&
575
- (responseBody.redirect_uris === undefined ||
576
- responseBody.redirect_uris[0] !== options.redirectUrl.toString())) {
577
- throw new Error(`Dynamic client registration failed: the returned redirect URIs ${JSON.stringify(responseBody.redirect_uris)} don't match the provided ${JSON.stringify([
578
- options.redirectUrl.toString(),
579
- ])}`);
580
- }
581
- }
582
- async function registerClient(options, issuerConfig) {
583
- var _a;
584
- if (!issuerConfig.registrationEndpoint) {
585
- throw new Error("Dynamic Registration could not be completed because the issuer has no registration endpoint.");
586
- }
587
- if (!Array.isArray(issuerConfig.idTokenSigningAlgValuesSupported)) {
588
- throw new Error("The OIDC issuer discovery profile is missing the 'id_token_signing_alg_values_supported' value, which is mandatory.");
589
- }
590
- const signingAlg = solidClientAuthnCore.determineSigningAlg(issuerConfig.idTokenSigningAlgValuesSupported, solidClientAuthnCore.PREFERRED_SIGNING_ALG);
591
- const config = {
592
- client_name: options.clientName,
593
- application_type: "web",
594
- redirect_uris: [(_a = options.redirectUrl) === null || _a === void 0 ? void 0 : _a.toString()],
595
- subject_type: "public",
596
- token_endpoint_auth_method: "client_secret_basic",
597
- id_token_signed_response_alg: signingAlg,
598
- grant_types: ["authorization_code", "refresh_token"],
599
- };
600
- const headers = {
601
- "Content-Type": "application/json",
602
- };
603
- if (options.registrationAccessToken) {
604
- headers.Authorization = `Bearer ${options.registrationAccessToken}`;
605
- }
606
- const registerResponse = await fetch(issuerConfig.registrationEndpoint.toString(), {
607
- method: "POST",
608
- headers,
609
- body: JSON.stringify(config),
610
- });
611
- if (registerResponse.ok) {
612
- const responseBody = await registerResponse.json();
613
- validateRegistrationResponse(responseBody, options);
614
- return {
615
- clientId: responseBody.client_id,
616
- clientSecret: responseBody.client_secret,
617
- idTokenSignedResponseAlg: responseBody.id_token_signed_response_alg,
618
- clientType: "dynamic",
619
- };
620
- }
621
- if (registerResponse.status === 400) {
622
- processErrorResponse(await registerResponse.json(), options);
623
- }
624
- throw new Error(`Dynamic client registration failed: the server returned ${registerResponse.status} ${registerResponse.statusText} - ${await registerResponse.text()}`);
625
- }
626
-
627
- function hasError(value) {
628
- return value.error !== undefined && typeof value.error === "string";
629
- }
630
- function hasErrorDescription(value) {
631
- return (value.error_description !== undefined &&
632
- typeof value.error_description === "string");
633
- }
634
- function hasErrorUri(value) {
635
- return value.error_uri !== undefined && typeof value.error_uri === "string";
636
- }
637
- function hasAccessToken(value) {
638
- return (value.access_token !== undefined && typeof value.access_token === "string");
639
- }
640
- function hasIdToken(value) {
641
- return value.id_token !== undefined && typeof value.id_token === "string";
642
- }
643
- function hasRefreshToken(value) {
644
- return (value.refresh_token !== undefined && typeof value.refresh_token === "string");
645
- }
646
- function hasTokenType(value) {
647
- return value.token_type !== undefined && typeof value.token_type === "string";
648
- }
649
- function hasExpiresIn(value) {
650
- return value.expires_in === undefined || typeof value.expires_in === "number";
651
- }
652
- function validatePreconditions(issuer, data) {
653
- if (data.grantType &&
654
- (!issuer.grantTypesSupported ||
655
- !issuer.grantTypesSupported.includes(data.grantType))) {
656
- throw new Error(`The issuer [${issuer.issuer}] does not support the [${data.grantType}] grant`);
657
- }
658
- if (!issuer.tokenEndpoint) {
659
- throw new Error(`This issuer [${issuer.issuer}] does not have a token endpoint`);
660
- }
661
- }
662
- function validateTokenEndpointResponse(tokenResponse, dpop) {
663
- if (hasError(tokenResponse)) {
664
- throw new solidClientAuthnCore.OidcProviderError(`Token endpoint returned error [${tokenResponse.error}]${hasErrorDescription(tokenResponse)
665
- ? `: ${tokenResponse.error_description}`
666
- : ""}${hasErrorUri(tokenResponse) ? ` (see ${tokenResponse.error_uri})` : ""}`, tokenResponse.error, hasErrorDescription(tokenResponse)
667
- ? tokenResponse.error_description
668
- : undefined);
669
- }
670
- if (!hasAccessToken(tokenResponse)) {
671
- throw new solidClientAuthnCore.InvalidResponseError(["access_token"]);
672
- }
673
- if (!hasIdToken(tokenResponse)) {
674
- throw new solidClientAuthnCore.InvalidResponseError(["id_token"]);
675
- }
676
- if (!hasTokenType(tokenResponse)) {
677
- throw new solidClientAuthnCore.InvalidResponseError(["token_type"]);
678
- }
679
- if (!hasExpiresIn(tokenResponse)) {
680
- throw new solidClientAuthnCore.InvalidResponseError(["expires_in"]);
681
- }
682
- if (!dpop && tokenResponse.token_type.toLowerCase() !== "bearer") {
683
- throw new Error(`Invalid token endpoint response: requested a [Bearer] token, but got a 'token_type' value of [${tokenResponse.token_type}].`);
684
- }
685
- return tokenResponse;
686
- }
687
- async function getTokens(issuer, client, data, dpop) {
688
- validatePreconditions(issuer, data);
689
- const headers = {
690
- "content-type": "application/x-www-form-urlencoded",
691
- };
692
- let dpopKey;
693
- if (dpop) {
694
- dpopKey = await solidClientAuthnCore.generateDpopKeyPair();
695
- headers.DPoP = await solidClientAuthnCore.createDpopHeader(issuer.tokenEndpoint, "POST", dpopKey);
696
- }
697
- if (client.clientSecret) {
698
- headers.Authorization = `Basic ${btoa(`${client.clientId}:${client.clientSecret}`)}`;
699
- }
700
- const requestBody = {
701
- grant_type: data.grantType,
702
- redirect_uri: data.redirectUrl,
703
- code: data.code,
704
- code_verifier: data.codeVerifier,
705
- client_id: client.clientId,
706
- };
707
- const tokenRequestInit = {
708
- method: "POST",
709
- headers,
710
- body: new URLSearchParams(requestBody).toString(),
711
- };
712
- const rawTokenResponse = await await fetch(issuer.tokenEndpoint, tokenRequestInit);
713
- const jsonTokenResponse = (await rawTokenResponse.json());
714
- const tokenResponse = validateTokenEndpointResponse(jsonTokenResponse, dpop);
715
- const webId = await solidClientAuthnCore.getWebidFromTokenPayload(tokenResponse.id_token, issuer.jwksUri, issuer.issuer, client.clientId);
716
- return {
717
- accessToken: tokenResponse.access_token,
718
- idToken: tokenResponse.id_token,
719
- refreshToken: hasRefreshToken(tokenResponse)
720
- ? tokenResponse.refresh_token
721
- : undefined,
722
- webId,
723
- dpopKey,
724
- expiresIn: tokenResponse.expires_in,
725
- };
726
- }
727
- async function getBearerToken(redirectUrl) {
728
- let signinResponse;
729
- try {
730
- const client = new oidcClient.OidcClient({
731
- response_mode: "query",
732
- loadUserInfo: false,
733
- });
734
- signinResponse = await client.processSigninResponse(redirectUrl);
735
- if (client.settings.metadata === undefined) {
736
- throw new Error("Cannot retrieve issuer metadata from client information in storage.");
737
- }
738
- if (client.settings.metadata.jwks_uri === undefined) {
739
- throw new Error("Missing some issuer metadata from client information in storage: 'jwks_uri' is undefined");
740
- }
741
- if (client.settings.metadata.issuer === undefined) {
742
- throw new Error("Missing some issuer metadata from client information in storage: 'issuer' is undefined");
743
- }
744
- if (client.settings.client_id === undefined) {
745
- throw new Error("Missing some client information in storage: 'client_id' is undefined");
746
- }
747
- const webId = await solidClientAuthnCore.getWebidFromTokenPayload(signinResponse.id_token, client.settings.metadata.jwks_uri, client.settings.metadata.issuer, client.settings.client_id);
748
- return {
749
- accessToken: signinResponse.access_token,
750
- idToken: signinResponse.id_token,
751
- webId,
752
- refreshToken: signinResponse.refresh_token,
753
- };
754
- }
755
- catch (err) {
756
- throw new Error(`Problem handling Auth Code Grant (Flow) redirect - URL [${redirectUrl}]: ${err}`);
757
- }
758
- }
759
- async function getDpopToken(issuer, client, data) {
760
- return getTokens(issuer, client, data, true);
761
- }
762
-
763
- async function refresh(refreshToken, issuer, client, dpopKey) {
764
- const requestBody = {
765
- grant_type: "refresh_token",
766
- refresh_token: refreshToken,
767
- scope: "openid offline_access",
768
- };
769
- let dpopHeader = {};
770
- if (dpopKey !== undefined) {
771
- dpopHeader = {
772
- DPoP: await solidClientAuthnCore.createDpopHeader(issuer.tokenEndpoint, "POST", dpopKey),
773
- };
774
- }
775
- let authHeader = {};
776
- if (client.clientSecret !== undefined) {
777
- authHeader = {
778
- Authorization: `Basic ${btoa(`${client.clientId}:${client.clientSecret}`)}`,
779
- };
780
- }
781
- const rawResponse = await fetch(issuer.tokenEndpoint, {
782
- method: "POST",
783
- body: new URLSearchParams(requestBody).toString(),
784
- headers: {
785
- ...dpopHeader,
786
- ...authHeader,
787
- "Content-Type": "application/x-www-form-urlencoded",
788
- },
789
- });
790
- let response;
791
- try {
792
- response = await rawResponse.json();
793
- }
794
- catch (e) {
795
- throw new Error(`The token endpoint of issuer ${issuer.issuer} returned a malformed response.`);
796
- }
797
- const validatedResponse = validateTokenEndpointResponse(response, dpopKey !== undefined);
798
- const webId = await solidClientAuthnCore.getWebidFromTokenPayload(validatedResponse.id_token, issuer.jwksUri, issuer.issuer, client.clientId);
799
- return {
800
- accessToken: validatedResponse.access_token,
801
- idToken: validatedResponse.id_token,
802
- refreshToken: typeof validatedResponse.refresh_token === "string"
803
- ? validatedResponse.refresh_token
804
- : undefined,
805
- webId,
806
- dpopKey,
807
- expiresIn: validatedResponse.expires_in,
808
- };
809
- }
810
-
811
- function removeOidcQueryParam(redirectUrl) {
812
- const cleanedUrl = new URL(redirectUrl);
813
- cleanedUrl.searchParams.delete("code");
814
- cleanedUrl.searchParams.delete("state");
815
- cleanedUrl.hash = "";
816
- return cleanedUrl.toString();
817
- }
818
- async function clearOidcPersistentStorage() {
819
- const client = new oidcClient.OidcClient({
820
- response_mode: "query",
821
- });
822
- await client.clearStaleState(new oidcClient.WebStorageStateStore({}));
823
- const myStorage = window.localStorage;
824
- const itemsToRemove = [];
825
- for (let i = 0; i <= myStorage.length; i += 1) {
826
- const key = myStorage.key(i);
827
- if (key &&
828
- (key.match(/^oidc\..+$/) ||
829
- key.match(/^solidClientAuthenticationUser:.+$/))) {
830
- itemsToRemove.push(key);
831
- }
832
- }
833
- itemsToRemove.forEach((key) => myStorage.removeItem(key));
834
- }
835
-
836
487
  const globalFetch = (request, init) => window.fetch(request, init);
837
488
  class ClientAuthentication {
838
489
  constructor(loginHandler, redirectHandler, logoutHandler, sessionInfoManager, issuerConfigFetcher) {
@@ -844,7 +495,7 @@ class ClientAuthentication {
844
495
  this.login = async (options, eventEmitter) => {
845
496
  var _a, _b;
846
497
  await this.sessionInfoManager.clear(options.sessionId);
847
- const redirectUrl = removeOidcQueryParam((_a = options.redirectUrl) !== null && _a !== void 0 ? _a : window.location.href);
498
+ const redirectUrl = oidcClientExt.removeOidcQueryParam((_a = options.redirectUrl) !== null && _a !== void 0 ? _a : window.location.href);
848
499
  await this.loginHandler.handle({
849
500
  ...options,
850
501
  redirectUrl,
@@ -962,7 +613,7 @@ class AuthorizationCodeWithPkceOidcHandler {
962
613
  code_verifier: true,
963
614
  prompt: (_a = oidcLoginOptions.prompt) !== null && _a !== void 0 ? _a : "consent",
964
615
  };
965
- const oidcClientLibrary = new oidcClient.OidcClient(oidcOptions);
616
+ const oidcClientLibrary = new oidcClientExt.OidcClient(oidcOptions);
966
617
  const { redirector } = this;
967
618
  const storage = this.storageUtility;
968
619
  try {
@@ -1118,7 +769,7 @@ class IssuerConfigFetcher {
1118
769
  function getUnauthenticatedSession() {
1119
770
  return {
1120
771
  isLoggedIn: false,
1121
- sessionId: v4(),
772
+ sessionId: uuid.v4(),
1122
773
  fetch,
1123
774
  };
1124
775
  }
@@ -1128,7 +779,7 @@ async function clear(sessionId, storage) {
1128
779
  storage.deleteAllUserData(sessionId, { secure: true }),
1129
780
  storage.delete("clientKey", { secure: false }),
1130
781
  ]);
1131
- await clearOidcPersistentStorage();
782
+ await oidcClientExt.clearOidcPersistentStorage();
1132
783
  }
1133
784
  class SessionInfoManager {
1134
785
  constructor(storageUtility) {
@@ -1266,7 +917,7 @@ class AuthCodeRedirectHandler {
1266
917
  let tokens;
1267
918
  const tokenCreatedAt = Date.now();
1268
919
  if (isDpop) {
1269
- tokens = await getDpopToken(issuerConfig, client, {
920
+ tokens = await oidcClientExt.getDpopToken(issuerConfig, client, {
1270
921
  grantType: "authorization_code",
1271
922
  code: url.searchParams.get("code"),
1272
923
  codeVerifier,
@@ -1275,7 +926,7 @@ class AuthCodeRedirectHandler {
1275
926
  window.localStorage.removeItem(`oidc.${oauthState}`);
1276
927
  }
1277
928
  else {
1278
- tokens = await getBearerToken(url.toString());
929
+ tokens = await oidcClientExt.getBearerToken(url.toString());
1279
930
  }
1280
931
  let refreshOptions;
1281
932
  if (tokens.refreshToken !== undefined) {
@@ -1414,7 +1065,7 @@ class ClientRegistrar {
1414
1065
  extendedOptions.registrationAccessToken =
1415
1066
  (_a = extendedOptions.registrationAccessToken) !== null && _a !== void 0 ? _a : (await this.storageUtility.getForUser(options.sessionId, "registrationAccessToken"));
1416
1067
  try {
1417
- const registeredClient = await registerClient(extendedOptions, issuerConfig);
1068
+ const registeredClient = await oidcClientExt.registerClient(extendedOptions, issuerConfig);
1418
1069
  const infoToSave = {
1419
1070
  clientId: registeredClient.clientId,
1420
1071
  };
@@ -1471,7 +1122,7 @@ class TokenRefresher {
1471
1122
  if (oidcContext.dpop && dpopKey === undefined) {
1472
1123
  throw new Error(`For session [${sessionId}], the key bound to the DPoP access token must be provided to refresh said access token.`);
1473
1124
  }
1474
- const tokenSet = await refresh(refreshToken, oidcContext.issuerConfig, clientInfo, dpopKey);
1125
+ const tokenSet = await oidcClientExt.refresh(refreshToken, oidcContext.issuerConfig, clientInfo, dpopKey);
1475
1126
  if (tokenSet.refreshToken !== undefined) {
1476
1127
  eventEmitter === null || eventEmitter === void 0 ? void 0 : eventEmitter.emit(solidClientAuthnCore.EVENTS.NEW_REFRESH_TOKEN, tokenSet.refreshToken);
1477
1128
  await this.storageUtility.setForUser(sessionId, {
@@ -1612,7 +1263,7 @@ class Session extends EventEmitter {
1612
1263
  }
1613
1264
  else {
1614
1265
  this.info = {
1615
- sessionId: sessionId !== null && sessionId !== void 0 ? sessionId : v4(),
1266
+ sessionId: sessionId !== null && sessionId !== void 0 ? sessionId : uuid.v4(),
1616
1267
  isLoggedIn: false,
1617
1268
  };
1618
1269
  }
@@ -1,8 +1,8 @@
1
1
  (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@inrupt/solid-client-authn-core'), require('@inrupt/oidc-client')) :
3
- typeof define === 'function' && define.amd ? define(['exports', '@inrupt/solid-client-authn-core', '@inrupt/oidc-client'], factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.solidClientAuthentication = {}, global.solidClientAuthnCore, global.oidcClient));
5
- })(this, (function (exports, solidClientAuthnCore, oidcClient) { 'use strict';
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@inrupt/solid-client-authn-core'), require('uuid'), require('@inrupt/oidc-client-ext')) :
3
+ typeof define === 'function' && define.amd ? define(['exports', '@inrupt/solid-client-authn-core', 'uuid', '@inrupt/oidc-client-ext'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.solidClientAuthentication = {}, global.solidClientAuthnCore, global.uuid, global.oidcClientExt));
5
+ })(this, (function (exports, solidClientAuthnCore, uuid, oidcClientExt) { 'use strict';
6
6
 
7
7
  var domain;
8
8
 
@@ -476,362 +476,12 @@
476
476
  return ret;
477
477
  }
478
478
 
479
- // Unique ID creation requires a high quality random # generator. In the browser we therefore
480
- // require the crypto API and do not support built-in fallback to lower quality random number
481
- // generators (like Math.random()).
482
- var getRandomValues;
483
- var rnds8 = new Uint8Array(16);
484
- function rng() {
485
- // lazy load so that environments that need to polyfill have a chance to do so
486
- if (!getRandomValues) {
487
- // getRandomValues needs to be invoked in a context where "this" is a Crypto implementation. Also,
488
- // find the complete implementation of crypto (msCrypto) on IE11.
489
- getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto) || typeof msCrypto !== 'undefined' && typeof msCrypto.getRandomValues === 'function' && msCrypto.getRandomValues.bind(msCrypto);
490
-
491
- if (!getRandomValues) {
492
- throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported');
493
- }
494
- }
495
-
496
- return getRandomValues(rnds8);
497
- }
498
-
499
- var REGEX = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;
500
-
501
- function validate(uuid) {
502
- return typeof uuid === 'string' && REGEX.test(uuid);
503
- }
504
-
505
- /**
506
- * Convert array of 16 byte values to UUID string format of the form:
507
- * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
508
- */
509
-
510
- var byteToHex = [];
511
-
512
- for (var i = 0; i < 256; ++i) {
513
- byteToHex.push((i + 0x100).toString(16).substr(1));
514
- }
515
-
516
- function stringify(arr) {
517
- var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
518
- // Note: Be careful editing this code! It's been tuned for performance
519
- // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434
520
- var uuid = (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); // Consistency check for valid UUID. If this throws, it's likely due to one
521
- // of the following:
522
- // - One or more input array values don't map to a hex octet (leading to
523
- // "undefined" in the uuid)
524
- // - Invalid input values for the RFC `version` or `variant` fields
525
-
526
- if (!validate(uuid)) {
527
- throw TypeError('Stringified UUID is invalid');
528
- }
529
-
530
- return uuid;
531
- }
532
-
533
- function v4(options, buf, offset) {
534
- options = options || {};
535
- var rnds = options.random || (options.rng || rng)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
536
-
537
- rnds[6] = rnds[6] & 0x0f | 0x40;
538
- rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided
539
-
540
- if (buf) {
541
- offset = offset || 0;
542
-
543
- for (var i = 0; i < 16; ++i) {
544
- buf[offset + i] = rnds[i];
545
- }
546
-
547
- return buf;
548
- }
549
-
550
- return stringify(rnds);
551
- }
552
-
553
479
  class StorageUtilityBrowser extends solidClientAuthnCore.StorageUtility {
554
480
  constructor(secureStorage, insecureStorage) {
555
481
  super(secureStorage, insecureStorage);
556
482
  }
557
483
  }
558
484
 
559
- function processErrorResponse(responseBody, options) {
560
- var _a, _b, _c, _d;
561
- if (responseBody.error === "invalid_redirect_uri") {
562
- throw new Error(`Dynamic client registration failed: the provided redirect uri [${(_a = options.redirectUrl) === null || _a === void 0 ? void 0 : _a.toString()}] is invalid - ${(_b = responseBody.error_description) !== null && _b !== void 0 ? _b : ""}`);
563
- }
564
- if (responseBody.error === "invalid_client_metadata") {
565
- throw new Error(`Dynamic client registration failed: the provided client metadata ${JSON.stringify(options)} is invalid - ${(_c = responseBody.error_description) !== null && _c !== void 0 ? _c : ""}`);
566
- }
567
- throw new Error(`Dynamic client registration failed: ${responseBody.error} - ${(_d = responseBody.error_description) !== null && _d !== void 0 ? _d : ""}`);
568
- }
569
- function validateRegistrationResponse(responseBody, options) {
570
- if (responseBody.client_id === undefined) {
571
- throw new Error(`Dynamic client registration failed: no client_id has been found on ${JSON.stringify(responseBody)}`);
572
- }
573
- if (options.redirectUrl &&
574
- (responseBody.redirect_uris === undefined ||
575
- responseBody.redirect_uris[0] !== options.redirectUrl.toString())) {
576
- throw new Error(`Dynamic client registration failed: the returned redirect URIs ${JSON.stringify(responseBody.redirect_uris)} don't match the provided ${JSON.stringify([
577
- options.redirectUrl.toString(),
578
- ])}`);
579
- }
580
- }
581
- async function registerClient(options, issuerConfig) {
582
- var _a;
583
- if (!issuerConfig.registrationEndpoint) {
584
- throw new Error("Dynamic Registration could not be completed because the issuer has no registration endpoint.");
585
- }
586
- if (!Array.isArray(issuerConfig.idTokenSigningAlgValuesSupported)) {
587
- throw new Error("The OIDC issuer discovery profile is missing the 'id_token_signing_alg_values_supported' value, which is mandatory.");
588
- }
589
- const signingAlg = solidClientAuthnCore.determineSigningAlg(issuerConfig.idTokenSigningAlgValuesSupported, solidClientAuthnCore.PREFERRED_SIGNING_ALG);
590
- const config = {
591
- client_name: options.clientName,
592
- application_type: "web",
593
- redirect_uris: [(_a = options.redirectUrl) === null || _a === void 0 ? void 0 : _a.toString()],
594
- subject_type: "public",
595
- token_endpoint_auth_method: "client_secret_basic",
596
- id_token_signed_response_alg: signingAlg,
597
- grant_types: ["authorization_code", "refresh_token"],
598
- };
599
- const headers = {
600
- "Content-Type": "application/json",
601
- };
602
- if (options.registrationAccessToken) {
603
- headers.Authorization = `Bearer ${options.registrationAccessToken}`;
604
- }
605
- const registerResponse = await fetch(issuerConfig.registrationEndpoint.toString(), {
606
- method: "POST",
607
- headers,
608
- body: JSON.stringify(config),
609
- });
610
- if (registerResponse.ok) {
611
- const responseBody = await registerResponse.json();
612
- validateRegistrationResponse(responseBody, options);
613
- return {
614
- clientId: responseBody.client_id,
615
- clientSecret: responseBody.client_secret,
616
- idTokenSignedResponseAlg: responseBody.id_token_signed_response_alg,
617
- clientType: "dynamic",
618
- };
619
- }
620
- if (registerResponse.status === 400) {
621
- processErrorResponse(await registerResponse.json(), options);
622
- }
623
- throw new Error(`Dynamic client registration failed: the server returned ${registerResponse.status} ${registerResponse.statusText} - ${await registerResponse.text()}`);
624
- }
625
-
626
- function hasError(value) {
627
- return value.error !== undefined && typeof value.error === "string";
628
- }
629
- function hasErrorDescription(value) {
630
- return (value.error_description !== undefined &&
631
- typeof value.error_description === "string");
632
- }
633
- function hasErrorUri(value) {
634
- return value.error_uri !== undefined && typeof value.error_uri === "string";
635
- }
636
- function hasAccessToken(value) {
637
- return (value.access_token !== undefined && typeof value.access_token === "string");
638
- }
639
- function hasIdToken(value) {
640
- return value.id_token !== undefined && typeof value.id_token === "string";
641
- }
642
- function hasRefreshToken(value) {
643
- return (value.refresh_token !== undefined && typeof value.refresh_token === "string");
644
- }
645
- function hasTokenType(value) {
646
- return value.token_type !== undefined && typeof value.token_type === "string";
647
- }
648
- function hasExpiresIn(value) {
649
- return value.expires_in === undefined || typeof value.expires_in === "number";
650
- }
651
- function validatePreconditions(issuer, data) {
652
- if (data.grantType &&
653
- (!issuer.grantTypesSupported ||
654
- !issuer.grantTypesSupported.includes(data.grantType))) {
655
- throw new Error(`The issuer [${issuer.issuer}] does not support the [${data.grantType}] grant`);
656
- }
657
- if (!issuer.tokenEndpoint) {
658
- throw new Error(`This issuer [${issuer.issuer}] does not have a token endpoint`);
659
- }
660
- }
661
- function validateTokenEndpointResponse(tokenResponse, dpop) {
662
- if (hasError(tokenResponse)) {
663
- throw new solidClientAuthnCore.OidcProviderError(`Token endpoint returned error [${tokenResponse.error}]${hasErrorDescription(tokenResponse)
664
- ? `: ${tokenResponse.error_description}`
665
- : ""}${hasErrorUri(tokenResponse) ? ` (see ${tokenResponse.error_uri})` : ""}`, tokenResponse.error, hasErrorDescription(tokenResponse)
666
- ? tokenResponse.error_description
667
- : undefined);
668
- }
669
- if (!hasAccessToken(tokenResponse)) {
670
- throw new solidClientAuthnCore.InvalidResponseError(["access_token"]);
671
- }
672
- if (!hasIdToken(tokenResponse)) {
673
- throw new solidClientAuthnCore.InvalidResponseError(["id_token"]);
674
- }
675
- if (!hasTokenType(tokenResponse)) {
676
- throw new solidClientAuthnCore.InvalidResponseError(["token_type"]);
677
- }
678
- if (!hasExpiresIn(tokenResponse)) {
679
- throw new solidClientAuthnCore.InvalidResponseError(["expires_in"]);
680
- }
681
- if (!dpop && tokenResponse.token_type.toLowerCase() !== "bearer") {
682
- throw new Error(`Invalid token endpoint response: requested a [Bearer] token, but got a 'token_type' value of [${tokenResponse.token_type}].`);
683
- }
684
- return tokenResponse;
685
- }
686
- async function getTokens(issuer, client, data, dpop) {
687
- validatePreconditions(issuer, data);
688
- const headers = {
689
- "content-type": "application/x-www-form-urlencoded",
690
- };
691
- let dpopKey;
692
- if (dpop) {
693
- dpopKey = await solidClientAuthnCore.generateDpopKeyPair();
694
- headers.DPoP = await solidClientAuthnCore.createDpopHeader(issuer.tokenEndpoint, "POST", dpopKey);
695
- }
696
- if (client.clientSecret) {
697
- headers.Authorization = `Basic ${btoa(`${client.clientId}:${client.clientSecret}`)}`;
698
- }
699
- const requestBody = {
700
- grant_type: data.grantType,
701
- redirect_uri: data.redirectUrl,
702
- code: data.code,
703
- code_verifier: data.codeVerifier,
704
- client_id: client.clientId,
705
- };
706
- const tokenRequestInit = {
707
- method: "POST",
708
- headers,
709
- body: new URLSearchParams(requestBody).toString(),
710
- };
711
- const rawTokenResponse = await await fetch(issuer.tokenEndpoint, tokenRequestInit);
712
- const jsonTokenResponse = (await rawTokenResponse.json());
713
- const tokenResponse = validateTokenEndpointResponse(jsonTokenResponse, dpop);
714
- const webId = await solidClientAuthnCore.getWebidFromTokenPayload(tokenResponse.id_token, issuer.jwksUri, issuer.issuer, client.clientId);
715
- return {
716
- accessToken: tokenResponse.access_token,
717
- idToken: tokenResponse.id_token,
718
- refreshToken: hasRefreshToken(tokenResponse)
719
- ? tokenResponse.refresh_token
720
- : undefined,
721
- webId,
722
- dpopKey,
723
- expiresIn: tokenResponse.expires_in,
724
- };
725
- }
726
- async function getBearerToken(redirectUrl) {
727
- let signinResponse;
728
- try {
729
- const client = new oidcClient.OidcClient({
730
- response_mode: "query",
731
- loadUserInfo: false,
732
- });
733
- signinResponse = await client.processSigninResponse(redirectUrl);
734
- if (client.settings.metadata === undefined) {
735
- throw new Error("Cannot retrieve issuer metadata from client information in storage.");
736
- }
737
- if (client.settings.metadata.jwks_uri === undefined) {
738
- throw new Error("Missing some issuer metadata from client information in storage: 'jwks_uri' is undefined");
739
- }
740
- if (client.settings.metadata.issuer === undefined) {
741
- throw new Error("Missing some issuer metadata from client information in storage: 'issuer' is undefined");
742
- }
743
- if (client.settings.client_id === undefined) {
744
- throw new Error("Missing some client information in storage: 'client_id' is undefined");
745
- }
746
- const webId = await solidClientAuthnCore.getWebidFromTokenPayload(signinResponse.id_token, client.settings.metadata.jwks_uri, client.settings.metadata.issuer, client.settings.client_id);
747
- return {
748
- accessToken: signinResponse.access_token,
749
- idToken: signinResponse.id_token,
750
- webId,
751
- refreshToken: signinResponse.refresh_token,
752
- };
753
- }
754
- catch (err) {
755
- throw new Error(`Problem handling Auth Code Grant (Flow) redirect - URL [${redirectUrl}]: ${err}`);
756
- }
757
- }
758
- async function getDpopToken(issuer, client, data) {
759
- return getTokens(issuer, client, data, true);
760
- }
761
-
762
- async function refresh(refreshToken, issuer, client, dpopKey) {
763
- const requestBody = {
764
- grant_type: "refresh_token",
765
- refresh_token: refreshToken,
766
- scope: "openid offline_access",
767
- };
768
- let dpopHeader = {};
769
- if (dpopKey !== undefined) {
770
- dpopHeader = {
771
- DPoP: await solidClientAuthnCore.createDpopHeader(issuer.tokenEndpoint, "POST", dpopKey),
772
- };
773
- }
774
- let authHeader = {};
775
- if (client.clientSecret !== undefined) {
776
- authHeader = {
777
- Authorization: `Basic ${btoa(`${client.clientId}:${client.clientSecret}`)}`,
778
- };
779
- }
780
- const rawResponse = await fetch(issuer.tokenEndpoint, {
781
- method: "POST",
782
- body: new URLSearchParams(requestBody).toString(),
783
- headers: {
784
- ...dpopHeader,
785
- ...authHeader,
786
- "Content-Type": "application/x-www-form-urlencoded",
787
- },
788
- });
789
- let response;
790
- try {
791
- response = await rawResponse.json();
792
- }
793
- catch (e) {
794
- throw new Error(`The token endpoint of issuer ${issuer.issuer} returned a malformed response.`);
795
- }
796
- const validatedResponse = validateTokenEndpointResponse(response, dpopKey !== undefined);
797
- const webId = await solidClientAuthnCore.getWebidFromTokenPayload(validatedResponse.id_token, issuer.jwksUri, issuer.issuer, client.clientId);
798
- return {
799
- accessToken: validatedResponse.access_token,
800
- idToken: validatedResponse.id_token,
801
- refreshToken: typeof validatedResponse.refresh_token === "string"
802
- ? validatedResponse.refresh_token
803
- : undefined,
804
- webId,
805
- dpopKey,
806
- expiresIn: validatedResponse.expires_in,
807
- };
808
- }
809
-
810
- function removeOidcQueryParam(redirectUrl) {
811
- const cleanedUrl = new URL(redirectUrl);
812
- cleanedUrl.searchParams.delete("code");
813
- cleanedUrl.searchParams.delete("state");
814
- cleanedUrl.hash = "";
815
- return cleanedUrl.toString();
816
- }
817
- async function clearOidcPersistentStorage() {
818
- const client = new oidcClient.OidcClient({
819
- response_mode: "query",
820
- });
821
- await client.clearStaleState(new oidcClient.WebStorageStateStore({}));
822
- const myStorage = window.localStorage;
823
- const itemsToRemove = [];
824
- for (let i = 0; i <= myStorage.length; i += 1) {
825
- const key = myStorage.key(i);
826
- if (key &&
827
- (key.match(/^oidc\..+$/) ||
828
- key.match(/^solidClientAuthenticationUser:.+$/))) {
829
- itemsToRemove.push(key);
830
- }
831
- }
832
- itemsToRemove.forEach((key) => myStorage.removeItem(key));
833
- }
834
-
835
485
  const globalFetch = (request, init) => window.fetch(request, init);
836
486
  class ClientAuthentication {
837
487
  constructor(loginHandler, redirectHandler, logoutHandler, sessionInfoManager, issuerConfigFetcher) {
@@ -843,7 +493,7 @@
843
493
  this.login = async (options, eventEmitter) => {
844
494
  var _a, _b;
845
495
  await this.sessionInfoManager.clear(options.sessionId);
846
- const redirectUrl = removeOidcQueryParam((_a = options.redirectUrl) !== null && _a !== void 0 ? _a : window.location.href);
496
+ const redirectUrl = oidcClientExt.removeOidcQueryParam((_a = options.redirectUrl) !== null && _a !== void 0 ? _a : window.location.href);
847
497
  await this.loginHandler.handle({
848
498
  ...options,
849
499
  redirectUrl,
@@ -961,7 +611,7 @@
961
611
  code_verifier: true,
962
612
  prompt: (_a = oidcLoginOptions.prompt) !== null && _a !== void 0 ? _a : "consent",
963
613
  };
964
- const oidcClientLibrary = new oidcClient.OidcClient(oidcOptions);
614
+ const oidcClientLibrary = new oidcClientExt.OidcClient(oidcOptions);
965
615
  const { redirector } = this;
966
616
  const storage = this.storageUtility;
967
617
  try {
@@ -1117,7 +767,7 @@
1117
767
  function getUnauthenticatedSession() {
1118
768
  return {
1119
769
  isLoggedIn: false,
1120
- sessionId: v4(),
770
+ sessionId: uuid.v4(),
1121
771
  fetch,
1122
772
  };
1123
773
  }
@@ -1127,7 +777,7 @@
1127
777
  storage.deleteAllUserData(sessionId, { secure: true }),
1128
778
  storage.delete("clientKey", { secure: false }),
1129
779
  ]);
1130
- await clearOidcPersistentStorage();
780
+ await oidcClientExt.clearOidcPersistentStorage();
1131
781
  }
1132
782
  class SessionInfoManager {
1133
783
  constructor(storageUtility) {
@@ -1265,7 +915,7 @@
1265
915
  let tokens;
1266
916
  const tokenCreatedAt = Date.now();
1267
917
  if (isDpop) {
1268
- tokens = await getDpopToken(issuerConfig, client, {
918
+ tokens = await oidcClientExt.getDpopToken(issuerConfig, client, {
1269
919
  grantType: "authorization_code",
1270
920
  code: url.searchParams.get("code"),
1271
921
  codeVerifier,
@@ -1274,7 +924,7 @@
1274
924
  window.localStorage.removeItem(`oidc.${oauthState}`);
1275
925
  }
1276
926
  else {
1277
- tokens = await getBearerToken(url.toString());
927
+ tokens = await oidcClientExt.getBearerToken(url.toString());
1278
928
  }
1279
929
  let refreshOptions;
1280
930
  if (tokens.refreshToken !== undefined) {
@@ -1413,7 +1063,7 @@
1413
1063
  extendedOptions.registrationAccessToken =
1414
1064
  (_a = extendedOptions.registrationAccessToken) !== null && _a !== void 0 ? _a : (await this.storageUtility.getForUser(options.sessionId, "registrationAccessToken"));
1415
1065
  try {
1416
- const registeredClient = await registerClient(extendedOptions, issuerConfig);
1066
+ const registeredClient = await oidcClientExt.registerClient(extendedOptions, issuerConfig);
1417
1067
  const infoToSave = {
1418
1068
  clientId: registeredClient.clientId,
1419
1069
  };
@@ -1470,7 +1120,7 @@
1470
1120
  if (oidcContext.dpop && dpopKey === undefined) {
1471
1121
  throw new Error(`For session [${sessionId}], the key bound to the DPoP access token must be provided to refresh said access token.`);
1472
1122
  }
1473
- const tokenSet = await refresh(refreshToken, oidcContext.issuerConfig, clientInfo, dpopKey);
1123
+ const tokenSet = await oidcClientExt.refresh(refreshToken, oidcContext.issuerConfig, clientInfo, dpopKey);
1474
1124
  if (tokenSet.refreshToken !== undefined) {
1475
1125
  eventEmitter === null || eventEmitter === void 0 ? void 0 : eventEmitter.emit(solidClientAuthnCore.EVENTS.NEW_REFRESH_TOKEN, tokenSet.refreshToken);
1476
1126
  await this.storageUtility.setForUser(sessionId, {
@@ -1611,7 +1261,7 @@
1611
1261
  }
1612
1262
  else {
1613
1263
  this.info = {
1614
- sessionId: sessionId !== null && sessionId !== void 0 ? sessionId : v4(),
1264
+ sessionId: sessionId !== null && sessionId !== void 0 ? sessionId : uuid.v4(),
1615
1265
  isLoggedIn: false,
1616
1266
  };
1617
1267
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inrupt/solid-client-authn-browser",
3
- "version": "1.11.9-alpha.1",
3
+ "version": "1.11.9-alpha.2",
4
4
  "license": "MIT",
5
5
  "browser": "dist/solid-client-authn.bundle.js",
6
6
  "main": "dist/index.js",
@@ -25,8 +25,8 @@
25
25
  "build-docs-preview-site": "npm run build-api-docs; cd docs/api; make html"
26
26
  },
27
27
  "dependencies": {
28
- "@inrupt/oidc-client-ext": "^1.11.9-alpha.1",
29
- "@inrupt/solid-client-authn-core": "^1.11.9-alpha.1",
28
+ "@inrupt/oidc-client-ext": "^1.11.9-alpha.2",
29
+ "@inrupt/solid-client-authn-core": "^1.11.9-alpha.2",
30
30
  "@types/lodash.clonedeep": "^4.5.6",
31
31
  "@types/node": "^17.0.2",
32
32
  "@types/uuid": "^8.3.0",
@@ -38,5 +38,5 @@
38
38
  "publishConfig": {
39
39
  "access": "public"
40
40
  },
41
- "gitHead": "f6eabf0ccb5b5b818afc1015a5d1605bfd61461a"
41
+ "gitHead": "efdd6c8909e7bfb7360bdf976d7a122259ef0183"
42
42
  }
package/rollup.config.js CHANGED
@@ -34,11 +34,6 @@ export default {
34
34
  nodeResolve({
35
35
  browser: true,
36
36
  preferBuiltins: true,
37
- resolveOnly: [
38
- "uuid",
39
- "@inrupt/solid-client-authn-core",
40
- "@inrupt/oidc-client-ext",
41
- ],
42
37
  }),
43
38
  typescript({
44
39
  // Use our own version of TypeScript, rather than the one bundled with the plugin:
@@ -50,5 +45,10 @@ export default {
50
45
  },
51
46
  }),
52
47
  ],
53
- external: ["@inrupt/solid-client", "@inrupt/solid-client-authn-core"],
48
+ external: [
49
+ "@inrupt/solid-client",
50
+ "@inrupt/solid-client-authn-core",
51
+ "@inrupt/oidc-client-ext",
52
+ "uuid",
53
+ ],
54
54
  };