{"_id":"@514labs/express-pbkdf2-api-key-auth","_rev":"4-478dfcbe2dae5c4e7fff9f68d5b70854","name":"@514labs/express-pbkdf2-api-key-auth","dist-tags":{"latest":"1.0.4"},"versions":{"1.0.2":{"name":"@514labs/express-pbkdf2-api-key-auth","version":"1.0.2","_id":"@514labs/express-pbkdf2-api-key-auth@1.0.2","maintainers":[{"name":"callicles","email":"nicolas@nicolasjoseph.com"},{"name":"timgdelisle","email":"tim@polarizedcapital.com"},{"name":"jonathan514","email":"jonathan@fiveonefour.com"},{"name":"georgevanderson","email":"george.anderson@fiveonefour.com"},{"name":"514bot","email":"engineering+npm@fiveonefour.com"}],"bin":{"generate-api-key":"dist/bin/generate-api-key.js"},"dist":{"shasum":"faad9dd568ac85305be7d46bcdf67fe5f3a665e2","tarball":"https://registry.npmjs.org/@514labs/express-pbkdf2-api-key-auth/-/express-pbkdf2-api-key-auth-1.0.2.tgz","fileCount":12,"integrity":"sha512-RS79VA8g/dbUSyHK42H9/IxfUII2PvtmgiI5930+Gspiq7c2VWFZNZ5XPLNiBK89/9NVaw4gKTcjElsSD4Y0tA==","signatures":[{"sig":"MEQCIFtpENuBqrq7J+6Nec2HJ1dz6UvrkgFCN2Aye9m9pCu/AiBcZZCDNUKnQaAqjwRNhyRVr0rk+5VwoS826pp0DDHjyQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":15324},"main":"./dist/index.js","types":"./dist/index.d.ts","module":"./dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"gitHead":"8053a54a49e0f3bceac14e183fc9ea1ca92758c4","scripts":{"lint":"biome check","test":"tsup && mocha 'tests/**/*.test.ts'","build":"tsup","lint:fix":"biome check --write","typecheck":"tsc --noEmit","prepublishOnly":"npm run lint && npm run test"},"_npmUser":{"name":"514bot","email":"engineering+npm@fiveonefour.com"},"_npmVersion":"10.8.2","description":"Express middleware for PBKDF2 API key authentication","directories":{},"_nodeVersion":"20.19.5","_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.6","chai":"^6.2.1","tsup":"^8.5.1","mocha":"^11.7.5","express":"^4.18.2","typescript":"^5.9.3","@types/chai":"^5.2.3","@types/node":"^24.10.1","@types/mocha":"^10.0.10","@biomejs/biome":"^2.3.7","@types/express":"^5.0.5"},"peerDependencies":{"express":"^4.0.0 || ^5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/express-pbkdf2-api-key-auth_1.0.2_1764112080773_0.9373393801270073","host":"s3://npm-registry-packages-npm-production"}},"1.0.3":{"name":"@514labs/express-pbkdf2-api-key-auth","version":"1.0.3","_id":"@514labs/express-pbkdf2-api-key-auth@1.0.3","maintainers":[{"name":"callicles","email":"nicolas@nicolasjoseph.com"},{"name":"timgdelisle","email":"tim@polarizedcapital.com"},{"name":"jonathan514","email":"jonathan@fiveonefour.com"},{"name":"georgevanderson","email":"george.anderson@fiveonefour.com"},{"name":"514bot","email":"engineering+npm@fiveonefour.com"}],"bin":{"generate-api-key":"dist/bin/generate-api-key.js"},"dist":{"shasum":"a96d38c3a39caca124576c64b53073a9f5f079c7","tarball":"https://registry.npmjs.org/@514labs/express-pbkdf2-api-key-auth/-/express-pbkdf2-api-key-auth-1.0.3.tgz","fileCount":12,"integrity":"sha512-O+S7RHqOOyu9g/z7MuisWgHlGiHhcNxmpPAKKsjd9YmzHr9kAcJFcyjyvKU0ZjNw/CWddq8NXGXrxZsiCSu1Gg==","signatures":[{"sig":"MEQCIBcBgykqlFTzXandGcysGlE6wfN/AMocOffU2fDZIZi3AiA2F4h8AQygfw4KHPYgKazJcwGSO5gx7YNYGmhX7vp34w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":15320},"main":"./dist/index.js","types":"./dist/index.d.ts","module":"./dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"gitHead":"687812c9873dc7d9f498e89d313e6beec3d1208c","scripts":{"lint":"biome check","test":"tsup && mocha 'tests/**/*.test.ts'","build":"tsup","lint:fix":"biome check --write","typecheck":"tsc --noEmit","prepublishOnly":"npm run lint && npm run test"},"_npmUser":{"name":"514bot","email":"engineering+npm@fiveonefour.com"},"_npmVersion":"10.8.2","description":"Express middleware for PBKDF2 API key authentication","directories":{},"_nodeVersion":"20.19.5","_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.6","chai":"^6.2.1","tsup":"^8.5.1","mocha":"^11.7.5","express":"^4.18.2","typescript":"^5.9.3","@types/chai":"^5.2.3","@types/node":"^24.10.1","@types/mocha":"^10.0.10","@biomejs/biome":"^2.3.7","@types/express":"^5.0.5"},"peerDependencies":{"express":"^4.0.0 || ^5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/express-pbkdf2-api-key-auth_1.0.3_1764112368385_0.34428477939046287","host":"s3://npm-registry-packages-npm-production"}},"1.0.4":{"name":"@514labs/express-pbkdf2-api-key-auth","version":"1.0.4","_id":"@514labs/express-pbkdf2-api-key-auth@1.0.4","maintainers":[{"name":"callicles","email":"nicolas@nicolasjoseph.com"},{"name":"timgdelisle","email":"tim@polarizedcapital.com"},{"name":"jonathan514","email":"jonathan@fiveonefour.com"},{"name":"georgevanderson","email":"george.anderson@fiveonefour.com"},{"name":"514bot","email":"engineering+npm@fiveonefour.com"}],"bin":{"generate-api-key":"dist/bin/generate-api-key.js"},"dist":{"shasum":"500858e4728dc987b32133b39f7fc658a06e67da","tarball":"https://registry.npmjs.org/@514labs/express-pbkdf2-api-key-auth/-/express-pbkdf2-api-key-auth-1.0.4.tgz","fileCount":12,"integrity":"sha512-esTFwKtRvrfy7eHvqFNpoDhHlTC4W2u7vwsvk6Wb5UQe4YN4ZyFamt1jT94z7DJ0EkBcp4qaoTfYyvbt4NlTBQ==","signatures":[{"sig":"MEUCIQDW8+Ictpp/DzLEO5Kfc3Jr817dNhDhQYbLSOO2UKRChgIgBSy1COAgfUcF1D3xzPYmTEI/GSlAb+U+BYWrKe+8wpE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":15347},"main":"./dist/index.js","types":"./dist/index.d.ts","module":"./dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"gitHead":"64e88c8a74952d90f11eca77adad64b5842a61ed","scripts":{"lint":"biome check","test":"tsup && mocha 'tests/**/*.test.ts'","build":"tsup","lint:fix":"biome check --write","typecheck":"tsc --noEmit","prepublishOnly":"npm run lint && npm run test"},"_npmUser":{"name":"514bot","email":"engineering+npm@fiveonefour.com"},"_npmVersion":"10.8.2","description":"Express middleware for PBKDF2 API key authentication","directories":{},"_nodeVersion":"20.19.5","_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.6","chai":"^6.2.1","tsup":"^8.5.1","mocha":"^11.7.5","express":"^4.18.2","typescript":"^5.9.3","@types/chai":"^5.2.3","@types/node":"^24.10.1","@types/mocha":"^10.0.10","@biomejs/biome":"^2.3.7","@types/express":"^5.0.5"},"peerDependencies":{"express":"^4.0.0 || ^5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/express-pbkdf2-api-key-auth_1.0.4_1764112903038_0.16169275586067045","host":"s3://npm-registry-packages-npm-production"}}},"time":{"created":"2025-11-25T23:08:00.667Z","modified":"2025-12-10T21:17:35.852Z","1.0.2":"2025-11-25T23:08:00.967Z","1.0.3":"2025-11-25T23:12:48.574Z","1.0.4":"2025-11-25T23:21:43.227Z"},"description":"Express middleware for PBKDF2 API key authentication","maintainers":[{"email":"nicolas@nicolasjoseph.com","name":"callicles"},{"email":"tim@polarizedcapital.com","name":"timgdelisle"},{"email":"jonathan@fiveonefour.com","name":"jonathan514"},{"email":"luciofranco14@gmail.com","name":"luciofranco"},{"email":"george.anderson@fiveonefour.com","name":"georgevanderson"},{"email":"engineering+npm@fiveonefour.com","name":"514bot"}],"readme":"<div align=\"center\">\n  <a href=\"https://docs.fiveonefour.com/moose/\">\n    <picture>\n      <img alt=\"MooseStack logo\" src=\"https://raw.githubusercontent.com/514-labs/moose/main/logo-m-light.png\" height=\"128\">\n    </picture>\n  </a>\n  <h1>MooseStack</h1>\n\n<a href=\"https://www.fiveonefour.com\"><img alt=\"MooseStack logo\" src=\"https://img.shields.io/badge/MADE%20BY-Fiveonefour-black.svg\"></a>\n<a href=\"https://github.com/514-labs/express-pbkdf2-api-key-auth/actions/workflows/ci.yml\"><img alt=\"CI\" src=\"https://img.shields.io/github/actions/workflow/status/514-labs/express-pbkdf2-api-key-auth/ci.yml?branch=main&logo=github\"></a>\n<a href=\"https://www.npmjs.com/package/@514labs/express-pbkdf2-api-key-auth?activeTab=readme\"><img alt=\"NPM version\" src=\"https://img.shields.io/npm/v/%40514labs%2Fexpress-pbkdf2-api-key-auth?logo=npm\"></a>\n<a href=\"https://join.slack.com/t/moose-community/shared_invite/zt-2fjh5n3wz-cnOmM9Xe9DYAgQrNu8xKxg\"><img alt=\"MooseStack Community\" src=\"https://img.shields.io/badge/Slack-MooseStack_community-purple.svg?logo=slack\"></a>\n<a href=\"LICENSE\"><img alt=\"MIT License\" src=\"https://img.shields.io/badge/License-MIT-yellow.svg\"></a>\n\n</div>\n\n# express-pbkdf2-api-key-auth\n\n[Express](https://expressjs.com/) middleware for [PBKDF2](https://en.wikipedia.org/wiki/PBKDF2) (Password-Based Key Derivation Function 2) API key authentication. Zero external dependencies (uses [Node.js](https://nodejs.org) [crypto](https://nodejs.org/api/crypto.html)).\nCompatible with [MooseStack](https://github.com/514-labs/moosestack) token format.\n\n## Installation\n\n```bash\nnpm install @514labs/express-pbkdf2-api-key-auth\n```\n\n## Generating API Keys\n\nUse the CLI to generate an API key pair:\n\n```bash\nnpx generate-api-key\n```\n\nOutput:\n\n```\nAPI Key Hash (store server-side):\n1ee1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxf64b\n\nBearer Token (client sends in header; Authorization: Bearer ...):\n3cb3xxxxxxxxxxxxxxxxxxxxxxxx0dad.1f67xxxxxxxxxxxxxxxxxxxxxxxx6f33\n```\n\nOr programmatically:\n\n```javascript\nimport { generateApiKey } from \"@514labs/express-pbkdf2-api-key-auth\";\n\nconst { bearerToken, apiKeyHash } = generateApiKey();\n```\n\n## Usage\n\n```javascript\nimport express from \"express\";\nimport { createAuthMiddleware } from \"@514labs/express-pbkdf2-api-key-auth\";\n\nconst authMiddleware = createAuthMiddleware((req) => {\n  return process.env.API_KEY_HASH;\n});\n\nconst app = express();\napp.use(authMiddleware);\n\napp.get(\"/api/protected\", (req, res) => {\n  res.json({ message: \"Authenticated!\" });\n});\n\napp.listen(3000);\n```\n\nClients authenticate with:\n\n```\nAuthorization: Bearer {token_hex}.{salt_hex}\n```\n\n## Token Format\n\nThe token format is compatible with [MooseStack](https://github.com/514-labs/moosestack)'s `moose generate hash-token` command, and can be used in any Express project:\n\n- Token: 16 random bytes (32-char hex string)\n- Salt: 16 random bytes (32-char hex string)\n- Hash: PBKDF2-HMAC-SHA256, 1000 iterations, 20-byte output\n- Constant-time comparison (timing-attack safe)\n\n## API\n\n### `createAuthMiddleware(getExpectedHash)`\n\nCreates an Express middleware for authentication.\n\n**Parameters:**\n\n- `getExpectedHash(req)` - Function that returns the expected hash for the request, or `null` if no key is configured\n\n**Returns:** Express middleware function\n\n**Responses:**\n\n- `401` - Missing/invalid Authorization header, no API key configured, or invalid token\n- Calls `next()` on successful authentication\n\n### `generateApiKey()`\n\nGenerates a new API key pair.\n\n**Returns:** `{ bearerToken: string, apiKeyHash: string }`\n\n## Made by\n\nThe team at [Fiveonefour labs](https://www.fiveonefour.com/), the maintainers of [MooseStack](https://github.com/514-labs/moosestack).\n","readmeFilename":"README.md"}