@insforge/nextjs 0.6.9 → 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 +121 -112
- package/dist/api.d.mts +1 -12
- package/dist/api.d.ts +1 -12
- package/dist/api.js +6 -62
- package/dist/api.js.map +1 -1
- package/dist/api.mjs +5 -60
- package/dist/api.mjs.map +1 -1
- package/dist/index.d.mts +14 -19
- package/dist/index.d.ts +14 -19
- package/dist/index.js +218 -132
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +215 -128
- package/dist/index.mjs.map +1 -1
- package/dist/middleware.js +17 -21
- package/dist/middleware.js.map +1 -1
- package/dist/middleware.mjs +17 -21
- package/dist/middleware.mjs.map +1 -1
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -24,9 +24,13 @@
|
|
|
24
24
|
## Installation
|
|
25
25
|
|
|
26
26
|
```bash
|
|
27
|
-
npm install @insforge/nextjs
|
|
27
|
+
npm install @insforge/nextjs @insforge/sdk
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
+
<Note>
|
|
31
|
+
**SDK Integration**: `@insforge/nextjs` works seamlessly with `@insforge/sdk`. The SDK handles API calls, token management, and OAuth callback detection automatically. Always use SDK methods instead of raw `fetch` calls.
|
|
32
|
+
</Note>
|
|
33
|
+
|
|
30
34
|
## Quick Start
|
|
31
35
|
|
|
32
36
|
### 1. Add InsforgeProvider
|
|
@@ -48,6 +52,8 @@ export default function RootLayout({ children }: { children: React.ReactNode })
|
|
|
48
52
|
}
|
|
49
53
|
```
|
|
50
54
|
|
|
55
|
+
> **✨ Auto-styled**: Component styles are automatically loaded when you add `InsforgeProvider`. No CSS imports needed!
|
|
56
|
+
|
|
51
57
|
### 2. Create API route (enables SSR)
|
|
52
58
|
|
|
53
59
|
```tsx
|
|
@@ -68,12 +74,17 @@ export const DELETE = handlers.DELETE;
|
|
|
68
74
|
|
|
69
75
|
### 3. Create callback page
|
|
70
76
|
|
|
77
|
+
<Note>
|
|
78
|
+
**SDK Integration**: This callback page uses `@insforge/sdk` to automatically detect and handle URL parameters. The SDK handles token storage automatically, making the callback page simpler and more reliable.
|
|
79
|
+
</Note>
|
|
80
|
+
|
|
71
81
|
```tsx
|
|
72
82
|
// app/auth/callback/page.tsx
|
|
73
83
|
'use client';
|
|
74
84
|
|
|
75
85
|
import { useEffect, useRef, Suspense } from 'react';
|
|
76
86
|
import { useRouter, useSearchParams } from 'next/navigation';
|
|
87
|
+
import { createClient } from '@insforge/sdk';
|
|
77
88
|
|
|
78
89
|
function CallbackContent() {
|
|
79
90
|
const router = useRouter();
|
|
@@ -85,28 +96,45 @@ function CallbackContent() {
|
|
|
85
96
|
if (isProcessingRef.current) return;
|
|
86
97
|
isProcessingRef.current = true;
|
|
87
98
|
|
|
88
|
-
const accessToken = searchParams.get('access_token');
|
|
89
99
|
const error = searchParams.get('error');
|
|
90
|
-
|
|
91
100
|
if (error) {
|
|
92
101
|
router.push('/?error=' + encodeURIComponent(error));
|
|
93
102
|
return;
|
|
94
103
|
}
|
|
95
104
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
105
|
+
// Create SDK client - it automatically detects and stores URL parameters
|
|
106
|
+
// SDK's detectOAuthCallback() handles: access_token, user_id, email, name
|
|
107
|
+
// This automatically stores token in 'insforge-auth-token' and basic user info
|
|
108
|
+
const insforge = createClient({
|
|
109
|
+
baseUrl: process.env.NEXT_PUBLIC_INSFORGE_BASE_URL!,
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
// Fetch complete user data (including profile) using SDK method
|
|
113
|
+
const { data: userData, error: userError } = await insforge.auth.getCurrentUser();
|
|
114
|
+
|
|
115
|
+
if (userError || !userData) {
|
|
116
|
+
router.push('/?error=authentication_failed');
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Store complete user profile for InsforgeProvider (enables instant UI updates)
|
|
121
|
+
localStorage.setItem('insforge-user-profile', JSON.stringify(userData));
|
|
122
|
+
|
|
123
|
+
// Sync token to HTTP-only cookie (for server-side middleware)
|
|
124
|
+
const token = localStorage.getItem('insforge-auth-token');
|
|
125
|
+
if (token) {
|
|
99
126
|
await fetch('/api/auth', {
|
|
100
127
|
method: 'POST',
|
|
101
128
|
headers: { 'Content-Type': 'application/json' },
|
|
102
|
-
body: JSON.stringify({ action: 'sync-token', token
|
|
129
|
+
body: JSON.stringify({ action: 'sync-token', token }),
|
|
103
130
|
});
|
|
104
|
-
|
|
105
|
-
const destination = sessionStorage.getItem('auth_destination') || '/dashboard';
|
|
106
|
-
sessionStorage.removeItem('auth_destination');
|
|
107
|
-
|
|
108
|
-
setTimeout(() => router.push(destination), 100);
|
|
109
131
|
}
|
|
132
|
+
|
|
133
|
+
// Clean up URL and redirect
|
|
134
|
+
window.history.replaceState({}, '', '/auth/callback');
|
|
135
|
+
const destination = sessionStorage.getItem('auth_destination') || '/';
|
|
136
|
+
sessionStorage.removeItem('auth_destination');
|
|
137
|
+
setTimeout(() => router.push(destination), 100);
|
|
110
138
|
};
|
|
111
139
|
|
|
112
140
|
processCallback();
|
|
@@ -131,7 +159,7 @@ export default function CallbackPage() {
|
|
|
131
159
|
}
|
|
132
160
|
```
|
|
133
161
|
|
|
134
|
-
> **Why?**
|
|
162
|
+
> **Why SDK?** The SDK automatically detects URL parameters (`access_token`, `user_id`, `email`, `name`) and stores them. Using SDK methods ensures consistency and reduces errors.
|
|
135
163
|
|
|
136
164
|
### 4. Add middleware (protects routes)
|
|
137
165
|
|
|
@@ -192,7 +220,7 @@ export default function Home() {
|
|
|
192
220
|
|
|
193
221
|
**Why API route + callback?**
|
|
194
222
|
- **API route**: Syncs tokens to HTTP-only cookies (enables server-side middleware)
|
|
195
|
-
- **Callback page**: Receives tokens from backend auth pages (OAuth + email/password)
|
|
223
|
+
- **Callback page**: Receives tokens from backend auth pages (OAuth + email/password) and uses SDK to handle them automatically
|
|
196
224
|
|
|
197
225
|
---
|
|
198
226
|
|
|
@@ -211,73 +239,6 @@ Provider automatically uses `NEXT_PUBLIC_INSFORGE_FRONTEND_URL` for auth redirec
|
|
|
211
239
|
|
|
212
240
|
---
|
|
213
241
|
|
|
214
|
-
## Advanced: Custom Components
|
|
215
|
-
|
|
216
|
-
Need custom branding? Disable built-in auth:
|
|
217
|
-
|
|
218
|
-
```tsx
|
|
219
|
-
// app/layout.tsx
|
|
220
|
-
import { InsforgeProvider } from '@insforge/nextjs';
|
|
221
|
-
import '@insforge/nextjs/styles.css'; // Required for custom components
|
|
222
|
-
|
|
223
|
-
export default function RootLayout({ children }) {
|
|
224
|
-
return (
|
|
225
|
-
<InsforgeProvider
|
|
226
|
-
baseUrl={process.env.NEXT_PUBLIC_INSFORGE_BASE_URL!}
|
|
227
|
-
useBuiltInAuth={false}
|
|
228
|
-
>
|
|
229
|
-
{children}
|
|
230
|
-
</InsforgeProvider>
|
|
231
|
-
);
|
|
232
|
-
}
|
|
233
|
-
```
|
|
234
|
-
|
|
235
|
-
### Pre-built Components
|
|
236
|
-
|
|
237
|
-
```tsx
|
|
238
|
-
// app/sign-in/page.tsx
|
|
239
|
-
import { SignIn } from '@insforge/nextjs';
|
|
240
|
-
|
|
241
|
-
export default function SignInPage() {
|
|
242
|
-
return <SignIn afterSignInUrl="/dashboard" />;
|
|
243
|
-
}
|
|
244
|
-
```
|
|
245
|
-
|
|
246
|
-
OAuth providers are auto-detected from your backend config.
|
|
247
|
-
|
|
248
|
-
### Build from Primitives
|
|
249
|
-
|
|
250
|
-
For complete control:
|
|
251
|
-
|
|
252
|
-
```tsx
|
|
253
|
-
import {
|
|
254
|
-
AuthContainer,
|
|
255
|
-
AuthHeader,
|
|
256
|
-
AuthFormField,
|
|
257
|
-
AuthPasswordField,
|
|
258
|
-
AuthSubmitButton,
|
|
259
|
-
AuthOAuthProviders,
|
|
260
|
-
} from '@insforge/nextjs';
|
|
261
|
-
|
|
262
|
-
function CustomSignIn() {
|
|
263
|
-
// Build your own auth UI with full control
|
|
264
|
-
}
|
|
265
|
-
```
|
|
266
|
-
|
|
267
|
-
**Available primitives**: `AuthContainer`, `AuthHeader`, `AuthErrorBanner`, `AuthFormField`, `AuthPasswordField`, `AuthSubmitButton`, `AuthDivider`, `AuthLink`, `AuthOAuthProviders`, `AuthBranding`.
|
|
268
|
-
|
|
269
|
-
### Update Middleware
|
|
270
|
-
|
|
271
|
-
```ts
|
|
272
|
-
// middleware.ts
|
|
273
|
-
export default InsforgeMiddleware({
|
|
274
|
-
baseUrl: process.env.INSFORGE_BASE_URL!,
|
|
275
|
-
publicRoutes: ['/sign-in', '/sign-up', '/auth/callback', '/'],
|
|
276
|
-
signInUrl: '/sign-in',
|
|
277
|
-
useBuiltInAuth: false, // Important!
|
|
278
|
-
});
|
|
279
|
-
```
|
|
280
|
-
|
|
281
242
|
---
|
|
282
243
|
|
|
283
244
|
## API Reference
|
|
@@ -286,29 +247,75 @@ export default InsforgeMiddleware({
|
|
|
286
247
|
|
|
287
248
|
#### `useAuth()`
|
|
288
249
|
|
|
250
|
+
Access authentication methods (uses SDK internally):
|
|
251
|
+
|
|
289
252
|
```tsx
|
|
290
253
|
import { useAuth } from '@insforge/nextjs';
|
|
291
254
|
|
|
292
255
|
function Component() {
|
|
293
|
-
const {
|
|
294
|
-
|
|
256
|
+
const { signIn, signUp, signOut, isSignedIn, isLoaded } = useAuth();
|
|
257
|
+
|
|
258
|
+
async function handleSignIn(email: string, password: string) {
|
|
259
|
+
try {
|
|
260
|
+
await signIn(email, password); // Uses SDK internally
|
|
261
|
+
} catch (error) {
|
|
262
|
+
console.error('Sign in failed:', error);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
return (
|
|
267
|
+
<div>
|
|
268
|
+
{isSignedIn && <button onClick={() => signOut()}>Sign Out</button>}
|
|
269
|
+
</div>
|
|
270
|
+
);
|
|
295
271
|
}
|
|
296
272
|
```
|
|
297
273
|
|
|
298
|
-
**Returns**: `
|
|
274
|
+
**Returns**: `signIn()`, `signUp()`, `signOut()`, `isLoaded`, `isSignedIn`
|
|
299
275
|
|
|
300
276
|
#### `useUser()`
|
|
301
277
|
|
|
278
|
+
Access current user data (from SDK-managed storage):
|
|
279
|
+
|
|
302
280
|
```tsx
|
|
303
|
-
|
|
281
|
+
import { useUser } from '@insforge/nextjs';
|
|
282
|
+
|
|
283
|
+
function UserProfile() {
|
|
284
|
+
const { user, isLoaded, updateUser } = useUser();
|
|
285
|
+
|
|
286
|
+
if (!isLoaded) return <div>Loading...</div>;
|
|
287
|
+
if (!user) return <div>Not signed in</div>;
|
|
288
|
+
|
|
289
|
+
return (
|
|
290
|
+
<div>
|
|
291
|
+
<p>Email: {user.email}</p>
|
|
292
|
+
{user.nickname && <p>Nickname: {user.nickname}</p>}
|
|
293
|
+
</div>
|
|
294
|
+
);
|
|
295
|
+
}
|
|
304
296
|
```
|
|
305
297
|
|
|
298
|
+
**Returns**: `user`, `isLoaded`, `updateUser()`
|
|
299
|
+
|
|
306
300
|
#### `useSession()`
|
|
307
301
|
|
|
302
|
+
Access session data (from SDK-managed storage):
|
|
303
|
+
|
|
308
304
|
```tsx
|
|
309
|
-
|
|
305
|
+
import { useSession } from '@insforge/nextjs';
|
|
306
|
+
|
|
307
|
+
function SessionInfo() {
|
|
308
|
+
const { session, isLoaded } = useSession();
|
|
309
|
+
|
|
310
|
+
if (!isLoaded) return <div>Loading...</div>;
|
|
311
|
+
if (!session) return <div>No active session</div>;
|
|
312
|
+
|
|
313
|
+
return <div>User ID: {session.userId}</div>;
|
|
314
|
+
}
|
|
310
315
|
```
|
|
311
316
|
|
|
317
|
+
**Returns**: `session`, `isLoaded`
|
|
318
|
+
|
|
312
319
|
### Components
|
|
313
320
|
|
|
314
321
|
#### `<SignIn>` / `<SignUp>`
|
|
@@ -325,9 +332,11 @@ Pre-built auth forms (only with `useBuiltInAuth={false}`):
|
|
|
325
332
|
#### `<UserButton>`
|
|
326
333
|
|
|
327
334
|
```tsx
|
|
328
|
-
<UserButton afterSignOutUrl="/"
|
|
335
|
+
<UserButton afterSignOutUrl="/" mode="detailed" />
|
|
329
336
|
```
|
|
330
337
|
|
|
338
|
+
**Props**: `afterSignOutUrl`, `mode` ('detailed' | 'simple'), `appearance`
|
|
339
|
+
|
|
331
340
|
#### `<SignedIn>` / `<SignedOut>` / `<Protect>`
|
|
332
341
|
|
|
333
342
|
```tsx
|
|
@@ -342,39 +351,30 @@ Pre-built auth forms (only with `useBuiltInAuth={false}`):
|
|
|
342
351
|
// app/dashboard/page.tsx (Server Component)
|
|
343
352
|
import { headers } from 'next/headers';
|
|
344
353
|
import { getAuthUserId, getAuthToken } from '@insforge/nextjs/middleware';
|
|
354
|
+
import { createClient } from '@insforge/sdk';
|
|
345
355
|
|
|
346
356
|
export default async function Dashboard() {
|
|
347
357
|
const userId = getAuthUserId(headers());
|
|
348
358
|
const token = getAuthToken(headers());
|
|
349
359
|
|
|
350
|
-
|
|
351
|
-
|
|
360
|
+
if (!userId) {
|
|
361
|
+
return <div>Not authenticated</div>;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
// Use SDK to fetch user data server-side
|
|
365
|
+
const insforge = createClient({
|
|
366
|
+
baseUrl: process.env.INSFORGE_BASE_URL!,
|
|
367
|
+
edgeFunctionToken: token || undefined,
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
const { data: userData } = await insforge.auth.getCurrentUser();
|
|
371
|
+
|
|
372
|
+
return <div>Welcome, {userData?.user.email}</div>;
|
|
352
373
|
}
|
|
353
|
-
|
|
354
374
|
```
|
|
355
375
|
|
|
356
376
|
---
|
|
357
377
|
|
|
358
|
-
## Customization
|
|
359
|
-
|
|
360
|
-
### Styling (Custom Components Only)
|
|
361
|
-
|
|
362
|
-
When using `useBuiltInAuth={false}`, import styles:
|
|
363
|
-
|
|
364
|
-
```tsx
|
|
365
|
-
import '@insforge/nextjs/styles.css';
|
|
366
|
-
```
|
|
367
|
-
|
|
368
|
-
Override with `appearance` prop or CSS classes:
|
|
369
|
-
|
|
370
|
-
```tsx
|
|
371
|
-
<SignIn appearance={{ container: { background: '#f5f5f5' } }} />
|
|
372
|
-
```
|
|
373
|
-
|
|
374
|
-
```css
|
|
375
|
-
.insforge-btn-primary { background: #8b5cf6; }
|
|
376
|
-
```
|
|
377
|
-
|
|
378
378
|
### Auth Callbacks
|
|
379
379
|
|
|
380
380
|
```tsx
|
|
@@ -386,11 +386,20 @@ Override with `appearance` prop or CSS classes:
|
|
|
386
386
|
|
|
387
387
|
---
|
|
388
388
|
|
|
389
|
+
## SDK + Next.js Package = Complete Solution
|
|
390
|
+
|
|
391
|
+
The `@insforge/nextjs` package works seamlessly with `@insforge/sdk`:
|
|
392
|
+
|
|
393
|
+
- **SDK handles**: API calls, token management, OAuth callback detection, user data fetching
|
|
394
|
+
- **Next.js package handles**: React components, hooks, middleware, SSR support
|
|
395
|
+
|
|
396
|
+
Always use SDK methods (`insforge.auth.getCurrentUser()`, `insforge.auth.signIn()`, etc.) instead of raw `fetch` calls. This ensures consistency, type safety, and automatic error handling.
|
|
397
|
+
|
|
389
398
|
## Why @insforge/nextjs?
|
|
390
399
|
|
|
391
|
-
**For Developers**: 5-minute auth setup instead of hours. Production-ready security and session management included.
|
|
400
|
+
**For Developers**: 5-minute auth setup instead of hours. Production-ready security and session management included. SDK integration means less code to write and maintain.
|
|
392
401
|
|
|
393
|
-
**For AI Agents**: Minimal code generation (5 files vs 20+ for custom auth).
|
|
402
|
+
**For AI Agents**: Minimal code generation (5 files vs 20+ for custom auth). SDK-first approach reduces errors. Consistent patterns across projects.
|
|
394
403
|
|
|
395
404
|
---
|
|
396
405
|
|
package/dist/api.d.mts
CHANGED
|
@@ -36,15 +36,4 @@ declare function createAuthRouteHandlers(config: AuthRouteConfig): {
|
|
|
36
36
|
}>>;
|
|
37
37
|
};
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
baseUrl: string;
|
|
41
|
-
}
|
|
42
|
-
declare function createProfileHandler(config: ProfileHandlerConfig): (request: NextRequest) => Promise<NextResponse<{
|
|
43
|
-
success: boolean;
|
|
44
|
-
error: string;
|
|
45
|
-
}> | NextResponse<{
|
|
46
|
-
success: boolean;
|
|
47
|
-
user: any;
|
|
48
|
-
}>>;
|
|
49
|
-
|
|
50
|
-
export { type AuthRouteConfig, type ProfileHandlerConfig, createAuthRouteHandlers, createProfileHandler };
|
|
39
|
+
export { type AuthRouteConfig, createAuthRouteHandlers };
|
package/dist/api.d.ts
CHANGED
|
@@ -36,15 +36,4 @@ declare function createAuthRouteHandlers(config: AuthRouteConfig): {
|
|
|
36
36
|
}>>;
|
|
37
37
|
};
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
baseUrl: string;
|
|
41
|
-
}
|
|
42
|
-
declare function createProfileHandler(config: ProfileHandlerConfig): (request: NextRequest) => Promise<NextResponse<{
|
|
43
|
-
success: boolean;
|
|
44
|
-
error: string;
|
|
45
|
-
}> | NextResponse<{
|
|
46
|
-
success: boolean;
|
|
47
|
-
user: any;
|
|
48
|
-
}>>;
|
|
49
|
-
|
|
50
|
-
export { type AuthRouteConfig, type ProfileHandlerConfig, createAuthRouteHandlers, createProfileHandler };
|
|
39
|
+
export { type AuthRouteConfig, createAuthRouteHandlers };
|
package/dist/api.js
CHANGED
|
@@ -20,8 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/api/index.ts
|
|
21
21
|
var api_exports = {};
|
|
22
22
|
__export(api_exports, {
|
|
23
|
-
createAuthRouteHandlers: () => createAuthRouteHandlers
|
|
24
|
-
createProfileHandler: () => createProfileHandler
|
|
23
|
+
createAuthRouteHandlers: () => createAuthRouteHandlers
|
|
25
24
|
});
|
|
26
25
|
module.exports = __toCommonJS(api_exports);
|
|
27
26
|
|
|
@@ -92,7 +91,7 @@ function createAuthRouteHandlers(config) {
|
|
|
92
91
|
{ status: 401 }
|
|
93
92
|
);
|
|
94
93
|
}
|
|
95
|
-
if (!result.data) {
|
|
94
|
+
if (!result.data || !result.data.user) {
|
|
96
95
|
return import_server.NextResponse.json(
|
|
97
96
|
{ error: "Authentication failed" },
|
|
98
97
|
{ status: 401 }
|
|
@@ -106,7 +105,7 @@ function createAuthRouteHandlers(config) {
|
|
|
106
105
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
107
106
|
}
|
|
108
107
|
});
|
|
109
|
-
setAuthCookie(response, result.data.accessToken);
|
|
108
|
+
setAuthCookie(response, result.data.accessToken || "");
|
|
110
109
|
return response;
|
|
111
110
|
}
|
|
112
111
|
case "sign-up": {
|
|
@@ -123,7 +122,7 @@ function createAuthRouteHandlers(config) {
|
|
|
123
122
|
{ status: 400 }
|
|
124
123
|
);
|
|
125
124
|
}
|
|
126
|
-
if (!result.data) {
|
|
125
|
+
if (!result.data || !result.data.user) {
|
|
127
126
|
return import_server.NextResponse.json(
|
|
128
127
|
{ error: "Sign up failed" },
|
|
129
128
|
{ status: 400 }
|
|
@@ -137,7 +136,7 @@ function createAuthRouteHandlers(config) {
|
|
|
137
136
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
138
137
|
}
|
|
139
138
|
});
|
|
140
|
-
setAuthCookie(response, result.data.accessToken);
|
|
139
|
+
setAuthCookie(response, result.data.accessToken || "");
|
|
141
140
|
return response;
|
|
142
141
|
}
|
|
143
142
|
case "sync-token": {
|
|
@@ -261,63 +260,8 @@ function createAuthRouteHandlers(config) {
|
|
|
261
260
|
DELETE
|
|
262
261
|
};
|
|
263
262
|
}
|
|
264
|
-
|
|
265
|
-
// src/api/profile-handler.ts
|
|
266
|
-
var import_server2 = require("next/server");
|
|
267
|
-
function createProfileHandler(config) {
|
|
268
|
-
const { baseUrl } = config;
|
|
269
|
-
return async function POST(request) {
|
|
270
|
-
try {
|
|
271
|
-
const body = await request.json();
|
|
272
|
-
const { token } = body;
|
|
273
|
-
if (!token) {
|
|
274
|
-
return import_server2.NextResponse.json(
|
|
275
|
-
{ success: false, error: "Token is required" },
|
|
276
|
-
{ status: 400 }
|
|
277
|
-
);
|
|
278
|
-
}
|
|
279
|
-
console.log("[Profile Handler] Fetching user profile from backend");
|
|
280
|
-
const response = await fetch(`${baseUrl}/api/auth/sessions/current`, {
|
|
281
|
-
headers: {
|
|
282
|
-
Authorization: `Bearer ${token}`,
|
|
283
|
-
"Content-Type": "application/json"
|
|
284
|
-
}
|
|
285
|
-
});
|
|
286
|
-
if (!response.ok) {
|
|
287
|
-
const errorText = await response.text();
|
|
288
|
-
console.error("[Profile Handler] Backend error:", {
|
|
289
|
-
status: response.status,
|
|
290
|
-
error: errorText
|
|
291
|
-
});
|
|
292
|
-
return import_server2.NextResponse.json(
|
|
293
|
-
{
|
|
294
|
-
success: false,
|
|
295
|
-
error: `Failed to fetch profile: ${response.status} ${response.statusText}`
|
|
296
|
-
},
|
|
297
|
-
{ status: response.status }
|
|
298
|
-
);
|
|
299
|
-
}
|
|
300
|
-
const userData = await response.json();
|
|
301
|
-
console.log("[Profile Handler] User profile fetched successfully");
|
|
302
|
-
return import_server2.NextResponse.json({
|
|
303
|
-
success: true,
|
|
304
|
-
user: userData
|
|
305
|
-
});
|
|
306
|
-
} catch (error) {
|
|
307
|
-
console.error("[Profile Handler] Error:", error);
|
|
308
|
-
return import_server2.NextResponse.json(
|
|
309
|
-
{
|
|
310
|
-
success: false,
|
|
311
|
-
error: error instanceof Error ? error.message : "Internal server error"
|
|
312
|
-
},
|
|
313
|
-
{ status: 500 }
|
|
314
|
-
);
|
|
315
|
-
}
|
|
316
|
-
};
|
|
317
|
-
}
|
|
318
263
|
// Annotate the CommonJS export names for ESM import in node:
|
|
319
264
|
0 && (module.exports = {
|
|
320
|
-
createAuthRouteHandlers
|
|
321
|
-
createProfileHandler
|
|
265
|
+
createAuthRouteHandlers
|
|
322
266
|
});
|
|
323
267
|
//# sourceMappingURL=api.js.map
|
package/dist/api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/api/index.ts","../src/api/route-handlers.ts","../src/api/profile-handler.ts"],"sourcesContent":["export { createAuthRouteHandlers } from './route-handlers';\r\nexport type { AuthRouteConfig } from './route-handlers';\r\n\r\n// Profile handler (server-side proxy for fetching user profile)\r\nexport { createProfileHandler } from './profile-handler';\r\nexport type { ProfileHandlerConfig } from './profile-handler';","import { NextRequest, NextResponse } from 'next/server';\r\nimport { createClient } from '@insforge/sdk';\r\n\r\nexport interface AuthRouteConfig {\r\n /**\r\n * Base URL of your Insforge backend\r\n */\r\n baseUrl: string;\r\n\r\n /**\r\n * Cookie name for the auth token\r\n * @default 'insforge_token'\r\n */\r\n cookieName?: string;\r\n\r\n /**\r\n * Cookie max age in seconds (default: 7 days)\r\n * @default 604800\r\n */\r\n cookieMaxAge?: number;\r\n\r\n /**\r\n * Whether to use secure cookies (HTTPS only)\r\n * Auto-detected based on environment\r\n */\r\n secure?: boolean;\r\n}\r\n\r\n/**\r\n * Creates authentication route handlers for Next.js App Router\r\n * These handlers set HTTP-only cookies that can be read by middleware\r\n *\r\n * @example\r\n * ```ts\r\n * // app/api/auth/[...auth]/route.ts\r\n * import { createAuthRouteHandlers } from '@insforge/nextjs/api';\r\n *\r\n * const handlers = createAuthRouteHandlers({\r\n * baseUrl: process.env.NEXT_PUBLIC_INSFORGE_BASE_URL!,\r\n * });\r\n *\r\n * export const POST = handlers.POST;\r\n * export const GET = handlers.GET;\r\n * export const DELETE = handlers.DELETE;\r\n * ```\r\n */\r\nexport function createAuthRouteHandlers(config: AuthRouteConfig) {\r\n const {\r\n baseUrl,\r\n cookieName = 'insforge_token',\r\n cookieMaxAge = 7 * 24 * 60 * 60, // 7 days\r\n } = config;\r\n\r\n const insforge = createClient({ baseUrl });\r\n\r\n /**\r\n * Helper to set auth cookie\r\n */\r\n function setAuthCookie(response: NextResponse, token: string) {\r\n // NODE_ENV is automatically set by Next.js runtime ('development' | 'production' | 'test')\r\n // In production, cookies are sent over HTTPS only (secure flag)\r\n const isProduction = process.env.NODE_ENV === 'production';\r\n const secure = config.secure ?? isProduction;\r\n\r\n response.cookies.set({\r\n name: cookieName,\r\n value: token,\r\n httpOnly: true, // Cannot be accessed by JavaScript\r\n secure, // Only sent over HTTPS in production\r\n sameSite: 'lax',\r\n maxAge: cookieMaxAge,\r\n path: '/',\r\n });\r\n\r\n return response;\r\n }\r\n\r\n /**\r\n * Helper to clear auth cookie\r\n */\r\n function clearAuthCookie(response: NextResponse) {\r\n response.cookies.set({\r\n name: cookieName,\r\n value: '',\r\n httpOnly: true,\r\n secure: config.secure ?? (process.env.NODE_ENV === 'production'),\r\n sameSite: 'lax',\r\n maxAge: 0,\r\n path: '/',\r\n });\r\n\r\n return response;\r\n }\r\n\r\n /**\r\n * POST handler for authentication actions\r\n * Supports: sign-in, sign-up\r\n */\r\n async function POST(request: NextRequest) {\r\n try {\r\n const body = await request.json();\r\n const { action, email, password } = body;\r\n\r\n if (!action) {\r\n return NextResponse.json(\r\n { error: 'Action is required' },\r\n { status: 400 }\r\n );\r\n }\r\n\r\n switch (action) {\r\n case 'sign-in': {\r\n if (!email || !password) {\r\n return NextResponse.json(\r\n { error: 'Email and password are required' },\r\n { status: 400 }\r\n );\r\n }\r\n\r\n const result = await insforge.auth.signInWithPassword({\r\n email,\r\n password,\r\n });\r\n\r\n if (result.error) {\r\n return NextResponse.json(\r\n { error: result.error.message },\r\n { status: 401 }\r\n );\r\n }\r\n\r\n if (!result.data) {\r\n return NextResponse.json(\r\n { error: 'Authentication failed' },\r\n { status: 401 }\r\n );\r\n }\r\n\r\n const response = NextResponse.json({\r\n user: result.data.user,\r\n session: {\r\n userId: result.data.user.id,\r\n expiresAt: '',\r\n createdAt: new Date().toISOString(),\r\n },\r\n });\r\n\r\n setAuthCookie(response, result.data.accessToken);\r\n\r\n return response;\r\n }\r\n\r\n case 'sign-up': {\r\n if (!email || !password) {\r\n return NextResponse.json(\r\n { error: 'Email and password are required' },\r\n { status: 400 }\r\n );\r\n }\r\n\r\n const result = await insforge.auth.signUp({ email, password });\r\n\r\n if (result.error) {\r\n return NextResponse.json(\r\n { error: result.error.message },\r\n { status: 400 }\r\n );\r\n }\r\n\r\n if (!result.data) {\r\n return NextResponse.json(\r\n { error: 'Sign up failed' },\r\n { status: 400 }\r\n );\r\n }\r\n\r\n const response = NextResponse.json({\r\n user: result.data.user,\r\n session: {\r\n userId: result.data.user.id,\r\n expiresAt: '',\r\n createdAt: new Date().toISOString(),\r\n },\r\n });\r\n\r\n setAuthCookie(response, result.data.accessToken);\r\n\r\n return response;\r\n }\r\n\r\n case 'sync-token': {\r\n // Syncs a token from localStorage to HTTP-only cookie\r\n const { token } = body;\r\n\r\n if (!token) {\r\n return NextResponse.json(\r\n { error: 'Token is required' },\r\n { status: 400 }\r\n );\r\n }\r\n\r\n // Verify the token is valid by checking with backend\r\n try {\r\n const response = await fetch(`${baseUrl}/api/auth/sessions/current`, {\r\n headers: {\r\n Authorization: `Bearer ${token}`,\r\n 'Content-Type': 'application/json',\r\n },\r\n });\r\n\r\n if (!response.ok) {\r\n const errorText = await response.text();\r\n console.error('[Auth API] Token validation failed:', errorText);\r\n return NextResponse.json(\r\n { error: 'Invalid token', details: errorText },\r\n { status: 401 }\r\n );\r\n }\r\n\r\n const session = await response.json();\r\n\r\n const nextResponse = NextResponse.json({\r\n user: session.user,\r\n session: {\r\n userId: session.user.id,\r\n expiresAt: '',\r\n createdAt: new Date().toISOString(),\r\n },\r\n });\r\n\r\n setAuthCookie(nextResponse, token);\r\n\r\n return nextResponse;\r\n } catch (error) {\r\n console.error('[Auth API] Token validation error:', error);\r\n return NextResponse.json(\r\n { error: 'Token validation failed', details: String(error) },\r\n { status: 401 }\r\n );\r\n }\r\n }\r\n\r\n default:\r\n return NextResponse.json(\r\n { error: 'Invalid action' },\r\n { status: 400 }\r\n );\r\n }\r\n } catch (error) {\r\n console.error('[Auth API Error]:', error);\r\n return NextResponse.json(\r\n { error: 'Internal server error' },\r\n { status: 500 }\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * GET handler to check current session\r\n */\r\n async function GET(request: NextRequest) {\r\n try {\r\n const token = request.cookies.get(cookieName)?.value;\r\n\r\n if (!token) {\r\n return NextResponse.json({ user: null, session: null });\r\n }\r\n\r\n // Verify token with backend\r\n const response = await fetch(`${baseUrl}/api/auth/sessions/current`, {\r\n headers: {\r\n Authorization: `Bearer ${token}`,\r\n 'Content-Type': 'application/json',\r\n },\r\n });\r\n\r\n if (!response.ok) {\r\n const nextResponse = NextResponse.json({ user: null, session: null });\r\n clearAuthCookie(nextResponse);\r\n return nextResponse;\r\n }\r\n\r\n const session = await response.json();\r\n\r\n return NextResponse.json({\r\n user: session.user,\r\n session: {\r\n userId: session.user.id,\r\n token,\r\n expiresAt: '',\r\n createdAt: new Date().toISOString(),\r\n },\r\n });\r\n } catch (error) {\r\n console.error('[Auth API Error]:', error);\r\n return NextResponse.json({ user: null, session: null });\r\n }\r\n }\r\n\r\n /**\r\n * DELETE handler for sign out\r\n */\r\n async function DELETE(request: NextRequest) {\r\n try {\r\n const token = request.cookies.get(cookieName)?.value;\r\n\r\n if (token) {\r\n // Call backend sign out\r\n try {\r\n await fetch(`${baseUrl}/auth/sessions/current`, {\r\n method: 'DELETE',\r\n headers: {\r\n Authorization: `Bearer ${token}`,\r\n 'Content-Type': 'application/json',\r\n },\r\n });\r\n } catch (error) {\r\n // Ignore backend errors during sign out\r\n console.error('[Auth API] Sign out error:', error);\r\n }\r\n }\r\n\r\n const response = NextResponse.json({ success: true });\r\n clearAuthCookie(response);\r\n\r\n return response;\r\n } catch (error) {\r\n console.error('[Auth API Error]:', error);\r\n return NextResponse.json(\r\n { error: 'Internal server error' },\r\n { status: 500 }\r\n );\r\n }\r\n }\r\n\r\n return {\r\n POST,\r\n GET,\r\n DELETE,\r\n };\r\n}\r\n","import { NextRequest, NextResponse } from 'next/server';\r\n\r\nexport interface ProfileHandlerConfig {\r\n /**\r\n * Base URL of your Insforge backend\r\n */\r\n baseUrl: string;\r\n}\r\n\r\n/**\r\n * Creates a profile fetcher API route that acts as a proxy to your Insforge backend\r\n * \r\n * This handler accepts a token and fetches the user profile from the backend,\r\n * acting as a secure server-side proxy to avoid exposing backend URLs to clients.\r\n * \r\n * @param config - Configuration for the profile handler\r\n * @returns Next.js API route handler (POST method)\r\n * \r\n * @example\r\n * ```ts\r\n * // app/api/auth/profile/route.ts\r\n * import { createProfileHandler } from '@insforge/nextjs/api';\r\n * \r\n * export const POST = createProfileHandler({\r\n * baseUrl: process.env.INSFORGE_BASE_URL!,\r\n * });\r\n * ```\r\n * \r\n * @example\r\n * ```tsx\r\n * // Usage in callback page (client-side)\r\n * const response = await fetch('/api/auth/profile', {\r\n * method: 'POST',\r\n * headers: { 'Content-Type': 'application/json' },\r\n * body: JSON.stringify({ token: accessToken }),\r\n * });\r\n * \r\n * const result = await response.json();\r\n * if (result.success) {\r\n * // Store user profile\r\n * localStorage.setItem('insforge-user-profile', JSON.stringify(result.user));\r\n * }\r\n * ```\r\n */\r\nexport function createProfileHandler(config: ProfileHandlerConfig) {\r\n const { baseUrl } = config;\r\n\r\n return async function POST(request: NextRequest) {\r\n try {\r\n const body = await request.json();\r\n const { token } = body;\r\n\r\n if (!token) {\r\n return NextResponse.json(\r\n { success: false, error: 'Token is required' },\r\n { status: 400 }\r\n );\r\n }\r\n\r\n console.log('[Profile Handler] Fetching user profile from backend');\r\n\r\n // Call Insforge backend to get user profile (proxy)\r\n const response = await fetch(`${baseUrl}/api/auth/sessions/current`, {\r\n headers: {\r\n Authorization: `Bearer ${token}`,\r\n 'Content-Type': 'application/json',\r\n },\r\n });\r\n\r\n if (!response.ok) {\r\n const errorText = await response.text();\r\n console.error('[Profile Handler] Backend error:', {\r\n status: response.status,\r\n error: errorText,\r\n });\r\n \r\n return NextResponse.json(\r\n { \r\n success: false, \r\n error: `Failed to fetch profile: ${response.status} ${response.statusText}` \r\n },\r\n { status: response.status }\r\n );\r\n }\r\n\r\n const userData = await response.json();\r\n console.log('[Profile Handler] User profile fetched successfully');\r\n\r\n return NextResponse.json({\r\n success: true,\r\n user: userData,\r\n });\r\n } catch (error) {\r\n console.error('[Profile Handler] Error:', error);\r\n return NextResponse.json(\r\n { \r\n success: false, \r\n error: error instanceof Error ? error.message : 'Internal server error' \r\n },\r\n { status: 500 }\r\n );\r\n }\r\n };\r\n}\r\n\r\n"],"mappings":"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","names":["import_server"]}
|
|
1
|
+
{"version":3,"sources":["../src/api/index.ts","../src/api/route-handlers.ts"],"sourcesContent":["export { createAuthRouteHandlers } from './route-handlers';\r\nexport type { AuthRouteConfig } from './route-handlers';","import { NextRequest, NextResponse } from 'next/server';\nimport { createClient } from '@insforge/sdk';\n\nexport interface AuthRouteConfig {\n /**\n * Base URL of your Insforge backend\n */\n baseUrl: string;\n\n /**\n * Cookie name for the auth token\n * @default 'insforge_token'\n */\n cookieName?: string;\n\n /**\n * Cookie max age in seconds (default: 7 days)\n * @default 604800\n */\n cookieMaxAge?: number;\n\n /**\n * Whether to use secure cookies (HTTPS only)\n * Auto-detected based on environment\n */\n secure?: boolean;\n}\n\n/**\n * Creates authentication route handlers for Next.js App Router\n * These handlers set HTTP-only cookies that can be read by middleware\n *\n * @example\n * ```ts\n * // app/api/auth/[...auth]/route.ts\n * import { createAuthRouteHandlers } from '@insforge/nextjs/api';\n *\n * const handlers = createAuthRouteHandlers({\n * baseUrl: process.env.NEXT_PUBLIC_INSFORGE_BASE_URL!,\n * });\n *\n * export const POST = handlers.POST;\n * export const GET = handlers.GET;\n * export const DELETE = handlers.DELETE;\n * ```\n */\nexport function createAuthRouteHandlers(config: AuthRouteConfig) {\n const {\n baseUrl,\n cookieName = 'insforge_token',\n cookieMaxAge = 7 * 24 * 60 * 60, // 7 days\n } = config;\n\n const insforge = createClient({ baseUrl });\n\n /**\n * Helper to set auth cookie\n */\n function setAuthCookie(response: NextResponse, token: string) {\n // NODE_ENV is automatically set by Next.js runtime ('development' | 'production' | 'test')\n // In production, cookies are sent over HTTPS only (secure flag)\n const isProduction = process.env.NODE_ENV === 'production';\n const secure = config.secure ?? isProduction;\n\n response.cookies.set({\n name: cookieName,\n value: token,\n httpOnly: true, // Cannot be accessed by JavaScript\n secure, // Only sent over HTTPS in production\n sameSite: 'lax',\n maxAge: cookieMaxAge,\n path: '/',\n });\n\n return response;\n }\n\n /**\n * Helper to clear auth cookie\n */\n function clearAuthCookie(response: NextResponse) {\n response.cookies.set({\n name: cookieName,\n value: '',\n httpOnly: true,\n secure: config.secure ?? (process.env.NODE_ENV === 'production'),\n sameSite: 'lax',\n maxAge: 0,\n path: '/',\n });\n\n return response;\n }\n\n /**\n * POST handler for authentication actions\n * Supports: sign-in, sign-up\n */\n async function POST(request: NextRequest) {\n try {\n const body = await request.json();\n const { action, email, password } = body;\n\n if (!action) {\n return NextResponse.json(\n { error: 'Action is required' },\n { status: 400 }\n );\n }\n\n switch (action) {\n case 'sign-in': {\n if (!email || !password) {\n return NextResponse.json(\n { error: 'Email and password are required' },\n { status: 400 }\n );\n }\n\n const result = await insforge.auth.signInWithPassword({\n email,\n password,\n });\n\n if (result.error) {\n return NextResponse.json(\n { error: result.error.message },\n { status: 401 }\n );\n }\n\n if (!result.data || !result.data.user) {\n return NextResponse.json(\n { error: 'Authentication failed' },\n { status: 401 }\n );\n }\n\n const response = NextResponse.json({\n user: result.data.user,\n session: {\n userId: result.data.user.id,\n expiresAt: '',\n createdAt: new Date().toISOString(),\n },\n });\n\n setAuthCookie(response, result.data.accessToken || '');\n\n return response;\n }\n\n case 'sign-up': {\n if (!email || !password) {\n return NextResponse.json(\n { error: 'Email and password are required' },\n { status: 400 }\n );\n }\n\n const result = await insforge.auth.signUp({ email, password });\n\n if (result.error) {\n return NextResponse.json(\n { error: result.error.message },\n { status: 400 }\n );\n }\n\n if (!result.data || !result.data.user) {\n return NextResponse.json(\n { error: 'Sign up failed' },\n { status: 400 }\n );\n }\n\n const response = NextResponse.json({\n user: result.data.user,\n session: {\n userId: result.data.user.id,\n expiresAt: '',\n createdAt: new Date().toISOString(),\n },\n });\n\n setAuthCookie(response, result.data.accessToken || '');\n\n return response;\n }\n\n case 'sync-token': {\n // Syncs a token from localStorage to HTTP-only cookie\n const { token } = body;\n\n if (!token) {\n return NextResponse.json(\n { error: 'Token is required' },\n { status: 400 }\n );\n }\n\n // Verify the token is valid by checking with backend\n try {\n const response = await fetch(`${baseUrl}/api/auth/sessions/current`, {\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n console.error('[Auth API] Token validation failed:', errorText);\n return NextResponse.json(\n { error: 'Invalid token', details: errorText },\n { status: 401 }\n );\n }\n\n const session = await response.json();\n\n const nextResponse = NextResponse.json({\n user: session.user,\n session: {\n userId: session.user.id,\n expiresAt: '',\n createdAt: new Date().toISOString(),\n },\n });\n\n setAuthCookie(nextResponse, token);\n\n return nextResponse;\n } catch (error) {\n console.error('[Auth API] Token validation error:', error);\n return NextResponse.json(\n { error: 'Token validation failed', details: String(error) },\n { status: 401 }\n );\n }\n }\n\n default:\n return NextResponse.json(\n { error: 'Invalid action' },\n { status: 400 }\n );\n }\n } catch (error) {\n console.error('[Auth API Error]:', error);\n return NextResponse.json(\n { error: 'Internal server error' },\n { status: 500 }\n );\n }\n }\n\n /**\n * GET handler to check current session\n */\n async function GET(request: NextRequest) {\n try {\n const token = request.cookies.get(cookieName)?.value;\n\n if (!token) {\n return NextResponse.json({ user: null, session: null });\n }\n\n // Verify token with backend\n const response = await fetch(`${baseUrl}/api/auth/sessions/current`, {\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n });\n\n if (!response.ok) {\n const nextResponse = NextResponse.json({ user: null, session: null });\n clearAuthCookie(nextResponse);\n return nextResponse;\n }\n\n const session = await response.json();\n\n return NextResponse.json({\n user: session.user,\n session: {\n userId: session.user.id,\n token,\n expiresAt: '',\n createdAt: new Date().toISOString(),\n },\n });\n } catch (error) {\n console.error('[Auth API Error]:', error);\n return NextResponse.json({ user: null, session: null });\n }\n }\n\n /**\n * DELETE handler for sign out\n */\n async function DELETE(request: NextRequest) {\n try {\n const token = request.cookies.get(cookieName)?.value;\n\n if (token) {\n // Call backend sign out\n try {\n await fetch(`${baseUrl}/auth/sessions/current`, {\n method: 'DELETE',\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n });\n } catch (error) {\n // Ignore backend errors during sign out\n console.error('[Auth API] Sign out error:', error);\n }\n }\n\n const response = NextResponse.json({ success: true });\n clearAuthCookie(response);\n\n return response;\n } catch (error) {\n console.error('[Auth API Error]:', error);\n return NextResponse.json(\n { error: 'Internal server error' },\n { status: 500 }\n );\n }\n }\n\n return {\n POST,\n GET,\n DELETE,\n };\n}\n"],"mappings":"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","names":[]}
|
package/dist/api.mjs
CHANGED
|
@@ -65,7 +65,7 @@ function createAuthRouteHandlers(config) {
|
|
|
65
65
|
{ status: 401 }
|
|
66
66
|
);
|
|
67
67
|
}
|
|
68
|
-
if (!result.data) {
|
|
68
|
+
if (!result.data || !result.data.user) {
|
|
69
69
|
return NextResponse.json(
|
|
70
70
|
{ error: "Authentication failed" },
|
|
71
71
|
{ status: 401 }
|
|
@@ -79,7 +79,7 @@ function createAuthRouteHandlers(config) {
|
|
|
79
79
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
80
80
|
}
|
|
81
81
|
});
|
|
82
|
-
setAuthCookie(response, result.data.accessToken);
|
|
82
|
+
setAuthCookie(response, result.data.accessToken || "");
|
|
83
83
|
return response;
|
|
84
84
|
}
|
|
85
85
|
case "sign-up": {
|
|
@@ -96,7 +96,7 @@ function createAuthRouteHandlers(config) {
|
|
|
96
96
|
{ status: 400 }
|
|
97
97
|
);
|
|
98
98
|
}
|
|
99
|
-
if (!result.data) {
|
|
99
|
+
if (!result.data || !result.data.user) {
|
|
100
100
|
return NextResponse.json(
|
|
101
101
|
{ error: "Sign up failed" },
|
|
102
102
|
{ status: 400 }
|
|
@@ -110,7 +110,7 @@ function createAuthRouteHandlers(config) {
|
|
|
110
110
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
111
111
|
}
|
|
112
112
|
});
|
|
113
|
-
setAuthCookie(response, result.data.accessToken);
|
|
113
|
+
setAuthCookie(response, result.data.accessToken || "");
|
|
114
114
|
return response;
|
|
115
115
|
}
|
|
116
116
|
case "sync-token": {
|
|
@@ -234,62 +234,7 @@ function createAuthRouteHandlers(config) {
|
|
|
234
234
|
DELETE
|
|
235
235
|
};
|
|
236
236
|
}
|
|
237
|
-
|
|
238
|
-
// src/api/profile-handler.ts
|
|
239
|
-
import { NextResponse as NextResponse2 } from "next/server";
|
|
240
|
-
function createProfileHandler(config) {
|
|
241
|
-
const { baseUrl } = config;
|
|
242
|
-
return async function POST(request) {
|
|
243
|
-
try {
|
|
244
|
-
const body = await request.json();
|
|
245
|
-
const { token } = body;
|
|
246
|
-
if (!token) {
|
|
247
|
-
return NextResponse2.json(
|
|
248
|
-
{ success: false, error: "Token is required" },
|
|
249
|
-
{ status: 400 }
|
|
250
|
-
);
|
|
251
|
-
}
|
|
252
|
-
console.log("[Profile Handler] Fetching user profile from backend");
|
|
253
|
-
const response = await fetch(`${baseUrl}/api/auth/sessions/current`, {
|
|
254
|
-
headers: {
|
|
255
|
-
Authorization: `Bearer ${token}`,
|
|
256
|
-
"Content-Type": "application/json"
|
|
257
|
-
}
|
|
258
|
-
});
|
|
259
|
-
if (!response.ok) {
|
|
260
|
-
const errorText = await response.text();
|
|
261
|
-
console.error("[Profile Handler] Backend error:", {
|
|
262
|
-
status: response.status,
|
|
263
|
-
error: errorText
|
|
264
|
-
});
|
|
265
|
-
return NextResponse2.json(
|
|
266
|
-
{
|
|
267
|
-
success: false,
|
|
268
|
-
error: `Failed to fetch profile: ${response.status} ${response.statusText}`
|
|
269
|
-
},
|
|
270
|
-
{ status: response.status }
|
|
271
|
-
);
|
|
272
|
-
}
|
|
273
|
-
const userData = await response.json();
|
|
274
|
-
console.log("[Profile Handler] User profile fetched successfully");
|
|
275
|
-
return NextResponse2.json({
|
|
276
|
-
success: true,
|
|
277
|
-
user: userData
|
|
278
|
-
});
|
|
279
|
-
} catch (error) {
|
|
280
|
-
console.error("[Profile Handler] Error:", error);
|
|
281
|
-
return NextResponse2.json(
|
|
282
|
-
{
|
|
283
|
-
success: false,
|
|
284
|
-
error: error instanceof Error ? error.message : "Internal server error"
|
|
285
|
-
},
|
|
286
|
-
{ status: 500 }
|
|
287
|
-
);
|
|
288
|
-
}
|
|
289
|
-
};
|
|
290
|
-
}
|
|
291
237
|
export {
|
|
292
|
-
createAuthRouteHandlers
|
|
293
|
-
createProfileHandler
|
|
238
|
+
createAuthRouteHandlers
|
|
294
239
|
};
|
|
295
240
|
//# sourceMappingURL=api.mjs.map
|