@dotbots-boutique/auth-sdk 1.0.9 → 1.0.11

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/README.md CHANGED
@@ -115,7 +115,7 @@ App (frontend) → Local proxy (per server) → api.dotbots.ai
115
115
 
116
116
  During `initialize()`, the SDK fetches the proxy config from `GET {apiUrl}/api/proxy/config`. After that, all `auth.fetch()` calls are routed through the proxy automatically. If the proxy config cannot be fetched, the SDK falls back to direct communication with `apiUrl`.
117
117
 
118
- Auth endpoints (`/auth/*`) and the proxy config endpoint always go directly to `apiUrl` never through the proxy.
118
+ Only `GET /api/proxy/config` always goes directly to `apiUrl`. All other calls — auth token exchange, refresh, revoke, user info, payments, and `auth.fetch()` — go to `proxyUrl` when available, falling back to `apiUrl` when proxy is unavailable.
119
119
 
120
120
  ---
121
121
 
@@ -150,7 +150,7 @@ const response = await auth.fetch('/api/customers', {
150
150
  });
151
151
  ```
152
152
 
153
- This is the **only** method that routes via `proxyUrl`. All auth calls and the proxy config call always go directly to `apiUrl`.
153
+ All SDK calls route via `proxyUrl` when available. Only `GET /api/proxy/config` always goes to `apiUrl`.
154
154
 
155
155
  ---
156
156
 
@@ -210,6 +210,7 @@ auth.on('sessionExpired', () => {
210
210
  });
211
211
  auth.on('loggedOut', () => { });
212
212
  auth.on('userLoaded', () => { });
213
+ auth.on('charged', () => { });
213
214
  ```
214
215
 
215
216
  | Event | Description |
@@ -218,6 +219,7 @@ auth.on('userLoaded', () => { });
218
219
  | `loggedOut` | User logged out |
219
220
  | `sessionExpired` | Refresh token expired, user must re-authenticate |
220
221
  | `userLoaded` | User data was fetched |
222
+ | `charged` | Successful charge — also sent as `DOTBOTS_CHARGE` postMessage to parent |
221
223
 
222
224
  ---
223
225
 
@@ -283,19 +285,17 @@ interface DotBotsConfig {
283
285
  ```typescript
284
286
  interface DotBotsUser {
285
287
  id: string;
286
- name: string | null; // null if 'profile' scope not granted
287
- email: string | null; // null if 'email' scope not granted
288
+ name: string;
289
+ email: string;
288
290
  orgId: string;
289
- orgName: string | null; // null if 'org' scope not granted
291
+ orgName: string;
290
292
  teams: { teamId: string; teamName: string }[];
291
293
  roles: string[];
292
294
  permissions: string[];
293
- avatarUrl: string | null; // null if 'avatar' scope not granted
295
+ avatarUrl?: string;
294
296
  }
295
297
  ```
296
298
 
297
- Fields marked as `null` are not provided by the platform because the user has not granted the corresponding scope.
298
-
299
299
  ---
300
300
 
301
301
  ## API Reference
@@ -340,7 +340,7 @@ Authenticated fetch wrapper. Routes through the proxy when available, falls back
340
340
 
341
341
  #### `charge(featureCode: string, paidBy: 'org' | 'app', quantity?: number): Promise<{ transactionId: string }>`
342
342
 
343
- Charges a feature usage. Calls `POST {proxyUrl}/payments/charge`. Throws `PAYMENT_FAILED` on 402 with a message indicating the reason (`INSUFFICIENT_BALANCE`, `BUDGET_EXCEEDED`, `FEATURE_NOT_FOUND`, `PAYMENT_REJECTED`).
343
+ Charges a feature usage. Calls `POST {proxyUrl}/payments/charge`. On success, sends a `DOTBOTS_CHARGE` postMessage to the parent window (iframe only) and emits the `charged` event. Throws `PAYMENT_FAILED` on 402 with a message indicating the reason (`INSUFFICIENT_BALANCE`, `BUDGET_EXCEEDED`, `FEATURE_NOT_FOUND`, `PAYMENT_REJECTED`).
344
344
 
345
345
  #### `logout(): Promise<void>`
346
346
 
package/dist/cjs/index.js CHANGED
@@ -193,6 +193,15 @@ class PostMessageHandler {
193
193
  window.parent.postMessage({ type: 'DOTBOTS_LOGOUT' }, this.marketplaceOrigin);
194
194
  }
195
195
  }
196
+ /**
197
+ * Notify the parent of a successful charge (for real-time payment indicator).
198
+ */
199
+ sendCharge(appId, featureCode, amount, transactionId) {
200
+ if (this.isInIframe()) {
201
+ console.warn(`[DotBotsAuth] Sending DOTBOTS_CHARGE postMessage — featureCode: ${featureCode}, amount: ${amount}, transactionId: ${transactionId}`);
202
+ window.parent.postMessage({ type: 'DOTBOTS_CHARGE', appId, featureCode, amount, transactionId }, this.marketplaceOrigin);
203
+ }
204
+ }
196
205
  }
197
206
 
198
207
  class ProxyConfigManager {
@@ -328,6 +337,7 @@ class DotBotsAuth {
328
337
  async charge(featureCode, paidBy, quantity) {
329
338
  this.assertInitialized();
330
339
  const baseUrl = this.proxyConfigManager.getBaseUrl();
340
+ console.warn(`[DotBotsAuth] charge() — featureCode: ${featureCode}, paidBy: ${paidBy}, quantity: ${quantity ?? 1}`);
331
341
  const response = await this.buildRequest(`${baseUrl}/payments/charge`, {
332
342
  method: 'POST',
333
343
  headers: { 'Content-Type': 'application/json' },
@@ -335,12 +345,18 @@ class DotBotsAuth {
335
345
  });
336
346
  if (response.status === 402) {
337
347
  const body = await response.json();
348
+ console.error(`[DotBotsAuth] charge() failed — 402: ${body.error}`, body.reason);
338
349
  throw new DotBotsAuthError('PAYMENT_FAILED', body.error, body.reason);
339
350
  }
340
351
  if (!response.ok) {
352
+ console.error(`[DotBotsAuth] charge() failed — HTTP ${response.status}`);
341
353
  throw new DotBotsAuthError('NETWORK_ERROR', 'Payment request failed');
342
354
  }
343
- return response.json();
355
+ const result = await response.json();
356
+ console.warn(`[DotBotsAuth] charge() success — transactionId: ${result.transactionId}, amount: ${result.amount}`);
357
+ this.postMessageHandler.sendCharge(this.config.appId, featureCode, result.amount, result.transactionId);
358
+ this.emit('charged');
359
+ return result;
344
360
  }
345
361
  async logout() {
346
362
  this.assertInitialized();
@@ -352,7 +368,7 @@ class DotBotsAuth {
352
368
  }
353
369
  else {
354
370
  const redirectUri = encodeURIComponent(window.location.origin);
355
- window.location.href = `${this.config.apiUrl}/auth/logout?redirectUri=${redirectUri}`;
371
+ window.location.href = `${this.config.apiUrl}/api/auth/logout?redirectUri=${redirectUri}`;
356
372
  }
357
373
  }
358
374
  on(event, handler) {
@@ -400,7 +416,7 @@ class DotBotsAuth {
400
416
  else if (!this.tokenManager.isAuthenticated()) {
401
417
  // Redirect to auth
402
418
  const redirectUri = encodeURIComponent(window.location.href);
403
- window.location.href = `${this.config.apiUrl}/auth/authorize?appId=${this.config.appId}&redirectUri=${redirectUri}`;
419
+ window.location.href = `${this.config.apiUrl}/api/auth/authorize?appId=${this.config.appId}&redirectUri=${redirectUri}`;
404
420
  }
405
421
  }
406
422
  async buildRequest(url, options) {
@@ -432,7 +448,7 @@ class DotBotsAuth {
432
448
  }
433
449
  }
434
450
  }
435
- DotBotsAuth.SDK_VERSION = '1.0.9';
451
+ DotBotsAuth.SDK_VERSION = '1.0.11';
436
452
 
437
453
  exports.DotBotsAuth = DotBotsAuth;
438
454
  exports.DotBotsAuthError = DotBotsAuthError;
package/dist/esm/index.js CHANGED
@@ -191,6 +191,15 @@ class PostMessageHandler {
191
191
  window.parent.postMessage({ type: 'DOTBOTS_LOGOUT' }, this.marketplaceOrigin);
192
192
  }
193
193
  }
194
+ /**
195
+ * Notify the parent of a successful charge (for real-time payment indicator).
196
+ */
197
+ sendCharge(appId, featureCode, amount, transactionId) {
198
+ if (this.isInIframe()) {
199
+ console.warn(`[DotBotsAuth] Sending DOTBOTS_CHARGE postMessage — featureCode: ${featureCode}, amount: ${amount}, transactionId: ${transactionId}`);
200
+ window.parent.postMessage({ type: 'DOTBOTS_CHARGE', appId, featureCode, amount, transactionId }, this.marketplaceOrigin);
201
+ }
202
+ }
194
203
  }
195
204
 
196
205
  class ProxyConfigManager {
@@ -326,6 +335,7 @@ class DotBotsAuth {
326
335
  async charge(featureCode, paidBy, quantity) {
327
336
  this.assertInitialized();
328
337
  const baseUrl = this.proxyConfigManager.getBaseUrl();
338
+ console.warn(`[DotBotsAuth] charge() — featureCode: ${featureCode}, paidBy: ${paidBy}, quantity: ${quantity ?? 1}`);
329
339
  const response = await this.buildRequest(`${baseUrl}/payments/charge`, {
330
340
  method: 'POST',
331
341
  headers: { 'Content-Type': 'application/json' },
@@ -333,12 +343,18 @@ class DotBotsAuth {
333
343
  });
334
344
  if (response.status === 402) {
335
345
  const body = await response.json();
346
+ console.error(`[DotBotsAuth] charge() failed — 402: ${body.error}`, body.reason);
336
347
  throw new DotBotsAuthError('PAYMENT_FAILED', body.error, body.reason);
337
348
  }
338
349
  if (!response.ok) {
350
+ console.error(`[DotBotsAuth] charge() failed — HTTP ${response.status}`);
339
351
  throw new DotBotsAuthError('NETWORK_ERROR', 'Payment request failed');
340
352
  }
341
- return response.json();
353
+ const result = await response.json();
354
+ console.warn(`[DotBotsAuth] charge() success — transactionId: ${result.transactionId}, amount: ${result.amount}`);
355
+ this.postMessageHandler.sendCharge(this.config.appId, featureCode, result.amount, result.transactionId);
356
+ this.emit('charged');
357
+ return result;
342
358
  }
343
359
  async logout() {
344
360
  this.assertInitialized();
@@ -350,7 +366,7 @@ class DotBotsAuth {
350
366
  }
351
367
  else {
352
368
  const redirectUri = encodeURIComponent(window.location.origin);
353
- window.location.href = `${this.config.apiUrl}/auth/logout?redirectUri=${redirectUri}`;
369
+ window.location.href = `${this.config.apiUrl}/api/auth/logout?redirectUri=${redirectUri}`;
354
370
  }
355
371
  }
356
372
  on(event, handler) {
@@ -398,7 +414,7 @@ class DotBotsAuth {
398
414
  else if (!this.tokenManager.isAuthenticated()) {
399
415
  // Redirect to auth
400
416
  const redirectUri = encodeURIComponent(window.location.href);
401
- window.location.href = `${this.config.apiUrl}/auth/authorize?appId=${this.config.appId}&redirectUri=${redirectUri}`;
417
+ window.location.href = `${this.config.apiUrl}/api/auth/authorize?appId=${this.config.appId}&redirectUri=${redirectUri}`;
402
418
  }
403
419
  }
404
420
  async buildRequest(url, options) {
@@ -430,6 +446,6 @@ class DotBotsAuth {
430
446
  }
431
447
  }
432
448
  }
433
- DotBotsAuth.SDK_VERSION = '1.0.9';
449
+ DotBotsAuth.SDK_VERSION = '1.0.11';
434
450
 
435
451
  export { DotBotsAuth, DotBotsAuthError };
@@ -8,7 +8,7 @@ export declare class DotBotsAuth {
8
8
  private readonly listeners;
9
9
  private cachedUser;
10
10
  private initialized;
11
- static readonly SDK_VERSION = "1.0.9";
11
+ static readonly SDK_VERSION = "1.0.11";
12
12
  constructor(config: DotBotsConfig);
13
13
  initialize(): Promise<void>;
14
14
  getUser(): Promise<DotBotsUser>;
@@ -15,4 +15,8 @@ export declare class PostMessageHandler {
15
15
  * Notify the parent that the user has logged out.
16
16
  */
17
17
  sendLogout(): void;
18
+ /**
19
+ * Notify the parent of a successful charge (for real-time payment indicator).
20
+ */
21
+ sendCharge(appId: string, featureCode: string, amount: number, transactionId: string): void;
18
22
  }
@@ -191,6 +191,15 @@ class PostMessageHandler {
191
191
  window.parent.postMessage({ type: 'DOTBOTS_LOGOUT' }, this.marketplaceOrigin);
192
192
  }
193
193
  }
194
+ /**
195
+ * Notify the parent of a successful charge (for real-time payment indicator).
196
+ */
197
+ sendCharge(appId, featureCode, amount, transactionId) {
198
+ if (this.isInIframe()) {
199
+ console.warn(`[DotBotsAuth] Sending DOTBOTS_CHARGE postMessage — featureCode: ${featureCode}, amount: ${amount}, transactionId: ${transactionId}`);
200
+ window.parent.postMessage({ type: 'DOTBOTS_CHARGE', appId, featureCode, amount, transactionId }, this.marketplaceOrigin);
201
+ }
202
+ }
194
203
  }
195
204
 
196
205
  class ProxyConfigManager {
@@ -326,6 +335,7 @@ class DotBotsAuth {
326
335
  async charge(featureCode, paidBy, quantity) {
327
336
  this.assertInitialized();
328
337
  const baseUrl = this.proxyConfigManager.getBaseUrl();
338
+ console.warn(`[DotBotsAuth] charge() — featureCode: ${featureCode}, paidBy: ${paidBy}, quantity: ${quantity ?? 1}`);
329
339
  const response = await this.buildRequest(`${baseUrl}/payments/charge`, {
330
340
  method: 'POST',
331
341
  headers: { 'Content-Type': 'application/json' },
@@ -333,12 +343,18 @@ class DotBotsAuth {
333
343
  });
334
344
  if (response.status === 402) {
335
345
  const body = await response.json();
346
+ console.error(`[DotBotsAuth] charge() failed — 402: ${body.error}`, body.reason);
336
347
  throw new DotBotsAuthError('PAYMENT_FAILED', body.error, body.reason);
337
348
  }
338
349
  if (!response.ok) {
350
+ console.error(`[DotBotsAuth] charge() failed — HTTP ${response.status}`);
339
351
  throw new DotBotsAuthError('NETWORK_ERROR', 'Payment request failed');
340
352
  }
341
- return response.json();
353
+ const result = await response.json();
354
+ console.warn(`[DotBotsAuth] charge() success — transactionId: ${result.transactionId}, amount: ${result.amount}`);
355
+ this.postMessageHandler.sendCharge(this.config.appId, featureCode, result.amount, result.transactionId);
356
+ this.emit('charged');
357
+ return result;
342
358
  }
343
359
  async logout() {
344
360
  this.assertInitialized();
@@ -350,7 +366,7 @@ class DotBotsAuth {
350
366
  }
351
367
  else {
352
368
  const redirectUri = encodeURIComponent(window.location.origin);
353
- window.location.href = `${this.config.apiUrl}/auth/logout?redirectUri=${redirectUri}`;
369
+ window.location.href = `${this.config.apiUrl}/api/auth/logout?redirectUri=${redirectUri}`;
354
370
  }
355
371
  }
356
372
  on(event, handler) {
@@ -398,7 +414,7 @@ class DotBotsAuth {
398
414
  else if (!this.tokenManager.isAuthenticated()) {
399
415
  // Redirect to auth
400
416
  const redirectUri = encodeURIComponent(window.location.href);
401
- window.location.href = `${this.config.apiUrl}/auth/authorize?appId=${this.config.appId}&redirectUri=${redirectUri}`;
417
+ window.location.href = `${this.config.apiUrl}/api/auth/authorize?appId=${this.config.appId}&redirectUri=${redirectUri}`;
402
418
  }
403
419
  }
404
420
  async buildRequest(url, options) {
@@ -430,6 +446,6 @@ class DotBotsAuth {
430
446
  }
431
447
  }
432
448
  }
433
- DotBotsAuth.SDK_VERSION = '1.0.9';
449
+ DotBotsAuth.SDK_VERSION = '1.0.11';
434
450
 
435
451
  export { DotBotsAuth, DotBotsAuthError };
@@ -19,17 +19,17 @@ export interface DotBotsConfig {
19
19
  }
20
20
  export interface DotBotsUser {
21
21
  id: string;
22
- name: string | null;
23
- email: string | null;
22
+ name: string;
23
+ email: string;
24
24
  orgId: string;
25
- orgName: string | null;
25
+ orgName: string;
26
26
  teams: {
27
27
  teamId: string;
28
28
  teamName: string;
29
29
  }[];
30
30
  roles: string[];
31
31
  permissions: string[];
32
- avatarUrl: string | null;
32
+ avatarUrl?: string;
33
33
  }
34
34
  export interface DotBotsProxyConfig {
35
35
  /** URL of the local proxy, e.g. 'https://proxy.test-apps.dotbots.boutique' */
@@ -40,7 +40,7 @@ export interface DotBotsProxyConfig {
40
40
  cacheTtl: number;
41
41
  }
42
42
  export type ProxyFeature = 'cache' | 'localdb' | 'webhooks' | 'ratelimit';
43
- export type DotBotsAuthEvent = 'tokenRefreshed' | 'loggedOut' | 'sessionExpired' | 'userLoaded';
43
+ export type DotBotsAuthEvent = 'tokenRefreshed' | 'loggedOut' | 'sessionExpired' | 'userLoaded' | 'charged';
44
44
  export type DotBotsAuthErrorCode = 'IFRAME_TIMEOUT' | 'CODE_EXPIRED' | 'UNAUTHORIZED' | 'REFRESH_FAILED' | 'NETWORK_ERROR' | 'NOT_INITIALIZED' | 'PROXY_UNAVAILABLE' | 'PAYMENT_FAILED';
45
45
  export interface TokenPair {
46
46
  accessToken: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dotbots-boutique/auth-sdk",
3
- "version": "1.0.9",
3
+ "version": "1.0.11",
4
4
  "description": "Authentication SDK for DotBots marketplace apps",
5
5
  "license": "MIT",
6
6
  "type": "module",