@inkbox/sdk 0.1.4 → 0.2.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/README.md +31 -35
- package/dist/_http.d.ts +7 -1
- package/dist/_http.d.ts.map +1 -1
- package/dist/_http.js +13 -1
- package/dist/_http.js.map +1 -1
- package/dist/agent_identity.d.ts +89 -71
- package/dist/agent_identity.d.ts.map +1 -1
- package/dist/agent_identity.js +145 -113
- package/dist/agent_identity.js.map +1 -1
- package/dist/credentials.d.ts +97 -0
- package/dist/credentials.d.ts.map +1 -0
- package/dist/credentials.js +147 -0
- package/dist/credentials.js.map +1 -0
- package/dist/identities/resources/identities.d.ts +1 -16
- package/dist/identities/resources/identities.d.ts.map +1 -1
- package/dist/identities/resources/identities.js +1 -19
- package/dist/identities/resources/identities.js.map +1 -1
- package/dist/identities/types.d.ts +0 -21
- package/dist/identities/types.d.ts.map +1 -1
- package/dist/identities/types.js +0 -11
- package/dist/identities/types.js.map +1 -1
- package/dist/index.d.ts +11 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -1
- package/dist/index.js.map +1 -1
- package/dist/inkbox.d.ts +42 -6
- package/dist/inkbox.d.ts.map +1 -1
- package/dist/inkbox.js +59 -10
- package/dist/inkbox.js.map +1 -1
- package/dist/mail/resources/messages.d.ts +2 -2
- package/dist/mail/resources/messages.d.ts.map +1 -1
- package/dist/mail/resources/messages.js.map +1 -1
- package/dist/mail/types.d.ts +8 -1
- package/dist/mail/types.d.ts.map +1 -1
- package/dist/mail/types.js +8 -0
- package/dist/mail/types.js.map +1 -1
- package/dist/vault/crypto.d.ts +138 -0
- package/dist/vault/crypto.d.ts.map +1 -0
- package/dist/vault/crypto.js +273 -0
- package/dist/vault/crypto.js.map +1 -0
- package/dist/vault/resources/vault.d.ts +183 -0
- package/dist/vault/resources/vault.d.ts.map +1 -0
- package/dist/vault/resources/vault.js +396 -0
- package/dist/vault/resources/vault.js.map +1 -0
- package/dist/vault/totp.d.ts +73 -0
- package/dist/vault/totp.d.ts.map +1 -0
- package/dist/vault/totp.js +230 -0
- package/dist/vault/totp.js.map +1 -0
- package/dist/vault/types.d.ts +239 -0
- package/dist/vault/types.d.ts.map +1 -0
- package/dist/vault/types.js +229 -0
- package/dist/vault/types.js.map +1 -0
- package/package.json +5 -1
- package/dist/authenticator/resources/accounts.d.ts +0 -70
- package/dist/authenticator/resources/accounts.d.ts.map +0 -1
- package/dist/authenticator/resources/accounts.js +0 -91
- package/dist/authenticator/resources/accounts.js.map +0 -1
- package/dist/authenticator/resources/apps.d.ts +0 -38
- package/dist/authenticator/resources/apps.d.ts.map +0 -1
- package/dist/authenticator/resources/apps.js +0 -52
- package/dist/authenticator/resources/apps.js.map +0 -1
- package/dist/authenticator/types.d.ts +0 -83
- package/dist/authenticator/types.d.ts.map +0 -1
- package/dist/authenticator/types.js +0 -43
- package/dist/authenticator/types.js.map +0 -1
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* inkbox-vault/resources/vault.ts
|
|
3
|
+
*
|
|
4
|
+
* VaultResource — org-level vault operations.
|
|
5
|
+
* UnlockedVault — crypto-enabled wrapper for secret CRUD after unlock.
|
|
6
|
+
*/
|
|
7
|
+
import { generateTotp, parseTotpUri } from "../totp.js";
|
|
8
|
+
import { computeAuthHash, decryptPayload, deriveMasterKey, deriveSalt, encryptPayload, unwrapOrgKey, } from "../crypto.js";
|
|
9
|
+
import { VaultSecretType, inferSecretType, parseAccessRule, parsePayload, parseVaultInfo, parseVaultKey, parseVaultSecret, parseVaultSecretDetail, serializePayload, } from "../types.js";
|
|
10
|
+
/**
|
|
11
|
+
* Org-level vault operations.
|
|
12
|
+
*
|
|
13
|
+
* Access via `inkbox.vault`. Most read-only operations work without
|
|
14
|
+
* unlocking. To create, read, or update secret payloads, call
|
|
15
|
+
* {@link unlock} first.
|
|
16
|
+
*/
|
|
17
|
+
export class VaultResource {
|
|
18
|
+
/** @internal */
|
|
19
|
+
http;
|
|
20
|
+
/** @internal */
|
|
21
|
+
_unlocked = null;
|
|
22
|
+
/** @internal */
|
|
23
|
+
constructor(http) {
|
|
24
|
+
this.http = http;
|
|
25
|
+
}
|
|
26
|
+
// ------------------------------------------------------------------
|
|
27
|
+
// Vault metadata
|
|
28
|
+
// ------------------------------------------------------------------
|
|
29
|
+
/** Get vault metadata for the caller's organisation. */
|
|
30
|
+
async info() {
|
|
31
|
+
const data = await this.http.get("/info");
|
|
32
|
+
return parseVaultInfo(data);
|
|
33
|
+
}
|
|
34
|
+
// ------------------------------------------------------------------
|
|
35
|
+
// Keys (read-only via API key)
|
|
36
|
+
// ------------------------------------------------------------------
|
|
37
|
+
/**
|
|
38
|
+
* List vault keys (metadata only — no wrapped key material).
|
|
39
|
+
*
|
|
40
|
+
* @param options.keyType - Optional filter: `"primary"` or `"recovery"`.
|
|
41
|
+
*/
|
|
42
|
+
async listKeys(options = {}) {
|
|
43
|
+
const params = {};
|
|
44
|
+
if (options.keyType !== undefined)
|
|
45
|
+
params["type"] = options.keyType;
|
|
46
|
+
const data = await this.http.get("/keys", params);
|
|
47
|
+
return data.map(parseVaultKey);
|
|
48
|
+
}
|
|
49
|
+
// ------------------------------------------------------------------
|
|
50
|
+
// Secrets (metadata-only operations)
|
|
51
|
+
// ------------------------------------------------------------------
|
|
52
|
+
/**
|
|
53
|
+
* List vault secrets (metadata only, no encrypted payload).
|
|
54
|
+
*
|
|
55
|
+
* @param options.secretType - Optional filter: `"login"`, `"ssh_key"`,
|
|
56
|
+
* `"api_key"`, or `"other"`.
|
|
57
|
+
*/
|
|
58
|
+
async listSecrets(options = {}) {
|
|
59
|
+
const params = {};
|
|
60
|
+
if (options.secretType !== undefined)
|
|
61
|
+
params["secret_type"] = options.secretType;
|
|
62
|
+
const data = await this.http.get("/secrets", params);
|
|
63
|
+
return data.map(parseVaultSecret);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Delete a vault secret.
|
|
67
|
+
*
|
|
68
|
+
* @param secretId - UUID of the secret to delete.
|
|
69
|
+
*/
|
|
70
|
+
async deleteSecret(secretId) {
|
|
71
|
+
await this.http.delete(`/secrets/${secretId}`);
|
|
72
|
+
}
|
|
73
|
+
// ------------------------------------------------------------------
|
|
74
|
+
// Access rules
|
|
75
|
+
// ------------------------------------------------------------------
|
|
76
|
+
/**
|
|
77
|
+
* List identity access rules for a vault secret.
|
|
78
|
+
*
|
|
79
|
+
* @param secretId - UUID of the secret.
|
|
80
|
+
*/
|
|
81
|
+
async listAccessRules(secretId) {
|
|
82
|
+
const data = await this.http.get(`/secrets/${secretId}/access`);
|
|
83
|
+
return data.map(parseAccessRule);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Grant an identity access to a vault secret.
|
|
87
|
+
*
|
|
88
|
+
* @param secretId - UUID of the secret.
|
|
89
|
+
* @param identityId - UUID of the identity to grant access to.
|
|
90
|
+
*/
|
|
91
|
+
async grantAccess(secretId, identityId) {
|
|
92
|
+
const data = await this.http.post(`/secrets/${secretId}/access`, { identity_id: identityId });
|
|
93
|
+
return parseAccessRule(data);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Revoke an identity's access to a vault secret.
|
|
97
|
+
*
|
|
98
|
+
* @param secretId - UUID of the secret.
|
|
99
|
+
* @param identityId - UUID of the identity to revoke access from.
|
|
100
|
+
*/
|
|
101
|
+
async revokeAccess(secretId, identityId) {
|
|
102
|
+
await this.http.delete(`/secrets/${secretId}/access/${identityId}`);
|
|
103
|
+
}
|
|
104
|
+
// ------------------------------------------------------------------
|
|
105
|
+
// Unlock
|
|
106
|
+
// ------------------------------------------------------------------
|
|
107
|
+
/**
|
|
108
|
+
* Unlock the vault with a vault key.
|
|
109
|
+
*
|
|
110
|
+
* Derives the encryption key from the provided vault key, fetches
|
|
111
|
+
* and decrypts all vault secrets.
|
|
112
|
+
*
|
|
113
|
+
* @param vaultKey - Vault key or recovery code.
|
|
114
|
+
* @param options.identityId - Optional agent identity UUID. When
|
|
115
|
+
* provided, only secrets that this identity has been granted access
|
|
116
|
+
* to are included in {@link UnlockedVault.secrets}.
|
|
117
|
+
* @returns {@link UnlockedVault} with decrypted secrets and methods for
|
|
118
|
+
* secret CRUD.
|
|
119
|
+
* @throws If the vault key is incorrect or the vault key has been deleted.
|
|
120
|
+
*/
|
|
121
|
+
async unlock(vaultKey, options = {}) {
|
|
122
|
+
// Step 1: get org_id for salt derivation
|
|
123
|
+
const vaultInfo = await this.info();
|
|
124
|
+
const salt = deriveSalt(vaultInfo.organizationId);
|
|
125
|
+
// Step 2: derive master key → auth hash
|
|
126
|
+
const masterKey = await deriveMasterKey(vaultKey, salt);
|
|
127
|
+
const authHash = computeAuthHash(masterKey);
|
|
128
|
+
// Step 3: fetch wrapped key + encrypted secrets
|
|
129
|
+
// We always send auth_hash, so the server returns the singular
|
|
130
|
+
// wrapped_org_encryption_key for the matching vault key. The
|
|
131
|
+
// plural wrapped_org_encryption_keys is only returned when
|
|
132
|
+
// auth_hash is omitted (a recovery flow this SDK does not use,
|
|
133
|
+
// since recovery codes are derived the same way as vault keys).
|
|
134
|
+
const data = await this.http.get("/unlock", {
|
|
135
|
+
auth_hash: authHash,
|
|
136
|
+
});
|
|
137
|
+
const wrapped = data.wrapped_org_encryption_key;
|
|
138
|
+
if (!wrapped) {
|
|
139
|
+
throw new Error("No vault key matched. " +
|
|
140
|
+
"Check that the vault key is correct and has not been deleted.");
|
|
141
|
+
}
|
|
142
|
+
// Step 4: unwrap the org encryption key.
|
|
143
|
+
// The wrapped key was encrypted with the vault key UUID as AAD.
|
|
144
|
+
// Fetch all key IDs and try each as AAD until one works.
|
|
145
|
+
const keysData = await this.http.get("/keys");
|
|
146
|
+
const allKeyIds = keysData
|
|
147
|
+
.filter((k) => k.status === "active")
|
|
148
|
+
.map((k) => k.id);
|
|
149
|
+
let orgKey = null;
|
|
150
|
+
for (const keyId of allKeyIds) {
|
|
151
|
+
try {
|
|
152
|
+
orgKey = unwrapOrgKey(masterKey, wrapped, keyId);
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
catch {
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if (!orgKey) {
|
|
160
|
+
throw new Error("Failed to unwrap org encryption key. Check that the vault key is correct.");
|
|
161
|
+
}
|
|
162
|
+
// Step 5: decrypt all secrets from the unlock bundle
|
|
163
|
+
const decrypted = [];
|
|
164
|
+
for (const raw of data.encrypted_secrets ?? []) {
|
|
165
|
+
const detail = parseVaultSecretDetail(raw);
|
|
166
|
+
const payloadDict = decryptPayload(orgKey, detail.encryptedPayload, detail.id);
|
|
167
|
+
const payload = parsePayload(detail.secretType, payloadDict);
|
|
168
|
+
decrypted.push({
|
|
169
|
+
id: detail.id,
|
|
170
|
+
name: detail.name,
|
|
171
|
+
description: detail.description,
|
|
172
|
+
secretType: detail.secretType,
|
|
173
|
+
status: detail.status,
|
|
174
|
+
createdAt: detail.createdAt,
|
|
175
|
+
updatedAt: detail.updatedAt,
|
|
176
|
+
payload,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
// Always store the unfiltered vault so identity.getCredentials()
|
|
180
|
+
// has the full set to filter from, even when identityId is provided.
|
|
181
|
+
this._unlocked = new UnlockedVault(this.http, orgKey, [...decrypted]);
|
|
182
|
+
// Step 6 (optional): filter by identity access rules
|
|
183
|
+
if (options.identityId !== undefined) {
|
|
184
|
+
const idStr = options.identityId;
|
|
185
|
+
const filtered = [];
|
|
186
|
+
for (const secret of decrypted) {
|
|
187
|
+
const rules = await this.http.get(`/secrets/${secret.id}/access`);
|
|
188
|
+
if (rules.some((r) => r.identity_id === idStr)) {
|
|
189
|
+
filtered.push(secret);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
return new UnlockedVault(this.http, orgKey, filtered);
|
|
193
|
+
}
|
|
194
|
+
return this._unlocked;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* A vault unlocked with a valid vault key.
|
|
199
|
+
*
|
|
200
|
+
* Provides transparent encrypt/decrypt for secret CRUD operations.
|
|
201
|
+
*
|
|
202
|
+
* Obtain via {@link VaultResource.unlock}.
|
|
203
|
+
*/
|
|
204
|
+
export class UnlockedVault {
|
|
205
|
+
http;
|
|
206
|
+
orgKey;
|
|
207
|
+
secretsCache;
|
|
208
|
+
constructor(http, orgKey, secretsCache) {
|
|
209
|
+
this.http = http;
|
|
210
|
+
this.orgKey = orgKey;
|
|
211
|
+
this.secretsCache = secretsCache;
|
|
212
|
+
}
|
|
213
|
+
/** All vault secrets decrypted from the unlock response. */
|
|
214
|
+
get secrets() {
|
|
215
|
+
return [...this.secretsCache];
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Re-fetch, decrypt, and update a single secret in the cache.
|
|
219
|
+
*
|
|
220
|
+
* Best-effort — if the re-fetch fails the cache is left unchanged.
|
|
221
|
+
*/
|
|
222
|
+
async refreshCachedSecret(secretId) {
|
|
223
|
+
try {
|
|
224
|
+
const updated = await this.getSecret(secretId);
|
|
225
|
+
this.secretsCache = this.secretsCache.map((s) => s.id === secretId ? updated : s);
|
|
226
|
+
}
|
|
227
|
+
catch {
|
|
228
|
+
// Cache refresh is best-effort.
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
// ------------------------------------------------------------------
|
|
232
|
+
// Encrypted CRUD
|
|
233
|
+
// ------------------------------------------------------------------
|
|
234
|
+
/**
|
|
235
|
+
* Fetch and decrypt a single vault secret.
|
|
236
|
+
*
|
|
237
|
+
* @param secretId - UUID of the secret.
|
|
238
|
+
*/
|
|
239
|
+
async getSecret(secretId) {
|
|
240
|
+
const data = await this.http.get(`/secrets/${secretId}`);
|
|
241
|
+
const detail = parseVaultSecretDetail(data);
|
|
242
|
+
const payloadDict = decryptPayload(this.orgKey, detail.encryptedPayload, detail.id);
|
|
243
|
+
const payload = parsePayload(detail.secretType, payloadDict);
|
|
244
|
+
return {
|
|
245
|
+
id: detail.id,
|
|
246
|
+
name: detail.name,
|
|
247
|
+
description: detail.description,
|
|
248
|
+
secretType: detail.secretType,
|
|
249
|
+
status: detail.status,
|
|
250
|
+
createdAt: detail.createdAt,
|
|
251
|
+
updatedAt: detail.updatedAt,
|
|
252
|
+
payload,
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Encrypt and store a new secret.
|
|
257
|
+
*
|
|
258
|
+
* The `secretType` is inferred from the payload shape.
|
|
259
|
+
*
|
|
260
|
+
* @param options.name - Display name (max 255 characters).
|
|
261
|
+
* @param options.description - Optional description.
|
|
262
|
+
* @param options.payload - One of {@link LoginPayload}, {@link SSHKeyPayload},
|
|
263
|
+
* {@link APIKeyPayload}, or {@link OtherPayload}.
|
|
264
|
+
*/
|
|
265
|
+
async createSecret(options) {
|
|
266
|
+
const secretType = inferSecretType(options.payload);
|
|
267
|
+
const serialized = serializePayload(secretType, options.payload);
|
|
268
|
+
// Generate the UUID client-side so we can use it as AAD for
|
|
269
|
+
// encryption in the same request.
|
|
270
|
+
const secretId = crypto.randomUUID();
|
|
271
|
+
const encrypted = encryptPayload(this.orgKey, serialized, secretId);
|
|
272
|
+
const body = {
|
|
273
|
+
id: secretId,
|
|
274
|
+
name: options.name,
|
|
275
|
+
secret_type: secretType,
|
|
276
|
+
encrypted_payload: encrypted,
|
|
277
|
+
};
|
|
278
|
+
if (options.description !== undefined)
|
|
279
|
+
body["description"] = options.description;
|
|
280
|
+
const data = await this.http.post("/secrets", body);
|
|
281
|
+
const result = parseVaultSecret(data);
|
|
282
|
+
// Append the new secret to the cache so it's immediately visible.
|
|
283
|
+
try {
|
|
284
|
+
const decrypted = await this.getSecret(result.id);
|
|
285
|
+
this.secretsCache.push(decrypted);
|
|
286
|
+
}
|
|
287
|
+
catch {
|
|
288
|
+
// best-effort
|
|
289
|
+
}
|
|
290
|
+
return result;
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Update a vault secret's name, description, and/or encrypted payload.
|
|
294
|
+
*
|
|
295
|
+
* Only provided fields are sent to the server.
|
|
296
|
+
*
|
|
297
|
+
* **Note:** The `secretType` is immutable after creation. If a payload
|
|
298
|
+
* is provided it must be the **same type** as the original (e.g. update
|
|
299
|
+
* a `login` secret with a new {@link LoginPayload}). To change the
|
|
300
|
+
* type, delete the secret and create a new one.
|
|
301
|
+
*
|
|
302
|
+
* @param secretId - UUID of the secret to update.
|
|
303
|
+
* @param options.name - New display name.
|
|
304
|
+
* @param options.description - New description.
|
|
305
|
+
* @param options.payload - New payload of the **same type** as the
|
|
306
|
+
* original (will be re-encrypted).
|
|
307
|
+
*/
|
|
308
|
+
async updateSecret(secretId, options) {
|
|
309
|
+
const body = {};
|
|
310
|
+
if ("name" in options)
|
|
311
|
+
body["name"] = options.name;
|
|
312
|
+
if ("description" in options)
|
|
313
|
+
body["description"] = options.description;
|
|
314
|
+
if (options.payload !== undefined) {
|
|
315
|
+
// Enforce secret_type immutability — the server treats the
|
|
316
|
+
// payload as opaque ciphertext and cannot check this itself.
|
|
317
|
+
const current = parseVaultSecret(await this.http.get(`/secrets/${secretId}`));
|
|
318
|
+
const newType = inferSecretType(options.payload);
|
|
319
|
+
if (newType !== current.secretType) {
|
|
320
|
+
throw new TypeError(`Cannot update a '${current.secretType}' secret with a '${newType}' payload. Delete and recreate instead.`);
|
|
321
|
+
}
|
|
322
|
+
const serialized = serializePayload(newType, options.payload);
|
|
323
|
+
body["encrypted_payload"] = encryptPayload(this.orgKey, serialized, secretId);
|
|
324
|
+
}
|
|
325
|
+
const data = await this.http.patch(`/secrets/${secretId}`, body);
|
|
326
|
+
// Refresh the cache so subsequent reads are consistent.
|
|
327
|
+
await this.refreshCachedSecret(secretId);
|
|
328
|
+
return parseVaultSecret(data);
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Delete a vault secret.
|
|
332
|
+
*
|
|
333
|
+
* @param secretId - UUID of the secret to delete.
|
|
334
|
+
*/
|
|
335
|
+
async deleteSecret(secretId) {
|
|
336
|
+
await this.http.delete(`/secrets/${secretId}`);
|
|
337
|
+
this.secretsCache = this.secretsCache.filter((s) => s.id !== secretId);
|
|
338
|
+
}
|
|
339
|
+
// ------------------------------------------------------------------
|
|
340
|
+
// TOTP helpers
|
|
341
|
+
// ------------------------------------------------------------------
|
|
342
|
+
/**
|
|
343
|
+
* Add or replace the TOTP configuration on a login secret.
|
|
344
|
+
*
|
|
345
|
+
* @param secretId - UUID of the login secret.
|
|
346
|
+
* @param totp - A {@link TOTPConfig} object or an `otpauth://totp/...` URI string.
|
|
347
|
+
* @returns Updated {@link VaultSecret} metadata.
|
|
348
|
+
* @throws TypeError if the secret is not a login type.
|
|
349
|
+
* @throws Error if a URI string is invalid or not TOTP.
|
|
350
|
+
*/
|
|
351
|
+
async setTotp(secretId, totp) {
|
|
352
|
+
const config = typeof totp === "string" ? parseTotpUri(totp) : totp;
|
|
353
|
+
const secret = await this.getSecret(secretId);
|
|
354
|
+
if (secret.secretType !== VaultSecretType.LOGIN) {
|
|
355
|
+
throw new TypeError(`Cannot set TOTP on a '${secret.secretType}' secret — only login secrets support TOTP`);
|
|
356
|
+
}
|
|
357
|
+
const payload = { ...secret.payload, totp: config };
|
|
358
|
+
return this.updateSecret(secretId, { payload });
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Remove TOTP configuration from a login secret.
|
|
362
|
+
*
|
|
363
|
+
* @param secretId - UUID of the login secret.
|
|
364
|
+
* @returns Updated {@link VaultSecret} metadata.
|
|
365
|
+
* @throws TypeError if the secret is not a login type.
|
|
366
|
+
*/
|
|
367
|
+
async removeTotp(secretId) {
|
|
368
|
+
const secret = await this.getSecret(secretId);
|
|
369
|
+
if (secret.secretType !== VaultSecretType.LOGIN) {
|
|
370
|
+
throw new TypeError(`Cannot remove TOTP from a '${secret.secretType}' secret — only login secrets support TOTP`);
|
|
371
|
+
}
|
|
372
|
+
const loginPayload = secret.payload;
|
|
373
|
+
const { totp: _, ...rest } = loginPayload;
|
|
374
|
+
return this.updateSecret(secretId, { payload: rest });
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Generate the current TOTP code for a login secret.
|
|
378
|
+
*
|
|
379
|
+
* @param secretId - UUID of the login secret.
|
|
380
|
+
* @returns A {@link TOTPCode}.
|
|
381
|
+
* @throws TypeError if the secret is not a login type.
|
|
382
|
+
* @throws Error if the login has no TOTP configured.
|
|
383
|
+
*/
|
|
384
|
+
async getTotpCode(secretId) {
|
|
385
|
+
const secret = await this.getSecret(secretId);
|
|
386
|
+
if (secret.secretType !== VaultSecretType.LOGIN) {
|
|
387
|
+
throw new TypeError(`Cannot generate TOTP for a '${secret.secretType}' secret — only login secrets support TOTP`);
|
|
388
|
+
}
|
|
389
|
+
const loginPayload = secret.payload;
|
|
390
|
+
if (!loginPayload.totp) {
|
|
391
|
+
throw new Error(`Login secret '${secretId}' has no TOTP configured`);
|
|
392
|
+
}
|
|
393
|
+
return generateTotp(loginPayload.totp);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
//# sourceMappingURL=vault.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vault.js","sourceRoot":"","sources":["../../../src/vault/resources/vault.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,EACL,eAAe,EACf,cAAc,EACd,eAAe,EACf,UAAU,EACV,cAAc,EACd,YAAY,GACb,MAAM,cAAc,CAAC;AAUtB,OAAO,EACL,eAAe,EACf,eAAe,EACf,eAAe,EACf,YAAY,EACZ,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,sBAAsB,EACtB,gBAAgB,GACjB,MAAM,aAAa,CAAC;AAUrB;;;;;;GAMG;AACH,MAAM,OAAO,aAAa;IACxB,gBAAgB;IACP,IAAI,CAAgB;IAE7B,gBAAgB;IAChB,SAAS,GAAyB,IAAI,CAAC;IAEvC,gBAAgB;IAChB,YAAY,IAAmB;QAC7B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED,qEAAqE;IACrE,iBAAiB;IACjB,qEAAqE;IAErE,wDAAwD;IACxD,KAAK,CAAC,IAAI;QACR,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAe,OAAO,CAAC,CAAC;QACxD,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IAED,qEAAqE;IACrE,+BAA+B;IAC/B,qEAAqE;IAErE;;;;OAIG;IACH,KAAK,CAAC,QAAQ,CAAC,UAAgC,EAAE;QAC/C,MAAM,MAAM,GAA2B,EAAE,CAAC;QAC1C,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS;YAAE,MAAM,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;QACpE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAgB,OAAO,EAAE,MAAM,CAAC,CAAC;QACjE,OAAO,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IACjC,CAAC;IAED,qEAAqE;IACrE,qCAAqC;IACrC,qEAAqE;IAErE;;;;;OAKG;IACH,KAAK,CAAC,WAAW,CAAC,UAAmC,EAAE;QACrD,MAAM,MAAM,GAA2B,EAAE,CAAC;QAC1C,IAAI,OAAO,CAAC,UAAU,KAAK,SAAS;YAAE,MAAM,CAAC,aAAa,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC;QACjF,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAmB,UAAU,EAAE,MAAM,CAAC,CAAC;QACvE,OAAO,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IACpC,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,YAAY,CAAC,QAAgB;QACjC,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,QAAQ,EAAE,CAAC,CAAC;IACjD,CAAC;IAED,qEAAqE;IACrE,eAAe;IACf,qEAAqE;IAErE;;;;OAIG;IACH,KAAK,CAAC,eAAe,CAAC,QAAgB;QACpC,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAC9B,YAAY,QAAQ,SAAS,CAC9B,CAAC;QACF,OAAO,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IACnC,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,WAAW,CAAC,QAAgB,EAAE,UAAkB;QACpD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAC/B,YAAY,QAAQ,SAAS,EAC7B,EAAE,WAAW,EAAE,UAAU,EAAE,CAC5B,CAAC;QACF,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,YAAY,CAAC,QAAgB,EAAE,UAAkB;QACrD,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,QAAQ,WAAW,UAAU,EAAE,CAAC,CAAC;IACtE,CAAC;IAED,qEAAqE;IACrE,SAAS;IACT,qEAAqE;IAErE;;;;;;;;;;;;;OAaG;IACH,KAAK,CAAC,MAAM,CACV,QAAgB,EAChB,UAAmC,EAAE;QAErC,yCAAyC;QACzC,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QACpC,MAAM,IAAI,GAAG,UAAU,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;QAElD,wCAAwC;QACxC,MAAM,SAAS,GAAG,MAAM,eAAe,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QACxD,MAAM,QAAQ,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;QAE5C,gDAAgD;QAChD,+DAA+D;QAC/D,8DAA8D;QAC9D,2DAA2D;QAC3D,+DAA+D;QAC/D,gEAAgE;QAChE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAyB,SAAS,EAAE;YAClE,SAAS,EAAE,QAAQ;SACpB,CAAC,CAAC;QAEH,MAAM,OAAO,GAAG,IAAI,CAAC,0BAA0B,CAAC;QAChD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CACb,wBAAwB;gBACtB,+DAA+D,CAClE,CAAC;QACJ,CAAC;QAED,yCAAyC;QACzC,gEAAgE;QAChE,yDAAyD;QACzD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAgB,OAAO,CAAC,CAAC;QAC7D,MAAM,SAAS,GAAG,QAAQ;aACvB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC;aACpC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAEpB,IAAI,MAAM,GAAsB,IAAI,CAAC;QACrC,KAAK,MAAM,KAAK,IAAI,SAAS,EAAE,CAAC;YAC9B,IAAI,CAAC;gBACH,MAAM,GAAG,YAAY,CAAC,SAAS,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;gBACjD,MAAM;YACR,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;QACH,CAAC;QACD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CACb,2EAA2E,CAC5E,CAAC;QACJ,CAAC;QAED,qDAAqD;QACrD,MAAM,SAAS,GAA2B,EAAE,CAAC;QAC7C,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,iBAAiB,IAAI,EAAE,EAAE,CAAC;YAC/C,MAAM,MAAM,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC;YAC3C,MAAM,WAAW,GAAG,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;YAC/E,MAAM,OAAO,GAAG,YAAY,CAC1B,MAAM,CAAC,UAAU,EACjB,WAAsC,CACvC,CAAC;YACF,SAAS,CAAC,IAAI,CAAC;gBACb,EAAE,EAAE,MAAM,CAAC,EAAE;gBACb,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,WAAW,EAAE,MAAM,CAAC,WAAW;gBAC/B,UAAU,EAAE,MAAM,CAAC,UAAU;gBAC7B,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,SAAS,EAAE,MAAM,CAAC,SAAS;gBAC3B,SAAS,EAAE,MAAM,CAAC,SAAS;gBAC3B,OAAO;aACR,CAAC,CAAC;QACL,CAAC;QAED,iEAAiE;QACjE,qEAAqE;QACrE,IAAI,CAAC,SAAS,GAAG,IAAI,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC;QAEtE,qDAAqD;QACrD,IAAI,OAAO,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YACrC,MAAM,KAAK,GAAG,OAAO,CAAC,UAAU,CAAC;YACjC,MAAM,QAAQ,GAA2B,EAAE,CAAC;YAC5C,KAAK,MAAM,MAAM,IAAI,SAAS,EAAE,CAAC;gBAC/B,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAE/B,YAAY,MAAM,CAAC,EAAE,SAAS,CAAC,CAAC;gBAClC,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,KAAK,KAAK,CAAC,EAAE,CAAC;oBAC/C,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBACxB,CAAC;YACH,CAAC;YACD,OAAO,IAAI,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;QACxD,CAAC;QAED,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;CACF;AAED;;;;;;GAMG;AACH,MAAM,OAAO,aAAa;IACP,IAAI,CAAgB;IACpB,MAAM,CAAa;IAC5B,YAAY,CAAyB;IAE7C,YACE,IAAmB,EACnB,MAAkB,EAClB,YAAoC;QAEpC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;IACnC,CAAC;IAED,4DAA4D;IAC5D,IAAI,OAAO;QACT,OAAO,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC;IAChC,CAAC;IAED;;;;OAIG;IACK,KAAK,CAAC,mBAAmB,CAAC,QAAgB;QAChD,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;YAC/C,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAC9C,CAAC,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAChC,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,gCAAgC;QAClC,CAAC;IACH,CAAC;IAED,qEAAqE;IACrE,iBAAiB;IACjB,qEAAqE;IAErE;;;;OAIG;IACH,KAAK,CAAC,SAAS,CAAC,QAAgB;QAC9B,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAC9B,YAAY,QAAQ,EAAE,CACvB,CAAC;QACF,MAAM,MAAM,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAC;QAC5C,MAAM,WAAW,GAAG,cAAc,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;QACpF,MAAM,OAAO,GAAG,YAAY,CAC1B,MAAM,CAAC,UAAU,EACjB,WAAsC,CACvC,CAAC;QACF,OAAO;YACL,EAAE,EAAE,MAAM,CAAC,EAAE;YACb,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,OAAO;SACR,CAAC;IACJ,CAAC;IAED;;;;;;;;;OASG;IACH,KAAK,CAAC,YAAY,CAAC,OAIlB;QACC,MAAM,UAAU,GAAG,eAAe,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACpD,MAAM,UAAU,GAAG,gBAAgB,CAAC,UAAU,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;QACjE,4DAA4D;QAC5D,kCAAkC;QAClC,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;QACrC,MAAM,SAAS,GAAG,cAAc,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;QACpE,MAAM,IAAI,GAA4B;YACpC,EAAE,EAAE,QAAQ;YACZ,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,WAAW,EAAE,UAAU;YACvB,iBAAiB,EAAE,SAAS;SAC7B,CAAC;QACF,IAAI,OAAO,CAAC,WAAW,KAAK,SAAS;YAAE,IAAI,CAAC,aAAa,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC;QACjF,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAiB,UAAU,EAAE,IAAI,CAAC,CAAC;QACpE,MAAM,MAAM,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACtC,kEAAkE;QAClE,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAClD,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACpC,CAAC;QAAC,MAAM,CAAC;YACP,cAAc;QAChB,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;;;;;;;;;;;;;OAeG;IACH,KAAK,CAAC,YAAY,CAChB,QAAgB,EAChB,OAIC;QAED,MAAM,IAAI,GAA4B,EAAE,CAAC;QACzC,IAAI,MAAM,IAAI,OAAO;YAAE,IAAI,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;QACnD,IAAI,aAAa,IAAI,OAAO;YAAE,IAAI,CAAC,aAAa,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC;QACxE,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAClC,2DAA2D;YAC3D,6DAA6D;YAC7D,MAAM,OAAO,GAAG,gBAAgB,CAC9B,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAiB,YAAY,QAAQ,EAAE,CAAC,CAC5D,CAAC;YACF,MAAM,OAAO,GAAG,eAAe,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YACjD,IAAI,OAAO,KAAK,OAAO,CAAC,UAAU,EAAE,CAAC;gBACnC,MAAM,IAAI,SAAS,CACjB,oBAAoB,OAAO,CAAC,UAAU,oBAAoB,OAAO,yCAAyC,CAC3G,CAAC;YACJ,CAAC;YACD,MAAM,UAAU,GAAG,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;YAC9D,IAAI,CAAC,mBAAmB,CAAC,GAAG,cAAc,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;QAChF,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAChC,YAAY,QAAQ,EAAE,EACtB,IAAI,CACL,CAAC;QACF,wDAAwD;QACxD,MAAM,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC;QACzC,OAAO,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAChC,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,YAAY,CAAC,QAAgB;QACjC,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,QAAQ,EAAE,CAAC,CAAC;QAC/C,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC;IACzE,CAAC;IAED,qEAAqE;IACrE,eAAe;IACf,qEAAqE;IAErE;;;;;;;;OAQG;IACH,KAAK,CAAC,OAAO,CACX,QAAgB,EAChB,IAAyB;QAEzB,MAAM,MAAM,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACpE,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QAC9C,IAAI,MAAM,CAAC,UAAU,KAAK,eAAe,CAAC,KAAK,EAAE,CAAC;YAChD,MAAM,IAAI,SAAS,CACjB,yBAAyB,MAAM,CAAC,UAAU,4CAA4C,CACvF,CAAC;QACJ,CAAC;QACD,MAAM,OAAO,GAAG,EAAE,GAAG,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QACpD,OAAO,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;IAClD,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,UAAU,CAAC,QAAgB;QAC/B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QAC9C,IAAI,MAAM,CAAC,UAAU,KAAK,eAAe,CAAC,KAAK,EAAE,CAAC;YAChD,MAAM,IAAI,SAAS,CACjB,8BAA8B,MAAM,CAAC,UAAU,4CAA4C,CAC5F,CAAC;QACJ,CAAC;QACD,MAAM,YAAY,GAAG,MAAM,CAAC,OAA6C,CAAC;QAC1E,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,GAAG,YAAY,CAAC;QAC1C,OAAO,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IACxD,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,WAAW,CAAC,QAAgB;QAChC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QAC9C,IAAI,MAAM,CAAC,UAAU,KAAK,eAAe,CAAC,KAAK,EAAE,CAAC;YAChD,MAAM,IAAI,SAAS,CACjB,+BAA+B,MAAM,CAAC,UAAU,4CAA4C,CAC7F,CAAC;QACJ,CAAC;QACD,MAAM,YAAY,GAAG,MAAM,CAAC,OAA6C,CAAC;QAC1E,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,iBAAiB,QAAQ,0BAA0B,CAAC,CAAC;QACvE,CAAC;QACD,OAAO,YAAY,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;IACzC,CAAC;CACF"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* inkbox-vault/totp.ts
|
|
3
|
+
*
|
|
4
|
+
* Client-side TOTP (RFC 6238) implementation.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Hash algorithm for TOTP code generation.
|
|
8
|
+
*
|
|
9
|
+
* Values are lowercase to match `otpauth://` URI convention.
|
|
10
|
+
*/
|
|
11
|
+
export declare const TOTPAlgorithm: {
|
|
12
|
+
readonly SHA1: "sha1";
|
|
13
|
+
readonly SHA256: "sha256";
|
|
14
|
+
readonly SHA512: "sha512";
|
|
15
|
+
};
|
|
16
|
+
export type TOTPAlgorithm = (typeof TOTPAlgorithm)[keyof typeof TOTPAlgorithm];
|
|
17
|
+
/** A generated TOTP code with timing metadata. */
|
|
18
|
+
export interface TOTPCode {
|
|
19
|
+
/** The OTP code string (e.g. `"482901"`). */
|
|
20
|
+
code: string;
|
|
21
|
+
/** Unix timestamp when this code became valid. */
|
|
22
|
+
periodStart: number;
|
|
23
|
+
/** Unix timestamp when this code expires. */
|
|
24
|
+
periodEnd: number;
|
|
25
|
+
/** Seconds left until expiry. */
|
|
26
|
+
secondsRemaining: number;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* TOTP configuration stored inside a {@link LoginPayload}.
|
|
30
|
+
*/
|
|
31
|
+
export interface TOTPConfig {
|
|
32
|
+
/** Base32-encoded shared secret. */
|
|
33
|
+
secret: string;
|
|
34
|
+
/** Hash algorithm (default `"sha1"`). */
|
|
35
|
+
algorithm?: TOTPAlgorithm;
|
|
36
|
+
/** Number of digits in the OTP code (6 or 8, default 6). */
|
|
37
|
+
digits?: number;
|
|
38
|
+
/** Time step in seconds (30 or 60, default 30). */
|
|
39
|
+
period?: number;
|
|
40
|
+
/** Optional issuer name (e.g. `"GitHub"`). */
|
|
41
|
+
issuer?: string;
|
|
42
|
+
/** Optional account identifier (e.g. `"user@example.com"`). */
|
|
43
|
+
accountName?: string;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Validate a TOTPConfig's fields.
|
|
47
|
+
*
|
|
48
|
+
* @throws Error if any field is invalid.
|
|
49
|
+
*/
|
|
50
|
+
export declare function validateTotpConfig(config: TOTPConfig): void;
|
|
51
|
+
/**
|
|
52
|
+
* Generate the current TOTP code per RFC 6238.
|
|
53
|
+
*
|
|
54
|
+
* @param config - TOTP configuration with the shared secret and parameters.
|
|
55
|
+
* @returns A {@link TOTPCode} with the code and timing metadata.
|
|
56
|
+
*/
|
|
57
|
+
export declare function generateTotp(config: TOTPConfig): TOTPCode;
|
|
58
|
+
/**
|
|
59
|
+
* Parse an `otpauth://totp/...` URI into a {@link TOTPConfig}.
|
|
60
|
+
*
|
|
61
|
+
* Supports the Google Authenticator Key URI format.
|
|
62
|
+
* Rejects HOTP URIs with an error.
|
|
63
|
+
*
|
|
64
|
+
* @param uri - The full `otpauth://` URI string.
|
|
65
|
+
* @returns A validated {@link TOTPConfig}.
|
|
66
|
+
* @throws Error on invalid scheme, HOTP type, missing secret, or invalid parameters.
|
|
67
|
+
*/
|
|
68
|
+
export declare function parseTotpUri(uri: string): TOTPConfig;
|
|
69
|
+
/** Serialize a TOTPConfig to the snake_case wire format. @internal */
|
|
70
|
+
export declare function serializeTotpConfig(config: TOTPConfig): Record<string, unknown>;
|
|
71
|
+
/** Parse a TOTPConfig from the snake_case wire format. @internal */
|
|
72
|
+
export declare function parseTotpConfig(raw: Record<string, unknown>): TOTPConfig;
|
|
73
|
+
//# sourceMappingURL=totp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"totp.d.ts","sourceRoot":"","sources":["../../src/vault/totp.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH;;;;GAIG;AACH,eAAO,MAAM,aAAa;;;;CAIhB,CAAC;AACX,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,OAAO,aAAa,CAAC,CAAC;AAI/E,kDAAkD;AAClD,MAAM,WAAW,QAAQ;IACvB,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,kDAAkD;IAClD,WAAW,EAAE,MAAM,CAAC;IACpB,6CAA6C;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,iCAAiC;IACjC,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,oCAAoC;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,yCAAyC;IACzC,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,4DAA4D;IAC5D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8CAA8C;IAC9C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,+DAA+D;IAC/D,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAQD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAiB3D;AA+DD;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,QAAQ,CAgBzD;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAsFpD;AAID,sEAAsE;AACtE,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,UAAU,GACjB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAUzB;AAED,oEAAoE;AACpE,wBAAgB,eAAe,CAC7B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC3B,UAAU,CAWZ"}
|