@inai-dev/nextjs 1.3.0 → 1.5.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 +5 -0
- package/dist/middleware.cjs +47 -11
- package/dist/middleware.cjs.map +1 -1
- package/dist/middleware.d.cts +2 -0
- package/dist/middleware.d.ts +2 -0
- package/dist/middleware.js +49 -12
- package/dist/middleware.js.map +1 -1
- package/dist/server.cjs +8 -0
- package/dist/server.cjs.map +1 -1
- package/dist/server.js +8 -0
- package/dist/server.js.map +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -26,11 +26,14 @@ import { inaiAuthMiddleware } from "@inai-dev/nextjs/middleware";
|
|
|
26
26
|
export default inaiAuthMiddleware({
|
|
27
27
|
publicRoutes: ["/", "/about", "/login"],
|
|
28
28
|
signInUrl: "/login",
|
|
29
|
+
// jwksUrl: "https://apiauth.inai.dev/.well-known/jwks.json", // optional override
|
|
29
30
|
});
|
|
30
31
|
|
|
31
32
|
export const config = { matcher: ["/((?!_next|static|favicon.ico).*)"] };
|
|
32
33
|
```
|
|
33
34
|
|
|
35
|
+
> All tokens are cryptographically verified using ES256 (ECDSA P-256). Public keys are fetched from the JWKS endpoint and cached for 5 minutes.
|
|
36
|
+
|
|
34
37
|
### 2. Provider
|
|
35
38
|
|
|
36
39
|
```tsx
|
|
@@ -107,6 +110,8 @@ export default async function Dashboard() {
|
|
|
107
110
|
| `orgId` | `string \| null` | Active organization ID |
|
|
108
111
|
| `orgRole` | `string \| null` | Role in active organization |
|
|
109
112
|
| `sessionId` | `string \| null` | Session ID |
|
|
113
|
+
| `roles` | `string[]` | User's global roles |
|
|
114
|
+
| `permissions` | `string[]` | User's global permissions |
|
|
110
115
|
| `getToken()` | `() => Promise<string \| null>` | Get the access token |
|
|
111
116
|
| `has(params)` | `({ role?, permission? }) => boolean` | Check role or permission |
|
|
112
117
|
| `protect(params?)` | `({ role?, permission?, redirectTo? }) => ProtectedAuthObject` | Assert auth or redirect |
|
package/dist/middleware.cjs
CHANGED
|
@@ -27,6 +27,17 @@ __export(middleware_exports, {
|
|
|
27
27
|
module.exports = __toCommonJS(middleware_exports);
|
|
28
28
|
var import_server = require("next/server");
|
|
29
29
|
var import_shared = require("@inai-dev/shared");
|
|
30
|
+
var import_shared2 = require("@inai-dev/shared");
|
|
31
|
+
var sharedJwksClient = null;
|
|
32
|
+
var sharedJwksUrl = null;
|
|
33
|
+
function getJwksClient(config) {
|
|
34
|
+
const jwksUrl = config.jwksUrl ?? `${config.apiUrl ?? import_shared.DEFAULT_API_URL}/.well-known/jwks.json`;
|
|
35
|
+
if (!sharedJwksClient || sharedJwksUrl !== jwksUrl) {
|
|
36
|
+
sharedJwksClient = new import_shared.JWKSClient(jwksUrl);
|
|
37
|
+
sharedJwksUrl = jwksUrl;
|
|
38
|
+
}
|
|
39
|
+
return sharedJwksClient;
|
|
40
|
+
}
|
|
30
41
|
function createRouteMatcher(patterns) {
|
|
31
42
|
const matchers = patterns.map((pattern) => {
|
|
32
43
|
if (pattern instanceof RegExp) return pattern;
|
|
@@ -55,7 +66,26 @@ function isPublicRoute(req, publicRoutes, builtinPublic) {
|
|
|
55
66
|
if (typeof publicRoutes === "function") return publicRoutes(req);
|
|
56
67
|
return matchesRoute(pathname, publicRoutes);
|
|
57
68
|
}
|
|
58
|
-
function buildAuthObject(token,
|
|
69
|
+
async function buildAuthObject(token, jwksClient) {
|
|
70
|
+
const header = (0, import_shared.decodeJWTHeader)(token);
|
|
71
|
+
if (!header?.kid) return null;
|
|
72
|
+
let publicKey;
|
|
73
|
+
try {
|
|
74
|
+
publicKey = await jwksClient.getKey(header.kid);
|
|
75
|
+
} catch {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
let claims = await (0, import_shared.verifyES256)(token, publicKey);
|
|
79
|
+
if (!claims) {
|
|
80
|
+
jwksClient.invalidate();
|
|
81
|
+
try {
|
|
82
|
+
publicKey = await jwksClient.getKey(header.kid);
|
|
83
|
+
} catch {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
claims = await (0, import_shared.verifyES256)(token, publicKey);
|
|
87
|
+
if (!claims) return null;
|
|
88
|
+
}
|
|
59
89
|
const roles = claims.roles ?? [];
|
|
60
90
|
const permissions = claims.permissions ?? [];
|
|
61
91
|
return {
|
|
@@ -66,6 +96,8 @@ function buildAuthObject(token, claims) {
|
|
|
66
96
|
orgId: claims.org_id ?? null,
|
|
67
97
|
orgRole: claims.org_role ?? null,
|
|
68
98
|
sessionId: null,
|
|
99
|
+
roles,
|
|
100
|
+
permissions,
|
|
69
101
|
getToken: async () => token,
|
|
70
102
|
has: (params) => {
|
|
71
103
|
if (params.role && roles.includes(params.role)) return true;
|
|
@@ -75,10 +107,10 @@ function buildAuthObject(token, claims) {
|
|
|
75
107
|
}
|
|
76
108
|
};
|
|
77
109
|
}
|
|
78
|
-
async function runAuthCheck(req, signInUrl, apiUrl) {
|
|
110
|
+
async function runAuthCheck(req, signInUrl, jwksClient, apiUrl) {
|
|
79
111
|
const { pathname } = req.nextUrl;
|
|
80
112
|
const token = req.cookies.get(import_shared.COOKIE_AUTH_TOKEN)?.value;
|
|
81
|
-
if (!token || (0,
|
|
113
|
+
if (!token || (0, import_shared2.isTokenExpired)(token)) {
|
|
82
114
|
const refreshToken = req.cookies.get(import_shared.COOKIE_REFRESH_TOKEN)?.value;
|
|
83
115
|
if (refreshToken) {
|
|
84
116
|
try {
|
|
@@ -160,14 +192,14 @@ async function runAuthCheck(req, signInUrl, apiUrl) {
|
|
|
160
192
|
response.cookies.set(import_shared.COOKIE_AUTH_SESSION, "", { path: "/", maxAge: 0 });
|
|
161
193
|
return { authObj: null, response };
|
|
162
194
|
}
|
|
163
|
-
const
|
|
164
|
-
if (!
|
|
195
|
+
const authObj = await buildAuthObject(token, jwksClient);
|
|
196
|
+
if (!authObj) {
|
|
165
197
|
return {
|
|
166
198
|
authObj: null,
|
|
167
199
|
response: import_server.NextResponse.redirect(new URL(signInUrl, req.url))
|
|
168
200
|
};
|
|
169
201
|
}
|
|
170
|
-
return { authObj
|
|
202
|
+
return { authObj };
|
|
171
203
|
}
|
|
172
204
|
function inaiAuthMiddleware(config = {}) {
|
|
173
205
|
const {
|
|
@@ -178,6 +210,7 @@ function inaiAuthMiddleware(config = {}) {
|
|
|
178
210
|
afterAuth
|
|
179
211
|
} = config;
|
|
180
212
|
const builtinPublic = ["/_next/*", "/favicon.ico", "/api/*", signInUrl];
|
|
213
|
+
const jwksClient = getJwksClient(config);
|
|
181
214
|
return async function middleware(req) {
|
|
182
215
|
if (beforeAuth) {
|
|
183
216
|
const result = beforeAuth(req);
|
|
@@ -186,8 +219,8 @@ function inaiAuthMiddleware(config = {}) {
|
|
|
186
219
|
if (isPublicRoute(req, publicRoutes, builtinPublic)) {
|
|
187
220
|
return import_server.NextResponse.next();
|
|
188
221
|
}
|
|
189
|
-
const apiUrl = authMode === "platform" ? import_shared.DEFAULT_API_URL : void 0;
|
|
190
|
-
const { authObj, response } = await runAuthCheck(req, signInUrl, apiUrl);
|
|
222
|
+
const apiUrl = authMode === "platform" ? config.apiUrl ?? import_shared.DEFAULT_API_URL : void 0;
|
|
223
|
+
const { authObj, response } = await runAuthCheck(req, signInUrl, jwksClient, apiUrl);
|
|
191
224
|
if (response) return response;
|
|
192
225
|
if (!authObj)
|
|
193
226
|
return import_server.NextResponse.redirect(new URL(signInUrl, req.url));
|
|
@@ -207,6 +240,7 @@ function withInAIAuth(wrappedMiddleware, config = {}) {
|
|
|
207
240
|
afterAuth
|
|
208
241
|
} = config;
|
|
209
242
|
const builtinPublic = ["/_next/*", "/favicon.ico", "/api/*", signInUrl];
|
|
243
|
+
const jwksClient = getJwksClient(config);
|
|
210
244
|
return async function middleware(req) {
|
|
211
245
|
if (beforeAuth) {
|
|
212
246
|
const result = beforeAuth(req);
|
|
@@ -214,8 +248,8 @@ function withInAIAuth(wrappedMiddleware, config = {}) {
|
|
|
214
248
|
}
|
|
215
249
|
const isPublic = isPublicRoute(req, publicRoutes, builtinPublic);
|
|
216
250
|
if (!isPublic) {
|
|
217
|
-
const apiUrl = authMode === "platform" ? import_shared.DEFAULT_API_URL : void 0;
|
|
218
|
-
const { authObj, response } = await runAuthCheck(req, signInUrl, apiUrl);
|
|
251
|
+
const apiUrl = authMode === "platform" ? config.apiUrl ?? import_shared.DEFAULT_API_URL : void 0;
|
|
252
|
+
const { authObj, response } = await runAuthCheck(req, signInUrl, jwksClient, apiUrl);
|
|
219
253
|
if (response) return response;
|
|
220
254
|
if (!authObj)
|
|
221
255
|
return import_server.NextResponse.redirect(new URL(signInUrl, req.url));
|
|
@@ -229,7 +263,9 @@ function withInAIAuth(wrappedMiddleware, config = {}) {
|
|
|
229
263
|
appId: authObj.appId,
|
|
230
264
|
envId: authObj.envId,
|
|
231
265
|
orgId: authObj.orgId,
|
|
232
|
-
orgRole: authObj.orgRole
|
|
266
|
+
orgRole: authObj.orgRole,
|
|
267
|
+
roles: authObj.roles,
|
|
268
|
+
permissions: authObj.permissions
|
|
233
269
|
});
|
|
234
270
|
req.headers.set("x-inai-auth", authHeader);
|
|
235
271
|
}
|
package/dist/middleware.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/middleware.ts"],"sourcesContent":["import { NextResponse } from \"next/server\";\nimport type { NextRequest } from \"next/server\";\nimport type { AuthObject } from \"@inai-dev/types\";\nimport {\n COOKIE_AUTH_TOKEN,\n COOKIE_AUTH_SESSION,\n COOKIE_REFRESH_TOKEN,\n DEFAULT_API_URL,\n getClaimsFromToken,\n isTokenExpired,\n} from \"@inai-dev/shared\";\n\nexport interface InAIMiddlewareConfig {\n authMode?: \"app\" | \"platform\";\n publicRoutes?: string[] | ((req: NextRequest) => boolean);\n signInUrl?: string;\n beforeAuth?: (req: NextRequest) => NextResponse | void;\n afterAuth?: (auth: AuthObject, req: NextRequest) => NextResponse | void;\n}\n\nexport function createRouteMatcher(\n patterns: (string | RegExp)[],\n): (req: NextRequest) => boolean {\n const matchers = patterns.map((pattern) => {\n if (pattern instanceof RegExp) return pattern;\n let regexStr = pattern;\n if (regexStr.endsWith(\"*\") && !regexStr.includes(\"(\")) {\n regexStr = regexStr.slice(0, -1) + \".*\";\n }\n return new RegExp(`^${regexStr}$`);\n });\n\n return (req: NextRequest) => {\n const pathname = req.nextUrl.pathname;\n return matchers.some((m) => m.test(pathname));\n };\n}\n\nfunction matchesRoute(pathname: string, patterns: string[]): boolean {\n return patterns.some((pattern) => {\n if (pattern.endsWith(\"*\")) {\n return pathname.startsWith(pattern.slice(0, -1));\n }\n return pathname === pattern;\n });\n}\n\nfunction isPublicRoute(\n req: NextRequest,\n publicRoutes: string[] | ((req: NextRequest) => boolean),\n builtinPublic: string[],\n): boolean {\n const pathname = req.nextUrl.pathname;\n if (matchesRoute(pathname, builtinPublic)) return true;\n if (typeof publicRoutes === \"function\") return publicRoutes(req);\n return matchesRoute(pathname, publicRoutes);\n}\n\nfunction buildAuthObject(\n token: string,\n claims: NonNullable<ReturnType<typeof getClaimsFromToken>>,\n): AuthObject {\n const roles = claims.roles ?? [];\n const permissions = claims.permissions ?? [];\n return {\n userId: claims.sub,\n tenantId: claims.tenant_id,\n appId: claims.app_id ?? null,\n envId: claims.env_id ?? null,\n orgId: claims.org_id ?? null,\n orgRole: claims.org_role ?? null,\n sessionId: null,\n getToken: async () => token,\n has: (params: { role?: string; permission?: string }) => {\n if (params.role && roles.includes(params.role)) return true;\n if (params.permission && permissions.includes(params.permission))\n return true;\n return false;\n },\n };\n}\n\nasync function runAuthCheck(\n req: NextRequest,\n signInUrl: string,\n apiUrl?: string,\n): Promise<{ authObj: AuthObject | null; response?: NextResponse }> {\n const { pathname } = req.nextUrl;\n const token = req.cookies.get(COOKIE_AUTH_TOKEN)?.value;\n\n if (!token || isTokenExpired(token)) {\n const refreshToken = req.cookies.get(COOKIE_REFRESH_TOKEN)?.value;\n if (refreshToken) {\n try {\n if (apiUrl) {\n const refreshRes = await fetch(`${apiUrl}/api/platform/auth/refresh`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ refresh_token: refreshToken }),\n });\n if (refreshRes.ok) {\n const newTokens = await refreshRes.json() as {\n access_token: string;\n refresh_token: string;\n expires_in: number;\n };\n const meRes = await fetch(`${apiUrl}/api/platform/auth/me`, {\n headers: { Authorization: `Bearer ${newTokens.access_token}` },\n });\n if (meRes.ok) {\n const meData = await meRes.json();\n const newUser = meData.data ?? meData;\n const isProduction = process.env.NODE_ENV === \"production\";\n const response = NextResponse.next();\n response.cookies.set(COOKIE_AUTH_TOKEN, newTokens.access_token, {\n httpOnly: true, secure: isProduction, sameSite: \"lax\",\n path: \"/\", maxAge: newTokens.expires_in,\n });\n response.cookies.set(COOKIE_REFRESH_TOKEN, newTokens.refresh_token, {\n httpOnly: true, secure: isProduction, sameSite: \"strict\",\n path: \"/api/auth\", maxAge: 7 * 24 * 60 * 60,\n });\n response.cookies.set(COOKIE_AUTH_SESSION, JSON.stringify({\n user: newUser,\n expiresAt: new Date(Date.now() + newTokens.expires_in * 1000).toISOString(),\n }), {\n httpOnly: false, secure: isProduction, sameSite: \"lax\",\n path: \"/\", maxAge: newTokens.expires_in,\n });\n return { authObj: null, response };\n }\n }\n } else {\n const refreshUrl = new URL(\"/api/auth/refresh\", req.url);\n const refreshRes = await fetch(refreshUrl.toString(), {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Cookie: req.headers.get(\"cookie\") ?? \"\",\n },\n });\n if (refreshRes.ok) {\n const response = NextResponse.next();\n const setCookies = refreshRes.headers.getSetCookie?.() ?? [];\n for (const cookie of setCookies) {\n response.headers.append(\"Set-Cookie\", cookie);\n }\n return { authObj: null, response };\n }\n }\n } catch {\n // Refresh failed, fall through to redirect\n }\n }\n\n const response = NextResponse.redirect(\n new URL(\n `${signInUrl}?returnTo=${encodeURIComponent(pathname)}`,\n req.url,\n ),\n );\n response.cookies.set(COOKIE_AUTH_TOKEN, \"\", { path: \"/\", maxAge: 0 });\n response.cookies.set(COOKIE_REFRESH_TOKEN, \"\", {\n path: \"/api/auth\",\n maxAge: 0,\n });\n response.cookies.set(COOKIE_AUTH_SESSION, \"\", { path: \"/\", maxAge: 0 });\n return { authObj: null, response };\n }\n\n const claims = getClaimsFromToken(token);\n if (!claims) {\n return {\n authObj: null,\n response: NextResponse.redirect(new URL(signInUrl, req.url)),\n };\n }\n\n return { authObj: buildAuthObject(token, claims) };\n}\n\nexport function inaiAuthMiddleware(config: InAIMiddlewareConfig = {}) {\n const {\n authMode = \"app\",\n publicRoutes = [],\n signInUrl = \"/login\",\n beforeAuth,\n afterAuth,\n } = config;\n\n const builtinPublic = [\"/_next/*\", \"/favicon.ico\", \"/api/*\", signInUrl];\n\n return async function middleware(\n req: NextRequest,\n ): Promise<NextResponse> {\n if (beforeAuth) {\n const result = beforeAuth(req);\n if (result) return result;\n }\n\n if (isPublicRoute(req, publicRoutes, builtinPublic)) {\n return NextResponse.next();\n }\n\n const apiUrl = authMode === \"platform\" ? DEFAULT_API_URL : undefined;\n const { authObj, response } = await runAuthCheck(req, signInUrl, apiUrl);\n if (response) return response;\n if (!authObj)\n return NextResponse.redirect(new URL(signInUrl, req.url));\n\n if (afterAuth) {\n const result = afterAuth(authObj, req);\n if (result) return result;\n }\n\n return NextResponse.next();\n };\n}\n\nexport function withInAIAuth(\n wrappedMiddleware: (\n req: NextRequest,\n ) => NextResponse | Response | Promise<NextResponse | Response>,\n config: InAIMiddlewareConfig = {},\n): (req: NextRequest) => Promise<NextResponse> {\n const {\n authMode = \"app\",\n publicRoutes = [],\n signInUrl = \"/login\",\n beforeAuth,\n afterAuth,\n } = config;\n\n const builtinPublic = [\"/_next/*\", \"/favicon.ico\", \"/api/*\", signInUrl];\n\n return async function middleware(\n req: NextRequest,\n ): Promise<NextResponse> {\n if (beforeAuth) {\n const result = beforeAuth(req);\n if (result) return result;\n }\n\n const isPublic = isPublicRoute(req, publicRoutes, builtinPublic);\n\n if (!isPublic) {\n const apiUrl = authMode === \"platform\" ? DEFAULT_API_URL : undefined;\n const { authObj, response } = await runAuthCheck(req, signInUrl, apiUrl);\n if (response) return response;\n if (!authObj)\n return NextResponse.redirect(new URL(signInUrl, req.url));\n\n if (afterAuth) {\n const result = afterAuth(authObj, req);\n if (result) return result;\n }\n\n const authHeader = JSON.stringify({\n userId: authObj.userId,\n tenantId: authObj.tenantId,\n appId: authObj.appId,\n envId: authObj.envId,\n orgId: authObj.orgId,\n orgRole: authObj.orgRole,\n });\n req.headers.set(\"x-inai-auth\", authHeader);\n }\n\n const wrappedResponse = await wrappedMiddleware(req);\n if (wrappedResponse instanceof NextResponse) return wrappedResponse;\n return new NextResponse(wrappedResponse.body, wrappedResponse);\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAA6B;AAG7B,oBAOO;AAUA,SAAS,mBACd,UAC+B;AAC/B,QAAM,WAAW,SAAS,IAAI,CAAC,YAAY;AACzC,QAAI,mBAAmB,OAAQ,QAAO;AACtC,QAAI,WAAW;AACf,QAAI,SAAS,SAAS,GAAG,KAAK,CAAC,SAAS,SAAS,GAAG,GAAG;AACrD,iBAAW,SAAS,MAAM,GAAG,EAAE,IAAI;AAAA,IACrC;AACA,WAAO,IAAI,OAAO,IAAI,QAAQ,GAAG;AAAA,EACnC,CAAC;AAED,SAAO,CAAC,QAAqB;AAC3B,UAAM,WAAW,IAAI,QAAQ;AAC7B,WAAO,SAAS,KAAK,CAAC,MAAM,EAAE,KAAK,QAAQ,CAAC;AAAA,EAC9C;AACF;AAEA,SAAS,aAAa,UAAkB,UAA6B;AACnE,SAAO,SAAS,KAAK,CAAC,YAAY;AAChC,QAAI,QAAQ,SAAS,GAAG,GAAG;AACzB,aAAO,SAAS,WAAW,QAAQ,MAAM,GAAG,EAAE,CAAC;AAAA,IACjD;AACA,WAAO,aAAa;AAAA,EACtB,CAAC;AACH;AAEA,SAAS,cACP,KACA,cACA,eACS;AACT,QAAM,WAAW,IAAI,QAAQ;AAC7B,MAAI,aAAa,UAAU,aAAa,EAAG,QAAO;AAClD,MAAI,OAAO,iBAAiB,WAAY,QAAO,aAAa,GAAG;AAC/D,SAAO,aAAa,UAAU,YAAY;AAC5C;AAEA,SAAS,gBACP,OACA,QACY;AACZ,QAAM,QAAQ,OAAO,SAAS,CAAC;AAC/B,QAAM,cAAc,OAAO,eAAe,CAAC;AAC3C,SAAO;AAAA,IACL,QAAQ,OAAO;AAAA,IACf,UAAU,OAAO;AAAA,IACjB,OAAO,OAAO,UAAU;AAAA,IACxB,OAAO,OAAO,UAAU;AAAA,IACxB,OAAO,OAAO,UAAU;AAAA,IACxB,SAAS,OAAO,YAAY;AAAA,IAC5B,WAAW;AAAA,IACX,UAAU,YAAY;AAAA,IACtB,KAAK,CAAC,WAAmD;AACvD,UAAI,OAAO,QAAQ,MAAM,SAAS,OAAO,IAAI,EAAG,QAAO;AACvD,UAAI,OAAO,cAAc,YAAY,SAAS,OAAO,UAAU;AAC7D,eAAO;AACT,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAEA,eAAe,aACb,KACA,WACA,QACkE;AAClE,QAAM,EAAE,SAAS,IAAI,IAAI;AACzB,QAAM,QAAQ,IAAI,QAAQ,IAAI,+BAAiB,GAAG;AAElD,MAAI,CAAC,aAAS,8BAAe,KAAK,GAAG;AACnC,UAAM,eAAe,IAAI,QAAQ,IAAI,kCAAoB,GAAG;AAC5D,QAAI,cAAc;AAChB,UAAI;AACF,YAAI,QAAQ;AACV,gBAAM,aAAa,MAAM,MAAM,GAAG,MAAM,8BAA8B;AAAA,YACpE,QAAQ;AAAA,YACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,YAC9C,MAAM,KAAK,UAAU,EAAE,eAAe,aAAa,CAAC;AAAA,UACtD,CAAC;AACD,cAAI,WAAW,IAAI;AACjB,kBAAM,YAAY,MAAM,WAAW,KAAK;AAKxC,kBAAM,QAAQ,MAAM,MAAM,GAAG,MAAM,yBAAyB;AAAA,cAC1D,SAAS,EAAE,eAAe,UAAU,UAAU,YAAY,GAAG;AAAA,YAC/D,CAAC;AACD,gBAAI,MAAM,IAAI;AACZ,oBAAM,SAAS,MAAM,MAAM,KAAK;AAChC,oBAAM,UAAU,OAAO,QAAQ;AAC/B,oBAAM,eAAe,QAAQ,IAAI,aAAa;AAC9C,oBAAMA,YAAW,2BAAa,KAAK;AACnC,cAAAA,UAAS,QAAQ,IAAI,iCAAmB,UAAU,cAAc;AAAA,gBAC9D,UAAU;AAAA,gBAAM,QAAQ;AAAA,gBAAc,UAAU;AAAA,gBAChD,MAAM;AAAA,gBAAK,QAAQ,UAAU;AAAA,cAC/B,CAAC;AACD,cAAAA,UAAS,QAAQ,IAAI,oCAAsB,UAAU,eAAe;AAAA,gBAClE,UAAU;AAAA,gBAAM,QAAQ;AAAA,gBAAc,UAAU;AAAA,gBAChD,MAAM;AAAA,gBAAa,QAAQ,IAAI,KAAK,KAAK;AAAA,cAC3C,CAAC;AACD,cAAAA,UAAS,QAAQ,IAAI,mCAAqB,KAAK,UAAU;AAAA,gBACvD,MAAM;AAAA,gBACN,WAAW,IAAI,KAAK,KAAK,IAAI,IAAI,UAAU,aAAa,GAAI,EAAE,YAAY;AAAA,cAC5E,CAAC,GAAG;AAAA,gBACF,UAAU;AAAA,gBAAO,QAAQ;AAAA,gBAAc,UAAU;AAAA,gBACjD,MAAM;AAAA,gBAAK,QAAQ,UAAU;AAAA,cAC/B,CAAC;AACD,qBAAO,EAAE,SAAS,MAAM,UAAAA,UAAS;AAAA,YACnC;AAAA,UACF;AAAA,QACF,OAAO;AACL,gBAAM,aAAa,IAAI,IAAI,qBAAqB,IAAI,GAAG;AACvD,gBAAM,aAAa,MAAM,MAAM,WAAW,SAAS,GAAG;AAAA,YACpD,QAAQ;AAAA,YACR,SAAS;AAAA,cACP,gBAAgB;AAAA,cAChB,QAAQ,IAAI,QAAQ,IAAI,QAAQ,KAAK;AAAA,YACvC;AAAA,UACF,CAAC;AACD,cAAI,WAAW,IAAI;AACjB,kBAAMA,YAAW,2BAAa,KAAK;AACnC,kBAAM,aAAa,WAAW,QAAQ,eAAe,KAAK,CAAC;AAC3D,uBAAW,UAAU,YAAY;AAC/B,cAAAA,UAAS,QAAQ,OAAO,cAAc,MAAM;AAAA,YAC9C;AACA,mBAAO,EAAE,SAAS,MAAM,UAAAA,UAAS;AAAA,UACnC;AAAA,QACF;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AAEA,UAAM,WAAW,2BAAa;AAAA,MAC5B,IAAI;AAAA,QACF,GAAG,SAAS,aAAa,mBAAmB,QAAQ,CAAC;AAAA,QACrD,IAAI;AAAA,MACN;AAAA,IACF;AACA,aAAS,QAAQ,IAAI,iCAAmB,IAAI,EAAE,MAAM,KAAK,QAAQ,EAAE,CAAC;AACpE,aAAS,QAAQ,IAAI,oCAAsB,IAAI;AAAA,MAC7C,MAAM;AAAA,MACN,QAAQ;AAAA,IACV,CAAC;AACD,aAAS,QAAQ,IAAI,mCAAqB,IAAI,EAAE,MAAM,KAAK,QAAQ,EAAE,CAAC;AACtE,WAAO,EAAE,SAAS,MAAM,SAAS;AAAA,EACnC;AAEA,QAAM,aAAS,kCAAmB,KAAK;AACvC,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,MACL,SAAS;AAAA,MACT,UAAU,2BAAa,SAAS,IAAI,IAAI,WAAW,IAAI,GAAG,CAAC;AAAA,IAC7D;AAAA,EACF;AAEA,SAAO,EAAE,SAAS,gBAAgB,OAAO,MAAM,EAAE;AACnD;AAEO,SAAS,mBAAmB,SAA+B,CAAC,GAAG;AACpE,QAAM;AAAA,IACJ,WAAW;AAAA,IACX,eAAe,CAAC;AAAA,IAChB,YAAY;AAAA,IACZ;AAAA,IACA;AAAA,EACF,IAAI;AAEJ,QAAM,gBAAgB,CAAC,YAAY,gBAAgB,UAAU,SAAS;AAEtE,SAAO,eAAe,WACpB,KACuB;AACvB,QAAI,YAAY;AACd,YAAM,SAAS,WAAW,GAAG;AAC7B,UAAI,OAAQ,QAAO;AAAA,IACrB;AAEA,QAAI,cAAc,KAAK,cAAc,aAAa,GAAG;AACnD,aAAO,2BAAa,KAAK;AAAA,IAC3B;AAEA,UAAM,SAAS,aAAa,aAAa,gCAAkB;AAC3D,UAAM,EAAE,SAAS,SAAS,IAAI,MAAM,aAAa,KAAK,WAAW,MAAM;AACvE,QAAI,SAAU,QAAO;AACrB,QAAI,CAAC;AACH,aAAO,2BAAa,SAAS,IAAI,IAAI,WAAW,IAAI,GAAG,CAAC;AAE1D,QAAI,WAAW;AACb,YAAM,SAAS,UAAU,SAAS,GAAG;AACrC,UAAI,OAAQ,QAAO;AAAA,IACrB;AAEA,WAAO,2BAAa,KAAK;AAAA,EAC3B;AACF;AAEO,SAAS,aACd,mBAGA,SAA+B,CAAC,GACa;AAC7C,QAAM;AAAA,IACJ,WAAW;AAAA,IACX,eAAe,CAAC;AAAA,IAChB,YAAY;AAAA,IACZ;AAAA,IACA;AAAA,EACF,IAAI;AAEJ,QAAM,gBAAgB,CAAC,YAAY,gBAAgB,UAAU,SAAS;AAEtE,SAAO,eAAe,WACpB,KACuB;AACvB,QAAI,YAAY;AACd,YAAM,SAAS,WAAW,GAAG;AAC7B,UAAI,OAAQ,QAAO;AAAA,IACrB;AAEA,UAAM,WAAW,cAAc,KAAK,cAAc,aAAa;AAE/D,QAAI,CAAC,UAAU;AACb,YAAM,SAAS,aAAa,aAAa,gCAAkB;AAC3D,YAAM,EAAE,SAAS,SAAS,IAAI,MAAM,aAAa,KAAK,WAAW,MAAM;AACvE,UAAI,SAAU,QAAO;AACrB,UAAI,CAAC;AACH,eAAO,2BAAa,SAAS,IAAI,IAAI,WAAW,IAAI,GAAG,CAAC;AAE1D,UAAI,WAAW;AACb,cAAM,SAAS,UAAU,SAAS,GAAG;AACrC,YAAI,OAAQ,QAAO;AAAA,MACrB;AAEA,YAAM,aAAa,KAAK,UAAU;AAAA,QAChC,QAAQ,QAAQ;AAAA,QAChB,UAAU,QAAQ;AAAA,QAClB,OAAO,QAAQ;AAAA,QACf,OAAO,QAAQ;AAAA,QACf,OAAO,QAAQ;AAAA,QACf,SAAS,QAAQ;AAAA,MACnB,CAAC;AACD,UAAI,QAAQ,IAAI,eAAe,UAAU;AAAA,IAC3C;AAEA,UAAM,kBAAkB,MAAM,kBAAkB,GAAG;AACnD,QAAI,2BAA2B,2BAAc,QAAO;AACpD,WAAO,IAAI,2BAAa,gBAAgB,MAAM,eAAe;AAAA,EAC/D;AACF;","names":["response"]}
|
|
1
|
+
{"version":3,"sources":["../src/middleware.ts"],"sourcesContent":["import { NextResponse } from \"next/server\";\nimport type { NextRequest } from \"next/server\";\nimport type { AuthObject } from \"@inai-dev/types\";\nimport {\n COOKIE_AUTH_TOKEN,\n COOKIE_AUTH_SESSION,\n COOKIE_REFRESH_TOKEN,\n DEFAULT_API_URL,\n decodeJWTHeader,\n verifyES256,\n JWKSClient,\n} from \"@inai-dev/shared\";\nimport { isTokenExpired } from \"@inai-dev/shared\";\n\nexport interface InAIMiddlewareConfig {\n authMode?: \"app\" | \"platform\";\n publicRoutes?: string[] | ((req: NextRequest) => boolean);\n signInUrl?: string;\n beforeAuth?: (req: NextRequest) => NextResponse | void;\n afterAuth?: (auth: AuthObject, req: NextRequest) => NextResponse | void;\n jwksUrl?: string;\n apiUrl?: string;\n}\n\n// Module-level JWKS client (shared across requests in the same worker/process)\nlet sharedJwksClient: JWKSClient | null = null;\nlet sharedJwksUrl: string | null = null;\n\nfunction getJwksClient(config: InAIMiddlewareConfig): JWKSClient {\n const jwksUrl = config.jwksUrl\n ?? `${config.apiUrl ?? DEFAULT_API_URL}/.well-known/jwks.json`;\n\n if (!sharedJwksClient || sharedJwksUrl !== jwksUrl) {\n sharedJwksClient = new JWKSClient(jwksUrl);\n sharedJwksUrl = jwksUrl;\n }\n return sharedJwksClient;\n}\n\nexport function createRouteMatcher(\n patterns: (string | RegExp)[],\n): (req: NextRequest) => boolean {\n const matchers = patterns.map((pattern) => {\n if (pattern instanceof RegExp) return pattern;\n let regexStr = pattern;\n if (regexStr.endsWith(\"*\") && !regexStr.includes(\"(\")) {\n regexStr = regexStr.slice(0, -1) + \".*\";\n }\n return new RegExp(`^${regexStr}$`);\n });\n\n return (req: NextRequest) => {\n const pathname = req.nextUrl.pathname;\n return matchers.some((m) => m.test(pathname));\n };\n}\n\nfunction matchesRoute(pathname: string, patterns: string[]): boolean {\n return patterns.some((pattern) => {\n if (pattern.endsWith(\"*\")) {\n return pathname.startsWith(pattern.slice(0, -1));\n }\n return pathname === pattern;\n });\n}\n\nfunction isPublicRoute(\n req: NextRequest,\n publicRoutes: string[] | ((req: NextRequest) => boolean),\n builtinPublic: string[],\n): boolean {\n const pathname = req.nextUrl.pathname;\n if (matchesRoute(pathname, builtinPublic)) return true;\n if (typeof publicRoutes === \"function\") return publicRoutes(req);\n return matchesRoute(pathname, publicRoutes);\n}\n\nasync function buildAuthObject(\n token: string,\n jwksClient: JWKSClient,\n): Promise<AuthObject | null> {\n const header = decodeJWTHeader(token);\n if (!header?.kid) return null;\n\n let publicKey: CryptoKey;\n try {\n publicKey = await jwksClient.getKey(header.kid);\n } catch {\n return null;\n }\n\n let claims = await verifyES256(token, publicKey);\n if (!claims) {\n // Signature failed with cached key — refetch once in case of key rotation\n jwksClient.invalidate();\n try {\n publicKey = await jwksClient.getKey(header.kid);\n } catch {\n return null;\n }\n claims = await verifyES256(token, publicKey);\n if (!claims) return null;\n }\n\n const roles = claims.roles ?? [];\n const permissions = claims.permissions ?? [];\n return {\n userId: claims.sub,\n tenantId: claims.tenant_id,\n appId: claims.app_id ?? null,\n envId: claims.env_id ?? null,\n orgId: claims.org_id ?? null,\n orgRole: claims.org_role ?? null,\n sessionId: null,\n roles,\n permissions,\n getToken: async () => token,\n has: (params: { role?: string; permission?: string }) => {\n if (params.role && roles.includes(params.role)) return true;\n if (params.permission && permissions.includes(params.permission))\n return true;\n return false;\n },\n };\n}\n\nasync function runAuthCheck(\n req: NextRequest,\n signInUrl: string,\n jwksClient: JWKSClient,\n apiUrl?: string,\n): Promise<{ authObj: AuthObject | null; response?: NextResponse }> {\n const { pathname } = req.nextUrl;\n const token = req.cookies.get(COOKIE_AUTH_TOKEN)?.value;\n\n if (!token || isTokenExpired(token)) {\n const refreshToken = req.cookies.get(COOKIE_REFRESH_TOKEN)?.value;\n if (refreshToken) {\n try {\n if (apiUrl) {\n const refreshRes = await fetch(`${apiUrl}/api/platform/auth/refresh`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ refresh_token: refreshToken }),\n });\n if (refreshRes.ok) {\n const newTokens = await refreshRes.json() as {\n access_token: string;\n refresh_token: string;\n expires_in: number;\n };\n const meRes = await fetch(`${apiUrl}/api/platform/auth/me`, {\n headers: { Authorization: `Bearer ${newTokens.access_token}` },\n });\n if (meRes.ok) {\n const meData = await meRes.json();\n const newUser = meData.data ?? meData;\n const isProduction = process.env.NODE_ENV === \"production\";\n const response = NextResponse.next();\n response.cookies.set(COOKIE_AUTH_TOKEN, newTokens.access_token, {\n httpOnly: true, secure: isProduction, sameSite: \"lax\",\n path: \"/\", maxAge: newTokens.expires_in,\n });\n response.cookies.set(COOKIE_REFRESH_TOKEN, newTokens.refresh_token, {\n httpOnly: true, secure: isProduction, sameSite: \"strict\",\n path: \"/api/auth\", maxAge: 7 * 24 * 60 * 60,\n });\n response.cookies.set(COOKIE_AUTH_SESSION, JSON.stringify({\n user: newUser,\n expiresAt: new Date(Date.now() + newTokens.expires_in * 1000).toISOString(),\n }), {\n httpOnly: false, secure: isProduction, sameSite: \"lax\",\n path: \"/\", maxAge: newTokens.expires_in,\n });\n return { authObj: null, response };\n }\n }\n } else {\n const refreshUrl = new URL(\"/api/auth/refresh\", req.url);\n const refreshRes = await fetch(refreshUrl.toString(), {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Cookie: req.headers.get(\"cookie\") ?? \"\",\n },\n });\n if (refreshRes.ok) {\n const response = NextResponse.next();\n const setCookies = refreshRes.headers.getSetCookie?.() ?? [];\n for (const cookie of setCookies) {\n response.headers.append(\"Set-Cookie\", cookie);\n }\n return { authObj: null, response };\n }\n }\n } catch {\n // Refresh failed, fall through to redirect\n }\n }\n\n const response = NextResponse.redirect(\n new URL(\n `${signInUrl}?returnTo=${encodeURIComponent(pathname)}`,\n req.url,\n ),\n );\n response.cookies.set(COOKIE_AUTH_TOKEN, \"\", { path: \"/\", maxAge: 0 });\n response.cookies.set(COOKIE_REFRESH_TOKEN, \"\", {\n path: \"/api/auth\",\n maxAge: 0,\n });\n response.cookies.set(COOKIE_AUTH_SESSION, \"\", { path: \"/\", maxAge: 0 });\n return { authObj: null, response };\n }\n\n const authObj = await buildAuthObject(token, jwksClient);\n if (!authObj) {\n return {\n authObj: null,\n response: NextResponse.redirect(new URL(signInUrl, req.url)),\n };\n }\n\n return { authObj };\n}\n\nexport function inaiAuthMiddleware(config: InAIMiddlewareConfig = {}) {\n const {\n authMode = \"app\",\n publicRoutes = [],\n signInUrl = \"/login\",\n beforeAuth,\n afterAuth,\n } = config;\n\n const builtinPublic = [\"/_next/*\", \"/favicon.ico\", \"/api/*\", signInUrl];\n const jwksClient = getJwksClient(config);\n\n return async function middleware(\n req: NextRequest,\n ): Promise<NextResponse> {\n if (beforeAuth) {\n const result = beforeAuth(req);\n if (result) return result;\n }\n\n if (isPublicRoute(req, publicRoutes, builtinPublic)) {\n return NextResponse.next();\n }\n\n const apiUrl = authMode === \"platform\" ? (config.apiUrl ?? DEFAULT_API_URL) : undefined;\n const { authObj, response } = await runAuthCheck(req, signInUrl, jwksClient, apiUrl);\n if (response) return response;\n if (!authObj)\n return NextResponse.redirect(new URL(signInUrl, req.url));\n\n if (afterAuth) {\n const result = afterAuth(authObj, req);\n if (result) return result;\n }\n\n return NextResponse.next();\n };\n}\n\nexport function withInAIAuth(\n wrappedMiddleware: (\n req: NextRequest,\n ) => NextResponse | Response | Promise<NextResponse | Response>,\n config: InAIMiddlewareConfig = {},\n): (req: NextRequest) => Promise<NextResponse> {\n const {\n authMode = \"app\",\n publicRoutes = [],\n signInUrl = \"/login\",\n beforeAuth,\n afterAuth,\n } = config;\n\n const builtinPublic = [\"/_next/*\", \"/favicon.ico\", \"/api/*\", signInUrl];\n const jwksClient = getJwksClient(config);\n\n return async function middleware(\n req: NextRequest,\n ): Promise<NextResponse> {\n if (beforeAuth) {\n const result = beforeAuth(req);\n if (result) return result;\n }\n\n const isPublic = isPublicRoute(req, publicRoutes, builtinPublic);\n\n if (!isPublic) {\n const apiUrl = authMode === \"platform\" ? (config.apiUrl ?? DEFAULT_API_URL) : undefined;\n const { authObj, response } = await runAuthCheck(req, signInUrl, jwksClient, apiUrl);\n if (response) return response;\n if (!authObj)\n return NextResponse.redirect(new URL(signInUrl, req.url));\n\n if (afterAuth) {\n const result = afterAuth(authObj, req);\n if (result) return result;\n }\n\n const authHeader = JSON.stringify({\n userId: authObj.userId,\n tenantId: authObj.tenantId,\n appId: authObj.appId,\n envId: authObj.envId,\n orgId: authObj.orgId,\n orgRole: authObj.orgRole,\n roles: authObj.roles,\n permissions: authObj.permissions,\n });\n req.headers.set(\"x-inai-auth\", authHeader);\n }\n\n const wrappedResponse = await wrappedMiddleware(req);\n if (wrappedResponse instanceof NextResponse) return wrappedResponse;\n return new NextResponse(wrappedResponse.body, wrappedResponse);\n };\n}\n"],"mappings":"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","names":["import_shared","response"]}
|
package/dist/middleware.d.cts
CHANGED
|
@@ -7,6 +7,8 @@ interface InAIMiddlewareConfig {
|
|
|
7
7
|
signInUrl?: string;
|
|
8
8
|
beforeAuth?: (req: NextRequest) => NextResponse | void;
|
|
9
9
|
afterAuth?: (auth: AuthObject, req: NextRequest) => NextResponse | void;
|
|
10
|
+
jwksUrl?: string;
|
|
11
|
+
apiUrl?: string;
|
|
10
12
|
}
|
|
11
13
|
declare function createRouteMatcher(patterns: (string | RegExp)[]): (req: NextRequest) => boolean;
|
|
12
14
|
declare function inaiAuthMiddleware(config?: InAIMiddlewareConfig): (req: NextRequest) => Promise<NextResponse>;
|
package/dist/middleware.d.ts
CHANGED
|
@@ -7,6 +7,8 @@ interface InAIMiddlewareConfig {
|
|
|
7
7
|
signInUrl?: string;
|
|
8
8
|
beforeAuth?: (req: NextRequest) => NextResponse | void;
|
|
9
9
|
afterAuth?: (auth: AuthObject, req: NextRequest) => NextResponse | void;
|
|
10
|
+
jwksUrl?: string;
|
|
11
|
+
apiUrl?: string;
|
|
10
12
|
}
|
|
11
13
|
declare function createRouteMatcher(patterns: (string | RegExp)[]): (req: NextRequest) => boolean;
|
|
12
14
|
declare function inaiAuthMiddleware(config?: InAIMiddlewareConfig): (req: NextRequest) => Promise<NextResponse>;
|
package/dist/middleware.js
CHANGED
|
@@ -5,9 +5,21 @@ import {
|
|
|
5
5
|
COOKIE_AUTH_SESSION,
|
|
6
6
|
COOKIE_REFRESH_TOKEN,
|
|
7
7
|
DEFAULT_API_URL,
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
decodeJWTHeader,
|
|
9
|
+
verifyES256,
|
|
10
|
+
JWKSClient
|
|
10
11
|
} from "@inai-dev/shared";
|
|
12
|
+
import { isTokenExpired } from "@inai-dev/shared";
|
|
13
|
+
var sharedJwksClient = null;
|
|
14
|
+
var sharedJwksUrl = null;
|
|
15
|
+
function getJwksClient(config) {
|
|
16
|
+
const jwksUrl = config.jwksUrl ?? `${config.apiUrl ?? DEFAULT_API_URL}/.well-known/jwks.json`;
|
|
17
|
+
if (!sharedJwksClient || sharedJwksUrl !== jwksUrl) {
|
|
18
|
+
sharedJwksClient = new JWKSClient(jwksUrl);
|
|
19
|
+
sharedJwksUrl = jwksUrl;
|
|
20
|
+
}
|
|
21
|
+
return sharedJwksClient;
|
|
22
|
+
}
|
|
11
23
|
function createRouteMatcher(patterns) {
|
|
12
24
|
const matchers = patterns.map((pattern) => {
|
|
13
25
|
if (pattern instanceof RegExp) return pattern;
|
|
@@ -36,7 +48,26 @@ function isPublicRoute(req, publicRoutes, builtinPublic) {
|
|
|
36
48
|
if (typeof publicRoutes === "function") return publicRoutes(req);
|
|
37
49
|
return matchesRoute(pathname, publicRoutes);
|
|
38
50
|
}
|
|
39
|
-
function buildAuthObject(token,
|
|
51
|
+
async function buildAuthObject(token, jwksClient) {
|
|
52
|
+
const header = decodeJWTHeader(token);
|
|
53
|
+
if (!header?.kid) return null;
|
|
54
|
+
let publicKey;
|
|
55
|
+
try {
|
|
56
|
+
publicKey = await jwksClient.getKey(header.kid);
|
|
57
|
+
} catch {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
let claims = await verifyES256(token, publicKey);
|
|
61
|
+
if (!claims) {
|
|
62
|
+
jwksClient.invalidate();
|
|
63
|
+
try {
|
|
64
|
+
publicKey = await jwksClient.getKey(header.kid);
|
|
65
|
+
} catch {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
claims = await verifyES256(token, publicKey);
|
|
69
|
+
if (!claims) return null;
|
|
70
|
+
}
|
|
40
71
|
const roles = claims.roles ?? [];
|
|
41
72
|
const permissions = claims.permissions ?? [];
|
|
42
73
|
return {
|
|
@@ -47,6 +78,8 @@ function buildAuthObject(token, claims) {
|
|
|
47
78
|
orgId: claims.org_id ?? null,
|
|
48
79
|
orgRole: claims.org_role ?? null,
|
|
49
80
|
sessionId: null,
|
|
81
|
+
roles,
|
|
82
|
+
permissions,
|
|
50
83
|
getToken: async () => token,
|
|
51
84
|
has: (params) => {
|
|
52
85
|
if (params.role && roles.includes(params.role)) return true;
|
|
@@ -56,7 +89,7 @@ function buildAuthObject(token, claims) {
|
|
|
56
89
|
}
|
|
57
90
|
};
|
|
58
91
|
}
|
|
59
|
-
async function runAuthCheck(req, signInUrl, apiUrl) {
|
|
92
|
+
async function runAuthCheck(req, signInUrl, jwksClient, apiUrl) {
|
|
60
93
|
const { pathname } = req.nextUrl;
|
|
61
94
|
const token = req.cookies.get(COOKIE_AUTH_TOKEN)?.value;
|
|
62
95
|
if (!token || isTokenExpired(token)) {
|
|
@@ -141,14 +174,14 @@ async function runAuthCheck(req, signInUrl, apiUrl) {
|
|
|
141
174
|
response.cookies.set(COOKIE_AUTH_SESSION, "", { path: "/", maxAge: 0 });
|
|
142
175
|
return { authObj: null, response };
|
|
143
176
|
}
|
|
144
|
-
const
|
|
145
|
-
if (!
|
|
177
|
+
const authObj = await buildAuthObject(token, jwksClient);
|
|
178
|
+
if (!authObj) {
|
|
146
179
|
return {
|
|
147
180
|
authObj: null,
|
|
148
181
|
response: NextResponse.redirect(new URL(signInUrl, req.url))
|
|
149
182
|
};
|
|
150
183
|
}
|
|
151
|
-
return { authObj
|
|
184
|
+
return { authObj };
|
|
152
185
|
}
|
|
153
186
|
function inaiAuthMiddleware(config = {}) {
|
|
154
187
|
const {
|
|
@@ -159,6 +192,7 @@ function inaiAuthMiddleware(config = {}) {
|
|
|
159
192
|
afterAuth
|
|
160
193
|
} = config;
|
|
161
194
|
const builtinPublic = ["/_next/*", "/favicon.ico", "/api/*", signInUrl];
|
|
195
|
+
const jwksClient = getJwksClient(config);
|
|
162
196
|
return async function middleware(req) {
|
|
163
197
|
if (beforeAuth) {
|
|
164
198
|
const result = beforeAuth(req);
|
|
@@ -167,8 +201,8 @@ function inaiAuthMiddleware(config = {}) {
|
|
|
167
201
|
if (isPublicRoute(req, publicRoutes, builtinPublic)) {
|
|
168
202
|
return NextResponse.next();
|
|
169
203
|
}
|
|
170
|
-
const apiUrl = authMode === "platform" ? DEFAULT_API_URL : void 0;
|
|
171
|
-
const { authObj, response } = await runAuthCheck(req, signInUrl, apiUrl);
|
|
204
|
+
const apiUrl = authMode === "platform" ? config.apiUrl ?? DEFAULT_API_URL : void 0;
|
|
205
|
+
const { authObj, response } = await runAuthCheck(req, signInUrl, jwksClient, apiUrl);
|
|
172
206
|
if (response) return response;
|
|
173
207
|
if (!authObj)
|
|
174
208
|
return NextResponse.redirect(new URL(signInUrl, req.url));
|
|
@@ -188,6 +222,7 @@ function withInAIAuth(wrappedMiddleware, config = {}) {
|
|
|
188
222
|
afterAuth
|
|
189
223
|
} = config;
|
|
190
224
|
const builtinPublic = ["/_next/*", "/favicon.ico", "/api/*", signInUrl];
|
|
225
|
+
const jwksClient = getJwksClient(config);
|
|
191
226
|
return async function middleware(req) {
|
|
192
227
|
if (beforeAuth) {
|
|
193
228
|
const result = beforeAuth(req);
|
|
@@ -195,8 +230,8 @@ function withInAIAuth(wrappedMiddleware, config = {}) {
|
|
|
195
230
|
}
|
|
196
231
|
const isPublic = isPublicRoute(req, publicRoutes, builtinPublic);
|
|
197
232
|
if (!isPublic) {
|
|
198
|
-
const apiUrl = authMode === "platform" ? DEFAULT_API_URL : void 0;
|
|
199
|
-
const { authObj, response } = await runAuthCheck(req, signInUrl, apiUrl);
|
|
233
|
+
const apiUrl = authMode === "platform" ? config.apiUrl ?? DEFAULT_API_URL : void 0;
|
|
234
|
+
const { authObj, response } = await runAuthCheck(req, signInUrl, jwksClient, apiUrl);
|
|
200
235
|
if (response) return response;
|
|
201
236
|
if (!authObj)
|
|
202
237
|
return NextResponse.redirect(new URL(signInUrl, req.url));
|
|
@@ -210,7 +245,9 @@ function withInAIAuth(wrappedMiddleware, config = {}) {
|
|
|
210
245
|
appId: authObj.appId,
|
|
211
246
|
envId: authObj.envId,
|
|
212
247
|
orgId: authObj.orgId,
|
|
213
|
-
orgRole: authObj.orgRole
|
|
248
|
+
orgRole: authObj.orgRole,
|
|
249
|
+
roles: authObj.roles,
|
|
250
|
+
permissions: authObj.permissions
|
|
214
251
|
});
|
|
215
252
|
req.headers.set("x-inai-auth", authHeader);
|
|
216
253
|
}
|
package/dist/middleware.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/middleware.ts"],"sourcesContent":["import { NextResponse } from \"next/server\";\nimport type { NextRequest } from \"next/server\";\nimport type { AuthObject } from \"@inai-dev/types\";\nimport {\n COOKIE_AUTH_TOKEN,\n COOKIE_AUTH_SESSION,\n COOKIE_REFRESH_TOKEN,\n DEFAULT_API_URL,\n getClaimsFromToken,\n isTokenExpired,\n} from \"@inai-dev/shared\";\n\nexport interface InAIMiddlewareConfig {\n authMode?: \"app\" | \"platform\";\n publicRoutes?: string[] | ((req: NextRequest) => boolean);\n signInUrl?: string;\n beforeAuth?: (req: NextRequest) => NextResponse | void;\n afterAuth?: (auth: AuthObject, req: NextRequest) => NextResponse | void;\n}\n\nexport function createRouteMatcher(\n patterns: (string | RegExp)[],\n): (req: NextRequest) => boolean {\n const matchers = patterns.map((pattern) => {\n if (pattern instanceof RegExp) return pattern;\n let regexStr = pattern;\n if (regexStr.endsWith(\"*\") && !regexStr.includes(\"(\")) {\n regexStr = regexStr.slice(0, -1) + \".*\";\n }\n return new RegExp(`^${regexStr}$`);\n });\n\n return (req: NextRequest) => {\n const pathname = req.nextUrl.pathname;\n return matchers.some((m) => m.test(pathname));\n };\n}\n\nfunction matchesRoute(pathname: string, patterns: string[]): boolean {\n return patterns.some((pattern) => {\n if (pattern.endsWith(\"*\")) {\n return pathname.startsWith(pattern.slice(0, -1));\n }\n return pathname === pattern;\n });\n}\n\nfunction isPublicRoute(\n req: NextRequest,\n publicRoutes: string[] | ((req: NextRequest) => boolean),\n builtinPublic: string[],\n): boolean {\n const pathname = req.nextUrl.pathname;\n if (matchesRoute(pathname, builtinPublic)) return true;\n if (typeof publicRoutes === \"function\") return publicRoutes(req);\n return matchesRoute(pathname, publicRoutes);\n}\n\nfunction buildAuthObject(\n token: string,\n claims: NonNullable<ReturnType<typeof getClaimsFromToken>>,\n): AuthObject {\n const roles = claims.roles ?? [];\n const permissions = claims.permissions ?? [];\n return {\n userId: claims.sub,\n tenantId: claims.tenant_id,\n appId: claims.app_id ?? null,\n envId: claims.env_id ?? null,\n orgId: claims.org_id ?? null,\n orgRole: claims.org_role ?? null,\n sessionId: null,\n getToken: async () => token,\n has: (params: { role?: string; permission?: string }) => {\n if (params.role && roles.includes(params.role)) return true;\n if (params.permission && permissions.includes(params.permission))\n return true;\n return false;\n },\n };\n}\n\nasync function runAuthCheck(\n req: NextRequest,\n signInUrl: string,\n apiUrl?: string,\n): Promise<{ authObj: AuthObject | null; response?: NextResponse }> {\n const { pathname } = req.nextUrl;\n const token = req.cookies.get(COOKIE_AUTH_TOKEN)?.value;\n\n if (!token || isTokenExpired(token)) {\n const refreshToken = req.cookies.get(COOKIE_REFRESH_TOKEN)?.value;\n if (refreshToken) {\n try {\n if (apiUrl) {\n const refreshRes = await fetch(`${apiUrl}/api/platform/auth/refresh`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ refresh_token: refreshToken }),\n });\n if (refreshRes.ok) {\n const newTokens = await refreshRes.json() as {\n access_token: string;\n refresh_token: string;\n expires_in: number;\n };\n const meRes = await fetch(`${apiUrl}/api/platform/auth/me`, {\n headers: { Authorization: `Bearer ${newTokens.access_token}` },\n });\n if (meRes.ok) {\n const meData = await meRes.json();\n const newUser = meData.data ?? meData;\n const isProduction = process.env.NODE_ENV === \"production\";\n const response = NextResponse.next();\n response.cookies.set(COOKIE_AUTH_TOKEN, newTokens.access_token, {\n httpOnly: true, secure: isProduction, sameSite: \"lax\",\n path: \"/\", maxAge: newTokens.expires_in,\n });\n response.cookies.set(COOKIE_REFRESH_TOKEN, newTokens.refresh_token, {\n httpOnly: true, secure: isProduction, sameSite: \"strict\",\n path: \"/api/auth\", maxAge: 7 * 24 * 60 * 60,\n });\n response.cookies.set(COOKIE_AUTH_SESSION, JSON.stringify({\n user: newUser,\n expiresAt: new Date(Date.now() + newTokens.expires_in * 1000).toISOString(),\n }), {\n httpOnly: false, secure: isProduction, sameSite: \"lax\",\n path: \"/\", maxAge: newTokens.expires_in,\n });\n return { authObj: null, response };\n }\n }\n } else {\n const refreshUrl = new URL(\"/api/auth/refresh\", req.url);\n const refreshRes = await fetch(refreshUrl.toString(), {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Cookie: req.headers.get(\"cookie\") ?? \"\",\n },\n });\n if (refreshRes.ok) {\n const response = NextResponse.next();\n const setCookies = refreshRes.headers.getSetCookie?.() ?? [];\n for (const cookie of setCookies) {\n response.headers.append(\"Set-Cookie\", cookie);\n }\n return { authObj: null, response };\n }\n }\n } catch {\n // Refresh failed, fall through to redirect\n }\n }\n\n const response = NextResponse.redirect(\n new URL(\n `${signInUrl}?returnTo=${encodeURIComponent(pathname)}`,\n req.url,\n ),\n );\n response.cookies.set(COOKIE_AUTH_TOKEN, \"\", { path: \"/\", maxAge: 0 });\n response.cookies.set(COOKIE_REFRESH_TOKEN, \"\", {\n path: \"/api/auth\",\n maxAge: 0,\n });\n response.cookies.set(COOKIE_AUTH_SESSION, \"\", { path: \"/\", maxAge: 0 });\n return { authObj: null, response };\n }\n\n const claims = getClaimsFromToken(token);\n if (!claims) {\n return {\n authObj: null,\n response: NextResponse.redirect(new URL(signInUrl, req.url)),\n };\n }\n\n return { authObj: buildAuthObject(token, claims) };\n}\n\nexport function inaiAuthMiddleware(config: InAIMiddlewareConfig = {}) {\n const {\n authMode = \"app\",\n publicRoutes = [],\n signInUrl = \"/login\",\n beforeAuth,\n afterAuth,\n } = config;\n\n const builtinPublic = [\"/_next/*\", \"/favicon.ico\", \"/api/*\", signInUrl];\n\n return async function middleware(\n req: NextRequest,\n ): Promise<NextResponse> {\n if (beforeAuth) {\n const result = beforeAuth(req);\n if (result) return result;\n }\n\n if (isPublicRoute(req, publicRoutes, builtinPublic)) {\n return NextResponse.next();\n }\n\n const apiUrl = authMode === \"platform\" ? DEFAULT_API_URL : undefined;\n const { authObj, response } = await runAuthCheck(req, signInUrl, apiUrl);\n if (response) return response;\n if (!authObj)\n return NextResponse.redirect(new URL(signInUrl, req.url));\n\n if (afterAuth) {\n const result = afterAuth(authObj, req);\n if (result) return result;\n }\n\n return NextResponse.next();\n };\n}\n\nexport function withInAIAuth(\n wrappedMiddleware: (\n req: NextRequest,\n ) => NextResponse | Response | Promise<NextResponse | Response>,\n config: InAIMiddlewareConfig = {},\n): (req: NextRequest) => Promise<NextResponse> {\n const {\n authMode = \"app\",\n publicRoutes = [],\n signInUrl = \"/login\",\n beforeAuth,\n afterAuth,\n } = config;\n\n const builtinPublic = [\"/_next/*\", \"/favicon.ico\", \"/api/*\", signInUrl];\n\n return async function middleware(\n req: NextRequest,\n ): Promise<NextResponse> {\n if (beforeAuth) {\n const result = beforeAuth(req);\n if (result) return result;\n }\n\n const isPublic = isPublicRoute(req, publicRoutes, builtinPublic);\n\n if (!isPublic) {\n const apiUrl = authMode === \"platform\" ? DEFAULT_API_URL : undefined;\n const { authObj, response } = await runAuthCheck(req, signInUrl, apiUrl);\n if (response) return response;\n if (!authObj)\n return NextResponse.redirect(new URL(signInUrl, req.url));\n\n if (afterAuth) {\n const result = afterAuth(authObj, req);\n if (result) return result;\n }\n\n const authHeader = JSON.stringify({\n userId: authObj.userId,\n tenantId: authObj.tenantId,\n appId: authObj.appId,\n envId: authObj.envId,\n orgId: authObj.orgId,\n orgRole: authObj.orgRole,\n });\n req.headers.set(\"x-inai-auth\", authHeader);\n }\n\n const wrappedResponse = await wrappedMiddleware(req);\n if (wrappedResponse instanceof NextResponse) return wrappedResponse;\n return new NextResponse(wrappedResponse.body, wrappedResponse);\n };\n}\n"],"mappings":"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","names":["response"]}
|
|
1
|
+
{"version":3,"sources":["../src/middleware.ts"],"sourcesContent":["import { NextResponse } from \"next/server\";\nimport type { NextRequest } from \"next/server\";\nimport type { AuthObject } from \"@inai-dev/types\";\nimport {\n COOKIE_AUTH_TOKEN,\n COOKIE_AUTH_SESSION,\n COOKIE_REFRESH_TOKEN,\n DEFAULT_API_URL,\n decodeJWTHeader,\n verifyES256,\n JWKSClient,\n} from \"@inai-dev/shared\";\nimport { isTokenExpired } from \"@inai-dev/shared\";\n\nexport interface InAIMiddlewareConfig {\n authMode?: \"app\" | \"platform\";\n publicRoutes?: string[] | ((req: NextRequest) => boolean);\n signInUrl?: string;\n beforeAuth?: (req: NextRequest) => NextResponse | void;\n afterAuth?: (auth: AuthObject, req: NextRequest) => NextResponse | void;\n jwksUrl?: string;\n apiUrl?: string;\n}\n\n// Module-level JWKS client (shared across requests in the same worker/process)\nlet sharedJwksClient: JWKSClient | null = null;\nlet sharedJwksUrl: string | null = null;\n\nfunction getJwksClient(config: InAIMiddlewareConfig): JWKSClient {\n const jwksUrl = config.jwksUrl\n ?? `${config.apiUrl ?? DEFAULT_API_URL}/.well-known/jwks.json`;\n\n if (!sharedJwksClient || sharedJwksUrl !== jwksUrl) {\n sharedJwksClient = new JWKSClient(jwksUrl);\n sharedJwksUrl = jwksUrl;\n }\n return sharedJwksClient;\n}\n\nexport function createRouteMatcher(\n patterns: (string | RegExp)[],\n): (req: NextRequest) => boolean {\n const matchers = patterns.map((pattern) => {\n if (pattern instanceof RegExp) return pattern;\n let regexStr = pattern;\n if (regexStr.endsWith(\"*\") && !regexStr.includes(\"(\")) {\n regexStr = regexStr.slice(0, -1) + \".*\";\n }\n return new RegExp(`^${regexStr}$`);\n });\n\n return (req: NextRequest) => {\n const pathname = req.nextUrl.pathname;\n return matchers.some((m) => m.test(pathname));\n };\n}\n\nfunction matchesRoute(pathname: string, patterns: string[]): boolean {\n return patterns.some((pattern) => {\n if (pattern.endsWith(\"*\")) {\n return pathname.startsWith(pattern.slice(0, -1));\n }\n return pathname === pattern;\n });\n}\n\nfunction isPublicRoute(\n req: NextRequest,\n publicRoutes: string[] | ((req: NextRequest) => boolean),\n builtinPublic: string[],\n): boolean {\n const pathname = req.nextUrl.pathname;\n if (matchesRoute(pathname, builtinPublic)) return true;\n if (typeof publicRoutes === \"function\") return publicRoutes(req);\n return matchesRoute(pathname, publicRoutes);\n}\n\nasync function buildAuthObject(\n token: string,\n jwksClient: JWKSClient,\n): Promise<AuthObject | null> {\n const header = decodeJWTHeader(token);\n if (!header?.kid) return null;\n\n let publicKey: CryptoKey;\n try {\n publicKey = await jwksClient.getKey(header.kid);\n } catch {\n return null;\n }\n\n let claims = await verifyES256(token, publicKey);\n if (!claims) {\n // Signature failed with cached key — refetch once in case of key rotation\n jwksClient.invalidate();\n try {\n publicKey = await jwksClient.getKey(header.kid);\n } catch {\n return null;\n }\n claims = await verifyES256(token, publicKey);\n if (!claims) return null;\n }\n\n const roles = claims.roles ?? [];\n const permissions = claims.permissions ?? [];\n return {\n userId: claims.sub,\n tenantId: claims.tenant_id,\n appId: claims.app_id ?? null,\n envId: claims.env_id ?? null,\n orgId: claims.org_id ?? null,\n orgRole: claims.org_role ?? null,\n sessionId: null,\n roles,\n permissions,\n getToken: async () => token,\n has: (params: { role?: string; permission?: string }) => {\n if (params.role && roles.includes(params.role)) return true;\n if (params.permission && permissions.includes(params.permission))\n return true;\n return false;\n },\n };\n}\n\nasync function runAuthCheck(\n req: NextRequest,\n signInUrl: string,\n jwksClient: JWKSClient,\n apiUrl?: string,\n): Promise<{ authObj: AuthObject | null; response?: NextResponse }> {\n const { pathname } = req.nextUrl;\n const token = req.cookies.get(COOKIE_AUTH_TOKEN)?.value;\n\n if (!token || isTokenExpired(token)) {\n const refreshToken = req.cookies.get(COOKIE_REFRESH_TOKEN)?.value;\n if (refreshToken) {\n try {\n if (apiUrl) {\n const refreshRes = await fetch(`${apiUrl}/api/platform/auth/refresh`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ refresh_token: refreshToken }),\n });\n if (refreshRes.ok) {\n const newTokens = await refreshRes.json() as {\n access_token: string;\n refresh_token: string;\n expires_in: number;\n };\n const meRes = await fetch(`${apiUrl}/api/platform/auth/me`, {\n headers: { Authorization: `Bearer ${newTokens.access_token}` },\n });\n if (meRes.ok) {\n const meData = await meRes.json();\n const newUser = meData.data ?? meData;\n const isProduction = process.env.NODE_ENV === \"production\";\n const response = NextResponse.next();\n response.cookies.set(COOKIE_AUTH_TOKEN, newTokens.access_token, {\n httpOnly: true, secure: isProduction, sameSite: \"lax\",\n path: \"/\", maxAge: newTokens.expires_in,\n });\n response.cookies.set(COOKIE_REFRESH_TOKEN, newTokens.refresh_token, {\n httpOnly: true, secure: isProduction, sameSite: \"strict\",\n path: \"/api/auth\", maxAge: 7 * 24 * 60 * 60,\n });\n response.cookies.set(COOKIE_AUTH_SESSION, JSON.stringify({\n user: newUser,\n expiresAt: new Date(Date.now() + newTokens.expires_in * 1000).toISOString(),\n }), {\n httpOnly: false, secure: isProduction, sameSite: \"lax\",\n path: \"/\", maxAge: newTokens.expires_in,\n });\n return { authObj: null, response };\n }\n }\n } else {\n const refreshUrl = new URL(\"/api/auth/refresh\", req.url);\n const refreshRes = await fetch(refreshUrl.toString(), {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Cookie: req.headers.get(\"cookie\") ?? \"\",\n },\n });\n if (refreshRes.ok) {\n const response = NextResponse.next();\n const setCookies = refreshRes.headers.getSetCookie?.() ?? [];\n for (const cookie of setCookies) {\n response.headers.append(\"Set-Cookie\", cookie);\n }\n return { authObj: null, response };\n }\n }\n } catch {\n // Refresh failed, fall through to redirect\n }\n }\n\n const response = NextResponse.redirect(\n new URL(\n `${signInUrl}?returnTo=${encodeURIComponent(pathname)}`,\n req.url,\n ),\n );\n response.cookies.set(COOKIE_AUTH_TOKEN, \"\", { path: \"/\", maxAge: 0 });\n response.cookies.set(COOKIE_REFRESH_TOKEN, \"\", {\n path: \"/api/auth\",\n maxAge: 0,\n });\n response.cookies.set(COOKIE_AUTH_SESSION, \"\", { path: \"/\", maxAge: 0 });\n return { authObj: null, response };\n }\n\n const authObj = await buildAuthObject(token, jwksClient);\n if (!authObj) {\n return {\n authObj: null,\n response: NextResponse.redirect(new URL(signInUrl, req.url)),\n };\n }\n\n return { authObj };\n}\n\nexport function inaiAuthMiddleware(config: InAIMiddlewareConfig = {}) {\n const {\n authMode = \"app\",\n publicRoutes = [],\n signInUrl = \"/login\",\n beforeAuth,\n afterAuth,\n } = config;\n\n const builtinPublic = [\"/_next/*\", \"/favicon.ico\", \"/api/*\", signInUrl];\n const jwksClient = getJwksClient(config);\n\n return async function middleware(\n req: NextRequest,\n ): Promise<NextResponse> {\n if (beforeAuth) {\n const result = beforeAuth(req);\n if (result) return result;\n }\n\n if (isPublicRoute(req, publicRoutes, builtinPublic)) {\n return NextResponse.next();\n }\n\n const apiUrl = authMode === \"platform\" ? (config.apiUrl ?? DEFAULT_API_URL) : undefined;\n const { authObj, response } = await runAuthCheck(req, signInUrl, jwksClient, apiUrl);\n if (response) return response;\n if (!authObj)\n return NextResponse.redirect(new URL(signInUrl, req.url));\n\n if (afterAuth) {\n const result = afterAuth(authObj, req);\n if (result) return result;\n }\n\n return NextResponse.next();\n };\n}\n\nexport function withInAIAuth(\n wrappedMiddleware: (\n req: NextRequest,\n ) => NextResponse | Response | Promise<NextResponse | Response>,\n config: InAIMiddlewareConfig = {},\n): (req: NextRequest) => Promise<NextResponse> {\n const {\n authMode = \"app\",\n publicRoutes = [],\n signInUrl = \"/login\",\n beforeAuth,\n afterAuth,\n } = config;\n\n const builtinPublic = [\"/_next/*\", \"/favicon.ico\", \"/api/*\", signInUrl];\n const jwksClient = getJwksClient(config);\n\n return async function middleware(\n req: NextRequest,\n ): Promise<NextResponse> {\n if (beforeAuth) {\n const result = beforeAuth(req);\n if (result) return result;\n }\n\n const isPublic = isPublicRoute(req, publicRoutes, builtinPublic);\n\n if (!isPublic) {\n const apiUrl = authMode === \"platform\" ? (config.apiUrl ?? DEFAULT_API_URL) : undefined;\n const { authObj, response } = await runAuthCheck(req, signInUrl, jwksClient, apiUrl);\n if (response) return response;\n if (!authObj)\n return NextResponse.redirect(new URL(signInUrl, req.url));\n\n if (afterAuth) {\n const result = afterAuth(authObj, req);\n if (result) return result;\n }\n\n const authHeader = JSON.stringify({\n userId: authObj.userId,\n tenantId: authObj.tenantId,\n appId: authObj.appId,\n envId: authObj.envId,\n orgId: authObj.orgId,\n orgRole: authObj.orgRole,\n roles: authObj.roles,\n permissions: authObj.permissions,\n });\n req.headers.set(\"x-inai-auth\", authHeader);\n }\n\n const wrappedResponse = await wrappedMiddleware(req);\n if (wrappedResponse instanceof NextResponse) return wrappedResponse;\n return new NextResponse(wrappedResponse.body, wrappedResponse);\n };\n}\n"],"mappings":"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","names":["response"]}
|
package/dist/server.cjs
CHANGED
|
@@ -430,6 +430,8 @@ async function auth() {
|
|
|
430
430
|
orgId: null,
|
|
431
431
|
orgRole: null,
|
|
432
432
|
sessionId: null,
|
|
433
|
+
roles: [],
|
|
434
|
+
permissions: [],
|
|
433
435
|
getToken: async () => null,
|
|
434
436
|
has: () => false,
|
|
435
437
|
protect: () => {
|
|
@@ -448,6 +450,8 @@ async function auth() {
|
|
|
448
450
|
orgId: null,
|
|
449
451
|
orgRole: null,
|
|
450
452
|
sessionId: null,
|
|
453
|
+
roles: [],
|
|
454
|
+
permissions: [],
|
|
451
455
|
getToken: async () => null,
|
|
452
456
|
has: () => false,
|
|
453
457
|
protect: () => {
|
|
@@ -472,6 +476,8 @@ async function auth() {
|
|
|
472
476
|
orgId: claims.org_id ?? null,
|
|
473
477
|
orgRole: claims.org_role ?? null,
|
|
474
478
|
sessionId: null,
|
|
479
|
+
roles,
|
|
480
|
+
permissions,
|
|
475
481
|
isSignedIn: true,
|
|
476
482
|
getToken: async () => token,
|
|
477
483
|
has
|
|
@@ -484,6 +490,8 @@ async function auth() {
|
|
|
484
490
|
orgId: claims.org_id ?? null,
|
|
485
491
|
orgRole: claims.org_role ?? null,
|
|
486
492
|
sessionId: null,
|
|
493
|
+
roles,
|
|
494
|
+
permissions,
|
|
487
495
|
getToken: async () => token,
|
|
488
496
|
has,
|
|
489
497
|
protect: (params) => {
|
package/dist/server.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/server.ts","../src/cookies.ts","../src/config.ts","../src/api-routes.ts","../src/platform-api-routes.ts"],"sourcesContent":["import { cookies } from \"next/headers\";\nimport { redirect } from \"next/navigation\";\nimport type {\n AuthObject,\n ServerAuthObject,\n ProtectedAuthObject,\n UserResource,\n PlatformUserResource,\n} from \"@inai-dev/types\";\nimport { InAIAuthClient } from \"@inai-dev/backend\";\nimport { isTokenExpired, getClaimsFromToken } from \"@inai-dev/shared\";\nimport {\n getAuthTokenFromCookies,\n getSessionFromCookies,\n} from \"./cookies\";\nimport { getAuthConfig } from \"./config\";\n\nexport { createAuthRoutes } from \"./api-routes\";\nexport { createPlatformAuthRoutes } from \"./platform-api-routes\";\nexport { configureAuth, getAuthConfig } from \"./config\";\nexport { setAuthCookies, clearAuthCookies, getRefreshTokenFromCookies, getAuthTokenFromCookies } from \"./cookies\";\n\nexport async function auth(): Promise<ServerAuthObject> {\n const cookieStore = await cookies();\n const token = getAuthTokenFromCookies(cookieStore);\n const config = getAuthConfig();\n\n function redirectToSignIn(opts?: { returnTo?: string }): never {\n const returnTo = opts?.returnTo;\n const url = returnTo\n ? `${config.signInUrl}?returnTo=${encodeURIComponent(returnTo)}`\n : config.signInUrl;\n redirect(url);\n }\n\n if (!token || isTokenExpired(token)) {\n return {\n userId: null,\n tenantId: null,\n appId: null,\n envId: null,\n orgId: null,\n orgRole: null,\n sessionId: null,\n getToken: async () => null,\n has: () => false,\n protect: () => {\n redirectToSignIn();\n },\n redirectToSignIn,\n };\n }\n\n const claims = getClaimsFromToken(token);\n if (!claims) {\n return {\n userId: null,\n tenantId: null,\n appId: null,\n envId: null,\n orgId: null,\n orgRole: null,\n sessionId: null,\n getToken: async () => null,\n has: () => false,\n protect: () => {\n redirectToSignIn();\n },\n redirectToSignIn,\n };\n }\n\n const roles = claims.roles ?? [];\n const permissions = claims.permissions ?? [];\n\n const has = (params: { role?: string; permission?: string }) => {\n if (params.role && roles.includes(params.role)) return true;\n if (params.permission && permissions.includes(params.permission))\n return true;\n return false;\n };\n\n const protectedObj: ProtectedAuthObject = {\n userId: claims.sub,\n tenantId: claims.tenant_id,\n appId: claims.app_id ?? null,\n envId: claims.env_id ?? null,\n orgId: claims.org_id ?? null,\n orgRole: claims.org_role ?? null,\n sessionId: null,\n isSignedIn: true,\n getToken: async () => token,\n has,\n };\n\n return {\n userId: claims.sub,\n tenantId: claims.tenant_id,\n appId: claims.app_id ?? null,\n envId: claims.env_id ?? null,\n orgId: claims.org_id ?? null,\n orgRole: claims.org_role ?? null,\n sessionId: null,\n getToken: async () => token,\n has,\n protect: (params?: {\n role?: string;\n permission?: string;\n redirectTo?: string;\n }) => {\n if (params?.role || params?.permission) {\n if (!has({ role: params.role, permission: params.permission })) {\n redirect(params.redirectTo ?? \"/unauthorized\");\n }\n }\n return protectedObj;\n },\n redirectToSignIn,\n };\n}\n\nexport async function currentUser(\n opts?: { fresh?: boolean },\n): Promise<UserResource | PlatformUserResource | null> {\n const cookieStore = await cookies();\n\n if (opts?.fresh) {\n const token = getAuthTokenFromCookies(cookieStore);\n if (!token || isTokenExpired(token)) return null;\n\n const config = getAuthConfig();\n if (!config.apiUrl || !config.publishableKey) {\n const session = getSessionFromCookies(cookieStore);\n return session?.user ?? null;\n }\n\n const client = new InAIAuthClient({\n apiUrl: config.apiUrl,\n publishableKey: config.publishableKey,\n });\n try {\n const { data } = await client.getMe(token);\n return data;\n } catch {\n return null;\n }\n }\n\n const session = getSessionFromCookies(cookieStore);\n return session?.user ?? null;\n}\n","import type { UserResource, PlatformUserResource, JWTClaims, TokenPair } from \"@inai-dev/types\";\nimport {\n COOKIE_AUTH_TOKEN,\n COOKIE_REFRESH_TOKEN,\n COOKIE_AUTH_SESSION,\n decodeJWTPayload,\n} from \"@inai-dev/shared\";\n\nexport {\n COOKIE_AUTH_TOKEN,\n COOKIE_REFRESH_TOKEN,\n COOKIE_AUTH_SESSION,\n} from \"@inai-dev/shared\";\n\nexport { isTokenExpired, getClaimsFromToken } from \"@inai-dev/shared\";\n\ninterface CookieStore {\n get(name: string): { value: string } | undefined;\n set(name: string, value: string, options?: Record<string, unknown>): void;\n}\n\ninterface SessionData {\n user: UserResource | PlatformUserResource;\n expiresAt: string;\n permissions?: string[];\n orgId?: string;\n orgRole?: string;\n appId?: string;\n envId?: string;\n}\n\nexport function setAuthCookies(\n cookieStore: CookieStore,\n tokens: TokenPair,\n user: UserResource | PlatformUserResource,\n): void {\n const isProduction = process.env.NODE_ENV === \"production\";\n const claims = decodeJWTPayload(tokens.access_token);\n const expiresAt = claims\n ? new Date(claims.exp * 1000).toISOString()\n : new Date(Date.now() + tokens.expires_in * 1000).toISOString();\n\n cookieStore.set(COOKIE_AUTH_TOKEN, tokens.access_token, {\n httpOnly: true,\n secure: isProduction,\n sameSite: \"lax\",\n path: \"/\",\n maxAge: tokens.expires_in,\n });\n\n cookieStore.set(COOKIE_REFRESH_TOKEN, tokens.refresh_token, {\n httpOnly: true,\n secure: isProduction,\n sameSite: \"strict\",\n path: \"/api/auth\",\n maxAge: 7 * 24 * 60 * 60,\n });\n\n const sessionData: SessionData = {\n user,\n expiresAt,\n permissions: claims?.permissions ?? [],\n orgId: claims?.org_id,\n orgRole: claims?.org_role,\n appId: claims?.app_id,\n envId: claims?.env_id,\n };\n cookieStore.set(COOKIE_AUTH_SESSION, JSON.stringify(sessionData), {\n httpOnly: false,\n secure: isProduction,\n sameSite: \"lax\",\n path: \"/\",\n maxAge: tokens.expires_in,\n });\n}\n\nexport function clearAuthCookies(\n cookieStore: CookieStore,\n): void {\n const opts = { path: \"/\", maxAge: 0 };\n cookieStore.set(COOKIE_AUTH_TOKEN, \"\", opts);\n cookieStore.set(COOKIE_REFRESH_TOKEN, \"\", { ...opts, path: \"/api/auth\" });\n cookieStore.set(COOKIE_AUTH_SESSION, \"\", opts);\n}\n\nexport function getAuthTokenFromCookies(\n cookieStore: CookieStore,\n): string | null {\n return cookieStore.get(COOKIE_AUTH_TOKEN)?.value ?? null;\n}\n\nexport function getRefreshTokenFromCookies(\n cookieStore: CookieStore,\n): string | null {\n return cookieStore.get(COOKIE_REFRESH_TOKEN)?.value ?? null;\n}\n\nexport function getSessionFromCookies(\n cookieStore: CookieStore,\n): SessionData | null {\n const raw = cookieStore.get(COOKIE_AUTH_SESSION)?.value;\n if (!raw) return null;\n try {\n return JSON.parse(raw) as SessionData;\n } catch {\n return null;\n }\n}\n","import type { InAIAuthSDKConfig } from \"@inai-dev/types\";\nimport { DEFAULT_API_URL } from \"@inai-dev/shared\";\n\ntype ResolvedConfig = Required<InAIAuthSDKConfig>;\n\nconst defaults: ResolvedConfig = {\n signInUrl: \"/login\",\n signUpUrl: \"/register\",\n afterSignInUrl: \"/\",\n afterSignOutUrl: \"/login\",\n apiUrl: DEFAULT_API_URL,\n publishableKey: \"\",\n};\n\nlet userConfig: Partial<InAIAuthSDKConfig> = {};\n\nexport function configureAuth(config: InAIAuthSDKConfig): void {\n userConfig = config;\n}\n\nexport function getAuthConfig(): ResolvedConfig {\n return {\n signInUrl: userConfig.signInUrl ?? defaults.signInUrl,\n signUpUrl: userConfig.signUpUrl ?? defaults.signUpUrl,\n afterSignInUrl: userConfig.afterSignInUrl ?? defaults.afterSignInUrl,\n afterSignOutUrl: userConfig.afterSignOutUrl ?? defaults.afterSignOutUrl,\n apiUrl:\n userConfig.apiUrl ??\n defaults.apiUrl,\n publishableKey:\n userConfig.publishableKey ??\n process.env.INAI_PUBLISHABLE_KEY ??\n defaults.publishableKey,\n };\n}\n","import { cookies } from \"next/headers\";\nimport { NextResponse } from \"next/server\";\nimport type { NextRequest } from \"next/server\";\nimport { InAIAuthClient } from \"@inai-dev/backend\";\nimport type {\n InAIAuthConfig,\n TokenPair,\n UserResource,\n LoginResult,\n} from \"@inai-dev/types\";\nimport {\n setAuthCookies,\n clearAuthCookies,\n getRefreshTokenFromCookies,\n} from \"./cookies\";\n\nexport function createAuthRoutes(config: InAIAuthConfig = {}) {\n const client = new InAIAuthClient(config);\n\n async function handleLogin(req: NextRequest) {\n try {\n const body = (await req.json()) as Record<string, string>;\n const result = (await client.login({\n email: body.email,\n password: body.password,\n })) as LoginResult & { user?: UserResource };\n\n if (result.mfa_required) {\n return NextResponse.json({\n mfa_required: true,\n mfa_token: result.mfa_token,\n });\n }\n\n const tokens = result as TokenPair;\n const loginUser = (result as { user?: UserResource }).user;\n const user =\n loginUser ?? (await client.getMe(tokens.access_token)).data;\n const cookieStore = await cookies();\n setAuthCookies(cookieStore, tokens, user);\n\n return NextResponse.json({ user });\n } catch (err) {\n const message = err instanceof Error ? err.message : \"Login failed\";\n return NextResponse.json({ error: message }, { status: 401 });\n }\n }\n\n async function handleMFAChallenge(req: NextRequest) {\n try {\n const body = (await req.json()) as Record<string, string>;\n const tokens = await client.mfaChallenge({\n mfa_token: body.mfa_token,\n code: body.code,\n });\n\n const { data: user } = await client.getMe(tokens.access_token);\n const cookieStore = await cookies();\n setAuthCookies(cookieStore, tokens, user);\n\n return NextResponse.json({ user });\n } catch (err) {\n const message =\n err instanceof Error ? err.message : \"MFA verification failed\";\n return NextResponse.json({ error: message }, { status: 401 });\n }\n }\n\n async function handleRefresh() {\n try {\n const cookieStore = await cookies();\n const refreshToken = getRefreshTokenFromCookies(cookieStore);\n\n if (!refreshToken) {\n clearAuthCookies(cookieStore);\n return NextResponse.json(\n { error: \"No refresh token\" },\n { status: 401 },\n );\n }\n\n const tokens = await client.refresh(refreshToken);\n const { data: user } = await client.getMe(tokens.access_token);\n setAuthCookies(cookieStore, tokens, user);\n\n return NextResponse.json({ user });\n } catch {\n const cookieStore = await cookies();\n clearAuthCookies(cookieStore);\n return NextResponse.json(\n { error: \"Refresh failed\" },\n { status: 401 },\n );\n }\n }\n\n async function handleRegister(req: NextRequest) {\n try {\n const body = (await req.json()) as Record<string, string>;\n const result = await client.register({\n email: body.email,\n password: body.password,\n firstName: body.firstName,\n lastName: body.lastName,\n });\n\n if (!result.access_token) {\n return NextResponse.json({\n needs_email_verification: true,\n user: result.user,\n });\n }\n\n const tokens = result as TokenPair;\n const loginUser = result.user;\n const user =\n loginUser ?? (await client.getMe(tokens.access_token)).data;\n const cookieStore = await cookies();\n setAuthCookies(cookieStore, tokens, user);\n\n return NextResponse.json({ user });\n } catch (err) {\n const message =\n err instanceof Error ? err.message : \"Registration failed\";\n return NextResponse.json({ error: message }, { status: 400 });\n }\n }\n\n async function handleLogout() {\n try {\n const cookieStore = await cookies();\n const refreshToken = getRefreshTokenFromCookies(cookieStore);\n if (refreshToken) {\n await client.logout(refreshToken).catch(() => {});\n }\n clearAuthCookies(cookieStore);\n return NextResponse.json({ success: true });\n } catch {\n const cookieStore = await cookies();\n clearAuthCookies(cookieStore);\n return NextResponse.json({ success: true });\n }\n }\n\n async function handler(\n req: NextRequest,\n context: { params: Promise<{ inai: string[] }> },\n ) {\n const params = await context.params;\n const path = params.inai?.join(\"/\") ?? \"\";\n\n if (req.method === \"POST\") {\n switch (path) {\n case \"login\":\n return handleLogin(req);\n case \"register\":\n return handleRegister(req);\n case \"mfa-challenge\":\n return handleMFAChallenge(req);\n case \"refresh\":\n return handleRefresh();\n case \"logout\":\n return handleLogout();\n }\n }\n\n return NextResponse.json({ error: \"Not found\" }, { status: 404 });\n }\n\n return {\n GET: handler,\n POST: handler,\n };\n}\n","import { cookies } from \"next/headers\";\nimport { NextResponse } from \"next/server\";\nimport type { NextRequest } from \"next/server\";\nimport { InAIAuthClient } from \"@inai-dev/backend\";\nimport type { InAIAuthConfig, TokenPair, PlatformUserResource } from \"@inai-dev/types\";\nimport {\n COOKIE_AUTH_TOKEN,\n COOKIE_AUTH_SESSION,\n COOKIE_REFRESH_TOKEN,\n} from \"@inai-dev/shared\";\n\nexport function createPlatformAuthRoutes(config: InAIAuthConfig = {}) {\n const client = new InAIAuthClient(config);\n const isProduction = process.env.NODE_ENV === \"production\";\n\n function setPlatformCookies(\n cookieStore: Awaited<ReturnType<typeof cookies>>,\n tokens: TokenPair,\n user?: PlatformUserResource,\n ) {\n cookieStore.set(COOKIE_AUTH_TOKEN, tokens.access_token, {\n httpOnly: true,\n secure: isProduction,\n sameSite: \"lax\",\n path: \"/\",\n maxAge: tokens.expires_in,\n });\n cookieStore.set(COOKIE_REFRESH_TOKEN, tokens.refresh_token, {\n httpOnly: true,\n secure: isProduction,\n sameSite: \"strict\",\n path: \"/api/auth\",\n maxAge: 7 * 24 * 60 * 60,\n });\n if (user) {\n const expiresAt = Date.now() + tokens.expires_in * 1000;\n cookieStore.set(\n COOKIE_AUTH_SESSION,\n JSON.stringify({ user, expiresAt }),\n {\n httpOnly: false,\n secure: isProduction,\n sameSite: \"lax\",\n path: \"/\",\n maxAge: tokens.expires_in,\n },\n );\n }\n }\n\n function clearPlatformCookies(\n cookieStore: Awaited<ReturnType<typeof cookies>>,\n ) {\n cookieStore.set(COOKIE_AUTH_TOKEN, \"\", { path: \"/\", maxAge: 0 });\n cookieStore.set(COOKIE_REFRESH_TOKEN, \"\", {\n path: \"/api/auth\",\n maxAge: 0,\n });\n cookieStore.set(COOKIE_AUTH_SESSION, \"\", { path: \"/\", maxAge: 0 });\n }\n\n async function handleLogin(req: NextRequest) {\n try {\n const body = (await req.json()) as Record<string, string>;\n const result = await client.platformLogin({\n email: body.email,\n password: body.password,\n });\n\n if (result.mfa_required) {\n return NextResponse.json({\n mfa_required: true,\n mfa_token: result.mfa_token,\n });\n }\n\n const tokens = result as TokenPair;\n const user = result.user;\n const cookieStore = await cookies();\n setPlatformCookies(cookieStore, tokens, user);\n\n return NextResponse.json({ user });\n } catch (err) {\n const message = err instanceof Error ? err.message : \"Login failed\";\n return NextResponse.json({ error: message }, { status: 401 });\n }\n }\n\n async function handleMFAChallenge(req: NextRequest) {\n try {\n const body = (await req.json()) as Record<string, string>;\n const result = await client.platformMfaChallenge({\n mfa_token: body.mfa_token,\n code: body.code,\n });\n\n const tokens = result as TokenPair;\n const user = result.user;\n const cookieStore = await cookies();\n setPlatformCookies(cookieStore, tokens, user);\n\n return NextResponse.json({ user });\n } catch (err) {\n const message =\n err instanceof Error ? err.message : \"MFA verification failed\";\n return NextResponse.json({ error: message }, { status: 401 });\n }\n }\n\n async function handleRefresh() {\n try {\n const cookieStore = await cookies();\n const refreshToken = cookieStore.get(COOKIE_REFRESH_TOKEN)?.value;\n\n if (!refreshToken) {\n clearPlatformCookies(cookieStore);\n return NextResponse.json(\n { error: \"No refresh token\" },\n { status: 401 },\n );\n }\n\n const tokens = await client.platformRefresh(refreshToken);\n const { data: user } = await client.platformGetMe(\n tokens.access_token,\n );\n setPlatformCookies(cookieStore, tokens, user);\n\n return NextResponse.json({ user });\n } catch {\n const cookieStore = await cookies();\n clearPlatformCookies(cookieStore);\n return NextResponse.json(\n { error: \"Refresh failed\" },\n { status: 401 },\n );\n }\n }\n\n async function handleLogout() {\n try {\n const cookieStore = await cookies();\n const refreshToken = cookieStore.get(COOKIE_REFRESH_TOKEN)?.value;\n if (refreshToken) {\n await client.platformLogout(refreshToken).catch(() => {});\n }\n clearPlatformCookies(cookieStore);\n return NextResponse.json({ success: true });\n } catch {\n const cookieStore = await cookies();\n clearPlatformCookies(cookieStore);\n return NextResponse.json({ success: true });\n }\n }\n\n async function handler(\n req: NextRequest,\n context: { params: Promise<{ inai: string[] }> },\n ) {\n const params = await context.params;\n const path = params.inai?.join(\"/\") ?? \"\";\n\n if (req.method === \"POST\") {\n switch (path) {\n case \"login\":\n return handleLogin(req);\n case \"mfa-challenge\":\n return handleMFAChallenge(req);\n case \"refresh\":\n return handleRefresh();\n case \"logout\":\n return handleLogout();\n }\n }\n\n return NextResponse.json({ error: \"Not found\" }, { status: 404 });\n }\n\n return {\n GET: handler,\n POST: handler,\n };\n}\n"],"mappings":"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","names":["import_headers","import_backend","import_shared","import_shared","import_shared","import_headers","import_server","import_backend","import_shared","session"]}
|
|
1
|
+
{"version":3,"sources":["../src/server.ts","../src/cookies.ts","../src/config.ts","../src/api-routes.ts","../src/platform-api-routes.ts"],"sourcesContent":["import { cookies } from \"next/headers\";\nimport { redirect } from \"next/navigation\";\nimport type {\n AuthObject,\n ServerAuthObject,\n ProtectedAuthObject,\n UserResource,\n PlatformUserResource,\n} from \"@inai-dev/types\";\nimport { InAIAuthClient } from \"@inai-dev/backend\";\nimport { isTokenExpired, getClaimsFromToken } from \"@inai-dev/shared\";\nimport {\n getAuthTokenFromCookies,\n getSessionFromCookies,\n} from \"./cookies\";\nimport { getAuthConfig } from \"./config\";\n\nexport { createAuthRoutes } from \"./api-routes\";\nexport { createPlatformAuthRoutes } from \"./platform-api-routes\";\nexport { configureAuth, getAuthConfig } from \"./config\";\nexport { setAuthCookies, clearAuthCookies, getRefreshTokenFromCookies, getAuthTokenFromCookies } from \"./cookies\";\n\nexport async function auth(): Promise<ServerAuthObject> {\n const cookieStore = await cookies();\n const token = getAuthTokenFromCookies(cookieStore);\n const config = getAuthConfig();\n\n function redirectToSignIn(opts?: { returnTo?: string }): never {\n const returnTo = opts?.returnTo;\n const url = returnTo\n ? `${config.signInUrl}?returnTo=${encodeURIComponent(returnTo)}`\n : config.signInUrl;\n redirect(url);\n }\n\n if (!token || isTokenExpired(token)) {\n return {\n userId: null,\n tenantId: null,\n appId: null,\n envId: null,\n orgId: null,\n orgRole: null,\n sessionId: null,\n roles: [],\n permissions: [],\n getToken: async () => null,\n has: () => false,\n protect: () => {\n redirectToSignIn();\n },\n redirectToSignIn,\n };\n }\n\n const claims = getClaimsFromToken(token);\n if (!claims) {\n return {\n userId: null,\n tenantId: null,\n appId: null,\n envId: null,\n orgId: null,\n orgRole: null,\n sessionId: null,\n roles: [],\n permissions: [],\n getToken: async () => null,\n has: () => false,\n protect: () => {\n redirectToSignIn();\n },\n redirectToSignIn,\n };\n }\n\n const roles = claims.roles ?? [];\n const permissions = claims.permissions ?? [];\n\n const has = (params: { role?: string; permission?: string }) => {\n if (params.role && roles.includes(params.role)) return true;\n if (params.permission && permissions.includes(params.permission))\n return true;\n return false;\n };\n\n const protectedObj: ProtectedAuthObject = {\n userId: claims.sub,\n tenantId: claims.tenant_id,\n appId: claims.app_id ?? null,\n envId: claims.env_id ?? null,\n orgId: claims.org_id ?? null,\n orgRole: claims.org_role ?? null,\n sessionId: null,\n roles,\n permissions,\n isSignedIn: true,\n getToken: async () => token,\n has,\n };\n\n return {\n userId: claims.sub,\n tenantId: claims.tenant_id,\n appId: claims.app_id ?? null,\n envId: claims.env_id ?? null,\n orgId: claims.org_id ?? null,\n orgRole: claims.org_role ?? null,\n sessionId: null,\n roles,\n permissions,\n getToken: async () => token,\n has,\n protect: (params?: {\n role?: string;\n permission?: string;\n redirectTo?: string;\n }) => {\n if (params?.role || params?.permission) {\n if (!has({ role: params.role, permission: params.permission })) {\n redirect(params.redirectTo ?? \"/unauthorized\");\n }\n }\n return protectedObj;\n },\n redirectToSignIn,\n };\n}\n\nexport async function currentUser(\n opts?: { fresh?: boolean },\n): Promise<UserResource | PlatformUserResource | null> {\n const cookieStore = await cookies();\n\n if (opts?.fresh) {\n const token = getAuthTokenFromCookies(cookieStore);\n if (!token || isTokenExpired(token)) return null;\n\n const config = getAuthConfig();\n if (!config.apiUrl || !config.publishableKey) {\n const session = getSessionFromCookies(cookieStore);\n return session?.user ?? null;\n }\n\n const client = new InAIAuthClient({\n apiUrl: config.apiUrl,\n publishableKey: config.publishableKey,\n });\n try {\n const { data } = await client.getMe(token);\n return data;\n } catch {\n return null;\n }\n }\n\n const session = getSessionFromCookies(cookieStore);\n return session?.user ?? null;\n}\n","import type { UserResource, PlatformUserResource, JWTClaims, TokenPair } from \"@inai-dev/types\";\nimport {\n COOKIE_AUTH_TOKEN,\n COOKIE_REFRESH_TOKEN,\n COOKIE_AUTH_SESSION,\n decodeJWTPayload,\n} from \"@inai-dev/shared\";\n\nexport {\n COOKIE_AUTH_TOKEN,\n COOKIE_REFRESH_TOKEN,\n COOKIE_AUTH_SESSION,\n} from \"@inai-dev/shared\";\n\nexport { isTokenExpired, getClaimsFromToken } from \"@inai-dev/shared\";\n\ninterface CookieStore {\n get(name: string): { value: string } | undefined;\n set(name: string, value: string, options?: Record<string, unknown>): void;\n}\n\ninterface SessionData {\n user: UserResource | PlatformUserResource;\n expiresAt: string;\n permissions?: string[];\n orgId?: string;\n orgRole?: string;\n appId?: string;\n envId?: string;\n}\n\nexport function setAuthCookies(\n cookieStore: CookieStore,\n tokens: TokenPair,\n user: UserResource | PlatformUserResource,\n): void {\n const isProduction = process.env.NODE_ENV === \"production\";\n const claims = decodeJWTPayload(tokens.access_token);\n const expiresAt = claims\n ? new Date(claims.exp * 1000).toISOString()\n : new Date(Date.now() + tokens.expires_in * 1000).toISOString();\n\n cookieStore.set(COOKIE_AUTH_TOKEN, tokens.access_token, {\n httpOnly: true,\n secure: isProduction,\n sameSite: \"lax\",\n path: \"/\",\n maxAge: tokens.expires_in,\n });\n\n cookieStore.set(COOKIE_REFRESH_TOKEN, tokens.refresh_token, {\n httpOnly: true,\n secure: isProduction,\n sameSite: \"strict\",\n path: \"/api/auth\",\n maxAge: 7 * 24 * 60 * 60,\n });\n\n const sessionData: SessionData = {\n user,\n expiresAt,\n permissions: claims?.permissions ?? [],\n orgId: claims?.org_id,\n orgRole: claims?.org_role,\n appId: claims?.app_id,\n envId: claims?.env_id,\n };\n cookieStore.set(COOKIE_AUTH_SESSION, JSON.stringify(sessionData), {\n httpOnly: false,\n secure: isProduction,\n sameSite: \"lax\",\n path: \"/\",\n maxAge: tokens.expires_in,\n });\n}\n\nexport function clearAuthCookies(\n cookieStore: CookieStore,\n): void {\n const opts = { path: \"/\", maxAge: 0 };\n cookieStore.set(COOKIE_AUTH_TOKEN, \"\", opts);\n cookieStore.set(COOKIE_REFRESH_TOKEN, \"\", { ...opts, path: \"/api/auth\" });\n cookieStore.set(COOKIE_AUTH_SESSION, \"\", opts);\n}\n\nexport function getAuthTokenFromCookies(\n cookieStore: CookieStore,\n): string | null {\n return cookieStore.get(COOKIE_AUTH_TOKEN)?.value ?? null;\n}\n\nexport function getRefreshTokenFromCookies(\n cookieStore: CookieStore,\n): string | null {\n return cookieStore.get(COOKIE_REFRESH_TOKEN)?.value ?? null;\n}\n\nexport function getSessionFromCookies(\n cookieStore: CookieStore,\n): SessionData | null {\n const raw = cookieStore.get(COOKIE_AUTH_SESSION)?.value;\n if (!raw) return null;\n try {\n return JSON.parse(raw) as SessionData;\n } catch {\n return null;\n }\n}\n","import type { InAIAuthSDKConfig } from \"@inai-dev/types\";\nimport { DEFAULT_API_URL } from \"@inai-dev/shared\";\n\ntype ResolvedConfig = Required<InAIAuthSDKConfig>;\n\nconst defaults: ResolvedConfig = {\n signInUrl: \"/login\",\n signUpUrl: \"/register\",\n afterSignInUrl: \"/\",\n afterSignOutUrl: \"/login\",\n apiUrl: DEFAULT_API_URL,\n publishableKey: \"\",\n};\n\nlet userConfig: Partial<InAIAuthSDKConfig> = {};\n\nexport function configureAuth(config: InAIAuthSDKConfig): void {\n userConfig = config;\n}\n\nexport function getAuthConfig(): ResolvedConfig {\n return {\n signInUrl: userConfig.signInUrl ?? defaults.signInUrl,\n signUpUrl: userConfig.signUpUrl ?? defaults.signUpUrl,\n afterSignInUrl: userConfig.afterSignInUrl ?? defaults.afterSignInUrl,\n afterSignOutUrl: userConfig.afterSignOutUrl ?? defaults.afterSignOutUrl,\n apiUrl:\n userConfig.apiUrl ??\n defaults.apiUrl,\n publishableKey:\n userConfig.publishableKey ??\n process.env.INAI_PUBLISHABLE_KEY ??\n defaults.publishableKey,\n };\n}\n","import { cookies } from \"next/headers\";\nimport { NextResponse } from \"next/server\";\nimport type { NextRequest } from \"next/server\";\nimport { InAIAuthClient } from \"@inai-dev/backend\";\nimport type {\n InAIAuthConfig,\n TokenPair,\n UserResource,\n LoginResult,\n} from \"@inai-dev/types\";\nimport {\n setAuthCookies,\n clearAuthCookies,\n getRefreshTokenFromCookies,\n} from \"./cookies\";\n\nexport function createAuthRoutes(config: InAIAuthConfig = {}) {\n const client = new InAIAuthClient(config);\n\n async function handleLogin(req: NextRequest) {\n try {\n const body = (await req.json()) as Record<string, string>;\n const result = (await client.login({\n email: body.email,\n password: body.password,\n })) as LoginResult & { user?: UserResource };\n\n if (result.mfa_required) {\n return NextResponse.json({\n mfa_required: true,\n mfa_token: result.mfa_token,\n });\n }\n\n const tokens = result as TokenPair;\n const loginUser = (result as { user?: UserResource }).user;\n const user =\n loginUser ?? (await client.getMe(tokens.access_token)).data;\n const cookieStore = await cookies();\n setAuthCookies(cookieStore, tokens, user);\n\n return NextResponse.json({ user });\n } catch (err) {\n const message = err instanceof Error ? err.message : \"Login failed\";\n return NextResponse.json({ error: message }, { status: 401 });\n }\n }\n\n async function handleMFAChallenge(req: NextRequest) {\n try {\n const body = (await req.json()) as Record<string, string>;\n const tokens = await client.mfaChallenge({\n mfa_token: body.mfa_token,\n code: body.code,\n });\n\n const { data: user } = await client.getMe(tokens.access_token);\n const cookieStore = await cookies();\n setAuthCookies(cookieStore, tokens, user);\n\n return NextResponse.json({ user });\n } catch (err) {\n const message =\n err instanceof Error ? err.message : \"MFA verification failed\";\n return NextResponse.json({ error: message }, { status: 401 });\n }\n }\n\n async function handleRefresh() {\n try {\n const cookieStore = await cookies();\n const refreshToken = getRefreshTokenFromCookies(cookieStore);\n\n if (!refreshToken) {\n clearAuthCookies(cookieStore);\n return NextResponse.json(\n { error: \"No refresh token\" },\n { status: 401 },\n );\n }\n\n const tokens = await client.refresh(refreshToken);\n const { data: user } = await client.getMe(tokens.access_token);\n setAuthCookies(cookieStore, tokens, user);\n\n return NextResponse.json({ user });\n } catch {\n const cookieStore = await cookies();\n clearAuthCookies(cookieStore);\n return NextResponse.json(\n { error: \"Refresh failed\" },\n { status: 401 },\n );\n }\n }\n\n async function handleRegister(req: NextRequest) {\n try {\n const body = (await req.json()) as Record<string, string>;\n const result = await client.register({\n email: body.email,\n password: body.password,\n firstName: body.firstName,\n lastName: body.lastName,\n });\n\n if (!result.access_token) {\n return NextResponse.json({\n needs_email_verification: true,\n user: result.user,\n });\n }\n\n const tokens = result as TokenPair;\n const loginUser = result.user;\n const user =\n loginUser ?? (await client.getMe(tokens.access_token)).data;\n const cookieStore = await cookies();\n setAuthCookies(cookieStore, tokens, user);\n\n return NextResponse.json({ user });\n } catch (err) {\n const message =\n err instanceof Error ? err.message : \"Registration failed\";\n return NextResponse.json({ error: message }, { status: 400 });\n }\n }\n\n async function handleLogout() {\n try {\n const cookieStore = await cookies();\n const refreshToken = getRefreshTokenFromCookies(cookieStore);\n if (refreshToken) {\n await client.logout(refreshToken).catch(() => {});\n }\n clearAuthCookies(cookieStore);\n return NextResponse.json({ success: true });\n } catch {\n const cookieStore = await cookies();\n clearAuthCookies(cookieStore);\n return NextResponse.json({ success: true });\n }\n }\n\n async function handler(\n req: NextRequest,\n context: { params: Promise<{ inai: string[] }> },\n ) {\n const params = await context.params;\n const path = params.inai?.join(\"/\") ?? \"\";\n\n if (req.method === \"POST\") {\n switch (path) {\n case \"login\":\n return handleLogin(req);\n case \"register\":\n return handleRegister(req);\n case \"mfa-challenge\":\n return handleMFAChallenge(req);\n case \"refresh\":\n return handleRefresh();\n case \"logout\":\n return handleLogout();\n }\n }\n\n return NextResponse.json({ error: \"Not found\" }, { status: 404 });\n }\n\n return {\n GET: handler,\n POST: handler,\n };\n}\n","import { cookies } from \"next/headers\";\nimport { NextResponse } from \"next/server\";\nimport type { NextRequest } from \"next/server\";\nimport { InAIAuthClient } from \"@inai-dev/backend\";\nimport type { InAIAuthConfig, TokenPair, PlatformUserResource } from \"@inai-dev/types\";\nimport {\n COOKIE_AUTH_TOKEN,\n COOKIE_AUTH_SESSION,\n COOKIE_REFRESH_TOKEN,\n} from \"@inai-dev/shared\";\n\nexport function createPlatformAuthRoutes(config: InAIAuthConfig = {}) {\n const client = new InAIAuthClient(config);\n const isProduction = process.env.NODE_ENV === \"production\";\n\n function setPlatformCookies(\n cookieStore: Awaited<ReturnType<typeof cookies>>,\n tokens: TokenPair,\n user?: PlatformUserResource,\n ) {\n cookieStore.set(COOKIE_AUTH_TOKEN, tokens.access_token, {\n httpOnly: true,\n secure: isProduction,\n sameSite: \"lax\",\n path: \"/\",\n maxAge: tokens.expires_in,\n });\n cookieStore.set(COOKIE_REFRESH_TOKEN, tokens.refresh_token, {\n httpOnly: true,\n secure: isProduction,\n sameSite: \"strict\",\n path: \"/api/auth\",\n maxAge: 7 * 24 * 60 * 60,\n });\n if (user) {\n const expiresAt = Date.now() + tokens.expires_in * 1000;\n cookieStore.set(\n COOKIE_AUTH_SESSION,\n JSON.stringify({ user, expiresAt }),\n {\n httpOnly: false,\n secure: isProduction,\n sameSite: \"lax\",\n path: \"/\",\n maxAge: tokens.expires_in,\n },\n );\n }\n }\n\n function clearPlatformCookies(\n cookieStore: Awaited<ReturnType<typeof cookies>>,\n ) {\n cookieStore.set(COOKIE_AUTH_TOKEN, \"\", { path: \"/\", maxAge: 0 });\n cookieStore.set(COOKIE_REFRESH_TOKEN, \"\", {\n path: \"/api/auth\",\n maxAge: 0,\n });\n cookieStore.set(COOKIE_AUTH_SESSION, \"\", { path: \"/\", maxAge: 0 });\n }\n\n async function handleLogin(req: NextRequest) {\n try {\n const body = (await req.json()) as Record<string, string>;\n const result = await client.platformLogin({\n email: body.email,\n password: body.password,\n });\n\n if (result.mfa_required) {\n return NextResponse.json({\n mfa_required: true,\n mfa_token: result.mfa_token,\n });\n }\n\n const tokens = result as TokenPair;\n const user = result.user;\n const cookieStore = await cookies();\n setPlatformCookies(cookieStore, tokens, user);\n\n return NextResponse.json({ user });\n } catch (err) {\n const message = err instanceof Error ? err.message : \"Login failed\";\n return NextResponse.json({ error: message }, { status: 401 });\n }\n }\n\n async function handleMFAChallenge(req: NextRequest) {\n try {\n const body = (await req.json()) as Record<string, string>;\n const result = await client.platformMfaChallenge({\n mfa_token: body.mfa_token,\n code: body.code,\n });\n\n const tokens = result as TokenPair;\n const user = result.user;\n const cookieStore = await cookies();\n setPlatformCookies(cookieStore, tokens, user);\n\n return NextResponse.json({ user });\n } catch (err) {\n const message =\n err instanceof Error ? err.message : \"MFA verification failed\";\n return NextResponse.json({ error: message }, { status: 401 });\n }\n }\n\n async function handleRefresh() {\n try {\n const cookieStore = await cookies();\n const refreshToken = cookieStore.get(COOKIE_REFRESH_TOKEN)?.value;\n\n if (!refreshToken) {\n clearPlatformCookies(cookieStore);\n return NextResponse.json(\n { error: \"No refresh token\" },\n { status: 401 },\n );\n }\n\n const tokens = await client.platformRefresh(refreshToken);\n const { data: user } = await client.platformGetMe(\n tokens.access_token,\n );\n setPlatformCookies(cookieStore, tokens, user);\n\n return NextResponse.json({ user });\n } catch {\n const cookieStore = await cookies();\n clearPlatformCookies(cookieStore);\n return NextResponse.json(\n { error: \"Refresh failed\" },\n { status: 401 },\n );\n }\n }\n\n async function handleLogout() {\n try {\n const cookieStore = await cookies();\n const refreshToken = cookieStore.get(COOKIE_REFRESH_TOKEN)?.value;\n if (refreshToken) {\n await client.platformLogout(refreshToken).catch(() => {});\n }\n clearPlatformCookies(cookieStore);\n return NextResponse.json({ success: true });\n } catch {\n const cookieStore = await cookies();\n clearPlatformCookies(cookieStore);\n return NextResponse.json({ success: true });\n }\n }\n\n async function handler(\n req: NextRequest,\n context: { params: Promise<{ inai: string[] }> },\n ) {\n const params = await context.params;\n const path = params.inai?.join(\"/\") ?? \"\";\n\n if (req.method === \"POST\") {\n switch (path) {\n case \"login\":\n return handleLogin(req);\n case \"mfa-challenge\":\n return handleMFAChallenge(req);\n case \"refresh\":\n return handleRefresh();\n case \"logout\":\n return handleLogout();\n }\n }\n\n return NextResponse.json({ error: \"Not found\" }, { status: 404 });\n }\n\n return {\n GET: handler,\n POST: handler,\n };\n}\n"],"mappings":"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","names":["import_headers","import_backend","import_shared","import_shared","import_shared","import_headers","import_server","import_backend","import_shared","session"]}
|
package/dist/server.js
CHANGED
|
@@ -410,6 +410,8 @@ async function auth() {
|
|
|
410
410
|
orgId: null,
|
|
411
411
|
orgRole: null,
|
|
412
412
|
sessionId: null,
|
|
413
|
+
roles: [],
|
|
414
|
+
permissions: [],
|
|
413
415
|
getToken: async () => null,
|
|
414
416
|
has: () => false,
|
|
415
417
|
protect: () => {
|
|
@@ -428,6 +430,8 @@ async function auth() {
|
|
|
428
430
|
orgId: null,
|
|
429
431
|
orgRole: null,
|
|
430
432
|
sessionId: null,
|
|
433
|
+
roles: [],
|
|
434
|
+
permissions: [],
|
|
431
435
|
getToken: async () => null,
|
|
432
436
|
has: () => false,
|
|
433
437
|
protect: () => {
|
|
@@ -452,6 +456,8 @@ async function auth() {
|
|
|
452
456
|
orgId: claims.org_id ?? null,
|
|
453
457
|
orgRole: claims.org_role ?? null,
|
|
454
458
|
sessionId: null,
|
|
459
|
+
roles,
|
|
460
|
+
permissions,
|
|
455
461
|
isSignedIn: true,
|
|
456
462
|
getToken: async () => token,
|
|
457
463
|
has
|
|
@@ -464,6 +470,8 @@ async function auth() {
|
|
|
464
470
|
orgId: claims.org_id ?? null,
|
|
465
471
|
orgRole: claims.org_role ?? null,
|
|
466
472
|
sessionId: null,
|
|
473
|
+
roles,
|
|
474
|
+
permissions,
|
|
467
475
|
getToken: async () => token,
|
|
468
476
|
has,
|
|
469
477
|
protect: (params) => {
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/server.ts","../src/cookies.ts","../src/config.ts","../src/api-routes.ts","../src/platform-api-routes.ts"],"sourcesContent":["import { cookies } from \"next/headers\";\nimport { redirect } from \"next/navigation\";\nimport type {\n AuthObject,\n ServerAuthObject,\n ProtectedAuthObject,\n UserResource,\n PlatformUserResource,\n} from \"@inai-dev/types\";\nimport { InAIAuthClient } from \"@inai-dev/backend\";\nimport { isTokenExpired, getClaimsFromToken } from \"@inai-dev/shared\";\nimport {\n getAuthTokenFromCookies,\n getSessionFromCookies,\n} from \"./cookies\";\nimport { getAuthConfig } from \"./config\";\n\nexport { createAuthRoutes } from \"./api-routes\";\nexport { createPlatformAuthRoutes } from \"./platform-api-routes\";\nexport { configureAuth, getAuthConfig } from \"./config\";\nexport { setAuthCookies, clearAuthCookies, getRefreshTokenFromCookies, getAuthTokenFromCookies } from \"./cookies\";\n\nexport async function auth(): Promise<ServerAuthObject> {\n const cookieStore = await cookies();\n const token = getAuthTokenFromCookies(cookieStore);\n const config = getAuthConfig();\n\n function redirectToSignIn(opts?: { returnTo?: string }): never {\n const returnTo = opts?.returnTo;\n const url = returnTo\n ? `${config.signInUrl}?returnTo=${encodeURIComponent(returnTo)}`\n : config.signInUrl;\n redirect(url);\n }\n\n if (!token || isTokenExpired(token)) {\n return {\n userId: null,\n tenantId: null,\n appId: null,\n envId: null,\n orgId: null,\n orgRole: null,\n sessionId: null,\n getToken: async () => null,\n has: () => false,\n protect: () => {\n redirectToSignIn();\n },\n redirectToSignIn,\n };\n }\n\n const claims = getClaimsFromToken(token);\n if (!claims) {\n return {\n userId: null,\n tenantId: null,\n appId: null,\n envId: null,\n orgId: null,\n orgRole: null,\n sessionId: null,\n getToken: async () => null,\n has: () => false,\n protect: () => {\n redirectToSignIn();\n },\n redirectToSignIn,\n };\n }\n\n const roles = claims.roles ?? [];\n const permissions = claims.permissions ?? [];\n\n const has = (params: { role?: string; permission?: string }) => {\n if (params.role && roles.includes(params.role)) return true;\n if (params.permission && permissions.includes(params.permission))\n return true;\n return false;\n };\n\n const protectedObj: ProtectedAuthObject = {\n userId: claims.sub,\n tenantId: claims.tenant_id,\n appId: claims.app_id ?? null,\n envId: claims.env_id ?? null,\n orgId: claims.org_id ?? null,\n orgRole: claims.org_role ?? null,\n sessionId: null,\n isSignedIn: true,\n getToken: async () => token,\n has,\n };\n\n return {\n userId: claims.sub,\n tenantId: claims.tenant_id,\n appId: claims.app_id ?? null,\n envId: claims.env_id ?? null,\n orgId: claims.org_id ?? null,\n orgRole: claims.org_role ?? null,\n sessionId: null,\n getToken: async () => token,\n has,\n protect: (params?: {\n role?: string;\n permission?: string;\n redirectTo?: string;\n }) => {\n if (params?.role || params?.permission) {\n if (!has({ role: params.role, permission: params.permission })) {\n redirect(params.redirectTo ?? \"/unauthorized\");\n }\n }\n return protectedObj;\n },\n redirectToSignIn,\n };\n}\n\nexport async function currentUser(\n opts?: { fresh?: boolean },\n): Promise<UserResource | PlatformUserResource | null> {\n const cookieStore = await cookies();\n\n if (opts?.fresh) {\n const token = getAuthTokenFromCookies(cookieStore);\n if (!token || isTokenExpired(token)) return null;\n\n const config = getAuthConfig();\n if (!config.apiUrl || !config.publishableKey) {\n const session = getSessionFromCookies(cookieStore);\n return session?.user ?? null;\n }\n\n const client = new InAIAuthClient({\n apiUrl: config.apiUrl,\n publishableKey: config.publishableKey,\n });\n try {\n const { data } = await client.getMe(token);\n return data;\n } catch {\n return null;\n }\n }\n\n const session = getSessionFromCookies(cookieStore);\n return session?.user ?? null;\n}\n","import type { UserResource, PlatformUserResource, JWTClaims, TokenPair } from \"@inai-dev/types\";\nimport {\n COOKIE_AUTH_TOKEN,\n COOKIE_REFRESH_TOKEN,\n COOKIE_AUTH_SESSION,\n decodeJWTPayload,\n} from \"@inai-dev/shared\";\n\nexport {\n COOKIE_AUTH_TOKEN,\n COOKIE_REFRESH_TOKEN,\n COOKIE_AUTH_SESSION,\n} from \"@inai-dev/shared\";\n\nexport { isTokenExpired, getClaimsFromToken } from \"@inai-dev/shared\";\n\ninterface CookieStore {\n get(name: string): { value: string } | undefined;\n set(name: string, value: string, options?: Record<string, unknown>): void;\n}\n\ninterface SessionData {\n user: UserResource | PlatformUserResource;\n expiresAt: string;\n permissions?: string[];\n orgId?: string;\n orgRole?: string;\n appId?: string;\n envId?: string;\n}\n\nexport function setAuthCookies(\n cookieStore: CookieStore,\n tokens: TokenPair,\n user: UserResource | PlatformUserResource,\n): void {\n const isProduction = process.env.NODE_ENV === \"production\";\n const claims = decodeJWTPayload(tokens.access_token);\n const expiresAt = claims\n ? new Date(claims.exp * 1000).toISOString()\n : new Date(Date.now() + tokens.expires_in * 1000).toISOString();\n\n cookieStore.set(COOKIE_AUTH_TOKEN, tokens.access_token, {\n httpOnly: true,\n secure: isProduction,\n sameSite: \"lax\",\n path: \"/\",\n maxAge: tokens.expires_in,\n });\n\n cookieStore.set(COOKIE_REFRESH_TOKEN, tokens.refresh_token, {\n httpOnly: true,\n secure: isProduction,\n sameSite: \"strict\",\n path: \"/api/auth\",\n maxAge: 7 * 24 * 60 * 60,\n });\n\n const sessionData: SessionData = {\n user,\n expiresAt,\n permissions: claims?.permissions ?? [],\n orgId: claims?.org_id,\n orgRole: claims?.org_role,\n appId: claims?.app_id,\n envId: claims?.env_id,\n };\n cookieStore.set(COOKIE_AUTH_SESSION, JSON.stringify(sessionData), {\n httpOnly: false,\n secure: isProduction,\n sameSite: \"lax\",\n path: \"/\",\n maxAge: tokens.expires_in,\n });\n}\n\nexport function clearAuthCookies(\n cookieStore: CookieStore,\n): void {\n const opts = { path: \"/\", maxAge: 0 };\n cookieStore.set(COOKIE_AUTH_TOKEN, \"\", opts);\n cookieStore.set(COOKIE_REFRESH_TOKEN, \"\", { ...opts, path: \"/api/auth\" });\n cookieStore.set(COOKIE_AUTH_SESSION, \"\", opts);\n}\n\nexport function getAuthTokenFromCookies(\n cookieStore: CookieStore,\n): string | null {\n return cookieStore.get(COOKIE_AUTH_TOKEN)?.value ?? null;\n}\n\nexport function getRefreshTokenFromCookies(\n cookieStore: CookieStore,\n): string | null {\n return cookieStore.get(COOKIE_REFRESH_TOKEN)?.value ?? null;\n}\n\nexport function getSessionFromCookies(\n cookieStore: CookieStore,\n): SessionData | null {\n const raw = cookieStore.get(COOKIE_AUTH_SESSION)?.value;\n if (!raw) return null;\n try {\n return JSON.parse(raw) as SessionData;\n } catch {\n return null;\n }\n}\n","import type { InAIAuthSDKConfig } from \"@inai-dev/types\";\nimport { DEFAULT_API_URL } from \"@inai-dev/shared\";\n\ntype ResolvedConfig = Required<InAIAuthSDKConfig>;\n\nconst defaults: ResolvedConfig = {\n signInUrl: \"/login\",\n signUpUrl: \"/register\",\n afterSignInUrl: \"/\",\n afterSignOutUrl: \"/login\",\n apiUrl: DEFAULT_API_URL,\n publishableKey: \"\",\n};\n\nlet userConfig: Partial<InAIAuthSDKConfig> = {};\n\nexport function configureAuth(config: InAIAuthSDKConfig): void {\n userConfig = config;\n}\n\nexport function getAuthConfig(): ResolvedConfig {\n return {\n signInUrl: userConfig.signInUrl ?? defaults.signInUrl,\n signUpUrl: userConfig.signUpUrl ?? defaults.signUpUrl,\n afterSignInUrl: userConfig.afterSignInUrl ?? defaults.afterSignInUrl,\n afterSignOutUrl: userConfig.afterSignOutUrl ?? defaults.afterSignOutUrl,\n apiUrl:\n userConfig.apiUrl ??\n defaults.apiUrl,\n publishableKey:\n userConfig.publishableKey ??\n process.env.INAI_PUBLISHABLE_KEY ??\n defaults.publishableKey,\n };\n}\n","import { cookies } from \"next/headers\";\nimport { NextResponse } from \"next/server\";\nimport type { NextRequest } from \"next/server\";\nimport { InAIAuthClient } from \"@inai-dev/backend\";\nimport type {\n InAIAuthConfig,\n TokenPair,\n UserResource,\n LoginResult,\n} from \"@inai-dev/types\";\nimport {\n setAuthCookies,\n clearAuthCookies,\n getRefreshTokenFromCookies,\n} from \"./cookies\";\n\nexport function createAuthRoutes(config: InAIAuthConfig = {}) {\n const client = new InAIAuthClient(config);\n\n async function handleLogin(req: NextRequest) {\n try {\n const body = (await req.json()) as Record<string, string>;\n const result = (await client.login({\n email: body.email,\n password: body.password,\n })) as LoginResult & { user?: UserResource };\n\n if (result.mfa_required) {\n return NextResponse.json({\n mfa_required: true,\n mfa_token: result.mfa_token,\n });\n }\n\n const tokens = result as TokenPair;\n const loginUser = (result as { user?: UserResource }).user;\n const user =\n loginUser ?? (await client.getMe(tokens.access_token)).data;\n const cookieStore = await cookies();\n setAuthCookies(cookieStore, tokens, user);\n\n return NextResponse.json({ user });\n } catch (err) {\n const message = err instanceof Error ? err.message : \"Login failed\";\n return NextResponse.json({ error: message }, { status: 401 });\n }\n }\n\n async function handleMFAChallenge(req: NextRequest) {\n try {\n const body = (await req.json()) as Record<string, string>;\n const tokens = await client.mfaChallenge({\n mfa_token: body.mfa_token,\n code: body.code,\n });\n\n const { data: user } = await client.getMe(tokens.access_token);\n const cookieStore = await cookies();\n setAuthCookies(cookieStore, tokens, user);\n\n return NextResponse.json({ user });\n } catch (err) {\n const message =\n err instanceof Error ? err.message : \"MFA verification failed\";\n return NextResponse.json({ error: message }, { status: 401 });\n }\n }\n\n async function handleRefresh() {\n try {\n const cookieStore = await cookies();\n const refreshToken = getRefreshTokenFromCookies(cookieStore);\n\n if (!refreshToken) {\n clearAuthCookies(cookieStore);\n return NextResponse.json(\n { error: \"No refresh token\" },\n { status: 401 },\n );\n }\n\n const tokens = await client.refresh(refreshToken);\n const { data: user } = await client.getMe(tokens.access_token);\n setAuthCookies(cookieStore, tokens, user);\n\n return NextResponse.json({ user });\n } catch {\n const cookieStore = await cookies();\n clearAuthCookies(cookieStore);\n return NextResponse.json(\n { error: \"Refresh failed\" },\n { status: 401 },\n );\n }\n }\n\n async function handleRegister(req: NextRequest) {\n try {\n const body = (await req.json()) as Record<string, string>;\n const result = await client.register({\n email: body.email,\n password: body.password,\n firstName: body.firstName,\n lastName: body.lastName,\n });\n\n if (!result.access_token) {\n return NextResponse.json({\n needs_email_verification: true,\n user: result.user,\n });\n }\n\n const tokens = result as TokenPair;\n const loginUser = result.user;\n const user =\n loginUser ?? (await client.getMe(tokens.access_token)).data;\n const cookieStore = await cookies();\n setAuthCookies(cookieStore, tokens, user);\n\n return NextResponse.json({ user });\n } catch (err) {\n const message =\n err instanceof Error ? err.message : \"Registration failed\";\n return NextResponse.json({ error: message }, { status: 400 });\n }\n }\n\n async function handleLogout() {\n try {\n const cookieStore = await cookies();\n const refreshToken = getRefreshTokenFromCookies(cookieStore);\n if (refreshToken) {\n await client.logout(refreshToken).catch(() => {});\n }\n clearAuthCookies(cookieStore);\n return NextResponse.json({ success: true });\n } catch {\n const cookieStore = await cookies();\n clearAuthCookies(cookieStore);\n return NextResponse.json({ success: true });\n }\n }\n\n async function handler(\n req: NextRequest,\n context: { params: Promise<{ inai: string[] }> },\n ) {\n const params = await context.params;\n const path = params.inai?.join(\"/\") ?? \"\";\n\n if (req.method === \"POST\") {\n switch (path) {\n case \"login\":\n return handleLogin(req);\n case \"register\":\n return handleRegister(req);\n case \"mfa-challenge\":\n return handleMFAChallenge(req);\n case \"refresh\":\n return handleRefresh();\n case \"logout\":\n return handleLogout();\n }\n }\n\n return NextResponse.json({ error: \"Not found\" }, { status: 404 });\n }\n\n return {\n GET: handler,\n POST: handler,\n };\n}\n","import { cookies } from \"next/headers\";\nimport { NextResponse } from \"next/server\";\nimport type { NextRequest } from \"next/server\";\nimport { InAIAuthClient } from \"@inai-dev/backend\";\nimport type { InAIAuthConfig, TokenPair, PlatformUserResource } from \"@inai-dev/types\";\nimport {\n COOKIE_AUTH_TOKEN,\n COOKIE_AUTH_SESSION,\n COOKIE_REFRESH_TOKEN,\n} from \"@inai-dev/shared\";\n\nexport function createPlatformAuthRoutes(config: InAIAuthConfig = {}) {\n const client = new InAIAuthClient(config);\n const isProduction = process.env.NODE_ENV === \"production\";\n\n function setPlatformCookies(\n cookieStore: Awaited<ReturnType<typeof cookies>>,\n tokens: TokenPair,\n user?: PlatformUserResource,\n ) {\n cookieStore.set(COOKIE_AUTH_TOKEN, tokens.access_token, {\n httpOnly: true,\n secure: isProduction,\n sameSite: \"lax\",\n path: \"/\",\n maxAge: tokens.expires_in,\n });\n cookieStore.set(COOKIE_REFRESH_TOKEN, tokens.refresh_token, {\n httpOnly: true,\n secure: isProduction,\n sameSite: \"strict\",\n path: \"/api/auth\",\n maxAge: 7 * 24 * 60 * 60,\n });\n if (user) {\n const expiresAt = Date.now() + tokens.expires_in * 1000;\n cookieStore.set(\n COOKIE_AUTH_SESSION,\n JSON.stringify({ user, expiresAt }),\n {\n httpOnly: false,\n secure: isProduction,\n sameSite: \"lax\",\n path: \"/\",\n maxAge: tokens.expires_in,\n },\n );\n }\n }\n\n function clearPlatformCookies(\n cookieStore: Awaited<ReturnType<typeof cookies>>,\n ) {\n cookieStore.set(COOKIE_AUTH_TOKEN, \"\", { path: \"/\", maxAge: 0 });\n cookieStore.set(COOKIE_REFRESH_TOKEN, \"\", {\n path: \"/api/auth\",\n maxAge: 0,\n });\n cookieStore.set(COOKIE_AUTH_SESSION, \"\", { path: \"/\", maxAge: 0 });\n }\n\n async function handleLogin(req: NextRequest) {\n try {\n const body = (await req.json()) as Record<string, string>;\n const result = await client.platformLogin({\n email: body.email,\n password: body.password,\n });\n\n if (result.mfa_required) {\n return NextResponse.json({\n mfa_required: true,\n mfa_token: result.mfa_token,\n });\n }\n\n const tokens = result as TokenPair;\n const user = result.user;\n const cookieStore = await cookies();\n setPlatformCookies(cookieStore, tokens, user);\n\n return NextResponse.json({ user });\n } catch (err) {\n const message = err instanceof Error ? err.message : \"Login failed\";\n return NextResponse.json({ error: message }, { status: 401 });\n }\n }\n\n async function handleMFAChallenge(req: NextRequest) {\n try {\n const body = (await req.json()) as Record<string, string>;\n const result = await client.platformMfaChallenge({\n mfa_token: body.mfa_token,\n code: body.code,\n });\n\n const tokens = result as TokenPair;\n const user = result.user;\n const cookieStore = await cookies();\n setPlatformCookies(cookieStore, tokens, user);\n\n return NextResponse.json({ user });\n } catch (err) {\n const message =\n err instanceof Error ? err.message : \"MFA verification failed\";\n return NextResponse.json({ error: message }, { status: 401 });\n }\n }\n\n async function handleRefresh() {\n try {\n const cookieStore = await cookies();\n const refreshToken = cookieStore.get(COOKIE_REFRESH_TOKEN)?.value;\n\n if (!refreshToken) {\n clearPlatformCookies(cookieStore);\n return NextResponse.json(\n { error: \"No refresh token\" },\n { status: 401 },\n );\n }\n\n const tokens = await client.platformRefresh(refreshToken);\n const { data: user } = await client.platformGetMe(\n tokens.access_token,\n );\n setPlatformCookies(cookieStore, tokens, user);\n\n return NextResponse.json({ user });\n } catch {\n const cookieStore = await cookies();\n clearPlatformCookies(cookieStore);\n return NextResponse.json(\n { error: \"Refresh failed\" },\n { status: 401 },\n );\n }\n }\n\n async function handleLogout() {\n try {\n const cookieStore = await cookies();\n const refreshToken = cookieStore.get(COOKIE_REFRESH_TOKEN)?.value;\n if (refreshToken) {\n await client.platformLogout(refreshToken).catch(() => {});\n }\n clearPlatformCookies(cookieStore);\n return NextResponse.json({ success: true });\n } catch {\n const cookieStore = await cookies();\n clearPlatformCookies(cookieStore);\n return NextResponse.json({ success: true });\n }\n }\n\n async function handler(\n req: NextRequest,\n context: { params: Promise<{ inai: string[] }> },\n ) {\n const params = await context.params;\n const path = params.inai?.join(\"/\") ?? \"\";\n\n if (req.method === \"POST\") {\n switch (path) {\n case \"login\":\n return handleLogin(req);\n case \"mfa-challenge\":\n return handleMFAChallenge(req);\n case \"refresh\":\n return handleRefresh();\n case \"logout\":\n return handleLogout();\n }\n }\n\n return NextResponse.json({ error: \"Not found\" }, { status: 404 });\n }\n\n return {\n GET: handler,\n POST: handler,\n };\n}\n"],"mappings":"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","names":["cookies","InAIAuthClient","isTokenExpired","getClaimsFromToken","COOKIE_AUTH_TOKEN","COOKIE_REFRESH_TOKEN","COOKIE_AUTH_SESSION","cookies","NextResponse","InAIAuthClient","COOKIE_AUTH_TOKEN","COOKIE_AUTH_SESSION","COOKIE_REFRESH_TOKEN","cookies","isTokenExpired","getClaimsFromToken","session","InAIAuthClient"]}
|
|
1
|
+
{"version":3,"sources":["../src/server.ts","../src/cookies.ts","../src/config.ts","../src/api-routes.ts","../src/platform-api-routes.ts"],"sourcesContent":["import { cookies } from \"next/headers\";\nimport { redirect } from \"next/navigation\";\nimport type {\n AuthObject,\n ServerAuthObject,\n ProtectedAuthObject,\n UserResource,\n PlatformUserResource,\n} from \"@inai-dev/types\";\nimport { InAIAuthClient } from \"@inai-dev/backend\";\nimport { isTokenExpired, getClaimsFromToken } from \"@inai-dev/shared\";\nimport {\n getAuthTokenFromCookies,\n getSessionFromCookies,\n} from \"./cookies\";\nimport { getAuthConfig } from \"./config\";\n\nexport { createAuthRoutes } from \"./api-routes\";\nexport { createPlatformAuthRoutes } from \"./platform-api-routes\";\nexport { configureAuth, getAuthConfig } from \"./config\";\nexport { setAuthCookies, clearAuthCookies, getRefreshTokenFromCookies, getAuthTokenFromCookies } from \"./cookies\";\n\nexport async function auth(): Promise<ServerAuthObject> {\n const cookieStore = await cookies();\n const token = getAuthTokenFromCookies(cookieStore);\n const config = getAuthConfig();\n\n function redirectToSignIn(opts?: { returnTo?: string }): never {\n const returnTo = opts?.returnTo;\n const url = returnTo\n ? `${config.signInUrl}?returnTo=${encodeURIComponent(returnTo)}`\n : config.signInUrl;\n redirect(url);\n }\n\n if (!token || isTokenExpired(token)) {\n return {\n userId: null,\n tenantId: null,\n appId: null,\n envId: null,\n orgId: null,\n orgRole: null,\n sessionId: null,\n roles: [],\n permissions: [],\n getToken: async () => null,\n has: () => false,\n protect: () => {\n redirectToSignIn();\n },\n redirectToSignIn,\n };\n }\n\n const claims = getClaimsFromToken(token);\n if (!claims) {\n return {\n userId: null,\n tenantId: null,\n appId: null,\n envId: null,\n orgId: null,\n orgRole: null,\n sessionId: null,\n roles: [],\n permissions: [],\n getToken: async () => null,\n has: () => false,\n protect: () => {\n redirectToSignIn();\n },\n redirectToSignIn,\n };\n }\n\n const roles = claims.roles ?? [];\n const permissions = claims.permissions ?? [];\n\n const has = (params: { role?: string; permission?: string }) => {\n if (params.role && roles.includes(params.role)) return true;\n if (params.permission && permissions.includes(params.permission))\n return true;\n return false;\n };\n\n const protectedObj: ProtectedAuthObject = {\n userId: claims.sub,\n tenantId: claims.tenant_id,\n appId: claims.app_id ?? null,\n envId: claims.env_id ?? null,\n orgId: claims.org_id ?? null,\n orgRole: claims.org_role ?? null,\n sessionId: null,\n roles,\n permissions,\n isSignedIn: true,\n getToken: async () => token,\n has,\n };\n\n return {\n userId: claims.sub,\n tenantId: claims.tenant_id,\n appId: claims.app_id ?? null,\n envId: claims.env_id ?? null,\n orgId: claims.org_id ?? null,\n orgRole: claims.org_role ?? null,\n sessionId: null,\n roles,\n permissions,\n getToken: async () => token,\n has,\n protect: (params?: {\n role?: string;\n permission?: string;\n redirectTo?: string;\n }) => {\n if (params?.role || params?.permission) {\n if (!has({ role: params.role, permission: params.permission })) {\n redirect(params.redirectTo ?? \"/unauthorized\");\n }\n }\n return protectedObj;\n },\n redirectToSignIn,\n };\n}\n\nexport async function currentUser(\n opts?: { fresh?: boolean },\n): Promise<UserResource | PlatformUserResource | null> {\n const cookieStore = await cookies();\n\n if (opts?.fresh) {\n const token = getAuthTokenFromCookies(cookieStore);\n if (!token || isTokenExpired(token)) return null;\n\n const config = getAuthConfig();\n if (!config.apiUrl || !config.publishableKey) {\n const session = getSessionFromCookies(cookieStore);\n return session?.user ?? null;\n }\n\n const client = new InAIAuthClient({\n apiUrl: config.apiUrl,\n publishableKey: config.publishableKey,\n });\n try {\n const { data } = await client.getMe(token);\n return data;\n } catch {\n return null;\n }\n }\n\n const session = getSessionFromCookies(cookieStore);\n return session?.user ?? null;\n}\n","import type { UserResource, PlatformUserResource, JWTClaims, TokenPair } from \"@inai-dev/types\";\nimport {\n COOKIE_AUTH_TOKEN,\n COOKIE_REFRESH_TOKEN,\n COOKIE_AUTH_SESSION,\n decodeJWTPayload,\n} from \"@inai-dev/shared\";\n\nexport {\n COOKIE_AUTH_TOKEN,\n COOKIE_REFRESH_TOKEN,\n COOKIE_AUTH_SESSION,\n} from \"@inai-dev/shared\";\n\nexport { isTokenExpired, getClaimsFromToken } from \"@inai-dev/shared\";\n\ninterface CookieStore {\n get(name: string): { value: string } | undefined;\n set(name: string, value: string, options?: Record<string, unknown>): void;\n}\n\ninterface SessionData {\n user: UserResource | PlatformUserResource;\n expiresAt: string;\n permissions?: string[];\n orgId?: string;\n orgRole?: string;\n appId?: string;\n envId?: string;\n}\n\nexport function setAuthCookies(\n cookieStore: CookieStore,\n tokens: TokenPair,\n user: UserResource | PlatformUserResource,\n): void {\n const isProduction = process.env.NODE_ENV === \"production\";\n const claims = decodeJWTPayload(tokens.access_token);\n const expiresAt = claims\n ? new Date(claims.exp * 1000).toISOString()\n : new Date(Date.now() + tokens.expires_in * 1000).toISOString();\n\n cookieStore.set(COOKIE_AUTH_TOKEN, tokens.access_token, {\n httpOnly: true,\n secure: isProduction,\n sameSite: \"lax\",\n path: \"/\",\n maxAge: tokens.expires_in,\n });\n\n cookieStore.set(COOKIE_REFRESH_TOKEN, tokens.refresh_token, {\n httpOnly: true,\n secure: isProduction,\n sameSite: \"strict\",\n path: \"/api/auth\",\n maxAge: 7 * 24 * 60 * 60,\n });\n\n const sessionData: SessionData = {\n user,\n expiresAt,\n permissions: claims?.permissions ?? [],\n orgId: claims?.org_id,\n orgRole: claims?.org_role,\n appId: claims?.app_id,\n envId: claims?.env_id,\n };\n cookieStore.set(COOKIE_AUTH_SESSION, JSON.stringify(sessionData), {\n httpOnly: false,\n secure: isProduction,\n sameSite: \"lax\",\n path: \"/\",\n maxAge: tokens.expires_in,\n });\n}\n\nexport function clearAuthCookies(\n cookieStore: CookieStore,\n): void {\n const opts = { path: \"/\", maxAge: 0 };\n cookieStore.set(COOKIE_AUTH_TOKEN, \"\", opts);\n cookieStore.set(COOKIE_REFRESH_TOKEN, \"\", { ...opts, path: \"/api/auth\" });\n cookieStore.set(COOKIE_AUTH_SESSION, \"\", opts);\n}\n\nexport function getAuthTokenFromCookies(\n cookieStore: CookieStore,\n): string | null {\n return cookieStore.get(COOKIE_AUTH_TOKEN)?.value ?? null;\n}\n\nexport function getRefreshTokenFromCookies(\n cookieStore: CookieStore,\n): string | null {\n return cookieStore.get(COOKIE_REFRESH_TOKEN)?.value ?? null;\n}\n\nexport function getSessionFromCookies(\n cookieStore: CookieStore,\n): SessionData | null {\n const raw = cookieStore.get(COOKIE_AUTH_SESSION)?.value;\n if (!raw) return null;\n try {\n return JSON.parse(raw) as SessionData;\n } catch {\n return null;\n }\n}\n","import type { InAIAuthSDKConfig } from \"@inai-dev/types\";\nimport { DEFAULT_API_URL } from \"@inai-dev/shared\";\n\ntype ResolvedConfig = Required<InAIAuthSDKConfig>;\n\nconst defaults: ResolvedConfig = {\n signInUrl: \"/login\",\n signUpUrl: \"/register\",\n afterSignInUrl: \"/\",\n afterSignOutUrl: \"/login\",\n apiUrl: DEFAULT_API_URL,\n publishableKey: \"\",\n};\n\nlet userConfig: Partial<InAIAuthSDKConfig> = {};\n\nexport function configureAuth(config: InAIAuthSDKConfig): void {\n userConfig = config;\n}\n\nexport function getAuthConfig(): ResolvedConfig {\n return {\n signInUrl: userConfig.signInUrl ?? defaults.signInUrl,\n signUpUrl: userConfig.signUpUrl ?? defaults.signUpUrl,\n afterSignInUrl: userConfig.afterSignInUrl ?? defaults.afterSignInUrl,\n afterSignOutUrl: userConfig.afterSignOutUrl ?? defaults.afterSignOutUrl,\n apiUrl:\n userConfig.apiUrl ??\n defaults.apiUrl,\n publishableKey:\n userConfig.publishableKey ??\n process.env.INAI_PUBLISHABLE_KEY ??\n defaults.publishableKey,\n };\n}\n","import { cookies } from \"next/headers\";\nimport { NextResponse } from \"next/server\";\nimport type { NextRequest } from \"next/server\";\nimport { InAIAuthClient } from \"@inai-dev/backend\";\nimport type {\n InAIAuthConfig,\n TokenPair,\n UserResource,\n LoginResult,\n} from \"@inai-dev/types\";\nimport {\n setAuthCookies,\n clearAuthCookies,\n getRefreshTokenFromCookies,\n} from \"./cookies\";\n\nexport function createAuthRoutes(config: InAIAuthConfig = {}) {\n const client = new InAIAuthClient(config);\n\n async function handleLogin(req: NextRequest) {\n try {\n const body = (await req.json()) as Record<string, string>;\n const result = (await client.login({\n email: body.email,\n password: body.password,\n })) as LoginResult & { user?: UserResource };\n\n if (result.mfa_required) {\n return NextResponse.json({\n mfa_required: true,\n mfa_token: result.mfa_token,\n });\n }\n\n const tokens = result as TokenPair;\n const loginUser = (result as { user?: UserResource }).user;\n const user =\n loginUser ?? (await client.getMe(tokens.access_token)).data;\n const cookieStore = await cookies();\n setAuthCookies(cookieStore, tokens, user);\n\n return NextResponse.json({ user });\n } catch (err) {\n const message = err instanceof Error ? err.message : \"Login failed\";\n return NextResponse.json({ error: message }, { status: 401 });\n }\n }\n\n async function handleMFAChallenge(req: NextRequest) {\n try {\n const body = (await req.json()) as Record<string, string>;\n const tokens = await client.mfaChallenge({\n mfa_token: body.mfa_token,\n code: body.code,\n });\n\n const { data: user } = await client.getMe(tokens.access_token);\n const cookieStore = await cookies();\n setAuthCookies(cookieStore, tokens, user);\n\n return NextResponse.json({ user });\n } catch (err) {\n const message =\n err instanceof Error ? err.message : \"MFA verification failed\";\n return NextResponse.json({ error: message }, { status: 401 });\n }\n }\n\n async function handleRefresh() {\n try {\n const cookieStore = await cookies();\n const refreshToken = getRefreshTokenFromCookies(cookieStore);\n\n if (!refreshToken) {\n clearAuthCookies(cookieStore);\n return NextResponse.json(\n { error: \"No refresh token\" },\n { status: 401 },\n );\n }\n\n const tokens = await client.refresh(refreshToken);\n const { data: user } = await client.getMe(tokens.access_token);\n setAuthCookies(cookieStore, tokens, user);\n\n return NextResponse.json({ user });\n } catch {\n const cookieStore = await cookies();\n clearAuthCookies(cookieStore);\n return NextResponse.json(\n { error: \"Refresh failed\" },\n { status: 401 },\n );\n }\n }\n\n async function handleRegister(req: NextRequest) {\n try {\n const body = (await req.json()) as Record<string, string>;\n const result = await client.register({\n email: body.email,\n password: body.password,\n firstName: body.firstName,\n lastName: body.lastName,\n });\n\n if (!result.access_token) {\n return NextResponse.json({\n needs_email_verification: true,\n user: result.user,\n });\n }\n\n const tokens = result as TokenPair;\n const loginUser = result.user;\n const user =\n loginUser ?? (await client.getMe(tokens.access_token)).data;\n const cookieStore = await cookies();\n setAuthCookies(cookieStore, tokens, user);\n\n return NextResponse.json({ user });\n } catch (err) {\n const message =\n err instanceof Error ? err.message : \"Registration failed\";\n return NextResponse.json({ error: message }, { status: 400 });\n }\n }\n\n async function handleLogout() {\n try {\n const cookieStore = await cookies();\n const refreshToken = getRefreshTokenFromCookies(cookieStore);\n if (refreshToken) {\n await client.logout(refreshToken).catch(() => {});\n }\n clearAuthCookies(cookieStore);\n return NextResponse.json({ success: true });\n } catch {\n const cookieStore = await cookies();\n clearAuthCookies(cookieStore);\n return NextResponse.json({ success: true });\n }\n }\n\n async function handler(\n req: NextRequest,\n context: { params: Promise<{ inai: string[] }> },\n ) {\n const params = await context.params;\n const path = params.inai?.join(\"/\") ?? \"\";\n\n if (req.method === \"POST\") {\n switch (path) {\n case \"login\":\n return handleLogin(req);\n case \"register\":\n return handleRegister(req);\n case \"mfa-challenge\":\n return handleMFAChallenge(req);\n case \"refresh\":\n return handleRefresh();\n case \"logout\":\n return handleLogout();\n }\n }\n\n return NextResponse.json({ error: \"Not found\" }, { status: 404 });\n }\n\n return {\n GET: handler,\n POST: handler,\n };\n}\n","import { cookies } from \"next/headers\";\nimport { NextResponse } from \"next/server\";\nimport type { NextRequest } from \"next/server\";\nimport { InAIAuthClient } from \"@inai-dev/backend\";\nimport type { InAIAuthConfig, TokenPair, PlatformUserResource } from \"@inai-dev/types\";\nimport {\n COOKIE_AUTH_TOKEN,\n COOKIE_AUTH_SESSION,\n COOKIE_REFRESH_TOKEN,\n} from \"@inai-dev/shared\";\n\nexport function createPlatformAuthRoutes(config: InAIAuthConfig = {}) {\n const client = new InAIAuthClient(config);\n const isProduction = process.env.NODE_ENV === \"production\";\n\n function setPlatformCookies(\n cookieStore: Awaited<ReturnType<typeof cookies>>,\n tokens: TokenPair,\n user?: PlatformUserResource,\n ) {\n cookieStore.set(COOKIE_AUTH_TOKEN, tokens.access_token, {\n httpOnly: true,\n secure: isProduction,\n sameSite: \"lax\",\n path: \"/\",\n maxAge: tokens.expires_in,\n });\n cookieStore.set(COOKIE_REFRESH_TOKEN, tokens.refresh_token, {\n httpOnly: true,\n secure: isProduction,\n sameSite: \"strict\",\n path: \"/api/auth\",\n maxAge: 7 * 24 * 60 * 60,\n });\n if (user) {\n const expiresAt = Date.now() + tokens.expires_in * 1000;\n cookieStore.set(\n COOKIE_AUTH_SESSION,\n JSON.stringify({ user, expiresAt }),\n {\n httpOnly: false,\n secure: isProduction,\n sameSite: \"lax\",\n path: \"/\",\n maxAge: tokens.expires_in,\n },\n );\n }\n }\n\n function clearPlatformCookies(\n cookieStore: Awaited<ReturnType<typeof cookies>>,\n ) {\n cookieStore.set(COOKIE_AUTH_TOKEN, \"\", { path: \"/\", maxAge: 0 });\n cookieStore.set(COOKIE_REFRESH_TOKEN, \"\", {\n path: \"/api/auth\",\n maxAge: 0,\n });\n cookieStore.set(COOKIE_AUTH_SESSION, \"\", { path: \"/\", maxAge: 0 });\n }\n\n async function handleLogin(req: NextRequest) {\n try {\n const body = (await req.json()) as Record<string, string>;\n const result = await client.platformLogin({\n email: body.email,\n password: body.password,\n });\n\n if (result.mfa_required) {\n return NextResponse.json({\n mfa_required: true,\n mfa_token: result.mfa_token,\n });\n }\n\n const tokens = result as TokenPair;\n const user = result.user;\n const cookieStore = await cookies();\n setPlatformCookies(cookieStore, tokens, user);\n\n return NextResponse.json({ user });\n } catch (err) {\n const message = err instanceof Error ? err.message : \"Login failed\";\n return NextResponse.json({ error: message }, { status: 401 });\n }\n }\n\n async function handleMFAChallenge(req: NextRequest) {\n try {\n const body = (await req.json()) as Record<string, string>;\n const result = await client.platformMfaChallenge({\n mfa_token: body.mfa_token,\n code: body.code,\n });\n\n const tokens = result as TokenPair;\n const user = result.user;\n const cookieStore = await cookies();\n setPlatformCookies(cookieStore, tokens, user);\n\n return NextResponse.json({ user });\n } catch (err) {\n const message =\n err instanceof Error ? err.message : \"MFA verification failed\";\n return NextResponse.json({ error: message }, { status: 401 });\n }\n }\n\n async function handleRefresh() {\n try {\n const cookieStore = await cookies();\n const refreshToken = cookieStore.get(COOKIE_REFRESH_TOKEN)?.value;\n\n if (!refreshToken) {\n clearPlatformCookies(cookieStore);\n return NextResponse.json(\n { error: \"No refresh token\" },\n { status: 401 },\n );\n }\n\n const tokens = await client.platformRefresh(refreshToken);\n const { data: user } = await client.platformGetMe(\n tokens.access_token,\n );\n setPlatformCookies(cookieStore, tokens, user);\n\n return NextResponse.json({ user });\n } catch {\n const cookieStore = await cookies();\n clearPlatformCookies(cookieStore);\n return NextResponse.json(\n { error: \"Refresh failed\" },\n { status: 401 },\n );\n }\n }\n\n async function handleLogout() {\n try {\n const cookieStore = await cookies();\n const refreshToken = cookieStore.get(COOKIE_REFRESH_TOKEN)?.value;\n if (refreshToken) {\n await client.platformLogout(refreshToken).catch(() => {});\n }\n clearPlatformCookies(cookieStore);\n return NextResponse.json({ success: true });\n } catch {\n const cookieStore = await cookies();\n clearPlatformCookies(cookieStore);\n return NextResponse.json({ success: true });\n }\n }\n\n async function handler(\n req: NextRequest,\n context: { params: Promise<{ inai: string[] }> },\n ) {\n const params = await context.params;\n const path = params.inai?.join(\"/\") ?? \"\";\n\n if (req.method === \"POST\") {\n switch (path) {\n case \"login\":\n return handleLogin(req);\n case \"mfa-challenge\":\n return handleMFAChallenge(req);\n case \"refresh\":\n return handleRefresh();\n case \"logout\":\n return handleLogout();\n }\n }\n\n return NextResponse.json({ error: \"Not found\" }, { status: 404 });\n }\n\n return {\n GET: handler,\n POST: handler,\n };\n}\n"],"mappings":"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","names":["cookies","InAIAuthClient","isTokenExpired","getClaimsFromToken","COOKIE_AUTH_TOKEN","COOKIE_REFRESH_TOKEN","COOKIE_AUTH_SESSION","cookies","NextResponse","InAIAuthClient","COOKIE_AUTH_TOKEN","COOKIE_AUTH_SESSION","COOKIE_REFRESH_TOKEN","cookies","isTokenExpired","getClaimsFromToken","session","InAIAuthClient"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inai-dev/nextjs",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "Next.js integration for InAI Auth SDK",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -35,10 +35,10 @@
|
|
|
35
35
|
"prepublishOnly": "npm run build"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@inai-dev/types": "^1.
|
|
39
|
-
"@inai-dev/shared": "^1.
|
|
40
|
-
"@inai-dev/backend": "^1.
|
|
41
|
-
"@inai-dev/react": "^0.
|
|
38
|
+
"@inai-dev/types": "^1.4.0",
|
|
39
|
+
"@inai-dev/shared": "^1.5.0",
|
|
40
|
+
"@inai-dev/backend": "^1.5.0",
|
|
41
|
+
"@inai-dev/react": "^0.5.0"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
44
|
"next": ">=14.0.0",
|