@bsv/message-box-client 2.0.3 → 2.0.4

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": "@bsv/message-box-client",
3
- "version": "2.0.3",
3
+ "version": "2.0.4",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -521,7 +521,29 @@ export class MessageBoxClient {
521
521
  } catch (err) {
522
522
  Logger.error('[MB CLIENT ERROR] _queryAdvertisements failed:', err)
523
523
  }
524
- return hosts
524
+ return hosts.filter(item => {
525
+ const h = item.host.trim().toLowerCase()
526
+ if (!h) return false
527
+ try {
528
+ const url = new URL(h)
529
+ if (url.protocol !== 'https:') return false
530
+ const hostname = url.hostname
531
+ if (
532
+ hostname === 'localhost' ||
533
+ hostname === '127.0.0.1' ||
534
+ hostname === '0.0.0.0' ||
535
+ hostname === '::1' ||
536
+ hostname.endsWith('.local') ||
537
+ hostname.endsWith('.example.com') ||
538
+ hostname.endsWith('.test') ||
539
+ hostname.endsWith('.invalid') ||
540
+ hostname.endsWith('.localhost')
541
+ ) return false
542
+ return true
543
+ } catch {
544
+ return false
545
+ }
546
+ })
525
547
  }
526
548
 
527
549
  /**
@@ -1137,14 +1159,14 @@ export class MessageBoxClient {
1137
1159
  throw new Error('Missing delivery agent identity keys in quote response.')
1138
1160
  }
1139
1161
  if (Object.keys(deliveryAgentIdentityKeyByHost).length > 1 && !overrideHost) {
1140
- // To keep the single-POST invariant, we require all recipients to share a host
1162
+ // To keep the single-POST invariant, we require all recipients to share a host
1141
1163
  throw new Error('Recipients resolve to multiple hosts. Use overrideHost to force a single server or split by host.')
1142
1164
  }
1143
1165
 
1144
1166
  // pick the host to POST to
1145
1167
  const finalHost = (overrideHost ?? await this.resolveHostForRecipient(allowedRecipients[0])).replace(/\/+$/, '')
1146
1168
  const singleDeliveryKey = deliveryAgentIdentityKeyByHost[finalHost] ??
1147
- Object.values(deliveryAgentIdentityKeyByHost)[0]
1169
+ Object.values(deliveryAgentIdentityKeyByHost)[0]
1148
1170
 
1149
1171
  if (!singleDeliveryKey) {
1150
1172
  throw new Error('Could not determine server delivery agent identity key.')
@@ -1174,7 +1196,7 @@ export class MessageBoxClient {
1174
1196
  if (skipEncryption === true) {
1175
1197
  finalBody = typeof body === 'string' ? body : JSON.stringify(body)
1176
1198
  } else {
1177
- // safest for now: send plaintext; the recipients can decrypt payload fields client-side if needed
1199
+ // safest for now: send plaintext; the recipients can decrypt payload fields client-side if needed
1178
1200
  finalBody = typeof body === 'string' ? body : JSON.stringify(body)
1179
1201
  }
1180
1202
 
@@ -1217,18 +1239,18 @@ export class MessageBoxClient {
1217
1239
  const failed: Array<{ recipient: string, error: string }> = [] // handled server-side now
1218
1240
 
1219
1241
  const status: SendListResult['status'] =
1220
- sent.length === allowedRecipients.length
1221
- ? 'success'
1222
- : sent.length > 0
1223
- ? 'partial'
1224
- : 'error'
1242
+ sent.length === allowedRecipients.length
1243
+ ? 'success'
1244
+ : sent.length > 0
1245
+ ? 'partial'
1246
+ : 'error'
1225
1247
 
1226
1248
  const description =
1227
- status === 'success'
1228
- ? `Sent to ${sent.length} recipients.`
1229
- : status === 'partial'
1230
- ? `Sent to ${sent.length} recipients; ${allowedRecipients.length - sent.length} failed; ${blocked.length} blocked.`
1231
- : `Failed to send to ${allowedRecipients.length} allowed recipients. ${blocked.length} blocked.`
1249
+ status === 'success'
1250
+ ? `Sent to ${sent.length} recipients.`
1251
+ : status === 'partial'
1252
+ ? `Sent to ${sent.length} recipients; ${allowedRecipients.length - sent.length} failed; ${blocked.length} blocked.`
1253
+ : `Failed to send to ${allowedRecipients.length} allowed recipients. ${blocked.length} blocked.`
1232
1254
 
1233
1255
  return { status, description, sent, blocked, failed, totals }
1234
1256
  } catch (err) {
@@ -1755,7 +1777,7 @@ export class MessageBoxClient {
1755
1777
  }
1756
1778
  }
1757
1779
 
1758
- private async mapWithConcurrency<T, R> (
1780
+ private async mapWithConcurrency<T, R>(
1759
1781
  items: T[],
1760
1782
  limit: number,
1761
1783
  fn: (item: T, index: number) => Promise<R>
@@ -2071,7 +2093,7 @@ export class MessageBoxClient {
2071
2093
  params: GetQuoteParams,
2072
2094
  overrideHost?: string
2073
2095
  ): Promise<MessageBoxQuote | MessageBoxMultiQuote> {
2074
- // ---------- SINGLE RECIPIENT (back-compat) ----------
2096
+ // ---------- SINGLE RECIPIENT (back-compat) ----------
2075
2097
  if (!Array.isArray(params.recipient)) {
2076
2098
  const finalHost = overrideHost ?? await this.resolveHostForRecipient(params.recipient)
2077
2099
  const queryParams = new URLSearchParams({
@@ -2082,14 +2104,14 @@ export class MessageBoxClient {
2082
2104
  Logger.log('[MB CLIENT] Getting messageBox quote (single)...')
2083
2105
  console.log('HELP IM QUOTING', `${finalHost}/permissions/quote?${queryParams.toString()}`)
2084
2106
  const response = await this.authFetch.fetch(
2085
- `${finalHost}/permissions/quote?${queryParams.toString()}`,
2086
- { method: 'GET' }
2107
+ `${finalHost}/permissions/quote?${queryParams.toString()}`,
2108
+ { method: 'GET' }
2087
2109
  )
2088
2110
  console.log('server response from getquote]', response)
2089
2111
  if (!response.ok) {
2090
2112
  const errorData = await response.json().catch(() => ({}))
2091
2113
  throw new Error(
2092
- `Failed to get quote: HTTP ${response.status} - ${String(errorData.description) ?? response.statusText}`
2114
+ `Failed to get quote: HTTP ${response.status} - ${String(errorData.description) ?? response.statusText}`
2093
2115
  )
2094
2116
  }
2095
2117
 
@@ -2162,7 +2184,7 @@ export class MessageBoxClient {
2162
2184
  if (!resp.ok) {
2163
2185
  const errorData = await resp.json().catch(() => ({}))
2164
2186
  throw new Error(
2165
- `Failed to get quote (host ${host}): HTTP ${resp.status} - ${String(errorData.description) ?? resp.statusText}`
2187
+ `Failed to get quote (host ${host}): HTTP ${resp.status} - ${String(errorData.description) ?? resp.statusText}`
2166
2188
  )
2167
2189
  }
2168
2190
 
@@ -2177,7 +2199,7 @@ export class MessageBoxClient {
2177
2199
  // Server supports both shapes. For multi we expect:
2178
2200
  // { quotesByRecipient, totals, blockedRecipients }
2179
2201
  if (Array.isArray(payload?.quotesByRecipient)) {
2180
- // merge quotes
2202
+ // merge quotes
2181
2203
  for (const q of payload.quotesByRecipient) {
2182
2204
  quotesByRecipient.push({
2183
2205
  recipient: q.recipient,
@@ -2203,12 +2225,12 @@ export class MessageBoxClient {
2203
2225
  }
2204
2226
  }
2205
2227
  } else if (payload?.quote) {
2206
- // Defensive: if an overlay still returns single-quote shape for multi (shouldn’t),
2207
- // we map it to each recipient in the group uniformly.
2228
+ // Defensive: if an overlay still returns single-quote shape for multi (shouldn’t),
2229
+ // we map it to each recipient in the group uniformly.
2208
2230
  for (const r of groupRecipients) {
2209
2231
  const { deliveryFee, recipientFee } = payload.quote
2210
2232
  const status =
2211
- recipientFee === -1 ? 'blocked' : recipientFee === 0 ? 'always_allow' : 'payment_required'
2233
+ recipientFee === -1 ? 'blocked' : recipientFee === 0 ? 'always_allow' : 'payment_required'
2212
2234
  quotesByRecipient.push({
2213
2235
  recipient: r,
2214
2236
  messageBox: params.messageBox,