@executor-js/emulate 0.6.0 → 0.7.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.
@@ -45,9 +45,9 @@ function boolFromQuery(value, fallback) {
45
45
  if (lowered === "false" || lowered === "0") return false;
46
46
  return fallback;
47
47
  }
48
- function resolveOktaIssuer(baseUrl, authServerId) {
49
- if (authServerId === ORG_AUTH_SERVER_ID) return baseUrl;
50
- return `${baseUrl}/oauth2/${authServerId}`;
48
+ function resolveOktaIssuer(baseUrl, authServerId2) {
49
+ if (authServerId2 === ORG_AUTH_SERVER_ID) return baseUrl;
50
+ return `${baseUrl}/oauth2/${authServerId2}`;
51
51
  }
52
52
  function userDisplayName(user) {
53
53
  if (user.display_name) return user.display_name;
@@ -695,10 +695,10 @@ function appRoutes({ app, store, baseUrl, tokenMap }) {
695
695
  app.get("/api/v1/apps", (c) => {
696
696
  const auth = requireManagementAuth(c, tokenMap);
697
697
  if (auth instanceof Response) return auth;
698
- const q = (c.req.query("q") ?? "").toLowerCase();
698
+ const q2 = (c.req.query("q") ?? "").toLowerCase();
699
699
  let apps = oktaStore.apps.all();
700
- if (q) {
701
- apps = apps.filter((entry) => `${entry.name} ${entry.label}`.toLowerCase().includes(q));
700
+ if (q2) {
701
+ apps = apps.filter((entry) => `${entry.name} ${entry.label}`.toLowerCase().includes(q2));
702
702
  }
703
703
  const { page, per_page } = parsePagination(c);
704
704
  const total = apps.length;
@@ -919,10 +919,10 @@ function groupRoutes({ app, store, baseUrl, tokenMap }) {
919
919
  app.get("/api/v1/groups", (c) => {
920
920
  const auth = requireManagementAuth(c, tokenMap);
921
921
  if (auth instanceof Response) return auth;
922
- const q = (c.req.query("q") ?? "").toLowerCase();
922
+ const q2 = (c.req.query("q") ?? "").toLowerCase();
923
923
  let groups = oktaStore.groups.all();
924
- if (q) {
925
- groups = groups.filter((group) => `${group.name} ${group.description ?? ""}`.toLowerCase().includes(q));
924
+ if (q2) {
925
+ groups = groups.filter((group) => `${group.name} ${group.description ?? ""}`.toLowerCase().includes(q2));
926
926
  }
927
927
  const { page, per_page } = parsePagination(c);
928
928
  const total = groups.length;
@@ -1060,26 +1060,26 @@ function getRefreshTokens(store) {
1060
1060
  function isCodeExpired(code) {
1061
1061
  return Date.now() - code.createdAt > CODE_TTL_MS;
1062
1062
  }
1063
- function buildOAuthBasePath(authServerId) {
1064
- if (authServerId === ORG_AUTH_SERVER_ID) return "/oauth2/v1";
1065
- return `/oauth2/${encodeURIComponent(authServerId)}/v1`;
1063
+ function buildOAuthBasePath(authServerId2) {
1064
+ if (authServerId2 === ORG_AUTH_SERVER_ID) return "/oauth2/v1";
1065
+ return `/oauth2/${encodeURIComponent(authServerId2)}/v1`;
1066
1066
  }
1067
- function getClientsForServer(clients, authServerId) {
1068
- return clients.filter((client) => client.auth_server_id === authServerId);
1067
+ function getClientsForServer(clients, authServerId2) {
1068
+ return clients.filter((client) => client.auth_server_id === authServerId2);
1069
1069
  }
1070
- function resolveServer(authServerId, baseUrl, store) {
1071
- if (authServerId === ORG_AUTH_SERVER_ID) {
1070
+ function resolveServer(authServerId2, baseUrl, store) {
1071
+ if (authServerId2 === ORG_AUTH_SERVER_ID) {
1072
1072
  return {
1073
- authServerId,
1073
+ authServerId: authServerId2,
1074
1074
  issuer: baseUrl,
1075
1075
  audiences: [DEFAULT_AUDIENCE]
1076
1076
  };
1077
1077
  }
1078
- const server = store.authorizationServers.findOneBy("server_id", authServerId);
1078
+ const server = store.authorizationServers.findOneBy("server_id", authServerId2);
1079
1079
  if (!server) return null;
1080
1080
  return {
1081
- authServerId,
1082
- issuer: resolveOktaIssuer(baseUrl, authServerId),
1081
+ authServerId: authServerId2,
1082
+ issuer: resolveOktaIssuer(baseUrl, authServerId2),
1083
1083
  audiences: server.audiences.length > 0 ? server.audiences : [DEFAULT_AUDIENCE]
1084
1084
  };
1085
1085
  }
@@ -1162,8 +1162,8 @@ function parseClientCredentials(c, body) {
1162
1162
  }
1163
1163
  return { clientId, clientSecret };
1164
1164
  }
1165
- function validateClient(clients, authServerId, clientId, clientSecret) {
1166
- const scopedClients = getClientsForServer(clients, authServerId);
1165
+ function validateClient(clients, authServerId2, clientId, clientSecret) {
1166
+ const scopedClients = getClientsForServer(clients, authServerId2);
1167
1167
  if (scopedClients.length === 0) {
1168
1168
  return { client: null, error: null };
1169
1169
  }
@@ -1238,9 +1238,9 @@ function oauthRoutes({ app, store, baseUrl, tokenMap }) {
1238
1238
  return c.json(buildOidcConfiguration(baseUrl, server));
1239
1239
  });
1240
1240
  app.get("/oauth2/:authServerId/.well-known/openid-configuration", (c) => {
1241
- const authServerId = c.req.param("authServerId");
1242
- const server = resolveServer(authServerId, baseUrl, oktaStore);
1243
- if (!server) return oktaError(c, 404, "E0000007", `Not found: authorization server '${authServerId}'`);
1241
+ const authServerId2 = c.req.param("authServerId");
1242
+ const server = resolveServer(authServerId2, baseUrl, oktaStore);
1243
+ if (!server) return oktaError(c, 404, "E0000007", `Not found: authorization server '${authServerId2}'`);
1244
1244
  return c.json(buildOidcConfiguration(baseUrl, server));
1245
1245
  });
1246
1246
  app.get("/oauth2/v1/keys", async (c) => {
@@ -1251,18 +1251,18 @@ function oauthRoutes({ app, store, baseUrl, tokenMap }) {
1251
1251
  });
1252
1252
  });
1253
1253
  app.get("/oauth2/:authServerId/v1/keys", async (c) => {
1254
- const authServerId = c.req.param("authServerId");
1255
- const server = resolveServer(authServerId, baseUrl, oktaStore);
1256
- if (!server) return oktaError(c, 404, "E0000007", `Not found: authorization server '${authServerId}'`);
1254
+ const authServerId2 = c.req.param("authServerId");
1255
+ const server = resolveServer(authServerId2, baseUrl, oktaStore);
1256
+ if (!server) return oktaError(c, 404, "E0000007", `Not found: authorization server '${authServerId2}'`);
1257
1257
  const { publicKey } = await keyPairPromise;
1258
1258
  const jwk = await exportJWK(publicKey);
1259
1259
  return c.json({
1260
1260
  keys: [{ ...jwk, kid: KID, use: "sig", alg: "RS256" }]
1261
1261
  });
1262
1262
  });
1263
- const renderAuthorizePage = (c, authServerId) => {
1264
- const server = resolveServer(authServerId, baseUrl, oktaStore);
1265
- if (!server) return oktaError(c, 404, "E0000007", `Not found: authorization server '${authServerId}'`);
1263
+ const renderAuthorizePage = (c, authServerId2) => {
1264
+ const server = resolveServer(authServerId2, baseUrl, oktaStore);
1265
+ if (!server) return oktaError(c, 404, "E0000007", `Not found: authorization server '${authServerId2}'`);
1266
1266
  const clientId = c.req.query("client_id") ?? "";
1267
1267
  const redirectUri = c.req.query("redirect_uri") ?? "";
1268
1268
  const scope = c.req.query("scope") ?? "openid profile email";
@@ -1284,7 +1284,7 @@ function oauthRoutes({ app, store, baseUrl, tokenMap }) {
1284
1284
  400
1285
1285
  );
1286
1286
  }
1287
- const configuredClients = getClientsForServer(oktaStore.oauthClients.all(), authServerId);
1287
+ const configuredClients = getClientsForServer(oktaStore.oauthClients.all(), authServerId2);
1288
1288
  let clientName = "";
1289
1289
  if (configuredClients.length > 0) {
1290
1290
  const client = configuredClients.find((entry) => entry.client_id === clientId);
@@ -1307,7 +1307,7 @@ function oauthRoutes({ app, store, baseUrl, tokenMap }) {
1307
1307
  clientName = client.name;
1308
1308
  }
1309
1309
  const users = oktaStore.users.all();
1310
- const callbackPath = `${baseUrl}${buildOAuthBasePath(authServerId)}/authorize/callback`;
1310
+ const callbackPath = `${baseUrl}${buildOAuthBasePath(authServerId2)}/authorize/callback`;
1311
1311
  const buttons = users.map(
1312
1312
  (user) => renderUserButton({
1313
1313
  letter: (user.login[0] ?? "?").toUpperCase(),
@@ -1325,7 +1325,7 @@ function oauthRoutes({ app, store, baseUrl, tokenMap }) {
1325
1325
  response_mode: responseMode,
1326
1326
  code_challenge: codeChallenge,
1327
1327
  code_challenge_method: codeChallengeMethod,
1328
- auth_server_id: authServerId
1328
+ auth_server_id: authServerId2
1329
1329
  }
1330
1330
  })
1331
1331
  ).join("\n");
@@ -1341,9 +1341,9 @@ function oauthRoutes({ app, store, baseUrl, tokenMap }) {
1341
1341
  };
1342
1342
  app.get("/oauth2/v1/authorize", (c) => renderAuthorizePage(c, ORG_AUTH_SERVER_ID));
1343
1343
  app.get("/oauth2/:authServerId/v1/authorize", (c) => renderAuthorizePage(c, c.req.param("authServerId")));
1344
- const handleAuthorizeCallback = async (c, authServerId) => {
1345
- const server = resolveServer(authServerId, baseUrl, oktaStore);
1346
- if (!server) return oktaError(c, 404, "E0000007", `Not found: authorization server '${authServerId}'`);
1344
+ const handleAuthorizeCallback = async (c, authServerId2) => {
1345
+ const server = resolveServer(authServerId2, baseUrl, oktaStore);
1346
+ if (!server) return oktaError(c, 404, "E0000007", `Not found: authorization server '${authServerId2}'`);
1347
1347
  const body = await c.req.parseBody();
1348
1348
  const userRef = bodyStr(body.user_ref);
1349
1349
  const redirectUri = bodyStr(body.redirect_uri);
@@ -1364,7 +1364,7 @@ function oauthRoutes({ app, store, baseUrl, tokenMap }) {
1364
1364
  if (!user) {
1365
1365
  return c.html(renderErrorPage("Unknown user", "The selected user is not available.", SERVICE_LABEL), 400);
1366
1366
  }
1367
- const configuredClients = getClientsForServer(oktaStore.oauthClients.all(), authServerId);
1367
+ const configuredClients = getClientsForServer(oktaStore.oauthClients.all(), authServerId2);
1368
1368
  if (configuredClients.length > 0) {
1369
1369
  const client = configuredClients.find((entry) => entry.client_id === clientId);
1370
1370
  if (!client) {
@@ -1393,10 +1393,10 @@ function oauthRoutes({ app, store, baseUrl, tokenMap }) {
1393
1393
  nonce: nonce || null,
1394
1394
  codeChallenge: codeChallenge || null,
1395
1395
  codeChallengeMethod: codeChallengeMethod || null,
1396
- authServerId,
1396
+ authServerId: authServerId2,
1397
1397
  createdAt: Date.now()
1398
1398
  });
1399
- debug("okta.oauth", `[callback] code=${code.slice(0, 8)}... user=${user.login} server=${authServerId}`);
1399
+ debug("okta.oauth", `[callback] code=${code.slice(0, 8)}... user=${user.login} server=${authServerId2}`);
1400
1400
  if (responseMode === "form_post") {
1401
1401
  return c.html(renderFormPostPage(redirectUri, { code, state }, SERVICE_LABEL));
1402
1402
  }
@@ -1410,9 +1410,9 @@ function oauthRoutes({ app, store, baseUrl, tokenMap }) {
1410
1410
  "/oauth2/:authServerId/v1/authorize/callback",
1411
1411
  (c) => handleAuthorizeCallback(c, c.req.param("authServerId"))
1412
1412
  );
1413
- const handleToken = async (c, authServerId) => {
1414
- const server = resolveServer(authServerId, baseUrl, oktaStore);
1415
- if (!server) return oktaError(c, 404, "E0000007", `Not found: authorization server '${authServerId}'`);
1413
+ const handleToken = async (c, authServerId2) => {
1414
+ const server = resolveServer(authServerId2, baseUrl, oktaStore);
1415
+ if (!server) return oktaError(c, 404, "E0000007", `Not found: authorization server '${authServerId2}'`);
1416
1416
  const body = await parseTokenLikeBody(c);
1417
1417
  const grantType = body.grant_type ?? "";
1418
1418
  const code = body.code ?? "";
@@ -1421,7 +1421,7 @@ function oauthRoutes({ app, store, baseUrl, tokenMap }) {
1421
1421
  const refreshToken = body.refresh_token ?? "";
1422
1422
  const requestedScope = body.scope ?? "";
1423
1423
  const creds = parseClientCredentials(c, body);
1424
- const validation = validateClient(oktaStore.oauthClients.all(), authServerId, creds.clientId, creds.clientSecret);
1424
+ const validation = validateClient(oktaStore.oauthClients.all(), authServerId2, creds.clientId, creds.clientSecret);
1425
1425
  if (validation.error) {
1426
1426
  return c.json(validation.error.body, validation.error.status);
1427
1427
  }
@@ -1432,7 +1432,7 @@ function oauthRoutes({ app, store, baseUrl, tokenMap }) {
1432
1432
  if (pending) getPendingCodes(store).delete(code);
1433
1433
  return c.json({ error: "invalid_grant", error_description: "Authorization code is invalid or expired." }, 400);
1434
1434
  }
1435
- if (pending.authServerId !== authServerId) {
1435
+ if (pending.authServerId !== authServerId2) {
1436
1436
  return c.json({ error: "invalid_grant", error_description: "Authorization server mismatch." }, 400);
1437
1437
  }
1438
1438
  if (redirectUri && redirectUri !== pending.redirectUri) {
@@ -1471,7 +1471,7 @@ function oauthRoutes({ app, store, baseUrl, tokenMap }) {
1471
1471
  const accessToken = `okta_${randomBytes(20).toString("base64url")}`;
1472
1472
  const newRefreshToken = `r_okta_${randomBytes(20).toString("base64url")}`;
1473
1473
  getAccessTokens(store).set(accessToken, {
1474
- authServerId,
1474
+ authServerId: authServerId2,
1475
1475
  clientId: audienceClient,
1476
1476
  scope,
1477
1477
  issuedAt: now,
@@ -1480,7 +1480,7 @@ function oauthRoutes({ app, store, baseUrl, tokenMap }) {
1480
1480
  username: user.login
1481
1481
  });
1482
1482
  getRefreshTokens(store).set(newRefreshToken, {
1483
- authServerId,
1483
+ authServerId: authServerId2,
1484
1484
  clientId: audienceClient,
1485
1485
  scope,
1486
1486
  userOktaId: user.okta_id,
@@ -1507,7 +1507,7 @@ function oauthRoutes({ app, store, baseUrl, tokenMap }) {
1507
1507
  if (!existing) {
1508
1508
  return c.json({ error: "invalid_grant", error_description: "Invalid refresh token." }, 400);
1509
1509
  }
1510
- if (existing.authServerId !== authServerId) {
1510
+ if (existing.authServerId !== authServerId2) {
1511
1511
  return c.json({ error: "invalid_grant", error_description: "Authorization server mismatch." }, 400);
1512
1512
  }
1513
1513
  if (validatedClient && validatedClient.client_id !== existing.clientId) {
@@ -1524,7 +1524,7 @@ function oauthRoutes({ app, store, baseUrl, tokenMap }) {
1524
1524
  const nextRefreshToken = `r_okta_${randomBytes(20).toString("base64url")}`;
1525
1525
  const scope = requestedScope || existing.scope;
1526
1526
  getAccessTokens(store).set(nextAccessToken, {
1527
- authServerId,
1527
+ authServerId: authServerId2,
1528
1528
  clientId: existing.clientId,
1529
1529
  scope,
1530
1530
  issuedAt: now,
@@ -1572,7 +1572,7 @@ function oauthRoutes({ app, store, baseUrl, tokenMap }) {
1572
1572
  return c.json({ error: "invalid_client", error_description: "client_id is required." }, 401);
1573
1573
  }
1574
1574
  getAccessTokens(store).set(accessToken, {
1575
- authServerId,
1575
+ authServerId: authServerId2,
1576
1576
  clientId,
1577
1577
  scope,
1578
1578
  issuedAt: now,
@@ -1596,12 +1596,12 @@ function oauthRoutes({ app, store, baseUrl, tokenMap }) {
1596
1596
  };
1597
1597
  app.post("/oauth2/v1/token", (c) => handleToken(c, ORG_AUTH_SERVER_ID));
1598
1598
  app.post("/oauth2/:authServerId/v1/token", (c) => handleToken(c, c.req.param("authServerId")));
1599
- const handleUserInfo = (c, authServerId) => {
1600
- const server = resolveServer(authServerId, baseUrl, oktaStore);
1601
- if (!server) return oktaError(c, 404, "E0000007", `Not found: authorization server '${authServerId}'`);
1599
+ const handleUserInfo = (c, authServerId2) => {
1600
+ const server = resolveServer(authServerId2, baseUrl, oktaStore);
1601
+ if (!server) return oktaError(c, 404, "E0000007", `Not found: authorization server '${authServerId2}'`);
1602
1602
  const token = c.get("authToken") ?? "";
1603
1603
  const access = getAccessTokens(store).get(token);
1604
- if (!access || access.authServerId !== authServerId || !access.userOktaId) {
1604
+ if (!access || access.authServerId !== authServerId2 || !access.userOktaId) {
1605
1605
  return unauthorizedOAuthError();
1606
1606
  }
1607
1607
  const user = oktaStore.users.findOneBy("okta_id", access.userOktaId);
@@ -1622,9 +1622,9 @@ function oauthRoutes({ app, store, baseUrl, tokenMap }) {
1622
1622
  };
1623
1623
  app.get("/oauth2/v1/userinfo", (c) => handleUserInfo(c, ORG_AUTH_SERVER_ID));
1624
1624
  app.get("/oauth2/:authServerId/v1/userinfo", (c) => handleUserInfo(c, c.req.param("authServerId")));
1625
- const handleRevoke = async (c, authServerId) => {
1626
- const server = resolveServer(authServerId, baseUrl, oktaStore);
1627
- if (!server) return oktaError(c, 404, "E0000007", `Not found: authorization server '${authServerId}'`);
1625
+ const handleRevoke = async (c, authServerId2) => {
1626
+ const server = resolveServer(authServerId2, baseUrl, oktaStore);
1627
+ if (!server) return oktaError(c, 404, "E0000007", `Not found: authorization server '${authServerId2}'`);
1628
1628
  const body = await parseTokenLikeBody(c);
1629
1629
  const token = body.token ?? "";
1630
1630
  getAccessTokens(store).delete(token);
@@ -1634,19 +1634,19 @@ function oauthRoutes({ app, store, baseUrl, tokenMap }) {
1634
1634
  };
1635
1635
  app.post("/oauth2/v1/revoke", (c) => handleRevoke(c, ORG_AUTH_SERVER_ID));
1636
1636
  app.post("/oauth2/:authServerId/v1/revoke", (c) => handleRevoke(c, c.req.param("authServerId")));
1637
- const handleIntrospect = async (c, authServerId) => {
1638
- const server = resolveServer(authServerId, baseUrl, oktaStore);
1639
- if (!server) return oktaError(c, 404, "E0000007", `Not found: authorization server '${authServerId}'`);
1637
+ const handleIntrospect = async (c, authServerId2) => {
1638
+ const server = resolveServer(authServerId2, baseUrl, oktaStore);
1639
+ if (!server) return oktaError(c, 404, "E0000007", `Not found: authorization server '${authServerId2}'`);
1640
1640
  const body = await parseTokenLikeBody(c);
1641
1641
  const token = body.token ?? "";
1642
1642
  const creds = parseClientCredentials(c, body);
1643
- const validation = validateClient(oktaStore.oauthClients.all(), authServerId, creds.clientId, creds.clientSecret);
1643
+ const validation = validateClient(oktaStore.oauthClients.all(), authServerId2, creds.clientId, creds.clientSecret);
1644
1644
  if (validation.error) {
1645
1645
  return c.json(validation.error.body, validation.error.status);
1646
1646
  }
1647
1647
  const now = Math.floor(Date.now() / 1e3);
1648
1648
  const access = getAccessTokens(store).get(token);
1649
- if (access && access.authServerId === authServerId && access.expiresAt > now) {
1649
+ if (access && access.authServerId === authServerId2 && access.expiresAt > now) {
1650
1650
  return c.json({
1651
1651
  active: true,
1652
1652
  token_type: "Bearer",
@@ -1661,7 +1661,7 @@ function oauthRoutes({ app, store, baseUrl, tokenMap }) {
1661
1661
  });
1662
1662
  }
1663
1663
  const refresh = getRefreshTokens(store).get(token);
1664
- if (refresh && refresh.authServerId === authServerId) {
1664
+ if (refresh && refresh.authServerId === authServerId2) {
1665
1665
  return c.json({
1666
1666
  active: true,
1667
1667
  token_type: "refresh_token",
@@ -1677,12 +1677,12 @@ function oauthRoutes({ app, store, baseUrl, tokenMap }) {
1677
1677
  };
1678
1678
  app.post("/oauth2/v1/introspect", (c) => handleIntrospect(c, ORG_AUTH_SERVER_ID));
1679
1679
  app.post("/oauth2/:authServerId/v1/introspect", (c) => handleIntrospect(c, c.req.param("authServerId")));
1680
- const handleLogout = (c, authServerId) => {
1681
- const server = resolveServer(authServerId, baseUrl, oktaStore);
1682
- if (!server) return oktaError(c, 404, "E0000007", `Not found: authorization server '${authServerId}'`);
1680
+ const handleLogout = (c, authServerId2) => {
1681
+ const server = resolveServer(authServerId2, baseUrl, oktaStore);
1682
+ if (!server) return oktaError(c, 404, "E0000007", `Not found: authorization server '${authServerId2}'`);
1683
1683
  const postLogoutRedirectUri = c.req.query("post_logout_redirect_uri");
1684
1684
  if (!postLogoutRedirectUri) return c.text("Logged out");
1685
- const scopedClients = getClientsForServer(oktaStore.oauthClients.all(), authServerId);
1685
+ const scopedClients = getClientsForServer(oktaStore.oauthClients.all(), authServerId2);
1686
1686
  if (scopedClients.length > 0) {
1687
1687
  const isAllowed = scopedClients.some((client) => matchesRedirectUri(postLogoutRedirectUri, client.redirect_uris));
1688
1688
  if (!isAllowed) return c.text("Invalid post_logout_redirect_uri", 400);
@@ -1692,6 +1692,429 @@ function oauthRoutes({ app, store, baseUrl, tokenMap }) {
1692
1692
  app.get("/oauth2/v1/logout", (c) => handleLogout(c, ORG_AUTH_SERVER_ID));
1693
1693
  app.get("/oauth2/:authServerId/v1/logout", (c) => handleLogout(c, c.req.param("authServerId")));
1694
1694
  }
1695
+ function openapiRoutes({ app, baseUrl }) {
1696
+ app.get("/openapi.json", (c) => c.json(buildSpec(baseUrl)));
1697
+ }
1698
+ var ok = (description) => ({
1699
+ description,
1700
+ content: { "application/json": { schema: { type: "object" } } }
1701
+ });
1702
+ var noContent = (description) => ({ description });
1703
+ var userId = { name: "userId", in: "path", required: true, schema: { type: "string" } };
1704
+ var groupId = { name: "groupId", in: "path", required: true, schema: { type: "string" } };
1705
+ var appId = { name: "appId", in: "path", required: true, schema: { type: "string" } };
1706
+ var authServerId = { name: "authServerId", in: "path", required: true, schema: { type: "string" } };
1707
+ var q = { name: "q", in: "query", required: false, schema: { type: "string" } };
1708
+ var jsonBody = (properties, required, description) => ({
1709
+ required: true,
1710
+ description,
1711
+ content: {
1712
+ "application/json": {
1713
+ schema: { type: "object", properties, required: [...required] }
1714
+ }
1715
+ }
1716
+ });
1717
+ var userProfileBody = (description) => jsonBody(
1718
+ {
1719
+ profile: {
1720
+ type: "object",
1721
+ properties: {
1722
+ login: { type: "string" },
1723
+ email: { type: "string" },
1724
+ firstName: { type: "string" },
1725
+ lastName: { type: "string" },
1726
+ displayName: { type: "string" },
1727
+ locale: { type: "string" },
1728
+ timeZone: { type: "string" }
1729
+ }
1730
+ }
1731
+ },
1732
+ ["profile"],
1733
+ description
1734
+ );
1735
+ var groupProfileBody = (description) => jsonBody(
1736
+ {
1737
+ profile: {
1738
+ type: "object",
1739
+ properties: { name: { type: "string" }, description: { type: "string" } }
1740
+ },
1741
+ type: { type: "string" }
1742
+ },
1743
+ ["profile"],
1744
+ description
1745
+ );
1746
+ var appBody = (description, required) => jsonBody(
1747
+ {
1748
+ name: { type: "string" },
1749
+ label: { type: "string" },
1750
+ status: { type: "string", enum: ["ACTIVE", "INACTIVE"] },
1751
+ signOnMode: { type: "string" },
1752
+ settings: { type: "object" },
1753
+ credentials: { type: "object" }
1754
+ },
1755
+ required,
1756
+ description
1757
+ );
1758
+ var authServerBody = (description, required) => jsonBody(
1759
+ {
1760
+ id: { type: "string" },
1761
+ name: { type: "string" },
1762
+ description: { type: "string" },
1763
+ audiences: { type: "array", items: { type: "string" } },
1764
+ status: { type: "string", enum: ["ACTIVE", "INACTIVE"] }
1765
+ },
1766
+ required,
1767
+ description
1768
+ );
1769
+ function buildSpec(baseUrl) {
1770
+ return {
1771
+ openapi: "3.1.0",
1772
+ info: {
1773
+ title: "Okta Management API (Emulated)",
1774
+ version: "1.0.0",
1775
+ description: 'Emulated subset of the Okta management REST API. Authenticate with an SSWS API token (mint one at POST /_emulate/credentials with {"type":"api-key"}).'
1776
+ },
1777
+ servers: [{ url: baseUrl }],
1778
+ components: {
1779
+ securitySchemes: {
1780
+ ssws: {
1781
+ type: "apiKey",
1782
+ in: "header",
1783
+ name: "Authorization",
1784
+ description: "Okta API token, sent as `Authorization: SSWS {token}`."
1785
+ }
1786
+ }
1787
+ },
1788
+ security: [{ ssws: [] }],
1789
+ paths: {
1790
+ "/api/v1/users": {
1791
+ get: {
1792
+ operationId: "users/list",
1793
+ tags: ["users"],
1794
+ summary: "List users",
1795
+ parameters: [
1796
+ q,
1797
+ { name: "search", in: "query", required: false, schema: { type: "string" } },
1798
+ { name: "filter", in: "query", required: false, schema: { type: "string" } }
1799
+ ],
1800
+ responses: { "200": ok("User list.") }
1801
+ },
1802
+ post: {
1803
+ operationId: "users/create",
1804
+ tags: ["users"],
1805
+ summary: "Create a user",
1806
+ parameters: [{ name: "activate", in: "query", required: false, schema: { type: "boolean" } }],
1807
+ requestBody: userProfileBody("The user profile (profile.login and profile.email are required)."),
1808
+ responses: { "201": ok("The created user."), "400": ok("Validation error.") }
1809
+ }
1810
+ },
1811
+ "/api/v1/users/me": {
1812
+ get: {
1813
+ operationId: "users/getCurrent",
1814
+ tags: ["users"],
1815
+ summary: "Get the current user",
1816
+ responses: { "200": ok("The current user."), "404": ok("Not found.") }
1817
+ }
1818
+ },
1819
+ "/api/v1/users/{userId}": {
1820
+ get: {
1821
+ operationId: "users/get",
1822
+ tags: ["users"],
1823
+ summary: "Retrieve a user by id, login, or email",
1824
+ parameters: [userId],
1825
+ responses: { "200": ok("The user."), "404": ok("Not found.") }
1826
+ },
1827
+ put: {
1828
+ operationId: "users/update",
1829
+ tags: ["users"],
1830
+ summary: "Update a user profile",
1831
+ parameters: [userId],
1832
+ requestBody: userProfileBody("The profile fields to replace."),
1833
+ responses: { "200": ok("The updated user."), "404": ok("Not found.") }
1834
+ },
1835
+ post: {
1836
+ operationId: "users/partialUpdate",
1837
+ tags: ["users"],
1838
+ summary: "Partially update a user profile",
1839
+ parameters: [userId],
1840
+ requestBody: userProfileBody("The profile fields to merge."),
1841
+ responses: { "200": ok("The updated user."), "404": ok("Not found.") }
1842
+ },
1843
+ delete: {
1844
+ operationId: "users/delete",
1845
+ tags: ["users"],
1846
+ summary: "Deactivate, then delete a user",
1847
+ description: "Like real Okta, the first delete deactivates the user; a second delete removes them.",
1848
+ parameters: [userId],
1849
+ responses: { "204": noContent("Deactivated or deleted."), "404": ok("Not found.") }
1850
+ }
1851
+ },
1852
+ "/api/v1/users/{userId}/groups": {
1853
+ get: {
1854
+ operationId: "users/listGroups",
1855
+ tags: ["users"],
1856
+ summary: "List a user's groups",
1857
+ parameters: [userId],
1858
+ responses: { "200": ok("Group list."), "404": ok("Not found.") }
1859
+ }
1860
+ },
1861
+ "/api/v1/users/{userId}/lifecycle/activate": {
1862
+ post: {
1863
+ operationId: "users/activate",
1864
+ tags: ["users"],
1865
+ summary: "Activate a user",
1866
+ parameters: [userId],
1867
+ responses: { "200": ok("The activated user."), "404": ok("Not found.") }
1868
+ }
1869
+ },
1870
+ "/api/v1/users/{userId}/lifecycle/deactivate": {
1871
+ post: {
1872
+ operationId: "users/deactivate",
1873
+ tags: ["users"],
1874
+ summary: "Deactivate a user",
1875
+ parameters: [userId],
1876
+ responses: { "200": ok("The deactivated user."), "404": ok("Not found.") }
1877
+ }
1878
+ },
1879
+ "/api/v1/users/{userId}/lifecycle/suspend": {
1880
+ post: {
1881
+ operationId: "users/suspend",
1882
+ tags: ["users"],
1883
+ summary: "Suspend a user",
1884
+ parameters: [userId],
1885
+ responses: { "200": ok("The suspended user."), "404": ok("Not found.") }
1886
+ }
1887
+ },
1888
+ "/api/v1/users/{userId}/lifecycle/unsuspend": {
1889
+ post: {
1890
+ operationId: "users/unsuspend",
1891
+ tags: ["users"],
1892
+ summary: "Unsuspend a user",
1893
+ parameters: [userId],
1894
+ responses: { "200": ok("The unsuspended user."), "404": ok("Not found.") }
1895
+ }
1896
+ },
1897
+ "/api/v1/users/{userId}/lifecycle/reactivate": {
1898
+ post: {
1899
+ operationId: "users/reactivate",
1900
+ tags: ["users"],
1901
+ summary: "Reactivate a user",
1902
+ parameters: [userId],
1903
+ responses: { "200": ok("The reactivated user."), "404": ok("Not found.") }
1904
+ }
1905
+ },
1906
+ "/api/v1/groups": {
1907
+ get: {
1908
+ operationId: "groups/list",
1909
+ tags: ["groups"],
1910
+ summary: "List groups",
1911
+ parameters: [q],
1912
+ responses: { "200": ok("Group list.") }
1913
+ },
1914
+ post: {
1915
+ operationId: "groups/create",
1916
+ tags: ["groups"],
1917
+ summary: "Create a group",
1918
+ requestBody: groupProfileBody("The group to create (profile.name is required)."),
1919
+ responses: { "201": ok("The created group."), "400": ok("Validation error.") }
1920
+ }
1921
+ },
1922
+ "/api/v1/groups/{groupId}": {
1923
+ get: {
1924
+ operationId: "groups/get",
1925
+ tags: ["groups"],
1926
+ summary: "Retrieve a group",
1927
+ parameters: [groupId],
1928
+ responses: { "200": ok("The group."), "404": ok("Not found.") }
1929
+ },
1930
+ put: {
1931
+ operationId: "groups/update",
1932
+ tags: ["groups"],
1933
+ summary: "Update a group",
1934
+ parameters: [groupId],
1935
+ requestBody: groupProfileBody("The group fields to replace."),
1936
+ responses: { "200": ok("The updated group."), "404": ok("Not found.") }
1937
+ },
1938
+ delete: {
1939
+ operationId: "groups/delete",
1940
+ tags: ["groups"],
1941
+ summary: "Delete a group",
1942
+ parameters: [groupId],
1943
+ responses: { "204": noContent("Deleted."), "404": ok("Not found.") }
1944
+ }
1945
+ },
1946
+ "/api/v1/groups/{groupId}/users": {
1947
+ get: {
1948
+ operationId: "groups/listUsers",
1949
+ tags: ["groups"],
1950
+ summary: "List a group's members",
1951
+ parameters: [groupId],
1952
+ responses: { "200": ok("User list."), "404": ok("Not found.") }
1953
+ }
1954
+ },
1955
+ "/api/v1/groups/{groupId}/users/{userId}": {
1956
+ put: {
1957
+ operationId: "groups/addUser",
1958
+ tags: ["groups"],
1959
+ summary: "Add a user to a group",
1960
+ parameters: [groupId, userId],
1961
+ responses: { "204": noContent("Added."), "404": ok("Not found.") }
1962
+ },
1963
+ delete: {
1964
+ operationId: "groups/removeUser",
1965
+ tags: ["groups"],
1966
+ summary: "Remove a user from a group",
1967
+ parameters: [groupId, userId],
1968
+ responses: { "204": noContent("Removed."), "404": ok("Not found.") }
1969
+ }
1970
+ },
1971
+ "/api/v1/apps": {
1972
+ get: {
1973
+ operationId: "apps/list",
1974
+ tags: ["apps"],
1975
+ summary: "List applications",
1976
+ parameters: [q],
1977
+ responses: { "200": ok("Application list.") }
1978
+ },
1979
+ post: {
1980
+ operationId: "apps/create",
1981
+ tags: ["apps"],
1982
+ summary: "Create an application",
1983
+ requestBody: appBody("The application to create.", []),
1984
+ responses: { "201": ok("The created application.") }
1985
+ }
1986
+ },
1987
+ "/api/v1/apps/{appId}": {
1988
+ get: {
1989
+ operationId: "apps/get",
1990
+ tags: ["apps"],
1991
+ summary: "Retrieve an application",
1992
+ parameters: [appId],
1993
+ responses: { "200": ok("The application."), "404": ok("Not found.") }
1994
+ },
1995
+ put: {
1996
+ operationId: "apps/update",
1997
+ tags: ["apps"],
1998
+ summary: "Update an application",
1999
+ parameters: [appId],
2000
+ requestBody: appBody("The application fields to replace.", []),
2001
+ responses: { "200": ok("The updated application."), "404": ok("Not found.") }
2002
+ },
2003
+ delete: {
2004
+ operationId: "apps/delete",
2005
+ tags: ["apps"],
2006
+ summary: "Delete an INACTIVE application",
2007
+ parameters: [appId],
2008
+ responses: {
2009
+ "204": noContent("Deleted."),
2010
+ "400": ok("App must be INACTIVE before deletion."),
2011
+ "404": ok("Not found.")
2012
+ }
2013
+ }
2014
+ },
2015
+ "/api/v1/apps/{appId}/users": {
2016
+ get: {
2017
+ operationId: "apps/listUsers",
2018
+ tags: ["apps"],
2019
+ summary: "List users assigned to an application",
2020
+ parameters: [appId],
2021
+ responses: { "200": ok("Assigned user list."), "404": ok("Not found.") }
2022
+ }
2023
+ },
2024
+ "/api/v1/apps/{appId}/users/{userId}": {
2025
+ put: {
2026
+ operationId: "apps/assignUser",
2027
+ tags: ["apps"],
2028
+ summary: "Assign a user to an application",
2029
+ parameters: [appId, userId],
2030
+ responses: { "204": noContent("Assigned."), "404": ok("Not found.") }
2031
+ },
2032
+ delete: {
2033
+ operationId: "apps/unassignUser",
2034
+ tags: ["apps"],
2035
+ summary: "Unassign a user from an application",
2036
+ parameters: [appId, userId],
2037
+ responses: { "204": noContent("Unassigned."), "404": ok("Not found.") }
2038
+ }
2039
+ },
2040
+ "/api/v1/apps/{appId}/lifecycle/activate": {
2041
+ post: {
2042
+ operationId: "apps/activate",
2043
+ tags: ["apps"],
2044
+ summary: "Activate an application",
2045
+ parameters: [appId],
2046
+ responses: { "200": ok("The activated application."), "404": ok("Not found.") }
2047
+ }
2048
+ },
2049
+ "/api/v1/apps/{appId}/lifecycle/deactivate": {
2050
+ post: {
2051
+ operationId: "apps/deactivate",
2052
+ tags: ["apps"],
2053
+ summary: "Deactivate an application",
2054
+ parameters: [appId],
2055
+ responses: { "200": ok("The deactivated application."), "404": ok("Not found.") }
2056
+ }
2057
+ },
2058
+ "/api/v1/authorizationServers": {
2059
+ get: {
2060
+ operationId: "authorizationServers/list",
2061
+ tags: ["authorizationServers"],
2062
+ summary: "List authorization servers",
2063
+ responses: { "200": ok("Authorization server list.") }
2064
+ },
2065
+ post: {
2066
+ operationId: "authorizationServers/create",
2067
+ tags: ["authorizationServers"],
2068
+ summary: "Create an authorization server",
2069
+ requestBody: authServerBody("The authorization server to create (name is required).", ["name"]),
2070
+ responses: { "201": ok("The created authorization server."), "400": ok("Validation error.") }
2071
+ }
2072
+ },
2073
+ "/api/v1/authorizationServers/{authServerId}": {
2074
+ get: {
2075
+ operationId: "authorizationServers/get",
2076
+ tags: ["authorizationServers"],
2077
+ summary: "Retrieve an authorization server",
2078
+ parameters: [authServerId],
2079
+ responses: { "200": ok("The authorization server."), "404": ok("Not found.") }
2080
+ },
2081
+ put: {
2082
+ operationId: "authorizationServers/update",
2083
+ tags: ["authorizationServers"],
2084
+ summary: "Update an authorization server",
2085
+ parameters: [authServerId],
2086
+ requestBody: authServerBody("The authorization server fields to replace.", []),
2087
+ responses: { "200": ok("The updated authorization server."), "404": ok("Not found.") }
2088
+ },
2089
+ delete: {
2090
+ operationId: "authorizationServers/delete",
2091
+ tags: ["authorizationServers"],
2092
+ summary: "Delete an authorization server and its clients",
2093
+ parameters: [authServerId],
2094
+ responses: { "204": noContent("Deleted."), "404": ok("Not found.") }
2095
+ }
2096
+ },
2097
+ "/api/v1/authorizationServers/{authServerId}/lifecycle/activate": {
2098
+ post: {
2099
+ operationId: "authorizationServers/activate",
2100
+ tags: ["authorizationServers"],
2101
+ summary: "Activate an authorization server",
2102
+ parameters: [authServerId],
2103
+ responses: { "200": ok("The activated authorization server."), "404": ok("Not found.") }
2104
+ }
2105
+ },
2106
+ "/api/v1/authorizationServers/{authServerId}/lifecycle/deactivate": {
2107
+ post: {
2108
+ operationId: "authorizationServers/deactivate",
2109
+ tags: ["authorizationServers"],
2110
+ summary: "Deactivate an authorization server",
2111
+ parameters: [authServerId],
2112
+ responses: { "200": ok("The deactivated authorization server."), "404": ok("Not found.") }
2113
+ }
2114
+ }
2115
+ }
2116
+ };
2117
+ }
1695
2118
  function updateUserProfile(user, profile) {
1696
2119
  const nextFirstName = typeof profile.firstName === "string" ? profile.firstName : user.first_name;
1697
2120
  const nextLastName = typeof profile.lastName === "string" ? profile.lastName : user.last_name;
@@ -1721,13 +2144,13 @@ function userRoutes({ app, store, baseUrl, tokenMap }) {
1721
2144
  app.get("/api/v1/users", (c) => {
1722
2145
  const auth = requireManagementAuth(c, tokenMap);
1723
2146
  if (auth instanceof Response) return auth;
1724
- const q = (c.req.query("q") ?? "").toLowerCase();
2147
+ const q2 = (c.req.query("q") ?? "").toLowerCase();
1725
2148
  const search = (c.req.query("search") ?? "").toLowerCase();
1726
2149
  const filter = c.req.query("filter") ?? "";
1727
2150
  let users = oktaStore.users.all();
1728
- if (q) {
2151
+ if (q2) {
1729
2152
  users = users.filter(
1730
- (user) => [user.login, user.email, user.first_name, user.last_name, user.display_name].join(" ").toLowerCase().includes(q)
2153
+ (user) => [user.login, user.email, user.first_name, user.last_name, user.display_name].join(" ").toLowerCase().includes(q2)
1731
2154
  );
1732
2155
  }
1733
2156
  if (search) {
@@ -1930,7 +2353,8 @@ var manifest = {
1930
2353
  type: "oauth-client-credentials",
1931
2354
  status: "supported"
1932
2355
  },
1933
- { id: "oidc", title: "OIDC identity tokens", type: "oidc", status: "supported" }
2356
+ { id: "oidc", title: "OIDC identity tokens", type: "oidc", status: "supported" },
2357
+ { id: "api-token", title: "SSWS API token", type: "api-key", status: "supported" }
1934
2358
  ],
1935
2359
  specs: [
1936
2360
  {
@@ -1960,15 +2384,17 @@ var manifest = {
1960
2384
  ]
1961
2385
  },
1962
2386
  {
1963
- kind: "manual",
1964
- title: "Okta management API behavior",
1965
- coverage: "partial",
2387
+ kind: "openapi",
2388
+ title: "Okta management API subset",
2389
+ coverage: "hand-authored",
2390
+ url: "/openapi.json",
1966
2391
  operations: [
1967
2392
  { operationId: "users/list", method: "GET", path: "/api/v1/users", status: "hand-authored" },
1968
2393
  { operationId: "users/create", method: "POST", path: "/api/v1/users", status: "hand-authored" },
1969
2394
  { operationId: "users/getCurrent", method: "GET", path: "/api/v1/users/me", status: "hand-authored" },
1970
2395
  { operationId: "users/get", method: "GET", path: "/api/v1/users/:userId", status: "hand-authored" },
1971
2396
  { operationId: "users/update", method: "PUT", path: "/api/v1/users/:userId", status: "hand-authored" },
2397
+ { operationId: "users/partialUpdate", method: "POST", path: "/api/v1/users/:userId", status: "hand-authored" },
1972
2398
  { operationId: "users/delete", method: "DELETE", path: "/api/v1/users/:userId", status: "hand-authored" },
1973
2399
  {
1974
2400
  operationId: "users/listGroups",
@@ -1988,9 +2414,29 @@ var manifest = {
1988
2414
  path: "/api/v1/users/:userId/lifecycle/deactivate",
1989
2415
  status: "hand-authored"
1990
2416
  },
2417
+ {
2418
+ operationId: "users/suspend",
2419
+ method: "POST",
2420
+ path: "/api/v1/users/:userId/lifecycle/suspend",
2421
+ status: "hand-authored"
2422
+ },
2423
+ {
2424
+ operationId: "users/unsuspend",
2425
+ method: "POST",
2426
+ path: "/api/v1/users/:userId/lifecycle/unsuspend",
2427
+ status: "hand-authored"
2428
+ },
2429
+ {
2430
+ operationId: "users/reactivate",
2431
+ method: "POST",
2432
+ path: "/api/v1/users/:userId/lifecycle/reactivate",
2433
+ status: "hand-authored"
2434
+ },
1991
2435
  { operationId: "groups/list", method: "GET", path: "/api/v1/groups", status: "hand-authored" },
1992
2436
  { operationId: "groups/create", method: "POST", path: "/api/v1/groups", status: "hand-authored" },
1993
2437
  { operationId: "groups/get", method: "GET", path: "/api/v1/groups/:groupId", status: "hand-authored" },
2438
+ { operationId: "groups/update", method: "PUT", path: "/api/v1/groups/:groupId", status: "hand-authored" },
2439
+ { operationId: "groups/delete", method: "DELETE", path: "/api/v1/groups/:groupId", status: "hand-authored" },
1994
2440
  {
1995
2441
  operationId: "groups/listUsers",
1996
2442
  method: "GET",
@@ -2012,12 +2458,33 @@ var manifest = {
2012
2458
  { operationId: "apps/list", method: "GET", path: "/api/v1/apps", status: "hand-authored" },
2013
2459
  { operationId: "apps/create", method: "POST", path: "/api/v1/apps", status: "hand-authored" },
2014
2460
  { operationId: "apps/get", method: "GET", path: "/api/v1/apps/:appId", status: "hand-authored" },
2461
+ { operationId: "apps/update", method: "PUT", path: "/api/v1/apps/:appId", status: "hand-authored" },
2462
+ { operationId: "apps/delete", method: "DELETE", path: "/api/v1/apps/:appId", status: "hand-authored" },
2463
+ { operationId: "apps/listUsers", method: "GET", path: "/api/v1/apps/:appId/users", status: "hand-authored" },
2015
2464
  {
2016
2465
  operationId: "apps/assignUser",
2017
2466
  method: "PUT",
2018
2467
  path: "/api/v1/apps/:appId/users/:userId",
2019
2468
  status: "hand-authored"
2020
2469
  },
2470
+ {
2471
+ operationId: "apps/unassignUser",
2472
+ method: "DELETE",
2473
+ path: "/api/v1/apps/:appId/users/:userId",
2474
+ status: "hand-authored"
2475
+ },
2476
+ {
2477
+ operationId: "apps/activate",
2478
+ method: "POST",
2479
+ path: "/api/v1/apps/:appId/lifecycle/activate",
2480
+ status: "hand-authored"
2481
+ },
2482
+ {
2483
+ operationId: "apps/deactivate",
2484
+ method: "POST",
2485
+ path: "/api/v1/apps/:appId/lifecycle/deactivate",
2486
+ status: "hand-authored"
2487
+ },
2021
2488
  {
2022
2489
  operationId: "authorizationServers/list",
2023
2490
  method: "GET",
@@ -2035,6 +2502,30 @@ var manifest = {
2035
2502
  method: "GET",
2036
2503
  path: "/api/v1/authorizationServers/:authServerId",
2037
2504
  status: "hand-authored"
2505
+ },
2506
+ {
2507
+ operationId: "authorizationServers/update",
2508
+ method: "PUT",
2509
+ path: "/api/v1/authorizationServers/:authServerId",
2510
+ status: "hand-authored"
2511
+ },
2512
+ {
2513
+ operationId: "authorizationServers/delete",
2514
+ method: "DELETE",
2515
+ path: "/api/v1/authorizationServers/:authServerId",
2516
+ status: "hand-authored"
2517
+ },
2518
+ {
2519
+ operationId: "authorizationServers/activate",
2520
+ method: "POST",
2521
+ path: "/api/v1/authorizationServers/:authServerId/lifecycle/activate",
2522
+ status: "hand-authored"
2523
+ },
2524
+ {
2525
+ operationId: "authorizationServers/deactivate",
2526
+ method: "POST",
2527
+ path: "/api/v1/authorizationServers/:authServerId/lifecycle/deactivate",
2528
+ status: "hand-authored"
2038
2529
  }
2039
2530
  ]
2040
2531
  }
@@ -2318,6 +2809,7 @@ var oktaPlugin = {
2318
2809
  groupRoutes(ctx);
2319
2810
  appRoutes(ctx);
2320
2811
  authorizationServerRoutes(ctx);
2812
+ openapiRoutes(ctx);
2321
2813
  },
2322
2814
  seed(store, baseUrl) {
2323
2815
  seedDefaults(store, baseUrl);
@@ -2331,4 +2823,4 @@ export {
2331
2823
  oktaPlugin,
2332
2824
  seedFromConfig
2333
2825
  };
2334
- //# sourceMappingURL=dist-BTEY33DJ.js.map
2826
+ //# sourceMappingURL=dist-QXFWC3LV.js.map