@bitspark/archon-cli 0.6.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/src/cmd/key.d.ts +1 -0
- package/dist/src/cmd/key.js +138 -0
- package/dist/src/cmd/key.js.map +1 -0
- package/dist/src/cmd/key_store.d.ts +84 -0
- package/dist/src/cmd/key_store.js +482 -0
- package/dist/src/cmd/key_store.js.map +1 -0
- package/dist/src/cmd/keygen.d.ts +1 -0
- package/dist/src/cmd/keygen.js +114 -0
- package/dist/src/cmd/keygen.js.map +1 -0
- package/dist/src/cmd/login.d.ts +148 -0
- package/dist/src/cmd/login.js +777 -0
- package/dist/src/cmd/login.js.map +1 -0
- package/dist/src/cmd/sign.d.ts +1 -0
- package/dist/src/cmd/sign.js +51 -0
- package/dist/src/cmd/sign.js.map +1 -0
- package/dist/src/cmd/verify.d.ts +1 -0
- package/dist/src/cmd/verify.js +68 -0
- package/dist/src/cmd/verify.js.map +1 -0
- package/dist/src/cmd/version.d.ts +2 -0
- package/dist/src/cmd/version.js +16 -0
- package/dist/src/cmd/version.js.map +1 -0
- package/dist/src/io.d.ts +19 -0
- package/dist/src/io.js +65 -0
- package/dist/src/io.js.map +1 -0
- package/dist/src/keystore.d.ts +55 -0
- package/dist/src/keystore.js +204 -0
- package/dist/src/keystore.js.map +1 -0
- package/dist/src/main.d.ts +2 -0
- package/dist/src/main.js +51 -0
- package/dist/src/main.js.map +1 -0
- package/dist/src/pubrender.d.ts +5 -0
- package/dist/src/pubrender.js +30 -0
- package/dist/src/pubrender.js.map +1 -0
- package/package.json +34 -0
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/** Where the offers form writes its interactive lines and how it waits, injected so a test can
|
|
2
|
+
* pin the code and the page mark on stderr, the pacing, and the ledger's wall-clock end —
|
|
3
|
+
* without sleeping through the pacing or patching process streams. `run` hands the real ones. */
|
|
4
|
+
export interface LoginIo {
|
|
5
|
+
writeErr: (text: string) => void;
|
|
6
|
+
sleep: (seconds: number) => Promise<void>;
|
|
7
|
+
/** Seconds since the Unix epoch. */
|
|
8
|
+
now: () => number;
|
|
9
|
+
}
|
|
10
|
+
/** What the service answers on GET <audience>/login/<id>.
|
|
11
|
+
*
|
|
12
|
+
* NOTE the absent field: there is no `audience` here, by design (Finding 1). */
|
|
13
|
+
export interface LoginRequest {
|
|
14
|
+
id: string;
|
|
15
|
+
/** hex */
|
|
16
|
+
nonce: string;
|
|
17
|
+
/** canonical key text, ed25519:<hex> */
|
|
18
|
+
browser: string;
|
|
19
|
+
/** ordered, verbatim, displayed to the person */
|
|
20
|
+
scope: string[];
|
|
21
|
+
/** seconds */
|
|
22
|
+
valid_for: number;
|
|
23
|
+
/** RFC 3339; when the REQUEST dies, not the delegation */
|
|
24
|
+
expires?: string;
|
|
25
|
+
}
|
|
26
|
+
/** What we POST to <audience>/login/<id>/answer. */
|
|
27
|
+
export interface LoginAnswer {
|
|
28
|
+
principal: string;
|
|
29
|
+
possession: string;
|
|
30
|
+
authority: string;
|
|
31
|
+
}
|
|
32
|
+
/** WHICH custody will sign. Decided at flag-parse time — before the audience is derived —
|
|
33
|
+
* so the statement can name it and a bad choice is refused before anything is fetched or
|
|
34
|
+
* shown. */
|
|
35
|
+
export interface LoginSource {
|
|
36
|
+
seedHex?: string;
|
|
37
|
+
keyFile?: string;
|
|
38
|
+
seedFile?: string;
|
|
39
|
+
/** A NAME in the store, never a principal (ADR 0007 §A). Set by --key, or by the store's
|
|
40
|
+
* default pointer when no source flag was given. */
|
|
41
|
+
storeKey?: string;
|
|
42
|
+
}
|
|
43
|
+
/** Settles the source: exactly one flag, or none and the store's default. It never guesses
|
|
44
|
+
* a seed file — the only fallback is the pointer the person set with `archon key default`.
|
|
45
|
+
* A named store key is checked to EXIST here (a stat, opening nothing), so a typo is
|
|
46
|
+
* refused before a pointless fetch; the password and the unlock still wait for consent. */
|
|
47
|
+
export declare function decideLoginSource(src: LoginSource): void;
|
|
48
|
+
/** Entry point. The order is the security order and is not an accident: derive the
|
|
49
|
+
* audience, fetch, validate, SHOW, confirm, only then unlock and sign.
|
|
50
|
+
*
|
|
51
|
+
* Everything decidable WITHOUT the network — which custody signs, whether the flags agree,
|
|
52
|
+
* whether a named store key exists, whether the authority file is readable — is decided
|
|
53
|
+
* first, so those refusals land before a request is made and before the person reads a
|
|
54
|
+
* statement they could not have signed.
|
|
55
|
+
*
|
|
56
|
+
* `write` is where the statement and the outcome go — stdout by default, and injectable so
|
|
57
|
+
* a test can pin what a person would have seen WITHOUT patching process.stdout.write. Under
|
|
58
|
+
* `node --test` the test file is a child that reports to the runner over its own stdout, so
|
|
59
|
+
* a patch there swallows the report and silently drops tests from the run. */
|
|
60
|
+
export declare function run(args: string[], write?: (text: string) => void, io?: LoginIo): Promise<void>;
|
|
61
|
+
/** Refuse a malformed request BEFORE anything is displayed, so the person is never shown a
|
|
62
|
+
* statement built from junk. Every refusal names the field. */
|
|
63
|
+
export declare function validateLoginRequest(r: LoginRequest, wantId: string): void;
|
|
64
|
+
/** EXACTLY what the person is asked to approve, and the text all three lanes must print
|
|
65
|
+
* byte-identically. nowSeconds is a parameter so the wall-clock end is testable. */
|
|
66
|
+
export declare function renderStatement(audience: string, r: LoginRequest, nowSeconds: number, keySource: string): string;
|
|
67
|
+
/** The offers form's counterpart (docs/login.md §4.1 rule 4): the same fields as the
|
|
68
|
+
* statement, printed AFTER answering rather than before signing, because in that form nobody
|
|
69
|
+
* confirmed — the person typed the scope and the audience is the CLI's own. It names K as the
|
|
70
|
+
* request delivered it, the source that signed, and the service's verdict (`undefined` for an
|
|
71
|
+
* accepted answer, else the code). Never the code: the ledger goes to stdout, and stdout may
|
|
72
|
+
* be a log. */
|
|
73
|
+
export declare function renderLedger(audience: string, r: LoginRequest, nowSeconds: number, keySource: string, refused: string | undefined): string;
|
|
74
|
+
/** Name the custody the signature will come from, for the last line of the statement
|
|
75
|
+
* (seat:cca ruling, 2026-09-10).
|
|
76
|
+
*
|
|
77
|
+
* It is the SOURCE and not the principal, on purpose: naming the principal would mean
|
|
78
|
+
* unlocking the key before the person has agreed to sign — which, for a password-protected
|
|
79
|
+
* store, means demanding a password in order to show someone what they are being asked to
|
|
80
|
+
* approve. The source is known without touching the key at all.
|
|
81
|
+
*
|
|
82
|
+
* A store key is named by its NAME, whether --key chose it or the default pointer did: the
|
|
83
|
+
* statement says what will sign, and how the name was chosen is not part of what is being
|
|
84
|
+
* approved. The pinned wording is cca's (2026-09-10 20:47Z). */
|
|
85
|
+
export declare function describeKeySource(src: LoginSource): string;
|
|
86
|
+
/** Render seconds the same way in every lane. Written out explicitly so Go and Rust
|
|
87
|
+
* reproduce it exactly — a shared format nobody has to reverse-engineer. */
|
|
88
|
+
export declare function formatDuration(seconds: number): string;
|
|
89
|
+
/** Format a Unix timestamp as YYYY-MM-DDTHH:MM:SSZ, matching the other two lanes. */
|
|
90
|
+
export declare function formatRfc3339Utc(unixSeconds: number): string;
|
|
91
|
+
/** Read a y/N answer. Default is NO: anything that is not an explicit yes refuses,
|
|
92
|
+
* including EOF, so a login cannot be completed by a closed stdin. */
|
|
93
|
+
export declare function confirm(): Promise<boolean>;
|
|
94
|
+
/** Accept the two hex seed-file shapes in use: 64 hex characters (a raw 32-byte seed) and
|
|
95
|
+
* 128 (seed followed by public key), the shape the first consumer's `key` files carry (answer 4). */
|
|
96
|
+
export declare function seedFromHexFile(text: string): Uint8Array;
|
|
97
|
+
/** GET the request. The CLI owns HTTP; the SDK never opens a socket (archon#16). */
|
|
98
|
+
export declare function fetchLoginRequest(audience: string, id: string): Promise<LoginRequest>;
|
|
99
|
+
/** Deliver the answer and report the service's verdict as an error, which is what the
|
|
100
|
+
* confirmed form wants: a refusal ends the command. */
|
|
101
|
+
export declare function postLoginAnswer(audience: string, id: string, answer: LoginAnswer): Promise<void>;
|
|
102
|
+
/** The service's answer to an offer. `page`, when the service has one, is the address the
|
|
103
|
+
* person opens, carrying the code in its fragment. No audience here either — in this form the
|
|
104
|
+
* audience is the prover's own configuration — and a response carrying one is refused. */
|
|
105
|
+
export interface OfferResponse {
|
|
106
|
+
code: string;
|
|
107
|
+
scope: string[];
|
|
108
|
+
valid_for: number;
|
|
109
|
+
expires_in: number;
|
|
110
|
+
interval: number;
|
|
111
|
+
page?: string;
|
|
112
|
+
}
|
|
113
|
+
/** The offers form. The order is §4.1's, rule by rule, and the same before-any-network
|
|
114
|
+
* discipline as the confirmed form: everything decidable without the service — the custody,
|
|
115
|
+
* the authority file, the scope, the validity, the audience — is decided first, so those
|
|
116
|
+
* refusals land before an offer exists. */
|
|
117
|
+
export declare function runOffer(args: string[], write: (text: string) => void, io: LoginIo): Promise<void>;
|
|
118
|
+
/** §4.1 rule 1. The audience is --audience, or ARCHON_AUDIENCE as the configured default,
|
|
119
|
+
* checked exactly the same way: it must be a fixed point of §2.1's grammar — the very check
|
|
120
|
+
* the server applies to its own configuration — and the CLI refuses to start otherwise. The
|
|
121
|
+
* `/login/00` is the shortest invocation URL the grammar admits, there only to make the
|
|
122
|
+
* audience parseable as one; feeding the audience through the scheme's derivation asks the
|
|
123
|
+
* one question that matters: is this the string the service binds? */
|
|
124
|
+
export declare function configuredAudience(flag: string | undefined): string;
|
|
125
|
+
/** The one line about the page address, printed and MARKED, never opened (§4.1 rule 1; ADR
|
|
126
|
+
* 0007 §C.7 (6)). "On the service's own origin" is a byte-exact comparison of scheme and host
|
|
127
|
+
* with the audience's — a differently spelled origin fails closed, the right direction for an
|
|
128
|
+
* address a person is about to click — and launching a browser is the person's action, never
|
|
129
|
+
* this command's: spawning a platform opener by name is the PATH surface §C.5 refuses. */
|
|
130
|
+
export declare function describePage(audience: string, page: string): string;
|
|
131
|
+
/** §4.1 rule 2, done by the prover for itself: the request's scope must be what was offered,
|
|
132
|
+
* entry for entry, in order, and its validity equal. The service refuses a mismatched begin
|
|
133
|
+
* before storing anything — but a prover that relied on that would be trusting the service
|
|
134
|
+
* about the one thing it is about to sign. */
|
|
135
|
+
export declare function checkAgainstOffer(r: LoginRequest, scope: string[], validFor: number): void;
|
|
136
|
+
/** Turn a non-success response into a diagnosis. RFC 8628's error vocabulary is used where
|
|
137
|
+
* the service speaks it, since this protocol adopts that shape. */
|
|
138
|
+
export declare function loginHttpError(status: number, body: string): string;
|
|
139
|
+
/** The possession proof over this request, plus the person's principal as canonical key
|
|
140
|
+
* text. The principal is derived here — a property of the seed, not of the scheme — so
|
|
141
|
+
* only the proof itself waits on sdk/ts/login.
|
|
142
|
+
*
|
|
143
|
+
* LOUD ON PURPOSE until then: a locally computed binding that merely looks right would
|
|
144
|
+
* produce proofs that verify nowhere and take a day to explain. */
|
|
145
|
+
export declare function proveLogin(seed: Uint8Array, audience: string, request: LoginRequest): {
|
|
146
|
+
proof: Uint8Array;
|
|
147
|
+
principal: string;
|
|
148
|
+
};
|