forgelayer-node 1.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/server.js +11 -5
package/package.json
CHANGED
package/src/server.js
CHANGED
|
@@ -40,7 +40,7 @@ try {
|
|
|
40
40
|
|
|
41
41
|
const FL_API_BASE = 'https://api.forgelayer.io/v1';
|
|
42
42
|
const CG_API_BASE = 'https://api.coingecko.com/api/v3';
|
|
43
|
-
const SDK_VERSION = '1.1.
|
|
43
|
+
const SDK_VERSION = '1.1.1';
|
|
44
44
|
|
|
45
45
|
// Stablecoins pegged 1:1 to USD — skip CoinGecko for these
|
|
46
46
|
const USD_STABLECOINS = new Set([
|
|
@@ -259,7 +259,8 @@ function createCheckout(config) {
|
|
|
259
259
|
// ── Helpers ─────────────────────────────────────────────────────────────────
|
|
260
260
|
|
|
261
261
|
function toSessionKey(orderId) {
|
|
262
|
-
|
|
262
|
+
// SHA-256 so ORDER-1 and ORDER_1 don't collapse to the same key
|
|
263
|
+
return 'fl_' + crypto.createHash('sha256').update(String(orderId)).digest('hex').slice(0, 32);
|
|
263
264
|
}
|
|
264
265
|
|
|
265
266
|
async function markConfirmed(sessionKey, order) {
|
|
@@ -410,7 +411,10 @@ function createCheckout(config) {
|
|
|
410
411
|
}
|
|
411
412
|
|
|
412
413
|
const expected = crypto.createHmac('sha256', webhookSecret).update(rawBody).digest('hex');
|
|
413
|
-
|
|
414
|
+
// timingSafeEqual throws if buffer lengths differ, so check length first
|
|
415
|
+
const sigBuf = Buffer.from(sig);
|
|
416
|
+
const expBuf = Buffer.from(expected);
|
|
417
|
+
if (sigBuf.length !== expBuf.length || !crypto.timingSafeEqual(sigBuf, expBuf)) {
|
|
414
418
|
return res.status(401).json({ ok: false, error: 'Invalid signature.' });
|
|
415
419
|
}
|
|
416
420
|
|
|
@@ -507,8 +511,10 @@ function readBody(req) {
|
|
|
507
511
|
|
|
508
512
|
// ── Webhook secret/ID persistence ─────────────────────────────────────────────
|
|
509
513
|
|
|
510
|
-
|
|
511
|
-
|
|
514
|
+
// Use process.cwd() so the file lands in the developer's project root,
|
|
515
|
+
// not inside node_modules/forgelayer-node/ where it gets wiped on reinstall.
|
|
516
|
+
const SECRET_FILE = path.join(process.cwd(), '.fl_webhook_secret');
|
|
517
|
+
const ID_FILE = path.join(process.cwd(), '.fl_webhook_id');
|
|
512
518
|
|
|
513
519
|
function loadSavedWebhookSecret() {
|
|
514
520
|
try { return fs.readFileSync(SECRET_FILE, 'utf8').trim(); } catch (_) { return ''; }
|