@aurabase/aurabase-js 0.6.2 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -2
- package/dist/{AuraClient-BWdcX_k0.d.cts → AuraClient-B1OOZCSX.d.cts} +1 -0
- package/dist/{AuraClient-BWdcX_k0.d.ts → AuraClient-B1OOZCSX.d.ts} +1 -0
- package/dist/index.cjs +14 -6
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +11 -7
- package/dist/nextjs.cjs +52 -15
- package/dist/nextjs.d.cts +3 -3
- package/dist/nextjs.d.ts +3 -3
- package/dist/nextjs.js +52 -15
- package/dist/react.d.cts +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/ssr.cjs +43 -6
- package/dist/ssr.d.cts +4 -2
- package/dist/ssr.d.ts +4 -2
- package/dist/ssr.js +43 -6
- package/package.json +10 -9
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
|
-
|
|
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]
|
|
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]
|
|
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]
|
|
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()
|
|
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-
|
|
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-
|
|
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
|
-
|
|
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]
|
|
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]
|
|
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]
|
|
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()
|
|
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
|
-
|
|
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]
|
|
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]
|
|
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]
|
|
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
|
-
|
|
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
|
|
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]
|
|
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:
|
|
365
|
-
const
|
|
366
|
-
const
|
|
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()
|
|
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.
|
|
420
|
-
const
|
|
421
|
-
const
|
|
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-
|
|
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
|
|
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
|
|
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-
|
|
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
|
|
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
|
|
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
|
-
|
|
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]
|
|
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]
|
|
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]
|
|
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
|
-
|
|
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
|
|
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]
|
|
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:
|
|
363
|
-
const
|
|
364
|
-
const
|
|
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()
|
|
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.
|
|
418
|
-
const
|
|
419
|
-
const
|
|
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
package/dist/react.d.ts
CHANGED
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
|
-
|
|
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]
|
|
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]
|
|
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]
|
|
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
|
-
|
|
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-
|
|
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
|
-
*
|
|
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-
|
|
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
|
-
*
|
|
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
|
-
|
|
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]
|
|
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]
|
|
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]
|
|
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
|
-
|
|
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.
|
|
3
|
+
"version": "0.7.0",
|
|
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.
|
|
80
|
-
"@aurabase/auth": "0.
|
|
81
|
-
"@aurabase/
|
|
82
|
-
"@aurabase/
|
|
83
|
-
"@aurabase/
|
|
84
|
-
"@aurabase/
|
|
85
|
-
"@aurabase/
|
|
86
|
-
"@aurabase/
|
|
80
|
+
"@aurabase/core": "0.7.0",
|
|
81
|
+
"@aurabase/auth": "0.7.0",
|
|
82
|
+
"@aurabase/storage": "0.7.0",
|
|
83
|
+
"@aurabase/ai": "0.7.0",
|
|
84
|
+
"@aurabase/functions": "0.7.0",
|
|
85
|
+
"@aurabase/notifications": "0.7.0",
|
|
86
|
+
"@aurabase/db": "0.7.0",
|
|
87
|
+
"@aurabase/realtime": "0.7.0"
|
|
87
88
|
},
|
|
88
89
|
"devDependencies": {
|
|
89
90
|
"@types/node": "20.14.15",
|