Skip to content

Commit 9c0c302

Browse files
Merge branch 'main' into dependabot/npm_and_yarn/multi-d0f6e8601e
2 parents c098249 + 43bda4c commit 9c0c302

8 files changed

Lines changed: 123 additions & 85 deletions

File tree

-6 Bytes
Binary file not shown.

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ jobs:
1212
node-version: [18.x, 20.x, 22.x, 24.x]
1313

1414
steps:
15-
- uses: actions/checkout@v4
15+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
1616
- name: Set up Node.js ${{ matrix.node-version }}
17-
uses: actions/setup-node@v4
17+
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
1818
with:
1919
node-version: ${{ matrix.node-version }}
2020
- name: Install and build

.github/workflows/nightly.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,12 @@ jobs:
2929

3030
steps:
3131
- name: Checkout source for staging
32-
uses: actions/checkout@v4
32+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
3333
with:
3434
ref: ${{ github.event.client_payload.ref || github.ref }}
3535

3636
- name: Set up Node.js
37-
uses: actions/setup-node@v4
37+
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
3838
with:
3939
node-version: 18.x
4040

@@ -72,7 +72,7 @@ jobs:
7272
# Attach the packaged artifacts to the workflow output. These can be manually
7373
# downloaded for later inspection if necessary.
7474
- name: Archive artifacts
75-
uses: actions/upload-artifact@v4
75+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
7676
with:
7777
name: dist
7878
path: dist

.github/workflows/release.yml

Lines changed: 32 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -15,37 +15,41 @@
1515
name: Release Candidate
1616

1717
on:
18-
# Only run the workflow when a PR is updated or when a developer explicitly requests
19-
# a build by sending a 'firebase_build' event.
18+
# Run the workflow when:
19+
# 1. A PR is created or updated (staging checks).
20+
# 2. A commit is pushed to main (release publication).
21+
# 3. A developer explicitly requests a build via 'firebase_build' event.
2022
pull_request:
21-
types: [opened, synchronize, closed]
23+
types: [opened, synchronize]
24+
25+
push:
26+
branches:
27+
- main
28+
paths:
29+
- 'package.json'
2230

2331
repository_dispatch:
2432
types:
2533
- firebase_build
2634

2735
jobs:
2836
stage_release:
29-
# To publish a release, merge the release PR with the label 'release:publish'.
37+
# To publish a release, merge a PR with the title prefix '[chore] Release ' to main
38+
# and ensure the squashed commit message also has the prefix.
3039
# To stage a release without publishing it, send a 'firebase_build' event or apply
3140
# the 'release:stage' label to a PR.
3241
if: github.event.action == 'firebase_build' ||
3342
contains(github.event.pull_request.labels.*.name, 'release:stage') ||
34-
(github.event.pull_request.merged &&
35-
contains(github.event.pull_request.labels.*.name, 'release:publish'))
43+
(github.event_name == 'push' && startsWith(github.event.head_commit.message, '[chore] Release '))
3644

3745
runs-on: ubuntu-latest
3846

39-
# When manually triggering the build, the requester can specify a target branch or a tag
40-
# via the 'ref' client parameter.
4147
steps:
4248
- name: Checkout source for staging
43-
uses: actions/checkout@v4
44-
with:
45-
ref: ${{ github.event.client_payload.ref || github.ref }}
49+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
4650

4751
- name: Set up Node.js
48-
uses: actions/setup-node@v4
52+
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
4953
with:
5054
node-version: 18.x
5155

@@ -77,7 +81,7 @@ jobs:
7781
# Attach the packaged artifacts to the workflow output. These can be manually
7882
# downloaded for later inspection if necessary.
7983
- name: Archive artifacts
80-
uses: actions/upload-artifact@v4
84+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
8185
with:
8286
name: dist
8387
path: dist
@@ -90,35 +94,33 @@ jobs:
9094
publish_release:
9195
needs: stage_release
9296

93-
# Check whether the release should be published. We publish only when the trigger PR is
94-
# 1. merged
97+
# Check whether the release should be published. We publish only when the trigger is
98+
# 1. a push (merge)
9599
# 2. to the main branch
96-
# 3. with the label 'release:publish', and
97-
# 4. the title prefix '[chore] Release '.
98-
if: |
99-
github.event.pull_request.merged &&
100+
# 3. and the commit message has the title prefix '[chore] Release '.
101+
if: github.event_name == 'push' &&
100102
github.ref == 'refs/heads/main' &&
101-
contains(github.event.pull_request.labels.*.name, 'release:publish') &&
102-
startsWith(github.event.pull_request.title, '[chore] Release ')
103+
startsWith(github.event.head_commit.message, '[chore] Release ')
103104

104105
runs-on: ubuntu-latest
106+
environment: Release
105107
permissions:
106108
contents: write
107109

108110
steps:
109111
- name: Checkout source for publish
110-
uses: actions/checkout@v4
112+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
111113

112114
# Download the artifacts created by the stage_release job.
113115
- name: Download release candidates
114-
uses: actions/download-artifact@v4.1.7
116+
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
115117
with:
116118
name: dist
117119
path: dist
118120

119121
# Node.js and NPM are needed to complete the publish.
120122
- name: Set up Node.js
121-
uses: actions/setup-node@v4
123+
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
122124
with:
123125
node-version: 18.x
124126

@@ -130,27 +132,15 @@ jobs:
130132
- name: Create release tag
131133
env:
132134
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
133-
run: gh release create ${{ steps.preflight.outputs.version }}
134-
--title "Firebase Admin Node.js SDK ${{ steps.preflight.outputs.version }}"
135-
--notes '${{ steps.preflight.outputs.changelog }}'
135+
RELEASE_VER: ${{ steps.preflight.outputs.version }}
136+
RELEASE_BODY: ${{ steps.preflight.outputs.changelog }}
137+
run: |
138+
gh release create "$RELEASE_VER" \
139+
--title "Firebase Admin Node.js SDK $RELEASE_VER" \
140+
--notes "$RELEASE_BODY"
136141
137142
- name: Publish to NPM
138143
run: ./.github/scripts/publish_package.sh
139144
env:
140145
NPM_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}
141146
VERSION: ${{ steps.preflight.outputs.version }}
142-
143-
# Post to Twitter if explicitly opted-in by adding the label 'release:tweet'.
144-
- name: Post to Twitter
145-
if: success() &&
146-
contains(github.event.pull_request.labels.*.name, 'release:tweet')
147-
uses: ./.github/actions/send-tweet
148-
with:
149-
status: >
150-
${{ steps.preflight.outputs.version }} of @Firebase Admin Node.js SDK is available.
151-
https://github.com/firebase/firebase-admin-node/releases/tag/${{ steps.preflight.outputs.version }}
152-
consumer-key: ${{ secrets.TWITTER_CONSUMER_KEY }}
153-
consumer-secret: ${{ secrets.TWITTER_CONSUMER_SECRET }}
154-
access-token: ${{ secrets.TWITTER_ACCESS_TOKEN }}
155-
access-token-secret: ${{ secrets.TWITTER_ACCESS_TOKEN_SECRET }}
156-
continue-on-error: true

package-lock.json

Lines changed: 9 additions & 18 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/data-connect/data-connect-api-client-internal.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -413,10 +413,7 @@ export class DataConnectApiClient {
413413
*/
414414
private objectToString(data: unknown): string {
415415
if (typeof data === 'string') {
416-
const escapedString = data
417-
.replace(/\\/g, '\\\\') // Replace \ with \\
418-
.replace(/"/g, '\\"'); // Replace " with \"
419-
return `"${escapedString}"`;
416+
return JSON.stringify(data);
420417
}
421418
if (typeof data === 'number' || typeof data === 'boolean' || data === null) {
422419
return String(data);

src/utils/validator.ts

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515
* limitations under the License.
1616
*/
1717

18-
import url = require('url');
19-
2018
/**
2119
* Validates that a value is a byte buffer.
2220
*
@@ -234,33 +232,38 @@ export function isURL(urlStr: any): boolean {
234232
return false;
235233
}
236234
try {
237-
const uri = url.parse(urlStr);
235+
const uri = new URL(urlStr);
238236
const scheme = uri.protocol;
239-
const slashes = uri.slashes;
240-
const hostname = uri.hostname;
241-
const pathname = uri.pathname;
242-
if ((scheme !== 'http:' && scheme !== 'https:') || !slashes) {
237+
if (scheme !== 'http:' && scheme !== 'https:') {
243238
return false;
244239
}
245-
// Validate hostname: Can contain letters, numbers, underscore and dashes separated by a dot.
246-
// Each zone must not start with a hyphen or underscore.
247-
if (!hostname || !/^[a-zA-Z0-9]+[\w-]*([.]?[a-zA-Z0-9]+[\w-]*)*$/.test(hostname)) {
248-
return false;
240+
const hostname = uri.hostname;
241+
// Validate hostname strictly to match previous behavior and prevent weak/invalid domains.
242+
// Must be alphanumeric with optional dashes/underscores, separated by dots.
243+
// Cannot start/end with dot or dash (mostly).
244+
// This regex is safe (no nested quantifiers with overlap).
245+
if (!/^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?)*$/.test(hostname)) {
246+
// Check for IPv6 literals which are valid but behave differently.
247+
// Node 'new URL' keeps brackets for IPv6: [::1] -> [::1]
248+
// Check for IPv6 address (simple check for brackets)
249+
if (!/^\[[a-fA-F0-9:.]+\]$/.test(hostname)) {
250+
return false;
251+
}
249252
}
250-
// Allow for pathnames: (/chars+)*/?
253+
// Restore strict pathname validation: (/chars+)*/?
251254
// Where chars can be a combination of: a-z A-Z 0-9 - _ . ~ ! $ & ' ( ) * + , ; = : @ %
252255
const pathnameRe = /^(\/[\w\-.~!$'()*+,;=:@%]+)*\/?$/;
253256
// Validate pathname.
257+
const pathname = uri.pathname;
254258
if (pathname &&
255-
pathname !== '/' &&
256-
!pathnameRe.test(pathname)) {
259+
pathname !== '/' &&
260+
!pathnameRe.test(pathname)) {
257261
return false;
258262
}
259-
// Allow any query string and hash as long as no invalid character is used.
263+
return true;
260264
} catch (e) {
261265
return false;
262266
}
263-
return true;
264267
}
265268

266269

0 commit comments

Comments
 (0)