@wishknish/knishio-client-ts 1.1.0 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wishknish/knishio-client-ts",
3
- "version": "1.1.0",
3
+ "version": "1.2.1",
4
4
  "productName": "Knish.IO TypeScript SDK Client",
5
5
  "description": "TypeScript implementation of the Knish.IO SDK to consume Knish.IO GraphQL APIs with enhanced type safety.",
6
6
  "license": "GPL-3.0-or-later",
@@ -81,7 +81,11 @@
81
81
  "vitest": "^4.1.11"
82
82
  },
83
83
  "resolutions": {
84
- "wonka": "6.3.6"
84
+ "wonka": "6.3.6",
85
+ "esbuild": "^0.28.1"
86
+ },
87
+ "overrides": {
88
+ "esbuild": "^0.28.1"
85
89
  },
86
90
  "browserslist": [
87
91
  "> 1%",
@@ -2572,6 +2572,7 @@ export default class KnishIOClient {
2572
2572
  pubkey: response.pubKey()
2573
2573
  }, wallet)
2574
2574
  this.setAuthToken(authToken)
2575
+ this.lastMoleculeQuery = null
2575
2576
  } else {
2576
2577
  throw new AuthorizationRejectedException(
2577
2578
  `KnishIOClient::requestProfileAuthToken() - Authorization attempt rejected by ledger. Reason: ${response.reason()}`
package/src/index.ts CHANGED
@@ -403,7 +403,7 @@ export {
403
403
  // MUST equal package.json's "version". The CI `version consistency` job enforces this via
404
404
  // .github/scripts/check-version.sh, which parses this exact line — keep the literal form
405
405
  // `export const SDK_VERSION = '<semver>'` intact so the gate can read it.
406
- export const SDK_VERSION = '1.1.0'
406
+ export const SDK_VERSION = '1.2.1'
407
407
  export const SDK_NAME = 'KnishIO-Client-TS'
408
408
  export const COMPATIBLE_SERVER_VERSIONS = [4, 5]
409
409
 
@@ -55,6 +55,7 @@ import {
55
55
  } from '@urql/core'
56
56
  import { createClient as createWSClient } from 'graphql-ws'
57
57
  import { pipe, subscribe } from 'wonka'
58
+ import { CodeException } from '@/exception'
58
59
  import type {
59
60
  GraphQLClient as IGraphQLClient,
60
61
  GraphQLRequest,
@@ -200,17 +201,29 @@ export default class GraphQLClient implements IGraphQLClient {
200
201
  private async cipherFetch(input: any, init: any): Promise<Response> {
201
202
  const wallet = this.$__wallet
202
203
  const serverPubkey = this.$__pubkey
203
- let encryptedRequest = false
204
+ // Non-null only on the encrypted path, so the response decrypt needs no assertion.
205
+ let cipherWallet: Wallet | null = null
204
206
  let requestInit = init
205
207
 
206
- if (wallet && serverPubkey && init && typeof init.body === 'string' && this.shouldEncrypt(init.body)) {
208
+ // Decide the bypass FIRST, then demand the keys: a bypassed operation (`__schema`,
209
+ // `ContinuId`, `AccessToken`, U-isotope `ProposeMolecule`) must still go out in plaintext or
210
+ // the auth bootstrap would deadlock encrypting to a server pubkey it has not learned yet.
211
+ // Anything else on an encryption-enabled client fails closed rather than silently
212
+ // downgrading to plaintext (matches PHP Cipher.php / Kotlin HttpClient).
213
+ if (init && typeof init.body === 'string' && this.shouldEncrypt(init.body)) {
214
+ if (!wallet) {
215
+ throw new CodeException('Authorized wallet missing.')
216
+ }
217
+ if (!serverPubkey) {
218
+ throw new CodeException('Server public key missing.')
219
+ }
207
220
  const hashVar = await wallet.encryptStringML(init.body, serverPubkey)
208
221
  requestInit = { ...init, body: JSON.stringify({ query: CIPHER_HASH_QUERY, variables: { Hash: hashVar } }) }
209
- encryptedRequest = true
222
+ cipherWallet = wallet
210
223
  }
211
224
 
212
225
  const response = await fetch(input, requestInit)
213
- if (!encryptedRequest) {
226
+ if (!cipherWallet) {
214
227
  return response
215
228
  }
216
229
 
@@ -228,7 +241,7 @@ export default class GraphQLClient implements IGraphQLClient {
228
241
  // Plaintext (e.g. a validator-side error response) — pass through unchanged.
229
242
  return new Response(text, init2)
230
243
  }
231
- const decrypted = await wallet!.decryptMyMessageML(JSON.parse(hash))
244
+ const decrypted = await cipherWallet.decryptMyMessageML(JSON.parse(hash))
232
245
  return new Response(decrypted != null ? decrypted : text, init2)
233
246
  }
234
247
 
@@ -169,7 +169,8 @@ export default class ResponseProposeMolecule extends Response {
169
169
  code: 'HASH_MISMATCH'
170
170
  })
171
171
  }
172
- if (/ots.*position.*reuse|position.*already.*used|ots.*verification/.test(lc)) {
172
+ // Validator 0.5.0 words the same rejection as "OTS key reuse rejected ... is already consumed".
173
+ if (/ots.*(?:position|key).*reuse|position.*already.*(?:used|consumed)|ots.*verification/.test(lc)) {
173
174
  return new SignatureMismatchException(reason, {
174
175
  details: { reason },
175
176
  code: 'OTS_VERIFICATION_FAILED'