@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 +119 -5
- package/dist/api.d.mts +12 -1
- package/dist/api.d.ts +12 -1
- package/dist/api.js +58 -2
- package/dist/api.js.map +1 -1
- package/dist/api.mjs +56 -1
- package/dist/api.mjs.map +1 -1
- package/dist/index.d.mts +5 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +45 -5
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +45 -5
- package/dist/index.mjs.map +1 -1
- package/dist/middleware.d.mts +7 -1
- package/dist/middleware.d.ts +7 -1
- package/dist/middleware.js +52 -9
- package/dist/middleware.js.map +1 -1
- package/dist/middleware.mjs +48 -8
- package/dist/middleware.mjs.map +1 -1
- package/package.json +4 -4
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!**
|
|
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: ['/
|
|
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
|
-
-
|
|
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
|
-
|
|
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
|
-
|
|
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(): {
|