@corenel/tools-node 0.2.2 → 0.3.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/auth.d.ts +262 -5
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +413 -24
- package/dist/auth.js.map +1 -1
- package/dist/fileService.d.ts.map +1 -1
- package/dist/fileService.js +7 -2
- package/dist/fileService.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +8 -3
package/dist/auth.d.ts
CHANGED
|
@@ -8,9 +8,266 @@ export declare function sidecarDir(base?: string): string;
|
|
|
8
8
|
/** The ACCOUNT token from the device flow. Top level, and staying there: it is
|
|
9
9
|
* not the daemon's, and moving it would sign the user out on upgrade. */
|
|
10
10
|
export declare function authTokenPath(base?: string): string;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
/**
|
|
12
|
+
* The directory both credential files live in.
|
|
13
|
+
*
|
|
14
|
+
* STATE-DIR DECISION, made deliberately: the token file stays HOME-scoped by
|
|
15
|
+
* default and does NOT move under a daemon-private directory. @corenel/cli
|
|
16
|
+
* resolves it from homedir() with no notion of a state dir, and `corenel login`
|
|
17
|
+
* writes it there; relocating it would sign every existing user out on upgrade
|
|
18
|
+
* and leave the CLI unable to find the credential it just wrote. What
|
|
19
|
+
* `--state-dir` does instead is redirect the whole state dir, exactly as the
|
|
20
|
+
* sidecar's `authDir` already does — so `<stateDir>/token` and
|
|
21
|
+
* `<stateDir>/auth.json` stay siblings, an isolated state dir stays isolated
|
|
22
|
+
* (nothing reaches back into the real home), and with no `--state-dir` this
|
|
23
|
+
* resolves to the same `~/.corenel/token` the CLI reads. Identical computation
|
|
24
|
+
* to packages/sidecar/src/auth/store.ts `authDir`, and it must stay identical.
|
|
25
|
+
*/
|
|
26
|
+
export declare function credentialDir(stateDir?: string): string;
|
|
27
|
+
/** `<credentialDir>/token` — equals authTokenPath() when no state dir is given. */
|
|
28
|
+
export declare function tokenFilePath(stateDir?: string): string;
|
|
29
|
+
/** `<credentialDir>/auth.json` — the sidecar's richer credential record. */
|
|
30
|
+
export declare function credentialFilePath(stateDir?: string): string;
|
|
31
|
+
/** The environment variable that carries a headless credential. */
|
|
32
|
+
export declare const TOKEN_ENV = "CORENEL_TOKEN";
|
|
33
|
+
/** The environment variable that names the API. Same spelling @corenel/cli's
|
|
34
|
+
* `apiBase()` reads, because two names for one decision is how they drift. */
|
|
35
|
+
export declare const API_BASE_ENV = "CORENEL_API_BASE";
|
|
36
|
+
/** The credential file's shape. `expiresAt` absent means the issuer did not say
|
|
37
|
+
* — which is NOT the same as "not expired". */
|
|
38
|
+
export interface StoredCredential {
|
|
39
|
+
accessToken: string;
|
|
40
|
+
refreshToken?: string;
|
|
41
|
+
/** Epoch ms. Absent means the issuer did not say. */
|
|
42
|
+
expiresAt?: number;
|
|
43
|
+
/**
|
|
44
|
+
* WHO this credential belongs to, as the sign-in reported it.
|
|
45
|
+
*
|
|
46
|
+
* Never an authorization input: nothing is granted on the strength of this
|
|
47
|
+
* string. It IS an identity input in one place -- a sidecar daemon compares
|
|
48
|
+
* it against what a same-machine client claims to be signed in as, and files
|
|
49
|
+
* a match under one synced directory instead of one per browser origin
|
|
50
|
+
* (@corenel/sidecar's hostIdentity.ts). That comparison decides a directory,
|
|
51
|
+
* not an access decision, and a mismatch simply keeps today's behaviour.
|
|
52
|
+
*
|
|
53
|
+
* Consequence worth stating: this is frequently an EMAIL ADDRESS. It lives in
|
|
54
|
+
* a 0600 file on purpose. It must not be logged, printed, or used to name a
|
|
55
|
+
* directory -- the rule that consumes it keys off a truncated digest for
|
|
56
|
+
* exactly that reason.
|
|
57
|
+
*/
|
|
58
|
+
account?: string;
|
|
59
|
+
/**
|
|
60
|
+
* The API base this credential was MINTED against.
|
|
61
|
+
*
|
|
62
|
+
* A token is only valid at the host that issued it, so the base belongs to
|
|
63
|
+
* the login, not to the machine: a daemon defaulting to a different host
|
|
64
|
+
* spends a token nobody there has heard of, and the failure is a 401 a long
|
|
65
|
+
* way from the sign-in that caused it. Absent on every credential written
|
|
66
|
+
* before this was recorded, which is why every reader falls back to the
|
|
67
|
+
* default rather than treating absence as an error.
|
|
68
|
+
*/
|
|
69
|
+
apiBase?: string;
|
|
70
|
+
}
|
|
71
|
+
export declare function writeAuthToken(token: string, stateDir?: string): Promise<void>;
|
|
72
|
+
/**
|
|
73
|
+
* Record a completed sign-in in BOTH stores, including WHERE it was minted.
|
|
74
|
+
*
|
|
75
|
+
* `writeAuthToken` alone leaves the token file holding a bearer token with no
|
|
76
|
+
* record of which API issued it -- which is fine right up until the machine is
|
|
77
|
+
* pointed somewhere else by a default, and then it is a 401 with no visible
|
|
78
|
+
* cause. The base goes in auth.json because the token file is one line by
|
|
79
|
+
* contract and every existing reader of it splits on nothing.
|
|
80
|
+
*
|
|
81
|
+
* The credential record is REPLACED, not merged: a new sign-in may be a
|
|
82
|
+
* different account at a different host, and carrying the previous one's
|
|
83
|
+
* account or base onto it would report something nobody established.
|
|
84
|
+
*
|
|
85
|
+
* TWO FILES, AND A READER BETWEEN THEM. `resolveNodeCredential` borrows the
|
|
86
|
+
* account from auth.json only when auth.json describes the SAME token the
|
|
87
|
+
* token file holds -- which is right, and which means that during a RE-login
|
|
88
|
+
* the two disagree and the account reads as absent. That is fail-closed (a
|
|
89
|
+
* daemon files that handshake under its per-origin id, exactly as it did
|
|
90
|
+
* before any of this) but it is not free: the directory it mints then
|
|
91
|
+
* persists. So the window is made as small as two files allow. Both new
|
|
92
|
+
* contents are staged first, and the two renames happen back to back with no
|
|
93
|
+
* mkdir, no chmod and no JSON encoding between them -- microseconds rather
|
|
94
|
+
* than the duration of two file writes.
|
|
95
|
+
*
|
|
96
|
+
* It is not ZERO, and cannot be while the credential lives in two files. The
|
|
97
|
+
* honest fix is one file, which means changing what the gateway client and
|
|
98
|
+
* @corenel/cli have always read; the precedence comment at the top of this
|
|
99
|
+
* module is the record of why that has not been done.
|
|
100
|
+
*
|
|
101
|
+
* The credential file is renamed FIRST. Whichever order is chosen the
|
|
102
|
+
* intermediate state loses the account, so the tiebreak is which token a
|
|
103
|
+
* reader gets in that instant: credential-first leaves the token file holding
|
|
104
|
+
* the PREVIOUS token, which is the credential that was working a moment ago.
|
|
105
|
+
* Token-first would publish the new token with no account and no recorded
|
|
106
|
+
* base -- a state no sign-in ever produced.
|
|
107
|
+
*/
|
|
108
|
+
export declare function writeLoginCredential(token: string, opts?: {
|
|
109
|
+
apiBase?: string;
|
|
110
|
+
stateDir?: string;
|
|
111
|
+
account?: string;
|
|
112
|
+
}): Promise<void>;
|
|
113
|
+
/**
|
|
114
|
+
* A store read that says WHICH kind of nothing it found.
|
|
115
|
+
*
|
|
116
|
+
* "There is no credential" and "the credential could not be read" are the same
|
|
117
|
+
* `null` to every caller that only wants a token, and that is right for them:
|
|
118
|
+
* neither can be authenticated with. They are NOT the same to a caller that
|
|
119
|
+
* publishes a STATE off the answer. A daemon that re-reads its own sign-in
|
|
120
|
+
* treats a null as a logout -- and an antivirus lock, an EMFILE under load or a
|
|
121
|
+
* directory mode change then publishes a sign-out that never happened, which in
|
|
122
|
+
* the sidecar's case permanently mints a synced directory (see
|
|
123
|
+
* @corenel/sidecar's accountWatch.ts). So the distinction is carried here,
|
|
124
|
+
* where it is known, rather than guessed at by the caller.
|
|
125
|
+
*
|
|
126
|
+
* `unreadable` is true only for a store that EXISTS as far as the filesystem is
|
|
127
|
+
* concerned and could not be read: ENOENT is a clean absence and never sets it.
|
|
128
|
+
* A malformed credential file is also an absence, deliberately -- the writes
|
|
129
|
+
* are atomic renames, so a parse failure is a corrupt file rather than a
|
|
130
|
+
* half-written one, and corruption should send the user through sign-in rather
|
|
131
|
+
* than being retried forever.
|
|
132
|
+
*/
|
|
133
|
+
export interface CredentialRead<T> {
|
|
134
|
+
/** What was read, or null when there is nothing to read. */
|
|
135
|
+
value: T | null;
|
|
136
|
+
/** The store is there but could not be read. Never true alongside a value. */
|
|
137
|
+
unreadable: boolean;
|
|
138
|
+
}
|
|
139
|
+
export declare function readAuthToken(stateDir?: string): Promise<string | null>;
|
|
140
|
+
/** `readAuthToken`, keeping the absent/unreadable distinction. */
|
|
141
|
+
export declare function readAuthTokenRead(stateDir?: string): Promise<CredentialRead<string>>;
|
|
142
|
+
/** Remove the token file only. Prefer clearAllCredentials for anything a user
|
|
143
|
+
* would call signing out — see the warning there. */
|
|
144
|
+
export declare function clearAuthToken(stateDir?: string): Promise<void>;
|
|
145
|
+
/** Read `<dir>/auth.json`, or null when there is none. A malformed file is
|
|
146
|
+
* treated as absent rather than fatal — a corrupt credential should send the
|
|
147
|
+
* user through sign-in, not wedge the daemon. */
|
|
148
|
+
export declare function readCredentialFile(stateDir?: string): Promise<StoredCredential | null>;
|
|
149
|
+
/** `readCredentialFile`, keeping the absent/unreadable distinction. See
|
|
150
|
+
* CredentialRead for why a caller would want it. */
|
|
151
|
+
export declare function readCredentialFileRead(stateDir?: string): Promise<CredentialRead<StoredCredential>>;
|
|
152
|
+
/**
|
|
153
|
+
* Sign out of BOTH stores.
|
|
154
|
+
*
|
|
155
|
+
* Clearing one while the other still authenticates is the same divergence bug
|
|
156
|
+
* pointing the other way, and worse: the operator believes they signed out
|
|
157
|
+
* while the gateway keeps sending a credential. Every sign-out path must land
|
|
158
|
+
* here rather than removing a single file.
|
|
159
|
+
*/
|
|
160
|
+
export declare function clearAllCredentials(stateDir?: string): Promise<void>;
|
|
161
|
+
/** Which store answered. */
|
|
162
|
+
export type CredentialSource = 'env' | 'token-file' | 'credential-file' | 'none';
|
|
163
|
+
export interface ResolvedCredential {
|
|
164
|
+
token: string | null;
|
|
165
|
+
source: CredentialSource;
|
|
166
|
+
/** Where it was read from on disk. Absent for 'env' and 'none'. */
|
|
167
|
+
path?: string;
|
|
168
|
+
/** Epoch ms, when a store recorded one. Absent means UNKNOWN, not "fresh". */
|
|
169
|
+
expiresAt?: number;
|
|
170
|
+
/** True only when an expiry is known AND has passed. */
|
|
171
|
+
expired?: boolean;
|
|
172
|
+
/** Who the credential belongs to. Never an authorization input; see
|
|
173
|
+
* StoredCredential.account, including why it must not be logged. */
|
|
174
|
+
account?: string;
|
|
175
|
+
/** The API this credential was minted against, when the sign-in recorded one.
|
|
176
|
+
* Absent for an older credential — read that as "not recorded", never as
|
|
177
|
+
* "the default". */
|
|
178
|
+
apiBase?: string;
|
|
179
|
+
/**
|
|
180
|
+
* At least one credential store is present and could not be read.
|
|
181
|
+
*
|
|
182
|
+
* Absent means every store was read cleanly, so a missing token or a missing
|
|
183
|
+
* `account` above really is an absence. Present, it is not: the answer is
|
|
184
|
+
* incomplete for a reason that is likely to pass (a file lock, EMFILE under
|
|
185
|
+
* load), and a caller that publishes a STATE off this must not read it as a
|
|
186
|
+
* sign-out. Nothing is granted on it either way -- an unreadable credential
|
|
187
|
+
* authenticates nothing and identifies nobody. See CredentialRead.
|
|
188
|
+
*/
|
|
189
|
+
unreadable?: true;
|
|
190
|
+
}
|
|
191
|
+
export interface ResolveCredentialOptions {
|
|
192
|
+
env?: NodeJS.ProcessEnv;
|
|
193
|
+
stateDir?: string;
|
|
194
|
+
now?: () => number;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Resolve the credential this machine authenticates with, per the precedence
|
|
198
|
+
* documented at the top of this file.
|
|
199
|
+
*
|
|
200
|
+
* An expired stored credential is REPORTED, not skipped: the caller decides
|
|
201
|
+
* whether to refresh or re-prompt, and one that ignores `expired` fails at the
|
|
202
|
+
* gateway rather than here. A token file records no expiry at all, so
|
|
203
|
+
* `expiresAt` stays undefined for it unless the credential file beside it
|
|
204
|
+
* describes the same token — the absence of an expiry must never be read as
|
|
205
|
+
* evidence of freshness.
|
|
206
|
+
*/
|
|
207
|
+
export declare function resolveNodeCredential(opts?: ResolveCredentialOptions): Promise<ResolvedCredential>;
|
|
208
|
+
/** Which answer resolveApiBase gave. Reported so a startup banner can say why
|
|
209
|
+
* it is talking to the host it is talking to. */
|
|
210
|
+
export type ApiBaseSource = 'explicit' | 'env' | 'credential' | 'default';
|
|
211
|
+
export interface ResolvedApiBase {
|
|
212
|
+
base: string;
|
|
213
|
+
source: ApiBaseSource;
|
|
214
|
+
}
|
|
215
|
+
export interface ResolveApiBaseOptions {
|
|
216
|
+
/** A flag the operator typed (`--endpoint`, `--base`). Empty means absent —
|
|
217
|
+
* that is how a missing flag arrives from every caller here. */
|
|
218
|
+
explicit?: string;
|
|
219
|
+
env?: NodeJS.ProcessEnv;
|
|
220
|
+
stateDir?: string;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Which API to talk to.
|
|
224
|
+
*
|
|
225
|
+
* 1. an explicit flag — the operator is pointing somewhere on purpose
|
|
226
|
+
* 2. CORENEL_API_BASE — a container/CI statement of present intent
|
|
227
|
+
* 3. the credential's base — where the token this machine holds was minted
|
|
228
|
+
* 4. DEFAULT_API_BASE — nothing has been said, so say the product's own
|
|
229
|
+
*
|
|
230
|
+
* (3) is the change worth stating: the sidecar carried a literal default, so a
|
|
231
|
+
* user who signed in against one deployment had their daemon talk to another,
|
|
232
|
+
* and the only symptom was a 401 or a 404 far from the login. Preferring the
|
|
233
|
+
* credential's own base makes the common case need no flag at all, while (1)
|
|
234
|
+
* keeps `--endpoint` meaning exactly what it says for local dev.
|
|
235
|
+
*
|
|
236
|
+
* A second change to (1): the sidecar's `daemon.json` can also carry an
|
|
237
|
+
* `endpoint`, and since the CLI's config-layering fix it is passed in here as
|
|
238
|
+
* `explicit` too (an operator who wrote it into the file chose it, same as
|
|
239
|
+
* typing the flag) -- so it now outranks (2) `CORENEL_API_BASE` as well. A
|
|
240
|
+
* container/CI operator relying on the env var to override a baked-in
|
|
241
|
+
* `daemon.json` endpoint at deploy time now silently no-ops: the file wins.
|
|
242
|
+
* Override it with `--endpoint` (still rung 1, and still per-invocation) or by
|
|
243
|
+
* editing the file itself, not the environment.
|
|
244
|
+
*/
|
|
245
|
+
export declare function resolveApiBase(opts?: ResolveApiBaseOptions): Promise<ResolvedApiBase>;
|
|
246
|
+
/** A token is a credential; printing one puts it in scrollback, shell history
|
|
247
|
+
* and any screen share. Four leading characters identify WHICH token this is
|
|
248
|
+
* without being usable if the output is pasted somewhere. */
|
|
249
|
+
export declare function maskToken(token: string): string;
|
|
250
|
+
/**
|
|
251
|
+
* Mask an account/identity string for output that might land in a support
|
|
252
|
+
* thread or a public issue tracker (`corenel doctor`'s REACHABILITY line) --
|
|
253
|
+
* as opposed to `corenel login`/`corenel auth`, which print it in full because
|
|
254
|
+
* they are interactive and purpose-built for exactly that question. Preserves
|
|
255
|
+
* the domain (still answers "is this the org/deployment I expected?") while
|
|
256
|
+
* hiding the local part: `sbaker@logikbug.com` -> `s***r@logikbug.com`.
|
|
257
|
+
*
|
|
258
|
+
* A one- or two-character local part is NOT masked by keeping its first and
|
|
259
|
+
* last character -- for length 1 that character IS the whole local part, and
|
|
260
|
+
* for length 2 it is BOTH characters, so that scheme would print it in full
|
|
261
|
+
* under the name of masking it. Those collapse to a fixed, content-free `**`
|
|
262
|
+
* instead. A value that is not email-shaped at all (no `@`, or an empty local
|
|
263
|
+
* or domain half) -- or is empty/absent -- degrades to a generic redacted
|
|
264
|
+
* marker rather than being printed raw. Never throws: this runs in a
|
|
265
|
+
* diagnostic command that exists for when things are already broken, and a
|
|
266
|
+
* masking helper crashing on an unexpected shape would be exactly backwards.
|
|
267
|
+
*/
|
|
268
|
+
export declare function maskAccount(account: string | undefined | null): string;
|
|
269
|
+
/** The IAuthTokenProvider for node. Resolves exactly what `auth` reports, which
|
|
270
|
+
* is the whole point: the status command must describe the credential the
|
|
271
|
+
* gateway will actually send. */
|
|
272
|
+
export declare function nodeAuthToken(stateDir?: string): IAuthTokenProvider;
|
|
16
273
|
//# sourceMappingURL=auth.d.ts.map
|
package/dist/auth.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../auth.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../auth.ts"],"names":[],"mappings":"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"}
|
package/dist/auth.js
CHANGED
|
@@ -1,19 +1,60 @@
|
|
|
1
|
-
/* Node auth
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
1
|
+
/* Node auth credential store — the ONE place that decides which credential this
|
|
2
|
+
* machine authenticates with.
|
|
3
|
+
*
|
|
4
|
+
* TWO STORES, ONE ANSWER. A sign-in can land in either of two files, written by
|
|
5
|
+
* different halves of the product:
|
|
6
|
+
*
|
|
7
|
+
* <dir>/token a bare bearer token, one line. Written by `corenel login`
|
|
8
|
+
* (@corenel/cli's device flow) and read by the gateway
|
|
9
|
+
* client. This is the file real users are signed in with.
|
|
10
|
+
* <dir>/auth.json the richer record from the sidecar's PKCE flow
|
|
11
|
+
* (packages/sidecar/src/auth/store.ts): accessToken plus
|
|
12
|
+
* refreshToken, expiresAt and account.
|
|
13
|
+
*
|
|
14
|
+
* They used to be resolved independently, so `corenel-sidecar auth` could
|
|
15
|
+
* answer "Not signed in" about auth.json on a machine whose gateway calls were
|
|
16
|
+
* succeeding with the token file. That is the bug this module exists to close:
|
|
17
|
+
* everything that asks "is this machine signed in?" and everything that asks
|
|
18
|
+
* "what do I send?" now goes through resolveNodeCredential below.
|
|
19
|
+
*
|
|
20
|
+
* PRECEDENCE, stated once so nobody has to derive it:
|
|
21
|
+
*
|
|
22
|
+
* 1. CORENEL_TOKEN in the environment.
|
|
23
|
+
* 2. <dir>/token — the token file.
|
|
24
|
+
* 3. <dir>/auth.json — the credential file.
|
|
25
|
+
*
|
|
26
|
+
* (1) is first because the environment is a present-tense statement of intent:
|
|
27
|
+
* it is how a container, a CI job or an SSH session supplies identity, and
|
|
28
|
+
* those are exactly the places where a file on disk may be a stale artifact of
|
|
29
|
+
* an image build. It also means a `logout` cannot silently appear to fail — the
|
|
30
|
+
* commands say so explicitly when the variable is set.
|
|
31
|
+
*
|
|
32
|
+
* (2) beats (3) because the token file is the credential that already works:
|
|
33
|
+
* the gateway client and @corenel/cli have always read it, and real installs
|
|
34
|
+
* are signed in through it right now. Making the newer store win would change
|
|
35
|
+
* which token a working machine sends. The two only ever diverge on a machine
|
|
36
|
+
* that signed in both ways, because saveCredential writes BOTH and
|
|
37
|
+
* clearAllCredentials removes BOTH — so login and logout leave the two readers
|
|
38
|
+
* agreeing rather than leaning on the precedence at all. When the credential
|
|
39
|
+
* file describes the SAME token, its account/expiry metadata is carried over,
|
|
40
|
+
* which is the only reason (3) is consulted after (2) has already answered.
|
|
41
|
+
*
|
|
42
|
+
* Separate from the sidecar's <dir>/sidecar/daemon.token, which is the local
|
|
43
|
+
* PAIRING token: that authenticates a connection to a port, it does not say who
|
|
44
|
+
* the user is, and merging the two would turn "can reach the port" into "is the
|
|
45
|
+
* account owner".
|
|
46
|
+
*/
|
|
6
47
|
import { promises as fs } from 'node:fs';
|
|
7
48
|
import { homedir } from 'node:os';
|
|
8
49
|
import { join } from 'node:path';
|
|
9
|
-
import { stateDirName } from '@corenel/protocol';
|
|
50
|
+
import { stateDirName, DEFAULT_API_BASE } from '@corenel/protocol';
|
|
10
51
|
/* Every path helper takes an explicit base, defaulting to the real home.
|
|
11
52
|
*
|
|
12
53
|
* Not a convenience. The layout migration built on these MOVES files, and a
|
|
13
54
|
* helper that can only resolve homedir() would force every test of it to run
|
|
14
55
|
* against the developer's own ~/.corenel -- the one holding their edited
|
|
15
|
-
* personas
|
|
16
|
-
* discouraged. */
|
|
56
|
+
* personas, and the token they are signed in with right now. Taking a base
|
|
57
|
+
* makes that mistake impossible rather than discouraged. */
|
|
17
58
|
/** The state dir: `<home>/.corenel`. ALSO the global crew root -- global agents
|
|
18
59
|
* resolve as `<stateDir>/crew` -- so this never moves. */
|
|
19
60
|
export function corenelDir(base = homedir()) {
|
|
@@ -29,7 +70,72 @@ export function sidecarDir(base = homedir()) {
|
|
|
29
70
|
export function authTokenPath(base = homedir()) {
|
|
30
71
|
return join(corenelDir(base), 'token');
|
|
31
72
|
}
|
|
32
|
-
|
|
73
|
+
/**
|
|
74
|
+
* The directory both credential files live in.
|
|
75
|
+
*
|
|
76
|
+
* STATE-DIR DECISION, made deliberately: the token file stays HOME-scoped by
|
|
77
|
+
* default and does NOT move under a daemon-private directory. @corenel/cli
|
|
78
|
+
* resolves it from homedir() with no notion of a state dir, and `corenel login`
|
|
79
|
+
* writes it there; relocating it would sign every existing user out on upgrade
|
|
80
|
+
* and leave the CLI unable to find the credential it just wrote. What
|
|
81
|
+
* `--state-dir` does instead is redirect the whole state dir, exactly as the
|
|
82
|
+
* sidecar's `authDir` already does — so `<stateDir>/token` and
|
|
83
|
+
* `<stateDir>/auth.json` stay siblings, an isolated state dir stays isolated
|
|
84
|
+
* (nothing reaches back into the real home), and with no `--state-dir` this
|
|
85
|
+
* resolves to the same `~/.corenel/token` the CLI reads. Identical computation
|
|
86
|
+
* to packages/sidecar/src/auth/store.ts `authDir`, and it must stay identical.
|
|
87
|
+
*/
|
|
88
|
+
export function credentialDir(stateDir) {
|
|
89
|
+
return stateDir ?? corenelDir();
|
|
90
|
+
}
|
|
91
|
+
/** `<credentialDir>/token` — equals authTokenPath() when no state dir is given. */
|
|
92
|
+
export function tokenFilePath(stateDir) {
|
|
93
|
+
return join(credentialDir(stateDir), 'token');
|
|
94
|
+
}
|
|
95
|
+
/** `<credentialDir>/auth.json` — the sidecar's richer credential record. */
|
|
96
|
+
export function credentialFilePath(stateDir) {
|
|
97
|
+
return join(credentialDir(stateDir), 'auth.json');
|
|
98
|
+
}
|
|
99
|
+
/** The environment variable that carries a headless credential. */
|
|
100
|
+
export const TOKEN_ENV = 'CORENEL_TOKEN';
|
|
101
|
+
/** The environment variable that names the API. Same spelling @corenel/cli's
|
|
102
|
+
* `apiBase()` reads, because two names for one decision is how they drift. */
|
|
103
|
+
export const API_BASE_ENV = 'CORENEL_API_BASE';
|
|
104
|
+
/**
|
|
105
|
+
* Write one 0600 file so that no reader ever sees a half-written one.
|
|
106
|
+
*
|
|
107
|
+
* A credential is read by OTHER processes while it is being written -- a
|
|
108
|
+
* running daemon re-reads it, the gateway client reads it per request -- and
|
|
109
|
+
* `writeFile` truncates before it fills. A reader landing mid-write gets an
|
|
110
|
+
* empty token file (read as signed out) or a JSON parse failure on auth.json
|
|
111
|
+
* (read as no credential at all). A rename over the top is atomic on POSIX and
|
|
112
|
+
* on NTFS, so a reader sees the old file or the new one.
|
|
113
|
+
*
|
|
114
|
+
* The temp file is created 0600 and chmod'ed before the rename, never after:
|
|
115
|
+
* the point is that the file is never readable at a weaker mode, not that it
|
|
116
|
+
* ends up at the right one.
|
|
117
|
+
*/
|
|
118
|
+
async function writeFilePrivateAtomic(path, contents) {
|
|
119
|
+
const tmp = `${path}.tmp-${process.pid.toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
|
|
120
|
+
await fs.writeFile(tmp, contents, { mode: 0o600 });
|
|
121
|
+
// Best-effort: non-POSIX filesystems reject it, and a failure must not lose
|
|
122
|
+
// a credential that is otherwise written correctly.
|
|
123
|
+
try {
|
|
124
|
+
await fs.chmod(tmp, 0o600);
|
|
125
|
+
}
|
|
126
|
+
catch { /* non-POSIX */ }
|
|
127
|
+
try {
|
|
128
|
+
await fs.rename(tmp, path);
|
|
129
|
+
}
|
|
130
|
+
catch (e) {
|
|
131
|
+
try {
|
|
132
|
+
await fs.rm(tmp, { force: true });
|
|
133
|
+
}
|
|
134
|
+
catch { /* nothing to clean */ }
|
|
135
|
+
throw e;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
export async function writeAuthToken(token, stateDir) {
|
|
33
139
|
/* 0o700 on the DIRECTORY, not just 0o600 on the file. Without a mode, mkdir
|
|
34
140
|
* lands on the process umask -- typically 0o755, so the directory holding a
|
|
35
141
|
* bearer token is world-listable. The file's own contents stay protected
|
|
@@ -37,36 +143,319 @@ export async function writeAuthToken(token) {
|
|
|
37
143
|
* has a Corenel token and when they last refreshed it. `recursive: true`
|
|
38
144
|
* applies the mode only to directories it actually CREATES, so this never
|
|
39
145
|
* tightens a pre-existing ~/.corenel a user set up deliberately. */
|
|
40
|
-
|
|
41
|
-
await fs.
|
|
42
|
-
|
|
43
|
-
//
|
|
146
|
+
const dir = credentialDir(stateDir);
|
|
147
|
+
await fs.mkdir(dir, { recursive: true, mode: 0o700 });
|
|
148
|
+
await writeFilePrivateAtomic(tokenFilePath(stateDir), token.trim() + '\n');
|
|
149
|
+
// Best-effort: non-POSIX filesystems reject it, and a failure here must not
|
|
150
|
+
// lose a token that is already written correctly.
|
|
151
|
+
try {
|
|
152
|
+
await fs.chmod(dir, 0o700);
|
|
153
|
+
}
|
|
154
|
+
catch { /* non-POSIX */ }
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Record a completed sign-in in BOTH stores, including WHERE it was minted.
|
|
158
|
+
*
|
|
159
|
+
* `writeAuthToken` alone leaves the token file holding a bearer token with no
|
|
160
|
+
* record of which API issued it -- which is fine right up until the machine is
|
|
161
|
+
* pointed somewhere else by a default, and then it is a 401 with no visible
|
|
162
|
+
* cause. The base goes in auth.json because the token file is one line by
|
|
163
|
+
* contract and every existing reader of it splits on nothing.
|
|
164
|
+
*
|
|
165
|
+
* The credential record is REPLACED, not merged: a new sign-in may be a
|
|
166
|
+
* different account at a different host, and carrying the previous one's
|
|
167
|
+
* account or base onto it would report something nobody established.
|
|
168
|
+
*
|
|
169
|
+
* TWO FILES, AND A READER BETWEEN THEM. `resolveNodeCredential` borrows the
|
|
170
|
+
* account from auth.json only when auth.json describes the SAME token the
|
|
171
|
+
* token file holds -- which is right, and which means that during a RE-login
|
|
172
|
+
* the two disagree and the account reads as absent. That is fail-closed (a
|
|
173
|
+
* daemon files that handshake under its per-origin id, exactly as it did
|
|
174
|
+
* before any of this) but it is not free: the directory it mints then
|
|
175
|
+
* persists. So the window is made as small as two files allow. Both new
|
|
176
|
+
* contents are staged first, and the two renames happen back to back with no
|
|
177
|
+
* mkdir, no chmod and no JSON encoding between them -- microseconds rather
|
|
178
|
+
* than the duration of two file writes.
|
|
179
|
+
*
|
|
180
|
+
* It is not ZERO, and cannot be while the credential lives in two files. The
|
|
181
|
+
* honest fix is one file, which means changing what the gateway client and
|
|
182
|
+
* @corenel/cli have always read; the precedence comment at the top of this
|
|
183
|
+
* module is the record of why that has not been done.
|
|
184
|
+
*
|
|
185
|
+
* The credential file is renamed FIRST. Whichever order is chosen the
|
|
186
|
+
* intermediate state loses the account, so the tiebreak is which token a
|
|
187
|
+
* reader gets in that instant: credential-first leaves the token file holding
|
|
188
|
+
* the PREVIOUS token, which is the credential that was working a moment ago.
|
|
189
|
+
* Token-first would publish the new token with no account and no recorded
|
|
190
|
+
* base -- a state no sign-in ever produced.
|
|
191
|
+
*/
|
|
192
|
+
export async function writeLoginCredential(token, opts = {}) {
|
|
193
|
+
const cred = {
|
|
194
|
+
accessToken: token.trim(),
|
|
195
|
+
...(opts.account ? { account: opts.account } : {}),
|
|
196
|
+
...(opts.apiBase ? { apiBase: opts.apiBase } : {}),
|
|
197
|
+
};
|
|
198
|
+
const dir = credentialDir(opts.stateDir);
|
|
199
|
+
const credPath = credentialFilePath(opts.stateDir);
|
|
200
|
+
const tokPath = tokenFilePath(opts.stateDir);
|
|
201
|
+
await fs.mkdir(dir, { recursive: true, mode: 0o700 });
|
|
202
|
+
// Staged before either is published, so the publish is two renames and
|
|
203
|
+
// nothing else.
|
|
204
|
+
const credTmp = `${credPath}.tmp-${process.pid.toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
|
|
205
|
+
const tokTmp = `${tokPath}.tmp-${process.pid.toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
|
|
206
|
+
await fs.writeFile(credTmp, `${JSON.stringify(cred, null, 2)}\n`, { mode: 0o600 });
|
|
207
|
+
await fs.writeFile(tokTmp, `${cred.accessToken}\n`, { mode: 0o600 });
|
|
44
208
|
try {
|
|
45
|
-
await fs.chmod(
|
|
209
|
+
await fs.chmod(credTmp, 0o600);
|
|
46
210
|
}
|
|
47
211
|
catch { /* non-POSIX */ }
|
|
48
212
|
try {
|
|
49
|
-
await fs.chmod(
|
|
213
|
+
await fs.chmod(tokTmp, 0o600);
|
|
50
214
|
}
|
|
51
215
|
catch { /* non-POSIX */ }
|
|
216
|
+
try {
|
|
217
|
+
await fs.rename(credTmp, credPath);
|
|
218
|
+
await fs.rename(tokTmp, tokPath);
|
|
219
|
+
}
|
|
220
|
+
catch (e) {
|
|
221
|
+
try {
|
|
222
|
+
await fs.rm(credTmp, { force: true });
|
|
223
|
+
}
|
|
224
|
+
catch { /* nothing to clean */ }
|
|
225
|
+
try {
|
|
226
|
+
await fs.rm(tokTmp, { force: true });
|
|
227
|
+
}
|
|
228
|
+
catch { /* nothing to clean */ }
|
|
229
|
+
throw e;
|
|
230
|
+
}
|
|
231
|
+
try {
|
|
232
|
+
await fs.chmod(dir, 0o700);
|
|
233
|
+
}
|
|
234
|
+
catch { /* non-POSIX */ }
|
|
235
|
+
}
|
|
236
|
+
/** ENOENT -- the store simply is not there -- as opposed to any other failure. */
|
|
237
|
+
function isMissing(err) {
|
|
238
|
+
return typeof err === 'object' && err !== null && err.code === 'ENOENT';
|
|
239
|
+
}
|
|
240
|
+
export async function readAuthToken(stateDir) {
|
|
241
|
+
return (await readAuthTokenRead(stateDir)).value;
|
|
242
|
+
}
|
|
243
|
+
/** `readAuthToken`, keeping the absent/unreadable distinction. */
|
|
244
|
+
export async function readAuthTokenRead(stateDir) {
|
|
245
|
+
try {
|
|
246
|
+
const t = (await fs.readFile(tokenFilePath(stateDir), 'utf8')).trim();
|
|
247
|
+
// An empty file is an absence, not a failure: that is what a half-finished
|
|
248
|
+
// sign-out or an interrupted write leaves, and there is nothing to retry.
|
|
249
|
+
return { value: t || null, unreadable: false };
|
|
250
|
+
}
|
|
251
|
+
catch (err) {
|
|
252
|
+
return { value: null, unreadable: !isMissing(err) };
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
/** Remove the token file only. Prefer clearAllCredentials for anything a user
|
|
256
|
+
* would call signing out — see the warning there. */
|
|
257
|
+
export async function clearAuthToken(stateDir) {
|
|
258
|
+
try {
|
|
259
|
+
await fs.rm(tokenFilePath(stateDir), { force: true });
|
|
260
|
+
}
|
|
261
|
+
catch { /* already gone */ }
|
|
52
262
|
}
|
|
53
|
-
|
|
263
|
+
/** Read `<dir>/auth.json`, or null when there is none. A malformed file is
|
|
264
|
+
* treated as absent rather than fatal — a corrupt credential should send the
|
|
265
|
+
* user through sign-in, not wedge the daemon. */
|
|
266
|
+
export async function readCredentialFile(stateDir) {
|
|
267
|
+
return (await readCredentialFileRead(stateDir)).value;
|
|
268
|
+
}
|
|
269
|
+
/** `readCredentialFile`, keeping the absent/unreadable distinction. See
|
|
270
|
+
* CredentialRead for why a caller would want it. */
|
|
271
|
+
export async function readCredentialFileRead(stateDir) {
|
|
272
|
+
let raw;
|
|
54
273
|
try {
|
|
55
|
-
|
|
56
|
-
|
|
274
|
+
raw = await fs.readFile(credentialFilePath(stateDir), 'utf8');
|
|
275
|
+
}
|
|
276
|
+
catch (err) {
|
|
277
|
+
// ENOENT is the ordinary case and is a clean absence. EACCES/EISDIR/EBUSY
|
|
278
|
+
// yield no usable credential either -- crashing the daemon over one helps
|
|
279
|
+
// nobody -- but they are REPORTED as unreadable, because a caller that
|
|
280
|
+
// publishes a state off this answer must not read them as a sign-out.
|
|
281
|
+
return { value: null, unreadable: !isMissing(err) };
|
|
282
|
+
}
|
|
283
|
+
try {
|
|
284
|
+
const parsed = JSON.parse(raw);
|
|
285
|
+
if (typeof parsed !== 'object' || parsed === null)
|
|
286
|
+
return { value: null, unreadable: false };
|
|
287
|
+
const c = parsed;
|
|
288
|
+
if (typeof c.accessToken !== 'string' || !c.accessToken)
|
|
289
|
+
return { value: null, unreadable: false };
|
|
290
|
+
return {
|
|
291
|
+
value: {
|
|
292
|
+
accessToken: c.accessToken,
|
|
293
|
+
...(typeof c.refreshToken === 'string' ? { refreshToken: c.refreshToken } : {}),
|
|
294
|
+
...(typeof c.expiresAt === 'number' ? { expiresAt: c.expiresAt } : {}),
|
|
295
|
+
...(typeof c.account === 'string' ? { account: c.account } : {}),
|
|
296
|
+
...(typeof c.apiBase === 'string' && c.apiBase ? { apiBase: c.apiBase } : {}),
|
|
297
|
+
},
|
|
298
|
+
unreadable: false,
|
|
299
|
+
};
|
|
57
300
|
}
|
|
58
301
|
catch {
|
|
59
|
-
return null;
|
|
302
|
+
return { value: null, unreadable: false };
|
|
60
303
|
}
|
|
61
304
|
}
|
|
62
|
-
|
|
305
|
+
/**
|
|
306
|
+
* Sign out of BOTH stores.
|
|
307
|
+
*
|
|
308
|
+
* Clearing one while the other still authenticates is the same divergence bug
|
|
309
|
+
* pointing the other way, and worse: the operator believes they signed out
|
|
310
|
+
* while the gateway keeps sending a credential. Every sign-out path must land
|
|
311
|
+
* here rather than removing a single file.
|
|
312
|
+
*/
|
|
313
|
+
export async function clearAllCredentials(stateDir) {
|
|
314
|
+
await clearAuthToken(stateDir);
|
|
63
315
|
try {
|
|
64
|
-
await fs.rm(
|
|
316
|
+
await fs.rm(credentialFilePath(stateDir), { force: true });
|
|
65
317
|
}
|
|
66
318
|
catch { /* already gone */ }
|
|
67
319
|
}
|
|
68
|
-
/**
|
|
69
|
-
|
|
70
|
-
|
|
320
|
+
/**
|
|
321
|
+
* Resolve the credential this machine authenticates with, per the precedence
|
|
322
|
+
* documented at the top of this file.
|
|
323
|
+
*
|
|
324
|
+
* An expired stored credential is REPORTED, not skipped: the caller decides
|
|
325
|
+
* whether to refresh or re-prompt, and one that ignores `expired` fails at the
|
|
326
|
+
* gateway rather than here. A token file records no expiry at all, so
|
|
327
|
+
* `expiresAt` stays undefined for it unless the credential file beside it
|
|
328
|
+
* describes the same token — the absence of an expiry must never be read as
|
|
329
|
+
* evidence of freshness.
|
|
330
|
+
*/
|
|
331
|
+
export async function resolveNodeCredential(opts = {}) {
|
|
332
|
+
const env = opts.env ?? process.env;
|
|
333
|
+
const now = opts.now ?? Date.now;
|
|
334
|
+
const stateDir = opts.stateDir;
|
|
335
|
+
const fromEnv = env[TOKEN_ENV]?.trim();
|
|
336
|
+
if (fromEnv)
|
|
337
|
+
return { token: fromEnv, source: 'env' };
|
|
338
|
+
const credRead = await readCredentialFileRead(stateDir);
|
|
339
|
+
const tokenRead = await readAuthTokenRead(stateDir);
|
|
340
|
+
const cred = credRead.value;
|
|
341
|
+
const fileToken = tokenRead.value;
|
|
342
|
+
/* Carried through whatever this resolves to, including a SUCCESSFUL resolve:
|
|
343
|
+
* a readable token file beside an unreadable auth.json answers with a token
|
|
344
|
+
* and no account, and a caller that publishes a sign-out off that missing
|
|
345
|
+
* account needs to know the difference. Omitted rather than set false, so an
|
|
346
|
+
* ordinary result is the same object it always was. */
|
|
347
|
+
const unreadable = credRead.unreadable || tokenRead.unreadable ? { unreadable: true } : {};
|
|
348
|
+
if (fileToken) {
|
|
349
|
+
// Metadata is borrowed ONLY when the credential file describes this same
|
|
350
|
+
// token. Two different tokens mean two different sign-ins, and attaching
|
|
351
|
+
// one's expiry to the other would report a freshness nobody established.
|
|
352
|
+
const same = cred && cred.accessToken === fileToken ? cred : null;
|
|
353
|
+
return {
|
|
354
|
+
...withExpiry({ token: fileToken, source: 'token-file', path: tokenFilePath(stateDir) }, same, now),
|
|
355
|
+
...unreadable,
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
if (cred) {
|
|
359
|
+
return {
|
|
360
|
+
...withExpiry({ token: cred.accessToken, source: 'credential-file', path: credentialFilePath(stateDir) }, cred, now),
|
|
361
|
+
...unreadable,
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
return { token: null, source: 'none', ...unreadable };
|
|
365
|
+
}
|
|
366
|
+
function withExpiry(base, cred, now) {
|
|
367
|
+
if (!cred)
|
|
368
|
+
return base;
|
|
369
|
+
const expired = typeof cred.expiresAt === 'number' && cred.expiresAt <= now();
|
|
370
|
+
return {
|
|
371
|
+
...base,
|
|
372
|
+
...(typeof cred.expiresAt === 'number' ? { expiresAt: cred.expiresAt } : {}),
|
|
373
|
+
...(expired ? { expired: true } : {}),
|
|
374
|
+
...(cred.account ? { account: cred.account } : {}),
|
|
375
|
+
...(cred.apiBase ? { apiBase: cred.apiBase } : {}),
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Which API to talk to.
|
|
380
|
+
*
|
|
381
|
+
* 1. an explicit flag — the operator is pointing somewhere on purpose
|
|
382
|
+
* 2. CORENEL_API_BASE — a container/CI statement of present intent
|
|
383
|
+
* 3. the credential's base — where the token this machine holds was minted
|
|
384
|
+
* 4. DEFAULT_API_BASE — nothing has been said, so say the product's own
|
|
385
|
+
*
|
|
386
|
+
* (3) is the change worth stating: the sidecar carried a literal default, so a
|
|
387
|
+
* user who signed in against one deployment had their daemon talk to another,
|
|
388
|
+
* and the only symptom was a 401 or a 404 far from the login. Preferring the
|
|
389
|
+
* credential's own base makes the common case need no flag at all, while (1)
|
|
390
|
+
* keeps `--endpoint` meaning exactly what it says for local dev.
|
|
391
|
+
*
|
|
392
|
+
* A second change to (1): the sidecar's `daemon.json` can also carry an
|
|
393
|
+
* `endpoint`, and since the CLI's config-layering fix it is passed in here as
|
|
394
|
+
* `explicit` too (an operator who wrote it into the file chose it, same as
|
|
395
|
+
* typing the flag) -- so it now outranks (2) `CORENEL_API_BASE` as well. A
|
|
396
|
+
* container/CI operator relying on the env var to override a baked-in
|
|
397
|
+
* `daemon.json` endpoint at deploy time now silently no-ops: the file wins.
|
|
398
|
+
* Override it with `--endpoint` (still rung 1, and still per-invocation) or by
|
|
399
|
+
* editing the file itself, not the environment.
|
|
400
|
+
*/
|
|
401
|
+
export async function resolveApiBase(opts = {}) {
|
|
402
|
+
const explicit = opts.explicit?.trim();
|
|
403
|
+
if (explicit)
|
|
404
|
+
return { base: explicit, source: 'explicit' };
|
|
405
|
+
const fromEnv = (opts.env ?? process.env)[API_BASE_ENV]?.trim();
|
|
406
|
+
if (fromEnv)
|
|
407
|
+
return { base: fromEnv, source: 'env' };
|
|
408
|
+
const cred = await resolveNodeCredential({
|
|
409
|
+
env: {},
|
|
410
|
+
...(opts.stateDir ? { stateDir: opts.stateDir } : {}),
|
|
411
|
+
});
|
|
412
|
+
if (cred.apiBase)
|
|
413
|
+
return { base: cred.apiBase, source: 'credential' };
|
|
414
|
+
return { base: DEFAULT_API_BASE, source: 'default' };
|
|
415
|
+
}
|
|
416
|
+
/** A token is a credential; printing one puts it in scrollback, shell history
|
|
417
|
+
* and any screen share. Four leading characters identify WHICH token this is
|
|
418
|
+
* without being usable if the output is pasted somewhere. */
|
|
419
|
+
export function maskToken(token) {
|
|
420
|
+
const t = token.trim();
|
|
421
|
+
if (t.length <= 8)
|
|
422
|
+
return '****';
|
|
423
|
+
return `${t.slice(0, 4)}…${t.slice(-2)} (${t.length} chars)`;
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Mask an account/identity string for output that might land in a support
|
|
427
|
+
* thread or a public issue tracker (`corenel doctor`'s REACHABILITY line) --
|
|
428
|
+
* as opposed to `corenel login`/`corenel auth`, which print it in full because
|
|
429
|
+
* they are interactive and purpose-built for exactly that question. Preserves
|
|
430
|
+
* the domain (still answers "is this the org/deployment I expected?") while
|
|
431
|
+
* hiding the local part: `sbaker@logikbug.com` -> `s***r@logikbug.com`.
|
|
432
|
+
*
|
|
433
|
+
* A one- or two-character local part is NOT masked by keeping its first and
|
|
434
|
+
* last character -- for length 1 that character IS the whole local part, and
|
|
435
|
+
* for length 2 it is BOTH characters, so that scheme would print it in full
|
|
436
|
+
* under the name of masking it. Those collapse to a fixed, content-free `**`
|
|
437
|
+
* instead. A value that is not email-shaped at all (no `@`, or an empty local
|
|
438
|
+
* or domain half) -- or is empty/absent -- degrades to a generic redacted
|
|
439
|
+
* marker rather than being printed raw. Never throws: this runs in a
|
|
440
|
+
* diagnostic command that exists for when things are already broken, and a
|
|
441
|
+
* masking helper crashing on an unexpected shape would be exactly backwards.
|
|
442
|
+
*/
|
|
443
|
+
export function maskAccount(account) {
|
|
444
|
+
const s = (account ?? '').trim();
|
|
445
|
+
if (!s)
|
|
446
|
+
return '(no identity recorded)';
|
|
447
|
+
const at = s.indexOf('@');
|
|
448
|
+
if (at <= 0 || at === s.length - 1)
|
|
449
|
+
return '(unrecognized identity)';
|
|
450
|
+
const local = s.slice(0, at);
|
|
451
|
+
const domain = s.slice(at + 1);
|
|
452
|
+
const maskedLocal = local.length <= 2 ? '**' : `${local[0]}***${local[local.length - 1]}`;
|
|
453
|
+
return `${maskedLocal}@${domain}`;
|
|
454
|
+
}
|
|
455
|
+
/** The IAuthTokenProvider for node. Resolves exactly what `auth` reports, which
|
|
456
|
+
* is the whole point: the status command must describe the credential the
|
|
457
|
+
* gateway will actually send. */
|
|
458
|
+
export function nodeAuthToken(stateDir) {
|
|
459
|
+
return { getToken: async () => (await resolveNodeCredential(stateDir ? { stateDir } : {})).token };
|
|
71
460
|
}
|
|
72
461
|
//# sourceMappingURL=auth.js.map
|
package/dist/auth.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../auth.ts"],"names":[],"mappings":"AAAA;;;;yEAIyE;AACzE,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD;;;;;;kBAMkB;AAElB;2DAC2D;AAC3D,MAAM,UAAU,UAAU,CAAC,OAAe,OAAO,EAAE;IACjD,OAAO,IAAI,CAAC,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC;AACpC,CAAC;AAED;iFACiF;AACjF,MAAM,UAAU,UAAU,CAAC,OAAe,OAAO,EAAE;IACjD,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,CAAC;AAC3C,CAAC;AAED;0EAC0E;AAC1E,MAAM,UAAU,aAAa,CAAC,OAAe,OAAO,EAAE;IACpD,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,KAAa;IAChD;;;;;;wEAMoE;IACpE,MAAM,EAAE,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC/D,MAAM,EAAE,CAAC,SAAS,CAAC,aAAa,EAAE,EAAE,KAAK,CAAC,IAAI,EAAE,GAAG,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC1E,wEAAwE;IACxE,wEAAwE;IACxE,IAAI,CAAC;QAAC,MAAM,EAAE,CAAC,KAAK,CAAC,aAAa,EAAE,EAAE,KAAK,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC;IACzE,IAAI,CAAC;QAAC,MAAM,EAAE,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,KAAK,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC;AACxE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,aAAa,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC9D,OAAO,CAAC,IAAI,IAAI,CAAC;IACnB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,IAAI,CAAC;QAAC,MAAM,EAAE,CAAC,EAAE,CAAC,aAAa,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,kBAAkB,CAAC,CAAC;AACrF,CAAC;AAED,uFAAuF;AACvF,MAAM,UAAU,aAAa;IAC3B,OAAO,EAAE,QAAQ,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,MAAM,aAAa,EAAE,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,IAAI,EAAE,CAAC;AAChG,CAAC"}
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fileService.d.ts","sourceRoot":"","sources":["../fileService.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAsE1F;;;;;;;;;;uBAUuB;AACvB,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,GAAE,MAAY,GAAG,OAAO,CAgB3E;AAED,qBAAa,eAAgB,YAAW,WAAW;IACjD,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAe;IAC7C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,QAAQ;IAC5B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;gBAElB,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAO;IAM3D,yEAAyE;IACzE,OAAO,CAAC,MAAM;IAId;sFACkF;IAClF,OAAO,CAAC,GAAG;IAMX;;uFAEmF;YACrE,UAAU;IAoBxB,mFAAmF;YACrE,OAAO;IAMf,IAAI,CAAC,GAAG,SAAK,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"fileService.d.ts","sourceRoot":"","sources":["../fileService.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAsE1F;;;;;;;;;;uBAUuB;AACvB,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,GAAE,MAAY,GAAG,OAAO,CAgB3E;AAED,qBAAa,eAAgB,YAAW,WAAW;IACjD,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAe;IAC7C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,QAAQ;IAC5B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;gBAElB,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAO;IAM3D,yEAAyE;IACzE,OAAO,CAAC,MAAM;IAId;sFACkF;IAClF,OAAO,CAAC,GAAG;IAMX;;uFAEmF;YACrE,UAAU;IAoBxB,mFAAmF;YACrE,OAAO;IAMf,IAAI,CAAC,GAAG,SAAK,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IA4BnC,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAInC,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAS5C,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOnD,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAO1D,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,SAAK,GAAG,OAAO,CAAC,IAAI,CAAC;IAYjD,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAInC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAO/C,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlC,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAU9C,QAAQ,IAAI,MAAM,IAAI;CAGvB"}
|
package/dist/fileService.js
CHANGED
|
@@ -206,8 +206,13 @@ export class NodeFileService {
|
|
|
206
206
|
out.push({ name: e.name, path, kind: 'directory', children: await walk(absChild) });
|
|
207
207
|
}
|
|
208
208
|
else {
|
|
209
|
+
// The stat is already being paid for `size`; `mtime` rides along for
|
|
210
|
+
// free. It is what lets a caller ORDER files without reading them
|
|
211
|
+
// (the session store pages its newest-first list off this), so the
|
|
212
|
+
// node backend now matches DirectoryHandleFileService, which has
|
|
213
|
+
// always supplied both.
|
|
209
214
|
const st = await fs.stat(absChild).catch(() => null);
|
|
210
|
-
out.push({ name: e.name, path, kind: 'file', size: st?.size, ext: extOf(e.name) });
|
|
215
|
+
out.push({ name: e.name, path, kind: 'file', size: st?.size, mtime: st?.mtimeMs, ext: extOf(e.name) });
|
|
211
216
|
}
|
|
212
217
|
}
|
|
213
218
|
return out;
|
|
@@ -220,7 +225,7 @@ export class NodeFileService {
|
|
|
220
225
|
async stat(path) {
|
|
221
226
|
try {
|
|
222
227
|
const st = await fs.stat(this.abs(path));
|
|
223
|
-
return { path: normalizeFilePath(path), kind: st.isDirectory() ? 'directory' : 'file', size: st.size, ext: extOf(path) };
|
|
228
|
+
return { path: normalizeFilePath(path), kind: st.isDirectory() ? 'directory' : 'file', size: st.size, mtime: st.mtimeMs, ext: extOf(path) };
|
|
224
229
|
}
|
|
225
230
|
catch {
|
|
226
231
|
return null;
|
package/dist/fileService.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fileService.js","sourceRoot":"","sources":["../fileService.ts"],"names":[],"mappings":"AAAA;;;;gDAIgD;AAChD,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAExF,OAAO,EAAE,iBAAiB,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAE3E;;;;;;;;;;;;;;;;;sCAiBsC;AACtC,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC;IACnB,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ;IACpE,cAAc,EAAE,cAAc,EAAE,mBAAmB;CACpD,CAAC,CAAC;AAEH;;;;;;;;eAQe;AACf,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC;AAE/C;;;;;;;;;;;;;;iDAciD;AACjD,MAAM,uBAAuB,GAAG,IAAI,GAAG,CAAC;IACtC,qBAAqB,EAAE,WAAW,EAAE,YAAY,EAAE,uBAAuB;IACzE,aAAa;CACd,CAAC,CAAC;AAEH;;;uBAGuB;AACvB,KAAK,UAAU,0BAA0B,CAAC,MAAc;IACtD,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACvC,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,uBAAuB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;;;;;;;uBAUuB;AACvB,MAAM,UAAU,WAAW,CAAC,GAAW,EAAE,cAAsB,GAAG;IAChE,IAAI,GAAG,KAAK,EAAE;QAAE,OAAO,KAAK,CAAC;IAC7B,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,GAAG,WAAW,CAAC;QAAE,OAAO,IAAI,CAAC;IACpE,IAAI,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACpD,gEAAgE;IAChE,sEAAsE;IACtE,oEAAoE;IACpE,oEAAoE;IACpE,wEAAwE;IACxE,yEAAyE;IACzE,IAAI,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACjC,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;QACzB,IAAI,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC,CAAC,oCAAoC;QAC7E,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC;YAAE,OAAO,IAAI,CAAC,CAAC,YAAY;IACvD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,OAAO,eAAe;IAO1B,YAAY,IAAY,EAAE,OAA+B,EAAE;QANlD;;;;mBAAwB,WAAW;WAAC;QACpC;;;;;WAAc;QACd;;;;mBAAc,IAAI;WAAC;QACnB;;;;;WAAkB;QACV;;;;;WAAa;QAG5B,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAC1B,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC;QAC9C,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC;IACxC,CAAC;IAED,yEAAyE;IACjE,MAAM,CAAC,CAAS;QACtB,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC9C,CAAC;IAED;sFACkF;IAC1E,GAAG,CAAC,CAAS;QACnB,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC;QACnD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,EAAE,CAAC,CAAC;QAC9E,OAAO,CAAC,CAAC;IACX,CAAC;IAED;;uFAEmF;IAC3E,KAAK,CAAC,UAAU,CAAC,CAAS;QAChC,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9C,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,SAAS,CAAC;YACR,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;gBACtC,MAAM,GAAG,GAAG,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;gBACrC,IAAI,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;oBACrB,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,EAAE,CAAC,CAAC;gBACvE,CAAC;gBACD,OAAO;YACT,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,IAAI,CAAC,YAAY,KAAK,IAAI,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC;oBAAE,MAAM,CAAC,CAAC;gBACrE,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;gBAC9B,IAAI,MAAM,KAAK,KAAK;oBAAE,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,EAAE,CAAC,CAAC;gBAC5F,KAAK,GAAG,MAAM,CAAC;YACjB,CAAC;QACH,CAAC;IACH,CAAC;IAED,mFAAmF;IAC3E,KAAK,CAAC,OAAO,CAAC,CAAS;QAC7B,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACtB,MAAM,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QACzB,OAAO,CAAC,CAAC;IACX,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,GAAG,GAAG,EAAE;QACjB,MAAM,IAAI,GAAG,KAAK,EAAE,MAAc,EAAuB,EAAE;YACzD,IAAI,OAAO,CAAC;YACZ,IAAI,CAAC;gBAAC,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC;gBAAC,OAAO,EAAE,CAAC;YAAC,CAAC;YACzF,MAAM,GAAG,GAAe,EAAE,CAAC;YAC3B,KAAK,MAAM,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;gBACrE,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;oBAAE,SAAS;gBAC/B,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;gBACtC,MAAM,IAAI,GAAG,iBAAiB,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;gBAC9D,IAAI,CAAC,CAAC,WAAW,EAAE,IAAI,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC;oBAAE,SAAS;gBACtD,IAAI,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,IAAI,KAAK,UAAU,IAAI,MAAM,0BAA0B,CAAC,QAAQ,CAAC;oBAAE,SAAS;gBACrG,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;oBACpB,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;gBACtF,CAAC;qBAAM,CAAC;oBACN,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;oBACrD,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"fileService.js","sourceRoot":"","sources":["../fileService.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { NodeFileService } from './fileService';
|
|
2
|
-
export { corenelDir, sidecarDir, authTokenPath, writeAuthToken, readAuthToken, clearAuthToken, nodeAuthToken, } from './auth';
|
|
2
|
+
export { corenelDir, sidecarDir, authTokenPath, credentialDir, tokenFilePath, credentialFilePath, writeAuthToken, readAuthToken, readAuthTokenRead, readCredentialFile, readCredentialFileRead, clearAuthToken, clearAllCredentials, resolveNodeCredential, nodeAuthToken, maskToken, maskAccount, TOKEN_ENV, writeLoginCredential, resolveApiBase, API_BASE_ENV, type StoredCredential, type CredentialSource, type ResolvedCredential, type ResolveCredentialOptions, type CredentialRead, type ApiBaseSource, type ResolvedApiBase, type ResolveApiBaseOptions, } from './auth';
|
|
3
3
|
export { nodePromptHost } from './promptHost';
|
|
4
4
|
export { migrateHomeLayout, type MigrationReport } from './migrateHome';
|
|
5
5
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EACL,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,cAAc,EAAE,aAAa,EAAE,cAAc,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EACL,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,aAAa,EAAE,aAAa,EAAE,kBAAkB,EACvF,cAAc,EAAE,aAAa,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,sBAAsB,EAC5F,cAAc,EAAE,mBAAmB,EACnC,qBAAqB,EAAE,aAAa,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EACvE,oBAAoB,EAAE,cAAc,EAAE,YAAY,EAClD,KAAK,gBAAgB,EAAE,KAAK,gBAAgB,EAAE,KAAK,kBAAkB,EAAE,KAAK,wBAAwB,EACpG,KAAK,cAAc,EACnB,KAAK,aAAa,EAAE,KAAK,eAAe,EAAE,KAAK,qBAAqB,GACrE,MAAM,QAAQ,CAAC;AAChB,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* @corenel/tools-node — node capabilities (the tools-web twin). */
|
|
2
2
|
export { NodeFileService } from './fileService';
|
|
3
|
-
export { corenelDir, sidecarDir, authTokenPath, writeAuthToken, readAuthToken, clearAuthToken, nodeAuthToken, } from './auth';
|
|
3
|
+
export { corenelDir, sidecarDir, authTokenPath, credentialDir, tokenFilePath, credentialFilePath, writeAuthToken, readAuthToken, readAuthTokenRead, readCredentialFile, readCredentialFileRead, clearAuthToken, clearAllCredentials, resolveNodeCredential, nodeAuthToken, maskToken, maskAccount, TOKEN_ENV, writeLoginCredential, resolveApiBase, API_BASE_ENV, } from './auth';
|
|
4
4
|
export { nodePromptHost } from './promptHost';
|
|
5
5
|
export { migrateHomeLayout } from './migrateHome';
|
|
6
6
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EACL,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,cAAc,EAAE,aAAa,EAAE,cAAc,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EACL,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,aAAa,EAAE,aAAa,EAAE,kBAAkB,EACvF,cAAc,EAAE,aAAa,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,sBAAsB,EAC5F,cAAc,EAAE,mBAAmB,EACnC,qBAAqB,EAAE,aAAa,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EACvE,oBAAoB,EAAE,cAAc,EAAE,YAAY,GAInD,MAAM,QAAQ,CAAC;AAChB,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAwB,MAAM,eAAe,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@corenel/tools-node",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"license": "Elastic-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Corenel node capabilities — the tools-web twin. A disk-backed FileService (the harness file tools + node PromptHost workspace) over node:fs, confined to a root. Shell/secrets/~/.corenel to follow.",
|
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"@prompd/core": "0.5.0-beta.10",
|
|
19
|
-
"@corenel/
|
|
20
|
-
"@corenel/
|
|
19
|
+
"@corenel/protocol": "0.6.1",
|
|
20
|
+
"@corenel/harness": "0.6.1"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
23
|
"@types/node": "^24.13.1",
|
|
@@ -30,6 +30,11 @@
|
|
|
30
30
|
"files": [
|
|
31
31
|
"dist"
|
|
32
32
|
],
|
|
33
|
+
"repository": {
|
|
34
|
+
"type": "git",
|
|
35
|
+
"url": "git+https://github.com/Prompd/prompd-web.git",
|
|
36
|
+
"directory": "packages/tools-node"
|
|
37
|
+
},
|
|
33
38
|
"scripts": {
|
|
34
39
|
"typecheck": "tsc --noEmit",
|
|
35
40
|
"preverify": "pnpm --filter @corenel/protocol build && pnpm --filter @corenel/harness build",
|