@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
|
@@ -9,11 +9,7 @@ function getWorkosStore(store) {
|
|
|
9
9
|
return {
|
|
10
10
|
users: store.collection("workos.users", ["workos_id", "email"]),
|
|
11
11
|
organizations: store.collection("workos.organizations", ["workos_id"]),
|
|
12
|
-
memberships: store.collection("workos.memberships", [
|
|
13
|
-
"workos_id",
|
|
14
|
-
"user_id",
|
|
15
|
-
"organization_id"
|
|
16
|
-
]),
|
|
12
|
+
memberships: store.collection("workos.memberships", ["workos_id", "user_id", "organization_id"]),
|
|
17
13
|
invitations: store.collection("workos.invitations", [
|
|
18
14
|
"workos_id",
|
|
19
15
|
"email",
|
|
@@ -23,12 +19,10 @@ function getWorkosStore(store) {
|
|
|
23
19
|
apiKeys: store.collection("workos.api_keys", ["workos_id", "value", "user_id"]),
|
|
24
20
|
authCodes: store.collection("workos.auth_codes", ["code"]),
|
|
25
21
|
sessions: store.collection("workos.sessions", ["refresh_token", "workos_id"]),
|
|
26
|
-
vaultObjects: store.collection("workos.vault_objects", [
|
|
27
|
-
"workos_id",
|
|
28
|
-
"name"
|
|
29
|
-
]),
|
|
22
|
+
vaultObjects: store.collection("workos.vault_objects", ["workos_id", "name"]),
|
|
30
23
|
oauthClients: store.collection("workos.oauth_clients", ["client_id"]),
|
|
31
|
-
oauthCodes: store.collection("workos.oauth_codes", ["code"])
|
|
24
|
+
oauthCodes: store.collection("workos.oauth_codes", ["code"]),
|
|
25
|
+
oauthSettings: store.collection("workos.oauth_settings", [])
|
|
32
26
|
};
|
|
33
27
|
}
|
|
34
28
|
function createErrorHandler(documentationUrl) {
|
|
@@ -527,7 +521,8 @@ async function authenticationResponse(c, ws, baseUrl, user, organizationId, clie
|
|
|
527
521
|
user_id: user.workos_id,
|
|
528
522
|
organization_id: organizationId,
|
|
529
523
|
client_id: clientId,
|
|
530
|
-
revoked: false
|
|
524
|
+
revoked: false,
|
|
525
|
+
scope: null
|
|
531
526
|
});
|
|
532
527
|
const membership = organizationId ? ws.memberships.findBy("user_id", user.workos_id).find((m) => m.organization_id === organizationId) : void 0;
|
|
533
528
|
const accessToken = await signAccessToken(
|
|
@@ -970,7 +965,8 @@ function oauthRoutes(ctx) {
|
|
|
970
965
|
client_id: workosId("client"),
|
|
971
966
|
client_secret: null,
|
|
972
967
|
redirect_uris: Array.isArray(body.redirect_uris) ? body.redirect_uris : [],
|
|
973
|
-
name: typeof body.client_name === "string" ? body.client_name : null
|
|
968
|
+
name: typeof body.client_name === "string" ? body.client_name : null,
|
|
969
|
+
access_token_ttl_seconds: typeof body.access_token_ttl_seconds === "number" && body.access_token_ttl_seconds > 0 ? Math.floor(body.access_token_ttl_seconds) : null
|
|
974
970
|
});
|
|
975
971
|
return c.json(
|
|
976
972
|
{
|
|
@@ -989,6 +985,7 @@ function oauthRoutes(ctx) {
|
|
|
989
985
|
const redirectUri = c.req.query("redirect_uri") ?? "";
|
|
990
986
|
const state = c.req.query("state") ?? "";
|
|
991
987
|
const codeChallenge = c.req.query("code_challenge") ?? "";
|
|
988
|
+
const scope = c.req.query("scope") ?? "";
|
|
992
989
|
const loginHint = c.req.query("login_hint");
|
|
993
990
|
if (!redirectUri) return workosError(c, 422, "invalid_request", "redirect_uri is required");
|
|
994
991
|
const issue = (email) => {
|
|
@@ -1002,6 +999,7 @@ function oauthRoutes(ctx) {
|
|
|
1002
999
|
client_id: clientId,
|
|
1003
1000
|
redirect_uri: redirectUri,
|
|
1004
1001
|
code_challenge: codeChallenge || null,
|
|
1002
|
+
scope: scope || null,
|
|
1005
1003
|
used: false
|
|
1006
1004
|
});
|
|
1007
1005
|
const target = new URL(redirectUri);
|
|
@@ -1023,7 +1021,8 @@ function oauthRoutes(ctx) {
|
|
|
1023
1021
|
client_id: clientId,
|
|
1024
1022
|
redirect_uri: redirectUri,
|
|
1025
1023
|
state,
|
|
1026
|
-
code_challenge: codeChallenge
|
|
1024
|
+
code_challenge: codeChallenge,
|
|
1025
|
+
scope
|
|
1027
1026
|
}
|
|
1028
1027
|
})
|
|
1029
1028
|
).join("\n");
|
|
@@ -1033,6 +1032,7 @@ function oauthRoutes(ctx) {
|
|
|
1033
1032
|
<input type="hidden" name="redirect_uri" value="${escapeHtml(redirectUri)}" />
|
|
1034
1033
|
<input type="hidden" name="state" value="${escapeHtml(state)}" />
|
|
1035
1034
|
<input type="hidden" name="code_challenge" value="${escapeHtml(codeChallenge)}" />
|
|
1035
|
+
<input type="hidden" name="scope" value="${escapeHtml(scope)}" />
|
|
1036
1036
|
<input type="email" name="email" class="checkout-input" placeholder="new-user@example.com" required />
|
|
1037
1037
|
<button type="submit" class="checkout-pay-btn">Continue as new user</button>
|
|
1038
1038
|
</form>`;
|
|
@@ -1058,6 +1058,7 @@ function oauthRoutes(ctx) {
|
|
|
1058
1058
|
client_id: String(form.client_id ?? ""),
|
|
1059
1059
|
redirect_uri: redirectUri,
|
|
1060
1060
|
code_challenge: String(form.code_challenge ?? "") || null,
|
|
1061
|
+
scope: String(form.scope ?? "") || null,
|
|
1061
1062
|
used: false
|
|
1062
1063
|
});
|
|
1063
1064
|
const target = new URL(redirectUri);
|
|
@@ -1070,6 +1071,7 @@ function oauthRoutes(ctx) {
|
|
|
1070
1071
|
const contentType = c.req.header("content-type") ?? "";
|
|
1071
1072
|
const body = contentType.includes("json") ? await c.req.json().catch(() => ({})) : await c.req.parseBody();
|
|
1072
1073
|
const grantType = String(body.grant_type ?? "");
|
|
1074
|
+
const ttlFor = (clientId) => ws().oauthClients.findOneBy("client_id", clientId)?.access_token_ttl_seconds ?? ws().oauthSettings.all()[0]?.default_access_token_ttl_seconds ?? 3600;
|
|
1073
1075
|
if (grantType === "refresh_token") {
|
|
1074
1076
|
const refreshToken = String(body.refresh_token ?? "");
|
|
1075
1077
|
const session2 = ws().sessions.findOneBy("refresh_token", refreshToken);
|
|
@@ -1083,9 +1085,11 @@ function oauthRoutes(ctx) {
|
|
|
1083
1085
|
user_id: session2.user_id,
|
|
1084
1086
|
organization_id: session2.organization_id,
|
|
1085
1087
|
client_id: session2.client_id,
|
|
1086
|
-
revoked: false
|
|
1088
|
+
revoked: false,
|
|
1089
|
+
scope: session2.scope
|
|
1087
1090
|
});
|
|
1088
1091
|
const audience2 = process.env.EMULATE_WORKOS_AUDIENCE ?? session2.client_id;
|
|
1092
|
+
const expiresIn2 = ttlFor(session2.client_id);
|
|
1089
1093
|
const accessToken2 = await signAccessToken(
|
|
1090
1094
|
{
|
|
1091
1095
|
sub: session2.user_id,
|
|
@@ -1093,13 +1097,14 @@ function oauthRoutes(ctx) {
|
|
|
1093
1097
|
...session2.organization_id ? { org_id: session2.organization_id } : {},
|
|
1094
1098
|
permissions: []
|
|
1095
1099
|
},
|
|
1096
|
-
{ issuer: baseUrl, audience: audience2 }
|
|
1100
|
+
{ issuer: baseUrl, audience: audience2, expiresIn: `${expiresIn2}s` }
|
|
1097
1101
|
);
|
|
1098
1102
|
return c.json({
|
|
1099
1103
|
access_token: accessToken2,
|
|
1100
1104
|
token_type: "Bearer",
|
|
1101
|
-
expires_in:
|
|
1102
|
-
refresh_token: rotated.refresh_token
|
|
1105
|
+
expires_in: expiresIn2,
|
|
1106
|
+
refresh_token: rotated.refresh_token,
|
|
1107
|
+
...session2.scope ? { scope: session2.scope } : {}
|
|
1103
1108
|
});
|
|
1104
1109
|
}
|
|
1105
1110
|
if (grantType !== "authorization_code") {
|
|
@@ -1112,31 +1117,442 @@ function oauthRoutes(ctx) {
|
|
|
1112
1117
|
}
|
|
1113
1118
|
ws().oauthCodes.update(oauthCode.id, { used: true });
|
|
1114
1119
|
const audience = process.env.EMULATE_WORKOS_AUDIENCE ?? oauthCode.client_id;
|
|
1115
|
-
const
|
|
1120
|
+
const grantedScopes = (oauthCode.scope ?? "").split(" ").filter(Boolean);
|
|
1121
|
+
const offline = grantedScopes.includes("offline_access");
|
|
1122
|
+
const session = offline ? ws().sessions.insert({
|
|
1116
1123
|
workos_id: workosId("session"),
|
|
1117
1124
|
refresh_token: randomToken("rt"),
|
|
1118
1125
|
user_id: oauthCode.user_id,
|
|
1119
1126
|
organization_id: oauthCode.organization_id,
|
|
1120
1127
|
client_id: oauthCode.client_id,
|
|
1121
|
-
revoked: false
|
|
1122
|
-
|
|
1128
|
+
revoked: false,
|
|
1129
|
+
scope: oauthCode.scope
|
|
1130
|
+
}) : null;
|
|
1131
|
+
const expiresIn = ttlFor(oauthCode.client_id);
|
|
1123
1132
|
const accessToken = await signAccessToken(
|
|
1124
1133
|
{
|
|
1125
1134
|
sub: oauthCode.user_id,
|
|
1126
|
-
sid: session
|
|
1135
|
+
sid: session?.workos_id ?? workosId("session"),
|
|
1127
1136
|
...oauthCode.organization_id ? { org_id: oauthCode.organization_id } : {},
|
|
1128
1137
|
permissions: []
|
|
1129
1138
|
},
|
|
1130
|
-
{ issuer: baseUrl, audience }
|
|
1139
|
+
{ issuer: baseUrl, audience, expiresIn: `${expiresIn}s` }
|
|
1131
1140
|
);
|
|
1132
1141
|
return c.json({
|
|
1133
1142
|
access_token: accessToken,
|
|
1134
1143
|
token_type: "Bearer",
|
|
1135
|
-
expires_in:
|
|
1136
|
-
refresh_token: session.refresh_token
|
|
1144
|
+
expires_in: expiresIn,
|
|
1145
|
+
...session ? { refresh_token: session.refresh_token } : {},
|
|
1146
|
+
...grantedScopes.length > 0 ? { scope: grantedScopes.join(" ") } : {}
|
|
1137
1147
|
});
|
|
1138
1148
|
});
|
|
1139
1149
|
}
|
|
1150
|
+
function openapiRoutes({ app, baseUrl }) {
|
|
1151
|
+
app.get("/openapi.json", (c) => c.json(buildSpec(baseUrl)));
|
|
1152
|
+
}
|
|
1153
|
+
var ok = (description) => ({
|
|
1154
|
+
description,
|
|
1155
|
+
content: { "application/json": { schema: { type: "object" } } }
|
|
1156
|
+
});
|
|
1157
|
+
var noContent = (description) => ({ description });
|
|
1158
|
+
var id = { name: "id", in: "path", required: true, schema: { type: "string" } };
|
|
1159
|
+
var query = (name, description) => ({
|
|
1160
|
+
name,
|
|
1161
|
+
in: "query",
|
|
1162
|
+
required: false,
|
|
1163
|
+
schema: { type: "string" },
|
|
1164
|
+
description
|
|
1165
|
+
});
|
|
1166
|
+
var jsonBody = (properties, required, description) => ({
|
|
1167
|
+
required: true,
|
|
1168
|
+
description,
|
|
1169
|
+
content: {
|
|
1170
|
+
"application/json": {
|
|
1171
|
+
schema: { type: "object", properties, required: [...required] }
|
|
1172
|
+
}
|
|
1173
|
+
}
|
|
1174
|
+
});
|
|
1175
|
+
function buildSpec(baseUrl) {
|
|
1176
|
+
return {
|
|
1177
|
+
openapi: "3.1.0",
|
|
1178
|
+
info: {
|
|
1179
|
+
title: "WorkOS API (Emulated)",
|
|
1180
|
+
version: "1.0.0",
|
|
1181
|
+
description: "Emulated subset of the WorkOS REST API: user management, organization memberships, invitations, API keys, Vault KV, and the OAuth token surface. Authenticate with a bearer secret key (mint one at POST /_emulate/credentials)."
|
|
1182
|
+
},
|
|
1183
|
+
servers: [{ url: baseUrl }],
|
|
1184
|
+
components: {
|
|
1185
|
+
securitySchemes: {
|
|
1186
|
+
bearerAuth: {
|
|
1187
|
+
type: "http",
|
|
1188
|
+
scheme: "bearer",
|
|
1189
|
+
description: "WorkOS secret API key, sent as `Authorization: Bearer sk_\u2026`."
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
},
|
|
1193
|
+
security: [{ bearerAuth: [] }],
|
|
1194
|
+
paths: {
|
|
1195
|
+
"/user_management/authenticate": {
|
|
1196
|
+
post: {
|
|
1197
|
+
operationId: "userManagement.authenticate",
|
|
1198
|
+
tags: ["user-management"],
|
|
1199
|
+
summary: "Exchange an authorization code or refresh token for a session",
|
|
1200
|
+
security: [],
|
|
1201
|
+
requestBody: jsonBody(
|
|
1202
|
+
{
|
|
1203
|
+
grant_type: { type: "string", enum: ["authorization_code", "refresh_token"] },
|
|
1204
|
+
client_id: { type: "string" },
|
|
1205
|
+
code: { type: "string" },
|
|
1206
|
+
refresh_token: { type: "string" },
|
|
1207
|
+
organization_id: { type: "string" }
|
|
1208
|
+
},
|
|
1209
|
+
["grant_type"],
|
|
1210
|
+
"authorization_code grants need `code`; refresh_token grants need `refresh_token` (optionally switching `organization_id`)."
|
|
1211
|
+
),
|
|
1212
|
+
responses: {
|
|
1213
|
+
"200": ok("User, access token, and refresh token."),
|
|
1214
|
+
"400": ok("Invalid or used grant.")
|
|
1215
|
+
}
|
|
1216
|
+
}
|
|
1217
|
+
},
|
|
1218
|
+
"/user_management/users/{id}": {
|
|
1219
|
+
get: {
|
|
1220
|
+
operationId: "userManagement.getUser",
|
|
1221
|
+
tags: ["user-management"],
|
|
1222
|
+
summary: "Retrieve a user",
|
|
1223
|
+
parameters: [id],
|
|
1224
|
+
responses: { "200": ok("The user."), "404": ok("Not found.") }
|
|
1225
|
+
}
|
|
1226
|
+
},
|
|
1227
|
+
"/user_management/organization_memberships": {
|
|
1228
|
+
get: {
|
|
1229
|
+
operationId: "memberships.list",
|
|
1230
|
+
tags: ["memberships"],
|
|
1231
|
+
summary: "List organization memberships",
|
|
1232
|
+
parameters: [
|
|
1233
|
+
query("user_id", "Filter by user."),
|
|
1234
|
+
query("organization_id", "Filter by organization."),
|
|
1235
|
+
query("statuses", "Comma-separated membership statuses.")
|
|
1236
|
+
],
|
|
1237
|
+
responses: { "200": ok("Membership list.") }
|
|
1238
|
+
},
|
|
1239
|
+
post: {
|
|
1240
|
+
operationId: "memberships.create",
|
|
1241
|
+
tags: ["memberships"],
|
|
1242
|
+
summary: "Add a user to an organization",
|
|
1243
|
+
requestBody: jsonBody(
|
|
1244
|
+
{
|
|
1245
|
+
user_id: { type: "string" },
|
|
1246
|
+
organization_id: { type: "string" },
|
|
1247
|
+
role_slug: { type: "string" }
|
|
1248
|
+
},
|
|
1249
|
+
["user_id", "organization_id"],
|
|
1250
|
+
"The membership to create."
|
|
1251
|
+
),
|
|
1252
|
+
responses: {
|
|
1253
|
+
"201": ok("The created membership."),
|
|
1254
|
+
"404": ok("User or organization not found."),
|
|
1255
|
+
"409": ok("Already a member.")
|
|
1256
|
+
}
|
|
1257
|
+
}
|
|
1258
|
+
},
|
|
1259
|
+
"/user_management/organization_memberships/{id}": {
|
|
1260
|
+
get: {
|
|
1261
|
+
operationId: "memberships.get",
|
|
1262
|
+
tags: ["memberships"],
|
|
1263
|
+
summary: "Retrieve a membership",
|
|
1264
|
+
parameters: [id],
|
|
1265
|
+
responses: { "200": ok("The membership."), "404": ok("Not found.") }
|
|
1266
|
+
},
|
|
1267
|
+
put: {
|
|
1268
|
+
operationId: "memberships.update",
|
|
1269
|
+
tags: ["memberships"],
|
|
1270
|
+
summary: "Update a membership's role",
|
|
1271
|
+
parameters: [id],
|
|
1272
|
+
requestBody: jsonBody({ role_slug: { type: "string" } }, [], "Fields to update."),
|
|
1273
|
+
responses: { "200": ok("The updated membership."), "404": ok("Not found.") }
|
|
1274
|
+
},
|
|
1275
|
+
delete: {
|
|
1276
|
+
operationId: "memberships.delete",
|
|
1277
|
+
tags: ["memberships"],
|
|
1278
|
+
summary: "Remove a membership",
|
|
1279
|
+
parameters: [id],
|
|
1280
|
+
responses: { "204": noContent("Deleted."), "404": ok("Not found.") }
|
|
1281
|
+
}
|
|
1282
|
+
},
|
|
1283
|
+
"/user_management/invitations": {
|
|
1284
|
+
get: {
|
|
1285
|
+
operationId: "invitations.list",
|
|
1286
|
+
tags: ["invitations"],
|
|
1287
|
+
summary: "List invitations",
|
|
1288
|
+
parameters: [query("email", "Filter by invitee email."), query("organization_id", "Filter by organization.")],
|
|
1289
|
+
responses: { "200": ok("Invitation list.") }
|
|
1290
|
+
},
|
|
1291
|
+
post: {
|
|
1292
|
+
operationId: "invitations.send",
|
|
1293
|
+
tags: ["invitations"],
|
|
1294
|
+
summary: "Send an invitation",
|
|
1295
|
+
requestBody: jsonBody(
|
|
1296
|
+
{
|
|
1297
|
+
email: { type: "string" },
|
|
1298
|
+
organization_id: { type: "string" },
|
|
1299
|
+
inviter_user_id: { type: "string" },
|
|
1300
|
+
role_slug: { type: "string" }
|
|
1301
|
+
},
|
|
1302
|
+
["email", "organization_id"],
|
|
1303
|
+
"The invitation to send."
|
|
1304
|
+
),
|
|
1305
|
+
responses: {
|
|
1306
|
+
"201": ok("The created invitation."),
|
|
1307
|
+
"404": ok("Organization not found."),
|
|
1308
|
+
"422": ok("Validation error.")
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
1311
|
+
},
|
|
1312
|
+
"/user_management/invitations/{id}/accept": {
|
|
1313
|
+
post: {
|
|
1314
|
+
operationId: "invitations.accept",
|
|
1315
|
+
tags: ["invitations"],
|
|
1316
|
+
summary: "Accept a pending invitation",
|
|
1317
|
+
parameters: [id],
|
|
1318
|
+
responses: {
|
|
1319
|
+
"200": ok("The accepted invitation."),
|
|
1320
|
+
"400": ok("Invitation is not pending."),
|
|
1321
|
+
"404": ok("Not found.")
|
|
1322
|
+
}
|
|
1323
|
+
}
|
|
1324
|
+
},
|
|
1325
|
+
"/user_management/users/{id}/api_keys": {
|
|
1326
|
+
get: {
|
|
1327
|
+
operationId: "userApiKeys.list",
|
|
1328
|
+
tags: ["api-keys"],
|
|
1329
|
+
summary: "List a user's API keys",
|
|
1330
|
+
parameters: [id, query("organization_id", "Filter by organization.")],
|
|
1331
|
+
responses: { "200": ok("API key list.") }
|
|
1332
|
+
},
|
|
1333
|
+
post: {
|
|
1334
|
+
operationId: "userApiKeys.create",
|
|
1335
|
+
tags: ["api-keys"],
|
|
1336
|
+
summary: "Create an API key for a user",
|
|
1337
|
+
parameters: [id],
|
|
1338
|
+
requestBody: jsonBody(
|
|
1339
|
+
{ name: { type: "string" }, organization_id: { type: "string" } },
|
|
1340
|
+
[],
|
|
1341
|
+
"The API key to create."
|
|
1342
|
+
),
|
|
1343
|
+
responses: {
|
|
1344
|
+
"201": ok("The created key (value shown once)."),
|
|
1345
|
+
"404": ok("User not found.")
|
|
1346
|
+
}
|
|
1347
|
+
}
|
|
1348
|
+
},
|
|
1349
|
+
"/api_keys/validations": {
|
|
1350
|
+
post: {
|
|
1351
|
+
operationId: "apiKeys.validate",
|
|
1352
|
+
tags: ["api-keys"],
|
|
1353
|
+
summary: "Validate an API key value",
|
|
1354
|
+
requestBody: jsonBody({ value: { type: "string" } }, ["value"], "The API key value to validate."),
|
|
1355
|
+
responses: { "200": ok("The matching key."), "404": ok("Invalid API key.") }
|
|
1356
|
+
}
|
|
1357
|
+
},
|
|
1358
|
+
"/api_keys/{id}": {
|
|
1359
|
+
delete: {
|
|
1360
|
+
operationId: "apiKeys.delete",
|
|
1361
|
+
tags: ["api-keys"],
|
|
1362
|
+
summary: "Delete an API key",
|
|
1363
|
+
parameters: [id],
|
|
1364
|
+
responses: { "204": noContent("Deleted."), "404": ok("Not found.") }
|
|
1365
|
+
}
|
|
1366
|
+
},
|
|
1367
|
+
"/organizations": {
|
|
1368
|
+
post: {
|
|
1369
|
+
operationId: "organizations.create",
|
|
1370
|
+
tags: ["organizations"],
|
|
1371
|
+
summary: "Create an organization",
|
|
1372
|
+
requestBody: jsonBody(
|
|
1373
|
+
{ name: { type: "string" }, external_id: { type: "string" } },
|
|
1374
|
+
["name"],
|
|
1375
|
+
"The organization to create."
|
|
1376
|
+
),
|
|
1377
|
+
responses: { "201": ok("The created organization."), "422": ok("Validation error.") }
|
|
1378
|
+
}
|
|
1379
|
+
},
|
|
1380
|
+
"/organizations/{id}": {
|
|
1381
|
+
get: {
|
|
1382
|
+
operationId: "organizations.get",
|
|
1383
|
+
tags: ["organizations"],
|
|
1384
|
+
summary: "Retrieve an organization",
|
|
1385
|
+
parameters: [id],
|
|
1386
|
+
responses: { "200": ok("The organization."), "404": ok("Not found.") }
|
|
1387
|
+
},
|
|
1388
|
+
put: {
|
|
1389
|
+
operationId: "organizations.update",
|
|
1390
|
+
tags: ["organizations"],
|
|
1391
|
+
summary: "Update an organization",
|
|
1392
|
+
parameters: [id],
|
|
1393
|
+
requestBody: jsonBody({ name: { type: "string" } }, [], "Fields to update."),
|
|
1394
|
+
responses: { "200": ok("The updated organization."), "404": ok("Not found.") }
|
|
1395
|
+
}
|
|
1396
|
+
},
|
|
1397
|
+
"/organizations/{id}/roles": {
|
|
1398
|
+
get: {
|
|
1399
|
+
operationId: "organizations.roles",
|
|
1400
|
+
tags: ["organizations"],
|
|
1401
|
+
summary: "List an organization's roles",
|
|
1402
|
+
parameters: [id],
|
|
1403
|
+
responses: { "200": ok("Role list."), "404": ok("Not found.") }
|
|
1404
|
+
}
|
|
1405
|
+
},
|
|
1406
|
+
"/sso/jwks/{clientId}": {
|
|
1407
|
+
get: {
|
|
1408
|
+
operationId: "sso.jwks",
|
|
1409
|
+
tags: ["oauth"],
|
|
1410
|
+
summary: "JWKS for verifying issued access tokens",
|
|
1411
|
+
security: [],
|
|
1412
|
+
parameters: [{ name: "clientId", in: "path", required: true, schema: { type: "string" } }],
|
|
1413
|
+
responses: { "200": ok("JSON Web Key Set.") }
|
|
1414
|
+
}
|
|
1415
|
+
},
|
|
1416
|
+
"/.well-known/oauth-authorization-server": {
|
|
1417
|
+
get: {
|
|
1418
|
+
operationId: "oauth.metadata",
|
|
1419
|
+
tags: ["oauth"],
|
|
1420
|
+
summary: "OAuth authorization-server metadata",
|
|
1421
|
+
security: [],
|
|
1422
|
+
responses: { "200": ok("Authorization-server metadata.") }
|
|
1423
|
+
}
|
|
1424
|
+
},
|
|
1425
|
+
"/oauth2/register": {
|
|
1426
|
+
post: {
|
|
1427
|
+
operationId: "oauth.register",
|
|
1428
|
+
tags: ["oauth"],
|
|
1429
|
+
summary: "Dynamically register an OAuth client",
|
|
1430
|
+
security: [],
|
|
1431
|
+
requestBody: jsonBody(
|
|
1432
|
+
{
|
|
1433
|
+
redirect_uris: { type: "array", items: { type: "string" } },
|
|
1434
|
+
client_name: { type: "string" }
|
|
1435
|
+
},
|
|
1436
|
+
[],
|
|
1437
|
+
"The client to register."
|
|
1438
|
+
),
|
|
1439
|
+
responses: { "201": ok("The registered client.") }
|
|
1440
|
+
}
|
|
1441
|
+
},
|
|
1442
|
+
"/oauth2/token": {
|
|
1443
|
+
post: {
|
|
1444
|
+
operationId: "oauth.token",
|
|
1445
|
+
tags: ["oauth"],
|
|
1446
|
+
summary: "Exchange an authorization code or refresh token for tokens",
|
|
1447
|
+
security: [],
|
|
1448
|
+
requestBody: {
|
|
1449
|
+
required: true,
|
|
1450
|
+
description: "Form-encoded or JSON. authorization_code grants need `code`; refresh_token grants need `refresh_token`.",
|
|
1451
|
+
content: {
|
|
1452
|
+
"application/x-www-form-urlencoded": {
|
|
1453
|
+
schema: {
|
|
1454
|
+
type: "object",
|
|
1455
|
+
properties: {
|
|
1456
|
+
grant_type: {
|
|
1457
|
+
type: "string",
|
|
1458
|
+
enum: ["authorization_code", "refresh_token"]
|
|
1459
|
+
},
|
|
1460
|
+
code: { type: "string" },
|
|
1461
|
+
refresh_token: { type: "string" }
|
|
1462
|
+
},
|
|
1463
|
+
required: ["grant_type"]
|
|
1464
|
+
}
|
|
1465
|
+
},
|
|
1466
|
+
"application/json": {
|
|
1467
|
+
schema: {
|
|
1468
|
+
type: "object",
|
|
1469
|
+
properties: {
|
|
1470
|
+
grant_type: {
|
|
1471
|
+
type: "string",
|
|
1472
|
+
enum: ["authorization_code", "refresh_token"]
|
|
1473
|
+
},
|
|
1474
|
+
code: { type: "string" },
|
|
1475
|
+
refresh_token: { type: "string" }
|
|
1476
|
+
},
|
|
1477
|
+
required: ["grant_type"]
|
|
1478
|
+
}
|
|
1479
|
+
}
|
|
1480
|
+
}
|
|
1481
|
+
},
|
|
1482
|
+
responses: { "200": ok("Access and refresh tokens."), "400": ok("Invalid grant.") }
|
|
1483
|
+
}
|
|
1484
|
+
},
|
|
1485
|
+
"/vault/v1/kv": {
|
|
1486
|
+
post: {
|
|
1487
|
+
operationId: "vault.create",
|
|
1488
|
+
tags: ["vault"],
|
|
1489
|
+
summary: "Create a Vault KV object",
|
|
1490
|
+
requestBody: jsonBody(
|
|
1491
|
+
{
|
|
1492
|
+
name: { type: "string" },
|
|
1493
|
+
value: { type: "string" },
|
|
1494
|
+
key_context: { type: "object" }
|
|
1495
|
+
},
|
|
1496
|
+
["name"],
|
|
1497
|
+
"The object to create."
|
|
1498
|
+
),
|
|
1499
|
+
responses: {
|
|
1500
|
+
"201": ok("The created object's metadata."),
|
|
1501
|
+
"400": ok("Validation error."),
|
|
1502
|
+
"409": ok("Name already exists.")
|
|
1503
|
+
}
|
|
1504
|
+
},
|
|
1505
|
+
get: {
|
|
1506
|
+
operationId: "vault.list",
|
|
1507
|
+
tags: ["vault"],
|
|
1508
|
+
summary: "List Vault KV objects",
|
|
1509
|
+
responses: { "200": ok("Object list (id + name).") }
|
|
1510
|
+
}
|
|
1511
|
+
},
|
|
1512
|
+
"/vault/v1/kv/name/{name}": {
|
|
1513
|
+
get: {
|
|
1514
|
+
operationId: "vault.readByName",
|
|
1515
|
+
tags: ["vault"],
|
|
1516
|
+
summary: "Read a Vault KV object by name",
|
|
1517
|
+
parameters: [{ name: "name", in: "path", required: true, schema: { type: "string" } }],
|
|
1518
|
+
responses: { "200": ok("The object."), "404": ok("Not found.") }
|
|
1519
|
+
}
|
|
1520
|
+
},
|
|
1521
|
+
"/vault/v1/kv/{id}": {
|
|
1522
|
+
get: {
|
|
1523
|
+
operationId: "vault.read",
|
|
1524
|
+
tags: ["vault"],
|
|
1525
|
+
summary: "Read a Vault KV object",
|
|
1526
|
+
parameters: [id],
|
|
1527
|
+
responses: { "200": ok("The object."), "404": ok("Not found.") }
|
|
1528
|
+
},
|
|
1529
|
+
put: {
|
|
1530
|
+
operationId: "vault.update",
|
|
1531
|
+
tags: ["vault"],
|
|
1532
|
+
summary: "Update a Vault KV object's value",
|
|
1533
|
+
parameters: [id],
|
|
1534
|
+
requestBody: jsonBody(
|
|
1535
|
+
{ value: { type: "string" }, version_check: { type: "string" } },
|
|
1536
|
+
[],
|
|
1537
|
+
"The new value; pass `version_check` for optimistic concurrency."
|
|
1538
|
+
),
|
|
1539
|
+
responses: {
|
|
1540
|
+
"200": ok("The updated object."),
|
|
1541
|
+
"404": ok("Not found."),
|
|
1542
|
+
"409": ok("Version check failed.")
|
|
1543
|
+
}
|
|
1544
|
+
},
|
|
1545
|
+
delete: {
|
|
1546
|
+
operationId: "vault.delete",
|
|
1547
|
+
tags: ["vault"],
|
|
1548
|
+
summary: "Delete a Vault KV object",
|
|
1549
|
+
parameters: [id],
|
|
1550
|
+
responses: { "204": noContent("Deleted."), "404": ok("Not found.") }
|
|
1551
|
+
}
|
|
1552
|
+
}
|
|
1553
|
+
}
|
|
1554
|
+
};
|
|
1555
|
+
}
|
|
1140
1556
|
var manifest = {
|
|
1141
1557
|
id: "workos",
|
|
1142
1558
|
name: "WorkOS",
|
|
@@ -1144,43 +1560,120 @@ var manifest = {
|
|
|
1144
1560
|
docsUrl: "https://docs.emulators.dev/workos",
|
|
1145
1561
|
surfaces: [
|
|
1146
1562
|
{ id: "rest", kind: "rest", title: "WorkOS REST API", status: "partial", basePath: "/" },
|
|
1147
|
-
{
|
|
1563
|
+
{
|
|
1564
|
+
id: "authkit",
|
|
1565
|
+
kind: "ui",
|
|
1566
|
+
title: "Hosted AuthKit login",
|
|
1567
|
+
status: "supported",
|
|
1568
|
+
basePath: "/user_management/authorize"
|
|
1569
|
+
},
|
|
1148
1570
|
{ id: "oauth", kind: "rest", title: "OAuth authorization server (MCP)", status: "supported", basePath: "/oauth2" },
|
|
1149
1571
|
{ id: "vault", kind: "rest", title: "Vault KV", status: "supported", basePath: "/vault/v1/kv" }
|
|
1150
1572
|
],
|
|
1151
1573
|
auth: [{ id: "api-key", title: "WorkOS secret key", type: "api-key", status: "supported" }],
|
|
1152
1574
|
specs: [
|
|
1153
1575
|
{
|
|
1154
|
-
kind: "
|
|
1576
|
+
kind: "openapi",
|
|
1155
1577
|
title: "WorkOS User Management + Organizations subset",
|
|
1156
1578
|
coverage: "hand-authored",
|
|
1579
|
+
url: "/openapi.json",
|
|
1157
1580
|
operations: [
|
|
1158
|
-
{
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
{
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
{
|
|
1581
|
+
{
|
|
1582
|
+
operationId: "userManagement.authenticate",
|
|
1583
|
+
method: "POST",
|
|
1584
|
+
path: "/user_management/authenticate",
|
|
1585
|
+
status: "hand-authored"
|
|
1586
|
+
},
|
|
1587
|
+
{
|
|
1588
|
+
operationId: "userManagement.getUser",
|
|
1589
|
+
method: "GET",
|
|
1590
|
+
path: "/user_management/users/:id",
|
|
1591
|
+
status: "hand-authored"
|
|
1592
|
+
},
|
|
1593
|
+
{
|
|
1594
|
+
operationId: "memberships.list",
|
|
1595
|
+
method: "GET",
|
|
1596
|
+
path: "/user_management/organization_memberships",
|
|
1597
|
+
status: "hand-authored"
|
|
1598
|
+
},
|
|
1599
|
+
{
|
|
1600
|
+
operationId: "memberships.create",
|
|
1601
|
+
method: "POST",
|
|
1602
|
+
path: "/user_management/organization_memberships",
|
|
1603
|
+
status: "hand-authored"
|
|
1604
|
+
},
|
|
1605
|
+
{
|
|
1606
|
+
operationId: "memberships.get",
|
|
1607
|
+
method: "GET",
|
|
1608
|
+
path: "/user_management/organization_memberships/:id",
|
|
1609
|
+
status: "hand-authored"
|
|
1610
|
+
},
|
|
1611
|
+
{
|
|
1612
|
+
operationId: "memberships.update",
|
|
1613
|
+
method: "PUT",
|
|
1614
|
+
path: "/user_management/organization_memberships/:id",
|
|
1615
|
+
status: "hand-authored"
|
|
1616
|
+
},
|
|
1617
|
+
{
|
|
1618
|
+
operationId: "memberships.delete",
|
|
1619
|
+
method: "DELETE",
|
|
1620
|
+
path: "/user_management/organization_memberships/:id",
|
|
1621
|
+
status: "hand-authored"
|
|
1622
|
+
},
|
|
1623
|
+
{
|
|
1624
|
+
operationId: "invitations.list",
|
|
1625
|
+
method: "GET",
|
|
1626
|
+
path: "/user_management/invitations",
|
|
1627
|
+
status: "hand-authored"
|
|
1628
|
+
},
|
|
1629
|
+
{
|
|
1630
|
+
operationId: "invitations.send",
|
|
1631
|
+
method: "POST",
|
|
1632
|
+
path: "/user_management/invitations",
|
|
1633
|
+
status: "hand-authored"
|
|
1634
|
+
},
|
|
1635
|
+
{
|
|
1636
|
+
operationId: "invitations.accept",
|
|
1637
|
+
method: "POST",
|
|
1638
|
+
path: "/user_management/invitations/:id/accept",
|
|
1639
|
+
status: "hand-authored"
|
|
1640
|
+
},
|
|
1641
|
+
{
|
|
1642
|
+
operationId: "userApiKeys.list",
|
|
1643
|
+
method: "GET",
|
|
1644
|
+
path: "/user_management/users/:id/api_keys",
|
|
1645
|
+
status: "hand-authored"
|
|
1646
|
+
},
|
|
1647
|
+
{
|
|
1648
|
+
operationId: "userApiKeys.create",
|
|
1649
|
+
method: "POST",
|
|
1650
|
+
path: "/user_management/users/:id/api_keys",
|
|
1651
|
+
status: "hand-authored"
|
|
1652
|
+
},
|
|
1171
1653
|
{ operationId: "apiKeys.validate", method: "POST", path: "/api_keys/validations", status: "hand-authored" },
|
|
1172
1654
|
{ operationId: "apiKeys.delete", method: "DELETE", path: "/api_keys/:id", status: "hand-authored" },
|
|
1173
1655
|
{ operationId: "organizations.create", method: "POST", path: "/organizations", status: "hand-authored" },
|
|
1174
1656
|
{ operationId: "organizations.get", method: "GET", path: "/organizations/:id", status: "hand-authored" },
|
|
1175
1657
|
{ operationId: "organizations.update", method: "PUT", path: "/organizations/:id", status: "hand-authored" },
|
|
1176
|
-
{
|
|
1658
|
+
{
|
|
1659
|
+
operationId: "organizations.roles",
|
|
1660
|
+
method: "GET",
|
|
1661
|
+
path: "/organizations/:id/roles",
|
|
1662
|
+
status: "hand-authored"
|
|
1663
|
+
},
|
|
1177
1664
|
{ operationId: "sso.jwks", method: "GET", path: "/sso/jwks/:clientId", status: "hand-authored" },
|
|
1178
|
-
{
|
|
1665
|
+
{
|
|
1666
|
+
operationId: "oauth.metadata",
|
|
1667
|
+
method: "GET",
|
|
1668
|
+
path: "/.well-known/oauth-authorization-server",
|
|
1669
|
+
status: "hand-authored"
|
|
1670
|
+
},
|
|
1179
1671
|
{ operationId: "oauth.register", method: "POST", path: "/oauth2/register", status: "hand-authored" },
|
|
1180
|
-
{ operationId: "oauth.authorize", method: "GET", path: "/oauth2/authorize", status: "hand-authored" },
|
|
1181
1672
|
{ operationId: "oauth.token", method: "POST", path: "/oauth2/token", status: "hand-authored" },
|
|
1182
1673
|
{ operationId: "vault.create", method: "POST", path: "/vault/v1/kv", status: "hand-authored" },
|
|
1674
|
+
{ operationId: "vault.list", method: "GET", path: "/vault/v1/kv", status: "hand-authored" },
|
|
1183
1675
|
{ operationId: "vault.readByName", method: "GET", path: "/vault/v1/kv/name/:name", status: "hand-authored" },
|
|
1676
|
+
{ operationId: "vault.read", method: "GET", path: "/vault/v1/kv/:id", status: "hand-authored" },
|
|
1184
1677
|
{ operationId: "vault.update", method: "PUT", path: "/vault/v1/kv/:id", status: "hand-authored" },
|
|
1185
1678
|
{ operationId: "vault.delete", method: "DELETE", path: "/vault/v1/kv/:id", status: "hand-authored" }
|
|
1186
1679
|
]
|
|
@@ -1233,6 +1726,12 @@ var manifest = {
|
|
|
1233
1726
|
};
|
|
1234
1727
|
function seedFromConfig(store, _baseUrl, config) {
|
|
1235
1728
|
const ws = getWorkosStore(store);
|
|
1729
|
+
if (config.oauth !== void 0) {
|
|
1730
|
+
const ttl = config.oauth.default_access_token_ttl_seconds ?? null;
|
|
1731
|
+
const existing = ws.oauthSettings.all()[0];
|
|
1732
|
+
if (existing) ws.oauthSettings.update(existing.id, { default_access_token_ttl_seconds: ttl });
|
|
1733
|
+
else ws.oauthSettings.insert({ default_access_token_ttl_seconds: ttl });
|
|
1734
|
+
}
|
|
1236
1735
|
for (const user of config.users ?? []) {
|
|
1237
1736
|
const created = ensureUserByEmail(ws, user.email);
|
|
1238
1737
|
if (user.first_name || user.last_name) {
|
|
@@ -1269,6 +1768,7 @@ var workosPlugin = {
|
|
|
1269
1768
|
organizationRoutes(ctx);
|
|
1270
1769
|
apiKeyRoutes(ctx);
|
|
1271
1770
|
vaultRoutes(ctx);
|
|
1771
|
+
openapiRoutes(ctx);
|
|
1272
1772
|
},
|
|
1273
1773
|
seed(_store, _baseUrl) {
|
|
1274
1774
|
}
|
|
@@ -1281,4 +1781,4 @@ export {
|
|
|
1281
1781
|
seedFromConfig,
|
|
1282
1782
|
workosPlugin
|
|
1283
1783
|
};
|
|
1284
|
-
//# sourceMappingURL=dist-
|
|
1784
|
+
//# sourceMappingURL=dist-S47YJ552.js.map
|