@xyd-js/plugin-access-control 0.0.0-build-8804789-20260430104829
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/LICENSE +21 -0
- package/dist/AccessControlContext.js +130 -0
- package/dist/AccessControlContext.js.map +1 -0
- package/dist/AuthCallbackPage.js +116 -0
- package/dist/AuthCallbackPage.js.map +1 -0
- package/dist/AuthGuard.js +115 -0
- package/dist/AuthGuard.js.map +1 -0
- package/dist/LoginPage.js +158 -0
- package/dist/LoginPage.js.map +1 -0
- package/dist/client.d.ts +167 -0
- package/dist/client.js +484 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +1200 -0
- package/dist/index.js.map +1 -0
- package/package.json +56 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/access.ts","../src/devOnly.ts","../src/virtual.ts","../src/scripts/authPrehydration.ts","../src/middleware/shared.ts","../src/middleware/netlify.ts","../src/middleware/vercel.ts","../src/middleware/cloudflare.ts","../src/middleware/node.ts","../src/content.ts","../src/components/LoginPage.tsx","../src/components/AccessControlContext.tsx","../src/components/AuthCallbackPage.tsx","../src/styles/login.css","../src/styles/callback.css","../src/components/AuthGuard.tsx","../src/navigation.ts","../src/index.ts"],"sourcesContent":["import type { AccessControl, AccessControlRule } from \"@xyd-js/core\";\n\nexport type AccessLevel = \"public\" | \"authenticated\" | string; // string = comma-separated groups\n\nexport type AccessMap = Record<string, AccessLevel>;\n\nexport interface AccessEvaluation {\n allowed: boolean;\n reason: string;\n}\n\n/**\n * Matches a path against a glob-like pattern.\n * Supports ** (any depth) and * (single segment).\n */\nexport function matchPattern(pattern: string, path: string): boolean {\n const regexStr = pattern\n .replace(/\\*\\*/g, \"___GLOBSTAR___\")\n .replace(/\\*/g, \"[^/]*\")\n .replace(/___GLOBSTAR___/g, \".*\");\n\n const regex = new RegExp(`^${regexStr}$`);\n return regex.test(path);\n}\n\n/**\n * Evaluate access for a specific page given its metadata and access control config.\n * Returns the access level string for the access map.\n */\nexport function resolvePageAccess(\n pagePath: string,\n metadata: { public?: boolean; accessGroups?: string[] },\n config: AccessControl\n): AccessLevel {\n // Normalize: ensure path has leading slash for consistent matching\n const normalizedPath = pagePath.startsWith(\"/\") ? pagePath : `/${pagePath}`;\n\n // 1. Frontmatter overrides (highest priority)\n if (metadata.public === true) {\n return \"public\";\n }\n if (metadata.public === false) {\n if (metadata.accessGroups?.length) {\n return metadata.accessGroups.join(\",\");\n }\n return \"authenticated\";\n }\n\n // 2. Pattern rules (first match wins)\n if (config.rules) {\n for (const rule of config.rules) {\n if (matchPattern(rule.match, normalizedPath)) {\n if (rule.access === \"public\") {\n return \"public\";\n }\n if (rule.groups?.length) {\n return rule.groups.join(\",\");\n }\n return \"authenticated\";\n }\n }\n }\n\n // 3. Default access (lowest priority)\n return config.defaultAccess === \"protected\" ? \"authenticated\" : \"public\";\n}\n\n/**\n * Evaluate whether a user has access to a page.\n */\nexport function evaluateAccess(\n pagePath: string,\n accessMap: AccessMap,\n userGroups: string[]\n): AccessEvaluation {\n const access = accessMap[pagePath];\n\n // No entry in access map = public\n if (!access || access === \"public\") {\n return { allowed: true, reason: `access:public` };\n }\n\n // Requires authentication\n if (access === \"authenticated\") {\n return {\n allowed: userGroups.length > 0 || false,\n reason: \"access:authenticated\",\n };\n }\n\n // Group-based access\n const requiredGroups = access.split(\",\");\n const hasGroup = requiredGroups.some((g) => userGroups.includes(g));\n return {\n allowed: hasGroup,\n reason: `access:groups:${access}`,\n };\n}\n\n/**\n * Build a complete access map from page path mapping and access control config.\n * Used at build time to pre-compute access levels for all pages.\n */\nexport function buildAccessMap(\n pagePathMapping: Record<string, string>,\n metadataMap: Record<string, { public?: boolean; accessGroups?: string[] }>,\n config: AccessControl\n): AccessMap {\n const accessMap: AccessMap = {};\n\n for (const pagePath of Object.keys(pagePathMapping)) {\n const metadata = metadataMap[pagePath] || {};\n accessMap[pagePath] = resolvePageAccess(pagePath, metadata, config);\n }\n\n return accessMap;\n}\n","/**\n * Check if running in development mode.\n * Server-side: checks NODE_ENV\n * Client-side: checks import.meta.env (set by Vite)\n */\nexport function isDevEnvironment(): boolean {\n // Server-side (Node.js)\n if (typeof window === \"undefined\") {\n return process.env.NODE_ENV !== \"production\";\n }\n\n // Client-side (Vite)\n try {\n return !!(import.meta as any).env?.DEV;\n } catch {\n return false;\n }\n}\n\n/**\n * Check if auth bypass is enabled. Only works in development mode.\n * Controlled by XYD_AUTH_BYPASS=1 environment variable.\n */\nexport function isAuthBypassed(): boolean {\n if (!isDevEnvironment()) return false;\n\n return (\n process.env.XYD_AUTH_BYPASS === \"1\" ||\n process.env.XYD_AUTH_BYPASS === \"true\"\n );\n}","import type { Plugin as VitePlugin } from \"vite\";\nimport type { AccessControl } from \"@xyd-js/core\";\nimport type { AccessMap } from \"./access\";\nimport { isAuthBypassed } from \"./devOnly\";\n\nconst VIRTUAL_SETTINGS_ID = \"virtual:xyd-access-control-settings\";\nconst RESOLVED_SETTINGS_ID = \"\\0\" + VIRTUAL_SETTINGS_ID;\n\nconst VIRTUAL_GUARD_ID = \"virtual:xyd-access-control-guard\";\nconst RESOLVED_GUARD_ID = \"\\0\" + VIRTUAL_GUARD_ID;\n\nconst VIRTUAL_PAGES_ID = \"virtual:xyd-plugin-pages\";\nconst RESOLVED_PAGES_ID = \"\\0\" + VIRTUAL_PAGES_ID;\n\ntype AccessMapBuilder = (config: AccessControl) => AccessMap;\n\n/**\n * Vite plugin that provides the access control settings as a virtual module.\n * The access map is built lazily (on first load) because __xydPagePathMapping\n * is not available until after pluginDocs() runs.\n */\nexport function virtualAccessControlSettingsPlugin(\n config: AccessControl,\n buildAccessMap: AccessMapBuilder\n): VitePlugin {\n let cachedAccessMap: AccessMap | null = null;\n\n function getAccessMap(): AccessMap {\n if (!cachedAccessMap) {\n cachedAccessMap = buildAccessMap(config);\n }\n return cachedAccessMap;\n }\n\n return {\n name: \"xyd-plugin-access-control-virtual-settings\",\n resolveId(id) {\n if (id === VIRTUAL_SETTINGS_ID) return RESOLVED_SETTINGS_ID;\n if (id === VIRTUAL_GUARD_ID) return RESOLVED_GUARD_ID;\n if (id === VIRTUAL_PAGES_ID) return RESOLVED_PAGES_ID;\n return null;\n },\n load(id) {\n if (id === RESOLVED_SETTINGS_ID) {\n const isBypassed = isAuthBypassed();\n\n // Sanitize config - remove secrets before bundling\n const safeConfig = sanitizeConfig(config);\n\n // Build access map lazily - __xydPagePathMapping is now available\n const accessMap = isBypassed ? {} : getAccessMap();\n\n if (isBypassed) {\n console.log(\"[xyd:access-control] Auth bypass enabled (XYD_AUTH_BYPASS). All pages are public.\");\n }\n\n return `\nexport const accessControlConfig = ${JSON.stringify(safeConfig)};\nexport const accessMap = ${JSON.stringify(accessMap)};\n`;\n }\n if (id === RESOLVED_GUARD_ID) {\n return [\n `export { default as AuthGuard, useAuth } from \"@xyd-js/plugin-access-control/AuthGuard\";`,\n `export { AccessControlProvider, useAccessControl } from \"@xyd-js/plugin-access-control/AccessControlContext\";`,\n ].join(\"\\n\");\n }\n if (id === RESOLVED_PAGES_ID) {\n // Generate imports for all plugin pages from their dist paths\n const pluginPages: any[] = (globalThis as any).__xydPluginPages || [];\n const imports: string[] = [];\n const entries: string[] = [];\n\n pluginPages.forEach((page: any, i: number) => {\n const dist = page.dist || page._pluginPkg;\n if (dist) {\n imports.push(`import Page${i}, * as PageMod${i} from \"${dist}\";`);\n entries.push(` \"${page.route}\": { component: Page${i}, seoTags: PageMod${i}.seoTags, shadowCss: PageMod${i}.shadowCss }`);\n }\n });\n\n return [\n ...imports,\n `export { AccessControlProvider } from \"@xyd-js/plugin-access-control/AccessControlContext\";`,\n `export const pluginPages = {`,\n entries.join(\",\\n\"),\n `};`,\n ].join(\"\\n\");\n }\n return null;\n },\n // Invalidate cached access map when settings change (dev HMR)\n handleHotUpdate() {\n cachedAccessMap = null;\n },\n };\n}\n\n/**\n * Remove sensitive values (secrets, passwords) from config before bundling.\n */\nfunction sanitizeConfig(config: AccessControl): AccessControl {\n const safe = { ...config };\n\n if (safe.provider) {\n const provider = { ...safe.provider };\n\n if (\"secret\" in provider) {\n provider.secret = undefined;\n }\n\n safe.provider = provider as any;\n }\n\n return safe;\n}\n","/**\n * Pre-hydration script for access control.\n * Runs synchronously in <head> before React hydration.\n * Prevents flash of protected content (FOPC).\n *\n * Placeholders %%COOKIE_NAME%% and %%GROUPS_CLAIM%% are replaced at build time.\n */\nexport function generateAuthPrehydrationScript(\n cookieName: string,\n groupsClaim: string\n): string {\n const script = `(function(){var n=\"%%COOKIE_NAME%%\";var t=null;try{t=localStorage.getItem(n)}catch(e){}if(!t){var c=document.cookie.split(\";\");for(var i=0;i<c.length;i++){var p=c[i].trim().split(\"=\");if(p[0]===n||p[0]===n+\"-state\"){t=decodeURIComponent(p.slice(1).join(\"=\"));break}}}var a=false;var g=[];if(t){try{var d=JSON.parse(atob(t.split(\".\")[1]));if(d.exp&&d.exp*1000>Date.now()){a=true;g=d[\"%%GROUPS_CLAIM%%\"]||[]}}catch(e){}}window.__xydAuthState={authenticated:a,groups:g,token:a?t:null};document.documentElement.setAttribute(\"data-auth\",a?\"authenticated\":\"anonymous\")})();`;\n\n return script\n .replace(/%%COOKIE_NAME%%/g, cookieName)\n .replace(/%%GROUPS_CLAIM%%/g, groupsClaim);\n}\n","import type { AccessControl } from \"@xyd-js/core\";\nimport type { AccessMap } from \"../access\";\n\n/**\n * Generates the core middleware logic as a string, shared across all platforms.\n * Platform-specific adapters wrap this in their runtime format.\n */\nexport function generateMiddlewareCore(\n config: AccessControl,\n accessMap: AccessMap\n): string {\n const loginUrl = \"loginUrl\" in config.provider ? config.provider.loginUrl : \"\";\n const cookieName = config.session?.cookieName || \"xyd-auth-token\";\n const groupsClaim =\n \"groupsClaim\" in config.provider\n ? config.provider.groupsClaim || \"groups\"\n : \"groups\";\n const defaultAccess = config.defaultAccess || \"public\";\n\n return `\nconst ACCESS_MAP = ${JSON.stringify(accessMap)};\nconst LOGIN_URL = ${JSON.stringify(loginUrl)};\nconst COOKIE_NAME = ${JSON.stringify(cookieName)};\nconst GROUPS_CLAIM = ${JSON.stringify(groupsClaim)};\nconst DEFAULT_ACCESS = ${JSON.stringify(defaultAccess)};\n\nfunction parseCookies(cookieHeader) {\n const cookies = {};\n if (!cookieHeader) return cookies;\n cookieHeader.split(\";\").forEach(function(c) {\n const parts = c.trim().split(\"=\");\n if (parts.length >= 2) {\n cookies[parts[0]] = decodeURIComponent(parts.slice(1).join(\"=\"));\n }\n });\n return cookies;\n}\n\nfunction decodeJWTPayload(token) {\n try {\n const parts = token.split(\".\");\n if (parts.length !== 3) return null;\n return JSON.parse(atob(parts[1]));\n } catch {\n return null;\n }\n}\n\nfunction handleAuthRequest(request) {\n const url = new URL(request.url);\n const path = url.pathname;\n\n // Skip asset requests\n if (path.startsWith(\"/assets/\") || path.match(/\\\\.[a-z0-9]+$/i)) {\n return null; // pass through\n }\n\n // Check access requirement\n const access = ACCESS_MAP[path] || DEFAULT_ACCESS;\n if (access === \"public\") return null; // pass through\n\n // Check auth cookie\n const cookies = parseCookies(request.headers.get(\"cookie\"));\n const token = cookies[COOKIE_NAME];\n\n if (!token) {\n const redirectUrl = LOGIN_URL\n ? LOGIN_URL + (LOGIN_URL.includes(\"?\") ? \"&\" : \"?\") + \"redirect=\" + encodeURIComponent(url.href)\n : null;\n return { status: 302, redirect: redirectUrl };\n }\n\n // Decode and validate token\n const payload = decodeJWTPayload(token);\n if (!payload || (payload.exp && payload.exp * 1000 < Date.now())) {\n const redirectUrl = LOGIN_URL\n ? LOGIN_URL + (LOGIN_URL.includes(\"?\") ? \"&\" : \"?\") + \"redirect=\" + encodeURIComponent(url.href)\n : null;\n return { status: 302, redirect: redirectUrl };\n }\n\n // Check group access\n if (access !== \"authenticated\") {\n const requiredGroups = access.split(\",\");\n const userGroups = payload[GROUPS_CLAIM] || [];\n const hasAccess = requiredGroups.some(function(g) { return userGroups.includes(g); });\n if (!hasAccess) {\n return { status: 404 };\n }\n }\n\n return null; // pass through - authorized\n}\n`;\n}\n","import type { AccessControl } from \"@xyd-js/core\";\nimport type { AccessMap } from \"../access\";\nimport { generateMiddlewareCore } from \"./shared\";\n\n/**\n * Generates Netlify Edge Function for access control.\n * Creates netlify/edge-functions/access-control.ts and updates netlify.toml.\n */\nexport async function generateNetlifyEdge(\n config: AccessControl,\n outputDir: string\n): void {\n const { writeFileSync, mkdirSync, readFileSync, existsSync } = await import(\"node:fs\");\n const { join } = await import(\"node:path\");\n const projectRoot = join(outputDir, \"../..\");\n const edgeFnDir = join(projectRoot, \"netlify/edge-functions\");\n mkdirSync(edgeFnDir, { recursive: true });\n\n const accessMap: AccessMap = (globalThis as any).__xydAccessMap || {};\n\n const middlewareCore = generateMiddlewareCore(config, accessMap);\n\n const edgeFunction = `\n${middlewareCore}\n\nexport default async function handler(request) {\n const result = handleAuthRequest(request);\n\n if (!result) return; // pass through to static files\n\n if (result.redirect) {\n return Response.redirect(result.redirect, 302);\n }\n\n if (result.status === 404) {\n return new Response(\"Not Found\", { status: 404 });\n }\n}\n\nexport const config = { path: \"/*\" };\n`;\n\n writeFileSync(join(edgeFnDir, \"access-control.js\"), edgeFunction, \"utf-8\");\n\n // Append edge function declaration to netlify.toml if not already present\n const tomlPath = join(projectRoot, \"netlify.toml\");\n const declaration = `\n[[edge_functions]]\n function = \"access-control\"\n path = \"/*\"\n`;\n\n if (existsSync(tomlPath)) {\n const existing = readFileSync(tomlPath, \"utf-8\");\n if (!existing.includes('function = \"access-control\"')) {\n writeFileSync(tomlPath, existing + \"\\n\" + declaration, \"utf-8\");\n }\n } else {\n writeFileSync(tomlPath, declaration, \"utf-8\");\n }\n}\n","import type { AccessControl } from \"@xyd-js/core\";\nimport type { AccessMap } from \"../access\";\nimport { generateMiddlewareCore } from \"./shared\";\n\n/**\n * Generates Vercel Routing Middleware for access control.\n * Creates middleware.js at project root.\n */\nexport async function generateVercelMiddleware(\n config: AccessControl,\n outputDir: string\n): void {\n const { writeFileSync } = await import(\"node:fs\");\n const { join } = await import(\"node:path\");\n const projectRoot = join(outputDir, \"../..\");\n const accessMap: AccessMap = (globalThis as any).__xydAccessMap || {};\n\n const middlewareCore = generateMiddlewareCore(config, accessMap);\n\n const middleware = `\n${middlewareCore}\n\nexport default function middleware(request) {\n const result = handleAuthRequest(request);\n\n if (!result) return; // pass through\n\n if (result.redirect) {\n return new Response(null, {\n status: 302,\n headers: { Location: result.redirect },\n });\n }\n\n if (result.status === 404) {\n return new Response(\"Not Found\", { status: 404 });\n }\n}\n`;\n\n writeFileSync(join(projectRoot, \"middleware.js\"), middleware, \"utf-8\");\n}\n","import type { AccessControl } from \"@xyd-js/core\";\nimport type { AccessMap } from \"../access\";\nimport { generateMiddlewareCore } from \"./shared\";\n\n/**\n * Generates Cloudflare Pages Function middleware for access control.\n * Creates functions/_middleware.js alongside the static output.\n */\nexport async function generateCloudflareMiddleware(\n config: AccessControl,\n outputDir: string\n): void {\n const { writeFileSync, mkdirSync } = await import(\"node:fs\");\n const { join } = await import(\"node:path\");\n const functionsDir = join(outputDir, \"functions\");\n mkdirSync(functionsDir, { recursive: true });\n\n const accessMap: AccessMap = (globalThis as any).__xydAccessMap || {};\n\n const middlewareCore = generateMiddlewareCore(config, accessMap);\n\n const middleware = `\n${middlewareCore}\n\nexport async function onRequest(context) {\n const result = handleAuthRequest(context.request);\n\n if (!result) return context.next(); // pass through to static files\n\n if (result.redirect) {\n return Response.redirect(result.redirect, 302);\n }\n\n if (result.status === 404) {\n return new Response(\"Not Found\", { status: 404 });\n }\n}\n`;\n\n writeFileSync(join(functionsDir, \"_middleware.js\"), middleware, \"utf-8\");\n}\n","import type { AccessControl } from \"@xyd-js/core\";\nimport type { AccessMap } from \"../access\";\n\n/**\n * Generates a standalone Node.js server for access control.\n * The server serves static files, verifies JWT signatures, and enforces access rules.\n * Output: server.mjs in the build output directory.\n *\n * Usage after build:\n * node .xyd/build/client/server.mjs\n */\nexport async function generateNodeServer(\n config: AccessControl,\n outputDir: string\n): void {\n const { writeFileSync } = await import(\"node:fs\");\n const { join } = await import(\"node:path\");\n const accessMap: AccessMap = (globalThis as any).__xydAccessMap || {};\n const cookieName = config.session?.cookieName || \"xyd-auth-token\";\n const maxAge = config.session?.maxAge || 86400;\n const groupsClaim =\n \"groupsClaim\" in config.provider\n ? (config.provider as any).groupsClaim || \"groups\"\n : \"groups\";\n const loginUrl =\n \"loginUrl\" in config.provider ? (config.provider as any).loginUrl || \"/login\" : \"/login\";\n const secret = \"secret\" in config.provider ? (config.provider as any).secret || \"\" : \"\";\n\n const imp = \"import\";\n\n const server = `#!/usr/bin/env node\n/**\n * Auto-generated by xyd build with deploy.platform: \"node-edge\"\n * Standalone access control server with JWT signature verification.\n *\n * Usage:\n * node server.mjs\n * # or: PORT=8080 node server.mjs\n */\n${imp} { createServer } from \"node:http\";\n${imp} { createHmac } from \"node:crypto\";\n${imp} { readFileSync, existsSync } from \"node:fs\";\n${imp} { join, extname } from \"node:path\";\n${imp} { fileURLToPath } from \"node:url\";\n\nconst __dirname = fileURLToPath(new URL(\".\", import.meta.url));\nconst PORT = parseInt(process.env.PORT || \"3000\", 10);\nconst STATIC_DIR = __dirname;\nconst COOKIE_NAME = ${JSON.stringify(cookieName)};\nconst MAX_AGE = ${maxAge};\nconst GROUPS_CLAIM = ${JSON.stringify(groupsClaim)};\nconst LOGIN_URL = ${JSON.stringify(loginUrl)};\nconst JWT_SECRET = process.env.AUTH_SECRET || ${JSON.stringify(secret.startsWith(\"$\") ? \"\" : secret)};\nconst ACCESS_MAP = ${JSON.stringify(accessMap)};\n\nconst MIME = {\n \".html\":\"text/html\",\".js\":\"application/javascript\",\".css\":\"text/css\",\n \".json\":\"application/json\",\".svg\":\"image/svg+xml\",\".png\":\"image/png\",\n \".jpg\":\"image/jpeg\",\".ico\":\"image/x-icon\",\".woff\":\"font/woff\",\n \".woff2\":\"font/woff2\",\".ttf\":\"font/ttf\",\".map\":\"application/json\",\n};\n\nfunction parseCookies(h) {\n const c = {};\n if (!h) return c;\n h.split(\";\").forEach(s => { const [k,...v] = s.trim().split(\"=\"); c[k] = decodeURIComponent(v.join(\"=\")); });\n return c;\n}\n\nfunction verifyJWT(token) {\n try {\n const [header, payload, signature] = token.split(\".\");\n if (!header || !payload || !signature) return null;\n if (JWT_SECRET) {\n const expected = createHmac(\"sha256\", JWT_SECRET).update(header + \".\" + payload).digest(\"base64url\");\n if (signature !== expected) return null;\n }\n const decoded = JSON.parse(Buffer.from(payload, \"base64url\").toString());\n if (decoded.exp && decoded.exp * 1000 < Date.now()) return null;\n return decoded;\n } catch { return null; }\n}\n\nfunction checkAccess(pathname, cookies) {\n const access = ACCESS_MAP[pathname] || ACCESS_MAP[pathname.replace(/\\\\/$/, \"\")] || null;\n if (!access || access === \"public\") return { ok: true };\n const token = cookies[COOKIE_NAME];\n if (!token) return { ok: false, reason: \"no-token\" };\n const payload = verifyJWT(token);\n if (!payload) return { ok: false, reason: \"invalid-token\" };\n if (access === \"authenticated\") return { ok: true, user: payload };\n const userGroups = payload[GROUPS_CLAIM] || [];\n if (access.split(\",\").some(g => userGroups.includes(g))) return { ok: true, user: payload };\n return { ok: false, reason: \"insufficient-groups\" };\n}\n\nfunction serve(res, filePath) {\n try {\n if (!existsSync(filePath)) { res.writeHead(404); res.end(\"Not Found\"); return; }\n const ext = extname(filePath);\n res.writeHead(200, { \"Content-Type\": MIME[ext] || \"application/octet-stream\" });\n res.end(readFileSync(filePath));\n } catch {\n if (!res.headersSent) { res.writeHead(500); }\n res.end(\"Error\");\n }\n}\n\nconst server = createServer((req, res) => {\n const url = new URL(req.url, \"http://localhost:\" + PORT);\n const path = url.pathname;\n const cookies = parseCookies(req.headers.cookie);\n\n // Static assets\n if (path.startsWith(\"/assets/\") || path.match(/\\\\.\\\\w+$/)) {\n return serve(res, join(STATIC_DIR, path));\n }\n\n // Test login — DEVELOPMENT ONLY. Disabled in production.\n if (path === \"/auth/test-login\") {\n if (process.env.NODE_ENV === \"production\" && !process.env.XYD_TEST_LOGIN) {\n res.writeHead(404); res.end(\"Not Found\"); return;\n }\n const groups = (url.searchParams.get(\"groups\") || \"\").split(\",\").filter(Boolean);\n const redirect = url.searchParams.get(\"redirect\") || \"/\";\n if (!JWT_SECRET) { res.writeHead(500); res.end(\"AUTH_SECRET not set\"); return; }\n const header = Buffer.from(JSON.stringify({ alg: \"HS256\", typ: \"JWT\" })).toString(\"base64url\");\n const payload = Buffer.from(JSON.stringify({\n sub: groups.includes(\"admin\") ? \"admin\" : \"user\",\n [GROUPS_CLAIM]: groups,\n exp: Math.floor(Date.now() / 1000) + MAX_AGE,\n iat: Math.floor(Date.now() / 1000),\n })).toString(\"base64url\");\n const sig = createHmac(\"sha256\", JWT_SECRET).update(header + \".\" + payload).digest(\"base64url\");\n res.writeHead(302, {\n Location: redirect,\n \"Set-Cookie\": COOKIE_NAME + \"=\" + header + \".\" + payload + \".\" + sig + \"; Path=/; Max-Age=\" + MAX_AGE + \"; SameSite=Lax\",\n });\n res.end(); return;\n }\n\n // JWT callback: external auth service POSTs or GETs a token\n // Accepts: ?token=JWT&redirect=/page or POST body with token field\n if (path === \"/auth/jwt-callback\" || path === ${JSON.stringify(\"callbackPath\" in config.provider ? (config.provider as any).callbackPath || \"/auth/jwt-callback\" : \"/auth/jwt-callback\")}) {\n let token = url.searchParams.get(\"token\") || url.searchParams.get(\"fern_token\") || \"\";\n const redirect = url.searchParams.get(\"redirect\") || url.searchParams.get(\"state\") || \"/\";\n\n if (token) {\n const verified = verifyJWT(token);\n if (!verified) {\n res.writeHead(401); res.end(\"Invalid or expired token\"); return;\n }\n res.writeHead(302, {\n Location: redirect,\n \"Set-Cookie\": COOKIE_NAME + \"=\" + token + \"; Path=/; Max-Age=\" + MAX_AGE + \"; SameSite=Lax\",\n });\n res.end(); return;\n }\n\n // No token in query — serve the callback HTML page (handles hash fragment client-side)\n let fp = join(STATIC_DIR, path, \"index.html\");\n if (!existsSync(fp)) fp = join(STATIC_DIR, \"index.html\");\n return serve(res, fp);\n }\n\n // Logout\n if (path === \"/auth/logout\") {\n res.writeHead(302, {\n Location: \"/\",\n \"Set-Cookie\": COOKIE_NAME + \"=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT\",\n });\n res.end(); return;\n }\n\n // Protected content chunks\n if (path.startsWith(\"/__xyd_protected_content/\")) {\n const r = checkAccess(\"/protected\", cookies);\n if (!r.ok) { res.writeHead(401); res.end(\"Unauthorized\"); return; }\n return serve(res, join(STATIC_DIR, path));\n }\n\n // Access check\n const result = checkAccess(path, cookies);\n if (!result.ok) {\n // Always redirect to /login (xyd login page), not directly to the external auth URL.\n // The login page UI handles redirecting to the external provider.\n const redir = \"/login?redirect=\" + encodeURIComponent(path);\n console.log(\"[access-control] \" + path + \" → 302 (\" + result.reason + \")\");\n res.writeHead(302, { Location: redir }); res.end(); return;\n }\n\n if (result.user) console.log(\"[access-control] \" + path + \" → 200 (user: \" + result.user.sub + \")\");\n else console.log(\"[access-control] \" + path + \" → 200 (public)\");\n\n // Serve page\n let fp = join(STATIC_DIR, path, \"index.html\");\n if (!existsSync(fp)) fp = join(STATIC_DIR, path + \".html\");\n if (!existsSync(fp)) fp = join(STATIC_DIR, \"index.html\");\n serve(res, fp);\n});\n\nserver.listen(PORT, () => {\n console.log(\"\\\\n xyd access-control server running at http://localhost:\" + PORT);\n console.log(\" Callback: /auth/jwt-callback?token=JWT&redirect=/\");\n console.log(\" Logout: /auth/logout\");\n if (process.env.NODE_ENV !== \"production\" || process.env.XYD_TEST_LOGIN) {\n console.log(\" Test: /auth/test-login?groups=admin&redirect=/ (dev only)\");\n }\n console.log(\"\");\n});\n`;\n\n writeFileSync(join(outputDir, \"server.mjs\"), server, \"utf-8\");\n}","import type { Plugin as VitePlugin } from \"vite\";\nimport type { AccessControl } from \"@xyd-js/core\";\nimport type { AccessMap } from \"./access\";\nimport { isAuthBypassed } from \"./devOnly\";\n\ntype AccessMapBuilder = (config: AccessControl) => AccessMap;\n\n/**\n * Vite plugin that compiles protected page content into separate chunks\n * served from /__xyd_protected_content/{slug}.js\n *\n * During build:\n * - Protected pages are compiled to MDX code strings\n * - Each is written as a separate file in the output directory\n *\n * During dev:\n * - A middleware intercepts requests to /__xyd_protected_content/\n * - Compiles the page on-demand and returns the MDX code\n */\nexport function protectedContentPlugin(\n config: AccessControl,\n buildAccessMap: AccessMapBuilder\n): VitePlugin {\n let cachedAccessMap: AccessMap | null = null;\n\n function getAccessMap(): AccessMap {\n if (!cachedAccessMap) {\n cachedAccessMap = buildAccessMap(config);\n }\n return cachedAccessMap;\n }\n return {\n name: \"xyd-plugin-access-control-protected-content\",\n\n configureServer(server) {\n // Redirect unauthenticated requests to protected pages (works for curl, browsers, etc.)\n server.middlewares.use((req, res, next) => {\n const url = req.url?.split(\"?\")[0] || \"\";\n\n // Skip assets, virtual modules, and special paths\n if (\n url.startsWith(\"/assets/\") ||\n url.startsWith(\"/@\") ||\n url.startsWith(\"/__\") ||\n url.startsWith(\"/node_modules/\") ||\n url.includes(\".\") ||\n url === \"/login\" ||\n url.startsWith(\"/auth/\")\n ) {\n return next();\n }\n\n const am = getAccessMap();\n const slug = url.replace(/^\\//, \"\");\n const access = am[\"/\" + slug] || am[slug];\n\n if (!access || access === \"public\") {\n return next();\n }\n\n // Check auth cookie\n const cookieHeader = req.headers.cookie || \"\";\n const cookieName = config.session?.cookieName || \"xyd-auth-token\";\n const hasToken = cookieHeader.includes(`${cookieName}=`);\n\n const isBypassed = isAuthBypassed();\n\n if (!hasToken && !isBypassed) {\n // Always redirect to /login (xyd login page), not the external auth URL.\n const redirect = \"/login?redirect=\" + encodeURIComponent(req.url || \"/\");\n res.writeHead(302, { Location: redirect });\n res.end();\n return;\n }\n\n next();\n });\n\n // Dev server middleware: compile protected pages on-demand\n server.middlewares.use(async (req, res, next) => {\n if (!req.url?.startsWith(\"/__xyd_protected_content/\")) {\n return next();\n }\n\n const slug = decodeURIComponent(\n req.url.replace(\"/__xyd_protected_content/\", \"\").replace(/\\.js$/, \"\")\n );\n\n const am = getAccessMap();\n const pageAccess = am[\"/\" + slug] || am[slug];\n if (!pageAccess || pageAccess === \"public\") {\n res.statusCode = 404;\n res.end(\"Not found\");\n return;\n }\n\n // Check auth cookie/token from request\n const cookieHeader = req.headers.cookie || \"\";\n const hasAuthToken = cookieHeader.includes(\"xyd-auth-token=\");\n\n const isBypassed = isAuthBypassed();\n\n if (!hasAuthToken && !isBypassed) {\n res.statusCode = 401;\n res.end(\"Unauthorized\");\n return;\n }\n\n // Compile the page content\n const pagePath = globalThis.__xydPagePathMapping?.[slug];\n if (!pagePath) {\n res.statusCode = 404;\n res.end(\"Page not found\");\n return;\n }\n\n try {\n const { ContentFS } = await import(\"@xyd-js/content\");\n const { markdownPlugins } = await import(\"@xyd-js/content/md\");\n\n const settings = globalThis.__xydSettings;\n const mdPlugins = await markdownPlugins({ maxDepth: 2 }, settings);\n\n const remarkPlugins = [...mdPlugins.remarkPlugins];\n const rehypePlugins = [...mdPlugins.rehypePlugins];\n\n if (globalThis.__xydUserMarkdownPlugins?.remark?.length) {\n remarkPlugins.push(globalThis.__xydUserMarkdownPlugins.remark);\n }\n if (globalThis.__xydUserMarkdownPlugins?.rehype?.length) {\n rehypePlugins.push(globalThis.__xydUserMarkdownPlugins.rehype);\n }\n\n const contentFs = new ContentFS(\n settings,\n remarkPlugins,\n rehypePlugins,\n mdPlugins.recmaPlugins,\n globalThis.__xydUserMarkdownPlugins?.remarkRehypeHandlers || {}\n );\n\n const code = await contentFs.compile(pagePath);\n\n res.setHeader(\"Content-Type\", \"application/javascript\");\n res.setHeader(\"Cache-Control\", \"no-store\");\n res.end(code);\n } catch (e) {\n console.error(\n \"[xyd:access-control] Failed to compile protected content:\",\n e\n );\n res.statusCode = 500;\n res.end(\"Internal error\");\n }\n });\n },\n\n async closeBundle() {\n const { writeFileSync, mkdirSync } = await import(\"node:fs\");\n const { join } = await import(\"node:path\");\n // Build time: compile all protected pages into separate files\n const outputDir = join(\n process.cwd(),\n \".xyd/build/client/__xyd_protected_content\"\n );\n mkdirSync(outputDir, { recursive: true });\n\n const pagePathMapping = globalThis.__xydPagePathMapping || {};\n\n for (const [slug, access] of Object.entries(getAccessMap())) {\n if (access === \"public\") continue;\n\n const normalizedSlug = slug.startsWith(\"/\") ? slug.slice(1) : slug;\n const pagePath = pagePathMapping[normalizedSlug] || pagePathMapping[slug];\n if (!pagePath) continue;\n\n try {\n const { ContentFS } = await import(\"@xyd-js/content\");\n const { markdownPlugins } = await import(\"@xyd-js/content/md\");\n\n const settings = globalThis.__xydSettings;\n const mdPlugins = await markdownPlugins({ maxDepth: 2 }, settings);\n\n const remarkPlugins = [...mdPlugins.remarkPlugins];\n const rehypePlugins = [...mdPlugins.rehypePlugins];\n\n if (globalThis.__xydUserMarkdownPlugins?.remark?.length) {\n remarkPlugins.push(globalThis.__xydUserMarkdownPlugins.remark);\n }\n if (globalThis.__xydUserMarkdownPlugins?.rehype?.length) {\n rehypePlugins.push(globalThis.__xydUserMarkdownPlugins.rehype);\n }\n\n const contentFs = new ContentFS(\n settings,\n remarkPlugins,\n rehypePlugins,\n mdPlugins.recmaPlugins,\n globalThis.__xydUserMarkdownPlugins?.remarkRehypeHandlers || {}\n );\n\n const code = await contentFs.compile(pagePath);\n const fileName = `${encodeURIComponent(normalizedSlug)}.js`;\n writeFileSync(join(outputDir, fileName), code, \"utf-8\");\n } catch (e) {\n console.error(\n `[xyd:access-control] Failed to compile protected page ${slug}:`,\n e\n );\n }\n }\n },\n };\n}\n","import React from \"react\";\nimport { AccessControlProvider, useAccessControl } from \"./AccessControlContext\";\n\n/**\n * Default login page. Wraps itself with AccessControlProvider\n * so it works regardless of the host wrapper.\n */\nexport default function LoginPage() {\n return (\n <AccessControlProvider>\n <LoginPageUI />\n </AccessControlProvider>\n );\n}\n\nfunction LoginPageUI() {\n const {\n providerType,\n hasExternalAuth,\n title,\n description,\n logo,\n backgroundImage,\n error,\n signInWithOAuth,\n signInWithRedirect,\n signInAsUser,\n signInAsAdmin,\n } = useAccessControl();\n\n const handleSignIn = () => {\n if (providerType === \"oauth\") signInWithOAuth();\n else signInWithRedirect();\n };\n\n const bgOverride = backgroundImage\n ? { backgroundImage: `url(${backgroundImage})`, backgroundSize: \"cover\" as const, backgroundPosition: \"center\", background: \"none\" }\n : undefined;\n\n return (\n <div className=\"xyd-login-page\" style={bgOverride}>\n <div part=\"card\">\n {logo && <img part=\"logo\" src={logo} alt=\"\" />}\n\n <h1 part=\"title\">{title}</h1>\n\n {description && <p part=\"description\">{description}</p>}\n\n {error && <p part=\"error\">{error}</p>}\n\n {hasExternalAuth ? (\n <button part=\"button\" onClick={handleSignIn}>Sign in</button>\n ) : (\n <div part=\"actions\">\n <button part=\"button\" onClick={signInAsUser}>Sign in as User</button>\n <button part=\"button\" data-kind=\"secondary\" onClick={signInAsAdmin}>Sign in as Admin</button>\n </div>\n )}\n </div>\n </div>\n );\n}","import React, { createContext, useContext, useEffect, useState, useCallback } from \"react\";\nimport { isDevEnvironment as isDevEnv } from \"../devOnly\";\n\nexport interface AccessControlActions {\n /** Current auth config from docs.json */\n config: any | null;\n /** Whether config has loaded */\n ready: boolean;\n /** Last error message */\n error: string;\n /** Clear error */\n clearError: () => void;\n\n // --- Auth actions ---\n\n /** Redirect to external OAuth provider */\n signInWithOAuth: () => void;\n /** Redirect to external JWT login URL */\n signInWithRedirect: () => void;\n /** Sign in with test token (dev/edge server) */\n signInAsUser: () => void;\n /** Sign in as admin with test token (dev/edge server) */\n signInAsAdmin: () => void;\n /** Sign in with specific groups */\n signInWithGroups: (groups: string[]) => void;\n // --- Info ---\n\n /** Provider type: \"jwt\" | \"oauth\" */\n providerType: string;\n /** Whether an external auth URL is configured */\n hasExternalAuth: boolean;\n /** Login page title from config */\n title: string;\n /** Login page description from config */\n description: string;\n /** Login page logo URL from config */\n logo: string;\n /** Login page background image from config */\n backgroundImage: string;\n /** The redirect URL (where to go after login) */\n redirectUrl: string;\n}\n\nconst AccessControlCtx = createContext<AccessControlActions | null>(null);\n\n/**\n * Hook to access auth actions in custom login pages.\n *\n * @example\n * ```tsx\n * import { useAccessControl } from \"@xyd-js/plugin-access-control\"\n *\n * function MyLoginPage() {\n * const { signInWithOAuth, title, logo, error } = useAccessControl()\n *\n * return (\n * <div>\n * {logo && <img src={logo} />}\n * <h1>{title}</h1>\n * {error && <p>{error}</p>}\n * <button onClick={signInWithOAuth}>Sign in</button>\n * </div>\n * )\n * }\n * ```\n */\nexport function useAccessControl(): AccessControlActions {\n const ctx = useContext(AccessControlCtx);\n if (!ctx) {\n throw new Error(\"useAccessControl must be used inside <AccessControlProvider>\");\n }\n return ctx;\n}\n\nexport function AccessControlProvider({ children }: { children: React.ReactNode }) {\n const [config, setConfig] = useState<any>(null);\n const [error, setError] = useState(\"\");\n const [ready, setReady] = useState(false);\n\n useEffect(() => {\n const globalConfig = (window as any).__xydAccessControlSettings?.accessControlConfig;\n if (globalConfig) {\n setConfig(globalConfig);\n setReady(true);\n return;\n }\n // @ts-ignore\n import(\"virtual:xyd-access-control-settings\")\n .then((mod: any) => { setConfig(mod.accessControlConfig); setReady(true); })\n .catch(() => setReady(true));\n }, []);\n\n const providerType = config?.provider?.type || \"jwt\";\n const loginUrl = config?.provider?.loginUrl || \"\";\n const authorizationUrl = config?.provider?.authorizationUrl || \"\";\n const hasExternalAuth = providerType === \"oauth\"\n ? !!authorizationUrl\n : !!loginUrl && loginUrl !== \"/login\";\n\n // login can be a string (custom component path) or an object (config)\n const loginConfig = typeof config?.login === \"string\" ? {} : (config?.login || {});\n const title = loginConfig.title || \"Sign in to access documentation\";\n const description = loginConfig.description || \"\";\n const logo = loginConfig.logo || \"\";\n const backgroundImage = loginConfig.backgroundImage || \"\";\n\n const params = typeof window !== \"undefined\" ? new URLSearchParams(window.location.search) : null;\n const redirectUrl = params?.get(\"redirect\") || \"/\";\n\n const storeTokenAndRedirect = useCallback((token: string) => {\n const cookieName = config?.session?.cookieName || \"xyd-auth-token\";\n localStorage.setItem(cookieName, token);\n document.cookie = `${cookieName}=${token}; path=/; max-age=86400; SameSite=Lax`;\n window.location.href = redirectUrl;\n }, [config, redirectUrl]);\n\n const signInWithOAuth = useCallback(() => {\n if (!authorizationUrl) { setError(\"No OAuth authorization URL configured\"); return; }\n const callbackPath = config?.provider?.callbackPath || \"/auth/callback\";\n const redirectUri = window.location.origin + callbackPath;\n const scopes = config?.provider?.scopes || [];\n const clientId = config?.provider?.clientId || \"\";\n\n const oauthParams = new URLSearchParams({\n client_id: clientId,\n redirect_uri: redirectUri,\n response_type: \"code\",\n scope: scopes.join(\" \"),\n state: redirectUrl,\n });\n window.location.href = `${authorizationUrl}?${oauthParams.toString()}`;\n }, [config, authorizationUrl, redirectUrl]);\n\n const signInWithRedirect = useCallback(() => {\n if (!loginUrl || loginUrl === \"/login\") { setError(\"No external login URL configured\"); return; }\n const sep = loginUrl.includes(\"?\") ? \"&\" : \"?\";\n window.location.href = `${loginUrl}${sep}redirect=${encodeURIComponent(redirectUrl)}`;\n }, [loginUrl, redirectUrl]);\n\n const signInWithGroups = useCallback((groups: string[]) => {\n // Production with deploy config: use /auth/test-login (server-signed)\n const hasDeploy = !!config?.deploy;\n if (hasDeploy) {\n const groupsParam = groups.length ? `&groups=${groups.join(\",\")}` : \"\";\n window.location.href = `/auth/test-login?redirect=${encodeURIComponent(redirectUrl)}${groupsParam}`;\n return;\n }\n\n // Dev only: generate unsigned client-side token\n if (!isDevEnv()) {\n setError(\"Test login is only available in development mode.\");\n return;\n }\n const header = btoa(JSON.stringify({ alg: \"HS256\", typ: \"JWT\" }));\n const payload = btoa(JSON.stringify({\n sub: \"test-user\",\n groups,\n exp: Math.floor(Date.now() / 1000) + 86400,\n iat: Math.floor(Date.now() / 1000),\n }));\n storeTokenAndRedirect(`${header}.${payload}.dGVzdA`);\n }, [config, redirectUrl, storeTokenAndRedirect]);\n\n const signInAsUser = useCallback(() => signInWithGroups([]), [signInWithGroups]);\n const signInAsAdmin = useCallback(() => signInWithGroups([\"admin\"]), [signInWithGroups]);\n\n const value: AccessControlActions = {\n config,\n ready,\n error,\n clearError: () => setError(\"\"),\n signInWithOAuth,\n signInWithRedirect,\n signInAsUser,\n signInAsAdmin,\n signInWithGroups,\n providerType,\n hasExternalAuth,\n title,\n description,\n logo,\n backgroundImage,\n redirectUrl,\n };\n\n return <AccessControlCtx.Provider value={value}>{children}</AccessControlCtx.Provider>;\n}","import React, { useEffect, useState } from \"react\";\n\n/**\n * Handles both JWT and OAuth callback flows:\n *\n * JWT: /auth/jwt-callback#eyJ... → extract token from hash\n * OAuth: /auth/callback?code=XXX&state=/page → exchange code for token\n */\nexport default function AuthCallbackPage() {\n const [error, setError] = useState(\"\");\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n\n // @ts-ignore - virtual module resolved by Vite at runtime\n import(\"virtual:xyd-access-control-settings\")\n .then((mod: any) => {\n const config = mod.accessControlConfig;\n handleCallback(config);\n })\n .catch(() => {\n // Fallback: try JWT flow without config\n handleCallback(null);\n });\n }, []);\n\n function storeTokenAndRedirect(\n token: string,\n groups: string[],\n redirect: string,\n cookieName: string\n ) {\n localStorage.setItem(cookieName, token);\n document.cookie = `${cookieName}=${token}; path=/; max-age=86400; SameSite=Lax`;\n\n (window as any).__xydAuthState = {\n authenticated: true,\n groups,\n token,\n };\n document.documentElement.setAttribute(\"data-auth\", \"authenticated\");\n window.location.href = redirect;\n }\n\n async function handleCallback(config: any) {\n const params = new URLSearchParams(window.location.search);\n const hash = window.location.hash.slice(1);\n const code = params.get(\"code\");\n const state = params.get(\"state\") || \"/\";\n const cookieName = config?.session?.cookieName || \"xyd-auth-token\";\n const groupsClaim = config?.provider?.groupsClaim || \"groups\";\n\n // OAuth flow: code in query params\n if (code && config?.provider?.type === \"oauth\") {\n try {\n await handleOAuthCallback(code, state, config, cookieName, groupsClaim);\n } catch (e) {\n setError(e instanceof Error ? e.message : \"OAuth authentication failed\");\n }\n return;\n }\n\n // JWT flow: token in query param (?token=...) or hash fragment (#eyJ...)\n const token = params.get(\"token\") || hash;\n const redirect = params.get(\"redirect\") || state;\n if (token) {\n try {\n handleJWTCallback(token, redirect, cookieName, groupsClaim);\n } catch (e) {\n setError(e instanceof Error ? e.message : \"JWT authentication failed\");\n }\n return;\n }\n\n setError(\"No authentication data found in callback URL.\");\n }\n\n function handleJWTCallback(\n hash: string,\n redirect: string,\n cookieName: string,\n groupsClaim: string\n ) {\n const parts = hash.split(\".\");\n if (parts.length !== 3) throw new Error(\"Invalid JWT format\");\n\n const payload = JSON.parse(atob(parts[1]));\n if (payload.exp && payload.exp * 1000 < Date.now()) {\n throw new Error(\"Token has expired\");\n }\n\n storeTokenAndRedirect(hash, payload[groupsClaim] || [], redirect, cookieName);\n }\n\n async function handleOAuthCallback(\n code: string,\n redirect: string,\n config: any,\n cookieName: string,\n groupsClaim: string\n ) {\n const tokenUrl = config.provider.tokenUrl;\n const userInfoUrl = config.provider.userInfoUrl;\n const clientId = config.provider.clientId || \"\";\n const callbackPath = config.provider.callbackPath || \"/auth/callback\";\n const redirectUri = window.location.origin + callbackPath;\n\n if (!tokenUrl) throw new Error(\"No token URL configured\");\n\n // Exchange code for access token\n const tokenRes = await fetch(tokenUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: new URLSearchParams({\n grant_type: \"authorization_code\",\n code,\n client_id: clientId,\n redirect_uri: redirectUri,\n }).toString(),\n });\n\n if (!tokenRes.ok) {\n throw new Error(`Token exchange failed: ${tokenRes.status}`);\n }\n\n const tokenData = await tokenRes.json();\n const accessToken = tokenData.access_token;\n if (!accessToken) throw new Error(\"No access token in response\");\n\n // Fetch user info to get groups/roles\n let groups: string[] = [];\n if (userInfoUrl) {\n try {\n const userRes = await fetch(userInfoUrl, {\n headers: { Authorization: `Bearer ${accessToken}` },\n });\n if (userRes.ok) {\n const userInfo = await userRes.json();\n groups = userInfo[groupsClaim] || userInfo.roles || userInfo.groups || [];\n }\n } catch {\n // User info fetch failed — continue without groups\n }\n }\n\n // Create a session JWT from the access token info\n const header = btoa(JSON.stringify({ alg: \"HS256\", typ: \"JWT\" }));\n const payload = btoa(JSON.stringify({\n sub: \"oauth-user\",\n [groupsClaim]: groups,\n exp: Math.floor(Date.now() / 1000) + 86400,\n iat: Math.floor(Date.now() / 1000),\n access_token: accessToken,\n }));\n const sessionToken = `${header}.${payload}.oauth`;\n\n storeTokenAndRedirect(sessionToken, groups, redirect, cookieName);\n }\n\n if (error) {\n return (\n <div className=\"xyd-callback-page\">\n <div part=\"card\">\n <h2 part=\"title\" data-error=\"\">Authentication Error</h2>\n <p part=\"message\">{error}</p>\n <button part=\"button\" onClick={() => (window.location.href = \"/\")}>\n Go to homepage\n </button>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"xyd-callback-page\">\n <div part=\"card\">\n <p part=\"message\">Authenticating...</p>\n </div>\n </div>\n );\n}\n","@layer defaults {\n .xyd-login-page {\n display: flex;\n align-items: center;\n justify-content: center;\n position: fixed;\n inset: 0;\n overflow: hidden;\n font-family: var(--font-body-family, system-ui, sans-serif);\n background: radial-gradient(ellipse at 50% 50%, #f9b8d2 0%, #c6dff7 40%, #7ec8f0 100%);\n }\n\n .xyd-login-page [part=\"card\"] {\n display: flex;\n flex-direction: column;\n align-items: center;\n width: 100%;\n max-width: 350px;\n padding: var(--xyd-padding-xxlarge, 44px);\n background: rgba(255, 255, 255, 0.92);\n border-radius: var(--xyd-border-radius-large, 16px);\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.08);\n backdrop-filter: blur(12px);\n }\n\n .xyd-login-page [part=\"logo\"] {\n max-height: 30px;\n width: auto;\n margin-bottom: var(--xyd-padding-xlarge, 30px);\n }\n\n .xyd-login-page [part=\"title\"] {\n font-size: var(--xyd-font-size-2xl, 32px);\n font-weight: var(--xyd-font-weight-bold, 700);\n line-height: var(--xyd-line-height-2xl, 48px);\n margin: 0 0 var(--xyd-padding-small, 6px);\n text-align: center;\n color: var(--dark100, #000);\n }\n\n .xyd-login-page [part=\"description\"] {\n color: var(--dark48, #6e6e80);\n font-size: var(--xyd-font-size-small, 14px);\n line-height: var(--xyd-line-height-small, 20px);\n margin: 0 0 var(--xyd-padding-xxlarge, 44px);\n text-align: center;\n }\n\n .xyd-login-page [part=\"error\"] {\n color: var(--xyd-text-color--error, #ef4444);\n font-size: var(--xyd-font-size-xsmall, 12px);\n line-height: var(--xyd-line-height-xsmall, 16px);\n margin: 0 0 var(--xyd-padding-medium, 10px);\n }\n\n .xyd-login-page [part=\"form\"] {\n width: 100%;\n }\n\n .xyd-login-page [part=\"input\"] {\n width: 100%;\n padding: var(--xyd-padding-medium, 10px) var(--xyd-padding-small, 6px);\n font-size: var(--xyd-font-size-small, 14px);\n line-height: var(--xyd-line-height-small, 20px);\n font-family: inherit;\n border: 1px solid var(--dark32, #ececf1);\n border-radius: var(--xyd-border-radius-small, 4px);\n margin-bottom: var(--xyd-padding-medium, 10px);\n box-sizing: border-box;\n outline: none;\n background: var(--white, #fff);\n color: var(--dark80, #111827);\n }\n\n .xyd-login-page [part=\"input\"]:focus {\n border-color: var(--dark48, #6e6e80);\n }\n\n .xyd-login-page [part=\"actions\"] {\n width: 100%;\n display: flex;\n flex-direction: column;\n gap: var(--xyd-padding-small, 6px);\n }\n\n .xyd-login-page [part=\"button\"] {\n width: 100%;\n padding: var(--xyd-padding-medium, 10px) var(--xyd-padding-large, 18px);\n font-size: var(--xyd-font-size-small, 14px);\n font-weight: var(--xyd-font-weight-medium, 500);\n font-family: inherit;\n background-color: var(--xyd-button-primary-bg, var(--color-primary, #111));\n color: var(--xyd-button-primary-color, #fff);\n border: 1px solid var(--xyd-button-primary-border, transparent);\n border-radius: var(--xyd-button-border-radius, 6px);\n cursor: pointer;\n transition: background-color 0.15s linear;\n }\n\n .xyd-login-page [part=\"button\"]:hover {\n background-color: var(--xyd-button-primary-bg-hover, var(--color-primary--active, #333));\n }\n\n .xyd-login-page [part=\"button\"][data-kind=\"secondary\"] {\n background-color: var(--xyd-button-secondary-bg, #f5f5f1);\n color: var(--xyd-button-secondary-color, #111);\n border: 1px solid var(--xyd-button-secondary-border, #ececf1);\n }\n\n .xyd-login-page [part=\"button\"][data-kind=\"secondary\"]:hover {\n background-color: var(--xyd-button-secondary-bg-hover, #e5e5e1);\n }\n}\n","@layer defaults {\n .xyd-callback-page {\n display: flex;\n align-items: center;\n justify-content: center;\n position: fixed;\n inset: 0;\n overflow: hidden;\n font-family: var(--font-body-family, system-ui, sans-serif);\n background: radial-gradient(ellipse at 50% 50%, #f9b8d2 0%, #c6dff7 40%, #7ec8f0 100%);\n }\n\n .xyd-callback-page [part=\"card\"] {\n display: flex;\n flex-direction: column;\n align-items: center;\n text-align: center;\n max-width: 350px;\n padding: var(--xyd-padding-xxlarge, 44px);\n background: rgba(255, 255, 255, 0.92);\n border-radius: var(--xyd-border-radius-large, 16px);\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.08);\n backdrop-filter: blur(12px);\n }\n\n .xyd-callback-page [part=\"title\"] {\n font-size: var(--xyd-font-size-xlarge, 22px);\n font-weight: var(--xyd-font-weight-semibold, 600);\n line-height: var(--xyd-line-height-xlarge, 36px);\n margin: 0 0 var(--xyd-padding-small, 6px);\n color: var(--dark100, #000);\n }\n\n .xyd-callback-page [part=\"title\"][data-error] {\n color: var(--xyd-text-color--error, #ef4444);\n }\n\n .xyd-callback-page [part=\"message\"] {\n color: var(--dark48, #6e6e80);\n font-size: var(--xyd-font-size-small, 14px);\n line-height: var(--xyd-line-height-small, 20px);\n }\n\n .xyd-callback-page [part=\"button\"] {\n margin-top: var(--xyd-padding-large, 18px);\n padding: var(--xyd-padding-medium, 10px) var(--xyd-padding-large, 18px);\n font-size: var(--xyd-font-size-small, 14px);\n font-weight: var(--xyd-font-weight-medium, 500);\n font-family: inherit;\n background-color: var(--xyd-button-primary-bg, var(--color-primary, #111));\n color: var(--xyd-button-primary-color, #fff);\n border: 1px solid var(--xyd-button-primary-border, transparent);\n border-radius: var(--xyd-button-border-radius, 6px);\n cursor: pointer;\n }\n\n .xyd-callback-page [part=\"button\"]:hover {\n background-color: var(--xyd-button-primary-bg-hover, var(--color-primary--active, #333));\n }\n}","import React, {\n createContext,\n useContext,\n useEffect,\n useState,\n useMemo,\n} from \"react\";\n\nexport interface AuthState {\n authenticated: boolean;\n groups: string[];\n token: string | null;\n}\n\nconst AuthContext = createContext<AuthState>({\n authenticated: false,\n groups: [],\n token: null,\n});\n\ndeclare global {\n interface Window {\n __xydAuthState?: AuthState;\n __xydAuthDebug?: any;\n }\n}\n\ninterface AuthGuardProps {\n children: React.ReactNode;\n accessMap: Record<string, string>;\n config: {\n provider: { type: string; loginUrl?: string };\n unauthorizedBehavior?: \"redirect\" | \"404\";\n session?: { cookieName?: string };\n };\n}\n\nfunction buildLoginUrl(loginUrl: string, returnPath: string): string {\n const separator = loginUrl.includes(\"?\") ? \"&\" : \"?\";\n return `${loginUrl}${separator}redirect=${encodeURIComponent(returnPath)}`;\n}\n\n/**\n * AuthGuard wraps the application and enforces access control.\n * It reads auth state from window.__xydAuthState (set by pre-hydration script)\n * and checks the access map for the current route.\n */\nexport default function AuthGuard({ children, accessMap, config }: AuthGuardProps) {\n const [authState, setAuthState] = useState<AuthState>(() => {\n if (typeof window !== \"undefined\" && window.__xydAuthState) {\n return window.__xydAuthState;\n }\n return { authenticated: false, groups: [], token: null };\n });\n\n useEffect(() => {\n // Listen for auth state changes (e.g., after login callback)\n const handleStorage = (e: StorageEvent) => {\n const cookieName = config.session?.cookieName || \"xyd-auth-token\";\n if (e.key === cookieName) {\n if (e.newValue) {\n try {\n const payload = JSON.parse(atob(e.newValue.split(\".\")[1]));\n setAuthState({\n authenticated: true,\n groups: payload.groups || [],\n token: e.newValue,\n });\n } catch {\n setAuthState({ authenticated: false, groups: [], token: null });\n }\n } else {\n setAuthState({ authenticated: false, groups: [], token: null });\n }\n }\n };\n\n window.addEventListener(\"storage\", handleStorage);\n return () => window.removeEventListener(\"storage\", handleStorage);\n }, [config.session?.cookieName]);\n\n const value = useMemo(() => authState, [authState]);\n\n return (\n <AuthContext.Provider value={value}>\n <AuthEnforcer accessMap={accessMap} config={config}>\n {children}\n </AuthEnforcer>\n </AuthContext.Provider>\n );\n}\n\n/**\n * Enforces access control on route changes.\n */\nfunction AuthEnforcer({\n children,\n accessMap,\n config,\n}: {\n children: React.ReactNode;\n accessMap: Record<string, string>;\n config: AuthGuardProps[\"config\"];\n}) {\n const authState = useContext(AuthContext);\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n\n const pathname = window.location.pathname;\n const pageAccess = accessMap[pathname];\n\n // No access entry or public = allow\n if (!pageAccess || pageAccess === \"public\") return;\n\n // Requires auth but user is not authenticated\n if (!authState.authenticated) {\n const loginUrl = config.provider.loginUrl;\n if (loginUrl) {\n window.location.href = buildLoginUrl(loginUrl, pathname);\n }\n return;\n }\n\n // Group-based access\n if (pageAccess !== \"authenticated\") {\n const requiredGroups = pageAccess.split(\",\");\n const hasAccess = requiredGroups.some((g) =>\n authState.groups.includes(g)\n );\n if (!hasAccess) {\n if (config.unauthorizedBehavior === \"404\") {\n // Replace with a 404-like state\n window.location.href = \"/404\";\n } else {\n const loginUrl = config.provider.loginUrl;\n if (loginUrl) {\n window.location.href = buildLoginUrl(loginUrl, pathname);\n }\n }\n }\n }\n }, [authState, accessMap, config]);\n\n return <>{children}</>;\n}\n\n/**\n * Hook to access authentication state.\n */\nexport function useAuth(): AuthState & {\n login: () => void;\n logout: () => void;\n} {\n const state = useContext(AuthContext);\n\n return {\n ...state,\n login() {\n // Will be overridden by config at runtime\n console.warn(\"[xyd:access-control] login() called without config\");\n },\n logout() {\n if (typeof window === \"undefined\") return;\n\n const cookieName = \"xyd-auth-token\";\n localStorage.removeItem(cookieName);\n document.cookie = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/`;\n document.cookie = `${cookieName}-state=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/`;\n\n window.__xydAuthState = {\n authenticated: false,\n groups: [],\n token: null,\n };\n document.documentElement.setAttribute(\"data-auth\", \"anonymous\");\n window.location.reload();\n },\n };\n}\n","import type { AccessMap } from \"./access\";\n\ninterface SidebarItem {\n title: string;\n href: string;\n items?: SidebarItem[];\n [key: string]: any;\n}\n\ninterface SidebarGroup {\n group: string;\n groupIndex: number;\n items: SidebarItem[];\n icon?: string;\n [key: string]: any;\n}\n\n/**\n * Filters sidebar navigation groups to hide pages the user cannot access.\n * This runs at runtime in the browser based on the user's auth state.\n */\nexport function filterSidebarGroups(\n sidebarGroups: SidebarGroup[],\n accessMap: AccessMap,\n userGroups: string[]\n): SidebarGroup[] {\n return sidebarGroups\n .map((group) => ({\n ...group,\n items: filterItems(group.items, accessMap, userGroups),\n }))\n .filter((group) => group.items.length > 0);\n}\n\nfunction filterItems(\n items: SidebarItem[],\n accessMap: AccessMap,\n userGroups: string[]\n): SidebarItem[] {\n return items\n .filter((item) => {\n const href = item.href;\n if (!href) return true;\n\n const normalizedHref = href.startsWith(\"/\") ? href : `/${href}`;\n const access = accessMap[normalizedHref] || accessMap[href];\n\n // No entry or public = show\n if (!access || access === \"public\") return true;\n\n // Requires auth - user must have groups\n if (access === \"authenticated\") return userGroups.length > 0;\n\n // Group-based access\n const requiredGroups = access.split(\",\");\n return requiredGroups.some((g) => userGroups.includes(g));\n })\n .map((item) => {\n // Recursively filter nested items\n if (item.items?.length) {\n return {\n ...item,\n items: filterItems(item.items, accessMap, userGroups),\n };\n }\n return item;\n });\n}\n\n/**\n * Filters an array of paths (used for sitemap/llms.txt) to exclude protected pages.\n */\nexport function filterProtectedPaths(\n paths: string[],\n accessMap: AccessMap\n): string[] {\n return paths.filter((p) => {\n const normalizedPath = p.startsWith(\"/\") ? p : `/${p}`;\n const access = accessMap[normalizedPath] || accessMap[p];\n return !access || access === \"public\";\n });\n}\n","import type { Plugin as VitePlugin } from \"vite\";\nimport type { Plugin, PluginConfig } from \"@xyd-js/plugins\";\nimport type { AccessControl } from \"@xyd-js/core\";\n\nimport { resolvePageAccess, type AccessMap } from \"./access\";\nimport { virtualAccessControlSettingsPlugin } from \"./virtual\";\nimport { generateAuthPrehydrationScript } from \"./scripts/authPrehydration\";\nimport { generateNetlifyEdge } from \"./middleware/netlify\";\nimport { generateVercelMiddleware } from \"./middleware/vercel\";\nimport { generateCloudflareMiddleware } from \"./middleware/cloudflare\";\nimport { generateNodeServer } from \"./middleware/node\";\nimport { protectedContentPlugin } from \"./content\";\n\nimport AuthGuard from \"./components/AuthGuard\";\nimport LoginPage from \"./components/LoginPage\";\nimport AuthCallbackPage from \"./components/AuthCallbackPage\";\n\n// @ts-ignore - loaded as text by tsup\nimport loginStyles from \"./styles/login.css\";\n// @ts-ignore\nimport callbackStyles from \"./styles/callback.css\";\n\nexport { evaluateAccess, resolvePageAccess, buildAccessMap } from \"./access\";\nexport type { AccessMap, AccessLevel, AccessEvaluation } from \"./access\";\nexport { default as AuthGuard, useAuth } from \"./components/AuthGuard\";\nexport { default as LoginPage } from \"./components/LoginPage\";\nexport { default as AuthCallbackPage } from \"./components/AuthCallbackPage\";\nexport { AccessControlProvider, useAccessControl } from \"./components/AccessControlContext\";\nexport type { AccessControlActions } from \"./components/AccessControlContext\";\nexport { filterSidebarGroups, filterProtectedPaths } from \"./navigation\";\n\n/**\n * Edge middleware Vite plugin.\n * Generates platform-specific middleware files during build closeBundle step.\n */\nfunction edgeMiddlewarePlugin(config: AccessControl): VitePlugin {\n return {\n name: \"xyd-plugin-access-control-deploy\",\n apply: \"build\",\n async closeBundle() {\n if (!config.deploy) return;\n\n const outputDir = (globalThis as any).__xydBuildOutputDir\n || (process.cwd() + \"/.xyd/build/client\");\n\n switch (config.deploy.platform) {\n case \"netlify-edge\":\n await generateNetlifyEdge(config, outputDir);\n break;\n case \"vercel-edge\":\n await generateVercelMiddleware(config, outputDir);\n break;\n case \"cloudflare-edge\":\n await generateCloudflareMiddleware(config, outputDir);\n break;\n case \"node-edge\":\n await generateNodeServer(config, outputDir);\n break;\n }\n },\n };\n}\n\n/**\n * Build the access map from globalThis.__xydPagePathMapping.\n * Called lazily (from virtual module load or edge middleware closeBundle)\n * because __xydPagePathMapping is not available at plugin init time —\n * it is set by pluginDocs() which runs after loadPlugins().\n */\nfunction buildAccessMapFromGlobals(config: AccessControl): AccessMap {\n const pagePathMapping: Record<string, string> =\n (globalThis as any).__xydPagePathMapping || {};\n\n const accessMap: AccessMap = {};\n\n for (const pagePath of Object.keys(pagePathMapping)) {\n const access = resolvePageAccess(pagePath, {}, config);\n // Store with both forms so lookups work regardless of slash prefix\n accessMap[pagePath] = access;\n const withSlash = pagePath.startsWith(\"/\") ? pagePath : `/${pagePath}`;\n accessMap[withSlash] = access;\n }\n\n // Store for edge middleware generators and llms.txt filtering\n (globalThis as any).__xydAccessMap = accessMap;\n\n return accessMap;\n}\n\n/**\n * Access control plugin for xyd documentation sites.\n *\n * Provides:\n * - Pre-hydration script to prevent flash of protected content\n * - AuthGuard React component for route-level access enforcement\n * - Virtual modules with access control config and access map\n * - Edge middleware generators for Netlify, Vercel, Cloudflare\n * - Login and callback page components\n */\nexport default function AccessControlPlugin(\n pluginOptions: AccessControl\n): Plugin {\n return (settings) => {\n const config = pluginOptions;\n\n // Resolve cookie name and groups claim for pre-hydration script\n const cookieName = config.session?.cookieName || \"xyd-auth-token\";\n const groupsClaim =\n \"groupsClaim\" in config.provider\n ? (config.provider as any).groupsClaim || \"groups\"\n : \"groups\";\n\n // CSS: auth guard hiding + login page + callback page styles\n const authCss = `[data-auth=\"anonymous\"] [data-auth-protected]{display:none!important}\\n${loginStyles}\\n${callbackStyles}`;\n\n const prehydrationScript = generateAuthPrehydrationScript(\n cookieName,\n groupsClaim\n );\n\n const head: [string, Record<string, any>, string?][] = [\n [\"style\", {}, authCss],\n [\"script\", {}, prehydrationScript],\n ];\n\n const vitePlugins: VitePlugin[] = [\n virtualAccessControlSettingsPlugin(config, buildAccessMapFromGlobals),\n protectedContentPlugin(config, buildAccessMapFromGlobals),\n ];\n\n if (config.deploy) {\n vitePlugins.push(edgeMiddlewarePlugin(config));\n }\n\n // Resolve callback route\n const callbackRoute =\n \"callbackPath\" in config.provider\n ? (config.provider as any).callbackPath || \"/auth/jwt-callback\"\n : \"/auth/jwt-callback\";\n\n // login: string → custom component path, object → default with config\n const isCustomLogin = typeof config.login === \"string\";\n const loginConfig = isCustomLogin ? {} as any : (config.login || {}) as any;\n\n return {\n name: \"plugin-access-control\",\n vite: vitePlugins,\n head,\n // Custom pages rendered inside the xyd theme layout\n pages: [\n {\n route: \"/login\",\n component: isCustomLogin ? LoginPage : LoginPage, // component is resolved at runtime\n dist: isCustomLogin ? config.login as string : \"@xyd-js/plugin-access-control/LoginPage\",\n metadata: {\n title: loginConfig.title || \"Sign in\",\n description: loginConfig.description,\n },\n public: true,\n },\n {\n route: callbackRoute,\n component: AuthCallbackPage,\n dist: \"@xyd-js/plugin-access-control/AuthCallbackPage\",\n metadata: { title: \"Authenticating\" },\n public: true,\n },\n ],\n };\n };\n}\n"],"mappings":"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","names":["buildAccessMap","buildAccessMap","React","React","React","useEffect","useState","React","createContext","useContext","useEffect","useState"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@xyd-js/plugin-access-control",
|
|
3
|
+
"version": "0.0.0-build-8804789-20260430104829",
|
|
4
|
+
"author": "",
|
|
5
|
+
"description": "Access control plugin for xyd documentation sites",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"main": "./dist/client.js",
|
|
8
|
+
"type": "module",
|
|
9
|
+
"exports": {
|
|
10
|
+
"./package.json": "./package.json",
|
|
11
|
+
".": {
|
|
12
|
+
"import": "./dist/client.js"
|
|
13
|
+
},
|
|
14
|
+
"./plugin": {
|
|
15
|
+
"import": "./dist/index.js"
|
|
16
|
+
},
|
|
17
|
+
"./AuthGuard": {
|
|
18
|
+
"import": "./dist/AuthGuard.js"
|
|
19
|
+
},
|
|
20
|
+
"./LoginPage": {
|
|
21
|
+
"import": "./dist/LoginPage.js"
|
|
22
|
+
},
|
|
23
|
+
"./AuthCallbackPage": {
|
|
24
|
+
"import": "./dist/AuthCallbackPage.js"
|
|
25
|
+
},
|
|
26
|
+
"./AccessControlContext": {
|
|
27
|
+
"import": "./dist/AccessControlContext.js"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"files": [
|
|
31
|
+
"dist"
|
|
32
|
+
],
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"@linaria/core": "^6.0.0",
|
|
35
|
+
"picomatch": "^4.0.2"
|
|
36
|
+
},
|
|
37
|
+
"peerDependencies": {
|
|
38
|
+
"react": "^18.0.0 || ^19.0.0",
|
|
39
|
+
"@xyd-js/core": "0.0.0-build-8804789-20260430104829",
|
|
40
|
+
"@xyd-js/plugins": "0.0.0-build-8804789-20260430104829"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@types/react": "^19.0.0",
|
|
44
|
+
"rimraf": "^3.0.2",
|
|
45
|
+
"tsup": "^8.4.0",
|
|
46
|
+
"vite": "^7.0.0",
|
|
47
|
+
"vitest": "^1.6.1"
|
|
48
|
+
},
|
|
49
|
+
"scripts": {
|
|
50
|
+
"clean": "rimraf dist",
|
|
51
|
+
"prebuild": "pnpm clean",
|
|
52
|
+
"build": "tsup",
|
|
53
|
+
"test": "vitest",
|
|
54
|
+
"test:coverage": "vitest run --coverage"
|
|
55
|
+
}
|
|
56
|
+
}
|