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