{"_id":"@agecheck/node","_rev":"3-b8cf5ac628568ba68989b6bf931d7ef3","name":"@agecheck/node","dist-tags":{"latest":"0.2.0"},"versions":{"0.1.0":{"name":"@agecheck/node","version":"0.1.0","license":"Apache-2.0","_id":"@agecheck/node@0.1.0","maintainers":[{"name":"vanderbr","email":"engineering@really.me"}],"homepage":"https://github.com/agecheck/node#readme","bugs":{"url":"https://github.com/agecheck/node/issues"},"dist":{"shasum":"eddb53e3cfc4d1f942d50c255727e94afe4da52f","tarball":"https://registry.npmjs.org/@agecheck/node/-/node-0.1.0.tgz","fileCount":7,"integrity":"sha512-CfQnRZk7SelTvK9t2KDdZhFh3y4h94wvBdcFtLigQ7WPzuYDLT+Onr9fijzLoDqnaOjgtAkzega5JHzL7mg5/w==","signatures":[{"sig":"MEUCIGiTp9I0yBPFGYr5vgtzmnpfxl/n6mw1tTubT3pHGIwoAiEA7Ll/Ln2qd6Y+JvhrKnTycHOaOW38FGldRWHAwl7euGU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":53803},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"e2680df582501890deae8fd5573443cb1cd5a5f4","scripts":{"test":"vitest run","build":"tsup src/index.ts --format esm,cjs --dts --clean","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"vanderbr","email":"engineering@really.me"},"repository":{"url":"git+https://github.com/agecheck/node.git","type":"git"},"_npmVersion":"11.9.0","description":"AgeCheck Node SDK for gate policy, JWT verification, and signed verification cookies.","directories":{},"_nodeVersion":"25.6.1","dependencies":{"@agecheck/core":"^0.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"pnpm@10.29.2","devDependencies":{"tsup":"^8.5.0","vitest":"^2.1.8","typescript":"^5.9.2","@types/node":"^24.5.2","@agecheck/core":"^0.1.0"},"_npmOperationalInternal":{"tmp":"tmp/node_0.1.0_1771413376389_0.39508759996853215","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@agecheck/node","version":"0.1.1","license":"Apache-2.0","_id":"@agecheck/node@0.1.1","maintainers":[{"name":"vanderbr","email":"engineering@really.me"}],"homepage":"https://github.com/agecheck/agecheck-node#readme","bugs":{"url":"https://github.com/agecheck/agecheck-node/issues"},"dist":{"shasum":"961df87d0fa03c2e1d823e007ac96ff284f99bd9","tarball":"https://registry.npmjs.org/@agecheck/node/-/node-0.1.1.tgz","fileCount":7,"integrity":"sha512-kDPjfZRBSJOF2GsoAD/yt8e99z2t3c94rCO5CvPhd2J07LlF6C/0xGOqLgRMTEAh5FLTQXVGukOUFLHH3wSkWA==","signatures":[{"sig":"MEUCIQDWzK7T+id+/4aagyNOSGv8qZ1sZfimrsYhJBlpDFDK4wIge8UJcd0tw48Z9cbHoxMnhwNpZ6wVWusaNmZDM+zYt4A=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":53812},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"e2680df582501890deae8fd5573443cb1cd5a5f4","scripts":{"test":"vitest run","build":"tsup src/index.ts --format esm,cjs --dts --clean","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"vanderbr","email":"engineering@really.me"},"repository":{"url":"git+https://github.com/agecheck/agecheck-node.git","type":"git"},"_npmVersion":"11.9.0","description":"AgeCheck Node SDK for gate policy, JWT verification, and signed verification cookies.","directories":{},"_nodeVersion":"25.6.1","dependencies":{"@agecheck/core":"^0.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"pnpm@10.29.2","devDependencies":{"tsup":"^8.5.0","vitest":"^2.1.8","typescript":"^5.9.2","@types/node":"^24.5.2","@agecheck/core":"^0.1.1"},"_npmOperationalInternal":{"tmp":"tmp/node_0.1.1_1771414207980_0.6426464155587572","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@agecheck/node","version":"0.2.0","description":"AgeCheck Node SDK for gate policy, JWT verification, and signed verification cookies.","license":"Apache-2.0","repository":{"type":"git","url":"git+https://github.com/agecheck/agecheck-node.git"},"type":"module","main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"publishConfig":{"access":"public"},"engines":{"node":">=20"},"scripts":{"build":"tsup src/index.ts --format esm,cjs --dts --clean","test":"vitest run","test:watch":"vitest","typecheck":"tsc --noEmit"},"dependencies":{"@agecheck/core":"^0.2.0"},"devDependencies":{"@agecheck/core":"^0.1.1","@types/node":"^24.5.2","tsup":"^8.5.0","typescript":"^5.9.2","vitest":"^2.1.8"},"packageManager":"pnpm@10.29.2","gitHead":"84d87def65e90802865d26ac5a41d69acc58026b","_id":"@agecheck/node@0.2.0","bugs":{"url":"https://github.com/agecheck/agecheck-node/issues"},"homepage":"https://github.com/agecheck/agecheck-node#readme","_nodeVersion":"25.6.1","_npmVersion":"11.9.0","dist":{"integrity":"sha512-+IbxVw+r2fVfhwgOaghdkAV79bJYbG/jZCDCBNV9exGL9IO7z4p9e+DPSzqqV8JVCTvajyXx5XwEbNYX4cOJbg==","shasum":"0c03d907ee3e3e365c3d2a11dd9560badcf59298","tarball":"https://registry.npmjs.org/@agecheck/node/-/node-0.2.0.tgz","fileCount":7,"unpackedSize":69666,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIDtw5b+3ieJIj/vNDXzbW+abOiU6oSUGi+HhBcZyOVmVAiEA7l4FrqGTiY3Jf6iYUyIGEGVbvT0v/AHKzcq31ifC0Go="}]},"_npmUser":{"name":"vanderbr","email":"engineering@really.me"},"directories":{},"maintainers":[{"name":"vanderbr","email":"engineering@really.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/node_0.2.0_1771435001827_0.3694811365408841"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-18T11:16:16.223Z","modified":"2026-02-18T17:16:42.101Z","0.1.0":"2026-02-18T11:16:16.523Z","0.1.1":"2026-02-18T11:30:08.111Z","0.2.0":"2026-02-18T17:16:41.974Z"},"bugs":{"url":"https://github.com/agecheck/agecheck-node/issues"},"license":"Apache-2.0","homepage":"https://github.com/agecheck/agecheck-node#readme","repository":{"type":"git","url":"git+https://github.com/agecheck/agecheck-node.git"},"description":"AgeCheck Node SDK for gate policy, JWT verification, and signed verification cookies.","maintainers":[{"name":"vanderbr","email":"engineering@really.me"}],"readme":"# AgeCheck Node SDK (`@agecheck/node`)\n\n[![CI](https://github.com/agecheck/agecheck-node/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/agecheck/agecheck-node/actions/workflows/ci.yml)\n[![Compatibility](https://github.com/agecheck/agecheck-node/actions/workflows/compatibility.yml/badge.svg?branch=main&event=push)](https://github.com/agecheck/agecheck-node/actions/workflows/compatibility.yml)\n[![npm](https://img.shields.io/npm/v/%40agecheck%2Fnode?label=npm)](https://www.npmjs.com/package/@agecheck/node)\n\nTypeScript server SDK for age verification, designed to help websites implement compliant age-assurance flows across jurisdictions.\n\n## What this package is for\n\n- enforce gate policy server-side\n- verify AgeCheck credentials (`did:web:agecheck.me` and optional demo issuer)\n- issue and validate signed HttpOnly verification cookies\n- support Existing Gate Integration and multi-provider coexistence\n\n## Install\n\n```bash\npnpm add @agecheck/node\n```\n\n## Supported integration modes\n\n1. Managed gate mode: use AgeCheck gate route + verify route + signed cookie.\n2. Existing Gate Integration: keep your existing gate and add AgeCheck as one provider option.\n3. Hybrid mode: use AgeCheck gate while also supporting other providers in Provider Mode.\n\nAll modes converge into one normalized provider assertion and one signed cookie pipeline.\n\n## Minimal managed-gate integration\n\n```ts\nimport { AgeCheckSdk } from \"@agecheck/node\";\n\nconst sdk = new AgeCheckSdk({\n  deploymentMode: \"production\", // \"demo\" for demo deployments\n  verify: {\n    requiredAge: 18,\n    allowCustomIssuer: false,\n  },\n  gate: {\n    headerName: \"X-Age-Gate\",\n    requiredValue: \"true\",\n  },\n  cookie: {\n    secret: process.env.AGECHECK_COOKIE_SECRET!,\n    cookieName: \"agecheck_verified\",\n    ttlSeconds: 86400, // hostmaster-controlled (e.g. 31536000 for 1 year)\n  },\n});\n\nexport async function enforce(request: Request): Promise<Response | null> {\n  return sdk.requireVerifiedOrRedirect(request, { gatePath: \"/ageverify\" });\n}\n\nexport async function verifyEndpoint(request: Request): Promise<Response> {\n  const body = (await request.json()) as {\n    jwt?: string;\n    payload?: { agegateway_session?: string };\n    redirect?: string;\n  };\n\n  const result = await sdk.verifyToken(body.jwt ?? \"\", body.payload?.agegateway_session ?? \"\");\n  if (!result.ok) {\n    return Response.json(\n      { verified: false, error: \"Age validation failed.\", code: result.code },\n      { status: 401 },\n    );\n  }\n\n  const setCookie = await sdk.buildSetCookieFromAssertion({\n    provider: \"agecheck\",\n    verified: true,\n    level: result.ageTier,\n    verifiedAtUnix: Math.floor(Date.now() / 1000),\n    assurance: \"passkey\",\n  });\n\n  const headers = new Headers({ \"content-type\": \"application/json\" });\n  headers.append(\"set-cookie\", setCookie);\n\n  return new Response(\n    JSON.stringify({ verified: true, redirect: body.redirect ?? \"/\" }),\n    { status: 200, headers },\n  );\n}\n```\n\n## Existing Gate Integration (Provider Mode)\n\nUse these helpers when a hostmaster already has a gate flow and wants to add AgeCheck as a provider:\n\n```ts\nimport {\n  AgeCheckSdk,\n  buildSetCookieFromProviderAssertion,\n  normalizeExternalProviderAssertion,\n  verifyAgeCheckCredential,\n  type ProviderVerificationResult,\n} from \"@agecheck/node\";\n\nconst sdk = new AgeCheckSdk({\n  deploymentMode: \"production\",\n  verify: { requiredAge: 18 },\n  cookie: { secret: process.env.AGECHECK_COOKIE_SECRET! },\n});\n\nexport async function verifyProviderEndpoint(body: {\n  provider?: string;\n  jwt?: string;\n  payload?: { agegateway_session?: string };\n  redirect?: string;\n}): Promise<Response> {\n  const expectedSession = body.payload?.agegateway_session;\n  if (typeof expectedSession !== \"string\" || expectedSession.length === 0) {\n    return Response.json({ verified: false, code: \"invalid_input\", error: \"Missing session.\" }, { status: 400 });\n  }\n\n  let assertion: ProviderVerificationResult;\n  if ((body.provider ?? \"agecheck\") === \"agecheck\") {\n    assertion = await verifyAgeCheckCredential(sdk, {\n      jwt: body.jwt ?? \"\",\n      expectedSession,\n      assurance: \"passkey\",\n    });\n  } else {\n    const externalResult: ProviderVerificationResult = await verifyOtherProvider(body);\n    assertion = normalizeExternalProviderAssertion(externalResult, expectedSession);\n  }\n\n  if (!assertion.verified) {\n    return Response.json(\n      { verified: false, code: assertion.code, error: assertion.message, detail: assertion.detail },\n      { status: 401 },\n    );\n  }\n\n  const setCookie = await buildSetCookieFromProviderAssertion(sdk, assertion);\n  return new Response(JSON.stringify({ verified: true, redirect: body.redirect ?? \"/\" }), {\n    status: 200,\n    headers: { \"content-type\": \"application/json\", \"set-cookie\": setCookie },\n  });\n}\n```\n\n## Deployment modes\n\n- `production`\n  - accepts production issuer credentials\n  - gate is raised only when policy header requires it\n- `demo`\n  - accepts demo + production issuer credentials\n  - gate is always raised\n\n## Provider assertion contract\n\nProvider results normalize to this shape:\n\n```ts\n{\n  provider: string;\n  verified: true;\n  level: \"18+\" | \"21+\" | `${number}+`;\n  session: string; // UUID\n  verifiedAtUnix: number;\n  assurance?: string;\n  verificationType?: \"passkey\" | \"oid4vp\" | \"other\";\n  evidenceType?: \"webauthn_assertion\" | \"sd_jwt\" | \"zk_attestation\" | \"other\";\n  providerTransactionId?: string;\n  loa?: string;\n}\n```\n\nThis keeps provider internals isolated while preserving one site-level cookie and enforcement model.\n`payload.agegateway_session` and provider assertion `session` are treated as required UUID values.\n\n## Framework adapters\n\n`@agecheck/node` includes framework adapter helpers:\n\n- `createExpressGateMiddleware`, `createExpressVerifyHandler`\n- `createFastifyGateHook`, `createFastifyVerifyHandler`\n- `createHonoGateMiddleware`, `createHonoVerifyHandler`\n- `createNuxtGateMiddleware`, `createNuxtVerifyHandler`\n\nSee `/docs/ADAPTERS.md` for adapter mapping and behavior notes.\n\n## Worker reference\n\n`worker-demo/` is a reference backend implementation (verify endpoint + gate page + cookie endpoints). It is useful for validation and demos, but production adopters should wire the SDK into their own server routes/middleware.\n\n## Existing sites\n\nSee `/docs/EXISTING_SITES.md` for the migration pattern that keeps your existing templates/content and moves enforcement into middleware.\n\n## Full hostmaster guide\n\nSee `/docs/HOSTMASTER_E2E.md` for the full request lifecycle and production enforcement model.\n\n## Framework compatibility\n\nSee `/docs/COMPATIBILITY.md` for latest-framework compatibility coverage and CI validation scope.\n\n## Versioning and releases\n\nSee `/docs/VERSIONING.md`.\n\n## Quality gates\n\n```bash\npnpm typecheck\npnpm test\npnpm build\n```\n\n## License\n\nApache-2.0\n","readmeFilename":"README.md"}