@firebase/auth 1.1.0 → 1.2.0-canary.cc77a2a19
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-43e33992.js} +566 -278
- package/dist/browser-cjs/index-43e33992.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-d78c561a.js} +754 -416
- package/dist/cordova/popup_redirect-d78c561a.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-ba845a0f.js} +566 -279
- package/dist/esm2017/index-ba845a0f.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-4859a753.js} +754 -416
- package/dist/esm5/index-4859a753.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-e15cd576.js} +717 -378
- package/dist/node/totp-e15cd576.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-495080fc.js} +554 -267
- package/dist/node-esm/totp-495080fc.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-2e00194a.js} +734 -395
- package/dist/rn/phone-2e00194a.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 +6 -6
- 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
|
@@ -104,6 +104,46 @@ const ActionCodeOperation = {
|
|
|
104
104
|
VERIFY_EMAIL: 'VERIFY_EMAIL'
|
|
105
105
|
};
|
|
106
106
|
|
|
107
|
+
/**
|
|
108
|
+
* @license
|
|
109
|
+
* Copyright 2020 Google LLC
|
|
110
|
+
*
|
|
111
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
112
|
+
* you may not use this file except in compliance with the License.
|
|
113
|
+
* You may obtain a copy of the License at
|
|
114
|
+
*
|
|
115
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
116
|
+
*
|
|
117
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
118
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
119
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
120
|
+
* See the License for the specific language governing permissions and
|
|
121
|
+
* limitations under the License.
|
|
122
|
+
*/
|
|
123
|
+
function isEnterprise(grecaptcha) {
|
|
124
|
+
return (grecaptcha !== undefined &&
|
|
125
|
+
grecaptcha.enterprise !== undefined);
|
|
126
|
+
}
|
|
127
|
+
class RecaptchaConfig {
|
|
128
|
+
constructor(response) {
|
|
129
|
+
/**
|
|
130
|
+
* The reCAPTCHA site key.
|
|
131
|
+
*/
|
|
132
|
+
this.siteKey = '';
|
|
133
|
+
/**
|
|
134
|
+
* The reCAPTCHA enablement status of the {@link EmailAuthProvider} for the current tenant.
|
|
135
|
+
*/
|
|
136
|
+
this.emailPasswordEnabled = false;
|
|
137
|
+
if (response.recaptchaKey === undefined) {
|
|
138
|
+
throw new Error('recaptchaKey undefined');
|
|
139
|
+
}
|
|
140
|
+
// Example response.recaptchaKey: "projects/proj123/keys/sitekey123"
|
|
141
|
+
this.siteKey = response.recaptchaKey.split('/')[3];
|
|
142
|
+
this.emailPasswordEnabled = response.recaptchaEnforcementState.some(enforcementState => enforcementState.provider === 'EMAIL_PASSWORD_PROVIDER' &&
|
|
143
|
+
enforcementState.enforcementState !== 'OFF');
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
107
147
|
/**
|
|
108
148
|
* @license
|
|
109
149
|
* Copyright 2020 Google LLC
|
|
@@ -274,7 +314,9 @@ function _debugErrorMap() {
|
|
|
274
314
|
["missing-client-type" /* AuthErrorCode.MISSING_CLIENT_TYPE */]: 'The reCAPTCHA client type is missing when sending request to the backend.',
|
|
275
315
|
["missing-recaptcha-version" /* AuthErrorCode.MISSING_RECAPTCHA_VERSION */]: 'The reCAPTCHA version is missing when sending request to the backend.',
|
|
276
316
|
["invalid-req-type" /* AuthErrorCode.INVALID_REQ_TYPE */]: 'Invalid request parameters.',
|
|
277
|
-
["invalid-recaptcha-version" /* AuthErrorCode.INVALID_RECAPTCHA_VERSION */]: 'The reCAPTCHA version is invalid when sending request to the backend.'
|
|
317
|
+
["invalid-recaptcha-version" /* AuthErrorCode.INVALID_RECAPTCHA_VERSION */]: 'The reCAPTCHA version is invalid when sending request to the backend.',
|
|
318
|
+
["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.',
|
|
319
|
+
["password-does-not-meet-requirements" /* AuthErrorCode.PASSWORD_DOES_NOT_MEET_REQUIREMENTS */]: 'The password does not meet the requirements.'
|
|
278
320
|
};
|
|
279
321
|
}
|
|
280
322
|
function _prodErrorMap() {
|
|
@@ -778,6 +820,7 @@ const SERVER_ERROR_MAP = {
|
|
|
778
820
|
["USER_NOT_FOUND" /* ServerError.USER_NOT_FOUND */]: "user-token-expired" /* AuthErrorCode.TOKEN_EXPIRED */,
|
|
779
821
|
// Other errors.
|
|
780
822
|
["TOO_MANY_ATTEMPTS_TRY_LATER" /* ServerError.TOO_MANY_ATTEMPTS_TRY_LATER */]: "too-many-requests" /* AuthErrorCode.TOO_MANY_ATTEMPTS_TRY_LATER */,
|
|
823
|
+
["PASSWORD_DOES_NOT_MEET_REQUIREMENTS" /* ServerError.PASSWORD_DOES_NOT_MEET_REQUIREMENTS */]: "password-does-not-meet-requirements" /* AuthErrorCode.PASSWORD_DOES_NOT_MEET_REQUIREMENTS */,
|
|
781
824
|
// Phone Auth related errors.
|
|
782
825
|
["INVALID_CODE" /* ServerError.INVALID_CODE */]: "invalid-verification-code" /* AuthErrorCode.INVALID_CODE */,
|
|
783
826
|
["INVALID_SESSION_INFO" /* ServerError.INVALID_SESSION_INFO */]: "invalid-verification-id" /* AuthErrorCode.INVALID_SESSION_INFO */,
|
|
@@ -962,6 +1005,26 @@ function _makeTaggedError(auth, code, response) {
|
|
|
962
1005
|
return error;
|
|
963
1006
|
}
|
|
964
1007
|
|
|
1008
|
+
/**
|
|
1009
|
+
* @license
|
|
1010
|
+
* Copyright 2020 Google LLC
|
|
1011
|
+
*
|
|
1012
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
1013
|
+
* you may not use this file except in compliance with the License.
|
|
1014
|
+
* You may obtain a copy of the License at
|
|
1015
|
+
*
|
|
1016
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
1017
|
+
*
|
|
1018
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
1019
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
1020
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
1021
|
+
* See the License for the specific language governing permissions and
|
|
1022
|
+
* limitations under the License.
|
|
1023
|
+
*/
|
|
1024
|
+
async function getRecaptchaConfig(auth, request) {
|
|
1025
|
+
return _performApiRequest(auth, "GET" /* HttpMethod.GET */, "/v2/recaptchaConfig" /* Endpoint.GET_RECAPTCHA_CONFIG */, _addTidIfNecessary(auth, request));
|
|
1026
|
+
}
|
|
1027
|
+
|
|
965
1028
|
/**
|
|
966
1029
|
* @license
|
|
967
1030
|
* Copyright 2020 Google LLC
|
|
@@ -2080,7 +2143,7 @@ function _getClientVersion(clientPlatform, frameworks = []) {
|
|
|
2080
2143
|
|
|
2081
2144
|
/**
|
|
2082
2145
|
* @license
|
|
2083
|
-
* Copyright
|
|
2146
|
+
* Copyright 2022 Google LLC
|
|
2084
2147
|
*
|
|
2085
2148
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
2086
2149
|
* you may not use this file except in compliance with the License.
|
|
@@ -2094,13 +2157,74 @@ function _getClientVersion(clientPlatform, frameworks = []) {
|
|
|
2094
2157
|
* See the License for the specific language governing permissions and
|
|
2095
2158
|
* limitations under the License.
|
|
2096
2159
|
*/
|
|
2097
|
-
|
|
2098
|
-
|
|
2160
|
+
class AuthMiddlewareQueue {
|
|
2161
|
+
constructor(auth) {
|
|
2162
|
+
this.auth = auth;
|
|
2163
|
+
this.queue = [];
|
|
2164
|
+
}
|
|
2165
|
+
pushCallback(callback, onAbort) {
|
|
2166
|
+
// The callback could be sync or async. Wrap it into a
|
|
2167
|
+
// function that is always async.
|
|
2168
|
+
const wrappedCallback = (user) => new Promise((resolve, reject) => {
|
|
2169
|
+
try {
|
|
2170
|
+
const result = callback(user);
|
|
2171
|
+
// Either resolve with existing promise or wrap a non-promise
|
|
2172
|
+
// return value into a promise.
|
|
2173
|
+
resolve(result);
|
|
2174
|
+
}
|
|
2175
|
+
catch (e) {
|
|
2176
|
+
// Sync callback throws.
|
|
2177
|
+
reject(e);
|
|
2178
|
+
}
|
|
2179
|
+
});
|
|
2180
|
+
// Attach the onAbort if present
|
|
2181
|
+
wrappedCallback.onAbort = onAbort;
|
|
2182
|
+
this.queue.push(wrappedCallback);
|
|
2183
|
+
const index = this.queue.length - 1;
|
|
2184
|
+
return () => {
|
|
2185
|
+
// Unsubscribe. Replace with no-op. Do not remove from array, or it will disturb
|
|
2186
|
+
// indexing of other elements.
|
|
2187
|
+
this.queue[index] = () => Promise.resolve();
|
|
2188
|
+
};
|
|
2189
|
+
}
|
|
2190
|
+
async runMiddleware(nextUser) {
|
|
2191
|
+
if (this.auth.currentUser === nextUser) {
|
|
2192
|
+
return;
|
|
2193
|
+
}
|
|
2194
|
+
// While running the middleware, build a temporary stack of onAbort
|
|
2195
|
+
// callbacks to call if one middleware callback rejects.
|
|
2196
|
+
const onAbortStack = [];
|
|
2197
|
+
try {
|
|
2198
|
+
for (const beforeStateCallback of this.queue) {
|
|
2199
|
+
await beforeStateCallback(nextUser);
|
|
2200
|
+
// Only push the onAbort if the callback succeeds
|
|
2201
|
+
if (beforeStateCallback.onAbort) {
|
|
2202
|
+
onAbortStack.push(beforeStateCallback.onAbort);
|
|
2203
|
+
}
|
|
2204
|
+
}
|
|
2205
|
+
}
|
|
2206
|
+
catch (e) {
|
|
2207
|
+
// Run all onAbort, with separate try/catch to ignore any errors and
|
|
2208
|
+
// continue
|
|
2209
|
+
onAbortStack.reverse();
|
|
2210
|
+
for (const onAbort of onAbortStack) {
|
|
2211
|
+
try {
|
|
2212
|
+
onAbort();
|
|
2213
|
+
}
|
|
2214
|
+
catch (_) {
|
|
2215
|
+
/* swallow error */
|
|
2216
|
+
}
|
|
2217
|
+
}
|
|
2218
|
+
throw this.auth._errorFactory.create("login-blocked" /* AuthErrorCode.LOGIN_BLOCKED */, {
|
|
2219
|
+
originalMessage: e === null || e === void 0 ? void 0 : e.message
|
|
2220
|
+
});
|
|
2221
|
+
}
|
|
2222
|
+
}
|
|
2099
2223
|
}
|
|
2100
2224
|
|
|
2101
2225
|
/**
|
|
2102
2226
|
* @license
|
|
2103
|
-
* Copyright
|
|
2227
|
+
* Copyright 2023 Google LLC
|
|
2104
2228
|
*
|
|
2105
2229
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
2106
2230
|
* you may not use this file except in compliance with the License.
|
|
@@ -2114,33 +2238,20 @@ async function getRecaptchaConfig(auth, request) {
|
|
|
2114
2238
|
* See the License for the specific language governing permissions and
|
|
2115
2239
|
* limitations under the License.
|
|
2116
2240
|
*/
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
this.siteKey = '';
|
|
2127
|
-
/**
|
|
2128
|
-
* The reCAPTCHA enablement status of the {@link EmailAuthProvider} for the current tenant.
|
|
2129
|
-
*/
|
|
2130
|
-
this.emailPasswordEnabled = false;
|
|
2131
|
-
if (response.recaptchaKey === undefined) {
|
|
2132
|
-
throw new Error('recaptchaKey undefined');
|
|
2133
|
-
}
|
|
2134
|
-
// Example response.recaptchaKey: "projects/proj123/keys/sitekey123"
|
|
2135
|
-
this.siteKey = response.recaptchaKey.split('/')[3];
|
|
2136
|
-
this.emailPasswordEnabled = response.recaptchaEnforcementState.some(enforcementState => enforcementState.provider === 'EMAIL_PASSWORD_PROVIDER' &&
|
|
2137
|
-
enforcementState.enforcementState !== 'OFF');
|
|
2138
|
-
}
|
|
2241
|
+
/**
|
|
2242
|
+
* Fetches the password policy for the currently set tenant or the project if no tenant is set.
|
|
2243
|
+
*
|
|
2244
|
+
* @param auth Auth object.
|
|
2245
|
+
* @param request Password policy request.
|
|
2246
|
+
* @returns Password policy response.
|
|
2247
|
+
*/
|
|
2248
|
+
async function _getPasswordPolicy(auth, request = {}) {
|
|
2249
|
+
return _performApiRequest(auth, "GET" /* HttpMethod.GET */, "/v2/passwordPolicy" /* Endpoint.GET_PASSWORD_POLICY */, _addTidIfNecessary(auth, request));
|
|
2139
2250
|
}
|
|
2140
2251
|
|
|
2141
2252
|
/**
|
|
2142
2253
|
* @license
|
|
2143
|
-
* Copyright
|
|
2254
|
+
* Copyright 2023 Google LLC
|
|
2144
2255
|
*
|
|
2145
2256
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
2146
2257
|
* you may not use this file except in compliance with the License.
|
|
@@ -2154,229 +2265,135 @@ class RecaptchaConfig {
|
|
|
2154
2265
|
* See the License for the specific language governing permissions and
|
|
2155
2266
|
* limitations under the License.
|
|
2156
2267
|
*/
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2268
|
+
// Minimum min password length enforced by the backend, even if no minimum length is set.
|
|
2269
|
+
const MINIMUM_MIN_PASSWORD_LENGTH = 6;
|
|
2270
|
+
/**
|
|
2271
|
+
* Stores password policy requirements and provides password validation against the policy.
|
|
2272
|
+
*
|
|
2273
|
+
* @internal
|
|
2274
|
+
*/
|
|
2275
|
+
class PasswordPolicyImpl {
|
|
2276
|
+
constructor(response) {
|
|
2277
|
+
var _a, _b, _c, _d;
|
|
2278
|
+
// Only include custom strength options defined in the response.
|
|
2279
|
+
const responseOptions = response.customStrengthOptions;
|
|
2280
|
+
this.customStrengthOptions = {};
|
|
2281
|
+
// TODO: Remove once the backend is updated to include the minimum min password length instead of undefined when there is no minimum length set.
|
|
2282
|
+
this.customStrengthOptions.minPasswordLength =
|
|
2283
|
+
(_a = responseOptions.minPasswordLength) !== null && _a !== void 0 ? _a : MINIMUM_MIN_PASSWORD_LENGTH;
|
|
2284
|
+
if (responseOptions.maxPasswordLength) {
|
|
2285
|
+
this.customStrengthOptions.maxPasswordLength =
|
|
2286
|
+
responseOptions.maxPasswordLength;
|
|
2287
|
+
}
|
|
2288
|
+
if (responseOptions.containsLowercaseCharacter !== undefined) {
|
|
2289
|
+
this.customStrengthOptions.containsLowercaseLetter =
|
|
2290
|
+
responseOptions.containsLowercaseCharacter;
|
|
2291
|
+
}
|
|
2292
|
+
if (responseOptions.containsUppercaseCharacter !== undefined) {
|
|
2293
|
+
this.customStrengthOptions.containsUppercaseLetter =
|
|
2294
|
+
responseOptions.containsUppercaseCharacter;
|
|
2295
|
+
}
|
|
2296
|
+
if (responseOptions.containsNumericCharacter !== undefined) {
|
|
2297
|
+
this.customStrengthOptions.containsNumericCharacter =
|
|
2298
|
+
responseOptions.containsNumericCharacter;
|
|
2299
|
+
}
|
|
2300
|
+
if (responseOptions.containsNonAlphanumericCharacter !== undefined) {
|
|
2301
|
+
this.customStrengthOptions.containsNonAlphanumericCharacter =
|
|
2302
|
+
responseOptions.containsNonAlphanumericCharacter;
|
|
2303
|
+
}
|
|
2304
|
+
this.enforcementState = response.enforcementState;
|
|
2305
|
+
if (this.enforcementState === 'ENFORCEMENT_STATE_UNSPECIFIED') {
|
|
2306
|
+
this.enforcementState = 'OFF';
|
|
2307
|
+
}
|
|
2308
|
+
// Use an empty string if no non-alphanumeric characters are specified in the response.
|
|
2309
|
+
this.allowedNonAlphanumericCharacters =
|
|
2310
|
+
(_c = (_b = response.allowedNonAlphanumericCharacters) === null || _b === void 0 ? void 0 : _b.join('')) !== null && _c !== void 0 ? _c : '';
|
|
2311
|
+
this.forceUpgradeOnSignin = (_d = response.forceUpgradeOnSignin) !== null && _d !== void 0 ? _d : false;
|
|
2312
|
+
this.schemaVersion = response.schemaVersion;
|
|
2313
|
+
}
|
|
2314
|
+
validatePassword(password) {
|
|
2315
|
+
var _a, _b, _c, _d, _e, _f;
|
|
2316
|
+
const status = {
|
|
2317
|
+
isValid: true,
|
|
2318
|
+
passwordPolicy: this
|
|
2171
2319
|
};
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
/**
|
|
2184
|
-
*
|
|
2185
|
-
* @param authExtern - The corresponding Firebase {@link Auth} instance.
|
|
2186
|
-
*
|
|
2187
|
-
*/
|
|
2188
|
-
constructor(authExtern) {
|
|
2189
|
-
/**
|
|
2190
|
-
* Identifies the type of application verifier (e.g. "recaptcha-enterprise").
|
|
2191
|
-
*/
|
|
2192
|
-
this.type = RECAPTCHA_ENTERPRISE_VERIFIER_TYPE;
|
|
2193
|
-
this.auth = _castAuth(authExtern);
|
|
2320
|
+
// Check the password length and character options.
|
|
2321
|
+
this.validatePasswordLengthOptions(password, status);
|
|
2322
|
+
this.validatePasswordCharacterOptions(password, status);
|
|
2323
|
+
// Combine the status into single isValid property.
|
|
2324
|
+
status.isValid && (status.isValid = (_a = status.meetsMinPasswordLength) !== null && _a !== void 0 ? _a : true);
|
|
2325
|
+
status.isValid && (status.isValid = (_b = status.meetsMaxPasswordLength) !== null && _b !== void 0 ? _b : true);
|
|
2326
|
+
status.isValid && (status.isValid = (_c = status.containsLowercaseLetter) !== null && _c !== void 0 ? _c : true);
|
|
2327
|
+
status.isValid && (status.isValid = (_d = status.containsUppercaseLetter) !== null && _d !== void 0 ? _d : true);
|
|
2328
|
+
status.isValid && (status.isValid = (_e = status.containsNumericCharacter) !== null && _e !== void 0 ? _e : true);
|
|
2329
|
+
status.isValid && (status.isValid = (_f = status.containsNonAlphanumericCharacter) !== null && _f !== void 0 ? _f : true);
|
|
2330
|
+
return status;
|
|
2194
2331
|
}
|
|
2195
2332
|
/**
|
|
2196
|
-
*
|
|
2333
|
+
* Validates that the password meets the length options for the policy.
|
|
2197
2334
|
*
|
|
2198
|
-
* @
|
|
2335
|
+
* @param password Password to validate.
|
|
2336
|
+
* @param status Validation status.
|
|
2199
2337
|
*/
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
}
|
|
2206
|
-
if (auth.tenantId != null &&
|
|
2207
|
-
auth._tenantRecaptchaConfigs[auth.tenantId] !== undefined) {
|
|
2208
|
-
return auth._tenantRecaptchaConfigs[auth.tenantId].siteKey;
|
|
2209
|
-
}
|
|
2210
|
-
}
|
|
2211
|
-
return new Promise(async (resolve, reject) => {
|
|
2212
|
-
getRecaptchaConfig(auth, {
|
|
2213
|
-
clientType: "CLIENT_TYPE_WEB" /* RecaptchaClientType.WEB */,
|
|
2214
|
-
version: "RECAPTCHA_ENTERPRISE" /* RecaptchaVersion.ENTERPRISE */
|
|
2215
|
-
})
|
|
2216
|
-
.then(response => {
|
|
2217
|
-
if (response.recaptchaKey === undefined) {
|
|
2218
|
-
reject(new Error('recaptcha Enterprise site key undefined'));
|
|
2219
|
-
}
|
|
2220
|
-
else {
|
|
2221
|
-
const config = new RecaptchaConfig(response);
|
|
2222
|
-
if (auth.tenantId == null) {
|
|
2223
|
-
auth._agentRecaptchaConfig = config;
|
|
2224
|
-
}
|
|
2225
|
-
else {
|
|
2226
|
-
auth._tenantRecaptchaConfigs[auth.tenantId] = config;
|
|
2227
|
-
}
|
|
2228
|
-
return resolve(config.siteKey);
|
|
2229
|
-
}
|
|
2230
|
-
})
|
|
2231
|
-
.catch(error => {
|
|
2232
|
-
reject(error);
|
|
2233
|
-
});
|
|
2234
|
-
});
|
|
2338
|
+
validatePasswordLengthOptions(password, status) {
|
|
2339
|
+
const minPasswordLength = this.customStrengthOptions.minPasswordLength;
|
|
2340
|
+
const maxPasswordLength = this.customStrengthOptions.maxPasswordLength;
|
|
2341
|
+
if (minPasswordLength) {
|
|
2342
|
+
status.meetsMinPasswordLength = password.length >= minPasswordLength;
|
|
2235
2343
|
}
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
if (isEnterprise(grecaptcha)) {
|
|
2239
|
-
grecaptcha.enterprise.ready(() => {
|
|
2240
|
-
grecaptcha.enterprise
|
|
2241
|
-
.execute(siteKey, { action })
|
|
2242
|
-
.then(token => {
|
|
2243
|
-
resolve(token);
|
|
2244
|
-
})
|
|
2245
|
-
.catch(() => {
|
|
2246
|
-
resolve(FAKE_TOKEN);
|
|
2247
|
-
});
|
|
2248
|
-
});
|
|
2249
|
-
}
|
|
2250
|
-
else {
|
|
2251
|
-
reject(Error('No reCAPTCHA enterprise script loaded.'));
|
|
2252
|
-
}
|
|
2344
|
+
if (maxPasswordLength) {
|
|
2345
|
+
status.meetsMaxPasswordLength = password.length <= maxPasswordLength;
|
|
2253
2346
|
}
|
|
2254
|
-
return new Promise((resolve, reject) => {
|
|
2255
|
-
retrieveSiteKey(this.auth)
|
|
2256
|
-
.then(siteKey => {
|
|
2257
|
-
if (!forceRefresh && isEnterprise(window.grecaptcha)) {
|
|
2258
|
-
retrieveRecaptchaToken(siteKey, resolve, reject);
|
|
2259
|
-
}
|
|
2260
|
-
else {
|
|
2261
|
-
if (typeof window === 'undefined') {
|
|
2262
|
-
reject(new Error('RecaptchaVerifier is only supported in browser'));
|
|
2263
|
-
return;
|
|
2264
|
-
}
|
|
2265
|
-
_loadJS(RECAPTCHA_ENTERPRISE_URL + siteKey)
|
|
2266
|
-
.then(() => {
|
|
2267
|
-
retrieveRecaptchaToken(siteKey, resolve, reject);
|
|
2268
|
-
})
|
|
2269
|
-
.catch(error => {
|
|
2270
|
-
reject(error);
|
|
2271
|
-
});
|
|
2272
|
-
}
|
|
2273
|
-
})
|
|
2274
|
-
.catch(error => {
|
|
2275
|
-
reject(error);
|
|
2276
|
-
});
|
|
2277
|
-
});
|
|
2278
2347
|
}
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
* @license
|
|
2305
|
-
* Copyright 2022 Google LLC
|
|
2306
|
-
*
|
|
2307
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
2308
|
-
* you may not use this file except in compliance with the License.
|
|
2309
|
-
* You may obtain a copy of the License at
|
|
2310
|
-
*
|
|
2311
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
2312
|
-
*
|
|
2313
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
2314
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
2315
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
2316
|
-
* See the License for the specific language governing permissions and
|
|
2317
|
-
* limitations under the License.
|
|
2318
|
-
*/
|
|
2319
|
-
class AuthMiddlewareQueue {
|
|
2320
|
-
constructor(auth) {
|
|
2321
|
-
this.auth = auth;
|
|
2322
|
-
this.queue = [];
|
|
2323
|
-
}
|
|
2324
|
-
pushCallback(callback, onAbort) {
|
|
2325
|
-
// The callback could be sync or async. Wrap it into a
|
|
2326
|
-
// function that is always async.
|
|
2327
|
-
const wrappedCallback = (user) => new Promise((resolve, reject) => {
|
|
2328
|
-
try {
|
|
2329
|
-
const result = callback(user);
|
|
2330
|
-
// Either resolve with existing promise or wrap a non-promise
|
|
2331
|
-
// return value into a promise.
|
|
2332
|
-
resolve(result);
|
|
2333
|
-
}
|
|
2334
|
-
catch (e) {
|
|
2335
|
-
// Sync callback throws.
|
|
2336
|
-
reject(e);
|
|
2337
|
-
}
|
|
2338
|
-
});
|
|
2339
|
-
// Attach the onAbort if present
|
|
2340
|
-
wrappedCallback.onAbort = onAbort;
|
|
2341
|
-
this.queue.push(wrappedCallback);
|
|
2342
|
-
const index = this.queue.length - 1;
|
|
2343
|
-
return () => {
|
|
2344
|
-
// Unsubscribe. Replace with no-op. Do not remove from array, or it will disturb
|
|
2345
|
-
// indexing of other elements.
|
|
2346
|
-
this.queue[index] = () => Promise.resolve();
|
|
2347
|
-
};
|
|
2348
|
+
/**
|
|
2349
|
+
* Validates that the password meets the character options for the policy.
|
|
2350
|
+
*
|
|
2351
|
+
* @param password Password to validate.
|
|
2352
|
+
* @param status Validation status.
|
|
2353
|
+
*/
|
|
2354
|
+
validatePasswordCharacterOptions(password, status) {
|
|
2355
|
+
// Assign statuses for requirements even if the password is an empty string.
|
|
2356
|
+
this.updatePasswordCharacterOptionsStatuses(status,
|
|
2357
|
+
/* containsLowercaseCharacter= */ false,
|
|
2358
|
+
/* containsUppercaseCharacter= */ false,
|
|
2359
|
+
/* containsNumericCharacter= */ false,
|
|
2360
|
+
/* containsNonAlphanumericCharacter= */ false);
|
|
2361
|
+
let passwordChar;
|
|
2362
|
+
for (let i = 0; i < password.length; i++) {
|
|
2363
|
+
passwordChar = password.charAt(i);
|
|
2364
|
+
this.updatePasswordCharacterOptionsStatuses(status,
|
|
2365
|
+
/* containsLowercaseCharacter= */ passwordChar >= 'a' &&
|
|
2366
|
+
passwordChar <= 'z',
|
|
2367
|
+
/* containsUppercaseCharacter= */ passwordChar >= 'A' &&
|
|
2368
|
+
passwordChar <= 'Z',
|
|
2369
|
+
/* containsNumericCharacter= */ passwordChar >= '0' &&
|
|
2370
|
+
passwordChar <= '9',
|
|
2371
|
+
/* containsNonAlphanumericCharacter= */ this.allowedNonAlphanumericCharacters.includes(passwordChar));
|
|
2372
|
+
}
|
|
2348
2373
|
}
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2374
|
+
/**
|
|
2375
|
+
* Updates the running validation status with the statuses for the character options.
|
|
2376
|
+
* Expected to be called each time a character is processed to update each option status
|
|
2377
|
+
* based on the current character.
|
|
2378
|
+
*
|
|
2379
|
+
* @param status Validation status.
|
|
2380
|
+
* @param containsLowercaseCharacter Whether the character is a lowercase letter.
|
|
2381
|
+
* @param containsUppercaseCharacter Whether the character is an uppercase letter.
|
|
2382
|
+
* @param containsNumericCharacter Whether the character is a numeric character.
|
|
2383
|
+
* @param containsNonAlphanumericCharacter Whether the character is a non-alphanumeric character.
|
|
2384
|
+
*/
|
|
2385
|
+
updatePasswordCharacterOptionsStatuses(status, containsLowercaseCharacter, containsUppercaseCharacter, containsNumericCharacter, containsNonAlphanumericCharacter) {
|
|
2386
|
+
if (this.customStrengthOptions.containsLowercaseLetter) {
|
|
2387
|
+
status.containsLowercaseLetter || (status.containsLowercaseLetter = containsLowercaseCharacter);
|
|
2352
2388
|
}
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
const onAbortStack = [];
|
|
2356
|
-
try {
|
|
2357
|
-
for (const beforeStateCallback of this.queue) {
|
|
2358
|
-
await beforeStateCallback(nextUser);
|
|
2359
|
-
// Only push the onAbort if the callback succeeds
|
|
2360
|
-
if (beforeStateCallback.onAbort) {
|
|
2361
|
-
onAbortStack.push(beforeStateCallback.onAbort);
|
|
2362
|
-
}
|
|
2363
|
-
}
|
|
2389
|
+
if (this.customStrengthOptions.containsUppercaseLetter) {
|
|
2390
|
+
status.containsUppercaseLetter || (status.containsUppercaseLetter = containsUppercaseCharacter);
|
|
2364
2391
|
}
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
try {
|
|
2371
|
-
onAbort();
|
|
2372
|
-
}
|
|
2373
|
-
catch (_) {
|
|
2374
|
-
/* swallow error */
|
|
2375
|
-
}
|
|
2376
|
-
}
|
|
2377
|
-
throw this.auth._errorFactory.create("login-blocked" /* AuthErrorCode.LOGIN_BLOCKED */, {
|
|
2378
|
-
originalMessage: e === null || e === void 0 ? void 0 : e.message
|
|
2379
|
-
});
|
|
2392
|
+
if (this.customStrengthOptions.containsNumericCharacter) {
|
|
2393
|
+
status.containsNumericCharacter || (status.containsNumericCharacter = containsNumericCharacter);
|
|
2394
|
+
}
|
|
2395
|
+
if (this.customStrengthOptions.containsNonAlphanumericCharacter) {
|
|
2396
|
+
status.containsNonAlphanumericCharacter || (status.containsNonAlphanumericCharacter = containsNonAlphanumericCharacter);
|
|
2380
2397
|
}
|
|
2381
2398
|
}
|
|
2382
2399
|
}
|
|
@@ -2411,6 +2428,7 @@ class AuthImpl {
|
|
|
2411
2428
|
this.beforeStateQueue = new AuthMiddlewareQueue(this);
|
|
2412
2429
|
this.redirectUser = null;
|
|
2413
2430
|
this.isProactiveRefreshEnabled = false;
|
|
2431
|
+
this.EXPECTED_PASSWORD_POLICY_SCHEMA_VERSION = 1;
|
|
2414
2432
|
// Any network calls will set this to true and prevent subsequent emulator
|
|
2415
2433
|
// initialization
|
|
2416
2434
|
this._canInitEmulator = true;
|
|
@@ -2421,6 +2439,8 @@ class AuthImpl {
|
|
|
2421
2439
|
this._errorFactory = _DEFAULT_AUTH_ERROR_FACTORY;
|
|
2422
2440
|
this._agentRecaptchaConfig = null;
|
|
2423
2441
|
this._tenantRecaptchaConfigs = {};
|
|
2442
|
+
this._projectPasswordPolicy = null;
|
|
2443
|
+
this._tenantPasswordPolicies = {};
|
|
2424
2444
|
// Tracks the last notified UID for state change listeners to prevent
|
|
2425
2445
|
// repeated calls to the callbacks. Undefined means it's never been
|
|
2426
2446
|
// called, whereas null means it's been called with a signed out user
|
|
@@ -2640,29 +2660,44 @@ class AuthImpl {
|
|
|
2640
2660
|
await this.assertedPersistence.setPersistence(_getInstance(persistence));
|
|
2641
2661
|
});
|
|
2642
2662
|
}
|
|
2643
|
-
|
|
2644
|
-
const response = await getRecaptchaConfig(this, {
|
|
2645
|
-
clientType: "CLIENT_TYPE_WEB" /* RecaptchaClientType.WEB */,
|
|
2646
|
-
version: "RECAPTCHA_ENTERPRISE" /* RecaptchaVersion.ENTERPRISE */
|
|
2647
|
-
});
|
|
2648
|
-
const config = new RecaptchaConfig(response);
|
|
2663
|
+
_getRecaptchaConfig() {
|
|
2649
2664
|
if (this.tenantId == null) {
|
|
2650
|
-
this._agentRecaptchaConfig
|
|
2665
|
+
return this._agentRecaptchaConfig;
|
|
2651
2666
|
}
|
|
2652
2667
|
else {
|
|
2653
|
-
this._tenantRecaptchaConfigs[this.tenantId]
|
|
2668
|
+
return this._tenantRecaptchaConfigs[this.tenantId];
|
|
2669
|
+
}
|
|
2670
|
+
}
|
|
2671
|
+
async validatePassword(password) {
|
|
2672
|
+
if (!this._getPasswordPolicyInternal()) {
|
|
2673
|
+
await this._updatePasswordPolicy();
|
|
2654
2674
|
}
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2675
|
+
// Password policy will be defined after fetching.
|
|
2676
|
+
const passwordPolicy = this._getPasswordPolicyInternal();
|
|
2677
|
+
// Check that the policy schema version is supported by the SDK.
|
|
2678
|
+
// TODO: Update this logic to use a max supported policy schema version once we have multiple schema versions.
|
|
2679
|
+
if (passwordPolicy.schemaVersion !==
|
|
2680
|
+
this.EXPECTED_PASSWORD_POLICY_SCHEMA_VERSION) {
|
|
2681
|
+
return Promise.reject(this._errorFactory.create("unsupported-password-policy-schema-version" /* AuthErrorCode.UNSUPPORTED_PASSWORD_POLICY_SCHEMA_VERSION */, {}));
|
|
2658
2682
|
}
|
|
2683
|
+
return passwordPolicy.validatePassword(password);
|
|
2659
2684
|
}
|
|
2660
|
-
|
|
2661
|
-
if (this.tenantId
|
|
2662
|
-
return this.
|
|
2685
|
+
_getPasswordPolicyInternal() {
|
|
2686
|
+
if (this.tenantId === null) {
|
|
2687
|
+
return this._projectPasswordPolicy;
|
|
2663
2688
|
}
|
|
2664
2689
|
else {
|
|
2665
|
-
return this.
|
|
2690
|
+
return this._tenantPasswordPolicies[this.tenantId];
|
|
2691
|
+
}
|
|
2692
|
+
}
|
|
2693
|
+
async _updatePasswordPolicy() {
|
|
2694
|
+
const response = await _getPasswordPolicy(this);
|
|
2695
|
+
const passwordPolicy = new PasswordPolicyImpl(response);
|
|
2696
|
+
if (this.tenantId === null) {
|
|
2697
|
+
this._projectPasswordPolicy = passwordPolicy;
|
|
2698
|
+
}
|
|
2699
|
+
else {
|
|
2700
|
+
this._tenantPasswordPolicies[this.tenantId] = passwordPolicy;
|
|
2666
2701
|
}
|
|
2667
2702
|
}
|
|
2668
2703
|
_getPersistence() {
|
|
@@ -2783,18 +2818,32 @@ class AuthImpl {
|
|
|
2783
2818
|
const cb = typeof nextOrObserver === 'function'
|
|
2784
2819
|
? nextOrObserver
|
|
2785
2820
|
: nextOrObserver.next.bind(nextOrObserver);
|
|
2821
|
+
let isUnsubscribed = false;
|
|
2786
2822
|
const promise = this._isInitialized
|
|
2787
2823
|
? Promise.resolve()
|
|
2788
2824
|
: this._initializationPromise;
|
|
2789
2825
|
_assert(promise, this, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
|
|
2790
2826
|
// The callback needs to be called asynchronously per the spec.
|
|
2791
2827
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
2792
|
-
promise.then(() =>
|
|
2828
|
+
promise.then(() => {
|
|
2829
|
+
if (isUnsubscribed) {
|
|
2830
|
+
return;
|
|
2831
|
+
}
|
|
2832
|
+
cb(this.currentUser);
|
|
2833
|
+
});
|
|
2793
2834
|
if (typeof nextOrObserver === 'function') {
|
|
2794
|
-
|
|
2835
|
+
const unsubscribe = subscription.addObserver(nextOrObserver, error, completed);
|
|
2836
|
+
return () => {
|
|
2837
|
+
isUnsubscribed = true;
|
|
2838
|
+
unsubscribe();
|
|
2839
|
+
};
|
|
2795
2840
|
}
|
|
2796
2841
|
else {
|
|
2797
|
-
|
|
2842
|
+
const unsubscribe = subscription.addObserver(nextOrObserver);
|
|
2843
|
+
return () => {
|
|
2844
|
+
isUnsubscribed = true;
|
|
2845
|
+
unsubscribe();
|
|
2846
|
+
};
|
|
2798
2847
|
}
|
|
2799
2848
|
}
|
|
2800
2849
|
/**
|
|
@@ -2900,6 +2949,186 @@ class Subscription {
|
|
|
2900
2949
|
}
|
|
2901
2950
|
}
|
|
2902
2951
|
|
|
2952
|
+
/**
|
|
2953
|
+
* @license
|
|
2954
|
+
* Copyright 2020 Google LLC
|
|
2955
|
+
*
|
|
2956
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
2957
|
+
* you may not use this file except in compliance with the License.
|
|
2958
|
+
* You may obtain a copy of the License at
|
|
2959
|
+
*
|
|
2960
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
2961
|
+
*
|
|
2962
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
2963
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
2964
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
2965
|
+
* See the License for the specific language governing permissions and
|
|
2966
|
+
* limitations under the License.
|
|
2967
|
+
*/
|
|
2968
|
+
function getScriptParentElement() {
|
|
2969
|
+
var _a, _b;
|
|
2970
|
+
return (_b = (_a = document.getElementsByTagName('head')) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : document;
|
|
2971
|
+
}
|
|
2972
|
+
function _loadJS(url) {
|
|
2973
|
+
// TODO: consider adding timeout support & cancellation
|
|
2974
|
+
return new Promise((resolve, reject) => {
|
|
2975
|
+
const el = document.createElement('script');
|
|
2976
|
+
el.setAttribute('src', url);
|
|
2977
|
+
el.onload = resolve;
|
|
2978
|
+
el.onerror = e => {
|
|
2979
|
+
const error = _createError("internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
|
|
2980
|
+
error.customData = e;
|
|
2981
|
+
reject(error);
|
|
2982
|
+
};
|
|
2983
|
+
el.type = 'text/javascript';
|
|
2984
|
+
el.charset = 'UTF-8';
|
|
2985
|
+
getScriptParentElement().appendChild(el);
|
|
2986
|
+
});
|
|
2987
|
+
}
|
|
2988
|
+
|
|
2989
|
+
/* eslint-disable @typescript-eslint/no-require-imports */
|
|
2990
|
+
const RECAPTCHA_ENTERPRISE_URL = 'https://www.google.com/recaptcha/enterprise.js?render=';
|
|
2991
|
+
const RECAPTCHA_ENTERPRISE_VERIFIER_TYPE = 'recaptcha-enterprise';
|
|
2992
|
+
const FAKE_TOKEN = 'NO_RECAPTCHA';
|
|
2993
|
+
class RecaptchaEnterpriseVerifier {
|
|
2994
|
+
/**
|
|
2995
|
+
*
|
|
2996
|
+
* @param authExtern - The corresponding Firebase {@link Auth} instance.
|
|
2997
|
+
*
|
|
2998
|
+
*/
|
|
2999
|
+
constructor(authExtern) {
|
|
3000
|
+
/**
|
|
3001
|
+
* Identifies the type of application verifier (e.g. "recaptcha-enterprise").
|
|
3002
|
+
*/
|
|
3003
|
+
this.type = RECAPTCHA_ENTERPRISE_VERIFIER_TYPE;
|
|
3004
|
+
this.auth = _castAuth(authExtern);
|
|
3005
|
+
}
|
|
3006
|
+
/**
|
|
3007
|
+
* Executes the verification process.
|
|
3008
|
+
*
|
|
3009
|
+
* @returns A Promise for a token that can be used to assert the validity of a request.
|
|
3010
|
+
*/
|
|
3011
|
+
async verify(action = 'verify', forceRefresh = false) {
|
|
3012
|
+
async function retrieveSiteKey(auth) {
|
|
3013
|
+
if (!forceRefresh) {
|
|
3014
|
+
if (auth.tenantId == null && auth._agentRecaptchaConfig != null) {
|
|
3015
|
+
return auth._agentRecaptchaConfig.siteKey;
|
|
3016
|
+
}
|
|
3017
|
+
if (auth.tenantId != null &&
|
|
3018
|
+
auth._tenantRecaptchaConfigs[auth.tenantId] !== undefined) {
|
|
3019
|
+
return auth._tenantRecaptchaConfigs[auth.tenantId].siteKey;
|
|
3020
|
+
}
|
|
3021
|
+
}
|
|
3022
|
+
return new Promise(async (resolve, reject) => {
|
|
3023
|
+
getRecaptchaConfig(auth, {
|
|
3024
|
+
clientType: "CLIENT_TYPE_WEB" /* RecaptchaClientType.WEB */,
|
|
3025
|
+
version: "RECAPTCHA_ENTERPRISE" /* RecaptchaVersion.ENTERPRISE */
|
|
3026
|
+
})
|
|
3027
|
+
.then(response => {
|
|
3028
|
+
if (response.recaptchaKey === undefined) {
|
|
3029
|
+
reject(new Error('recaptcha Enterprise site key undefined'));
|
|
3030
|
+
}
|
|
3031
|
+
else {
|
|
3032
|
+
const config = new RecaptchaConfig(response);
|
|
3033
|
+
if (auth.tenantId == null) {
|
|
3034
|
+
auth._agentRecaptchaConfig = config;
|
|
3035
|
+
}
|
|
3036
|
+
else {
|
|
3037
|
+
auth._tenantRecaptchaConfigs[auth.tenantId] = config;
|
|
3038
|
+
}
|
|
3039
|
+
return resolve(config.siteKey);
|
|
3040
|
+
}
|
|
3041
|
+
})
|
|
3042
|
+
.catch(error => {
|
|
3043
|
+
reject(error);
|
|
3044
|
+
});
|
|
3045
|
+
});
|
|
3046
|
+
}
|
|
3047
|
+
function retrieveRecaptchaToken(siteKey, resolve, reject) {
|
|
3048
|
+
const grecaptcha = window.grecaptcha;
|
|
3049
|
+
if (isEnterprise(grecaptcha)) {
|
|
3050
|
+
grecaptcha.enterprise.ready(() => {
|
|
3051
|
+
grecaptcha.enterprise
|
|
3052
|
+
.execute(siteKey, { action })
|
|
3053
|
+
.then(token => {
|
|
3054
|
+
resolve(token);
|
|
3055
|
+
})
|
|
3056
|
+
.catch(() => {
|
|
3057
|
+
resolve(FAKE_TOKEN);
|
|
3058
|
+
});
|
|
3059
|
+
});
|
|
3060
|
+
}
|
|
3061
|
+
else {
|
|
3062
|
+
reject(Error('No reCAPTCHA enterprise script loaded.'));
|
|
3063
|
+
}
|
|
3064
|
+
}
|
|
3065
|
+
return new Promise((resolve, reject) => {
|
|
3066
|
+
retrieveSiteKey(this.auth)
|
|
3067
|
+
.then(siteKey => {
|
|
3068
|
+
if (!forceRefresh && isEnterprise(window.grecaptcha)) {
|
|
3069
|
+
retrieveRecaptchaToken(siteKey, resolve, reject);
|
|
3070
|
+
}
|
|
3071
|
+
else {
|
|
3072
|
+
if (typeof window === 'undefined') {
|
|
3073
|
+
reject(new Error('RecaptchaVerifier is only supported in browser'));
|
|
3074
|
+
return;
|
|
3075
|
+
}
|
|
3076
|
+
_loadJS(RECAPTCHA_ENTERPRISE_URL + siteKey)
|
|
3077
|
+
.then(() => {
|
|
3078
|
+
retrieveRecaptchaToken(siteKey, resolve, reject);
|
|
3079
|
+
})
|
|
3080
|
+
.catch(error => {
|
|
3081
|
+
reject(error);
|
|
3082
|
+
});
|
|
3083
|
+
}
|
|
3084
|
+
})
|
|
3085
|
+
.catch(error => {
|
|
3086
|
+
reject(error);
|
|
3087
|
+
});
|
|
3088
|
+
});
|
|
3089
|
+
}
|
|
3090
|
+
}
|
|
3091
|
+
async function injectRecaptchaFields(auth, request, action, captchaResp = false) {
|
|
3092
|
+
const verifier = new RecaptchaEnterpriseVerifier(auth);
|
|
3093
|
+
let captchaResponse;
|
|
3094
|
+
try {
|
|
3095
|
+
captchaResponse = await verifier.verify(action);
|
|
3096
|
+
}
|
|
3097
|
+
catch (error) {
|
|
3098
|
+
captchaResponse = await verifier.verify(action, true);
|
|
3099
|
+
}
|
|
3100
|
+
const newRequest = Object.assign({}, request);
|
|
3101
|
+
if (!captchaResp) {
|
|
3102
|
+
Object.assign(newRequest, { captchaResponse });
|
|
3103
|
+
}
|
|
3104
|
+
else {
|
|
3105
|
+
Object.assign(newRequest, { 'captchaResp': captchaResponse });
|
|
3106
|
+
}
|
|
3107
|
+
Object.assign(newRequest, { 'clientType': "CLIENT_TYPE_WEB" /* RecaptchaClientType.WEB */ });
|
|
3108
|
+
Object.assign(newRequest, {
|
|
3109
|
+
'recaptchaVersion': "RECAPTCHA_ENTERPRISE" /* RecaptchaVersion.ENTERPRISE */
|
|
3110
|
+
});
|
|
3111
|
+
return newRequest;
|
|
3112
|
+
}
|
|
3113
|
+
async function _initializeRecaptchaConfig(auth) {
|
|
3114
|
+
const authInternal = _castAuth(auth);
|
|
3115
|
+
const response = await getRecaptchaConfig(authInternal, {
|
|
3116
|
+
clientType: "CLIENT_TYPE_WEB" /* RecaptchaClientType.WEB */,
|
|
3117
|
+
version: "RECAPTCHA_ENTERPRISE" /* RecaptchaVersion.ENTERPRISE */
|
|
3118
|
+
});
|
|
3119
|
+
const config = new RecaptchaConfig(response);
|
|
3120
|
+
if (authInternal.tenantId == null) {
|
|
3121
|
+
authInternal._agentRecaptchaConfig = config;
|
|
3122
|
+
}
|
|
3123
|
+
else {
|
|
3124
|
+
authInternal._tenantRecaptchaConfigs[authInternal.tenantId] = config;
|
|
3125
|
+
}
|
|
3126
|
+
if (config.emailPasswordEnabled) {
|
|
3127
|
+
const verifier = new RecaptchaEnterpriseVerifier(authInternal);
|
|
3128
|
+
void verifier.verify();
|
|
3129
|
+
}
|
|
3130
|
+
}
|
|
3131
|
+
|
|
2903
3132
|
/**
|
|
2904
3133
|
* @license
|
|
2905
3134
|
* Copyright 2020 Google LLC
|
|
@@ -5254,6 +5483,25 @@ function _setActionCodeSettingsOnRequest(auth, request, actionCodeSettings) {
|
|
|
5254
5483
|
* See the License for the specific language governing permissions and
|
|
5255
5484
|
* limitations under the License.
|
|
5256
5485
|
*/
|
|
5486
|
+
/**
|
|
5487
|
+
* Updates the password policy cached in the {@link Auth} instance if a policy is already
|
|
5488
|
+
* cached for the project or tenant.
|
|
5489
|
+
*
|
|
5490
|
+
* @remarks
|
|
5491
|
+
* We only fetch the password policy if the password did not meet policy requirements and
|
|
5492
|
+
* there is an existing policy cached. A developer must call validatePassword at least
|
|
5493
|
+
* once for the cache to be automatically updated.
|
|
5494
|
+
*
|
|
5495
|
+
* @param auth - The {@link Auth} instance.
|
|
5496
|
+
*
|
|
5497
|
+
* @private
|
|
5498
|
+
*/
|
|
5499
|
+
async function recachePasswordPolicy(auth) {
|
|
5500
|
+
const authInternal = _castAuth(auth);
|
|
5501
|
+
if (authInternal._getPasswordPolicyInternal()) {
|
|
5502
|
+
await authInternal._updatePasswordPolicy();
|
|
5503
|
+
}
|
|
5504
|
+
}
|
|
5257
5505
|
/**
|
|
5258
5506
|
* Sends a password reset email to the given email address.
|
|
5259
5507
|
*
|
|
@@ -5334,6 +5582,13 @@ async function confirmPasswordReset(auth, oobCode, newPassword) {
|
|
|
5334
5582
|
await resetPassword(getModularInstance(auth), {
|
|
5335
5583
|
oobCode,
|
|
5336
5584
|
newPassword
|
|
5585
|
+
})
|
|
5586
|
+
.catch(async (error) => {
|
|
5587
|
+
if (error.code ===
|
|
5588
|
+
`auth/${"password-does-not-meet-requirements" /* AuthErrorCode.PASSWORD_DOES_NOT_MEET_REQUIREMENTS */}`) {
|
|
5589
|
+
void recachePasswordPolicy(auth);
|
|
5590
|
+
}
|
|
5591
|
+
throw error;
|
|
5337
5592
|
});
|
|
5338
5593
|
// Do not return the email.
|
|
5339
5594
|
}
|
|
@@ -5452,13 +5707,14 @@ async function createUserWithEmailAndPassword(auth, email, password) {
|
|
|
5452
5707
|
const requestWithRecaptcha = await injectRecaptchaFields(authInternal, request, "signUpPassword" /* RecaptchaActionName.SIGN_UP_PASSWORD */);
|
|
5453
5708
|
return signUp(authInternal, requestWithRecaptcha);
|
|
5454
5709
|
}
|
|
5455
|
-
|
|
5456
|
-
return Promise.reject(error);
|
|
5457
|
-
}
|
|
5710
|
+
throw error;
|
|
5458
5711
|
});
|
|
5459
5712
|
}
|
|
5460
5713
|
const response = await signUpResponse.catch(error => {
|
|
5461
|
-
|
|
5714
|
+
if (error.code === `auth/${"password-does-not-meet-requirements" /* AuthErrorCode.PASSWORD_DOES_NOT_MEET_REQUIREMENTS */}`) {
|
|
5715
|
+
void recachePasswordPolicy(auth);
|
|
5716
|
+
}
|
|
5717
|
+
throw error;
|
|
5462
5718
|
});
|
|
5463
5719
|
const userCredential = await UserCredentialImpl._fromIdTokenResponse(authInternal, "signIn" /* OperationType.SIGN_IN */, response);
|
|
5464
5720
|
await authInternal._updateCurrentUser(userCredential.user);
|
|
@@ -5481,7 +5737,12 @@ async function createUserWithEmailAndPassword(auth, email, password) {
|
|
|
5481
5737
|
* @public
|
|
5482
5738
|
*/
|
|
5483
5739
|
function signInWithEmailAndPassword(auth, email, password) {
|
|
5484
|
-
return signInWithCredential(getModularInstance(auth), EmailAuthProvider.credential(email, password))
|
|
5740
|
+
return signInWithCredential(getModularInstance(auth), EmailAuthProvider.credential(email, password)).catch(async (error) => {
|
|
5741
|
+
if (error.code === `auth/${"password-does-not-meet-requirements" /* AuthErrorCode.PASSWORD_DOES_NOT_MEET_REQUIREMENTS */}`) {
|
|
5742
|
+
void recachePasswordPolicy(auth);
|
|
5743
|
+
}
|
|
5744
|
+
throw error;
|
|
5745
|
+
});
|
|
5485
5746
|
}
|
|
5486
5747
|
|
|
5487
5748
|
/**
|
|
@@ -6096,8 +6357,34 @@ function setPersistence(auth, persistence) {
|
|
|
6096
6357
|
* @public
|
|
6097
6358
|
*/
|
|
6098
6359
|
function initializeRecaptchaConfig(auth) {
|
|
6360
|
+
return _initializeRecaptchaConfig(auth);
|
|
6361
|
+
}
|
|
6362
|
+
/**
|
|
6363
|
+
* Validates the password against the password policy configured for the project or tenant.
|
|
6364
|
+
*
|
|
6365
|
+
* @remarks
|
|
6366
|
+
* If no tenant ID is set on the `Auth` instance, then this method will use the password
|
|
6367
|
+
* policy configured for the project. Otherwise, this method will use the policy configured
|
|
6368
|
+
* for the tenant. If a password policy has not been configured, then the default policy
|
|
6369
|
+
* configured for all projects will be used.
|
|
6370
|
+
*
|
|
6371
|
+
* If an auth flow fails because a submitted password does not meet the password policy
|
|
6372
|
+
* requirements and this method has previously been called, then this method will use the
|
|
6373
|
+
* most recent policy available when called again.
|
|
6374
|
+
*
|
|
6375
|
+
* @example
|
|
6376
|
+
* ```javascript
|
|
6377
|
+
* validatePassword(auth, 'some-password');
|
|
6378
|
+
* ```
|
|
6379
|
+
*
|
|
6380
|
+
* @param auth The {@link Auth} instance.
|
|
6381
|
+
* @param password The password to validate.
|
|
6382
|
+
*
|
|
6383
|
+
* @public
|
|
6384
|
+
*/
|
|
6385
|
+
async function validatePassword(auth, password) {
|
|
6099
6386
|
const authInternal = _castAuth(auth);
|
|
6100
|
-
return authInternal.
|
|
6387
|
+
return authInternal.validatePassword(password);
|
|
6101
6388
|
}
|
|
6102
6389
|
/**
|
|
6103
6390
|
* Adds an observer for changes to the signed-in user's ID token.
|
|
@@ -6428,7 +6715,7 @@ function multiFactor(user) {
|
|
|
6428
6715
|
}
|
|
6429
6716
|
|
|
6430
6717
|
var name = "@firebase/auth";
|
|
6431
|
-
var version = "1.
|
|
6718
|
+
var version = "1.2.0-canary.cc77a2a19";
|
|
6432
6719
|
|
|
6433
6720
|
/**
|
|
6434
6721
|
* @license
|
|
@@ -6837,5 +7124,5 @@ function _isEmptyString(input) {
|
|
|
6837
7124
|
return typeof input === 'undefined' || (input === null || input === void 0 ? void 0 : input.length) === 0;
|
|
6838
7125
|
}
|
|
6839
7126
|
|
|
6840
|
-
export {
|
|
6841
|
-
//# sourceMappingURL=totp-
|
|
7127
|
+
export { signInAnonymously as $, ActionCodeOperation as A, updateCurrentUser as B, signOut as C, deleteUser as D, debugErrorMap as E, FactorId as F, prodErrorMap as G, AUTH_ERROR_CODES_MAP_DO_NOT_USE_INTERNALLY as H, initializeAuth as I, connectAuthEmulator as J, AuthCredential as K, EmailAuthCredential as L, OAuthCredential as M, PhoneAuthCredential as N, OperationType as O, PhoneAuthProvider as P, inMemoryPersistence as Q, RecaptchaVerifier as R, SignInMethod as S, TotpMultiFactorGenerator as T, EmailAuthProvider as U, FacebookAuthProvider as V, GoogleAuthProvider as W, GithubAuthProvider as X, OAuthProvider as Y, SAMLAuthProvider as Z, TwitterAuthProvider as _, browserSessionPersistence as a, signInWithCredential as a0, linkWithCredential as a1, reauthenticateWithCredential as a2, signInWithCustomToken as a3, sendPasswordResetEmail as a4, confirmPasswordReset as a5, applyActionCode as a6, checkActionCode as a7, verifyPasswordResetCode as a8, createUserWithEmailAndPassword as a9, debugAssert as aA, _persistenceKeyName as aB, _castAuth as aC, FederatedAuthProvider as aD, BaseOAuthProvider as aE, _emulatorUrl as aF, _performApiRequest as aG, _isIOS as aH, _isAndroid as aI, _isIOS7Or8 as aJ, _createError as aK, _isIframe as aL, _isMobileBrowser as aM, _isIE10 as aN, _isSafari as aO, UserImpl as aP, AuthImpl as aQ, _getClientVersion as aR, FetchProvider as aS, SAMLAuthCredential as aT, signInWithEmailAndPassword as aa, sendSignInLinkToEmail as ab, isSignInWithEmailLink as ac, signInWithEmailLink as ad, fetchSignInMethodsForEmail as ae, sendEmailVerification as af, verifyBeforeUpdateEmail as ag, ActionCodeURL as ah, parseActionCodeURL as ai, updateProfile as aj, updateEmail as ak, updatePassword as al, getIdToken as am, getIdTokenResult as an, unlink as ao, getAdditionalUserInfo as ap, reload as aq, getMultiFactorResolver as ar, multiFactor as as, _getInstance as at, _assert as au, _signInWithCredential as av, _reauthenticate as aw, _link as ax, signInWithIdp as ay, _fail as az, browserLocalPersistence as b, signInWithPopup as c, linkWithPopup as d, reauthenticateWithPopup as e, signInWithRedirect as f, linkWithRedirect as g, reauthenticateWithRedirect as h, indexedDBLocalPersistence as i, getRedirectResult as j, browserPopupRedirectResolver as k, linkWithPhoneNumber as l, PhoneMultiFactorGenerator as m, TotpSecret as n, getAuth as o, ProviderId as p, setPersistence as q, reauthenticateWithPhoneNumber as r, signInWithPhoneNumber as s, initializeRecaptchaConfig as t, updatePhoneNumber as u, validatePassword as v, onIdTokenChanged as w, beforeAuthStateChanged as x, onAuthStateChanged as y, useDeviceLanguage as z };
|
|
7128
|
+
//# sourceMappingURL=totp-495080fc.js.map
|