@tinycloud/sdk-core 3.10.0 → 3.11.0-beta.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/index.d.cts CHANGED
@@ -1864,6 +1864,14 @@ interface TinyCloudAuthorizationRequestV1 {
1864
1864
  keyId?: string;
1865
1865
  /** Optional presentation envelope for the review page. */
1866
1866
  presentation?: CapabilityPresentationEnvelopeV1;
1867
+ /**
1868
+ * The user may change the expiration time in the OpenKey approval. Send it
1869
+ * only when the app accepts the signed value; without it a changed
1870
+ * `Expiration Time` in the signed message is refused. `@openkey/sdk`
1871
+ * >= 0.13.0 (beta: 0.13.0-beta.0) forwards the field; 0.12.x drops it and
1872
+ * the approval keeps the app's expiry.
1873
+ */
1874
+ expiryChangeable?: boolean;
1867
1875
  }
1868
1876
  interface TinyCloudAuthorizationResultV1 {
1869
1877
  protocolVersion: 1;
@@ -2048,10 +2056,56 @@ declare function extractImmutableSiweFields(siwe: string): ImmutableSiweFields;
2048
2056
  * Callers signal which regime applies via `options.originalHasRecap`.
2049
2057
  * When omitted (legacy callers), statement is included in the diff — the
2050
2058
  * safer default for non-ReCap flows.
2059
+ *
2060
+ * `options.allowExpirationChange` drops `expirationTime` from the comparison and
2061
+ * nothing else. Use it only for a request that carried `expiryChangeable: true`,
2062
+ * and gate the changed value with `checkChangedExpiration`.
2051
2063
  */
2052
2064
  declare function diffImmutableSiweFields(original: ImmutableSiweFields, signed: ImmutableSiweFields, options?: {
2053
2065
  originalHasRecap?: boolean;
2066
+ allowExpirationChange?: boolean;
2054
2067
  }): string[];
2068
+ interface CheckChangedExpirationInput {
2069
+ /** The SIWE the SDK prepared and sent. */
2070
+ preparedSiwe: string;
2071
+ /** The exact message OpenKey returned and signed. */
2072
+ signedSiwe: string;
2073
+ /** Current time, as a Date or epoch milliseconds. */
2074
+ now: Date | number;
2075
+ /** The latest expiry this request allows (for example from a grant lifetime), when it has one. */
2076
+ maxExpiresAt?: Date | number;
2077
+ /** Whether the prepared message carries a ReCap. Computed from `preparedSiwe` when omitted. */
2078
+ originalHasRecap?: boolean;
2079
+ }
2080
+ /**
2081
+ * Decide whether a signed message whose `Expiration Time` the user may have
2082
+ * changed is acceptable. Returns `null` to accept, else a short reason.
2083
+ * Call it only for a request that carried `expiryChangeable: true`.
2084
+ *
2085
+ * Call it only after `signedSiwe` was parsed and its signature verified with
2086
+ * `SiweMessage` (as `NodeUserAuthorization` does). The helper also refuses a
2087
+ * non-canonical `Expiration Time` line on its own (CR or CRLF anywhere, a
2088
+ * separator other than one space, trailing characters, or the line after
2089
+ * `Resources:`), but it is not a SIWE parser.
2090
+ *
2091
+ * Refused unless:
2092
+ * - `now` and `maxExpiresAt` (when given) are finite;
2093
+ * - both messages have EXACTLY ONE `Expiration Time` line (the field
2094
+ * extractor is last-wins, so it cannot be trusted to find a hidden second
2095
+ * line), and the signed one is canonical;
2096
+ * - every other immutable field is byte-identical (`domain`, `uri`,
2097
+ * `version`, `chainId`, `nonce`, `issuedAt`, `notBefore`, `address`,
2098
+ * non-ReCap resources, and the statement when there is no ReCap);
2099
+ * - a CHANGED expiry is a valid timestamp, more than 60 seconds from now,
2100
+ * after `Issued At` and after `Not Before` (when the prepared message has
2101
+ * them), not after `maxExpiresAt` (when given), and no later than
2102
+ * 9999-12-31T23:59:59Z, the latest a sign-in message can carry
2103
+ * (`MAX_SIWE_EXPIRY_MS`).
2104
+ *
2105
+ * An unchanged expiry passes the expiry rules. The ReCap subset check and the
2106
+ * rest of the result verification stay with the caller and are not relaxed.
2107
+ */
2108
+ declare function checkChangedExpiration(input: CheckChangedExpirationInput): string | null;
2055
2109
  /**
2056
2110
  * Parsed ReCap attenuation payload. Keyed by resource URI ("space/service/path"),
2057
2111
  * each value is a map of action -> list of caveat objects. Consumers care about
@@ -3977,9 +4031,32 @@ declare const EXPIRY: {
3977
4031
  readonly SESSION_MS: number;
3978
4032
  readonly SHARE_MS: number;
3979
4033
  readonly APP_MS: number;
3980
- readonly MAX_MS: number;
3981
4034
  };
4035
+ /**
4036
+ * The latest expiry a wallet-signed message (a SIWE session or delegation) can
4037
+ * carry: 9999-12-31T23:59:59Z. SIWE writes times as RFC 3339 with a four-digit
4038
+ * year, and the WASM and the node both refuse a year of 10000 or more.
4039
+ */
4040
+ declare const MAX_SIWE_EXPIRY_MS = 253402300799000;
4041
+ /**
4042
+ * The latest expiry a token signed by the session key (`delegateTo`, agent and
4043
+ * share delegations) can carry: 2255-06-05T23:47:34Z, floored to the second.
4044
+ * The WASM's UCAN timestamps are exact to the microsecond in a double, which
4045
+ * stops there. A session itself may still be signed to 9999.
4046
+ */
4047
+ declare const MAX_UCAN_EXPIRY_MS = 9007199254000;
4048
+ type TechnicalExpiryKind = "siwe" | "ucan";
4049
+ /**
4050
+ * Why `expiresAt` cannot be written into a message of this kind, or `null` when
4051
+ * it can. These are the only upper limits on a lifetime the owner chooses; they
4052
+ * are technical, not policy. An invalid Date, NaN, Infinity and an instant before
4053
+ * 1970 are refused too, because `toISOString()` throws a bare `RangeError` on the
4054
+ * first three and writes a negative year the WASM cannot read for the last.
4055
+ */
4056
+ declare function technicalExpiryRefusal(expiresAt: Date | number, kind: TechnicalExpiryKind): string | null;
4057
+ /** Throws the {@link technicalExpiryRefusal} message as an `Error`. */
4058
+ declare function assertExpiryWithinTechnicalLimit(expiresAt: Date | number, kind: TechnicalExpiryKind): void;
3982
4059
  declare const DEFAULT_SIGNED_READ_URL_EXPIRY_MS: number;
3983
4060
  type ExpiryTier = keyof typeof EXPIRY;
3984
4061
 
3985
- export { ACCOUNT_REGISTRY_PATH, ACCOUNT_REGISTRY_SPACE, type AbilitiesMap, type AccountApplication, type AccountApplicationListOptions, type AccountApplicationRegisterOptions, type AccountDelegation, type AccountDelegationListOptions, AccountDelegationPage, AccountDelegationQueryOptions, type AccountDelegationRevokeOptions, type AccountIndexEnsureResult, type AccountIndexRebuildResult, type AccountIndexStatus, type AccountIndexedReadOptions, AccountService, type AccountServiceConfig, type AccountSpace, type AccountSpaceListOptions, type AccountStatus, AutoApproveSpaceCreationHandler, type AutoRejectStrategy, type AutoSignStrategy, type Bytes, CREDENTIAL_ERROR_CODES, type CallbackStrategy, type CanonicalAddress, type CanonicalParsedNetworkId, type CanonicalTinyCloudIdentity, type CapabilityPresentationEnvelopeV1, CaveatedDelegationUnsupportedError, type ClassifyRegistryLookupOptions, type ClientSession, ClientSessionSchema, CloudLocationResolutionError, type ComposeManifestOptions, type ComposedManifestRequest, type CreateDelegationFunction, CreateDelegationParams, CredentialError, type CredentialErrorCode, CredentialFlowDescriptor, CredentialHolderBinding, CredentialIssuerMetadata, CredentialRequirement, CredentialStorageReceipt, DEFAULT_DEFAULTS, DEFAULT_EXPIRY, DEFAULT_KNOWLEDGE_ROOT, DEFAULT_LOCAL_NODE_PIN_STORAGE_KEY, DEFAULT_LOCAL_NODE_URL, DEFAULT_MANIFEST_SPACE, DEFAULT_MANIFEST_VERSION, DEFAULT_NEW_USER_HOST, DEFAULT_REGISTRY_LOOKUP_TIMEOUT_MS, DEFAULT_REGISTRY_OWNER_CHAIN_ID, DEFAULT_REGISTRY_SEQUENCE_STORAGE_KEY, DEFAULT_SIGNED_READ_URL_EXPIRY_MS, DEFAULT_TINYCLOUD_FALLBACK_HOST, DEFAULT_TINYCLOUD_LOCATION_REGISTRY_URL, Delegation, DelegationManager, DelegationRevocationReceipt, type DidCacheKeyOptions, type DidEqualsOptions, type DiscoverLocalTinyCloudNodeOptions, type DiscoveredLocalTinyCloudNode, EMAIL_CREDENTIAL_MAX_AGE_SECONDS, EMAIL_DOMAIN_CREDENTIAL_MAX_AGE_SECONDS, ENCRYPTION_MANIFEST_SPACE, ENCRYPTION_PERMISSION_SERVICE, EXPIRY, type EnsData, EnsDataSchema, type EventEmitterStrategy, type ExpiryTier, type Extension, type FailClosedHostOptions, type FailClosedHosts, GenerateShareParams, ICapabilityKeyRegistry, type IENSResolver, type INotificationHandler, type ISessionManager, type ISessionStorage, ISharingService, type ISigner, type ISpace, type ISpaceCreationHandler, type ISpaceScopedDelegations, type ISpaceScopedSharing, type ISpaceService, type IUserAuthorization, type IWasmBindings, IdentityParseError, type ImmutableSiweFields, IssuedCredentialEnvelope, LOCAL_LINK_HOST_SUFFIX, LOCAL_LINK_PROBE_TIMEOUT_MS, LOCAL_LOOPBACK_PROBE_TIMEOUT_MS, type LocalNodeIdentityStore, type LocationCandidate, type LocationCandidateInput, type LocationRecord, type LocationRecordPayload, type LocationRecordSigner, LocationRecordValidationError, LocationRegistryHttpError, type LocationResolutionAttempt, type LocationSource, type LookupOwnerRegistryVerdictOptions, type Manifest, type ManifestDefaults, type ManifestKnowledge, type ManifestRegistryRecord, type ManifestSecretActions, ManifestValidationError, type NodeInfo, type NodeNotFoundContext, type NodeNotFoundDecision, NodeNotFoundError, NodeRegistryEntryExistsError, OPENKEY_ACTION_ID_SEPARATOR, OWNER_NODE_BINDING_TIMEOUT_MS, type OnNodeNotFound, type OpenKeyCallbackStrategy, type OpenKeyManageKeyCallbackStrategy, OpenKeyManageKeyError, type OpenKeyManageKeyErrorCode, type OpenKeyManageKeyFetch, type OpenKeyManageKeySigningRequestBody, type OpenKeyManageKeySigningResponseBody, type OpenKeyManageKeySigningStrategyOptions, type OpenKeySigningRequestBody, type OpenKeySigningResponseBody, type OpenKeySigningStrategyOptions, type ParseRecapFromSiwe, type PartialSiweMessage, type PermissionEntry, PermissionNotInManifestError, type PersistedSessionData, type PersistedSessionProof, type PersistedTinyCloudSession, type PkhDidParts, ProtocolMismatchError, type PublishLocationRecordOptions, REGISTRY_LOOKUP_MAX_BODY_BYTES, REGISTRY_NOT_FOUND_BODY, type RecapAttenuation, type RegisterBatchSuccess, type RegisteredRegistryVerdict, type RegistryHost, type RegistryHostSource, RegistryLookupInputError, type RegistryLookupInputErrorCode, type RegistryLookupResponse, type RegistryPolicy, type RegistrySequenceStore, RegistryUnavailableError, type RegistryUnavailableReason, type RegistryVerdict, type RegistryVerdictSource, type RegistryVerdictStatus, type ResolveCloudLocationOptions, type ResolveOwnerHostsOptions, type ResolveTinyCloudHostsOptions, type ResolvedCapabilities, type ResolvedCloudLocation, type ResolvedDelegate, type ResolvedTinyCloudHosts, type ResourceCapability, SECRETS_SPACE, SERVICE_LONG_TO_SHORT, SERVICE_SHORT_TO_LONG, type ServerHost, SessionExpiredError, ShareLink, type SignCallback, type SignInOptions, type SignRequest, type SignResponse, type SignStrategy, type SignedSiweCacao, SilentNotificationHandler, type SiweConfig, SiweConfigSchema, Space, type SpaceAbilitiesMap, type SpaceConfig, type SpaceCreationContext, type SpaceDelegationParams, type SpaceErrorCode, SpaceErrorCodes, type SpaceHostResult, SpaceInfo, SpaceService, type SpaceServiceConfig, StoredCredentialRecord, type SubsetCheckResult, TERMINAL_DELEGATION_FACT, TINYCLOUD_CANONICAL_IDENTITY_CLAIM, TINYCLOUD_MANAGE_KEY_SCOPE, type TerminalDelegationSigningKey, TicketHolderBinding, TinyCloud, type TinyCloudAuthorizationRequestV1, type TinyCloudAuthorizationResultV1, type TinyCloudConfig, type TinyCloudEffectiveGrantV1, type TinyCloudSession, type UnavailableRegistryVerdict, type UnregisteredRegistryVerdict, UnsupportedFeatureError, type UserAuthorizationConfig, VAULT_PERMISSION_SERVICE, type ValidatedPersistedSessionProof, type ValidationError, VerifiedCredential, type VerifiedOwnerNodeBinding, type VerifyOwnerNodeBindingOptions, VersionCheckError, type WasmRecapEntry, type WebStorageLike, actionContains, activateSessionWithHost, addressStorageKey, applyPrefix, assertSpaceCreationAllowed, buildSpaceUri, canonicalDigest, canonicalLocationPayload, canonicalizeAddress, canonicalizeDid, canonicalizeDidUrl, canonicalizeNetworkId, canonicalizeRecapCaveats, checkNodeInfo, classifyRegistryLookup, composeManifestRequest, createEmailCredentialRequirement, createEmailDomainCredentialRequirement, createHolderBinding, createInMemoryLocalNodeIdentityStore, createInMemoryRegistrySequenceStore, createLocalStorageLocalNodeIdentityStore, createLocalStorageRegistrySequenceStore, createOpenKeyCallbackSigningStrategy, createOpenKeyManageKeySigningStrategy, createSpaceService, createStorageReceipt, createStoredCredentialRecord, credentialEndpointPath, credentialError, credentialIndexKey, credentialMatchesRequirement, credentialRecordKey, credentialRequirementDigest, decodeBase64Url, defaultSignStrategy, defaultSpaceCreationHandler, descriptorSatisfiesRequirement, didCacheKey, didEquals, diffImmutableSiweFields, discoverLocalTinyCloudNode, encodeBase64Url, expandActionShortNames, expandDelegationPermissionEntries, expandPermissionEntries, expandPermissionEntry, expandRuntimePermissionEntries, extractImmutableSiweFields, extractRecapAttenuations, fetchLocationRecord, fetchPeerId, hasTinyCloudManageKeyScope, holderBindingCanonicalBytes, holderBindingSigningBytes, httpResponseError, httpUrlToMultiaddr, isCapabilitySubset, isDigest, isEvmAddress, isExplicitOnlyAction, isPlausibleOpenKeyActionId, loadManifest, locationPayloadForRecord, lookupOwnerRegistryVerdict, makePkhSpaceId, makePublicSpaceId, manifestAbilitiesUnion, markDelegationTerminal, multiaddrToHttpUrl, normalizeDefaults, parseCanonicalNetworkId, parseCanonicalRecapResource, parseCanonicalTinyCloudIdentity, parseCanonicalTinyCloudIdentityClaims, parseExpiry, parsePkhDid, parseRecapCapabilities, parseSignedSiweCacao, parseSpaceUri, pkhDid, principalDid, principalDidEquals, publishLocationRecord, recapCaveatsEqual, registryOwnerSubjectV1, requestTinyCloudManageKeyScope, resolveCloudLocation, resolveFailClosedTinyCloudHosts, resolveManifest, resolveManifestKnowledgeRoot, resolveOwnerHosts, resolveTinyCloudHosts, resourceCapabilitiesToAbilitiesMap, resourceCapabilitiesToSpaceAbilitiesMap, sha256Base64Url, signLocationRecord, submitHostDelegation, unauthorizedRecapCapabilities, validateAuthorizationResultV1, validateClientSession, validateCredentialFlowDescriptor, validateCredentialHolderBinding, validateCredentialRequirement, validateLocationRecord, validateLocationRecordPayload, validateManifest, validatePersistedSessionData, verifyDidKeyEd25519Signature, verifyEip191MessageSignature, verifyIssuedCredential, verifyLocationRecord, verifyOwnerNodeBinding, verifyStorageReceipt };
4062
+ export { ACCOUNT_REGISTRY_PATH, ACCOUNT_REGISTRY_SPACE, type AbilitiesMap, type AccountApplication, type AccountApplicationListOptions, type AccountApplicationRegisterOptions, type AccountDelegation, type AccountDelegationListOptions, AccountDelegationPage, AccountDelegationQueryOptions, type AccountDelegationRevokeOptions, type AccountIndexEnsureResult, type AccountIndexRebuildResult, type AccountIndexStatus, type AccountIndexedReadOptions, AccountService, type AccountServiceConfig, type AccountSpace, type AccountSpaceListOptions, type AccountStatus, AutoApproveSpaceCreationHandler, type AutoRejectStrategy, type AutoSignStrategy, type Bytes, CREDENTIAL_ERROR_CODES, type CallbackStrategy, type CanonicalAddress, type CanonicalParsedNetworkId, type CanonicalTinyCloudIdentity, type CapabilityPresentationEnvelopeV1, CaveatedDelegationUnsupportedError, type CheckChangedExpirationInput, type ClassifyRegistryLookupOptions, type ClientSession, ClientSessionSchema, CloudLocationResolutionError, type ComposeManifestOptions, type ComposedManifestRequest, type CreateDelegationFunction, CreateDelegationParams, CredentialError, type CredentialErrorCode, CredentialFlowDescriptor, CredentialHolderBinding, CredentialIssuerMetadata, CredentialRequirement, CredentialStorageReceipt, DEFAULT_DEFAULTS, DEFAULT_EXPIRY, DEFAULT_KNOWLEDGE_ROOT, DEFAULT_LOCAL_NODE_PIN_STORAGE_KEY, DEFAULT_LOCAL_NODE_URL, DEFAULT_MANIFEST_SPACE, DEFAULT_MANIFEST_VERSION, DEFAULT_NEW_USER_HOST, DEFAULT_REGISTRY_LOOKUP_TIMEOUT_MS, DEFAULT_REGISTRY_OWNER_CHAIN_ID, DEFAULT_REGISTRY_SEQUENCE_STORAGE_KEY, DEFAULT_SIGNED_READ_URL_EXPIRY_MS, DEFAULT_TINYCLOUD_FALLBACK_HOST, DEFAULT_TINYCLOUD_LOCATION_REGISTRY_URL, Delegation, DelegationManager, DelegationRevocationReceipt, type DidCacheKeyOptions, type DidEqualsOptions, type DiscoverLocalTinyCloudNodeOptions, type DiscoveredLocalTinyCloudNode, EMAIL_CREDENTIAL_MAX_AGE_SECONDS, EMAIL_DOMAIN_CREDENTIAL_MAX_AGE_SECONDS, ENCRYPTION_MANIFEST_SPACE, ENCRYPTION_PERMISSION_SERVICE, EXPIRY, type EnsData, EnsDataSchema, type EventEmitterStrategy, type ExpiryTier, type Extension, type FailClosedHostOptions, type FailClosedHosts, GenerateShareParams, ICapabilityKeyRegistry, type IENSResolver, type INotificationHandler, type ISessionManager, type ISessionStorage, ISharingService, type ISigner, type ISpace, type ISpaceCreationHandler, type ISpaceScopedDelegations, type ISpaceScopedSharing, type ISpaceService, type IUserAuthorization, type IWasmBindings, IdentityParseError, type ImmutableSiweFields, IssuedCredentialEnvelope, LOCAL_LINK_HOST_SUFFIX, LOCAL_LINK_PROBE_TIMEOUT_MS, LOCAL_LOOPBACK_PROBE_TIMEOUT_MS, type LocalNodeIdentityStore, type LocationCandidate, type LocationCandidateInput, type LocationRecord, type LocationRecordPayload, type LocationRecordSigner, LocationRecordValidationError, LocationRegistryHttpError, type LocationResolutionAttempt, type LocationSource, type LookupOwnerRegistryVerdictOptions, MAX_SIWE_EXPIRY_MS, MAX_UCAN_EXPIRY_MS, type Manifest, type ManifestDefaults, type ManifestKnowledge, type ManifestRegistryRecord, type ManifestSecretActions, ManifestValidationError, type NodeInfo, type NodeNotFoundContext, type NodeNotFoundDecision, NodeNotFoundError, NodeRegistryEntryExistsError, OPENKEY_ACTION_ID_SEPARATOR, OWNER_NODE_BINDING_TIMEOUT_MS, type OnNodeNotFound, type OpenKeyCallbackStrategy, type OpenKeyManageKeyCallbackStrategy, OpenKeyManageKeyError, type OpenKeyManageKeyErrorCode, type OpenKeyManageKeyFetch, type OpenKeyManageKeySigningRequestBody, type OpenKeyManageKeySigningResponseBody, type OpenKeyManageKeySigningStrategyOptions, type OpenKeySigningRequestBody, type OpenKeySigningResponseBody, type OpenKeySigningStrategyOptions, type ParseRecapFromSiwe, type PartialSiweMessage, type PermissionEntry, PermissionNotInManifestError, type PersistedSessionData, type PersistedSessionProof, type PersistedTinyCloudSession, type PkhDidParts, ProtocolMismatchError, type PublishLocationRecordOptions, REGISTRY_LOOKUP_MAX_BODY_BYTES, REGISTRY_NOT_FOUND_BODY, type RecapAttenuation, type RegisterBatchSuccess, type RegisteredRegistryVerdict, type RegistryHost, type RegistryHostSource, RegistryLookupInputError, type RegistryLookupInputErrorCode, type RegistryLookupResponse, type RegistryPolicy, type RegistrySequenceStore, RegistryUnavailableError, type RegistryUnavailableReason, type RegistryVerdict, type RegistryVerdictSource, type RegistryVerdictStatus, type ResolveCloudLocationOptions, type ResolveOwnerHostsOptions, type ResolveTinyCloudHostsOptions, type ResolvedCapabilities, type ResolvedCloudLocation, type ResolvedDelegate, type ResolvedTinyCloudHosts, type ResourceCapability, SECRETS_SPACE, SERVICE_LONG_TO_SHORT, SERVICE_SHORT_TO_LONG, type ServerHost, SessionExpiredError, ShareLink, type SignCallback, type SignInOptions, type SignRequest, type SignResponse, type SignStrategy, type SignedSiweCacao, SilentNotificationHandler, type SiweConfig, SiweConfigSchema, Space, type SpaceAbilitiesMap, type SpaceConfig, type SpaceCreationContext, type SpaceDelegationParams, type SpaceErrorCode, SpaceErrorCodes, type SpaceHostResult, SpaceInfo, SpaceService, type SpaceServiceConfig, StoredCredentialRecord, type SubsetCheckResult, TERMINAL_DELEGATION_FACT, TINYCLOUD_CANONICAL_IDENTITY_CLAIM, TINYCLOUD_MANAGE_KEY_SCOPE, type TechnicalExpiryKind, type TerminalDelegationSigningKey, TicketHolderBinding, TinyCloud, type TinyCloudAuthorizationRequestV1, type TinyCloudAuthorizationResultV1, type TinyCloudConfig, type TinyCloudEffectiveGrantV1, type TinyCloudSession, type UnavailableRegistryVerdict, type UnregisteredRegistryVerdict, UnsupportedFeatureError, type UserAuthorizationConfig, VAULT_PERMISSION_SERVICE, type ValidatedPersistedSessionProof, type ValidationError, VerifiedCredential, type VerifiedOwnerNodeBinding, type VerifyOwnerNodeBindingOptions, VersionCheckError, type WasmRecapEntry, type WebStorageLike, actionContains, activateSessionWithHost, addressStorageKey, applyPrefix, assertExpiryWithinTechnicalLimit, assertSpaceCreationAllowed, buildSpaceUri, canonicalDigest, canonicalLocationPayload, canonicalizeAddress, canonicalizeDid, canonicalizeDidUrl, canonicalizeNetworkId, canonicalizeRecapCaveats, checkChangedExpiration, checkNodeInfo, classifyRegistryLookup, composeManifestRequest, createEmailCredentialRequirement, createEmailDomainCredentialRequirement, createHolderBinding, createInMemoryLocalNodeIdentityStore, createInMemoryRegistrySequenceStore, createLocalStorageLocalNodeIdentityStore, createLocalStorageRegistrySequenceStore, createOpenKeyCallbackSigningStrategy, createOpenKeyManageKeySigningStrategy, createSpaceService, createStorageReceipt, createStoredCredentialRecord, credentialEndpointPath, credentialError, credentialIndexKey, credentialMatchesRequirement, credentialRecordKey, credentialRequirementDigest, decodeBase64Url, defaultSignStrategy, defaultSpaceCreationHandler, descriptorSatisfiesRequirement, didCacheKey, didEquals, diffImmutableSiweFields, discoverLocalTinyCloudNode, encodeBase64Url, expandActionShortNames, expandDelegationPermissionEntries, expandPermissionEntries, expandPermissionEntry, expandRuntimePermissionEntries, extractImmutableSiweFields, extractRecapAttenuations, fetchLocationRecord, fetchPeerId, hasTinyCloudManageKeyScope, holderBindingCanonicalBytes, holderBindingSigningBytes, httpResponseError, httpUrlToMultiaddr, isCapabilitySubset, isDigest, isEvmAddress, isExplicitOnlyAction, isPlausibleOpenKeyActionId, loadManifest, locationPayloadForRecord, lookupOwnerRegistryVerdict, makePkhSpaceId, makePublicSpaceId, manifestAbilitiesUnion, markDelegationTerminal, multiaddrToHttpUrl, normalizeDefaults, parseCanonicalNetworkId, parseCanonicalRecapResource, parseCanonicalTinyCloudIdentity, parseCanonicalTinyCloudIdentityClaims, parseExpiry, parsePkhDid, parseRecapCapabilities, parseSignedSiweCacao, parseSpaceUri, pkhDid, principalDid, principalDidEquals, publishLocationRecord, recapCaveatsEqual, registryOwnerSubjectV1, requestTinyCloudManageKeyScope, resolveCloudLocation, resolveFailClosedTinyCloudHosts, resolveManifest, resolveManifestKnowledgeRoot, resolveOwnerHosts, resolveTinyCloudHosts, resourceCapabilitiesToAbilitiesMap, resourceCapabilitiesToSpaceAbilitiesMap, sha256Base64Url, signLocationRecord, submitHostDelegation, technicalExpiryRefusal, unauthorizedRecapCapabilities, validateAuthorizationResultV1, validateClientSession, validateCredentialFlowDescriptor, validateCredentialHolderBinding, validateCredentialRequirement, validateLocationRecord, validateLocationRecordPayload, validateManifest, validatePersistedSessionData, verifyDidKeyEd25519Signature, verifyEip191MessageSignature, verifyIssuedCredential, verifyLocationRecord, verifyOwnerNodeBinding, verifyStorageReceipt };
package/dist/index.d.ts CHANGED
@@ -1864,6 +1864,14 @@ interface TinyCloudAuthorizationRequestV1 {
1864
1864
  keyId?: string;
1865
1865
  /** Optional presentation envelope for the review page. */
1866
1866
  presentation?: CapabilityPresentationEnvelopeV1;
1867
+ /**
1868
+ * The user may change the expiration time in the OpenKey approval. Send it
1869
+ * only when the app accepts the signed value; without it a changed
1870
+ * `Expiration Time` in the signed message is refused. `@openkey/sdk`
1871
+ * >= 0.13.0 (beta: 0.13.0-beta.0) forwards the field; 0.12.x drops it and
1872
+ * the approval keeps the app's expiry.
1873
+ */
1874
+ expiryChangeable?: boolean;
1867
1875
  }
1868
1876
  interface TinyCloudAuthorizationResultV1 {
1869
1877
  protocolVersion: 1;
@@ -2048,10 +2056,56 @@ declare function extractImmutableSiweFields(siwe: string): ImmutableSiweFields;
2048
2056
  * Callers signal which regime applies via `options.originalHasRecap`.
2049
2057
  * When omitted (legacy callers), statement is included in the diff — the
2050
2058
  * safer default for non-ReCap flows.
2059
+ *
2060
+ * `options.allowExpirationChange` drops `expirationTime` from the comparison and
2061
+ * nothing else. Use it only for a request that carried `expiryChangeable: true`,
2062
+ * and gate the changed value with `checkChangedExpiration`.
2051
2063
  */
2052
2064
  declare function diffImmutableSiweFields(original: ImmutableSiweFields, signed: ImmutableSiweFields, options?: {
2053
2065
  originalHasRecap?: boolean;
2066
+ allowExpirationChange?: boolean;
2054
2067
  }): string[];
2068
+ interface CheckChangedExpirationInput {
2069
+ /** The SIWE the SDK prepared and sent. */
2070
+ preparedSiwe: string;
2071
+ /** The exact message OpenKey returned and signed. */
2072
+ signedSiwe: string;
2073
+ /** Current time, as a Date or epoch milliseconds. */
2074
+ now: Date | number;
2075
+ /** The latest expiry this request allows (for example from a grant lifetime), when it has one. */
2076
+ maxExpiresAt?: Date | number;
2077
+ /** Whether the prepared message carries a ReCap. Computed from `preparedSiwe` when omitted. */
2078
+ originalHasRecap?: boolean;
2079
+ }
2080
+ /**
2081
+ * Decide whether a signed message whose `Expiration Time` the user may have
2082
+ * changed is acceptable. Returns `null` to accept, else a short reason.
2083
+ * Call it only for a request that carried `expiryChangeable: true`.
2084
+ *
2085
+ * Call it only after `signedSiwe` was parsed and its signature verified with
2086
+ * `SiweMessage` (as `NodeUserAuthorization` does). The helper also refuses a
2087
+ * non-canonical `Expiration Time` line on its own (CR or CRLF anywhere, a
2088
+ * separator other than one space, trailing characters, or the line after
2089
+ * `Resources:`), but it is not a SIWE parser.
2090
+ *
2091
+ * Refused unless:
2092
+ * - `now` and `maxExpiresAt` (when given) are finite;
2093
+ * - both messages have EXACTLY ONE `Expiration Time` line (the field
2094
+ * extractor is last-wins, so it cannot be trusted to find a hidden second
2095
+ * line), and the signed one is canonical;
2096
+ * - every other immutable field is byte-identical (`domain`, `uri`,
2097
+ * `version`, `chainId`, `nonce`, `issuedAt`, `notBefore`, `address`,
2098
+ * non-ReCap resources, and the statement when there is no ReCap);
2099
+ * - a CHANGED expiry is a valid timestamp, more than 60 seconds from now,
2100
+ * after `Issued At` and after `Not Before` (when the prepared message has
2101
+ * them), not after `maxExpiresAt` (when given), and no later than
2102
+ * 9999-12-31T23:59:59Z, the latest a sign-in message can carry
2103
+ * (`MAX_SIWE_EXPIRY_MS`).
2104
+ *
2105
+ * An unchanged expiry passes the expiry rules. The ReCap subset check and the
2106
+ * rest of the result verification stay with the caller and are not relaxed.
2107
+ */
2108
+ declare function checkChangedExpiration(input: CheckChangedExpirationInput): string | null;
2055
2109
  /**
2056
2110
  * Parsed ReCap attenuation payload. Keyed by resource URI ("space/service/path"),
2057
2111
  * each value is a map of action -> list of caveat objects. Consumers care about
@@ -3977,9 +4031,32 @@ declare const EXPIRY: {
3977
4031
  readonly SESSION_MS: number;
3978
4032
  readonly SHARE_MS: number;
3979
4033
  readonly APP_MS: number;
3980
- readonly MAX_MS: number;
3981
4034
  };
4035
+ /**
4036
+ * The latest expiry a wallet-signed message (a SIWE session or delegation) can
4037
+ * carry: 9999-12-31T23:59:59Z. SIWE writes times as RFC 3339 with a four-digit
4038
+ * year, and the WASM and the node both refuse a year of 10000 or more.
4039
+ */
4040
+ declare const MAX_SIWE_EXPIRY_MS = 253402300799000;
4041
+ /**
4042
+ * The latest expiry a token signed by the session key (`delegateTo`, agent and
4043
+ * share delegations) can carry: 2255-06-05T23:47:34Z, floored to the second.
4044
+ * The WASM's UCAN timestamps are exact to the microsecond in a double, which
4045
+ * stops there. A session itself may still be signed to 9999.
4046
+ */
4047
+ declare const MAX_UCAN_EXPIRY_MS = 9007199254000;
4048
+ type TechnicalExpiryKind = "siwe" | "ucan";
4049
+ /**
4050
+ * Why `expiresAt` cannot be written into a message of this kind, or `null` when
4051
+ * it can. These are the only upper limits on a lifetime the owner chooses; they
4052
+ * are technical, not policy. An invalid Date, NaN, Infinity and an instant before
4053
+ * 1970 are refused too, because `toISOString()` throws a bare `RangeError` on the
4054
+ * first three and writes a negative year the WASM cannot read for the last.
4055
+ */
4056
+ declare function technicalExpiryRefusal(expiresAt: Date | number, kind: TechnicalExpiryKind): string | null;
4057
+ /** Throws the {@link technicalExpiryRefusal} message as an `Error`. */
4058
+ declare function assertExpiryWithinTechnicalLimit(expiresAt: Date | number, kind: TechnicalExpiryKind): void;
3982
4059
  declare const DEFAULT_SIGNED_READ_URL_EXPIRY_MS: number;
3983
4060
  type ExpiryTier = keyof typeof EXPIRY;
3984
4061
 
3985
- export { ACCOUNT_REGISTRY_PATH, ACCOUNT_REGISTRY_SPACE, type AbilitiesMap, type AccountApplication, type AccountApplicationListOptions, type AccountApplicationRegisterOptions, type AccountDelegation, type AccountDelegationListOptions, AccountDelegationPage, AccountDelegationQueryOptions, type AccountDelegationRevokeOptions, type AccountIndexEnsureResult, type AccountIndexRebuildResult, type AccountIndexStatus, type AccountIndexedReadOptions, AccountService, type AccountServiceConfig, type AccountSpace, type AccountSpaceListOptions, type AccountStatus, AutoApproveSpaceCreationHandler, type AutoRejectStrategy, type AutoSignStrategy, type Bytes, CREDENTIAL_ERROR_CODES, type CallbackStrategy, type CanonicalAddress, type CanonicalParsedNetworkId, type CanonicalTinyCloudIdentity, type CapabilityPresentationEnvelopeV1, CaveatedDelegationUnsupportedError, type ClassifyRegistryLookupOptions, type ClientSession, ClientSessionSchema, CloudLocationResolutionError, type ComposeManifestOptions, type ComposedManifestRequest, type CreateDelegationFunction, CreateDelegationParams, CredentialError, type CredentialErrorCode, CredentialFlowDescriptor, CredentialHolderBinding, CredentialIssuerMetadata, CredentialRequirement, CredentialStorageReceipt, DEFAULT_DEFAULTS, DEFAULT_EXPIRY, DEFAULT_KNOWLEDGE_ROOT, DEFAULT_LOCAL_NODE_PIN_STORAGE_KEY, DEFAULT_LOCAL_NODE_URL, DEFAULT_MANIFEST_SPACE, DEFAULT_MANIFEST_VERSION, DEFAULT_NEW_USER_HOST, DEFAULT_REGISTRY_LOOKUP_TIMEOUT_MS, DEFAULT_REGISTRY_OWNER_CHAIN_ID, DEFAULT_REGISTRY_SEQUENCE_STORAGE_KEY, DEFAULT_SIGNED_READ_URL_EXPIRY_MS, DEFAULT_TINYCLOUD_FALLBACK_HOST, DEFAULT_TINYCLOUD_LOCATION_REGISTRY_URL, Delegation, DelegationManager, DelegationRevocationReceipt, type DidCacheKeyOptions, type DidEqualsOptions, type DiscoverLocalTinyCloudNodeOptions, type DiscoveredLocalTinyCloudNode, EMAIL_CREDENTIAL_MAX_AGE_SECONDS, EMAIL_DOMAIN_CREDENTIAL_MAX_AGE_SECONDS, ENCRYPTION_MANIFEST_SPACE, ENCRYPTION_PERMISSION_SERVICE, EXPIRY, type EnsData, EnsDataSchema, type EventEmitterStrategy, type ExpiryTier, type Extension, type FailClosedHostOptions, type FailClosedHosts, GenerateShareParams, ICapabilityKeyRegistry, type IENSResolver, type INotificationHandler, type ISessionManager, type ISessionStorage, ISharingService, type ISigner, type ISpace, type ISpaceCreationHandler, type ISpaceScopedDelegations, type ISpaceScopedSharing, type ISpaceService, type IUserAuthorization, type IWasmBindings, IdentityParseError, type ImmutableSiweFields, IssuedCredentialEnvelope, LOCAL_LINK_HOST_SUFFIX, LOCAL_LINK_PROBE_TIMEOUT_MS, LOCAL_LOOPBACK_PROBE_TIMEOUT_MS, type LocalNodeIdentityStore, type LocationCandidate, type LocationCandidateInput, type LocationRecord, type LocationRecordPayload, type LocationRecordSigner, LocationRecordValidationError, LocationRegistryHttpError, type LocationResolutionAttempt, type LocationSource, type LookupOwnerRegistryVerdictOptions, type Manifest, type ManifestDefaults, type ManifestKnowledge, type ManifestRegistryRecord, type ManifestSecretActions, ManifestValidationError, type NodeInfo, type NodeNotFoundContext, type NodeNotFoundDecision, NodeNotFoundError, NodeRegistryEntryExistsError, OPENKEY_ACTION_ID_SEPARATOR, OWNER_NODE_BINDING_TIMEOUT_MS, type OnNodeNotFound, type OpenKeyCallbackStrategy, type OpenKeyManageKeyCallbackStrategy, OpenKeyManageKeyError, type OpenKeyManageKeyErrorCode, type OpenKeyManageKeyFetch, type OpenKeyManageKeySigningRequestBody, type OpenKeyManageKeySigningResponseBody, type OpenKeyManageKeySigningStrategyOptions, type OpenKeySigningRequestBody, type OpenKeySigningResponseBody, type OpenKeySigningStrategyOptions, type ParseRecapFromSiwe, type PartialSiweMessage, type PermissionEntry, PermissionNotInManifestError, type PersistedSessionData, type PersistedSessionProof, type PersistedTinyCloudSession, type PkhDidParts, ProtocolMismatchError, type PublishLocationRecordOptions, REGISTRY_LOOKUP_MAX_BODY_BYTES, REGISTRY_NOT_FOUND_BODY, type RecapAttenuation, type RegisterBatchSuccess, type RegisteredRegistryVerdict, type RegistryHost, type RegistryHostSource, RegistryLookupInputError, type RegistryLookupInputErrorCode, type RegistryLookupResponse, type RegistryPolicy, type RegistrySequenceStore, RegistryUnavailableError, type RegistryUnavailableReason, type RegistryVerdict, type RegistryVerdictSource, type RegistryVerdictStatus, type ResolveCloudLocationOptions, type ResolveOwnerHostsOptions, type ResolveTinyCloudHostsOptions, type ResolvedCapabilities, type ResolvedCloudLocation, type ResolvedDelegate, type ResolvedTinyCloudHosts, type ResourceCapability, SECRETS_SPACE, SERVICE_LONG_TO_SHORT, SERVICE_SHORT_TO_LONG, type ServerHost, SessionExpiredError, ShareLink, type SignCallback, type SignInOptions, type SignRequest, type SignResponse, type SignStrategy, type SignedSiweCacao, SilentNotificationHandler, type SiweConfig, SiweConfigSchema, Space, type SpaceAbilitiesMap, type SpaceConfig, type SpaceCreationContext, type SpaceDelegationParams, type SpaceErrorCode, SpaceErrorCodes, type SpaceHostResult, SpaceInfo, SpaceService, type SpaceServiceConfig, StoredCredentialRecord, type SubsetCheckResult, TERMINAL_DELEGATION_FACT, TINYCLOUD_CANONICAL_IDENTITY_CLAIM, TINYCLOUD_MANAGE_KEY_SCOPE, type TerminalDelegationSigningKey, TicketHolderBinding, TinyCloud, type TinyCloudAuthorizationRequestV1, type TinyCloudAuthorizationResultV1, type TinyCloudConfig, type TinyCloudEffectiveGrantV1, type TinyCloudSession, type UnavailableRegistryVerdict, type UnregisteredRegistryVerdict, UnsupportedFeatureError, type UserAuthorizationConfig, VAULT_PERMISSION_SERVICE, type ValidatedPersistedSessionProof, type ValidationError, VerifiedCredential, type VerifiedOwnerNodeBinding, type VerifyOwnerNodeBindingOptions, VersionCheckError, type WasmRecapEntry, type WebStorageLike, actionContains, activateSessionWithHost, addressStorageKey, applyPrefix, assertSpaceCreationAllowed, buildSpaceUri, canonicalDigest, canonicalLocationPayload, canonicalizeAddress, canonicalizeDid, canonicalizeDidUrl, canonicalizeNetworkId, canonicalizeRecapCaveats, checkNodeInfo, classifyRegistryLookup, composeManifestRequest, createEmailCredentialRequirement, createEmailDomainCredentialRequirement, createHolderBinding, createInMemoryLocalNodeIdentityStore, createInMemoryRegistrySequenceStore, createLocalStorageLocalNodeIdentityStore, createLocalStorageRegistrySequenceStore, createOpenKeyCallbackSigningStrategy, createOpenKeyManageKeySigningStrategy, createSpaceService, createStorageReceipt, createStoredCredentialRecord, credentialEndpointPath, credentialError, credentialIndexKey, credentialMatchesRequirement, credentialRecordKey, credentialRequirementDigest, decodeBase64Url, defaultSignStrategy, defaultSpaceCreationHandler, descriptorSatisfiesRequirement, didCacheKey, didEquals, diffImmutableSiweFields, discoverLocalTinyCloudNode, encodeBase64Url, expandActionShortNames, expandDelegationPermissionEntries, expandPermissionEntries, expandPermissionEntry, expandRuntimePermissionEntries, extractImmutableSiweFields, extractRecapAttenuations, fetchLocationRecord, fetchPeerId, hasTinyCloudManageKeyScope, holderBindingCanonicalBytes, holderBindingSigningBytes, httpResponseError, httpUrlToMultiaddr, isCapabilitySubset, isDigest, isEvmAddress, isExplicitOnlyAction, isPlausibleOpenKeyActionId, loadManifest, locationPayloadForRecord, lookupOwnerRegistryVerdict, makePkhSpaceId, makePublicSpaceId, manifestAbilitiesUnion, markDelegationTerminal, multiaddrToHttpUrl, normalizeDefaults, parseCanonicalNetworkId, parseCanonicalRecapResource, parseCanonicalTinyCloudIdentity, parseCanonicalTinyCloudIdentityClaims, parseExpiry, parsePkhDid, parseRecapCapabilities, parseSignedSiweCacao, parseSpaceUri, pkhDid, principalDid, principalDidEquals, publishLocationRecord, recapCaveatsEqual, registryOwnerSubjectV1, requestTinyCloudManageKeyScope, resolveCloudLocation, resolveFailClosedTinyCloudHosts, resolveManifest, resolveManifestKnowledgeRoot, resolveOwnerHosts, resolveTinyCloudHosts, resourceCapabilitiesToAbilitiesMap, resourceCapabilitiesToSpaceAbilitiesMap, sha256Base64Url, signLocationRecord, submitHostDelegation, unauthorizedRecapCapabilities, validateAuthorizationResultV1, validateClientSession, validateCredentialFlowDescriptor, validateCredentialHolderBinding, validateCredentialRequirement, validateLocationRecord, validateLocationRecordPayload, validateManifest, validatePersistedSessionData, verifyDidKeyEd25519Signature, verifyEip191MessageSignature, verifyIssuedCredential, verifyLocationRecord, verifyOwnerNodeBinding, verifyStorageReceipt };
4062
+ export { ACCOUNT_REGISTRY_PATH, ACCOUNT_REGISTRY_SPACE, type AbilitiesMap, type AccountApplication, type AccountApplicationListOptions, type AccountApplicationRegisterOptions, type AccountDelegation, type AccountDelegationListOptions, AccountDelegationPage, AccountDelegationQueryOptions, type AccountDelegationRevokeOptions, type AccountIndexEnsureResult, type AccountIndexRebuildResult, type AccountIndexStatus, type AccountIndexedReadOptions, AccountService, type AccountServiceConfig, type AccountSpace, type AccountSpaceListOptions, type AccountStatus, AutoApproveSpaceCreationHandler, type AutoRejectStrategy, type AutoSignStrategy, type Bytes, CREDENTIAL_ERROR_CODES, type CallbackStrategy, type CanonicalAddress, type CanonicalParsedNetworkId, type CanonicalTinyCloudIdentity, type CapabilityPresentationEnvelopeV1, CaveatedDelegationUnsupportedError, type CheckChangedExpirationInput, type ClassifyRegistryLookupOptions, type ClientSession, ClientSessionSchema, CloudLocationResolutionError, type ComposeManifestOptions, type ComposedManifestRequest, type CreateDelegationFunction, CreateDelegationParams, CredentialError, type CredentialErrorCode, CredentialFlowDescriptor, CredentialHolderBinding, CredentialIssuerMetadata, CredentialRequirement, CredentialStorageReceipt, DEFAULT_DEFAULTS, DEFAULT_EXPIRY, DEFAULT_KNOWLEDGE_ROOT, DEFAULT_LOCAL_NODE_PIN_STORAGE_KEY, DEFAULT_LOCAL_NODE_URL, DEFAULT_MANIFEST_SPACE, DEFAULT_MANIFEST_VERSION, DEFAULT_NEW_USER_HOST, DEFAULT_REGISTRY_LOOKUP_TIMEOUT_MS, DEFAULT_REGISTRY_OWNER_CHAIN_ID, DEFAULT_REGISTRY_SEQUENCE_STORAGE_KEY, DEFAULT_SIGNED_READ_URL_EXPIRY_MS, DEFAULT_TINYCLOUD_FALLBACK_HOST, DEFAULT_TINYCLOUD_LOCATION_REGISTRY_URL, Delegation, DelegationManager, DelegationRevocationReceipt, type DidCacheKeyOptions, type DidEqualsOptions, type DiscoverLocalTinyCloudNodeOptions, type DiscoveredLocalTinyCloudNode, EMAIL_CREDENTIAL_MAX_AGE_SECONDS, EMAIL_DOMAIN_CREDENTIAL_MAX_AGE_SECONDS, ENCRYPTION_MANIFEST_SPACE, ENCRYPTION_PERMISSION_SERVICE, EXPIRY, type EnsData, EnsDataSchema, type EventEmitterStrategy, type ExpiryTier, type Extension, type FailClosedHostOptions, type FailClosedHosts, GenerateShareParams, ICapabilityKeyRegistry, type IENSResolver, type INotificationHandler, type ISessionManager, type ISessionStorage, ISharingService, type ISigner, type ISpace, type ISpaceCreationHandler, type ISpaceScopedDelegations, type ISpaceScopedSharing, type ISpaceService, type IUserAuthorization, type IWasmBindings, IdentityParseError, type ImmutableSiweFields, IssuedCredentialEnvelope, LOCAL_LINK_HOST_SUFFIX, LOCAL_LINK_PROBE_TIMEOUT_MS, LOCAL_LOOPBACK_PROBE_TIMEOUT_MS, type LocalNodeIdentityStore, type LocationCandidate, type LocationCandidateInput, type LocationRecord, type LocationRecordPayload, type LocationRecordSigner, LocationRecordValidationError, LocationRegistryHttpError, type LocationResolutionAttempt, type LocationSource, type LookupOwnerRegistryVerdictOptions, MAX_SIWE_EXPIRY_MS, MAX_UCAN_EXPIRY_MS, type Manifest, type ManifestDefaults, type ManifestKnowledge, type ManifestRegistryRecord, type ManifestSecretActions, ManifestValidationError, type NodeInfo, type NodeNotFoundContext, type NodeNotFoundDecision, NodeNotFoundError, NodeRegistryEntryExistsError, OPENKEY_ACTION_ID_SEPARATOR, OWNER_NODE_BINDING_TIMEOUT_MS, type OnNodeNotFound, type OpenKeyCallbackStrategy, type OpenKeyManageKeyCallbackStrategy, OpenKeyManageKeyError, type OpenKeyManageKeyErrorCode, type OpenKeyManageKeyFetch, type OpenKeyManageKeySigningRequestBody, type OpenKeyManageKeySigningResponseBody, type OpenKeyManageKeySigningStrategyOptions, type OpenKeySigningRequestBody, type OpenKeySigningResponseBody, type OpenKeySigningStrategyOptions, type ParseRecapFromSiwe, type PartialSiweMessage, type PermissionEntry, PermissionNotInManifestError, type PersistedSessionData, type PersistedSessionProof, type PersistedTinyCloudSession, type PkhDidParts, ProtocolMismatchError, type PublishLocationRecordOptions, REGISTRY_LOOKUP_MAX_BODY_BYTES, REGISTRY_NOT_FOUND_BODY, type RecapAttenuation, type RegisterBatchSuccess, type RegisteredRegistryVerdict, type RegistryHost, type RegistryHostSource, RegistryLookupInputError, type RegistryLookupInputErrorCode, type RegistryLookupResponse, type RegistryPolicy, type RegistrySequenceStore, RegistryUnavailableError, type RegistryUnavailableReason, type RegistryVerdict, type RegistryVerdictSource, type RegistryVerdictStatus, type ResolveCloudLocationOptions, type ResolveOwnerHostsOptions, type ResolveTinyCloudHostsOptions, type ResolvedCapabilities, type ResolvedCloudLocation, type ResolvedDelegate, type ResolvedTinyCloudHosts, type ResourceCapability, SECRETS_SPACE, SERVICE_LONG_TO_SHORT, SERVICE_SHORT_TO_LONG, type ServerHost, SessionExpiredError, ShareLink, type SignCallback, type SignInOptions, type SignRequest, type SignResponse, type SignStrategy, type SignedSiweCacao, SilentNotificationHandler, type SiweConfig, SiweConfigSchema, Space, type SpaceAbilitiesMap, type SpaceConfig, type SpaceCreationContext, type SpaceDelegationParams, type SpaceErrorCode, SpaceErrorCodes, type SpaceHostResult, SpaceInfo, SpaceService, type SpaceServiceConfig, StoredCredentialRecord, type SubsetCheckResult, TERMINAL_DELEGATION_FACT, TINYCLOUD_CANONICAL_IDENTITY_CLAIM, TINYCLOUD_MANAGE_KEY_SCOPE, type TechnicalExpiryKind, type TerminalDelegationSigningKey, TicketHolderBinding, TinyCloud, type TinyCloudAuthorizationRequestV1, type TinyCloudAuthorizationResultV1, type TinyCloudConfig, type TinyCloudEffectiveGrantV1, type TinyCloudSession, type UnavailableRegistryVerdict, type UnregisteredRegistryVerdict, UnsupportedFeatureError, type UserAuthorizationConfig, VAULT_PERMISSION_SERVICE, type ValidatedPersistedSessionProof, type ValidationError, VerifiedCredential, type VerifiedOwnerNodeBinding, type VerifyOwnerNodeBindingOptions, VersionCheckError, type WasmRecapEntry, type WebStorageLike, actionContains, activateSessionWithHost, addressStorageKey, applyPrefix, assertExpiryWithinTechnicalLimit, assertSpaceCreationAllowed, buildSpaceUri, canonicalDigest, canonicalLocationPayload, canonicalizeAddress, canonicalizeDid, canonicalizeDidUrl, canonicalizeNetworkId, canonicalizeRecapCaveats, checkChangedExpiration, checkNodeInfo, classifyRegistryLookup, composeManifestRequest, createEmailCredentialRequirement, createEmailDomainCredentialRequirement, createHolderBinding, createInMemoryLocalNodeIdentityStore, createInMemoryRegistrySequenceStore, createLocalStorageLocalNodeIdentityStore, createLocalStorageRegistrySequenceStore, createOpenKeyCallbackSigningStrategy, createOpenKeyManageKeySigningStrategy, createSpaceService, createStorageReceipt, createStoredCredentialRecord, credentialEndpointPath, credentialError, credentialIndexKey, credentialMatchesRequirement, credentialRecordKey, credentialRequirementDigest, decodeBase64Url, defaultSignStrategy, defaultSpaceCreationHandler, descriptorSatisfiesRequirement, didCacheKey, didEquals, diffImmutableSiweFields, discoverLocalTinyCloudNode, encodeBase64Url, expandActionShortNames, expandDelegationPermissionEntries, expandPermissionEntries, expandPermissionEntry, expandRuntimePermissionEntries, extractImmutableSiweFields, extractRecapAttenuations, fetchLocationRecord, fetchPeerId, hasTinyCloudManageKeyScope, holderBindingCanonicalBytes, holderBindingSigningBytes, httpResponseError, httpUrlToMultiaddr, isCapabilitySubset, isDigest, isEvmAddress, isExplicitOnlyAction, isPlausibleOpenKeyActionId, loadManifest, locationPayloadForRecord, lookupOwnerRegistryVerdict, makePkhSpaceId, makePublicSpaceId, manifestAbilitiesUnion, markDelegationTerminal, multiaddrToHttpUrl, normalizeDefaults, parseCanonicalNetworkId, parseCanonicalRecapResource, parseCanonicalTinyCloudIdentity, parseCanonicalTinyCloudIdentityClaims, parseExpiry, parsePkhDid, parseRecapCapabilities, parseSignedSiweCacao, parseSpaceUri, pkhDid, principalDid, principalDidEquals, publishLocationRecord, recapCaveatsEqual, registryOwnerSubjectV1, requestTinyCloudManageKeyScope, resolveCloudLocation, resolveFailClosedTinyCloudHosts, resolveManifest, resolveManifestKnowledgeRoot, resolveOwnerHosts, resolveTinyCloudHosts, resourceCapabilitiesToAbilitiesMap, resourceCapabilitiesToSpaceAbilitiesMap, sha256Base64Url, signLocationRecord, submitHostDelegation, technicalExpiryRefusal, unauthorizedRecapCapabilities, validateAuthorizationResultV1, validateClientSession, validateCredentialFlowDescriptor, validateCredentialHolderBinding, validateCredentialRequirement, validateLocationRecord, validateLocationRecordPayload, validateManifest, validatePersistedSessionData, verifyDidKeyEd25519Signature, verifyEip191MessageSignature, verifyIssuedCredential, verifyLocationRecord, verifyOwnerNodeBinding, verifyStorageReceipt };
package/dist/index.js CHANGED
@@ -10617,15 +10617,27 @@ var SIGNED_READ_URL_MS = 5 * 60 * 1e3;
10617
10617
  var SESSION_MS = 30 * 24 * 60 * 60 * 1e3;
10618
10618
  var SHARE_MS = 7 * 24 * 60 * 60 * 1e3;
10619
10619
  var APP_MS = 30 * 24 * 60 * 60 * 1e3;
10620
- var MAX_MS = 10 * 365 * 24 * 60 * 60 * 1e3;
10621
10620
  var EXPIRY = {
10622
10621
  EPHEMERAL_MS,
10623
10622
  SIGNED_READ_URL_MS,
10624
10623
  SESSION_MS,
10625
10624
  SHARE_MS,
10626
- APP_MS,
10627
- MAX_MS
10625
+ APP_MS
10628
10626
  };
10627
+ var MAX_SIWE_EXPIRY_MS = 253402300799e3;
10628
+ var MAX_UCAN_EXPIRY_MS = 9007199254e3;
10629
+ function technicalExpiryRefusal(expiresAt, kind) {
10630
+ const ms2 = Number(expiresAt);
10631
+ const siwe = kind === "siwe";
10632
+ const last = siwe ? "9999-12-31" : "2255-06-05";
10633
+ if (!Number.isFinite(ms2) || ms2 < 0) return `expiry is not a valid date or is too far away to hold; choose one before ${last}`;
10634
+ if (ms2 <= (siwe ? MAX_SIWE_EXPIRY_MS : MAX_UCAN_EXPIRY_MS)) return null;
10635
+ return `expiry is later than ${last}, ${siwe ? "the latest date a TinyCloud signed message can carry" : "the latest date an agent or share delegation can carry (UCAN limit); a delegation signed by the wallet (delegateTo with forceWalletSign: true) can go to 9999-12-31"}; choose an earlier expiry`;
10636
+ }
10637
+ function assertExpiryWithinTechnicalLimit(expiresAt, kind) {
10638
+ const refusal = technicalExpiryRefusal(expiresAt, kind);
10639
+ if (refusal) throw new Error(refusal);
10640
+ }
10629
10641
  var DEFAULT_SIGNED_READ_URL_EXPIRY_MS = EXPIRY.SIGNED_READ_URL_MS;
10630
10642
 
10631
10643
  // src/delegations/SharingService.ts
@@ -16298,7 +16310,7 @@ function diffImmutableSiweFields(original, signed, options2) {
16298
16310
  "requestId",
16299
16311
  "nonRecapResources"
16300
16312
  ];
16301
- const keys = options2?.originalHasRecap ? baseKeys : [...baseKeys, "statement"];
16313
+ const keys = (options2?.originalHasRecap ? baseKeys : [...baseKeys, "statement"]).filter((key) => !(options2?.allowExpirationChange === true && key === "expirationTime"));
16302
16314
  const diffs = [];
16303
16315
  for (const key of keys) {
16304
16316
  const a = original[key] ?? "";
@@ -16309,6 +16321,62 @@ function diffImmutableSiweFields(original, signed, options2) {
16309
16321
  }
16310
16322
  return diffs;
16311
16323
  }
16324
+ var CHANGED_EXPIRY_MIN_REMAINING_MS = 6e4;
16325
+ var ISO_INSTANT = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/;
16326
+ function parseInstantMs(value) {
16327
+ const match = value === void 0 ? null : ISO_INSTANT.exec(value);
16328
+ if (!match || value === void 0) return void 0;
16329
+ const [year, month, day] = [Number(match[1]), Number(match[2]), Number(match[3])];
16330
+ if (new Date(Date.UTC(year, month - 1, day)).getUTCDate() !== day) return void 0;
16331
+ const ms2 = Date.parse(value);
16332
+ return Number.isFinite(ms2) ? ms2 : void 0;
16333
+ }
16334
+ var EXPIRATION_LINE = /^Expiration Time:/;
16335
+ function hasCanonicalExpirationLine(siwe) {
16336
+ if (siwe.includes("\r")) return false;
16337
+ const lines = siwe.split("\n");
16338
+ const index = lines.findIndex((line) => EXPIRATION_LINE.test(line));
16339
+ if (index < 0 || !/^Expiration Time: \S+$/.test(lines[index])) return false;
16340
+ const resources = lines.indexOf("Resources:", 4);
16341
+ return resources < 0 || index < resources;
16342
+ }
16343
+ function checkChangedExpiration(input) {
16344
+ const nowMs = input.now instanceof Date ? input.now.getTime() : input.now;
16345
+ if (!Number.isFinite(nowMs)) return "expiry check needs a finite current time";
16346
+ const maxMs = input.maxExpiresAt === void 0 ? void 0 : input.maxExpiresAt instanceof Date ? input.maxExpiresAt.getTime() : input.maxExpiresAt;
16347
+ if (maxMs !== void 0 && !Number.isFinite(new Date(maxMs).getTime())) return "expiry check needs a finite maximum";
16348
+ const originalHasRecap = input.originalHasRecap ?? /(?:^|\n)-\s+urn:recap:/i.test(input.preparedSiwe);
16349
+ const countLines = (siwe) => siwe.split(/\r?\n/).filter((line) => EXPIRATION_LINE.test(line)).length;
16350
+ if (countLines(input.preparedSiwe) !== 1 || countLines(input.signedSiwe) !== 1) {
16351
+ return "expiry check needs exactly one Expiration Time line in both messages";
16352
+ }
16353
+ if (!hasCanonicalExpirationLine(input.signedSiwe)) {
16354
+ return "the Expiration Time line is not in canonical SIWE form";
16355
+ }
16356
+ const prepared = extractImmutableSiweFields(input.preparedSiwe);
16357
+ const signed = extractImmutableSiweFields(input.signedSiwe);
16358
+ const drift = diffImmutableSiweFields(prepared, signed, { originalHasRecap, allowExpirationChange: true });
16359
+ if (drift.length > 0) return `altered immutable SIWE fields: ${drift.join(", ")}`;
16360
+ if (signed.expirationTime === prepared.expirationTime) return null;
16361
+ const expiresAt = parseInstantMs(signed.expirationTime);
16362
+ if (expiresAt === void 0) {
16363
+ const later = Date.parse(signed.expirationTime ?? "");
16364
+ return later > MAX_SIWE_EXPIRY_MS ? technicalExpiryRefusal(later, "siwe") : "expiry is not a valid timestamp";
16365
+ }
16366
+ if (expiresAt <= nowMs + CHANGED_EXPIRY_MIN_REMAINING_MS) {
16367
+ return "expiry must be more than 60 seconds from now; choose a longer expiry";
16368
+ }
16369
+ for (const [label, value] of [["Issued At", prepared.issuedAt], ["Not Before", prepared.notBefore]]) {
16370
+ if (value === void 0 || value === "") continue;
16371
+ const bound = parseInstantMs(value);
16372
+ if (bound === void 0) return `${label} is not a valid timestamp`;
16373
+ if (expiresAt <= bound) return `expiry must be after ${label}; choose a later expiry`;
16374
+ }
16375
+ if (maxMs !== void 0 && expiresAt > maxMs) {
16376
+ return `expiry is later than the maximum for this request (the latest allowed is ${new Date(maxMs).toISOString()}); choose an earlier expiry`;
16377
+ }
16378
+ return technicalExpiryRefusal(expiresAt, "siwe");
16379
+ }
16312
16380
  function extractRecapAttenuations(siwe) {
16313
16381
  const merged = {};
16314
16382
  const lines = siwe.split(/\r?\n/);
@@ -19813,6 +19881,8 @@ export {
19813
19881
  MAX_SECRET_SCOPE_LENGTH,
19814
19882
  MAX_SHARE_ARTIFACT_BYTES,
19815
19883
  MAX_SHARE_CONTENT_BYTES,
19884
+ MAX_SIWE_EXPIRY_MS,
19885
+ MAX_UCAN_EXPIRY_MS,
19816
19886
  ManifestValidationError,
19817
19887
  MemorySenderShareKeyStorage,
19818
19888
  MemorySenderShareRecordStorage,
@@ -19932,6 +20002,7 @@ export {
19932
20002
  admitPolicyCredentialV4,
19933
20003
  appSecretScope,
19934
20004
  applyPrefix,
20005
+ assertExpiryWithinTechnicalLimit,
19935
20006
  assertSpaceCreationAllowed,
19936
20007
  authorizationVerdictOf2 as authorizationVerdictOf,
19937
20008
  bootstrapEncryptionNetworkId,
@@ -19961,6 +20032,7 @@ export {
19961
20032
  canonicalizeSecretScope,
19962
20033
  canonicalizeSignedObjectUnsigned,
19963
20034
  canonicalizeUnifiedPolicyCapability,
20035
+ checkChangedExpiration,
19964
20036
  checkDecryptInvocationInput,
19965
20037
  checkNodeInfo,
19966
20038
  classifyRegistryLookup,
@@ -20148,6 +20220,7 @@ export {
20148
20220
  signedObjectIdFor,
20149
20221
  storageUsageState,
20150
20222
  submitHostDelegation,
20223
+ technicalExpiryRefusal,
20151
20224
  tinyCloudDebugLogger,
20152
20225
  toSignedObjectError,
20153
20226
  unauthorizedRecapCapabilities,