security: harden admin auth, reconciler locking, and connection pooling

- Use secrets.compare_digest for timing-safe admin key comparison
- Strip whitespace from ADMIN_API_KEY env var
- Add PostgreSQL advisory locks per-invoice in reconciler to prevent
  duplicate processing during deployments
- Add wallet-RPC retry with backoff (3 attempts: 0.5s, 1s, 2s)
- Raise MAX_SUBADDRESS_INDEX from 100 to 300
- Tune DB connection pool (pool_size=20, max_overflow=10, recycle=3600)
- Add 1-hour admin session timeout
- Regenerate UI lockfile
This commit is contained in:
jwinterm
2026-03-15 10:49:55 -04:00
parent 20eff23335
commit 00e04c74bb
7 changed files with 131 additions and 10 deletions
+86 -2
View File
@@ -1,17 +1,19 @@
{
"name": "xmrcheckout-ui",
"name": "wowcheckout-ui",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "xmrcheckout-ui",
"name": "wowcheckout-ui",
"dependencies": {
"@marsidev/react-turnstile": "^1.4.2",
"doctrine": "^3.0.0",
"esutils": "^2.0.3",
"next": "15.5.9",
"qrcode": "1.5.4",
"react": "19.2.3",
"react-dom": "19.2.3",
"resend": "^6.9.3",
"tsconfig-paths": "^4.2.0"
},
"devDependencies": {
@@ -707,6 +709,16 @@
"@jridgewell/sourcemap-codec": "^1.4.14"
}
},
"node_modules/@marsidev/react-turnstile": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/@marsidev/react-turnstile/-/react-turnstile-1.4.2.tgz",
"integrity": "sha512-xs1qOuyeMOz6t9BXXCXWiukC0/0+48vR08B7uwNdG05wCMnbcNgxiFmdFKDOFbM76qFYFRYlGeRfhfq1U/iZmA==",
"license": "MIT",
"peerDependencies": {
"react": "^17.0.2 || ^18.0.0 || ^19.0",
"react-dom": "^17.0.2 || ^18.0.0 || ^19.0"
}
},
"node_modules/@napi-rs/wasm-runtime": {
"version": "0.2.12",
"resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz",
@@ -926,6 +938,12 @@
"dev": true,
"license": "MIT"
},
"node_modules/@stablelib/base64": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@stablelib/base64/-/base64-1.0.1.tgz",
"integrity": "sha512-1bnPQqSxSuc3Ii6MhBysoWCg58j97aUjuCSZrGSmDxNqtytIi0k8utUenAwTZN4V5mXXYGsVUI9zeBqy+jBOSQ==",
"license": "MIT"
},
"node_modules/@swc/helpers": {
"version": "0.5.15",
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz",
@@ -3214,6 +3232,12 @@
"dev": true,
"license": "MIT"
},
"node_modules/fast-sha256": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/fast-sha256/-/fast-sha256-1.3.0.tgz",
"integrity": "sha512-n11RGP/lrWEFI/bWdygLxhI+pVeo1ZYIVwvvPkW7azl/rOy+F3HYRZ2K5zeE9mmkhQppyv9sQFx0JM9UabnpPQ==",
"license": "Unlicense"
},
"node_modules/fastq": {
"version": "1.19.1",
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz",
@@ -4819,6 +4843,12 @@
"node": ">= 0.4"
}
},
"node_modules/postal-mime": {
"version": "2.7.3",
"resolved": "https://registry.npmjs.org/postal-mime/-/postal-mime-2.7.3.tgz",
"integrity": "sha512-MjhXadAJaWgYzevi46+3kLak8y6gbg0ku14O1gO/LNOuay8dO+1PtcSGvAdgDR0DoIsSaiIA8y/Ddw6MnrO0Tw==",
"license": "MIT-0"
},
"node_modules/postcss": {
"version": "8.5.6",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
@@ -5162,6 +5192,27 @@
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
"license": "ISC"
},
"node_modules/resend": {
"version": "6.9.3",
"resolved": "https://registry.npmjs.org/resend/-/resend-6.9.3.tgz",
"integrity": "sha512-GRXjH9XZBJA+daH7bBVDuTShr22iWCxXA8P7t495G4dM/RC+d+3gHBK/6bz9K6Vpcq11zRQKmD+B+jECwQlyGQ==",
"license": "MIT",
"dependencies": {
"postal-mime": "2.7.3",
"svix": "1.84.1"
},
"engines": {
"node": ">=20"
},
"peerDependencies": {
"@react-email/render": "*"
},
"peerDependenciesMeta": {
"@react-email/render": {
"optional": true
}
}
},
"node_modules/resolve": {
"version": "1.22.11",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz",
@@ -5527,6 +5578,16 @@
"dev": true,
"license": "MIT"
},
"node_modules/standardwebhooks": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/standardwebhooks/-/standardwebhooks-1.0.0.tgz",
"integrity": "sha512-BbHGOQK9olHPMvQNHWul6MYlrRTAOKn03rOe4A8O3CLWhNf4YHBqq2HJKKC+sfqpxiBY52pNeesD6jIiLDz8jg==",
"license": "MIT",
"dependencies": {
"@stablelib/base64": "^1.0.0",
"fast-sha256": "^1.3.0"
}
},
"node_modules/stop-iteration-iterator": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz",
@@ -5774,6 +5835,16 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/svix": {
"version": "1.84.1",
"resolved": "https://registry.npmjs.org/svix/-/svix-1.84.1.tgz",
"integrity": "sha512-K8DPPSZaW/XqXiz1kEyzSHYgmGLnhB43nQCMeKjWGCUpLIpAMMM8kx3rVVOSm6Bo6EHyK1RQLPT4R06skM/MlQ==",
"license": "MIT",
"dependencies": {
"standardwebhooks": "1.0.0",
"uuid": "^10.0.0"
}
},
"node_modules/tailwindcss": {
"version": "3.4.19",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.19.tgz",
@@ -6197,6 +6268,19 @@
"dev": true,
"license": "MIT"
},
"node_modules/uuid": {
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz",
"integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==",
"funding": [
"https://github.com/sponsors/broofa",
"https://github.com/sponsors/ctavan"
],
"license": "MIT",
"bin": {
"uuid": "dist/bin/uuid"
}
},
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",