@insforge/nextjs 1.0.3 → 1.0.5-dev.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/dist/client/provider.d.ts +1 -1
- package/dist/esm/api/route-handlers.js +4 -10
- package/dist/esm/api/route-handlers.js.map +1 -1
- package/dist/esm/client/hooks.js.map +1 -1
- package/dist/esm/client/provider.js +2 -2
- package/dist/esm/client/provider.js.map +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/lib/cookies.js +2 -2
- package/dist/esm/lib/cookies.js.map +1 -1
- package/dist/esm/middleware/InsforgeMiddleware.js +1 -1
- package/dist/esm/middleware/InsforgeMiddleware.js.map +1 -1
- package/dist/esm/server/InsforgeProvider.js +8 -65
- package/dist/esm/server/InsforgeProvider.js.map +1 -1
- package/dist/esm/server/auth.js.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/lib/cookies.d.ts +4 -15
- package/dist/server/InsforgeProvider.d.ts +1 -8
- package/dist/server/auth.d.ts +2 -3
- package/dist/server/index.d.ts +1 -2
- package/package.json +75 -75
|
@@ -22,7 +22,7 @@ interface ExtendedProviderProps extends InsforgeProviderProps {
|
|
|
22
22
|
*
|
|
23
23
|
* @internal - Not intended for direct use. Use the Server Provider instead.
|
|
24
24
|
*/
|
|
25
|
-
declare function ClientInsforgeProvider({ children,
|
|
25
|
+
declare function ClientInsforgeProvider({ children, client, afterSignInUrl, onAuthChange, initialState, }: ExtendedProviderProps): react_jsx_runtime.JSX.Element;
|
|
26
26
|
/**
|
|
27
27
|
* Hook to access Insforge context
|
|
28
28
|
*
|
|
@@ -75,7 +75,7 @@ function createAuthRouteHandlers(config) {
|
|
|
75
75
|
setAuthCookies(response, result.data.accessToken || "", {
|
|
76
76
|
id: result.data.user.id,
|
|
77
77
|
email: result.data.user.email,
|
|
78
|
-
|
|
78
|
+
profile: result.data.user.profile || null
|
|
79
79
|
});
|
|
80
80
|
return response;
|
|
81
81
|
}
|
|
@@ -102,7 +102,7 @@ function createAuthRouteHandlers(config) {
|
|
|
102
102
|
setAuthCookies(response, result.data.accessToken || "", {
|
|
103
103
|
id: result.data.user.id,
|
|
104
104
|
email: result.data.user.email,
|
|
105
|
-
|
|
105
|
+
profile: result.data.user.profile || null
|
|
106
106
|
});
|
|
107
107
|
return response;
|
|
108
108
|
}
|
|
@@ -141,7 +141,7 @@ function createAuthRouteHandlers(config) {
|
|
|
141
141
|
setAuthCookies(nextResponse, token, {
|
|
142
142
|
id: session.user.id,
|
|
143
143
|
email: session.user.email,
|
|
144
|
-
|
|
144
|
+
profile: session.user.profile || null
|
|
145
145
|
});
|
|
146
146
|
return nextResponse;
|
|
147
147
|
} catch (error) {
|
|
@@ -179,13 +179,7 @@ function createAuthRouteHandlers(config) {
|
|
|
179
179
|
}
|
|
180
180
|
const session = await response.json();
|
|
181
181
|
return NextResponse.json({
|
|
182
|
-
user: session.user
|
|
183
|
-
session: {
|
|
184
|
-
userId: session.user.id,
|
|
185
|
-
token,
|
|
186
|
-
expiresAt: "",
|
|
187
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
188
|
-
}
|
|
182
|
+
user: session.user
|
|
189
183
|
});
|
|
190
184
|
} catch (error) {
|
|
191
185
|
console.error("[Auth API Error]:", error);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/api/route-handlers.ts"],"sourcesContent":["import { NextRequest, NextResponse } from 'next/server';\nimport { createClient } from '@insforge/sdk';\nimport {\n COOKIE_NAMES,\n COOKIE_DEFAULTS,\n getBaseCookieOptions,\n getClearCookieOptions,\n serializeUserCookie,\n} from '../lib/cookies';\n\ninterface SignInRequestBody {\n action: 'sign-in';\n email: string;\n password: string;\n}\n\ninterface SignUpRequestBody {\n action: 'sign-up';\n email: string;\n password: string;\n}\n\ninterface SyncTokenRequestBody {\n action: 'sync-token';\n}\n\ntype AuthRequestBody = SignInRequestBody | SignUpRequestBody | SyncTokenRequestBody;\n\ninterface UserWithOptionalName {\n id: string;\n email: string;\n name?: string;\n [key: string]: unknown;\n}\n\ninterface SessionResponse {\n user: UserWithOptionalName;\n [key: string]: unknown;\n}\n\nexport interface AuthRouteConfig {\n /**\n * Base URL of your Insforge backend\n */\n baseUrl: 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\ninterface AuthRouteHandlers {\n POST: (request: NextRequest) => Promise<NextResponse>;\n GET: (request: NextRequest) => Promise<NextResponse>;\n DELETE: (request: NextRequest) => Promise<NextResponse>;\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): AuthRouteHandlers {\n const { baseUrl, cookieMaxAge = COOKIE_DEFAULTS.MAX_AGE } = config;\n\n const insforge = createClient({ baseUrl });\n\n /**\n * Helper to set auth cookies (session token + user identity)\n */\n function setAuthCookies(\n response: NextResponse,\n token: string,\n user: { id: string; email: string; name?: string }\n ) {\n const cookieOptions = getBaseCookieOptions({\n maxAge: cookieMaxAge,\n secure: config.secure,\n });\n\n // Set session cookie (access token)\n response.cookies.set({\n name: COOKIE_NAMES.SESSION,\n value: token,\n ...cookieOptions,\n });\n\n // Set user identity cookie (basic info for SSR)\n response.cookies.set({\n name: COOKIE_NAMES.USER,\n value: serializeUserCookie(user),\n ...cookieOptions,\n });\n\n return response;\n }\n\n /**\n * Helper to clear auth cookies\n */\n function clearAuthCookies(response: NextResponse) {\n const clearOptions = getClearCookieOptions({ secure: config.secure });\n\n // Clear session cookie\n response.cookies.set({\n name: COOKIE_NAMES.SESSION,\n value: '',\n ...clearOptions,\n });\n\n // Clear user cookie\n response.cookies.set({\n name: COOKIE_NAMES.USER,\n value: '',\n ...clearOptions,\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()) as AuthRequestBody;\n const { action } = body;\n\n if (!action) {\n return NextResponse.json({ error: 'Action is required' }, { status: 400 });\n }\n\n switch (action) {\n case 'sign-in': {\n const { email, password } = body;\n if (!email || !password) {\n return NextResponse.json({ error: 'Email and password are required' }, { status: 400 });\n }\n\n const result = await insforge.auth.signInWithPassword({\n email,\n password,\n });\n\n if (result.error) {\n return NextResponse.json({ error: result.error.message }, { status: 401 });\n }\n\n if (!result.data || !result.data.user) {\n return NextResponse.json({ error: 'Authentication failed' }, { status: 401 });\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 setAuthCookies(response, result.data.accessToken || '', {\n id: result.data.user.id,\n email: result.data.user.email,\n name: result.data.user.profile?.name || '',\n });\n\n return response;\n }\n\n case 'sign-up': {\n const { email, password } = body;\n if (!email || !password) {\n return NextResponse.json({ error: 'Email and password are required' }, { status: 400 });\n }\n\n const result = await insforge.auth.signUp({ email, password });\n\n if (result.error) {\n return NextResponse.json({ error: result.error.message }, { status: 400 });\n }\n\n if (!result.data || !result.data.user) {\n return NextResponse.json({ error: 'Sign up failed' }, { status: 400 });\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 setAuthCookies(response, result.data.accessToken || '', {\n id: result.data.user.id,\n email: result.data.user.email,\n name: result.data.user.profile?.name || '',\n });\n\n return response;\n }\n\n case 'sync-token': {\n // Syncs access token to HTTP-only cookie for server-side usage\n // Token is passed via Authorization header (preferred)\n const authHeader = request.headers.get('Authorization');\n const tokenFromHeader = authHeader?.startsWith('Bearer ') ? authHeader.slice(7) : null;\n const token = tokenFromHeader;\n\n if (!token) {\n console.error('[Auth Route] No token provided in header');\n return NextResponse.json({ error: 'Token is required' }, { status: 400 });\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()) as SessionResponse;\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 setAuthCookies(nextResponse, token, {\n id: session.user.id,\n email: session.user.email,\n name: session.user.name,\n });\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({ error: 'Invalid action' }, { status: 400 });\n }\n } catch (error) {\n console.error('[Auth API Error]:', error);\n return NextResponse.json({ error: 'Internal server error' }, { status: 500 });\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(COOKIE_NAMES.SESSION)?.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 clearAuthCookies(nextResponse);\n return nextResponse;\n }\n\n const session = (await response.json()) as SessionResponse;\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(COOKIE_NAMES.SESSION)?.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 clearAuthCookies(response);\n\n return response;\n } catch (error) {\n console.error('[Auth API Error]:', error);\n return NextResponse.json({ error: 'Internal server error' }, { status: 500 });\n }\n }\n\n return {\n POST,\n GET,\n DELETE,\n };\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/api/route-handlers.ts"],"sourcesContent":["import { NextRequest, NextResponse } from 'next/server';\r\nimport { createClient } from '@insforge/sdk';\r\nimport {\r\n COOKIE_NAMES,\r\n COOKIE_DEFAULTS,\r\n getBaseCookieOptions,\r\n getClearCookieOptions,\r\n serializeUserCookie,\r\n} from '../lib/cookies';\r\nimport { InsforgeUser } from '@insforge/shared';\r\nimport { GetCurrentSessionResponse } from '@insforge/shared-schemas';\r\n\r\ninterface SignInRequestBody {\r\n action: 'sign-in';\r\n email: string;\r\n password: string;\r\n}\r\n\r\ninterface SignUpRequestBody {\r\n action: 'sign-up';\r\n email: string;\r\n password: string;\r\n}\r\n\r\ninterface SyncTokenRequestBody {\r\n action: 'sync-token';\r\n}\r\n\r\ntype AuthRequestBody = SignInRequestBody | SignUpRequestBody | SyncTokenRequestBody;\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 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\ninterface AuthRouteHandlers {\r\n POST: (request: NextRequest) => Promise<NextResponse>;\r\n GET: (request: NextRequest) => Promise<NextResponse>;\r\n DELETE: (request: NextRequest) => Promise<NextResponse>;\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): AuthRouteHandlers {\r\n const { baseUrl, cookieMaxAge = COOKIE_DEFAULTS.MAX_AGE } = config;\r\n\r\n const insforge = createClient({ baseUrl });\r\n\r\n /**\r\n * Helper to set auth cookies (session token + user identity)\r\n */\r\n function setAuthCookies(\r\n response: NextResponse,\r\n token: string,\r\n user: InsforgeUser\r\n ) {\r\n const cookieOptions = getBaseCookieOptions({\r\n maxAge: cookieMaxAge,\r\n secure: config.secure,\r\n });\r\n\r\n // Set session cookie (access token)\r\n response.cookies.set({\r\n name: COOKIE_NAMES.SESSION,\r\n value: token,\r\n ...cookieOptions,\r\n });\r\n\r\n // Set user identity cookie (basic info for SSR)\r\n response.cookies.set({\r\n name: COOKIE_NAMES.USER,\r\n value: serializeUserCookie(user),\r\n ...cookieOptions,\r\n });\r\n\r\n return response;\r\n }\r\n\r\n /**\r\n * Helper to clear auth cookies\r\n */\r\n function clearAuthCookies(response: NextResponse) {\r\n const clearOptions = getClearCookieOptions({ secure: config.secure });\r\n\r\n // Clear session cookie\r\n response.cookies.set({\r\n name: COOKIE_NAMES.SESSION,\r\n value: '',\r\n ...clearOptions,\r\n });\r\n\r\n // Clear user cookie\r\n response.cookies.set({\r\n name: COOKIE_NAMES.USER,\r\n value: '',\r\n ...clearOptions,\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()) as AuthRequestBody;\r\n const { action } = body;\r\n\r\n if (!action) {\r\n return NextResponse.json({ error: 'Action is required' }, { status: 400 });\r\n }\r\n\r\n switch (action) {\r\n case 'sign-in': {\r\n const { email, password } = body;\r\n if (!email || !password) {\r\n return NextResponse.json({ error: 'Email and password are required' }, { status: 400 });\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({ error: result.error.message }, { status: 401 });\r\n }\r\n\r\n if (!result.data || !result.data.user) {\r\n return NextResponse.json({ error: 'Authentication failed' }, { status: 401 });\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 setAuthCookies(response, result.data.accessToken || '', {\r\n id: result.data.user.id,\r\n email: result.data.user.email,\r\n profile: result.data.user.profile || null,\r\n });\r\n\r\n return response;\r\n }\r\n\r\n case 'sign-up': {\r\n const { email, password } = body;\r\n if (!email || !password) {\r\n return NextResponse.json({ error: 'Email and password are required' }, { status: 400 });\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({ error: result.error.message }, { status: 400 });\r\n }\r\n\r\n if (!result.data || !result.data.user) {\r\n return NextResponse.json({ error: 'Sign up failed' }, { status: 400 });\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 setAuthCookies(response, result.data.accessToken || '', {\r\n id: result.data.user.id,\r\n email: result.data.user.email,\r\n profile: result.data.user.profile || null,\r\n });\r\n\r\n return response;\r\n }\r\n\r\n case 'sync-token': {\r\n // Syncs access token to HTTP-only cookie for server-side usage\r\n // Token is passed via Authorization header (preferred)\r\n const authHeader = request.headers.get('Authorization');\r\n const tokenFromHeader = authHeader?.startsWith('Bearer ') ? authHeader.slice(7) : null;\r\n const token = tokenFromHeader;\r\n\r\n if (!token) {\r\n console.error('[Auth Route] No token provided in header');\r\n return NextResponse.json({ error: 'Token is required' }, { status: 400 });\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()) as GetCurrentSessionResponse;\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 setAuthCookies(nextResponse, token, {\r\n id: session.user.id,\r\n email: session.user.email,\r\n profile: session.user.profile || null,\r\n });\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({ error: 'Invalid action' }, { status: 400 });\r\n }\r\n } catch (error) {\r\n console.error('[Auth API Error]:', error);\r\n return NextResponse.json({ error: 'Internal server error' }, { status: 500 });\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(COOKIE_NAMES.SESSION)?.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 clearAuthCookies(nextResponse);\r\n return nextResponse;\r\n }\r\n\r\n const session = (await response.json()) as GetCurrentSessionResponse;\r\n\r\n return NextResponse.json({\r\n user: session.user,\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(COOKIE_NAMES.SESSION)?.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 clearAuthCookies(response);\r\n\r\n return response;\r\n } catch (error) {\r\n console.error('[Auth API Error]:', error);\r\n return NextResponse.json({ error: 'Internal server error' }, { status: 500 });\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 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/client/hooks.ts"],"sourcesContent":["'use client';\n\nimport { useInsforge } from './provider';\nimport { CreateSessionResponse, CreateUserResponse } from '@insforge/shared-schemas';\n\n/**\n * Next.js specific hooks - implemented locally to avoid Context duplication\n */\n\nexport function useAuth(): {\n signIn: (email: string, password: string) => Promise<CreateSessionResponse | { error?: string }>;\n signUp: (email: string, password: string) => Promise<CreateUserResponse | { error?: string }>;\n signOut: () => Promise<void>;\n isLoaded: boolean;\n isSignedIn: boolean | undefined;\n} {\n const { signIn, signUp, signOut, isLoaded, isSignedIn } = useInsforge();\n return { signIn, signUp, signOut, isLoaded, isSignedIn };\n}\n\nexport function useUser() {\n const { user, isLoaded } = useInsforge();\n return { user, isLoaded };\n}\n\nexport function usePublicAuthConfig() {\n const { getPublicAuthConfig } = useInsforge();\n return { getPublicAuthConfig };\n}\n"],"mappings":";AAEA,SAAS,mBAAmB;AAOrB,SAAS,UAMd;AACA,QAAM,EAAE,QAAQ,QAAQ,SAAS,UAAU,WAAW,IAAI,YAAY;AACtE,SAAO,EAAE,QAAQ,QAAQ,SAAS,UAAU,WAAW;AACzD;AAEO,SAAS,UAAU;AACxB,QAAM,EAAE,MAAM,SAAS,IAAI,YAAY;AACvC,SAAO,EAAE,MAAM,SAAS;AAC1B;AAEO,SAAS,sBAAsB;AACpC,QAAM,EAAE,oBAAoB,IAAI,YAAY;AAC5C,SAAO,EAAE,oBAAoB;AAC/B;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/client/hooks.ts"],"sourcesContent":["'use client';\r\n\r\nimport { useInsforge } from './provider';\r\nimport { CreateSessionResponse, CreateUserResponse } from '@insforge/shared-schemas';\r\n\r\n/**\r\n * Next.js specific hooks - implemented locally to avoid Context duplication\r\n */\r\n\r\nexport function useAuth(): {\r\n signIn: (email: string, password: string) => Promise<CreateSessionResponse | { error?: string }>;\r\n signUp: (email: string, password: string) => Promise<CreateUserResponse | { error?: string }>;\r\n signOut: () => Promise<void>;\r\n isLoaded: boolean;\r\n isSignedIn: boolean | undefined;\r\n} {\r\n const { signIn, signUp, signOut, isLoaded, isSignedIn } = useInsforge();\r\n return { signIn, signUp, signOut, isLoaded, isSignedIn };\r\n}\r\n\r\nexport function useUser() {\r\n const { user, isLoaded } = useInsforge();\r\n return { user, isLoaded };\r\n}\r\n\r\nexport function usePublicAuthConfig() {\r\n const { getPublicAuthConfig } = useInsforge();\r\n return { getPublicAuthConfig };\r\n}\r\n"],"mappings":";AAEA,SAAS,mBAAmB;AAOrB,SAAS,UAMd;AACA,QAAM,EAAE,QAAQ,QAAQ,SAAS,UAAU,WAAW,IAAI,YAAY;AACtE,SAAO,EAAE,QAAQ,QAAQ,SAAS,UAAU,WAAW;AACzD;AAEO,SAAS,UAAU;AACxB,QAAM,EAAE,MAAM,SAAS,IAAI,YAAY;AACvC,SAAO,EAAE,MAAM,SAAS;AAC1B;AAEO,SAAS,sBAAsB;AACpC,QAAM,EAAE,oBAAoB,IAAI,YAAY;AAC5C,SAAO,EAAE,oBAAoB;AAC/B;","names":[]}
|
|
@@ -41,14 +41,14 @@ async function handleSignOut() {
|
|
|
41
41
|
}
|
|
42
42
|
function ClientInsforgeProvider({
|
|
43
43
|
children,
|
|
44
|
-
|
|
44
|
+
client,
|
|
45
45
|
afterSignInUrl = "/",
|
|
46
46
|
onAuthChange,
|
|
47
47
|
initialState
|
|
48
48
|
}) {
|
|
49
49
|
const providerProps = {
|
|
50
50
|
children,
|
|
51
|
-
|
|
51
|
+
client,
|
|
52
52
|
afterSignInUrl,
|
|
53
53
|
onAuthChange,
|
|
54
54
|
onSignIn: handleSignIn,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/client/provider.tsx"],"sourcesContent":["'use client';\n\nimport {\n InsforgeProviderCore,\n type InsforgeProviderProps,\n type InitialAuthState,\n useInsforge as useReactInsforge,\n NavigationProvider,\n StyleProvider,\n} from '@insforge/react';\nimport { NavigationAdapter } from '../navigation';\n\n// Extended interface for Next.js provider\ninterface ExtendedProviderProps extends InsforgeProviderProps {\n afterSignInUrl?: string;\n onSignIn?: (authToken: string) => Promise<void>;\n onSignOut?: () => Promise<void>;\n onRefresh?: (authToken: string) => Promise<void>;\n /**\n * Initial auth state from server (for SSR hydration)\n * @internal\n */\n initialState?: InitialAuthState;\n}\n\n// Sync token to server-side cookie using Authorization header\nasync function syncTokenToCookie(token: string): Promise<void> {\n try {\n const response = await fetch('/api/auth', {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n action: 'sync-token',\n }),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n console.error('[Insforge Client Provider] sync-token failed:', errorText);\n }\n } catch (err) {\n console.error('[Insforge Client Provider] Failed to sync token to cookie:', err);\n }\n}\n\n// Sync token to server-side cookie on sign in\nasync function handleSignIn(token: string): Promise<void> {\n await syncTokenToCookie(token);\n}\n\n// Sync token to server-side cookie on refresh (page load/refresh)\nasync function handleRefresh(token: string): Promise<void> {\n await syncTokenToCookie(token);\n}\n\n// Clear HTTP-only cookie on sign out\nasync function handleSignOut(): Promise<void> {\n try {\n await fetch('/api/auth', { method: 'DELETE' });\n } catch {\n // API route doesn't exist - ignore\n }\n}\n\n/**\n * Client Insforge Provider for Next.js\n *\n * This is a Client Component ('use client') that:\n * 1. Receives initialState from Server Provider\n * 2. Manages authentication state on the client\n * 3. Syncs tokens to HTTP-only cookies via /api/auth\n *\n * @internal - Not intended for direct use. Use the Server Provider instead.\n */\nexport function ClientInsforgeProvider({\n children,\n
|
|
1
|
+
{"version":3,"sources":["../../../src/client/provider.tsx"],"sourcesContent":["'use client';\r\n\r\nimport {\r\n InsforgeProviderCore,\r\n type InsforgeProviderProps,\r\n type InitialAuthState,\r\n useInsforge as useReactInsforge,\r\n NavigationProvider,\r\n StyleProvider,\r\n} from '@insforge/react';\r\nimport { NavigationAdapter } from '../navigation';\r\n\r\n// Extended interface for Next.js provider\r\ninterface ExtendedProviderProps extends InsforgeProviderProps {\r\n afterSignInUrl?: string;\r\n onSignIn?: (authToken: string) => Promise<void>;\r\n onSignOut?: () => Promise<void>;\r\n onRefresh?: (authToken: string) => Promise<void>;\r\n /**\r\n * Initial auth state from server (for SSR hydration)\r\n * @internal\r\n */\r\n initialState?: InitialAuthState;\r\n}\r\n\r\n// Sync token to server-side cookie using Authorization header\r\nasync function syncTokenToCookie(token: string): Promise<void> {\r\n try {\r\n const response = await fetch('/api/auth', {\r\n method: 'POST',\r\n headers: {\r\n Authorization: `Bearer ${token}`,\r\n 'Content-Type': 'application/json',\r\n },\r\n body: JSON.stringify({\r\n action: 'sync-token',\r\n }),\r\n });\r\n\r\n if (!response.ok) {\r\n const errorText = await response.text();\r\n console.error('[Insforge Client Provider] sync-token failed:', errorText);\r\n }\r\n } catch (err) {\r\n console.error('[Insforge Client Provider] Failed to sync token to cookie:', err);\r\n }\r\n}\r\n\r\n// Sync token to server-side cookie on sign in\r\nasync function handleSignIn(token: string): Promise<void> {\r\n await syncTokenToCookie(token);\r\n}\r\n\r\n// Sync token to server-side cookie on refresh (page load/refresh)\r\nasync function handleRefresh(token: string): Promise<void> {\r\n await syncTokenToCookie(token);\r\n}\r\n\r\n// Clear HTTP-only cookie on sign out\r\nasync function handleSignOut(): Promise<void> {\r\n try {\r\n await fetch('/api/auth', { method: 'DELETE' });\r\n } catch {\r\n // API route doesn't exist - ignore\r\n }\r\n}\r\n\r\n/**\r\n * Client Insforge Provider for Next.js\r\n *\r\n * This is a Client Component ('use client') that:\r\n * 1. Receives initialState from Server Provider\r\n * 2. Manages authentication state on the client\r\n * 3. Syncs tokens to HTTP-only cookies via /api/auth\r\n *\r\n * @internal - Not intended for direct use. Use the Server Provider instead.\r\n */\r\nexport function ClientInsforgeProvider({\r\n children,\r\n client,\r\n afterSignInUrl = '/',\r\n onAuthChange,\r\n initialState,\r\n}: ExtendedProviderProps) {\r\n const providerProps: ExtendedProviderProps = {\r\n children,\r\n client,\r\n afterSignInUrl,\r\n onAuthChange,\r\n onSignIn: handleSignIn,\r\n onSignOut: handleSignOut,\r\n onRefresh: handleRefresh,\r\n initialState,\r\n };\r\n\r\n return (\r\n <StyleProvider>\r\n <NavigationProvider adapter={NavigationAdapter}>\r\n <InsforgeProviderCore {...providerProps}>{children}</InsforgeProviderCore>\r\n </NavigationProvider>\r\n </StyleProvider>\r\n );\r\n}\r\n\r\n/**\r\n * Hook to access Insforge context\r\n *\r\n * Re-exports the hook from @insforge/react for convenience.\r\n *\r\n * @example\r\n * ```tsx\r\n * function MyComponent() {\r\n * const { user, isSignedIn, signOut } = useInsforge();\r\n *\r\n * if (!isSignedIn) return <SignIn />;\r\n *\r\n * return (\r\n * <div>\r\n * <p>Welcome {user.email}</p>\r\n * <button onClick={signOut}>Sign Out</button>\r\n * </div>\r\n * );\r\n * }\r\n * ```\r\n */\r\nexport const useInsforge = useReactInsforge;\r\n"],"mappings":";AAkGQ;AAhGR;AAAA,EACE;AAAA,EAGA,eAAe;AAAA,EACf;AAAA,EACA;AAAA,OACK;AACP,SAAS,yBAAyB;AAgBlC,eAAe,kBAAkB,OAA8B;AAC7D,MAAI;AACF,UAAM,WAAW,MAAM,MAAM,aAAa;AAAA,MACxC,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,eAAe,UAAU,KAAK;AAAA,QAC9B,gBAAgB;AAAA,MAClB;AAAA,MACA,MAAM,KAAK,UAAU;AAAA,QACnB,QAAQ;AAAA,MACV,CAAC;AAAA,IACH,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,YAAY,MAAM,SAAS,KAAK;AACtC,cAAQ,MAAM,iDAAiD,SAAS;AAAA,IAC1E;AAAA,EACF,SAAS,KAAK;AACZ,YAAQ,MAAM,8DAA8D,GAAG;AAAA,EACjF;AACF;AAGA,eAAe,aAAa,OAA8B;AACxD,QAAM,kBAAkB,KAAK;AAC/B;AAGA,eAAe,cAAc,OAA8B;AACzD,QAAM,kBAAkB,KAAK;AAC/B;AAGA,eAAe,gBAA+B;AAC5C,MAAI;AACF,UAAM,MAAM,aAAa,EAAE,QAAQ,SAAS,CAAC;AAAA,EAC/C,QAAQ;AAAA,EAER;AACF;AAYO,SAAS,uBAAuB;AAAA,EACrC;AAAA,EACA;AAAA,EACA,iBAAiB;AAAA,EACjB;AAAA,EACA;AACF,GAA0B;AACxB,QAAM,gBAAuC;AAAA,IAC3C;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU;AAAA,IACV,WAAW;AAAA,IACX,WAAW;AAAA,IACX;AAAA,EACF;AAEA,SACE,oBAAC,iBACC,8BAAC,sBAAmB,SAAS,mBAC3B,8BAAC,wBAAsB,GAAG,eAAgB,UAAS,GACrD,GACF;AAEJ;AAuBO,MAAM,cAAc;","names":[]}
|
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/index.ts"],"sourcesContent":["//
|
|
1
|
+
{"version":3,"sources":["../../src/index.ts"],"sourcesContent":["// Provider - Uses conditional exports to provide correct version\n// In Server Components: exports from server/InsforgeProvider (async, uses next/headers)\n// In Client Components: exports from client/provider (use client)\nexport { InsforgeProvider } from '#components';\n\n// Hooks (from client)\nexport { useInsforge } from './client/provider';\n\n/**\n * These need to be explicitly listed. Do not use an * here.\n * If you do, app router will break.\n *\n * Pattern learned from @clerk/nextjs\n */\n\n// Main UI Components\nexport {\n SignIn,\n SignUp,\n ForgotPassword,\n ResetPassword,\n VerifyEmail,\n UserButton,\n Protect,\n SignedIn,\n SignedOut,\n SignInButton,\n SignUpButton,\n} from './client/components';\n\n// Form Components\nexport {\n SignInForm,\n SignUpForm,\n ForgotPasswordForm,\n ResetPasswordForm,\n VerifyEmailStatus,\n} from './client/components';\n\n// Atom Components\nexport {\n AuthBranding,\n AuthContainer,\n AuthHeader,\n AuthErrorBanner,\n AuthFormField,\n AuthPasswordField,\n AuthPasswordStrengthIndicator,\n AuthSubmitButton,\n AuthLink,\n AuthDivider,\n AuthOAuthButton,\n AuthOAuthProviders,\n AuthVerificationCodeInput,\n AuthEmailVerificationStep,\n AuthResetPasswordVerificationStep,\n} from './client/components';\n\n// Component Types\nexport type {\n SignInProps,\n SignUpProps,\n ForgotPasswordProps,\n ResetPasswordProps,\n VerifyEmailProps,\n UserButtonProps,\n ProtectProps,\n ConditionalProps,\n SignInFormProps,\n SignUpFormProps,\n ForgotPasswordFormProps,\n ResetPasswordFormProps,\n VerifyEmailStatusProps,\n AuthContainerProps,\n AuthHeaderProps,\n AuthErrorBannerProps,\n AuthFormFieldProps,\n AuthPasswordFieldProps,\n AuthPasswordStrengthIndicatorProps,\n AuthSubmitButtonProps,\n AuthLinkProps,\n AuthDividerProps,\n AuthOAuthButtonProps,\n AuthOAuthProvidersProps,\n AuthVerificationCodeInputProps,\n} from './client/components';\n\n// Hooks\nexport { useAuth, useUser, usePublicAuthConfig } from './client/hooks';\n"],"mappings":"AAGA,SAAS,wBAAwB;AAGjC,SAAS,mBAAmB;AAU5B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAgCP,SAAS,SAAS,SAAS,2BAA2B;","names":[]}
|
package/dist/esm/lib/cookies.js
CHANGED
|
@@ -43,7 +43,7 @@ function serializeUserCookie(user) {
|
|
|
43
43
|
return JSON.stringify({
|
|
44
44
|
id: user.id,
|
|
45
45
|
email: user.email,
|
|
46
|
-
|
|
46
|
+
profile: user.profile || null
|
|
47
47
|
});
|
|
48
48
|
}
|
|
49
49
|
function parseUserCookie(cookieValue) {
|
|
@@ -52,7 +52,7 @@ function parseUserCookie(cookieValue) {
|
|
|
52
52
|
}
|
|
53
53
|
try {
|
|
54
54
|
const parsed = JSON.parse(cookieValue);
|
|
55
|
-
if (parsed && typeof parsed === "object" && "id" in parsed && "email" in parsed && "
|
|
55
|
+
if (parsed && typeof parsed === "object" && "id" in parsed && "email" in parsed && "profile" in parsed && typeof parsed.id === "string" && typeof parsed.email === "string" && typeof parsed.profile === "object") {
|
|
56
56
|
return parsed;
|
|
57
57
|
}
|
|
58
58
|
return null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/cookies.ts"],"sourcesContent":["import type { ResponseCookie } from 'next/dist/compiled/@edge-runtime/cookies';\n\n/**\n * Cookie names used by Insforge authentication\n * These are fixed and should not be changed to ensure consistency\n */\nexport const COOKIE_NAMES = {\n /** Session cookie storing the access token */\n SESSION: 'insforge-session',\n /** User info cookie storing basic user data for SSR */\n USER: 'insforge-user',\n} as const;\n\n/**\n * Default cookie configuration values\n */\nexport const COOKIE_DEFAULTS = {\n /** Default max age: 7 days in seconds */\n MAX_AGE: 7 * 24 * 60 * 60,\n /** Cookie path */\n PATH: '/',\n /** SameSite policy */\n SAME_SITE: 'lax' as const,\n} as const;\
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/cookies.ts"],"sourcesContent":["import type { ResponseCookie } from 'next/dist/compiled/@edge-runtime/cookies';\r\nimport { InsforgeUser } from '@insforge/shared';\r\n\r\n/**\r\n * Cookie names used by Insforge authentication\r\n * These are fixed and should not be changed to ensure consistency\r\n */\r\nexport const COOKIE_NAMES = {\r\n /** Session cookie storing the access token */\r\n SESSION: 'insforge-session',\r\n /** User info cookie storing basic user data for SSR */\r\n USER: 'insforge-user',\r\n} as const;\r\n\r\n/**\r\n * Default cookie configuration values\r\n */\r\nexport const COOKIE_DEFAULTS = {\r\n /** Default max age: 7 days in seconds */\r\n MAX_AGE: 7 * 24 * 60 * 60,\r\n /** Cookie path */\r\n PATH: '/',\r\n /** SameSite policy */\r\n SAME_SITE: 'lax' as const,\r\n} as const;\r\n\r\n/**\r\n * Options for cookie operations\r\n */\r\nexport interface CookieOptions {\r\n /** Max age in seconds (default: 7 days) */\r\n maxAge?: number;\r\n /** Whether to use secure cookies (HTTPS only). Auto-detected if not provided */\r\n secure?: boolean;\r\n}\r\n\r\n/**\r\n * Determines if secure cookies should be used based on environment\r\n * @param explicitSecure - Explicit secure value if provided\r\n * @returns Whether to use secure cookies\r\n */\r\nexport function isSecureCookie(explicitSecure?: boolean): boolean {\r\n if (explicitSecure !== undefined) {\r\n return explicitSecure;\r\n }\r\n // NODE_ENV is automatically set by Next.js runtime ('development' | 'production' | 'test')\r\n return process.env.NODE_ENV === 'production';\r\n}\r\n\r\n/**\r\n * Get base cookie options for auth cookies\r\n * @param options - Optional cookie configuration\r\n * @returns Cookie options object compatible with Next.js cookies API\r\n */\r\nexport function getBaseCookieOptions(\r\n options?: CookieOptions\r\n): Omit<ResponseCookie, 'name' | 'value'> {\r\n const secure = isSecureCookie(options?.secure);\r\n const maxAge = options?.maxAge ?? COOKIE_DEFAULTS.MAX_AGE;\r\n\r\n return {\r\n httpOnly: true,\r\n secure,\r\n sameSite: COOKIE_DEFAULTS.SAME_SITE,\r\n maxAge,\r\n path: COOKIE_DEFAULTS.PATH,\r\n };\r\n}\r\n\r\n/**\r\n * Get cookie options for clearing/deleting a cookie\r\n * @param options - Optional cookie configuration\r\n * @returns Cookie options for deletion (maxAge: 0)\r\n */\r\nexport function getClearCookieOptions(\r\n options?: Pick<CookieOptions, 'secure'>\r\n): Omit<ResponseCookie, 'name' | 'value'> {\r\n const secure = isSecureCookie(options?.secure);\r\n\r\n return {\r\n httpOnly: true,\r\n secure,\r\n sameSite: COOKIE_DEFAULTS.SAME_SITE,\r\n maxAge: 0,\r\n path: COOKIE_DEFAULTS.PATH,\r\n };\r\n}\r\n\r\n/**\r\n * Serialize user info for storage in cookie\r\n * @param user - User information to serialize\r\n * @returns JSON string of user info\r\n */\r\nexport function serializeUserCookie(user: InsforgeUser): string {\r\n return JSON.stringify({\r\n id: user.id,\r\n email: user.email,\r\n profile: user.profile || null,\r\n });\r\n}\r\n\r\n/**\r\n * Parse user info from cookie value\r\n * @param cookieValue - Raw cookie value\r\n * @returns Parsed user info or null if invalid\r\n */\r\nexport function parseUserCookie(cookieValue: string | undefined): InsforgeUser | null {\r\n if (!cookieValue) {\r\n return null;\r\n }\r\n\r\n try {\r\n const parsed = JSON.parse(cookieValue) as unknown;\r\n\r\n // Type guard to validate the parsed data\r\n if (\r\n parsed &&\r\n typeof parsed === 'object' &&\r\n 'id' in parsed &&\r\n 'email' in parsed &&\r\n 'profile' in parsed &&\r\n typeof parsed.id === 'string' &&\r\n typeof parsed.email === 'string' &&\r\n typeof parsed.profile === 'object'\r\n ) {\r\n return parsed as InsforgeUser;\r\n }\r\n\r\n return null;\r\n } catch {\r\n return null;\r\n }\r\n}\r\n"],"mappings":"AAOO,MAAM,eAAe;AAAA;AAAA,EAE1B,SAAS;AAAA;AAAA,EAET,MAAM;AACR;AAKO,MAAM,kBAAkB;AAAA;AAAA,EAE7B,SAAS,IAAI,KAAK,KAAK;AAAA;AAAA,EAEvB,MAAM;AAAA;AAAA,EAEN,WAAW;AACb;AAiBO,SAAS,eAAe,gBAAmC;AAChE,MAAI,mBAAmB,QAAW;AAChC,WAAO;AAAA,EACT;AAEA,SAAO,QAAQ,IAAI,aAAa;AAClC;AAOO,SAAS,qBACd,SACwC;AACxC,QAAM,SAAS,eAAe,SAAS,MAAM;AAC7C,QAAM,SAAS,SAAS,UAAU,gBAAgB;AAElD,SAAO;AAAA,IACL,UAAU;AAAA,IACV;AAAA,IACA,UAAU,gBAAgB;AAAA,IAC1B;AAAA,IACA,MAAM,gBAAgB;AAAA,EACxB;AACF;AAOO,SAAS,sBACd,SACwC;AACxC,QAAM,SAAS,eAAe,SAAS,MAAM;AAE7C,SAAO;AAAA,IACL,UAAU;AAAA,IACV;AAAA,IACA,UAAU,gBAAgB;AAAA,IAC1B,QAAQ;AAAA,IACR,MAAM,gBAAgB;AAAA,EACxB;AACF;AAOO,SAAS,oBAAoB,MAA4B;AAC9D,SAAO,KAAK,UAAU;AAAA,IACpB,IAAI,KAAK;AAAA,IACT,OAAO,KAAK;AAAA,IACZ,SAAS,KAAK,WAAW;AAAA,EAC3B,CAAC;AACH;AAOO,SAAS,gBAAgB,aAAsD;AACpF,MAAI,CAAC,aAAa;AAChB,WAAO;AAAA,EACT;AAEA,MAAI;AACF,UAAM,SAAS,KAAK,MAAM,WAAW;AAGrC,QACE,UACA,OAAO,WAAW,YAClB,QAAQ,UACR,WAAW,UACX,aAAa,UACb,OAAO,OAAO,OAAO,YACrB,OAAO,OAAO,UAAU,YACxB,OAAO,OAAO,YAAY,UAC1B;AACA,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;","names":[]}
|
|
@@ -22,7 +22,7 @@ const InsforgeMiddleware = (config) => {
|
|
|
22
22
|
response.cookies.set(COOKIE_NAMES.SESSION, accessToken, cookieOptions);
|
|
23
23
|
response.cookies.set(
|
|
24
24
|
COOKIE_NAMES.USER,
|
|
25
|
-
serializeUserCookie({ id: userId, email, name: name || void 0 }),
|
|
25
|
+
serializeUserCookie({ id: userId, email, profile: { name: name || void 0 } }),
|
|
26
26
|
cookieOptions
|
|
27
27
|
);
|
|
28
28
|
return response;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/middleware/InsforgeMiddleware.ts"],"sourcesContent":["import { NextRequest, NextResponse } from 'next/server';\nimport { COOKIE_NAMES, getBaseCookieOptions, serializeUserCookie } from '../lib/cookies';\n\nexport interface InsforgeMiddlewareConfig {\n /**\n * Base URL of your Insforge backend\n * @example 'https://your-backend.com' or 'http://localhost:3001'\n */\n baseUrl: string;\n\n /**\n * Routes that are public and don't require authentication\n * @default ['/']\n * @example ['/sign-in', '/sign-up', '/', '/about']\n */\n publicRoutes?: string[];\n\n /**\n * Local route path for sign-in (can be customized to any path like '/login')\n * When using built-in auth, this will redirect to backend's `/auth/sign-in`\n * @default '/sign-in'\n */\n signInUrl?: string;\n\n /**\n * Local route path for sign-up (can be customized to any path like '/register')\n * When using built-in auth, this will redirect to backend's `/auth/sign-up`\n * @default '/sign-up'\n */\n signUpUrl?: string;\n\n /**\n * Local route path for forgot password\n * When using built-in auth, this will redirect to backend's `/auth/forgot-password`\n * @default '/forgot-password'\n */\n forgotPasswordUrl?: string;\n\n /**\n * URL to redirect to after successful authentication\n * When user completes sign-in/sign-up, they will be redirected to this URL with token in URL\n * @default '/'\n */\n afterSignInUrl?: string;\n\n /**\n * Whether to use built-in authentication pages hosted on the backend\n * - When true: redirects to backend's `/auth/sign-in` and `/auth/sign-up` pages\n * - When false: redirects to local sign-in/sign-up pages (you provide your own components)\n * @default true\n */\n useBuiltInAuth?: boolean;\n}\n\n/**\n * Creates Next.js middleware for protecting routes with Insforge authentication.\n *\n * This middleware provides lightweight route protection by:\n * - Detecting and storing auth tokens from URL parameters (after backend redirect)\n * - Checking for auth token presence in cookies\n * - Redirecting unauthenticated users to sign-in page\n * - Allowing public routes to be accessed without authentication\n * - Mapping local auth routes to backend's fixed paths when using built-in auth\n *\n * **How Authentication Flow Works:**\n * 1. User visits protected route → Middleware checks for token\n * 2. No token → Redirects to sign-in (backend or local)\n * 3. User accesses auth page (e.g., /sign-in) → Redirects to backend with afterSignInUrl as redirect target\n * 4. After sign-in → Backend redirects to `yourapp.com/afterSignInUrl?access_token=xxx&user_id=xxx...`\n * 5. Middleware detects `access_token` in URL → Stores in HTTP-only cookie → Cleans URL → Allows access\n * 6. SDK also detects token from URL → Stores in localStorage → Updates auth state\n *\n * **Important Notes:**\n * - This middleware only checks if a token exists, it doesn't validate it\n * - Tokens from URL are automatically extracted and stored in cookies\n * - When `useBuiltInAuth: true`, local routes map to backend's fixed auth paths\n * - You can customize local route paths (e.g., `/login`) while backend paths remain fixed\n * - After successful auth, users are redirected to `afterSignInUrl` (default: `/`), not back to the auth page\n *\n * @param config - Middleware configuration\n * @returns Next.js middleware function\n *\n * @example\n * ```ts\n * // middleware.ts - Using built-in auth\n * import { InsforgeMiddleware } from '@insforge/nextjs/middleware';\n *\n * export default InsforgeMiddleware({\n * baseUrl: process.env.INSFORGE_BASE_URL!,\n * publicRoutes: ['/', '/about'],\n * afterSignInUrl: '/', // Redirect here after successful auth\n * useBuiltInAuth: true,\n * });\n *\n * export const config = {\n * matcher: ['/((?!_next|api|.*\\\\..*).*)'],\n * };\n * ```\n *\n * @example\n * ```ts\n * // middleware.ts - Custom local auth pages with custom paths\n * import { InsforgeMiddleware } from '@insforge/nextjs/middleware';\n *\n * export default InsforgeMiddleware({\n * baseUrl: process.env.INSFORGE_BASE_URL!,\n * publicRoutes: ['/login', '/register', '/', '/about'],\n * signInUrl: '/login',\n * signUpUrl: '/register',\n * afterSignInUrl: '/dashboard',\n * useBuiltInAuth: false,\n * });\n *\n * export const config = {\n * matcher: ['/((?!_next|api|.*\\\\..*).*)'],\n * };\n * ```\n *\n * @example\n * ```ts\n * // middleware.ts - Built-in auth with custom auth route paths\n * import { InsforgeMiddleware } from '@insforge/nextjs/middleware';\n *\n * export default InsforgeMiddleware({\n * baseUrl: 'https://your-backend.com',\n * signInUrl: '/login',\n * signUpUrl: '/register',\n * forgotPasswordUrl: '/forgot',\n * afterSignInUrl: '/dashboard',\n * useBuiltInAuth: true,\n * });\n * ```\n */\nexport const InsforgeMiddleware = (config: InsforgeMiddlewareConfig) => {\n const {\n baseUrl,\n publicRoutes = ['/'],\n signInUrl = '/sign-in',\n signUpUrl = '/sign-up',\n forgotPasswordUrl = '/forgot-password',\n afterSignInUrl = '/',\n useBuiltInAuth = true,\n } = config;\n\n return function middleware(request: NextRequest) {\n const { pathname, searchParams } = request.nextUrl;\n\n // STEP 1: Check if URL contains access_token (from backend redirect after auth)\n const accessToken = searchParams.get('access_token');\n const userId = searchParams.get('user_id');\n const email = searchParams.get('email');\n const name = searchParams.get('name');\n\n if (accessToken && userId && email) {\n // Token detected in URL - store it in HTTP-only cookies\n const response = NextResponse.next();\n const cookieOptions = getBaseCookieOptions();\n\n // Set session cookie (access token)\n response.cookies.set(COOKIE_NAMES.SESSION, accessToken, cookieOptions);\n\n // Set user identity cookie (basic user info for SSR)\n response.cookies.set(\n COOKIE_NAMES.USER,\n serializeUserCookie({ id: userId, email, name: name || undefined }),\n cookieOptions\n );\n\n return response;\n }\n\n // STEP 2: Handle built-in auth redirects for authentication pages\n // Map local auth routes to backend's fixed auth pages\n if (useBuiltInAuth) {\n const authRouteMapping: Record<string, string> = {\n [signInUrl]: '/auth/sign-in',\n [signUpUrl]: '/auth/sign-up',\n [forgotPasswordUrl]: '/auth/forgot-password',\n };\n\n const backendAuthPath = authRouteMapping[pathname];\n if (backendAuthPath) {\n // Redirect to afterSignInUrl after successful authentication\n const redirectUrl = new URL(afterSignInUrl, request.url).toString();\n const backendAuthUrl = new URL(backendAuthPath, baseUrl);\n backendAuthUrl.searchParams.set('redirect', redirectUrl);\n return NextResponse.redirect(backendAuthUrl.toString());\n }\n }\n\n // STEP 3: Check if route is public\n const isPublicRoute = publicRoutes.some((route) => {\n if (route.endsWith('*')) {\n // Wildcard route: /admin/* matches /admin/anything\n return pathname.startsWith(route.slice(0, -1));\n }\n // Exact match or starts with route path\n return pathname === route || pathname.startsWith(route + '/');\n });\n\n if (isPublicRoute) {\n return NextResponse.next();\n }\n\n // STEP 4: Check for authentication token in cookies\n const token = request.cookies.get(COOKIE_NAMES.SESSION)?.value;\n\n if (!token) {\n // No token found, redirect to sign-in\n if (useBuiltInAuth) {\n // Built-in auth: redirect to backend's /auth/sign-in page\n // Backend will redirect back to current URL with token\n const backendSignInUrl = new URL('/auth/sign-in', baseUrl);\n backendSignInUrl.searchParams.set('redirect', request.url);\n return NextResponse.redirect(backendSignInUrl);\n } else {\n // Custom auth: redirect to local sign-in page\n const localSignInUrl = new URL(signInUrl, request.url);\n localSignInUrl.searchParams.set('redirect', pathname);\n return NextResponse.redirect(localSignInUrl);\n }\n }\n\n // Token exists in cookie, allow request to continue\n return NextResponse.next();\n };\n};\n"],"mappings":"AAAA,SAAsB,oBAAoB;AAC1C,SAAS,cAAc,sBAAsB,2BAA2B;AAoIjE,MAAM,qBAAqB,CAAC,WAAqC;AACtE,QAAM;AAAA,IACJ;AAAA,IACA,eAAe,CAAC,GAAG;AAAA,IACnB,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,oBAAoB;AAAA,IACpB,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,EACnB,IAAI;AAEJ,SAAO,SAAS,WAAW,SAAsB;AAC/C,UAAM,EAAE,UAAU,aAAa,IAAI,QAAQ;AAG3C,UAAM,cAAc,aAAa,IAAI,cAAc;AACnD,UAAM,SAAS,aAAa,IAAI,SAAS;AACzC,UAAM,QAAQ,aAAa,IAAI,OAAO;AACtC,UAAM,OAAO,aAAa,IAAI,MAAM;AAEpC,QAAI,eAAe,UAAU,OAAO;AAElC,YAAM,WAAW,aAAa,KAAK;AACnC,YAAM,gBAAgB,qBAAqB;AAG3C,eAAS,QAAQ,IAAI,aAAa,SAAS,aAAa,aAAa;AAGrE,eAAS,QAAQ;AAAA,QACf,aAAa;AAAA,QACb,oBAAoB,EAAE,IAAI,QAAQ,OAAO,MAAM,QAAQ,OAAU,CAAC;AAAA,QAClE;AAAA,MACF;AAEA,aAAO;AAAA,IACT;AAIA,QAAI,gBAAgB;AAClB,YAAM,mBAA2C;AAAA,QAC/C,CAAC,SAAS,GAAG;AAAA,QACb,CAAC,SAAS,GAAG;AAAA,QACb,CAAC,iBAAiB,GAAG;AAAA,MACvB;AAEA,YAAM,kBAAkB,iBAAiB,QAAQ;AACjD,UAAI,iBAAiB;AAEnB,cAAM,cAAc,IAAI,IAAI,gBAAgB,QAAQ,GAAG,EAAE,SAAS;AAClE,cAAM,iBAAiB,IAAI,IAAI,iBAAiB,OAAO;AACvD,uBAAe,aAAa,IAAI,YAAY,WAAW;AACvD,eAAO,aAAa,SAAS,eAAe,SAAS,CAAC;AAAA,MACxD;AAAA,IACF;AAGA,UAAM,gBAAgB,aAAa,KAAK,CAAC,UAAU;AACjD,UAAI,MAAM,SAAS,GAAG,GAAG;AAEvB,eAAO,SAAS,WAAW,MAAM,MAAM,GAAG,EAAE,CAAC;AAAA,MAC/C;AAEA,aAAO,aAAa,SAAS,SAAS,WAAW,QAAQ,GAAG;AAAA,IAC9D,CAAC;AAED,QAAI,eAAe;AACjB,aAAO,aAAa,KAAK;AAAA,IAC3B;AAGA,UAAM,QAAQ,QAAQ,QAAQ,IAAI,aAAa,OAAO,GAAG;AAEzD,QAAI,CAAC,OAAO;AAEV,UAAI,gBAAgB;AAGlB,cAAM,mBAAmB,IAAI,IAAI,iBAAiB,OAAO;AACzD,yBAAiB,aAAa,IAAI,YAAY,QAAQ,GAAG;AACzD,eAAO,aAAa,SAAS,gBAAgB;AAAA,MAC/C,OAAO;AAEL,cAAM,iBAAiB,IAAI,IAAI,WAAW,QAAQ,GAAG;AACrD,uBAAe,aAAa,IAAI,YAAY,QAAQ;AACpD,eAAO,aAAa,SAAS,cAAc;AAAA,MAC7C;AAAA,IACF;AAGA,WAAO,aAAa,KAAK;AAAA,EAC3B;AACF;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/middleware/InsforgeMiddleware.ts"],"sourcesContent":["import { NextRequest, NextResponse } from 'next/server';\r\nimport { COOKIE_NAMES, getBaseCookieOptions, serializeUserCookie } from '../lib/cookies';\r\n\r\nexport interface InsforgeMiddlewareConfig {\r\n /**\r\n * Base URL of your Insforge backend\r\n * @example 'https://your-backend.com' or 'http://localhost:3001'\r\n */\r\n baseUrl: string;\r\n\r\n /**\r\n * Routes that are public and don't require authentication\r\n * @default ['/']\r\n * @example ['/sign-in', '/sign-up', '/', '/about']\r\n */\r\n publicRoutes?: string[];\r\n\r\n /**\r\n * Local route path for sign-in (can be customized to any path like '/login')\r\n * When using built-in auth, this will redirect to backend's `/auth/sign-in`\r\n * @default '/sign-in'\r\n */\r\n signInUrl?: string;\r\n\r\n /**\r\n * Local route path for sign-up (can be customized to any path like '/register')\r\n * When using built-in auth, this will redirect to backend's `/auth/sign-up`\r\n * @default '/sign-up'\r\n */\r\n signUpUrl?: string;\r\n\r\n /**\r\n * Local route path for forgot password\r\n * When using built-in auth, this will redirect to backend's `/auth/forgot-password`\r\n * @default '/forgot-password'\r\n */\r\n forgotPasswordUrl?: string;\r\n\r\n /**\r\n * URL to redirect to after successful authentication\r\n * When user completes sign-in/sign-up, they will be redirected to this URL with token in URL\r\n * @default '/'\r\n */\r\n afterSignInUrl?: string;\r\n\r\n /**\r\n * Whether to use built-in authentication pages hosted on the backend\r\n * - When true: redirects to backend's `/auth/sign-in` and `/auth/sign-up` pages\r\n * - When false: redirects to local sign-in/sign-up pages (you provide your own components)\r\n * @default true\r\n */\r\n useBuiltInAuth?: boolean;\r\n}\r\n\r\n/**\r\n * Creates Next.js middleware for protecting routes with Insforge authentication.\r\n *\r\n * This middleware provides lightweight route protection by:\r\n * - Detecting and storing auth tokens from URL parameters (after backend redirect)\r\n * - Checking for auth token presence in cookies\r\n * - Redirecting unauthenticated users to sign-in page\r\n * - Allowing public routes to be accessed without authentication\r\n * - Mapping local auth routes to backend's fixed paths when using built-in auth\r\n *\r\n * **How Authentication Flow Works:**\r\n * 1. User visits protected route → Middleware checks for token\r\n * 2. No token → Redirects to sign-in (backend or local)\r\n * 3. User accesses auth page (e.g., /sign-in) → Redirects to backend with afterSignInUrl as redirect target\r\n * 4. After sign-in → Backend redirects to `yourapp.com/afterSignInUrl?access_token=xxx&user_id=xxx...`\r\n * 5. Middleware detects `access_token` in URL → Stores in HTTP-only cookie → Cleans URL → Allows access\r\n * 6. SDK also detects token from URL → Stores in localStorage → Updates auth state\r\n *\r\n * **Important Notes:**\r\n * - This middleware only checks if a token exists, it doesn't validate it\r\n * - Tokens from URL are automatically extracted and stored in cookies\r\n * - When `useBuiltInAuth: true`, local routes map to backend's fixed auth paths\r\n * - You can customize local route paths (e.g., `/login`) while backend paths remain fixed\r\n * - After successful auth, users are redirected to `afterSignInUrl` (default: `/`), not back to the auth page\r\n *\r\n * @param config - Middleware configuration\r\n * @returns Next.js middleware function\r\n *\r\n * @example\r\n * ```ts\r\n * // middleware.ts - Using built-in auth\r\n * import { InsforgeMiddleware } from '@insforge/nextjs/middleware';\r\n *\r\n * export default InsforgeMiddleware({\r\n * baseUrl: process.env.INSFORGE_BASE_URL!,\r\n * publicRoutes: ['/', '/about'],\r\n * afterSignInUrl: '/', // Redirect here after successful auth\r\n * useBuiltInAuth: true,\r\n * });\r\n *\r\n * export const config = {\r\n * matcher: ['/((?!_next|api|.*\\\\..*).*)'],\r\n * };\r\n * ```\r\n *\r\n * @example\r\n * ```ts\r\n * // middleware.ts - Custom local auth pages with custom paths\r\n * import { InsforgeMiddleware } from '@insforge/nextjs/middleware';\r\n *\r\n * export default InsforgeMiddleware({\r\n * baseUrl: process.env.INSFORGE_BASE_URL!,\r\n * publicRoutes: ['/login', '/register', '/', '/about'],\r\n * signInUrl: '/login',\r\n * signUpUrl: '/register',\r\n * afterSignInUrl: '/dashboard',\r\n * useBuiltInAuth: false,\r\n * });\r\n *\r\n * export const config = {\r\n * matcher: ['/((?!_next|api|.*\\\\..*).*)'],\r\n * };\r\n * ```\r\n *\r\n * @example\r\n * ```ts\r\n * // middleware.ts - Built-in auth with custom auth route paths\r\n * import { InsforgeMiddleware } from '@insforge/nextjs/middleware';\r\n *\r\n * export default InsforgeMiddleware({\r\n * baseUrl: 'https://your-backend.com',\r\n * signInUrl: '/login',\r\n * signUpUrl: '/register',\r\n * forgotPasswordUrl: '/forgot',\r\n * afterSignInUrl: '/dashboard',\r\n * useBuiltInAuth: true,\r\n * });\r\n * ```\r\n */\r\nexport const InsforgeMiddleware = (config: InsforgeMiddlewareConfig) => {\r\n const {\r\n baseUrl,\r\n publicRoutes = ['/'],\r\n signInUrl = '/sign-in',\r\n signUpUrl = '/sign-up',\r\n forgotPasswordUrl = '/forgot-password',\r\n afterSignInUrl = '/',\r\n useBuiltInAuth = true,\r\n } = config;\r\n\r\n return function middleware(request: NextRequest) {\r\n const { pathname, searchParams } = request.nextUrl;\r\n\r\n // STEP 1: Check if URL contains access_token (from backend redirect after auth)\r\n const accessToken = searchParams.get('access_token');\r\n const userId = searchParams.get('user_id');\r\n const email = searchParams.get('email');\r\n const name = searchParams.get('name');\r\n\r\n if (accessToken && userId && email) {\r\n // Token detected in URL - store it in HTTP-only cookies\r\n const response = NextResponse.next();\r\n const cookieOptions = getBaseCookieOptions();\r\n\r\n // Set session cookie (access token)\r\n response.cookies.set(COOKIE_NAMES.SESSION, accessToken, cookieOptions);\r\n\r\n // Set user identity cookie (basic user info for SSR)\r\n response.cookies.set(\r\n COOKIE_NAMES.USER,\r\n serializeUserCookie({ id: userId, email, profile: { name: name || undefined } }),\r\n cookieOptions\r\n );\r\n\r\n return response;\r\n }\r\n\r\n // STEP 2: Handle built-in auth redirects for authentication pages\r\n // Map local auth routes to backend's fixed auth pages\r\n if (useBuiltInAuth) {\r\n const authRouteMapping: Record<string, string> = {\r\n [signInUrl]: '/auth/sign-in',\r\n [signUpUrl]: '/auth/sign-up',\r\n [forgotPasswordUrl]: '/auth/forgot-password',\r\n };\r\n\r\n const backendAuthPath = authRouteMapping[pathname];\r\n if (backendAuthPath) {\r\n // Redirect to afterSignInUrl after successful authentication\r\n const redirectUrl = new URL(afterSignInUrl, request.url).toString();\r\n const backendAuthUrl = new URL(backendAuthPath, baseUrl);\r\n backendAuthUrl.searchParams.set('redirect', redirectUrl);\r\n return NextResponse.redirect(backendAuthUrl.toString());\r\n }\r\n }\r\n\r\n // STEP 3: Check if route is public\r\n const isPublicRoute = publicRoutes.some((route) => {\r\n if (route.endsWith('*')) {\r\n // Wildcard route: /admin/* matches /admin/anything\r\n return pathname.startsWith(route.slice(0, -1));\r\n }\r\n // Exact match or starts with route path\r\n return pathname === route || pathname.startsWith(route + '/');\r\n });\r\n\r\n if (isPublicRoute) {\r\n return NextResponse.next();\r\n }\r\n\r\n // STEP 4: Check for authentication token in cookies\r\n const token = request.cookies.get(COOKIE_NAMES.SESSION)?.value;\r\n\r\n if (!token) {\r\n // No token found, redirect to sign-in\r\n if (useBuiltInAuth) {\r\n // Built-in auth: redirect to backend's /auth/sign-in page\r\n // Backend will redirect back to current URL with token\r\n const backendSignInUrl = new URL('/auth/sign-in', baseUrl);\r\n backendSignInUrl.searchParams.set('redirect', request.url);\r\n return NextResponse.redirect(backendSignInUrl);\r\n } else {\r\n // Custom auth: redirect to local sign-in page\r\n const localSignInUrl = new URL(signInUrl, request.url);\r\n localSignInUrl.searchParams.set('redirect', pathname);\r\n return NextResponse.redirect(localSignInUrl);\r\n }\r\n }\r\n\r\n // Token exists in cookie, allow request to continue\r\n return NextResponse.next();\r\n };\r\n};\r\n"],"mappings":"AAAA,SAAsB,oBAAoB;AAC1C,SAAS,cAAc,sBAAsB,2BAA2B;AAoIjE,MAAM,qBAAqB,CAAC,WAAqC;AACtE,QAAM;AAAA,IACJ;AAAA,IACA,eAAe,CAAC,GAAG;AAAA,IACnB,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,oBAAoB;AAAA,IACpB,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,EACnB,IAAI;AAEJ,SAAO,SAAS,WAAW,SAAsB;AAC/C,UAAM,EAAE,UAAU,aAAa,IAAI,QAAQ;AAG3C,UAAM,cAAc,aAAa,IAAI,cAAc;AACnD,UAAM,SAAS,aAAa,IAAI,SAAS;AACzC,UAAM,QAAQ,aAAa,IAAI,OAAO;AACtC,UAAM,OAAO,aAAa,IAAI,MAAM;AAEpC,QAAI,eAAe,UAAU,OAAO;AAElC,YAAM,WAAW,aAAa,KAAK;AACnC,YAAM,gBAAgB,qBAAqB;AAG3C,eAAS,QAAQ,IAAI,aAAa,SAAS,aAAa,aAAa;AAGrE,eAAS,QAAQ;AAAA,QACf,aAAa;AAAA,QACb,oBAAoB,EAAE,IAAI,QAAQ,OAAO,SAAS,EAAE,MAAM,QAAQ,OAAU,EAAE,CAAC;AAAA,QAC/E;AAAA,MACF;AAEA,aAAO;AAAA,IACT;AAIA,QAAI,gBAAgB;AAClB,YAAM,mBAA2C;AAAA,QAC/C,CAAC,SAAS,GAAG;AAAA,QACb,CAAC,SAAS,GAAG;AAAA,QACb,CAAC,iBAAiB,GAAG;AAAA,MACvB;AAEA,YAAM,kBAAkB,iBAAiB,QAAQ;AACjD,UAAI,iBAAiB;AAEnB,cAAM,cAAc,IAAI,IAAI,gBAAgB,QAAQ,GAAG,EAAE,SAAS;AAClE,cAAM,iBAAiB,IAAI,IAAI,iBAAiB,OAAO;AACvD,uBAAe,aAAa,IAAI,YAAY,WAAW;AACvD,eAAO,aAAa,SAAS,eAAe,SAAS,CAAC;AAAA,MACxD;AAAA,IACF;AAGA,UAAM,gBAAgB,aAAa,KAAK,CAAC,UAAU;AACjD,UAAI,MAAM,SAAS,GAAG,GAAG;AAEvB,eAAO,SAAS,WAAW,MAAM,MAAM,GAAG,EAAE,CAAC;AAAA,MAC/C;AAEA,aAAO,aAAa,SAAS,SAAS,WAAW,QAAQ,GAAG;AAAA,IAC9D,CAAC;AAED,QAAI,eAAe;AACjB,aAAO,aAAa,KAAK;AAAA,IAC3B;AAGA,UAAM,QAAQ,QAAQ,QAAQ,IAAI,aAAa,OAAO,GAAG;AAEzD,QAAI,CAAC,OAAO;AAEV,UAAI,gBAAgB;AAGlB,cAAM,mBAAmB,IAAI,IAAI,iBAAiB,OAAO;AACzD,yBAAiB,aAAa,IAAI,YAAY,QAAQ,GAAG;AACzD,eAAO,aAAa,SAAS,gBAAgB;AAAA,MAC/C,OAAO;AAEL,cAAM,iBAAiB,IAAI,IAAI,WAAW,QAAQ,GAAG;AACrD,uBAAe,aAAa,IAAI,YAAY,QAAQ;AACpD,eAAO,aAAa,SAAS,cAAc;AAAA,MAC7C;AAAA,IACF;AAGA,WAAO,aAAa,KAAK;AAAA,EAC3B;AACF;","names":[]}
|
|
@@ -1,32 +1,23 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
2
|
import { ClientInsforgeProvider } from "../client/provider";
|
|
3
3
|
import { cookies } from "next/headers";
|
|
4
|
+
import { COOKIE_NAMES, parseUserCookie } from "../lib/cookies";
|
|
4
5
|
async function getAuthFromCookies() {
|
|
5
6
|
try {
|
|
6
7
|
const cookieStore = await cookies();
|
|
7
|
-
const
|
|
8
|
-
if (!
|
|
9
|
-
return {
|
|
10
|
-
user: null,
|
|
11
|
-
userId: null
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
const userCookie = cookieStore.get("insforge-user")?.value;
|
|
15
|
-
if (!userCookie) {
|
|
8
|
+
const token = cookieStore.get(COOKIE_NAMES.SESSION)?.value || null;
|
|
9
|
+
if (!token) {
|
|
16
10
|
return {
|
|
17
11
|
user: null,
|
|
18
12
|
userId: null
|
|
19
13
|
};
|
|
20
14
|
}
|
|
15
|
+
const userCookie = cookieStore.get(COOKIE_NAMES.USER)?.value;
|
|
21
16
|
try {
|
|
22
|
-
const user =
|
|
17
|
+
const user = parseUserCookie(userCookie);
|
|
23
18
|
return {
|
|
24
|
-
user
|
|
25
|
-
|
|
26
|
-
email: user.email,
|
|
27
|
-
name: user.name || ""
|
|
28
|
-
},
|
|
29
|
-
userId: user.id
|
|
19
|
+
user,
|
|
20
|
+
userId: user?.id || null
|
|
30
21
|
};
|
|
31
22
|
} catch {
|
|
32
23
|
return {
|
|
@@ -42,53 +33,6 @@ async function getAuthFromCookies() {
|
|
|
42
33
|
};
|
|
43
34
|
}
|
|
44
35
|
}
|
|
45
|
-
function getAuthFromRequest(request) {
|
|
46
|
-
try {
|
|
47
|
-
const cookieHeader = request.headers.get("cookie") || "";
|
|
48
|
-
const cookies2 = Object.fromEntries(
|
|
49
|
-
cookieHeader.split("; ").map((c) => {
|
|
50
|
-
const [key, ...v] = c.split("=");
|
|
51
|
-
return [key, v.join("=")];
|
|
52
|
-
})
|
|
53
|
-
);
|
|
54
|
-
const sessionToken = cookies2["insforge-session"];
|
|
55
|
-
if (!sessionToken) {
|
|
56
|
-
return {
|
|
57
|
-
user: null,
|
|
58
|
-
userId: null
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
const userCookie = cookies2["insforge-user"];
|
|
62
|
-
if (!userCookie) {
|
|
63
|
-
return {
|
|
64
|
-
user: null,
|
|
65
|
-
userId: null
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
try {
|
|
69
|
-
const user = JSON.parse(decodeURIComponent(userCookie));
|
|
70
|
-
return {
|
|
71
|
-
user: {
|
|
72
|
-
id: user.id,
|
|
73
|
-
email: user.email,
|
|
74
|
-
name: user.name || ""
|
|
75
|
-
},
|
|
76
|
-
userId: user.id
|
|
77
|
-
};
|
|
78
|
-
} catch {
|
|
79
|
-
return {
|
|
80
|
-
user: null,
|
|
81
|
-
userId: null
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
} catch (error) {
|
|
85
|
-
console.error("[Insforge] Error reading cookies from request:", error);
|
|
86
|
-
return {
|
|
87
|
-
user: null,
|
|
88
|
-
userId: null
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
36
|
async function InsforgeProvider(props) {
|
|
93
37
|
const { children, dynamic = true, ...restProps } = props;
|
|
94
38
|
const initialAuth = dynamic ? await getAuthFromCookies() : { user: null, userId: null };
|
|
@@ -96,7 +40,6 @@ async function InsforgeProvider(props) {
|
|
|
96
40
|
}
|
|
97
41
|
export {
|
|
98
42
|
InsforgeProvider,
|
|
99
|
-
getAuthFromCookies
|
|
100
|
-
getAuthFromRequest
|
|
43
|
+
getAuthFromCookies
|
|
101
44
|
};
|
|
102
45
|
//# sourceMappingURL=InsforgeProvider.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/server/InsforgeProvider.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport { ClientInsforgeProvider } from '../client/provider';\nimport type { InsforgeProviderProps } from '@insforge/react';\nimport { cookies } from 'next/headers';\nimport
|
|
1
|
+
{"version":3,"sources":["../../../src/server/InsforgeProvider.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport { ClientInsforgeProvider } from '../client/provider';\nimport type { InsforgeProviderProps, InitialAuthState } from '@insforge/react';\nimport { cookies } from 'next/headers';\nimport { COOKIE_NAMES, parseUserCookie } from '../lib/cookies';\n\nexport interface InsforgeProviderServerProps extends Omit<InsforgeProviderProps, 'initialState'> {\n children: ReactNode;\n /**\n * Opt into dynamic rendering to read auth state from cookies during SSR.\n *\n * - When true: Reads cookies on server, prevents content flashing, opts into dynamic rendering\n * - When false: Static rendering, may see brief content flash during hydration\n *\n * Following Clerk's pattern: dynamic prop controls server-side auth state access\n *\n * @default false\n *\n * @example\n * ```tsx\n * <InsforgeProvider baseUrl={...} dynamic>\n * {children}\n * </InsforgeProvider>\n * ```\n */\n dynamic?: boolean;\n}\n\n/**\n * Get initial auth state from cookies (server-side)\n *\n * This helper reads the authentication state from cookies set by the SDK.\n * Use this in Server Components or Server Actions to get the initial auth state\n * and pass it to the InsforgeProvider via initialState prop.\n *\n * This prevents hydration mismatches by ensuring SSR and client render have the same state.\n *\n * @example\n * ```tsx\n * // app/layout.tsx (Server Component)\n * import { InsforgeProvider } from '@insforge/nextjs';\n * import { getAuthFromCookies } from '@insforge/nextjs/api/auth-helpers';\n *\n * export default async function RootLayout({ children }) {\n * const initialAuth = await getAuthFromCookies();\n *\n * return (\n * <html>\n * <body>\n * <InsforgeProvider\n * baseUrl={process.env.NEXT_PUBLIC_INSFORGE_BASE_URL!}\n * initialState={initialAuth}\n * >\n * {children}\n * </InsforgeProvider>\n * </body>\n * </html>\n * );\n * }\n * ```\n *\n * @returns Initial auth state with user and userId, or empty object if not authenticated\n */\nexport async function getAuthFromCookies(): Promise<InitialAuthState> {\n try {\n const cookieStore = await cookies();\n\n // Read session token from cookie (set by middleware or /api/auth route)\n const token = cookieStore.get(COOKIE_NAMES.SESSION)?.value || null;\n\n if (!token) {\n // Not authenticated - return null to indicate signed out\n return {\n user: null,\n userId: null,\n };\n }\n\n // Read user identity from cookie (set by middleware or /api/auth route)\n const userCookie = cookieStore.get(COOKIE_NAMES.USER)?.value;\n\n try {\n const user = parseUserCookie(userCookie);\n\n // Return basic user info from cookie\n // This is lightweight data for SSR hydration only\n // Full profile will be loaded by SDK's getCurrentUser() after hydration\n return {\n user,\n userId: user?.id || null,\n };\n } catch {\n // Invalid user data in cookie\n return {\n user: null,\n userId: null,\n };\n }\n } catch (error) {\n // Error reading cookies (might be in middleware or edge runtime)\n console.error('[Insforge] Error reading cookies:', error);\n return {\n user: null,\n userId: null,\n };\n }\n}\n\n/**\n * Server Component Provider for Insforge\n *\n * This is a Server Component (no 'use client') that:\n * 1. Optionally reads auth state from cookies on the server (when dynamic=true)\n * 2. Passes initialState to the Client Provider\n * 3. Ensures SSR and client hydration match perfectly\n *\n * Following Clerk's pattern: packages/nextjs/src/app-router/server/ClerkProvider.tsx\n *\n * @example\n * ```tsx\n * // app/layout.tsx (Server Component)\n * import { InsforgeProvider } from '@insforge/nextjs';\n *\n * export default async function RootLayout({ children }) {\n * return (\n * <html>\n * <body>\n * <InsforgeProvider\n * baseUrl={process.env.NEXT_PUBLIC_INSFORGE_BASE_URL!}\n * dynamic // 👈 Enable dynamic rendering for SSR auth\n * >\n * {children}\n * </InsforgeProvider>\n * </body>\n * </html>\n * );\n * }\n * ```\n */\nexport async function InsforgeProvider(props: InsforgeProviderServerProps) {\n const { children, dynamic = true, ...restProps } = props;\n\n // Only read cookies if dynamic=true (opts into dynamic rendering)\n // When dynamic=false, Next.js can statically generate the page\n const initialAuth = dynamic ? await getAuthFromCookies() : { user: null, userId: null };\n\n // Pass initialState to Client Provider\n return (\n <ClientInsforgeProvider {...restProps} initialState={initialAuth}>\n {children}\n </ClientInsforgeProvider>\n );\n}\n"],"mappings":"AAoJI;AAnJJ,SAAS,8BAA8B;AAEvC,SAAS,eAAe;AACxB,SAAS,cAAc,uBAAuB;AA2D9C,eAAsB,qBAAgD;AACpE,MAAI;AACF,UAAM,cAAc,MAAM,QAAQ;AAGlC,UAAM,QAAQ,YAAY,IAAI,aAAa,OAAO,GAAG,SAAS;AAE9D,QAAI,CAAC,OAAO;AAEV,aAAO;AAAA,QACL,MAAM;AAAA,QACN,QAAQ;AAAA,MACV;AAAA,IACF;AAGA,UAAM,aAAa,YAAY,IAAI,aAAa,IAAI,GAAG;AAEvD,QAAI;AACF,YAAM,OAAO,gBAAgB,UAAU;AAKvC,aAAO;AAAA,QACL;AAAA,QACA,QAAQ,MAAM,MAAM;AAAA,MACtB;AAAA,IACF,QAAQ;AAEN,aAAO;AAAA,QACL,MAAM;AAAA,QACN,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AAEd,YAAQ,MAAM,qCAAqC,KAAK;AACxD,WAAO;AAAA,MACL,MAAM;AAAA,MACN,QAAQ;AAAA,IACV;AAAA,EACF;AACF;AAiCA,eAAsB,iBAAiB,OAAoC;AACzE,QAAM,EAAE,UAAU,UAAU,MAAM,GAAG,UAAU,IAAI;AAInD,QAAM,cAAc,UAAU,MAAM,mBAAmB,IAAI,EAAE,MAAM,MAAM,QAAQ,KAAK;AAGtF,SACE,oBAAC,0BAAwB,GAAG,WAAW,cAAc,aAClD,UACH;AAEJ;","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/server/auth.ts"],"sourcesContent":["import { cookies } from 'next/headers';\nimport { COOKIE_NAMES, parseUserCookie
|
|
1
|
+
{"version":3,"sources":["../../../src/server/auth.ts"],"sourcesContent":["import { cookies } from 'next/headers';\r\nimport type { InsforgeUser } from '@insforge/shared';\r\nimport { COOKIE_NAMES, parseUserCookie } from '../lib/cookies';\r\n\r\n/**\r\n * Session information extracted from cookies\r\n */\r\nexport interface InsforgeAuth {\r\n /**\r\n * The current user's ID, or null if not authenticated\r\n */\r\n userId: string | null;\r\n\r\n /**\r\n * The current session token, or null if not authenticated\r\n */\r\n token: string | null;\r\n\r\n /**\r\n * User information (email, name) if available\r\n */\r\n user: InsforgeUser | null;\r\n}\r\n\r\n/**\r\n * Get authentication information from cookies in Server Components,\r\n * Route Handlers, and Server Actions.\r\n *\r\n * This function reads the HTTP-only cookies set by the middleware\r\n * and returns user authentication data.\r\n *\r\n * @example\r\n * ```ts\r\n * // In a Server Component\r\n * import { auth } from '@insforge/nextjs/server';\r\n *\r\n * export default async function Page() {\r\n * const { userId, token } = await auth();\r\n *\r\n * if (!userId) {\r\n * return <div>Not authenticated</div>;\r\n * }\r\n *\r\n * return <div>User ID: {userId}</div>;\r\n * }\r\n * ```\r\n *\r\n * @example\r\n * ```ts\r\n * // In an API Route Handler\r\n * import { auth } from '@insforge/nextjs/server';\r\n * import { createClient } from '@insforge/sdk';\r\n *\r\n * export async function GET() {\r\n * const { userId, token } = await auth();\r\n *\r\n * if (!userId || !token) {\r\n * return Response.json({ error: 'Unauthorized' }, { status: 401 });\r\n * }\r\n *\r\n * // Use token with SDK\r\n * const insforge = createClient({\r\n * baseUrl: process.env.INSFORGE_BASE_URL!,\r\n * edgeFunctionToken: token,\r\n * });\r\n *\r\n * const result = await insforge.database.from('posts').select();\r\n * return Response.json(result.data);\r\n * }\r\n * ```\r\n *\r\n * @example\r\n * ```ts\r\n * // In a Server Action\r\n * 'use server';\r\n *\r\n * import { auth } from '@insforge/nextjs/server';\r\n *\r\n * export async function createPost(formData: FormData) {\r\n * const { userId } = await auth();\r\n *\r\n * if (!userId) {\r\n * throw new Error('Not authenticated');\r\n * }\r\n *\r\n * // Create post with userId\r\n * }\r\n * ```\r\n */\r\nexport async function auth(): Promise<InsforgeAuth> {\r\n const cookieStore = await cookies();\r\n\r\n // Get session token\r\n const token = cookieStore.get(COOKIE_NAMES.SESSION)?.value || null;\r\n\r\n // Get user info using centralized parsing\r\n const userCookie = cookieStore.get(COOKIE_NAMES.USER)?.value;\r\n const user = parseUserCookie(userCookie);\r\n const userId = user?.id || null;\r\n\r\n return {\r\n userId,\r\n token,\r\n user,\r\n };\r\n}\r\n"],"mappings":"AAAA,SAAS,eAAe;AAExB,SAAS,cAAc,uBAAuB;AAuF9C,eAAsB,OAA8B;AAClD,QAAM,cAAc,MAAM,QAAQ;AAGlC,QAAM,QAAQ,YAAY,IAAI,aAAa,OAAO,GAAG,SAAS;AAG9D,QAAM,aAAa,YAAY,IAAI,aAAa,IAAI,GAAG;AACvD,QAAM,OAAO,gBAAgB,UAAU;AACvC,QAAM,SAAS,MAAM,MAAM;AAE3B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","names":[]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
export { AuthConfig, EmailVerificationMethod, InsforgeUser, OAuthProvider, OAuthProviderConfig } from '@insforge/react/types';
|
|
2
1
|
export { InsforgeProvider } from './server/InsforgeProvider.js';
|
|
3
2
|
export { useInsforge } from './client/provider.js';
|
|
4
3
|
export { AuthBranding, AuthContainer, AuthContainerProps, AuthDivider, AuthDividerProps, AuthEmailVerificationStep, AuthErrorBanner, AuthErrorBannerProps, AuthFormField, AuthFormFieldProps, AuthHeader, AuthHeaderProps, AuthLink, AuthLinkProps, AuthOAuthButton, AuthOAuthButtonProps, AuthOAuthProviders, AuthOAuthProvidersProps, AuthPasswordField, AuthPasswordFieldProps, AuthPasswordStrengthIndicator, AuthPasswordStrengthIndicatorProps, AuthResetPasswordVerificationStep, AuthSubmitButton, AuthSubmitButtonProps, AuthVerificationCodeInput, AuthVerificationCodeInputProps, ConditionalProps, ForgotPassword, ForgotPasswordForm, ForgotPasswordFormProps, ForgotPasswordProps, Protect, ProtectProps, ResetPassword, ResetPasswordForm, ResetPasswordFormProps, ResetPasswordProps, SignIn, SignInButton, SignInForm, SignInFormProps, SignInProps, SignUp, SignUpButton, SignUpForm, SignUpFormProps, SignUpProps, SignedIn, SignedOut, UserButton, UserButtonProps, VerifyEmail, VerifyEmailProps, VerifyEmailStatus, VerifyEmailStatusProps } from '@insforge/react/components';
|
package/dist/lib/cookies.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ResponseCookie } from 'next/dist/compiled/@edge-runtime/cookies';
|
|
2
|
+
import { InsforgeUser } from '@insforge/shared';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Cookie names used by Insforge authentication
|
|
@@ -21,14 +22,6 @@ declare const COOKIE_DEFAULTS: {
|
|
|
21
22
|
/** SameSite policy */
|
|
22
23
|
readonly SAME_SITE: "lax";
|
|
23
24
|
};
|
|
24
|
-
/**
|
|
25
|
-
* User information stored in the user cookie
|
|
26
|
-
*/
|
|
27
|
-
interface CookieUserInfo {
|
|
28
|
-
id: string;
|
|
29
|
-
email: string;
|
|
30
|
-
name: string;
|
|
31
|
-
}
|
|
32
25
|
/**
|
|
33
26
|
* Options for cookie operations
|
|
34
27
|
*/
|
|
@@ -61,16 +54,12 @@ declare function getClearCookieOptions(options?: Pick<CookieOptions, 'secure'>):
|
|
|
61
54
|
* @param user - User information to serialize
|
|
62
55
|
* @returns JSON string of user info
|
|
63
56
|
*/
|
|
64
|
-
declare function serializeUserCookie(user:
|
|
65
|
-
id: string;
|
|
66
|
-
email: string;
|
|
67
|
-
name?: string;
|
|
68
|
-
}): string;
|
|
57
|
+
declare function serializeUserCookie(user: InsforgeUser): string;
|
|
69
58
|
/**
|
|
70
59
|
* Parse user info from cookie value
|
|
71
60
|
* @param cookieValue - Raw cookie value
|
|
72
61
|
* @returns Parsed user info or null if invalid
|
|
73
62
|
*/
|
|
74
|
-
declare function parseUserCookie(cookieValue: string | undefined):
|
|
63
|
+
declare function parseUserCookie(cookieValue: string | undefined): InsforgeUser | null;
|
|
75
64
|
|
|
76
|
-
export { COOKIE_DEFAULTS, COOKIE_NAMES, type CookieOptions,
|
|
65
|
+
export { COOKIE_DEFAULTS, COOKIE_NAMES, type CookieOptions, getBaseCookieOptions, getClearCookieOptions, isSecureCookie, parseUserCookie, serializeUserCookie };
|
|
@@ -59,13 +59,6 @@ interface InsforgeProviderServerProps extends Omit<InsforgeProviderProps, 'initi
|
|
|
59
59
|
* @returns Initial auth state with user and userId, or empty object if not authenticated
|
|
60
60
|
*/
|
|
61
61
|
declare function getAuthFromCookies(): Promise<InitialAuthState>;
|
|
62
|
-
/**
|
|
63
|
-
* Synchronous version for use in middleware or edge runtime
|
|
64
|
-
*
|
|
65
|
-
* @param request - Next.js request object
|
|
66
|
-
* @returns Initial auth state
|
|
67
|
-
*/
|
|
68
|
-
declare function getAuthFromRequest(request: Request): InitialAuthState;
|
|
69
62
|
/**
|
|
70
63
|
* Server Component Provider for Insforge
|
|
71
64
|
*
|
|
@@ -99,4 +92,4 @@ declare function getAuthFromRequest(request: Request): InitialAuthState;
|
|
|
99
92
|
*/
|
|
100
93
|
declare function InsforgeProvider(props: InsforgeProviderServerProps): Promise<react_jsx_runtime.JSX.Element>;
|
|
101
94
|
|
|
102
|
-
export { InsforgeProvider, type InsforgeProviderServerProps, getAuthFromCookies
|
|
95
|
+
export { InsforgeProvider, type InsforgeProviderServerProps, getAuthFromCookies };
|
package/dist/server/auth.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import 'next/dist/compiled/@edge-runtime/cookies';
|
|
1
|
+
import { InsforgeUser } from '@insforge/shared';
|
|
3
2
|
|
|
4
3
|
/**
|
|
5
4
|
* Session information extracted from cookies
|
|
@@ -16,7 +15,7 @@ interface InsforgeAuth {
|
|
|
16
15
|
/**
|
|
17
16
|
* User information (email, name) if available
|
|
18
17
|
*/
|
|
19
|
-
user:
|
|
18
|
+
user: InsforgeUser | null;
|
|
20
19
|
}
|
|
21
20
|
/**
|
|
22
21
|
* Get authentication information from cookies in Server Components,
|
package/dist/server/index.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,75 +1,75 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@insforge/nextjs",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "Pre-built authentication UI components for Next.js with Insforge backend - zero configuration required",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"types": "./dist/index.d.ts",
|
|
7
|
-
"exports": {
|
|
8
|
-
".": {
|
|
9
|
-
"types": "./dist/index.d.ts",
|
|
10
|
-
"import": "./dist/esm/index.js"
|
|
11
|
-
},
|
|
12
|
-
"./server": {
|
|
13
|
-
"types": "./dist/server/index.d.ts",
|
|
14
|
-
"import": "./dist/esm/server/index.js"
|
|
15
|
-
},
|
|
16
|
-
"./middleware": {
|
|
17
|
-
"types": "./dist/middleware/index.d.ts",
|
|
18
|
-
"import": "./dist/esm/middleware/index.js"
|
|
19
|
-
},
|
|
20
|
-
"./api": {
|
|
21
|
-
"types": "./dist/api/index.d.ts",
|
|
22
|
-
"import": "./dist/esm/api/index.js"
|
|
23
|
-
},
|
|
24
|
-
"./styles.css": "./src/styles.css"
|
|
25
|
-
},
|
|
26
|
-
"files": [
|
|
27
|
-
"dist",
|
|
28
|
-
"src/styles.css",
|
|
29
|
-
"README.md"
|
|
30
|
-
],
|
|
31
|
-
"scripts": {
|
|
32
|
-
"build": "tsup",
|
|
33
|
-
"dev": "tsup --watch",
|
|
34
|
-
"type-check": "tsc --noEmit"
|
|
35
|
-
},
|
|
36
|
-
"keywords": [
|
|
37
|
-
"insforge",
|
|
38
|
-
"nextjs",
|
|
39
|
-
"authentication",
|
|
40
|
-
"auth",
|
|
41
|
-
"ui",
|
|
42
|
-
"components",
|
|
43
|
-
"react"
|
|
44
|
-
],
|
|
45
|
-
"author": "Insforge",
|
|
46
|
-
"license": "MIT",
|
|
47
|
-
"dependencies": {
|
|
48
|
-
"@insforge/react": "^1.0.
|
|
49
|
-
"@insforge/sdk": "1.0.4",
|
|
50
|
-
"@insforge/shared": "^1.0.
|
|
51
|
-
"@insforge/shared-schemas": "^1.1.35"
|
|
52
|
-
},
|
|
53
|
-
"devDependencies": {
|
|
54
|
-
"@eslint/js": "^9.21.0",
|
|
55
|
-
"@types/node": "^24.9.2",
|
|
56
|
-
"@types/react": "^19.2.2",
|
|
57
|
-
"@types/react-dom": "^19.2.2",
|
|
58
|
-
"eslint": "^9.21.0",
|
|
59
|
-
"eslint-config-prettier": "^10.0.2",
|
|
60
|
-
"eslint-plugin-prettier": "^5.2.1",
|
|
61
|
-
"eslint-plugin-react": "^7.37.5",
|
|
62
|
-
"eslint-plugin-react-hooks": "^5.1.2",
|
|
63
|
-
"globals": "^15.12.0",
|
|
64
|
-
"prettier": "^3.4.2",
|
|
65
|
-
"rimraf": "^6.1.0",
|
|
66
|
-
"tsup": "^8.5.0",
|
|
67
|
-
"typescript": "^5.9.3",
|
|
68
|
-
"typescript-eslint": "^8.23.0"
|
|
69
|
-
},
|
|
70
|
-
"peerDependencies": {
|
|
71
|
-
"next": ">=14.0.0 <17.0.0",
|
|
72
|
-
"react": ">=18.0.0 <20.0.0",
|
|
73
|
-
"react-dom": ">=18.0.0 <20.0.0"
|
|
74
|
-
}
|
|
75
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@insforge/nextjs",
|
|
3
|
+
"version": "1.0.5-dev.0",
|
|
4
|
+
"description": "Pre-built authentication UI components for Next.js with Insforge backend - zero configuration required",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"import": "./dist/esm/index.js"
|
|
11
|
+
},
|
|
12
|
+
"./server": {
|
|
13
|
+
"types": "./dist/server/index.d.ts",
|
|
14
|
+
"import": "./dist/esm/server/index.js"
|
|
15
|
+
},
|
|
16
|
+
"./middleware": {
|
|
17
|
+
"types": "./dist/middleware/index.d.ts",
|
|
18
|
+
"import": "./dist/esm/middleware/index.js"
|
|
19
|
+
},
|
|
20
|
+
"./api": {
|
|
21
|
+
"types": "./dist/api/index.d.ts",
|
|
22
|
+
"import": "./dist/esm/api/index.js"
|
|
23
|
+
},
|
|
24
|
+
"./styles.css": "./src/styles.css"
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"dist",
|
|
28
|
+
"src/styles.css",
|
|
29
|
+
"README.md"
|
|
30
|
+
],
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "tsup",
|
|
33
|
+
"dev": "tsup --watch",
|
|
34
|
+
"type-check": "tsc --noEmit"
|
|
35
|
+
},
|
|
36
|
+
"keywords": [
|
|
37
|
+
"insforge",
|
|
38
|
+
"nextjs",
|
|
39
|
+
"authentication",
|
|
40
|
+
"auth",
|
|
41
|
+
"ui",
|
|
42
|
+
"components",
|
|
43
|
+
"react"
|
|
44
|
+
],
|
|
45
|
+
"author": "Insforge",
|
|
46
|
+
"license": "MIT",
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"@insforge/react": "^1.0.5-dev.1",
|
|
49
|
+
"@insforge/sdk": "^1.0.4",
|
|
50
|
+
"@insforge/shared": "^1.0.12-dev.4",
|
|
51
|
+
"@insforge/shared-schemas": "^1.1.35"
|
|
52
|
+
},
|
|
53
|
+
"devDependencies": {
|
|
54
|
+
"@eslint/js": "^9.21.0",
|
|
55
|
+
"@types/node": "^24.9.2",
|
|
56
|
+
"@types/react": "^19.2.2",
|
|
57
|
+
"@types/react-dom": "^19.2.2",
|
|
58
|
+
"eslint": "^9.21.0",
|
|
59
|
+
"eslint-config-prettier": "^10.0.2",
|
|
60
|
+
"eslint-plugin-prettier": "^5.2.1",
|
|
61
|
+
"eslint-plugin-react": "^7.37.5",
|
|
62
|
+
"eslint-plugin-react-hooks": "^5.1.2",
|
|
63
|
+
"globals": "^15.12.0",
|
|
64
|
+
"prettier": "^3.4.2",
|
|
65
|
+
"rimraf": "^6.1.0",
|
|
66
|
+
"tsup": "^8.5.0",
|
|
67
|
+
"typescript": "^5.9.3",
|
|
68
|
+
"typescript-eslint": "^8.23.0"
|
|
69
|
+
},
|
|
70
|
+
"peerDependencies": {
|
|
71
|
+
"next": ">=14.0.0 <17.0.0",
|
|
72
|
+
"react": ">=18.0.0 <20.0.0",
|
|
73
|
+
"react-dom": ">=18.0.0 <20.0.0"
|
|
74
|
+
}
|
|
75
|
+
}
|