{"_id":"@activescott/auth","_rev":"11-19bbb6a6a9fca080e6a04ae4901b0f6d","name":"@activescott/auth","dist-tags":{"latest":"5.0.0"},"versions":{"0.1.1":{"name":"@activescott/auth","version":"0.1.1","keywords":["auth","authentication","magic-link","jwt","session"],"author":{"name":"Scott Willeke"},"license":"MIT","_id":"@activescott/auth@0.1.1","maintainers":[{"name":"activescott","email":"scott@willeke.com"}],"homepage":"https://github.com/activescott/auth#readme","bugs":{"url":"https://github.com/activescott/auth/issues"},"dist":{"shasum":"0206ec71a21fb986ddbf16d582eaed6f0d538367","tarball":"https://registry.npmjs.org/@activescott/auth/-/auth-0.1.1.tgz","fileCount":25,"integrity":"sha512-B0oZMpVSW4FeWimpC+m8HxSWM/36OBfKxGN4Df3TDoXuZIUZTJ11Fbsq8wfuA7tXzcOoUgikw1yusJ5fNVgYKg==","signatures":[{"sig":"MEYCIQDatwwPo4mUT4NTm394UE9OKqofhsyyd60B8YgPMfFnswIhAKZ1JDF6b+7E1uXVSiQL5UtN17vmOVFZL/OY9yEUSoRm","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":58885},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"5a64c5f74cb44b53a723a3c507c43ee46ff256e5","scripts":{"dev":"tsc --watch","test":"vitest run","build":"tsc","typecheck":"tsc --noEmit","prepublishOnly":"npm run build"},"_npmUser":{"name":"activescott","email":"scott@willeke.com"},"repository":{"url":"git+https://github.com/activescott/auth.git","type":"git","directory":"packages/auth"},"_npmVersion":"10.9.4","description":"Framework-agnostic authentication with provider pattern for magic links, OAuth, and more","directories":{},"_nodeVersion":"22.22.1","dependencies":{"zod":"^4.3.6","jsonwebtoken":"^9.0.2"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.0.16","typescript":"^5.7.2","@types/node":"^22","@types/jsonwebtoken":"^9.0.10"},"_npmOperationalInternal":{"tmp":"tmp/auth_0.1.1_1773687676617_0.10118039239279963","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@activescott/auth","version":"0.1.3","keywords":["auth","authentication","magic-link","jwt","session"],"author":{"name":"Scott Willeke"},"license":"MIT","_id":"@activescott/auth@0.1.3","maintainers":[{"name":"activescott","email":"scott@willeke.com"}],"homepage":"https://github.com/activescott/auth#readme","bugs":{"url":"https://github.com/activescott/auth/issues"},"dist":{"shasum":"787789430ce3c322af4b5dfb78d872239795fda8","tarball":"https://registry.npmjs.org/@activescott/auth/-/auth-0.1.3.tgz","fileCount":27,"integrity":"sha512-FYXdvM5rlCDACTlDbnx2zerM8ZIqC/f3BT0/jZ+Jbti+vEttE33r4EwjYTFzswUW5MuPi/SO30U2D8WjmPcW9w==","signatures":[{"sig":"MEUCIB8rSFdNWms3BLtc+9MWEFNWRyipRRsbFSbB9G1NxerEAiEAnSub5XJjmTIwfe/qTnuzTIesgHG8Z7on6R0yuheDt0Q=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@activescott%2fauth@0.1.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":63560},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"a6c9490bc1c9257189044f5bd9679791e3c91ee2","scripts":{"dev":"tsc --watch","test":"vitest run","build":"tsc","typecheck":"tsc --noEmit","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:f149a3bb-4c70-4797-a4c8-ae9865aeaa50"}},"repository":{"url":"git+https://github.com/activescott/auth.git","type":"git","directory":"packages/auth"},"_npmVersion":"11.11.0","description":"Framework-agnostic authentication with provider pattern for magic links, OAuth, and more","directories":{},"_nodeVersion":"24.14.1","dependencies":{"zod":"^4.3.6","jsonwebtoken":"^9.0.2"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.0.16","typescript":"^5.7.2","@types/node":"^22","@types/jsonwebtoken":"^9.0.10"},"_npmOperationalInternal":{"tmp":"tmp/auth_0.1.3_1778342282512_0.17329411707278664","host":"s3://npm-registry-packages-npm-production"}},"1.0.0":{"name":"@activescott/auth","version":"1.0.0","keywords":["auth","authentication","magic-link","jwt","session"],"author":{"name":"Scott Willeke"},"license":"MIT","_id":"@activescott/auth@1.0.0","maintainers":[{"name":"activescott","email":"scott@willeke.com"}],"homepage":"https://github.com/activescott/auth#readme","bugs":{"url":"https://github.com/activescott/auth/issues"},"dist":{"shasum":"fe04be49e68ebf86f6a6af62e9f2b84c19dd9ca8","tarball":"https://registry.npmjs.org/@activescott/auth/-/auth-1.0.0.tgz","fileCount":35,"integrity":"sha512-WfjVoQ9eP83v8MkTiqagmX5rJxprhRlk3TI37KF40frJxtVciX8cUfDxXL2L2ytCwUN1ZrycZtBTwgt+d0vkiw==","signatures":[{"sig":"MEQCIBC2pDBuW1GTpwk+svt9PzTt4GIdvspdm2hotPUWKUcoAiA6tX7V/3PZO4053Z4d3tqrfiauitqFNetywZEi8lkyeA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@activescott%2fauth@1.0.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":81542},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"f36371d391dccd803c32ef2a75600e9b4a9e2111","scripts":{"dev":"tsc --watch","test":"vitest run","build":"tsc","typecheck":"tsc --noEmit","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:f149a3bb-4c70-4797-a4c8-ae9865aeaa50"}},"repository":{"url":"git+https://github.com/activescott/auth.git","type":"git","directory":"packages/auth"},"_npmVersion":"11.16.0","description":"Framework-agnostic authentication with provider pattern for magic links, OAuth, and more","directories":{},"_nodeVersion":"24.18.0","dependencies":{"zod":"^4.3.6","jsonwebtoken":"^9.0.2"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.0.16","typescript":"^5.7.2","@types/node":"^22","@types/jsonwebtoken":"^9.0.10"},"_npmOperationalInternal":{"tmp":"tmp/auth_1.0.0_1785522250106_0.3148439184148748","host":"s3://npm-registry-packages-npm-production"}},"2.0.0":{"name":"@activescott/auth","version":"2.0.0","keywords":["auth","authentication","magic-link","jwt","session"],"author":{"name":"Scott Willeke"},"license":"MIT","_id":"@activescott/auth@2.0.0","maintainers":[{"name":"activescott","email":"scott@willeke.com"}],"homepage":"https://github.com/activescott/auth#readme","bugs":{"url":"https://github.com/activescott/auth/issues"},"dist":{"shasum":"d0855d4d65606c0d2c838c2ac446c1ae26d394a4","tarball":"https://registry.npmjs.org/@activescott/auth/-/auth-2.0.0.tgz","fileCount":35,"integrity":"sha512-uaqDCP+BDRwnIfIbOmqBkK2LBtSn2skfsXLhYjHqrZVdQSRdG7Aavs9zTKEl9Sm5qZrZAo+8BVwtnG66S7nEPQ==","signatures":[{"sig":"MEUCIFiFMznCX6lMAQi2a2YpU50qYpmG5BMNOUqCWAcVgbJGAiEA4G7L6lWtTvEeipbGxX3dptP20tuzrhKYwlp3jkDsAjI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@activescott%2fauth@2.0.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":82392},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"ade8601c4673589fbf6d3f4387976a4a5dea3a91","scripts":{"dev":"tsc --watch","test":"vitest run","build":"tsc","typecheck":"tsc --noEmit","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:f149a3bb-4c70-4797-a4c8-ae9865aeaa50"}},"repository":{"url":"git+https://github.com/activescott/auth.git","type":"git","directory":"packages/auth"},"_npmVersion":"11.16.0","description":"Framework-agnostic authentication with provider pattern for magic links, OAuth, and more","directories":{},"_nodeVersion":"24.18.0","dependencies":{"jose":"^6.2.6"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.0.16","typescript":"^5.7.2","@types/node":"^22"},"_npmOperationalInternal":{"tmp":"tmp/auth_2.0.0_1785527639742_0.12624063965092502","host":"s3://npm-registry-packages-npm-production"}},"2.1.0":{"name":"@activescott/auth","version":"2.1.0","keywords":["auth","authentication","magic-link","jwt","session"],"author":{"name":"Scott Willeke"},"license":"MIT","_id":"@activescott/auth@2.1.0","maintainers":[{"name":"activescott","email":"scott@willeke.com"}],"homepage":"https://github.com/activescott/auth#readme","bugs":{"url":"https://github.com/activescott/auth/issues"},"dist":{"shasum":"ef05f99a9cbf125ad694d4bc171a180412959e79","tarball":"https://registry.npmjs.org/@activescott/auth/-/auth-2.1.0.tgz","fileCount":39,"integrity":"sha512-UiH8J7VksXdiL5INfuM1a+TB5+CNYMuUPc5+AqF7fWtNUvjx1pVF2J2K1hDb+KDyAUK5VowvbuERwcdkv83j2Q==","signatures":[{"sig":"MEQCIBQyUJO9lbJDuaNGOS6381j2nfDfParPzBEz4CoeZQpLAiBGomyb/sPaR998wSHCi9v/DLhJoJ/afm+q5ocMyFBWpw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":98102},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"9405943132469bb2401e9ef502a324bc4906f4e4","scripts":{"dev":"tsc --watch","test":"vitest run","build":"tsc","typecheck":"tsc --noEmit","prepublishOnly":"npm run build"},"_npmUser":{"name":"activescott","email":"scott@willeke.com"},"repository":{"url":"git+https://github.com/activescott/auth.git","type":"git","directory":"packages/auth"},"_npmVersion":"10.9.4","description":"Framework-agnostic authentication with provider pattern for magic links, OAuth, and more","directories":{},"_nodeVersion":"22.21.1","dependencies":{"jose":"^6.2.6"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.0.16","typescript":"^5.7.2","@types/node":"^22"},"_npmOperationalInternal":{"tmp":"tmp/auth_2.1.0_1785610697430_0.49994276600465093","host":"s3://npm-registry-packages-npm-production"}},"3.0.0":{"name":"@activescott/auth","version":"3.0.0","keywords":["auth","authentication","magic-link","jwt","session"],"author":{"name":"Scott Willeke"},"license":"MIT","_id":"@activescott/auth@3.0.0","maintainers":[{"name":"activescott","email":"scott@willeke.com"}],"homepage":"https://github.com/activescott/auth#readme","bugs":{"url":"https://github.com/activescott/auth/issues"},"dist":{"shasum":"9e7cd8921c7ca49bb985de4eb92dcd78ac4038ee","tarball":"https://registry.npmjs.org/@activescott/auth/-/auth-3.0.0.tgz","fileCount":39,"integrity":"sha512-JPsubk/u3RAd3gDUMddjyAFjXbCSBe/g6aY1yEFMtybXk7Ye5RAdhpYictI9JRr24XRFv5bIQEQkLv0ZANxJBw==","signatures":[{"sig":"MEUCIQDbQDM7WEkc7BmY2xT5km/mALP+ubVA0mMyZXSJYK/xdwIgX8lq7XGPbQn8OuccAhDgXBD6kWzFMwyjuF/o1CEcJ4o=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@activescott%2fauth@3.0.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":100595},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"248dd93ce638d887a6732d0aca0c30a2aba866f8","scripts":{"dev":"tsc --watch","test":"vitest run","build":"tsc","typecheck":"tsc --noEmit","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:f149a3bb-4c70-4797-a4c8-ae9865aeaa50"}},"repository":{"url":"git+https://github.com/activescott/auth.git","type":"git","directory":"packages/auth"},"_npmVersion":"11.16.0","description":"Framework-agnostic authentication with provider pattern for magic links, OAuth, and more","directories":{},"_nodeVersion":"24.18.0","dependencies":{"jose":"^6.2.6"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.0.16","typescript":"^5.7.2","@types/node":"^22"},"_npmOperationalInternal":{"tmp":"tmp/auth_3.0.0_1785650597818_0.44622040768740634","host":"s3://npm-registry-packages-npm-production"}},"3.0.1":{"name":"@activescott/auth","version":"3.0.1","keywords":["auth","authentication","magic-link","jwt","session"],"author":{"name":"Scott Willeke"},"license":"MIT","_id":"@activescott/auth@3.0.1","maintainers":[{"name":"activescott","email":"scott@willeke.com"}],"homepage":"https://github.com/activescott/auth#readme","bugs":{"url":"https://github.com/activescott/auth/issues"},"dist":{"shasum":"ad6c06bad3f5ac976fec2d32616e930a22f31c25","tarball":"https://registry.npmjs.org/@activescott/auth/-/auth-3.0.1.tgz","fileCount":39,"integrity":"sha512-EaN+c8S1dIhjg0ExXBIcbSGuoDG7zJexRegX3iB/kEUH1Gj6vN3Dv6DRN4IlektWMOjdQZxjlWM4fwqrDyRI6Q==","signatures":[{"sig":"MEQCIBGaZ8nA+F0mP+mkDERbJKGp8EtUXdHbBrd3lEng0543AiAgSuu3VN2lFKISlooBusyNnw2485xq/RCBJ4Bc4+aLnQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@activescott%2fauth@3.0.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":104162},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"857dde22c82e6945acdb99e8677579fbc1484aee","scripts":{"dev":"tsc --watch","test":"vitest run","build":"tsc","typecheck":"tsc --noEmit","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:f149a3bb-4c70-4797-a4c8-ae9865aeaa50"}},"repository":{"url":"git+https://github.com/activescott/auth.git","type":"git","directory":"packages/auth"},"_npmVersion":"11.16.0","description":"Framework-agnostic authentication with provider pattern for magic links, OAuth, and more","directories":{},"_nodeVersion":"24.18.0","dependencies":{"jose":"^6.2.6"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.0.16","typescript":"^5.7.2","@types/node":"^22"},"_npmOperationalInternal":{"tmp":"tmp/auth_3.0.1_1785651667816_0.9165604795774114","host":"s3://npm-registry-packages-npm-production"}},"3.1.0":{"name":"@activescott/auth","version":"3.1.0","keywords":["auth","authentication","magic-link","jwt","session"],"author":{"name":"Scott Willeke"},"license":"MIT","_id":"@activescott/auth@3.1.0","maintainers":[{"name":"activescott","email":"scott@willeke.com"}],"homepage":"https://github.com/activescott/auth#readme","bugs":{"url":"https://github.com/activescott/auth/issues"},"dist":{"shasum":"50bcedeff01fbb12382220dcfc3ad13a621af75b","tarball":"https://registry.npmjs.org/@activescott/auth/-/auth-3.1.0.tgz","fileCount":63,"integrity":"sha512-21rPcgKrY0Ny0liSYjm2NzkeyuoX/+i6SxjFMxttZ9Y2JYXuM87K6NYNd5+Pr8y2gC0hwV9vjgf4Sd8TKmojcQ==","signatures":[{"sig":"MEYCIQCZ0ZNuNAPdk4zhEk7n3J/ONdPQingQP5HEvq/ugw82ggIhAPZWkSP5HDEZvnw57eKgpKnyzKdImLq6ymx5fIS30yS5","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@activescott%2fauth@3.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":161963},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"7f88f666cbdf9b9562c66db181b0aef70be2a6fe","scripts":{"dev":"tsc --watch","test":"vitest run","build":"tsc","typecheck":"tsc --noEmit","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:f149a3bb-4c70-4797-a4c8-ae9865aeaa50"}},"repository":{"url":"git+https://github.com/activescott/auth.git","type":"git","directory":"packages/auth"},"_npmVersion":"11.16.0","description":"Framework-agnostic authentication with provider pattern for magic links, OAuth, and more","directories":{},"_nodeVersion":"24.18.0","dependencies":{"jose":"^6.2.6"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.0.16","typescript":"^5.7.2","@types/node":"^22"},"_npmOperationalInternal":{"tmp":"tmp/auth_3.1.0_1786000558138_0.19607866502347093","host":"s3://npm-registry-packages-npm-production"}},"4.0.0":{"name":"@activescott/auth","version":"4.0.0","keywords":["auth","authentication","magic-link","jwt","session"],"author":{"name":"Scott Willeke"},"license":"MIT","_id":"@activescott/auth@4.0.0","maintainers":[{"name":"activescott","email":"scott@willeke.com"}],"homepage":"https://github.com/activescott/auth#readme","bugs":{"url":"https://github.com/activescott/auth/issues"},"dist":{"shasum":"0dc8309e6d75131f003a28bbbeb22cc20123ee34","tarball":"https://registry.npmjs.org/@activescott/auth/-/auth-4.0.0.tgz","fileCount":67,"integrity":"sha512-DYgAL1tNJi0siRFKvV8Ly4UH7j/S6Af6o9gk9N1hanPGzMaaHgIr9eARfvuDBOuuWvKuzJOmUsAPnokmuHpDkg==","signatures":[{"sig":"MEUCIQCU/LrM8JGpNxgCOkXOR4GT7fWG9+FSewvASgzBut43bgIgQMToy4hogkXyyMjak0iaqco/HOJpVY/wyeNJqBTRoEw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@activescott%2fauth@4.0.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":188596},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./admin":{"types":"./dist/admin/admin-data.d.ts","import":"./dist/admin/admin-data.js"}},"gitHead":"843a5ec640514b2cda1ca6de8c63eec0ef9a69ed","scripts":{"dev":"tsc --watch","test":"vitest run","build":"tsc","typecheck":"tsc --noEmit","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:f149a3bb-4c70-4797-a4c8-ae9865aeaa50"}},"repository":{"url":"git+https://github.com/activescott/auth.git","type":"git","directory":"packages/auth"},"_npmVersion":"11.16.0","description":"Framework-agnostic authentication with provider pattern for magic links, OAuth, and more","directories":{},"_nodeVersion":"24.18.0","dependencies":{"jose":"^6.2.6"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.0.16","typescript":"^5.7.2","@types/node":"^22"},"_npmOperationalInternal":{"tmp":"tmp/auth_4.0.0_1786208138962_0.38987435601417997","host":"s3://npm-registry-packages-npm-production"}},"4.1.0":{"name":"@activescott/auth","version":"4.1.0","keywords":["auth","authentication","magic-link","jwt","session"],"author":{"name":"Scott Willeke"},"license":"MIT","_id":"@activescott/auth@4.1.0","maintainers":[{"name":"activescott","email":"scott@willeke.com"}],"homepage":"https://github.com/activescott/auth#readme","bugs":{"url":"https://github.com/activescott/auth/issues"},"dist":{"shasum":"6186710da770b38c06b0d070123b9a03430940ab","tarball":"https://registry.npmjs.org/@activescott/auth/-/auth-4.1.0.tgz","fileCount":67,"integrity":"sha512-EMoqv0hXFkXjF+R3cyNzxWG43V/O625LZNas0J94gC3qO0ZOsBI6KY6NmqjBHGGpBVHB99lgzxr1oQJpSPpjfQ==","signatures":[{"sig":"MEQCIB0E75Mj82drfLd8NPYMmsUR6Q6dmpo4HIlZ+jiw/XURAiBy1jaFG6xQVU+6KX/5X2yu7aGSe03FVNL9HdtIjcotEg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@activescott%2fauth@4.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":214554},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./admin":{"types":"./dist/admin/admin-data.d.ts","import":"./dist/admin/admin-data.js"}},"gitHead":"a1933ba2887884db3a1437db58c8fa323b6a32c2","scripts":{"dev":"tsc --watch","test":"vitest run","build":"tsc","typecheck":"tsc --noEmit","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:f149a3bb-4c70-4797-a4c8-ae9865aeaa50"}},"repository":{"url":"git+https://github.com/activescott/auth.git","type":"git","directory":"packages/auth"},"_npmVersion":"11.16.0","description":"Framework-agnostic authentication with provider pattern for magic links, OAuth, and more","directories":{},"_nodeVersion":"24.18.0","dependencies":{"jose":"^6.2.6"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.0.16","typescript":"^5.7.2","@types/node":"^22"},"_npmOperationalInternal":{"tmp":"tmp/auth_4.1.0_1786467137704_0.5611689857399784","host":"s3://npm-registry-packages-npm-production"}},"5.0.0":{"name":"@activescott/auth","version":"5.0.0","description":"Framework-agnostic authentication with provider pattern for magic links, OAuth, and more","type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./admin":{"types":"./dist/admin/admin-data.d.ts","import":"./dist/admin/admin-data.js"}},"scripts":{"build":"tsc","dev":"tsc --watch","typecheck":"tsc --noEmit","test":"vitest run","prepublishOnly":"npm run build"},"keywords":["auth","authentication","magic-link","jwt","session"],"author":{"name":"Scott Willeke"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/activescott/auth.git","directory":"packages/auth"},"dependencies":{"jose":"^6.2.6"},"devDependencies":{"@types/node":"^22","typescript":"^5.7.2","vitest":"^4.0.16"},"gitHead":"f52acc55d81da8a0b3f8cbe8314f9b65ac02bc9c","_id":"@activescott/auth@5.0.0","bugs":{"url":"https://github.com/activescott/auth/issues"},"homepage":"https://github.com/activescott/auth#readme","_nodeVersion":"24.18.0","_npmVersion":"11.16.0","dist":{"integrity":"sha512-Pv2XfyXvRtYHvUaoUiI3LJKVZf3eXlZg/eIAlIcvdXwNQRKqOjJ+k+w3FvKQjhEyiyFlnQv0uggm6tkt6B12CA==","shasum":"c4cf4cd664ca9a00300fff026a078f9629ee5f9e","tarball":"https://registry.npmjs.org/@activescott/auth/-/auth-5.0.0.tgz","fileCount":67,"unpackedSize":218226,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@activescott%2fauth@5.0.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCnjdxF1DSqKEOf6ErQ2F5L6jDkUBF0dV3hTvHmJpbeOQIgA7MLG+5B6u8eTvmI50S3V3GJXzUtft5WUb0tytNBih4="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:f149a3bb-4c70-4797-a4c8-ae9865aeaa50"}},"directories":{},"maintainers":[{"name":"activescott","email":"scott@willeke.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/auth_5.0.0_1786467608931_0.2867729534601957"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-16T19:01:16.521Z","modified":"2026-08-11T17:00:09.351Z","0.1.1":"2026-03-16T19:01:16.756Z","0.1.3":"2026-05-09T15:58:02.662Z","1.0.0":"2026-07-31T18:24:10.250Z","2.0.0":"2026-07-31T19:53:59.896Z","2.1.0":"2026-08-01T18:58:17.568Z","3.0.0":"2026-08-02T06:03:17.974Z","3.0.1":"2026-08-02T06:21:07.956Z","3.1.0":"2026-08-06T07:15:58.277Z","4.0.0":"2026-08-08T16:55:39.104Z","4.1.0":"2026-08-11T16:52:17.901Z","5.0.0":"2026-08-11T17:00:09.075Z"},"bugs":{"url":"https://github.com/activescott/auth/issues"},"author":{"name":"Scott Willeke"},"license":"MIT","homepage":"https://github.com/activescott/auth#readme","keywords":["auth","authentication","magic-link","jwt","session"],"repository":{"type":"git","url":"git+https://github.com/activescott/auth.git","directory":"packages/auth"},"description":"Framework-agnostic authentication with provider pattern for magic links, OAuth, and more","maintainers":[{"name":"activescott","email":"scott@willeke.com"}],"readme":"# @activescott/auth\n\n[![npm version](https://img.shields.io/npm/v/@activescott/auth.svg)](https://www.npmjs.com/package/@activescott/auth)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\nFramework-agnostic direct authentication, deliberately small: single-use magic links and one-time codes via email and SMS, and passkeys (WebAuthn). No third-party identity providers. Runs on Node and edge runtimes (e.g. Cloudflare Workers).\n\nThis package is the core: the `Auth` class, JWT-cookie session management, and the provider/store interfaces. It does not handle any specific authentication method by itself — pair it with one or more provider packages and (optionally) a framework adapter:\n\n- [`@activescott/auth-provider-email`](https://www.npmjs.com/package/@activescott/auth-provider-email) — email magic links + one-time codes\n- [`@activescott/auth-provider-sms`](https://www.npmjs.com/package/@activescott/auth-provider-sms) — SMS one-time codes ([`@activescott/auth-sms-twilio`](https://www.npmjs.com/package/@activescott/auth-sms-twilio) provides both Twilio transports: Messaging and Verify)\n- [`@activescott/auth-provider-passkey`](https://www.npmjs.com/package/@activescott/auth-provider-passkey) — passkeys (WebAuthn)\n- [`@activescott/auth-adapter-react-router`](https://www.npmjs.com/package/@activescott/auth-adapter-react-router) — React Router v8 adapter\n\nUsed in production by [ramblefeed.com](https://ramblefeed.com) and [tinkerbellbot.com](https://tinkerbellbot.com).\n\n## Why direct, passwordless authentication?\n\nEveryone has an email address or a phone number. Nobody wants another password. And many users hesitate at \"Sign in with Google/Apple/Microsoft\" because it shares their sign-in activity with a third party. This library focuses on the ways a person can authenticate **directly** with your app:\n\n- **Lowest friction for your users.** No password to create, forget, or reset, and no account with a third party required. Modern platforms AutoFill the codes we send, so signing in is: type your email, type the code your OS offers you.\n- **Easiest for you.** No OAuth app registrations, no identity-provider dashboards, no extra services. An SMTP server and your database are the only dependencies.\n- **Private by design.** No third-party identity provider in the loop — big tech doesn't learn when (or that) your users sign in to your app.\n- **Deliberately small.** This is not a works-with-every-OAuth-provider auth library — that niche is well served by projects like [BetterAuth](https://www.better-auth.com/). Constraining the scope is what keeps this one easy to drop into a new app.\n\nPasskeys push the same idea further: phishing-resistant, no shared secret, and still no third party.\n\n## Features\n\n- ✅ **Email magic links** — single-use, server-backed sign-in links with a confirm step that email security scanners can't consume (see the [FAQ](https://github.com/activescott/auth#faq)). In production.\n- ✅ **Email one-time codes** — every sign-in email also includes a numeric code with iOS/macOS AutoFill support, so users can type the code instead of switching to the inbox tab.\n- ✅ **Bring your own database** — three small store interfaces (`IdentityStore`, `UserStore`, `ChallengeStore`); implement them with Prisma, Drizzle, raw SQL, Redis, whatever you use.\n- ✅ **Edge-ready, [WinterTC-compatible](https://wintertc.org/faq) core** — standard Fetch `Request`/`Response`, WebCrypto, and [`jose`](https://github.com/panva/jose) for session JWTs; no Node-only APIs, so it runs on Cloudflare Workers, Deno, Bun, and any WinterTC-aligned runtime.\n- ✅ **React Router v8 adapter** — `createAuthHandlers`, `requireAuth`, `optionalAuth`, `getSession`, `logout`.\n- ✅ **SMS one-time codes** — vendor-neutral provider with a Twilio Messaging transport (RCS-ready) and [WebOTP](https://developer.mozilla.org/docs/Web/API/WebOTP_API) autofill support.\n- ✅ **Hosted verification (no US A2P 10DLC)** — the same SMS provider accepts a `VerificationTransport` where the vendor generates, sends, and checks the code. `TwilioVerifyTransport` ships in the Twilio package: no number to buy, no brand or campaign registration — at the cost of ~4–6x per sign-in.\n- ✅ **Abuse protection, on by default** — per-IP and per-recipient rate limits, a minimum-form-fill-time check, blocked attempts logged, and a blocked caller gets the same response a successful send would produce. Optional packages add hosted bot checks ([Turnstile](https://www.npmjs.com/package/@activescott/auth-botcheck-turnstile)).\n- ✅ **Passkeys (WebAuthn)** — add a passkey while signed in, then sign in usernameless with Touch ID, Face ID, Windows Hello, 1Password, iCloud Keychain, or a security key; conditional UI (passkey autofill) supported. Verification via [`@simplewebauthn/server`](https://simplewebauthn.dev/); zero-dependency browser client included.\n\nThe provider interface (`AuthProvider`) is the extension point. Implementing a new provider does not require changes to this core package.\n\n## Documentation & example\n\nFull docs — quick start, architecture diagram, custom-provider guide, e2e-testing pattern, FAQ — and a runnable React Router framework-mode example with Playwright tests live in the monorepo:\n\n→ **https://github.com/activescott/auth**\n\nThe rest of this README covers what this core package itself exports and expects.\n\n## Install\n\n```bash\nnpm install @activescott/auth\n```\n\n## What's in the box\n\n| Export                                                            | Purpose                                                                                                               |\n| ----------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |\n| `Auth`                                                            | Orchestrator. Routes auth requests to providers, manages session cookies.                                             |\n| `SessionManager`                                                  | Standalone JWT session signer/verifier (rarely needed directly).                                                      |\n| `AuthProvider`                                                    | Interface every provider implements (`initiate`, `verify`, `canHandle`, optional `handleAction` for extra endpoints). |\n| `IdentityStore`, `UserStore`                                      | Interfaces you implement to plug in your database.                                                                    |\n| `ChallengeStore`, `InMemoryChallengeStore`                        | Storage for short-lived, single-use challenges (see below).                                                           |\n| `AbuseConfig`, `RateLimitStore`, `InMemoryRateLimitStore`         | Abuse protection for the initiate endpoints — on by default (see below).                                              |\n| `BotCheckProvider`, `createFormToken`, `FORM_TOKEN_FIELD`         | Bot-check interface and the login form's anti-bot fields.                                                             |\n| `generateOtpCode`, `hashOtpCode`, `verifyOtpCode`                 | One-time-code utilities used by OTP-capable providers.                                                                |\n| `AuthUser`, `Identity`, `Session`, `AuthResult`, `AuthInitResult` | Core data types.                                                                                                      |\n| `AuthErrors`, `getAuthErrorMessage`, `AUTH_ERROR_CODES`           | Structured error helpers.                                                                                             |\n\n## Data model\n\nYou bring three adapters — `IdentityStore`, `UserStore`, and `ChallengeStore` — that read/write your database. The library handles challenges, cookies, provider routing, and session verification.\n\nAn `Identity` is a `(provider, identifier)` pair (e.g. `(\"email\", \"alice@example.com\")`) linked to one of your `User` records. One user can have multiple identities — email, phone, and passkeys all use the same table.\n\n`Identity.metadata` is **provider-owned state**, opaque to your application: persist it unmodified (a JSON/JSONB column) and return it exactly as stored. Providers with per-identity state keep it there — the passkey provider stores each credential's public key and signature counter — and stateless providers store `{}`. It may contain sensitive material, so protect it like credential data (encryption at rest is a reasonable default). `IdentityStore.update(id, {metadata, verifiedAt})` replaces stored metadata wholesale; providers rely on it, so it is a required method.\n\n## Minimal shape\n\n```ts\nimport { Auth, InMemoryChallengeStore } from \"@activescott/auth\"\nimport { EmailProvider } from \"@activescott/auth-provider-email\"\n\nconst auth = new Auth({\n  session: {\n    secret: process.env.JWT_SECRET!,\n    maxAge: \"30d\",\n    cookieName: \"session\",\n    cookie: { secure: true, sameSite: \"lax\", path: \"/\" },\n  },\n  identityStore, // your impl\n  userStore, // your impl\n  challengeStore: new InMemoryChallengeStore(), // DB-backed in production\n  providers: [new EmailProvider({ ... })],\n})\n```\n\nThen call `auth.handleRequest(request)` from your framework's routing layer (or use a framework adapter), and `auth.verifySession(request)` to check the session cookie on protected routes.\n\n## ChallengeStore\n\nEvery sign-in attempt is backed by a server-side challenge: magic links and one-time codes store the hashed secret, an attempt counter, and an expiry; passkey ceremonies record the WebAuthn challenge so it is redeemable exactly once. That state lives in the `challengeStore`, which is why it is a required part of the `Auth` config.\n\n`InMemoryChallengeStore` is right for a single server process (and dev/examples). Challenges are lost on restart and not shared across instances — for multi-instance deployments implement the four-method `ChallengeStore` interface against shared storage. A SQL implementation is roughly:\n\n```sql\nCREATE TABLE challenges (\n  id TEXT PRIMARY KEY,\n  type TEXT NOT NULL,\n  identifier TEXT NOT NULL,\n  hashed_code TEXT,\n  data JSONB,\n  attempts INT NOT NULL DEFAULT 0,\n  max_attempts INT NOT NULL,\n  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),\n  expires_at TIMESTAMPTZ NOT NULL\n);\n```\n\nwith `incrementAttempts` as `UPDATE challenges SET attempts = attempts + 1 WHERE id = $1 RETURNING attempts` (the increment must be atomic — it enforces the guess limit), and a periodic `DELETE ... WHERE expires_at < now()`.\n\n## Abuse protection\n\nThe `initiate` endpoints send mail and texts to whatever address a caller submits, which makes them an attractive way to mail-bomb a third party or burn your sending reputation on bounces. Protection is **on by default** — you do not have to configure or implement anything:\n\n| Layer                  | Default                                                    |\n| ---------------------- | ---------------------------------------------------------- |\n| Per client IP          | 3 per minute, then 10 per hour                             |\n| Per recipient          | 3 per hour, then 10 per day                                |\n| Minimum form-fill time | 2 seconds (only enforced if the form posts a token, below) |\n| Counter storage        | `InMemoryRateLimitStore`                                   |\n| Blocked response       | identical to a successful send                             |\n\nBlocked attempts are always logged (`console.warn`) with the reason, provider, IP, requested identifier, and rule, so an abuse burst is visible:\n\n```\n[auth] blocked initiate: reason=identifier_rate_limited provider=email ip=203.0.113.7 identifier=victim@example.com rule=3/3600s retryAfter=2841s\n```\n\n### A blocked caller sees a success\n\nBy design a throttled or bot-flagged request gets exactly the response a real send would produce — the same 302 back to `?sent=1`, or the same `{success: true, message}` — minus the challenge cookie. Nothing is sent and nothing is stored. This is what keeps a bot from mapping which addresses or IPs are throttled. If you would rather return `429 RATE_LIMITED` (reasonable for an API-only deployment), set `abuse.respondWith: \"rateLimited\"`.\n\n### Tuning\n\n```ts\nconst auth = new Auth({\n  // ...\n  abuse: {\n    perIp: [\n      { windowSeconds: 60, max: 3 },\n      { windowSeconds: 3600, max: 10 },\n    ],\n    perIdentifier: [{ windowSeconds: 3600, max: 3 }],\n    store: myRedisRateLimitStore, // multi-instance: share the counters\n    onBlocked: (event) => logger.warn(event, \"auth abuse blocked\"),\n  },\n})\n```\n\n`abuse: { enabled: false }` turns everything off.\n\n`InMemoryRateLimitStore` counts per process, so a multi-instance deployment effectively multiplies every limit by the instance count. Implement the one-method `RateLimitStore` interface against Redis (`INCR` + `EXPIRE`) or your database to share counters.\n\nClient IPs come from `cf-connecting-ip`, then `x-forwarded-for` (rightmost hop; set `abuse.clientIp.trustedProxyHops` if more than one proxy appends), then `x-real-ip`. These headers are spoofable unless a proxy in front of your app rewrites them — supply `abuse.clientIp.getClientIp` when your runtime exposes the peer address. When no IP can be determined, per-IP limits are skipped and per-recipient limits still apply.\n\n### Form token\n\nThe minimum-form-fill-time check needs one hidden field in your login form:\n\n```tsx\nimport { createFormToken, FORM_TOKEN_FIELD } from \"@activescott/auth\"\n\n// in the route/loader that renders the form:\nconst formToken = await createFormToken(process.env.JWT_SECRET!)\n```\n\n```html\n<input type=\"hidden\" name=\"authFormToken\" value=\"{formToken}\" />\n```\n\nThe token is a signed render timestamp; the server rejects submissions that arrive faster than `minFormFillSeconds`. It must be signed — an unsigned timestamp is just another field to forge. A submission with **no** token is allowed, so adding the field is optional and can be rolled out later. A token older than a day is also allowed rather than rejected — a login page left open in a tab is a human.\n\n### Hosted bot checks\n\nCloudflare Turnstile, hCaptcha, and friends live in their own packages, so you only install the vendor you use:\n\n```ts\nimport { TurnstileBotCheck } from \"@activescott/auth-botcheck-turnstile\"\n\nabuse: {\n  botChecks: [new TurnstileBotCheck({ secretKey: process.env.TURNSTILE_SECRET_KEY! })],\n}\n```\n\nImplement `BotCheckProvider` (`{ id, verify({ request, body, ip, providerId }) }`) to add your own.\n\n## License\n\nMIT\n","readmeFilename":"README.md"}