@bandeira-tech/b3nd-web 0.3.4 → 0.5.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.
@@ -48,9 +48,15 @@ var HttpClient = class {
48
48
  try {
49
49
  const { protocol, domain, path } = this.parseUri(uri);
50
50
  const requestPath = `/api/v1/write/${protocol}/${domain}${path}`;
51
+ const isBinary = value instanceof Uint8Array;
52
+ const body = isBinary ? value : JSON.stringify({ value });
53
+ const contentType = isBinary ? "application/octet-stream" : "application/json";
51
54
  const response = await this.request(requestPath, {
52
55
  method: "POST",
53
- body: JSON.stringify({ value })
56
+ body,
57
+ headers: {
58
+ "Content-Type": contentType
59
+ }
54
60
  });
55
61
  const result = await response.json();
56
62
  if (!response.ok) {
@@ -90,6 +96,16 @@ var HttpClient = class {
90
96
  error: `Read failed: ${response.statusText}`
91
97
  };
92
98
  }
99
+ const contentType = response.headers.get("Content-Type") || "";
100
+ const isBinary = contentType === "application/octet-stream" || contentType.startsWith("image/") || contentType.startsWith("audio/") || contentType.startsWith("video/") || contentType.startsWith("font/") || contentType === "application/wasm";
101
+ if (isBinary) {
102
+ const buffer = await response.arrayBuffer();
103
+ const data = new Uint8Array(buffer);
104
+ return {
105
+ success: true,
106
+ record: { data, ts: Date.now() }
107
+ };
108
+ }
93
109
  const result = await response.json();
94
110
  return {
95
111
  success: true,
@@ -5,12 +5,11 @@ import {
5
5
  decrypt,
6
6
  encodeHex,
7
7
  encrypt,
8
- verify,
9
8
  verifyPayload
10
9
  } from "./chunk-JN75UL5C.js";
11
10
  import {
12
11
  HttpClient
13
- } from "./chunk-OY4CDOHY.js";
12
+ } from "./chunk-32YBATXQ.js";
14
13
 
15
14
  // wallet-server/interfaces.ts
16
15
  var defaultLogger = {
@@ -1407,28 +1406,16 @@ var WalletServerCore = class {
1407
1406
  if (!res.success) {
1408
1407
  return { valid: false, reason: "session_not_approved" };
1409
1408
  }
1410
- if (res.record?.data === 1) {
1409
+ const data = res.record?.data;
1410
+ const status = typeof data === "object" && data !== null && "payload" in data ? data.payload : data;
1411
+ if (status === 1) {
1411
1412
  return { valid: true };
1412
1413
  }
1413
- if (res.record?.data === 0) {
1414
+ if (status === 0) {
1414
1415
  return { valid: false, reason: "session_revoked" };
1415
1416
  }
1416
1417
  return { valid: false, reason: "invalid_session_status" };
1417
1418
  }
1418
- /**
1419
- * Verify that a login request signature is valid for the given session pubkey.
1420
- * The signature should be over the stringified login payload (without the signature field).
1421
- * Uses SDK crypto for consistent verification across the codebase.
1422
- */
1423
- async verifySessionSignature(sessionPubkey, signature, payload) {
1424
- try {
1425
- const { sessionSignature: _, ...signedPayload } = payload;
1426
- return await verify(sessionPubkey, signature, signedPayload);
1427
- } catch (error) {
1428
- this.logger.error("Session signature verification failed:", error);
1429
- return false;
1430
- }
1431
- }
1432
1419
  createApp() {
1433
1420
  const app = new Hono();
1434
1421
  const serverPublicKey = this.serverKeys.identityKey.publicKeyHex;
@@ -1525,40 +1512,38 @@ var WalletServerCore = class {
1525
1512
  app.post("/api/v1/auth/signup/:appKey", async (c) => {
1526
1513
  try {
1527
1514
  const appKey = c.req.param("appKey");
1528
- const payload = await c.req.json();
1515
+ const message = await c.req.json();
1529
1516
  if (!appKey) {
1530
1517
  return c.json({ success: false, error: "appKey is required" }, 400);
1531
1518
  }
1532
- if (!payload.sessionPubkey) {
1533
- return c.json({ success: false, error: "sessionPubkey is required" }, 400);
1519
+ if (!message.auth?.[0]?.pubkey) {
1520
+ return c.json({ success: false, error: "auth[0].pubkey (session public key) is required" }, 400);
1534
1521
  }
1535
- if (!payload.sessionSignature) {
1536
- return c.json({ success: false, error: "sessionSignature is required" }, 400);
1522
+ if (!message.auth?.[0]?.signature) {
1523
+ return c.json({ success: false, error: "auth[0].signature is required" }, 400);
1537
1524
  }
1538
- if (!payload.type) {
1525
+ if (!message.payload?.type) {
1539
1526
  return c.json({
1540
1527
  success: false,
1541
- error: `type is required. Supported: ${getSupportedCredentialTypes().join(", ")}`
1528
+ error: `payload.type is required. Supported: ${getSupportedCredentialTypes().join(", ")}`
1542
1529
  }, 400);
1543
1530
  }
1544
- const signatureValid = await this.verifySessionSignature(
1545
- payload.sessionPubkey,
1546
- payload.sessionSignature,
1547
- payload
1548
- );
1549
- if (!signatureValid) {
1531
+ const sessionPubkey = message.auth[0].pubkey;
1532
+ const credentials = message.payload;
1533
+ const { verified } = await verifyPayload({ payload: credentials, auth: message.auth });
1534
+ if (!verified) {
1550
1535
  return c.json({ success: false, error: "Invalid session signature" }, 401);
1551
1536
  }
1552
- const sessionResult = await this.sessionExists(appKey, payload.sessionPubkey);
1537
+ const sessionResult = await this.sessionExists(appKey, sessionPubkey);
1553
1538
  if (!sessionResult.valid) {
1554
1539
  return c.json({
1555
1540
  success: false,
1556
1541
  error: sessionResult.reason === "session_revoked" ? "Session has been revoked" : sessionResult.reason === "session_not_approved" ? "Session not approved by app" : "Invalid session"
1557
1542
  }, 401);
1558
1543
  }
1559
- const handler = getCredentialHandler(payload.type);
1544
+ const handler = getCredentialHandler(credentials.type);
1560
1545
  let googleClientId;
1561
- if (payload.type === "google") {
1546
+ if (credentials.type === "google") {
1562
1547
  const appProfileUri = `mutable://accounts/${appKey}/app-profile`;
1563
1548
  const appProfileResult = await this.credentialClient.read(appProfileUri);
1564
1549
  if (appProfileResult.success && appProfileResult.record?.data) {
@@ -1585,7 +1570,7 @@ var WalletServerCore = class {
1585
1570
  logger: this.logger,
1586
1571
  fetch: this.fetchImpl
1587
1572
  };
1588
- const result = await handler.signup(payload, context);
1573
+ const result = await handler.signup(credentials, context);
1589
1574
  const jwt = await createJwt(
1590
1575
  result.username,
1591
1576
  this.config.jwtSecret,
@@ -1613,40 +1598,38 @@ var WalletServerCore = class {
1613
1598
  app.post("/api/v1/auth/login/:appKey", async (c) => {
1614
1599
  try {
1615
1600
  const appKey = c.req.param("appKey");
1616
- const payload = await c.req.json();
1601
+ const message = await c.req.json();
1617
1602
  if (!appKey) {
1618
1603
  return c.json({ success: false, error: "appKey is required" }, 400);
1619
1604
  }
1620
- if (!payload.sessionPubkey) {
1621
- return c.json({ success: false, error: "sessionPubkey is required" }, 400);
1605
+ if (!message.auth?.[0]?.pubkey) {
1606
+ return c.json({ success: false, error: "auth[0].pubkey (session public key) is required" }, 400);
1622
1607
  }
1623
- if (!payload.sessionSignature) {
1624
- return c.json({ success: false, error: "sessionSignature is required" }, 400);
1608
+ if (!message.auth?.[0]?.signature) {
1609
+ return c.json({ success: false, error: "auth[0].signature is required" }, 400);
1625
1610
  }
1626
- if (!payload.type) {
1611
+ if (!message.payload?.type) {
1627
1612
  return c.json({
1628
1613
  success: false,
1629
- error: `type is required. Supported: ${getSupportedCredentialTypes().join(", ")}`
1614
+ error: `payload.type is required. Supported: ${getSupportedCredentialTypes().join(", ")}`
1630
1615
  }, 400);
1631
1616
  }
1632
- const signatureValid = await this.verifySessionSignature(
1633
- payload.sessionPubkey,
1634
- payload.sessionSignature,
1635
- payload
1636
- );
1637
- if (!signatureValid) {
1617
+ const sessionPubkey = message.auth[0].pubkey;
1618
+ const credentials = message.payload;
1619
+ const { verified } = await verifyPayload({ payload: credentials, auth: message.auth });
1620
+ if (!verified) {
1638
1621
  return c.json({ success: false, error: "Invalid session signature" }, 401);
1639
1622
  }
1640
- const sessionResult = await this.sessionExists(appKey, payload.sessionPubkey);
1623
+ const sessionResult = await this.sessionExists(appKey, sessionPubkey);
1641
1624
  if (!sessionResult.valid) {
1642
1625
  return c.json({
1643
1626
  success: false,
1644
1627
  error: sessionResult.reason === "session_revoked" ? "Session has been revoked" : sessionResult.reason === "session_not_approved" ? "Session not approved by app" : "Invalid session"
1645
1628
  }, 401);
1646
1629
  }
1647
- const handler = getCredentialHandler(payload.type);
1630
+ const handler = getCredentialHandler(credentials.type);
1648
1631
  let googleClientId;
1649
- if (payload.type === "google") {
1632
+ if (credentials.type === "google") {
1650
1633
  const appProfileUri = `mutable://accounts/${appKey}/app-profile`;
1651
1634
  const appProfileResult = await this.credentialClient.read(appProfileUri);
1652
1635
  if (appProfileResult.success && appProfileResult.record?.data) {
@@ -1673,7 +1656,7 @@ var WalletServerCore = class {
1673
1656
  logger: this.logger,
1674
1657
  fetch: this.fetchImpl
1675
1658
  };
1676
- const result = await handler.login(payload, context);
1659
+ const result = await handler.login(credentials, context);
1677
1660
  const jwt = await createJwt(
1678
1661
  result.username,
1679
1662
  this.config.jwtSecret,
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  WalletServerCore
3
- } from "./chunk-B4VAPGAO.js";
3
+ } from "./chunk-7PZMJECC.js";
4
4
  import {
5
+ createAuthenticatedMessageWithHex,
5
6
  exportPrivateKeyPem,
6
7
  generateEncryptionKeyPair,
7
- generateSigningKeyPair,
8
- signWithHex
8
+ generateSigningKeyPair
9
9
  } from "./chunk-JN75UL5C.js";
10
10
  import {
11
11
  MemoryClient,
@@ -143,31 +143,15 @@ var WalletClient = class {
143
143
  if (!session?.publicKeyHex || !session?.privateKeyHex) {
144
144
  throw new Error("session keypair is required");
145
145
  }
146
- let payloadToSign;
147
- if (credentials.type === "password") {
148
- payloadToSign = {
149
- sessionPubkey: session.publicKeyHex,
150
- type: "password",
151
- username: credentials.username,
152
- password: credentials.password
153
- };
154
- } else if (credentials.type === "google") {
155
- payloadToSign = {
156
- sessionPubkey: session.publicKeyHex,
157
- type: "google",
158
- googleIdToken: credentials.googleIdToken
159
- };
160
- } else {
161
- throw new Error(`Unknown credential type: ${credentials.type}`);
162
- }
163
- const sessionSignature = await signWithHex(session.privateKeyHex, payloadToSign);
146
+ const message = await createAuthenticatedMessageWithHex(
147
+ credentials,
148
+ session.publicKeyHex,
149
+ session.privateKeyHex
150
+ );
164
151
  const response = await this.fetchImpl(this.buildAppKeyUrl("/auth/signup", appKey), {
165
152
  method: "POST",
166
153
  headers: { "Content-Type": "application/json" },
167
- body: JSON.stringify({
168
- ...payloadToSign,
169
- sessionSignature
170
- })
154
+ body: JSON.stringify(message)
171
155
  });
172
156
  const data = await response.json();
173
157
  if (!response.ok || !data.success) {
@@ -199,31 +183,15 @@ var WalletClient = class {
199
183
  if (!session?.publicKeyHex || !session?.privateKeyHex) {
200
184
  throw new Error("session keypair is required");
201
185
  }
202
- let payloadToSign;
203
- if (credentials.type === "password") {
204
- payloadToSign = {
205
- sessionPubkey: session.publicKeyHex,
206
- type: "password",
207
- username: credentials.username,
208
- password: credentials.password
209
- };
210
- } else if (credentials.type === "google") {
211
- payloadToSign = {
212
- sessionPubkey: session.publicKeyHex,
213
- type: "google",
214
- googleIdToken: credentials.googleIdToken
215
- };
216
- } else {
217
- throw new Error(`Unknown credential type: ${credentials.type}`);
218
- }
219
- const sessionSignature = await signWithHex(session.privateKeyHex, payloadToSign);
186
+ const message = await createAuthenticatedMessageWithHex(
187
+ credentials,
188
+ session.publicKeyHex,
189
+ session.privateKeyHex
190
+ );
220
191
  const response = await this.fetchImpl(this.buildAppKeyUrl("/auth/login", appKey), {
221
192
  method: "POST",
222
193
  headers: { "Content-Type": "application/json" },
223
- body: JSON.stringify({
224
- ...payloadToSign,
225
- sessionSignature
226
- })
194
+ body: JSON.stringify(message)
227
195
  });
228
196
  const data = await response.json();
229
197
  if (!response.ok || !data.success) {
@@ -574,28 +542,12 @@ var MemoryWalletClient = class _MemoryWalletClient {
574
542
  if (!session?.publicKeyHex || !session?.privateKeyHex) {
575
543
  throw new Error("session keypair is required");
576
544
  }
577
- let payloadToSign;
578
- if (credentials.type === "password") {
579
- payloadToSign = {
580
- sessionPubkey: session.publicKeyHex,
581
- type: "password",
582
- username: credentials.username,
583
- password: credentials.password
584
- };
585
- } else if (credentials.type === "google") {
586
- payloadToSign = {
587
- sessionPubkey: session.publicKeyHex,
588
- type: "google",
589
- googleIdToken: credentials.googleIdToken
590
- };
591
- } else {
592
- throw new Error(`Unknown credential type: ${credentials.type}`);
593
- }
594
- const sessionSignature = await signWithHex(session.privateKeyHex, payloadToSign);
595
- const response = await this.request("POST", `/auth/signup/${appKey}`, {
596
- ...payloadToSign,
597
- sessionSignature
598
- });
545
+ const message = await createAuthenticatedMessageWithHex(
546
+ credentials,
547
+ session.publicKeyHex,
548
+ session.privateKeyHex
549
+ );
550
+ const response = await this.request("POST", `/auth/signup/${appKey}`, message);
599
551
  const data = await response.json();
600
552
  if (!response.ok || !data.success) {
601
553
  throw new Error(data.error || `Signup failed: ${response.statusText}`);
@@ -626,28 +578,12 @@ var MemoryWalletClient = class _MemoryWalletClient {
626
578
  if (!session?.publicKeyHex || !session?.privateKeyHex) {
627
579
  throw new Error("session keypair is required");
628
580
  }
629
- let payloadToSign;
630
- if (credentials.type === "password") {
631
- payloadToSign = {
632
- sessionPubkey: session.publicKeyHex,
633
- type: "password",
634
- username: credentials.username,
635
- password: credentials.password
636
- };
637
- } else if (credentials.type === "google") {
638
- payloadToSign = {
639
- sessionPubkey: session.publicKeyHex,
640
- type: "google",
641
- googleIdToken: credentials.googleIdToken
642
- };
643
- } else {
644
- throw new Error(`Unknown credential type: ${credentials.type}`);
645
- }
646
- const sessionSignature = await signWithHex(session.privateKeyHex, payloadToSign);
647
- const response = await this.request("POST", `/auth/login/${appKey}`, {
648
- ...payloadToSign,
649
- sessionSignature
650
- });
581
+ const message = await createAuthenticatedMessageWithHex(
582
+ credentials,
583
+ session.publicKeyHex,
584
+ session.privateKeyHex
585
+ );
586
+ const response = await this.request("POST", `/auth/login/${appKey}`, message);
651
587
  const data = await response.json();
652
588
  if (!response.ok || !data.success) {
653
589
  throw new Error(data.error || `Login failed: ${response.statusText}`);
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  HttpClient
3
- } from "../../chunk-OY4CDOHY.js";
3
+ } from "../../chunk-32YBATXQ.js";
4
4
  import "../../chunk-MLKGABMK.js";
5
5
  export {
6
6
  HttpClient
@@ -279,12 +279,6 @@ declare class WalletServerCore {
279
279
  * @returns { valid: true } if approved, { valid: false, reason } if not
280
280
  */
281
281
  private sessionExists;
282
- /**
283
- * Verify that a login request signature is valid for the given session pubkey.
284
- * The signature should be over the stringified login payload (without the signature field).
285
- * Uses SDK crypto for consistent verification across the codebase.
286
- */
287
- private verifySessionSignature;
288
282
  private createApp;
289
283
  }
290
284
 
@@ -1,19 +1,19 @@
1
1
  import {
2
2
  WebSocketClient
3
3
  } from "../chunk-UUHVOWVI.js";
4
- import {
5
- WalletClient
6
- } from "../chunk-NEYGL7RS.js";
7
4
  import {
8
5
  AppsClient
9
6
  } from "../chunk-VAZUCGED.js";
10
- import "../chunk-B4VAPGAO.js";
7
+ import {
8
+ WalletClient
9
+ } from "../chunk-PYCSO5U6.js";
10
+ import "../chunk-7PZMJECC.js";
11
11
  import {
12
12
  mod_exports
13
13
  } from "../chunk-JN75UL5C.js";
14
14
  import {
15
15
  HttpClient
16
- } from "../chunk-OY4CDOHY.js";
16
+ } from "../chunk-32YBATXQ.js";
17
17
  import {
18
18
  LocalStorageClient
19
19
  } from "../chunk-PZFEKQ7F.js";
@@ -1,7 +1,7 @@
1
1
  import { A as AuthSession, H as HealthResponse, S as SessionKeypair, U as UserCredentials, P as PasswordResetToken, a as UserPublicKeys, b as ProxyWriteRequest, c as ProxyWriteResponse, d as ProxyReadRequest, e as ProxyReadResponse, f as ProxyReadMultiRequest, g as ProxyReadMultiResponse } from '../client-DHCiJ9I7.js';
2
2
  export { l as ApiResponse, C as ChangePasswordResponse, G as GoogleAuthSession, q as GoogleLoginResponse, p as GoogleSignupResponse, L as LoginResponse, k as ProxyReadMultiResultItem, n as PublicKeysResponse, R as RequestPasswordResetResponse, o as ResetPasswordResponse, m as SignupResponse, W as WalletClient, j as WalletClientConfig, i as WalletClientInterface, h as generateSessionKeypair } from '../client-DHCiJ9I7.js';
3
3
  import { N as NodeProtocolInterface, S as Schema } from '../types-uuvn4oKw.js';
4
- import { S as ServerKeys, W as WalletServerCore } from '../core-ClnuubZw.js';
4
+ import { S as ServerKeys, W as WalletServerCore } from '../core-BGUpkKnP.js';
5
5
  import { MemoryClient } from '../clients/memory/mod.js';
6
6
  import 'hono';
7
7
 
@@ -4,10 +4,10 @@ import {
4
4
  createTestEnvironment,
5
5
  generateSessionKeypair,
6
6
  generateTestServerKeys
7
- } from "../chunk-NEYGL7RS.js";
8
- import "../chunk-B4VAPGAO.js";
7
+ } from "../chunk-PYCSO5U6.js";
8
+ import "../chunk-7PZMJECC.js";
9
9
  import "../chunk-JN75UL5C.js";
10
- import "../chunk-OY4CDOHY.js";
10
+ import "../chunk-32YBATXQ.js";
11
11
  import "../chunk-O53KW746.js";
12
12
  import "../chunk-MLKGABMK.js";
13
13
  export {
@@ -1,5 +1,5 @@
1
- import { F as FileStorage, S as ServerKeys, W as WalletServerCore } from '../../core-ClnuubZw.js';
2
- export { C as BrowserEnvironment, M as BrowserMemoryStorage } from '../../core-ClnuubZw.js';
1
+ import { F as FileStorage, S as ServerKeys, W as WalletServerCore } from '../../core-BGUpkKnP.js';
2
+ export { C as BrowserEnvironment, M as BrowserMemoryStorage } from '../../core-BGUpkKnP.js';
3
3
  import 'hono';
4
4
  import '../../types-uuvn4oKw.js';
5
5
 
@@ -2,9 +2,9 @@ import {
2
2
  ConfigEnvironment,
3
3
  MemoryFileStorage,
4
4
  WalletServerCore
5
- } from "../../chunk-B4VAPGAO.js";
5
+ } from "../../chunk-7PZMJECC.js";
6
6
  import "../../chunk-JN75UL5C.js";
7
- import "../../chunk-OY4CDOHY.js";
7
+ import "../../chunk-32YBATXQ.js";
8
8
  import {
9
9
  LocalStorageClient
10
10
  } from "../../chunk-PZFEKQ7F.js";
@@ -1,5 +1,5 @@
1
- import { P as ProxyWriteRequest, a as ProxyWriteResponse, b as ProxyReadResponse, U as UserKeys, L as Logger, H as HttpFetch } from '../core-ClnuubZw.js';
2
- export { A as AppBackendConfig, f as AuthSessionResponse, C as ConfigEnvironment, E as Environment, F as FileStorage, h as HealthResponse, M as MemoryFileStorage, g as PublicKeysResponse, R as ResolvedWalletServerConfig, e as ServerKeyPair, S as ServerKeys, i as ServerKeysResponse, c as WalletServerConfig, W as WalletServerCore, d as WalletServerDeps, j as defaultLogger } from '../core-ClnuubZw.js';
1
+ import { P as ProxyWriteRequest, a as ProxyWriteResponse, b as ProxyReadResponse, U as UserKeys, L as Logger, H as HttpFetch } from '../core-BGUpkKnP.js';
2
+ export { A as AppBackendConfig, f as AuthSessionResponse, C as ConfigEnvironment, E as Environment, F as FileStorage, h as HealthResponse, M as MemoryFileStorage, g as PublicKeysResponse, R as ResolvedWalletServerConfig, e as ServerKeyPair, S as ServerKeys, i as ServerKeysResponse, c as WalletServerConfig, W as WalletServerCore, d as WalletServerDeps, j as defaultLogger } from '../core-BGUpkKnP.js';
3
3
  import { N as NodeProtocolInterface } from '../types-uuvn4oKw.js';
4
4
  import { S as SignedEncryptedMessage, E as EncryptedPayload } from '../mod-CII9wqu2.js';
5
5
  import 'hono';
@@ -34,9 +34,9 @@ import {
34
34
  userExists,
35
35
  verifyGoogleIdToken,
36
36
  verifyJwt
37
- } from "../chunk-B4VAPGAO.js";
37
+ } from "../chunk-7PZMJECC.js";
38
38
  import "../chunk-JN75UL5C.js";
39
- import "../chunk-OY4CDOHY.js";
39
+ import "../chunk-32YBATXQ.js";
40
40
  import "../chunk-MLKGABMK.js";
41
41
  export {
42
42
  ConfigEnvironment,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bandeira-tech/b3nd-web",
3
- "version": "0.3.4",
3
+ "version": "0.5.0",
4
4
  "description": "Browser-focused B3nd SDK bundle",
5
5
  "type": "module",
6
6
  "main": "./dist/src/mod.web.js",