@dotbots-boutique/auth-sdk 1.0.5 → 1.0.7

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 (`/api/auth/*`) and the proxy config endpoint always go directly to `apiUrl` — never through the proxy.
118
+ Auth endpoints (`/auth/*`) and the proxy config endpoint always go directly to `apiUrl` — never through the proxy.
119
119
 
120
120
  ---
121
121
 
package/dist/cjs/index.js CHANGED
@@ -10,7 +10,7 @@ class DotBotsAuthError extends Error {
10
10
  }
11
11
 
12
12
  class TokenManager {
13
- constructor(config, environment, onRefreshed, onSessionExpired) {
13
+ constructor(config, environment, onRefreshed, onSessionExpired, getBaseUrl) {
14
14
  this.accessToken = null;
15
15
  this.refreshToken = null;
16
16
  this.expiresAt = 0;
@@ -19,6 +19,7 @@ class TokenManager {
19
19
  this.environment = environment;
20
20
  this.onRefreshed = onRefreshed;
21
21
  this.onSessionExpired = onSessionExpired;
22
+ this.getBaseUrl = getBaseUrl;
22
23
  }
23
24
  setTokens(tokens) {
24
25
  this.accessToken = tokens.accessToken;
@@ -33,7 +34,12 @@ class TokenManager {
33
34
  return this.accessToken !== null && Date.now() < this.expiresAt;
34
35
  }
35
36
  async exchangeCode(code) {
36
- const response = await this.apiRequest('/api/auth/token', {
37
+ if (!code) {
38
+ console.error('[DotBotsAuth] exchangeCode called without a code — aborting token exchange');
39
+ throw new DotBotsAuthError('CODE_EXPIRED', 'No auth code provided');
40
+ }
41
+ console.warn(`[DotBotsAuth] Exchanging auth code: ${code.substring(0, 2)}**`);
42
+ const response = await this.apiRequest('/auth/token', {
37
43
  method: 'POST',
38
44
  headers: { 'Content-Type': 'application/json' },
39
45
  body: JSON.stringify({ code, appId: this.config.appId }),
@@ -53,7 +59,7 @@ class TokenManager {
53
59
  }
54
60
  let response;
55
61
  try {
56
- response = await this.apiRequest('/api/auth/refresh', {
62
+ response = await this.apiRequest('/auth/refresh', {
57
63
  method: 'POST',
58
64
  headers: { 'Content-Type': 'application/json' },
59
65
  body: JSON.stringify({
@@ -74,7 +80,7 @@ class TokenManager {
74
80
  async revoke() {
75
81
  if (this.accessToken && this.refreshToken) {
76
82
  try {
77
- await this.apiRequest('/api/auth/revoke', {
83
+ await this.apiRequest('/auth/revoke', {
78
84
  method: 'POST',
79
85
  headers: {
80
86
  'Content-Type': 'application/json',
@@ -116,10 +122,13 @@ class TokenManager {
116
122
  }, delay);
117
123
  }
118
124
  apiRequest(path, init) {
125
+ const baseUrl = this.getBaseUrl();
126
+ const fullUrl = `${baseUrl}${path}`;
127
+ console.warn(`[DotBotsAuth] API request: ${init.method ?? 'GET'} ${fullUrl}`);
119
128
  const headers = new Headers(init.headers);
120
129
  headers.set('X-App-Id', this.config.appId);
121
130
  headers.set('X-Environment', this.environment);
122
- return fetch(`${this.config.apiUrl}${path}`, { ...init, headers });
131
+ return fetch(fullUrl, { ...init, headers });
123
132
  }
124
133
  }
125
134
 
@@ -195,7 +204,9 @@ class ProxyConfigManager {
195
204
  }
196
205
  async fetchConfig() {
197
206
  try {
198
- const response = await fetch(`${this.apiUrl}/api/proxy/config`, {
207
+ const url = `${this.apiUrl}/api/proxy/config`;
208
+ console.warn(`[DotBotsAuth] Fetching proxy config from ${url}`);
209
+ const response = await fetch(url, {
199
210
  headers: {
200
211
  'X-App-Id': this.appId,
201
212
  'X-Environment': this.environment,
@@ -205,10 +216,10 @@ class ProxyConfigManager {
205
216
  throw new Error(`Proxy config request failed: ${response.status}`);
206
217
  }
207
218
  this.config = await response.json();
219
+ console.warn(`[DotBotsAuth] Proxy config loaded — proxyUrl: ${this.config.proxyUrl}`);
208
220
  }
209
221
  catch (err) {
210
- // Non-fatal: log warning, SDK falls back to direct apiUrl
211
- console.warn('[DotBotsAuth] Could not fetch proxy config, falling back to direct API:', err instanceof Error ? err.message : err);
222
+ console.error('[DotBotsAuth] Could not fetch proxy config:', err instanceof Error ? err.message : err);
212
223
  this.config = null;
213
224
  }
214
225
  }
@@ -219,11 +230,16 @@ class ProxyConfigManager {
219
230
  return this.config;
220
231
  }
221
232
  /**
222
- * Returns the base URL to use for auth.fetch() calls.
223
- * Uses the proxy if available, otherwise falls back to apiUrl.
233
+ * Returns the base URL to use for API calls.
234
+ * Returns proxyUrl if available. If not, logs an error and returns apiUrl.
224
235
  */
225
236
  getBaseUrl() {
226
- return this.config !== null ? this.config.proxyUrl : this.apiUrl;
237
+ if (this.config !== null) {
238
+ console.warn(`[DotBotsAuth] getBaseUrl → ${this.config.proxyUrl}`);
239
+ return this.config.proxyUrl;
240
+ }
241
+ console.error('[DotBotsAuth] No proxyUrl available — proxy config was not fetched or failed. Falling back to apiUrl.');
242
+ return this.apiUrl;
227
243
  }
228
244
  }
229
245
 
@@ -234,8 +250,9 @@ class DotBotsAuth {
234
250
  this.initialized = false;
235
251
  this.config = config;
236
252
  this.environment = this.detectEnvironment();
253
+ console.warn(`[DotBotsAuth] SDK v${DotBotsAuth.SDK_VERSION} — env: ${this.environment}, appId: ${config.appId}`);
237
254
  const marketplaceOrigin = config.marketplaceOrigin ?? 'https://dotbots.boutique';
238
- this.tokenManager = new TokenManager(config, this.environment, () => this.emit('tokenRefreshed'), () => this.emit('sessionExpired'));
255
+ this.tokenManager = new TokenManager(config, this.environment, () => this.emit('tokenRefreshed'), () => this.emit('sessionExpired'), () => this.proxyConfigManager.getBaseUrl());
239
256
  this.postMessageHandler = new PostMessageHandler(marketplaceOrigin);
240
257
  this.proxyConfigManager = new ProxyConfigManager(config.apiUrl, config.appId, this.environment);
241
258
  }
@@ -255,7 +272,7 @@ class DotBotsAuth {
255
272
  this.assertInitialized();
256
273
  if (this.cachedUser)
257
274
  return this.cachedUser;
258
- const response = await this.buildRequest(`${this.config.apiUrl}/api/auth/me`);
275
+ const response = await this.buildRequest(`${this.proxyConfigManager.getBaseUrl()}/auth/me`);
259
276
  if (!response.ok) {
260
277
  if (response.status === 401) {
261
278
  throw new DotBotsAuthError('UNAUTHORIZED', 'Not authorized to access this app');
@@ -312,7 +329,7 @@ class DotBotsAuth {
312
329
  }
313
330
  else {
314
331
  const redirectUri = encodeURIComponent(window.location.origin);
315
- window.location.href = `${this.config.apiUrl}/api/auth/logout?redirectUri=${redirectUri}`;
332
+ window.location.href = `${this.config.apiUrl}/auth/logout?redirectUri=${redirectUri}`;
316
333
  }
317
334
  }
318
335
  on(event, handler) {
@@ -340,12 +357,18 @@ class DotBotsAuth {
340
357
  async initializeIframe() {
341
358
  const timeout = this.config.iframeTimeout ?? 5000;
342
359
  const code = await this.postMessageHandler.requestAuthCode(this.config.appId, timeout);
360
+ if (!code) {
361
+ console.error('[DotBotsAuth] Received empty auth code from iframe parent');
362
+ throw new DotBotsAuthError('CODE_EXPIRED', 'Received empty auth code from iframe parent');
363
+ }
364
+ console.warn(`[DotBotsAuth] Received auth code from iframe: ${code.substring(0, 2)}**`);
343
365
  await this.tokenManager.exchangeCode(code);
344
366
  }
345
367
  async initializeStandalone() {
346
368
  const url = new URL(window.location.href);
347
369
  const code = url.searchParams.get('code');
348
370
  if (code) {
371
+ console.warn(`[DotBotsAuth] Received auth code from URL: ${code.substring(0, 2)}**`);
349
372
  // Remove code from URL immediately
350
373
  url.searchParams.delete('code');
351
374
  window.history.replaceState({}, '', url.toString());
@@ -354,7 +377,7 @@ class DotBotsAuth {
354
377
  else if (!this.tokenManager.isAuthenticated()) {
355
378
  // Redirect to auth
356
379
  const redirectUri = encodeURIComponent(window.location.href);
357
- window.location.href = `${this.config.apiUrl}/api/auth/authorize?appId=${this.config.appId}&redirectUri=${redirectUri}`;
380
+ window.location.href = `${this.config.apiUrl}/auth/authorize?appId=${this.config.appId}&redirectUri=${redirectUri}`;
358
381
  }
359
382
  }
360
383
  async buildRequest(url, options) {
@@ -386,6 +409,7 @@ class DotBotsAuth {
386
409
  }
387
410
  }
388
411
  }
412
+ DotBotsAuth.SDK_VERSION = '1.0.7';
389
413
 
390
414
  exports.DotBotsAuth = DotBotsAuth;
391
415
  exports.DotBotsAuthError = DotBotsAuthError;
package/dist/esm/index.js CHANGED
@@ -8,7 +8,7 @@ class DotBotsAuthError extends Error {
8
8
  }
9
9
 
10
10
  class TokenManager {
11
- constructor(config, environment, onRefreshed, onSessionExpired) {
11
+ constructor(config, environment, onRefreshed, onSessionExpired, getBaseUrl) {
12
12
  this.accessToken = null;
13
13
  this.refreshToken = null;
14
14
  this.expiresAt = 0;
@@ -17,6 +17,7 @@ class TokenManager {
17
17
  this.environment = environment;
18
18
  this.onRefreshed = onRefreshed;
19
19
  this.onSessionExpired = onSessionExpired;
20
+ this.getBaseUrl = getBaseUrl;
20
21
  }
21
22
  setTokens(tokens) {
22
23
  this.accessToken = tokens.accessToken;
@@ -31,7 +32,12 @@ class TokenManager {
31
32
  return this.accessToken !== null && Date.now() < this.expiresAt;
32
33
  }
33
34
  async exchangeCode(code) {
34
- const response = await this.apiRequest('/api/auth/token', {
35
+ if (!code) {
36
+ console.error('[DotBotsAuth] exchangeCode called without a code — aborting token exchange');
37
+ throw new DotBotsAuthError('CODE_EXPIRED', 'No auth code provided');
38
+ }
39
+ console.warn(`[DotBotsAuth] Exchanging auth code: ${code.substring(0, 2)}**`);
40
+ const response = await this.apiRequest('/auth/token', {
35
41
  method: 'POST',
36
42
  headers: { 'Content-Type': 'application/json' },
37
43
  body: JSON.stringify({ code, appId: this.config.appId }),
@@ -51,7 +57,7 @@ class TokenManager {
51
57
  }
52
58
  let response;
53
59
  try {
54
- response = await this.apiRequest('/api/auth/refresh', {
60
+ response = await this.apiRequest('/auth/refresh', {
55
61
  method: 'POST',
56
62
  headers: { 'Content-Type': 'application/json' },
57
63
  body: JSON.stringify({
@@ -72,7 +78,7 @@ class TokenManager {
72
78
  async revoke() {
73
79
  if (this.accessToken && this.refreshToken) {
74
80
  try {
75
- await this.apiRequest('/api/auth/revoke', {
81
+ await this.apiRequest('/auth/revoke', {
76
82
  method: 'POST',
77
83
  headers: {
78
84
  'Content-Type': 'application/json',
@@ -114,10 +120,13 @@ class TokenManager {
114
120
  }, delay);
115
121
  }
116
122
  apiRequest(path, init) {
123
+ const baseUrl = this.getBaseUrl();
124
+ const fullUrl = `${baseUrl}${path}`;
125
+ console.warn(`[DotBotsAuth] API request: ${init.method ?? 'GET'} ${fullUrl}`);
117
126
  const headers = new Headers(init.headers);
118
127
  headers.set('X-App-Id', this.config.appId);
119
128
  headers.set('X-Environment', this.environment);
120
- return fetch(`${this.config.apiUrl}${path}`, { ...init, headers });
129
+ return fetch(fullUrl, { ...init, headers });
121
130
  }
122
131
  }
123
132
 
@@ -193,7 +202,9 @@ class ProxyConfigManager {
193
202
  }
194
203
  async fetchConfig() {
195
204
  try {
196
- const response = await fetch(`${this.apiUrl}/api/proxy/config`, {
205
+ const url = `${this.apiUrl}/api/proxy/config`;
206
+ console.warn(`[DotBotsAuth] Fetching proxy config from ${url}`);
207
+ const response = await fetch(url, {
197
208
  headers: {
198
209
  'X-App-Id': this.appId,
199
210
  'X-Environment': this.environment,
@@ -203,10 +214,10 @@ class ProxyConfigManager {
203
214
  throw new Error(`Proxy config request failed: ${response.status}`);
204
215
  }
205
216
  this.config = await response.json();
217
+ console.warn(`[DotBotsAuth] Proxy config loaded — proxyUrl: ${this.config.proxyUrl}`);
206
218
  }
207
219
  catch (err) {
208
- // Non-fatal: log warning, SDK falls back to direct apiUrl
209
- console.warn('[DotBotsAuth] Could not fetch proxy config, falling back to direct API:', err instanceof Error ? err.message : err);
220
+ console.error('[DotBotsAuth] Could not fetch proxy config:', err instanceof Error ? err.message : err);
210
221
  this.config = null;
211
222
  }
212
223
  }
@@ -217,11 +228,16 @@ class ProxyConfigManager {
217
228
  return this.config;
218
229
  }
219
230
  /**
220
- * Returns the base URL to use for auth.fetch() calls.
221
- * Uses the proxy if available, otherwise falls back to apiUrl.
231
+ * Returns the base URL to use for API calls.
232
+ * Returns proxyUrl if available. If not, logs an error and returns apiUrl.
222
233
  */
223
234
  getBaseUrl() {
224
- return this.config !== null ? this.config.proxyUrl : this.apiUrl;
235
+ if (this.config !== null) {
236
+ console.warn(`[DotBotsAuth] getBaseUrl → ${this.config.proxyUrl}`);
237
+ return this.config.proxyUrl;
238
+ }
239
+ console.error('[DotBotsAuth] No proxyUrl available — proxy config was not fetched or failed. Falling back to apiUrl.');
240
+ return this.apiUrl;
225
241
  }
226
242
  }
227
243
 
@@ -232,8 +248,9 @@ class DotBotsAuth {
232
248
  this.initialized = false;
233
249
  this.config = config;
234
250
  this.environment = this.detectEnvironment();
251
+ console.warn(`[DotBotsAuth] SDK v${DotBotsAuth.SDK_VERSION} — env: ${this.environment}, appId: ${config.appId}`);
235
252
  const marketplaceOrigin = config.marketplaceOrigin ?? 'https://dotbots.boutique';
236
- this.tokenManager = new TokenManager(config, this.environment, () => this.emit('tokenRefreshed'), () => this.emit('sessionExpired'));
253
+ this.tokenManager = new TokenManager(config, this.environment, () => this.emit('tokenRefreshed'), () => this.emit('sessionExpired'), () => this.proxyConfigManager.getBaseUrl());
237
254
  this.postMessageHandler = new PostMessageHandler(marketplaceOrigin);
238
255
  this.proxyConfigManager = new ProxyConfigManager(config.apiUrl, config.appId, this.environment);
239
256
  }
@@ -253,7 +270,7 @@ class DotBotsAuth {
253
270
  this.assertInitialized();
254
271
  if (this.cachedUser)
255
272
  return this.cachedUser;
256
- const response = await this.buildRequest(`${this.config.apiUrl}/api/auth/me`);
273
+ const response = await this.buildRequest(`${this.proxyConfigManager.getBaseUrl()}/auth/me`);
257
274
  if (!response.ok) {
258
275
  if (response.status === 401) {
259
276
  throw new DotBotsAuthError('UNAUTHORIZED', 'Not authorized to access this app');
@@ -310,7 +327,7 @@ class DotBotsAuth {
310
327
  }
311
328
  else {
312
329
  const redirectUri = encodeURIComponent(window.location.origin);
313
- window.location.href = `${this.config.apiUrl}/api/auth/logout?redirectUri=${redirectUri}`;
330
+ window.location.href = `${this.config.apiUrl}/auth/logout?redirectUri=${redirectUri}`;
314
331
  }
315
332
  }
316
333
  on(event, handler) {
@@ -338,12 +355,18 @@ class DotBotsAuth {
338
355
  async initializeIframe() {
339
356
  const timeout = this.config.iframeTimeout ?? 5000;
340
357
  const code = await this.postMessageHandler.requestAuthCode(this.config.appId, timeout);
358
+ if (!code) {
359
+ console.error('[DotBotsAuth] Received empty auth code from iframe parent');
360
+ throw new DotBotsAuthError('CODE_EXPIRED', 'Received empty auth code from iframe parent');
361
+ }
362
+ console.warn(`[DotBotsAuth] Received auth code from iframe: ${code.substring(0, 2)}**`);
341
363
  await this.tokenManager.exchangeCode(code);
342
364
  }
343
365
  async initializeStandalone() {
344
366
  const url = new URL(window.location.href);
345
367
  const code = url.searchParams.get('code');
346
368
  if (code) {
369
+ console.warn(`[DotBotsAuth] Received auth code from URL: ${code.substring(0, 2)}**`);
347
370
  // Remove code from URL immediately
348
371
  url.searchParams.delete('code');
349
372
  window.history.replaceState({}, '', url.toString());
@@ -352,7 +375,7 @@ class DotBotsAuth {
352
375
  else if (!this.tokenManager.isAuthenticated()) {
353
376
  // Redirect to auth
354
377
  const redirectUri = encodeURIComponent(window.location.href);
355
- window.location.href = `${this.config.apiUrl}/api/auth/authorize?appId=${this.config.appId}&redirectUri=${redirectUri}`;
378
+ window.location.href = `${this.config.apiUrl}/auth/authorize?appId=${this.config.appId}&redirectUri=${redirectUri}`;
356
379
  }
357
380
  }
358
381
  async buildRequest(url, options) {
@@ -384,5 +407,6 @@ class DotBotsAuth {
384
407
  }
385
408
  }
386
409
  }
410
+ DotBotsAuth.SDK_VERSION = '1.0.7';
387
411
 
388
412
  export { DotBotsAuth, DotBotsAuthError };
@@ -8,6 +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.7";
11
12
  constructor(config: DotBotsConfig);
12
13
  initialize(): Promise<void>;
13
14
  getUser(): Promise<DotBotsUser>;
@@ -9,8 +9,8 @@ export declare class ProxyConfigManager {
9
9
  getProxyUrl(): string | null;
10
10
  getConfig(): DotBotsProxyConfig | null;
11
11
  /**
12
- * Returns the base URL to use for auth.fetch() calls.
13
- * Uses the proxy if available, otherwise falls back to apiUrl.
12
+ * Returns the base URL to use for API calls.
13
+ * Returns proxyUrl if available. If not, logs an error and returns apiUrl.
14
14
  */
15
15
  getBaseUrl(): string;
16
16
  }
@@ -8,7 +8,8 @@ export declare class TokenManager {
8
8
  private readonly environment;
9
9
  private readonly onRefreshed;
10
10
  private readonly onSessionExpired;
11
- constructor(config: DotBotsConfig, environment: DotBotsEnvironment, onRefreshed: () => void, onSessionExpired: () => void);
11
+ private readonly getBaseUrl;
12
+ constructor(config: DotBotsConfig, environment: DotBotsEnvironment, onRefreshed: () => void, onSessionExpired: () => void, getBaseUrl: () => string);
12
13
  setTokens(tokens: TokenPair): void;
13
14
  getAccessToken(): string | null;
14
15
  isAuthenticated(): boolean;
@@ -8,7 +8,7 @@ class DotBotsAuthError extends Error {
8
8
  }
9
9
 
10
10
  class TokenManager {
11
- constructor(config, environment, onRefreshed, onSessionExpired) {
11
+ constructor(config, environment, onRefreshed, onSessionExpired, getBaseUrl) {
12
12
  this.accessToken = null;
13
13
  this.refreshToken = null;
14
14
  this.expiresAt = 0;
@@ -17,6 +17,7 @@ class TokenManager {
17
17
  this.environment = environment;
18
18
  this.onRefreshed = onRefreshed;
19
19
  this.onSessionExpired = onSessionExpired;
20
+ this.getBaseUrl = getBaseUrl;
20
21
  }
21
22
  setTokens(tokens) {
22
23
  this.accessToken = tokens.accessToken;
@@ -31,7 +32,12 @@ class TokenManager {
31
32
  return this.accessToken !== null && Date.now() < this.expiresAt;
32
33
  }
33
34
  async exchangeCode(code) {
34
- const response = await this.apiRequest('/api/auth/token', {
35
+ if (!code) {
36
+ console.error('[DotBotsAuth] exchangeCode called without a code — aborting token exchange');
37
+ throw new DotBotsAuthError('CODE_EXPIRED', 'No auth code provided');
38
+ }
39
+ console.warn(`[DotBotsAuth] Exchanging auth code: ${code.substring(0, 2)}**`);
40
+ const response = await this.apiRequest('/auth/token', {
35
41
  method: 'POST',
36
42
  headers: { 'Content-Type': 'application/json' },
37
43
  body: JSON.stringify({ code, appId: this.config.appId }),
@@ -51,7 +57,7 @@ class TokenManager {
51
57
  }
52
58
  let response;
53
59
  try {
54
- response = await this.apiRequest('/api/auth/refresh', {
60
+ response = await this.apiRequest('/auth/refresh', {
55
61
  method: 'POST',
56
62
  headers: { 'Content-Type': 'application/json' },
57
63
  body: JSON.stringify({
@@ -72,7 +78,7 @@ class TokenManager {
72
78
  async revoke() {
73
79
  if (this.accessToken && this.refreshToken) {
74
80
  try {
75
- await this.apiRequest('/api/auth/revoke', {
81
+ await this.apiRequest('/auth/revoke', {
76
82
  method: 'POST',
77
83
  headers: {
78
84
  'Content-Type': 'application/json',
@@ -114,10 +120,13 @@ class TokenManager {
114
120
  }, delay);
115
121
  }
116
122
  apiRequest(path, init) {
123
+ const baseUrl = this.getBaseUrl();
124
+ const fullUrl = `${baseUrl}${path}`;
125
+ console.warn(`[DotBotsAuth] API request: ${init.method ?? 'GET'} ${fullUrl}`);
117
126
  const headers = new Headers(init.headers);
118
127
  headers.set('X-App-Id', this.config.appId);
119
128
  headers.set('X-Environment', this.environment);
120
- return fetch(`${this.config.apiUrl}${path}`, { ...init, headers });
129
+ return fetch(fullUrl, { ...init, headers });
121
130
  }
122
131
  }
123
132
 
@@ -193,7 +202,9 @@ class ProxyConfigManager {
193
202
  }
194
203
  async fetchConfig() {
195
204
  try {
196
- const response = await fetch(`${this.apiUrl}/api/proxy/config`, {
205
+ const url = `${this.apiUrl}/api/proxy/config`;
206
+ console.warn(`[DotBotsAuth] Fetching proxy config from ${url}`);
207
+ const response = await fetch(url, {
197
208
  headers: {
198
209
  'X-App-Id': this.appId,
199
210
  'X-Environment': this.environment,
@@ -203,10 +214,10 @@ class ProxyConfigManager {
203
214
  throw new Error(`Proxy config request failed: ${response.status}`);
204
215
  }
205
216
  this.config = await response.json();
217
+ console.warn(`[DotBotsAuth] Proxy config loaded — proxyUrl: ${this.config.proxyUrl}`);
206
218
  }
207
219
  catch (err) {
208
- // Non-fatal: log warning, SDK falls back to direct apiUrl
209
- console.warn('[DotBotsAuth] Could not fetch proxy config, falling back to direct API:', err instanceof Error ? err.message : err);
220
+ console.error('[DotBotsAuth] Could not fetch proxy config:', err instanceof Error ? err.message : err);
210
221
  this.config = null;
211
222
  }
212
223
  }
@@ -217,11 +228,16 @@ class ProxyConfigManager {
217
228
  return this.config;
218
229
  }
219
230
  /**
220
- * Returns the base URL to use for auth.fetch() calls.
221
- * Uses the proxy if available, otherwise falls back to apiUrl.
231
+ * Returns the base URL to use for API calls.
232
+ * Returns proxyUrl if available. If not, logs an error and returns apiUrl.
222
233
  */
223
234
  getBaseUrl() {
224
- return this.config !== null ? this.config.proxyUrl : this.apiUrl;
235
+ if (this.config !== null) {
236
+ console.warn(`[DotBotsAuth] getBaseUrl → ${this.config.proxyUrl}`);
237
+ return this.config.proxyUrl;
238
+ }
239
+ console.error('[DotBotsAuth] No proxyUrl available — proxy config was not fetched or failed. Falling back to apiUrl.');
240
+ return this.apiUrl;
225
241
  }
226
242
  }
227
243
 
@@ -232,8 +248,9 @@ class DotBotsAuth {
232
248
  this.initialized = false;
233
249
  this.config = config;
234
250
  this.environment = this.detectEnvironment();
251
+ console.warn(`[DotBotsAuth] SDK v${DotBotsAuth.SDK_VERSION} — env: ${this.environment}, appId: ${config.appId}`);
235
252
  const marketplaceOrigin = config.marketplaceOrigin ?? 'https://dotbots.boutique';
236
- this.tokenManager = new TokenManager(config, this.environment, () => this.emit('tokenRefreshed'), () => this.emit('sessionExpired'));
253
+ this.tokenManager = new TokenManager(config, this.environment, () => this.emit('tokenRefreshed'), () => this.emit('sessionExpired'), () => this.proxyConfigManager.getBaseUrl());
237
254
  this.postMessageHandler = new PostMessageHandler(marketplaceOrigin);
238
255
  this.proxyConfigManager = new ProxyConfigManager(config.apiUrl, config.appId, this.environment);
239
256
  }
@@ -253,7 +270,7 @@ class DotBotsAuth {
253
270
  this.assertInitialized();
254
271
  if (this.cachedUser)
255
272
  return this.cachedUser;
256
- const response = await this.buildRequest(`${this.config.apiUrl}/api/auth/me`);
273
+ const response = await this.buildRequest(`${this.proxyConfigManager.getBaseUrl()}/auth/me`);
257
274
  if (!response.ok) {
258
275
  if (response.status === 401) {
259
276
  throw new DotBotsAuthError('UNAUTHORIZED', 'Not authorized to access this app');
@@ -310,7 +327,7 @@ class DotBotsAuth {
310
327
  }
311
328
  else {
312
329
  const redirectUri = encodeURIComponent(window.location.origin);
313
- window.location.href = `${this.config.apiUrl}/api/auth/logout?redirectUri=${redirectUri}`;
330
+ window.location.href = `${this.config.apiUrl}/auth/logout?redirectUri=${redirectUri}`;
314
331
  }
315
332
  }
316
333
  on(event, handler) {
@@ -338,12 +355,18 @@ class DotBotsAuth {
338
355
  async initializeIframe() {
339
356
  const timeout = this.config.iframeTimeout ?? 5000;
340
357
  const code = await this.postMessageHandler.requestAuthCode(this.config.appId, timeout);
358
+ if (!code) {
359
+ console.error('[DotBotsAuth] Received empty auth code from iframe parent');
360
+ throw new DotBotsAuthError('CODE_EXPIRED', 'Received empty auth code from iframe parent');
361
+ }
362
+ console.warn(`[DotBotsAuth] Received auth code from iframe: ${code.substring(0, 2)}**`);
341
363
  await this.tokenManager.exchangeCode(code);
342
364
  }
343
365
  async initializeStandalone() {
344
366
  const url = new URL(window.location.href);
345
367
  const code = url.searchParams.get('code');
346
368
  if (code) {
369
+ console.warn(`[DotBotsAuth] Received auth code from URL: ${code.substring(0, 2)}**`);
347
370
  // Remove code from URL immediately
348
371
  url.searchParams.delete('code');
349
372
  window.history.replaceState({}, '', url.toString());
@@ -352,7 +375,7 @@ class DotBotsAuth {
352
375
  else if (!this.tokenManager.isAuthenticated()) {
353
376
  // Redirect to auth
354
377
  const redirectUri = encodeURIComponent(window.location.href);
355
- window.location.href = `${this.config.apiUrl}/api/auth/authorize?appId=${this.config.appId}&redirectUri=${redirectUri}`;
378
+ window.location.href = `${this.config.apiUrl}/auth/authorize?appId=${this.config.appId}&redirectUri=${redirectUri}`;
356
379
  }
357
380
  }
358
381
  async buildRequest(url, options) {
@@ -384,5 +407,6 @@ class DotBotsAuth {
384
407
  }
385
408
  }
386
409
  }
410
+ DotBotsAuth.SDK_VERSION = '1.0.7';
387
411
 
388
412
  export { DotBotsAuth, DotBotsAuthError };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dotbots-boutique/auth-sdk",
3
- "version": "1.0.5",
3
+ "version": "1.0.7",
4
4
  "description": "Authentication SDK for DotBots marketplace apps",
5
5
  "license": "MIT",
6
6
  "type": "module",