@irongate-dev/nextjs 0.1.0-beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/server.js ADDED
@@ -0,0 +1,230 @@
1
+ // src/server-auth.ts
2
+ import { headers } from "next/headers";
3
+ import { redirect } from "next/navigation";
4
+ async function auth() {
5
+ const headerStore = await headers();
6
+ const userJson = headerStore.get("x-irongate-user-json");
7
+ if (!userJson) {
8
+ return null;
9
+ }
10
+ const user = JSON.parse(userJson);
11
+ return { user, userId: user.sub };
12
+ }
13
+ async function requireAuth(redirectUrl) {
14
+ const session = await auth();
15
+ if (!session) {
16
+ redirect(redirectUrl ?? process.env.IRONGATE_SIGN_IN_URL ?? "/sign-in");
17
+ }
18
+ return session;
19
+ }
20
+ function errorResponse(code, message, status) {
21
+ return Response.json({ type: `urn:irongate:error:${code}`, code, message }, { status });
22
+ }
23
+ function withAuth(handler, options) {
24
+ return async (req) => {
25
+ const session = await auth();
26
+ if (!session) {
27
+ if (options?.onUnauthenticated === "return401") {
28
+ return errorResponse("REAUTH_REQUIRED", "Authentication required", 401);
29
+ }
30
+ return Response.redirect(new URL(process.env.IRONGATE_SIGN_IN_URL ?? "/sign-in", req.url));
31
+ }
32
+ if (options?.noImpersonation && session.user.impersonation === true) {
33
+ return errorResponse(
34
+ "IMPERSONATION_NOT_ALLOWED",
35
+ "This endpoint does not accept impersonation sessions.",
36
+ 403
37
+ );
38
+ }
39
+ return handler(req, { session });
40
+ };
41
+ }
42
+
43
+ // src/server-route-handlers.ts
44
+ import { NextResponse } from "next/server";
45
+ import {
46
+ IrongateError,
47
+ generateCodeVerifier,
48
+ generateState,
49
+ computeChallenge,
50
+ createJwksCache,
51
+ createVerifyToken,
52
+ getAuthCookieNames,
53
+ buildAuthCookies,
54
+ buildClearCookies
55
+ } from "@irongate-dev/core";
56
+
57
+ // src/cookie-env.ts
58
+ function parseBooleanEnv(value) {
59
+ if (value === "true") return true;
60
+ if (value === "false") return false;
61
+ return void 0;
62
+ }
63
+ function resolveSecureDefault(explicit) {
64
+ return explicit ?? parseBooleanEnv(process.env.IRONGATE_COOKIE_SECURE) ?? process.env.NODE_ENV === "production";
65
+ }
66
+ function resolveEnvCookieConfig() {
67
+ const cookieDomain = process.env.IRONGATE_COOKIE_DOMAIN;
68
+ const sameSite = process.env.IRONGATE_COOKIE_SAMESITE;
69
+ return {
70
+ ...cookieDomain ? { cookieDomain } : {},
71
+ secure: resolveSecureDefault(),
72
+ ...sameSite ? { sameSite } : {}
73
+ };
74
+ }
75
+
76
+ // src/server-route-handlers.ts
77
+ var PKCE_STATE_COOKIE = "irongate_pkce_state";
78
+ var PKCE_VERIFIER_COOKIE = "irongate_pkce_verifier";
79
+ var PKCE_REDIRECT_COOKIE = "irongate_pkce_redirect";
80
+ var PKCE_COOKIE_MAX_AGE = 600;
81
+ function pkceCookieOptions() {
82
+ return {
83
+ httpOnly: true,
84
+ secure: resolveSecureDefault(),
85
+ sameSite: "lax",
86
+ path: "/",
87
+ maxAge: PKCE_COOKIE_MAX_AGE
88
+ };
89
+ }
90
+ function initiateSignIn(options) {
91
+ return async (_request) => {
92
+ const baseUrl = process.env.IRONGATE_BASE_URL;
93
+ const clientId = process.env.IRONGATE_CLIENT_ID;
94
+ if (!baseUrl) {
95
+ throw new IrongateError("INVALID_CONFIG", "IRONGATE_BASE_URL is required");
96
+ }
97
+ if (!clientId) {
98
+ throw new IrongateError("INVALID_CONFIG", "IRONGATE_CLIENT_ID is required");
99
+ }
100
+ const verifier = generateCodeVerifier();
101
+ const challenge = await computeChallenge(verifier);
102
+ const state = generateState();
103
+ const authorizeUrl = new URL("/authorize", baseUrl);
104
+ authorizeUrl.searchParams.set("client_id", clientId);
105
+ authorizeUrl.searchParams.set("redirect_uri", options.redirectUri);
106
+ authorizeUrl.searchParams.set("scope", options.scope ?? "openid email");
107
+ authorizeUrl.searchParams.set("state", state);
108
+ authorizeUrl.searchParams.set("code_challenge", challenge);
109
+ authorizeUrl.searchParams.set("code_challenge_method", "S256");
110
+ authorizeUrl.searchParams.set("response_type", "code");
111
+ const response = NextResponse.redirect(authorizeUrl);
112
+ const cookieOptions = pkceCookieOptions();
113
+ response.cookies.set(PKCE_STATE_COOKIE, state, cookieOptions);
114
+ response.cookies.set(PKCE_VERIFIER_COOKIE, verifier, cookieOptions);
115
+ response.cookies.set(
116
+ PKCE_REDIRECT_COOKIE,
117
+ options.afterSignInUrl ?? process.env.IRONGATE_AFTER_SIGN_IN ?? "/dashboard",
118
+ cookieOptions
119
+ );
120
+ return response;
121
+ };
122
+ }
123
+ function handleCallback(options = {}) {
124
+ return async (request) => {
125
+ const url = new URL(request.url);
126
+ const code = url.searchParams.get("code");
127
+ const state = url.searchParams.get("state");
128
+ const oauthError = url.searchParams.get("error");
129
+ const signInUrl = process.env.IRONGATE_SIGN_IN_URL ?? "/sign-in";
130
+ if (oauthError) {
131
+ return options.onError?.(new IrongateError("AUTH_CALLBACK_ERROR", oauthError)) ?? NextResponse.redirect(new URL(`${signInUrl}?error=callback_failed`, request.url));
132
+ }
133
+ if (!code) {
134
+ return options.onError?.(new IrongateError("AUTH_CODE_MISSING", "Missing authorization code")) ?? NextResponse.redirect(new URL(`${signInUrl}?error=callback_failed`, request.url));
135
+ }
136
+ const storedState = request.cookies.get(PKCE_STATE_COOKIE)?.value;
137
+ const codeVerifier = request.cookies.get(PKCE_VERIFIER_COOKIE)?.value;
138
+ const afterCallbackUrl = request.cookies.get(PKCE_REDIRECT_COOKIE)?.value ?? process.env.IRONGATE_AFTER_SIGN_IN ?? "/dashboard";
139
+ if (!storedState || state !== storedState) {
140
+ return NextResponse.redirect(new URL(`${signInUrl}?error=state_mismatch`, request.url));
141
+ }
142
+ if (!codeVerifier) {
143
+ return options.onError?.(new IrongateError("PKCE_VERIFIER_INVALID", "Missing PKCE verifier")) ?? NextResponse.redirect(new URL(`${signInUrl}?error=callback_failed`, request.url));
144
+ }
145
+ const baseUrl = process.env.IRONGATE_BASE_URL;
146
+ const clientId = process.env.IRONGATE_CLIENT_ID;
147
+ if (!baseUrl || !clientId) {
148
+ throw new IrongateError("INVALID_CONFIG", "IRONGATE_BASE_URL and IRONGATE_CLIENT_ID are required");
149
+ }
150
+ const tokenResponse = await fetch(`${baseUrl}/token`, {
151
+ method: "POST",
152
+ headers: { "Content-Type": "application/json" },
153
+ body: JSON.stringify({
154
+ grantType: "authorization_code",
155
+ code,
156
+ codeVerifier,
157
+ redirectUri: new URL(request.nextUrl.pathname, request.url).toString(),
158
+ clientId
159
+ })
160
+ });
161
+ if (!tokenResponse.ok) {
162
+ const errorBody = await tokenResponse.json().catch(() => ({}));
163
+ const err = new IrongateError(errorBody.code ?? "AUTH_CALLBACK_ERROR", errorBody.message);
164
+ return options.onError?.(err) ?? NextResponse.redirect(new URL(`${signInUrl}?error=callback_failed`, request.url));
165
+ }
166
+ const tokens = await tokenResponse.json();
167
+ const jwksCache = createJwksCache({ baseUrl, fetch, jwksCacheTtlMs: 36e5 });
168
+ const verifyToken = createVerifyToken({
169
+ baseUrl,
170
+ fetch,
171
+ clockSkewToleranceMs: 0,
172
+ jwksCache,
173
+ checkJtiRevoked: void 0
174
+ });
175
+ const claims = await verifyToken(tokens.accessToken);
176
+ const response = NextResponse.redirect(new URL(afterCallbackUrl, request.url));
177
+ const cookieNames = getAuthCookieNames(process.env.IRONGATE_COOKIE_PREFIX);
178
+ const cookieConfig = resolveEnvCookieConfig();
179
+ for (const cookie of buildAuthCookies(
180
+ {
181
+ accessToken: tokens.accessToken,
182
+ ...tokens.refreshToken ? { refreshToken: tokens.refreshToken } : {},
183
+ expiresIn: tokens.expiresIn,
184
+ ...tokens.user ? { user: tokens.user } : {},
185
+ isImpersonating: claims.impersonation === true
186
+ },
187
+ cookieNames,
188
+ cookieConfig
189
+ )) {
190
+ response.cookies.set(cookie.name, cookie.value, cookie.options);
191
+ }
192
+ response.cookies.delete(PKCE_STATE_COOKIE);
193
+ response.cookies.delete(PKCE_VERIFIER_COOKIE);
194
+ response.cookies.delete(PKCE_REDIRECT_COOKIE);
195
+ return response;
196
+ };
197
+ }
198
+ function signOut(options = {}) {
199
+ return async (request) => {
200
+ const cookieNames = getAuthCookieNames(process.env.IRONGATE_COOKIE_PREFIX);
201
+ const accessToken = request.cookies.get(cookieNames.accessToken)?.value;
202
+ const baseUrl = process.env.IRONGATE_BASE_URL;
203
+ if (accessToken && baseUrl) {
204
+ try {
205
+ await fetch(`${baseUrl}/v1/auth/logout`, {
206
+ method: "POST",
207
+ headers: { Authorization: `Bearer ${accessToken}` }
208
+ });
209
+ } catch {
210
+ }
211
+ }
212
+ const response = NextResponse.redirect(
213
+ new URL(options.afterSignOutUrl ?? process.env.IRONGATE_AFTER_SIGN_OUT ?? "/", request.url)
214
+ );
215
+ const cookieConfig = resolveEnvCookieConfig();
216
+ for (const cookie of buildClearCookies(cookieNames, cookieConfig)) {
217
+ response.cookies.set(cookie.name, cookie.value, cookie.options);
218
+ }
219
+ return response;
220
+ };
221
+ }
222
+ export {
223
+ auth,
224
+ handleCallback,
225
+ initiateSignIn,
226
+ requireAuth,
227
+ signOut,
228
+ withAuth
229
+ };
230
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/server-auth.ts","../src/server-route-handlers.ts","../src/cookie-env.ts"],"sourcesContent":["import { headers } from \"next/headers\";\nimport { redirect } from \"next/navigation\";\nimport type { NextRequest } from \"next/server\";\nimport type { IrongateErrorCode, TokenClaims } from \"@irongate-dev/types\";\n\nexport interface AuthSession {\n user: TokenClaims;\n userId: string;\n}\n\nexport async function auth(): Promise<AuthSession | null> {\n const headerStore = await headers();\n const userJson = headerStore.get(\"x-irongate-user-json\");\n\n if (!userJson) {\n // SEC-F18-03: this means EITHER (a) unauthenticated, OR (b) this route\n // is not covered by the middleware matcher — auth() cannot distinguish\n // the two. Use requireAuth() if you want a redirect either way; ensure\n // your middleware.ts matcher covers every route that calls auth().\n return null;\n }\n\n // Trusted: this header is only ever set by our own middleware, which\n // already stripped any externally-supplied x-irongate-* headers first.\n const user = JSON.parse(userJson) as TokenClaims;\n return { user, userId: user.sub };\n}\n\nexport async function requireAuth(redirectUrl?: string): Promise<AuthSession> {\n const session = await auth();\n if (!session) {\n redirect(redirectUrl ?? process.env.IRONGATE_SIGN_IN_URL ?? \"/sign-in\");\n }\n return session;\n}\n\nexport interface WithAuthOptions {\n onUnauthenticated?: \"redirect\" | \"return401\";\n noImpersonation?: boolean;\n}\n\nexport type AuthedRouteHandler = (req: NextRequest, ctx: { session: AuthSession }) => Promise<Response>;\n\nfunction errorResponse(code: IrongateErrorCode, message: string, status: number): Response {\n return Response.json({ type: `urn:irongate:error:${code}`, code, message }, { status });\n}\n\nexport function withAuth(\n handler: AuthedRouteHandler,\n options?: WithAuthOptions,\n): (req: NextRequest) => Promise<Response> {\n return async (req: NextRequest): Promise<Response> => {\n const session = await auth();\n\n if (!session) {\n if (options?.onUnauthenticated === \"return401\") {\n return errorResponse(\"REAUTH_REQUIRED\", \"Authentication required\", 401);\n }\n return Response.redirect(new URL(process.env.IRONGATE_SIGN_IN_URL ?? \"/sign-in\", req.url));\n }\n\n if (options?.noImpersonation && session.user.impersonation === true) {\n return errorResponse(\n \"IMPERSONATION_NOT_ALLOWED\",\n \"This endpoint does not accept impersonation sessions.\",\n 403\n );\n }\n\n return handler(req, { session });\n };\n}\n","import { NextResponse } from \"next/server\";\nimport type { NextRequest } from \"next/server\";\nimport {\n IrongateError,\n generateCodeVerifier,\n generateState,\n computeChallenge,\n createJwksCache,\n createVerifyToken,\n getAuthCookieNames,\n buildAuthCookies,\n buildClearCookies,\n} from \"@irongate-dev/core\";\nimport type { IrongateErrorCode, TokenSet } from \"@irongate-dev/types\";\nimport { resolveSecureDefault, resolveEnvCookieConfig } from \"./cookie-env.js\";\n\nconst PKCE_STATE_COOKIE = \"irongate_pkce_state\";\nconst PKCE_VERIFIER_COOKIE = \"irongate_pkce_verifier\";\nconst PKCE_REDIRECT_COOKIE = \"irongate_pkce_redirect\";\nconst PKCE_COOKIE_MAX_AGE = 600; // 10 minutes — long enough for the /authorize round-trip, no longer\n\nfunction pkceCookieOptions() {\n return {\n httpOnly: true,\n secure: resolveSecureDefault(),\n sameSite: \"lax\" as const,\n path: \"/\",\n maxAge: PKCE_COOKIE_MAX_AGE,\n };\n}\n\nexport interface InitiateSignInOptions {\n redirectUri: string;\n scope?: string;\n afterSignInUrl?: string;\n}\n\nexport function initiateSignIn(options: InitiateSignInOptions): (request: NextRequest) => Promise<NextResponse> {\n return async (_request: NextRequest): Promise<NextResponse> => {\n const baseUrl = process.env.IRONGATE_BASE_URL;\n const clientId = process.env.IRONGATE_CLIENT_ID;\n if (!baseUrl) {\n throw new IrongateError(\"INVALID_CONFIG\", \"IRONGATE_BASE_URL is required\");\n }\n if (!clientId) {\n throw new IrongateError(\"INVALID_CONFIG\", \"IRONGATE_CLIENT_ID is required\");\n }\n\n const verifier = generateCodeVerifier();\n const challenge = await computeChallenge(verifier);\n const state = generateState();\n\n const authorizeUrl = new URL(\"/authorize\", baseUrl);\n authorizeUrl.searchParams.set(\"client_id\", clientId);\n authorizeUrl.searchParams.set(\"redirect_uri\", options.redirectUri);\n authorizeUrl.searchParams.set(\"scope\", options.scope ?? \"openid email\");\n authorizeUrl.searchParams.set(\"state\", state);\n authorizeUrl.searchParams.set(\"code_challenge\", challenge);\n authorizeUrl.searchParams.set(\"code_challenge_method\", \"S256\");\n authorizeUrl.searchParams.set(\"response_type\", \"code\");\n\n const response = NextResponse.redirect(authorizeUrl);\n const cookieOptions = pkceCookieOptions();\n response.cookies.set(PKCE_STATE_COOKIE, state, cookieOptions);\n response.cookies.set(PKCE_VERIFIER_COOKIE, verifier, cookieOptions);\n response.cookies.set(\n PKCE_REDIRECT_COOKIE,\n options.afterSignInUrl ?? process.env.IRONGATE_AFTER_SIGN_IN ?? \"/dashboard\",\n cookieOptions\n );\n return response;\n };\n}\n\n// Derived from the canonical TokenSet (not a local redefinition, CC-P1-1) —\n// only the fields the code-exchange response actually needs.\ntype TokenExchangeResponse = Pick<TokenSet, \"accessToken\" | \"refreshToken\" | \"expiresIn\" | \"user\">;\n\nexport interface CallbackOptions {\n onError?: (err: unknown) => Response;\n}\n\nexport function handleCallback(options: CallbackOptions = {}): (request: NextRequest) => Promise<Response> {\n return async (request: NextRequest): Promise<Response> => {\n const url = new URL(request.url);\n const code = url.searchParams.get(\"code\");\n const state = url.searchParams.get(\"state\");\n const oauthError = url.searchParams.get(\"error\");\n const signInUrl = process.env.IRONGATE_SIGN_IN_URL ?? \"/sign-in\";\n\n if (oauthError) {\n return (\n options.onError?.(new IrongateError(\"AUTH_CALLBACK_ERROR\", oauthError)) ??\n NextResponse.redirect(new URL(`${signInUrl}?error=callback_failed`, request.url))\n );\n }\n if (!code) {\n return (\n options.onError?.(new IrongateError(\"AUTH_CODE_MISSING\", \"Missing authorization code\")) ??\n NextResponse.redirect(new URL(`${signInUrl}?error=callback_failed`, request.url))\n );\n }\n\n const storedState = request.cookies.get(PKCE_STATE_COOKIE)?.value;\n const codeVerifier = request.cookies.get(PKCE_VERIFIER_COOKIE)?.value;\n const afterCallbackUrl =\n request.cookies.get(PKCE_REDIRECT_COOKIE)?.value ?? process.env.IRONGATE_AFTER_SIGN_IN ?? \"/dashboard\";\n\n if (!storedState || state !== storedState) {\n return NextResponse.redirect(new URL(`${signInUrl}?error=state_mismatch`, request.url));\n }\n if (!codeVerifier) {\n return (\n options.onError?.(new IrongateError(\"PKCE_VERIFIER_INVALID\", \"Missing PKCE verifier\")) ??\n NextResponse.redirect(new URL(`${signInUrl}?error=callback_failed`, request.url))\n );\n }\n\n const baseUrl = process.env.IRONGATE_BASE_URL;\n const clientId = process.env.IRONGATE_CLIENT_ID;\n if (!baseUrl || !clientId) {\n throw new IrongateError(\"INVALID_CONFIG\", \"IRONGATE_BASE_URL and IRONGATE_CLIENT_ID are required\");\n }\n\n // redirectUri must match what was passed to initiateSignIn() — both\n // point at this same callback route.\n const tokenResponse = await fetch(`${baseUrl}/token`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n grantType: \"authorization_code\",\n code,\n codeVerifier,\n redirectUri: new URL(request.nextUrl.pathname, request.url).toString(),\n clientId,\n }),\n });\n\n if (!tokenResponse.ok) {\n const errorBody = (await tokenResponse.json().catch(() => ({}))) as { code?: IrongateErrorCode; message?: string };\n const err = new IrongateError(errorBody.code ?? \"AUTH_CALLBACK_ERROR\", errorBody.message);\n return options.onError?.(err) ?? NextResponse.redirect(new URL(`${signInUrl}?error=callback_failed`, request.url));\n }\n\n const tokens = (await tokenResponse.json()) as TokenExchangeResponse;\n\n // Verify (not just decode) the freshly-issued access token to obtain\n // trustworthy claims.impersonation for the session cookie — reuses the\n // exact pattern Milestone 2's middleware uses.\n const jwksCache = createJwksCache({ baseUrl, fetch, jwksCacheTtlMs: 3_600_000 });\n const verifyToken = createVerifyToken({\n baseUrl,\n fetch,\n clockSkewToleranceMs: 0,\n jwksCache,\n checkJtiRevoked: undefined,\n });\n const claims = await verifyToken(tokens.accessToken);\n\n const response = NextResponse.redirect(new URL(afterCallbackUrl, request.url));\n const cookieNames = getAuthCookieNames(process.env.IRONGATE_COOKIE_PREFIX);\n const cookieConfig = resolveEnvCookieConfig();\n\n for (const cookie of buildAuthCookies(\n {\n accessToken: tokens.accessToken,\n ...(tokens.refreshToken ? { refreshToken: tokens.refreshToken } : {}),\n expiresIn: tokens.expiresIn,\n ...(tokens.user ? { user: tokens.user } : {}),\n isImpersonating: claims.impersonation === true,\n },\n cookieNames,\n cookieConfig\n )) {\n response.cookies.set(cookie.name, cookie.value, cookie.options);\n }\n\n response.cookies.delete(PKCE_STATE_COOKIE);\n response.cookies.delete(PKCE_VERIFIER_COOKIE);\n response.cookies.delete(PKCE_REDIRECT_COOKIE);\n\n return response;\n };\n}\n\nexport interface SignOutOptions {\n afterSignOutUrl?: string;\n}\n\nexport function signOut(options: SignOutOptions = {}): (request: NextRequest) => Promise<NextResponse> {\n return async (request: NextRequest): Promise<NextResponse> => {\n const cookieNames = getAuthCookieNames(process.env.IRONGATE_COOKIE_PREFIX);\n const accessToken = request.cookies.get(cookieNames.accessToken)?.value;\n const baseUrl = process.env.IRONGATE_BASE_URL;\n\n if (accessToken && baseUrl) {\n try {\n await fetch(`${baseUrl}/v1/auth/logout`, {\n method: \"POST\",\n headers: { Authorization: `Bearer ${accessToken}` },\n });\n } catch {\n // Best-effort server-side logout — cookies are cleared below regardless.\n }\n }\n\n const response = NextResponse.redirect(\n new URL(options.afterSignOutUrl ?? process.env.IRONGATE_AFTER_SIGN_OUT ?? \"/\", request.url)\n );\n const cookieConfig = resolveEnvCookieConfig();\n for (const cookie of buildClearCookies(cookieNames, cookieConfig)) {\n response.cookies.set(cookie.name, cookie.value, cookie.options);\n }\n return response;\n };\n}\n","export type SameSite = \"lax\" | \"strict\" | \"none\";\n\nexport function parseBooleanEnv(value: string | undefined): boolean | undefined {\n if (value === \"true\") return true;\n if (value === \"false\") return false;\n return undefined;\n}\n\n// @irongate-dev/core never reads process.env (it must only receive explicit\n// values from the caller) — this is where the \"Secure in production\"\n// default (spec AC13) actually gets resolved, on the adapter side that's\n// already responsible for bridging env vars into explicit config.\nexport function resolveSecureDefault(explicit?: boolean): boolean {\n return explicit ?? parseBooleanEnv(process.env.IRONGATE_COOKIE_SECURE) ?? process.env.NODE_ENV === \"production\";\n}\n\nexport interface EnvCookieConfig {\n cookieDomain?: string;\n secure: boolean;\n sameSite?: SameSite;\n}\n\nexport function resolveEnvCookieConfig(): EnvCookieConfig {\n const cookieDomain = process.env.IRONGATE_COOKIE_DOMAIN;\n const sameSite = process.env.IRONGATE_COOKIE_SAMESITE as SameSite | undefined;\n return {\n ...(cookieDomain ? { cookieDomain } : {}),\n secure: resolveSecureDefault(),\n ...(sameSite ? { sameSite } : {}),\n };\n}\n"],"mappings":"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","names":[]}
package/package.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "@irongate-dev/nextjs",
3
+ "version": "0.1.0-beta",
4
+ "description": "Next.js adapter for Irongate authentication (App Router + Pages Router)",
5
+ "type": "module",
6
+ "sideEffects": false,
7
+ "publishConfig": {
8
+ "access": "public"
9
+ },
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.js",
14
+ "require": "./dist/index.cjs"
15
+ },
16
+ "./server": {
17
+ "types": "./dist/server.d.ts",
18
+ "import": "./dist/server.js",
19
+ "require": "./dist/server.cjs"
20
+ },
21
+ "./middleware": {
22
+ "types": "./dist/middleware.d.ts",
23
+ "import": "./dist/middleware.js",
24
+ "require": "./dist/middleware.cjs"
25
+ },
26
+ "./client": {
27
+ "types": "./dist/client.d.ts",
28
+ "import": "./dist/client.js",
29
+ "require": "./dist/client.cjs"
30
+ }
31
+ },
32
+ "main": "./dist/index.cjs",
33
+ "module": "./dist/index.js",
34
+ "types": "./dist/index.d.ts",
35
+ "files": [
36
+ "dist"
37
+ ],
38
+ "dependencies": {
39
+ "@irongate-dev/core": "0.1.0-beta",
40
+ "@irongate-dev/react": "0.1.0-beta",
41
+ "@irongate-dev/types": "0.1.0-beta"
42
+ },
43
+ "peerDependencies": {
44
+ "next": ">=14.0.0",
45
+ "react": ">=18.0.0"
46
+ },
47
+ "devDependencies": {
48
+ "next": "^15.5.21",
49
+ "react": "^18.3.0",
50
+ "react-dom": "^18.3.0",
51
+ "@types/react": "^18.3.0",
52
+ "@types/react-dom": "^18.3.0",
53
+ "@testing-library/react": "^16.0.1",
54
+ "happy-dom": "^20.8.9",
55
+ "tsup": "^8.0.0",
56
+ "typescript": "5.4.x",
57
+ "vitest": "^3.2.6"
58
+ },
59
+ "scripts": {
60
+ "build": "tsup",
61
+ "typecheck": "tsc --noEmit",
62
+ "test": "vitest run --passWithNoTests",
63
+ "lint": "eslint src/",
64
+ "clean": "rm -rf dist"
65
+ }
66
+ }