@prmichaelsen/firebase-admin-sdk-v8 2.3.0 → 2.3.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/CHANGELOG.md +8 -0
- package/dist/index.js +20 -14
- package/dist/index.mjs +20 -14
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [2.3.1] - 2026-02-14
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- **CRITICAL**: Fixed signed URL generation to match Google Cloud Storage SDK encoding
|
|
14
|
+
- Implemented `fixedEncodeURIComponent` to additionally encode `! * ' ( )` characters
|
|
15
|
+
- This fixes `SignatureDoesNotMatch` errors in production environments
|
|
16
|
+
- Path encoding now exactly matches official `@google-cloud/storage` SDK behavior
|
|
17
|
+
|
|
10
18
|
## [2.3.0] - 2026-02-14
|
|
11
19
|
|
|
12
20
|
### Added
|
package/dist/index.js
CHANGED
|
@@ -1372,7 +1372,7 @@ function getStorageBucket() {
|
|
|
1372
1372
|
return customBucket;
|
|
1373
1373
|
}
|
|
1374
1374
|
const projectId = getProjectId();
|
|
1375
|
-
return `${projectId}.
|
|
1375
|
+
return `${projectId}.firebasestorage.app`;
|
|
1376
1376
|
}
|
|
1377
1377
|
function getExpirationTimestamp(expires) {
|
|
1378
1378
|
if (expires instanceof Date) {
|
|
@@ -1390,10 +1390,18 @@ function actionToMethod(action) {
|
|
|
1390
1390
|
return "DELETE";
|
|
1391
1391
|
}
|
|
1392
1392
|
}
|
|
1393
|
-
function
|
|
1393
|
+
function fixedEncodeURIComponent(str) {
|
|
1394
|
+
return encodeURIComponent(str).replace(
|
|
1395
|
+
/[!'()*]/g,
|
|
1396
|
+
(c) => "%" + c.charCodeAt(0).toString(16).toUpperCase()
|
|
1397
|
+
);
|
|
1398
|
+
}
|
|
1399
|
+
async function sha256Hex(str) {
|
|
1394
1400
|
const encoder = new TextEncoder();
|
|
1395
|
-
const
|
|
1396
|
-
|
|
1401
|
+
const data = encoder.encode(str);
|
|
1402
|
+
const hashBuffer = await crypto.subtle.digest("SHA-256", data);
|
|
1403
|
+
const hashArray = new Uint8Array(hashBuffer);
|
|
1404
|
+
return Array.from(hashArray).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
1397
1405
|
}
|
|
1398
1406
|
async function signData(data, privateKey) {
|
|
1399
1407
|
const pemHeader = "-----BEGIN PRIVATE KEY-----";
|
|
@@ -1458,17 +1466,15 @@ async function generateSignedUrl(path, options) {
|
|
|
1458
1466
|
}
|
|
1459
1467
|
const sortedParams = Object.keys(queryParams).sort();
|
|
1460
1468
|
const canonicalQueryString = sortedParams.map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(queryParams[key])}`).join("&");
|
|
1461
|
-
const encodedPath = path.split("/").map((segment) =>
|
|
1469
|
+
const encodedPath = path.split("/").map((segment) => fixedEncodeURIComponent(segment)).join("/");
|
|
1462
1470
|
const canonicalUri = `/${bucket}/${encodedPath}`;
|
|
1463
|
-
const canonicalRequest =
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
].join("\n");
|
|
1471
|
-
const canonicalRequestHash = stringToHex(canonicalRequest);
|
|
1471
|
+
const canonicalRequest = `${method}
|
|
1472
|
+
${canonicalUri}
|
|
1473
|
+
${canonicalQueryString}
|
|
1474
|
+
${canonicalHeaders}
|
|
1475
|
+
${signedHeaders}
|
|
1476
|
+
UNSIGNED-PAYLOAD`;
|
|
1477
|
+
const canonicalRequestHash = await sha256Hex(canonicalRequest);
|
|
1472
1478
|
const stringToSign = [
|
|
1473
1479
|
"GOOG4-RSA-SHA256",
|
|
1474
1480
|
dateTimeStamp,
|
package/dist/index.mjs
CHANGED
|
@@ -1316,7 +1316,7 @@ function getStorageBucket() {
|
|
|
1316
1316
|
return customBucket;
|
|
1317
1317
|
}
|
|
1318
1318
|
const projectId = getProjectId();
|
|
1319
|
-
return `${projectId}.
|
|
1319
|
+
return `${projectId}.firebasestorage.app`;
|
|
1320
1320
|
}
|
|
1321
1321
|
function getExpirationTimestamp(expires) {
|
|
1322
1322
|
if (expires instanceof Date) {
|
|
@@ -1334,10 +1334,18 @@ function actionToMethod(action) {
|
|
|
1334
1334
|
return "DELETE";
|
|
1335
1335
|
}
|
|
1336
1336
|
}
|
|
1337
|
-
function
|
|
1337
|
+
function fixedEncodeURIComponent(str) {
|
|
1338
|
+
return encodeURIComponent(str).replace(
|
|
1339
|
+
/[!'()*]/g,
|
|
1340
|
+
(c) => "%" + c.charCodeAt(0).toString(16).toUpperCase()
|
|
1341
|
+
);
|
|
1342
|
+
}
|
|
1343
|
+
async function sha256Hex(str) {
|
|
1338
1344
|
const encoder = new TextEncoder();
|
|
1339
|
-
const
|
|
1340
|
-
|
|
1345
|
+
const data = encoder.encode(str);
|
|
1346
|
+
const hashBuffer = await crypto.subtle.digest("SHA-256", data);
|
|
1347
|
+
const hashArray = new Uint8Array(hashBuffer);
|
|
1348
|
+
return Array.from(hashArray).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
1341
1349
|
}
|
|
1342
1350
|
async function signData(data, privateKey) {
|
|
1343
1351
|
const pemHeader = "-----BEGIN PRIVATE KEY-----";
|
|
@@ -1402,17 +1410,15 @@ async function generateSignedUrl(path, options) {
|
|
|
1402
1410
|
}
|
|
1403
1411
|
const sortedParams = Object.keys(queryParams).sort();
|
|
1404
1412
|
const canonicalQueryString = sortedParams.map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(queryParams[key])}`).join("&");
|
|
1405
|
-
const encodedPath = path.split("/").map((segment) =>
|
|
1413
|
+
const encodedPath = path.split("/").map((segment) => fixedEncodeURIComponent(segment)).join("/");
|
|
1406
1414
|
const canonicalUri = `/${bucket}/${encodedPath}`;
|
|
1407
|
-
const canonicalRequest =
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
].join("\n");
|
|
1415
|
-
const canonicalRequestHash = stringToHex(canonicalRequest);
|
|
1415
|
+
const canonicalRequest = `${method}
|
|
1416
|
+
${canonicalUri}
|
|
1417
|
+
${canonicalQueryString}
|
|
1418
|
+
${canonicalHeaders}
|
|
1419
|
+
${signedHeaders}
|
|
1420
|
+
UNSIGNED-PAYLOAD`;
|
|
1421
|
+
const canonicalRequestHash = await sha256Hex(canonicalRequest);
|
|
1416
1422
|
const stringToSign = [
|
|
1417
1423
|
"GOOG4-RSA-SHA256",
|
|
1418
1424
|
dateTimeStamp,
|
package/package.json
CHANGED