@insforge/nextjs 0.5.6 → 0.6.6
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 +152 -785
- 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/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(): {
|
package/dist/index.js
CHANGED
|
@@ -85,11 +85,15 @@ async function fetchOAuthProviders(baseUrl) {
|
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
87
|
function getTokenFromSDK() {
|
|
88
|
+
console.log("[InsforgeProvider] Getting token from SDK");
|
|
88
89
|
if (typeof window === "undefined") return null;
|
|
90
|
+
console.log("[InsforgeProvider] Window:", window);
|
|
89
91
|
try {
|
|
90
92
|
const token = localStorage.getItem("insforge-auth-token");
|
|
93
|
+
console.log("[InsforgeProvider] Token:", token);
|
|
91
94
|
return token;
|
|
92
95
|
} catch (error) {
|
|
96
|
+
console.error("[InsforgeProvider] Error getting token from SDK:", error);
|
|
93
97
|
return null;
|
|
94
98
|
}
|
|
95
99
|
}
|
|
@@ -116,7 +120,9 @@ async function syncTokenToCookie(token) {
|
|
|
116
120
|
function InsforgeProvider({
|
|
117
121
|
children,
|
|
118
122
|
baseUrl,
|
|
119
|
-
|
|
123
|
+
frontendUrl,
|
|
124
|
+
onAuthChange,
|
|
125
|
+
useBuiltInAuth = true
|
|
120
126
|
}) {
|
|
121
127
|
const [user, setUser] = (0, import_react.useState)(null);
|
|
122
128
|
const [session, setSession] = (0, import_react.useState)(null);
|
|
@@ -145,33 +151,63 @@ function InsforgeProvider({
|
|
|
145
151
|
setIsLoaded(true);
|
|
146
152
|
return;
|
|
147
153
|
}
|
|
154
|
+
const cachedUserStr = localStorage.getItem("insforge-user-profile");
|
|
155
|
+
if (cachedUserStr) {
|
|
156
|
+
try {
|
|
157
|
+
const cachedData = JSON.parse(cachedUserStr);
|
|
158
|
+
if (cachedData.user) {
|
|
159
|
+
console.log("[InsforgeProvider] Loading user from cache");
|
|
160
|
+
const userData = {
|
|
161
|
+
id: cachedData.user.id,
|
|
162
|
+
email: cachedData.user.email,
|
|
163
|
+
createdAt: cachedData.user.createdAt || (/* @__PURE__ */ new Date()).toISOString(),
|
|
164
|
+
updatedAt: cachedData.user.updatedAt || (/* @__PURE__ */ new Date()).toISOString(),
|
|
165
|
+
...cachedData.profile
|
|
166
|
+
};
|
|
167
|
+
setUser(userData);
|
|
168
|
+
setSession({
|
|
169
|
+
userId: cachedData.user.id,
|
|
170
|
+
token,
|
|
171
|
+
expiresAt: "",
|
|
172
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
173
|
+
});
|
|
174
|
+
if (onAuthChange) {
|
|
175
|
+
onAuthChange(userData);
|
|
176
|
+
}
|
|
177
|
+
setIsLoaded(true);
|
|
178
|
+
}
|
|
179
|
+
} catch (e) {
|
|
180
|
+
console.warn("[InsforgeProvider] Failed to parse cached user data:", e);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
148
183
|
try {
|
|
149
184
|
await syncTokenToCookie(token);
|
|
150
185
|
} catch (error) {
|
|
151
186
|
}
|
|
152
187
|
const userResult = await insforge.auth.getCurrentUser();
|
|
153
188
|
if (userResult.data) {
|
|
189
|
+
console.log("[InsforgeProvider] User data refreshed from API");
|
|
154
190
|
const userData = {
|
|
155
191
|
id: userResult.data.user.id,
|
|
156
192
|
email: userResult.data.user.email,
|
|
157
193
|
createdAt: userResult.data.user.createdAt || (/* @__PURE__ */ new Date()).toISOString(),
|
|
158
194
|
updatedAt: userResult.data.user.updatedAt || (/* @__PURE__ */ new Date()).toISOString(),
|
|
159
195
|
...userResult.data.profile
|
|
160
|
-
// Add profile data if available
|
|
161
196
|
};
|
|
162
197
|
setUser(userData);
|
|
163
198
|
setSession({
|
|
164
199
|
userId: userResult.data.user.id,
|
|
165
200
|
token,
|
|
166
201
|
expiresAt: "",
|
|
167
|
-
// Insforge tokens are long-lived
|
|
168
202
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
169
203
|
});
|
|
204
|
+
localStorage.setItem("insforge-user-profile", JSON.stringify(userResult.data));
|
|
170
205
|
if (onAuthChange) {
|
|
171
206
|
onAuthChange(userData);
|
|
172
207
|
}
|
|
173
208
|
} else {
|
|
174
209
|
localStorage.removeItem("insforge-auth-token");
|
|
210
|
+
localStorage.removeItem("insforge-user-profile");
|
|
175
211
|
try {
|
|
176
212
|
await fetch("/api/auth", { method: "DELETE" });
|
|
177
213
|
} catch (error) {
|
|
@@ -183,7 +219,9 @@ function InsforgeProvider({
|
|
|
183
219
|
}
|
|
184
220
|
}
|
|
185
221
|
} catch (error) {
|
|
222
|
+
console.error("[InsforgeProvider] Token validation failed:", error);
|
|
186
223
|
localStorage.removeItem("insforge-auth-token");
|
|
224
|
+
localStorage.removeItem("insforge-user-profile");
|
|
187
225
|
try {
|
|
188
226
|
await fetch("/api/auth", { method: "DELETE" });
|
|
189
227
|
} catch (error2) {
|
|
@@ -274,6 +312,7 @@ function InsforgeProvider({
|
|
|
274
312
|
);
|
|
275
313
|
const signOut = (0, import_react.useCallback)(async () => {
|
|
276
314
|
await insforge.auth.signOut();
|
|
315
|
+
localStorage.removeItem("insforge-user-profile");
|
|
277
316
|
await fetch("/api/auth", { method: "DELETE" }).catch(() => {
|
|
278
317
|
});
|
|
279
318
|
if (refreshIntervalRef.current) {
|
|
@@ -361,6 +400,7 @@ function InsforgeProvider({
|
|
|
361
400
|
session,
|
|
362
401
|
isLoaded,
|
|
363
402
|
isSignedIn: !!user,
|
|
403
|
+
setUser,
|
|
364
404
|
signIn,
|
|
365
405
|
signUp,
|
|
366
406
|
signOut,
|
|
@@ -395,8 +435,8 @@ function useAuth() {
|
|
|
395
435
|
|
|
396
436
|
// src/hooks/useUser.ts
|
|
397
437
|
function useUser() {
|
|
398
|
-
const { user, isLoaded, updateUser } = useInsforge();
|
|
399
|
-
return { user, isLoaded, updateUser };
|
|
438
|
+
const { user, isLoaded, updateUser, setUser } = useInsforge();
|
|
439
|
+
return { user, isLoaded, updateUser, setUser };
|
|
400
440
|
}
|
|
401
441
|
|
|
402
442
|
// src/hooks/useSession.ts
|