@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 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
- if (accessToken) {
97
- localStorage.setItem('insforge-auth-token', accessToken);
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: accessToken }),
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?** Receives token from backend auth pages and syncs to localStorage + cookie.
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 { user, isSignedIn, signOut } = useAuth();
294
- return <div>{user?.email}</div>;
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**: `user`, `session`, `isLoaded`, `isSignedIn`, `signIn()`, `signUp()`, `signOut()`, `updateUser()`
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
- const { user, isLoaded } = useUser();
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
- const { session, isSignedIn } = useSession();
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="/" showEmail={true} />
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
- // Fetch user data server-side
351
- return <div>User ID: {userId}</div>;
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). Reduced token usage. Consistent patterns across projects.
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
- interface ProfileHandlerConfig {
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
- interface ProfileHandlerConfig {
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":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,oBAA0C;AAC1C,iBAA6B;AA6CtB,SAAS,wBAAwB,QAAyB;AAC/D,QAAM;AAAA,IACJ;AAAA,IACA,aAAa;AAAA,IACb,eAAe,IAAI,KAAK,KAAK;AAAA;AAAA,EAC/B,IAAI;AAEJ,QAAM,eAAW,yBAAa,EAAE,QAAQ,CAAC;AAKzC,WAAS,cAAc,UAAwB,OAAe;AAG5D,UAAM,eAAe,QAAQ,IAAI,aAAa;AAC9C,UAAM,SAAS,OAAO,UAAU;AAEhC,aAAS,QAAQ,IAAI;AAAA,MACnB,MAAM;AAAA,MACN,OAAO;AAAA,MACP,UAAU;AAAA;AAAA,MACV;AAAA;AAAA,MACA,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,MAAM;AAAA,IACR,CAAC;AAED,WAAO;AAAA,EACT;AAKA,WAAS,gBAAgB,UAAwB;AAC/C,aAAS,QAAQ,IAAI;AAAA,MACnB,MAAM;AAAA,MACN,OAAO;AAAA,MACP,UAAU;AAAA,MACV,QAAQ,OAAO,UAAW,QAAQ,IAAI,aAAa;AAAA,MACnD,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,MAAM;AAAA,IACR,CAAC;AAED,WAAO;AAAA,EACT;AAMA,iBAAe,KAAK,SAAsB;AACxC,QAAI;AACF,YAAM,OAAO,MAAM,QAAQ,KAAK;AAChC,YAAM,EAAE,QAAQ,OAAO,SAAS,IAAI;AAEpC,UAAI,CAAC,QAAQ;AACX,eAAO,2BAAa;AAAA,UAClB,EAAE,OAAO,qBAAqB;AAAA,UAC9B,EAAE,QAAQ,IAAI;AAAA,QAChB;AAAA,MACF;AAEA,cAAQ,QAAQ;AAAA,QACd,KAAK,WAAW;AACd,cAAI,CAAC,SAAS,CAAC,UAAU;AACvB,mBAAO,2BAAa;AAAA,cAClB,EAAE,OAAO,kCAAkC;AAAA,cAC3C,EAAE,QAAQ,IAAI;AAAA,YAChB;AAAA,UACF;AAEA,gBAAM,SAAS,MAAM,SAAS,KAAK,mBAAmB;AAAA,YACpD;AAAA,YACA;AAAA,UACF,CAAC;AAED,cAAI,OAAO,OAAO;AAChB,mBAAO,2BAAa;AAAA,cAClB,EAAE,OAAO,OAAO,MAAM,QAAQ;AAAA,cAC9B,EAAE,QAAQ,IAAI;AAAA,YAChB;AAAA,UACF;AAEA,cAAI,CAAC,OAAO,MAAM;AAChB,mBAAO,2BAAa;AAAA,cAClB,EAAE,OAAO,wBAAwB;AAAA,cACjC,EAAE,QAAQ,IAAI;AAAA,YAChB;AAAA,UACF;AAEA,gBAAM,WAAW,2BAAa,KAAK;AAAA,YACjC,MAAM,OAAO,KAAK;AAAA,YAClB,SAAS;AAAA,cACP,QAAQ,OAAO,KAAK,KAAK;AAAA,cACzB,WAAW;AAAA,cACX,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,YACpC;AAAA,UACF,CAAC;AAED,wBAAc,UAAU,OAAO,KAAK,WAAW;AAE/C,iBAAO;AAAA,QACT;AAAA,QAEA,KAAK,WAAW;AACd,cAAI,CAAC,SAAS,CAAC,UAAU;AACvB,mBAAO,2BAAa;AAAA,cAClB,EAAE,OAAO,kCAAkC;AAAA,cAC3C,EAAE,QAAQ,IAAI;AAAA,YAChB;AAAA,UACF;AAEA,gBAAM,SAAS,MAAM,SAAS,KAAK,OAAO,EAAE,OAAO,SAAS,CAAC;AAE7D,cAAI,OAAO,OAAO;AAChB,mBAAO,2BAAa;AAAA,cAClB,EAAE,OAAO,OAAO,MAAM,QAAQ;AAAA,cAC9B,EAAE,QAAQ,IAAI;AAAA,YAChB;AAAA,UACF;AAEA,cAAI,CAAC,OAAO,MAAM;AAChB,mBAAO,2BAAa;AAAA,cAClB,EAAE,OAAO,iBAAiB;AAAA,cAC1B,EAAE,QAAQ,IAAI;AAAA,YAChB;AAAA,UACF;AAEA,gBAAM,WAAW,2BAAa,KAAK;AAAA,YACjC,MAAM,OAAO,KAAK;AAAA,YAClB,SAAS;AAAA,cACP,QAAQ,OAAO,KAAK,KAAK;AAAA,cACzB,WAAW;AAAA,cACX,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,YACpC;AAAA,UACF,CAAC;AAED,wBAAc,UAAU,OAAO,KAAK,WAAW;AAE/C,iBAAO;AAAA,QACT;AAAA,QAEA,KAAK,cAAc;AAEjB,gBAAM,EAAE,MAAM,IAAI;AAElB,cAAI,CAAC,OAAO;AACV,mBAAO,2BAAa;AAAA,cAClB,EAAE,OAAO,oBAAoB;AAAA,cAC7B,EAAE,QAAQ,IAAI;AAAA,YAChB;AAAA,UACF;AAGA,cAAI;AACF,kBAAM,WAAW,MAAM,MAAM,GAAG,OAAO,8BAA8B;AAAA,cACnE,SAAS;AAAA,gBACP,eAAe,UAAU,KAAK;AAAA,gBAC9B,gBAAgB;AAAA,cAClB;AAAA,YACF,CAAC;AAED,gBAAI,CAAC,SAAS,IAAI;AAChB,oBAAM,YAAY,MAAM,SAAS,KAAK;AACtC,sBAAQ,MAAM,uCAAuC,SAAS;AAC9D,qBAAO,2BAAa;AAAA,gBAClB,EAAE,OAAO,iBAAiB,SAAS,UAAU;AAAA,gBAC7C,EAAE,QAAQ,IAAI;AAAA,cAChB;AAAA,YACF;AAEA,kBAAM,UAAU,MAAM,SAAS,KAAK;AAEpC,kBAAM,eAAe,2BAAa,KAAK;AAAA,cACrC,MAAM,QAAQ;AAAA,cACd,SAAS;AAAA,gBACP,QAAQ,QAAQ,KAAK;AAAA,gBACrB,WAAW;AAAA,gBACX,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,cACpC;AAAA,YACF,CAAC;AAED,0BAAc,cAAc,KAAK;AAEjC,mBAAO;AAAA,UACT,SAAS,OAAO;AACd,oBAAQ,MAAM,sCAAsC,KAAK;AACzD,mBAAO,2BAAa;AAAA,cAClB,EAAE,OAAO,2BAA2B,SAAS,OAAO,KAAK,EAAE;AAAA,cAC3D,EAAE,QAAQ,IAAI;AAAA,YAChB;AAAA,UACF;AAAA,QACF;AAAA,QAEA;AACE,iBAAO,2BAAa;AAAA,YAClB,EAAE,OAAO,iBAAiB;AAAA,YAC1B,EAAE,QAAQ,IAAI;AAAA,UAChB;AAAA,MACJ;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,MAAM,qBAAqB,KAAK;AACxC,aAAO,2BAAa;AAAA,QAClB,EAAE,OAAO,wBAAwB;AAAA,QACjC,EAAE,QAAQ,IAAI;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AAKA,iBAAe,IAAI,SAAsB;AACvC,QAAI;AACF,YAAM,QAAQ,QAAQ,QAAQ,IAAI,UAAU,GAAG;AAE/C,UAAI,CAAC,OAAO;AACV,eAAO,2BAAa,KAAK,EAAE,MAAM,MAAM,SAAS,KAAK,CAAC;AAAA,MACxD;AAGA,YAAM,WAAW,MAAM,MAAM,GAAG,OAAO,8BAA8B;AAAA,QACnE,SAAS;AAAA,UACP,eAAe,UAAU,KAAK;AAAA,UAC9B,gBAAgB;AAAA,QAClB;AAAA,MACF,CAAC;AAED,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,eAAe,2BAAa,KAAK,EAAE,MAAM,MAAM,SAAS,KAAK,CAAC;AACpE,wBAAgB,YAAY;AAC5B,eAAO;AAAA,MACT;AAEA,YAAM,UAAU,MAAM,SAAS,KAAK;AAEpC,aAAO,2BAAa,KAAK;AAAA,QACvB,MAAM,QAAQ;AAAA,QACd,SAAS;AAAA,UACP,QAAQ,QAAQ,KAAK;AAAA,UACrB;AAAA,UACA,WAAW;AAAA,UACX,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,QACpC;AAAA,MACF,CAAC;AAAA,IACH,SAAS,OAAO;AACd,cAAQ,MAAM,qBAAqB,KAAK;AACxC,aAAO,2BAAa,KAAK,EAAE,MAAM,MAAM,SAAS,KAAK,CAAC;AAAA,IACxD;AAAA,EACF;AAKA,iBAAe,OAAO,SAAsB;AAC1C,QAAI;AACF,YAAM,QAAQ,QAAQ,QAAQ,IAAI,UAAU,GAAG;AAE/C,UAAI,OAAO;AAET,YAAI;AACF,gBAAM,MAAM,GAAG,OAAO,0BAA0B;AAAA,YAC9C,QAAQ;AAAA,YACR,SAAS;AAAA,cACP,eAAe,UAAU,KAAK;AAAA,cAC9B,gBAAgB;AAAA,YAClB;AAAA,UACF,CAAC;AAAA,QACH,SAAS,OAAO;AAEd,kBAAQ,MAAM,8BAA8B,KAAK;AAAA,QACnD;AAAA,MACF;AAEA,YAAM,WAAW,2BAAa,KAAK,EAAE,SAAS,KAAK,CAAC;AACpD,sBAAgB,QAAQ;AAExB,aAAO;AAAA,IACT,SAAS,OAAO;AACd,cAAQ,MAAM,qBAAqB,KAAK;AACxC,aAAO,2BAAa;AAAA,QAClB,EAAE,OAAO,wBAAwB;AAAA,QACjC,EAAE,QAAQ,IAAI;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;ACpVA,IAAAA,iBAA0C;AA4CnC,SAAS,qBAAqB,QAA8B;AACjE,QAAM,EAAE,QAAQ,IAAI;AAEpB,SAAO,eAAe,KAAK,SAAsB;AAC/C,QAAI;AACF,YAAM,OAAO,MAAM,QAAQ,KAAK;AAChC,YAAM,EAAE,MAAM,IAAI;AAElB,UAAI,CAAC,OAAO;AACV,eAAO,4BAAa;AAAA,UAClB,EAAE,SAAS,OAAO,OAAO,oBAAoB;AAAA,UAC7C,EAAE,QAAQ,IAAI;AAAA,QAChB;AAAA,MACF;AAEA,cAAQ,IAAI,sDAAsD;AAGlE,YAAM,WAAW,MAAM,MAAM,GAAG,OAAO,8BAA8B;AAAA,QACnE,SAAS;AAAA,UACP,eAAe,UAAU,KAAK;AAAA,UAC9B,gBAAgB;AAAA,QAClB;AAAA,MACF,CAAC;AAED,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,YAAY,MAAM,SAAS,KAAK;AACtC,gBAAQ,MAAM,oCAAoC;AAAA,UAChD,QAAQ,SAAS;AAAA,UACjB,OAAO;AAAA,QACT,CAAC;AAED,eAAO,4BAAa;AAAA,UAClB;AAAA,YACE,SAAS;AAAA,YACT,OAAO,4BAA4B,SAAS,MAAM,IAAI,SAAS,UAAU;AAAA,UAC3E;AAAA,UACA,EAAE,QAAQ,SAAS,OAAO;AAAA,QAC5B;AAAA,MACF;AAEA,YAAM,WAAW,MAAM,SAAS,KAAK;AACrC,cAAQ,IAAI,qDAAqD;AAEjE,aAAO,4BAAa,KAAK;AAAA,QACvB,SAAS;AAAA,QACT,MAAM;AAAA,MACR,CAAC;AAAA,IACH,SAAS,OAAO;AACd,cAAQ,MAAM,4BAA4B,KAAK;AAC/C,aAAO,4BAAa;AAAA,QAClB;AAAA,UACE,SAAS;AAAA,UACT,OAAO,iBAAiB,QAAQ,MAAM,UAAU;AAAA,QAClD;AAAA,QACA,EAAE,QAAQ,IAAI;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AACF;","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