|
| 1 | +/** |
| 2 | + * @license |
| 3 | + * Copyright 2019 Google LLC |
| 4 | + * |
| 5 | + * Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 | + * you may not use this file except in compliance with the License. |
| 7 | + * You may obtain a copy of the License at |
| 8 | + * |
| 9 | + * http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | + * |
| 11 | + * Unless required by applicable law or agreed to in writing, software |
| 12 | + * distributed under the License is distributed on an "AS IS" BASIS, |
| 13 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 | + * See the License for the specific language governing permissions and |
| 15 | + * limitations under the License. |
| 16 | + */ |
| 17 | + |
| 18 | +import { ErrorFactory, ErrorMap } from '@firebase/util'; |
| 19 | +import { AppName } from '../model/auth'; |
| 20 | +import { User } from '../model/user'; |
| 21 | + |
| 22 | +/* |
| 23 | + * Developer facing Firebase Auth error codes. |
| 24 | + */ |
| 25 | +export const enum AuthErrorCode { |
| 26 | + ADMIN_ONLY_OPERATION = 'admin-restricted-operation', |
| 27 | + ARGUMENT_ERROR = 'argument-error', |
| 28 | + APP_NOT_AUTHORIZED = 'app-not-authorized', |
| 29 | + APP_NOT_INSTALLED = 'app-not-installed', |
| 30 | + CAPTCHA_CHECK_FAILED = 'captcha-check-failed', |
| 31 | + CODE_EXPIRED = 'code-expired', |
| 32 | + CORDOVA_NOT_READY = 'cordova-not-ready', |
| 33 | + CORS_UNSUPPORTED = 'cors-unsupported', |
| 34 | + CREDENTIAL_ALREADY_IN_USE = 'credential-already-in-use', |
| 35 | + CREDENTIAL_MISMATCH = 'custom-token-mismatch', |
| 36 | + CREDENTIAL_TOO_OLD_LOGIN_AGAIN = 'requires-recent-login', |
| 37 | + DYNAMIC_LINK_NOT_ACTIVATED = 'dynamic-link-not-activated', |
| 38 | + EMAIL_EXISTS = 'email-already-in-use', |
| 39 | + EXPIRED_OOB_CODE = 'expired-action-code', |
| 40 | + EXPIRED_POPUP_REQUEST = 'cancelled-popup-request', |
| 41 | + INTERNAL_ERROR = 'internal-error', |
| 42 | + INVALID_API_KEY = 'invalid-api-key', |
| 43 | + INVALID_APP_CREDENTIAL = 'invalid-app-credential', |
| 44 | + INVALID_APP_ID = 'invalid-app-id', |
| 45 | + INVALID_AUTH = 'invalid-user-token', |
| 46 | + INVALID_AUTH_EVENT = 'invalid-auth-event', |
| 47 | + INVALID_CERT_HASH = 'invalid-cert-hash', |
| 48 | + INVALID_CODE = 'invalid-verification-code', |
| 49 | + INVALID_CONTINUE_URI = 'invalid-continue-uri', |
| 50 | + INVALID_CORDOVA_CONFIGURATION = 'invalid-cordova-configuration', |
| 51 | + INVALID_CUSTOM_TOKEN = 'invalid-custom-token', |
| 52 | + INVALID_DYNAMIC_LINK_DOMAIN = 'invalid-dynamic-link-domain', |
| 53 | + INVALID_EMAIL = 'invalid-email', |
| 54 | + INVALID_IDP_RESPONSE = 'invalid-credential', |
| 55 | + INVALID_MESSAGE_PAYLOAD = 'invalid-message-payload', |
| 56 | + INVALID_OAUTH_CLIENT_ID = 'invalid-oauth-client-id', |
| 57 | + INVALID_OAUTH_PROVIDER = 'invalid-oauth-provider', |
| 58 | + INVALID_OOB_CODE = 'invalid-action-code', |
| 59 | + INVALID_ORIGIN = 'unauthorized-domain', |
| 60 | + INVALID_PASSWORD = 'wrong-password', |
| 61 | + INVALID_PERSISTENCE = 'invalid-persistence-type', |
| 62 | + INVALID_PHONE_NUMBER = 'invalid-phone-number', |
| 63 | + INVALID_PROVIDER_ID = 'invalid-provider-id', |
| 64 | + INVALID_RECIPIENT_EMAIL = 'invalid-recipient-email', |
| 65 | + INVALID_SENDER = 'invalid-sender', |
| 66 | + INVALID_SESSION_INFO = 'invalid-verification-id', |
| 67 | + INVALID_TENANT_ID = 'invalid-tenant-id', |
| 68 | + MISSING_ANDROID_PACKAGE_NAME = 'missing-android-pkg-name', |
| 69 | + MISSING_APP_CREDENTIAL = 'missing-app-credential', |
| 70 | + MISSING_AUTH_DOMAIN = 'auth-domain-config-required', |
| 71 | + MISSING_CODE = 'missing-verification-code', |
| 72 | + MISSING_CONTINUE_URI = 'missing-continue-uri', |
| 73 | + MISSING_IFRAME_START = 'missing-iframe-start', |
| 74 | + MISSING_IOS_BUNDLE_ID = 'missing-ios-bundle-id', |
| 75 | + MISSING_OR_INVALID_NONCE = 'missing-or-invalid-nonce', |
| 76 | + MISSING_PHONE_NUMBER = 'missing-phone-number', |
| 77 | + MISSING_SESSION_INFO = 'missing-verification-id', |
| 78 | + MODULE_DESTROYED = 'app-deleted', |
| 79 | + MFA_REQUIRED = 'multi-factor-auth-required', |
| 80 | + NEED_CONFIRMATION = 'account-exists-with-different-credential', |
| 81 | + NETWORK_REQUEST_FAILED = 'network-request-failed', |
| 82 | + NULL_USER = 'null-user', |
| 83 | + NO_AUTH_EVENT = 'no-auth-event', |
| 84 | + NO_SUCH_PROVIDER = 'no-such-provider', |
| 85 | + OPERATION_NOT_ALLOWED = 'operation-not-allowed', |
| 86 | + OPERATION_NOT_SUPPORTED = 'operation-not-supported-in-this-environment', |
| 87 | + POPUP_BLOCKED = 'popup-blocked', |
| 88 | + POPUP_CLOSED_BY_USER = 'popup-closed-by-user', |
| 89 | + PROVIDER_ALREADY_LINKED = 'provider-already-linked', |
| 90 | + QUOTA_EXCEEDED = 'quota-exceeded', |
| 91 | + REDIRECT_CANCELLED_BY_USER = 'redirect-cancelled-by-user', |
| 92 | + REDIRECT_OPERATION_PENDING = 'redirect-operation-pending', |
| 93 | + REJECTED_CREDENTIAL = 'rejected-credential', |
| 94 | + TENANT_ID_MISMATCH = 'tenant-id-mismatch', |
| 95 | + TIMEOUT = 'timeout', |
| 96 | + TOKEN_EXPIRED = 'user-token-expired', |
| 97 | + TOO_MANY_ATTEMPTS_TRY_LATER = 'too-many-requests', |
| 98 | + UNAUTHORIZED_DOMAIN = 'unauthorized-continue-uri', |
| 99 | + UNSUPPORTED_PERSISTENCE = 'unsupported-persistence-type', |
| 100 | + UNSUPPORTED_TENANT_OPERATION = 'unsupported-tenant-operation', |
| 101 | + USER_CANCELLED = 'user-cancelled', |
| 102 | + USER_DELETED = 'user-not-found', |
| 103 | + USER_DISABLED = 'user-disabled', |
| 104 | + USER_MISMATCH = 'user-mismatch', |
| 105 | + USER_SIGNED_OUT = 'user-signed-out', |
| 106 | + WEAK_PASSWORD = 'weak-password', |
| 107 | + WEB_STORAGE_UNSUPPORTED = 'web-storage-unsupported' |
| 108 | +} |
| 109 | + |
| 110 | +const ERRORS: ErrorMap<AuthErrorCode> = { |
| 111 | + [AuthErrorCode.ADMIN_ONLY_OPERATION]: |
| 112 | + 'This operation is restricted to administrators only.', |
| 113 | + [AuthErrorCode.ARGUMENT_ERROR]: '', |
| 114 | + [AuthErrorCode.APP_NOT_AUTHORIZED]: |
| 115 | + "This app]: identified by the domain where it's hosted]: is not " + |
| 116 | + 'authorized to use Firebase Authentication with the provided API key. ' + |
| 117 | + 'Review your key configuration in the Google API console.', |
| 118 | + [AuthErrorCode.APP_NOT_INSTALLED]: |
| 119 | + 'The requested mobile application corresponding to the identifier (' + |
| 120 | + 'Android package name or iOS bundle ID) provided is not installed on ' + |
| 121 | + 'this device.', |
| 122 | + [AuthErrorCode.CAPTCHA_CHECK_FAILED]: |
| 123 | + 'The reCAPTCHA response token provided is either invalid]: expired]: ' + |
| 124 | + 'already used or the domain associated with it does not match the list ' + |
| 125 | + 'of whitelisted domains.', |
| 126 | + [AuthErrorCode.CODE_EXPIRED]: |
| 127 | + 'The SMS code has expired. Please re-send the verification code to try ' + |
| 128 | + 'again.', |
| 129 | + [AuthErrorCode.CORDOVA_NOT_READY]: 'Cordova framework is not ready.', |
| 130 | + [AuthErrorCode.CORS_UNSUPPORTED]: 'This browser is not supported.', |
| 131 | + [AuthErrorCode.CREDENTIAL_ALREADY_IN_USE]: |
| 132 | + 'This credential is already associated with a different user account.', |
| 133 | + [AuthErrorCode.CREDENTIAL_MISMATCH]: |
| 134 | + 'The custom token corresponds to a different audience.', |
| 135 | + [AuthErrorCode.CREDENTIAL_TOO_OLD_LOGIN_AGAIN]: |
| 136 | + 'This operation is sensitive and requires recent authentication. Log in ' + |
| 137 | + 'again before retrying this request.', |
| 138 | + [AuthErrorCode.DYNAMIC_LINK_NOT_ACTIVATED]: |
| 139 | + 'Please activate ' + |
| 140 | + 'Dynamic Links in the Firebase Console and agree to the terms and ' + |
| 141 | + 'conditions.', |
| 142 | + [AuthErrorCode.EMAIL_EXISTS]: |
| 143 | + 'The email address is already in use by another account.', |
| 144 | + [AuthErrorCode.EXPIRED_OOB_CODE]: 'The action code has expired. ', |
| 145 | + [AuthErrorCode.EXPIRED_POPUP_REQUEST]: |
| 146 | + 'This operation has been cancelled due to another conflicting popup ' + |
| 147 | + 'being opened.', |
| 148 | + [AuthErrorCode.INTERNAL_ERROR]: 'An internal AuthError has occurred.', |
| 149 | + [AuthErrorCode.INVALID_APP_CREDENTIAL]: |
| 150 | + 'The phone verification request contains an invalid application verifier.' + |
| 151 | + ' The reCAPTCHA token response is either invalid or expired.', |
| 152 | + [AuthErrorCode.INVALID_APP_ID]: |
| 153 | + 'The mobile app identifier is not registed for the current project.', |
| 154 | + [AuthErrorCode.INVALID_AUTH]: |
| 155 | + "This user's credential isn't valid for this project. This can happen " + |
| 156 | + "if the user's token has been tampered with]: or if the user isn't for " + |
| 157 | + 'the project associated with this API key.', |
| 158 | + [AuthErrorCode.INVALID_AUTH_EVENT]: 'An internal AuthError has occurred.', |
| 159 | + [AuthErrorCode.INVALID_CODE]: |
| 160 | + 'The SMS verification code used to create the phone auth credential is ' + |
| 161 | + 'invalid. Please resend the verification code sms and be sure use the ' + |
| 162 | + 'verification code provided by the user.', |
| 163 | + [AuthErrorCode.INVALID_CONTINUE_URI]: |
| 164 | + 'The continue URL provided in the request is invalid.', |
| 165 | + [AuthErrorCode.INVALID_CORDOVA_CONFIGURATION]: |
| 166 | + 'The following' + |
| 167 | + ' Cordova plugins must be installed to enable OAuth sign-in= ' + |
| 168 | + 'cordova-plugin-buildinfo]: cordova-universal-links-plugin]: ' + |
| 169 | + 'cordova-plugin-browsertab]: cordova-plugin-inappbrowser and ' + |
| 170 | + 'cordova-plugin-customurlscheme.', |
| 171 | + [AuthErrorCode.INVALID_CUSTOM_TOKEN]: |
| 172 | + 'The custom token format is incorrect. Please check the documentation.', |
| 173 | + [AuthErrorCode.INVALID_DYNAMIC_LINK_DOMAIN]: |
| 174 | + 'The provided ' + |
| 175 | + 'dynamic link domain is not configured or authorized for the current ' + |
| 176 | + 'project.', |
| 177 | + [AuthErrorCode.INVALID_EMAIL]: 'The email address is badly formatted.', |
| 178 | + [AuthErrorCode.INVALID_API_KEY]: |
| 179 | + 'Your API key is invalid]: please check you have copied it correctly.', |
| 180 | + [AuthErrorCode.INVALID_CERT_HASH]: |
| 181 | + 'The SHA-1 certificate hash provided is invalid.', |
| 182 | + [AuthErrorCode.INVALID_IDP_RESPONSE]: |
| 183 | + 'The supplied auth credential is malformed or has expired.', |
| 184 | + [AuthErrorCode.INVALID_MESSAGE_PAYLOAD]: |
| 185 | + 'The email template corresponding to this action contains invalid charac' + |
| 186 | + 'ters in its message. Please fix by going to the Auth email templates se' + |
| 187 | + 'ction in the Firebase Console.', |
| 188 | + [AuthErrorCode.INVALID_OAUTH_PROVIDER]: |
| 189 | + 'EmailAuthProvider is not supported for this operation. This operation ' + |
| 190 | + 'only supports OAuth providers.', |
| 191 | + [AuthErrorCode.INVALID_OAUTH_CLIENT_ID]: |
| 192 | + 'The OAuth client ID provided is either invalid or does not match the ' + |
| 193 | + 'specified API key.', |
| 194 | + [AuthErrorCode.INVALID_ORIGIN]: |
| 195 | + 'This domain is not authorized for OAuth operations for your Firebase ' + |
| 196 | + 'project. Edit the list of authorized domains from the Firebase console.', |
| 197 | + [AuthErrorCode.INVALID_OOB_CODE]: |
| 198 | + 'The action code is invalid. This can happen if the code is malformed]: ' + |
| 199 | + 'expired]: or has already been used.', |
| 200 | + [AuthErrorCode.INVALID_PASSWORD]: |
| 201 | + 'The password is invalid or the user does not have a password.', |
| 202 | + [AuthErrorCode.INVALID_PERSISTENCE]: |
| 203 | + 'The specified persistence type is invalid. It can only be local]: ' + |
| 204 | + 'session or none.', |
| 205 | + [AuthErrorCode.INVALID_PHONE_NUMBER]: |
| 206 | + 'The format of the phone number provided is incorrect. Please enter the ' + |
| 207 | + 'phone number in a format that can be parsed into E.164 format. E.164 ' + |
| 208 | + 'phone numbers are written in the format [+,[country code,[subscriber ' + |
| 209 | + 'number including area code,.', |
| 210 | + [AuthErrorCode.INVALID_PROVIDER_ID]: 'The specified provider ID is invalid.', |
| 211 | + [AuthErrorCode.INVALID_RECIPIENT_EMAIL]: |
| 212 | + 'The email corresponding to this action failed to send as the provided ' + |
| 213 | + 'recipient email address is invalid.', |
| 214 | + [AuthErrorCode.INVALID_SENDER]: |
| 215 | + 'The email template corresponding to this action contains an invalid sen' + |
| 216 | + 'der email or name. Please fix by going to the Auth email templates sect' + |
| 217 | + 'ion in the Firebase Console.', |
| 218 | + [AuthErrorCode.INVALID_SESSION_INFO]: |
| 219 | + 'The verification ID used to create the phone auth credential is invalid.', |
| 220 | + [AuthErrorCode.INVALID_TENANT_ID]: |
| 221 | + "The Auth instance's tenant ID is invalid.", |
| 222 | + [AuthErrorCode.MISSING_ANDROID_PACKAGE_NAME]: |
| 223 | + 'An Android ' + |
| 224 | + 'Package Name must be provided if the Android App is required to be ' + |
| 225 | + 'installed.', |
| 226 | + [AuthErrorCode.MISSING_AUTH_DOMAIN]: |
| 227 | + 'Be sure to include authDomain when calling firebase.initializeApp()]: ' + |
| 228 | + 'by following the instructions in the Firebase console.', |
| 229 | + [AuthErrorCode.MISSING_APP_CREDENTIAL]: |
| 230 | + 'The phone verification request is missing an application verifier ' + |
| 231 | + 'assertion. A reCAPTCHA response token needs to be provided.', |
| 232 | + [AuthErrorCode.MISSING_CODE]: |
| 233 | + 'The phone auth credential was created with an empty SMS verification ' + |
| 234 | + 'code.', |
| 235 | + [AuthErrorCode.MISSING_CONTINUE_URI]: |
| 236 | + 'A continue URL must be provided in the request.', |
| 237 | + [AuthErrorCode.MISSING_IFRAME_START]: 'An internal AuthError has occurred.', |
| 238 | + [AuthErrorCode.MISSING_IOS_BUNDLE_ID]: |
| 239 | + 'An iOS Bundle ID must be provided if an App Store ID is provided.', |
| 240 | + [AuthErrorCode.MISSING_OR_INVALID_NONCE]: |
| 241 | + 'The request does not contain a valid nonce. This can occur if the ' + |
| 242 | + 'SHA-256 hash of the provided raw nonce does not match the hashed nonce ' + |
| 243 | + 'in the ID token payload.', |
| 244 | + [AuthErrorCode.MISSING_PHONE_NUMBER]: |
| 245 | + 'To send verification codes]: provide a phone number for the recipient.', |
| 246 | + [AuthErrorCode.MISSING_SESSION_INFO]: |
| 247 | + 'The phone auth credential was created with an empty verification ID.', |
| 248 | + [AuthErrorCode.MODULE_DESTROYED]: |
| 249 | + 'This instance of FirebaseApp has been deleted.', |
| 250 | + [AuthErrorCode.MFA_REQUIRED]: |
| 251 | + 'Proof of ownership of a second factor is required to complete sign-in.', |
| 252 | + [AuthErrorCode.NEED_CONFIRMATION]: |
| 253 | + 'An account already exists with the same email address but different ' + |
| 254 | + 'sign-in credentials. Sign in using a provider associated with this ' + |
| 255 | + 'email address.', |
| 256 | + [AuthErrorCode.NETWORK_REQUEST_FAILED]: |
| 257 | + 'A network AuthError (such as timeout]: interrupted connection or ' + |
| 258 | + 'unreachable host) has occurred.', |
| 259 | + [AuthErrorCode.NO_AUTH_EVENT]: 'An internal AuthError has occurred.', |
| 260 | + [AuthErrorCode.NO_SUCH_PROVIDER]: |
| 261 | + 'User was not linked to an account with the given provider.', |
| 262 | + [AuthErrorCode.NULL_USER]: |
| 263 | + 'A null user object was provided as the argument for an operation which ' + |
| 264 | + 'requires a non-null user object.', |
| 265 | + [AuthErrorCode.OPERATION_NOT_ALLOWED]: |
| 266 | + 'The given sign-in provider is disabled for this Firebase project. ' + |
| 267 | + 'Enable it in the Firebase console]: under the sign-in method tab of the ' + |
| 268 | + 'Auth section.', |
| 269 | + [AuthErrorCode.OPERATION_NOT_SUPPORTED]: |
| 270 | + 'This operation is not supported in the environment this application is ' + |
| 271 | + 'running on. "location.protocol" must be http]: https or chrome-extension' + |
| 272 | + ' and web storage must be enabled.', |
| 273 | + [AuthErrorCode.POPUP_BLOCKED]: |
| 274 | + 'Unable to establish a connection with the popup. It may have been ' + |
| 275 | + 'blocked by the browser.', |
| 276 | + [AuthErrorCode.POPUP_CLOSED_BY_USER]: |
| 277 | + 'The popup has been closed by the user before finalizing the operation.', |
| 278 | + [AuthErrorCode.PROVIDER_ALREADY_LINKED]: |
| 279 | + 'User can only be linked to one identity for the given provider.', |
| 280 | + [AuthErrorCode.QUOTA_EXCEEDED]: |
| 281 | + "The project's quota for this operation has been exceeded.", |
| 282 | + [AuthErrorCode.REDIRECT_CANCELLED_BY_USER]: |
| 283 | + 'The redirect operation has been cancelled by the user before finalizing.', |
| 284 | + [AuthErrorCode.REDIRECT_OPERATION_PENDING]: |
| 285 | + 'A redirect sign-in operation is already pending.', |
| 286 | + [AuthErrorCode.REJECTED_CREDENTIAL]: |
| 287 | + 'The request contains malformed or mismatching credentials.', |
| 288 | + [AuthErrorCode.TENANT_ID_MISMATCH]: |
| 289 | + "The provided tenant ID does not match the Auth instance's tenant ID", |
| 290 | + [AuthErrorCode.TIMEOUT]: 'The operation has timed out.', |
| 291 | + [AuthErrorCode.TOKEN_EXPIRED]: |
| 292 | + "The user's credential is no longer valid. The user must sign in again.", |
| 293 | + [AuthErrorCode.TOO_MANY_ATTEMPTS_TRY_LATER]: |
| 294 | + 'We have blocked all requests from this device due to unusual activity. ' + |
| 295 | + 'Try again later.', |
| 296 | + [AuthErrorCode.UNAUTHORIZED_DOMAIN]: |
| 297 | + 'The domain of the continue URL is not whitelisted. Please whitelist ' + |
| 298 | + 'the domain in the Firebase console.', |
| 299 | + [AuthErrorCode.UNSUPPORTED_PERSISTENCE]: |
| 300 | + 'The current environment does not support the specified persistence type.', |
| 301 | + [AuthErrorCode.UNSUPPORTED_TENANT_OPERATION]: |
| 302 | + 'This operation is not supported in a multi-tenant context.', |
| 303 | + [AuthErrorCode.USER_CANCELLED]: |
| 304 | + 'The user did not grant your application the permissions it requested.', |
| 305 | + [AuthErrorCode.USER_DELETED]: |
| 306 | + 'There is no user record corresponding to this identifier. The user may ' + |
| 307 | + 'have been deleted.', |
| 308 | + [AuthErrorCode.USER_DISABLED]: |
| 309 | + 'The user account has been disabled by an administrator.', |
| 310 | + [AuthErrorCode.USER_MISMATCH]: |
| 311 | + 'The supplied credentials do not correspond to the previously signed in ' + |
| 312 | + 'user.', |
| 313 | + [AuthErrorCode.USER_SIGNED_OUT]: '', |
| 314 | + [AuthErrorCode.WEAK_PASSWORD]: |
| 315 | + 'The password must be 6 characters long or more.', |
| 316 | + [AuthErrorCode.WEB_STORAGE_UNSUPPORTED]: |
| 317 | + 'This browser is not supported or 3rd party cookies and data may be ' + |
| 318 | + 'disabled.' |
| 319 | +}; |
| 320 | + |
| 321 | +type AuthErrorParams = { |
| 322 | + [key in AuthErrorCode]: { |
| 323 | + appName: AppName; |
| 324 | + serverResponse?: object; |
| 325 | + user?: User; |
| 326 | + }; |
| 327 | +}; |
| 328 | + |
| 329 | +export const AUTH_ERROR_FACTORY = new ErrorFactory< |
| 330 | + AuthErrorCode, |
| 331 | + AuthErrorParams |
| 332 | +>('auth', 'Firebase', ERRORS); |
0 commit comments