{"_id":"@bernierllc/validators-signature-replay","_rev":"9-5f0d9cac320db3a8b8402114fd767b13","name":"@bernierllc/validators-signature-replay","dist-tags":{"latest":"1.7.0"},"versions":{"1.0.2":{"name":"@bernierllc/validators-signature-replay","version":"1.0.2","keywords":["validator","security","webhook","signature","hmac","replay-attack","timestamp","nonce","cryptography","primitive"],"author":{"name":"Bernier LLC"},"license":"UNLICENSED","_id":"@bernierllc/validators-signature-replay@1.0.2","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"dist":{"shasum":"95af4403bc07e33e3444f9dc005c7e691926394f","tarball":"https://registry.npmjs.org/@bernierllc/validators-signature-replay/-/validators-signature-replay-1.0.2.tgz","fileCount":24,"integrity":"sha512-gE4GEg1kRutMHqdeq2d0XmsiTMh3vnPnkolPmmgMGiNO8lWHSPZgT+7wlglHybghDK8aNHUS2jH9/UN/9TnCvQ==","signatures":[{"sig":"MEUCIG0+3jA2R3z9tGQTrwnqnRlFBBJkcGTRDT0zIffCSap7AiEAvr3Lb4MsvfEyGGOItG8MdsjqcqCSBFeEKWnlLsagIV8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":42720},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","gitHead":"9f17da2eb77b898307db9ec2eea45e18fa554fbd","scripts":{"lint":"eslint src --ext .ts","test":"jest","build":"tsc","clean":"rm -rf dist","test:watch":"jest --watch","test:coverage":"jest --coverage","prepublishOnly":"npm run clean && npm run build && rm -rf dist/__tests__"},"_npmUser":{"name":"mkbernier","email":"mkbernier@gmail.com"},"_npmVersion":"11.4.2","description":"Primitive validator for webhook signature validation and replay attack protection","directories":{},"_nodeVersion":"24.4.1","dependencies":{"@bernierllc/crypto-utils":"^1.0.2","@bernierllc/validators-core":"^0.1.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","eslint":"^8.0.0","ts-jest":"^29.1.0","typescript":"^5.0.0","@types/jest":"^29.5.0","@types/node":"^20.0.0","@typescript-eslint/parser":"^6.0.0","@typescript-eslint/eslint-plugin":"^6.0.0"},"_npmOperationalInternal":{"tmp":"tmp/validators-signature-replay_1.0.2_1760223837431_0.9047091637316387","host":"s3://npm-registry-packages-npm-production"}},"1.0.3":{"name":"@bernierllc/validators-signature-replay","version":"1.0.3","keywords":["validator","security","webhook","signature","hmac","replay-attack","timestamp","nonce","cryptography","primitive"],"author":{"name":"Bernier LLC"},"license":"UNLICENSED","_id":"@bernierllc/validators-signature-replay@1.0.3","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"dist":{"shasum":"a522c5d3c321d5e894242fc3dcd6ecbc928b4aee","tarball":"https://registry.npmjs.org/@bernierllc/validators-signature-replay/-/validators-signature-replay-1.0.3.tgz","fileCount":24,"integrity":"sha512-pXvSRxnKQdyeoAiua7JaRX5FH5pyNJPxldYhM0EaaSO6Qi/rJh0z0DCMRis082CvfKRJg9LLdMFusu7bukV3Hw==","signatures":[{"sig":"MEYCIQDrtZc1jmmVx8bsdxIFpD9FeV3x7IldoCwGxAQapaO9ugIhAMMdBXUb9Gmwn4HvdOnhewfVoEq/siRXhBlcNBK1hkns","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":42720},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","gitHead":"baa1fafa32f4076d475cbaf1fbec2a68b177c8d5","scripts":{"lint":"eslint src --ext .ts","test":"jest","build":"tsc","clean":"rm -rf dist","test:watch":"jest --watch","test:coverage":"jest --coverage","prepublishOnly":"npm run clean && npm run build && rm -rf dist/__tests__"},"_npmUser":{"name":"mkbernier","email":"mkbernier@gmail.com"},"_npmVersion":"11.4.2","description":"Primitive validator for webhook signature validation and replay attack protection","directories":{},"_nodeVersion":"24.4.1","dependencies":{"@bernierllc/crypto-utils":"^1.0.2","@bernierllc/validators-core":"^0.1.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","eslint":"^8.0.0","ts-jest":"^29.1.0","typescript":"^5.0.0","@types/jest":"^29.5.0","@types/node":"^20.0.0","@typescript-eslint/parser":"^6.0.0","@typescript-eslint/eslint-plugin":"^6.0.0"},"_npmOperationalInternal":{"tmp":"tmp/validators-signature-replay_1.0.3_1760224085143_0.21992385062030517","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"@bernierllc/validators-signature-replay","version":"1.2.0","keywords":["validator","security","webhook","signature","hmac","replay-attack","timestamp","nonce","cryptography","primitive"],"author":{"name":"Bernier LLC"},"license":"UNLICENSED","_id":"@bernierllc/validators-signature-replay@1.2.0","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"dist":{"shasum":"43637ba5e752db4dcd8b59afff414cc24b85614a","tarball":"https://registry.npmjs.org/@bernierllc/validators-signature-replay/-/validators-signature-replay-1.2.0.tgz","fileCount":24,"integrity":"sha512-i0TJt5FJmQj2+cVkdBxD7NGLqpQOUfQnNUi5oQd198mqmK1noXU7494jpxnoaEZtBsLYkgxoj6Jy2PiYWpLDTw==","signatures":[{"sig":"MEQCIBQxf4Cpk5kLo7IajzHLprnfZ/c/hJSD06wZvBcbGOcAAiBNDoGgLZ+r1Ye1hZ4ptOqUf5yI7n/OFeD/zeEq7IDPFg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":42822},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","gitHead":"af7e74b3715d56d3a193e1bb6743b337c2b0df6d","scripts":{"lint":"eslint src --ext .ts","test":"jest","build":"tsc","clean":"rm -rf dist","test:watch":"jest --watch","test:coverage":"jest --coverage","prepublishOnly":"npm run clean && npm run build && rm -rf dist/__tests__"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:7e6bd04b-2ce1-4bee-b6fa-4c13374bca43"}},"_npmVersion":"lerna/9.0.3/node@v20.19.6+x64 (linux)","description":"Primitive validator for webhook signature validation and replay attack protection","directories":{},"_nodeVersion":"20.19.6","dependencies":{"@bernierllc/crypto-utils":"1.0.6","@bernierllc/validators-core":"0.1.2"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","eslint":"^8.0.0","ts-jest":"^29.1.0","typescript":"^5.0.0","@types/jest":"^29.5.0","@types/node":"^20.0.0","@typescript-eslint/parser":"^6.0.0","@typescript-eslint/eslint-plugin":"^6.0.0"},"_npmOperationalInternal":{"tmp":"tmp/validators-signature-replay_1.2.0_1767642390808_0.12713144028075618","host":"s3://npm-registry-packages-npm-production"}},"1.2.1":{"name":"@bernierllc/validators-signature-replay","version":"1.2.1","keywords":["validator","security","webhook","signature","hmac","replay-attack","timestamp","nonce","cryptography","primitive"],"author":{"name":"Bernier LLC"},"license":"UNLICENSED","_id":"@bernierllc/validators-signature-replay@1.2.1","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"dist":{"shasum":"1cf4096a8e7f2392609b30d29e9e4f9a933c1a43","tarball":"https://registry.npmjs.org/@bernierllc/validators-signature-replay/-/validators-signature-replay-1.2.1.tgz","fileCount":24,"integrity":"sha512-RQ43otCsIJLj/q0pP3ctR4MiBaYqtZFBOODc1LI3/CuTdLffDPiF5gJoPIeHPJ1bYIx8WESkO5N93p05D2kdCw==","signatures":[{"sig":"MEUCIQDEwONJHyLjLMb8Rh8e3yp2Fx3BP2MgrzBi5BGDifmuZQIgfkRD/VrzHzbNEQAD9Pmlb2V2yAP5NBmV2lQ5GpO6jik=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":42683},"main":"dist/index.js","type":"module","_from":"file:bernierllc-validators-signature-replay-1.2.1.tgz","types":"dist/index.d.ts","scripts":{"lint":"eslint src --ext .ts","test":"jest","build":"tsc","clean":"rm -rf dist","test:watch":"jest --watch","test:coverage":"jest --coverage"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:7e6bd04b-2ce1-4bee-b6fa-4c13374bca43"}},"_resolved":"/tmp/58b49d447fbf47ebcd4c8a1d34220ef8/bernierllc-validators-signature-replay-1.2.1.tgz","_integrity":"sha512-RQ43otCsIJLj/q0pP3ctR4MiBaYqtZFBOODc1LI3/CuTdLffDPiF5gJoPIeHPJ1bYIx8WESkO5N93p05D2kdCw==","_npmVersion":"11.11.0","description":"Primitive validator for webhook signature validation and replay attack protection","directories":{},"_nodeVersion":"20.20.0","dependencies":{"@bernierllc/crypto-utils":"1.0.7","@bernierllc/validators-core":"0.1.3"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","eslint":"^8.0.0","ts-jest":"^29.1.0","typescript":"^5.0.0","@types/jest":"^29.5.0","@types/node":"^20.0.0","@typescript-eslint/parser":"^6.0.0","@typescript-eslint/eslint-plugin":"^6.0.0"},"_npmOperationalInternal":{"tmp":"tmp/validators-signature-replay_1.2.1_1773078335443_0.18221012995176245","host":"s3://npm-registry-packages-npm-production"}},"1.2.2":{"name":"@bernierllc/validators-signature-replay","version":"1.2.2","keywords":["validator","security","webhook","signature","hmac","replay-attack","timestamp","nonce","cryptography","primitive"],"author":{"name":"Bernier LLC"},"license":"UNLICENSED","_id":"@bernierllc/validators-signature-replay@1.2.2","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"dist":{"shasum":"3dd87a3e295724f01ed0ba99b78497814e06179f","tarball":"https://registry.npmjs.org/@bernierllc/validators-signature-replay/-/validators-signature-replay-1.2.2.tgz","fileCount":24,"integrity":"sha512-lwbTIL3Lky3bv/cJLXFJSQqGZqYPFH4HaeFgtWk7bO8Cju1xA3SbWHg/BxRvf6YLFX5KY+i5Sp9yICS9Y4IzhA==","signatures":[{"sig":"MEYCIQDNxe4ocxKvOVRP8dyMMUKsHFI/HniLAQtalf9727wqdwIhAP9pXGnLQeK1Oqh4CEQ7hfW5vnjYoGX62WGAAHqJLPR+","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":42683},"main":"dist/index.js","type":"module","_from":"file:bernierllc-validators-signature-replay-1.2.2.tgz","types":"dist/index.d.ts","scripts":{"lint":"eslint src --ext .ts","test":"jest","build":"tsc","clean":"rm -rf dist","test:watch":"jest --watch","test:coverage":"jest --coverage"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:7e6bd04b-2ce1-4bee-b6fa-4c13374bca43"}},"_resolved":"/home/runner/work/tools/tools/packages/validators/validators-signature-replay/bernierllc-validators-signature-replay-1.2.2.tgz","_integrity":"sha512-lwbTIL3Lky3bv/cJLXFJSQqGZqYPFH4HaeFgtWk7bO8Cju1xA3SbWHg/BxRvf6YLFX5KY+i5Sp9yICS9Y4IzhA==","_npmVersion":"11.11.0","description":"Primitive validator for webhook signature validation and replay attack protection","directories":{},"_nodeVersion":"20.20.0","dependencies":{"@bernierllc/crypto-utils":"1.0.8","@bernierllc/validators-core":"0.1.4"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","eslint":"^8.0.0","ts-jest":"^29.1.0","typescript":"^5.0.0","@types/jest":"^29.5.0","@types/node":"^20.0.0","@typescript-eslint/parser":"^6.0.0","@typescript-eslint/eslint-plugin":"^6.0.0"},"_npmOperationalInternal":{"tmp":"tmp/validators-signature-replay_1.2.2_1773163997821_0.1310233189107055","host":"s3://npm-registry-packages-npm-production"}},"1.3.0":{"name":"@bernierllc/validators-signature-replay","version":"1.3.0","keywords":["validator","security","webhook","signature","hmac","replay-attack","timestamp","nonce","cryptography","primitive"],"author":{"name":"Bernier LLC"},"license":"UNLICENSED","_id":"@bernierllc/validators-signature-replay@1.3.0","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"dist":{"shasum":"3f9c87fefe5b03f0a40e81bd884b3f651ff3e9c9","tarball":"https://registry.npmjs.org/@bernierllc/validators-signature-replay/-/validators-signature-replay-1.3.0.tgz","fileCount":24,"integrity":"sha512-ORErCFU3iZpzv/cCpdZmOTYStvCdfCGvAjci2BgFZxeJvfThO4c5e4csDxegddliFthlxrYdJLqutG+AyFWIlQ==","signatures":[{"sig":"MEQCIDDkMa2O4SuKVp0JN90btjI7KkgLYGJ7q5dd80Ril11ZAiBkWu+gVyUrimDTF1eTWJXK9RYAIfYhax2LahwpSi9bmw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":42683},"main":"dist/index.js","type":"module","_from":"file:bernierllc-validators-signature-replay-1.3.0.tgz","types":"dist/index.d.ts","scripts":{"lint":"eslint src --ext .ts","test":"jest","build":"tsc","clean":"rm -rf dist","test:watch":"jest --watch","test:coverage":"jest --coverage"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:7e6bd04b-2ce1-4bee-b6fa-4c13374bca43"}},"_resolved":"/home/runner/work/tools/tools/packages/validators/validators-signature-replay/bernierllc-validators-signature-replay-1.3.0.tgz","_integrity":"sha512-ORErCFU3iZpzv/cCpdZmOTYStvCdfCGvAjci2BgFZxeJvfThO4c5e4csDxegddliFthlxrYdJLqutG+AyFWIlQ==","_npmVersion":"11.14.1","description":"Primitive validator for webhook signature validation and replay attack protection","directories":{},"_nodeVersion":"20.20.2","dependencies":{"@bernierllc/crypto-utils":"1.2.0","@bernierllc/validators-core":"0.1.4"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","eslint":"^8.0.0","ts-jest":"^29.1.0","typescript":"^5.0.0","@types/jest":"^29.5.0","@types/node":"^20.0.0","@typescript-eslint/parser":"^6.0.0","@typescript-eslint/eslint-plugin":"^6.0.0"},"_npmOperationalInternal":{"tmp":"tmp/validators-signature-replay_1.3.0_1779221930113_0.10428929850348623","host":"s3://npm-registry-packages-npm-production"}},"1.4.0":{"name":"@bernierllc/validators-signature-replay","version":"1.4.0","keywords":["validator","security","webhook","signature","hmac","replay-attack","timestamp","nonce","cryptography","primitive"],"author":{"name":"Bernier LLC"},"license":"UNLICENSED","_id":"@bernierllc/validators-signature-replay@1.4.0","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"dist":{"shasum":"e499cfd5a08cace463ac6b8e59c9febc67faad23","tarball":"https://registry.npmjs.org/@bernierllc/validators-signature-replay/-/validators-signature-replay-1.4.0.tgz","fileCount":24,"integrity":"sha512-TJABiJOQakizl4ttzYWuh1WcK0rffz7Prwszib/7dvExDDeAD9VtJTthg1KjQsfFU+uECwvQrfwsbNwXWCYHAg==","signatures":[{"sig":"MEYCIQDo1lVRixZSi2GRaSki3dVovw2M77d1wxOwgbXwGNkOEQIhAN39aJammjZlDoSee2YXKPHnBJ9Orabhc7Fk1dpv0UzS","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":42683},"main":"dist/index.js","type":"module","_from":"file:bernierllc-validators-signature-replay-1.4.0.tgz","types":"dist/index.d.ts","scripts":{"lint":"eslint src --ext .ts","test":"jest","build":"tsc","clean":"rm -rf dist","test:watch":"jest --watch","test:coverage":"jest --coverage"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:7e6bd04b-2ce1-4bee-b6fa-4c13374bca43"}},"_resolved":"/home/runner/work/tools/tools/packages/validators/validators-signature-replay/bernierllc-validators-signature-replay-1.4.0.tgz","_integrity":"sha512-TJABiJOQakizl4ttzYWuh1WcK0rffz7Prwszib/7dvExDDeAD9VtJTthg1KjQsfFU+uECwvQrfwsbNwXWCYHAg==","_npmVersion":"11.14.1","description":"Primitive validator for webhook signature validation and replay attack protection","directories":{},"_nodeVersion":"20.20.2","dependencies":{"@bernierllc/crypto-utils":"1.3.0","@bernierllc/validators-core":"0.2.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","eslint":"^8.0.0","ts-jest":"^29.1.0","typescript":"^5.0.0","@types/jest":"^29.5.0","@types/node":"^20.0.0","@typescript-eslint/parser":"^6.0.0","@typescript-eslint/eslint-plugin":"^6.0.0"},"_npmOperationalInternal":{"tmp":"tmp/validators-signature-replay_1.4.0_1779242233254_0.38437698225508","host":"s3://npm-registry-packages-npm-production"}},"1.5.0":{"name":"@bernierllc/validators-signature-replay","version":"1.5.0","keywords":["validator","security","webhook","signature","hmac","replay-attack","timestamp","nonce","cryptography","primitive"],"author":{"name":"Bernier LLC"},"license":"UNLICENSED","_id":"@bernierllc/validators-signature-replay@1.5.0","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"dist":{"shasum":"482a1b3436a00fd47bdcb86972f6dad82498deb4","tarball":"https://registry.npmjs.org/@bernierllc/validators-signature-replay/-/validators-signature-replay-1.5.0.tgz","fileCount":24,"integrity":"sha512-r1CxTKtp5L1AHnyrx0sH+xvxjGZV4DsK2GPXwqiYaU23Ug3JcjJRDjVpl9PQnuXUtvr9P2+Xq5vjI5pP8R1xKA==","signatures":[{"sig":"MEYCIQDTI2elil5wAJGy71UMaBiuK1wBYR12UAFTBFDSuYBTFAIhAP8luB3mOvWRBHIaatqxPBqOk/YryI9DFPobvoC9YRQq","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":42683},"main":"dist/index.js","type":"module","_from":"file:bernierllc-validators-signature-replay-1.5.0.tgz","types":"dist/index.d.ts","scripts":{"lint":"eslint src --ext .ts","test":"jest","build":"tsc","clean":"rm -rf dist","test:watch":"jest --watch","test:coverage":"jest --coverage"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:7e6bd04b-2ce1-4bee-b6fa-4c13374bca43"}},"_resolved":"/home/runner/work/tools/tools/packages/validators/validators-signature-replay/bernierllc-validators-signature-replay-1.5.0.tgz","_integrity":"sha512-r1CxTKtp5L1AHnyrx0sH+xvxjGZV4DsK2GPXwqiYaU23Ug3JcjJRDjVpl9PQnuXUtvr9P2+Xq5vjI5pP8R1xKA==","_npmVersion":"11.14.1","description":"Primitive validator for webhook signature validation and replay attack protection","directories":{},"_nodeVersion":"20.20.2","dependencies":{"@bernierllc/crypto-utils":"1.4.0","@bernierllc/validators-core":"0.3.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","eslint":"^8.0.0","ts-jest":"^29.1.0","typescript":"^5.0.0","@types/jest":"^29.5.0","@types/node":"^20.0.0","@typescript-eslint/parser":"^6.0.0","@typescript-eslint/eslint-plugin":"^6.0.0"},"_npmOperationalInternal":{"tmp":"tmp/validators-signature-replay_1.5.0_1779250988363_0.058157648453222244","host":"s3://npm-registry-packages-npm-production"}},"1.7.0":{"name":"@bernierllc/validators-signature-replay","version":"1.7.0","description":"Primitive validator for webhook signature validation and replay attack protection","main":"dist/index.js","types":"dist/index.d.ts","type":"module","keywords":["validator","security","webhook","signature","hmac","replay-attack","timestamp","nonce","cryptography","primitive"],"author":{"name":"Bernier LLC"},"license":"UNLICENSED","dependencies":{"@bernierllc/validators-core":"0.4.0","@bernierllc/crypto-utils":"1.4.0"},"devDependencies":{"@types/jest":"^29.5.0","@types/node":"^20.0.0","@typescript-eslint/eslint-plugin":"^6.0.0","@typescript-eslint/parser":"^6.0.0","eslint":"^8.0.0","jest":"^29.5.0","ts-jest":"^29.1.0","typescript":"^5.0.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"scripts":{"build":"tsc","clean":"rm -rf dist","test":"jest","test:watch":"jest --watch","test:coverage":"jest --coverage","lint":"eslint src --ext .ts"},"_id":"@bernierllc/validators-signature-replay@1.7.0","_integrity":"sha512-xpnMsiFPQofPz6P+2WE+tRB04RnlnmEN2ezz/kRhAuTzVbon6eSuF3B8EpqX8wqdd3JZSKWcfr1OPfJfE4hgmA==","_resolved":"/home/runner/work/tools/tools/packages/validators/validators-signature-replay/bernierllc-validators-signature-replay-1.7.0.tgz","_from":"file:bernierllc-validators-signature-replay-1.7.0.tgz","_nodeVersion":"20.20.2","_npmVersion":"11.14.1","dist":{"integrity":"sha512-xpnMsiFPQofPz6P+2WE+tRB04RnlnmEN2ezz/kRhAuTzVbon6eSuF3B8EpqX8wqdd3JZSKWcfr1OPfJfE4hgmA==","shasum":"7579bd0a5384e670ca6677300e87234ba48b0750","tarball":"https://registry.npmjs.org/@bernierllc/validators-signature-replay/-/validators-signature-replay-1.7.0.tgz","fileCount":27,"unpackedSize":44877,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDAhfPQG5m+XJN2r0FuhX4C51MV/9hQHb6M58JPa4iK4wIgOakf+ynIgL/nBuUPwB9g4ckMYVSv5UFxp9jlXjVyoWo="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:7e6bd04b-2ce1-4bee-b6fa-4c13374bca43"}},"directories":{},"maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/validators-signature-replay_1.7.0_1779252274200_0.4140220870991409"},"_hasShrinkwrap":false}},"time":{"created":"2025-10-11T23:03:57.347Z","modified":"2026-05-20T04:44:34.478Z","1.0.2":"2025-10-11T23:03:57.613Z","1.0.3":"2025-10-11T23:08:05.333Z","1.2.0":"2026-01-05T19:46:30.943Z","1.2.1":"2026-03-09T17:45:35.594Z","1.2.2":"2026-03-10T17:33:17.959Z","1.3.0":"2026-05-19T20:18:50.304Z","1.4.0":"2026-05-20T01:57:13.426Z","1.5.0":"2026-05-20T04:23:08.505Z","1.7.0":"2026-05-20T04:44:34.333Z"},"author":{"name":"Bernier LLC"},"license":"UNLICENSED","keywords":["validator","security","webhook","signature","hmac","replay-attack","timestamp","nonce","cryptography","primitive"],"description":"Primitive validator for webhook signature validation and replay attack protection","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"readme":"# @bernierllc/validators-signature-replay\n\nWebhook signature validation and replay attack protection utilities for Node.js applications.\n\n## Overview\n\nProvides comprehensive security validation for webhooks and API requests by validating HMAC signatures, checking timestamp freshness, and preventing replay attacks through nonce validation.\n\n## Installation\n\n```bash\nnpm install @bernierllc/validators-signature-replay\n```\n\n## Features\n\n- **HMAC Signature Validation** - Verify cryptographic signatures using SHA256/384/512\n- **Timestamp Freshness** - Reject old requests to prevent replay attacks\n- **Nonce Validation** - Track and reject reused request IDs\n- **Comprehensive Replay Protection** - All-in-one validation combining signature, timestamp, and nonce\n- **Timing-Safe Comparison** - Prevent timing attacks on signature validation\n- **Automatic Cleanup** - Expired nonces are automatically removed from memory\n- **TypeScript Support** - Full type definitions included\n\n## Usage\n\n### Quick Start: Complete Replay Protection\n\n```typescript\nimport { validateReplayAttack, generateSignature, getCurrentTimestamp } from '@bernierllc/validators-signature-replay';\n\n// In your webhook handler\napp.post('/webhook', async (req, res) => {\n  const signature = req.headers['x-signature'];\n  const timestamp = parseInt(req.headers['x-timestamp']);\n  const nonce = req.headers['x-nonce'];\n  const payload = JSON.stringify(req.body);\n\n  const result = validateReplayAttack({\n    secret: process.env.WEBHOOK_SECRET,\n    signature,\n    payload,\n    timestamp,\n    nonce,\n    algorithm: 'sha256',\n    maxAgeSeconds: 300, // 5 minutes\n  });\n\n  if (!result.isValid) {\n    console.error('Validation failed:', result.errors);\n    return res.status(401).send('Unauthorized');\n  }\n\n  // Process webhook safely\n  await processWebhook(req.body);\n  res.status(200).send('OK');\n});\n```\n\n### Signature Validation\n\n```typescript\nimport { validateSignature, generateSignature } from '@bernierllc/validators-signature-replay';\n\n// Generate signature\nconst payload = JSON.stringify({ event: 'test' });\nconst signature = generateSignature(payload, 'secret-key', 'sha256');\n\n// Validate signature\nconst result = validateSignature({\n  secret: 'secret-key',\n  signature,\n  payload,\n  algorithm: 'sha256',\n});\n\nif (result.isValid) {\n  console.log('Signature valid');\n} else {\n  console.error('Invalid signature:', result.errors);\n}\n```\n\n### Timestamp Validation\n\n```typescript\nimport { validateTimestamp, getCurrentTimestamp } from '@bernierllc/validators-signature-replay';\n\n// Get current timestamp\nconst timestamp = getCurrentTimestamp(); // Unix timestamp in seconds\n\n// Validate timestamp freshness\nconst result = validateTimestamp({\n  timestamp,\n  maxAgeSeconds: 300, // Reject requests older than 5 minutes\n  isMilliseconds: false, // Set true if timestamp is in milliseconds\n});\n\nif (!result.isValid) {\n  console.error('Timestamp too old:', result.errors);\n}\n```\n\n### Nonce Validation\n\n```typescript\nimport { validateNonce, generateNonce } from '@bernierllc/validators-signature-replay';\n\n// Generate unique nonce\nconst nonce = await generateNonce();\n\n// Validate nonce (automatically tracks used nonces)\nconst result = validateNonce({\n  nonce: req.headers['x-nonce'],\n  ttlSeconds: 300, // How long to remember this nonce\n});\n\nif (!result.isValid) {\n  console.error('Replay attack detected:', result.errors);\n}\n```\n\n### Custom Nonce Store Management\n\n```typescript\nimport { NonceStore, getGlobalNonceStore, resetGlobalNonceStore } from '@bernierllc/validators-signature-replay';\n\n// Use global singleton store (default)\nconst globalStore = getGlobalNonceStore();\n\n// Or create your own store\nconst customStore = new NonceStore();\ncustomStore.addNonce('custom-nonce', 600);\n\n// Reset global store (useful for testing)\nresetGlobalNonceStore();\n\n// Cleanup when done\ncustomStore.destroy();\n```\n\n## API Reference\n\n### `validateReplayAttack(options)`\n\nComprehensive validation combining signature, timestamp, and nonce validation.\n\n**Parameters:**\n- `secret` (string) - Secret key for HMAC signature\n- `signature` (string) - Expected signature to validate\n- `payload` (string) - Payload that was signed\n- `timestamp` (number) - Request timestamp\n- `nonce` (string) - Unique request identifier\n- `algorithm` (string, optional) - HMAC algorithm (default: 'sha256')\n- `maxAgeSeconds` (number, optional) - Maximum timestamp age (default: 300)\n- `isMilliseconds` (boolean, optional) - Whether timestamp is in milliseconds (default: false)\n- `nonceTtlSeconds` (number, optional) - Nonce TTL (default: 300)\n\n**Returns:** `ReplayValidationResult`\n- `isValid` (boolean) - Whether all validations passed\n- `errors` (string[]) - Array of error messages\n- `metadata` (object) - Detailed validation metadata\n\n### `validateSignature(options)`\n\nValidate HMAC signature with timing-safe comparison.\n\n**Parameters:**\n- `secret` (string) - Secret key\n- `signature` (string) - Signature to validate\n- `payload` (string) - Payload that was signed\n- `algorithm` (string, optional) - HMAC algorithm (default: 'sha256')\n\n**Returns:** `SignatureValidationResult`\n\n### `generateSignature(payload, secret, algorithm?)`\n\nGenerate HMAC signature for a payload.\n\n**Parameters:**\n- `payload` (string) - Data to sign\n- `secret` (string) - Secret key\n- `algorithm` (string, optional) - HMAC algorithm (default: 'sha256')\n\n**Returns:** string - Hex-encoded signature\n\n### `validateTimestamp(options)`\n\nValidate timestamp freshness to prevent replay attacks.\n\n**Parameters:**\n- `timestamp` (number) - Timestamp to validate\n- `maxAgeSeconds` (number, optional) - Maximum age in seconds (default: 300)\n- `isMilliseconds` (boolean, optional) - Whether timestamp is in milliseconds (default: false)\n\n**Returns:** `TimestampValidationResult`\n\n### `validateNonce(options)`\n\nValidate nonce uniqueness to prevent replay attacks.\n\n**Parameters:**\n- `nonce` (string) - Nonce to validate\n- `ttlSeconds` (number, optional) - Time to live in seconds (default: 300)\n\n**Returns:** `NonceValidationResult`\n\n### `generateNonce()`\n\nGenerate cryptographically secure random nonce.\n\n**Returns:** Promise<string> - Random nonce string\n\n### Utility Functions\n\n- `getCurrentTimestamp()` - Get current Unix timestamp in seconds\n- `getCurrentTimestampMs()` - Get current Unix timestamp in milliseconds\n- `getGlobalNonceStore()` - Get global singleton nonce store\n- `resetGlobalNonceStore()` - Reset global nonce store (useful for testing)\n\n## Real-World Examples\n\n### GitHub Webhook Validation\n\n```typescript\napp.post('/github-webhook', async (req, res) => {\n  const signature = req.headers['x-hub-signature-256'];\n  const deliveryId = req.headers['x-github-delivery'];\n  const payload = JSON.stringify(req.body);\n\n  const result = validateReplayAttack({\n    secret: process.env.GITHUB_WEBHOOK_SECRET,\n    signature: signature.replace('sha256=', ''),\n    payload,\n    timestamp: Date.now() / 1000,\n    nonce: deliveryId,\n    algorithm: 'sha256',\n  });\n\n  if (!result.isValid) {\n    return res.status(401).send('Unauthorized');\n  }\n\n  // Process GitHub event\n  await handleGitHubEvent(req.body);\n  res.status(200).send('OK');\n});\n```\n\n### Stripe Webhook Validation\n\n```typescript\napp.post('/stripe-webhook', async (req, res) => {\n  const signature = req.headers['stripe-signature'];\n  const eventId = req.body.id;\n  const timestamp = Math.floor(Date.now() / 1000);\n  const payload = JSON.stringify(req.body);\n\n  const result = validateReplayAttack({\n    secret: process.env.STRIPE_WEBHOOK_SECRET,\n    signature,\n    payload: timestamp + '.' + payload,\n    timestamp,\n    nonce: eventId,\n  });\n\n  if (!result.isValid) {\n    return res.status(401).send('Unauthorized');\n  }\n\n  // Process Stripe event\n  await handleStripeEvent(req.body);\n  res.status(200).send('OK');\n});\n```\n\n## Security Best Practices\n\n1. **Always Use HTTPS** - Signature validation doesn't prevent man-in-the-middle attacks\n2. **Short Timestamp Windows** - Default 5 minutes is recommended, adjust based on clock skew\n3. **Unique Nonces** - Use cryptographically secure random generation\n4. **Rotate Secrets** - Periodically rotate webhook secrets\n5. **Monitor Failed Validations** - Log and alert on validation failures\n6. **Limit Request Rate** - Combine with rate limiting for defense in depth\n\n## Dependencies\n\n- `@bernierllc/validators-core` - Core validation types and utilities\n- `@bernierllc/crypto-utils` - Cryptographic utilities (optional, used for nonce generation)\n\n## Integration Status\n\n- **Logger integration**: Not applicable - This is a primitive validator package with no runtime logging needs\n- **Docs-Suite**: Ready - Full API documentation with JSDoc comments\n- **NeverHub integration**: Not applicable - This is a primitive validator package with no service discovery needs\n\n## License\n\nCopyright (c) 2025 Bernier LLC\n\nThis file is licensed to the client under a limited-use license.\n","readmeFilename":"README.md"}