@tinycloud/sdk-core 3.10.0 → 3.11.0-beta.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.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,55 @@ 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 within ten years
2102
+ * (`EXPIRY.MAX_MS`).
2103
+ *
2104
+ * An unchanged expiry passes the expiry rules. The ReCap subset check and the
2105
+ * rest of the result verification stay with the caller and are not relaxed.
2106
+ */
2107
+ declare function checkChangedExpiration(input: CheckChangedExpirationInput): string | null;
2055
2108
  /**
2056
2109
  * Parsed ReCap attenuation payload. Keyed by resource URI ("space/service/path"),
2057
2110
  * each value is a map of action -> list of caveat objects. Consumers care about
@@ -3982,4 +4035,4 @@ declare const EXPIRY: {
3982
4035
  declare const DEFAULT_SIGNED_READ_URL_EXPIRY_MS: number;
3983
4036
  type ExpiryTier = keyof typeof EXPIRY;
3984
4037
 
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 };
4038
+ 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, 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, 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, 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,55 @@ 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 within ten years
2102
+ * (`EXPIRY.MAX_MS`).
2103
+ *
2104
+ * An unchanged expiry passes the expiry rules. The ReCap subset check and the
2105
+ * rest of the result verification stay with the caller and are not relaxed.
2106
+ */
2107
+ declare function checkChangedExpiration(input: CheckChangedExpirationInput): string | null;
2055
2108
  /**
2056
2109
  * Parsed ReCap attenuation payload. Keyed by resource URI ("space/service/path"),
2057
2110
  * each value is a map of action -> list of caveat objects. Consumers care about
@@ -3982,4 +4035,4 @@ declare const EXPIRY: {
3982
4035
  declare const DEFAULT_SIGNED_READ_URL_EXPIRY_MS: number;
3983
4036
  type ExpiryTier = keyof typeof EXPIRY;
3984
4037
 
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 };
4038
+ 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, 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, 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, unauthorizedRecapCapabilities, validateAuthorizationResultV1, validateClientSession, validateCredentialFlowDescriptor, validateCredentialHolderBinding, validateCredentialRequirement, validateLocationRecord, validateLocationRecordPayload, validateManifest, validatePersistedSessionData, verifyDidKeyEd25519Signature, verifyEip191MessageSignature, verifyIssuedCredential, verifyLocationRecord, verifyOwnerNodeBinding, verifyStorageReceipt };
package/dist/index.js CHANGED
@@ -16298,7 +16298,7 @@ function diffImmutableSiweFields(original, signed, options2) {
16298
16298
  "requestId",
16299
16299
  "nonRecapResources"
16300
16300
  ];
16301
- const keys = options2?.originalHasRecap ? baseKeys : [...baseKeys, "statement"];
16301
+ const keys = (options2?.originalHasRecap ? baseKeys : [...baseKeys, "statement"]).filter((key) => !(options2?.allowExpirationChange === true && key === "expirationTime"));
16302
16302
  const diffs = [];
16303
16303
  for (const key of keys) {
16304
16304
  const a = original[key] ?? "";
@@ -16309,6 +16309,62 @@ function diffImmutableSiweFields(original, signed, options2) {
16309
16309
  }
16310
16310
  return diffs;
16311
16311
  }
16312
+ var CHANGED_EXPIRY_MIN_REMAINING_MS = 6e4;
16313
+ var ISO_INSTANT = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/;
16314
+ function parseInstantMs(value) {
16315
+ const match = value === void 0 ? null : ISO_INSTANT.exec(value);
16316
+ if (!match || value === void 0) return void 0;
16317
+ const [year, month, day] = [Number(match[1]), Number(match[2]), Number(match[3])];
16318
+ if (new Date(Date.UTC(year, month - 1, day)).getUTCDate() !== day) return void 0;
16319
+ const ms2 = Date.parse(value);
16320
+ return Number.isFinite(ms2) ? ms2 : void 0;
16321
+ }
16322
+ var EXPIRATION_LINE = /^Expiration Time:/;
16323
+ function hasCanonicalExpirationLine(siwe) {
16324
+ if (siwe.includes("\r")) return false;
16325
+ const lines = siwe.split("\n");
16326
+ const index = lines.findIndex((line) => EXPIRATION_LINE.test(line));
16327
+ if (index < 0 || !/^Expiration Time: \S+$/.test(lines[index])) return false;
16328
+ const resources = lines.indexOf("Resources:", 4);
16329
+ return resources < 0 || index < resources;
16330
+ }
16331
+ function checkChangedExpiration(input) {
16332
+ const nowMs = input.now instanceof Date ? input.now.getTime() : input.now;
16333
+ if (!Number.isFinite(nowMs)) return "expiry check needs a finite current time";
16334
+ const maxMs = input.maxExpiresAt === void 0 ? void 0 : input.maxExpiresAt instanceof Date ? input.maxExpiresAt.getTime() : input.maxExpiresAt;
16335
+ if (maxMs !== void 0 && !Number.isFinite(new Date(maxMs).getTime())) return "expiry check needs a finite maximum";
16336
+ const originalHasRecap = input.originalHasRecap ?? /(?:^|\n)-\s+urn:recap:/i.test(input.preparedSiwe);
16337
+ const countLines = (siwe) => siwe.split(/\r?\n/).filter((line) => EXPIRATION_LINE.test(line)).length;
16338
+ if (countLines(input.preparedSiwe) !== 1 || countLines(input.signedSiwe) !== 1) {
16339
+ return "expiry check needs exactly one Expiration Time line in both messages";
16340
+ }
16341
+ if (!hasCanonicalExpirationLine(input.signedSiwe)) {
16342
+ return "the Expiration Time line is not in canonical SIWE form";
16343
+ }
16344
+ const prepared = extractImmutableSiweFields(input.preparedSiwe);
16345
+ const signed = extractImmutableSiweFields(input.signedSiwe);
16346
+ const drift = diffImmutableSiweFields(prepared, signed, { originalHasRecap, allowExpirationChange: true });
16347
+ if (drift.length > 0) return `altered immutable SIWE fields: ${drift.join(", ")}`;
16348
+ if (signed.expirationTime === prepared.expirationTime) return null;
16349
+ const expiresAt = parseInstantMs(signed.expirationTime);
16350
+ if (expiresAt === void 0) return "expiry is not a valid timestamp";
16351
+ if (expiresAt <= nowMs + CHANGED_EXPIRY_MIN_REMAINING_MS) {
16352
+ return "expiry must be more than 60 seconds from now; choose a longer expiry";
16353
+ }
16354
+ for (const [label, value] of [["Issued At", prepared.issuedAt], ["Not Before", prepared.notBefore]]) {
16355
+ if (value === void 0 || value === "") continue;
16356
+ const bound = parseInstantMs(value);
16357
+ if (bound === void 0) return `${label} is not a valid timestamp`;
16358
+ if (expiresAt <= bound) return `expiry must be after ${label}; choose a later expiry`;
16359
+ }
16360
+ if (maxMs !== void 0 && expiresAt > maxMs) {
16361
+ return `expiry is later than the maximum for this request (the latest allowed is ${new Date(maxMs).toISOString()}); choose an earlier expiry`;
16362
+ }
16363
+ if (expiresAt > nowMs + EXPIRY.MAX_MS) {
16364
+ return "expiry is more than 10 years away, the longest this SDK accepts; choose a shorter expiry";
16365
+ }
16366
+ return null;
16367
+ }
16312
16368
  function extractRecapAttenuations(siwe) {
16313
16369
  const merged = {};
16314
16370
  const lines = siwe.split(/\r?\n/);
@@ -19961,6 +20017,7 @@ export {
19961
20017
  canonicalizeSecretScope,
19962
20018
  canonicalizeSignedObjectUnsigned,
19963
20019
  canonicalizeUnifiedPolicyCapability,
20020
+ checkChangedExpiration,
19964
20021
  checkDecryptInvocationInput,
19965
20022
  checkNodeInfo,
19966
20023
  classifyRegistryLookup,