@tinycloud/node-sdk 3.8.0-beta.10 → 3.8.0-beta.11

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.
@@ -1,6 +1,6 @@
1
1
  import { NamedKeyClient } from '@tinycloud/sdk-services/encryption/named-keys';
2
2
  export { DecryptManyResult, KeyCallOptions, KeyDescriptor, KeyEncryptOptions, NamedKeyClient, NamedKeyEnvelope, NamedKeyError, NamedKeyErrorCode, PublicKeyDescriptor, buildKeyAdminFacts, buildKeyDescribeFacts } from '@tinycloud/sdk-services/encryption/named-keys';
3
- import { T as TinyCloudNode } from './TinyCloudNode-Dy65bxqs.cjs';
3
+ import { T as TinyCloudNode } from './TinyCloudNode-BVDUdEcf.cjs';
4
4
  import '@tinycloud/sdk-core';
5
5
  import '@tinycloud/sdk-services/kv/replication';
6
6
  import '@tinycloud/sdk-services';
@@ -1,6 +1,6 @@
1
1
  import { NamedKeyClient } from '@tinycloud/sdk-services/encryption/named-keys';
2
2
  export { DecryptManyResult, KeyCallOptions, KeyDescriptor, KeyEncryptOptions, NamedKeyClient, NamedKeyEnvelope, NamedKeyError, NamedKeyErrorCode, PublicKeyDescriptor, buildKeyAdminFacts, buildKeyDescribeFacts } from '@tinycloud/sdk-services/encryption/named-keys';
3
- import { T as TinyCloudNode } from './TinyCloudNode-DnD-SH6t.js';
3
+ import { T as TinyCloudNode } from './TinyCloudNode-jMK_2Uj8.js';
4
4
  import '@tinycloud/sdk-core';
5
5
  import '@tinycloud/sdk-services/kv/replication';
6
6
  import '@tinycloud/sdk-services';
package/dist/index.cjs CHANGED
@@ -19019,6 +19019,7 @@ function cloneAbilitiesMap(actions) {
19019
19019
  var NodeUserAuthorization = class {
19020
19020
  constructor(config) {
19021
19021
  this.activeSessionKeyId = "default";
19022
+ this.preparedSessionCounter = 0;
19022
19023
  /** Incremented by resetSession; a sign-in started earlier publishes nothing. */
19023
19024
  this.sessionGeneration = 0;
19024
19025
  /**
@@ -20152,9 +20153,8 @@ var NodeUserAuthorization = class {
20152
20153
  const address = (0, import_sdk_core5.canonicalizeAddress)(await this.signer.getAddress());
20153
20154
  const chainId = await this.signer.getChainId();
20154
20155
  await this.refreshNamedKeyFeatureForSignIn(address, chainId);
20155
- const keyId = `session-${Date.now()}`;
20156
- this.sessionManager.renameSessionKeyId(this.activeSessionKeyId, keyId);
20157
- this.activeSessionKeyId = keyId;
20156
+ const keyId = `openkey-session-${Date.now()}-${++this.preparedSessionCounter}`;
20157
+ this.sessionManager.createSessionKey(keyId);
20158
20158
  const jwkString = this.sessionManager.jwk(keyId);
20159
20159
  if (!jwkString) {
20160
20160
  throw new Error("Failed to create session key");
@@ -20235,6 +20235,7 @@ var NodeUserAuthorization = class {
20235
20235
  await this.sessionStorage.save(address, persistedData);
20236
20236
  this._session = clientSession;
20237
20237
  this._tinyCloudSession = tinyCloudSession;
20238
+ this.activeSessionKeyId = keyId;
20238
20239
  this._address = address;
20239
20240
  this._chainId = chainId;
20240
20241
  await this.refreshNodeInfo();
@@ -20281,6 +20282,11 @@ var NodeUserAuthorization = class {
20281
20282
  * @param options Optional overrides for the OpenKey request.
20282
20283
  */
20283
20284
  async signInWithOpenKey(authorizeFn, options) {
20285
+ const pending = await this.prepareOpenKeySignIn(options);
20286
+ return this.completeOpenKeySignIn(pending, authorizeFn(pending.request), options);
20287
+ }
20288
+ /** Finish address, host and SIWE preparation before an approval click. */
20289
+ async prepareOpenKeySignIn(options) {
20284
20290
  refuseCaveated(this.getCapabilityRequest()?.manifests);
20285
20291
  if (options?.host !== void 0) {
20286
20292
  const overrideHost = options.host.trim();
@@ -20292,7 +20298,7 @@ var NodeUserAuthorization = class {
20292
20298
  const signingAddress = (0, import_sdk_core5.canonicalizeAddress)(await this.signer.getAddress());
20293
20299
  const signingChainId = await this.signer.getChainId();
20294
20300
  await this.resolveTinyCloudHostsForSignIn(signingAddress, signingChainId);
20295
- const { prepared, keyId, jwk } = await this.prepareSessionForSigning();
20301
+ const { prepared, keyId, jwk, address, chainId } = await this.prepareSessionForSigning();
20296
20302
  const presentation = this.buildPresentationEnvelope(options?.reason);
20297
20303
  const hostHint = this.primaryTinyCloudHost;
20298
20304
  const originalRequest = {
@@ -20304,12 +20310,32 @@ var NodeUserAuthorization = class {
20304
20310
  keyId: options?.openkeyKeyId,
20305
20311
  presentation
20306
20312
  };
20313
+ return {
20314
+ request: originalRequest,
20315
+ prepared,
20316
+ keyId,
20317
+ jwk,
20318
+ address,
20319
+ chainId,
20320
+ generation: this.sessionGeneration,
20321
+ createdAt: Date.now()
20322
+ };
20323
+ }
20324
+ /** Complete a prepared approval. The caller starts authorization before awaiting this method. */
20325
+ async completeOpenKeySignIn(pending, authorization, options) {
20326
+ if (Date.now() - pending.createdAt > 5 * 6e4) {
20327
+ throw new Error("Prepared OpenKey sign-in expired; prepare again");
20328
+ }
20329
+ if (pending.generation !== this.sessionGeneration) {
20330
+ throw new Error("Prepared OpenKey sign-in expired after sign-out");
20331
+ }
20332
+ const { request: originalRequest, prepared, keyId, jwk } = pending;
20307
20333
  let result;
20308
20334
  let signed2;
20309
20335
  let signature2;
20310
20336
  for (let attempt = 0; ; ) {
20311
20337
  try {
20312
- result ?? (result = await authorizeFn(originalRequest));
20338
+ result ?? (result = await authorization);
20313
20339
  signed2 = await this.verifyOpenKeyResult(result, prepared);
20314
20340
  signature2 = result.signature;
20315
20341
  break;
@@ -21703,6 +21729,7 @@ var _TinyCloudNode = class _TinyCloudNode {
21703
21729
  constructor(config = {}) {
21704
21730
  this.signer = null;
21705
21731
  this.auth = null;
21732
+ this.consumedOpenKeyPendings = /* @__PURE__ */ new WeakSet();
21706
21733
  this.tc = null;
21707
21734
  this._chainId = 1;
21708
21735
  this.replicaPurgeFailedHandlers = /* @__PURE__ */ new Set();
@@ -22643,6 +22670,37 @@ var _TinyCloudNode = class _TinyCloudNode {
22643
22670
  }
22644
22671
  await this.signInWith(() => this.auth.signInWithOpenKey(authorizeFn, options));
22645
22672
  }
22673
+ /** Prepare the OpenKey request before the approval click. */
22674
+ async prepareOpenKeySignIn() {
22675
+ if (!this.signer || !this.tc || !this.auth) {
22676
+ throw new Error("Cannot prepare OpenKey sign-in in session-only mode. Provide a signer in config.");
22677
+ }
22678
+ await this.signOutInFlight;
22679
+ await this.accountRegistryTail;
22680
+ await this.wasmBindings.ensureInitialized?.();
22681
+ return this.auth.prepareOpenKeySignIn();
22682
+ }
22683
+ /** Start OpenKey authorization synchronously, then complete normal session setup. */
22684
+ signInWithPreparedOpenKey(pending, authorizeFn) {
22685
+ if (!this.signer || !this.tc || !this.auth || this.signOutInFlight) {
22686
+ throw new Error("Prepared OpenKey sign-in is unavailable");
22687
+ }
22688
+ if (this.consumedOpenKeyPendings.has(pending)) {
22689
+ throw new Error("Prepared OpenKey sign-in was already used");
22690
+ }
22691
+ if (Date.now() - pending.createdAt > 5 * 6e4) {
22692
+ throw new Error("Prepared OpenKey sign-in expired; prepare again");
22693
+ }
22694
+ this.consumedOpenKeyPendings.add(pending);
22695
+ const authorization = authorizeFn(pending.request);
22696
+ void authorization.catch(() => void 0);
22697
+ return this.signInWith(() => {
22698
+ if (this._address !== pending.address || this._chainId !== pending.chainId) {
22699
+ throw new Error("OpenKey account changed after sign-in preparation");
22700
+ }
22701
+ return this.auth.completeOpenKeySignIn(pending, authorization);
22702
+ });
22703
+ }
22646
22704
  async signInWith(performSignIn) {
22647
22705
  refuseCaveated(this.auth?.capabilityRequest?.manifests);
22648
22706
  const epoch = this.sessionEpoch;
@@ -28141,7 +28199,7 @@ var FileSessionStorage = class {
28141
28199
  };
28142
28200
 
28143
28201
  // src/authorization/openKeyBridge.ts
28144
- function wireOpenKeyAuthorize(openkey) {
28202
+ function wireOpenKeyAuthorize(openkey, opts) {
28145
28203
  return async (input) => {
28146
28204
  const result = await openkey.authorizeTinyCloud({
28147
28205
  protocolVersion: 1,
@@ -28152,7 +28210,7 @@ function wireOpenKeyAuthorize(openkey) {
28152
28210
  // Forward the presentation envelope verbatim — the OpenKey SDK
28153
28211
  // validates and size-bounds it before use.
28154
28212
  presentation: input.presentation
28155
- });
28213
+ }, opts);
28156
28214
  if (result.protocolVersion !== 1) {
28157
28215
  throw new Error(
28158
28216
  `wireOpenKeyAuthorize: OpenKey returned unsupported protocolVersion ${result.protocolVersion}`