@muze-nl/metro-oidc 0.5.6 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/browser.js CHANGED
@@ -737,6 +737,20 @@
737
737
  }
738
738
  var everything_default = metro;
739
739
 
740
+ // node_modules/@muze-nl/metro-oauth2/src/oauth2.mjs
741
+ var oauth2_exports = {};
742
+ __export(oauth2_exports, {
743
+ base64url_encode: () => base64url_encode,
744
+ createState: () => createState,
745
+ default: () => oauth2mw,
746
+ generateCodeChallenge: () => generateCodeChallenge,
747
+ generateCodeVerifier: () => generateCodeVerifier,
748
+ getExpires: () => getExpires,
749
+ isAuthorized: () => isAuthorized,
750
+ isExpired: () => isExpired,
751
+ isRedirected: () => isRedirected
752
+ });
753
+
740
754
  // node_modules/@muze-nl/assert/src/assert.mjs
741
755
  globalThis.assertEnabled = false;
742
756
  function enable() {
@@ -1030,9 +1044,9 @@
1030
1044
  }
1031
1045
  };
1032
1046
  assert(options, {});
1033
- const oauth2 = Object.assign({}, defaultOptions.oauth2_configuration, options?.oauth2_configuration);
1047
+ const oauth22 = Object.assign({}, defaultOptions.oauth2_configuration, options?.oauth2_configuration);
1034
1048
  options = Object.assign({}, defaultOptions, options);
1035
- options.oauth2_configuration = oauth2;
1049
+ options.oauth2_configuration = oauth22;
1036
1050
  const store = tokenStore(options.site);
1037
1051
  if (!options.tokens) {
1038
1052
  options.tokens = store.tokens;
@@ -1049,12 +1063,12 @@
1049
1063
  redirect_uri: Required(validURL)
1050
1064
  }
1051
1065
  });
1052
- for (let option in oauth2) {
1066
+ for (let option in oauth22) {
1053
1067
  switch (option) {
1054
1068
  case "access_token":
1055
1069
  case "authorization_code":
1056
1070
  case "refresh_token":
1057
- options.tokens.set(option, oauth2[option]);
1071
+ options.tokens.set(option, oauth22[option]);
1058
1072
  break;
1059
1073
  }
1060
1074
  }
@@ -1151,7 +1165,7 @@
1151
1165
  }
1152
1166
  }
1153
1167
  async function fetchAccessToken() {
1154
- if (oauth2.grant_type === "authorization_code" && !options.tokens.has("authorization_code")) {
1168
+ if (oauth22.grant_type === "authorization_code" && !options.tokens.has("authorization_code")) {
1155
1169
  let authReqURL = await getAuthorizationCodeURL();
1156
1170
  if (!options.authorize_callback || typeof options.authorize_callback !== "function") {
1157
1171
  throw metroError("oauth2mw: oauth2 with grant_type:authorization_code requires a callback function in client options.authorize_callback");
@@ -1209,11 +1223,11 @@
1209
1223
  return data;
1210
1224
  }
1211
1225
  async function getAuthorizationCodeURL() {
1212
- if (!oauth2.authorization_endpoint) {
1226
+ if (!oauth22.authorization_endpoint) {
1213
1227
  throw metroError("oauth2mw: Missing options.oauth2_configuration.authorization_endpoint");
1214
1228
  }
1215
- let url2 = url(oauth2.authorization_endpoint, { hash: "" });
1216
- assert(oauth2, {
1229
+ let url2 = url(oauth22.authorization_endpoint, { hash: "" });
1230
+ assert(oauth22, {
1217
1231
  client_id: /.+/,
1218
1232
  redirect_uri: /.+/,
1219
1233
  scope: /.*/
@@ -1221,56 +1235,56 @@
1221
1235
  let search = {
1222
1236
  response_type: "code",
1223
1237
  // implicit flow uses 'token' here, but is not considered safe, so not supported
1224
- client_id: oauth2.client_id,
1225
- redirect_uri: oauth2.redirect_uri,
1226
- state: oauth2.state || createState(40)
1238
+ client_id: oauth22.client_id,
1239
+ redirect_uri: oauth22.redirect_uri,
1240
+ state: oauth22.state || createState(40)
1227
1241
  // OAuth2.1 RFC says optional, but its a good idea to always add/check it
1228
1242
  };
1229
- if (oauth2.response_type) {
1230
- search.response_type = oauth2.response_type;
1243
+ if (oauth22.response_type) {
1244
+ search.response_type = oauth22.response_type;
1231
1245
  }
1232
- if (oauth2.response_mode) {
1233
- search.response_mode = oauth2.response_mode;
1246
+ if (oauth22.response_mode) {
1247
+ search.response_mode = oauth22.response_mode;
1234
1248
  }
1235
1249
  options.state.set(search.state);
1236
- if (oauth2.client_secret) {
1237
- search.client_secret = oauth2.client_secret;
1250
+ if (oauth22.client_secret) {
1251
+ search.client_secret = oauth22.client_secret;
1238
1252
  }
1239
- if (oauth2.code_verifier) {
1240
- options.tokens.set("code_verifier", oauth2.code_verifier);
1241
- search.code_challenge = await generateCodeChallenge(oauth2.code_verifier);
1253
+ if (oauth22.code_verifier) {
1254
+ options.tokens.set("code_verifier", oauth22.code_verifier);
1255
+ search.code_challenge = await generateCodeChallenge(oauth22.code_verifier);
1242
1256
  search.code_challenge_method = "S256";
1243
1257
  }
1244
- if (oauth2.scope) {
1245
- search.scope = oauth2.scope;
1258
+ if (oauth22.scope) {
1259
+ search.scope = oauth22.scope;
1246
1260
  }
1247
- if (oauth2.prompt) {
1248
- search.prompt = oauth2.prompt;
1261
+ if (oauth22.prompt) {
1262
+ search.prompt = oauth22.prompt;
1249
1263
  }
1250
1264
  return url(url2, { search });
1251
1265
  }
1252
1266
  function getAccessTokenRequest(grant_type = null) {
1253
- assert(oauth2, {
1267
+ assert(oauth22, {
1254
1268
  client_id: /.+/,
1255
1269
  redirect_uri: /.+/
1256
1270
  });
1257
- if (!oauth2.token_endpoint) {
1271
+ if (!oauth22.token_endpoint) {
1258
1272
  throw metroError("oauth2mw: Missing options.endpoints.token url");
1259
1273
  }
1260
- let url2 = url(oauth2.token_endpoint, { hash: "" });
1274
+ let url2 = url(oauth22.token_endpoint, { hash: "" });
1261
1275
  let params = {
1262
- grant_type: grant_type || oauth2.grant_type,
1263
- client_id: oauth2.client_id
1276
+ grant_type: grant_type || oauth22.grant_type,
1277
+ client_id: oauth22.client_id
1264
1278
  };
1265
- if (oauth2.client_secret) {
1266
- params.client_secret = oauth2.client_secret;
1279
+ if (oauth22.client_secret) {
1280
+ params.client_secret = oauth22.client_secret;
1267
1281
  }
1268
- if (oauth2.scope) {
1269
- params.scope = oauth2.scope;
1282
+ if (oauth22.scope) {
1283
+ params.scope = oauth22.scope;
1270
1284
  }
1271
1285
  switch (params.grant_type) {
1272
1286
  case "authorization_code":
1273
- params.redirect_uri = oauth2.redirect_uri;
1287
+ params.redirect_uri = oauth22.redirect_uri;
1274
1288
  params.code = options.tokens.get("authorization_code");
1275
1289
  const code_verifier = options.tokens.get("code_verifier");
1276
1290
  if (code_verifier) {
@@ -1347,6 +1361,277 @@
1347
1361
  }
1348
1362
  return true;
1349
1363
  }
1364
+ function isAuthorized(tokens) {
1365
+ if (typeof tokens == "string") {
1366
+ tokens = tokenStore(tokens).tokens;
1367
+ }
1368
+ let accessToken = tokens.get("access_token");
1369
+ if (accessToken && !isExpired(accessToken)) {
1370
+ return true;
1371
+ }
1372
+ let refreshToken = tokens.get("refresh_token");
1373
+ if (refreshToken) {
1374
+ return true;
1375
+ }
1376
+ return false;
1377
+ }
1378
+
1379
+ // node_modules/@muze-nl/metro-oauth2/src/oauth2.mockserver.mjs
1380
+ var oauth2_mockserver_exports = {};
1381
+ __export(oauth2_mockserver_exports, {
1382
+ default: () => oauth2mockserver
1383
+ });
1384
+ var baseResponse = {
1385
+ status: 200,
1386
+ statusText: "OK",
1387
+ headers: {
1388
+ "Content-Type": "application/json"
1389
+ }
1390
+ };
1391
+ var badRequest = (error3) => {
1392
+ return {
1393
+ status: 400,
1394
+ statusText: "Bad Request",
1395
+ headers: {
1396
+ "Content-Type": "application/json"
1397
+ },
1398
+ body: JSON.stringify({
1399
+ error: "invalid_request",
1400
+ error_description: error3
1401
+ })
1402
+ };
1403
+ };
1404
+ var error2;
1405
+ var pkce = {};
1406
+ function oauth2mockserver(options = {}) {
1407
+ const defaultOptions = {
1408
+ "PKCE": false,
1409
+ "DPoP": false
1410
+ };
1411
+ options = Object.assign({}, defaultOptions, options);
1412
+ return async (req, next) => {
1413
+ let url2 = everything_default.url(req.url);
1414
+ switch (url2.pathname) {
1415
+ case "/authorize/":
1416
+ if (error2 = fails(url2.searchParams, {
1417
+ response_type: "code",
1418
+ client_id: "mockClientId",
1419
+ state: Optional(/.*/)
1420
+ })) {
1421
+ return everything_default.response(badRequest(error2));
1422
+ }
1423
+ if (url2.searchParams.has("code_challenge")) {
1424
+ if (!url2.searchParams.has("code_challenge_method")) {
1425
+ return everything_default.response(badRequest("missing code_challenge_method"));
1426
+ }
1427
+ pkce.code_challenge = url2.searchParams.get("code_challenge");
1428
+ pkce.code_challenge_method = url2.searchParams.get("code_challenge_method");
1429
+ }
1430
+ return everything_default.response(baseResponse, {
1431
+ body: JSON.stringify({
1432
+ code: "mockAuthorizeToken",
1433
+ state: url2.searchParams.get("state")
1434
+ })
1435
+ });
1436
+ break;
1437
+ case "/token/":
1438
+ if (req.data instanceof URLSearchParams) {
1439
+ let body = {};
1440
+ req.data.forEach((value, key) => body[key] = value);
1441
+ req = req.with({ body });
1442
+ }
1443
+ if (error2 = fails(req, {
1444
+ method: "POST",
1445
+ data: {
1446
+ grant_type: oneOf("refresh_token", "authorization_code")
1447
+ }
1448
+ })) {
1449
+ return everything_default.response(badRequest(error2));
1450
+ }
1451
+ switch (req.data.grant_type) {
1452
+ case "refresh_token":
1453
+ if (error2 = fails(req.data, oneOf({
1454
+ refresh_token: "mockRefreshToken",
1455
+ client_id: "mockClientId",
1456
+ client_secret: "mockClientSecret"
1457
+ }, {
1458
+ refresh_token: "mockRefreshToken",
1459
+ client_id: "mockClientId",
1460
+ code_verifier: /.+/
1461
+ }))) {
1462
+ return everything_default.response(badRequest(error2));
1463
+ }
1464
+ break;
1465
+ case "access_token":
1466
+ if (error2 = fails(req.data, oneOf({
1467
+ client_id: "mockClientId",
1468
+ client_secret: "mockClientSecret"
1469
+ }, {
1470
+ client_id: "mockClientId",
1471
+ code_challenge: /.*/,
1472
+ //FIXME: check that this matches code_verifier
1473
+ code_challenge_method: "S256"
1474
+ }))) {
1475
+ return everything_default.response(badRequest(error2));
1476
+ }
1477
+ break;
1478
+ }
1479
+ return everything_default.response(baseResponse, {
1480
+ body: JSON.stringify({
1481
+ access_token: "mockAccessToken",
1482
+ token_type: "mockExample",
1483
+ expires_in: 3600,
1484
+ refresh_token: "mockRefreshToken",
1485
+ example_parameter: "mockExampleValue"
1486
+ })
1487
+ });
1488
+ break;
1489
+ case "/protected/":
1490
+ let auth = req.headers.get("Authorization");
1491
+ let [type, token] = auth ? auth.split(" ") : [];
1492
+ if (!token || token !== "mockAccessToken") {
1493
+ return everything_default.response({
1494
+ status: 401,
1495
+ statusText: "Forbidden",
1496
+ body: "401 Forbidden"
1497
+ });
1498
+ }
1499
+ return everything_default.response(baseResponse, {
1500
+ body: JSON.stringify({
1501
+ result: "Success"
1502
+ })
1503
+ });
1504
+ break;
1505
+ case "/public/":
1506
+ return everything_default.response(baseResponse, {
1507
+ body: JSON.stringify({
1508
+ result: "Success"
1509
+ })
1510
+ });
1511
+ break;
1512
+ default:
1513
+ return everything_default.response({
1514
+ status: 404,
1515
+ statusText: "not found",
1516
+ body: "404 Not Found " + url2
1517
+ });
1518
+ break;
1519
+ }
1520
+ };
1521
+ }
1522
+
1523
+ // node_modules/@muze-nl/metro-oauth2/src/oauth2.discovery.mjs
1524
+ var oauth2_discovery_exports = {};
1525
+ __export(oauth2_discovery_exports, {
1526
+ default: () => makeClient
1527
+ });
1528
+ var validAlgorithms = [
1529
+ "HS256",
1530
+ "HS384",
1531
+ "HS512",
1532
+ "RS256",
1533
+ "RS384",
1534
+ "RS512",
1535
+ "ES256",
1536
+ "ES384",
1537
+ "ES512"
1538
+ ];
1539
+ var validAuthMethods = [
1540
+ "client_secret_post",
1541
+ "client_secret_base",
1542
+ "client_secret_jwt",
1543
+ "private_key_jwt"
1544
+ ];
1545
+ var oauth_authorization_server_metadata = {
1546
+ issuer: Required(validURL),
1547
+ authorization_endpoint: Required(validURL),
1548
+ token_endpoint: Required(validURL),
1549
+ jwks_uri: Optional(validURL),
1550
+ registration_endpoint: Optional(validURL),
1551
+ scopes_supported: Recommended([]),
1552
+ response_types_supported: Required(anyOf("code", "token")),
1553
+ response_modes_supported: Optional([]),
1554
+ grant_types_supported: Optional([]),
1555
+ token_endpoint_auth_methods_supported: Optional([]),
1556
+ token_endpoint_auth_signing_alg_values_supported: Optional([]),
1557
+ service_documentation: Optional(validURL),
1558
+ ui_locales_supported: Optional([]),
1559
+ op_policy_uri: Optional(validURL),
1560
+ op_tos_uri: Optional(validURL),
1561
+ revocation_endpoint: Optional(validURL),
1562
+ revocation_endpoint_auth_methods_supported: Optional(validAuthMethods),
1563
+ revocation_endpoint_auth_signing_alg_values_supported: Optional(validAlgorithms),
1564
+ introspection_endpoint: Optional(validURL),
1565
+ introspection_endpoint_auth_methods_supported: Optional(validAuthMethods),
1566
+ introspection_endpoint_auth_signing_alg_values_supported: Optional(validAlgorithms),
1567
+ code_challendge_methods_supported: Optional([])
1568
+ };
1569
+ function makeClient(options = {}) {
1570
+ const defaultOptions = {
1571
+ client: everything_default.client()
1572
+ };
1573
+ options = Object.assign({}, defaultOptions, options);
1574
+ assert(options, {
1575
+ issuer: Required(validURL)
1576
+ });
1577
+ const oauth_authorization_server_configuration = fetchWellknownOauthAuthorizationServer(options.issuer);
1578
+ return options.client.with(options.issuer);
1579
+ }
1580
+ async function fetchWellknownOauthAuthorizationServer(issuer, client2) {
1581
+ let res = client2.get(everything_default.url(issuer, ".wellknown/oauth_authorization_server"));
1582
+ if (res.ok) {
1583
+ assert(res.headers.get("Content-Type"), /application\/json.*/);
1584
+ let configuration = await res.json();
1585
+ assert(configuration, oauth_authorization_server_metadata);
1586
+ return configuration;
1587
+ }
1588
+ throw everything_default.metroError("metro.oidcmw: Error while fetching " + issuer + ".wellknown/oauth_authorization_server", res);
1589
+ }
1590
+
1591
+ // node_modules/@muze-nl/metro-oauth2/src/oauth2.popup.mjs
1592
+ function handleRedirect(origin = null) {
1593
+ let success = false;
1594
+ origin = origin || window.location.origin;
1595
+ let params = new URLSearchParams(window.location.search);
1596
+ if (!params.has("code") && window.location.hash) {
1597
+ let query = window.location.hash.substr(1);
1598
+ params = new URLSearchParams("?" + query);
1599
+ }
1600
+ let parent = window.parent !== window ? window.parent : window.opener;
1601
+ if (!parent) {
1602
+ console.error("No parent window found, cannot post authorization code (or error)");
1603
+ } else {
1604
+ if (params.has("code")) {
1605
+ parent.postMessage({
1606
+ authorization_code: params.get("code")
1607
+ }, origin);
1608
+ success = true;
1609
+ } else if (params.has("error")) {
1610
+ parent.postMessage({
1611
+ error: params.get("error")
1612
+ }, origin);
1613
+ } else {
1614
+ parent.postMessage({
1615
+ error: "Could not find an authorization_code"
1616
+ }, origin);
1617
+ }
1618
+ }
1619
+ return success;
1620
+ }
1621
+ function authorizePopup(authorizationCodeURL) {
1622
+ return new Promise((resolve, reject) => {
1623
+ addEventListener("message", (event) => {
1624
+ if (event.data.authorization_code) {
1625
+ resolve(event.data.authorization_code);
1626
+ } else if (event.data.error) {
1627
+ reject(event.data.error);
1628
+ } else {
1629
+ reject("Unknown authorization error");
1630
+ }
1631
+ }, { once: true });
1632
+ window.open(authorizationCodeURL);
1633
+ });
1634
+ }
1350
1635
 
1351
1636
  // node_modules/@muze-nl/metro-oauth2/src/keysstore.mjs
1352
1637
  function keysStore() {
@@ -1659,6 +1944,21 @@
1659
1944
  };
1660
1945
  }
1661
1946
 
1947
+ // node_modules/@muze-nl/metro-oauth2/src/browser.mjs
1948
+ var oauth2 = Object.assign({}, oauth2_exports, {
1949
+ oauth2mw,
1950
+ mockserver: oauth2_mockserver_exports,
1951
+ discover: oauth2_discovery_exports,
1952
+ tokenstore: tokenStore,
1953
+ dpopmw,
1954
+ keysstore: keysStore,
1955
+ authorizePopup,
1956
+ popupHandleRedirect: handleRedirect
1957
+ });
1958
+ if (!globalThis.metro.oauth2) {
1959
+ globalThis.metro.oauth2 = oauth2;
1960
+ }
1961
+
1662
1962
  // src/oidc.util.mjs
1663
1963
  var MustHave = (...options) => (value, root) => {
1664
1964
  if (options.filter((o) => root.hasOwnKey(o)).length > 0) {
@@ -1684,7 +1984,7 @@
1684
1984
  "ES384",
1685
1985
  "ES512"
1686
1986
  ];
1687
- var validAuthMethods = [
1987
+ var validAuthMethods2 = [
1688
1988
  "client_secret_post",
1689
1989
  "client_secret_basic",
1690
1990
  "client_secret_jwt",
@@ -1730,7 +2030,7 @@
1730
2030
  // not testing for 'none'
1731
2031
  request_object_encryption_alg_values_supported: Optional([]),
1732
2032
  request_object_encryption_enc_values_supported: Optional([]),
1733
- token_endpoint_auth_methods_supported: Optional(anyOf(...validAuthMethods)),
2033
+ token_endpoint_auth_methods_supported: Optional(anyOf(...validAuthMethods2)),
1734
2034
  token_endpoint_auth_signing_alg_values_supported: Optional(MustInclude("RS256"), not(MustInclude("none"))),
1735
2035
  display_values_supported: Optional(anyOf("page", "popup", "touch", "wap")),
1736
2036
  claim_types_supported: Optional(anyOf("normal", "aggregated", "distributed")),
@@ -1783,7 +2083,7 @@
1783
2083
  request_object_signing_alg: Optional(oneOf(...validJWA)),
1784
2084
  request_object_encryption_alg: Optional(oneOf(...validJWA)),
1785
2085
  request_object_encryption_enc: Optional(oneOf(...validJWA)),
1786
- token_endpoint_auth_method: Optional(oneOf(...validAuthMethods)),
2086
+ token_endpoint_auth_method: Optional(oneOf(...validAuthMethods2)),
1787
2087
  token_endpoint_auth_signing_alg: Optional(oneOf(...validJWA)),
1788
2088
  default_max_age: Optional(Number),
1789
2089
  require_auth_time: Optional(Boolean),
@@ -1984,6 +2284,6 @@
1984
2284
  if (!globalThis.metro.oidc) {
1985
2285
  globalThis.metro.oidc = oidc;
1986
2286
  }
1987
- var browser_default = oidc;
2287
+ var browser_default2 = oidc;
1988
2288
  })();
1989
2289
  //# sourceMappingURL=browser.js.map