@bandeira-tech/b3nd-web 0.2.1 → 0.2.2

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.
@@ -6,7 +6,6 @@ interface AppsClientConfig {
6
6
  appServerUrl: string;
7
7
  apiBasePath: string;
8
8
  fetch?: typeof fetch;
9
- authToken?: string;
10
9
  }
11
10
  interface AppActionDef {
12
11
  action: string;
@@ -20,27 +19,34 @@ interface AppActionDef {
20
19
  plain?: string;
21
20
  };
22
21
  }
23
- interface AppRegistration {
24
- appKey: string;
25
- accountPrivateKeyPem: string;
26
- encryptionPublicKeyHex?: string;
27
- encryptionPrivateKeyPem?: string;
28
- allowedOrigins: string[];
29
- actions: AppActionDef[];
30
- }
22
+ type AuthenticatedMessage<T = unknown> = {
23
+ auth: Array<{
24
+ pubkey: string;
25
+ signature: string;
26
+ }>;
27
+ payload: T;
28
+ };
31
29
  declare class AppsClient {
32
30
  private base;
33
31
  private api;
34
32
  private f;
35
- private authToken?;
36
33
  constructor(cfg: AppsClientConfig);
37
- setAuthToken(token?: string): void;
38
34
  health(): Promise<unknown>;
39
- registerApp(reg: AppRegistration): Promise<{
35
+ updateOrigins(appKey: string, message: AuthenticatedMessage<{
36
+ allowedOrigins?: string[];
37
+ encryptionPublicKeyHex?: string | null;
38
+ }>): Promise<{
40
39
  success: boolean;
41
- error?: string;
42
40
  }>;
43
- updateSchema(appKey: string, actions: AppActionDef[]): Promise<{
41
+ updateGoogleClientId(appKey: string, message: AuthenticatedMessage<{
42
+ googleClientId: string | null;
43
+ }>): Promise<{
44
+ success: boolean;
45
+ }>;
46
+ updateSchema(appKey: string, message: AuthenticatedMessage<{
47
+ actions: AppActionDef[];
48
+ encryptionPublicKeyHex?: string | null;
49
+ }>): Promise<{
44
50
  success: boolean;
45
51
  error?: string;
46
52
  }>;
@@ -50,14 +56,17 @@ declare class AppsClient {
50
56
  appKey: string;
51
57
  allowedOrigins: string[];
52
58
  actions: AppActionDef[];
59
+ encryptionPublicKeyHex?: string | null;
53
60
  };
54
61
  }>;
55
- createSession(appKey: string, token: string): Promise<{
62
+ createSession(appKey: string, message: AuthenticatedMessage<{
63
+ session: string;
64
+ }>): Promise<{
56
65
  success: true;
57
66
  session: string;
58
67
  uri: string;
59
68
  }>;
60
- invokeAction(appKey: string, action: string, payload: string, origin?: string): Promise<{
69
+ invokeAction(appKey: string, action: string, signedMessage: AuthenticatedMessage<any>, origin?: string): Promise<{
61
70
  success: true;
62
71
  uri: string;
63
72
  record: {
@@ -76,4 +85,4 @@ declare class AppsClient {
76
85
  }>;
77
86
  }
78
87
 
79
- export { type AppActionDef, type AppRegistration, AppsClient, type AppsClientConfig };
88
+ export { type AppActionDef, AppsClient, type AppsClientConfig, type AuthenticatedMessage };
package/dist/apps/mod.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  AppsClient
3
- } from "../chunk-YJKJJ323.js";
3
+ } from "../chunk-VAZUCGED.js";
4
4
  import "../chunk-MLKGABMK.js";
5
5
  export {
6
6
  AppsClient
@@ -16,6 +16,16 @@ var WalletClient = class {
16
16
  this.fetchImpl = fetch;
17
17
  }
18
18
  }
19
+ buildUrl(path) {
20
+ const normalized = path.startsWith("/") ? path : `/${path}`;
21
+ return `${this.walletServerUrl}${this.apiBasePath}${normalized}`;
22
+ }
23
+ buildAppKeyUrl(path, appKey) {
24
+ if (!appKey || typeof appKey !== "string") {
25
+ throw new Error("appKey is required");
26
+ }
27
+ return `${this.buildUrl(path)}/${appKey}`;
28
+ }
19
29
  /**
20
30
  * Get the current authenticated session
21
31
  */
@@ -82,12 +92,12 @@ var WalletClient = class {
82
92
  * Change password for current user
83
93
  * Requires active authentication session
84
94
  */
85
- async changePassword(oldPassword, newPassword) {
95
+ async changePassword(appKey, oldPassword, newPassword) {
86
96
  if (!this.currentSession) {
87
97
  throw new Error("Not authenticated. Please login first.");
88
98
  }
89
99
  const response = await this.fetchImpl(
90
- `${this.walletServerUrl}${this.apiBasePath}/auth/change-password`,
100
+ this.buildAppKeyUrl("/auth/credentials/change-password", appKey),
91
101
  {
92
102
  method: "POST",
93
103
  headers: {
@@ -110,24 +120,30 @@ var WalletClient = class {
110
120
  * Does not require authentication
111
121
  */
112
122
  async requestPasswordReset(_username) {
113
- throw new Error("Use requestPasswordResetWithToken(token, username)");
123
+ throw new Error("Use requestPasswordResetWithToken(appKey, username)");
114
124
  }
115
125
  /**
116
126
  * Reset password using a reset token
117
127
  * Returns session data - call setSession() to activate it
118
128
  */
119
129
  async resetPassword(_username, _resetToken, _newPassword) {
120
- throw new Error("Use resetPasswordWithToken(token, username, resetToken, newPassword)");
130
+ throw new Error("Use resetPasswordWithToken(appKey, username, resetToken, newPassword)");
121
131
  }
122
132
  /**
123
133
  * Sign up with app token (scoped to an app)
124
134
  */
125
- async signupWithToken(token, credentials) {
126
- if (!token) throw new Error("token is required");
127
- const response = await this.fetchImpl(`${this.walletServerUrl}${this.apiBasePath}/auth/signup`, {
135
+ async signupWithToken(appKey, tokenOrCredentials, maybeCredentials) {
136
+ const credentials = typeof tokenOrCredentials === "string" ? maybeCredentials : tokenOrCredentials;
137
+ if (!credentials) throw new Error("credentials are required");
138
+ const response = await this.fetchImpl(this.buildAppKeyUrl("/auth/signup", appKey), {
128
139
  method: "POST",
129
140
  headers: { "Content-Type": "application/json" },
130
- body: JSON.stringify({ token, username: credentials.username, password: credentials.password })
141
+ body: JSON.stringify({
142
+ token: typeof tokenOrCredentials === "string" ? tokenOrCredentials : void 0,
143
+ type: "password",
144
+ username: credentials.username,
145
+ password: credentials.password
146
+ })
131
147
  });
132
148
  const data = await response.json();
133
149
  if (!response.ok || !data.success) {
@@ -138,13 +154,20 @@ var WalletClient = class {
138
154
  /**
139
155
  * Login with app token and session (scoped to an app)
140
156
  */
141
- async loginWithTokenSession(token, session, credentials) {
142
- if (!token) throw new Error("token is required");
143
- if (!session) throw new Error("session is required");
144
- const response = await this.fetchImpl(`${this.walletServerUrl}${this.apiBasePath}/auth/login`, {
157
+ async loginWithTokenSession(appKey, tokenOrSession, sessionOrCredentials, maybeCredentials) {
158
+ const session = typeof sessionOrCredentials === "string" && maybeCredentials ? sessionOrCredentials : tokenOrSession;
159
+ const credentials = maybeCredentials || sessionOrCredentials;
160
+ if (!session || typeof session !== "string") throw new Error("session is required");
161
+ const response = await this.fetchImpl(this.buildAppKeyUrl("/auth/login", appKey), {
145
162
  method: "POST",
146
163
  headers: { "Content-Type": "application/json" },
147
- body: JSON.stringify({ token, session, username: credentials.username, password: credentials.password })
164
+ body: JSON.stringify({
165
+ token: typeof tokenOrSession === "string" && maybeCredentials ? tokenOrSession : void 0,
166
+ session,
167
+ type: "password",
168
+ username: credentials.username,
169
+ password: credentials.password
170
+ })
148
171
  });
149
172
  const data = await response.json();
150
173
  if (!response.ok || !data.success) {
@@ -155,12 +178,12 @@ var WalletClient = class {
155
178
  /**
156
179
  * Request password reset scoped to app token
157
180
  */
158
- async requestPasswordResetWithToken(token, username) {
159
- if (!token) throw new Error("token is required");
160
- const response = await this.fetchImpl(`${this.walletServerUrl}${this.apiBasePath}/auth/request-password-reset`, {
181
+ async requestPasswordResetWithToken(appKey, tokenOrUsername, maybeUsername) {
182
+ const username = maybeUsername || tokenOrUsername;
183
+ const response = await this.fetchImpl(this.buildAppKeyUrl("/auth/credentials/request-password-reset", appKey), {
161
184
  method: "POST",
162
185
  headers: { "Content-Type": "application/json" },
163
- body: JSON.stringify({ token, username })
186
+ body: JSON.stringify({ username })
164
187
  });
165
188
  const data = await response.json();
166
189
  if (!response.ok || !data.success) {
@@ -169,14 +192,17 @@ var WalletClient = class {
169
192
  return { resetToken: data.resetToken, expiresIn: data.expiresIn };
170
193
  }
171
194
  /**
172
- * Reset password scoped to app token
195
+ * Reset password scoped to an app
173
196
  */
174
- async resetPasswordWithToken(token, username, resetToken, newPassword) {
175
- if (!token) throw new Error("token is required");
176
- const response = await this.fetchImpl(`${this.walletServerUrl}${this.apiBasePath}/auth/reset-password`, {
197
+ async resetPasswordWithToken(appKey, _tokenOrUsername, usernameOrReset, resetToken, newPassword) {
198
+ const username = usernameOrReset;
199
+ if (!resetToken || !newPassword) {
200
+ throw new Error("resetToken and newPassword are required");
201
+ }
202
+ const response = await this.fetchImpl(this.buildAppKeyUrl("/auth/credentials/reset-password", appKey), {
177
203
  method: "POST",
178
204
  headers: { "Content-Type": "application/json" },
179
- body: JSON.stringify({ token, username, resetToken, newPassword })
205
+ body: JSON.stringify({ username, resetToken, newPassword })
180
206
  });
181
207
  const data = await response.json();
182
208
  if (!response.ok || !data.success) {
@@ -188,12 +214,15 @@ var WalletClient = class {
188
214
  * Get public keys for the current authenticated user.
189
215
  * Requires an active authentication session.
190
216
  */
191
- async getPublicKeys() {
217
+ async getPublicKeys(appKey) {
192
218
  if (!this.currentSession) {
193
219
  throw new Error("Not authenticated. Please login first.");
194
220
  }
221
+ if (!appKey || typeof appKey !== "string") {
222
+ throw new Error("appKey is required");
223
+ }
195
224
  const response = await this.fetchImpl(
196
- `${this.walletServerUrl}${this.apiBasePath}/public-keys`,
225
+ this.buildAppKeyUrl("/auth/public-keys", appKey),
197
226
  {
198
227
  headers: {
199
228
  Authorization: `Bearer ${this.currentSession.token}`
@@ -242,8 +271,8 @@ var WalletClient = class {
242
271
  * Convenience method: Get current user's public keys
243
272
  * Requires active authentication session
244
273
  */
245
- async getMyPublicKeys() {
246
- return this.getPublicKeys();
274
+ async getMyPublicKeys(appKey) {
275
+ return this.getPublicKeys(appKey);
247
276
  }
248
277
  /**
249
278
  * Get server's public keys
@@ -265,6 +294,66 @@ var WalletClient = class {
265
294
  encryptionPublicKeyHex: data.encryptionPublicKeyHex
266
295
  };
267
296
  }
297
+ /**
298
+ * Sign up with Google OAuth (scoped to app token)
299
+ * Returns session data with Google profile info - call setSession() to activate it
300
+ *
301
+ * @param token - App token from app server
302
+ * @param googleIdToken - Google ID token from Google Sign-In
303
+ * @returns GoogleAuthSession with username, JWT token, and Google profile info
304
+ */
305
+ async signupWithGoogle(appKey, token, googleIdToken) {
306
+ if (!token) throw new Error("token is required");
307
+ if (!googleIdToken) throw new Error("googleIdToken is required");
308
+ const response = await this.fetchImpl(this.buildAppKeyUrl("/auth/signup", appKey), {
309
+ method: "POST",
310
+ headers: { "Content-Type": "application/json" },
311
+ body: JSON.stringify({ token, type: "google", googleIdToken })
312
+ });
313
+ const data = await response.json();
314
+ if (!response.ok || !data.success) {
315
+ throw new Error(data.error || `Google signup failed: ${response.statusText}`);
316
+ }
317
+ return {
318
+ username: data.username,
319
+ token: data.token,
320
+ expiresIn: data.expiresIn,
321
+ email: data.email,
322
+ name: data.name,
323
+ picture: data.picture
324
+ };
325
+ }
326
+ /**
327
+ * Login with Google OAuth (scoped to app token and session)
328
+ * Returns session data with Google profile info - call setSession() to activate it
329
+ *
330
+ * @param token - App token from app server
331
+ * @param session - Session key from app server
332
+ * @param googleIdToken - Google ID token from Google Sign-In
333
+ * @returns GoogleAuthSession with username, JWT token, and Google profile info
334
+ */
335
+ async loginWithGoogle(appKey, token, session, googleIdToken) {
336
+ if (!token) throw new Error("token is required");
337
+ if (!session) throw new Error("session is required");
338
+ if (!googleIdToken) throw new Error("googleIdToken is required");
339
+ const response = await this.fetchImpl(this.buildAppKeyUrl("/auth/login", appKey), {
340
+ method: "POST",
341
+ headers: { "Content-Type": "application/json" },
342
+ body: JSON.stringify({ token, session, type: "google", googleIdToken })
343
+ });
344
+ const data = await response.json();
345
+ if (!response.ok || !data.success) {
346
+ throw new Error(data.error || `Google login failed: ${response.statusText}`);
347
+ }
348
+ return {
349
+ username: data.username,
350
+ token: data.token,
351
+ expiresIn: data.expiresIn,
352
+ email: data.email,
353
+ name: data.name,
354
+ picture: data.picture
355
+ };
356
+ }
268
357
  };
269
358
 
270
359
  export {