@insforge/nextjs 0.5.6 → 0.6.5

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
@@ -4,6 +4,7 @@ Pre-built authentication UI components for Next.js applications using Insforge b
4
4
 
5
5
  ## Features
6
6
 
7
+ - **Built-in Authentication (v0.6.0+)**: Zero-config authentication using backend-hosted pages
7
8
  - **Drop-in UI Components**: Pre-styled SignIn, SignUp, and UserButton components
8
9
  - **Auth Primitives (v0.5.0+)**: 10 low-level components for building custom auth UIs
9
10
  - **React Hooks**: Easy access to auth state with `useAuth()`, `useUser()`, `useSession()`
@@ -47,7 +48,104 @@ export default function RootLayout({ children }: { children: React.ReactNode })
47
48
  }
48
49
  ```
49
50
 
50
- **That's it!** No Tailwind configuration needed. The package uses standalone CSS.
51
+ **That's it!** By default, the package uses **built-in authentication** - users will be automatically redirected to your backend's authentication pages when not signed in. No additional setup required!
52
+
53
+ ## Built-in Authentication (Default)
54
+
55
+ The package now includes **built-in authentication** by default, which means:
56
+
57
+ - ✅ **Zero UI Code**: No need to create SignIn/SignUp pages
58
+ - ✅ **Automatic Redirects**: Users are redirected to backend auth pages when not signed in
59
+ - ✅ **Same-Domain Performance**: Faster API calls without CORS overhead
60
+ - ✅ **Unified Experience**: Consistent auth UI across all Insforge apps
61
+
62
+ ### How it works
63
+
64
+ 1. User visits a protected page (e.g., `/dashboard`)
65
+ 2. Provider detects user is not signed in
66
+ 3. Automatically redirects to: `https://your-backend.insforge.app/auth/signin?redirect=https://yourapp.com/auth/callback`
67
+ 4. User signs in on the backend's authentication page
68
+ 5. Backend redirects back to: `https://yourapp.com/auth/callback?access_token=xxx`
69
+ 6. Your callback page stores the token and redirects to the original destination
70
+
71
+ ### Local Development Setup
72
+
73
+ For local development, your backend API and frontend typically run on different ports. You can configure this in two ways:
74
+
75
+ **Option 1: Using environment variables (recommended)**
76
+
77
+ ```bash
78
+ # .env.local
79
+ NEXT_PUBLIC_INSFORGE_BASE_URL=http://localhost:7130 # Backend API
80
+ NEXT_PUBLIC_INSFORGE_FRONTEND_URL=http://localhost:7131 # Backend Frontend
81
+ ```
82
+
83
+ ```tsx
84
+ // app/layout.tsx
85
+ import { InsforgeProvider } from '@insforge/nextjs';
86
+
87
+ export default function RootLayout({ children }: { children: React.ReactNode }) {
88
+ return (
89
+ <html lang="en">
90
+ <body>
91
+ <InsforgeProvider baseUrl={process.env.NEXT_PUBLIC_INSFORGE_BASE_URL!}>
92
+ {children}
93
+ </InsforgeProvider>
94
+ </body>
95
+ </html>
96
+ );
97
+ }
98
+ ```
99
+
100
+ **Option 2: Using the `frontendUrl` prop**
101
+
102
+ ```tsx
103
+ // app/layout.tsx
104
+ import { InsforgeProvider } from '@insforge/nextjs';
105
+
106
+ export default function RootLayout({ children }: { children: React.ReactNode }) {
107
+ return (
108
+ <html lang="en">
109
+ <body>
110
+ <InsforgeProvider
111
+ baseUrl={process.env.NEXT_PUBLIC_INSFORGE_BASE_URL!}
112
+ frontendUrl={process.env.NEXT_PUBLIC_INSFORGE_FRONTEND_URL}
113
+ >
114
+ {children}
115
+ </InsforgeProvider>
116
+ </body>
117
+ </html>
118
+ );
119
+ }
120
+ ```
121
+
122
+ **Priority:** `frontendUrl` prop > `NEXT_PUBLIC_INSFORGE_FRONTEND_URL` env var > `baseUrl` (fallback)
123
+
124
+ **Production:** If your API and frontend share the same URL, you only need `NEXT_PUBLIC_INSFORGE_BASE_URL`.
125
+
126
+ ### Using Custom SignIn/SignUp Components
127
+
128
+ If you prefer to use your own authentication UI, set `useBuiltInAuth={false}`:
129
+
130
+ ```tsx
131
+ // app/layout.tsx
132
+ import { InsforgeProvider } from '@insforge/nextjs';
133
+
134
+ export default function RootLayout({ children }: { children: React.ReactNode }) {
135
+ return (
136
+ <html lang="en">
137
+ <body>
138
+ <InsforgeProvider
139
+ baseUrl={process.env.NEXT_PUBLIC_INSFORGE_BASE_URL!}
140
+ useBuiltInAuth={false} // Use custom components instead
141
+ >
142
+ {children}
143
+ </InsforgeProvider>
144
+ </body>
145
+ </html>
146
+ );
147
+ }
148
+ ```
51
149
 
52
150
  ### 2. Set up API route for authentication (Required for SSR)
53
151
 
@@ -256,13 +354,12 @@ export default function Home() {
256
354
  ### 7. Protect routes with middleware
257
355
 
258
356
  ```ts
259
- // middleware.ts
357
+ // middleware.ts - Built-in authentication (default)
260
358
  import { InsforgeMiddleware } from '@insforge/nextjs/middleware';
261
359
 
262
360
  export default InsforgeMiddleware({
263
361
  baseUrl: process.env.INSFORGE_BASE_URL!,
264
- publicRoutes: ['/sign-in', '/sign-up', '/', '/auth/callback'], // Include callback!
265
- signInUrl: '/sign-in',
362
+ publicRoutes: ['/auth/callback', '/'], // Include callback!
266
363
  cookieName: 'insforge_token', // Must match API route cookie name
267
364
  });
268
365
 
@@ -271,10 +368,27 @@ export const config = {
271
368
  };
272
369
  ```
273
370
 
371
+ ```ts
372
+ // middleware.ts - Custom SignIn/SignUp components
373
+ import { InsforgeMiddleware } from '@insforge/nextjs/middleware';
374
+
375
+ export default InsforgeMiddleware({
376
+ baseUrl: process.env.INSFORGE_BASE_URL!,
377
+ publicRoutes: ['/sign-in', '/sign-up', '/', '/auth/callback'],
378
+ signInUrl: '/sign-in',
379
+ cookieName: 'insforge_token',
380
+ useBuiltInAuth: false, // Use custom components
381
+ });
382
+
383
+ export const config = {
384
+ matcher: ['/((?!api|_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)'],
385
+ };
386
+ ```
387
+
274
388
  **Important:**
275
389
  - **Must include** `/auth/callback` in `publicRoutes` to allow authentication returns
276
390
  - Use the same `cookieName` in both middleware and API route
277
- - The `cookieName` must match between middleware and API route configuration
391
+ - With built-in auth, middleware won't redirect to local sign-in pages
278
392
 
279
393
  **Alternative imports:**
280
394
  - `InsforgeMiddleware` - Recommended, most descriptive
package/dist/api.d.mts CHANGED
@@ -36,4 +36,15 @@ declare function createAuthRouteHandlers(config: AuthRouteConfig): {
36
36
  }>>;
37
37
  };
38
38
 
39
- export { type AuthRouteConfig, createAuthRouteHandlers };
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 };
package/dist/api.d.ts CHANGED
@@ -36,4 +36,15 @@ declare function createAuthRouteHandlers(config: AuthRouteConfig): {
36
36
  }>>;
37
37
  };
38
38
 
39
- export { type AuthRouteConfig, createAuthRouteHandlers };
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 };
package/dist/api.js CHANGED
@@ -20,7 +20,8 @@ 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
23
+ createAuthRouteHandlers: () => createAuthRouteHandlers,
24
+ createProfileHandler: () => createProfileHandler
24
25
  });
25
26
  module.exports = __toCommonJS(api_exports);
26
27
 
@@ -260,8 +261,63 @@ function createAuthRouteHandlers(config) {
260
261
  DELETE
261
262
  };
262
263
  }
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
+ }
263
318
  // Annotate the CommonJS export names for ESM import in node:
264
319
  0 && (module.exports = {
265
- createAuthRouteHandlers
320
+ createAuthRouteHandlers,
321
+ createProfileHandler
266
322
  });
267
323
  //# 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"],"sourcesContent":["export { createAuthRouteHandlers } from './route-handlers';\r\nexport type { AuthRouteConfig } from './route-handlers';\r\n","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"],"mappings":"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","names":[]}
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"]}
package/dist/api.mjs CHANGED
@@ -234,7 +234,62 @@ 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
+ }
237
291
  export {
238
- createAuthRouteHandlers
292
+ createAuthRouteHandlers,
293
+ createProfileHandler
239
294
  };
240
295
  //# sourceMappingURL=api.mjs.map
package/dist/api.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/api/route-handlers.ts"],"sourcesContent":["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"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/api/route-handlers.ts","../src/api/profile-handler.ts"],"sourcesContent":["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":["NextResponse"]}
package/dist/index.d.mts CHANGED
@@ -96,6 +96,7 @@ interface InsforgeContextValue {
96
96
  session: InsforgeSession | null;
97
97
  isLoaded: boolean;
98
98
  isSignedIn: boolean;
99
+ setUser: (user: InsforgeUser | null) => void;
99
100
  signIn: (email: string, password: string) => Promise<void>;
100
101
  signUp: (email: string, password: string) => Promise<void>;
101
102
  signOut: () => Promise<void>;
@@ -110,9 +111,11 @@ interface InsforgeContextValue {
110
111
  interface InsforgeProviderProps {
111
112
  children: ReactNode;
112
113
  baseUrl: string;
114
+ frontendUrl?: string;
113
115
  onAuthChange?: (user: InsforgeUser | null) => void;
116
+ useBuiltInAuth?: boolean;
114
117
  }
115
- declare function InsforgeProvider({ children, baseUrl, onAuthChange }: InsforgeProviderProps): react_jsx_runtime.JSX.Element;
118
+ declare function InsforgeProvider({ children, baseUrl, frontendUrl, onAuthChange, useBuiltInAuth }: InsforgeProviderProps): react_jsx_runtime.JSX.Element;
116
119
  declare function useInsforge(): InsforgeContextValue;
117
120
 
118
121
  declare function useAuth(): {
@@ -127,6 +130,7 @@ declare function useUser(): {
127
130
  user: InsforgeUser | null;
128
131
  isLoaded: boolean;
129
132
  updateUser: (data: Partial<InsforgeUser>) => Promise<void>;
133
+ setUser: (user: InsforgeUser | null) => void;
130
134
  };
131
135
 
132
136
  declare function useSession(): {
package/dist/index.d.ts CHANGED
@@ -96,6 +96,7 @@ interface InsforgeContextValue {
96
96
  session: InsforgeSession | null;
97
97
  isLoaded: boolean;
98
98
  isSignedIn: boolean;
99
+ setUser: (user: InsforgeUser | null) => void;
99
100
  signIn: (email: string, password: string) => Promise<void>;
100
101
  signUp: (email: string, password: string) => Promise<void>;
101
102
  signOut: () => Promise<void>;
@@ -110,9 +111,11 @@ interface InsforgeContextValue {
110
111
  interface InsforgeProviderProps {
111
112
  children: ReactNode;
112
113
  baseUrl: string;
114
+ frontendUrl?: string;
113
115
  onAuthChange?: (user: InsforgeUser | null) => void;
116
+ useBuiltInAuth?: boolean;
114
117
  }
115
- declare function InsforgeProvider({ children, baseUrl, onAuthChange }: InsforgeProviderProps): react_jsx_runtime.JSX.Element;
118
+ declare function InsforgeProvider({ children, baseUrl, frontendUrl, onAuthChange, useBuiltInAuth }: InsforgeProviderProps): react_jsx_runtime.JSX.Element;
116
119
  declare function useInsforge(): InsforgeContextValue;
117
120
 
118
121
  declare function useAuth(): {
@@ -127,6 +130,7 @@ declare function useUser(): {
127
130
  user: InsforgeUser | null;
128
131
  isLoaded: boolean;
129
132
  updateUser: (data: Partial<InsforgeUser>) => Promise<void>;
133
+ setUser: (user: InsforgeUser | null) => void;
130
134
  };
131
135
 
132
136
  declare function useSession(): {