@witnium-tech/witniumchain 0.10.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -177,9 +177,10 @@ var WitniumchainClient = class {
177
177
  * the contract with the caller's client-generated `ownerPublicKey` +
178
178
  * `initialSigningPublicKey`. Witnium never sees the private bytes.
179
179
  *
180
- * Returns `{ orgId, userId, contractAddress, contractVersion,
181
- * emailVerifyToken }`. The verify token is also emailed; it's echoed here
182
- * for UIs that prefer to render the verify link themselves.
180
+ * Returns `{ orgId, userId, contractAddress, contractVersion }`. The
181
+ * email-verify link is mailed to `adminEmail` and never returned, so there
182
+ * is nothing to render. If the mail cannot be sent, nothing is created and
183
+ * the call fails with a 502; retry it.
183
184
  */
184
185
  createOrg(body) {
185
186
  return this.req("POST", "/v1/orgs", { auth: "Public", body });
@@ -237,11 +238,36 @@ var WitniumchainClient = class {
237
238
  query: { token }
238
239
  });
239
240
  }
241
+ /**
242
+ * Password login. Check `status`: `'authenticated'` means the session
243
+ * cookie is set. `'mfa_required'` means NO session exists yet: the server
244
+ * set a short-lived challenge cookie, and {@link loginMfa} must follow with
245
+ * the user's TOTP or recovery code.
246
+ */
240
247
  login(body) {
241
248
  return this.req("POST", "/v1/auth/login", { auth: "Public", body });
242
249
  }
243
- logout() {
244
- return this.req("POST", "/v1/auth/logout", { auth: "Public" });
250
+ /**
251
+ * Second step of an MFA login, after `login()` returned `'mfa_required'`.
252
+ * Relies on the challenge cookie from that call (`credentials: 'include'`).
253
+ * 401 `mfa_code_invalid`: wrong or reused code, the user may retry.
254
+ * 401 `mfa_challenge_invalid`: expired or used up, start again at `login()`.
255
+ * 429 `mfa_rate_limited`: the body carries `retryAfterSeconds`.
256
+ */
257
+ loginMfa(body) {
258
+ return this.req("POST", "/v1/auth/login/mfa", { auth: "Public", body });
259
+ }
260
+ /**
261
+ * End the first-party session. The cached bearer token is dropped even when
262
+ * the request fails, so a logged-out tab never keeps the previous user's
263
+ * token.
264
+ */
265
+ async logout() {
266
+ try {
267
+ return await this.req("POST", "/v1/auth/logout", { auth: "Public" });
268
+ } finally {
269
+ this.signOut();
270
+ }
245
271
  }
246
272
  forgotPassword(body) {
247
273
  return this.req("POST", "/v1/auth/forgot-password", { auth: "Public", body });
@@ -275,43 +301,6 @@ var WitniumchainClient = class {
275
301
  return this.req("GET", "/v1/orgs/me/users", { auth: "OrgApiKey" });
276
302
  }
277
303
  // ────────────────────────────────────────────────────────────────────────
278
- // Admin (/v1/admin/organizations/*)
279
- // ────────────────────────────────────────────────────────────────────────
280
- createOrganization(body) {
281
- return this.req("POST", "/v1/admin/organizations", {
282
- auth: "AdminToken",
283
- body
284
- });
285
- }
286
- setOrgAccountType(id, body) {
287
- return this.req(
288
- "PATCH",
289
- `/v1/admin/organizations/${encodeURIComponent(id)}/account-type`,
290
- { auth: "AdminToken", body }
291
- );
292
- }
293
- verifyOrganization(id) {
294
- return this.req(
295
- "PATCH",
296
- `/v1/admin/organizations/${encodeURIComponent(id)}/verify`,
297
- { auth: "AdminToken" }
298
- );
299
- }
300
- rotateOrgApiKey(id) {
301
- return this.req(
302
- "POST",
303
- `/v1/admin/organizations/${encodeURIComponent(id)}/rotate-key`,
304
- { auth: "AdminToken" }
305
- );
306
- }
307
- adjustOrgCredits(id, body) {
308
- return this.req(
309
- "POST",
310
- `/v1/admin/organizations/${encodeURIComponent(id)}/adjust-credits`,
311
- { auth: "AdminToken", body }
312
- );
313
- }
314
- // ────────────────────────────────────────────────────────────────────────
315
304
  // Delegated keys (/v1/users/me/delegated-keys/*)
316
305
  // ────────────────────────────────────────────────────────────────────────
317
306
  listDelegatedKeys(query) {
@@ -511,20 +500,34 @@ var WitniumchainClient = class {
511
500
  auth: "SessionCookie"
512
501
  });
513
502
  }
514
- confirmTotp(body) {
515
- return this.req("POST", "/v1/account/mfa/totp/confirm", {
503
+ /**
504
+ * Confirming bumps the user's security epoch server-side, which ends every
505
+ * session-minted access token. A cached one is dropped so the next bearer
506
+ * call mints a fresh token.
507
+ */
508
+ async confirmTotp(body) {
509
+ const res = await this.req("POST", "/v1/account/mfa/totp/confirm", {
516
510
  auth: "SessionCookie",
517
511
  body
518
512
  });
513
+ if (this.accessTokenFromSession) {
514
+ this.accessToken = void 0;
515
+ this.accessTokenFromSession = false;
516
+ }
517
+ return res;
519
518
  }
520
- disableTotp() {
519
+ /** Step-up: 403 `mfa_step_up_failed` on a wrong proof, 429 `mfa_rate_limited`. */
520
+ disableTotp(body) {
521
521
  return this.req("DELETE", "/v1/account/mfa/totp", {
522
- auth: "SessionCookie"
522
+ auth: "SessionCookie",
523
+ body
523
524
  });
524
525
  }
525
- regenerateRecoveryCodes() {
526
+ /** Step-up: 403 `mfa_step_up_failed` on a wrong proof, 429 `mfa_rate_limited`. */
527
+ regenerateRecoveryCodes(body) {
526
528
  return this.req("POST", "/v1/account/mfa/recovery-codes/regenerate", {
527
- auth: "SessionCookie"
529
+ auth: "SessionCookie",
530
+ body
528
531
  });
529
532
  }
530
533
  // ────────────────────────────────────────────────────────────────────────
@@ -1201,15 +1204,6 @@ var WitniumchainClient = class {
1201
1204
  headers["authorization"] = `Bearer ${this.cfg.orgApiKey}`;
1202
1205
  return;
1203
1206
  }
1204
- case "AdminToken": {
1205
- if (!this.cfg.adminToken) {
1206
- throw new Error(
1207
- `WitniumchainClient: ${method} ${path} requires an admin token. Pass \`adminToken\` to the constructor.`
1208
- );
1209
- }
1210
- headers["authorization"] = `Bearer ${this.cfg.adminToken}`;
1211
- return;
1212
- }
1213
1207
  case "SignedRequest": {
1214
1208
  if (!this.cfg.signedRequest) {
1215
1209
  throw new Error(
@@ -1398,7 +1392,12 @@ var OrgMembers = class {
1398
1392
  list() {
1399
1393
  return this.client.listMembers();
1400
1394
  }
1401
- /** Invite a member by email (default role `member`). */
1395
+ /**
1396
+ * Invite a member by email (default role `member`). `inviteEmailSent` says
1397
+ * whether the invitation (with the verify link) was mailed; the token is
1398
+ * never returned. A 502 means the membership was recorded but the mail
1399
+ * failed; retry.
1400
+ */
1402
1401
  invite(body) {
1403
1402
  return this.client.inviteMember(body);
1404
1403
  }
@@ -1418,7 +1417,10 @@ var OrgMembers = class {
1418
1417
  remove(userId) {
1419
1418
  return this.client.removeMember(userId);
1420
1419
  }
1421
- /** Re-mint an email-verify token for a pending member. */
1420
+ /**
1421
+ * Re-send the invitation email to a pending member. Returns `{ email }`;
1422
+ * the fresh verify token is mailed, never returned.
1423
+ */
1422
1424
  resendInvite(userId) {
1423
1425
  return this.client.resendMemberInvite(userId);
1424
1426
  }
@@ -1442,14 +1444,18 @@ var MfaTotp = class {
1442
1444
  * Confirm enrolment with the first user-supplied code. Returns the 10
1443
1445
  * single-use recovery codes — show them to the user ONCE; the server never
1444
1446
  * returns them again. Throws `WitniumchainApiError` with status 400 when
1445
- * the code is invalid or the enrolment is already confirmed.
1447
+ * the code is invalid or the enrolment is already confirmed. Signs the
1448
+ * user out of every other device and connected app.
1446
1449
  */
1447
1450
  confirm(code) {
1448
1451
  return this.client.confirmTotp({ code });
1449
1452
  }
1450
- /** Disable TOTP, wiping both the secret and all recovery codes. */
1451
- disable() {
1452
- return this.client.disableTotp();
1453
+ /**
1454
+ * Disable TOTP, wiping both the secret and all recovery codes. Requires the
1455
+ * user's current code or a recovery code.
1456
+ */
1457
+ disable(proof) {
1458
+ return this.client.disableTotp(proof);
1453
1459
  }
1454
1460
  };
1455
1461
  var MfaRecoveryCodes = class {
@@ -1460,9 +1466,10 @@ var MfaRecoveryCodes = class {
1460
1466
  /**
1461
1467
  * Issue a fresh set of 10 recovery codes, invalidating the prior ones.
1462
1468
  * Same as `confirm` — codes are returned ONCE and never readable again.
1469
+ * Requires the user's current code or a recovery code.
1463
1470
  */
1464
- regenerate() {
1465
- return this.client.regenerateRecoveryCodes();
1471
+ regenerate(proof) {
1472
+ return this.client.regenerateRecoveryCodes(proof);
1466
1473
  }
1467
1474
  };
1468
1475
  function sleep(ms) {
@@ -1496,60 +1503,6 @@ async function sha256Hex(input) {
1496
1503
  return out;
1497
1504
  }
1498
1505
 
1499
- // src/admin-client.ts
1500
- var WitniumchainAdminClient = class {
1501
- inner;
1502
- constructor(config) {
1503
- if (!config.adminToken) {
1504
- throw new Error("WitniumchainAdminClient: adminToken is required");
1505
- }
1506
- this.inner = new WitniumchainClient({
1507
- baseUrl: config.baseUrl,
1508
- adminToken: config.adminToken,
1509
- timeout: config.timeout,
1510
- fetch: config.fetch
1511
- });
1512
- }
1513
- /**
1514
- * Mint a new organisation. The returned `apiKey` is shown ONCE — the server
1515
- * only retains its SHA-256 hash. Persist it before the response leaves
1516
- * scope; there is no recovery path.
1517
- *
1518
- * @param body Organisation seed: name, email, optional accountType and
1519
- * signup credit grant, optional skip-email-verification flag.
1520
- */
1521
- createOrganization(body) {
1522
- return this.inner.createOrganization(body);
1523
- }
1524
- /** Flip an org between `metered` (Stripe checkout + credit ledger) and `unlimited` (flat-fee). */
1525
- setAccountType(orgId, accountType) {
1526
- return this.inner.setOrgAccountType(orgId, { accountType });
1527
- }
1528
- /** Mark an org's email as verified. Prerequisite for the org to create users. */
1529
- verifyEmail(orgId) {
1530
- return this.inner.verifyOrganization(orgId);
1531
- }
1532
- /**
1533
- * Rotate the org's API key. The previous `wcorg_live_…` is invalidated and
1534
- * the new key is returned ONCE — same one-time-secret semantics as
1535
- * {@link createOrganization}.
1536
- */
1537
- rotateApiKey(orgId) {
1538
- return this.inner.rotateOrgApiKey(orgId);
1539
- }
1540
- /**
1541
- * Apply a signed credit delta to an org's ledger. Positive `delta` grants
1542
- * credits (goodwill, migration backfill); negative claws them back.
1543
- * Recorded as `reason: adjustment` with the supplied `note`.
1544
- *
1545
- * Use sparingly — this bypasses Stripe and should be auditable from the
1546
- * `note` alone.
1547
- */
1548
- adjustCredits(orgId, delta, note) {
1549
- return this.inner.adjustOrgCredits(orgId, { delta, note });
1550
- }
1551
- };
1552
-
1553
1506
  // src/chain-admin-client.ts
1554
1507
  var WitniumchainChainAdminClient = class {
1555
1508
  baseUrl;
@@ -1751,7 +1704,6 @@ exports.OrgMembers = OrgMembers;
1751
1704
  exports.OrgUsers = OrgUsers;
1752
1705
  exports.SigningKeys = SigningKeys;
1753
1706
  exports.Subscriptions = Subscriptions;
1754
- exports.WitniumchainAdminClient = WitniumchainAdminClient;
1755
1707
  exports.WitniumchainApiError = WitniumchainApiError;
1756
1708
  exports.WitniumchainChainAdminClient = WitniumchainChainAdminClient;
1757
1709
  exports.WitniumchainClient = WitniumchainClient;