diff --git a/Node/quickstarts/firestore-sync-auth/.gitignore b/Node/quickstarts/firestore-sync-auth/.gitignore new file mode 100644 index 000000000..f62685251 --- /dev/null +++ b/Node/quickstarts/firestore-sync-auth/.gitignore @@ -0,0 +1,65 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +firebase-debug.log* + +# Firebase cache +.firebase/ + +# Firebase config + +# Uncomment this if you'd like others to create their own Firebase project. +# For a team working on the same Firebase project(s), it is recommended to leave +# it commented so all members can deploy to the same project(s) in .firebaserc. +# .firebaserc + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env diff --git a/Node/quickstarts/firestore-sync-auth/README.md b/Node/quickstarts/firestore-sync-auth/README.md new file mode 100644 index 000000000..b336945fa --- /dev/null +++ b/Node/quickstarts/firestore-sync-auth/README.md @@ -0,0 +1,70 @@ +# Firebase SDK for Cloud Functions Quickstart - Firestore with auth context + +This quickstart demonstrates using the **Firebase SDK for Cloud Functions** with +**Firestore** with authentication context. + +## Introduction + +This sample app adds auth metadata to all documents written to a collection. + +## Set up the sample + +Before you can test the functions locally or deploy to a Firebase project, +you'll need to run `npm install` in the `functions` directory. + +## Run locally with the Firebase Emulator suite + +The +[Firebase Local Emulator Suite](https://firebase.google.com/docs/emulator-suite) +allows you to build and test apps on your local machine instead of deploying to +a Firebase project. + +1. Create a Firebase project in the + [Firebase Console](https://console.firebase.google.com) + > _Wondering why this step is needed?_ Even though the emulator will run this + > sample on your local machine, it needs to interact with a Firebase project + > to retrieve some configuration values. +1. [Set up or update the Firebase CLI](https://firebase.google.com/docs/cli#setup_update_cli) +1. Run `firebase emulators:start` +1. Open the Emulator Suite UI + 1. Look in the output of the `firebase emulators:start` command for the URL + of the Emulator Suite UI. It defaults to + [localhost:4000](http://localhost:4000), but may be hosted on a different + port on your machine. + 1. Enter that URL in your browser to open the UI. +1. Trigger the functions + 1. Look in the output of the `firebase emulators:start` command for the URL + of the http function "verifyComment". It will look similar to: + `http://localhost:5001/MY_PROJECT/us-central1/verifyComment` + 1. `MY_PROJECT` will be replaced with your project ID + 1. The port may be different on your local machine + 1. Create a new document in the `comments` collection in Firestore in the emulator UI. +1. View the effects of the functions in the Emulator Suite UI + + 1. In the "Logs" tab, you should see new logs indicating that the functions + "verifyComment" and "makeuppercase" ran: + + > `functions: Beginning execution of "verifyComment"` + + 1. In the "Firestore" tab, you should see the document containing your original + message updated to include auth context. + +## Deploy and test on a live Firebase project + +To deploy and test the sample: + +1. Create a Firebase project on the + [Firebase Console](https://console.firebase.google.com) +1. Deploy your project's code using `firebase deploy` +1. Create a new document in the `comments` collection in Firestore in the Firebase console. + +You should see the document containing your original message updated to include auth context. + +## Contributing + +We'd love that you contribute to the project. Before doing so please read our +[Contributor guide](../../CONTRIBUTING.md). + +## License + +© Google, 2023. Licensed under an [Apache-2](../../LICENSE) license. diff --git a/Node/quickstarts/firestore-sync-auth/firebase.json b/Node/quickstarts/firestore-sync-auth/firebase.json new file mode 100644 index 000000000..4a49197d7 --- /dev/null +++ b/Node/quickstarts/firestore-sync-auth/firebase.json @@ -0,0 +1,20 @@ +{ + "functions": { + "codebase": "firestore-sync-auth" + }, + "firestore": { + "rules": "firestore.rules", + "indexes": "firestore.indexes.json" + }, + "emulators": { + "functions": { + "port": 5001 + }, + "firestore": { + "port": 8080 + }, + "ui": { + "enabled": true + } + } +} diff --git a/Node/quickstarts/firestore-sync-auth/firestore.indexes.json b/Node/quickstarts/firestore-sync-auth/firestore.indexes.json new file mode 100644 index 000000000..415027e5d --- /dev/null +++ b/Node/quickstarts/firestore-sync-auth/firestore.indexes.json @@ -0,0 +1,4 @@ +{ + "indexes": [], + "fieldOverrides": [] +} diff --git a/Node/quickstarts/firestore-sync-auth/firestore.rules b/Node/quickstarts/firestore-sync-auth/firestore.rules new file mode 100644 index 000000000..8d3e84cd6 --- /dev/null +++ b/Node/quickstarts/firestore-sync-auth/firestore.rules @@ -0,0 +1,8 @@ +service cloud.firestore { + match /databases/{database}/documents { + match /comments/{comment} { + // Allow authenticated users to read/write the comments collection + allow read, write: if request.auth != null; + } + } +} diff --git a/Node/quickstarts/firestore-sync-auth/functions/.eslintrc.js b/Node/quickstarts/firestore-sync-auth/functions/.eslintrc.js new file mode 100644 index 000000000..14cf70935 --- /dev/null +++ b/Node/quickstarts/firestore-sync-auth/functions/.eslintrc.js @@ -0,0 +1,30 @@ +/** + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +module.exports = { + root: true, + env: { + es2020: true, + node: true, + }, + extends: [ + "eslint:recommended", + "google", + ], + rules: { + quotes: ["error", "double"], + }, +}; diff --git a/Node/quickstarts/firestore-sync-auth/functions/.gitignore b/Node/quickstarts/firestore-sync-auth/functions/.gitignore new file mode 100644 index 000000000..40b878db5 --- /dev/null +++ b/Node/quickstarts/firestore-sync-auth/functions/.gitignore @@ -0,0 +1 @@ +node_modules/ \ No newline at end of file diff --git a/Node/quickstarts/firestore-sync-auth/functions/index.js b/Node/quickstarts/firestore-sync-auth/functions/index.js new file mode 100644 index 000000000..50096532d --- /dev/null +++ b/Node/quickstarts/firestore-sync-auth/functions/index.js @@ -0,0 +1,60 @@ +/** + * Copyright 2023 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +"use strict"; + +// [START all] +// [START import] +// The Cloud Functions for Firebase SDK to create Cloud Functions and triggers. +const { + onDocumentWrittenWithAuthContext, +} = require("firebase-functions/v2/firestore"); +const {logger} = require("firebase-functions"); + +exports.verifyComment = onDocumentWrittenWithAuthContext( + "comments/{commentId}", + (event) => { + const snapshot = event.data.after; + if (!snapshot) { + logger.log("No data associated with the event"); + return; + } + + // retrieve auth context from event + const {authType, authId} = event; + + let verified = false; + if (authType === "system") { + // system-generated users are automatically verified + verified = true; + } else if (authType === "unknown" || authType === "unauthenticated") { + // admin users from a specific domain are verified + if (authId.endsWith("@example.com")) { + verified = true; + } + } + + // add auth medadata to the document + return snapshot.ref.set( + { + created_by: authId ?? "undefined", + verified, + }, + {merge: true}, + ); + }, +); + +// [END all] diff --git a/Node/quickstarts/firestore-sync-auth/functions/package.json b/Node/quickstarts/firestore-sync-auth/functions/package.json new file mode 100644 index 000000000..9f6fd5f95 --- /dev/null +++ b/Node/quickstarts/firestore-sync-auth/functions/package.json @@ -0,0 +1,28 @@ +{ + "name": "firestore-sync-auth", + "description": "Cloud Functions for Firebase", + "dependencies": { + "firebase-admin": "^11.9.0", + "firebase-functions": "^4.9.0" + }, + "devDependencies": { + "chai": "^4.3.6", + "chai-as-promised": "^7.1.1", + "eslint": "^8.40.0", + "mocha": "^7.2.0", + "sinon": "^9.2.4" + }, + "scripts": { + "lint": "./node_modules/.bin/eslint --max-warnings=0 .", + "serve": "firebase emulators:start --only functions", + "shell": "firebase functions:shell", + "start": "npm run shell", + "deploy": "firebase deploy --only functions", + "logs": "firebase functions:log", + "compile": "cp ../../../../tsconfig.template.json ./tsconfig-compile.json && tsc --project tsconfig-compile.json" + }, + "engines": { + "node": "18" + }, + "private": true +} diff --git a/Python/quickstarts/firestore-sync-auth/README.md b/Python/quickstarts/firestore-sync-auth/README.md new file mode 100644 index 000000000..7a15ada12 --- /dev/null +++ b/Python/quickstarts/firestore-sync-auth/README.md @@ -0,0 +1 @@ +# uppercase-firestore diff --git a/Python/quickstarts/firestore-sync-auth/firebase.json b/Python/quickstarts/firestore-sync-auth/firebase.json new file mode 100644 index 000000000..9c2f9a51e --- /dev/null +++ b/Python/quickstarts/firestore-sync-auth/firebase.json @@ -0,0 +1,5 @@ +{ + "functions": { + "codebase": "firestore-sync-auth" + } +} diff --git a/Python/quickstarts/firestore-sync-auth/functions/main.py b/Python/quickstarts/firestore-sync-auth/functions/main.py new file mode 100644 index 000000000..c897f63a3 --- /dev/null +++ b/Python/quickstarts/firestore-sync-auth/functions/main.py @@ -0,0 +1,43 @@ +# Copyright 2023 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# [START all] +from firebase_functions import firestore_fn + + +# [START verifyComment] +@firestore_fn.on_document_updated_with_auth_context(document="comments/{comment_id}") +def verify_comment(event: Event[Change[DocumentSnapshot]]) -> None: + + # Get the current and previous document values. + new_value = event.data.after + prev_value = event.data.before + + # Get the auth context from the event + user_auth_type = event.auth_type + user_auth_id = event.auth_id + + verified = False + if user_auth_type == "system": + # system-generated users are automatically verified + verified = True + elif user_auth_type in ("unknown", "unauthenticated"): + if user_auth_id.endswith("@example.com"): + # admin users from a specific domain are verified + verified = True + + # add auth medadata to the document + new_value.reference.update({"created_by": user_auth_id, "verified": verified}) +# [END verifyComment] +# [END all] diff --git a/Python/quickstarts/firestore-sync-auth/functions/requirements.txt b/Python/quickstarts/firestore-sync-auth/functions/requirements.txt new file mode 100644 index 000000000..7c976ce4c --- /dev/null +++ b/Python/quickstarts/firestore-sync-auth/functions/requirements.txt @@ -0,0 +1,2 @@ +firebase-functions +firebase-admin diff --git a/package-lock.json b/package-lock.json index 1800f73f5..14ad13303 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "1.0.0", "license": "Apache-2.0", "devDependencies": { - "eslint": "^8.40.0", + "eslint": "^8.44.0", "pnpm": "^8.2.0", "typescript": "^5.0.4" }, @@ -17,6 +17,15 @@ "node": "18" } }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -33,23 +42,23 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz", - "integrity": "sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", "dev": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/eslintrc": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz", - "integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.5.2", + "espree": "^9.6.0", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -65,22 +74,22 @@ } }, "node_modules/@eslint/js": { - "version": "8.40.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.40.0.tgz", - "integrity": "sha512-ElyB54bJIhXQYVKjDSvCkPO1iU1tSAeVQJbllWJq1XQSmmA4dgFk8CbiBGpiOPxleE48vDogxCtmMYku4HSVLA==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.8", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", - "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", "dev": true, "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", "minimatch": "^3.0.5" }, "engines": { @@ -101,9 +110,9 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", "dev": true }, "node_modules/@nodelib/fs.scandir": { @@ -141,10 +150,16 @@ "node": ">= 8" } }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, "node_modules/acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -335,27 +350,28 @@ } }, "node_modules/eslint": { - "version": "8.40.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.40.0.tgz", - "integrity": "sha512-bvR+TsP9EHL3TqNtj9sCNJVAFK3fBN8Q7g5waghxyRsPLIMwL73XSKnZFK0hk/O2ANC+iAoq6PWMQ+IfBAJIiQ==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.0.3", - "@eslint/js": "8.40.0", - "@humanwhocodes/config-array": "^0.11.8", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.0", - "eslint-visitor-keys": "^3.4.1", - "espree": "^9.5.2", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -363,22 +379,19 @@ "find-up": "^5.0.0", "glob-parent": "^6.0.2", "globals": "^13.19.0", - "grapheme-splitter": "^1.0.4", + "graphemer": "^1.4.0", "ignore": "^5.2.0", - "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", - "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.1", + "optionator": "^0.9.3", "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" }, "bin": { @@ -392,9 +405,9 @@ } }, "node_modules/eslint-scope": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", - "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "dependencies": { "esrecurse": "^4.3.0", @@ -408,9 +421,9 @@ } }, "node_modules/eslint-visitor-keys": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", - "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -420,12 +433,12 @@ } }, "node_modules/espree": { - "version": "9.5.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz", - "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, "dependencies": { - "acorn": "^8.8.0", + "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.4.1" }, @@ -591,9 +604,9 @@ } }, "node_modules/globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -605,10 +618,10 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, "node_modules/has-flag": { @@ -621,9 +634,9 @@ } }, "node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "dev": true, "engines": { "node": ">= 4" @@ -706,16 +719,6 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, - "node_modules/js-sdsl": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz", - "integrity": "sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg==", - "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/js-sdsl" - } - }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -808,17 +811,17 @@ } }, "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "type-check": "^0.4.0" }, "engines": { "node": ">= 0.8.0" @@ -919,9 +922,9 @@ } }, "node_modules/punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, "engines": { "node": ">=6" @@ -1128,15 +1131,6 @@ "node": ">= 8" } }, - "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 954a96aa4..f84cadcd8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,9 +1,5 @@ lockfileVersion: '6.0' -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - importers: .: @@ -1216,6 +1212,31 @@ importers: specifier: ^0.14.0 version: 0.14.0(eslint@8.44.0) + Node/quickstarts/firestore-sync-auth/functions: + dependencies: + firebase-admin: + specifier: ^11.9.0 + version: 11.9.0 + firebase-functions: + specifier: ^4.9.0 + version: 4.9.0(firebase-admin@11.9.0) + devDependencies: + chai: + specifier: ^4.3.6 + version: 4.3.6 + chai-as-promised: + specifier: ^7.1.1 + version: 7.1.1(chai@4.3.6) + eslint: + specifier: ^8.40.0 + version: 8.44.0 + mocha: + specifier: ^7.2.0 + version: 7.2.0 + sinon: + specifier: ^9.2.4 + version: 9.2.4 + Node/quickstarts/https-time-server/functions: dependencies: firebase-admin: @@ -3272,7 +3293,7 @@ packages: /@types/cors@2.8.13: resolution: {integrity: sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==} dependencies: - '@types/node': 20.4.0 + '@types/node': 17.0.45 /@types/debug@0.0.30: resolution: {integrity: sha512-orGL5LXERPYsLov6CWs3Fh6203+dXzJkR7OnddIr2514Hsecwc8xRpzCapshBbKFImCsvS/mk6+FWiN5LyZJAQ==} @@ -3285,14 +3306,6 @@ packages: '@types/express-unless': 2.0.1 dev: false - /@types/express-serve-static-core@4.17.34: - resolution: {integrity: sha512-fvr49XlCGoUj2Pp730AItckfjat4WNb0lb3kfrLWffd+RLeoGAMsq7UOy04PAPtoL01uKwcp6u8nhzpgpDYr3w==} - dependencies: - '@types/node': 17.0.45 - '@types/qs': 6.9.7 - '@types/range-parser': 1.2.4 - '@types/send': 0.17.1 - /@types/express-serve-static-core@4.17.35: resolution: {integrity: sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg==} dependencies: @@ -3312,9 +3325,9 @@ packages: resolution: {integrity: sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==} dependencies: '@types/body-parser': 1.19.2 - '@types/express-serve-static-core': 4.17.34 + '@types/express-serve-static-core': 4.17.35 '@types/qs': 6.9.7 - '@types/serve-static': 1.15.1 + '@types/serve-static': 1.15.2 /@types/express@4.17.3: resolution: {integrity: sha512-I8cGRJj3pyOLs/HndoP+25vOqhqWkAZsWMEmq1qXy/b/M3ppufecUwaK2/TVDVxcV61/iSdhykUjQQ2DLSrTdg==} @@ -3451,9 +3464,6 @@ packages: /@types/node@17.0.45: resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==} - /@types/node@20.4.0: - resolution: {integrity: sha512-jfT7iTf/4kOQ9S7CHV9BIyRaQqHu67mOjsIQBC3BKZvzvUB6zLxEwJ6sBE3ozcvP8kF6Uk5PXN0Q+c0dfhGX0g==} - /@types/prettier@2.7.3: resolution: {integrity: sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==} dev: true @@ -3488,12 +3498,6 @@ packages: '@types/mime': 1.3.2 '@types/node': 17.0.45 - /@types/serve-static@1.15.1: - resolution: {integrity: sha512-NUo5XNiAdULrJENtJXZZ3fHtfMolzZwczzBbnAeBbqBwG+LaG6YaJtuwzwGSQZ2wsCrxjEhNNjAkKigy3n8teQ==} - dependencies: - '@types/mime': 3.0.1 - '@types/node': 17.0.45 - /@types/serve-static@1.15.2: resolution: {integrity: sha512-J2LqtvFYCzaj8pVYKw8klQXrLLk7TBZmQ4ShlcdkELFKGwGMfevMLneMMRkMgZxotOD9wg497LpC7O8PcvAmfw==} dependencies: @@ -5554,7 +5558,7 @@ packages: '@fastify/busboy': 1.2.1 '@firebase/database-compat': 0.3.4 '@firebase/database-types': 0.10.4 - '@types/node': 20.4.0 + '@types/node': 17.0.45 jsonwebtoken: 9.0.1 jwks-rsa: 3.0.1 node-forge: 1.3.1 @@ -5600,6 +5604,23 @@ packages: - encoding - supports-color + /firebase-functions@4.9.0(firebase-admin@11.9.0): + resolution: {integrity: sha512-IqxOEsVAWGcRv9KRGzWQR5mOFuNsil3vsfkRPPiaV1U/ATC27/jbahh4z8I4rW8Xqa6cQE5xqnw0ueyMH7i7Ag==} + engines: {node: '>=14.10.0'} + hasBin: true + peerDependencies: + firebase-admin: ^10.0.0 || ^11.0.0 || ^12.0.0 + dependencies: + '@types/cors': 2.8.13 + '@types/express': 4.17.3 + cors: 2.8.5 + express: 4.18.2 + firebase-admin: 11.9.0 + protobufjs: 7.2.4 + transitivePeerDependencies: + - supports-color + dev: false + /flat-cache@3.0.4: resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==} engines: {node: ^10.12.0 || >=12.0.0} @@ -6340,7 +6361,7 @@ packages: extend: 3.0.2 gaxios: 2.3.4 google-auth-library: 5.10.1 - qs: 6.11.1 + qs: 6.11.2 url-template: 2.0.8 uuid: 7.0.3 transitivePeerDependencies: @@ -8810,7 +8831,7 @@ packages: '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.0 '@types/long': 4.0.2 - '@types/node': 20.4.0 + '@types/node': 17.0.45 long: 4.0.0 dev: false @@ -8848,7 +8869,7 @@ packages: '@protobufjs/path': 1.1.2 '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.0 - '@types/node': 20.4.0 + '@types/node': 17.0.45 long: 5.2.3 /proxy-addr@2.0.7: @@ -9389,6 +9410,7 @@ packages: /sinon@9.2.4: resolution: {integrity: sha512-zljcULZQsJxVra28qIAL6ow1Z9tpattkCTEJR4RBP3TGc00FcttsP5pK284Nas5WjMZU5Yzy3kAIp3B3KRf5Yg==} + deprecated: 16.1.1 dependencies: '@sinonjs/commons': 1.8.6 '@sinonjs/fake-timers': 6.0.1 @@ -10369,3 +10391,7 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} requiresBuild: true + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false