tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

FxAccountsCommon.sys.mjs (19772B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 import { AppConstants } from "resource://gre/modules/AppConstants.sys.mjs";
      6 import { Log } from "resource://gre/modules/Log.sys.mjs";
      7 import { LogManager } from "resource://gre/modules/LogManager.sys.mjs";
      8 
      9 // loglevel should be one of "Fatal", "Error", "Warn", "Info", "Config",
     10 // "Debug", "Trace" or "All". If none is specified, "Debug" will be used by
     11 // default.  Note "Debug" is usually appropriate so that when this log is
     12 // included in the Sync file logs we get verbose output.
     13 const PREF_LOG_LEVEL = "identity.fxaccounts.loglevel";
     14 
     15 // A pref that can be set so "sensitive" information (eg, personally
     16 // identifiable info, credentials, etc) will be logged.
     17 const PREF_LOG_SENSITIVE_DETAILS = "identity.fxaccounts.log.sensitive";
     18 
     19 export let log = Log.repository.getLogger("FirefoxAccounts");
     20 log.manageLevelFromPref(PREF_LOG_LEVEL);
     21 
     22 let logs = [
     23  "Sync",
     24  "Services.Common",
     25  "FirefoxAccounts",
     26  "Hawk",
     27  "browserwindow.syncui",
     28  "BookmarkSyncUtils",
     29  "addons.xpi",
     30 ];
     31 
     32 // For legacy reasons, the log manager still thinks it's part of sync.
     33 export let logManager = new LogManager({
     34  prefRoot: "services.sync.",
     35  logNames: logs,
     36  logFilePrefix: "sync",
     37  logFileSubDirectoryEntries: ["weave", "logs"],
     38  testTopicPrefix: "services-tests:common:log-manager:",
     39 });
     40 
     41 // A boolean to indicate if personally identifiable information (or anything
     42 // else sensitive, such as credentials) should be logged.
     43 export let logPII = () =>
     44  Services.prefs.getBoolPref(PREF_LOG_SENSITIVE_DETAILS, false);
     45 
     46 export let FXACCOUNTS_PERMISSION = "firefox-accounts";
     47 
     48 export let DATA_FORMAT_VERSION = 1;
     49 export let DEFAULT_STORAGE_FILENAME = "signedInUser.json";
     50 
     51 export let OAUTH_TOKEN_FOR_SYNC_LIFETIME_SECONDS = 3600 * 6; // 6 hours
     52 export let ATTACHED_CLIENTS_CACHE_DURATION = 4 * 60 * 60 * 1000; // 4 hours in ms
     53 
     54 // After we start polling for account verification, we stop polling when this
     55 // many milliseconds have elapsed.
     56 export let POLL_SESSION = 1000 * 60 * 20; // 20 minutes
     57 
     58 // Observer notifications.
     59 export let ONLOGIN_NOTIFICATION = "fxaccounts:onlogin";
     60 export let ONVERIFIED_NOTIFICATION = "fxaccounts:onverified";
     61 export let ONLOGOUT_NOTIFICATION = "fxaccounts:onlogout";
     62 export let ON_PRELOGOUT_NOTIFICATION = "fxaccounts:on_pre_logout";
     63 // Internal to services/fxaccounts only
     64 export let ON_DEVICE_CONNECTED_NOTIFICATION = "fxaccounts:device_connected";
     65 export let ON_DEVICE_DISCONNECTED_NOTIFICATION =
     66  "fxaccounts:device_disconnected";
     67 export let ON_PROFILE_UPDATED_NOTIFICATION = "fxaccounts:profile_updated"; // Push
     68 export let ON_PASSWORD_CHANGED_NOTIFICATION = "fxaccounts:password_changed";
     69 export let ON_PASSWORD_RESET_NOTIFICATION = "fxaccounts:password_reset";
     70 export let ON_ACCOUNT_DESTROYED_NOTIFICATION = "fxaccounts:account_destroyed";
     71 export let ON_COLLECTION_CHANGED_NOTIFICATION = "sync:collection_changed";
     72 export let ON_VERIFY_LOGIN_NOTIFICATION = "fxaccounts:verify_login";
     73 export let ON_COMMAND_RECEIVED_NOTIFICATION = "fxaccounts:command_received";
     74 
     75 export let FXA_PUSH_SCOPE_ACCOUNT_UPDATE = "chrome://fxa-device-update";
     76 
     77 export let ON_PROFILE_CHANGE_NOTIFICATION = "fxaccounts:profilechange"; // WebChannel
     78 export let ON_ACCOUNT_STATE_CHANGE_NOTIFICATION = "fxaccounts:statechange";
     79 export let ON_NEW_DEVICE_ID = "fxaccounts:new_device_id";
     80 export let ON_DEVICELIST_UPDATED = "fxaccounts:devicelist_updated";
     81 
     82 // The common prefix for all commands.
     83 export let COMMAND_PREFIX = "https://identity.mozilla.com/cmd/";
     84 
     85 // The commands we support - only the _TAIL values are recorded in telemetry.
     86 export let COMMAND_SENDTAB_TAIL = "open-uri";
     87 export let COMMAND_SENDTAB = COMMAND_PREFIX + COMMAND_SENDTAB_TAIL;
     88 // A command to close a tab on this device
     89 export let COMMAND_CLOSETAB_TAIL = "close-uri/v1";
     90 export let COMMAND_CLOSETAB = COMMAND_PREFIX + COMMAND_CLOSETAB_TAIL;
     91 
     92 // OAuth
     93 export let CLIENT_IS_THUNDERBIRD = AppConstants.MOZ_APP_NAME == "thunderbird";
     94 let FX_OAUTH_CLIENT_ID = "5882386c6d801776";
     95 let TB_OAUTH_CLIENT_ID = "8269bacd7bbc7f80";
     96 export let OAUTH_CLIENT_ID = CLIENT_IS_THUNDERBIRD
     97  ? TB_OAUTH_CLIENT_ID
     98  : FX_OAUTH_CLIENT_ID;
     99 export let SCOPE_PROFILE = "profile";
    100 export let SCOPE_PROFILE_WRITE = "profile:write";
    101 // Sync scope in Firefox.
    102 export let SCOPE_OLD_SYNC = "https://identity.mozilla.com/apps/oldsync";
    103 // Sync scope in Thunderbird.
    104 let SCOPE_THUNDERBIRD_SYNC = "https://identity.thunderbird.net/apps/sync";
    105 // The scope to use for sync, depending on the current application.
    106 export let SCOPE_APP_SYNC = CLIENT_IS_THUNDERBIRD
    107  ? SCOPE_THUNDERBIRD_SYNC
    108  : SCOPE_OLD_SYNC;
    109 
    110 // This scope was previously used to calculate a telemetry tracking identifier for
    111 // the account, but that system has since been decommissioned. It's here entirely
    112 // so that we can remove the corresponding key from storage if present. We should
    113 // be safe to remove it after some sensible period of time has elapsed to allow
    114 // most clients to update; ref Bug 1697596.
    115 export let DEPRECATED_SCOPE_ECOSYSTEM_TELEMETRY =
    116  "https://identity.mozilla.com/ids/ecosystem_telemetry";
    117 
    118 // OAuth metadata for other Firefox-related services that we might need to know about
    119 // in order to provide an enhanced user experience.
    120 export let FX_MONITOR_OAUTH_CLIENT_ID = "802d56ef2a9af9fa";
    121 export let FX_RELAY_OAUTH_CLIENT_ID = "9ebfe2c2f9ea3c58";
    122 export let VPN_OAUTH_CLIENT_ID = "e6eb0d1e856335fc";
    123 
    124 // UI Requests.
    125 export let UI_REQUEST_SIGN_IN_FLOW = "signInFlow";
    126 export let UI_REQUEST_REFRESH_AUTH = "refreshAuthentication";
    127 
    128 // Firefox Accounts WebChannel ID
    129 export let WEBCHANNEL_ID = "account_updates";
    130 
    131 // WebChannel commands
    132 export let COMMAND_PAIR_HEARTBEAT = "fxaccounts:pair_heartbeat";
    133 export let COMMAND_PAIR_SUPP_METADATA = "fxaccounts:pair_supplicant_metadata";
    134 export let COMMAND_PAIR_AUTHORIZE = "fxaccounts:pair_authorize";
    135 export let COMMAND_PAIR_DECLINE = "fxaccounts:pair_decline";
    136 export let COMMAND_PAIR_COMPLETE = "fxaccounts:pair_complete";
    137 
    138 export let COMMAND_PROFILE_CHANGE = "profile:change";
    139 export let COMMAND_CAN_LINK_ACCOUNT = "fxaccounts:can_link_account";
    140 export let COMMAND_LOGIN = "fxaccounts:login";
    141 export let COMMAND_OAUTH = "fxaccounts:oauth_login";
    142 export let COMMAND_LOGOUT = "fxaccounts:logout";
    143 export let COMMAND_DELETE = "fxaccounts:delete";
    144 export let COMMAND_SYNC_PREFERENCES = "fxaccounts:sync_preferences";
    145 export let COMMAND_CHANGE_PASSWORD = "fxaccounts:change_password";
    146 export let COMMAND_FXA_STATUS = "fxaccounts:fxa_status";
    147 export let COMMAND_PAIR_PREFERENCES = "fxaccounts:pair_preferences";
    148 export let COMMAND_FIREFOX_VIEW = "fxaccounts:firefox_view";
    149 
    150 // The pref branch where any prefs which relate to a specific account should
    151 // be stored. This branch will be reset on account signout and signin.
    152 export let PREF_ACCOUNT_ROOT = "identity.fxaccounts.account.";
    153 
    154 // Where we store the hashed uid of the previous user.
    155 export let PREF_LAST_FXA_USER_UID =
    156  "identity.fxaccounts.lastSignedInUserIdHash";
    157 // Where we used to store the hashed email of the previous user. We now store the
    158 // uid, but need to migrate from this.
    159 export let PREF_LAST_FXA_USER_EMAIL =
    160  "identity.fxaccounts.lastSignedInUserHash";
    161 export let PREF_REMOTE_PAIRING_URI = "identity.fxaccounts.remote.pairing.uri";
    162 
    163 // Server errno.
    164 // From https://github.com/mozilla/fxa-auth-server/blob/master/docs/api.md#response-format
    165 export let ERRNO_ACCOUNT_ALREADY_EXISTS = 101;
    166 export let ERRNO_ACCOUNT_DOES_NOT_EXIST = 102;
    167 export let ERRNO_INCORRECT_PASSWORD = 103;
    168 export let ERRNO_UNVERIFIED_ACCOUNT = 104;
    169 export let ERRNO_INVALID_VERIFICATION_CODE = 105;
    170 export let ERRNO_NOT_VALID_JSON_BODY = 106;
    171 export let ERRNO_INVALID_BODY_PARAMETERS = 107;
    172 export let ERRNO_MISSING_BODY_PARAMETERS = 108;
    173 export let ERRNO_INVALID_REQUEST_SIGNATURE = 109;
    174 export let ERRNO_INVALID_AUTH_TOKEN = 110;
    175 export let ERRNO_INVALID_AUTH_TIMESTAMP = 111;
    176 export let ERRNO_MISSING_CONTENT_LENGTH = 112;
    177 export let ERRNO_REQUEST_BODY_TOO_LARGE = 113;
    178 export let ERRNO_TOO_MANY_CLIENT_REQUESTS = 114;
    179 export let ERRNO_INVALID_AUTH_NONCE = 115;
    180 export let ERRNO_ENDPOINT_NO_LONGER_SUPPORTED = 116;
    181 export let ERRNO_INCORRECT_LOGIN_METHOD = 117;
    182 export let ERRNO_INCORRECT_KEY_RETRIEVAL_METHOD = 118;
    183 export let ERRNO_INCORRECT_API_VERSION = 119;
    184 export let ERRNO_INCORRECT_EMAIL_CASE = 120;
    185 export let ERRNO_ACCOUNT_LOCKED = 121;
    186 export let ERRNO_ACCOUNT_UNLOCKED = 122;
    187 export let ERRNO_UNKNOWN_DEVICE = 123;
    188 export let ERRNO_DEVICE_SESSION_CONFLICT = 124;
    189 export let ERRNO_SERVICE_TEMP_UNAVAILABLE = 201;
    190 export let ERRNO_PARSE = 997;
    191 export let ERRNO_NETWORK = 998;
    192 export let ERRNO_UNKNOWN_ERROR = 999;
    193 
    194 // Offset oauth server errnos so they don't conflict with auth server errnos
    195 export let OAUTH_SERVER_ERRNO_OFFSET = 1000;
    196 
    197 // OAuth Server errno.
    198 export let ERRNO_UNKNOWN_CLIENT_ID = 101 + OAUTH_SERVER_ERRNO_OFFSET;
    199 export let ERRNO_INCORRECT_CLIENT_SECRET = 102 + OAUTH_SERVER_ERRNO_OFFSET;
    200 export let ERRNO_INCORRECT_REDIRECT_URI = 103 + OAUTH_SERVER_ERRNO_OFFSET;
    201 export let ERRNO_INVALID_FXA_ASSERTION = 104 + OAUTH_SERVER_ERRNO_OFFSET;
    202 export let ERRNO_UNKNOWN_CODE = 105 + OAUTH_SERVER_ERRNO_OFFSET;
    203 export let ERRNO_INCORRECT_CODE = 106 + OAUTH_SERVER_ERRNO_OFFSET;
    204 export let ERRNO_EXPIRED_CODE = 107 + OAUTH_SERVER_ERRNO_OFFSET;
    205 export let ERRNO_OAUTH_INVALID_TOKEN = 108 + OAUTH_SERVER_ERRNO_OFFSET;
    206 export let ERRNO_INVALID_REQUEST_PARAM = 109 + OAUTH_SERVER_ERRNO_OFFSET;
    207 export let ERRNO_INVALID_RESPONSE_TYPE = 110 + OAUTH_SERVER_ERRNO_OFFSET;
    208 export let ERRNO_UNAUTHORIZED = 111 + OAUTH_SERVER_ERRNO_OFFSET;
    209 export let ERRNO_FORBIDDEN = 112 + OAUTH_SERVER_ERRNO_OFFSET;
    210 export let ERRNO_INVALID_CONTENT_TYPE = 113 + OAUTH_SERVER_ERRNO_OFFSET;
    211 
    212 // Errors.
    213 export let ERROR_ACCOUNT_ALREADY_EXISTS = "ACCOUNT_ALREADY_EXISTS";
    214 export let ERROR_ACCOUNT_DOES_NOT_EXIST = "ACCOUNT_DOES_NOT_EXIST ";
    215 export let ERROR_ACCOUNT_LOCKED = "ACCOUNT_LOCKED";
    216 export let ERROR_ACCOUNT_UNLOCKED = "ACCOUNT_UNLOCKED";
    217 export let ERROR_ALREADY_SIGNED_IN_USER = "ALREADY_SIGNED_IN_USER";
    218 export let ERROR_DEVICE_SESSION_CONFLICT = "DEVICE_SESSION_CONFLICT";
    219 export let ERROR_ENDPOINT_NO_LONGER_SUPPORTED = "ENDPOINT_NO_LONGER_SUPPORTED";
    220 export let ERROR_INCORRECT_API_VERSION = "INCORRECT_API_VERSION";
    221 export let ERROR_INCORRECT_EMAIL_CASE = "INCORRECT_EMAIL_CASE";
    222 export let ERROR_INCORRECT_KEY_RETRIEVAL_METHOD =
    223  "INCORRECT_KEY_RETRIEVAL_METHOD";
    224 export let ERROR_INCORRECT_LOGIN_METHOD = "INCORRECT_LOGIN_METHOD";
    225 export let ERROR_INVALID_EMAIL = "INVALID_EMAIL";
    226 export let ERROR_INVALID_AUDIENCE = "INVALID_AUDIENCE";
    227 export let ERROR_INVALID_AUTH_TOKEN = "INVALID_AUTH_TOKEN";
    228 export let ERROR_INVALID_AUTH_TIMESTAMP = "INVALID_AUTH_TIMESTAMP";
    229 export let ERROR_INVALID_AUTH_NONCE = "INVALID_AUTH_NONCE";
    230 export let ERROR_INVALID_BODY_PARAMETERS = "INVALID_BODY_PARAMETERS";
    231 export let ERROR_INVALID_PASSWORD = "INVALID_PASSWORD";
    232 export let ERROR_INVALID_VERIFICATION_CODE = "INVALID_VERIFICATION_CODE";
    233 export let ERROR_INVALID_REFRESH_AUTH_VALUE = "INVALID_REFRESH_AUTH_VALUE";
    234 export let ERROR_INVALID_REQUEST_SIGNATURE = "INVALID_REQUEST_SIGNATURE";
    235 export let ERROR_INTERNAL_INVALID_USER = "INTERNAL_ERROR_INVALID_USER";
    236 export let ERROR_MISSING_BODY_PARAMETERS = "MISSING_BODY_PARAMETERS";
    237 export let ERROR_MISSING_CONTENT_LENGTH = "MISSING_CONTENT_LENGTH";
    238 export let ERROR_NO_TOKEN_SESSION = "NO_TOKEN_SESSION";
    239 export let ERROR_NO_SILENT_REFRESH_AUTH = "NO_SILENT_REFRESH_AUTH";
    240 export let ERROR_NOT_VALID_JSON_BODY = "NOT_VALID_JSON_BODY";
    241 export let ERROR_OFFLINE = "OFFLINE";
    242 export let ERROR_PERMISSION_DENIED = "PERMISSION_DENIED";
    243 export let ERROR_REQUEST_BODY_TOO_LARGE = "REQUEST_BODY_TOO_LARGE";
    244 export let ERROR_SERVER_ERROR = "SERVER_ERROR";
    245 export let ERROR_SYNC_DISABLED = "SYNC_DISABLED";
    246 export let ERROR_TOO_MANY_CLIENT_REQUESTS = "TOO_MANY_CLIENT_REQUESTS";
    247 export let ERROR_SERVICE_TEMP_UNAVAILABLE = "SERVICE_TEMPORARY_UNAVAILABLE";
    248 export let ERROR_UI_ERROR = "UI_ERROR";
    249 export let ERROR_UI_REQUEST = "UI_REQUEST";
    250 export let ERROR_PARSE = "PARSE_ERROR";
    251 export let ERROR_NETWORK = "NETWORK_ERROR";
    252 export let ERROR_UNKNOWN = "UNKNOWN_ERROR";
    253 export let ERROR_UNKNOWN_DEVICE = "UNKNOWN_DEVICE";
    254 export let ERROR_UNVERIFIED_ACCOUNT = "UNVERIFIED_ACCOUNT";
    255 
    256 // OAuth errors.
    257 export let ERROR_UNKNOWN_CLIENT_ID = "UNKNOWN_CLIENT_ID";
    258 export let ERROR_INCORRECT_CLIENT_SECRET = "INCORRECT_CLIENT_SECRET";
    259 export let ERROR_INCORRECT_REDIRECT_URI = "INCORRECT_REDIRECT_URI";
    260 export let ERROR_INVALID_FXA_ASSERTION = "INVALID_FXA_ASSERTION";
    261 export let ERROR_UNKNOWN_CODE = "UNKNOWN_CODE";
    262 export let ERROR_INCORRECT_CODE = "INCORRECT_CODE";
    263 export let ERROR_EXPIRED_CODE = "EXPIRED_CODE";
    264 export let ERROR_OAUTH_INVALID_TOKEN = "OAUTH_INVALID_TOKEN";
    265 export let ERROR_INVALID_REQUEST_PARAM = "INVALID_REQUEST_PARAM";
    266 export let ERROR_INVALID_RESPONSE_TYPE = "INVALID_RESPONSE_TYPE";
    267 export let ERROR_UNAUTHORIZED = "UNAUTHORIZED";
    268 export let ERROR_FORBIDDEN = "FORBIDDEN";
    269 export let ERROR_INVALID_CONTENT_TYPE = "INVALID_CONTENT_TYPE";
    270 
    271 // Additional generic error classes for external consumers
    272 export let ERROR_NO_ACCOUNT = "NO_ACCOUNT";
    273 export let ERROR_AUTH_ERROR = "AUTH_ERROR";
    274 export let ERROR_INVALID_PARAMETER = "INVALID_PARAMETER";
    275 
    276 // Status code errors
    277 export let ERROR_CODE_METHOD_NOT_ALLOWED = 405;
    278 export let ERROR_MSG_METHOD_NOT_ALLOWED = "METHOD_NOT_ALLOWED";
    279 
    280 // FxAccounts has the ability to "split" the credentials between a plain-text
    281 // JSON file in the profile dir and in the login manager.
    282 // In order to prevent new fields accidentally ending up in the "wrong" place,
    283 // all fields stored are listed here.
    284 
    285 // The fields we save in the plaintext JSON.
    286 // See bug 1013064 comments 23-25 for why the sessionToken is "safe"
    287 export let FXA_PWDMGR_PLAINTEXT_FIELDS = new Set([
    288  "email",
    289  "verified",
    290  "authAt",
    291  "sessionToken",
    292  "uid",
    293  "oauthTokens",
    294  "profile",
    295  "device",
    296  "profileCache",
    297  "encryptedSendTabKeys",
    298  "encryptedCloseTabKeys",
    299  "requestedServices", // info about services which should be configured, used during oauth flows.
    300 ]);
    301 
    302 // Fields we store in secure storage if it exists.
    303 export let FXA_PWDMGR_SECURE_FIELDS = new Set([
    304  "keyFetchToken",
    305  "unwrapBKey",
    306  "scopedKeys",
    307 ]);
    308 
    309 // An allowlist of fields that remain in storage when the user needs to
    310 // reauthenticate. All other fields will be removed.
    311 export let FXA_PWDMGR_REAUTH_ALLOWLIST = new Set([
    312  "email",
    313  "uid",
    314  "profile",
    315  "device",
    316  "verified",
    317 ]);
    318 
    319 // The pseudo-host we use in the login manager
    320 export let FXA_PWDMGR_HOST = "chrome://FirefoxAccounts";
    321 // The realm we use in the login manager.
    322 export let FXA_PWDMGR_REALM = "Firefox Accounts credentials";
    323 
    324 // Error matching.
    325 export let SERVER_ERRNO_TO_ERROR = {
    326  [ERRNO_ACCOUNT_ALREADY_EXISTS]: ERROR_ACCOUNT_ALREADY_EXISTS,
    327  [ERRNO_ACCOUNT_DOES_NOT_EXIST]: ERROR_ACCOUNT_DOES_NOT_EXIST,
    328  [ERRNO_INCORRECT_PASSWORD]: ERROR_INVALID_PASSWORD,
    329  [ERRNO_UNVERIFIED_ACCOUNT]: ERROR_UNVERIFIED_ACCOUNT,
    330  [ERRNO_INVALID_VERIFICATION_CODE]: ERROR_INVALID_VERIFICATION_CODE,
    331  [ERRNO_NOT_VALID_JSON_BODY]: ERROR_NOT_VALID_JSON_BODY,
    332  [ERRNO_INVALID_BODY_PARAMETERS]: ERROR_INVALID_BODY_PARAMETERS,
    333  [ERRNO_MISSING_BODY_PARAMETERS]: ERROR_MISSING_BODY_PARAMETERS,
    334  [ERRNO_INVALID_REQUEST_SIGNATURE]: ERROR_INVALID_REQUEST_SIGNATURE,
    335  [ERRNO_INVALID_AUTH_TOKEN]: ERROR_INVALID_AUTH_TOKEN,
    336  [ERRNO_INVALID_AUTH_TIMESTAMP]: ERROR_INVALID_AUTH_TIMESTAMP,
    337  [ERRNO_MISSING_CONTENT_LENGTH]: ERROR_MISSING_CONTENT_LENGTH,
    338  [ERRNO_REQUEST_BODY_TOO_LARGE]: ERROR_REQUEST_BODY_TOO_LARGE,
    339  [ERRNO_TOO_MANY_CLIENT_REQUESTS]: ERROR_TOO_MANY_CLIENT_REQUESTS,
    340  [ERRNO_INVALID_AUTH_NONCE]: ERROR_INVALID_AUTH_NONCE,
    341  [ERRNO_ENDPOINT_NO_LONGER_SUPPORTED]: ERROR_ENDPOINT_NO_LONGER_SUPPORTED,
    342  [ERRNO_INCORRECT_LOGIN_METHOD]: ERROR_INCORRECT_LOGIN_METHOD,
    343  [ERRNO_INCORRECT_KEY_RETRIEVAL_METHOD]: ERROR_INCORRECT_KEY_RETRIEVAL_METHOD,
    344  [ERRNO_INCORRECT_API_VERSION]: ERROR_INCORRECT_API_VERSION,
    345  [ERRNO_INCORRECT_EMAIL_CASE]: ERROR_INCORRECT_EMAIL_CASE,
    346  [ERRNO_ACCOUNT_LOCKED]: ERROR_ACCOUNT_LOCKED,
    347  [ERRNO_ACCOUNT_UNLOCKED]: ERROR_ACCOUNT_UNLOCKED,
    348  [ERRNO_UNKNOWN_DEVICE]: ERROR_UNKNOWN_DEVICE,
    349  [ERRNO_DEVICE_SESSION_CONFLICT]: ERROR_DEVICE_SESSION_CONFLICT,
    350  [ERRNO_SERVICE_TEMP_UNAVAILABLE]: ERROR_SERVICE_TEMP_UNAVAILABLE,
    351  [ERRNO_UNKNOWN_ERROR]: ERROR_UNKNOWN,
    352  [ERRNO_NETWORK]: ERROR_NETWORK,
    353  // oauth
    354  [ERRNO_UNKNOWN_CLIENT_ID]: ERROR_UNKNOWN_CLIENT_ID,
    355  [ERRNO_INCORRECT_CLIENT_SECRET]: ERROR_INCORRECT_CLIENT_SECRET,
    356  [ERRNO_INCORRECT_REDIRECT_URI]: ERROR_INCORRECT_REDIRECT_URI,
    357  [ERRNO_INVALID_FXA_ASSERTION]: ERROR_INVALID_FXA_ASSERTION,
    358  [ERRNO_UNKNOWN_CODE]: ERROR_UNKNOWN_CODE,
    359  [ERRNO_INCORRECT_CODE]: ERROR_INCORRECT_CODE,
    360  [ERRNO_EXPIRED_CODE]: ERROR_EXPIRED_CODE,
    361  [ERRNO_OAUTH_INVALID_TOKEN]: ERROR_OAUTH_INVALID_TOKEN,
    362  [ERRNO_INVALID_REQUEST_PARAM]: ERROR_INVALID_REQUEST_PARAM,
    363  [ERRNO_INVALID_RESPONSE_TYPE]: ERROR_INVALID_RESPONSE_TYPE,
    364  [ERRNO_UNAUTHORIZED]: ERROR_UNAUTHORIZED,
    365  [ERRNO_FORBIDDEN]: ERROR_FORBIDDEN,
    366  [ERRNO_INVALID_CONTENT_TYPE]: ERROR_INVALID_CONTENT_TYPE,
    367 };
    368 
    369 // Map internal errors to more generic error classes for consumers
    370 export let ERROR_TO_GENERAL_ERROR_CLASS = {
    371  [ERROR_ACCOUNT_ALREADY_EXISTS]: ERROR_AUTH_ERROR,
    372  [ERROR_ACCOUNT_DOES_NOT_EXIST]: ERROR_AUTH_ERROR,
    373  [ERROR_ACCOUNT_LOCKED]: ERROR_AUTH_ERROR,
    374  [ERROR_ACCOUNT_UNLOCKED]: ERROR_AUTH_ERROR,
    375  [ERROR_ALREADY_SIGNED_IN_USER]: ERROR_AUTH_ERROR,
    376  [ERROR_DEVICE_SESSION_CONFLICT]: ERROR_AUTH_ERROR,
    377  [ERROR_ENDPOINT_NO_LONGER_SUPPORTED]: ERROR_AUTH_ERROR,
    378  [ERROR_INCORRECT_API_VERSION]: ERROR_AUTH_ERROR,
    379  [ERROR_INCORRECT_EMAIL_CASE]: ERROR_AUTH_ERROR,
    380  [ERROR_INCORRECT_KEY_RETRIEVAL_METHOD]: ERROR_AUTH_ERROR,
    381  [ERROR_INCORRECT_LOGIN_METHOD]: ERROR_AUTH_ERROR,
    382  [ERROR_INVALID_EMAIL]: ERROR_AUTH_ERROR,
    383  [ERROR_INVALID_AUDIENCE]: ERROR_AUTH_ERROR,
    384  [ERROR_INVALID_AUTH_TOKEN]: ERROR_AUTH_ERROR,
    385  [ERROR_INVALID_AUTH_TIMESTAMP]: ERROR_AUTH_ERROR,
    386  [ERROR_INVALID_AUTH_NONCE]: ERROR_AUTH_ERROR,
    387  [ERROR_INVALID_BODY_PARAMETERS]: ERROR_AUTH_ERROR,
    388  [ERROR_INVALID_PASSWORD]: ERROR_AUTH_ERROR,
    389  [ERROR_INVALID_VERIFICATION_CODE]: ERROR_AUTH_ERROR,
    390  [ERROR_INVALID_REFRESH_AUTH_VALUE]: ERROR_AUTH_ERROR,
    391  [ERROR_INVALID_REQUEST_SIGNATURE]: ERROR_AUTH_ERROR,
    392  [ERROR_INTERNAL_INVALID_USER]: ERROR_AUTH_ERROR,
    393  [ERROR_MISSING_BODY_PARAMETERS]: ERROR_AUTH_ERROR,
    394  [ERROR_MISSING_CONTENT_LENGTH]: ERROR_AUTH_ERROR,
    395  [ERROR_NO_TOKEN_SESSION]: ERROR_AUTH_ERROR,
    396  [ERROR_NO_SILENT_REFRESH_AUTH]: ERROR_AUTH_ERROR,
    397  [ERROR_NOT_VALID_JSON_BODY]: ERROR_AUTH_ERROR,
    398  [ERROR_PERMISSION_DENIED]: ERROR_AUTH_ERROR,
    399  [ERROR_REQUEST_BODY_TOO_LARGE]: ERROR_AUTH_ERROR,
    400  [ERROR_UNKNOWN_DEVICE]: ERROR_AUTH_ERROR,
    401  [ERROR_UNVERIFIED_ACCOUNT]: ERROR_AUTH_ERROR,
    402  [ERROR_UI_ERROR]: ERROR_AUTH_ERROR,
    403  [ERROR_UI_REQUEST]: ERROR_AUTH_ERROR,
    404  [ERROR_OFFLINE]: ERROR_NETWORK,
    405  [ERROR_SERVER_ERROR]: ERROR_NETWORK,
    406  [ERROR_TOO_MANY_CLIENT_REQUESTS]: ERROR_NETWORK,
    407  [ERROR_SERVICE_TEMP_UNAVAILABLE]: ERROR_NETWORK,
    408  [ERROR_PARSE]: ERROR_NETWORK,
    409  [ERROR_NETWORK]: ERROR_NETWORK,
    410 
    411  // oauth
    412  [ERROR_INCORRECT_CLIENT_SECRET]: ERROR_AUTH_ERROR,
    413  [ERROR_INCORRECT_REDIRECT_URI]: ERROR_AUTH_ERROR,
    414  [ERROR_INVALID_FXA_ASSERTION]: ERROR_AUTH_ERROR,
    415  [ERROR_UNKNOWN_CODE]: ERROR_AUTH_ERROR,
    416  [ERROR_INCORRECT_CODE]: ERROR_AUTH_ERROR,
    417  [ERROR_EXPIRED_CODE]: ERROR_AUTH_ERROR,
    418  [ERROR_OAUTH_INVALID_TOKEN]: ERROR_AUTH_ERROR,
    419  [ERROR_INVALID_REQUEST_PARAM]: ERROR_AUTH_ERROR,
    420  [ERROR_INVALID_RESPONSE_TYPE]: ERROR_AUTH_ERROR,
    421  [ERROR_UNAUTHORIZED]: ERROR_AUTH_ERROR,
    422  [ERROR_FORBIDDEN]: ERROR_AUTH_ERROR,
    423  [ERROR_INVALID_CONTENT_TYPE]: ERROR_AUTH_ERROR,
    424 };