emulate 0.4.0 → 0.5.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/README.md +59 -10
- package/dist/api.d.ts +2 -1
- package/dist/api.js +232 -96
- package/dist/api.js.map +1 -1
- package/dist/{chunk-TEPNEZ63.js → chunk-AQ2CLRU3.js} +26 -23
- package/dist/chunk-AQ2CLRU3.js.map +1 -0
- package/dist/chunk-WVQMFHQM.js +83 -0
- package/dist/chunk-WVQMFHQM.js.map +1 -0
- package/dist/{dist-RDFBZ5O6.js → dist-4X2KPMAJ.js} +212 -47
- package/dist/dist-4X2KPMAJ.js.map +1 -0
- package/dist/{dist-OTJZRQ3Q.js → dist-5JVGPOL3.js} +217 -75
- package/dist/dist-5JVGPOL3.js.map +1 -0
- package/dist/{dist-G7WQPZ3Y.js → dist-CE6BUCWQ.js} +211 -60
- package/dist/dist-CE6BUCWQ.js.map +1 -0
- package/dist/{dist-6JFNJPUU.js → dist-CFST4X4K.js} +172 -22
- package/dist/dist-CFST4X4K.js.map +1 -0
- package/dist/{dist-YOVM5HEY.js → dist-ENKE2S7V.js} +521 -60
- package/dist/dist-ENKE2S7V.js.map +1 -0
- package/dist/{dist-RMK3BS5M.js → dist-ETHHYBGF.js} +197 -33
- package/dist/dist-ETHHYBGF.js.map +1 -0
- package/dist/{dist-QMOJM6DV.js → dist-IBXD3O6A.js} +239 -54
- package/dist/dist-IBXD3O6A.js.map +1 -0
- package/dist/dist-J6LHUR52.js +1899 -0
- package/dist/dist-J6LHUR52.js.map +1 -0
- package/dist/{dist-6EW7SSOZ.js → dist-KKTYBE5S.js} +391 -222
- package/dist/dist-KKTYBE5S.js.map +1 -0
- package/dist/{dist-VVXVP5EZ.js → dist-LDUHEJAN.js} +553 -91
- package/dist/dist-LDUHEJAN.js.map +1 -0
- package/dist/{dist-B674PYKV.js → dist-PWGOAQC6.js} +22 -43
- package/dist/dist-PWGOAQC6.js.map +1 -0
- package/dist/{dist-H6JYGQM4.js → dist-REDHDZ3V.js} +272 -157
- package/dist/dist-REDHDZ3V.js.map +1 -0
- package/dist/fonts/favicon.ico +0 -0
- package/dist/helpers-LXLP3DFE-LBOTATT5.js +17 -0
- package/dist/helpers-LXLP3DFE-LBOTATT5.js.map +1 -0
- package/dist/index.js +365 -108
- package/dist/index.js.map +1 -1
- package/package.json +17 -14
- package/dist/chunk-TEPNEZ63.js.map +0 -1
- package/dist/dist-6EW7SSOZ.js.map +0 -1
- package/dist/dist-6JFNJPUU.js.map +0 -1
- package/dist/dist-B674PYKV.js.map +0 -1
- package/dist/dist-G7WQPZ3Y.js.map +0 -1
- package/dist/dist-H6JYGQM4.js.map +0 -1
- package/dist/dist-OTJZRQ3Q.js.map +0 -1
- package/dist/dist-QMOJM6DV.js.map +0 -1
- package/dist/dist-RDFBZ5O6.js.map +0 -1
- package/dist/dist-RMK3BS5M.js.map +0 -1
- package/dist/dist-VVXVP5EZ.js.map +0 -1
- package/dist/dist-YOVM5HEY.js.map +0 -1
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
exportJWK,
|
|
4
4
|
generateKeyPair
|
|
5
5
|
} from "./chunk-D6EKRYGP.js";
|
|
6
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-AQ2CLRU3.js";
|
|
7
7
|
|
|
8
8
|
// ../@emulators/okta/dist/index.js
|
|
9
9
|
import { randomUUID } from "crypto";
|
|
@@ -129,6 +129,7 @@ var FONTS = {
|
|
|
129
129
|
"geist-sans.woff2": readFileSync(join(__dirname, "fonts", "geist-sans.woff2")),
|
|
130
130
|
"GeistPixel-Square.woff2": readFileSync(join(__dirname, "fonts", "GeistPixel-Square.woff2"))
|
|
131
131
|
};
|
|
132
|
+
var FAVICON = readFileSync(join(__dirname, "fonts", "favicon.ico"));
|
|
132
133
|
function parsePagination(c) {
|
|
133
134
|
const page = Math.max(1, parseInt(c.req.query("page") ?? "1", 10) || 1);
|
|
134
135
|
const per_page = Math.min(100, Math.max(1, parseInt(c.req.query("per_page") ?? "30", 10) || 30));
|
|
@@ -306,6 +307,132 @@ body{
|
|
|
306
307
|
.app-link-name{font-weight:600;font-size:.875rem;color:#33ff00;}
|
|
307
308
|
.app-link-scopes{font-size:.6875rem;color:#1a8c00;margin-top:1px;}
|
|
308
309
|
.empty{color:#1a8c00;text-align:center;padding:28px 0;font-size:.875rem;}
|
|
310
|
+
|
|
311
|
+
.inspector-layout{max-width:960px;margin:0 auto;padding:28px 20px;}
|
|
312
|
+
.inspector-tabs{display:flex;gap:4px;margin-bottom:20px;}
|
|
313
|
+
.inspector-tabs a{
|
|
314
|
+
padding:7px 16px;border-radius:6px;text-decoration:none;
|
|
315
|
+
font-size:.8125rem;color:#1a8c00;border:1px solid transparent;
|
|
316
|
+
transition:color .15s,border-color .15s;
|
|
317
|
+
}
|
|
318
|
+
.inspector-tabs a:hover{color:#33ff00;}
|
|
319
|
+
.inspector-tabs a.active{color:#33ff00;font-weight:600;border-color:#0a3300;background:#0a3300;}
|
|
320
|
+
.inspector-section{margin-bottom:24px;}
|
|
321
|
+
.inspector-section h2{
|
|
322
|
+
font-family:'Geist Pixel',monospace;
|
|
323
|
+
font-size:1rem;font-weight:600;color:#33ff00;margin-bottom:10px;
|
|
324
|
+
}
|
|
325
|
+
.inspector-section h3{
|
|
326
|
+
font-family:'Geist Pixel',monospace;
|
|
327
|
+
font-size:.875rem;font-weight:600;color:#1a8c00;margin:16px 0 8px;
|
|
328
|
+
}
|
|
329
|
+
.inspector-table{width:100%;border-collapse:collapse;margin-bottom:12px;}
|
|
330
|
+
.inspector-table th,.inspector-table td{
|
|
331
|
+
text-align:left;padding:8px 12px;border-bottom:1px solid #0a3300;
|
|
332
|
+
font-size:.8125rem;
|
|
333
|
+
}
|
|
334
|
+
.inspector-table th{color:#1a8c00;font-weight:600;font-size:.75rem;text-transform:uppercase;letter-spacing:.04em;}
|
|
335
|
+
.inspector-table td{color:#33ff00;}
|
|
336
|
+
.inspector-table tbody tr{transition:background .1s;}
|
|
337
|
+
.inspector-table tbody tr:hover{background:#0a3300;}
|
|
338
|
+
.inspector-empty{color:#1a8c00;text-align:center;padding:20px 0;font-size:.8125rem;}
|
|
339
|
+
|
|
340
|
+
.checkout-layout{
|
|
341
|
+
display:flex;min-height:calc(100vh - 42px);
|
|
342
|
+
}
|
|
343
|
+
.checkout-summary{
|
|
344
|
+
flex:1;background:#020;padding:48px 40px 48px 10%;
|
|
345
|
+
display:flex;flex-direction:column;justify-content:center;
|
|
346
|
+
border-right:1px solid #0a3300;
|
|
347
|
+
}
|
|
348
|
+
.checkout-form-side{
|
|
349
|
+
flex:1;background:#000;padding:48px 10% 48px 40px;
|
|
350
|
+
display:flex;flex-direction:column;justify-content:center;
|
|
351
|
+
}
|
|
352
|
+
.checkout-merchant{
|
|
353
|
+
display:flex;align-items:center;gap:10px;margin-bottom:6px;
|
|
354
|
+
}
|
|
355
|
+
.checkout-merchant-name{
|
|
356
|
+
font-family:'Geist Pixel',monospace;
|
|
357
|
+
font-size:.9375rem;font-weight:600;color:#33ff00;
|
|
358
|
+
}
|
|
359
|
+
.checkout-test-badge{
|
|
360
|
+
font-size:.625rem;font-weight:700;letter-spacing:.04em;text-transform:uppercase;
|
|
361
|
+
background:#0a3300;color:#1a8c00;padding:2px 8px;border-radius:4px;
|
|
362
|
+
}
|
|
363
|
+
.checkout-total{
|
|
364
|
+
font-family:'Geist Pixel',monospace;
|
|
365
|
+
font-size:2rem;font-weight:700;color:#33ff00;margin:8px 0 28px;
|
|
366
|
+
}
|
|
367
|
+
.checkout-line-item{
|
|
368
|
+
display:flex;align-items:center;gap:14px;padding:14px 0;
|
|
369
|
+
border-bottom:1px solid #0a3300;
|
|
370
|
+
}
|
|
371
|
+
.checkout-line-item:first-child{border-top:1px solid #0a3300;}
|
|
372
|
+
.checkout-item-icon{
|
|
373
|
+
width:42px;height:42px;border-radius:6px;background:#0a3300;
|
|
374
|
+
display:flex;align-items:center;justify-content:center;flex-shrink:0;
|
|
375
|
+
font-family:'Geist Pixel',monospace;font-size:.875rem;font-weight:700;color:#116600;
|
|
376
|
+
}
|
|
377
|
+
.checkout-item-details{flex:1;min-width:0;}
|
|
378
|
+
.checkout-item-name{font-size:.875rem;font-weight:600;color:#33ff00;}
|
|
379
|
+
.checkout-item-qty{font-size:.75rem;color:#1a8c00;margin-top:2px;}
|
|
380
|
+
.checkout-item-price{
|
|
381
|
+
font-size:.875rem;font-weight:600;color:#33ff00;text-align:right;white-space:nowrap;
|
|
382
|
+
}
|
|
383
|
+
.checkout-item-unit{font-size:.6875rem;color:#1a8c00;text-align:right;margin-top:2px;}
|
|
384
|
+
.checkout-totals{margin-top:20px;}
|
|
385
|
+
.checkout-totals-row{
|
|
386
|
+
display:flex;justify-content:space-between;padding:6px 0;
|
|
387
|
+
font-size:.8125rem;color:#1a8c00;
|
|
388
|
+
}
|
|
389
|
+
.checkout-totals-row.total{
|
|
390
|
+
border-top:1px solid #0a3300;margin-top:8px;padding-top:14px;
|
|
391
|
+
font-size:.9375rem;font-weight:600;color:#33ff00;
|
|
392
|
+
}
|
|
393
|
+
.checkout-form-section{margin-bottom:24px;}
|
|
394
|
+
.checkout-form-label{
|
|
395
|
+
font-size:.8125rem;font-weight:600;color:#33ff00;margin-bottom:8px;display:block;
|
|
396
|
+
}
|
|
397
|
+
.checkout-input{
|
|
398
|
+
width:100%;padding:10px 12px;border:1px solid #0a3300;border-radius:6px;
|
|
399
|
+
background:#020;color:#33ff00;font:inherit;font-size:.875rem;
|
|
400
|
+
transition:border-color .15s;outline:none;
|
|
401
|
+
}
|
|
402
|
+
.checkout-input:focus{border-color:#33ff00;}
|
|
403
|
+
.checkout-input::placeholder{color:#116600;}
|
|
404
|
+
.checkout-card-box{
|
|
405
|
+
border:1px solid #0a3300;border-radius:6px;padding:14px;
|
|
406
|
+
background:#020;
|
|
407
|
+
}
|
|
408
|
+
.checkout-card-row{
|
|
409
|
+
display:flex;gap:12px;margin-top:10px;
|
|
410
|
+
}
|
|
411
|
+
.checkout-card-row .checkout-input{flex:1;}
|
|
412
|
+
.checkout-sim-note{
|
|
413
|
+
font-size:.6875rem;color:#1a8c00;margin-top:10px;text-align:center;
|
|
414
|
+
font-style:italic;
|
|
415
|
+
}
|
|
416
|
+
.checkout-pay-btn{
|
|
417
|
+
width:100%;padding:14px;border:none;border-radius:8px;
|
|
418
|
+
background:#33ff00;color:#000;font:inherit;font-size:.9375rem;font-weight:700;
|
|
419
|
+
cursor:pointer;transition:background .15s;
|
|
420
|
+
font-family:'Geist Pixel',monospace;
|
|
421
|
+
}
|
|
422
|
+
.checkout-pay-btn:hover{background:#44ff22;}
|
|
423
|
+
.checkout-cancel{
|
|
424
|
+
text-align:center;margin-top:14px;
|
|
425
|
+
}
|
|
426
|
+
.checkout-cancel a{
|
|
427
|
+
color:#1a8c00;text-decoration:none;font-size:.8125rem;
|
|
428
|
+
transition:color .15s;
|
|
429
|
+
}
|
|
430
|
+
.checkout-cancel a:hover{color:#33ff00;}
|
|
431
|
+
@media(max-width:768px){
|
|
432
|
+
.checkout-layout{flex-direction:column;}
|
|
433
|
+
.checkout-summary{padding:32px 20px;border-right:none;border-bottom:1px solid #0a3300;}
|
|
434
|
+
.checkout-form-side{padding:32px 20px;}
|
|
435
|
+
}
|
|
309
436
|
`;
|
|
310
437
|
var POWERED_BY = `<div class="powered-by">Powered by <a href="https://emulate.dev" target="_blank" rel="noopener">emulate</a></div>`;
|
|
311
438
|
function emuBar(service) {
|
|
@@ -325,6 +452,7 @@ function head(title) {
|
|
|
325
452
|
<head>
|
|
326
453
|
<meta charset="utf-8"/>
|
|
327
454
|
<meta name="viewport" content="width=device-width,initial-scale=1"/>
|
|
455
|
+
<link rel="icon" href="/_emulate/favicon.ico"/>
|
|
328
456
|
<title>${escapeHtml(title)} | emulate</title>
|
|
329
457
|
<style>${CSS}</style>
|
|
330
458
|
</head>`;
|
|
@@ -356,6 +484,25 @@ ${emuBar(service)}
|
|
|
356
484
|
${POWERED_BY}
|
|
357
485
|
</body></html>`;
|
|
358
486
|
}
|
|
487
|
+
function renderFormPostPage(action, fields, service) {
|
|
488
|
+
const hiddens = Object.entries(fields).filter(([, v]) => v != null).map(([k, v]) => `<input type="hidden" name="${escapeAttr(k)}" value="${escapeAttr(v)}"/>`).join("\n");
|
|
489
|
+
return `${head("Redirecting")}
|
|
490
|
+
<body onload="document.forms[0].submit()">
|
|
491
|
+
${emuBar(service)}
|
|
492
|
+
<div class="content">
|
|
493
|
+
<div class="content-inner" style="text-align:center">
|
|
494
|
+
<div class="card-subtitle">Redirecting…</div>
|
|
495
|
+
<form method="POST" action="${escapeAttr(action)}">
|
|
496
|
+
${hiddens}
|
|
497
|
+
<noscript><button type="submit" class="user-btn" style="margin-top:12px;justify-content:center">
|
|
498
|
+
<span class="user-login">Continue</span>
|
|
499
|
+
</button></noscript>
|
|
500
|
+
</form>
|
|
501
|
+
</div>
|
|
502
|
+
</div>
|
|
503
|
+
${POWERED_BY}
|
|
504
|
+
</body></html>`;
|
|
505
|
+
}
|
|
359
506
|
function renderUserButton(opts) {
|
|
360
507
|
const hiddens = Object.entries(opts.hiddenFields).map(([k, v]) => `<input type="hidden" name="${escapeAttr(k)}" value="${escapeAttr(v)}"/>`).join("");
|
|
361
508
|
const nameLine = opts.name ? `<div class="user-meta">${escapeHtml(opts.name)}</div>` : "";
|
|
@@ -538,7 +685,10 @@ function getOktaStore(store) {
|
|
|
538
685
|
apps: store.collection("okta.apps", ["okta_id", "name"]),
|
|
539
686
|
oauthClients: store.collection("okta.oauth_clients", ["client_id", "auth_server_id"]),
|
|
540
687
|
authorizationServers: store.collection("okta.auth_servers", ["server_id"]),
|
|
541
|
-
groupMemberships: store.collection("okta.group_memberships", [
|
|
688
|
+
groupMemberships: store.collection("okta.group_memberships", [
|
|
689
|
+
"group_okta_id",
|
|
690
|
+
"user_okta_id"
|
|
691
|
+
]),
|
|
542
692
|
appAssignments: store.collection("okta.app_assignments", ["app_okta_id", "user_okta_id"])
|
|
543
693
|
};
|
|
544
694
|
}
|
|
@@ -550,9 +700,7 @@ function appRoutes({ app, store, baseUrl, tokenMap }) {
|
|
|
550
700
|
const q = (c.req.query("q") ?? "").toLowerCase();
|
|
551
701
|
let apps = oktaStore.apps.all();
|
|
552
702
|
if (q) {
|
|
553
|
-
apps = apps.filter(
|
|
554
|
-
(entry) => `${entry.name} ${entry.label}`.toLowerCase().includes(q)
|
|
555
|
-
);
|
|
703
|
+
apps = apps.filter((entry) => `${entry.name} ${entry.label}`.toLowerCase().includes(q));
|
|
556
704
|
}
|
|
557
705
|
const { page, per_page } = parsePagination(c);
|
|
558
706
|
const total = apps.length;
|
|
@@ -776,9 +924,7 @@ function groupRoutes({ app, store, baseUrl, tokenMap }) {
|
|
|
776
924
|
const q = (c.req.query("q") ?? "").toLowerCase();
|
|
777
925
|
let groups = oktaStore.groups.all();
|
|
778
926
|
if (q) {
|
|
779
|
-
groups = groups.filter(
|
|
780
|
-
(group) => `${group.name} ${group.description ?? ""}`.toLowerCase().includes(q)
|
|
781
|
-
);
|
|
927
|
+
groups = groups.filter((group) => `${group.name} ${group.description ?? ""}`.toLowerCase().includes(q));
|
|
782
928
|
}
|
|
783
929
|
const { page, per_page } = parsePagination(c);
|
|
784
930
|
const total = groups.length;
|
|
@@ -1080,10 +1226,10 @@ async function createIdToken(oktaStore, user, clientId, nonce, issuer, scope) {
|
|
|
1080
1226
|
return new SignJWT(claims).setProtectedHeader({ alg: "RS256", kid: KID, typ: "JWT" }).setIssuer(issuer).setAudience(clientId).setIssuedAt(now).setExpirationTime("1h").sign(privateKey);
|
|
1081
1227
|
}
|
|
1082
1228
|
function unauthorizedOAuthError() {
|
|
1083
|
-
return new Response(
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
);
|
|
1229
|
+
return new Response(JSON.stringify({ error: "invalid_token", error_description: "The access token is invalid." }), {
|
|
1230
|
+
status: 401,
|
|
1231
|
+
headers: { "Content-Type": "application/json" }
|
|
1232
|
+
});
|
|
1087
1233
|
}
|
|
1088
1234
|
function oauthRoutes({ app, store, baseUrl, tokenMap }) {
|
|
1089
1235
|
const oktaStore = getOktaStore(store);
|
|
@@ -1152,7 +1298,11 @@ function oauthRoutes({ app, store, baseUrl, tokenMap }) {
|
|
|
1152
1298
|
}
|
|
1153
1299
|
if (!matchesRedirectUri(redirectUri, client.redirect_uris)) {
|
|
1154
1300
|
return c.html(
|
|
1155
|
-
renderErrorPage(
|
|
1301
|
+
renderErrorPage(
|
|
1302
|
+
"Redirect URI mismatch",
|
|
1303
|
+
"The redirect_uri is not registered for this application.",
|
|
1304
|
+
SERVICE_LABEL
|
|
1305
|
+
),
|
|
1156
1306
|
400
|
|
1157
1307
|
);
|
|
1158
1308
|
}
|
|
@@ -1160,25 +1310,27 @@ function oauthRoutes({ app, store, baseUrl, tokenMap }) {
|
|
|
1160
1310
|
}
|
|
1161
1311
|
const users = oktaStore.users.all();
|
|
1162
1312
|
const callbackPath = `${buildOAuthBasePath(authServerId)}/authorize/callback`;
|
|
1163
|
-
const buttons = users.map(
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1313
|
+
const buttons = users.map(
|
|
1314
|
+
(user) => renderUserButton({
|
|
1315
|
+
letter: (user.login[0] ?? "?").toUpperCase(),
|
|
1316
|
+
login: user.login,
|
|
1317
|
+
name: userDisplayName(user),
|
|
1318
|
+
email: user.email,
|
|
1319
|
+
formAction: callbackPath,
|
|
1320
|
+
hiddenFields: {
|
|
1321
|
+
user_ref: user.okta_id,
|
|
1322
|
+
redirect_uri: redirectUri,
|
|
1323
|
+
scope,
|
|
1324
|
+
state,
|
|
1325
|
+
nonce,
|
|
1326
|
+
client_id: clientId,
|
|
1327
|
+
response_mode: responseMode,
|
|
1328
|
+
code_challenge: codeChallenge,
|
|
1329
|
+
code_challenge_method: codeChallengeMethod,
|
|
1330
|
+
auth_server_id: authServerId
|
|
1331
|
+
}
|
|
1332
|
+
})
|
|
1333
|
+
).join("\n");
|
|
1182
1334
|
const subtitle = clientName ? `Sign in to <strong>${escapeHtml(clientName)}</strong> with your Okta account.` : "Choose a seeded user to continue.";
|
|
1183
1335
|
return c.html(
|
|
1184
1336
|
renderCardPage(
|
|
@@ -1212,10 +1364,7 @@ function oauthRoutes({ app, store, baseUrl, tokenMap }) {
|
|
|
1212
1364
|
}
|
|
1213
1365
|
const user = findUserByRef(oktaStore, userRef);
|
|
1214
1366
|
if (!user) {
|
|
1215
|
-
return c.html(
|
|
1216
|
-
renderErrorPage("Unknown user", "The selected user is not available.", SERVICE_LABEL),
|
|
1217
|
-
400
|
|
1218
|
-
);
|
|
1367
|
+
return c.html(renderErrorPage("Unknown user", "The selected user is not available.", SERVICE_LABEL), 400);
|
|
1219
1368
|
}
|
|
1220
1369
|
const configuredClients = getClientsForServer(oktaStore.oauthClients.all(), authServerId);
|
|
1221
1370
|
if (configuredClients.length > 0) {
|
|
@@ -1228,7 +1377,11 @@ function oauthRoutes({ app, store, baseUrl, tokenMap }) {
|
|
|
1228
1377
|
}
|
|
1229
1378
|
if (!matchesRedirectUri(redirectUri, client.redirect_uris)) {
|
|
1230
1379
|
return c.html(
|
|
1231
|
-
renderErrorPage(
|
|
1380
|
+
renderErrorPage(
|
|
1381
|
+
"Redirect URI mismatch",
|
|
1382
|
+
"The redirect_uri is not registered for this application.",
|
|
1383
|
+
SERVICE_LABEL
|
|
1384
|
+
),
|
|
1232
1385
|
400
|
|
1233
1386
|
);
|
|
1234
1387
|
}
|
|
@@ -1247,17 +1400,7 @@ function oauthRoutes({ app, store, baseUrl, tokenMap }) {
|
|
|
1247
1400
|
});
|
|
1248
1401
|
debug("okta.oauth", `[callback] code=${code.slice(0, 8)}... user=${user.login} server=${authServerId}`);
|
|
1249
1402
|
if (responseMode === "form_post") {
|
|
1250
|
-
|
|
1251
|
-
<html>
|
|
1252
|
-
<head><title>Submit</title></head>
|
|
1253
|
-
<body onload="document.forms[0].submit()">
|
|
1254
|
-
<form method="POST" action="${escapeAttr(redirectUri)}">
|
|
1255
|
-
<input type="hidden" name="code" value="${escapeAttr(code)}" />
|
|
1256
|
-
<input type="hidden" name="state" value="${escapeAttr(state)}" />
|
|
1257
|
-
</form>
|
|
1258
|
-
</body>
|
|
1259
|
-
</html>`;
|
|
1260
|
-
return c.html(html);
|
|
1403
|
+
return c.html(renderFormPostPage(redirectUri, { code, state }, SERVICE_LABEL));
|
|
1261
1404
|
}
|
|
1262
1405
|
const url = new URL(redirectUri);
|
|
1263
1406
|
url.searchParams.set("code", code);
|
|
@@ -1265,7 +1408,10 @@ function oauthRoutes({ app, store, baseUrl, tokenMap }) {
|
|
|
1265
1408
|
return c.redirect(url.toString(), 302);
|
|
1266
1409
|
};
|
|
1267
1410
|
app.post("/oauth2/v1/authorize/callback", (c) => handleAuthorizeCallback(c, ORG_AUTH_SERVER_ID));
|
|
1268
|
-
app.post(
|
|
1411
|
+
app.post(
|
|
1412
|
+
"/oauth2/:authServerId/v1/authorize/callback",
|
|
1413
|
+
(c) => handleAuthorizeCallback(c, c.req.param("authServerId"))
|
|
1414
|
+
);
|
|
1269
1415
|
const handleToken = async (c, authServerId) => {
|
|
1270
1416
|
const server = resolveServer(authServerId, baseUrl, oktaStore);
|
|
1271
1417
|
if (!server) return oktaError(c, 404, "E0000007", `Not found: authorization server '${authServerId}'`);
|
|
@@ -1295,7 +1441,10 @@ function oauthRoutes({ app, store, baseUrl, tokenMap }) {
|
|
|
1295
1441
|
return c.json({ error: "invalid_grant", error_description: "redirect_uri does not match." }, 400);
|
|
1296
1442
|
}
|
|
1297
1443
|
if (validatedClient && validatedClient.client_id !== pending.clientId) {
|
|
1298
|
-
return c.json(
|
|
1444
|
+
return c.json(
|
|
1445
|
+
{ error: "invalid_grant", error_description: "Authorization code was not issued to this client." },
|
|
1446
|
+
400
|
|
1447
|
+
);
|
|
1299
1448
|
}
|
|
1300
1449
|
if (pending.codeChallenge !== null) {
|
|
1301
1450
|
if (!codeVerifier) {
|
|
@@ -1345,14 +1494,7 @@ function oauthRoutes({ app, store, baseUrl, tokenMap }) {
|
|
|
1345
1494
|
id: user.id,
|
|
1346
1495
|
scopes: parseScope(scope)
|
|
1347
1496
|
});
|
|
1348
|
-
const idToken = await createIdToken(
|
|
1349
|
-
oktaStore,
|
|
1350
|
-
user,
|
|
1351
|
-
audienceClient,
|
|
1352
|
-
pending.nonce,
|
|
1353
|
-
server.issuer,
|
|
1354
|
-
scope
|
|
1355
|
-
);
|
|
1497
|
+
const idToken = await createIdToken(oktaStore, user, audienceClient, pending.nonce, server.issuer, scope);
|
|
1356
1498
|
return c.json({
|
|
1357
1499
|
token_type: "Bearer",
|
|
1358
1500
|
expires_in: 3600,
|
|
@@ -1371,7 +1513,10 @@ function oauthRoutes({ app, store, baseUrl, tokenMap }) {
|
|
|
1371
1513
|
return c.json({ error: "invalid_grant", error_description: "Authorization server mismatch." }, 400);
|
|
1372
1514
|
}
|
|
1373
1515
|
if (validatedClient && validatedClient.client_id !== existing.clientId) {
|
|
1374
|
-
return c.json(
|
|
1516
|
+
return c.json(
|
|
1517
|
+
{ error: "invalid_grant", error_description: "Refresh token was not issued to this client." },
|
|
1518
|
+
400
|
|
1519
|
+
);
|
|
1375
1520
|
}
|
|
1376
1521
|
const user = oktaStore.users.findOneBy("okta_id", existing.userOktaId);
|
|
1377
1522
|
if (!user) return c.json({ error: "invalid_grant", error_description: "Unknown user." }, 400);
|
|
@@ -1541,9 +1686,7 @@ function oauthRoutes({ app, store, baseUrl, tokenMap }) {
|
|
|
1541
1686
|
if (!postLogoutRedirectUri) return c.text("Logged out");
|
|
1542
1687
|
const scopedClients = getClientsForServer(oktaStore.oauthClients.all(), authServerId);
|
|
1543
1688
|
if (scopedClients.length > 0) {
|
|
1544
|
-
const isAllowed = scopedClients.some(
|
|
1545
|
-
(client) => matchesRedirectUri(postLogoutRedirectUri, client.redirect_uris)
|
|
1546
|
-
);
|
|
1689
|
+
const isAllowed = scopedClients.some((client) => matchesRedirectUri(postLogoutRedirectUri, client.redirect_uris));
|
|
1547
1690
|
if (!isAllowed) return c.text("Invalid post_logout_redirect_uri", 400);
|
|
1548
1691
|
}
|
|
1549
1692
|
return c.redirect(postLogoutRedirectUri, 302);
|
|
@@ -1665,14 +1808,16 @@ function userRoutes({ app, store, baseUrl, tokenMap }) {
|
|
|
1665
1808
|
if (!user) return oktaError(c, 404, "E0000007", "Not found: user");
|
|
1666
1809
|
const memberships = oktaStore.groupMemberships.findBy("user_okta_id", user.okta_id);
|
|
1667
1810
|
const groups = memberships.map((membership) => oktaStore.groups.findOneBy("okta_id", membership.group_okta_id)).filter((group) => Boolean(group));
|
|
1668
|
-
return c.json(
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1811
|
+
return c.json(
|
|
1812
|
+
groups.map((group) => ({
|
|
1813
|
+
id: group.okta_id,
|
|
1814
|
+
profile: {
|
|
1815
|
+
name: group.name,
|
|
1816
|
+
description: group.description
|
|
1817
|
+
},
|
|
1818
|
+
type: group.type
|
|
1819
|
+
}))
|
|
1820
|
+
);
|
|
1676
1821
|
});
|
|
1677
1822
|
app.post("/api/v1/users/:userId/lifecycle/activate", (c) => {
|
|
1678
1823
|
const auth = requireManagementAuth(c, tokenMap);
|
|
@@ -1818,10 +1963,7 @@ function seedDefaults(store, _baseUrl) {
|
|
|
1818
1963
|
client_id: "okta-test-app",
|
|
1819
1964
|
client_secret: "",
|
|
1820
1965
|
name: "Sample Public PKCE Client",
|
|
1821
|
-
redirect_uris: [
|
|
1822
|
-
"http://localhost:3000/official-sdk/callback",
|
|
1823
|
-
"http://localhost:3000/official-sdk"
|
|
1824
|
-
],
|
|
1966
|
+
redirect_uris: ["http://localhost:3000/official-sdk/callback", "http://localhost:3000/official-sdk"],
|
|
1825
1967
|
response_types: ["code"],
|
|
1826
1968
|
grant_types: ["authorization_code", "refresh_token"],
|
|
1827
1969
|
token_endpoint_auth_method: "none",
|
|
@@ -1953,4 +2095,4 @@ export {
|
|
|
1953
2095
|
oktaPlugin,
|
|
1954
2096
|
seedFromConfig
|
|
1955
2097
|
};
|
|
1956
|
-
//# sourceMappingURL=dist-
|
|
2098
|
+
//# sourceMappingURL=dist-5JVGPOL3.js.map
|