@pidgeon-ai/cli 1.36.0 → 1.37.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/{chunk-FA77SSPH.js → chunk-RWZQSI67.js} +274 -17
- package/dist/chunk-RWZQSI67.js.map +1 -0
- package/dist/{chunk-W5VS5RM7.js → chunk-UBA2RP6N.js} +257 -1
- package/dist/{chunk-W5VS5RM7.js.map → chunk-UBA2RP6N.js.map} +1 -1
- package/dist/cli.js +2 -2
- package/dist/commands.gen.js +1 -1
- package/dist/index.js +2 -2
- package/package.json +2 -2
- package/dist/chunk-FA77SSPH.js.map +0 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
COMMANDS,
|
|
4
4
|
__export
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-UBA2RP6N.js";
|
|
6
6
|
|
|
7
7
|
// ../sdk/dist/index.js
|
|
8
8
|
var dist_exports = {};
|
|
@@ -67,6 +67,14 @@ __export(dist_exports, {
|
|
|
67
67
|
eventsSocket: () => eventsSocket,
|
|
68
68
|
eventsStream: () => eventsStream,
|
|
69
69
|
exportMail: () => exportMail,
|
|
70
|
+
grantsCreate: () => grantsCreate,
|
|
71
|
+
grantsGet: () => grantsGet,
|
|
72
|
+
grantsList: () => grantsList,
|
|
73
|
+
grantsRevoke: () => grantsRevoke,
|
|
74
|
+
grantsStatus: () => grantsStatus,
|
|
75
|
+
grantsTemplatesCreate: () => grantsTemplatesCreate,
|
|
76
|
+
grantsTemplatesDelete: () => grantsTemplatesDelete,
|
|
77
|
+
grantsTemplatesList: () => grantsTemplatesList,
|
|
70
78
|
identitiesAccessCreate: () => identitiesAccessCreate,
|
|
71
79
|
identitiesAccessDelete: () => identitiesAccessDelete,
|
|
72
80
|
identitiesAccessGet: () => identitiesAccessGet,
|
|
@@ -1025,6 +1033,10 @@ var logMonitorsDelete = (options) => (options.client ?? client).delete({
|
|
|
1025
1033
|
url: "/log/monitors/{id}",
|
|
1026
1034
|
...options
|
|
1027
1035
|
});
|
|
1036
|
+
var grantsStatus = (options) => (options.client ?? client).get({
|
|
1037
|
+
url: "/grants/{id}/status",
|
|
1038
|
+
...options
|
|
1039
|
+
});
|
|
1028
1040
|
var agentConnect = (options) => (options.client ?? client).post({
|
|
1029
1041
|
url: "/agent/connect",
|
|
1030
1042
|
...options,
|
|
@@ -1201,6 +1213,49 @@ var labelsUpdate = (options) => (options.client ?? client).patch({
|
|
|
1201
1213
|
...options.headers
|
|
1202
1214
|
}
|
|
1203
1215
|
});
|
|
1216
|
+
var grantsTemplatesList = (options) => (options?.client ?? client).get({
|
|
1217
|
+
security: [{ scheme: "bearer", type: "http" }],
|
|
1218
|
+
url: "/grant-templates",
|
|
1219
|
+
...options
|
|
1220
|
+
});
|
|
1221
|
+
var grantsTemplatesCreate = (options) => (options.client ?? client).post({
|
|
1222
|
+
security: [{ scheme: "bearer", type: "http" }],
|
|
1223
|
+
url: "/grant-templates",
|
|
1224
|
+
...options,
|
|
1225
|
+
headers: {
|
|
1226
|
+
"Content-Type": "application/json",
|
|
1227
|
+
...options.headers
|
|
1228
|
+
}
|
|
1229
|
+
});
|
|
1230
|
+
var grantsTemplatesDelete = (options) => (options.client ?? client).delete({
|
|
1231
|
+
security: [{ scheme: "bearer", type: "http" }],
|
|
1232
|
+
url: "/grant-templates/{id}",
|
|
1233
|
+
...options
|
|
1234
|
+
});
|
|
1235
|
+
var grantsList = (options) => (options.client ?? client).get({
|
|
1236
|
+
security: [{ scheme: "bearer", type: "http" }],
|
|
1237
|
+
url: "/grants",
|
|
1238
|
+
...options
|
|
1239
|
+
});
|
|
1240
|
+
var grantsCreate = (options) => (options.client ?? client).post({
|
|
1241
|
+
security: [{ scheme: "bearer", type: "http" }],
|
|
1242
|
+
url: "/grants",
|
|
1243
|
+
...options,
|
|
1244
|
+
headers: {
|
|
1245
|
+
"Content-Type": "application/json",
|
|
1246
|
+
...options.headers
|
|
1247
|
+
}
|
|
1248
|
+
});
|
|
1249
|
+
var grantsRevoke = (options) => (options.client ?? client).delete({
|
|
1250
|
+
security: [{ scheme: "bearer", type: "http" }],
|
|
1251
|
+
url: "/grants/{id}",
|
|
1252
|
+
...options
|
|
1253
|
+
});
|
|
1254
|
+
var grantsGet = (options) => (options.client ?? client).get({
|
|
1255
|
+
security: [{ scheme: "bearer", type: "http" }],
|
|
1256
|
+
url: "/grants/{id}",
|
|
1257
|
+
...options
|
|
1258
|
+
});
|
|
1204
1259
|
var contactsList = (options) => (options?.client ?? client).get({
|
|
1205
1260
|
security: [{ scheme: "bearer", type: "http" }],
|
|
1206
1261
|
url: "/contacts",
|
|
@@ -1972,7 +2027,7 @@ function sleep(ms, signal) {
|
|
|
1972
2027
|
});
|
|
1973
2028
|
}
|
|
1974
2029
|
|
|
1975
|
-
// ../id/dist/chunk-
|
|
2030
|
+
// ../id/dist/chunk-EAXZTLYY.js
|
|
1976
2031
|
import { createHash } from "crypto";
|
|
1977
2032
|
import { chmod, mkdir, readFile, readdir, writeFile } from "fs/promises";
|
|
1978
2033
|
import { homedir } from "os";
|
|
@@ -2414,7 +2469,8 @@ async function signRequest(identity, input) {
|
|
|
2414
2469
|
}
|
|
2415
2470
|
const added = {
|
|
2416
2471
|
"signature-agent": quote(`https://post.${identity.domain}`),
|
|
2417
|
-
...agent ? { from: agent } : {}
|
|
2472
|
+
...agent ? { from: agent } : {},
|
|
2473
|
+
...input.grants?.length ? { "post-grant": input.grants.map((jws) => jws.replace(/\s+/g, "")).join(", ") } : {}
|
|
2418
2474
|
};
|
|
2419
2475
|
const body = input.body === void 0 || input.body === null ? null : bytesOf(input.body);
|
|
2420
2476
|
if (body && body.length > 0) added["content-digest"] = contentDigest(body);
|
|
@@ -2425,6 +2481,7 @@ async function signRequest(identity, input) {
|
|
|
2425
2481
|
...url.search ? [["@query", url.search]] : [],
|
|
2426
2482
|
["signature-agent", added["signature-agent"]],
|
|
2427
2483
|
...added.from ? [["from", added.from]] : [],
|
|
2484
|
+
...added["post-grant"] ? [["post-grant", added["post-grant"]]] : [],
|
|
2428
2485
|
...added["content-digest"] ? [["content-digest", added["content-digest"]]] : []
|
|
2429
2486
|
];
|
|
2430
2487
|
const params = `(${values.map(([name]) => quote(name)).join(" ")});created=${created};expires=${expires};keyid=${quote(identity.kid)};alg="ed25519";nonce=${quote(randomBytes(32).toString("base64"))};tag=${quote(input.tag ?? TAG)}`;
|
|
@@ -2468,15 +2525,15 @@ var IdClient = class {
|
|
|
2468
2525
|
await signRequest(this.identity, { method, url, headers, body: text, tag: ISSUANCE_TAG })
|
|
2469
2526
|
);
|
|
2470
2527
|
const response = await this.fetcher(url, { method, headers, body: text ?? void 0 });
|
|
2471
|
-
const
|
|
2472
|
-
if (!response.ok || !
|
|
2528
|
+
const json2 = await response.json().catch(() => null);
|
|
2529
|
+
if (!response.ok || !json2 || json2.data === void 0) {
|
|
2473
2530
|
throw new IdApiError(
|
|
2474
2531
|
response.status,
|
|
2475
|
-
|
|
2476
|
-
|
|
2532
|
+
json2?.error?.code,
|
|
2533
|
+
json2?.error?.message ?? `Pidgeon answered ${response.status}.`
|
|
2477
2534
|
);
|
|
2478
2535
|
}
|
|
2479
|
-
return
|
|
2536
|
+
return json2.data;
|
|
2480
2537
|
}
|
|
2481
2538
|
/** Claim the domain with this key. Idempotent: a second call returns the same records. */
|
|
2482
2539
|
claim() {
|
|
@@ -2498,6 +2555,16 @@ var IdClient = class {
|
|
|
2498
2555
|
revoke(name) {
|
|
2499
2556
|
return this.call("DELETE", `/agents/${encodeURIComponent(name)}`);
|
|
2500
2557
|
}
|
|
2558
|
+
/**
|
|
2559
|
+
* The domain grants one of its own agents, at once: what it may do, for
|
|
2560
|
+
* which customer, account or order, where, until when (at most 90 days).
|
|
2561
|
+
*/
|
|
2562
|
+
grant(input) {
|
|
2563
|
+
return this.call("POST", "/grants", input);
|
|
2564
|
+
}
|
|
2565
|
+
revokeGrant(id) {
|
|
2566
|
+
return this.call("DELETE", `/grants/${encodeURIComponent(id)}`);
|
|
2567
|
+
}
|
|
2501
2568
|
/**
|
|
2502
2569
|
* Publish `next` as the domain's key, signed by the current one. `proof`
|
|
2503
2570
|
* is `next`'s own signature over the rotation, so nobody can rotate a
|
|
@@ -2517,6 +2584,128 @@ ${domain}
|
|
|
2517
2584
|
${from}
|
|
2518
2585
|
${to}`;
|
|
2519
2586
|
}
|
|
2587
|
+
var TOKEN_EXCHANGE = "urn:ietf:params:oauth:grant-type:token-exchange";
|
|
2588
|
+
var JWT_BEARER = "urn:ietf:params:oauth:grant-type:jwt-bearer";
|
|
2589
|
+
var TOKEN_TYPE_JWT = "urn:ietf:params:oauth:token-type:jwt";
|
|
2590
|
+
var SignInError = class extends Error {
|
|
2591
|
+
constructor(step, status, code, message) {
|
|
2592
|
+
super(message);
|
|
2593
|
+
this.step = step;
|
|
2594
|
+
this.status = status;
|
|
2595
|
+
this.code = code;
|
|
2596
|
+
}
|
|
2597
|
+
step;
|
|
2598
|
+
status;
|
|
2599
|
+
code;
|
|
2600
|
+
};
|
|
2601
|
+
async function json(response) {
|
|
2602
|
+
return await response.json().catch(() => null) ?? {};
|
|
2603
|
+
}
|
|
2604
|
+
function form(values) {
|
|
2605
|
+
return new URLSearchParams(values).toString();
|
|
2606
|
+
}
|
|
2607
|
+
async function siteMetadata(site, fetcher = fetch) {
|
|
2608
|
+
const response = await fetcher(site, { headers: { accept: "application/json" } });
|
|
2609
|
+
const body = await json(response);
|
|
2610
|
+
if (!response.ok || typeof body.issuer !== "string" || typeof body.client_id !== "string") {
|
|
2611
|
+
throw new SignInError(
|
|
2612
|
+
"site",
|
|
2613
|
+
response.status,
|
|
2614
|
+
void 0,
|
|
2615
|
+
`${site} does not offer Sign in with Pidgeon.`
|
|
2616
|
+
);
|
|
2617
|
+
}
|
|
2618
|
+
return { issuer: body.issuer, client_id: body.client_id, token_endpoint: site };
|
|
2619
|
+
}
|
|
2620
|
+
async function fetchCard(agent, fetcher = fetch, postHost = (domain) => `https://post.${domain}`) {
|
|
2621
|
+
const domain = agent.split("@")[1] ?? "";
|
|
2622
|
+
const response = await fetcher(
|
|
2623
|
+
`${postHost(domain)}/.well-known/post/card?address=${encodeURIComponent(agent)}`
|
|
2624
|
+
);
|
|
2625
|
+
const body = await json(response);
|
|
2626
|
+
if (!response.ok || typeof body.jws !== "string") {
|
|
2627
|
+
throw new SignInError(
|
|
2628
|
+
"card",
|
|
2629
|
+
response.status,
|
|
2630
|
+
void 0,
|
|
2631
|
+
`${agent} has no card to sign in with.`
|
|
2632
|
+
);
|
|
2633
|
+
}
|
|
2634
|
+
return body.jws;
|
|
2635
|
+
}
|
|
2636
|
+
async function signInWithPidgeon(identity, input) {
|
|
2637
|
+
const fetcher = input.fetch ?? fetch;
|
|
2638
|
+
const agent = input.agent.trim().toLowerCase();
|
|
2639
|
+
const site = await siteMetadata(input.site, fetcher);
|
|
2640
|
+
const card = input.card ?? await fetchCard(agent, fetcher, input.postHost);
|
|
2641
|
+
const discovery = await json(
|
|
2642
|
+
await fetcher(`${site.issuer.replace(/\/$/, "")}/.well-known/openid-configuration`)
|
|
2643
|
+
);
|
|
2644
|
+
const tokenEndpoint = discovery.token_endpoint;
|
|
2645
|
+
if (typeof tokenEndpoint !== "string") {
|
|
2646
|
+
throw new SignInError("pidgeon", 0, void 0, `${site.issuer} has no token endpoint.`);
|
|
2647
|
+
}
|
|
2648
|
+
const exchange = form({
|
|
2649
|
+
grant_type: TOKEN_EXCHANGE,
|
|
2650
|
+
subject_token: card,
|
|
2651
|
+
subject_token_type: TOKEN_TYPE_JWT,
|
|
2652
|
+
audience: site.client_id
|
|
2653
|
+
});
|
|
2654
|
+
const headers = { "content-type": "application/x-www-form-urlencoded" };
|
|
2655
|
+
const issued = await fetcher(tokenEndpoint, {
|
|
2656
|
+
method: "POST",
|
|
2657
|
+
headers: {
|
|
2658
|
+
...headers,
|
|
2659
|
+
...await signRequest(identity, {
|
|
2660
|
+
method: "POST",
|
|
2661
|
+
url: tokenEndpoint,
|
|
2662
|
+
headers,
|
|
2663
|
+
body: exchange,
|
|
2664
|
+
agent,
|
|
2665
|
+
grants: input.grant ? [input.grant] : void 0
|
|
2666
|
+
})
|
|
2667
|
+
},
|
|
2668
|
+
body: exchange
|
|
2669
|
+
});
|
|
2670
|
+
const tokens = await json(issued);
|
|
2671
|
+
if (!issued.ok || typeof tokens.id_token !== "string") {
|
|
2672
|
+
throw new SignInError(
|
|
2673
|
+
"pidgeon",
|
|
2674
|
+
issued.status,
|
|
2675
|
+
tokens.error,
|
|
2676
|
+
tokens.error_description ?? `Pidgeon answered ${issued.status}.`
|
|
2677
|
+
);
|
|
2678
|
+
}
|
|
2679
|
+
const bearer = form({ grant_type: JWT_BEARER, assertion: tokens.id_token });
|
|
2680
|
+
const answered = await fetcher(site.token_endpoint, {
|
|
2681
|
+
method: "POST",
|
|
2682
|
+
headers: {
|
|
2683
|
+
...headers,
|
|
2684
|
+
...await signRequest(identity, {
|
|
2685
|
+
method: "POST",
|
|
2686
|
+
url: site.token_endpoint,
|
|
2687
|
+
headers,
|
|
2688
|
+
body: bearer,
|
|
2689
|
+
agent
|
|
2690
|
+
})
|
|
2691
|
+
},
|
|
2692
|
+
body: bearer
|
|
2693
|
+
});
|
|
2694
|
+
const session = await json(answered);
|
|
2695
|
+
if (!answered.ok) {
|
|
2696
|
+
throw new SignInError(
|
|
2697
|
+
"site",
|
|
2698
|
+
answered.status,
|
|
2699
|
+
session.error,
|
|
2700
|
+
session.error_description ?? `The site answered ${answered.status}.`
|
|
2701
|
+
);
|
|
2702
|
+
}
|
|
2703
|
+
return {
|
|
2704
|
+
site: session,
|
|
2705
|
+
idToken: tokens.id_token,
|
|
2706
|
+
accessToken: tokens.access_token
|
|
2707
|
+
};
|
|
2708
|
+
}
|
|
2520
2709
|
var UsageError = class extends Error {
|
|
2521
2710
|
};
|
|
2522
2711
|
var HELP = `pidgeon id \u2014 a signed identity for your agents, on your own domain. No account.
|
|
@@ -2527,6 +2716,11 @@ var HELP = `pidgeon id \u2014 a signed identity for your agents, on your own dom
|
|
|
2527
2716
|
list Agents on the domain
|
|
2528
2717
|
revoke <name> Withdraw an agent's card now
|
|
2529
2718
|
rotate Replace the domain's key; the old one verifies for another day
|
|
2719
|
+
grant <name> Grant <name> what it may do, as the domain
|
|
2720
|
+
--scope bookings.change --label "manage bookings"
|
|
2721
|
+
--subject customer:42 --audience delta.com --days 30
|
|
2722
|
+
revoke-grant <id> Take a grant back now
|
|
2723
|
+
sign-in <site> Sign in to a site as an agent --as <name> --grant <jws>
|
|
2530
2724
|
|
|
2531
2725
|
--domain <domain> Which domain, when this machine holds more than one
|
|
2532
2726
|
--json Print the API's answer as JSON
|
|
@@ -2569,7 +2763,7 @@ async function runId(argv, env = process.env, options = {}) {
|
|
|
2569
2763
|
const [command, ...rest] = positional;
|
|
2570
2764
|
if (!command || flags.has("help") || command === "help") return HELP;
|
|
2571
2765
|
const dir = identityDir(env);
|
|
2572
|
-
const
|
|
2766
|
+
const json2 = flags.has("json");
|
|
2573
2767
|
const say = options.stderr ?? (() => {
|
|
2574
2768
|
});
|
|
2575
2769
|
const sleep2 = options.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
|
|
@@ -2600,7 +2794,7 @@ async function runId(argv, env = process.env, options = {}) {
|
|
|
2600
2794
|
made = true;
|
|
2601
2795
|
}
|
|
2602
2796
|
let state = await client2(identity).claim();
|
|
2603
|
-
if (
|
|
2797
|
+
if (json2 && (state.status === "verified" || flags.has("no-wait")))
|
|
2604
2798
|
return JSON.stringify(state, null, 2);
|
|
2605
2799
|
const lines = [
|
|
2606
2800
|
made ? `Made a signing key for ${domain} on this machine (${identity.kid}).` : `Using the key for ${domain} on this machine.`
|
|
@@ -2629,13 +2823,13 @@ Or add them by hand:` : "Add these records at your DNS provider:",
|
|
|
2629
2823
|
}
|
|
2630
2824
|
lines.length = 0;
|
|
2631
2825
|
}
|
|
2632
|
-
if (
|
|
2826
|
+
if (json2) return JSON.stringify(state, null, 2);
|
|
2633
2827
|
return [...lines, `${domain} is proved. Next: pidgeon id issue support-agent`].join("\n").trim();
|
|
2634
2828
|
}
|
|
2635
2829
|
case "check": {
|
|
2636
2830
|
const identity = rest[0] ? await loadIdentity(rest[0], { dir, env }) : await which();
|
|
2637
2831
|
const state = await client2(identity).check();
|
|
2638
|
-
if (
|
|
2832
|
+
if (json2) return JSON.stringify(state, null, 2);
|
|
2639
2833
|
return [
|
|
2640
2834
|
`${state.domain}: ${state.status === "verified" ? "proved" : state.status}`,
|
|
2641
2835
|
...describeRecords(state)
|
|
@@ -2655,7 +2849,7 @@ Or add them by hand:` : "Add these records at your DNS provider:",
|
|
|
2655
2849
|
...kind ? { kind } : {},
|
|
2656
2850
|
...typeof onBehalfOf === "string" ? { on_behalf_of: onBehalfOf } : {}
|
|
2657
2851
|
});
|
|
2658
|
-
if (
|
|
2852
|
+
if (json2) return JSON.stringify(card, null, 2);
|
|
2659
2853
|
return [
|
|
2660
2854
|
`${card.card.address} has a card: ${card.url}`,
|
|
2661
2855
|
`Found from the address at https://post.${identity.domain}/.well-known/post/card?address=${card.card.address}`,
|
|
@@ -2664,7 +2858,7 @@ Or add them by hand:` : "Add these records at your DNS provider:",
|
|
|
2664
2858
|
}
|
|
2665
2859
|
case "list": {
|
|
2666
2860
|
const agents = await client2(await which()).list();
|
|
2667
|
-
if (
|
|
2861
|
+
if (json2) return JSON.stringify(agents, null, 2);
|
|
2668
2862
|
if (agents.length === 0)
|
|
2669
2863
|
return "No agents yet. `pidgeon id issue <name>` gives one a card.";
|
|
2670
2864
|
return agents.map((agent) => `${agent.address} ${agent.kind} ${agent.card_url}`).join("\n");
|
|
@@ -2673,7 +2867,7 @@ Or add them by hand:` : "Add these records at your DNS provider:",
|
|
|
2673
2867
|
const name = rest[0]?.trim().toLowerCase();
|
|
2674
2868
|
if (!name) throw new UsageError("Name the agent: `pidgeon id revoke support-agent`.");
|
|
2675
2869
|
const revoked = await client2(await which()).revoke(name);
|
|
2676
|
-
if (
|
|
2870
|
+
if (json2) return JSON.stringify(revoked, null, 2);
|
|
2677
2871
|
return `${revoked.address} has no card from now on. Copies already fetched lapse within a day.`;
|
|
2678
2872
|
}
|
|
2679
2873
|
case "rotate": {
|
|
@@ -2682,9 +2876,72 @@ Or add them by hand:` : "Add these records at your DNS provider:",
|
|
|
2682
2876
|
const state = await client2(current).rotate(next);
|
|
2683
2877
|
next.previous = { kid: current.kid, publicKey: current.publicKey };
|
|
2684
2878
|
await saveIdentity(next, dir);
|
|
2685
|
-
if (
|
|
2879
|
+
if (json2) return JSON.stringify(state, null, 2);
|
|
2686
2880
|
return `${current.domain} signs with ${next.kid} now. ${current.kid} still verifies for a day.`;
|
|
2687
2881
|
}
|
|
2882
|
+
case "grant": {
|
|
2883
|
+
const name = rest[0]?.trim().toLowerCase();
|
|
2884
|
+
const scope = flags.get("scope");
|
|
2885
|
+
const label = flags.get("label");
|
|
2886
|
+
const subject = flags.get("subject");
|
|
2887
|
+
if (!name || typeof scope !== "string" || typeof label !== "string") {
|
|
2888
|
+
throw new UsageError(
|
|
2889
|
+
'Name the agent and the scope: `pidgeon id grant support-agent --scope bookings.change --label "manage bookings" --subject customer:42`.'
|
|
2890
|
+
);
|
|
2891
|
+
}
|
|
2892
|
+
const [type, ...idParts] = typeof subject === "string" ? subject.split(":") : [];
|
|
2893
|
+
if (!type || idParts.length === 0 || !["customer", "account", "order"].includes(type)) {
|
|
2894
|
+
throw new UsageError("--subject is customer:<id>, account:<id> or order:<id>.");
|
|
2895
|
+
}
|
|
2896
|
+
const days = flags.get("days");
|
|
2897
|
+
const audience = flags.get("audience");
|
|
2898
|
+
const grant = await client2(await which()).grant({
|
|
2899
|
+
agent: name,
|
|
2900
|
+
scope: { name: scope, label },
|
|
2901
|
+
subject: { type, id: idParts.join(":") },
|
|
2902
|
+
...typeof audience === "string" ? { audience } : {},
|
|
2903
|
+
...typeof days === "string" ? { expires_at: new Date(Date.now() + Number(days) * 864e5).toISOString() } : {}
|
|
2904
|
+
});
|
|
2905
|
+
if (json2) return JSON.stringify(grant, null, 2);
|
|
2906
|
+
return [
|
|
2907
|
+
`${grant.agent} may ${grant.scope.label} for ${grant.subject.type} ${grant.subject.id}${grant.audience ? ` at ${grant.audience}` : ""}, until ${grant.expires_at}.`,
|
|
2908
|
+
`Grant ${grant.id}. The agent carries it as Post-Grant; --json prints the JWS.`
|
|
2909
|
+
].join("\n");
|
|
2910
|
+
}
|
|
2911
|
+
case "revoke-grant": {
|
|
2912
|
+
const grantId = rest[0]?.trim();
|
|
2913
|
+
if (!grantId) throw new UsageError("Name the grant: `pidgeon id revoke-grant <id>`.");
|
|
2914
|
+
const revoked = await client2(await which()).revokeGrant(grantId);
|
|
2915
|
+
if (json2) return JSON.stringify(revoked, null, 2);
|
|
2916
|
+
return `Grant ${revoked.id} is revoked. The next check of it fails.`;
|
|
2917
|
+
}
|
|
2918
|
+
case "sign-in": {
|
|
2919
|
+
const site = rest[0];
|
|
2920
|
+
const name = flags.get("as");
|
|
2921
|
+
if (!site || typeof name !== "string") {
|
|
2922
|
+
throw new UsageError(
|
|
2923
|
+
"Name the site and the agent: `pidgeon id sign-in https://site.example/api/auth/pidgeon/token --as support-agent`."
|
|
2924
|
+
);
|
|
2925
|
+
}
|
|
2926
|
+
const identity = await which();
|
|
2927
|
+
const card = await client2(identity).issue({ name: name.trim().toLowerCase() });
|
|
2928
|
+
const grant = flags.get("grant");
|
|
2929
|
+
try {
|
|
2930
|
+
const signedIn = await signInWithPidgeon(identity, {
|
|
2931
|
+
agent: card.card.address,
|
|
2932
|
+
site,
|
|
2933
|
+
card: card.jws,
|
|
2934
|
+
...typeof grant === "string" ? { grant } : {},
|
|
2935
|
+
...options.fetch ? { fetch: options.fetch } : {}
|
|
2936
|
+
});
|
|
2937
|
+
if (json2) return JSON.stringify(signedIn.site, null, 2);
|
|
2938
|
+
return `Signed in to ${new URL(site).host} as ${card.card.address}.
|
|
2939
|
+
${JSON.stringify(signedIn.site, null, 2)}`;
|
|
2940
|
+
} catch (error) {
|
|
2941
|
+
if (error instanceof SignInError) throw new Error(`${error.step}: ${error.message}`);
|
|
2942
|
+
throw error;
|
|
2943
|
+
}
|
|
2944
|
+
}
|
|
2688
2945
|
default:
|
|
2689
2946
|
throw new UsageError(`No such command "${command}".
|
|
2690
2947
|
|
|
@@ -2890,4 +3147,4 @@ export {
|
|
|
2890
3147
|
find,
|
|
2891
3148
|
run
|
|
2892
3149
|
};
|
|
2893
|
-
//# sourceMappingURL=chunk-
|
|
3150
|
+
//# sourceMappingURL=chunk-RWZQSI67.js.map
|