{"_id":"@chrono-os/service-auth","_rev":"2-e5ca5310d33a103246e730da5d02cb27","name":"@chrono-os/service-auth","dist-tags":{"latest":"0.1.1"},"versions":{"0.1.0":{"name":"@chrono-os/service-auth","version":"0.1.0","keywords":["service-token","timing-safe","auth","fastify","nestjs","chrono-os"],"license":"MIT","_id":"@chrono-os/service-auth@0.1.0","maintainers":[{"name":"sugarhoneyicetea","email":"aquilaferraz@gmail.com"}],"homepage":"https://github.com/SugarHoneyIceTea/service-auth#readme","bugs":{"url":"https://github.com/SugarHoneyIceTea/service-auth/issues"},"dist":{"shasum":"f0b88094285f113b801fbc8a8bad31a766050e69","tarball":"https://registry.npmjs.org/@chrono-os/service-auth/-/service-auth-0.1.0.tgz","fileCount":9,"integrity":"sha512-+Jmwief1B1DrANC44jlcTIB9SttiNqLRNV5/hCjvpE22GLzi0OqstRIjDVYTRQHKj/NAIeWjDQS5n8lSSH+t/A==","signatures":[{"sig":"MEQCIHbymwuG5Wu/tGSI8o1D2OqU37Wi6rItVkyVPf9XT7U4AiB6lAYH44aRYT/5cg+z0jNsyVoBsCebuqNMihOceDNNgA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":12642},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"6bbc56befff1efa26525a6c6258036b64009a3b9","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"sugarhoneyicetea","email":"aquilaferraz@gmail.com"},"repository":{"url":"git+https://github.com/SugarHoneyIceTea/service-auth.git","type":"git"},"_npmVersion":"11.9.0","description":"Núcleo neutro de validação de service-token (gate de write-back dashboard → backend), framework-agnóstico. Comparação timing-safe via node:crypto, zero deps de runtime.","directories":{},"sideEffects":false,"_nodeVersion":"24.14.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","vitest":"^3","typescript":"^5.6.0","@types/node":"^25.9.1"},"_npmOperationalInternal":{"tmp":"tmp/service-auth_0.1.0_1780260563566_0.01832957341227437","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@chrono-os/service-auth","version":"0.1.1","description":"Núcleo neutro de validação de service-token (gate de write-back dashboard → backend), framework-agnóstico. Comparação timing-safe via node:crypto, zero deps de runtime.","license":"MIT","type":"module","main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"sideEffects":false,"publishConfig":{"registry":"https://registry.npmjs.org","access":"public"},"repository":{"type":"git","url":"git+https://github.com/SugarHoneyIceTea/service-auth.git"},"keywords":["service-token","timing-safe","auth","fastify","nestjs","chrono-os"],"scripts":{"build":"tsup","dev":"tsup --watch","test":"vitest run","test:watch":"vitest","typecheck":"tsc --noEmit"},"devDependencies":{"@types/node":"^25.9.1","tsup":"^8.3.0","typescript":"5.9.3","vitest":"^3"},"engines":{"node":">=18"},"gitHead":"cacc92566b3d621f66fc026374892a405bbe42ff","_id":"@chrono-os/service-auth@0.1.1","bugs":{"url":"https://github.com/SugarHoneyIceTea/service-auth/issues"},"homepage":"https://github.com/SugarHoneyIceTea/service-auth#readme","_nodeVersion":"24.14.0","_npmVersion":"11.9.0","dist":{"integrity":"sha512-cRrWzVs8JyRc41AK/eAKKE7fCX6bX2zC59GzzSmKhOF4Uoo9hg2nO0JK3zH3aJTXoS+sPWG8BNY1mTUujcSU0A==","shasum":"950bbdc2776986f12bae2bf6e77e946c2c596367","tarball":"https://registry.npmjs.org/@chrono-os/service-auth/-/service-auth-0.1.1.tgz","fileCount":9,"unpackedSize":12744,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCgrbbnq6X7CmcpbJ71R1NXBqlszpLRpuDE0YqzPdJWLgIgU9lha4CC94UU/jgsuGwfo+Z2KpfYtHj9riau9SPMkqU="}]},"_npmUser":{"name":"sugarhoneyicetea","email":"aquilaferraz@gmail.com"},"directories":{},"maintainers":[{"name":"sugarhoneyicetea","email":"aquilaferraz@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/service-auth_0.1.1_1789075753416_0.4258916193583877"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-31T20:49:23.405Z","modified":"2026-09-10T21:29:13.754Z","0.1.0":"2026-05-31T20:49:23.703Z","0.1.1":"2026-09-10T21:29:13.558Z"},"bugs":{"url":"https://github.com/SugarHoneyIceTea/service-auth/issues"},"license":"MIT","homepage":"https://github.com/SugarHoneyIceTea/service-auth#readme","keywords":["service-token","timing-safe","auth","fastify","nestjs","chrono-os"],"repository":{"type":"git","url":"git+https://github.com/SugarHoneyIceTea/service-auth.git"},"description":"Núcleo neutro de validação de service-token (gate de write-back dashboard → backend), framework-agnóstico. Comparação timing-safe via node:crypto, zero deps de runtime.","maintainers":[{"name":"sugarhoneyicetea","email":"aquilaferraz@gmail.com"}],"readme":"# @chrono-os/service-auth\n\nNúcleo neutro de validação de **service-token** — o gate usado no write-back do Admin Unificado (dashboard → backend). Framework-agnóstico: serve igual pra **Fastify** e **NestJS**. Comparação em tempo ~constante (timing-safe) via `node:crypto`, **zero dependências de runtime** e **zero dependência de framework**.\n\n## Install\n\nPacote público no [npmjs.org](https://www.npmjs.com/package/@chrono-os/service-auth) — sem necessidade de `.npmrc` ou token.\n\n```bash\nyarn add @chrono-os/service-auth\n```\n\n## API\n\n```ts\nimport {\n  checkServiceToken,\n  secureCompare,\n  SERVICE_TOKEN_HEADER,\n  type ServiceAuthResult,\n} from \"@chrono-os/service-auth\";\n```\n\n### `SERVICE_TOKEN_HEADER`\n\n`'x-service-token'` — header padrão onde o token trafega (dashboard → backend).\n\n### `ServiceAuthResult`\n\n```ts\ntype ServiceAuthResult = \"valid\" | \"invalid\" | \"absent\";\n```\n\n- `'absent'` — service-auth desligado (sem token esperado configurado) **ou** header ausente na request.\n- `'invalid'` — header presente mas não bate (logar/recusar).\n- `'valid'` — bate.\n\n### `checkServiceToken(provided, expected): ServiceAuthResult`\n\nValida o valor cru do header (`string | string[] | undefined`) contra o token esperado (`string | undefined`). Se `provided` for array (header repetido), usa o primeiro elemento.\n\n### `secureCompare(a, b): boolean`\n\nComparação de dois valores em tempo ~constante. Faz `sha256` dos dois lados antes do `timingSafeEqual` pra normalizar o comprimento (não lança com tamanhos diferentes) e não vazar o tamanho do token esperado.\n\n## Uso num backend\n\nLer o header da request, validar contra o token esperado (de uma env var) e tratar os três resultados:\n\n```ts\nimport { checkServiceToken, SERVICE_TOKEN_HEADER } from \"@chrono-os/service-auth\";\n\nconst expected = process.env.SERVICE_TOKEN; // pode ser undefined (gate desligado)\n\n// `request.headers[SERVICE_TOKEN_HEADER]` é string | string[] | undefined\nconst result = checkServiceToken(request.headers[SERVICE_TOKEN_HEADER], expected);\n\nswitch (result) {\n  case \"valid\":\n    // segue com o write-back\n    break;\n  case \"invalid\":\n    // header presente mas errado → 401/403 + log de tentativa\n    break;\n  case \"absent\":\n    // sem token esperado (gate off) ou sem header → política do app\n    break;\n}\n```\n\nO mesmo vale num guard/interceptor NestJS: leia `request.headers['x-service-token']` e chame `checkServiceToken`.\n\n## Nota de segurança\n\nA comparação é **timing-safe**: usa `crypto.timingSafeEqual` sobre o hash `sha256` de cada lado, evitando ataques de timing que comparam caractere a caractere. Nunca compare tokens com `===`. O hash prévio também impede que o tamanho do token esperado vaze pela duração da comparação.\n\n## Licença\n\nMIT\n","readmeFilename":"README.md"}