firebase-admin 10.2.0 → 11.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- 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 +7 -1
- package/lib/app/credential-internal.js +120 -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 +62 -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 +19 -1
- package/lib/functions/functions-api-client-internal.js +83 -103
- 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 +3 -1
- package/lib/security-rules/security-rules-api-client-internal.js +118 -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 +83 -92
- 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 +25 -10
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! firebase-admin
|
|
1
|
+
/*! firebase-admin v11.0.1 */
|
|
2
2
|
"use strict";
|
|
3
3
|
/*!
|
|
4
4
|
* @license
|
|
@@ -18,55 +18,54 @@
|
|
|
18
18
|
*/
|
|
19
19
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
20
|
exports.handleCryptoSignerError = exports.FirebaseTokenGenerator = exports.EmulatedSigner = exports.BLACKLISTED_CLAIMS = void 0;
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
const error_1 = require("../utils/error");
|
|
22
|
+
const crypto_signer_1 = require("../utils/crypto-signer");
|
|
23
|
+
const validator = require("../utils/validator");
|
|
24
|
+
const utils_1 = require("../utils");
|
|
25
|
+
const ALGORITHM_NONE = 'none';
|
|
26
|
+
const ONE_HOUR_IN_SECONDS = 60 * 60;
|
|
27
27
|
// List of blacklisted claims which cannot be provided when creating a custom token
|
|
28
28
|
exports.BLACKLISTED_CLAIMS = [
|
|
29
29
|
'acr', 'amr', 'at_hash', 'aud', 'auth_time', 'azp', 'cnf', 'c_hash', 'exp', 'iat', 'iss', 'jti',
|
|
30
30
|
'nbf', 'nonce',
|
|
31
31
|
];
|
|
32
32
|
// Audience to use for Firebase Auth Custom tokens
|
|
33
|
-
|
|
33
|
+
const FIREBASE_AUDIENCE = 'https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit';
|
|
34
34
|
/**
|
|
35
35
|
* A CryptoSigner implementation that is used when communicating with the Auth emulator.
|
|
36
36
|
* It produces unsigned tokens.
|
|
37
37
|
*/
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
class EmulatedSigner {
|
|
39
|
+
constructor() {
|
|
40
40
|
this.algorithm = ALGORITHM_NONE;
|
|
41
41
|
}
|
|
42
42
|
/**
|
|
43
43
|
* @inheritDoc
|
|
44
44
|
*/
|
|
45
45
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
46
|
-
|
|
46
|
+
sign(buffer) {
|
|
47
47
|
return Promise.resolve(Buffer.from(''));
|
|
48
|
-
}
|
|
48
|
+
}
|
|
49
49
|
/**
|
|
50
50
|
* @inheritDoc
|
|
51
51
|
*/
|
|
52
|
-
|
|
52
|
+
getAccountId() {
|
|
53
53
|
return Promise.resolve('firebase-auth-emulator@example.com');
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
}());
|
|
54
|
+
}
|
|
55
|
+
}
|
|
57
56
|
exports.EmulatedSigner = EmulatedSigner;
|
|
58
57
|
/**
|
|
59
58
|
* Class for generating different types of Firebase Auth tokens (JWTs).
|
|
60
59
|
*
|
|
61
60
|
* @internal
|
|
62
61
|
*/
|
|
63
|
-
|
|
62
|
+
class FirebaseTokenGenerator {
|
|
64
63
|
/**
|
|
65
64
|
* @param tenantId - The tenant ID to use for the generated Firebase Auth
|
|
66
65
|
* Custom token. If absent, then no tenant ID claim will be set in the
|
|
67
66
|
* resulting JWT.
|
|
68
67
|
*/
|
|
69
|
-
|
|
68
|
+
constructor(signer, tenantId) {
|
|
70
69
|
this.tenantId = tenantId;
|
|
71
70
|
if (!validator.isNonNullObject(signer)) {
|
|
72
71
|
throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_CREDENTIAL, 'INTERNAL ASSERT: Must provide a CryptoSigner to use FirebaseTokenGenerator.');
|
|
@@ -85,9 +84,8 @@ var FirebaseTokenGenerator = /** @class */ (function () {
|
|
|
85
84
|
* @returns A Promise fulfilled with a Firebase Auth Custom token signed with a
|
|
86
85
|
* service account key and containing the provided payload.
|
|
87
86
|
*/
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
var errorMessage;
|
|
87
|
+
createCustomToken(uid, developerClaims) {
|
|
88
|
+
let errorMessage;
|
|
91
89
|
if (!validator.isNonEmptyString(uid)) {
|
|
92
90
|
errorMessage = '`uid` argument must be a non-empty string uid.';
|
|
93
91
|
}
|
|
@@ -100,52 +98,51 @@ var FirebaseTokenGenerator = /** @class */ (function () {
|
|
|
100
98
|
if (errorMessage) {
|
|
101
99
|
throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_ARGUMENT, errorMessage);
|
|
102
100
|
}
|
|
103
|
-
|
|
101
|
+
const claims = {};
|
|
104
102
|
if (typeof developerClaims !== 'undefined') {
|
|
105
|
-
for (
|
|
103
|
+
for (const key in developerClaims) {
|
|
106
104
|
/* istanbul ignore else */
|
|
107
105
|
if (Object.prototype.hasOwnProperty.call(developerClaims, key)) {
|
|
108
106
|
if (exports.BLACKLISTED_CLAIMS.indexOf(key) !== -1) {
|
|
109
|
-
throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_ARGUMENT,
|
|
107
|
+
throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_ARGUMENT, `Developer claim "${key}" is reserved and cannot be specified.`);
|
|
110
108
|
}
|
|
111
109
|
claims[key] = developerClaims[key];
|
|
112
110
|
}
|
|
113
111
|
}
|
|
114
112
|
}
|
|
115
|
-
return this.signer.getAccountId().then(
|
|
116
|
-
|
|
117
|
-
alg:
|
|
113
|
+
return this.signer.getAccountId().then((account) => {
|
|
114
|
+
const header = {
|
|
115
|
+
alg: this.signer.algorithm,
|
|
118
116
|
typ: 'JWT',
|
|
119
117
|
};
|
|
120
|
-
|
|
121
|
-
|
|
118
|
+
const iat = Math.floor(Date.now() / 1000);
|
|
119
|
+
const body = {
|
|
122
120
|
aud: FIREBASE_AUDIENCE,
|
|
123
|
-
iat
|
|
121
|
+
iat,
|
|
124
122
|
exp: iat + ONE_HOUR_IN_SECONDS,
|
|
125
123
|
iss: account,
|
|
126
124
|
sub: account,
|
|
127
|
-
uid
|
|
125
|
+
uid,
|
|
128
126
|
};
|
|
129
|
-
if (
|
|
130
|
-
body.tenant_id =
|
|
127
|
+
if (this.tenantId) {
|
|
128
|
+
body.tenant_id = this.tenantId;
|
|
131
129
|
}
|
|
132
130
|
if (Object.keys(claims).length > 0) {
|
|
133
131
|
body.claims = claims;
|
|
134
132
|
}
|
|
135
|
-
|
|
136
|
-
|
|
133
|
+
const token = `${this.encodeSegment(header)}.${this.encodeSegment(body)}`;
|
|
134
|
+
const signPromise = this.signer.sign(Buffer.from(token));
|
|
137
135
|
return Promise.all([token, signPromise]);
|
|
138
|
-
}).then(
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
}).catch(function (err) {
|
|
136
|
+
}).then(([token, signature]) => {
|
|
137
|
+
return `${token}.${this.encodeSegment(signature)}`;
|
|
138
|
+
}).catch((err) => {
|
|
142
139
|
throw handleCryptoSignerError(err);
|
|
143
140
|
});
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
return utils_1.toWebSafeBase64(buffer).replace(/=+$/, '');
|
|
148
|
-
}
|
|
141
|
+
}
|
|
142
|
+
encodeSegment(segment) {
|
|
143
|
+
const buffer = (segment instanceof Buffer) ? segment : Buffer.from(JSON.stringify(segment));
|
|
144
|
+
return (0, utils_1.toWebSafeBase64)(buffer).replace(/=+$/, '');
|
|
145
|
+
}
|
|
149
146
|
/**
|
|
150
147
|
* Returns whether or not the provided developer claims are valid.
|
|
151
148
|
*
|
|
@@ -153,14 +150,13 @@ var FirebaseTokenGenerator = /** @class */ (function () {
|
|
|
153
150
|
* @returns True if the provided claims are valid; otherwise, false.
|
|
154
151
|
*/
|
|
155
152
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
156
|
-
|
|
153
|
+
isDeveloperClaimsValid_(developerClaims) {
|
|
157
154
|
if (typeof developerClaims === 'undefined') {
|
|
158
155
|
return true;
|
|
159
156
|
}
|
|
160
157
|
return validator.isNonNullObject(developerClaims);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
}());
|
|
158
|
+
}
|
|
159
|
+
}
|
|
164
160
|
exports.FirebaseTokenGenerator = FirebaseTokenGenerator;
|
|
165
161
|
/**
|
|
166
162
|
* Creates a new FirebaseAuthError by extracting the error code, message and other relevant
|
|
@@ -174,13 +170,13 @@ function handleCryptoSignerError(err) {
|
|
|
174
170
|
return err;
|
|
175
171
|
}
|
|
176
172
|
if (err.code === crypto_signer_1.CryptoSignerErrorCode.SERVER_ERROR && validator.isNonNullObject(err.cause)) {
|
|
177
|
-
|
|
178
|
-
|
|
173
|
+
const httpError = err.cause;
|
|
174
|
+
const errorResponse = httpError.response.data;
|
|
179
175
|
if (validator.isNonNullObject(errorResponse) && errorResponse.error) {
|
|
180
|
-
|
|
181
|
-
|
|
176
|
+
const errorCode = errorResponse.error.status;
|
|
177
|
+
const description = 'Please refer to https://firebase.google.com/docs/auth/admin/create-custom-tokens ' +
|
|
182
178
|
'for more details on how to use and troubleshoot this feature.';
|
|
183
|
-
|
|
179
|
+
const errorMsg = `${errorResponse.error.message}; ${description}`;
|
|
184
180
|
return error_1.FirebaseAuthError.fromServerError(errorCode, errorMsg, errorResponse);
|
|
185
181
|
}
|
|
186
182
|
return new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INTERNAL_ERROR, 'Error returned from server: ' + errorResponse + '. Additionally, an ' +
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! firebase-admin
|
|
1
|
+
/*! firebase-admin v11.0.1 */
|
|
2
2
|
"use strict";
|
|
3
3
|
/*!
|
|
4
4
|
* Copyright 2018 Google Inc.
|
|
@@ -17,18 +17,18 @@
|
|
|
17
17
|
*/
|
|
18
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
19
|
exports.createSessionCookieVerifier = exports.createAuthBlockingTokenVerifier = exports.createIdTokenVerifier = exports.FirebaseTokenVerifier = exports.SESSION_COOKIE_INFO = exports.AUTH_BLOCKING_TOKEN_INFO = exports.ID_TOKEN_INFO = void 0;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
const error_1 = require("../utils/error");
|
|
21
|
+
const util = require("../utils/index");
|
|
22
|
+
const validator = require("../utils/validator");
|
|
23
|
+
const jwt_1 = require("../utils/jwt");
|
|
24
24
|
// Audience to use for Firebase Auth Custom tokens
|
|
25
|
-
|
|
25
|
+
const FIREBASE_AUDIENCE = 'https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit';
|
|
26
26
|
// URL containing the public keys for the Google certs (whose private keys are used to sign Firebase
|
|
27
27
|
// Auth ID tokens)
|
|
28
|
-
|
|
28
|
+
const CLIENT_CERT_URL = 'https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com';
|
|
29
29
|
// URL containing the public keys for Firebase session cookies. This will be updated to a different URL soon.
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
const SESSION_COOKIE_CERT_URL = 'https://www.googleapis.com/identitytoolkit/v3/relyingparty/publicKeys';
|
|
31
|
+
const EMULATOR_VERIFIER = new jwt_1.EmulatorSignatureVerifier();
|
|
32
32
|
/**
|
|
33
33
|
* User facing token information related to the Firebase ID token.
|
|
34
34
|
*
|
|
@@ -70,8 +70,8 @@ exports.SESSION_COOKIE_INFO = {
|
|
|
70
70
|
*
|
|
71
71
|
* @internal
|
|
72
72
|
*/
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
class FirebaseTokenVerifier {
|
|
74
|
+
constructor(clientCertUrl, issuer, tokenInfo, app) {
|
|
75
75
|
this.issuer = issuer;
|
|
76
76
|
this.tokenInfo = tokenInfo;
|
|
77
77
|
this.app = app;
|
|
@@ -111,77 +111,71 @@ var FirebaseTokenVerifier = /** @class */ (function () {
|
|
|
111
111
|
* @param isEmulator - Whether to accept Auth Emulator tokens.
|
|
112
112
|
* @returns A promise fulfilled with the decoded claims of the Firebase Auth ID token.
|
|
113
113
|
*/
|
|
114
|
-
|
|
115
|
-
var _this = this;
|
|
116
|
-
if (isEmulator === void 0) { isEmulator = false; }
|
|
114
|
+
verifyJWT(jwtToken, isEmulator = false) {
|
|
117
115
|
if (!validator.isString(jwtToken)) {
|
|
118
|
-
throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_ARGUMENT,
|
|
116
|
+
throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_ARGUMENT, `First argument to ${this.tokenInfo.verifyApiName} must be a ${this.tokenInfo.jwtName} string.`);
|
|
119
117
|
}
|
|
120
118
|
return this.ensureProjectId()
|
|
121
|
-
.then(
|
|
122
|
-
return
|
|
119
|
+
.then((projectId) => {
|
|
120
|
+
return this.decodeAndVerify(jwtToken, projectId, isEmulator);
|
|
123
121
|
})
|
|
124
|
-
.then(
|
|
125
|
-
|
|
122
|
+
.then((decoded) => {
|
|
123
|
+
const decodedIdToken = decoded.payload;
|
|
126
124
|
decodedIdToken.uid = decodedIdToken.sub;
|
|
127
125
|
return decodedIdToken;
|
|
128
126
|
});
|
|
129
|
-
}
|
|
127
|
+
}
|
|
130
128
|
/** @alpha */
|
|
131
129
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
132
|
-
|
|
133
|
-
var _this = this;
|
|
130
|
+
_verifyAuthBlockingToken(jwtToken, isEmulator, audience) {
|
|
134
131
|
if (!validator.isString(jwtToken)) {
|
|
135
|
-
throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_ARGUMENT,
|
|
132
|
+
throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_ARGUMENT, `First argument to ${this.tokenInfo.verifyApiName} must be a ${this.tokenInfo.jwtName} string.`);
|
|
136
133
|
}
|
|
137
134
|
return this.ensureProjectId()
|
|
138
|
-
.then(
|
|
135
|
+
.then((projectId) => {
|
|
139
136
|
if (typeof audience === 'undefined') {
|
|
140
|
-
audience = projectId
|
|
137
|
+
audience = `${projectId}.cloudfunctions.net/`;
|
|
141
138
|
}
|
|
142
|
-
return
|
|
139
|
+
return this.decodeAndVerify(jwtToken, projectId, isEmulator, audience);
|
|
143
140
|
})
|
|
144
|
-
.then(
|
|
145
|
-
|
|
141
|
+
.then((decoded) => {
|
|
142
|
+
const decodedAuthBlockingToken = decoded.payload;
|
|
146
143
|
decodedAuthBlockingToken.uid = decodedAuthBlockingToken.sub;
|
|
147
144
|
return decodedAuthBlockingToken;
|
|
148
145
|
});
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
var _this = this;
|
|
146
|
+
}
|
|
147
|
+
ensureProjectId() {
|
|
152
148
|
return util.findProjectId(this.app)
|
|
153
|
-
.then(
|
|
149
|
+
.then((projectId) => {
|
|
154
150
|
if (!validator.isNonEmptyString(projectId)) {
|
|
155
151
|
throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_CREDENTIAL, 'Must initialize app with a cert credential or set your Firebase project ID as the ' +
|
|
156
|
-
|
|
152
|
+
`GOOGLE_CLOUD_PROJECT environment variable to call ${this.tokenInfo.verifyApiName}.`);
|
|
157
153
|
}
|
|
158
154
|
return Promise.resolve(projectId);
|
|
159
155
|
});
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
var _this = this;
|
|
156
|
+
}
|
|
157
|
+
decodeAndVerify(token, projectId, isEmulator, audience) {
|
|
163
158
|
return this.safeDecode(token)
|
|
164
|
-
.then(
|
|
165
|
-
|
|
166
|
-
return
|
|
167
|
-
.then(
|
|
159
|
+
.then((decodedToken) => {
|
|
160
|
+
this.verifyContent(decodedToken, projectId, isEmulator, audience);
|
|
161
|
+
return this.verifySignature(token, isEmulator)
|
|
162
|
+
.then(() => decodedToken);
|
|
168
163
|
});
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
.catch(function (err) {
|
|
164
|
+
}
|
|
165
|
+
safeDecode(jwtToken) {
|
|
166
|
+
return (0, jwt_1.decodeJwt)(jwtToken)
|
|
167
|
+
.catch((err) => {
|
|
174
168
|
if (err.code == jwt_1.JwtErrorCode.INVALID_ARGUMENT) {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
169
|
+
const verifyJwtTokenDocsMessage = ` See ${this.tokenInfo.url} ` +
|
|
170
|
+
`for details on how to retrieve ${this.shortNameArticle} ${this.tokenInfo.shortName}.`;
|
|
171
|
+
const errorMessage = `Decoding ${this.tokenInfo.jwtName} failed. Make sure you passed ` +
|
|
172
|
+
`the entire string JWT which represents ${this.shortNameArticle} ` +
|
|
173
|
+
`${this.tokenInfo.shortName}.` + verifyJwtTokenDocsMessage;
|
|
180
174
|
throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_ARGUMENT, errorMessage);
|
|
181
175
|
}
|
|
182
176
|
throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INTERNAL_ERROR, err.message);
|
|
183
177
|
});
|
|
184
|
-
}
|
|
178
|
+
}
|
|
185
179
|
/**
|
|
186
180
|
* Verifies the content of a Firebase Auth JWT.
|
|
187
181
|
*
|
|
@@ -189,99 +183,97 @@ var FirebaseTokenVerifier = /** @class */ (function () {
|
|
|
189
183
|
* @param projectId - The Firebase Project Id.
|
|
190
184
|
* @param isEmulator - Whether the token is an Emulator token.
|
|
191
185
|
*/
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
186
|
+
verifyContent(fullDecodedToken, projectId, isEmulator, audience) {
|
|
187
|
+
const header = fullDecodedToken && fullDecodedToken.header;
|
|
188
|
+
const payload = fullDecodedToken && fullDecodedToken.payload;
|
|
189
|
+
const projectIdMatchMessage = ` Make sure the ${this.tokenInfo.shortName} comes from the same ` +
|
|
196
190
|
'Firebase project as the service account used to authenticate this SDK.';
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
191
|
+
const verifyJwtTokenDocsMessage = ` See ${this.tokenInfo.url} ` +
|
|
192
|
+
`for details on how to retrieve ${this.shortNameArticle} ${this.tokenInfo.shortName}.`;
|
|
193
|
+
let errorMessage;
|
|
200
194
|
if (!isEmulator && typeof header.kid === 'undefined') {
|
|
201
|
-
|
|
202
|
-
|
|
195
|
+
const isCustomToken = (payload.aud === FIREBASE_AUDIENCE);
|
|
196
|
+
const isLegacyCustomToken = (header.alg === 'HS256' && payload.v === 0 && 'd' in payload && 'uid' in payload.d);
|
|
203
197
|
if (isCustomToken) {
|
|
204
|
-
errorMessage = this.tokenInfo.verifyApiName
|
|
205
|
-
|
|
198
|
+
errorMessage = `${this.tokenInfo.verifyApiName} expects ${this.shortNameArticle} ` +
|
|
199
|
+
`${this.tokenInfo.shortName}, but was given a custom token.`;
|
|
206
200
|
}
|
|
207
201
|
else if (isLegacyCustomToken) {
|
|
208
|
-
errorMessage = this.tokenInfo.verifyApiName
|
|
209
|
-
|
|
202
|
+
errorMessage = `${this.tokenInfo.verifyApiName} expects ${this.shortNameArticle} ` +
|
|
203
|
+
`${this.tokenInfo.shortName}, but was given a legacy custom token.`;
|
|
210
204
|
}
|
|
211
205
|
else {
|
|
212
|
-
errorMessage = this.tokenInfo.jwtName
|
|
206
|
+
errorMessage = `${this.tokenInfo.jwtName} has no "kid" claim.`;
|
|
213
207
|
}
|
|
214
208
|
errorMessage += verifyJwtTokenDocsMessage;
|
|
215
209
|
}
|
|
216
210
|
else if (!isEmulator && header.alg !== jwt_1.ALGORITHM_RS256) {
|
|
217
|
-
errorMessage = this.tokenInfo.jwtName
|
|
211
|
+
errorMessage = `${this.tokenInfo.jwtName} has incorrect algorithm. Expected "` + jwt_1.ALGORITHM_RS256 + '" but got ' +
|
|
218
212
|
'"' + header.alg + '".' + verifyJwtTokenDocsMessage;
|
|
219
213
|
}
|
|
220
214
|
else if (typeof audience !== 'undefined' && !payload.aud.includes(audience)) {
|
|
221
|
-
errorMessage = this.tokenInfo.jwtName
|
|
215
|
+
errorMessage = `${this.tokenInfo.jwtName} has incorrect "aud" (audience) claim. Expected "` +
|
|
222
216
|
audience + '" but got "' + payload.aud + '".' + verifyJwtTokenDocsMessage;
|
|
223
217
|
}
|
|
224
218
|
else if (typeof audience === 'undefined' && payload.aud !== projectId) {
|
|
225
|
-
errorMessage = this.tokenInfo.jwtName
|
|
219
|
+
errorMessage = `${this.tokenInfo.jwtName} has incorrect "aud" (audience) claim. Expected "` +
|
|
226
220
|
projectId + '" but got "' + payload.aud + '".' + projectIdMatchMessage +
|
|
227
221
|
verifyJwtTokenDocsMessage;
|
|
228
222
|
}
|
|
229
223
|
else if (payload.iss !== this.issuer + projectId) {
|
|
230
|
-
errorMessage = this.tokenInfo.jwtName
|
|
231
|
-
|
|
224
|
+
errorMessage = `${this.tokenInfo.jwtName} has incorrect "iss" (issuer) claim. Expected ` +
|
|
225
|
+
`"${this.issuer}` + projectId + '" but got "' +
|
|
232
226
|
payload.iss + '".' + projectIdMatchMessage + verifyJwtTokenDocsMessage;
|
|
233
227
|
}
|
|
234
228
|
else if (typeof payload.sub !== 'string') {
|
|
235
|
-
errorMessage = this.tokenInfo.jwtName
|
|
229
|
+
errorMessage = `${this.tokenInfo.jwtName} has no "sub" (subject) claim.` + verifyJwtTokenDocsMessage;
|
|
236
230
|
}
|
|
237
231
|
else if (payload.sub === '') {
|
|
238
|
-
errorMessage = this.tokenInfo.jwtName
|
|
232
|
+
errorMessage = `${this.tokenInfo.jwtName} has an empty string "sub" (subject) claim.` + verifyJwtTokenDocsMessage;
|
|
239
233
|
}
|
|
240
234
|
else if (payload.sub.length > 128) {
|
|
241
|
-
errorMessage = this.tokenInfo.jwtName
|
|
235
|
+
errorMessage = `${this.tokenInfo.jwtName} has "sub" (subject) claim longer than 128 characters.` +
|
|
242
236
|
verifyJwtTokenDocsMessage;
|
|
243
237
|
}
|
|
244
238
|
if (errorMessage) {
|
|
245
239
|
throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_ARGUMENT, errorMessage);
|
|
246
240
|
}
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
var verifier = isEmulator ? EMULATOR_VERIFIER : this.signatureVerifier;
|
|
241
|
+
}
|
|
242
|
+
verifySignature(jwtToken, isEmulator) {
|
|
243
|
+
const verifier = isEmulator ? EMULATOR_VERIFIER : this.signatureVerifier;
|
|
251
244
|
return verifier.verify(jwtToken)
|
|
252
|
-
.catch(
|
|
253
|
-
throw
|
|
245
|
+
.catch((error) => {
|
|
246
|
+
throw this.mapJwtErrorToAuthError(error);
|
|
254
247
|
});
|
|
255
|
-
}
|
|
248
|
+
}
|
|
256
249
|
/**
|
|
257
250
|
* Maps JwtError to FirebaseAuthError
|
|
258
251
|
*
|
|
259
252
|
* @param error - JwtError to be mapped.
|
|
260
253
|
* @returns FirebaseAuthError or Error instance.
|
|
261
254
|
*/
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
255
|
+
mapJwtErrorToAuthError(error) {
|
|
256
|
+
const verifyJwtTokenDocsMessage = ` See ${this.tokenInfo.url} ` +
|
|
257
|
+
`for details on how to retrieve ${this.shortNameArticle} ${this.tokenInfo.shortName}.`;
|
|
265
258
|
if (error.code === jwt_1.JwtErrorCode.TOKEN_EXPIRED) {
|
|
266
|
-
|
|
267
|
-
|
|
259
|
+
const errorMessage = `${this.tokenInfo.jwtName} has expired. Get a fresh ${this.tokenInfo.shortName}` +
|
|
260
|
+
` from your client app and try again (auth/${this.tokenInfo.expiredErrorCode.code}).` +
|
|
268
261
|
verifyJwtTokenDocsMessage;
|
|
269
262
|
return new error_1.FirebaseAuthError(this.tokenInfo.expiredErrorCode, errorMessage);
|
|
270
263
|
}
|
|
271
264
|
else if (error.code === jwt_1.JwtErrorCode.INVALID_SIGNATURE) {
|
|
272
|
-
|
|
265
|
+
const errorMessage = `${this.tokenInfo.jwtName} has invalid signature.` + verifyJwtTokenDocsMessage;
|
|
273
266
|
return new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_ARGUMENT, errorMessage);
|
|
274
267
|
}
|
|
275
268
|
else if (error.code === jwt_1.JwtErrorCode.NO_MATCHING_KID) {
|
|
276
|
-
|
|
277
|
-
|
|
269
|
+
const errorMessage = `${this.tokenInfo.jwtName} has "kid" claim which does not ` +
|
|
270
|
+
`correspond to a known public key. Most likely the ${this.tokenInfo.shortName} ` +
|
|
278
271
|
'is expired, so get a fresh token from your client app and try again.';
|
|
279
272
|
return new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_ARGUMENT, errorMessage);
|
|
280
273
|
}
|
|
281
274
|
return new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_ARGUMENT, error.message);
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
}());
|
|
275
|
+
}
|
|
276
|
+
}
|
|
285
277
|
exports.FirebaseTokenVerifier = FirebaseTokenVerifier;
|
|
286
278
|
/**
|
|
287
279
|
* Creates a new FirebaseTokenVerifier to verify Firebase ID tokens.
|