diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ef2552999..747c76eb02 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ # Unreleased +- [changed] Updated the Google Cloud Firestore client to v1.0.1. This contains + breaking changes. Refer to Cloud Firestore + [release notes](https://github.com/googleapis/nodejs-firestore/releases/tag/v0.20.0) + for more details and migration instructions. +- [changed] Updated the Google Cloud Storage client to v2.3.0. This contains + breaking changes. Refer to Cloud Storage + [release notes](https://github.com/googleapis/nodejs-storage/releases/tag/v2.0.0) + for more details and migration instructions. +- [changed] `verifyIdToken()` and `verifySessionCookie()` methods now return + `auth/id-token-expired` and `auth/session-cookie-expired` error codes for + expired JWTs. - [fixed] Including additional helpful details in the errors thrown due to credentials-related problems. diff --git a/package-lock.json b/package-lock.json index 2e9a5b4192..9318656611 100644 --- a/package-lock.json +++ b/package-lock.json @@ -67,95 +67,155 @@ } }, "@google-cloud/common": { - "version": "0.17.0", - "resolved": "http://registry.npmjs.org/@google-cloud/common/-/common-0.17.0.tgz", - "integrity": "sha512-HRZLSU762E6HaKoGfJGa8W95yRjb9rY7LePhjaHK9ILAnFacMuUGVamDbTHu1csZomm1g3tZTtXfX/aAhtie/Q==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-0.27.0.tgz", + "integrity": "sha512-lRA3RHjMNQODpobcHLK9qg4ebN+jjUl7y4ZbjHFM+FYzmZLJQL1LFCM0BJ1DAPyD14ScBZ8Zb2I48oOFVxfNvQ==", "optional": true, "requires": { - "array-uniq": "1.0.3", + "@google-cloud/projectify": "0.3.2", + "@google-cloud/promisify": "0.3.1", + "@types/duplexify": "3.6.0", + "@types/request": "2.48.1", "arrify": "1.0.1", - "concat-stream": "1.6.2", - "create-error-class": "3.0.2", "duplexify": "3.6.1", "ent": "2.2.0", "extend": "3.0.2", - "google-auto-auth": "0.10.1", + "google-auth-library": "2.0.1", + "pify": "4.0.1", + "retry-request": "4.0.0" + }, + "dependencies": { + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "optional": true + } + } + }, + "@google-cloud/firestore": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-1.0.1.tgz", + "integrity": "sha512-h8DxYkrP62VZjmwUJWwsm9F+fUagne2ANML9eIOPT3JWBS+41ZBxNgxOjH8hR5Htxz6GD+xsrr0KYxKBd1eepQ==", + "optional": true, + "requires": { + "@google-cloud/projectify": "0.3.2", + "bun": "0.0.12", + "deep-equal": "1.0.1", + "extend": "3.0.2", + "functional-red-black-tree": "1.0.1", + "google-gax": "0.24.0", "is": "3.2.1", - "log-driver": "1.2.7", - "methmeth": "1.1.0", - "modelo": "4.2.3", - "request": "2.88.0", - "retry-request": "3.3.2", - "split-array-stream": "1.0.3", - "stream-events": "1.0.5", - "string-format-obj": "1.1.1", - "through2": "2.0.5" + "lodash.merge": "4.6.1", + "protobufjs": "6.8.8", + "through2": "3.0.0" }, "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + "@grpc/proto-loader": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.4.0.tgz", + "integrity": "sha512-Jm6o+75uWT7E6+lt8edg4J1F/9+BedOjaMgwE14pxS/AO43/0ZqK+rCLVVrXLoExwSAZvgvOD2B0ivy3Spsspw==", + "optional": true, + "requires": { + "lodash.camelcase": "4.3.0", + "protobufjs": "6.8.8" + } }, - "readable-stream": { - "version": "2.3.6", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "gcp-metadata": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-0.9.3.tgz", + "integrity": "sha512-caV4S84xAjENtpezLCT/GILEAF5h/bC4cNqZFmt/tjTn8t+JBtTkQrgBrJu3857YdsnlM8rxX/PMcKGtE8hUlw==", + "optional": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", - "safe-buffer": "5.1.2", - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" + "gaxios": "1.2.6", + "json-bigint": "0.3.0" } }, - "retry-request": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-3.3.2.tgz", - "integrity": "sha512-WIiGp37XXDC6e7ku3LFoi7LCL/Gs9luGeeqvbPRb+Zl6OQMw4RCRfSaW+aLfE6lhz1R941UavE6Svl3Dm5xGIQ==", + "google-auth-library": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-3.0.1.tgz", + "integrity": "sha512-ZGTBMiQga/pwEw26ZKCn+q9PTPXvE4v5sL2V9HV3f2Gt0lrS+2H7XgbVCx850jrvlEL59JIheFiDqEn9CIa0nA==", "optional": true, "requires": { - "request": "2.88.0", - "through2": "2.0.5" + "base64-js": "1.3.0", + "fast-text-encoding": "1.0.0", + "gaxios": "1.2.6", + "gcp-metadata": "0.9.3", + "gtoken": "2.3.2", + "https-proxy-agent": "2.2.1", + "jws": "3.1.5", + "lru-cache": "5.1.1", + "semver": "5.6.0" } }, - "string_decoder": { - "version": "1.1.1", - "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "google-gax": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-0.24.0.tgz", + "integrity": "sha512-x+eeMgHlAFXScvuw3gm0r/DkN8519QtdST8U0KMt934dwfsavF2iFvOhnXaNvEL99CXtDImOON+NqkTfIzq/FQ==", + "optional": true, "requires": { - "safe-buffer": "5.1.2" + "@grpc/grpc-js": "0.3.2", + "@grpc/proto-loader": "0.4.0", + "duplexify": "3.6.1", + "google-auth-library": "3.0.1", + "google-proto-files": "0.18.0", + "grpc": "1.16.1", + "is-stream-ended": "0.1.4", + "lodash.at": "4.6.0", + "lodash.has": "4.5.2", + "protobufjs": "6.8.8", + "retry-request": "4.0.0", + "semver": "5.6.0", + "walkdir": "0.0.12" } }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "gtoken": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-2.3.2.tgz", + "integrity": "sha512-F8EObUGyC8Qd3WXTloNULZBwfUsOABoHElihB1F6zGhT/cy38iPL09wGLRY712I+hQnOyA+sYlgPFX2cOKz0qg==", + "optional": true, "requires": { - "readable-stream": "2.3.6", - "xtend": "4.0.1" + "gaxios": "1.2.6", + "google-p12-pem": "1.0.2", + "jws": "3.1.5", + "mime": "2.4.0", + "pify": "4.0.1" } + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "optional": true, + "requires": { + "yallist": "3.0.3" + } + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "optional": true + }, + "yallist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "optional": true } } }, - "@google-cloud/firestore": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-0.19.0.tgz", - "integrity": "sha512-5WBS4UT3e0pogjiq7Ih/ezBQFqM/eEWQfB0oPiCYl2uzAcMfIvYjQlbxG7QI0fSB93TIA7fa+xCHvRHnIVnF+Q==", + "@google-cloud/paginator": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-0.1.2.tgz", + "integrity": "sha512-XL09cuPSEPyyNifavxWJRYkUFr5zCJ9njcFjqc1AqSQ2QIKycwdTxOP/zHsAWj0xN3rw1ApevA8o+8VAD4R6hw==", "optional": true, "requires": { - "@google-cloud/projectify": "0.3.2", - "bun": "0.0.12", - "deep-equal": "1.0.1", + "arrify": "1.0.1", "extend": "3.0.2", - "functional-red-black-tree": "1.0.1", - "google-gax": "0.22.1", "is": "3.2.1", - "lodash.merge": "4.6.1", - "protobufjs": "6.8.8", - "through2": "3.0.0" + "split-array-stream": "2.0.0", + "stream-events": "1.0.5" } }, "@google-cloud/projectify": { @@ -164,75 +224,37 @@ "integrity": "sha512-t1bs5gE105IpgikX7zPCJZzVyXM5xZ/1kJomUPim2E2pNp4OUUFNyvKm/T2aM6GBP2F30o8abCD+/wbOhHWYYA==", "optional": true }, + "@google-cloud/promisify": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-0.3.1.tgz", + "integrity": "sha512-QzB0/IMvB0eFxFK7Eqh+bfC8NLv3E9ScjWQrPOk6GgfNroxcVITdTlT8NRsRrcp5+QQJVPLkRqKG0PUdaWXmHw==" + }, "@google-cloud/storage": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-1.7.0.tgz", - "integrity": "sha512-QaAxzCkbhspwajoaEnT0GcnQcpjPRcBrHYuQsXtD05BtOJgVnHCLXSsfUiRdU0nVpK+Thp7+sTkQ0fvk5PanKg==", + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-2.3.4.tgz", + "integrity": "sha512-TjEMVxdW1L18yyxvPWEylM1F4ijZ/k4lGKrKro2XNqqOy+fnisc+F2TbpiSJSbdmsMzeCunDkXepdb5AFA62cw==", "optional": true, "requires": { - "@google-cloud/common": "0.17.0", + "@google-cloud/common": "0.27.0", + "@google-cloud/paginator": "0.1.2", + "@google-cloud/promisify": "0.3.1", "arrify": "1.0.1", "async": "2.6.1", "compressible": "2.0.15", "concat-stream": "1.6.2", - "create-error-class": "3.0.2", "duplexify": "3.6.1", "extend": "3.0.2", - "gcs-resumable-upload": "0.10.2", + "gcs-resumable-upload": "0.13.0", "hash-stream-validation": "0.2.1", - "is": "3.2.1", "mime": "2.4.0", "mime-types": "2.1.21", "once": "1.4.0", "pumpify": "1.5.1", - "request": "2.88.0", - "safe-buffer": "5.1.2", "snakeize": "0.1.0", "stream-events": "1.0.5", - "through2": "2.0.5", + "teeny-request": "3.11.3", + "through2": "3.0.0", "xdg-basedir": "3.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "optional": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "optional": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", - "safe-buffer": "5.1.2", - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "optional": true, - "requires": { - "safe-buffer": "5.1.2" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "optional": true, - "requires": { - "readable-stream": "2.3.6", - "xtend": "4.0.1" - } - } } }, "@grpc/grpc-js": { @@ -245,26 +267,6 @@ "semver": "5.6.0" } }, - "@grpc/proto-loader": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.3.0.tgz", - "integrity": "sha512-9b8S/V+3W4Gv7G/JKSZ48zApgyYbfIR7mAC9XNnaSWme3zj57MIESu0ELzm9j5oxNIpFG8DgO00iJMIUZ5luqw==", - "optional": true, - "requires": { - "@types/lodash": "4.14.118", - "@types/node": "9.6.39", - "lodash": "4.17.11", - "protobufjs": "6.8.8" - }, - "dependencies": { - "@types/node": { - "version": "9.6.39", - "resolved": "https://registry.npmjs.org/@types/node/-/node-9.6.39.tgz", - "integrity": "sha512-c3OkjgNpSMdHan56WhklP0FMOk5ocilKz2Mpa0NOGzu8jw5YERjCf9FG0epYB1+TxScv/oI4uJ204u2mUg7Hcw==", - "optional": true - } - } - }, "@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", @@ -370,6 +372,15 @@ "@types/promises-a-plus": "0.0.27" } }, + "@types/duplexify": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@types/duplexify/-/duplexify-3.6.0.tgz", + "integrity": "sha512-5zOA53RUlzN74bvrSGwjudssD9F3a797sDZQkiYpUOxW+WHaXTCPz4/d5Dgi6FKnOqZ2CpaTo0DhgIfsXAOE/A==", + "optional": true, + "requires": { + "@types/node": "8.10.38" + } + }, "@types/firebase-token-generator": { "version": "2.0.28", "resolved": "http://registry.npmjs.org/@types/firebase-token-generator/-/firebase-token-generator-2.0.28.tgz", @@ -384,16 +395,6 @@ "@types/node": "8.10.38" } }, - "@types/google-cloud__storage": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@types/google-cloud__storage/-/google-cloud__storage-1.7.2.tgz", - "integrity": "sha512-RaQJ7+Ht20MRYJu7mgKBpbVNZIPneztKIl/DUKacRC6A8mXRsJfgDdPA7indHmJGIgm+hzUTj44+A3RyuuYZhg==", - "optional": true, - "requires": { - "@types/node": "8.10.38", - "@types/request": "2.48.1" - } - }, "@types/jsonwebtoken": { "version": "7.2.8", "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-7.2.8.tgz", @@ -406,7 +407,8 @@ "@types/lodash": { "version": "4.14.118", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.118.tgz", - "integrity": "sha512-iiJbKLZbhSa6FYRip/9ZDX6HXhayXLDGY2Fqws9cOkEQ6XeKfaxB0sC541mowZJueYyMnVUmmG+al5/4fCDrgw==" + "integrity": "sha512-iiJbKLZbhSa6FYRip/9ZDX6HXhayXLDGY2Fqws9cOkEQ6XeKfaxB0sC541mowZJueYyMnVUmmG+al5/4fCDrgw==", + "dev": true }, "@types/long": { "version": "4.0.0", @@ -500,7 +502,6 @@ "version": "4.2.1", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz", "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==", - "optional": true, "requires": { "es6-promisify": "5.0.0" } @@ -629,7 +630,8 @@ "array-uniq": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=" + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true }, "array-unique": { "version": "0.3.2", @@ -681,6 +683,7 @@ "version": "2.6.1", "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", + "optional": true, "requires": { "lodash": "4.17.11" } @@ -787,6 +790,12 @@ } } }, + "base64-js": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", + "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==", + "optional": true + }, "bcrypt": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-3.0.2.tgz", @@ -1301,6 +1310,12 @@ "integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=", "dev": true }, + "bignumber.js": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-7.2.1.tgz", + "integrity": "sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ==", + "optional": true + }, "binaryextensions": { "version": "1.0.1", "resolved": "http://registry.npmjs.org/binaryextensions/-/binaryextensions-1.0.1.tgz", @@ -1366,7 +1381,8 @@ "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "optional": true }, "builtin-modules": { "version": "1.1.1", @@ -1423,11 +1439,6 @@ "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", "optional": true }, - "capture-stack-trace": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz", - "integrity": "sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw==" - }, "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", @@ -1599,6 +1610,7 @@ "version": "1.6.2", "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "optional": true, "requires": { "buffer-from": "1.1.1", "inherits": "2.0.3", @@ -1609,12 +1621,14 @@ "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "optional": true }, "readable-stream": { "version": "2.3.6", "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "optional": true, "requires": { "core-util-is": "1.0.2", "inherits": "2.0.3", @@ -1629,6 +1643,7 @@ "version": "1.1.1", "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "optional": true, "requires": { "safe-buffer": "5.1.2" } @@ -1653,9 +1668,9 @@ } }, "configstore": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz", - "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-4.0.0.tgz", + "integrity": "sha512-CmquAXFBocrzaSM8mtGPMM/HiWmyIpr4CcJl/rgY2uCObZ/S7cKU0silxslqJejl+t/T9HS8E0PUNQD81JGUEQ==", "optional": true, "requires": { "dot-prop": "4.2.0", @@ -1686,14 +1701,6 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, - "create-error-class": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", - "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", - "requires": { - "capture-stack-trace": "1.0.1" - } - }, "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -2018,14 +2025,12 @@ "es6-promise": { "version": "4.2.5", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.5.tgz", - "integrity": "sha512-n6wvpdE43VFtJq+lUDYDBFUwV8TZbuGXLV4D6wKafg13ldznKsyEvatubnmUe31zcvelSzOHF+XbaT+Bl9ObDg==", - "optional": true + "integrity": "sha512-n6wvpdE43VFtJq+lUDYDBFUwV8TZbuGXLV4D6wKafg13ldznKsyEvatubnmUe31zcvelSzOHF+XbaT+Bl9ObDg==" }, "es6-promisify": { "version": "5.0.0", "resolved": "http://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "optional": true, "requires": { "es6-promise": "4.2.5" } @@ -2275,6 +2280,12 @@ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" }, + "fast-text-encoding": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.0.tgz", + "integrity": "sha512-R9bHCvweUxxwkDwhjav5vxpFvdPGlVngtqmx4pIZfSUhM/Q4NiIUHB456BAf+Q1Nwu3HEZYONtu+Rya+af4jiQ==", + "optional": true + }, "faye-websocket": { "version": "0.11.1", "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.1.tgz", @@ -2426,6 +2437,16 @@ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "optional": true }, + "gaxios": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-1.2.6.tgz", + "integrity": "sha512-A7IVK12d5SavNAGTtL5aBDJ6auqWDCbyMazX+QQIklMdashrIZs4QIm1a6TpenJYy0OskCks2sMqglGt6ZThEQ==", + "requires": { + "extend": "3.0.2", + "https-proxy-agent": "2.2.1", + "node-fetch": "2.3.0" + } + }, "gaze": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/gaze/-/gaze-0.5.2.tgz", @@ -2439,7 +2460,6 @@ "version": "0.7.0", "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-0.7.0.tgz", "integrity": "sha512-ffjC09amcDWjh3VZdkDngIo7WoluyC5Ag9PAYxZbmQLOLNI8lvPtoKTSCyU54j2gwy5roZh6sSMTfkY2ct7K3g==", - "optional": true, "requires": { "axios": "0.18.0", "extend": "3.0.2", @@ -2447,13 +2467,14 @@ } }, "gcs-resumable-upload": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/gcs-resumable-upload/-/gcs-resumable-upload-0.10.2.tgz", - "integrity": "sha1-fymz7iPc7EFwNnwHEUGCScZgVF8=", + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/gcs-resumable-upload/-/gcs-resumable-upload-0.13.0.tgz", + "integrity": "sha512-hrSYPFJWyx8FDLJEK3XeqbNcCjkRqcuKSaUxL1RpwEAWAxtV+AdUH+NX3n7st/U6/JddQkdb1mmWAy3jgRDflw==", "optional": true, "requires": { - "configstore": "3.1.2", - "google-auto-auth": "0.10.1", + "axios": "0.18.0", + "configstore": "4.0.0", + "google-auth-library": "2.0.1", "pumpify": "1.5.1", "request": "2.88.0", "stream-events": "1.0.5" @@ -2721,7 +2742,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-2.0.1.tgz", "integrity": "sha512-CWLKZxqYw4SE+fE3GWbVT9r/10h75w8lB3cdmmLpLtCfccFDcsI84qI5rx7npemlrHtKJh3C2HUz4s6SihCeIQ==", - "optional": true, "requires": { "axios": "0.18.0", "gcp-metadata": "0.7.0", @@ -2733,64 +2753,6 @@ "semver": "5.6.0" } }, - "google-auto-auth": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/google-auto-auth/-/google-auto-auth-0.10.1.tgz", - "integrity": "sha512-iIqSbY7Ypd32mnHGbYctp80vZzXoDlvI9gEfvtl3kmyy5HzOcrZCIGCBdSlIzRsg7nHpQiHE3Zl6Ycur6TSodQ==", - "requires": { - "async": "2.6.1", - "gcp-metadata": "0.6.3", - "google-auth-library": "1.6.1", - "request": "2.88.0" - }, - "dependencies": { - "gcp-metadata": { - "version": "0.6.3", - "resolved": "http://registry.npmjs.org/gcp-metadata/-/gcp-metadata-0.6.3.tgz", - "integrity": "sha512-MSmczZctbz91AxCvqp9GHBoZOSbJKAICV7Ow/AIWSJZRrRchUd5NL1b2P4OfP+4m490BEUPhhARfpHdqCxuCvg==", - "requires": { - "axios": "0.18.0", - "extend": "3.0.2", - "retry-axios": "0.3.2" - } - }, - "google-auth-library": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-1.6.1.tgz", - "integrity": "sha512-jYiWC8NA9n9OtQM7ANn0Tk464do9yhKEtaJ72pKcaBiEwn4LwcGYIYOfwtfsSm3aur/ed3tlSxbmg24IAT6gAg==", - "requires": { - "axios": "0.18.0", - "gcp-metadata": "0.6.3", - "gtoken": "2.3.0", - "jws": "3.1.5", - "lodash.isstring": "4.0.1", - "lru-cache": "4.1.5", - "retry-axios": "0.3.2" - } - } - } - }, - "google-gax": { - "version": "0.22.1", - "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-0.22.1.tgz", - "integrity": "sha512-QLvRQ00f5eLmkVm9c8JwqDSwQ6yEJXdtwCu+Xvk2EMpzzaTPZxgX+TtU1Ljg7AHJclpxChJpNYrCw10aB1IJlQ==", - "optional": true, - "requires": { - "@grpc/grpc-js": "0.3.2", - "@grpc/proto-loader": "0.3.0", - "duplexify": "3.6.1", - "google-auth-library": "2.0.1", - "google-proto-files": "0.18.0", - "grpc": "1.16.1", - "is-stream-ended": "0.1.4", - "lodash.at": "4.6.0", - "lodash.has": "4.5.2", - "protobufjs": "6.8.8", - "retry-request": "4.0.0", - "semver": "5.6.0", - "walkdir": "0.0.12" - } - }, "google-p12-pem": { "version": "1.0.2", "resolved": "http://registry.npmjs.org/google-p12-pem/-/google-p12-pem-1.0.2.tgz", @@ -4062,7 +4024,6 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz", "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==", - "optional": true, "requires": { "agent-base": "4.2.1", "debug": "3.1.0" @@ -4110,7 +4071,8 @@ "is": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/is/-/is-3.2.1.tgz", - "integrity": "sha1-0Kwq1V63sL7JJqUmb2xmKqqD3KU=" + "integrity": "sha1-0Kwq1V63sL7JJqUmb2xmKqqD3KU=", + "optional": true }, "is-absolute": { "version": "1.0.0", @@ -4452,6 +4414,15 @@ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" }, + "json-bigint": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-0.3.0.tgz", + "integrity": "sha1-DM2RLEuCcNBfBW+9E4FLU9OCWx4=", + "optional": true, + "requires": { + "bignumber.js": "7.2.1" + } + }, "json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", @@ -4698,6 +4669,12 @@ "integrity": "sha1-k83OZk8KGZTqM9181A4jr9EbD/g=", "optional": true }, + "lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", + "optional": true + }, "lodash.escape": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz", @@ -4822,12 +4799,6 @@ "lodash.escape": "3.2.0" } }, - "log-driver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", - "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==", - "optional": true - }, "lolex": { "version": "2.7.5", "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.7.5.tgz", @@ -4946,12 +4917,6 @@ "integrity": "sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA==", "dev": true }, - "methmeth": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/methmeth/-/methmeth-1.1.0.tgz", - "integrity": "sha1-6AomYY5S9cQiKGG7dIUQvRDikIk=", - "optional": true - }, "micromatch": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", @@ -5088,12 +5053,6 @@ } } }, - "modelo": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/modelo/-/modelo-4.2.3.tgz", - "integrity": "sha512-9DITV2YEMcw7XojdfvGl3gDD8J9QjZTJ7ZOUuSAkP+F3T6rDbzMJuPktxptsdHYEvZcmXrCD3LMOhdSAEq6zKA==", - "optional": true - }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -5216,6 +5175,11 @@ } } }, + "node-fetch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.3.0.tgz", + "integrity": "sha512-MOd8pV3fxENbryESLgVIeaGKrdl+uaYhCSSVkjeOb/31/njTpcis5aWfdqgNlHIrKOLRbMnfPINPOML2CIFeXA==" + }, "node-forge": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.4.tgz", @@ -8987,12 +8951,11 @@ "dev": true }, "split-array-stream": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/split-array-stream/-/split-array-stream-1.0.3.tgz", - "integrity": "sha1-0rdajl4Ngk1S/eyLgiWDncLjXfo=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/split-array-stream/-/split-array-stream-2.0.0.tgz", + "integrity": "sha512-hmMswlVY91WvGMxs0k8MRgq8zb2mSen4FmDNc5AFiTWtrBpdZN6nwD6kROVe4vNL+ywrvbCKsWVCnEd4riELIg==", "optional": true, "requires": { - "async": "2.6.1", "is-stream-ended": "0.1.4" } }, @@ -9073,12 +9036,6 @@ "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=" }, - "string-format-obj": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string-format-obj/-/string-format-obj-1.1.1.tgz", - "integrity": "sha512-Mm+sROy+pHJmx0P/0Bs1uxIX6UhGJGj6xDGQZ5zh9v/SZRmLGevp+p0VJxV7lirrkAmQ2mvva/gHKpnF/pTb+Q==", - "optional": true - }, "string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", @@ -9161,6 +9118,17 @@ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", "dev": true }, + "teeny-request": { + "version": "3.11.3", + "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-3.11.3.tgz", + "integrity": "sha512-CKncqSF7sH6p4rzCgkb/z/Pcos5efl0DmolzvlqRQUNcpRIruOhY9+T1FsIlyEbfWd7MsFpodROOwHYh2BaXzw==", + "optional": true, + "requires": { + "https-proxy-agent": "2.2.1", + "node-fetch": "2.3.0", + "uuid": "3.3.2" + } + }, "text-encoding": { "version": "0.6.4", "resolved": "http://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", @@ -9513,12 +9481,13 @@ "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "optional": true }, "typescript": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.2.tgz", - "integrity": "sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.2.2.tgz", + "integrity": "sha512-VCj5UiSyHBjwfYacmDuc/NOk4QQixbE+Wn7MFJuS0nRuPQbof132Pw4u53dm264O8LPc2MVsc7RJNml5szurkg==", "dev": true }, "unc-path-regex": { diff --git a/package.json b/package.json index 3613f69d32..760e2587e8 100644 --- a/package.json +++ b/package.json @@ -59,9 +59,8 @@ "node-forge": "0.7.4" }, "optionalDependencies": { - "@google-cloud/firestore": "^0.19.0", - "@google-cloud/storage": "^1.6.0", - "@types/google-cloud__storage": "^1.7.1" + "@google-cloud/firestore": "^1.0.1", + "@google-cloud/storage": "^2.3.0" }, "devDependencies": { "@types/bcrypt": "^2.0.0", @@ -105,6 +104,6 @@ "sinon-chai": "^2.8.0", "ts-node": "^3.3.0", "tslint": "^5.9.0", - "typescript": "^2.7.2" + "typescript": "^3.1.0" } } diff --git a/src/auth/token-verifier.ts b/src/auth/token-verifier.ts index c63e010232..aac7b31b54 100644 --- a/src/auth/token-verifier.ts +++ b/src/auth/token-verifier.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import {AuthClientErrorCode, FirebaseAuthError} from '../utils/error'; +import {AuthClientErrorCode, FirebaseAuthError, ErrorInfo} from '../utils/error'; import * as validator from '../utils/validator'; import * as jwt from 'jsonwebtoken'; @@ -38,7 +38,7 @@ export const ID_TOKEN_INFO: FirebaseTokenInfo = { verifyApiName: 'verifyIdToken()', jwtName: 'Firebase ID token', shortName: 'ID token', - expiredErrorCode: 'auth/id-token-expired', + expiredErrorCode: AuthClientErrorCode.ID_TOKEN_EXPIRED, }; /** User facing token information related to the Firebase session cookie. */ @@ -47,7 +47,7 @@ export const SESSION_COOKIE_INFO: FirebaseTokenInfo = { verifyApiName: 'verifySessionCookie()', jwtName: 'Firebase session cookie', shortName: 'session cookie', - expiredErrorCode: 'auth/session-cookie-expired', + expiredErrorCode: AuthClientErrorCode.SESSION_COOKIE_EXPIRED, }; /** Interface that defines token related user facing information. */ @@ -61,7 +61,7 @@ export interface FirebaseTokenInfo { /** The JWT short name. */ shortName: string; /** JWT Expiration error code. */ - expiredErrorCode: string; + expiredErrorCode: ErrorInfo; } /** @@ -115,10 +115,10 @@ export class FirebaseTokenVerifier { AuthClientErrorCode.INVALID_ARGUMENT, `The JWT public short name must be a non-empty string.`, ); - } else if (!validator.isNonEmptyString(tokenInfo.expiredErrorCode)) { + } else if (!validator.isNonNullObject(tokenInfo.expiredErrorCode) || !('code' in tokenInfo.expiredErrorCode)) { throw new FirebaseAuthError( AuthClientErrorCode.INVALID_ARGUMENT, - `The JWT expiration error code must be a non-empty string.`, + `The JWT expiration error code must be a non-null ErrorInfo object.`, ); } this.shortNameArticle = tokenInfo.shortName.charAt(0).match(/[aeiou]/i) ? 'an' : 'a'; @@ -228,22 +228,23 @@ export class FirebaseTokenVerifier { * verification. */ private verifyJwtSignatureWithKey(jwtToken: string, publicKey: string): Promise { - let errorMessage: string; const verifyJwtTokenDocsMessage = ` See ${this.tokenInfo.url} ` + `for details on how to retrieve ${this.shortNameArticle} ${this.tokenInfo.shortName}.`; return new Promise((resolve, reject) => { jwt.verify(jwtToken, publicKey, { algorithms: [this.algorithm], - }, (error: any, decodedToken: any) => { + }, (error: jwt.VerifyErrors, decodedToken: any) => { if (error) { if (error.name === 'TokenExpiredError') { - errorMessage = `${this.tokenInfo.jwtName} has expired. Get a fresh token from your client ` + - `app and try again (${this.tokenInfo.expiredErrorCode}).` + verifyJwtTokenDocsMessage; + const errorMessage = `${this.tokenInfo.jwtName} has expired. Get a fresh ${this.tokenInfo.shortName}` + + ` from your client app and try again (auth/${this.tokenInfo.expiredErrorCode.code}).` + + verifyJwtTokenDocsMessage; + return reject(new FirebaseAuthError(this.tokenInfo.expiredErrorCode, errorMessage)); } else if (error.name === 'JsonWebTokenError') { - errorMessage = `${this.tokenInfo.jwtName} has invalid signature.` + verifyJwtTokenDocsMessage; + const errorMessage = `${this.tokenInfo.jwtName} has invalid signature.` + verifyJwtTokenDocsMessage; + return reject(new FirebaseAuthError(AuthClientErrorCode.INVALID_ARGUMENT, errorMessage)); } - - return reject(new FirebaseAuthError(AuthClientErrorCode.INVALID_ARGUMENT, errorMessage)); + return reject(new FirebaseAuthError(AuthClientErrorCode.INVALID_ARGUMENT, error.message)); } else { decodedToken.uid = decodedToken.sub; resolve(decodedToken); diff --git a/src/storage/storage.ts b/src/storage/storage.ts index 7c853d91c7..d54bdb2331 100644 --- a/src/storage/storage.ts +++ b/src/storage/storage.ts @@ -18,7 +18,7 @@ import {FirebaseApp} from '../firebase-app'; import {FirebaseError} from '../utils/error'; import {FirebaseServiceInterface, FirebaseServiceInternalsInterface} from '../firebase-service'; import {ApplicationDefaultCredential, Certificate} from '../auth/credential'; -import * as gcs from '@google-cloud/storage'; +import {Bucket, Storage as StorageClient} from '@google-cloud/storage'; import * as validator from '../utils/validator'; @@ -44,7 +44,7 @@ export class Storage implements FirebaseServiceInterface { public readonly INTERNAL: StorageInternals = new StorageInternals(); private readonly appInternal: FirebaseApp; - private readonly storageClient: gcs; + private readonly storageClient: StorageClient; /** * @param {FirebaseApp} app The app for this Storage service. @@ -58,9 +58,9 @@ export class Storage implements FirebaseServiceInterface { }); } - let storage: typeof gcs; + let storage: typeof StorageClient; try { - storage = require('@google-cloud/storage'); + storage = require('@google-cloud/storage').Storage; } catch (err) { throw new FirebaseError({ code: 'storage/missing-dependencies', @@ -103,7 +103,7 @@ export class Storage implements FirebaseServiceInterface { * retrieves a reference to the default bucket. * @return {Bucket} A Bucket object from the @google-cloud/storage library. */ - public bucket(name?: string): gcs.Bucket { + public bucket(name?: string): Bucket { const bucketName = (typeof name !== 'undefined') ? name : this.appInternal.options.storageBucket; if (validator.isNonEmptyString(bucketName)) { diff --git a/src/utils/error.ts b/src/utils/error.ts index e149faa13b..e812cd3a2a 100644 --- a/src/utils/error.ts +++ b/src/utils/error.ts @@ -542,6 +542,10 @@ export class AuthClientErrorCode { 'https://firebase.google.com/docs/admin/setup for details on how to authenticate this SDK ' + 'with appropriate permissions.', }; + public static SESSION_COOKIE_EXPIRED = { + code: 'session-cookie-expired', + message: 'The Firebase session cookie is expired.', + }; public static SESSION_COOKIE_REVOKED = { code: 'session-cookie-revoked', message: 'The Firebase session cookie has been revoked.', diff --git a/test/integration/firestore.spec.ts b/test/integration/firestore.spec.ts index 021643684e..62a62dd4cd 100644 --- a/test/integration/firestore.spec.ts +++ b/test/integration/firestore.spec.ts @@ -35,7 +35,6 @@ describe('admin.firestore', () => { before(() => { const db = admin.firestore(); - db.settings({timestampsInSnapshots: true}); reference = db.collection('cities').doc(); }); diff --git a/test/unit/auth/token-verifier.spec.ts b/test/unit/auth/token-verifier.spec.ts index 573fd18e59..a7f09634f4 100644 --- a/test/unit/auth/token-verifier.spec.ts +++ b/test/unit/auth/token-verifier.spec.ts @@ -32,6 +32,7 @@ import {FirebaseTokenGenerator, ServiceAccountSigner} from '../../../src/auth/to import * as verifier from '../../../src/auth/token-verifier'; import {Certificate} from '../../../src/auth/credential'; +import { AuthClientErrorCode } from '../../../src/utils/error'; chai.should(); chai.use(sinonChai); @@ -39,20 +40,21 @@ chai.use(chaiAsPromised); const expect = chai.expect; - const ONE_HOUR_IN_SECONDS = 60 * 60; - +const idTokenPublicCertPath = '/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com'; /** * Returns a mocked out success response from the URL containing the public keys for the Google certs. * + * @param {string=} path URL path to which the mock request should be made. If not specified, defaults + * to the URL path of ID token public key certificates. * @return {Object} A nock response object. */ -function mockFetchPublicKeys(): nock.Scope { +function mockFetchPublicKeys(path: string = idTokenPublicCertPath): nock.Scope { const mockedResponse: {[key: string]: string} = {}; mockedResponse[mocks.certificateObject.private_key_id] = mocks.keyPairs[0].public; return nock('https://www.googleapis.com') - .get('/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com') + .get(path) .reply(200, mockedResponse, { 'cache-control': 'public, max-age=1, must-revalidate, no-transform', }); @@ -146,7 +148,7 @@ describe('FirebaseTokenVerifier', () => { verifyApiName: 'verifyToken()', jwtName: 'Important Token', shortName: 'token', - expiredErrorCode: 'auth/important-token-expired', + expiredErrorCode: AuthClientErrorCode.INVALID_ARGUMENT, }, ); }).not.to.throw(); @@ -208,7 +210,7 @@ describe('FirebaseTokenVerifier', () => { verifyApiName: invalidVerifyApiName as any, jwtName: 'Important Token', shortName: 'token', - expiredErrorCode: 'auth/important-token-expired', + expiredErrorCode: AuthClientErrorCode.INVALID_ARGUMENT, }); }).to.throw('The JWT verify API name must be a non-empty string.'); }); @@ -228,7 +230,7 @@ describe('FirebaseTokenVerifier', () => { verifyApiName: 'verifyToken()', jwtName: invalidJwtName as any, shortName: 'token', - expiredErrorCode: 'auth/important-token-expired', + expiredErrorCode: AuthClientErrorCode.INVALID_ARGUMENT, }); }).to.throw('The JWT public full name must be a non-empty string.'); }); @@ -248,13 +250,13 @@ describe('FirebaseTokenVerifier', () => { verifyApiName: 'verifyToken()', jwtName: 'Important Token', shortName: invalidShortName as any, - expiredErrorCode: 'auth/important-token-expired', + expiredErrorCode: AuthClientErrorCode.INVALID_ARGUMENT, }); }).to.throw('The JWT public short name must be a non-empty string.'); }); }); - const invalidExpiredErrorCodes = [null, NaN, 0, 1, true, false, [], {}, { a: 1 }, _.noop, '']; + const invalidExpiredErrorCodes = [null, NaN, 0, 1, true, false, [], {}, { a: 1 }, _.noop, '', 'test']; invalidExpiredErrorCodes.forEach((invalidExpiredErrorCode) => { it('should throw given an invalid expiration error code: ' + JSON.stringify(invalidExpiredErrorCode), () => { expect(() => { @@ -270,7 +272,7 @@ describe('FirebaseTokenVerifier', () => { shortName: 'token', expiredErrorCode: invalidExpiredErrorCode as any, }); - }).to.throw('The JWT expiration error code must be a non-empty string.'); + }).to.throw('The JWT expiration error code must be a non-null ErrorInfo object.'); }); }); }); @@ -410,8 +412,37 @@ describe('FirebaseTokenVerifier', () => { // Token should now be invalid return tokenVerifier.verifyJWT(mockIdToken) - .should.eventually.be.rejectedWith('Firebase ID token has expired. Get a fresh token from your client ' + - 'app and try again (auth/id-token-expired)'); + .should.eventually.be.rejectedWith('Firebase ID token has expired. Get a fresh ID token from your client ' + + 'app and try again (auth/id-token-expired)') + .and.have.property('code', 'auth/id-token-expired'); + }); + }); + + it('should be rejected given an expired Firebase session cookie', () => { + const tokenVerifierSessionCookie = new verifier.FirebaseTokenVerifier( + 'https://www.googleapis.com/identitytoolkit/v3/relyingparty/publicKeys', + 'RS256', + 'https://session.firebase.google.com/', + 'project_id', + verifier.SESSION_COOKIE_INFO, + ); + mockedRequests.push(mockFetchPublicKeys('/identitytoolkit/v3/relyingparty/publicKeys')); + + clock = sinon.useFakeTimers(1000); + + const mockSessionCookie = mocks.generateSessionCookie(); + + clock.tick((ONE_HOUR_IN_SECONDS * 1000) - 1); + + // Cookie should still be valid + return tokenVerifierSessionCookie.verifyJWT(mockSessionCookie).then(() => { + clock.tick(1); + + // Cookie should now be invalid + return tokenVerifierSessionCookie.verifyJWT(mockSessionCookie) + .should.eventually.be.rejectedWith('Firebase session cookie has expired. Get a fresh session cookie from ' + + 'your client app and try again (auth/session-cookie-expired).') + .and.have.property('code', 'auth/session-cookie-expired'); }); });