firebase-admin 10.3.0 → 11.0.0
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/README.md +1 -2
- package/lib/app/core.d.ts +1 -1
- package/lib/app/core.js +1 -1
- package/lib/app/credential-factory.d.ts +1 -1
- package/lib/app/credential-factory.js +8 -8
- package/lib/app/credential-internal.d.ts +1 -1
- package/lib/app/credential-internal.js +97 -106
- package/lib/app/credential.d.ts +1 -1
- package/lib/app/credential.js +1 -1
- package/lib/app/firebase-app.d.ts +1 -1
- package/lib/app/firebase-app.js +76 -91
- package/lib/app/firebase-namespace.d.ts +1 -1
- package/lib/app/firebase-namespace.js +209 -279
- package/lib/app/index.d.ts +1 -1
- package/lib/app/index.js +4 -4
- package/lib/app/lifecycle.d.ts +1 -1
- package/lib/app/lifecycle.js +37 -43
- package/lib/app-check/app-check-api-client-internal.d.ts +1 -1
- package/lib/app-check/app-check-api-client-internal.js +54 -73
- package/lib/app-check/app-check-api.d.ts +1 -1
- package/lib/app-check/app-check-api.js +1 -1
- package/lib/app-check/app-check-namespace.d.ts +1 -1
- package/lib/app-check/app-check-namespace.js +1 -1
- package/lib/app-check/app-check.d.ts +1 -1
- package/lib/app-check/app-check.js +17 -19
- package/lib/app-check/index.d.ts +1 -1
- package/lib/app-check/index.js +7 -7
- package/lib/app-check/token-generator.d.ts +1 -1
- package/lib/app-check/token-generator.js +47 -52
- package/lib/app-check/token-verifier.d.ts +1 -1
- package/lib/app-check/token-verifier.js +46 -50
- package/lib/auth/action-code-settings-builder.d.ts +1 -1
- package/lib/auth/action-code-settings-builder.js +10 -11
- package/lib/auth/auth-api-request.d.ts +1 -1
- package/lib/auth/auth-api-request.js +346 -393
- package/lib/auth/auth-config.d.ts +1 -1
- package/lib/auth/auth-config.js +95 -106
- package/lib/auth/auth-namespace.d.ts +1 -1
- package/lib/auth/auth-namespace.js +1 -1
- package/lib/auth/auth.d.ts +1 -1
- package/lib/auth/auth.js +20 -40
- package/lib/auth/base-auth.d.ts +1 -1
- package/lib/auth/base-auth.js +137 -144
- package/lib/auth/identifier.d.ts +1 -1
- package/lib/auth/identifier.js +2 -2
- package/lib/auth/index.d.ts +1 -1
- package/lib/auth/index.js +7 -7
- package/lib/auth/tenant-manager.d.ts +1 -1
- package/lib/auth/tenant-manager.js +49 -71
- package/lib/auth/tenant.d.ts +1 -1
- package/lib/auth/tenant.js +44 -55
- package/lib/auth/token-generator.d.ts +1 -1
- package/lib/auth/token-generator.js +49 -53
- package/lib/auth/token-verifier.d.ts +1 -1
- package/lib/auth/token-verifier.js +83 -91
- package/lib/auth/user-import-builder.d.ts +1 -1
- package/lib/auth/user-import-builder.js +70 -73
- package/lib/auth/user-record.d.ts +1 -1
- package/lib/auth/user-record.js +61 -84
- package/lib/credential/index.d.ts +1 -1
- package/lib/credential/index.js +2 -2
- package/lib/database/database-namespace.d.ts +1 -1
- package/lib/database/database-namespace.js +1 -1
- package/lib/database/database.d.ts +1 -1
- package/lib/database/database.js +92 -108
- package/lib/database/index.d.ts +1 -1
- package/lib/database/index.js +10 -10
- package/lib/default-namespace.d.ts +1 -1
- package/lib/default-namespace.js +2 -2
- package/lib/eventarc/cloudevent.d.ts +1 -1
- package/lib/eventarc/cloudevent.js +1 -1
- package/lib/eventarc/eventarc-client-internal.d.ts +1 -1
- package/lib/eventarc/eventarc-client-internal.js +63 -129
- package/lib/eventarc/eventarc-utils.d.ts +1 -1
- package/lib/eventarc/eventarc-utils.js +16 -32
- package/lib/eventarc/eventarc.d.ts +1 -1
- package/lib/eventarc/eventarc.js +51 -65
- package/lib/eventarc/index.d.ts +1 -1
- package/lib/eventarc/index.js +7 -7
- package/lib/firebase-namespace-api.d.ts +1 -1
- package/lib/firebase-namespace-api.js +8 -3
- package/lib/firestore/firestore-internal.d.ts +1 -1
- package/lib/firestore/firestore-internal.js +28 -37
- package/lib/firestore/firestore-namespace.d.ts +9 -1
- package/lib/firestore/firestore-namespace.js +2 -2
- package/lib/firestore/index.d.ts +2 -2
- package/lib/firestore/index.js +7 -7
- package/lib/functions/functions-api-client-internal.d.ts +1 -1
- package/lib/functions/functions-api-client-internal.js +71 -93
- package/lib/functions/functions-api.d.ts +1 -1
- package/lib/functions/functions-api.js +1 -1
- package/lib/functions/functions.d.ts +1 -1
- package/lib/functions/functions.js +13 -15
- package/lib/functions/index.d.ts +1 -1
- package/lib/functions/index.js +7 -7
- package/lib/index.d.ts +1 -1
- package/lib/index.js +14 -4
- package/lib/installations/index.d.ts +1 -1
- package/lib/installations/index.js +6 -6
- package/lib/installations/installations-namespace.d.ts +1 -1
- package/lib/installations/installations-namespace.js +1 -1
- package/lib/installations/installations-request-handler.d.ts +1 -1
- package/lib/installations/installations-request-handler.js +33 -36
- package/lib/installations/installations.d.ts +1 -1
- package/lib/installations/installations.js +17 -22
- package/lib/instance-id/index.d.ts +1 -1
- package/lib/instance-id/index.js +6 -6
- package/lib/instance-id/instance-id-namespace.d.ts +1 -1
- package/lib/instance-id/instance-id-namespace.js +1 -1
- package/lib/instance-id/instance-id.d.ts +1 -1
- package/lib/instance-id/instance-id.js +21 -26
- package/lib/machine-learning/index.d.ts +1 -1
- package/lib/machine-learning/index.js +7 -7
- package/lib/machine-learning/machine-learning-api-client.d.ts +1 -1
- package/lib/machine-learning/machine-learning-api-client.js +110 -124
- package/lib/machine-learning/machine-learning-namespace.d.ts +1 -1
- package/lib/machine-learning/machine-learning-namespace.js +1 -1
- package/lib/machine-learning/machine-learning-utils.d.ts +1 -1
- package/lib/machine-learning/machine-learning-utils.js +9 -24
- package/lib/machine-learning/machine-learning.d.ts +1 -1
- package/lib/machine-learning/machine-learning.js +146 -207
- package/lib/messaging/batch-request-internal.d.ts +1 -1
- package/lib/messaging/batch-request-internal.js +33 -35
- package/lib/messaging/index.d.ts +1 -1
- package/lib/messaging/index.js +7 -7
- package/lib/messaging/messaging-api-request-internal.d.ts +1 -1
- package/lib/messaging/messaging-api-request-internal.js +38 -40
- package/lib/messaging/messaging-api.d.ts +1 -1
- package/lib/messaging/messaging-api.js +1 -1
- package/lib/messaging/messaging-errors-internal.d.ts +1 -1
- package/lib/messaging/messaging-errors-internal.js +12 -13
- package/lib/messaging/messaging-internal.d.ts +1 -1
- package/lib/messaging/messaging-internal.js +51 -51
- package/lib/messaging/messaging-namespace.d.ts +1 -1
- package/lib/messaging/messaging-namespace.js +1 -1
- package/lib/messaging/messaging.d.ts +1 -1
- package/lib/messaging/messaging.js +184 -208
- package/lib/project-management/android-app.d.ts +1 -1
- package/lib/project-management/android-app.js +41 -43
- package/lib/project-management/app-metadata.d.ts +1 -1
- package/lib/project-management/app-metadata.js +1 -1
- package/lib/project-management/index.d.ts +1 -1
- package/lib/project-management/index.js +7 -7
- package/lib/project-management/ios-app.d.ts +1 -1
- package/lib/project-management/ios-app.js +25 -26
- package/lib/project-management/project-management-api-request-internal.d.ts +1 -1
- package/lib/project-management/project-management-api-request-internal.js +84 -89
- package/lib/project-management/project-management-namespace.d.ts +1 -1
- package/lib/project-management/project-management-namespace.js +1 -1
- package/lib/project-management/project-management.d.ts +1 -1
- package/lib/project-management/project-management.js +80 -87
- package/lib/remote-config/index.d.ts +1 -1
- package/lib/remote-config/index.js +7 -7
- package/lib/remote-config/remote-config-api-client-internal.d.ts +1 -1
- package/lib/remote-config/remote-config-api-client-internal.js +116 -154
- package/lib/remote-config/remote-config-api.d.ts +1 -1
- package/lib/remote-config/remote-config-api.js +1 -1
- package/lib/remote-config/remote-config-namespace.d.ts +1 -1
- package/lib/remote-config/remote-config-namespace.js +1 -1
- package/lib/remote-config/remote-config.d.ts +1 -1
- package/lib/remote-config/remote-config.js +51 -59
- package/lib/security-rules/index.d.ts +1 -1
- package/lib/security-rules/index.js +7 -7
- package/lib/security-rules/security-rules-api-client-internal.d.ts +1 -1
- package/lib/security-rules/security-rules-api-client-internal.js +95 -107
- package/lib/security-rules/security-rules-internal.d.ts +1 -1
- package/lib/security-rules/security-rules-internal.js +6 -21
- package/lib/security-rules/security-rules-namespace.d.ts +1 -1
- package/lib/security-rules/security-rules-namespace.js +1 -1
- package/lib/security-rules/security-rules.d.ts +1 -1
- package/lib/security-rules/security-rules.js +82 -91
- package/lib/storage/index.d.ts +1 -1
- package/lib/storage/index.js +7 -7
- package/lib/storage/storage-namespace.d.ts +1 -1
- package/lib/storage/storage-namespace.js +1 -1
- package/lib/storage/storage.d.ts +1 -1
- package/lib/storage/storage.js +25 -30
- package/lib/utils/api-request.d.ts +3 -1
- package/lib/utils/api-request.js +278 -356
- package/lib/utils/crypto-signer.d.ts +1 -1
- package/lib/utils/crypto-signer.js +58 -93
- package/lib/utils/deep-copy.d.ts +1 -1
- package/lib/utils/deep-copy.js +3 -3
- package/lib/utils/error.d.ts +1 -1
- package/lib/utils/error.js +611 -681
- package/lib/utils/index.d.ts +1 -1
- package/lib/utils/index.js +38 -43
- package/lib/utils/jwt.d.ts +1 -1
- package/lib/utils/jwt.js +97 -123
- package/lib/utils/validator.d.ts +1 -1
- package/lib/utils/validator.js +13 -13
- package/package.json +5 -5
package/lib/utils/index.d.ts
CHANGED
package/lib/utils/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! firebase-admin
|
|
1
|
+
/*! firebase-admin v11.0.0 */
|
|
2
2
|
"use strict";
|
|
3
3
|
/*!
|
|
4
4
|
* @license
|
|
@@ -18,13 +18,13 @@
|
|
|
18
18
|
*/
|
|
19
19
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
20
|
exports.parseResourceName = exports.transformMillisecondsToSecondsString = exports.generateUpdateMask = exports.formatString = exports.toWebSafeBase64 = exports.findServiceAccountEmail = exports.getExplicitServiceAccountEmail = exports.findProjectId = exports.getExplicitProjectId = exports.addReadonlyGetter = exports.renameProperties = exports.getSdkVersion = void 0;
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
const credential_internal_1 = require("../app/credential-internal");
|
|
22
|
+
const validator = require("./validator");
|
|
23
|
+
let sdkVersion;
|
|
24
24
|
// TODO: Move to firebase-admin/app as an internal member.
|
|
25
25
|
function getSdkVersion() {
|
|
26
26
|
if (!sdkVersion) {
|
|
27
|
-
|
|
27
|
+
const { version } = require('../../package.json'); // eslint-disable-line @typescript-eslint/no-var-requires
|
|
28
28
|
sdkVersion = version;
|
|
29
29
|
}
|
|
30
30
|
return sdkVersion;
|
|
@@ -39,9 +39,9 @@ exports.getSdkVersion = getSdkVersion;
|
|
|
39
39
|
* @param keyMap - The mapping from old to new property names.
|
|
40
40
|
*/
|
|
41
41
|
function renameProperties(obj, keyMap) {
|
|
42
|
-
Object.keys(keyMap).forEach(
|
|
42
|
+
Object.keys(keyMap).forEach((oldKey) => {
|
|
43
43
|
if (oldKey in obj) {
|
|
44
|
-
|
|
44
|
+
const newKey = keyMap[oldKey];
|
|
45
45
|
// The old key's value takes precedence over the new key's value.
|
|
46
46
|
obj[newKey] = obj[oldKey];
|
|
47
47
|
delete obj[oldKey];
|
|
@@ -58,7 +58,7 @@ exports.renameProperties = renameProperties;
|
|
|
58
58
|
*/
|
|
59
59
|
function addReadonlyGetter(obj, prop, value) {
|
|
60
60
|
Object.defineProperty(obj, prop, {
|
|
61
|
-
value
|
|
61
|
+
value,
|
|
62
62
|
// Make this property read-only.
|
|
63
63
|
writable: false,
|
|
64
64
|
// Include this property during enumeration of obj's properties.
|
|
@@ -76,15 +76,15 @@ exports.addReadonlyGetter = addReadonlyGetter;
|
|
|
76
76
|
* @returns A project ID string or null.
|
|
77
77
|
*/
|
|
78
78
|
function getExplicitProjectId(app) {
|
|
79
|
-
|
|
79
|
+
const options = app.options;
|
|
80
80
|
if (validator.isNonEmptyString(options.projectId)) {
|
|
81
81
|
return options.projectId;
|
|
82
82
|
}
|
|
83
|
-
|
|
83
|
+
const credential = app.options.credential;
|
|
84
84
|
if (credential instanceof credential_internal_1.ServiceAccountCredential) {
|
|
85
85
|
return credential.projectId;
|
|
86
86
|
}
|
|
87
|
-
|
|
87
|
+
const projectId = process.env.GOOGLE_CLOUD_PROJECT || process.env.GCLOUD_PROJECT;
|
|
88
88
|
if (validator.isNonEmptyString(projectId)) {
|
|
89
89
|
return projectId;
|
|
90
90
|
}
|
|
@@ -103,11 +103,11 @@ exports.getExplicitProjectId = getExplicitProjectId;
|
|
|
103
103
|
* @returns A project ID string or null.
|
|
104
104
|
*/
|
|
105
105
|
function findProjectId(app) {
|
|
106
|
-
|
|
106
|
+
const projectId = getExplicitProjectId(app);
|
|
107
107
|
if (projectId) {
|
|
108
108
|
return Promise.resolve(projectId);
|
|
109
109
|
}
|
|
110
|
-
|
|
110
|
+
const credential = app.options.credential;
|
|
111
111
|
if (credential instanceof credential_internal_1.ComputeEngineCredential) {
|
|
112
112
|
return credential.getProjectId();
|
|
113
113
|
}
|
|
@@ -124,11 +124,11 @@ exports.findProjectId = findProjectId;
|
|
|
124
124
|
* @returns A service account email string or null.
|
|
125
125
|
*/
|
|
126
126
|
function getExplicitServiceAccountEmail(app) {
|
|
127
|
-
|
|
127
|
+
const options = app.options;
|
|
128
128
|
if (validator.isNonEmptyString(options.serviceAccountId)) {
|
|
129
129
|
return options.serviceAccountId;
|
|
130
130
|
}
|
|
131
|
-
|
|
131
|
+
const credential = app.options.credential;
|
|
132
132
|
if (credential instanceof credential_internal_1.ServiceAccountCredential) {
|
|
133
133
|
return credential.clientEmail;
|
|
134
134
|
}
|
|
@@ -147,11 +147,11 @@ exports.getExplicitServiceAccountEmail = getExplicitServiceAccountEmail;
|
|
|
147
147
|
* @returns A service account email ID string or null.
|
|
148
148
|
*/
|
|
149
149
|
function findServiceAccountEmail(app) {
|
|
150
|
-
|
|
150
|
+
const accountId = getExplicitServiceAccountEmail(app);
|
|
151
151
|
if (accountId) {
|
|
152
152
|
return Promise.resolve(accountId);
|
|
153
153
|
}
|
|
154
|
-
|
|
154
|
+
const credential = app.options.credential;
|
|
155
155
|
if (credential instanceof credential_internal_1.ComputeEngineCredential) {
|
|
156
156
|
return credential.getServiceAccountEmail();
|
|
157
157
|
}
|
|
@@ -180,8 +180,8 @@ exports.toWebSafeBase64 = toWebSafeBase64;
|
|
|
180
180
|
* @returns The resulting formatted string.
|
|
181
181
|
*/
|
|
182
182
|
function formatString(str, params) {
|
|
183
|
-
|
|
184
|
-
Object.keys(params || {}).forEach(
|
|
183
|
+
let formatted = str;
|
|
184
|
+
Object.keys(params || {}).forEach((key) => {
|
|
185
185
|
formatted = formatted.replace(new RegExp('{' + key + '}', 'g'), params[key]);
|
|
186
186
|
});
|
|
187
187
|
return formatted;
|
|
@@ -198,16 +198,14 @@ exports.formatString = formatString;
|
|
|
198
198
|
* @param root - The path so far.
|
|
199
199
|
* @returns The computed update mask list.
|
|
200
200
|
*/
|
|
201
|
-
function generateUpdateMask(obj, terminalPaths, root) {
|
|
202
|
-
|
|
203
|
-
if (root === void 0) { root = ''; }
|
|
204
|
-
var updateMask = [];
|
|
201
|
+
function generateUpdateMask(obj, terminalPaths = [], root = '') {
|
|
202
|
+
const updateMask = [];
|
|
205
203
|
if (!validator.isNonNullObject(obj)) {
|
|
206
204
|
return updateMask;
|
|
207
205
|
}
|
|
208
|
-
|
|
206
|
+
for (const key in obj) {
|
|
209
207
|
if (typeof obj[key] !== 'undefined') {
|
|
210
|
-
|
|
208
|
+
const nextPath = root ? `${root}.${key}` : key;
|
|
211
209
|
// We hit maximum path.
|
|
212
210
|
// Consider switching to Set<string> if the list grows too large.
|
|
213
211
|
if (terminalPaths.indexOf(nextPath) !== -1) {
|
|
@@ -215,10 +213,10 @@ function generateUpdateMask(obj, terminalPaths, root) {
|
|
|
215
213
|
updateMask.push(key);
|
|
216
214
|
}
|
|
217
215
|
else {
|
|
218
|
-
|
|
216
|
+
const maskList = generateUpdateMask(obj[key], terminalPaths, nextPath);
|
|
219
217
|
if (maskList.length > 0) {
|
|
220
|
-
maskList.forEach(
|
|
221
|
-
updateMask.push(key
|
|
218
|
+
maskList.forEach((mask) => {
|
|
219
|
+
updateMask.push(`${key}.${mask}`);
|
|
222
220
|
});
|
|
223
221
|
}
|
|
224
222
|
else {
|
|
@@ -226,9 +224,6 @@ function generateUpdateMask(obj, terminalPaths, root) {
|
|
|
226
224
|
}
|
|
227
225
|
}
|
|
228
226
|
}
|
|
229
|
-
};
|
|
230
|
-
for (var key in obj) {
|
|
231
|
-
_loop_1(key);
|
|
232
227
|
}
|
|
233
228
|
return updateMask;
|
|
234
229
|
}
|
|
@@ -244,18 +239,18 @@ exports.generateUpdateMask = generateUpdateMask;
|
|
|
244
239
|
* digits, terminated by 's'.
|
|
245
240
|
*/
|
|
246
241
|
function transformMillisecondsToSecondsString(milliseconds) {
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
242
|
+
let duration;
|
|
243
|
+
const seconds = Math.floor(milliseconds / 1000);
|
|
244
|
+
const nanos = Math.floor((milliseconds - seconds * 1000) * 1000000);
|
|
250
245
|
if (nanos > 0) {
|
|
251
|
-
|
|
246
|
+
let nanoString = nanos.toString();
|
|
252
247
|
while (nanoString.length < 9) {
|
|
253
248
|
nanoString = '0' + nanoString;
|
|
254
249
|
}
|
|
255
|
-
duration = seconds
|
|
250
|
+
duration = `${seconds}.${nanoString}s`;
|
|
256
251
|
}
|
|
257
252
|
else {
|
|
258
|
-
duration = seconds
|
|
253
|
+
duration = `${seconds}s`;
|
|
259
254
|
}
|
|
260
255
|
return duration;
|
|
261
256
|
}
|
|
@@ -275,14 +270,14 @@ function parseResourceName(resourceName, resourceIdKey) {
|
|
|
275
270
|
if (!resourceName.includes('/')) {
|
|
276
271
|
return { resourceId: resourceName };
|
|
277
272
|
}
|
|
278
|
-
|
|
279
|
-
|
|
273
|
+
const CHANNEL_NAME_REGEX = new RegExp(`^(projects/([^/]+)/)?locations/([^/]+)/${resourceIdKey}/([^/]+)$`);
|
|
274
|
+
const match = CHANNEL_NAME_REGEX.exec(resourceName);
|
|
280
275
|
if (match === null) {
|
|
281
276
|
throw new Error('Invalid resource name format.');
|
|
282
277
|
}
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
return { projectId
|
|
278
|
+
const projectId = match[2];
|
|
279
|
+
const locationId = match[3];
|
|
280
|
+
const resourceId = match[4];
|
|
281
|
+
return { projectId, locationId, resourceId };
|
|
287
282
|
}
|
|
288
283
|
exports.parseResourceName = parseResourceName;
|
package/lib/utils/jwt.d.ts
CHANGED
package/lib/utils/jwt.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! firebase-admin
|
|
1
|
+
/*! firebase-admin v11.0.0 */
|
|
2
2
|
"use strict";
|
|
3
3
|
/*!
|
|
4
4
|
* Copyright 2021 Google Inc.
|
|
@@ -15,79 +15,64 @@
|
|
|
15
15
|
* See the License for the specific language governing permissions and
|
|
16
16
|
* limitations under the License.
|
|
17
17
|
*/
|
|
18
|
-
var __extends = (this && this.__extends) || (function () {
|
|
19
|
-
var extendStatics = function (d, b) {
|
|
20
|
-
extendStatics = Object.setPrototypeOf ||
|
|
21
|
-
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
22
|
-
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
|
23
|
-
return extendStatics(d, b);
|
|
24
|
-
};
|
|
25
|
-
return function (d, b) {
|
|
26
|
-
extendStatics(d, b);
|
|
27
|
-
function __() { this.constructor = d; }
|
|
28
|
-
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
29
|
-
};
|
|
30
|
-
})();
|
|
31
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
32
19
|
exports.JwtErrorCode = exports.JwtError = exports.decodeJwt = exports.verifyJwtSignature = exports.EmulatorSignatureVerifier = exports.PublicKeySignatureVerifier = exports.UrlKeyFetcher = exports.JwksFetcher = exports.ALGORITHM_RS256 = void 0;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
20
|
+
const validator = require("./validator");
|
|
21
|
+
const jwt = require("jsonwebtoken");
|
|
22
|
+
const jwks = require("jwks-rsa");
|
|
23
|
+
const api_request_1 = require("../utils/api-request");
|
|
37
24
|
exports.ALGORITHM_RS256 = 'RS256';
|
|
38
25
|
// `jsonwebtoken` converts errors from the `getKey` callback to its own `JsonWebTokenError` type
|
|
39
26
|
// and prefixes the error message with the following. Use the prefix to identify errors thrown
|
|
40
27
|
// from the key provider callback.
|
|
41
28
|
// https://github.com/auth0/node-jsonwebtoken/blob/d71e383862fc735991fd2e759181480f066bf138/verify.js#L96
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
29
|
+
const JWT_CALLBACK_ERROR_PREFIX = 'error in secret or public key callback: ';
|
|
30
|
+
const NO_MATCHING_KID_ERROR_MESSAGE = 'no-matching-kid-error';
|
|
31
|
+
const NO_KID_IN_HEADER_ERROR_MESSAGE = 'no-kid-in-header-error';
|
|
32
|
+
const HOUR_IN_SECONDS = 3600;
|
|
33
|
+
class JwksFetcher {
|
|
34
|
+
constructor(jwksUrl) {
|
|
48
35
|
this.publicKeysExpireAt = 0;
|
|
49
36
|
if (!validator.isURL(jwksUrl)) {
|
|
50
37
|
throw new Error('The provided JWKS URL is not a valid URL.');
|
|
51
38
|
}
|
|
52
39
|
this.client = jwks({
|
|
53
40
|
jwksUri: jwksUrl,
|
|
54
|
-
cache: false,
|
|
41
|
+
cache: false, // disable jwks-rsa LRU cache as the keys are always cached for 6 hours.
|
|
55
42
|
});
|
|
56
43
|
}
|
|
57
|
-
|
|
44
|
+
fetchPublicKeys() {
|
|
58
45
|
if (this.shouldRefresh()) {
|
|
59
46
|
return this.refresh();
|
|
60
47
|
}
|
|
61
48
|
return Promise.resolve(this.publicKeys);
|
|
62
|
-
}
|
|
63
|
-
|
|
49
|
+
}
|
|
50
|
+
shouldRefresh() {
|
|
64
51
|
return !this.publicKeys || this.publicKeysExpireAt <= Date.now();
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
var _this = this;
|
|
52
|
+
}
|
|
53
|
+
refresh() {
|
|
68
54
|
return this.client.getSigningKeys()
|
|
69
|
-
.then(
|
|
55
|
+
.then((signingKeys) => {
|
|
70
56
|
// reset expire at from previous set of keys.
|
|
71
|
-
|
|
72
|
-
|
|
57
|
+
this.publicKeysExpireAt = 0;
|
|
58
|
+
const newKeys = signingKeys.reduce((map, signingKey) => {
|
|
73
59
|
map[signingKey.kid] = signingKey.getPublicKey();
|
|
74
60
|
return map;
|
|
75
61
|
}, {});
|
|
76
|
-
|
|
77
|
-
|
|
62
|
+
this.publicKeysExpireAt = Date.now() + (HOUR_IN_SECONDS * 6 * 1000);
|
|
63
|
+
this.publicKeys = newKeys;
|
|
78
64
|
return newKeys;
|
|
79
|
-
}).catch(
|
|
80
|
-
throw new Error(
|
|
65
|
+
}).catch((err) => {
|
|
66
|
+
throw new Error(`Error fetching Json Web Keys: ${err.message}`);
|
|
81
67
|
});
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
}());
|
|
68
|
+
}
|
|
69
|
+
}
|
|
85
70
|
exports.JwksFetcher = JwksFetcher;
|
|
86
71
|
/**
|
|
87
72
|
* Class to fetch public keys from a client certificates URL.
|
|
88
73
|
*/
|
|
89
|
-
|
|
90
|
-
|
|
74
|
+
class UrlKeyFetcher {
|
|
75
|
+
constructor(clientCertUrl, httpAgent) {
|
|
91
76
|
this.clientCertUrl = clientCertUrl;
|
|
92
77
|
this.httpAgent = httpAgent;
|
|
93
78
|
this.publicKeysExpireAt = 0;
|
|
@@ -100,111 +85,107 @@ var UrlKeyFetcher = /** @class */ (function () {
|
|
|
100
85
|
*
|
|
101
86
|
* @returns A promise fulfilled with public keys for the Google certs.
|
|
102
87
|
*/
|
|
103
|
-
|
|
88
|
+
fetchPublicKeys() {
|
|
104
89
|
if (this.shouldRefresh()) {
|
|
105
90
|
return this.refresh();
|
|
106
91
|
}
|
|
107
92
|
return Promise.resolve(this.publicKeys);
|
|
108
|
-
}
|
|
93
|
+
}
|
|
109
94
|
/**
|
|
110
95
|
* Checks if the cached public keys need to be refreshed.
|
|
111
96
|
*
|
|
112
97
|
* @returns Whether the keys should be fetched from the client certs url or not.
|
|
113
98
|
*/
|
|
114
|
-
|
|
99
|
+
shouldRefresh() {
|
|
115
100
|
return !this.publicKeys || this.publicKeysExpireAt <= Date.now();
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
var request = {
|
|
101
|
+
}
|
|
102
|
+
refresh() {
|
|
103
|
+
const client = new api_request_1.HttpClient();
|
|
104
|
+
const request = {
|
|
121
105
|
method: 'GET',
|
|
122
106
|
url: this.clientCertUrl,
|
|
123
107
|
httpAgent: this.httpAgent,
|
|
124
108
|
};
|
|
125
|
-
return client.send(request).then(
|
|
109
|
+
return client.send(request).then((resp) => {
|
|
126
110
|
if (!resp.isJson() || resp.data.error) {
|
|
127
111
|
// Treat all non-json messages and messages with an 'error' field as
|
|
128
112
|
// error responses.
|
|
129
113
|
throw new api_request_1.HttpError(resp);
|
|
130
114
|
}
|
|
131
115
|
// reset expire at from previous set of keys.
|
|
132
|
-
|
|
116
|
+
this.publicKeysExpireAt = 0;
|
|
133
117
|
if (Object.prototype.hasOwnProperty.call(resp.headers, 'cache-control')) {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
parts.forEach(
|
|
137
|
-
|
|
118
|
+
const cacheControlHeader = resp.headers['cache-control'];
|
|
119
|
+
const parts = cacheControlHeader.split(',');
|
|
120
|
+
parts.forEach((part) => {
|
|
121
|
+
const subParts = part.trim().split('=');
|
|
138
122
|
if (subParts[0] === 'max-age') {
|
|
139
|
-
|
|
140
|
-
|
|
123
|
+
const maxAge = +subParts[1];
|
|
124
|
+
this.publicKeysExpireAt = Date.now() + (maxAge * 1000);
|
|
141
125
|
}
|
|
142
126
|
});
|
|
143
127
|
}
|
|
144
|
-
|
|
128
|
+
this.publicKeys = resp.data;
|
|
145
129
|
return resp.data;
|
|
146
|
-
}).catch(
|
|
130
|
+
}).catch((err) => {
|
|
147
131
|
if (err instanceof api_request_1.HttpError) {
|
|
148
|
-
|
|
149
|
-
|
|
132
|
+
let errorMessage = 'Error fetching public keys for Google certs: ';
|
|
133
|
+
const resp = err.response;
|
|
150
134
|
if (resp.isJson() && resp.data.error) {
|
|
151
|
-
errorMessage +=
|
|
135
|
+
errorMessage += `${resp.data.error}`;
|
|
152
136
|
if (resp.data.error_description) {
|
|
153
137
|
errorMessage += ' (' + resp.data.error_description + ')';
|
|
154
138
|
}
|
|
155
139
|
}
|
|
156
140
|
else {
|
|
157
|
-
errorMessage +=
|
|
141
|
+
errorMessage += `${resp.text}`;
|
|
158
142
|
}
|
|
159
143
|
throw new Error(errorMessage);
|
|
160
144
|
}
|
|
161
145
|
throw err;
|
|
162
146
|
});
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
}());
|
|
147
|
+
}
|
|
148
|
+
}
|
|
166
149
|
exports.UrlKeyFetcher = UrlKeyFetcher;
|
|
167
150
|
/**
|
|
168
151
|
* Class for verifying JWT signature with a public key.
|
|
169
152
|
*/
|
|
170
|
-
|
|
171
|
-
|
|
153
|
+
class PublicKeySignatureVerifier {
|
|
154
|
+
constructor(keyFetcher) {
|
|
172
155
|
this.keyFetcher = keyFetcher;
|
|
173
156
|
if (!validator.isNonNullObject(keyFetcher)) {
|
|
174
157
|
throw new Error('The provided key fetcher is not an object or null.');
|
|
175
158
|
}
|
|
176
159
|
}
|
|
177
|
-
|
|
160
|
+
static withCertificateUrl(clientCertUrl, httpAgent) {
|
|
178
161
|
return new PublicKeySignatureVerifier(new UrlKeyFetcher(clientCertUrl, httpAgent));
|
|
179
|
-
}
|
|
180
|
-
|
|
162
|
+
}
|
|
163
|
+
static withJwksUrl(jwksUrl) {
|
|
181
164
|
return new PublicKeySignatureVerifier(new JwksFetcher(jwksUrl));
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
var _this = this;
|
|
165
|
+
}
|
|
166
|
+
verify(token) {
|
|
185
167
|
if (!validator.isString(token)) {
|
|
186
168
|
return Promise.reject(new JwtError(JwtErrorCode.INVALID_ARGUMENT, 'The provided token must be a string.'));
|
|
187
169
|
}
|
|
188
170
|
return verifyJwtSignature(token, getKeyCallback(this.keyFetcher), { algorithms: [exports.ALGORITHM_RS256] })
|
|
189
|
-
.catch(
|
|
171
|
+
.catch((error) => {
|
|
190
172
|
if (error.code === JwtErrorCode.NO_KID_IN_HEADER) {
|
|
191
173
|
// No kid in JWT header. Try with all the public keys.
|
|
192
|
-
return
|
|
174
|
+
return this.verifyWithoutKid(token);
|
|
193
175
|
}
|
|
194
176
|
throw error;
|
|
195
177
|
});
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
var _this = this;
|
|
178
|
+
}
|
|
179
|
+
verifyWithoutKid(token) {
|
|
199
180
|
return this.keyFetcher.fetchPublicKeys()
|
|
200
|
-
.then(
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
Object.values(keys).forEach(
|
|
205
|
-
|
|
206
|
-
.then(
|
|
207
|
-
.catch(
|
|
181
|
+
.then(publicKeys => this.verifyWithAllKeys(token, publicKeys));
|
|
182
|
+
}
|
|
183
|
+
verifyWithAllKeys(token, keys) {
|
|
184
|
+
const promises = [];
|
|
185
|
+
Object.values(keys).forEach((key) => {
|
|
186
|
+
const result = verifyJwtSignature(token, key)
|
|
187
|
+
.then(() => true)
|
|
188
|
+
.catch((error) => {
|
|
208
189
|
if (error.code === JwtErrorCode.TOKEN_EXPIRED) {
|
|
209
190
|
throw error;
|
|
210
191
|
}
|
|
@@ -213,27 +194,23 @@ var PublicKeySignatureVerifier = /** @class */ (function () {
|
|
|
213
194
|
promises.push(result);
|
|
214
195
|
});
|
|
215
196
|
return Promise.all(promises)
|
|
216
|
-
.then(
|
|
217
|
-
if (result.every(
|
|
197
|
+
.then((result) => {
|
|
198
|
+
if (result.every((r) => r === false)) {
|
|
218
199
|
throw new JwtError(JwtErrorCode.INVALID_SIGNATURE, 'Invalid token signature.');
|
|
219
200
|
}
|
|
220
201
|
});
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
}());
|
|
202
|
+
}
|
|
203
|
+
}
|
|
224
204
|
exports.PublicKeySignatureVerifier = PublicKeySignatureVerifier;
|
|
225
205
|
/**
|
|
226
206
|
* Class for verifying unsigned (emulator) JWTs.
|
|
227
207
|
*/
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
}
|
|
231
|
-
EmulatorSignatureVerifier.prototype.verify = function (token) {
|
|
208
|
+
class EmulatorSignatureVerifier {
|
|
209
|
+
verify(token) {
|
|
232
210
|
// Signature checks skipped for emulator; no need to fetch public keys.
|
|
233
211
|
return verifyJwtSignature(token, '');
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
}());
|
|
212
|
+
}
|
|
213
|
+
}
|
|
237
214
|
exports.EmulatorSignatureVerifier = EmulatorSignatureVerifier;
|
|
238
215
|
/**
|
|
239
216
|
* Provides a callback to fetch public keys.
|
|
@@ -242,12 +219,12 @@ exports.EmulatorSignatureVerifier = EmulatorSignatureVerifier;
|
|
|
242
219
|
* @returns A callback function that can be used to get keys in `jsonwebtoken`.
|
|
243
220
|
*/
|
|
244
221
|
function getKeyCallback(fetcher) {
|
|
245
|
-
return
|
|
222
|
+
return (header, callback) => {
|
|
246
223
|
if (!header.kid) {
|
|
247
224
|
callback(new Error(NO_KID_IN_HEADER_ERROR_MESSAGE));
|
|
248
225
|
}
|
|
249
|
-
|
|
250
|
-
fetcher.fetchPublicKeys().then(
|
|
226
|
+
const kid = header.kid || '';
|
|
227
|
+
fetcher.fetchPublicKeys().then((publicKeys) => {
|
|
251
228
|
if (!Object.prototype.hasOwnProperty.call(publicKeys, kid)) {
|
|
252
229
|
callback(new Error(NO_MATCHING_KID_ERROR_MESSAGE));
|
|
253
230
|
}
|
|
@@ -255,7 +232,7 @@ function getKeyCallback(fetcher) {
|
|
|
255
232
|
callback(null, publicKeys[kid]);
|
|
256
233
|
}
|
|
257
234
|
})
|
|
258
|
-
.catch(
|
|
235
|
+
.catch(error => {
|
|
259
236
|
callback(error);
|
|
260
237
|
});
|
|
261
238
|
};
|
|
@@ -273,8 +250,8 @@ function verifyJwtSignature(token, secretOrPublicKey, options) {
|
|
|
273
250
|
if (!validator.isString(token)) {
|
|
274
251
|
return Promise.reject(new JwtError(JwtErrorCode.INVALID_ARGUMENT, 'The provided token must be a string.'));
|
|
275
252
|
}
|
|
276
|
-
return new Promise(
|
|
277
|
-
jwt.verify(token, secretOrPublicKey, options,
|
|
253
|
+
return new Promise((resolve, reject) => {
|
|
254
|
+
jwt.verify(token, secretOrPublicKey, options, (error) => {
|
|
278
255
|
if (!error) {
|
|
279
256
|
return resolve();
|
|
280
257
|
}
|
|
@@ -284,8 +261,8 @@ function verifyJwtSignature(token, secretOrPublicKey, options) {
|
|
|
284
261
|
}
|
|
285
262
|
else if (error.name === 'JsonWebTokenError') {
|
|
286
263
|
if (error.message && error.message.includes(JWT_CALLBACK_ERROR_PREFIX)) {
|
|
287
|
-
|
|
288
|
-
|
|
264
|
+
const message = error.message.split(JWT_CALLBACK_ERROR_PREFIX).pop() || 'Error fetching public keys.';
|
|
265
|
+
let code = JwtErrorCode.KEY_FETCH_ERROR;
|
|
289
266
|
if (message === NO_MATCHING_KID_ERROR_MESSAGE) {
|
|
290
267
|
code = JwtErrorCode.NO_MATCHING_KID;
|
|
291
268
|
}
|
|
@@ -310,15 +287,15 @@ function decodeJwt(jwtToken) {
|
|
|
310
287
|
if (!validator.isString(jwtToken)) {
|
|
311
288
|
return Promise.reject(new JwtError(JwtErrorCode.INVALID_ARGUMENT, 'The provided token must be a string.'));
|
|
312
289
|
}
|
|
313
|
-
|
|
290
|
+
const fullDecodedToken = jwt.decode(jwtToken, {
|
|
314
291
|
complete: true,
|
|
315
292
|
});
|
|
316
293
|
if (!fullDecodedToken) {
|
|
317
294
|
return Promise.reject(new JwtError(JwtErrorCode.INVALID_ARGUMENT, 'Decoding token failed.'));
|
|
318
295
|
}
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
return Promise.resolve({ header
|
|
296
|
+
const header = fullDecodedToken?.header;
|
|
297
|
+
const payload = fullDecodedToken?.payload;
|
|
298
|
+
return Promise.resolve({ header, payload });
|
|
322
299
|
}
|
|
323
300
|
exports.decodeJwt = decodeJwt;
|
|
324
301
|
/**
|
|
@@ -328,17 +305,14 @@ exports.decodeJwt = decodeJwt;
|
|
|
328
305
|
* @param message - The error message.
|
|
329
306
|
* @constructor
|
|
330
307
|
*/
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
_this.__proto__ = JwtError.prototype;
|
|
338
|
-
return _this;
|
|
308
|
+
class JwtError extends Error {
|
|
309
|
+
constructor(code, message) {
|
|
310
|
+
super(message);
|
|
311
|
+
this.code = code;
|
|
312
|
+
this.message = message;
|
|
313
|
+
this.__proto__ = JwtError.prototype;
|
|
339
314
|
}
|
|
340
|
-
|
|
341
|
-
}(Error));
|
|
315
|
+
}
|
|
342
316
|
exports.JwtError = JwtError;
|
|
343
317
|
/**
|
|
344
318
|
* JWT error codes.
|
package/lib/utils/validator.d.ts
CHANGED