@lastbrain/module-auth 0.1.1 → 0.1.3

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.
Files changed (41) hide show
  1. package/README.md +504 -0
  2. package/dist/api/admin/users.d.ts +36 -0
  3. package/dist/api/admin/users.d.ts.map +1 -0
  4. package/dist/api/admin/users.js +90 -0
  5. package/dist/api/auth/me.d.ts +17 -0
  6. package/dist/api/auth/me.d.ts.map +1 -0
  7. package/dist/api/auth/me.js +34 -0
  8. package/dist/api/auth/profile.d.ts +32 -0
  9. package/dist/api/auth/profile.d.ts.map +1 -0
  10. package/dist/api/auth/profile.js +108 -0
  11. package/dist/api/storage.d.ts +13 -0
  12. package/dist/api/storage.d.ts.map +1 -0
  13. package/dist/api/storage.js +47 -0
  14. package/dist/auth.build.config.d.ts.map +1 -1
  15. package/dist/auth.build.config.js +21 -0
  16. package/dist/web/admin/users.d.ts.map +1 -1
  17. package/dist/web/admin/users.js +87 -2
  18. package/dist/web/auth/dashboard.d.ts +1 -1
  19. package/dist/web/auth/dashboard.d.ts.map +1 -1
  20. package/dist/web/auth/dashboard.js +42 -2
  21. package/dist/web/auth/profile.d.ts.map +1 -1
  22. package/dist/web/auth/profile.js +152 -2
  23. package/dist/web/auth/reglage.d.ts.map +1 -1
  24. package/dist/web/auth/reglage.js +98 -2
  25. package/package.json +5 -4
  26. package/src/api/admin/users.ts +124 -0
  27. package/src/api/auth/me.ts +48 -0
  28. package/src/api/auth/profile.ts +156 -0
  29. package/src/api/public/signin.ts +31 -0
  30. package/src/api/storage.ts +63 -0
  31. package/src/auth.build.config.ts +137 -0
  32. package/src/components/Doc.tsx +310 -0
  33. package/src/index.ts +12 -0
  34. package/src/server.ts +2 -0
  35. package/src/web/admin/users.tsx +266 -0
  36. package/src/web/auth/dashboard.tsx +202 -0
  37. package/src/web/auth/profile.tsx +381 -0
  38. package/src/web/auth/reglage.tsx +304 -0
  39. package/src/web/public/ResetPassword.tsx +3 -0
  40. package/src/web/public/SignInPage.tsx +255 -0
  41. package/src/web/public/SignUpPage.tsx +293 -0
package/README.md ADDED
@@ -0,0 +1,504 @@
1
+ # Module Auth (@lastbrain/module-auth)
2
+
3
+ Module d'authentification complet pour LastBrain avec Supabase. Ce module fournit des pages web, des API routes et une gestion complète de l'authentification utilisateur, du profil et de l'administration.
4
+
5
+ ## Table des matières
6
+
7
+ - [Installation](#installation)
8
+ - [Configuration](#configuration)
9
+ - [Pages Web Fournies](#pages-web-fournies)
10
+ - [Routes API](#routes-api)
11
+ - [Schéma de Base de Données](#schéma-de-base-de-données)
12
+ - [Intégration dans une Application](#intégration-dans-une-application)
13
+ - [Sécurité](#sécurité)
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ npm install @lastbrain/module-auth
19
+ # or
20
+ pnpm add @lastbrain/module-auth
21
+ ```
22
+
23
+ ## Configuration
24
+
25
+ ### Prérequis
26
+
27
+ 1. **Supabase configuré** : Vous devez avoir un projet Supabase avec les variables d'environnement suivantes :
28
+ ```env
29
+ NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
30
+ NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
31
+ ```
32
+
33
+ 2. **Migrations appliquées** : Appliquez la migration fournie dans `supabase/migrations/20251112000000_user_init.sql` pour créer les tables nécessaires.
34
+
35
+ 3. **Fonction RPC is_superadmin** : Assurez-vous que la fonction `is_superadmin` est disponible (généralement fournie par la migration de base de l'app).
36
+
37
+ ### Configuration de la fonction is_superadmin
38
+
39
+ La fonction `is_superadmin` vérifie si un utilisateur a le rôle d'administrateur. Elle est définie dans la migration de base et examine les métadonnées utilisateur :
40
+
41
+ ```sql
42
+ CREATE OR REPLACE FUNCTION public.is_superadmin(user_id uuid)
43
+ RETURNS boolean
44
+ LANGUAGE sql
45
+ STABLE
46
+ SECURITY DEFINER
47
+ SET search_path = public, auth
48
+ AS $function$
49
+ SELECT COALESCE((
50
+ SELECT
51
+ COALESCE((raw_app_meta_data ->> 'is_super_admin')::boolean, FALSE)
52
+ OR COALESCE((raw_user_meta_data ->> 'is_super_admin')::boolean, FALSE)
53
+ OR COALESCE((raw_app_meta_data -> 'roles') ? 'admin', FALSE)
54
+ OR COALESCE((raw_user_meta_data -> 'roles') ? 'admin', FALSE)
55
+ FROM auth.users
56
+ WHERE id = user_id
57
+ ), FALSE);
58
+ $function$;
59
+ ```
60
+
61
+ ## Pages Web Fournies
62
+
63
+ Le module fournit plusieurs composants React prêts à l'emploi utilisant HeroUI :
64
+
65
+ ### Pages Utilisateur Authentifié
66
+
67
+ #### 1. Dashboard (`/auth/dashboard`)
68
+ **Component**: `DashboardPage`
69
+
70
+ Tableau de bord utilisateur affichant :
71
+ - Résumé du profil avec avatar
72
+ - Email et date de création du compte
73
+ - Statut du compte
74
+ - Statistiques rapides (projets, tâches, etc.)
75
+
76
+ **Usage** :
77
+ ```tsx
78
+ import { DashboardPage } from "@lastbrain/module-auth";
79
+
80
+ export default function Dashboard() {
81
+ return <DashboardPage />;
82
+ }
83
+ ```
84
+
85
+ #### 2. Profil (`/auth/profile`)
86
+ **Component**: `ProfilePage`
87
+
88
+ Page de modification du profil utilisateur permettant de mettre à jour :
89
+ - Informations personnelles (nom, prénom, téléphone, bio)
90
+ - Informations professionnelles (entreprise, site web, localisation)
91
+ - Préférences (langue, timezone, avatar)
92
+
93
+ **Usage** :
94
+ ```tsx
95
+ import { ProfilePage } from "@lastbrain/module-auth";
96
+
97
+ export default function Profile() {
98
+ return <ProfilePage />;
99
+ }
100
+ ```
101
+
102
+ #### 3. Paramètres (`/auth/settings`)
103
+ **Component**: `ReglagePage`
104
+
105
+ Page de configuration du compte avec :
106
+ - Notifications (email, push, marketing)
107
+ - Apparence (thème)
108
+ - Langue et région (langue, timezone)
109
+
110
+ **Usage** :
111
+ ```tsx
112
+ import { ReglagePage } from "@lastbrain/module-auth";
113
+
114
+ export default function Settings() {
115
+ return <ReglagePage />;
116
+ }
117
+ ```
118
+
119
+ ### Pages Publiques
120
+
121
+ #### 4. Connexion (`/signin`)
122
+ **Component**: `SignInPage`
123
+
124
+ Page de connexion avec gestion des erreurs et redirection.
125
+
126
+ **Usage** :
127
+ ```tsx
128
+ import { SignInPage } from "@lastbrain/module-auth";
129
+
130
+ export default function SignIn() {
131
+ return <SignInPage />;
132
+ }
133
+ ```
134
+
135
+ #### 5. Inscription (`/signup`)
136
+ **Component**: `SignUpPage`
137
+
138
+ Page d'inscription avec validation des champs.
139
+
140
+ **Usage** :
141
+ ```tsx
142
+ import { SignUpPage } from "@lastbrain/module-auth";
143
+
144
+ export default function SignUp() {
145
+ return <SignUpPage />;
146
+ }
147
+ ```
148
+
149
+ ### Pages Administration
150
+
151
+ #### 6. Gestion des Utilisateurs (`/admin/users`)
152
+ **Component**: `AdminUsersPage`
153
+
154
+ Page d'administration pour lister et gérer tous les utilisateurs.
155
+ **Accès réservé aux super admins uniquement.**
156
+
157
+ Fonctionnalités :
158
+ - Liste de tous les utilisateurs
159
+ - Recherche par email ou nom
160
+ - Pagination
161
+ - Affichage des informations (email, rôle, date de création)
162
+
163
+ **Usage** :
164
+ ```tsx
165
+ import { AdminUsersPage } from "@lastbrain/module-auth";
166
+
167
+ export default function AdminUsers() {
168
+ return <AdminUsersPage />;
169
+ }
170
+ ```
171
+
172
+ ## Routes API
173
+
174
+ Le module expose plusieurs routes API pour la gestion des utilisateurs et profils.
175
+
176
+ ### API Authentification (`/api/auth/*`)
177
+
178
+ #### GET `/api/auth/me`
179
+ Récupère les informations de l'utilisateur connecté et son profil.
180
+
181
+ **Réponse** :
182
+ ```json
183
+ {
184
+ "data": {
185
+ "id": "uuid",
186
+ "email": "user@example.com",
187
+ "created_at": "2024-01-01T00:00:00Z",
188
+ "profile": {
189
+ "first_name": "John",
190
+ "last_name": "Doe",
191
+ "avatar_url": "https://...",
192
+ "bio": "...",
193
+ "phone": "...",
194
+ "company": "...",
195
+ "website": "...",
196
+ "location": "...",
197
+ "language": "en",
198
+ "timezone": "UTC",
199
+ "preferences": {}
200
+ }
201
+ }
202
+ }
203
+ ```
204
+
205
+ **Erreurs** :
206
+ - `401` : Utilisateur non authentifié
207
+
208
+ #### GET `/api/auth/profile`
209
+ Récupère le profil de l'utilisateur connecté.
210
+
211
+ **Réponse** :
212
+ ```json
213
+ {
214
+ "data": {
215
+ "id": "uuid",
216
+ "owner_id": "uuid",
217
+ "first_name": "John",
218
+ "last_name": "Doe",
219
+ ...
220
+ }
221
+ }
222
+ ```
223
+
224
+ #### PUT/PATCH `/api/auth/profile`
225
+ Met à jour le profil de l'utilisateur. Crée le profil s'il n'existe pas.
226
+
227
+ **Body** :
228
+ ```json
229
+ {
230
+ "first_name": "John",
231
+ "last_name": "Doe",
232
+ "avatar_url": "https://...",
233
+ "bio": "...",
234
+ "phone": "...",
235
+ "company": "...",
236
+ "website": "...",
237
+ "location": "...",
238
+ "language": "fr",
239
+ "timezone": "Europe/Paris",
240
+ "preferences": {
241
+ "email_notifications": true,
242
+ "theme": "dark"
243
+ }
244
+ }
245
+ ```
246
+
247
+ **Réponse** :
248
+ ```json
249
+ {
250
+ "data": {
251
+ "id": "uuid",
252
+ "owner_id": "uuid",
253
+ "first_name": "John",
254
+ ...
255
+ }
256
+ }
257
+ ```
258
+
259
+ ### API Administration (`/api/admin/*`)
260
+
261
+ ⚠️ **Toutes les routes admin nécessitent un accès super admin.**
262
+
263
+ #### GET `/api/admin/users`
264
+ Liste tous les utilisateurs (paginé).
265
+
266
+ **Query Parameters** :
267
+ - `page` (optionnel, défaut: 1) : Numéro de page
268
+ - `per_page` (optionnel, défaut: 20) : Nombre d'éléments par page
269
+ - `search` (optionnel) : Recherche par email ou nom
270
+
271
+ **Réponse** :
272
+ ```json
273
+ {
274
+ "data": [
275
+ {
276
+ "id": "uuid",
277
+ "email": "user@example.com",
278
+ "created_at": "2024-01-01T00:00:00Z",
279
+ "profile": {
280
+ "first_name": "John",
281
+ "last_name": "Doe",
282
+ ...
283
+ }
284
+ }
285
+ ],
286
+ "pagination": {
287
+ "page": 1,
288
+ "per_page": 20,
289
+ "total": 100,
290
+ "total_pages": 5
291
+ }
292
+ }
293
+ ```
294
+
295
+ **Erreurs** :
296
+ - `401` : Utilisateur non authentifié
297
+ - `403` : Accès refusé (non super admin)
298
+
299
+ ### Utilisation dans une API Route Next.js
300
+
301
+ ```typescript
302
+ // app/api/auth/me/route.ts
303
+ export { GET } from "@lastbrain/module-auth/api/auth/me";
304
+
305
+ // app/api/auth/profile/route.ts
306
+ export { GET, PUT, PATCH } from "@lastbrain/module-auth/api/auth/profile";
307
+
308
+ // app/api/admin/users/route.ts
309
+ export { GET } from "@lastbrain/module-auth/api/admin/users";
310
+ ```
311
+
312
+ ## Schéma de Base de Données
313
+
314
+ Le module utilise les tables suivantes (créées par la migration `20251112000000_user_init.sql`) :
315
+
316
+ ### Table `user_profil`
317
+
318
+ Stocke les informations de profil utilisateur.
319
+
320
+ ```sql
321
+ CREATE TABLE public.user_profil (
322
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
323
+ owner_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
324
+ first_name TEXT,
325
+ last_name TEXT,
326
+ avatar_url TEXT,
327
+ bio TEXT,
328
+ phone TEXT,
329
+ company TEXT,
330
+ website TEXT,
331
+ location TEXT,
332
+ language TEXT DEFAULT 'en',
333
+ timezone TEXT,
334
+ preferences JSONB DEFAULT '{}'::jsonb,
335
+ created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
336
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
337
+ );
338
+ ```
339
+
340
+ **Index** :
341
+ - `idx_user_profil_owner_id` sur `owner_id`
342
+
343
+ **RLS (Row Level Security)** :
344
+ - Les utilisateurs peuvent lire, créer, modifier et supprimer leur propre profil
345
+ - Les super admins ont accès à tous les profils
346
+
347
+ ### Table `user_address`
348
+
349
+ Stocke les adresses des utilisateurs.
350
+
351
+ ```sql
352
+ CREATE TABLE public.user_address (
353
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
354
+ owner_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
355
+ street TEXT NOT NULL,
356
+ street2 TEXT,
357
+ city TEXT NOT NULL,
358
+ state TEXT,
359
+ postal_code TEXT,
360
+ country TEXT NOT NULL,
361
+ is_default BOOLEAN DEFAULT false,
362
+ address_type TEXT DEFAULT 'billing',
363
+ created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
364
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
365
+ );
366
+ ```
367
+
368
+ ### Table `user_notifications`
369
+
370
+ Stocke les notifications des utilisateurs.
371
+
372
+ ```sql
373
+ CREATE TABLE public.user_notifications (
374
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
375
+ owner_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
376
+ title TEXT NOT NULL,
377
+ body TEXT,
378
+ type TEXT NOT NULL DEFAULT 'primary',
379
+ read BOOLEAN NOT NULL DEFAULT false,
380
+ created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
381
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
382
+ );
383
+ ```
384
+
385
+ ## Intégration dans une Application
386
+
387
+ ### 1. Installer les dépendances
388
+
389
+ ```bash
390
+ pnpm add @lastbrain/module-auth @lastbrain/core @lastbrain/ui
391
+ ```
392
+
393
+ ### 2. Appliquer les migrations Supabase
394
+
395
+ Copiez les migrations du module dans votre projet Supabase et appliquez-les :
396
+
397
+ ```bash
398
+ cp node_modules/@lastbrain/module-auth/supabase/migrations/* supabase/migrations/
399
+ supabase db push
400
+ ```
401
+
402
+ ### 3. Créer les pages Next.js
403
+
404
+ Créez les pages dans votre application Next.js :
405
+
406
+ ```typescript
407
+ // app/auth/dashboard/page.tsx
408
+ import { DashboardPage } from "@lastbrain/module-auth";
409
+ export default DashboardPage;
410
+
411
+ // app/auth/profile/page.tsx
412
+ import { ProfilePage } from "@lastbrain/module-auth";
413
+ export default ProfilePage;
414
+
415
+ // app/auth/settings/page.tsx
416
+ import { ReglagePage } from "@lastbrain/module-auth";
417
+ export default ReglagePage;
418
+
419
+ // app/admin/users/page.tsx
420
+ import { AdminUsersPage } from "@lastbrain/module-auth";
421
+ export default AdminUsersPage;
422
+ ```
423
+
424
+ ### 4. Créer les routes API
425
+
426
+ ```typescript
427
+ // app/api/auth/me/route.ts
428
+ export { GET } from "@lastbrain/module-auth/api/auth/me";
429
+
430
+ // app/api/auth/profile/route.ts
431
+ export { GET, PUT, PATCH } from "@lastbrain/module-auth/api/auth/profile";
432
+
433
+ // app/api/admin/users/route.ts
434
+ export { GET } from "@lastbrain/module-auth/api/admin/users";
435
+ ```
436
+
437
+ ### 5. Configurer les variables d'environnement
438
+
439
+ ```env
440
+ NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
441
+ NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
442
+ ```
443
+
444
+ ## Sécurité
445
+
446
+ ### Row Level Security (RLS)
447
+
448
+ Toutes les tables sont protégées par RLS :
449
+ - Les utilisateurs ne peuvent accéder qu'à leurs propres données
450
+ - Les super admins ont accès à toutes les données
451
+
452
+ ### Vérification Super Admin
453
+
454
+ Les routes admin vérifient l'accès super admin via la RPC Supabase :
455
+
456
+ ```typescript
457
+ const { data: isSuperAdmin } = await supabase.rpc("is_superadmin", {
458
+ user_id: user.id,
459
+ });
460
+
461
+ if (!isSuperAdmin) {
462
+ return NextResponse.json(
463
+ { error: "Forbidden" },
464
+ { status: 403 }
465
+ );
466
+ }
467
+ ```
468
+
469
+ ### Authentification
470
+
471
+ Les routes API vérifient l'authentification :
472
+
473
+ ```typescript
474
+ const { data: { user }, error } = await supabase.auth.getUser();
475
+
476
+ if (error || !user) {
477
+ return NextResponse.json(
478
+ { error: "Unauthorized" },
479
+ { status: 401 }
480
+ );
481
+ }
482
+ ```
483
+
484
+ ## Développement
485
+
486
+ ### Build
487
+
488
+ ```bash
489
+ pnpm build
490
+ ```
491
+
492
+ ### Watch mode
493
+
494
+ ```bash
495
+ pnpm dev
496
+ ```
497
+
498
+ ## Support
499
+
500
+ Pour des questions ou des problèmes, ouvrez une issue sur [GitHub](https://github.com/lastpublication/starter).
501
+
502
+ ## Licence
503
+
504
+ MIT
@@ -0,0 +1,36 @@
1
+ import { NextRequest, NextResponse } from "next/server";
2
+ /**
3
+ * GET /api/admin/users
4
+ * Returns all users (superadmin only)
5
+ * Supports pagination via query params: page, per_page
6
+ * Supports search via query param: search (email)
7
+ */
8
+ export declare function GET(request: NextRequest): Promise<NextResponse<{
9
+ error: string;
10
+ message: string;
11
+ }> | NextResponse<{
12
+ data: {
13
+ id: any;
14
+ email: string;
15
+ created_at: any;
16
+ profile: {
17
+ first_name: any;
18
+ last_name: any;
19
+ avatar_url: any;
20
+ bio: any;
21
+ phone: any;
22
+ company: any;
23
+ website: any;
24
+ location: any;
25
+ language: any;
26
+ timezone: any;
27
+ };
28
+ }[];
29
+ pagination: {
30
+ page: number;
31
+ per_page: number;
32
+ total: number;
33
+ total_pages: number;
34
+ };
35
+ }>>;
36
+ //# sourceMappingURL=users.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"users.d.ts","sourceRoot":"","sources":["../../../src/api/admin/users.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGxD;;;;;GAKG;AACH,wBAAsB,GAAG,CAAC,OAAO,EAAE,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;IAkH7C"}
@@ -0,0 +1,90 @@
1
+ import { NextResponse } from "next/server";
2
+ import { getSupabaseServerClient } from "@lastbrain/core/server";
3
+ /**
4
+ * GET /api/admin/users
5
+ * Returns all users (superadmin only)
6
+ * Supports pagination via query params: page, per_page
7
+ * Supports search via query param: search (email)
8
+ */
9
+ export async function GET(request) {
10
+ try {
11
+ const supabase = await getSupabaseServerClient();
12
+ // Check authentication
13
+ const { data: { user }, error: authError, } = await supabase.auth.getUser();
14
+ if (authError || !user) {
15
+ return NextResponse.json({ error: "Unauthorized", message: "User not authenticated" }, { status: 401 });
16
+ }
17
+ // Check if user is superadmin
18
+ const { data: isSuperAdmin } = await supabase.rpc("is_superadmin", {
19
+ user_id: user.id,
20
+ });
21
+ if (!isSuperAdmin) {
22
+ return NextResponse.json({ error: "Forbidden", message: "Superadmin access required" }, { status: 403 });
23
+ }
24
+ // Get query parameters
25
+ const searchParams = request.nextUrl.searchParams;
26
+ const page = parseInt(searchParams.get("page") || "1");
27
+ const perPage = parseInt(searchParams.get("per_page") || "20");
28
+ const search = searchParams.get("search") || "";
29
+ // Note: We can only get public user data from auth.users via RPC or service role
30
+ // For now, we'll query user_profil which has owner_id references
31
+ let query = supabase
32
+ .from("user_profil")
33
+ .select("*, owner_id", { count: "exact" })
34
+ .order("created_at", { ascending: false });
35
+ // Add search filter if provided - using Supabase's built-in parameterized query
36
+ if (search) {
37
+ // Using .ilike with % wildcards - Supabase handles escaping
38
+ query = query.or(`first_name.ilike.%${search}%,last_name.ilike.%${search}%`);
39
+ }
40
+ // Apply pagination
41
+ const start = (page - 1) * perPage;
42
+ query = query.range(start, start + perPage - 1);
43
+ const { data: profiles, error: profileError, count } = await query;
44
+ if (profileError) {
45
+ console.error("Error fetching users:", profileError);
46
+ return NextResponse.json({ error: "Database Error", message: profileError.message }, { status: 500 });
47
+ }
48
+ // Get auth users data in batch - more efficient than individual calls
49
+ // Note: auth.admin methods require service role, so results may be limited
50
+ // In production, consider creating a database view or RPC function to join
51
+ // user_profil with auth.users for better performance
52
+ const users = await Promise.all((profiles || []).map(async (profile) => {
53
+ // Get basic auth info - this is limited to what's available
54
+ const { data: authData } = await supabase.auth.admin.getUserById(profile.owner_id);
55
+ return {
56
+ id: profile.owner_id,
57
+ email: authData?.user?.email || "N/A",
58
+ created_at: authData?.user?.created_at || profile.created_at,
59
+ profile: {
60
+ first_name: profile.first_name,
61
+ last_name: profile.last_name,
62
+ avatar_url: profile.avatar_url,
63
+ bio: profile.bio,
64
+ phone: profile.phone,
65
+ company: profile.company,
66
+ website: profile.website,
67
+ location: profile.location,
68
+ language: profile.language,
69
+ timezone: profile.timezone,
70
+ },
71
+ };
72
+ }));
73
+ return NextResponse.json({
74
+ data: users,
75
+ pagination: {
76
+ page,
77
+ per_page: perPage,
78
+ total: count || 0,
79
+ total_pages: Math.ceil((count || 0) / perPage),
80
+ },
81
+ });
82
+ }
83
+ catch (error) {
84
+ console.error("Error in admin users endpoint:", error);
85
+ return NextResponse.json({
86
+ error: "Internal Server Error",
87
+ message: "Failed to fetch users",
88
+ }, { status: 500 });
89
+ }
90
+ }
@@ -0,0 +1,17 @@
1
+ import { NextResponse } from "next/server";
2
+ /**
3
+ * GET /api/auth/me
4
+ * Returns the current authenticated user and their profile
5
+ */
6
+ export declare function GET(): Promise<NextResponse<{
7
+ error: string;
8
+ message: string;
9
+ }> | NextResponse<{
10
+ data: {
11
+ id: string;
12
+ email: string | undefined;
13
+ created_at: string;
14
+ profile: any;
15
+ };
16
+ }>>;
17
+ //# sourceMappingURL=me.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"me.d.ts","sourceRoot":"","sources":["../../../src/api/auth/me.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C;;;GAGG;AACH,wBAAsB,GAAG;;;;;;;;;;IAwCxB"}
@@ -0,0 +1,34 @@
1
+ import { NextResponse } from "next/server";
2
+ import { getSupabaseServerClient } from "@lastbrain/core/server";
3
+ /**
4
+ * GET /api/auth/me
5
+ * Returns the current authenticated user and their profile
6
+ */
7
+ export async function GET() {
8
+ try {
9
+ const supabase = await getSupabaseServerClient();
10
+ // Get the authenticated user
11
+ const { data: { user }, error: authError, } = await supabase.auth.getUser();
12
+ if (authError || !user) {
13
+ return NextResponse.json({ error: "Unauthorized", message: "User not authenticated" }, { status: 401 });
14
+ }
15
+ // Get user profile
16
+ const { data: profile, error: profileError } = await supabase
17
+ .from("user_profil")
18
+ .select("*")
19
+ .eq("owner_id", user.id)
20
+ .single();
21
+ // Profile might not exist yet, that's OK
22
+ const userData = {
23
+ id: user.id,
24
+ email: user.email,
25
+ created_at: user.created_at,
26
+ profile: profile || null,
27
+ };
28
+ return NextResponse.json({ data: userData });
29
+ }
30
+ catch (error) {
31
+ console.error("Error fetching user:", error);
32
+ return NextResponse.json({ error: "Internal Server Error", message: "Failed to fetch user data" }, { status: 500 });
33
+ }
34
+ }