firebase-admin 9.4.2 → 9.5.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/lib/auth/action-code-settings-builder.js +1 -1
- package/lib/auth/auth-api-request.js +52 -10
- package/lib/auth/auth-config.js +1 -1
- package/lib/auth/auth.js +78 -47
- package/lib/auth/identifier.js +1 -1
- package/lib/auth/index.d.ts +70 -1
- package/lib/auth/index.js +1 -1
- package/lib/auth/tenant-manager.js +1 -1
- package/lib/auth/tenant.js +7 -1
- package/lib/auth/token-generator.js +1 -1
- package/lib/auth/token-verifier.js +16 -20
- package/lib/auth/user-import-builder.js +1 -1
- package/lib/auth/user-record.js +1 -1
- package/lib/credential/credential-internal.js +1 -1
- package/lib/credential/credential.js +1 -1
- package/lib/credential/index.d.ts +1 -1
- package/lib/credential/index.js +1 -1
- package/lib/database/database-internal.js +19 -26
- package/lib/database/index.d.ts +1 -1
- package/lib/database/index.js +1 -1
- package/lib/default-namespace.js +1 -1
- package/lib/firebase-app.js +10 -33
- package/lib/firebase-namespace-api.d.ts +1 -1
- package/lib/firebase-namespace-api.js +1 -1
- package/lib/firebase-namespace.d.ts +1 -1
- package/lib/firebase-namespace.js +2 -67
- package/lib/firestore/firestore-internal.js +1 -19
- package/lib/firestore/index.d.ts +1 -1
- package/lib/firestore/index.js +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -1
- package/lib/instance-id/index.d.ts +1 -1
- package/lib/instance-id/index.js +1 -1
- package/lib/instance-id/instance-id-request-internal.js +1 -1
- package/lib/instance-id/instance-id.js +1 -19
- package/lib/machine-learning/index.d.ts +1 -1
- package/lib/machine-learning/index.js +1 -1
- package/lib/machine-learning/machine-learning-api-client.js +1 -1
- package/lib/machine-learning/machine-learning-utils.js +1 -1
- package/lib/machine-learning/machine-learning.js +1 -20
- package/lib/messaging/batch-request-internal.js +1 -1
- package/lib/messaging/index.d.ts +4 -4
- package/lib/messaging/index.js +1 -1
- package/lib/messaging/messaging-api-request-internal.js +1 -1
- package/lib/messaging/messaging-errors-internal.js +1 -1
- package/lib/messaging/messaging-internal.js +1 -1
- package/lib/messaging/messaging.js +1 -19
- package/lib/project-management/android-app.js +1 -1
- package/lib/project-management/index.d.ts +1 -1
- package/lib/project-management/index.js +1 -1
- package/lib/project-management/ios-app.js +1 -1
- package/lib/project-management/project-management-api-request-internal.js +1 -1
- package/lib/project-management/project-management.js +1 -19
- package/lib/remote-config/index.d.ts +1 -1
- package/lib/remote-config/index.js +1 -1
- package/lib/remote-config/remote-config-api-client-internal.js +1 -1
- package/lib/remote-config/remote-config.js +5 -21
- package/lib/security-rules/index.d.ts +1 -1
- package/lib/security-rules/index.js +1 -1
- package/lib/security-rules/security-rules-api-client-internal.js +1 -1
- package/lib/security-rules/security-rules-internal.js +1 -1
- package/lib/security-rules/security-rules.js +1 -10
- package/lib/storage/index.d.ts +1 -1
- package/lib/storage/index.js +1 -1
- package/lib/storage/storage.js +1 -19
- package/lib/utils/api-request.js +1 -1
- package/lib/utils/deep-copy.js +1 -1
- package/lib/utils/error.js +1 -1
- package/lib/utils/index.js +1 -1
- package/lib/utils/validator.js +1 -1
- package/package.json +2 -2
- package/lib/firebase-service.js +0 -19
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! firebase-admin v9.
|
|
1
|
+
/*! firebase-admin v9.5.0 */
|
|
2
2
|
"use strict";
|
|
3
3
|
/*!
|
|
4
4
|
* @license
|
|
@@ -337,6 +337,8 @@ function validateCreateEditRequest(request, writeOperationType) {
|
|
|
337
337
|
phoneNumber: true,
|
|
338
338
|
customAttributes: true,
|
|
339
339
|
validSince: true,
|
|
340
|
+
// Pass linkProviderUserInfo only for updates (i.e. not for uploads.)
|
|
341
|
+
linkProviderUserInfo: !uploadAccountRequest,
|
|
340
342
|
// Pass tenantId only for uploadAccount requests.
|
|
341
343
|
tenantId: uploadAccountRequest,
|
|
342
344
|
passwordHash: uploadAccountRequest,
|
|
@@ -481,6 +483,10 @@ function validateCreateEditRequest(request, writeOperationType) {
|
|
|
481
483
|
validateProviderUserInfo(providerUserInfoEntry);
|
|
482
484
|
});
|
|
483
485
|
}
|
|
486
|
+
// linkProviderUserInfo must be a (single) UserProvider value.
|
|
487
|
+
if (typeof request.linkProviderUserInfo !== 'undefined') {
|
|
488
|
+
validateProviderUserInfo(request.linkProviderUserInfo);
|
|
489
|
+
}
|
|
484
490
|
// mfaInfo is used for importUsers.
|
|
485
491
|
// mfa.enrollments is used for setAccountInfo.
|
|
486
492
|
// enrollments has to be an array of valid AuthFactorInfo requests.
|
|
@@ -876,6 +882,18 @@ var AbstractAuthRequestHandler = /** @class */ (function () {
|
|
|
876
882
|
};
|
|
877
883
|
return this.invokeRequestHandler(this.getAuthUrlBuilder(), exports.FIREBASE_AUTH_GET_ACCOUNT_INFO, request);
|
|
878
884
|
};
|
|
885
|
+
AbstractAuthRequestHandler.prototype.getAccountInfoByFederatedUid = function (providerId, rawId) {
|
|
886
|
+
if (!validator.isNonEmptyString(providerId) || !validator.isNonEmptyString(rawId)) {
|
|
887
|
+
throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_PROVIDER_ID);
|
|
888
|
+
}
|
|
889
|
+
var request = {
|
|
890
|
+
federatedUserId: [{
|
|
891
|
+
providerId: providerId,
|
|
892
|
+
rawId: rawId,
|
|
893
|
+
}],
|
|
894
|
+
};
|
|
895
|
+
return this.invokeRequestHandler(this.getAuthUrlBuilder(), exports.FIREBASE_AUTH_GET_ACCOUNT_INFO, request);
|
|
896
|
+
};
|
|
879
897
|
/**
|
|
880
898
|
* Looks up multiple users by their identifiers (uid, email, etc).
|
|
881
899
|
*
|
|
@@ -1064,6 +1082,26 @@ var AbstractAuthRequestHandler = /** @class */ (function () {
|
|
|
1064
1082
|
else if (!validator.isNonNullObject(properties)) {
|
|
1065
1083
|
return Promise.reject(new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_ARGUMENT, 'Properties argument must be a non-null object.'));
|
|
1066
1084
|
}
|
|
1085
|
+
else if (validator.isNonNullObject(properties.providerToLink)) {
|
|
1086
|
+
// TODO(rsgowman): These checks overlap somewhat with
|
|
1087
|
+
// validateProviderUserInfo. It may be possible to refactor a bit.
|
|
1088
|
+
if (!validator.isNonEmptyString(properties.providerToLink.providerId)) {
|
|
1089
|
+
throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_ARGUMENT, 'providerToLink.providerId of properties argument must be a non-empty string.');
|
|
1090
|
+
}
|
|
1091
|
+
if (!validator.isNonEmptyString(properties.providerToLink.uid)) {
|
|
1092
|
+
throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_ARGUMENT, 'providerToLink.uid of properties argument must be a non-empty string.');
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
else if (typeof properties.providersToUnlink !== 'undefined') {
|
|
1096
|
+
if (!validator.isArray(properties.providersToUnlink)) {
|
|
1097
|
+
throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_ARGUMENT, 'providersToUnlink of properties argument must be an array of strings.');
|
|
1098
|
+
}
|
|
1099
|
+
properties.providersToUnlink.forEach(function (providerId) {
|
|
1100
|
+
if (!validator.isNonEmptyString(providerId)) {
|
|
1101
|
+
throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_ARGUMENT, 'providersToUnlink of properties argument must be an array of strings.');
|
|
1102
|
+
}
|
|
1103
|
+
});
|
|
1104
|
+
}
|
|
1067
1105
|
// Build the setAccountInfo request.
|
|
1068
1106
|
var request = deep_copy_1.deepCopy(properties);
|
|
1069
1107
|
request.localId = uid;
|
|
@@ -1094,14 +1132,22 @@ var AbstractAuthRequestHandler = /** @class */ (function () {
|
|
|
1094
1132
|
// It will be removed from the backend request and an additional parameter
|
|
1095
1133
|
// deleteProvider: ['phone'] with an array of providerIds (phone in this case),
|
|
1096
1134
|
// will be passed.
|
|
1097
|
-
// Currently this applies to phone provider only.
|
|
1098
1135
|
if (request.phoneNumber === null) {
|
|
1099
|
-
request.deleteProvider = ['phone'];
|
|
1136
|
+
request.deleteProvider ? request.deleteProvider.push('phone') : request.deleteProvider = ['phone'];
|
|
1100
1137
|
delete request.phoneNumber;
|
|
1101
1138
|
}
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
delete request.
|
|
1139
|
+
if (typeof (request.providerToLink) !== 'undefined') {
|
|
1140
|
+
request.linkProviderUserInfo = deep_copy_1.deepCopy(request.providerToLink);
|
|
1141
|
+
delete request.providerToLink;
|
|
1142
|
+
request.linkProviderUserInfo.rawId = request.linkProviderUserInfo.uid;
|
|
1143
|
+
delete request.linkProviderUserInfo.uid;
|
|
1144
|
+
}
|
|
1145
|
+
if (typeof (request.providersToUnlink) !== 'undefined') {
|
|
1146
|
+
if (!validator.isArray(request.deleteProvider)) {
|
|
1147
|
+
request.deleteProvider = [];
|
|
1148
|
+
}
|
|
1149
|
+
request.deleteProvider = request.deleteProvider.concat(request.providersToUnlink);
|
|
1150
|
+
delete request.providersToUnlink;
|
|
1105
1151
|
}
|
|
1106
1152
|
// Rewrite photoURL to photoUrl.
|
|
1107
1153
|
if (typeof request.photoURL !== 'undefined') {
|
|
@@ -1805,10 +1851,6 @@ function emulatorHost() {
|
|
|
1805
1851
|
/**
|
|
1806
1852
|
* When true the SDK should communicate with the Auth Emulator for all API
|
|
1807
1853
|
* calls and also produce unsigned tokens.
|
|
1808
|
-
*
|
|
1809
|
-
* This alone does <b>NOT<b> short-circuit ID Token verification.
|
|
1810
|
-
* For security reasons that must be explicitly disabled through
|
|
1811
|
-
* setJwtVerificationEnabled(false);
|
|
1812
1854
|
*/
|
|
1813
1855
|
function useEmulator() {
|
|
1814
1856
|
return !!emulatorHost();
|
package/lib/auth/auth-config.js
CHANGED
package/lib/auth/auth.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! firebase-admin v9.
|
|
1
|
+
/*! firebase-admin v9.5.0 */
|
|
2
2
|
"use strict";
|
|
3
3
|
/*!
|
|
4
4
|
* @license
|
|
@@ -31,6 +31,7 @@ var __extends = (this && this.__extends) || (function () {
|
|
|
31
31
|
})();
|
|
32
32
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
33
33
|
exports.Auth = exports.TenantAwareAuth = exports.BaseAuth = void 0;
|
|
34
|
+
var deep_copy_1 = require("../utils/deep-copy");
|
|
34
35
|
var user_record_1 = require("./user-record");
|
|
35
36
|
var identifier_1 = require("./identifier");
|
|
36
37
|
var token_generator_1 = require("./token-generator");
|
|
@@ -41,23 +42,6 @@ var validator = require("../utils/validator");
|
|
|
41
42
|
var token_verifier_1 = require("./token-verifier");
|
|
42
43
|
var auth_config_1 = require("./auth-config");
|
|
43
44
|
var tenant_manager_1 = require("./tenant-manager");
|
|
44
|
-
/**
|
|
45
|
-
* Internals of an Auth instance.
|
|
46
|
-
*/
|
|
47
|
-
var AuthInternals = /** @class */ (function () {
|
|
48
|
-
function AuthInternals() {
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Deletes the service and its associated resources.
|
|
52
|
-
*
|
|
53
|
-
* @return {Promise<()>} An empty Promise that will be fulfilled when the service is deleted.
|
|
54
|
-
*/
|
|
55
|
-
AuthInternals.prototype.delete = function () {
|
|
56
|
-
// There are no resources to clean up
|
|
57
|
-
return Promise.resolve(undefined);
|
|
58
|
-
};
|
|
59
|
-
return AuthInternals;
|
|
60
|
-
}());
|
|
61
45
|
/**
|
|
62
46
|
* Base Auth class. Mainly used for user management APIs.
|
|
63
47
|
*/
|
|
@@ -111,13 +95,14 @@ var BaseAuth = /** @class */ (function () {
|
|
|
111
95
|
BaseAuth.prototype.verifyIdToken = function (idToken, checkRevoked) {
|
|
112
96
|
var _this = this;
|
|
113
97
|
if (checkRevoked === void 0) { checkRevoked = false; }
|
|
114
|
-
|
|
98
|
+
var isEmulator = auth_api_request_1.useEmulator();
|
|
99
|
+
return this.idTokenVerifier.verifyJWT(idToken, isEmulator)
|
|
115
100
|
.then(function (decodedIdToken) {
|
|
116
101
|
// Whether to check if the token was revoked.
|
|
117
|
-
if (
|
|
118
|
-
return decodedIdToken;
|
|
102
|
+
if (checkRevoked || isEmulator) {
|
|
103
|
+
return _this.verifyDecodedJWTNotRevoked(decodedIdToken, error_1.AuthClientErrorCode.ID_TOKEN_REVOKED);
|
|
119
104
|
}
|
|
120
|
-
return
|
|
105
|
+
return decodedIdToken;
|
|
121
106
|
});
|
|
122
107
|
};
|
|
123
108
|
/**
|
|
@@ -162,6 +147,35 @@ var BaseAuth = /** @class */ (function () {
|
|
|
162
147
|
return new user_record_1.UserRecord(response.users[0]);
|
|
163
148
|
});
|
|
164
149
|
};
|
|
150
|
+
/**
|
|
151
|
+
* Gets the user data for the user corresponding to a given provider id.
|
|
152
|
+
*
|
|
153
|
+
* See [Retrieve user data](/docs/auth/admin/manage-users#retrieve_user_data)
|
|
154
|
+
* for code samples and detailed documentation.
|
|
155
|
+
*
|
|
156
|
+
* @param providerId The provider ID, for example, "google.com" for the
|
|
157
|
+
* Google provider.
|
|
158
|
+
* @param uid The user identifier for the given provider.
|
|
159
|
+
*
|
|
160
|
+
* @return A promise fulfilled with the user data corresponding to the
|
|
161
|
+
* given provider id.
|
|
162
|
+
*/
|
|
163
|
+
BaseAuth.prototype.getUserByProviderUid = function (providerId, uid) {
|
|
164
|
+
// Although we don't really advertise it, we want to also handle
|
|
165
|
+
// non-federated idps with this call. So if we detect one of them, we'll
|
|
166
|
+
// reroute this request appropriately.
|
|
167
|
+
if (providerId === 'phone') {
|
|
168
|
+
return this.getUserByPhoneNumber(uid);
|
|
169
|
+
}
|
|
170
|
+
else if (providerId === 'email') {
|
|
171
|
+
return this.getUserByEmail(uid);
|
|
172
|
+
}
|
|
173
|
+
return this.authRequestHandler.getAccountInfoByFederatedUid(providerId, uid)
|
|
174
|
+
.then(function (response) {
|
|
175
|
+
// Returns the user record populated with server response.
|
|
176
|
+
return new user_record_1.UserRecord(response.users[0]);
|
|
177
|
+
});
|
|
178
|
+
};
|
|
165
179
|
/**
|
|
166
180
|
* Gets the user data corresponding to the specified identifiers.
|
|
167
181
|
*
|
|
@@ -326,6 +340,43 @@ var BaseAuth = /** @class */ (function () {
|
|
|
326
340
|
*/
|
|
327
341
|
BaseAuth.prototype.updateUser = function (uid, properties) {
|
|
328
342
|
var _this = this;
|
|
343
|
+
// Although we don't really advertise it, we want to also handle linking of
|
|
344
|
+
// non-federated idps with this call. So if we detect one of them, we'll
|
|
345
|
+
// adjust the properties parameter appropriately. This *does* imply that a
|
|
346
|
+
// conflict could arise, e.g. if the user provides a phoneNumber property,
|
|
347
|
+
// but also provides a providerToLink with a 'phone' provider id. In that
|
|
348
|
+
// case, we'll throw an error.
|
|
349
|
+
properties = deep_copy_1.deepCopy(properties);
|
|
350
|
+
if (properties === null || properties === void 0 ? void 0 : properties.providerToLink) {
|
|
351
|
+
if (properties.providerToLink.providerId === 'email') {
|
|
352
|
+
if (typeof properties.email !== 'undefined') {
|
|
353
|
+
throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_ARGUMENT, "Both UpdateRequest.email and UpdateRequest.providerToLink.providerId='email' were set. To "
|
|
354
|
+
+ 'link to the email/password provider, only specify the UpdateRequest.email field.');
|
|
355
|
+
}
|
|
356
|
+
properties.email = properties.providerToLink.uid;
|
|
357
|
+
delete properties.providerToLink;
|
|
358
|
+
}
|
|
359
|
+
else if (properties.providerToLink.providerId === 'phone') {
|
|
360
|
+
if (typeof properties.phoneNumber !== 'undefined') {
|
|
361
|
+
throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_ARGUMENT, "Both UpdateRequest.phoneNumber and UpdateRequest.providerToLink.providerId='phone' were set. To "
|
|
362
|
+
+ 'link to a phone provider, only specify the UpdateRequest.phoneNumber field.');
|
|
363
|
+
}
|
|
364
|
+
properties.phoneNumber = properties.providerToLink.uid;
|
|
365
|
+
delete properties.providerToLink;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
if (properties === null || properties === void 0 ? void 0 : properties.providersToUnlink) {
|
|
369
|
+
if (properties.providersToUnlink.indexOf('phone') !== -1) {
|
|
370
|
+
// If we've been told to unlink the phone provider both via setting
|
|
371
|
+
// phoneNumber to null *and* by setting providersToUnlink to include
|
|
372
|
+
// 'phone', then we'll reject that. Though it might also be reasonable
|
|
373
|
+
// to relax this restriction and just unlink it.
|
|
374
|
+
if (properties.phoneNumber === null) {
|
|
375
|
+
throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_ARGUMENT, "Both UpdateRequest.phoneNumber=null and UpdateRequest.providersToUnlink=['phone'] were set. To "
|
|
376
|
+
+ 'unlink from a phone provider, only specify the UpdateRequest.phoneNumber=null field.');
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
}
|
|
329
380
|
return this.authRequestHandler.updateExistingAccount(uid, properties)
|
|
330
381
|
.then(function (existingUid) {
|
|
331
382
|
// Return the corresponding user record.
|
|
@@ -412,13 +463,14 @@ var BaseAuth = /** @class */ (function () {
|
|
|
412
463
|
BaseAuth.prototype.verifySessionCookie = function (sessionCookie, checkRevoked) {
|
|
413
464
|
var _this = this;
|
|
414
465
|
if (checkRevoked === void 0) { checkRevoked = false; }
|
|
415
|
-
|
|
466
|
+
var isEmulator = auth_api_request_1.useEmulator();
|
|
467
|
+
return this.sessionCookieVerifier.verifyJWT(sessionCookie, isEmulator)
|
|
416
468
|
.then(function (decodedIdToken) {
|
|
417
469
|
// Whether to check if the token was revoked.
|
|
418
|
-
if (
|
|
419
|
-
return decodedIdToken;
|
|
470
|
+
if (checkRevoked || isEmulator) {
|
|
471
|
+
return _this.verifyDecodedJWTNotRevoked(decodedIdToken, error_1.AuthClientErrorCode.SESSION_COOKIE_REVOKED);
|
|
420
472
|
}
|
|
421
|
-
return
|
|
473
|
+
return decodedIdToken;
|
|
422
474
|
});
|
|
423
475
|
};
|
|
424
476
|
/**
|
|
@@ -627,26 +679,6 @@ var BaseAuth = /** @class */ (function () {
|
|
|
627
679
|
return decodedIdToken;
|
|
628
680
|
});
|
|
629
681
|
};
|
|
630
|
-
/**
|
|
631
|
-
* Enable or disable ID token verification. This is used to safely short-circuit token verification with the
|
|
632
|
-
* Auth emulator. When disabled ONLY unsigned tokens will pass verification, production tokens will not pass.
|
|
633
|
-
*
|
|
634
|
-
* WARNING: This is a dangerous method that will compromise your app's security and break your app in
|
|
635
|
-
* production. Developers should never call this method, it is for internal testing use only.
|
|
636
|
-
*
|
|
637
|
-
* @internal
|
|
638
|
-
*/
|
|
639
|
-
// @ts-expect-error: this method appears unused but is used privately.
|
|
640
|
-
BaseAuth.prototype.setJwtVerificationEnabled = function (enabled) {
|
|
641
|
-
if (!enabled && !auth_api_request_1.useEmulator()) {
|
|
642
|
-
// We only allow verification to be disabled in conjunction with
|
|
643
|
-
// the emulator environment variable.
|
|
644
|
-
throw new Error('This method is only available when connected to the Authentication emulator.');
|
|
645
|
-
}
|
|
646
|
-
var algorithm = enabled ? token_verifier_1.ALGORITHM_RS256 : 'none';
|
|
647
|
-
this.idTokenVerifier.setAlgorithm(algorithm);
|
|
648
|
-
this.sessionCookieVerifier.setAlgorithm(algorithm);
|
|
649
|
-
};
|
|
650
682
|
return BaseAuth;
|
|
651
683
|
}());
|
|
652
684
|
exports.BaseAuth = BaseAuth;
|
|
@@ -759,7 +791,6 @@ var Auth = /** @class */ (function (_super) {
|
|
|
759
791
|
*/
|
|
760
792
|
function Auth(app) {
|
|
761
793
|
var _this = _super.call(this, app, new auth_api_request_1.AuthRequestHandler(app)) || this;
|
|
762
|
-
_this.INTERNAL = new AuthInternals();
|
|
763
794
|
_this.app_ = app;
|
|
764
795
|
_this.tenantManager_ = new tenant_manager_1.TenantManager(app);
|
|
765
796
|
return _this;
|
package/lib/auth/identifier.js
CHANGED
package/lib/auth/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! firebase-admin v9.
|
|
1
|
+
/*! firebase-admin v9.5.0 */
|
|
2
2
|
/*!
|
|
3
3
|
* Copyright 2020 Google Inc.
|
|
4
4
|
*
|
|
@@ -130,6 +130,35 @@ export declare namespace auth {
|
|
|
130
130
|
*/
|
|
131
131
|
phoneNumber: string;
|
|
132
132
|
}
|
|
133
|
+
/**
|
|
134
|
+
* Represents a user identity provider that can be associated with a Firebase user.
|
|
135
|
+
*/
|
|
136
|
+
interface UserProvider {
|
|
137
|
+
/**
|
|
138
|
+
* The user identifier for the linked provider.
|
|
139
|
+
*/
|
|
140
|
+
uid?: string;
|
|
141
|
+
/**
|
|
142
|
+
* The display name for the linked provider.
|
|
143
|
+
*/
|
|
144
|
+
displayName?: string;
|
|
145
|
+
/**
|
|
146
|
+
* The email for the linked provider.
|
|
147
|
+
*/
|
|
148
|
+
email?: string;
|
|
149
|
+
/**
|
|
150
|
+
* The phone number for the linked provider.
|
|
151
|
+
*/
|
|
152
|
+
phoneNumber?: string;
|
|
153
|
+
/**
|
|
154
|
+
* The photo URL for the linked provider.
|
|
155
|
+
*/
|
|
156
|
+
photoURL?: string;
|
|
157
|
+
/**
|
|
158
|
+
* The linked provider ID (for example, "google.com" for the Google provider).
|
|
159
|
+
*/
|
|
160
|
+
providerId?: string;
|
|
161
|
+
}
|
|
133
162
|
/**
|
|
134
163
|
* Interface representing a user.
|
|
135
164
|
*/
|
|
@@ -325,6 +354,24 @@ export declare namespace auth {
|
|
|
325
354
|
* The user's updated multi-factor related properties.
|
|
326
355
|
*/
|
|
327
356
|
multiFactor?: MultiFactorUpdateSettings;
|
|
357
|
+
/**
|
|
358
|
+
* Links this user to the specified provider.
|
|
359
|
+
*
|
|
360
|
+
* Linking a provider to an existing user account does not invalidate the
|
|
361
|
+
* refresh token of that account. In other words, the existing account
|
|
362
|
+
* would continue to be able to access resources, despite not having used
|
|
363
|
+
* the newly linked provider to log in. If you wish to force the user to
|
|
364
|
+
* authenticate with this new provider, you need to (a) revoke their
|
|
365
|
+
* refresh token (see
|
|
366
|
+
* https://firebase.google.com/docs/auth/admin/manage-sessions#revoke_refresh_tokens),
|
|
367
|
+
* and (b) ensure no other authentication methods are present on this
|
|
368
|
+
* account.
|
|
369
|
+
*/
|
|
370
|
+
providerToLink?: UserProvider;
|
|
371
|
+
/**
|
|
372
|
+
* Unlinks this user from the specified providers.
|
|
373
|
+
*/
|
|
374
|
+
providersToUnlink?: string[];
|
|
328
375
|
}
|
|
329
376
|
/**
|
|
330
377
|
* Interface representing base properties of a user enrolled second factor for a
|
|
@@ -863,6 +910,10 @@ export declare namespace auth {
|
|
|
863
910
|
*/
|
|
864
911
|
passwordRequired?: boolean;
|
|
865
912
|
};
|
|
913
|
+
/**
|
|
914
|
+
* Whether the anonymous provider is enabled.
|
|
915
|
+
*/
|
|
916
|
+
anonymousSignInEnabled: boolean;
|
|
866
917
|
/**
|
|
867
918
|
* The multi-factor auth configuration on the current tenant.
|
|
868
919
|
*/
|
|
@@ -928,6 +979,10 @@ export declare namespace auth {
|
|
|
928
979
|
* The email sign in configuration.
|
|
929
980
|
*/
|
|
930
981
|
emailSignInConfig?: EmailSignInProviderConfig;
|
|
982
|
+
/**
|
|
983
|
+
* Whether the anonymous provider is enabled.
|
|
984
|
+
*/
|
|
985
|
+
anonymousSignInEnabled?: boolean;
|
|
931
986
|
/**
|
|
932
987
|
* The multi-factor auth configuration to update on the tenant.
|
|
933
988
|
*/
|
|
@@ -1302,6 +1357,20 @@ export declare namespace auth {
|
|
|
1302
1357
|
* data corresponding to the provided phone number.
|
|
1303
1358
|
*/
|
|
1304
1359
|
getUserByPhoneNumber(phoneNumber: string): Promise<UserRecord>;
|
|
1360
|
+
/**
|
|
1361
|
+
* Gets the user data for the user corresponding to a given provider ID.
|
|
1362
|
+
*
|
|
1363
|
+
* See [Retrieve user data](/docs/auth/admin/manage-users#retrieve_user_data)
|
|
1364
|
+
* for code samples and detailed documentation.
|
|
1365
|
+
*
|
|
1366
|
+
* @param providerId The provider ID, for example, "google.com" for the
|
|
1367
|
+
* Google provider.
|
|
1368
|
+
* @param uid The user identifier for the given provider.
|
|
1369
|
+
*
|
|
1370
|
+
* @return A promise fulfilled with the user data corresponding to the
|
|
1371
|
+
* given provider id.
|
|
1372
|
+
*/
|
|
1373
|
+
getUserByProviderUid(providerId: string, uid: string): Promise<UserRecord>;
|
|
1305
1374
|
/**
|
|
1306
1375
|
* Gets the user data corresponding to the specified identifiers.
|
|
1307
1376
|
*
|
package/lib/auth/index.js
CHANGED
package/lib/auth/tenant.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! firebase-admin v9.
|
|
1
|
+
/*! firebase-admin v9.5.0 */
|
|
2
2
|
"use strict";
|
|
3
3
|
/*!
|
|
4
4
|
* Copyright 2019 Google Inc.
|
|
@@ -47,6 +47,7 @@ var Tenant = /** @class */ (function () {
|
|
|
47
47
|
allowPasswordSignup: false,
|
|
48
48
|
});
|
|
49
49
|
}
|
|
50
|
+
this.anonymousSignInEnabled = !!response.enableAnonymousUser;
|
|
50
51
|
if (typeof response.mfaConfig !== 'undefined') {
|
|
51
52
|
this.multiFactorConfig = new auth_config_1.MultiFactorAuthConfig(response.mfaConfig);
|
|
52
53
|
}
|
|
@@ -71,6 +72,9 @@ var Tenant = /** @class */ (function () {
|
|
|
71
72
|
if (typeof tenantOptions.displayName !== 'undefined') {
|
|
72
73
|
request.displayName = tenantOptions.displayName;
|
|
73
74
|
}
|
|
75
|
+
if (typeof tenantOptions.anonymousSignInEnabled !== 'undefined') {
|
|
76
|
+
request.enableAnonymousUser = tenantOptions.anonymousSignInEnabled;
|
|
77
|
+
}
|
|
74
78
|
if (typeof tenantOptions.multiFactorConfig !== 'undefined') {
|
|
75
79
|
request.mfaConfig = auth_config_1.MultiFactorAuthConfig.buildServerRequest(tenantOptions.multiFactorConfig);
|
|
76
80
|
}
|
|
@@ -104,6 +108,7 @@ var Tenant = /** @class */ (function () {
|
|
|
104
108
|
var validKeys = {
|
|
105
109
|
displayName: true,
|
|
106
110
|
emailSignInConfig: true,
|
|
111
|
+
anonymousSignInEnabled: true,
|
|
107
112
|
multiFactorConfig: true,
|
|
108
113
|
testPhoneNumbers: true,
|
|
109
114
|
};
|
|
@@ -149,6 +154,7 @@ var Tenant = /** @class */ (function () {
|
|
|
149
154
|
tenantId: this.tenantId,
|
|
150
155
|
displayName: this.displayName,
|
|
151
156
|
emailSignInConfig: (_a = this.emailSignInConfig) === null || _a === void 0 ? void 0 : _a.toJSON(),
|
|
157
|
+
anonymousSignInEnabled: this.anonymousSignInEnabled,
|
|
152
158
|
multiFactorConfig: (_b = this.multiFactorConfig) === null || _b === void 0 ? void 0 : _b.toJSON(),
|
|
153
159
|
testPhoneNumbers: this.testPhoneNumbers,
|
|
154
160
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! firebase-admin v9.
|
|
1
|
+
/*! firebase-admin v9.5.0 */
|
|
2
2
|
"use strict";
|
|
3
3
|
/*!
|
|
4
4
|
* Copyright 2018 Google Inc.
|
|
@@ -90,27 +90,22 @@ var FirebaseTokenVerifier = /** @class */ (function () {
|
|
|
90
90
|
* Verifies the format and signature of a Firebase Auth JWT token.
|
|
91
91
|
*
|
|
92
92
|
* @param {string} jwtToken The Firebase Auth JWT token to verify.
|
|
93
|
+
* @param {boolean=} isEmulator Whether to accept Auth Emulator tokens.
|
|
93
94
|
* @return {Promise<DecodedIdToken>} A promise fulfilled with the decoded claims of the Firebase Auth ID
|
|
94
95
|
* token.
|
|
95
96
|
*/
|
|
96
|
-
FirebaseTokenVerifier.prototype.verifyJWT = function (jwtToken) {
|
|
97
|
+
FirebaseTokenVerifier.prototype.verifyJWT = function (jwtToken, isEmulator) {
|
|
97
98
|
var _this = this;
|
|
99
|
+
if (isEmulator === void 0) { isEmulator = false; }
|
|
98
100
|
if (!validator.isString(jwtToken)) {
|
|
99
101
|
throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_ARGUMENT, "First argument to " + this.tokenInfo.verifyApiName + " must be a " + this.tokenInfo.jwtName + " string.");
|
|
100
102
|
}
|
|
101
103
|
return util.findProjectId(this.app)
|
|
102
104
|
.then(function (projectId) {
|
|
103
|
-
return _this.verifyJWTWithProjectId(jwtToken, projectId);
|
|
105
|
+
return _this.verifyJWTWithProjectId(jwtToken, projectId, isEmulator);
|
|
104
106
|
});
|
|
105
107
|
};
|
|
106
|
-
|
|
107
|
-
* Override the JWT signing algorithm.
|
|
108
|
-
* @param algorithm the new signing algorithm.
|
|
109
|
-
*/
|
|
110
|
-
FirebaseTokenVerifier.prototype.setAlgorithm = function (algorithm) {
|
|
111
|
-
this.algorithm = algorithm;
|
|
112
|
-
};
|
|
113
|
-
FirebaseTokenVerifier.prototype.verifyJWTWithProjectId = function (jwtToken, projectId) {
|
|
108
|
+
FirebaseTokenVerifier.prototype.verifyJWTWithProjectId = function (jwtToken, projectId, isEmulator) {
|
|
114
109
|
var _this = this;
|
|
115
110
|
if (!validator.isNonEmptyString(projectId)) {
|
|
116
111
|
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 ' +
|
|
@@ -130,7 +125,7 @@ var FirebaseTokenVerifier = /** @class */ (function () {
|
|
|
130
125
|
errorMessage = "Decoding " + this.tokenInfo.jwtName + " failed. Make sure you passed the entire string JWT " +
|
|
131
126
|
("which represents " + this.shortNameArticle + " " + this.tokenInfo.shortName + ".") + verifyJwtTokenDocsMessage;
|
|
132
127
|
}
|
|
133
|
-
else if (typeof header.kid === 'undefined'
|
|
128
|
+
else if (!isEmulator && typeof header.kid === 'undefined') {
|
|
134
129
|
var isCustomToken = (payload.aud === FIREBASE_AUDIENCE);
|
|
135
130
|
var isLegacyCustomToken = (header.alg === 'HS256' && payload.v === 0 && 'd' in payload && 'uid' in payload.d);
|
|
136
131
|
if (isCustomToken) {
|
|
@@ -146,7 +141,7 @@ var FirebaseTokenVerifier = /** @class */ (function () {
|
|
|
146
141
|
}
|
|
147
142
|
errorMessage += verifyJwtTokenDocsMessage;
|
|
148
143
|
}
|
|
149
|
-
else if (header.alg !== this.algorithm) {
|
|
144
|
+
else if (!isEmulator && header.alg !== this.algorithm) {
|
|
150
145
|
errorMessage = this.tokenInfo.jwtName + " has incorrect algorithm. Expected \"" + this.algorithm + '" but got ' +
|
|
151
146
|
'"' + header.alg + '".' + verifyJwtTokenDocsMessage;
|
|
152
147
|
}
|
|
@@ -157,7 +152,7 @@ var FirebaseTokenVerifier = /** @class */ (function () {
|
|
|
157
152
|
}
|
|
158
153
|
else if (payload.iss !== this.issuer + projectId) {
|
|
159
154
|
errorMessage = this.tokenInfo.jwtName + " has incorrect \"iss\" (issuer) claim. Expected " +
|
|
160
|
-
("\"" + this.issuer
|
|
155
|
+
("\"" + this.issuer) + projectId + '" but got "' +
|
|
161
156
|
payload.iss + '".' + projectIdMatchMessage + verifyJwtTokenDocsMessage;
|
|
162
157
|
}
|
|
163
158
|
else if (typeof payload.sub !== 'string') {
|
|
@@ -173,9 +168,8 @@ var FirebaseTokenVerifier = /** @class */ (function () {
|
|
|
173
168
|
if (errorMessage) {
|
|
174
169
|
return Promise.reject(new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_ARGUMENT, errorMessage));
|
|
175
170
|
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
if (this.algorithm === 'none') {
|
|
171
|
+
if (isEmulator) {
|
|
172
|
+
// Signature checks skipped for emulator; no need to fetch public keys.
|
|
179
173
|
return this.verifyJwtSignatureWithKey(jwtToken, null);
|
|
180
174
|
}
|
|
181
175
|
return this.fetchPublicKeys().then(function (publicKeys) {
|
|
@@ -201,9 +195,11 @@ var FirebaseTokenVerifier = /** @class */ (function () {
|
|
|
201
195
|
var verifyJwtTokenDocsMessage = " See " + this.tokenInfo.url + " " +
|
|
202
196
|
("for details on how to retrieve " + this.shortNameArticle + " " + this.tokenInfo.shortName + ".");
|
|
203
197
|
return new Promise(function (resolve, reject) {
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
198
|
+
var verifyOptions = {};
|
|
199
|
+
if (publicKey !== null) {
|
|
200
|
+
verifyOptions.algorithms = [_this.algorithm];
|
|
201
|
+
}
|
|
202
|
+
jwt.verify(jwtToken, publicKey || '', verifyOptions, function (error, decodedToken) {
|
|
207
203
|
if (error) {
|
|
208
204
|
if (error.name === 'TokenExpiredError') {
|
|
209
205
|
var errorMessage = _this.tokenInfo.jwtName + " has expired. Get a fresh " + _this.tokenInfo.shortName +
|
package/lib/auth/user-record.js
CHANGED
package/lib/credential/index.js
CHANGED