@volter/world-core 2.0.16 → 2.0.17
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/credential.js +28 -0
- package/package.json +1 -1
- package/src/credential.ts +24 -0
package/dist/src/credential.js
CHANGED
|
@@ -131,6 +131,33 @@ export function transitSealer(options) {
|
|
|
131
131
|
const named = `${mount}/${options.key}`;
|
|
132
132
|
const addr = options.addr.replace(/\/+$/, '');
|
|
133
133
|
const fingerprintKey = options.fingerprintKey ?? `${options.key}-fingerprint`;
|
|
134
|
+
// a periodic token lives while it is renewed within its period: after a call it answered, at most once a day, the
|
|
135
|
+
// sealer renews its own. A vault that refuses (a token that is not renewable, a root or dev token) is asked again the
|
|
136
|
+
// next day; one that did not answer, after the next call. The token's own period is the bound.
|
|
137
|
+
let renewedAt = 0;
|
|
138
|
+
const renew = async () => {
|
|
139
|
+
if (Date.now() - renewedAt < 86_400_000)
|
|
140
|
+
return;
|
|
141
|
+
renewedAt = Date.now();
|
|
142
|
+
let status;
|
|
143
|
+
try {
|
|
144
|
+
status = (await (options.fetch ?? fetch)(`${addr}/v1/auth/token/renew-self`, {
|
|
145
|
+
method: 'POST',
|
|
146
|
+
headers: { 'x-vault-token': await options.token(), 'content-type': 'application/json', ...(options.namespace ? { 'x-vault-namespace': options.namespace } : {}) },
|
|
147
|
+
body: '{}',
|
|
148
|
+
signal: AbortSignal.timeout(options.timeoutMs ?? 10_000),
|
|
149
|
+
})).status;
|
|
150
|
+
}
|
|
151
|
+
catch (error) {
|
|
152
|
+
renewedAt = 0;
|
|
153
|
+
console.warn(`[credential] the vault at ${addr} did not answer renewing this host's token (${error.message})`);
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
if (status >= 500)
|
|
157
|
+
renewedAt = 0;
|
|
158
|
+
if (status >= 300)
|
|
159
|
+
console.warn(`[credential] the vault at ${addr} did not renew this host's token (${status})`);
|
|
160
|
+
};
|
|
134
161
|
const call = async (op, body, key = options.key) => {
|
|
135
162
|
const which = `${mount}/${key}`;
|
|
136
163
|
let response;
|
|
@@ -150,6 +177,7 @@ export function transitSealer(options) {
|
|
|
150
177
|
const answer = (await response.json());
|
|
151
178
|
if (!answer.data)
|
|
152
179
|
throw new Error(`the vault answered transit ${op} with ${which} without data`);
|
|
180
|
+
void renew();
|
|
153
181
|
return answer.data;
|
|
154
182
|
};
|
|
155
183
|
const fingerprintOf = async (plaintext) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@volter/world-core",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.17",
|
|
4
4
|
"description": "The kernel of Volter World: one log per twin, branches as pointers, checkpoints, the fold that keeps a twin current, the head that performs a write against the vendor, references, and the git plane. A twin package builds on it; the runtime serves it.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"twin",
|
package/src/credential.ts
CHANGED
|
@@ -207,6 +207,29 @@ export function transitSealer(options: TransitSealerOptions): Sealer {
|
|
|
207
207
|
const named = `${mount}/${options.key}`;
|
|
208
208
|
const addr = options.addr.replace(/\/+$/, '');
|
|
209
209
|
const fingerprintKey = options.fingerprintKey ?? `${options.key}-fingerprint`;
|
|
210
|
+
// a periodic token lives while it is renewed within its period: after a call it answered, at most once a day, the
|
|
211
|
+
// sealer renews its own. A vault that refuses (a token that is not renewable, a root or dev token) is asked again the
|
|
212
|
+
// next day; one that did not answer, after the next call. The token's own period is the bound.
|
|
213
|
+
let renewedAt = 0;
|
|
214
|
+
const renew = async (): Promise<void> => {
|
|
215
|
+
if (Date.now() - renewedAt < 86_400_000) return;
|
|
216
|
+
renewedAt = Date.now();
|
|
217
|
+
let status: number;
|
|
218
|
+
try {
|
|
219
|
+
status = (await (options.fetch ?? fetch)(`${addr}/v1/auth/token/renew-self`, {
|
|
220
|
+
method: 'POST',
|
|
221
|
+
headers: { 'x-vault-token': await options.token(), 'content-type': 'application/json', ...(options.namespace ? { 'x-vault-namespace': options.namespace } : {}) },
|
|
222
|
+
body: '{}',
|
|
223
|
+
signal: AbortSignal.timeout(options.timeoutMs ?? 10_000),
|
|
224
|
+
})).status;
|
|
225
|
+
} catch (error) {
|
|
226
|
+
renewedAt = 0;
|
|
227
|
+
console.warn(`[credential] the vault at ${addr} did not answer renewing this host's token (${(error as Error).message})`);
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
if (status >= 500) renewedAt = 0;
|
|
231
|
+
if (status >= 300) console.warn(`[credential] the vault at ${addr} did not renew this host's token (${status})`);
|
|
232
|
+
};
|
|
210
233
|
const call = async (op: 'encrypt' | 'decrypt' | 'hmac', body: Record<string, string | number>, key = options.key): Promise<Record<string, string>> => {
|
|
211
234
|
const which = `${mount}/${key}`;
|
|
212
235
|
let response: Response;
|
|
@@ -223,6 +246,7 @@ export function transitSealer(options: TransitSealerOptions): Sealer {
|
|
|
223
246
|
if (!response.ok) throw new Error(`the vault refused transit ${op} with ${which} (${response.status})`);
|
|
224
247
|
const answer = (await response.json()) as { data?: Record<string, string> };
|
|
225
248
|
if (!answer.data) throw new Error(`the vault answered transit ${op} with ${which} without data`);
|
|
249
|
+
void renew();
|
|
226
250
|
return answer.data;
|
|
227
251
|
};
|
|
228
252
|
const fingerprintOf = async (plaintext: Uint8Array): Promise<string> => {
|