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