apiblaze 0.16.0 → 0.17.1
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/index.js +160 -125
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -460,6 +460,7 @@ var init_admin = __esm({
|
|
|
460
460
|
// src/lib/tenant-create.ts
|
|
461
461
|
var tenant_create_exports = {};
|
|
462
462
|
__export(tenant_create_exports, {
|
|
463
|
+
addApiblazeHostedLogin: () => addApiblazeHostedLogin,
|
|
463
464
|
createTenantInteractive: () => createTenantInteractive
|
|
464
465
|
});
|
|
465
466
|
async function createTenantRow(teamId) {
|
|
@@ -490,23 +491,22 @@ async function createTenantRow(teamId) {
|
|
|
490
491
|
}
|
|
491
492
|
}
|
|
492
493
|
}
|
|
493
|
-
async function
|
|
494
|
+
async function addApiblazeHostedLogin(teamId, tenant2, opts = {}) {
|
|
494
495
|
const { default: inquirer2 } = await import("inquirer");
|
|
495
496
|
const base = `/teams/${encodeURIComponent(teamId)}/tenants/${encodeURIComponent(tenant2)}`;
|
|
496
497
|
const { provider } = await inquirer2.prompt([{
|
|
497
498
|
type: "list",
|
|
498
499
|
name: "provider",
|
|
499
|
-
message: "
|
|
500
|
+
message: "Which login provider?",
|
|
500
501
|
pageSize: 10,
|
|
501
502
|
choices: [
|
|
502
503
|
...PROVIDERS.map((p) => ({ name: p.label, value: p.id })),
|
|
503
|
-
new inquirer2.Separator(),
|
|
504
|
-
{ name: import_chalk22.default.dim("Skip for now \u2014 set up a login method later"), value: null }
|
|
504
|
+
...opts.allowSkip ? [new inquirer2.Separator(), { name: import_chalk22.default.dim("Skip for now \u2014 set up a login method later"), value: null }] : []
|
|
505
505
|
]
|
|
506
506
|
}]);
|
|
507
507
|
if (!provider) {
|
|
508
508
|
console.log(import_chalk22.default.dim(" No login method yet \u2014 add one later under Login methods."));
|
|
509
|
-
return;
|
|
509
|
+
return false;
|
|
510
510
|
}
|
|
511
511
|
const opt = PROVIDERS.find((p) => p.id === provider);
|
|
512
512
|
let providerBody;
|
|
@@ -542,8 +542,9 @@ async function setUpLogin(teamId, tenant2) {
|
|
|
542
542
|
const clientId = client?.clientId ?? client?.client_id;
|
|
543
543
|
await admin({ method: "POST", path: `${base}/app-clients/${encodeURIComponent(clientId)}/providers`, body: providerBody, summary: `Add ${provider} provider` });
|
|
544
544
|
spinner.succeed(opt.own ? `${opt.label} login is ready.` : "APIblaze-hosted GitHub login is ready.");
|
|
545
|
+
return true;
|
|
545
546
|
} catch (err) {
|
|
546
|
-
spinner.fail("Login setup failed
|
|
547
|
+
spinner.fail("Login setup failed.");
|
|
547
548
|
throw err;
|
|
548
549
|
}
|
|
549
550
|
}
|
|
@@ -562,7 +563,7 @@ async function createTenantInteractive(teamId) {
|
|
|
562
563
|
});
|
|
563
564
|
console.log(import_chalk22.default.green(" Users & groups enabled."));
|
|
564
565
|
}
|
|
565
|
-
await
|
|
566
|
+
await addApiblazeHostedLogin(teamId, tenant2, { allowSkip: true });
|
|
566
567
|
return tenant2;
|
|
567
568
|
}
|
|
568
569
|
var import_chalk22, import_ora8, PROVIDERS, DEFAULT_SCOPES;
|
|
@@ -686,7 +687,7 @@ var import_commander = require("commander");
|
|
|
686
687
|
var import_chalk35 = __toESM(require("chalk"));
|
|
687
688
|
|
|
688
689
|
// package.json
|
|
689
|
-
var version = "0.
|
|
690
|
+
var version = "0.17.1";
|
|
690
691
|
|
|
691
692
|
// src/index.ts
|
|
692
693
|
init_types();
|
|
@@ -3065,6 +3066,8 @@ Tenant ${tenant2}`));
|
|
|
3065
3066
|
const nEmails = (emails?.admin_emails ?? []).length;
|
|
3066
3067
|
const nIssuers = (issuers?.external_issuers ?? []).length;
|
|
3067
3068
|
const nClients = Array.isArray(clients) ? clients.length : 0;
|
|
3069
|
+
const nOpaque = opaque?.opaque?.endpoint ? 1 : 0;
|
|
3070
|
+
const nLogin = nClients + nIssuers + nOpaque;
|
|
3068
3071
|
const onOff = (b) => b ? import_chalk25.default.green("on") : import_chalk25.default.dim("off");
|
|
3069
3072
|
const { pick: pick2 } = await inquirer2.prompt([{
|
|
3070
3073
|
type: "list",
|
|
@@ -3072,21 +3075,19 @@ Tenant ${tenant2}`));
|
|
|
3072
3075
|
message: `Tenant ${tenant2}:`,
|
|
3073
3076
|
pageSize: 12,
|
|
3074
3077
|
choices: [
|
|
3075
|
-
{ name: `Login methods (${
|
|
3078
|
+
{ name: `Login methods (${nLogin}) ${import_chalk25.default.dim("how your consumers sign in")}`, value: "login" },
|
|
3076
3079
|
{ name: `Users & groups: ${onOff(iam?.iam_enabled)} ${import_chalk25.default.dim(`identity & key management (${tenant2}.iam.apiblaze.com)`)}`, value: "iam" },
|
|
3077
|
-
{ name: `Your own hosted login \u2014 JWT (${nIssuers}) ${import_chalk25.default.dim("trust tokens your own identity provider issues")}`, value: "issuers" },
|
|
3078
3080
|
{ name: `Portal admins (${nEmails}) ${import_chalk25.default.dim("emails allowed to administer this tenant's portal")}`, value: "emails" },
|
|
3079
3081
|
new inquirer2.Separator(import_chalk25.default.dim(" Settings")),
|
|
3080
3082
|
{ name: `CORS: ${cors?.cors ? import_chalk25.default.cyan(JSON.stringify(cors.cors)) : import_chalk25.default.dim("(unset)")} ${import_chalk25.default.dim("browser origins allowed to call this tenant")}`, value: "cors" },
|
|
3081
|
-
{ name: `Opaque-token login (advanced): ${opaque?.opaque?.endpoint ? import_chalk25.default.cyan(opaque.opaque.endpoint) : import_chalk25.default.dim("(unset)")}`, value: "opaque" },
|
|
3082
3083
|
{ name: "\u2190 Back", value: "back" }
|
|
3083
3084
|
]
|
|
3084
3085
|
}]);
|
|
3085
3086
|
switch (pick2) {
|
|
3086
3087
|
case "back":
|
|
3087
3088
|
return;
|
|
3088
|
-
case "
|
|
3089
|
-
await
|
|
3089
|
+
case "login":
|
|
3090
|
+
await loginMethodsMenu(teamId, tenant2, base);
|
|
3090
3091
|
break;
|
|
3091
3092
|
case "iam": {
|
|
3092
3093
|
const { v } = await inquirer2.prompt([{ type: "confirm", name: "v", message: "Enable Users & groups?", default: !!iam?.iam_enabled }]);
|
|
@@ -3114,38 +3115,88 @@ Tenant ${tenant2}`));
|
|
|
3114
3115
|
case "emails":
|
|
3115
3116
|
await emailsMenu(base, emails?.admin_emails ?? []);
|
|
3116
3117
|
break;
|
|
3117
|
-
case "issuers":
|
|
3118
|
-
await issuersMenu(base, issuers?.external_issuers ?? []);
|
|
3119
|
-
break;
|
|
3120
|
-
case "opaque": {
|
|
3121
|
-
const cur = opaque?.opaque;
|
|
3122
|
-
const { mode } = await inquirer2.prompt([{
|
|
3123
|
-
type: "list",
|
|
3124
|
-
name: "mode",
|
|
3125
|
-
message: "Opaque-token validator:",
|
|
3126
|
-
choices: [
|
|
3127
|
-
{ name: cur ? "Replace it" : "Set one up", value: "set" },
|
|
3128
|
-
...cur ? [{ name: "Clear it", value: "clear" }] : [],
|
|
3129
|
-
{ name: "\u2190 Back", value: "back" }
|
|
3130
|
-
]
|
|
3131
|
-
}]);
|
|
3132
|
-
if (mode === "back") break;
|
|
3133
|
-
if (mode === "clear") {
|
|
3134
|
-
await admin({ method: "PUT", path: `${base}/opaque`, body: { opaque: null }, summary: "Clear opaque validator" });
|
|
3135
|
-
console.log(import_chalk25.default.green(" Cleared."));
|
|
3136
|
-
break;
|
|
3137
|
-
}
|
|
3138
|
-
const a = await inquirer2.prompt([
|
|
3139
|
-
{ type: "input", name: "endpoint", message: "Introspection endpoint (https):", default: cur?.endpoint, validate: (s) => s.startsWith("https://") || "must be https" },
|
|
3140
|
-
{ type: "list", name: "method", message: "HTTP method:", choices: ["GET", "POST"], default: cur?.method ?? "GET" }
|
|
3141
|
-
]);
|
|
3142
|
-
await admin({ method: "PUT", path: `${base}/opaque`, body: { opaque: { endpoint: a.endpoint, method: a.method } }, summary: "Set opaque validator" });
|
|
3143
|
-
console.log(import_chalk25.default.green(" Opaque validator set."));
|
|
3144
|
-
break;
|
|
3145
|
-
}
|
|
3146
3118
|
}
|
|
3147
3119
|
}
|
|
3148
3120
|
}
|
|
3121
|
+
async function loginMethodsMenu(teamId, tenant2, base) {
|
|
3122
|
+
const { default: inquirer2 } = await import("inquirer");
|
|
3123
|
+
for (; ; ) {
|
|
3124
|
+
const spinner = (0, import_ora11.default)("Loading login methods...").start();
|
|
3125
|
+
const [rawClients, rawIssuers, rawOpaque] = await Promise.all([
|
|
3126
|
+
admin({ method: "GET", path: `${base}/app-clients`, summary: "List APIblaze-hosted logins" }).catch(() => []),
|
|
3127
|
+
admin({ method: "GET", path: `${base}/external-issuers`, summary: "List your-own-JWT logins" }).catch(() => null),
|
|
3128
|
+
admin({ method: "GET", path: `${base}/opaque`, summary: "Read opaque login" }).catch(() => null)
|
|
3129
|
+
]).finally(() => spinner.stop());
|
|
3130
|
+
const appClients = Array.isArray(rawClients) ? rawClients : [];
|
|
3131
|
+
const issuers = rawIssuers?.external_issuers ?? [];
|
|
3132
|
+
const opaque = rawOpaque?.opaque ?? null;
|
|
3133
|
+
const choices = [];
|
|
3134
|
+
for (const c of appClients) {
|
|
3135
|
+
const nP = (c.providers ?? []).length || c.providers_count || 0;
|
|
3136
|
+
choices.push({ name: `${import_chalk25.default.cyan("APIblaze-hosted")} ${import_chalk25.default.bold(c.name ?? c.clientId)} ${import_chalk25.default.dim(`${c.clientId}${nP ? ` \xB7 ${nP} provider${nP === 1 ? "" : "s"}` : import_chalk25.default.yellow(" \xB7 needs a provider")}`)}`, value: { kind: "client", item: c } });
|
|
3137
|
+
}
|
|
3138
|
+
for (const i of issuers) {
|
|
3139
|
+
choices.push({ name: `${import_chalk25.default.cyan("Your own \u2014 JWT ")} ${import_chalk25.default.bold(i.iss)} ${import_chalk25.default.dim(`aud=${i.aud}`)}`, value: { kind: "issuer", item: i } });
|
|
3140
|
+
}
|
|
3141
|
+
if (opaque?.endpoint) {
|
|
3142
|
+
choices.push({ name: `${import_chalk25.default.cyan("Your own \u2014 opaque")} ${import_chalk25.default.bold(opaque.endpoint)}`, value: { kind: "opaque", item: opaque } });
|
|
3143
|
+
}
|
|
3144
|
+
if (!choices.length) console.log(import_chalk25.default.dim("\n No login methods yet \u2014 consumers cannot sign in until you add one."));
|
|
3145
|
+
const { pick: pick2 } = await inquirer2.prompt([{
|
|
3146
|
+
type: "list",
|
|
3147
|
+
name: "pick",
|
|
3148
|
+
message: `Login methods for ${tenant2}:`,
|
|
3149
|
+
pageSize: 15,
|
|
3150
|
+
choices: [
|
|
3151
|
+
...choices,
|
|
3152
|
+
new inquirer2.Separator(),
|
|
3153
|
+
{ name: "\uFF0B Add a login method\u2026", value: { kind: "add" } },
|
|
3154
|
+
{ name: "\u2190 Back", value: { kind: "back" } }
|
|
3155
|
+
]
|
|
3156
|
+
}]);
|
|
3157
|
+
if (pick2.kind === "back") return;
|
|
3158
|
+
if (pick2.kind === "add") {
|
|
3159
|
+
await addLoginMethod(teamId, tenant2, base);
|
|
3160
|
+
continue;
|
|
3161
|
+
}
|
|
3162
|
+
if (pick2.kind === "client") {
|
|
3163
|
+
await clientHome(base, pick2.item);
|
|
3164
|
+
continue;
|
|
3165
|
+
}
|
|
3166
|
+
if (pick2.kind === "issuer") {
|
|
3167
|
+
await issuerHome(base, pick2.item);
|
|
3168
|
+
continue;
|
|
3169
|
+
}
|
|
3170
|
+
if (pick2.kind === "opaque") {
|
|
3171
|
+
await opaqueHome(base, pick2.item);
|
|
3172
|
+
continue;
|
|
3173
|
+
}
|
|
3174
|
+
}
|
|
3175
|
+
}
|
|
3176
|
+
async function addLoginMethod(teamId, tenant2, base) {
|
|
3177
|
+
const { default: inquirer2 } = await import("inquirer");
|
|
3178
|
+
const { kind } = await inquirer2.prompt([{
|
|
3179
|
+
type: "list",
|
|
3180
|
+
name: "kind",
|
|
3181
|
+
message: "How do people log in?",
|
|
3182
|
+
pageSize: 8,
|
|
3183
|
+
choices: [
|
|
3184
|
+
{ name: `APIblaze hosted login page ${import_chalk25.default.dim("we host login; pick a provider (GitHub/Google/\u2026) \u2014 easiest")}`, value: "apiblaze" },
|
|
3185
|
+
{ name: `Your own hosted login \u2014 JWT ${import_chalk25.default.dim("your identity provider issues JWTs; we trust them")}`, value: "jwt" },
|
|
3186
|
+
{ name: `Your own login \u2014 opaque token ${import_chalk25.default.dim("we validate your opaque tokens via an introspection endpoint")}`, value: "opaque" },
|
|
3187
|
+
{ name: "\u2190 Back", value: null }
|
|
3188
|
+
]
|
|
3189
|
+
}]);
|
|
3190
|
+
if (!kind) return;
|
|
3191
|
+
if (kind === "apiblaze") {
|
|
3192
|
+
const { addApiblazeHostedLogin: addApiblazeHostedLogin2 } = await Promise.resolve().then(() => (init_tenant_create(), tenant_create_exports));
|
|
3193
|
+
await addApiblazeHostedLogin2(teamId, tenant2);
|
|
3194
|
+
} else if (kind === "jwt") {
|
|
3195
|
+
await addIssuer(base);
|
|
3196
|
+
} else {
|
|
3197
|
+
await setOpaque(base, null);
|
|
3198
|
+
}
|
|
3199
|
+
}
|
|
3149
3200
|
function safeJson(s) {
|
|
3150
3201
|
try {
|
|
3151
3202
|
return JSON.parse(s);
|
|
@@ -3185,98 +3236,84 @@ async function emailsMenu(base, emails) {
|
|
|
3185
3236
|
console.log(import_chalk25.default.green(` ${e} removed.`));
|
|
3186
3237
|
}
|
|
3187
3238
|
}
|
|
3188
|
-
async function
|
|
3239
|
+
async function addIssuer(base) {
|
|
3189
3240
|
const { default: inquirer2 } = await import("inquirer");
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3241
|
+
const a = await inquirer2.prompt([
|
|
3242
|
+
{ type: "input", name: "iss", message: "Issuer URL (iss):", validate: (s) => !!s.trim() || "required" },
|
|
3243
|
+
{ type: "input", name: "aud", message: "Audience (aud):", validate: (s) => !!s.trim() || "required" },
|
|
3244
|
+
{ type: "input", name: "jwks", message: "JWKS URL (empty = derive from issuer):" },
|
|
3245
|
+
{ type: "list", name: "sem", message: "Where is the end-user id?", choices: [
|
|
3246
|
+
{ name: "The token sub IS the end user (tenant-owned)", value: "tenant_owned" },
|
|
3247
|
+
{ name: "Extract it from a claim\u2026", value: "extract_from_claim" }
|
|
3248
|
+
] }
|
|
3249
|
+
]);
|
|
3250
|
+
const claim = a.sem === "extract_from_claim" ? (await inquirer2.prompt([{ type: "input", name: "c", message: "Claim name:", validate: (s) => !!s.trim() || "required" }])).c : void 0;
|
|
3251
|
+
await admin({
|
|
3252
|
+
method: "POST",
|
|
3253
|
+
path: `${base}/external-issuers`,
|
|
3254
|
+
body: { iss: a.iss.trim(), aud: a.aud.trim(), jwks_url: a.jwks.trim() || null, sub_semantics: a.sem, ...claim ? { claim_name: claim } : {} },
|
|
3255
|
+
summary: `Add external issuer ${a.iss.trim()}`
|
|
3256
|
+
});
|
|
3257
|
+
console.log(import_chalk25.default.green(" JWT login method saved."));
|
|
3258
|
+
}
|
|
3259
|
+
async function issuerHome(base, issuer) {
|
|
3260
|
+
const { default: inquirer2 } = await import("inquirer");
|
|
3261
|
+
console.log(`
|
|
3262
|
+
${import_chalk25.default.bold(issuer.iss)} ${import_chalk25.default.dim(`aud=${issuer.aud} \xB7 ${issuer.sub_semantics ?? ""}`)}`);
|
|
3193
3263
|
const { act } = await inquirer2.prompt([{
|
|
3194
3264
|
type: "list",
|
|
3195
3265
|
name: "act",
|
|
3196
|
-
message: "
|
|
3266
|
+
message: "This JWT login method:",
|
|
3197
3267
|
choices: [
|
|
3198
|
-
{ name: "
|
|
3199
|
-
|
|
3268
|
+
{ name: "Replace it (re-enter details)", value: "edit" },
|
|
3269
|
+
{ name: import_chalk25.default.red("Delete it"), value: "rm" },
|
|
3200
3270
|
{ name: "\u2190 Back", value: "back" }
|
|
3201
3271
|
]
|
|
3202
3272
|
}]);
|
|
3203
3273
|
if (act === "back") return;
|
|
3204
|
-
if (act === "
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
{ type: "input", name: "aud", message: "Audience (aud):", validate: (s) => !!s.trim() || "required" },
|
|
3208
|
-
{ type: "input", name: "jwks", message: "JWKS URL (empty = derive from issuer):" },
|
|
3209
|
-
{ type: "list", name: "sem", message: "Where is the end-user id?", choices: [
|
|
3210
|
-
{ name: "The token sub IS the end user (tenant-owned)", value: "tenant_owned" },
|
|
3211
|
-
{ name: "Extract it from a claim\u2026", value: "extract_from_claim" }
|
|
3212
|
-
] }
|
|
3213
|
-
]);
|
|
3214
|
-
const claim = a.sem === "extract_from_claim" ? (await inquirer2.prompt([{ type: "input", name: "c", message: "Claim name:", validate: (s) => !!s.trim() || "required" }])).c : void 0;
|
|
3215
|
-
await admin({
|
|
3216
|
-
method: "POST",
|
|
3217
|
-
path: `${base}/external-issuers`,
|
|
3218
|
-
body: { iss: a.iss.trim(), aud: a.aud.trim(), jwks_url: a.jwks.trim() || null, sub_semantics: a.sem, ...claim ? { claim_name: claim } : {} },
|
|
3219
|
-
summary: `Add external issuer ${a.iss.trim()}`
|
|
3220
|
-
});
|
|
3221
|
-
console.log(import_chalk25.default.green(" Issuer saved."));
|
|
3222
|
-
} else {
|
|
3223
|
-
const { i } = await inquirer2.prompt([{
|
|
3224
|
-
type: "list",
|
|
3225
|
-
name: "i",
|
|
3226
|
-
message: "Delete which issuer?",
|
|
3227
|
-
choices: [...issuers.map((x) => ({ name: `${x.iss} (aud=${x.aud})`, value: x })), { name: "\u2190 Back", value: null }]
|
|
3228
|
-
}]);
|
|
3229
|
-
if (!i) return;
|
|
3230
|
-
await admin({
|
|
3231
|
-
method: "DELETE",
|
|
3232
|
-
path: `${base}/external-issuers?iss=${encodeURIComponent(i.iss)}&aud=${encodeURIComponent(i.aud)}`,
|
|
3233
|
-
summary: `Delete issuer ${i.iss}`
|
|
3234
|
-
});
|
|
3235
|
-
console.log(import_chalk25.default.green(" Issuer deleted."));
|
|
3274
|
+
if (act === "edit") {
|
|
3275
|
+
await addIssuer(base);
|
|
3276
|
+
return;
|
|
3236
3277
|
}
|
|
3278
|
+
const { sure } = await inquirer2.prompt([{ type: "confirm", name: "sure", message: `Delete the JWT login method for ${issuer.iss}? Consumers using it can no longer sign in.`, default: false }]);
|
|
3279
|
+
if (!sure) return;
|
|
3280
|
+
await admin({
|
|
3281
|
+
method: "DELETE",
|
|
3282
|
+
path: `${base}/external-issuers?iss=${encodeURIComponent(issuer.iss)}&aud=${encodeURIComponent(issuer.aud)}`,
|
|
3283
|
+
summary: `Delete issuer ${issuer.iss}`
|
|
3284
|
+
});
|
|
3285
|
+
console.log(import_chalk25.default.green(" Deleted."));
|
|
3237
3286
|
}
|
|
3238
|
-
async function
|
|
3287
|
+
async function setOpaque(base, cur) {
|
|
3239
3288
|
const { default: inquirer2 } = await import("inquirer");
|
|
3240
|
-
|
|
3241
|
-
|
|
3242
|
-
|
|
3243
|
-
|
|
3244
|
-
|
|
3245
|
-
|
|
3246
|
-
|
|
3247
|
-
|
|
3248
|
-
|
|
3249
|
-
|
|
3250
|
-
|
|
3251
|
-
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
|
|
3256
|
-
|
|
3257
|
-
|
|
3258
|
-
|
|
3259
|
-
|
|
3260
|
-
|
|
3261
|
-
|
|
3262
|
-
|
|
3263
|
-
|
|
3264
|
-
|
|
3265
|
-
]);
|
|
3266
|
-
const created = await admin({
|
|
3267
|
-
method: "POST",
|
|
3268
|
-
path: `${base}/app-clients`,
|
|
3269
|
-
body: {
|
|
3270
|
-
name: a.name.trim(),
|
|
3271
|
-
...a.callbacks.trim() ? { authorizedCallbackUrls: parseList(a.callbacks) } : {}
|
|
3272
|
-
},
|
|
3273
|
-
summary: `Create app client "${a.name.trim()}"`
|
|
3274
|
-
});
|
|
3275
|
-
console.log(import_chalk25.default.green(` Login method created${created?.clientId ? ` (${created.clientId})` : ""}.`));
|
|
3276
|
-
continue;
|
|
3277
|
-
}
|
|
3278
|
-
await clientHome(base, pick2);
|
|
3289
|
+
const a = await inquirer2.prompt([
|
|
3290
|
+
{ type: "input", name: "endpoint", message: "Introspection endpoint (https):", default: cur?.endpoint, validate: (s) => s.startsWith("https://") || "must be https" },
|
|
3291
|
+
{ type: "list", name: "method", message: "HTTP method:", choices: ["GET", "POST"], default: cur?.method ?? "GET" }
|
|
3292
|
+
]);
|
|
3293
|
+
await admin({ method: "PUT", path: `${base}/opaque`, body: { opaque: { endpoint: a.endpoint, method: a.method } }, summary: "Set opaque validator" });
|
|
3294
|
+
console.log(import_chalk25.default.green(" Opaque login method set."));
|
|
3295
|
+
}
|
|
3296
|
+
async function opaqueHome(base, cur) {
|
|
3297
|
+
const { default: inquirer2 } = await import("inquirer");
|
|
3298
|
+
console.log(`
|
|
3299
|
+
${import_chalk25.default.bold(cur.endpoint)} ${import_chalk25.default.dim(cur.method ?? "GET")}`);
|
|
3300
|
+
const { act } = await inquirer2.prompt([{
|
|
3301
|
+
type: "list",
|
|
3302
|
+
name: "act",
|
|
3303
|
+
message: "This opaque login method:",
|
|
3304
|
+
choices: [
|
|
3305
|
+
{ name: "Replace it", value: "edit" },
|
|
3306
|
+
{ name: import_chalk25.default.red("Delete it"), value: "rm" },
|
|
3307
|
+
{ name: "\u2190 Back", value: "back" }
|
|
3308
|
+
]
|
|
3309
|
+
}]);
|
|
3310
|
+
if (act === "back") return;
|
|
3311
|
+
if (act === "edit") {
|
|
3312
|
+
await setOpaque(base, cur);
|
|
3313
|
+
return;
|
|
3279
3314
|
}
|
|
3315
|
+
await admin({ method: "PUT", path: `${base}/opaque`, body: { opaque: null }, summary: "Clear opaque validator" });
|
|
3316
|
+
console.log(import_chalk25.default.green(" Deleted."));
|
|
3280
3317
|
}
|
|
3281
3318
|
async function clientHome(base, summary) {
|
|
3282
3319
|
const { default: inquirer2 } = await import("inquirer");
|
|
@@ -4357,15 +4394,13 @@ async function transformsMenu(proj2) {
|
|
|
4357
4394
|
{ type: "input", name: "destination", message: `Destination field ${fieldHint}:`, validate: (s) => !!s || "required" },
|
|
4358
4395
|
{ type: "confirm", name: "strip", message: "Remove the source field after copying?", default: false }
|
|
4359
4396
|
]);
|
|
4360
|
-
const source_fns = await buildFns("Transform the value
|
|
4361
|
-
const dest_fns = await buildFns("Transform the value as it is WRITTEN (destination functions)");
|
|
4397
|
+
const source_fns = await buildFns("Transform the value");
|
|
4362
4398
|
action2 = {
|
|
4363
4399
|
type: "copy",
|
|
4364
4400
|
source: a.source,
|
|
4365
4401
|
destination: a.destination,
|
|
4366
4402
|
...a.strip ? { strip_source: true } : {},
|
|
4367
|
-
...source_fns.length ? { source_fns } : {}
|
|
4368
|
-
...dest_fns.length ? { dest_fns } : {}
|
|
4403
|
+
...source_fns.length ? { source_fns } : {}
|
|
4369
4404
|
};
|
|
4370
4405
|
}
|
|
4371
4406
|
const condition = await buildCondition(ans.phase);
|
package/package.json
CHANGED