@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.
- package/dist/api.d.ts +333 -3
- package/dist/api.js +125 -13
- package/dist/api.js.map +1 -1
- package/dist/{dist-YPRJYQHW.js → dist-FE2JWST3.js} +846 -234
- package/dist/dist-FE2JWST3.js.map +1 -0
- package/dist/{dist-K4CVTD6K.js → dist-KBZ6SM7D.js} +357 -12
- package/dist/dist-KBZ6SM7D.js.map +1 -0
- package/dist/{dist-RMPDKZUA.js → dist-OT6R2YO2.js} +440 -81
- package/dist/dist-OT6R2YO2.js.map +1 -0
- package/dist/{dist-WBKONLOE.js → dist-OVTPVMMW.js} +636 -165
- package/dist/dist-OVTPVMMW.js.map +1 -0
- package/dist/{dist-BTEY33DJ.js → dist-QXFWC3LV.js} +567 -75
- package/dist/dist-QXFWC3LV.js.map +1 -0
- package/dist/{dist-IYZPDKJW.js → dist-S47YJ552.js} +543 -43
- package/dist/dist-S47YJ552.js.map +1 -0
- package/dist/{dist-XM5HSBDC.js → dist-TWJXVA7X.js} +268 -30
- package/dist/dist-TWJXVA7X.js.map +1 -0
- package/dist/{dist-JJ2ZRCAX.js → dist-YXHZTLFR.js} +138 -7
- package/dist/dist-YXHZTLFR.js.map +1 -0
- package/dist/index.js +10 -10
- package/dist/index.js.map +1 -1
- package/package.json +4 -7
- package/dist/dist-BTEY33DJ.js.map +0 -1
- package/dist/dist-IYZPDKJW.js.map +0 -1
- package/dist/dist-JJ2ZRCAX.js.map +0 -1
- package/dist/dist-K4CVTD6K.js.map +0 -1
- package/dist/dist-RMPDKZUA.js.map +0 -1
- package/dist/dist-WBKONLOE.js.map +0 -1
- package/dist/dist-XM5HSBDC.js.map +0 -1
- package/dist/dist-YPRJYQHW.js.map +0 -1
|
@@ -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,
|
|
49
|
-
if (
|
|
50
|
-
return `${baseUrl}/oauth2/${
|
|
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
|
|
698
|
+
const q2 = (c.req.query("q") ?? "").toLowerCase();
|
|
699
699
|
let apps = oktaStore.apps.all();
|
|
700
|
-
if (
|
|
701
|
-
apps = apps.filter((entry) => `${entry.name} ${entry.label}`.toLowerCase().includes(
|
|
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
|
|
922
|
+
const q2 = (c.req.query("q") ?? "").toLowerCase();
|
|
923
923
|
let groups = oktaStore.groups.all();
|
|
924
|
-
if (
|
|
925
|
-
groups = groups.filter((group) => `${group.name} ${group.description ?? ""}`.toLowerCase().includes(
|
|
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(
|
|
1064
|
-
if (
|
|
1065
|
-
return `/oauth2/${encodeURIComponent(
|
|
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,
|
|
1068
|
-
return clients.filter((client) => client.auth_server_id ===
|
|
1067
|
+
function getClientsForServer(clients, authServerId2) {
|
|
1068
|
+
return clients.filter((client) => client.auth_server_id === authServerId2);
|
|
1069
1069
|
}
|
|
1070
|
-
function resolveServer(
|
|
1071
|
-
if (
|
|
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",
|
|
1078
|
+
const server = store.authorizationServers.findOneBy("server_id", authServerId2);
|
|
1079
1079
|
if (!server) return null;
|
|
1080
1080
|
return {
|
|
1081
|
-
authServerId,
|
|
1082
|
-
issuer: resolveOktaIssuer(baseUrl,
|
|
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,
|
|
1166
|
-
const scopedClients = getClientsForServer(clients,
|
|
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
|
|
1242
|
-
const server = resolveServer(
|
|
1243
|
-
if (!server) return oktaError(c, 404, "E0000007", `Not found: authorization server '${
|
|
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
|
|
1255
|
-
const server = resolveServer(
|
|
1256
|
-
if (!server) return oktaError(c, 404, "E0000007", `Not found: authorization server '${
|
|
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,
|
|
1264
|
-
const server = resolveServer(
|
|
1265
|
-
if (!server) return oktaError(c, 404, "E0000007", `Not found: authorization server '${
|
|
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(),
|
|
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(
|
|
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:
|
|
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,
|
|
1345
|
-
const server = resolveServer(
|
|
1346
|
-
if (!server) return oktaError(c, 404, "E0000007", `Not found: authorization server '${
|
|
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(),
|
|
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=${
|
|
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,
|
|
1414
|
-
const server = resolveServer(
|
|
1415
|
-
if (!server) return oktaError(c, 404, "E0000007", `Not found: authorization server '${
|
|
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(),
|
|
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 !==
|
|
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 !==
|
|
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,
|
|
1600
|
-
const server = resolveServer(
|
|
1601
|
-
if (!server) return oktaError(c, 404, "E0000007", `Not found: authorization server '${
|
|
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 !==
|
|
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,
|
|
1626
|
-
const server = resolveServer(
|
|
1627
|
-
if (!server) return oktaError(c, 404, "E0000007", `Not found: authorization server '${
|
|
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,
|
|
1638
|
-
const server = resolveServer(
|
|
1639
|
-
if (!server) return oktaError(c, 404, "E0000007", `Not found: authorization server '${
|
|
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(),
|
|
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 ===
|
|
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 ===
|
|
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,
|
|
1681
|
-
const server = resolveServer(
|
|
1682
|
-
if (!server) return oktaError(c, 404, "E0000007", `Not found: authorization server '${
|
|
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(),
|
|
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
|
|
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 (
|
|
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(
|
|
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: "
|
|
1964
|
-
title: "Okta management API
|
|
1965
|
-
coverage: "
|
|
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-
|
|
2826
|
+
//# sourceMappingURL=dist-QXFWC3LV.js.map
|