@insforge/nextjs 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +759 -0
- package/dist/Manrope-VariableFont_wght-OKHRIJEM.ttf +0 -0
- package/dist/api.d.mts +39 -0
- package/dist/api.d.ts +39 -0
- package/dist/api.js +267 -0
- package/dist/api.js.map +1 -0
- package/dist/api.mjs +240 -0
- package/dist/api.mjs.map +1 -0
- package/dist/index.css +468 -0
- package/dist/index.css.map +1 -0
- package/dist/index.d.mts +146 -0
- package/dist/index.d.ts +146 -0
- package/dist/index.js +1086 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1037 -0
- package/dist/index.mjs.map +1 -0
- package/dist/middleware.d.mts +14 -0
- package/dist/middleware.d.ts +14 -0
- package/dist/middleware.js +99 -0
- package/dist/middleware.js.map +1 -0
- package/dist/middleware.mjs +70 -0
- package/dist/middleware.mjs.map +1 -0
- package/package.json +65 -0
- package/src/fonts/Manrope-VariableFont_wght.ttf +0 -0
- package/src/styles.css +551 -0
|
Binary file
|
package/dist/api.d.mts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
2
|
+
|
|
3
|
+
interface AuthRouteConfig {
|
|
4
|
+
baseUrl: string;
|
|
5
|
+
cookieName?: string;
|
|
6
|
+
cookieMaxAge?: number;
|
|
7
|
+
secure?: boolean;
|
|
8
|
+
}
|
|
9
|
+
declare function createAuthRouteHandlers(config: AuthRouteConfig): {
|
|
10
|
+
POST: (request: NextRequest) => Promise<NextResponse<{
|
|
11
|
+
error: string;
|
|
12
|
+
}> | NextResponse<{
|
|
13
|
+
user: any;
|
|
14
|
+
session: {
|
|
15
|
+
userId: any;
|
|
16
|
+
expiresAt: string;
|
|
17
|
+
createdAt: string;
|
|
18
|
+
};
|
|
19
|
+
}>>;
|
|
20
|
+
GET: (request: NextRequest) => Promise<NextResponse<{
|
|
21
|
+
user: null;
|
|
22
|
+
session: null;
|
|
23
|
+
}> | NextResponse<{
|
|
24
|
+
user: any;
|
|
25
|
+
session: {
|
|
26
|
+
userId: any;
|
|
27
|
+
token: string;
|
|
28
|
+
expiresAt: string;
|
|
29
|
+
createdAt: string;
|
|
30
|
+
};
|
|
31
|
+
}>>;
|
|
32
|
+
DELETE: (request: NextRequest) => Promise<NextResponse<{
|
|
33
|
+
success: boolean;
|
|
34
|
+
}> | NextResponse<{
|
|
35
|
+
error: string;
|
|
36
|
+
}>>;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export { type AuthRouteConfig, createAuthRouteHandlers };
|
package/dist/api.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
2
|
+
|
|
3
|
+
interface AuthRouteConfig {
|
|
4
|
+
baseUrl: string;
|
|
5
|
+
cookieName?: string;
|
|
6
|
+
cookieMaxAge?: number;
|
|
7
|
+
secure?: boolean;
|
|
8
|
+
}
|
|
9
|
+
declare function createAuthRouteHandlers(config: AuthRouteConfig): {
|
|
10
|
+
POST: (request: NextRequest) => Promise<NextResponse<{
|
|
11
|
+
error: string;
|
|
12
|
+
}> | NextResponse<{
|
|
13
|
+
user: any;
|
|
14
|
+
session: {
|
|
15
|
+
userId: any;
|
|
16
|
+
expiresAt: string;
|
|
17
|
+
createdAt: string;
|
|
18
|
+
};
|
|
19
|
+
}>>;
|
|
20
|
+
GET: (request: NextRequest) => Promise<NextResponse<{
|
|
21
|
+
user: null;
|
|
22
|
+
session: null;
|
|
23
|
+
}> | NextResponse<{
|
|
24
|
+
user: any;
|
|
25
|
+
session: {
|
|
26
|
+
userId: any;
|
|
27
|
+
token: string;
|
|
28
|
+
expiresAt: string;
|
|
29
|
+
createdAt: string;
|
|
30
|
+
};
|
|
31
|
+
}>>;
|
|
32
|
+
DELETE: (request: NextRequest) => Promise<NextResponse<{
|
|
33
|
+
success: boolean;
|
|
34
|
+
}> | NextResponse<{
|
|
35
|
+
error: string;
|
|
36
|
+
}>>;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export { type AuthRouteConfig, createAuthRouteHandlers };
|
package/dist/api.js
ADDED
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/api/index.ts
|
|
21
|
+
var api_exports = {};
|
|
22
|
+
__export(api_exports, {
|
|
23
|
+
createAuthRouteHandlers: () => createAuthRouteHandlers
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(api_exports);
|
|
26
|
+
|
|
27
|
+
// src/api/route-handlers.ts
|
|
28
|
+
var import_server = require("next/server");
|
|
29
|
+
var import_sdk = require("@insforge/sdk");
|
|
30
|
+
function createAuthRouteHandlers(config) {
|
|
31
|
+
const {
|
|
32
|
+
baseUrl,
|
|
33
|
+
cookieName = "insforge_token",
|
|
34
|
+
cookieMaxAge = 7 * 24 * 60 * 60
|
|
35
|
+
// 7 days
|
|
36
|
+
} = config;
|
|
37
|
+
const insforge = (0, import_sdk.createClient)({ baseUrl });
|
|
38
|
+
function setAuthCookie(response, token) {
|
|
39
|
+
const isProduction = process.env.NODE_ENV === "production";
|
|
40
|
+
const secure = config.secure ?? isProduction;
|
|
41
|
+
response.cookies.set({
|
|
42
|
+
name: cookieName,
|
|
43
|
+
value: token,
|
|
44
|
+
httpOnly: true,
|
|
45
|
+
// Cannot be accessed by JavaScript
|
|
46
|
+
secure,
|
|
47
|
+
// Only sent over HTTPS in production
|
|
48
|
+
sameSite: "lax",
|
|
49
|
+
maxAge: cookieMaxAge,
|
|
50
|
+
path: "/"
|
|
51
|
+
});
|
|
52
|
+
return response;
|
|
53
|
+
}
|
|
54
|
+
function clearAuthCookie(response) {
|
|
55
|
+
response.cookies.set({
|
|
56
|
+
name: cookieName,
|
|
57
|
+
value: "",
|
|
58
|
+
httpOnly: true,
|
|
59
|
+
secure: config.secure ?? process.env.NODE_ENV === "production",
|
|
60
|
+
sameSite: "lax",
|
|
61
|
+
maxAge: 0,
|
|
62
|
+
path: "/"
|
|
63
|
+
});
|
|
64
|
+
return response;
|
|
65
|
+
}
|
|
66
|
+
async function POST(request) {
|
|
67
|
+
try {
|
|
68
|
+
const body = await request.json();
|
|
69
|
+
const { action, email, password } = body;
|
|
70
|
+
if (!action) {
|
|
71
|
+
return import_server.NextResponse.json(
|
|
72
|
+
{ error: "Action is required" },
|
|
73
|
+
{ status: 400 }
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
switch (action) {
|
|
77
|
+
case "sign-in": {
|
|
78
|
+
if (!email || !password) {
|
|
79
|
+
return import_server.NextResponse.json(
|
|
80
|
+
{ error: "Email and password are required" },
|
|
81
|
+
{ status: 400 }
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
const result = await insforge.auth.signInWithPassword({
|
|
85
|
+
email,
|
|
86
|
+
password
|
|
87
|
+
});
|
|
88
|
+
if (result.error) {
|
|
89
|
+
return import_server.NextResponse.json(
|
|
90
|
+
{ error: result.error.message },
|
|
91
|
+
{ status: 401 }
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
if (!result.data) {
|
|
95
|
+
return import_server.NextResponse.json(
|
|
96
|
+
{ error: "Authentication failed" },
|
|
97
|
+
{ status: 401 }
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
const response = import_server.NextResponse.json({
|
|
101
|
+
user: result.data.user,
|
|
102
|
+
session: {
|
|
103
|
+
userId: result.data.user.id,
|
|
104
|
+
expiresAt: "",
|
|
105
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
setAuthCookie(response, result.data.accessToken);
|
|
109
|
+
return response;
|
|
110
|
+
}
|
|
111
|
+
case "sign-up": {
|
|
112
|
+
if (!email || !password) {
|
|
113
|
+
return import_server.NextResponse.json(
|
|
114
|
+
{ error: "Email and password are required" },
|
|
115
|
+
{ status: 400 }
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
const result = await insforge.auth.signUp({ email, password });
|
|
119
|
+
if (result.error) {
|
|
120
|
+
return import_server.NextResponse.json(
|
|
121
|
+
{ error: result.error.message },
|
|
122
|
+
{ status: 400 }
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
if (!result.data) {
|
|
126
|
+
return import_server.NextResponse.json(
|
|
127
|
+
{ error: "Sign up failed" },
|
|
128
|
+
{ status: 400 }
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
const response = import_server.NextResponse.json({
|
|
132
|
+
user: result.data.user,
|
|
133
|
+
session: {
|
|
134
|
+
userId: result.data.user.id,
|
|
135
|
+
expiresAt: "",
|
|
136
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
setAuthCookie(response, result.data.accessToken);
|
|
140
|
+
return response;
|
|
141
|
+
}
|
|
142
|
+
case "sync-token": {
|
|
143
|
+
const { token } = body;
|
|
144
|
+
if (!token) {
|
|
145
|
+
return import_server.NextResponse.json(
|
|
146
|
+
{ error: "Token is required" },
|
|
147
|
+
{ status: 400 }
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
try {
|
|
151
|
+
const response = await fetch(`${baseUrl}/api/auth/sessions/current`, {
|
|
152
|
+
headers: {
|
|
153
|
+
Authorization: `Bearer ${token}`,
|
|
154
|
+
"Content-Type": "application/json"
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
if (!response.ok) {
|
|
158
|
+
const errorText = await response.text();
|
|
159
|
+
console.error("[Auth API] Token validation failed:", errorText);
|
|
160
|
+
return import_server.NextResponse.json(
|
|
161
|
+
{ error: "Invalid token", details: errorText },
|
|
162
|
+
{ status: 401 }
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
const session = await response.json();
|
|
166
|
+
const nextResponse = import_server.NextResponse.json({
|
|
167
|
+
user: session.user,
|
|
168
|
+
session: {
|
|
169
|
+
userId: session.user.id,
|
|
170
|
+
expiresAt: "",
|
|
171
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
setAuthCookie(nextResponse, token);
|
|
175
|
+
return nextResponse;
|
|
176
|
+
} catch (error) {
|
|
177
|
+
console.error("[Auth API] Token validation error:", error);
|
|
178
|
+
return import_server.NextResponse.json(
|
|
179
|
+
{ error: "Token validation failed", details: String(error) },
|
|
180
|
+
{ status: 401 }
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
default:
|
|
185
|
+
return import_server.NextResponse.json(
|
|
186
|
+
{ error: "Invalid action" },
|
|
187
|
+
{ status: 400 }
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
} catch (error) {
|
|
191
|
+
console.error("[Auth API Error]:", error);
|
|
192
|
+
return import_server.NextResponse.json(
|
|
193
|
+
{ error: "Internal server error" },
|
|
194
|
+
{ status: 500 }
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
async function GET(request) {
|
|
199
|
+
try {
|
|
200
|
+
const token = request.cookies.get(cookieName)?.value;
|
|
201
|
+
if (!token) {
|
|
202
|
+
return import_server.NextResponse.json({ user: null, session: null });
|
|
203
|
+
}
|
|
204
|
+
const response = await fetch(`${baseUrl}/auth/sessions/current`, {
|
|
205
|
+
headers: {
|
|
206
|
+
Authorization: `Bearer ${token}`,
|
|
207
|
+
"Content-Type": "application/json"
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
if (!response.ok) {
|
|
211
|
+
const nextResponse = import_server.NextResponse.json({ user: null, session: null });
|
|
212
|
+
clearAuthCookie(nextResponse);
|
|
213
|
+
return nextResponse;
|
|
214
|
+
}
|
|
215
|
+
const session = await response.json();
|
|
216
|
+
return import_server.NextResponse.json({
|
|
217
|
+
user: session.user,
|
|
218
|
+
session: {
|
|
219
|
+
userId: session.user.id,
|
|
220
|
+
token,
|
|
221
|
+
expiresAt: "",
|
|
222
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
} catch (error) {
|
|
226
|
+
console.error("[Auth API Error]:", error);
|
|
227
|
+
return import_server.NextResponse.json({ user: null, session: null });
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
async function DELETE(request) {
|
|
231
|
+
try {
|
|
232
|
+
const token = request.cookies.get(cookieName)?.value;
|
|
233
|
+
if (token) {
|
|
234
|
+
try {
|
|
235
|
+
await fetch(`${baseUrl}/auth/sessions/current`, {
|
|
236
|
+
method: "DELETE",
|
|
237
|
+
headers: {
|
|
238
|
+
Authorization: `Bearer ${token}`,
|
|
239
|
+
"Content-Type": "application/json"
|
|
240
|
+
}
|
|
241
|
+
});
|
|
242
|
+
} catch (error) {
|
|
243
|
+
console.error("[Auth API] Sign out error:", error);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
const response = import_server.NextResponse.json({ success: true });
|
|
247
|
+
clearAuthCookie(response);
|
|
248
|
+
return response;
|
|
249
|
+
} catch (error) {
|
|
250
|
+
console.error("[Auth API Error]:", error);
|
|
251
|
+
return import_server.NextResponse.json(
|
|
252
|
+
{ error: "Internal server error" },
|
|
253
|
+
{ status: 500 }
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
return {
|
|
258
|
+
POST,
|
|
259
|
+
GET,
|
|
260
|
+
DELETE
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
264
|
+
0 && (module.exports = {
|
|
265
|
+
createAuthRouteHandlers
|
|
266
|
+
});
|
|
267
|
+
//# sourceMappingURL=api.js.map
|
package/dist/api.js.map
ADDED
|
@@ -0,0 +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}/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":[]}
|
package/dist/api.mjs
ADDED
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
// src/api/route-handlers.ts
|
|
2
|
+
import { NextResponse } from "next/server";
|
|
3
|
+
import { createClient } from "@insforge/sdk";
|
|
4
|
+
function createAuthRouteHandlers(config) {
|
|
5
|
+
const {
|
|
6
|
+
baseUrl,
|
|
7
|
+
cookieName = "insforge_token",
|
|
8
|
+
cookieMaxAge = 7 * 24 * 60 * 60
|
|
9
|
+
// 7 days
|
|
10
|
+
} = config;
|
|
11
|
+
const insforge = createClient({ baseUrl });
|
|
12
|
+
function setAuthCookie(response, token) {
|
|
13
|
+
const isProduction = process.env.NODE_ENV === "production";
|
|
14
|
+
const secure = config.secure ?? isProduction;
|
|
15
|
+
response.cookies.set({
|
|
16
|
+
name: cookieName,
|
|
17
|
+
value: token,
|
|
18
|
+
httpOnly: true,
|
|
19
|
+
// Cannot be accessed by JavaScript
|
|
20
|
+
secure,
|
|
21
|
+
// Only sent over HTTPS in production
|
|
22
|
+
sameSite: "lax",
|
|
23
|
+
maxAge: cookieMaxAge,
|
|
24
|
+
path: "/"
|
|
25
|
+
});
|
|
26
|
+
return response;
|
|
27
|
+
}
|
|
28
|
+
function clearAuthCookie(response) {
|
|
29
|
+
response.cookies.set({
|
|
30
|
+
name: cookieName,
|
|
31
|
+
value: "",
|
|
32
|
+
httpOnly: true,
|
|
33
|
+
secure: config.secure ?? process.env.NODE_ENV === "production",
|
|
34
|
+
sameSite: "lax",
|
|
35
|
+
maxAge: 0,
|
|
36
|
+
path: "/"
|
|
37
|
+
});
|
|
38
|
+
return response;
|
|
39
|
+
}
|
|
40
|
+
async function POST(request) {
|
|
41
|
+
try {
|
|
42
|
+
const body = await request.json();
|
|
43
|
+
const { action, email, password } = body;
|
|
44
|
+
if (!action) {
|
|
45
|
+
return NextResponse.json(
|
|
46
|
+
{ error: "Action is required" },
|
|
47
|
+
{ status: 400 }
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
switch (action) {
|
|
51
|
+
case "sign-in": {
|
|
52
|
+
if (!email || !password) {
|
|
53
|
+
return NextResponse.json(
|
|
54
|
+
{ error: "Email and password are required" },
|
|
55
|
+
{ status: 400 }
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
const result = await insforge.auth.signInWithPassword({
|
|
59
|
+
email,
|
|
60
|
+
password
|
|
61
|
+
});
|
|
62
|
+
if (result.error) {
|
|
63
|
+
return NextResponse.json(
|
|
64
|
+
{ error: result.error.message },
|
|
65
|
+
{ status: 401 }
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
if (!result.data) {
|
|
69
|
+
return NextResponse.json(
|
|
70
|
+
{ error: "Authentication failed" },
|
|
71
|
+
{ status: 401 }
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
const response = NextResponse.json({
|
|
75
|
+
user: result.data.user,
|
|
76
|
+
session: {
|
|
77
|
+
userId: result.data.user.id,
|
|
78
|
+
expiresAt: "",
|
|
79
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
setAuthCookie(response, result.data.accessToken);
|
|
83
|
+
return response;
|
|
84
|
+
}
|
|
85
|
+
case "sign-up": {
|
|
86
|
+
if (!email || !password) {
|
|
87
|
+
return NextResponse.json(
|
|
88
|
+
{ error: "Email and password are required" },
|
|
89
|
+
{ status: 400 }
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
const result = await insforge.auth.signUp({ email, password });
|
|
93
|
+
if (result.error) {
|
|
94
|
+
return NextResponse.json(
|
|
95
|
+
{ error: result.error.message },
|
|
96
|
+
{ status: 400 }
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
if (!result.data) {
|
|
100
|
+
return NextResponse.json(
|
|
101
|
+
{ error: "Sign up failed" },
|
|
102
|
+
{ status: 400 }
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
const response = NextResponse.json({
|
|
106
|
+
user: result.data.user,
|
|
107
|
+
session: {
|
|
108
|
+
userId: result.data.user.id,
|
|
109
|
+
expiresAt: "",
|
|
110
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
setAuthCookie(response, result.data.accessToken);
|
|
114
|
+
return response;
|
|
115
|
+
}
|
|
116
|
+
case "sync-token": {
|
|
117
|
+
const { token } = body;
|
|
118
|
+
if (!token) {
|
|
119
|
+
return NextResponse.json(
|
|
120
|
+
{ error: "Token is required" },
|
|
121
|
+
{ status: 400 }
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
try {
|
|
125
|
+
const response = await fetch(`${baseUrl}/api/auth/sessions/current`, {
|
|
126
|
+
headers: {
|
|
127
|
+
Authorization: `Bearer ${token}`,
|
|
128
|
+
"Content-Type": "application/json"
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
if (!response.ok) {
|
|
132
|
+
const errorText = await response.text();
|
|
133
|
+
console.error("[Auth API] Token validation failed:", errorText);
|
|
134
|
+
return NextResponse.json(
|
|
135
|
+
{ error: "Invalid token", details: errorText },
|
|
136
|
+
{ status: 401 }
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
const session = await response.json();
|
|
140
|
+
const nextResponse = NextResponse.json({
|
|
141
|
+
user: session.user,
|
|
142
|
+
session: {
|
|
143
|
+
userId: session.user.id,
|
|
144
|
+
expiresAt: "",
|
|
145
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
setAuthCookie(nextResponse, token);
|
|
149
|
+
return nextResponse;
|
|
150
|
+
} catch (error) {
|
|
151
|
+
console.error("[Auth API] Token validation error:", error);
|
|
152
|
+
return NextResponse.json(
|
|
153
|
+
{ error: "Token validation failed", details: String(error) },
|
|
154
|
+
{ status: 401 }
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
default:
|
|
159
|
+
return NextResponse.json(
|
|
160
|
+
{ error: "Invalid action" },
|
|
161
|
+
{ status: 400 }
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
} catch (error) {
|
|
165
|
+
console.error("[Auth API Error]:", error);
|
|
166
|
+
return NextResponse.json(
|
|
167
|
+
{ error: "Internal server error" },
|
|
168
|
+
{ status: 500 }
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
async function GET(request) {
|
|
173
|
+
try {
|
|
174
|
+
const token = request.cookies.get(cookieName)?.value;
|
|
175
|
+
if (!token) {
|
|
176
|
+
return NextResponse.json({ user: null, session: null });
|
|
177
|
+
}
|
|
178
|
+
const response = await fetch(`${baseUrl}/auth/sessions/current`, {
|
|
179
|
+
headers: {
|
|
180
|
+
Authorization: `Bearer ${token}`,
|
|
181
|
+
"Content-Type": "application/json"
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
if (!response.ok) {
|
|
185
|
+
const nextResponse = NextResponse.json({ user: null, session: null });
|
|
186
|
+
clearAuthCookie(nextResponse);
|
|
187
|
+
return nextResponse;
|
|
188
|
+
}
|
|
189
|
+
const session = await response.json();
|
|
190
|
+
return NextResponse.json({
|
|
191
|
+
user: session.user,
|
|
192
|
+
session: {
|
|
193
|
+
userId: session.user.id,
|
|
194
|
+
token,
|
|
195
|
+
expiresAt: "",
|
|
196
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
} catch (error) {
|
|
200
|
+
console.error("[Auth API Error]:", error);
|
|
201
|
+
return NextResponse.json({ user: null, session: null });
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
async function DELETE(request) {
|
|
205
|
+
try {
|
|
206
|
+
const token = request.cookies.get(cookieName)?.value;
|
|
207
|
+
if (token) {
|
|
208
|
+
try {
|
|
209
|
+
await fetch(`${baseUrl}/auth/sessions/current`, {
|
|
210
|
+
method: "DELETE",
|
|
211
|
+
headers: {
|
|
212
|
+
Authorization: `Bearer ${token}`,
|
|
213
|
+
"Content-Type": "application/json"
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
} catch (error) {
|
|
217
|
+
console.error("[Auth API] Sign out error:", error);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
const response = NextResponse.json({ success: true });
|
|
221
|
+
clearAuthCookie(response);
|
|
222
|
+
return response;
|
|
223
|
+
} catch (error) {
|
|
224
|
+
console.error("[Auth API Error]:", error);
|
|
225
|
+
return NextResponse.json(
|
|
226
|
+
{ error: "Internal server error" },
|
|
227
|
+
{ status: 500 }
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return {
|
|
232
|
+
POST,
|
|
233
|
+
GET,
|
|
234
|
+
DELETE
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
export {
|
|
238
|
+
createAuthRouteHandlers
|
|
239
|
+
};
|
|
240
|
+
//# sourceMappingURL=api.mjs.map
|
package/dist/api.mjs.map
ADDED
|
@@ -0,0 +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}/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":[]}
|