@aurabase/aurabase-js 0.6.2 → 0.7.1

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
@@ -25,8 +25,10 @@ bun add @aurabase/aurabase-js
25
25
  Ce package ne réimplémente aucune logique de service : il compose `AuthService`, `DatabaseService`, `StorageService`, `RealtimeService`, `FunctionsService`, `AiService` et `NotificationsService` (chacun dans son propre package `@aurabase/*`) derrière un seul client.
26
26
 
27
27
  - `createClient(projectUrl, apiKey, options?)` — client applicatif standard. **L'URL est le projet** : chaque projet est servi sur son propre sous-domaine (`https://<slug>.aurabase.cloud`) et la passerelle injecte elle-même le `project_id` dans le chemin. Aucun identifiant de projet dans le code client.
28
- - `createAdminClient(projectUrl, serviceRoleKey, options?)` — client serveur avec `authAdmin` (clé `service_role`, jamais côté navigateur).
29
- - `@aurabase/aurabase-js/ssr` — `createServerClient`/`createBrowserClient` pour Next.js et frameworks SSR (cookies, session partagée serveur/navigateur).
28
+ - `createAdminClient(projectUrl, serviceRoleKey, options?)` — client serveur avec `authAdmin` (clé `service_role`, jamais côté navigateur : gestion des utilisateurs, impersonation RFC 8693, import d'utilisateurs bcrypt/Argon2id).
29
+ - `@aurabase/aurabase-js/ssr` — `createServerClient`/`createBrowserClient` pour Next.js et frameworks SSR (cookies légers, session partagée serveur/navigateur).
30
+ - `@aurabase/aurabase-js/react` — Hooks React (`useAuraSession`, `useAuraUser`) et contexte pour applications React / Next.js Client Components.
31
+ - `@aurabase/aurabase-js/nextjs` — Helpers pour Next.js App Router (Middleware de rafraîchissement de session, Server Actions).
30
32
 
31
33
  ## Quick Start
32
34
 
@@ -65,6 +65,7 @@ declare class AuraClient<Database = any, Schema extends GenericSchema = Database
65
65
  private readonly _persistSession;
66
66
  private readonly _autoRefresh;
67
67
  private readonly _detectSessionInUrl;
68
+ private readonly _flowType;
68
69
  /**
69
70
  * @param baseUrl URL du projet (`https://<slug>.aurabase.cloud`).
70
71
  * @param apiKey Clé API du projet (`aura_anon_…`, `aura_auth_…`, `aura_sk_…`).
@@ -65,6 +65,7 @@ declare class AuraClient<Database = any, Schema extends GenericSchema = Database
65
65
  private readonly _persistSession;
66
66
  private readonly _autoRefresh;
67
67
  private readonly _detectSessionInUrl;
68
+ private readonly _flowType;
68
69
  /**
69
70
  * @param baseUrl URL du projet (`https://<slug>.aurabase.cloud`).
70
71
  * @param apiKey Clé API du projet (`aura_anon_…`, `aura_auth_…`, `aura_sk_…`).
package/dist/index.cjs CHANGED
@@ -56,6 +56,7 @@ var AuraClient = class {
56
56
  _persistSession;
57
57
  _autoRefresh;
58
58
  _detectSessionInUrl;
59
+ _flowType;
59
60
  /**
60
61
  * @param baseUrl URL du projet (`https://<slug>.aurabase.cloud`).
61
62
  * @param apiKey Clé API du projet (`aura_anon_…`, `aura_auth_…`, `aura_sk_…`).
@@ -87,17 +88,18 @@ var AuraClient = class {
87
88
  this.debug = resolvedOptions?.debug;
88
89
  if (!this.apiKey && typeof console !== "undefined") {
89
90
  console.warn(
90
- "[aurabase] No API key provided. Most operations require an API key (apikey header). Only public auth routes (register, login, refresh) will work without one."
91
+ // AUTH-041 — la passerelle refuse TOUTE requête sans clé (401), y compris register/login.
92
+ "[aurabase] No API key provided: every request will be refused (401). Pass the anon key shown in Studio \u203A Settings \u203A Connection."
91
93
  );
92
94
  }
93
95
  if (typeof console !== "undefined" && /^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?\/?$/.test(this.baseUrl)) {
94
96
  console.warn(
95
- "[aurabase] Attention : en local, l'URL du projet doit inclure le sous-domaine (ex: http://<slug>.localhost:8080) pour permettre la r\xE9solution automatique du projet par la passerelle."
97
+ "[aurabase] Warning: locally, the project URL must include the sub-domain (e.g. http://<slug>.localhost:8080) so that the gateway can resolve the project automatically."
96
98
  );
97
99
  }
98
100
  if (this.apiKey?.startsWith(SERVICE_ROLE_KEY_PREFIX) && isBrowserContext()) {
99
101
  const refuse = resolvedOptions?.refuseServiceRoleInBrowser ?? true;
100
- const message = "[aurabase] S\xC9CURIT\xC9 : une cl\xE9 service_role (aura_sk_\u2026) est fournie \xE0 createClient() dans un contexte navigateur. Cette cl\xE9 \xE0 privil\xE8ges \xE9lev\xE9s NE DOIT JAMAIS \xEAtre expos\xE9e c\xF4t\xE9 client (elle fuiterait dans le bundle). Utilisez une cl\xE9 anon (aura_anon_\u2026) c\xF4t\xE9 client, et createAdminClient() c\xF4t\xE9 serveur pour les op\xE9rations d'administration.";
102
+ const message = "[aurabase] SECURITY: a service_role key (aura_sk_\u2026) is passed to createClient() in a browser context. This high-privilege key MUST NEVER be exposed client-side (it would leak into the bundle). Use an anon key (aura_anon_\u2026) on the client, and createAdminClient() on the server for administration operations.";
101
103
  if (refuse) {
102
104
  throw new Error(message);
103
105
  } else if (typeof console !== "undefined") {
@@ -122,6 +124,7 @@ var AuraClient = class {
122
124
  this._persistSession = resolvedOptions?.auth?.persistSession !== false;
123
125
  this._autoRefresh = resolvedOptions?.auth?.autoRefresh ?? true;
124
126
  this._detectSessionInUrl = resolvedOptions?.auth?.detectSessionInUrl;
127
+ this._flowType = resolvedOptions?.auth?.flowType;
125
128
  if (this._autoRefresh && this._persistSession && typeof window !== "undefined") {
126
129
  void this.auth;
127
130
  }
@@ -146,7 +149,8 @@ var AuraClient = class {
146
149
  this._auth = new auth.AuthService(this, {
147
150
  autoRefresh: this._autoRefresh,
148
151
  persistSession: this._persistSession,
149
- detectSessionInUrl: this._detectSessionInUrl
152
+ detectSessionInUrl: this._detectSessionInUrl,
153
+ flowType: this._flowType
150
154
  });
151
155
  this._auth.onAuthStateChange(({ event, accessToken }) => {
152
156
  if (this._realtime) {
@@ -167,7 +171,7 @@ var AuraClient = class {
167
171
  get authAdmin() {
168
172
  if (isBrowserContext()) {
169
173
  throw new Error(
170
- "[aurabase] S\xC9CURIT\xC9 : authAdmin est inaccessible dans un contexte navigateur. L'API admin requiert une cl\xE9 service_role qui ne doit JAMAIS \xEAtre expos\xE9e c\xF4t\xE9 client (elle fuiterait dans le bundle). Utilisez createAdminClient() c\xF4t\xE9 serveur uniquement."
174
+ "[aurabase] SECURITY: authAdmin is not available in a browser context. The admin API requires a service_role key, which must NEVER be exposed client-side (it would leak into the bundle). Use createAdminClient() on the server only."
171
175
  );
172
176
  }
173
177
  if (!this._authAdmin) this._authAdmin = new auth.AuthAdminService(this);
@@ -270,7 +274,7 @@ function createClient(baseUrl, apiKey, options) {
270
274
  function createAdminClient(baseUrl, serviceRoleKey, options) {
271
275
  if (isBrowserContext()) {
272
276
  throw new Error(
273
- "[aurabase] createAdminClient() ne doit jamais \xEAtre appel\xE9 c\xF4t\xE9 navigateur : la cl\xE9 service_role serait expos\xE9e dans le bundle. \xC0 utiliser uniquement c\xF4t\xE9 serveur."
277
+ "[aurabase] createAdminClient() must never be called in a browser: the service_role key would be exposed in the bundle. Use it on the server only."
274
278
  );
275
279
  }
276
280
  return new AuraClient(baseUrl, serviceRoleKey, options);
@@ -348,6 +352,10 @@ Object.defineProperty(exports, "RealtimeService", {
348
352
  enumerable: true,
349
353
  get: function () { return realtime.RealtimeService; }
350
354
  });
355
+ Object.defineProperty(exports, "StorageBucketClient", {
356
+ enumerable: true,
357
+ get: function () { return storage.StorageBucketClient; }
358
+ });
351
359
  Object.defineProperty(exports, "StorageService", {
352
360
  enumerable: true,
353
361
  get: function () { return storage.StorageService; }
package/dist/index.d.cts CHANGED
@@ -7,7 +7,7 @@ export { FunctionsHttpError, FunctionsRelayError, FunctionsResponseType, Functio
7
7
  export { NotificationsAdminService, NotificationsService } from '@aurabase/notifications';
8
8
  export { AuraChannel, RealtimeService } from '@aurabase/realtime';
9
9
  export { StorageBucketClient, StorageService } from '@aurabase/storage';
10
- import { A as AuraClient } from './AuraClient-BWdcX_k0.cjs';
10
+ import { A as AuraClient } from './AuraClient-B1OOZCSX.cjs';
11
11
 
12
12
  /**
13
13
  * Create a new Aurabase client instance.
package/dist/index.d.ts CHANGED
@@ -7,7 +7,7 @@ export { FunctionsHttpError, FunctionsRelayError, FunctionsResponseType, Functio
7
7
  export { NotificationsAdminService, NotificationsService } from '@aurabase/notifications';
8
8
  export { AuraChannel, RealtimeService } from '@aurabase/realtime';
9
9
  export { StorageBucketClient, StorageService } from '@aurabase/storage';
10
- import { A as AuraClient } from './AuraClient-BWdcX_k0.js';
10
+ import { A as AuraClient } from './AuraClient-B1OOZCSX.js';
11
11
 
12
12
  /**
13
13
  * Create a new Aurabase client instance.
package/dist/index.js CHANGED
@@ -13,7 +13,7 @@ export { NotificationsAdminService, NotificationsService } from '@aurabase/notif
13
13
  import { RealtimeService } from '@aurabase/realtime';
14
14
  export { AuraChannel, RealtimeService } from '@aurabase/realtime';
15
15
  import { StorageService } from '@aurabase/storage';
16
- export { StorageService } from '@aurabase/storage';
16
+ export { StorageBucketClient, StorageService } from '@aurabase/storage';
17
17
 
18
18
  // src/index.ts
19
19
  function isBrowserContext() {
@@ -62,6 +62,7 @@ var AuraClient = class {
62
62
  _persistSession;
63
63
  _autoRefresh;
64
64
  _detectSessionInUrl;
65
+ _flowType;
65
66
  /**
66
67
  * @param baseUrl URL du projet (`https://<slug>.aurabase.cloud`).
67
68
  * @param apiKey Clé API du projet (`aura_anon_…`, `aura_auth_…`, `aura_sk_…`).
@@ -93,17 +94,18 @@ var AuraClient = class {
93
94
  this.debug = resolvedOptions?.debug;
94
95
  if (!this.apiKey && typeof console !== "undefined") {
95
96
  console.warn(
96
- "[aurabase] No API key provided. Most operations require an API key (apikey header). Only public auth routes (register, login, refresh) will work without one."
97
+ // AUTH-041 — la passerelle refuse TOUTE requête sans clé (401), y compris register/login.
98
+ "[aurabase] No API key provided: every request will be refused (401). Pass the anon key shown in Studio \u203A Settings \u203A Connection."
97
99
  );
98
100
  }
99
101
  if (typeof console !== "undefined" && /^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?\/?$/.test(this.baseUrl)) {
100
102
  console.warn(
101
- "[aurabase] Attention : en local, l'URL du projet doit inclure le sous-domaine (ex: http://<slug>.localhost:8080) pour permettre la r\xE9solution automatique du projet par la passerelle."
103
+ "[aurabase] Warning: locally, the project URL must include the sub-domain (e.g. http://<slug>.localhost:8080) so that the gateway can resolve the project automatically."
102
104
  );
103
105
  }
104
106
  if (this.apiKey?.startsWith(SERVICE_ROLE_KEY_PREFIX) && isBrowserContext()) {
105
107
  const refuse = resolvedOptions?.refuseServiceRoleInBrowser ?? true;
106
- const message = "[aurabase] S\xC9CURIT\xC9 : une cl\xE9 service_role (aura_sk_\u2026) est fournie \xE0 createClient() dans un contexte navigateur. Cette cl\xE9 \xE0 privil\xE8ges \xE9lev\xE9s NE DOIT JAMAIS \xEAtre expos\xE9e c\xF4t\xE9 client (elle fuiterait dans le bundle). Utilisez une cl\xE9 anon (aura_anon_\u2026) c\xF4t\xE9 client, et createAdminClient() c\xF4t\xE9 serveur pour les op\xE9rations d'administration.";
108
+ const message = "[aurabase] SECURITY: a service_role key (aura_sk_\u2026) is passed to createClient() in a browser context. This high-privilege key MUST NEVER be exposed client-side (it would leak into the bundle). Use an anon key (aura_anon_\u2026) on the client, and createAdminClient() on the server for administration operations.";
107
109
  if (refuse) {
108
110
  throw new Error(message);
109
111
  } else if (typeof console !== "undefined") {
@@ -128,6 +130,7 @@ var AuraClient = class {
128
130
  this._persistSession = resolvedOptions?.auth?.persistSession !== false;
129
131
  this._autoRefresh = resolvedOptions?.auth?.autoRefresh ?? true;
130
132
  this._detectSessionInUrl = resolvedOptions?.auth?.detectSessionInUrl;
133
+ this._flowType = resolvedOptions?.auth?.flowType;
131
134
  if (this._autoRefresh && this._persistSession && typeof window !== "undefined") {
132
135
  void this.auth;
133
136
  }
@@ -152,7 +155,8 @@ var AuraClient = class {
152
155
  this._auth = new AuthService(this, {
153
156
  autoRefresh: this._autoRefresh,
154
157
  persistSession: this._persistSession,
155
- detectSessionInUrl: this._detectSessionInUrl
158
+ detectSessionInUrl: this._detectSessionInUrl,
159
+ flowType: this._flowType
156
160
  });
157
161
  this._auth.onAuthStateChange(({ event, accessToken }) => {
158
162
  if (this._realtime) {
@@ -173,7 +177,7 @@ var AuraClient = class {
173
177
  get authAdmin() {
174
178
  if (isBrowserContext()) {
175
179
  throw new Error(
176
- "[aurabase] S\xC9CURIT\xC9 : authAdmin est inaccessible dans un contexte navigateur. L'API admin requiert une cl\xE9 service_role qui ne doit JAMAIS \xEAtre expos\xE9e c\xF4t\xE9 client (elle fuiterait dans le bundle). Utilisez createAdminClient() c\xF4t\xE9 serveur uniquement."
180
+ "[aurabase] SECURITY: authAdmin is not available in a browser context. The admin API requires a service_role key, which must NEVER be exposed client-side (it would leak into the bundle). Use createAdminClient() on the server only."
177
181
  );
178
182
  }
179
183
  if (!this._authAdmin) this._authAdmin = new AuthAdminService(this);
@@ -276,7 +280,7 @@ function createClient(baseUrl, apiKey, options) {
276
280
  function createAdminClient(baseUrl, serviceRoleKey, options) {
277
281
  if (isBrowserContext()) {
278
282
  throw new Error(
279
- "[aurabase] createAdminClient() ne doit jamais \xEAtre appel\xE9 c\xF4t\xE9 navigateur : la cl\xE9 service_role serait expos\xE9e dans le bundle. \xC0 utiliser uniquement c\xF4t\xE9 serveur."
283
+ "[aurabase] createAdminClient() must never be called in a browser: the service_role key would be exposed in the bundle. Use it on the server only."
280
284
  );
281
285
  }
282
286
  return new AuraClient(baseUrl, serviceRoleKey, options);
package/dist/nextjs.cjs CHANGED
@@ -56,6 +56,7 @@ var AuraClient = class {
56
56
  _persistSession;
57
57
  _autoRefresh;
58
58
  _detectSessionInUrl;
59
+ _flowType;
59
60
  /**
60
61
  * @param baseUrl URL du projet (`https://<slug>.aurabase.cloud`).
61
62
  * @param apiKey Clé API du projet (`aura_anon_…`, `aura_auth_…`, `aura_sk_…`).
@@ -87,17 +88,18 @@ var AuraClient = class {
87
88
  this.debug = resolvedOptions?.debug;
88
89
  if (!this.apiKey && typeof console !== "undefined") {
89
90
  console.warn(
90
- "[aurabase] No API key provided. Most operations require an API key (apikey header). Only public auth routes (register, login, refresh) will work without one."
91
+ // AUTH-041 — la passerelle refuse TOUTE requête sans clé (401), y compris register/login.
92
+ "[aurabase] No API key provided: every request will be refused (401). Pass the anon key shown in Studio \u203A Settings \u203A Connection."
91
93
  );
92
94
  }
93
95
  if (typeof console !== "undefined" && /^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?\/?$/.test(this.baseUrl)) {
94
96
  console.warn(
95
- "[aurabase] Attention : en local, l'URL du projet doit inclure le sous-domaine (ex: http://<slug>.localhost:8080) pour permettre la r\xE9solution automatique du projet par la passerelle."
97
+ "[aurabase] Warning: locally, the project URL must include the sub-domain (e.g. http://<slug>.localhost:8080) so that the gateway can resolve the project automatically."
96
98
  );
97
99
  }
98
100
  if (this.apiKey?.startsWith(SERVICE_ROLE_KEY_PREFIX) && isBrowserContext()) {
99
101
  const refuse = resolvedOptions?.refuseServiceRoleInBrowser ?? true;
100
- const message = "[aurabase] S\xC9CURIT\xC9 : une cl\xE9 service_role (aura_sk_\u2026) est fournie \xE0 createClient() dans un contexte navigateur. Cette cl\xE9 \xE0 privil\xE8ges \xE9lev\xE9s NE DOIT JAMAIS \xEAtre expos\xE9e c\xF4t\xE9 client (elle fuiterait dans le bundle). Utilisez une cl\xE9 anon (aura_anon_\u2026) c\xF4t\xE9 client, et createAdminClient() c\xF4t\xE9 serveur pour les op\xE9rations d'administration.";
102
+ const message = "[aurabase] SECURITY: a service_role key (aura_sk_\u2026) is passed to createClient() in a browser context. This high-privilege key MUST NEVER be exposed client-side (it would leak into the bundle). Use an anon key (aura_anon_\u2026) on the client, and createAdminClient() on the server for administration operations.";
101
103
  if (refuse) {
102
104
  throw new Error(message);
103
105
  } else if (typeof console !== "undefined") {
@@ -122,6 +124,7 @@ var AuraClient = class {
122
124
  this._persistSession = resolvedOptions?.auth?.persistSession !== false;
123
125
  this._autoRefresh = resolvedOptions?.auth?.autoRefresh ?? true;
124
126
  this._detectSessionInUrl = resolvedOptions?.auth?.detectSessionInUrl;
127
+ this._flowType = resolvedOptions?.auth?.flowType;
125
128
  if (this._autoRefresh && this._persistSession && typeof window !== "undefined") {
126
129
  void this.auth;
127
130
  }
@@ -146,7 +149,8 @@ var AuraClient = class {
146
149
  this._auth = new auth$1.AuthService(this, {
147
150
  autoRefresh: this._autoRefresh,
148
151
  persistSession: this._persistSession,
149
- detectSessionInUrl: this._detectSessionInUrl
152
+ detectSessionInUrl: this._detectSessionInUrl,
153
+ flowType: this._flowType
150
154
  });
151
155
  this._auth.onAuthStateChange(({ event, accessToken }) => {
152
156
  if (this._realtime) {
@@ -167,7 +171,7 @@ var AuraClient = class {
167
171
  get authAdmin() {
168
172
  if (isBrowserContext()) {
169
173
  throw new Error(
170
- "[aurabase] S\xC9CURIT\xC9 : authAdmin est inaccessible dans un contexte navigateur. L'API admin requiert une cl\xE9 service_role qui ne doit JAMAIS \xEAtre expos\xE9e c\xF4t\xE9 client (elle fuiterait dans le bundle). Utilisez createAdminClient() c\xF4t\xE9 serveur uniquement."
174
+ "[aurabase] SECURITY: authAdmin is not available in a browser context. The admin API requires a service_role key, which must NEVER be exposed client-side (it would leak into the bundle). Use createAdminClient() on the server only."
171
175
  );
172
176
  }
173
177
  if (!this._authAdmin) this._authAdmin = new auth$1.AuthAdminService(this);
@@ -263,6 +267,7 @@ var AuraClient = class {
263
267
  }
264
268
  };
265
269
  var MAX_CHUNK_SIZE = 3600;
270
+ var WARN_COOKIE_BYTES = 8 * 1024;
266
271
  function createServerClient(baseUrl, apiKey, options) {
267
272
  const cookieName = `aura-${core.clientScope(baseUrl)}-auth`;
268
273
  const store = new core.LocalAuthStore(cookieName);
@@ -284,6 +289,7 @@ function createServerClient(baseUrl, apiKey, options) {
284
289
  // 30 days
285
290
  ...options.cookieOptions
286
291
  };
292
+ let tailleAvertie = false;
287
293
  store.onChange(() => {
288
294
  const toSet = [];
289
295
  const used = /* @__PURE__ */ new Set();
@@ -308,15 +314,46 @@ function createServerClient(baseUrl, apiKey, options) {
308
314
  }
309
315
  }
310
316
  }
317
+ const total = toSet.filter((c) => used.has(c.name)).reduce((n, c) => n + c.name.length + encodeURIComponent(c.value).length, 0);
318
+ if (total > WARN_COOKIE_BYTES && !tailleAvertie) {
319
+ tailleAvertie = true;
320
+ console.warn(
321
+ `[aurabase] The session cookie is ${total} bytes (more than 8 KB): servers and proxies often reject requests above that size (431). The access token carries user_metadata: store less in user_metadata and keep large data in your own tables.`
322
+ );
323
+ }
311
324
  const expireOpts = { ...defaultCookieOpts, maxAge: 0 };
312
325
  for (const name of initialNames) {
313
326
  if (!used.has(name)) toSet.push({ name, value: "", options: expireOpts });
314
327
  }
315
328
  if (toSet.length > 0) options.cookies.setAll(toSet);
316
329
  });
317
- return new AuraClient(baseUrl, apiKey, {
330
+ const client = new AuraClient(baseUrl, apiKey, {
318
331
  auth: { persistSession: false, storage: store }
319
332
  });
333
+ const getUser = client.auth.getUser.bind(client.auth);
334
+ const getSession = client.auth.getSession.bind(client.auth);
335
+ let verifie = null;
336
+ let averti = false;
337
+ client.auth.getUser = (async (...args) => {
338
+ const r = await getUser(...args);
339
+ verifie = !r.error && r.data ? r.data : null;
340
+ return r;
341
+ });
342
+ client.auth.getSession = (async () => {
343
+ const r = await getSession();
344
+ if (verifie) {
345
+ if (r.data.session) r.data.session = { ...r.data.session, user: verifie };
346
+ return { ...r, user: r.data.session ? verifie : null };
347
+ }
348
+ if (!averti) {
349
+ averti = true;
350
+ console.warn(
351
+ "[aurabase] getSession() on the server returns the session read from the cookie without verifying it: never use it to authorize a request. Call auth.getUser() (verified by the server) first."
352
+ );
353
+ }
354
+ return r;
355
+ });
356
+ return client;
320
357
  }
321
358
 
322
359
  // src/nextjs.ts
@@ -336,7 +373,7 @@ function createAuthMiddleware(options = {}) {
336
373
  const nextServer = await loadNextModule("next/server");
337
374
  if (!nextServer?.NextResponse) {
338
375
  throw new Error(
339
- "[@aurabase/nextjs] Next.js n'est pas install\xE9. createAuthMiddleware n\xE9cessite next/server."
376
+ "[@aurabase/nextjs] Next.js is not installed. createAuthMiddleware requires next/server."
340
377
  );
341
378
  }
342
379
  const { NextResponse } = nextServer;
@@ -344,7 +381,7 @@ function createAuthMiddleware(options = {}) {
344
381
  const anonKey = options.anonKey ?? process.env.NEXT_PUBLIC_AURABASE_ANON_KEY ?? "";
345
382
  if (!projectUrl || !anonKey) {
346
383
  console.warn(
347
- "[@aurabase/nextjs] Variables d'environnement manquantes : NEXT_PUBLIC_AURABASE_URL ou NEXT_PUBLIC_AURABASE_ANON_KEY non d\xE9finies."
384
+ "[@aurabase/nextjs] Missing environment variables: NEXT_PUBLIC_AURABASE_URL or NEXT_PUBLIC_AURABASE_ANON_KEY is not set."
348
385
  );
349
386
  return NextResponse.next({ request });
350
387
  }
@@ -361,9 +398,9 @@ function createAuthMiddleware(options = {}) {
361
398
  const client = createServerClient(projectUrl, anonKey, {
362
399
  cookies: cookieHandler
363
400
  });
364
- const { data: sessionData } = await client.auth.getSession();
365
- const session = sessionData?.session ?? null;
366
- const user = session?.user ?? null;
401
+ const { data: verifiedUser } = await client.auth.getUser();
402
+ const user = verifiedUser ?? null;
403
+ const session = user ? (await client.auth.getSession()).data?.session ?? null : null;
367
404
  const pathname = request.nextUrl.pathname;
368
405
  const publicPatterns = options.publicRoutes ?? ["/", "/login", "/signup", "/auth/callback"];
369
406
  const isPublic = publicPatterns.some((pattern) => {
@@ -412,13 +449,13 @@ function createClientForServerAction(cookieStore, projectUrl, apiKey) {
412
449
  async function auth(options) {
413
450
  const nextHeaders = await loadNextModule("next/headers");
414
451
  if (!nextHeaders?.cookies) {
415
- throw new Error("[@aurabase/nextjs] auth() ne peut \xEAtre appel\xE9 que dans un environnement Next.js App Router.");
452
+ throw new Error("[@aurabase/nextjs] auth() can only be called in a Next.js App Router environment.");
416
453
  }
417
454
  const cookieStore = await nextHeaders.cookies();
418
455
  const client = createClientForServerComponent(cookieStore, options?.projectUrl, options?.apiKey);
419
- const { data } = await client.auth.getSession();
420
- const session = data?.session ?? null;
421
- const user = session?.user ?? null;
456
+ const { data: verifiedUser } = await client.auth.getUser();
457
+ const user = verifiedUser ?? null;
458
+ const session = user ? (await client.auth.getSession()).data?.session ?? null : null;
422
459
  return {
423
460
  userId: user?.id ?? null,
424
461
  user,
package/dist/nextjs.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { A as AuraClient } from './AuraClient-BWdcX_k0.cjs';
1
+ import { A as AuraClient } from './AuraClient-B1OOZCSX.cjs';
2
2
  import { User, Session } from '@aurabase/core';
3
3
  import '@aurabase/ai';
4
4
  import '@aurabase/auth';
@@ -53,9 +53,9 @@ interface AuthContextParam {
53
53
  request: NextRequestLike;
54
54
  }
55
55
  interface AuthMiddlewareOptions {
56
- /** Project URL (defaults to process.env.NEXT_PUBLIC_AURABASE_URL — J1-004 : seul nom reconnu). */
56
+ /** Project URL (defaults to process.env.NEXT_PUBLIC_AURABASE_URL, the only variable name read). */
57
57
  projectUrl?: string;
58
- /** Anon API Key (defaults to process.env.NEXT_PUBLIC_AURABASE_ANON_KEY — J1-004 : seul nom reconnu). */
58
+ /** Anon API Key (defaults to process.env.NEXT_PUBLIC_AURABASE_ANON_KEY, the only variable name read). */
59
59
  anonKey?: string;
60
60
  /** List of route patterns that do not require authentication (e.g. ['/', '/login', '/signup', '/auth/*']). */
61
61
  publicRoutes?: string[];
package/dist/nextjs.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { A as AuraClient } from './AuraClient-BWdcX_k0.js';
1
+ import { A as AuraClient } from './AuraClient-B1OOZCSX.js';
2
2
  import { User, Session } from '@aurabase/core';
3
3
  import '@aurabase/ai';
4
4
  import '@aurabase/auth';
@@ -53,9 +53,9 @@ interface AuthContextParam {
53
53
  request: NextRequestLike;
54
54
  }
55
55
  interface AuthMiddlewareOptions {
56
- /** Project URL (defaults to process.env.NEXT_PUBLIC_AURABASE_URL — J1-004 : seul nom reconnu). */
56
+ /** Project URL (defaults to process.env.NEXT_PUBLIC_AURABASE_URL, the only variable name read). */
57
57
  projectUrl?: string;
58
- /** Anon API Key (defaults to process.env.NEXT_PUBLIC_AURABASE_ANON_KEY — J1-004 : seul nom reconnu). */
58
+ /** Anon API Key (defaults to process.env.NEXT_PUBLIC_AURABASE_ANON_KEY, the only variable name read). */
59
59
  anonKey?: string;
60
60
  /** List of route patterns that do not require authentication (e.g. ['/', '/login', '/signup', '/auth/*']). */
61
61
  publicRoutes?: string[];
package/dist/nextjs.js CHANGED
@@ -54,6 +54,7 @@ var AuraClient = class {
54
54
  _persistSession;
55
55
  _autoRefresh;
56
56
  _detectSessionInUrl;
57
+ _flowType;
57
58
  /**
58
59
  * @param baseUrl URL du projet (`https://<slug>.aurabase.cloud`).
59
60
  * @param apiKey Clé API du projet (`aura_anon_…`, `aura_auth_…`, `aura_sk_…`).
@@ -85,17 +86,18 @@ var AuraClient = class {
85
86
  this.debug = resolvedOptions?.debug;
86
87
  if (!this.apiKey && typeof console !== "undefined") {
87
88
  console.warn(
88
- "[aurabase] No API key provided. Most operations require an API key (apikey header). Only public auth routes (register, login, refresh) will work without one."
89
+ // AUTH-041 — la passerelle refuse TOUTE requête sans clé (401), y compris register/login.
90
+ "[aurabase] No API key provided: every request will be refused (401). Pass the anon key shown in Studio \u203A Settings \u203A Connection."
89
91
  );
90
92
  }
91
93
  if (typeof console !== "undefined" && /^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?\/?$/.test(this.baseUrl)) {
92
94
  console.warn(
93
- "[aurabase] Attention : en local, l'URL du projet doit inclure le sous-domaine (ex: http://<slug>.localhost:8080) pour permettre la r\xE9solution automatique du projet par la passerelle."
95
+ "[aurabase] Warning: locally, the project URL must include the sub-domain (e.g. http://<slug>.localhost:8080) so that the gateway can resolve the project automatically."
94
96
  );
95
97
  }
96
98
  if (this.apiKey?.startsWith(SERVICE_ROLE_KEY_PREFIX) && isBrowserContext()) {
97
99
  const refuse = resolvedOptions?.refuseServiceRoleInBrowser ?? true;
98
- const message = "[aurabase] S\xC9CURIT\xC9 : une cl\xE9 service_role (aura_sk_\u2026) est fournie \xE0 createClient() dans un contexte navigateur. Cette cl\xE9 \xE0 privil\xE8ges \xE9lev\xE9s NE DOIT JAMAIS \xEAtre expos\xE9e c\xF4t\xE9 client (elle fuiterait dans le bundle). Utilisez une cl\xE9 anon (aura_anon_\u2026) c\xF4t\xE9 client, et createAdminClient() c\xF4t\xE9 serveur pour les op\xE9rations d'administration.";
100
+ const message = "[aurabase] SECURITY: a service_role key (aura_sk_\u2026) is passed to createClient() in a browser context. This high-privilege key MUST NEVER be exposed client-side (it would leak into the bundle). Use an anon key (aura_anon_\u2026) on the client, and createAdminClient() on the server for administration operations.";
99
101
  if (refuse) {
100
102
  throw new Error(message);
101
103
  } else if (typeof console !== "undefined") {
@@ -120,6 +122,7 @@ var AuraClient = class {
120
122
  this._persistSession = resolvedOptions?.auth?.persistSession !== false;
121
123
  this._autoRefresh = resolvedOptions?.auth?.autoRefresh ?? true;
122
124
  this._detectSessionInUrl = resolvedOptions?.auth?.detectSessionInUrl;
125
+ this._flowType = resolvedOptions?.auth?.flowType;
123
126
  if (this._autoRefresh && this._persistSession && typeof window !== "undefined") {
124
127
  void this.auth;
125
128
  }
@@ -144,7 +147,8 @@ var AuraClient = class {
144
147
  this._auth = new AuthService(this, {
145
148
  autoRefresh: this._autoRefresh,
146
149
  persistSession: this._persistSession,
147
- detectSessionInUrl: this._detectSessionInUrl
150
+ detectSessionInUrl: this._detectSessionInUrl,
151
+ flowType: this._flowType
148
152
  });
149
153
  this._auth.onAuthStateChange(({ event, accessToken }) => {
150
154
  if (this._realtime) {
@@ -165,7 +169,7 @@ var AuraClient = class {
165
169
  get authAdmin() {
166
170
  if (isBrowserContext()) {
167
171
  throw new Error(
168
- "[aurabase] S\xC9CURIT\xC9 : authAdmin est inaccessible dans un contexte navigateur. L'API admin requiert une cl\xE9 service_role qui ne doit JAMAIS \xEAtre expos\xE9e c\xF4t\xE9 client (elle fuiterait dans le bundle). Utilisez createAdminClient() c\xF4t\xE9 serveur uniquement."
172
+ "[aurabase] SECURITY: authAdmin is not available in a browser context. The admin API requires a service_role key, which must NEVER be exposed client-side (it would leak into the bundle). Use createAdminClient() on the server only."
169
173
  );
170
174
  }
171
175
  if (!this._authAdmin) this._authAdmin = new AuthAdminService(this);
@@ -261,6 +265,7 @@ var AuraClient = class {
261
265
  }
262
266
  };
263
267
  var MAX_CHUNK_SIZE = 3600;
268
+ var WARN_COOKIE_BYTES = 8 * 1024;
264
269
  function createServerClient(baseUrl, apiKey, options) {
265
270
  const cookieName = `aura-${clientScope(baseUrl)}-auth`;
266
271
  const store = new LocalAuthStore(cookieName);
@@ -282,6 +287,7 @@ function createServerClient(baseUrl, apiKey, options) {
282
287
  // 30 days
283
288
  ...options.cookieOptions
284
289
  };
290
+ let tailleAvertie = false;
285
291
  store.onChange(() => {
286
292
  const toSet = [];
287
293
  const used = /* @__PURE__ */ new Set();
@@ -306,15 +312,46 @@ function createServerClient(baseUrl, apiKey, options) {
306
312
  }
307
313
  }
308
314
  }
315
+ const total = toSet.filter((c) => used.has(c.name)).reduce((n, c) => n + c.name.length + encodeURIComponent(c.value).length, 0);
316
+ if (total > WARN_COOKIE_BYTES && !tailleAvertie) {
317
+ tailleAvertie = true;
318
+ console.warn(
319
+ `[aurabase] The session cookie is ${total} bytes (more than 8 KB): servers and proxies often reject requests above that size (431). The access token carries user_metadata: store less in user_metadata and keep large data in your own tables.`
320
+ );
321
+ }
309
322
  const expireOpts = { ...defaultCookieOpts, maxAge: 0 };
310
323
  for (const name of initialNames) {
311
324
  if (!used.has(name)) toSet.push({ name, value: "", options: expireOpts });
312
325
  }
313
326
  if (toSet.length > 0) options.cookies.setAll(toSet);
314
327
  });
315
- return new AuraClient(baseUrl, apiKey, {
328
+ const client = new AuraClient(baseUrl, apiKey, {
316
329
  auth: { persistSession: false, storage: store }
317
330
  });
331
+ const getUser = client.auth.getUser.bind(client.auth);
332
+ const getSession = client.auth.getSession.bind(client.auth);
333
+ let verifie = null;
334
+ let averti = false;
335
+ client.auth.getUser = (async (...args) => {
336
+ const r = await getUser(...args);
337
+ verifie = !r.error && r.data ? r.data : null;
338
+ return r;
339
+ });
340
+ client.auth.getSession = (async () => {
341
+ const r = await getSession();
342
+ if (verifie) {
343
+ if (r.data.session) r.data.session = { ...r.data.session, user: verifie };
344
+ return { ...r, user: r.data.session ? verifie : null };
345
+ }
346
+ if (!averti) {
347
+ averti = true;
348
+ console.warn(
349
+ "[aurabase] getSession() on the server returns the session read from the cookie without verifying it: never use it to authorize a request. Call auth.getUser() (verified by the server) first."
350
+ );
351
+ }
352
+ return r;
353
+ });
354
+ return client;
318
355
  }
319
356
 
320
357
  // src/nextjs.ts
@@ -334,7 +371,7 @@ function createAuthMiddleware(options = {}) {
334
371
  const nextServer = await loadNextModule("next/server");
335
372
  if (!nextServer?.NextResponse) {
336
373
  throw new Error(
337
- "[@aurabase/nextjs] Next.js n'est pas install\xE9. createAuthMiddleware n\xE9cessite next/server."
374
+ "[@aurabase/nextjs] Next.js is not installed. createAuthMiddleware requires next/server."
338
375
  );
339
376
  }
340
377
  const { NextResponse } = nextServer;
@@ -342,7 +379,7 @@ function createAuthMiddleware(options = {}) {
342
379
  const anonKey = options.anonKey ?? process.env.NEXT_PUBLIC_AURABASE_ANON_KEY ?? "";
343
380
  if (!projectUrl || !anonKey) {
344
381
  console.warn(
345
- "[@aurabase/nextjs] Variables d'environnement manquantes : NEXT_PUBLIC_AURABASE_URL ou NEXT_PUBLIC_AURABASE_ANON_KEY non d\xE9finies."
382
+ "[@aurabase/nextjs] Missing environment variables: NEXT_PUBLIC_AURABASE_URL or NEXT_PUBLIC_AURABASE_ANON_KEY is not set."
346
383
  );
347
384
  return NextResponse.next({ request });
348
385
  }
@@ -359,9 +396,9 @@ function createAuthMiddleware(options = {}) {
359
396
  const client = createServerClient(projectUrl, anonKey, {
360
397
  cookies: cookieHandler
361
398
  });
362
- const { data: sessionData } = await client.auth.getSession();
363
- const session = sessionData?.session ?? null;
364
- const user = session?.user ?? null;
399
+ const { data: verifiedUser } = await client.auth.getUser();
400
+ const user = verifiedUser ?? null;
401
+ const session = user ? (await client.auth.getSession()).data?.session ?? null : null;
365
402
  const pathname = request.nextUrl.pathname;
366
403
  const publicPatterns = options.publicRoutes ?? ["/", "/login", "/signup", "/auth/callback"];
367
404
  const isPublic = publicPatterns.some((pattern) => {
@@ -410,13 +447,13 @@ function createClientForServerAction(cookieStore, projectUrl, apiKey) {
410
447
  async function auth(options) {
411
448
  const nextHeaders = await loadNextModule("next/headers");
412
449
  if (!nextHeaders?.cookies) {
413
- throw new Error("[@aurabase/nextjs] auth() ne peut \xEAtre appel\xE9 que dans un environnement Next.js App Router.");
450
+ throw new Error("[@aurabase/nextjs] auth() can only be called in a Next.js App Router environment.");
414
451
  }
415
452
  const cookieStore = await nextHeaders.cookies();
416
453
  const client = createClientForServerComponent(cookieStore, options?.projectUrl, options?.apiKey);
417
- const { data } = await client.auth.getSession();
418
- const session = data?.session ?? null;
419
- const user = session?.user ?? null;
454
+ const { data: verifiedUser } = await client.auth.getUser();
455
+ const user = verifiedUser ?? null;
456
+ const session = user ? (await client.auth.getSession()).data?.session ?? null : null;
420
457
  return {
421
458
  userId: user?.id ?? null,
422
459
  user,
package/dist/react.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { User, Session } from '@aurabase/core';
2
- import { A as AuraClient } from './AuraClient-BWdcX_k0.cjs';
2
+ import { A as AuraClient } from './AuraClient-B1OOZCSX.cjs';
3
3
  import '@aurabase/ai';
4
4
  import '@aurabase/auth';
5
5
  import '@aurabase/db';
package/dist/react.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { User, Session } from '@aurabase/core';
2
- import { A as AuraClient } from './AuraClient-BWdcX_k0.js';
2
+ import { A as AuraClient } from './AuraClient-B1OOZCSX.js';
3
3
  import '@aurabase/ai';
4
4
  import '@aurabase/auth';
5
5
  import '@aurabase/db';
package/dist/ssr.cjs CHANGED
@@ -56,6 +56,7 @@ var AuraClient = class {
56
56
  _persistSession;
57
57
  _autoRefresh;
58
58
  _detectSessionInUrl;
59
+ _flowType;
59
60
  /**
60
61
  * @param baseUrl URL du projet (`https://<slug>.aurabase.cloud`).
61
62
  * @param apiKey Clé API du projet (`aura_anon_…`, `aura_auth_…`, `aura_sk_…`).
@@ -87,17 +88,18 @@ var AuraClient = class {
87
88
  this.debug = resolvedOptions?.debug;
88
89
  if (!this.apiKey && typeof console !== "undefined") {
89
90
  console.warn(
90
- "[aurabase] No API key provided. Most operations require an API key (apikey header). Only public auth routes (register, login, refresh) will work without one."
91
+ // AUTH-041 — la passerelle refuse TOUTE requête sans clé (401), y compris register/login.
92
+ "[aurabase] No API key provided: every request will be refused (401). Pass the anon key shown in Studio \u203A Settings \u203A Connection."
91
93
  );
92
94
  }
93
95
  if (typeof console !== "undefined" && /^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?\/?$/.test(this.baseUrl)) {
94
96
  console.warn(
95
- "[aurabase] Attention : en local, l'URL du projet doit inclure le sous-domaine (ex: http://<slug>.localhost:8080) pour permettre la r\xE9solution automatique du projet par la passerelle."
97
+ "[aurabase] Warning: locally, the project URL must include the sub-domain (e.g. http://<slug>.localhost:8080) so that the gateway can resolve the project automatically."
96
98
  );
97
99
  }
98
100
  if (this.apiKey?.startsWith(SERVICE_ROLE_KEY_PREFIX) && isBrowserContext()) {
99
101
  const refuse = resolvedOptions?.refuseServiceRoleInBrowser ?? true;
100
- const message = "[aurabase] S\xC9CURIT\xC9 : une cl\xE9 service_role (aura_sk_\u2026) est fournie \xE0 createClient() dans un contexte navigateur. Cette cl\xE9 \xE0 privil\xE8ges \xE9lev\xE9s NE DOIT JAMAIS \xEAtre expos\xE9e c\xF4t\xE9 client (elle fuiterait dans le bundle). Utilisez une cl\xE9 anon (aura_anon_\u2026) c\xF4t\xE9 client, et createAdminClient() c\xF4t\xE9 serveur pour les op\xE9rations d'administration.";
102
+ const message = "[aurabase] SECURITY: a service_role key (aura_sk_\u2026) is passed to createClient() in a browser context. This high-privilege key MUST NEVER be exposed client-side (it would leak into the bundle). Use an anon key (aura_anon_\u2026) on the client, and createAdminClient() on the server for administration operations.";
101
103
  if (refuse) {
102
104
  throw new Error(message);
103
105
  } else if (typeof console !== "undefined") {
@@ -122,6 +124,7 @@ var AuraClient = class {
122
124
  this._persistSession = resolvedOptions?.auth?.persistSession !== false;
123
125
  this._autoRefresh = resolvedOptions?.auth?.autoRefresh ?? true;
124
126
  this._detectSessionInUrl = resolvedOptions?.auth?.detectSessionInUrl;
127
+ this._flowType = resolvedOptions?.auth?.flowType;
125
128
  if (this._autoRefresh && this._persistSession && typeof window !== "undefined") {
126
129
  void this.auth;
127
130
  }
@@ -146,7 +149,8 @@ var AuraClient = class {
146
149
  this._auth = new auth.AuthService(this, {
147
150
  autoRefresh: this._autoRefresh,
148
151
  persistSession: this._persistSession,
149
- detectSessionInUrl: this._detectSessionInUrl
152
+ detectSessionInUrl: this._detectSessionInUrl,
153
+ flowType: this._flowType
150
154
  });
151
155
  this._auth.onAuthStateChange(({ event, accessToken }) => {
152
156
  if (this._realtime) {
@@ -167,7 +171,7 @@ var AuraClient = class {
167
171
  get authAdmin() {
168
172
  if (isBrowserContext()) {
169
173
  throw new Error(
170
- "[aurabase] S\xC9CURIT\xC9 : authAdmin est inaccessible dans un contexte navigateur. L'API admin requiert une cl\xE9 service_role qui ne doit JAMAIS \xEAtre expos\xE9e c\xF4t\xE9 client (elle fuiterait dans le bundle). Utilisez createAdminClient() c\xF4t\xE9 serveur uniquement."
174
+ "[aurabase] SECURITY: authAdmin is not available in a browser context. The admin API requires a service_role key, which must NEVER be exposed client-side (it would leak into the bundle). Use createAdminClient() on the server only."
171
175
  );
172
176
  }
173
177
  if (!this._authAdmin) this._authAdmin = new auth.AuthAdminService(this);
@@ -263,6 +267,7 @@ var AuraClient = class {
263
267
  }
264
268
  };
265
269
  var MAX_CHUNK_SIZE = 3600;
270
+ var WARN_COOKIE_BYTES = 8 * 1024;
266
271
  function createServerClient(baseUrl, apiKey, options) {
267
272
  const cookieName = `aura-${core.clientScope(baseUrl)}-auth`;
268
273
  const store = new core.LocalAuthStore(cookieName);
@@ -284,6 +289,7 @@ function createServerClient(baseUrl, apiKey, options) {
284
289
  // 30 days
285
290
  ...options.cookieOptions
286
291
  };
292
+ let tailleAvertie = false;
287
293
  store.onChange(() => {
288
294
  const toSet = [];
289
295
  const used = /* @__PURE__ */ new Set();
@@ -308,15 +314,46 @@ function createServerClient(baseUrl, apiKey, options) {
308
314
  }
309
315
  }
310
316
  }
317
+ const total = toSet.filter((c) => used.has(c.name)).reduce((n, c) => n + c.name.length + encodeURIComponent(c.value).length, 0);
318
+ if (total > WARN_COOKIE_BYTES && !tailleAvertie) {
319
+ tailleAvertie = true;
320
+ console.warn(
321
+ `[aurabase] The session cookie is ${total} bytes (more than 8 KB): servers and proxies often reject requests above that size (431). The access token carries user_metadata: store less in user_metadata and keep large data in your own tables.`
322
+ );
323
+ }
311
324
  const expireOpts = { ...defaultCookieOpts, maxAge: 0 };
312
325
  for (const name of initialNames) {
313
326
  if (!used.has(name)) toSet.push({ name, value: "", options: expireOpts });
314
327
  }
315
328
  if (toSet.length > 0) options.cookies.setAll(toSet);
316
329
  });
317
- return new AuraClient(baseUrl, apiKey, {
330
+ const client = new AuraClient(baseUrl, apiKey, {
318
331
  auth: { persistSession: false, storage: store }
319
332
  });
333
+ const getUser = client.auth.getUser.bind(client.auth);
334
+ const getSession = client.auth.getSession.bind(client.auth);
335
+ let verifie = null;
336
+ let averti = false;
337
+ client.auth.getUser = (async (...args) => {
338
+ const r = await getUser(...args);
339
+ verifie = !r.error && r.data ? r.data : null;
340
+ return r;
341
+ });
342
+ client.auth.getSession = (async () => {
343
+ const r = await getSession();
344
+ if (verifie) {
345
+ if (r.data.session) r.data.session = { ...r.data.session, user: verifie };
346
+ return { ...r, user: r.data.session ? verifie : null };
347
+ }
348
+ if (!averti) {
349
+ averti = true;
350
+ console.warn(
351
+ "[aurabase] getSession() on the server returns the session read from the cookie without verifying it: never use it to authorize a request. Call auth.getUser() (verified by the server) first."
352
+ );
353
+ }
354
+ return r;
355
+ });
356
+ return client;
320
357
  }
321
358
  function createBrowserClient(baseUrl, apiKey, options) {
322
359
  return new AuraClient(baseUrl, apiKey, options);
package/dist/ssr.d.cts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { SerializeCookieOptions, AuraClientOptions } from '@aurabase/core';
2
2
  export { SerializeCookieOptions, parseCookieHeader, serializeCookieHeader } from '@aurabase/core';
3
- import { A as AuraClient } from './AuraClient-BWdcX_k0.cjs';
3
+ import { A as AuraClient } from './AuraClient-B1OOZCSX.cjs';
4
4
  import '@aurabase/ai';
5
5
  import '@aurabase/auth';
6
6
  import '@aurabase/db';
@@ -29,7 +29,9 @@ import '@aurabase/storage';
29
29
  * },
30
30
  * },
31
31
  * })
32
- * await client.auth.getSession()
32
+ * // getUser() renouvelle les jetons ET fait vérifier l'utilisateur par le serveur.
33
+ * // Ne jamais autoriser avec getSession() côté serveur : elle lit le cookie sans le vérifier.
34
+ * const { data: user } = await client.auth.getUser()
33
35
  * return response
34
36
  * }
35
37
  * ```
package/dist/ssr.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { SerializeCookieOptions, AuraClientOptions } from '@aurabase/core';
2
2
  export { SerializeCookieOptions, parseCookieHeader, serializeCookieHeader } from '@aurabase/core';
3
- import { A as AuraClient } from './AuraClient-BWdcX_k0.js';
3
+ import { A as AuraClient } from './AuraClient-B1OOZCSX.js';
4
4
  import '@aurabase/ai';
5
5
  import '@aurabase/auth';
6
6
  import '@aurabase/db';
@@ -29,7 +29,9 @@ import '@aurabase/storage';
29
29
  * },
30
30
  * },
31
31
  * })
32
- * await client.auth.getSession()
32
+ * // getUser() renouvelle les jetons ET fait vérifier l'utilisateur par le serveur.
33
+ * // Ne jamais autoriser avec getSession() côté serveur : elle lit le cookie sans le vérifier.
34
+ * const { data: user } = await client.auth.getUser()
33
35
  * return response
34
36
  * }
35
37
  * ```
package/dist/ssr.js CHANGED
@@ -55,6 +55,7 @@ var AuraClient = class {
55
55
  _persistSession;
56
56
  _autoRefresh;
57
57
  _detectSessionInUrl;
58
+ _flowType;
58
59
  /**
59
60
  * @param baseUrl URL du projet (`https://<slug>.aurabase.cloud`).
60
61
  * @param apiKey Clé API du projet (`aura_anon_…`, `aura_auth_…`, `aura_sk_…`).
@@ -86,17 +87,18 @@ var AuraClient = class {
86
87
  this.debug = resolvedOptions?.debug;
87
88
  if (!this.apiKey && typeof console !== "undefined") {
88
89
  console.warn(
89
- "[aurabase] No API key provided. Most operations require an API key (apikey header). Only public auth routes (register, login, refresh) will work without one."
90
+ // AUTH-041 — la passerelle refuse TOUTE requête sans clé (401), y compris register/login.
91
+ "[aurabase] No API key provided: every request will be refused (401). Pass the anon key shown in Studio \u203A Settings \u203A Connection."
90
92
  );
91
93
  }
92
94
  if (typeof console !== "undefined" && /^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?\/?$/.test(this.baseUrl)) {
93
95
  console.warn(
94
- "[aurabase] Attention : en local, l'URL du projet doit inclure le sous-domaine (ex: http://<slug>.localhost:8080) pour permettre la r\xE9solution automatique du projet par la passerelle."
96
+ "[aurabase] Warning: locally, the project URL must include the sub-domain (e.g. http://<slug>.localhost:8080) so that the gateway can resolve the project automatically."
95
97
  );
96
98
  }
97
99
  if (this.apiKey?.startsWith(SERVICE_ROLE_KEY_PREFIX) && isBrowserContext()) {
98
100
  const refuse = resolvedOptions?.refuseServiceRoleInBrowser ?? true;
99
- const message = "[aurabase] S\xC9CURIT\xC9 : une cl\xE9 service_role (aura_sk_\u2026) est fournie \xE0 createClient() dans un contexte navigateur. Cette cl\xE9 \xE0 privil\xE8ges \xE9lev\xE9s NE DOIT JAMAIS \xEAtre expos\xE9e c\xF4t\xE9 client (elle fuiterait dans le bundle). Utilisez une cl\xE9 anon (aura_anon_\u2026) c\xF4t\xE9 client, et createAdminClient() c\xF4t\xE9 serveur pour les op\xE9rations d'administration.";
101
+ const message = "[aurabase] SECURITY: a service_role key (aura_sk_\u2026) is passed to createClient() in a browser context. This high-privilege key MUST NEVER be exposed client-side (it would leak into the bundle). Use an anon key (aura_anon_\u2026) on the client, and createAdminClient() on the server for administration operations.";
100
102
  if (refuse) {
101
103
  throw new Error(message);
102
104
  } else if (typeof console !== "undefined") {
@@ -121,6 +123,7 @@ var AuraClient = class {
121
123
  this._persistSession = resolvedOptions?.auth?.persistSession !== false;
122
124
  this._autoRefresh = resolvedOptions?.auth?.autoRefresh ?? true;
123
125
  this._detectSessionInUrl = resolvedOptions?.auth?.detectSessionInUrl;
126
+ this._flowType = resolvedOptions?.auth?.flowType;
124
127
  if (this._autoRefresh && this._persistSession && typeof window !== "undefined") {
125
128
  void this.auth;
126
129
  }
@@ -145,7 +148,8 @@ var AuraClient = class {
145
148
  this._auth = new AuthService(this, {
146
149
  autoRefresh: this._autoRefresh,
147
150
  persistSession: this._persistSession,
148
- detectSessionInUrl: this._detectSessionInUrl
151
+ detectSessionInUrl: this._detectSessionInUrl,
152
+ flowType: this._flowType
149
153
  });
150
154
  this._auth.onAuthStateChange(({ event, accessToken }) => {
151
155
  if (this._realtime) {
@@ -166,7 +170,7 @@ var AuraClient = class {
166
170
  get authAdmin() {
167
171
  if (isBrowserContext()) {
168
172
  throw new Error(
169
- "[aurabase] S\xC9CURIT\xC9 : authAdmin est inaccessible dans un contexte navigateur. L'API admin requiert une cl\xE9 service_role qui ne doit JAMAIS \xEAtre expos\xE9e c\xF4t\xE9 client (elle fuiterait dans le bundle). Utilisez createAdminClient() c\xF4t\xE9 serveur uniquement."
173
+ "[aurabase] SECURITY: authAdmin is not available in a browser context. The admin API requires a service_role key, which must NEVER be exposed client-side (it would leak into the bundle). Use createAdminClient() on the server only."
170
174
  );
171
175
  }
172
176
  if (!this._authAdmin) this._authAdmin = new AuthAdminService(this);
@@ -262,6 +266,7 @@ var AuraClient = class {
262
266
  }
263
267
  };
264
268
  var MAX_CHUNK_SIZE = 3600;
269
+ var WARN_COOKIE_BYTES = 8 * 1024;
265
270
  function createServerClient(baseUrl, apiKey, options) {
266
271
  const cookieName = `aura-${clientScope(baseUrl)}-auth`;
267
272
  const store = new LocalAuthStore(cookieName);
@@ -283,6 +288,7 @@ function createServerClient(baseUrl, apiKey, options) {
283
288
  // 30 days
284
289
  ...options.cookieOptions
285
290
  };
291
+ let tailleAvertie = false;
286
292
  store.onChange(() => {
287
293
  const toSet = [];
288
294
  const used = /* @__PURE__ */ new Set();
@@ -307,15 +313,46 @@ function createServerClient(baseUrl, apiKey, options) {
307
313
  }
308
314
  }
309
315
  }
316
+ const total = toSet.filter((c) => used.has(c.name)).reduce((n, c) => n + c.name.length + encodeURIComponent(c.value).length, 0);
317
+ if (total > WARN_COOKIE_BYTES && !tailleAvertie) {
318
+ tailleAvertie = true;
319
+ console.warn(
320
+ `[aurabase] The session cookie is ${total} bytes (more than 8 KB): servers and proxies often reject requests above that size (431). The access token carries user_metadata: store less in user_metadata and keep large data in your own tables.`
321
+ );
322
+ }
310
323
  const expireOpts = { ...defaultCookieOpts, maxAge: 0 };
311
324
  for (const name of initialNames) {
312
325
  if (!used.has(name)) toSet.push({ name, value: "", options: expireOpts });
313
326
  }
314
327
  if (toSet.length > 0) options.cookies.setAll(toSet);
315
328
  });
316
- return new AuraClient(baseUrl, apiKey, {
329
+ const client = new AuraClient(baseUrl, apiKey, {
317
330
  auth: { persistSession: false, storage: store }
318
331
  });
332
+ const getUser = client.auth.getUser.bind(client.auth);
333
+ const getSession = client.auth.getSession.bind(client.auth);
334
+ let verifie = null;
335
+ let averti = false;
336
+ client.auth.getUser = (async (...args) => {
337
+ const r = await getUser(...args);
338
+ verifie = !r.error && r.data ? r.data : null;
339
+ return r;
340
+ });
341
+ client.auth.getSession = (async () => {
342
+ const r = await getSession();
343
+ if (verifie) {
344
+ if (r.data.session) r.data.session = { ...r.data.session, user: verifie };
345
+ return { ...r, user: r.data.session ? verifie : null };
346
+ }
347
+ if (!averti) {
348
+ averti = true;
349
+ console.warn(
350
+ "[aurabase] getSession() on the server returns the session read from the cookie without verifying it: never use it to authorize a request. Call auth.getUser() (verified by the server) first."
351
+ );
352
+ }
353
+ return r;
354
+ });
355
+ return client;
319
356
  }
320
357
  function createBrowserClient(baseUrl, apiKey, options) {
321
358
  return new AuraClient(baseUrl, apiKey, options);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aurabase/aurabase-js",
3
- "version": "0.6.2",
3
+ "version": "0.7.1",
4
4
  "description": "Official JavaScript/TypeScript client for Aurabase BaaS",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -37,6 +37,7 @@
37
37
  "default": "./dist/nextjs.cjs"
38
38
  }
39
39
  },
40
+ "./package.json": "./package.json",
40
41
  "./react": {
41
42
  "import": {
42
43
  "types": "./dist/react.d.ts",
@@ -76,14 +77,14 @@
76
77
  "client"
77
78
  ],
78
79
  "dependencies": {
79
- "@aurabase/core": "0.6.2",
80
- "@aurabase/auth": "0.6.2",
81
- "@aurabase/db": "0.6.2",
82
- "@aurabase/storage": "0.6.2",
83
- "@aurabase/realtime": "0.6.2",
84
- "@aurabase/functions": "0.6.2",
85
- "@aurabase/ai": "0.6.2",
86
- "@aurabase/notifications": "0.6.2"
80
+ "@aurabase/core": "0.7.1",
81
+ "@aurabase/auth": "0.7.1",
82
+ "@aurabase/db": "0.7.1",
83
+ "@aurabase/storage": "0.7.1",
84
+ "@aurabase/realtime": "0.7.1",
85
+ "@aurabase/functions": "0.7.1",
86
+ "@aurabase/ai": "0.7.1",
87
+ "@aurabase/notifications": "0.7.1"
87
88
  },
88
89
  "devDependencies": {
89
90
  "@types/node": "20.14.15",