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