@firebase/auth 1.1.0 → 1.2.0-20230815211035
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 +28 -1
- package/dist/auth-public.d.ts +119 -0
- package/dist/auth.d.ts +179 -2
- package/dist/browser-cjs/{index-0b2238be.js → index-4a6bae3a.js} +566 -278
- package/dist/browser-cjs/index-4a6bae3a.js.map +1 -0
- package/dist/browser-cjs/index.js +3 -2
- package/dist/browser-cjs/index.js.map +1 -1
- package/dist/browser-cjs/internal.js +3 -2
- package/dist/browser-cjs/internal.js.map +1 -1
- package/dist/browser-cjs/src/api/errors.d.ts +2 -1
- package/dist/browser-cjs/src/api/index.d.ts +2 -1
- package/dist/browser-cjs/src/api/password_policy/get_password_policy.d.ts +48 -0
- package/dist/browser-cjs/src/api/password_policy/get_password_policy.test.d.ts +17 -0
- package/dist/browser-cjs/src/core/auth/auth_impl.d.ts +8 -2
- package/dist/browser-cjs/src/core/auth/password_policy_impl.d.ts +59 -0
- package/dist/browser-cjs/src/core/auth/password_policy_impl.test.d.ts +17 -0
- package/dist/browser-cjs/src/core/errors.d.ts +3 -1
- package/dist/browser-cjs/src/core/index.d.ts +25 -1
- package/dist/browser-cjs/src/model/auth.d.ts +7 -2
- package/dist/browser-cjs/src/model/password_policy.d.ts +111 -0
- package/dist/browser-cjs/src/model/public_types.d.ts +88 -0
- package/dist/browser-cjs/src/platform_browser/recaptcha/recaptcha_enterprise_verifier.d.ts +1 -0
- package/dist/browser-cjs/src/platform_node/index.d.ts +1 -0
- package/dist/browser-cjs/test/helpers/integration/helpers.d.ts +7 -1
- package/dist/browser-cjs/test/integration/flows/password_policy.test.d.ts +17 -0
- package/dist/cordova/index.js +2 -2
- package/dist/cordova/internal.js +2 -2
- package/dist/cordova/{popup_redirect-71c1ff0a.js → popup_redirect-03e63fe8.js} +754 -416
- package/dist/cordova/popup_redirect-03e63fe8.js.map +1 -0
- package/dist/cordova/src/api/errors.d.ts +2 -1
- package/dist/cordova/src/api/index.d.ts +2 -1
- package/dist/cordova/src/api/password_policy/get_password_policy.d.ts +48 -0
- package/dist/cordova/src/api/password_policy/get_password_policy.test.d.ts +17 -0
- package/dist/cordova/src/core/auth/auth_impl.d.ts +8 -2
- package/dist/cordova/src/core/auth/password_policy_impl.d.ts +59 -0
- package/dist/cordova/src/core/auth/password_policy_impl.test.d.ts +17 -0
- package/dist/cordova/src/core/errors.d.ts +3 -1
- package/dist/cordova/src/core/index.d.ts +25 -1
- package/dist/cordova/src/model/auth.d.ts +7 -2
- package/dist/cordova/src/model/password_policy.d.ts +111 -0
- package/dist/cordova/src/model/public_types.d.ts +88 -0
- package/dist/cordova/src/platform_browser/recaptcha/recaptcha_enterprise_verifier.d.ts +1 -0
- package/dist/cordova/src/platform_node/index.d.ts +1 -0
- package/dist/cordova/test/helpers/integration/helpers.d.ts +7 -1
- package/dist/cordova/test/integration/flows/password_policy.test.d.ts +17 -0
- package/dist/esm2017/{index-e24386e7.js → index-a2ce75d7.js} +566 -279
- package/dist/esm2017/index-a2ce75d7.js.map +1 -0
- package/dist/esm2017/index.js +2 -2
- package/dist/esm2017/internal.js +3 -3
- package/dist/esm2017/src/api/errors.d.ts +2 -1
- package/dist/esm2017/src/api/index.d.ts +2 -1
- package/dist/esm2017/src/api/password_policy/get_password_policy.d.ts +48 -0
- package/dist/esm2017/src/api/password_policy/get_password_policy.test.d.ts +17 -0
- package/dist/esm2017/src/core/auth/auth_impl.d.ts +8 -2
- package/dist/esm2017/src/core/auth/password_policy_impl.d.ts +59 -0
- package/dist/esm2017/src/core/auth/password_policy_impl.test.d.ts +17 -0
- package/dist/esm2017/src/core/errors.d.ts +3 -1
- package/dist/esm2017/src/core/index.d.ts +25 -1
- package/dist/esm2017/src/model/auth.d.ts +7 -2
- package/dist/esm2017/src/model/password_policy.d.ts +111 -0
- package/dist/esm2017/src/model/public_types.d.ts +88 -0
- package/dist/esm2017/src/platform_browser/recaptcha/recaptcha_enterprise_verifier.d.ts +1 -0
- package/dist/esm2017/src/platform_node/index.d.ts +1 -0
- package/dist/esm2017/test/helpers/integration/helpers.d.ts +7 -1
- package/dist/esm2017/test/integration/flows/password_policy.test.d.ts +17 -0
- package/dist/esm5/{index-be7bff78.js → index-aeb2d939.js} +754 -416
- package/dist/esm5/index-aeb2d939.js.map +1 -0
- package/dist/esm5/index.js +1 -1
- package/dist/esm5/internal.js +2 -2
- package/dist/esm5/src/api/errors.d.ts +2 -1
- package/dist/esm5/src/api/index.d.ts +2 -1
- package/dist/esm5/src/api/password_policy/get_password_policy.d.ts +48 -0
- package/dist/esm5/src/api/password_policy/get_password_policy.test.d.ts +17 -0
- package/dist/esm5/src/core/auth/auth_impl.d.ts +8 -2
- package/dist/esm5/src/core/auth/password_policy_impl.d.ts +59 -0
- package/dist/esm5/src/core/auth/password_policy_impl.test.d.ts +17 -0
- package/dist/esm5/src/core/errors.d.ts +3 -1
- package/dist/esm5/src/core/index.d.ts +25 -1
- package/dist/esm5/src/model/auth.d.ts +7 -2
- package/dist/esm5/src/model/password_policy.d.ts +111 -0
- package/dist/esm5/src/model/public_types.d.ts +88 -0
- package/dist/esm5/src/platform_browser/recaptcha/recaptcha_enterprise_verifier.d.ts +1 -0
- package/dist/esm5/src/platform_node/index.d.ts +1 -0
- package/dist/esm5/test/helpers/integration/helpers.d.ts +7 -1
- package/dist/esm5/test/integration/flows/password_policy.test.d.ts +17 -0
- package/dist/index.webworker.esm5.js +828 -490
- package/dist/index.webworker.esm5.js.map +1 -1
- package/dist/node/index.js +2 -1
- package/dist/node/index.js.map +1 -1
- package/dist/node/internal.js +2 -1
- package/dist/node/internal.js.map +1 -1
- package/dist/node/src/api/errors.d.ts +2 -1
- package/dist/node/src/api/index.d.ts +2 -1
- package/dist/node/src/api/password_policy/get_password_policy.d.ts +48 -0
- package/dist/node/src/api/password_policy/get_password_policy.test.d.ts +17 -0
- package/dist/node/src/core/auth/auth_impl.d.ts +8 -2
- package/dist/node/src/core/auth/password_policy_impl.d.ts +59 -0
- package/dist/node/src/core/auth/password_policy_impl.test.d.ts +17 -0
- package/dist/node/src/core/errors.d.ts +3 -1
- package/dist/node/src/core/index.d.ts +25 -1
- package/dist/node/src/model/auth.d.ts +7 -2
- package/dist/node/src/model/password_policy.d.ts +111 -0
- package/dist/node/src/model/public_types.d.ts +88 -0
- package/dist/node/src/platform_browser/recaptcha/recaptcha_enterprise_verifier.d.ts +1 -0
- package/dist/node/src/platform_node/index.d.ts +1 -0
- package/dist/node/test/helpers/integration/helpers.d.ts +7 -1
- package/dist/node/test/integration/flows/password_policy.test.d.ts +17 -0
- package/dist/node/{totp-8a876b1a.js → totp-59663c77.js} +717 -378
- package/dist/node/totp-59663c77.js.map +1 -0
- package/dist/node-esm/index.js +1 -1
- package/dist/node-esm/internal.js +2 -2
- package/dist/node-esm/src/api/errors.d.ts +2 -1
- package/dist/node-esm/src/api/index.d.ts +2 -1
- package/dist/node-esm/src/api/password_policy/get_password_policy.d.ts +48 -0
- package/dist/node-esm/src/api/password_policy/get_password_policy.test.d.ts +17 -0
- package/dist/node-esm/src/core/auth/auth_impl.d.ts +8 -2
- package/dist/node-esm/src/core/auth/password_policy_impl.d.ts +59 -0
- package/dist/node-esm/src/core/auth/password_policy_impl.test.d.ts +17 -0
- package/dist/node-esm/src/core/errors.d.ts +3 -1
- package/dist/node-esm/src/core/index.d.ts +25 -1
- package/dist/node-esm/src/model/auth.d.ts +7 -2
- package/dist/node-esm/src/model/password_policy.d.ts +111 -0
- package/dist/node-esm/src/model/public_types.d.ts +88 -0
- package/dist/node-esm/src/platform_browser/recaptcha/recaptcha_enterprise_verifier.d.ts +1 -0
- package/dist/node-esm/src/platform_node/index.d.ts +1 -0
- package/dist/node-esm/test/helpers/integration/helpers.d.ts +7 -1
- package/dist/node-esm/test/integration/flows/password_policy.test.d.ts +17 -0
- package/dist/node-esm/{totp-04ac595e.js → totp-8ca454e8.js} +554 -267
- package/dist/node-esm/totp-8ca454e8.js.map +1 -0
- package/dist/rn/index.js +2 -1
- package/dist/rn/index.js.map +1 -1
- package/dist/rn/internal.js +2 -1
- package/dist/rn/internal.js.map +1 -1
- package/dist/rn/{phone-2132481b.js → phone-14433b21.js} +734 -395
- package/dist/rn/phone-14433b21.js.map +1 -0
- package/dist/rn/src/api/errors.d.ts +2 -1
- package/dist/rn/src/api/index.d.ts +2 -1
- package/dist/rn/src/api/password_policy/get_password_policy.d.ts +48 -0
- package/dist/rn/src/api/password_policy/get_password_policy.test.d.ts +17 -0
- package/dist/rn/src/core/auth/auth_impl.d.ts +8 -2
- package/dist/rn/src/core/auth/password_policy_impl.d.ts +59 -0
- package/dist/rn/src/core/auth/password_policy_impl.test.d.ts +17 -0
- package/dist/rn/src/core/errors.d.ts +3 -1
- package/dist/rn/src/core/index.d.ts +25 -1
- package/dist/rn/src/model/auth.d.ts +7 -2
- package/dist/rn/src/model/password_policy.d.ts +111 -0
- package/dist/rn/src/model/public_types.d.ts +88 -0
- package/dist/rn/src/platform_browser/recaptcha/recaptcha_enterprise_verifier.d.ts +1 -0
- package/dist/rn/src/platform_node/index.d.ts +1 -0
- package/dist/rn/test/helpers/integration/helpers.d.ts +7 -1
- package/dist/rn/test/integration/flows/password_policy.test.d.ts +17 -0
- package/dist/src/api/errors.d.ts +2 -1
- package/dist/src/api/index.d.ts +2 -1
- package/dist/src/api/password_policy/get_password_policy.d.ts +48 -0
- package/dist/src/api/password_policy/get_password_policy.test.d.ts +17 -0
- package/dist/src/core/auth/auth_impl.d.ts +8 -2
- package/dist/src/core/auth/password_policy_impl.d.ts +59 -0
- package/dist/src/core/auth/password_policy_impl.test.d.ts +17 -0
- package/dist/src/core/errors.d.ts +3 -1
- package/dist/src/core/index.d.ts +25 -1
- package/dist/src/model/auth.d.ts +7 -2
- package/dist/src/model/password_policy.d.ts +111 -0
- package/dist/src/model/public_types.d.ts +88 -0
- package/dist/src/platform_browser/recaptcha/recaptcha_enterprise_verifier.d.ts +1 -0
- package/dist/src/platform_node/index.d.ts +1 -0
- package/dist/test/helpers/integration/helpers.d.ts +7 -1
- package/dist/test/integration/flows/password_policy.test.d.ts +17 -0
- package/package.json +1 -1
- package/dist/browser-cjs/index-0b2238be.js.map +0 -1
- package/dist/cordova/popup_redirect-71c1ff0a.js.map +0 -1
- package/dist/esm2017/index-e24386e7.js.map +0 -1
- package/dist/esm5/index-be7bff78.js.map +0 -1
- package/dist/node/totp-8a876b1a.js.map +0 -1
- package/dist/node-esm/totp-04ac595e.js.map +0 -1
- package/dist/rn/phone-2132481b.js.map +0 -1
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
var util = require('@firebase/util');
|
|
4
4
|
var app = require('@firebase/app');
|
|
5
|
-
var tslib = require('tslib');
|
|
6
5
|
var logger = require('@firebase/logger');
|
|
6
|
+
var tslib = require('tslib');
|
|
7
7
|
var component = require('@firebase/component');
|
|
8
8
|
|
|
9
9
|
/**
|
|
@@ -105,6 +105,50 @@ const ActionCodeOperation = {
|
|
|
105
105
|
VERIFY_EMAIL: 'VERIFY_EMAIL'
|
|
106
106
|
};
|
|
107
107
|
|
|
108
|
+
/**
|
|
109
|
+
* @license
|
|
110
|
+
* Copyright 2020 Google LLC
|
|
111
|
+
*
|
|
112
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
113
|
+
* you may not use this file except in compliance with the License.
|
|
114
|
+
* You may obtain a copy of the License at
|
|
115
|
+
*
|
|
116
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
117
|
+
*
|
|
118
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
119
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
120
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
121
|
+
* See the License for the specific language governing permissions and
|
|
122
|
+
* limitations under the License.
|
|
123
|
+
*/
|
|
124
|
+
function isV2(grecaptcha) {
|
|
125
|
+
return (grecaptcha !== undefined &&
|
|
126
|
+
grecaptcha.getResponse !== undefined);
|
|
127
|
+
}
|
|
128
|
+
function isEnterprise(grecaptcha) {
|
|
129
|
+
return (grecaptcha !== undefined &&
|
|
130
|
+
grecaptcha.enterprise !== undefined);
|
|
131
|
+
}
|
|
132
|
+
class RecaptchaConfig {
|
|
133
|
+
constructor(response) {
|
|
134
|
+
/**
|
|
135
|
+
* The reCAPTCHA site key.
|
|
136
|
+
*/
|
|
137
|
+
this.siteKey = '';
|
|
138
|
+
/**
|
|
139
|
+
* The reCAPTCHA enablement status of the {@link EmailAuthProvider} for the current tenant.
|
|
140
|
+
*/
|
|
141
|
+
this.emailPasswordEnabled = false;
|
|
142
|
+
if (response.recaptchaKey === undefined) {
|
|
143
|
+
throw new Error('recaptchaKey undefined');
|
|
144
|
+
}
|
|
145
|
+
// Example response.recaptchaKey: "projects/proj123/keys/sitekey123"
|
|
146
|
+
this.siteKey = response.recaptchaKey.split('/')[3];
|
|
147
|
+
this.emailPasswordEnabled = response.recaptchaEnforcementState.some(enforcementState => enforcementState.provider === 'EMAIL_PASSWORD_PROVIDER' &&
|
|
148
|
+
enforcementState.enforcementState !== 'OFF');
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
108
152
|
/**
|
|
109
153
|
* @license
|
|
110
154
|
* Copyright 2020 Google LLC
|
|
@@ -275,7 +319,9 @@ function _debugErrorMap() {
|
|
|
275
319
|
["missing-client-type" /* AuthErrorCode.MISSING_CLIENT_TYPE */]: 'The reCAPTCHA client type is missing when sending request to the backend.',
|
|
276
320
|
["missing-recaptcha-version" /* AuthErrorCode.MISSING_RECAPTCHA_VERSION */]: 'The reCAPTCHA version is missing when sending request to the backend.',
|
|
277
321
|
["invalid-req-type" /* AuthErrorCode.INVALID_REQ_TYPE */]: 'Invalid request parameters.',
|
|
278
|
-
["invalid-recaptcha-version" /* AuthErrorCode.INVALID_RECAPTCHA_VERSION */]: 'The reCAPTCHA version is invalid when sending request to the backend.'
|
|
322
|
+
["invalid-recaptcha-version" /* AuthErrorCode.INVALID_RECAPTCHA_VERSION */]: 'The reCAPTCHA version is invalid when sending request to the backend.',
|
|
323
|
+
["unsupported-password-policy-schema-version" /* AuthErrorCode.UNSUPPORTED_PASSWORD_POLICY_SCHEMA_VERSION */]: 'The password policy received from the backend uses a schema version that is not supported by this version of the Firebase SDK.',
|
|
324
|
+
["password-does-not-meet-requirements" /* AuthErrorCode.PASSWORD_DOES_NOT_MEET_REQUIREMENTS */]: 'The password does not meet the requirements.'
|
|
279
325
|
};
|
|
280
326
|
}
|
|
281
327
|
function _prodErrorMap() {
|
|
@@ -789,6 +835,7 @@ const SERVER_ERROR_MAP = {
|
|
|
789
835
|
["USER_NOT_FOUND" /* ServerError.USER_NOT_FOUND */]: "user-token-expired" /* AuthErrorCode.TOKEN_EXPIRED */,
|
|
790
836
|
// Other errors.
|
|
791
837
|
["TOO_MANY_ATTEMPTS_TRY_LATER" /* ServerError.TOO_MANY_ATTEMPTS_TRY_LATER */]: "too-many-requests" /* AuthErrorCode.TOO_MANY_ATTEMPTS_TRY_LATER */,
|
|
838
|
+
["PASSWORD_DOES_NOT_MEET_REQUIREMENTS" /* ServerError.PASSWORD_DOES_NOT_MEET_REQUIREMENTS */]: "password-does-not-meet-requirements" /* AuthErrorCode.PASSWORD_DOES_NOT_MEET_REQUIREMENTS */,
|
|
792
839
|
// Phone Auth related errors.
|
|
793
840
|
["INVALID_CODE" /* ServerError.INVALID_CODE */]: "invalid-verification-code" /* AuthErrorCode.INVALID_CODE */,
|
|
794
841
|
["INVALID_SESSION_INFO" /* ServerError.INVALID_SESSION_INFO */]: "invalid-verification-id" /* AuthErrorCode.INVALID_SESSION_INFO */,
|
|
@@ -973,6 +1020,29 @@ function _makeTaggedError(auth, code, response) {
|
|
|
973
1020
|
return error;
|
|
974
1021
|
}
|
|
975
1022
|
|
|
1023
|
+
/**
|
|
1024
|
+
* @license
|
|
1025
|
+
* Copyright 2020 Google LLC
|
|
1026
|
+
*
|
|
1027
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
1028
|
+
* you may not use this file except in compliance with the License.
|
|
1029
|
+
* You may obtain a copy of the License at
|
|
1030
|
+
*
|
|
1031
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
1032
|
+
*
|
|
1033
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
1034
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
1035
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
1036
|
+
* See the License for the specific language governing permissions and
|
|
1037
|
+
* limitations under the License.
|
|
1038
|
+
*/
|
|
1039
|
+
async function getRecaptchaParams(auth) {
|
|
1040
|
+
return ((await _performApiRequest(auth, "GET" /* HttpMethod.GET */, "/v1/recaptchaParams" /* Endpoint.GET_RECAPTCHA_PARAM */)).recaptchaSiteKey || '');
|
|
1041
|
+
}
|
|
1042
|
+
async function getRecaptchaConfig(auth, request) {
|
|
1043
|
+
return _performApiRequest(auth, "GET" /* HttpMethod.GET */, "/v2/recaptchaConfig" /* Endpoint.GET_RECAPTCHA_CONFIG */, _addTidIfNecessary(auth, request));
|
|
1044
|
+
}
|
|
1045
|
+
|
|
976
1046
|
/**
|
|
977
1047
|
* @license
|
|
978
1048
|
* Copyright 2020 Google LLC
|
|
@@ -2095,7 +2165,7 @@ function _getClientVersion(clientPlatform, frameworks = []) {
|
|
|
2095
2165
|
|
|
2096
2166
|
/**
|
|
2097
2167
|
* @license
|
|
2098
|
-
* Copyright
|
|
2168
|
+
* Copyright 2022 Google LLC
|
|
2099
2169
|
*
|
|
2100
2170
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
2101
2171
|
* you may not use this file except in compliance with the License.
|
|
@@ -2109,16 +2179,74 @@ function _getClientVersion(clientPlatform, frameworks = []) {
|
|
|
2109
2179
|
* See the License for the specific language governing permissions and
|
|
2110
2180
|
* limitations under the License.
|
|
2111
2181
|
*/
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2182
|
+
class AuthMiddlewareQueue {
|
|
2183
|
+
constructor(auth) {
|
|
2184
|
+
this.auth = auth;
|
|
2185
|
+
this.queue = [];
|
|
2186
|
+
}
|
|
2187
|
+
pushCallback(callback, onAbort) {
|
|
2188
|
+
// The callback could be sync or async. Wrap it into a
|
|
2189
|
+
// function that is always async.
|
|
2190
|
+
const wrappedCallback = (user) => new Promise((resolve, reject) => {
|
|
2191
|
+
try {
|
|
2192
|
+
const result = callback(user);
|
|
2193
|
+
// Either resolve with existing promise or wrap a non-promise
|
|
2194
|
+
// return value into a promise.
|
|
2195
|
+
resolve(result);
|
|
2196
|
+
}
|
|
2197
|
+
catch (e) {
|
|
2198
|
+
// Sync callback throws.
|
|
2199
|
+
reject(e);
|
|
2200
|
+
}
|
|
2201
|
+
});
|
|
2202
|
+
// Attach the onAbort if present
|
|
2203
|
+
wrappedCallback.onAbort = onAbort;
|
|
2204
|
+
this.queue.push(wrappedCallback);
|
|
2205
|
+
const index = this.queue.length - 1;
|
|
2206
|
+
return () => {
|
|
2207
|
+
// Unsubscribe. Replace with no-op. Do not remove from array, or it will disturb
|
|
2208
|
+
// indexing of other elements.
|
|
2209
|
+
this.queue[index] = () => Promise.resolve();
|
|
2210
|
+
};
|
|
2211
|
+
}
|
|
2212
|
+
async runMiddleware(nextUser) {
|
|
2213
|
+
if (this.auth.currentUser === nextUser) {
|
|
2214
|
+
return;
|
|
2215
|
+
}
|
|
2216
|
+
// While running the middleware, build a temporary stack of onAbort
|
|
2217
|
+
// callbacks to call if one middleware callback rejects.
|
|
2218
|
+
const onAbortStack = [];
|
|
2219
|
+
try {
|
|
2220
|
+
for (const beforeStateCallback of this.queue) {
|
|
2221
|
+
await beforeStateCallback(nextUser);
|
|
2222
|
+
// Only push the onAbort if the callback succeeds
|
|
2223
|
+
if (beforeStateCallback.onAbort) {
|
|
2224
|
+
onAbortStack.push(beforeStateCallback.onAbort);
|
|
2225
|
+
}
|
|
2226
|
+
}
|
|
2227
|
+
}
|
|
2228
|
+
catch (e) {
|
|
2229
|
+
// Run all onAbort, with separate try/catch to ignore any errors and
|
|
2230
|
+
// continue
|
|
2231
|
+
onAbortStack.reverse();
|
|
2232
|
+
for (const onAbort of onAbortStack) {
|
|
2233
|
+
try {
|
|
2234
|
+
onAbort();
|
|
2235
|
+
}
|
|
2236
|
+
catch (_) {
|
|
2237
|
+
/* swallow error */
|
|
2238
|
+
}
|
|
2239
|
+
}
|
|
2240
|
+
throw this.auth._errorFactory.create("login-blocked" /* AuthErrorCode.LOGIN_BLOCKED */, {
|
|
2241
|
+
originalMessage: e === null || e === void 0 ? void 0 : e.message
|
|
2242
|
+
});
|
|
2243
|
+
}
|
|
2244
|
+
}
|
|
2117
2245
|
}
|
|
2118
2246
|
|
|
2119
2247
|
/**
|
|
2120
2248
|
* @license
|
|
2121
|
-
* Copyright
|
|
2249
|
+
* Copyright 2023 Google LLC
|
|
2122
2250
|
*
|
|
2123
2251
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
2124
2252
|
* you may not use this file except in compliance with the License.
|
|
@@ -2132,37 +2260,20 @@ async function getRecaptchaConfig(auth, request) {
|
|
|
2132
2260
|
* See the License for the specific language governing permissions and
|
|
2133
2261
|
* limitations under the License.
|
|
2134
2262
|
*/
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
}
|
|
2143
|
-
|
|
2144
|
-
constructor(response) {
|
|
2145
|
-
/**
|
|
2146
|
-
* The reCAPTCHA site key.
|
|
2147
|
-
*/
|
|
2148
|
-
this.siteKey = '';
|
|
2149
|
-
/**
|
|
2150
|
-
* The reCAPTCHA enablement status of the {@link EmailAuthProvider} for the current tenant.
|
|
2151
|
-
*/
|
|
2152
|
-
this.emailPasswordEnabled = false;
|
|
2153
|
-
if (response.recaptchaKey === undefined) {
|
|
2154
|
-
throw new Error('recaptchaKey undefined');
|
|
2155
|
-
}
|
|
2156
|
-
// Example response.recaptchaKey: "projects/proj123/keys/sitekey123"
|
|
2157
|
-
this.siteKey = response.recaptchaKey.split('/')[3];
|
|
2158
|
-
this.emailPasswordEnabled = response.recaptchaEnforcementState.some(enforcementState => enforcementState.provider === 'EMAIL_PASSWORD_PROVIDER' &&
|
|
2159
|
-
enforcementState.enforcementState !== 'OFF');
|
|
2160
|
-
}
|
|
2263
|
+
/**
|
|
2264
|
+
* Fetches the password policy for the currently set tenant or the project if no tenant is set.
|
|
2265
|
+
*
|
|
2266
|
+
* @param auth Auth object.
|
|
2267
|
+
* @param request Password policy request.
|
|
2268
|
+
* @returns Password policy response.
|
|
2269
|
+
*/
|
|
2270
|
+
async function _getPasswordPolicy(auth, request = {}) {
|
|
2271
|
+
return _performApiRequest(auth, "GET" /* HttpMethod.GET */, "/v2/passwordPolicy" /* Endpoint.GET_PASSWORD_POLICY */, _addTidIfNecessary(auth, request));
|
|
2161
2272
|
}
|
|
2162
2273
|
|
|
2163
2274
|
/**
|
|
2164
2275
|
* @license
|
|
2165
|
-
* Copyright
|
|
2276
|
+
* Copyright 2023 Google LLC
|
|
2166
2277
|
*
|
|
2167
2278
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
2168
2279
|
* you may not use this file except in compliance with the License.
|
|
@@ -2176,232 +2287,135 @@ class RecaptchaConfig {
|
|
|
2176
2287
|
* See the License for the specific language governing permissions and
|
|
2177
2288
|
* limitations under the License.
|
|
2178
2289
|
*/
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2290
|
+
// Minimum min password length enforced by the backend, even if no minimum length is set.
|
|
2291
|
+
const MINIMUM_MIN_PASSWORD_LENGTH = 6;
|
|
2292
|
+
/**
|
|
2293
|
+
* Stores password policy requirements and provides password validation against the policy.
|
|
2294
|
+
*
|
|
2295
|
+
* @internal
|
|
2296
|
+
*/
|
|
2297
|
+
class PasswordPolicyImpl {
|
|
2298
|
+
constructor(response) {
|
|
2299
|
+
var _a, _b, _c, _d;
|
|
2300
|
+
// Only include custom strength options defined in the response.
|
|
2301
|
+
const responseOptions = response.customStrengthOptions;
|
|
2302
|
+
this.customStrengthOptions = {};
|
|
2303
|
+
// TODO: Remove once the backend is updated to include the minimum min password length instead of undefined when there is no minimum length set.
|
|
2304
|
+
this.customStrengthOptions.minPasswordLength =
|
|
2305
|
+
(_a = responseOptions.minPasswordLength) !== null && _a !== void 0 ? _a : MINIMUM_MIN_PASSWORD_LENGTH;
|
|
2306
|
+
if (responseOptions.maxPasswordLength) {
|
|
2307
|
+
this.customStrengthOptions.maxPasswordLength =
|
|
2308
|
+
responseOptions.maxPasswordLength;
|
|
2309
|
+
}
|
|
2310
|
+
if (responseOptions.containsLowercaseCharacter !== undefined) {
|
|
2311
|
+
this.customStrengthOptions.containsLowercaseLetter =
|
|
2312
|
+
responseOptions.containsLowercaseCharacter;
|
|
2313
|
+
}
|
|
2314
|
+
if (responseOptions.containsUppercaseCharacter !== undefined) {
|
|
2315
|
+
this.customStrengthOptions.containsUppercaseLetter =
|
|
2316
|
+
responseOptions.containsUppercaseCharacter;
|
|
2317
|
+
}
|
|
2318
|
+
if (responseOptions.containsNumericCharacter !== undefined) {
|
|
2319
|
+
this.customStrengthOptions.containsNumericCharacter =
|
|
2320
|
+
responseOptions.containsNumericCharacter;
|
|
2321
|
+
}
|
|
2322
|
+
if (responseOptions.containsNonAlphanumericCharacter !== undefined) {
|
|
2323
|
+
this.customStrengthOptions.containsNonAlphanumericCharacter =
|
|
2324
|
+
responseOptions.containsNonAlphanumericCharacter;
|
|
2325
|
+
}
|
|
2326
|
+
this.enforcementState = response.enforcementState;
|
|
2327
|
+
if (this.enforcementState === 'ENFORCEMENT_STATE_UNSPECIFIED') {
|
|
2328
|
+
this.enforcementState = 'OFF';
|
|
2329
|
+
}
|
|
2330
|
+
// Use an empty string if no non-alphanumeric characters are specified in the response.
|
|
2331
|
+
this.allowedNonAlphanumericCharacters =
|
|
2332
|
+
(_c = (_b = response.allowedNonAlphanumericCharacters) === null || _b === void 0 ? void 0 : _b.join('')) !== null && _c !== void 0 ? _c : '';
|
|
2333
|
+
this.forceUpgradeOnSignin = (_d = response.forceUpgradeOnSignin) !== null && _d !== void 0 ? _d : false;
|
|
2334
|
+
this.schemaVersion = response.schemaVersion;
|
|
2335
|
+
}
|
|
2336
|
+
validatePassword(password) {
|
|
2337
|
+
var _a, _b, _c, _d, _e, _f;
|
|
2338
|
+
const status = {
|
|
2339
|
+
isValid: true,
|
|
2340
|
+
passwordPolicy: this
|
|
2193
2341
|
};
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
const RECAPTCHA_ENTERPRISE_VERIFIER_TYPE = 'recaptcha-enterprise';
|
|
2206
|
-
const FAKE_TOKEN = 'NO_RECAPTCHA';
|
|
2207
|
-
class RecaptchaEnterpriseVerifier {
|
|
2208
|
-
/**
|
|
2209
|
-
*
|
|
2210
|
-
* @param authExtern - The corresponding Firebase {@link Auth} instance.
|
|
2211
|
-
*
|
|
2212
|
-
*/
|
|
2213
|
-
constructor(authExtern) {
|
|
2214
|
-
/**
|
|
2215
|
-
* Identifies the type of application verifier (e.g. "recaptcha-enterprise").
|
|
2216
|
-
*/
|
|
2217
|
-
this.type = RECAPTCHA_ENTERPRISE_VERIFIER_TYPE;
|
|
2218
|
-
this.auth = _castAuth(authExtern);
|
|
2342
|
+
// Check the password length and character options.
|
|
2343
|
+
this.validatePasswordLengthOptions(password, status);
|
|
2344
|
+
this.validatePasswordCharacterOptions(password, status);
|
|
2345
|
+
// Combine the status into single isValid property.
|
|
2346
|
+
status.isValid && (status.isValid = (_a = status.meetsMinPasswordLength) !== null && _a !== void 0 ? _a : true);
|
|
2347
|
+
status.isValid && (status.isValid = (_b = status.meetsMaxPasswordLength) !== null && _b !== void 0 ? _b : true);
|
|
2348
|
+
status.isValid && (status.isValid = (_c = status.containsLowercaseLetter) !== null && _c !== void 0 ? _c : true);
|
|
2349
|
+
status.isValid && (status.isValid = (_d = status.containsUppercaseLetter) !== null && _d !== void 0 ? _d : true);
|
|
2350
|
+
status.isValid && (status.isValid = (_e = status.containsNumericCharacter) !== null && _e !== void 0 ? _e : true);
|
|
2351
|
+
status.isValid && (status.isValid = (_f = status.containsNonAlphanumericCharacter) !== null && _f !== void 0 ? _f : true);
|
|
2352
|
+
return status;
|
|
2219
2353
|
}
|
|
2220
2354
|
/**
|
|
2221
|
-
*
|
|
2355
|
+
* Validates that the password meets the length options for the policy.
|
|
2222
2356
|
*
|
|
2223
|
-
* @
|
|
2357
|
+
* @param password Password to validate.
|
|
2358
|
+
* @param status Validation status.
|
|
2224
2359
|
*/
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
}
|
|
2231
|
-
if (auth.tenantId != null &&
|
|
2232
|
-
auth._tenantRecaptchaConfigs[auth.tenantId] !== undefined) {
|
|
2233
|
-
return auth._tenantRecaptchaConfigs[auth.tenantId].siteKey;
|
|
2234
|
-
}
|
|
2235
|
-
}
|
|
2236
|
-
return new Promise(async (resolve, reject) => {
|
|
2237
|
-
getRecaptchaConfig(auth, {
|
|
2238
|
-
clientType: "CLIENT_TYPE_WEB" /* RecaptchaClientType.WEB */,
|
|
2239
|
-
version: "RECAPTCHA_ENTERPRISE" /* RecaptchaVersion.ENTERPRISE */
|
|
2240
|
-
})
|
|
2241
|
-
.then(response => {
|
|
2242
|
-
if (response.recaptchaKey === undefined) {
|
|
2243
|
-
reject(new Error('recaptcha Enterprise site key undefined'));
|
|
2244
|
-
}
|
|
2245
|
-
else {
|
|
2246
|
-
const config = new RecaptchaConfig(response);
|
|
2247
|
-
if (auth.tenantId == null) {
|
|
2248
|
-
auth._agentRecaptchaConfig = config;
|
|
2249
|
-
}
|
|
2250
|
-
else {
|
|
2251
|
-
auth._tenantRecaptchaConfigs[auth.tenantId] = config;
|
|
2252
|
-
}
|
|
2253
|
-
return resolve(config.siteKey);
|
|
2254
|
-
}
|
|
2255
|
-
})
|
|
2256
|
-
.catch(error => {
|
|
2257
|
-
reject(error);
|
|
2258
|
-
});
|
|
2259
|
-
});
|
|
2360
|
+
validatePasswordLengthOptions(password, status) {
|
|
2361
|
+
const minPasswordLength = this.customStrengthOptions.minPasswordLength;
|
|
2362
|
+
const maxPasswordLength = this.customStrengthOptions.maxPasswordLength;
|
|
2363
|
+
if (minPasswordLength) {
|
|
2364
|
+
status.meetsMinPasswordLength = password.length >= minPasswordLength;
|
|
2260
2365
|
}
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
if (isEnterprise(grecaptcha)) {
|
|
2264
|
-
grecaptcha.enterprise.ready(() => {
|
|
2265
|
-
grecaptcha.enterprise
|
|
2266
|
-
.execute(siteKey, { action })
|
|
2267
|
-
.then(token => {
|
|
2268
|
-
resolve(token);
|
|
2269
|
-
})
|
|
2270
|
-
.catch(() => {
|
|
2271
|
-
resolve(FAKE_TOKEN);
|
|
2272
|
-
});
|
|
2273
|
-
});
|
|
2274
|
-
}
|
|
2275
|
-
else {
|
|
2276
|
-
reject(Error('No reCAPTCHA enterprise script loaded.'));
|
|
2277
|
-
}
|
|
2366
|
+
if (maxPasswordLength) {
|
|
2367
|
+
status.meetsMaxPasswordLength = password.length <= maxPasswordLength;
|
|
2278
2368
|
}
|
|
2279
|
-
return new Promise((resolve, reject) => {
|
|
2280
|
-
retrieveSiteKey(this.auth)
|
|
2281
|
-
.then(siteKey => {
|
|
2282
|
-
if (!forceRefresh && isEnterprise(window.grecaptcha)) {
|
|
2283
|
-
retrieveRecaptchaToken(siteKey, resolve, reject);
|
|
2284
|
-
}
|
|
2285
|
-
else {
|
|
2286
|
-
if (typeof window === 'undefined') {
|
|
2287
|
-
reject(new Error('RecaptchaVerifier is only supported in browser'));
|
|
2288
|
-
return;
|
|
2289
|
-
}
|
|
2290
|
-
_loadJS(RECAPTCHA_ENTERPRISE_URL + siteKey)
|
|
2291
|
-
.then(() => {
|
|
2292
|
-
retrieveRecaptchaToken(siteKey, resolve, reject);
|
|
2293
|
-
})
|
|
2294
|
-
.catch(error => {
|
|
2295
|
-
reject(error);
|
|
2296
|
-
});
|
|
2297
|
-
}
|
|
2298
|
-
})
|
|
2299
|
-
.catch(error => {
|
|
2300
|
-
reject(error);
|
|
2301
|
-
});
|
|
2302
|
-
});
|
|
2303
|
-
}
|
|
2304
|
-
}
|
|
2305
|
-
async function injectRecaptchaFields(auth, request, action, captchaResp = false) {
|
|
2306
|
-
const verifier = new RecaptchaEnterpriseVerifier(auth);
|
|
2307
|
-
let captchaResponse;
|
|
2308
|
-
try {
|
|
2309
|
-
captchaResponse = await verifier.verify(action);
|
|
2310
|
-
}
|
|
2311
|
-
catch (error) {
|
|
2312
|
-
captchaResponse = await verifier.verify(action, true);
|
|
2313
|
-
}
|
|
2314
|
-
const newRequest = Object.assign({}, request);
|
|
2315
|
-
if (!captchaResp) {
|
|
2316
|
-
Object.assign(newRequest, { captchaResponse });
|
|
2317
|
-
}
|
|
2318
|
-
else {
|
|
2319
|
-
Object.assign(newRequest, { 'captchaResp': captchaResponse });
|
|
2320
|
-
}
|
|
2321
|
-
Object.assign(newRequest, { 'clientType': "CLIENT_TYPE_WEB" /* RecaptchaClientType.WEB */ });
|
|
2322
|
-
Object.assign(newRequest, {
|
|
2323
|
-
'recaptchaVersion': "RECAPTCHA_ENTERPRISE" /* RecaptchaVersion.ENTERPRISE */
|
|
2324
|
-
});
|
|
2325
|
-
return newRequest;
|
|
2326
|
-
}
|
|
2327
|
-
|
|
2328
|
-
/**
|
|
2329
|
-
* @license
|
|
2330
|
-
* Copyright 2022 Google LLC
|
|
2331
|
-
*
|
|
2332
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
2333
|
-
* you may not use this file except in compliance with the License.
|
|
2334
|
-
* You may obtain a copy of the License at
|
|
2335
|
-
*
|
|
2336
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
2337
|
-
*
|
|
2338
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
2339
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
2340
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
2341
|
-
* See the License for the specific language governing permissions and
|
|
2342
|
-
* limitations under the License.
|
|
2343
|
-
*/
|
|
2344
|
-
class AuthMiddlewareQueue {
|
|
2345
|
-
constructor(auth) {
|
|
2346
|
-
this.auth = auth;
|
|
2347
|
-
this.queue = [];
|
|
2348
|
-
}
|
|
2349
|
-
pushCallback(callback, onAbort) {
|
|
2350
|
-
// The callback could be sync or async. Wrap it into a
|
|
2351
|
-
// function that is always async.
|
|
2352
|
-
const wrappedCallback = (user) => new Promise((resolve, reject) => {
|
|
2353
|
-
try {
|
|
2354
|
-
const result = callback(user);
|
|
2355
|
-
// Either resolve with existing promise or wrap a non-promise
|
|
2356
|
-
// return value into a promise.
|
|
2357
|
-
resolve(result);
|
|
2358
|
-
}
|
|
2359
|
-
catch (e) {
|
|
2360
|
-
// Sync callback throws.
|
|
2361
|
-
reject(e);
|
|
2362
|
-
}
|
|
2363
|
-
});
|
|
2364
|
-
// Attach the onAbort if present
|
|
2365
|
-
wrappedCallback.onAbort = onAbort;
|
|
2366
|
-
this.queue.push(wrappedCallback);
|
|
2367
|
-
const index = this.queue.length - 1;
|
|
2368
|
-
return () => {
|
|
2369
|
-
// Unsubscribe. Replace with no-op. Do not remove from array, or it will disturb
|
|
2370
|
-
// indexing of other elements.
|
|
2371
|
-
this.queue[index] = () => Promise.resolve();
|
|
2372
|
-
};
|
|
2373
2369
|
}
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2370
|
+
/**
|
|
2371
|
+
* Validates that the password meets the character options for the policy.
|
|
2372
|
+
*
|
|
2373
|
+
* @param password Password to validate.
|
|
2374
|
+
* @param status Validation status.
|
|
2375
|
+
*/
|
|
2376
|
+
validatePasswordCharacterOptions(password, status) {
|
|
2377
|
+
// Assign statuses for requirements even if the password is an empty string.
|
|
2378
|
+
this.updatePasswordCharacterOptionsStatuses(status,
|
|
2379
|
+
/* containsLowercaseCharacter= */ false,
|
|
2380
|
+
/* containsUppercaseCharacter= */ false,
|
|
2381
|
+
/* containsNumericCharacter= */ false,
|
|
2382
|
+
/* containsNonAlphanumericCharacter= */ false);
|
|
2383
|
+
let passwordChar;
|
|
2384
|
+
for (let i = 0; i < password.length; i++) {
|
|
2385
|
+
passwordChar = password.charAt(i);
|
|
2386
|
+
this.updatePasswordCharacterOptionsStatuses(status,
|
|
2387
|
+
/* containsLowercaseCharacter= */ passwordChar >= 'a' &&
|
|
2388
|
+
passwordChar <= 'z',
|
|
2389
|
+
/* containsUppercaseCharacter= */ passwordChar >= 'A' &&
|
|
2390
|
+
passwordChar <= 'Z',
|
|
2391
|
+
/* containsNumericCharacter= */ passwordChar >= '0' &&
|
|
2392
|
+
passwordChar <= '9',
|
|
2393
|
+
/* containsNonAlphanumericCharacter= */ this.allowedNonAlphanumericCharacters.includes(passwordChar));
|
|
2377
2394
|
}
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2395
|
+
}
|
|
2396
|
+
/**
|
|
2397
|
+
* Updates the running validation status with the statuses for the character options.
|
|
2398
|
+
* Expected to be called each time a character is processed to update each option status
|
|
2399
|
+
* based on the current character.
|
|
2400
|
+
*
|
|
2401
|
+
* @param status Validation status.
|
|
2402
|
+
* @param containsLowercaseCharacter Whether the character is a lowercase letter.
|
|
2403
|
+
* @param containsUppercaseCharacter Whether the character is an uppercase letter.
|
|
2404
|
+
* @param containsNumericCharacter Whether the character is a numeric character.
|
|
2405
|
+
* @param containsNonAlphanumericCharacter Whether the character is a non-alphanumeric character.
|
|
2406
|
+
*/
|
|
2407
|
+
updatePasswordCharacterOptionsStatuses(status, containsLowercaseCharacter, containsUppercaseCharacter, containsNumericCharacter, containsNonAlphanumericCharacter) {
|
|
2408
|
+
if (this.customStrengthOptions.containsLowercaseLetter) {
|
|
2409
|
+
status.containsLowercaseLetter || (status.containsLowercaseLetter = containsLowercaseCharacter);
|
|
2389
2410
|
}
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
catch (_) {
|
|
2399
|
-
/* swallow error */
|
|
2400
|
-
}
|
|
2401
|
-
}
|
|
2402
|
-
throw this.auth._errorFactory.create("login-blocked" /* AuthErrorCode.LOGIN_BLOCKED */, {
|
|
2403
|
-
originalMessage: e === null || e === void 0 ? void 0 : e.message
|
|
2404
|
-
});
|
|
2411
|
+
if (this.customStrengthOptions.containsUppercaseLetter) {
|
|
2412
|
+
status.containsUppercaseLetter || (status.containsUppercaseLetter = containsUppercaseCharacter);
|
|
2413
|
+
}
|
|
2414
|
+
if (this.customStrengthOptions.containsNumericCharacter) {
|
|
2415
|
+
status.containsNumericCharacter || (status.containsNumericCharacter = containsNumericCharacter);
|
|
2416
|
+
}
|
|
2417
|
+
if (this.customStrengthOptions.containsNonAlphanumericCharacter) {
|
|
2418
|
+
status.containsNonAlphanumericCharacter || (status.containsNonAlphanumericCharacter = containsNonAlphanumericCharacter);
|
|
2405
2419
|
}
|
|
2406
2420
|
}
|
|
2407
2421
|
}
|
|
@@ -2436,6 +2450,7 @@ class AuthImpl {
|
|
|
2436
2450
|
this.beforeStateQueue = new AuthMiddlewareQueue(this);
|
|
2437
2451
|
this.redirectUser = null;
|
|
2438
2452
|
this.isProactiveRefreshEnabled = false;
|
|
2453
|
+
this.EXPECTED_PASSWORD_POLICY_SCHEMA_VERSION = 1;
|
|
2439
2454
|
// Any network calls will set this to true and prevent subsequent emulator
|
|
2440
2455
|
// initialization
|
|
2441
2456
|
this._canInitEmulator = true;
|
|
@@ -2446,6 +2461,8 @@ class AuthImpl {
|
|
|
2446
2461
|
this._errorFactory = _DEFAULT_AUTH_ERROR_FACTORY;
|
|
2447
2462
|
this._agentRecaptchaConfig = null;
|
|
2448
2463
|
this._tenantRecaptchaConfigs = {};
|
|
2464
|
+
this._projectPasswordPolicy = null;
|
|
2465
|
+
this._tenantPasswordPolicies = {};
|
|
2449
2466
|
// Tracks the last notified UID for state change listeners to prevent
|
|
2450
2467
|
// repeated calls to the callbacks. Undefined means it's never been
|
|
2451
2468
|
// called, whereas null means it's been called with a signed out user
|
|
@@ -2665,29 +2682,44 @@ class AuthImpl {
|
|
|
2665
2682
|
await this.assertedPersistence.setPersistence(_getInstance(persistence));
|
|
2666
2683
|
});
|
|
2667
2684
|
}
|
|
2668
|
-
|
|
2669
|
-
const response = await getRecaptchaConfig(this, {
|
|
2670
|
-
clientType: "CLIENT_TYPE_WEB" /* RecaptchaClientType.WEB */,
|
|
2671
|
-
version: "RECAPTCHA_ENTERPRISE" /* RecaptchaVersion.ENTERPRISE */
|
|
2672
|
-
});
|
|
2673
|
-
const config = new RecaptchaConfig(response);
|
|
2685
|
+
_getRecaptchaConfig() {
|
|
2674
2686
|
if (this.tenantId == null) {
|
|
2675
|
-
this._agentRecaptchaConfig
|
|
2687
|
+
return this._agentRecaptchaConfig;
|
|
2676
2688
|
}
|
|
2677
2689
|
else {
|
|
2678
|
-
this._tenantRecaptchaConfigs[this.tenantId]
|
|
2690
|
+
return this._tenantRecaptchaConfigs[this.tenantId];
|
|
2679
2691
|
}
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2692
|
+
}
|
|
2693
|
+
async validatePassword(password) {
|
|
2694
|
+
if (!this._getPasswordPolicyInternal()) {
|
|
2695
|
+
await this._updatePasswordPolicy();
|
|
2696
|
+
}
|
|
2697
|
+
// Password policy will be defined after fetching.
|
|
2698
|
+
const passwordPolicy = this._getPasswordPolicyInternal();
|
|
2699
|
+
// Check that the policy schema version is supported by the SDK.
|
|
2700
|
+
// TODO: Update this logic to use a max supported policy schema version once we have multiple schema versions.
|
|
2701
|
+
if (passwordPolicy.schemaVersion !==
|
|
2702
|
+
this.EXPECTED_PASSWORD_POLICY_SCHEMA_VERSION) {
|
|
2703
|
+
return Promise.reject(this._errorFactory.create("unsupported-password-policy-schema-version" /* AuthErrorCode.UNSUPPORTED_PASSWORD_POLICY_SCHEMA_VERSION */, {}));
|
|
2683
2704
|
}
|
|
2705
|
+
return passwordPolicy.validatePassword(password);
|
|
2684
2706
|
}
|
|
2685
|
-
|
|
2686
|
-
if (this.tenantId
|
|
2687
|
-
return this.
|
|
2707
|
+
_getPasswordPolicyInternal() {
|
|
2708
|
+
if (this.tenantId === null) {
|
|
2709
|
+
return this._projectPasswordPolicy;
|
|
2688
2710
|
}
|
|
2689
2711
|
else {
|
|
2690
|
-
return this.
|
|
2712
|
+
return this._tenantPasswordPolicies[this.tenantId];
|
|
2713
|
+
}
|
|
2714
|
+
}
|
|
2715
|
+
async _updatePasswordPolicy() {
|
|
2716
|
+
const response = await _getPasswordPolicy(this);
|
|
2717
|
+
const passwordPolicy = new PasswordPolicyImpl(response);
|
|
2718
|
+
if (this.tenantId === null) {
|
|
2719
|
+
this._projectPasswordPolicy = passwordPolicy;
|
|
2720
|
+
}
|
|
2721
|
+
else {
|
|
2722
|
+
this._tenantPasswordPolicies[this.tenantId] = passwordPolicy;
|
|
2691
2723
|
}
|
|
2692
2724
|
}
|
|
2693
2725
|
_getPersistence() {
|
|
@@ -2808,18 +2840,32 @@ class AuthImpl {
|
|
|
2808
2840
|
const cb = typeof nextOrObserver === 'function'
|
|
2809
2841
|
? nextOrObserver
|
|
2810
2842
|
: nextOrObserver.next.bind(nextOrObserver);
|
|
2843
|
+
let isUnsubscribed = false;
|
|
2811
2844
|
const promise = this._isInitialized
|
|
2812
2845
|
? Promise.resolve()
|
|
2813
2846
|
: this._initializationPromise;
|
|
2814
2847
|
_assert(promise, this, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
|
|
2815
2848
|
// The callback needs to be called asynchronously per the spec.
|
|
2816
2849
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
2817
|
-
promise.then(() =>
|
|
2850
|
+
promise.then(() => {
|
|
2851
|
+
if (isUnsubscribed) {
|
|
2852
|
+
return;
|
|
2853
|
+
}
|
|
2854
|
+
cb(this.currentUser);
|
|
2855
|
+
});
|
|
2818
2856
|
if (typeof nextOrObserver === 'function') {
|
|
2819
|
-
|
|
2857
|
+
const unsubscribe = subscription.addObserver(nextOrObserver, error, completed);
|
|
2858
|
+
return () => {
|
|
2859
|
+
isUnsubscribed = true;
|
|
2860
|
+
unsubscribe();
|
|
2861
|
+
};
|
|
2820
2862
|
}
|
|
2821
2863
|
else {
|
|
2822
|
-
|
|
2864
|
+
const unsubscribe = subscription.addObserver(nextOrObserver);
|
|
2865
|
+
return () => {
|
|
2866
|
+
isUnsubscribed = true;
|
|
2867
|
+
unsubscribe();
|
|
2868
|
+
};
|
|
2823
2869
|
}
|
|
2824
2870
|
}
|
|
2825
2871
|
/**
|
|
@@ -2925,6 +2971,189 @@ class Subscription {
|
|
|
2925
2971
|
}
|
|
2926
2972
|
}
|
|
2927
2973
|
|
|
2974
|
+
/**
|
|
2975
|
+
* @license
|
|
2976
|
+
* Copyright 2020 Google LLC
|
|
2977
|
+
*
|
|
2978
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
2979
|
+
* you may not use this file except in compliance with the License.
|
|
2980
|
+
* You may obtain a copy of the License at
|
|
2981
|
+
*
|
|
2982
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
2983
|
+
*
|
|
2984
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
2985
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
2986
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
2987
|
+
* See the License for the specific language governing permissions and
|
|
2988
|
+
* limitations under the License.
|
|
2989
|
+
*/
|
|
2990
|
+
function getScriptParentElement() {
|
|
2991
|
+
var _a, _b;
|
|
2992
|
+
return (_b = (_a = document.getElementsByTagName('head')) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : document;
|
|
2993
|
+
}
|
|
2994
|
+
function _loadJS(url) {
|
|
2995
|
+
// TODO: consider adding timeout support & cancellation
|
|
2996
|
+
return new Promise((resolve, reject) => {
|
|
2997
|
+
const el = document.createElement('script');
|
|
2998
|
+
el.setAttribute('src', url);
|
|
2999
|
+
el.onload = resolve;
|
|
3000
|
+
el.onerror = e => {
|
|
3001
|
+
const error = _createError("internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
|
|
3002
|
+
error.customData = e;
|
|
3003
|
+
reject(error);
|
|
3004
|
+
};
|
|
3005
|
+
el.type = 'text/javascript';
|
|
3006
|
+
el.charset = 'UTF-8';
|
|
3007
|
+
getScriptParentElement().appendChild(el);
|
|
3008
|
+
});
|
|
3009
|
+
}
|
|
3010
|
+
function _generateCallbackName(prefix) {
|
|
3011
|
+
return `__${prefix}${Math.floor(Math.random() * 1000000)}`;
|
|
3012
|
+
}
|
|
3013
|
+
|
|
3014
|
+
/* eslint-disable @typescript-eslint/no-require-imports */
|
|
3015
|
+
const RECAPTCHA_ENTERPRISE_URL = 'https://www.google.com/recaptcha/enterprise.js?render=';
|
|
3016
|
+
const RECAPTCHA_ENTERPRISE_VERIFIER_TYPE = 'recaptcha-enterprise';
|
|
3017
|
+
const FAKE_TOKEN = 'NO_RECAPTCHA';
|
|
3018
|
+
class RecaptchaEnterpriseVerifier {
|
|
3019
|
+
/**
|
|
3020
|
+
*
|
|
3021
|
+
* @param authExtern - The corresponding Firebase {@link Auth} instance.
|
|
3022
|
+
*
|
|
3023
|
+
*/
|
|
3024
|
+
constructor(authExtern) {
|
|
3025
|
+
/**
|
|
3026
|
+
* Identifies the type of application verifier (e.g. "recaptcha-enterprise").
|
|
3027
|
+
*/
|
|
3028
|
+
this.type = RECAPTCHA_ENTERPRISE_VERIFIER_TYPE;
|
|
3029
|
+
this.auth = _castAuth(authExtern);
|
|
3030
|
+
}
|
|
3031
|
+
/**
|
|
3032
|
+
* Executes the verification process.
|
|
3033
|
+
*
|
|
3034
|
+
* @returns A Promise for a token that can be used to assert the validity of a request.
|
|
3035
|
+
*/
|
|
3036
|
+
async verify(action = 'verify', forceRefresh = false) {
|
|
3037
|
+
async function retrieveSiteKey(auth) {
|
|
3038
|
+
if (!forceRefresh) {
|
|
3039
|
+
if (auth.tenantId == null && auth._agentRecaptchaConfig != null) {
|
|
3040
|
+
return auth._agentRecaptchaConfig.siteKey;
|
|
3041
|
+
}
|
|
3042
|
+
if (auth.tenantId != null &&
|
|
3043
|
+
auth._tenantRecaptchaConfigs[auth.tenantId] !== undefined) {
|
|
3044
|
+
return auth._tenantRecaptchaConfigs[auth.tenantId].siteKey;
|
|
3045
|
+
}
|
|
3046
|
+
}
|
|
3047
|
+
return new Promise(async (resolve, reject) => {
|
|
3048
|
+
getRecaptchaConfig(auth, {
|
|
3049
|
+
clientType: "CLIENT_TYPE_WEB" /* RecaptchaClientType.WEB */,
|
|
3050
|
+
version: "RECAPTCHA_ENTERPRISE" /* RecaptchaVersion.ENTERPRISE */
|
|
3051
|
+
})
|
|
3052
|
+
.then(response => {
|
|
3053
|
+
if (response.recaptchaKey === undefined) {
|
|
3054
|
+
reject(new Error('recaptcha Enterprise site key undefined'));
|
|
3055
|
+
}
|
|
3056
|
+
else {
|
|
3057
|
+
const config = new RecaptchaConfig(response);
|
|
3058
|
+
if (auth.tenantId == null) {
|
|
3059
|
+
auth._agentRecaptchaConfig = config;
|
|
3060
|
+
}
|
|
3061
|
+
else {
|
|
3062
|
+
auth._tenantRecaptchaConfigs[auth.tenantId] = config;
|
|
3063
|
+
}
|
|
3064
|
+
return resolve(config.siteKey);
|
|
3065
|
+
}
|
|
3066
|
+
})
|
|
3067
|
+
.catch(error => {
|
|
3068
|
+
reject(error);
|
|
3069
|
+
});
|
|
3070
|
+
});
|
|
3071
|
+
}
|
|
3072
|
+
function retrieveRecaptchaToken(siteKey, resolve, reject) {
|
|
3073
|
+
const grecaptcha = window.grecaptcha;
|
|
3074
|
+
if (isEnterprise(grecaptcha)) {
|
|
3075
|
+
grecaptcha.enterprise.ready(() => {
|
|
3076
|
+
grecaptcha.enterprise
|
|
3077
|
+
.execute(siteKey, { action })
|
|
3078
|
+
.then(token => {
|
|
3079
|
+
resolve(token);
|
|
3080
|
+
})
|
|
3081
|
+
.catch(() => {
|
|
3082
|
+
resolve(FAKE_TOKEN);
|
|
3083
|
+
});
|
|
3084
|
+
});
|
|
3085
|
+
}
|
|
3086
|
+
else {
|
|
3087
|
+
reject(Error('No reCAPTCHA enterprise script loaded.'));
|
|
3088
|
+
}
|
|
3089
|
+
}
|
|
3090
|
+
return new Promise((resolve, reject) => {
|
|
3091
|
+
retrieveSiteKey(this.auth)
|
|
3092
|
+
.then(siteKey => {
|
|
3093
|
+
if (!forceRefresh && isEnterprise(window.grecaptcha)) {
|
|
3094
|
+
retrieveRecaptchaToken(siteKey, resolve, reject);
|
|
3095
|
+
}
|
|
3096
|
+
else {
|
|
3097
|
+
if (typeof window === 'undefined') {
|
|
3098
|
+
reject(new Error('RecaptchaVerifier is only supported in browser'));
|
|
3099
|
+
return;
|
|
3100
|
+
}
|
|
3101
|
+
_loadJS(RECAPTCHA_ENTERPRISE_URL + siteKey)
|
|
3102
|
+
.then(() => {
|
|
3103
|
+
retrieveRecaptchaToken(siteKey, resolve, reject);
|
|
3104
|
+
})
|
|
3105
|
+
.catch(error => {
|
|
3106
|
+
reject(error);
|
|
3107
|
+
});
|
|
3108
|
+
}
|
|
3109
|
+
})
|
|
3110
|
+
.catch(error => {
|
|
3111
|
+
reject(error);
|
|
3112
|
+
});
|
|
3113
|
+
});
|
|
3114
|
+
}
|
|
3115
|
+
}
|
|
3116
|
+
async function injectRecaptchaFields(auth, request, action, captchaResp = false) {
|
|
3117
|
+
const verifier = new RecaptchaEnterpriseVerifier(auth);
|
|
3118
|
+
let captchaResponse;
|
|
3119
|
+
try {
|
|
3120
|
+
captchaResponse = await verifier.verify(action);
|
|
3121
|
+
}
|
|
3122
|
+
catch (error) {
|
|
3123
|
+
captchaResponse = await verifier.verify(action, true);
|
|
3124
|
+
}
|
|
3125
|
+
const newRequest = Object.assign({}, request);
|
|
3126
|
+
if (!captchaResp) {
|
|
3127
|
+
Object.assign(newRequest, { captchaResponse });
|
|
3128
|
+
}
|
|
3129
|
+
else {
|
|
3130
|
+
Object.assign(newRequest, { 'captchaResp': captchaResponse });
|
|
3131
|
+
}
|
|
3132
|
+
Object.assign(newRequest, { 'clientType': "CLIENT_TYPE_WEB" /* RecaptchaClientType.WEB */ });
|
|
3133
|
+
Object.assign(newRequest, {
|
|
3134
|
+
'recaptchaVersion': "RECAPTCHA_ENTERPRISE" /* RecaptchaVersion.ENTERPRISE */
|
|
3135
|
+
});
|
|
3136
|
+
return newRequest;
|
|
3137
|
+
}
|
|
3138
|
+
async function _initializeRecaptchaConfig(auth) {
|
|
3139
|
+
const authInternal = _castAuth(auth);
|
|
3140
|
+
const response = await getRecaptchaConfig(authInternal, {
|
|
3141
|
+
clientType: "CLIENT_TYPE_WEB" /* RecaptchaClientType.WEB */,
|
|
3142
|
+
version: "RECAPTCHA_ENTERPRISE" /* RecaptchaVersion.ENTERPRISE */
|
|
3143
|
+
});
|
|
3144
|
+
const config = new RecaptchaConfig(response);
|
|
3145
|
+
if (authInternal.tenantId == null) {
|
|
3146
|
+
authInternal._agentRecaptchaConfig = config;
|
|
3147
|
+
}
|
|
3148
|
+
else {
|
|
3149
|
+
authInternal._tenantRecaptchaConfigs[authInternal.tenantId] = config;
|
|
3150
|
+
}
|
|
3151
|
+
if (config.emailPasswordEnabled) {
|
|
3152
|
+
const verifier = new RecaptchaEnterpriseVerifier(authInternal);
|
|
3153
|
+
void verifier.verify();
|
|
3154
|
+
}
|
|
3155
|
+
}
|
|
3156
|
+
|
|
2928
3157
|
/**
|
|
2929
3158
|
* @license
|
|
2930
3159
|
* Copyright 2020 Google LLC
|
|
@@ -5282,6 +5511,25 @@ function _setActionCodeSettingsOnRequest(auth, request, actionCodeSettings) {
|
|
|
5282
5511
|
* See the License for the specific language governing permissions and
|
|
5283
5512
|
* limitations under the License.
|
|
5284
5513
|
*/
|
|
5514
|
+
/**
|
|
5515
|
+
* Updates the password policy cached in the {@link Auth} instance if a policy is already
|
|
5516
|
+
* cached for the project or tenant.
|
|
5517
|
+
*
|
|
5518
|
+
* @remarks
|
|
5519
|
+
* We only fetch the password policy if the password did not meet policy requirements and
|
|
5520
|
+
* there is an existing policy cached. A developer must call validatePassword at least
|
|
5521
|
+
* once for the cache to be automatically updated.
|
|
5522
|
+
*
|
|
5523
|
+
* @param auth - The {@link Auth} instance.
|
|
5524
|
+
*
|
|
5525
|
+
* @private
|
|
5526
|
+
*/
|
|
5527
|
+
async function recachePasswordPolicy(auth) {
|
|
5528
|
+
const authInternal = _castAuth(auth);
|
|
5529
|
+
if (authInternal._getPasswordPolicyInternal()) {
|
|
5530
|
+
await authInternal._updatePasswordPolicy();
|
|
5531
|
+
}
|
|
5532
|
+
}
|
|
5285
5533
|
/**
|
|
5286
5534
|
* Sends a password reset email to the given email address.
|
|
5287
5535
|
*
|
|
@@ -5362,6 +5610,13 @@ async function confirmPasswordReset(auth, oobCode, newPassword) {
|
|
|
5362
5610
|
await resetPassword(util.getModularInstance(auth), {
|
|
5363
5611
|
oobCode,
|
|
5364
5612
|
newPassword
|
|
5613
|
+
})
|
|
5614
|
+
.catch(async (error) => {
|
|
5615
|
+
if (error.code ===
|
|
5616
|
+
`auth/${"password-does-not-meet-requirements" /* AuthErrorCode.PASSWORD_DOES_NOT_MEET_REQUIREMENTS */}`) {
|
|
5617
|
+
void recachePasswordPolicy(auth);
|
|
5618
|
+
}
|
|
5619
|
+
throw error;
|
|
5365
5620
|
});
|
|
5366
5621
|
// Do not return the email.
|
|
5367
5622
|
}
|
|
@@ -5480,13 +5735,14 @@ async function createUserWithEmailAndPassword(auth, email, password) {
|
|
|
5480
5735
|
const requestWithRecaptcha = await injectRecaptchaFields(authInternal, request, "signUpPassword" /* RecaptchaActionName.SIGN_UP_PASSWORD */);
|
|
5481
5736
|
return signUp(authInternal, requestWithRecaptcha);
|
|
5482
5737
|
}
|
|
5483
|
-
|
|
5484
|
-
return Promise.reject(error);
|
|
5485
|
-
}
|
|
5738
|
+
throw error;
|
|
5486
5739
|
});
|
|
5487
5740
|
}
|
|
5488
5741
|
const response = await signUpResponse.catch(error => {
|
|
5489
|
-
|
|
5742
|
+
if (error.code === `auth/${"password-does-not-meet-requirements" /* AuthErrorCode.PASSWORD_DOES_NOT_MEET_REQUIREMENTS */}`) {
|
|
5743
|
+
void recachePasswordPolicy(auth);
|
|
5744
|
+
}
|
|
5745
|
+
throw error;
|
|
5490
5746
|
});
|
|
5491
5747
|
const userCredential = await UserCredentialImpl._fromIdTokenResponse(authInternal, "signIn" /* OperationType.SIGN_IN */, response);
|
|
5492
5748
|
await authInternal._updateCurrentUser(userCredential.user);
|
|
@@ -5509,7 +5765,12 @@ async function createUserWithEmailAndPassword(auth, email, password) {
|
|
|
5509
5765
|
* @public
|
|
5510
5766
|
*/
|
|
5511
5767
|
function signInWithEmailAndPassword(auth, email, password) {
|
|
5512
|
-
return signInWithCredential(util.getModularInstance(auth), EmailAuthProvider.credential(email, password))
|
|
5768
|
+
return signInWithCredential(util.getModularInstance(auth), EmailAuthProvider.credential(email, password)).catch(async (error) => {
|
|
5769
|
+
if (error.code === `auth/${"password-does-not-meet-requirements" /* AuthErrorCode.PASSWORD_DOES_NOT_MEET_REQUIREMENTS */}`) {
|
|
5770
|
+
void recachePasswordPolicy(auth);
|
|
5771
|
+
}
|
|
5772
|
+
throw error;
|
|
5773
|
+
});
|
|
5513
5774
|
}
|
|
5514
5775
|
|
|
5515
5776
|
/**
|
|
@@ -6124,8 +6385,34 @@ function setPersistence(auth, persistence) {
|
|
|
6124
6385
|
* @public
|
|
6125
6386
|
*/
|
|
6126
6387
|
function initializeRecaptchaConfig(auth) {
|
|
6388
|
+
return _initializeRecaptchaConfig(auth);
|
|
6389
|
+
}
|
|
6390
|
+
/**
|
|
6391
|
+
* Validates the password against the password policy configured for the project or tenant.
|
|
6392
|
+
*
|
|
6393
|
+
* @remarks
|
|
6394
|
+
* If no tenant ID is set on the `Auth` instance, then this method will use the password
|
|
6395
|
+
* policy configured for the project. Otherwise, this method will use the policy configured
|
|
6396
|
+
* for the tenant. If a password policy has not been configured, then the default policy
|
|
6397
|
+
* configured for all projects will be used.
|
|
6398
|
+
*
|
|
6399
|
+
* If an auth flow fails because a submitted password does not meet the password policy
|
|
6400
|
+
* requirements and this method has previously been called, then this method will use the
|
|
6401
|
+
* most recent policy available when called again.
|
|
6402
|
+
*
|
|
6403
|
+
* @example
|
|
6404
|
+
* ```javascript
|
|
6405
|
+
* validatePassword(auth, 'some-password');
|
|
6406
|
+
* ```
|
|
6407
|
+
*
|
|
6408
|
+
* @param auth The {@link Auth} instance.
|
|
6409
|
+
* @param password The password to validate.
|
|
6410
|
+
*
|
|
6411
|
+
* @public
|
|
6412
|
+
*/
|
|
6413
|
+
async function validatePassword(auth, password) {
|
|
6127
6414
|
const authInternal = _castAuth(auth);
|
|
6128
|
-
return authInternal.
|
|
6415
|
+
return authInternal.validatePassword(password);
|
|
6129
6416
|
}
|
|
6130
6417
|
/**
|
|
6131
6418
|
* Adds an observer for changes to the signed-in user's ID token.
|
|
@@ -9933,7 +10220,7 @@ function _isEmptyString(input) {
|
|
|
9933
10220
|
}
|
|
9934
10221
|
|
|
9935
10222
|
var name = "@firebase/auth";
|
|
9936
|
-
var version = "1.
|
|
10223
|
+
var version = "1.2.0-20230815211035";
|
|
9937
10224
|
|
|
9938
10225
|
/**
|
|
9939
10226
|
* @license
|
|
@@ -10256,6 +10543,7 @@ exports.updatePassword = updatePassword;
|
|
|
10256
10543
|
exports.updatePhoneNumber = updatePhoneNumber;
|
|
10257
10544
|
exports.updateProfile = updateProfile;
|
|
10258
10545
|
exports.useDeviceLanguage = useDeviceLanguage;
|
|
10546
|
+
exports.validatePassword = validatePassword;
|
|
10259
10547
|
exports.verifyBeforeUpdateEmail = verifyBeforeUpdateEmail;
|
|
10260
10548
|
exports.verifyPasswordResetCode = verifyPasswordResetCode;
|
|
10261
|
-
//# sourceMappingURL=index-
|
|
10549
|
+
//# sourceMappingURL=index-4a6bae3a.js.map
|