@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/dist/cjs/package.json +1 -1
- package/dist/cjs/src/MessageBoxClient.js +25 -1
- package/dist/cjs/src/MessageBoxClient.js.map +1 -1
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/src/MessageBoxClient.js +25 -1
- package/dist/esm/src/MessageBoxClient.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/types/src/MessageBoxClient.d.ts.map +1 -1
- package/dist/types/tsconfig.types.tsbuildinfo +1 -1
- package/dist/umd/bundle.js +1 -1
- package/package.json +1 -1
- package/src/MessageBoxClient.ts +46 -24
package/package.json
CHANGED
package/src/MessageBoxClient.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1242
|
+
sent.length === allowedRecipients.length
|
|
1243
|
+
? 'success'
|
|
1244
|
+
: sent.length > 0
|
|
1245
|
+
? 'partial'
|
|
1246
|
+
: 'error'
|
|
1225
1247
|
|
|
1226
1248
|
const description =
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2086
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2207
|
-
|
|
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
|
-
|
|
2233
|
+
recipientFee === -1 ? 'blocked' : recipientFee === 0 ? 'always_allow' : 'payment_required'
|
|
2212
2234
|
quotesByRecipient.push({
|
|
2213
2235
|
recipient: r,
|
|
2214
2236
|
messageBox: params.messageBox,
|