michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: const { interfaces: Ci, utils: Cu } = Components; michael@0: michael@0: Cu.import("resource://gre/modules/XPCOMUtils.jsm"); michael@0: Cu.import("resource://gre/modules/Services.jsm"); michael@0: Cu.import("resource://gre/modules/Log.jsm"); michael@0: michael@0: // loglevel should be one of "Fatal", "Error", "Warn", "Info", "Config", michael@0: // "Debug", "Trace" or "All". If none is specified, "Debug" will be used by michael@0: // default. Note "Debug" is usually appropriate so that when this log is michael@0: // included in the Sync file logs we get verbose output. michael@0: const PREF_LOG_LEVEL = "identity.fxaccounts.loglevel"; michael@0: // The level of messages that will be dumped to the console. If not specified, michael@0: // "Error" will be used. michael@0: const PREF_LOG_LEVEL_DUMP = "identity.fxaccounts.log.appender.dump"; michael@0: michael@0: // A pref that can be set so "sensitive" information (eg, personally michael@0: // identifiable info, credentials, etc) will be logged. michael@0: const PREF_LOG_SENSITIVE_DETAILS = "identity.fxaccounts.log.sensitive"; michael@0: michael@0: XPCOMUtils.defineLazyGetter(this, 'log', function() { michael@0: let log = Log.repository.getLogger("FirefoxAccounts"); michael@0: // We set the log level to debug, but the default dump appender is set to michael@0: // the level reflected in the pref. Other code that consumes FxA may then michael@0: // choose to add another appender at a different level. michael@0: log.level = Log.Level.Debug; michael@0: let appender = new Log.DumpAppender(); michael@0: appender.level = Log.Level.Error; michael@0: michael@0: log.addAppender(appender); michael@0: try { michael@0: // The log itself. michael@0: let level = michael@0: Services.prefs.getPrefType(PREF_LOG_LEVEL) == Ci.nsIPrefBranch.PREF_STRING michael@0: && Services.prefs.getCharPref(PREF_LOG_LEVEL); michael@0: log.level = Log.Level[level] || Log.Level.Debug; michael@0: michael@0: // The appender. michael@0: level = michael@0: Services.prefs.getPrefType(PREF_LOG_LEVEL_DUMP) == Ci.nsIPrefBranch.PREF_STRING michael@0: && Services.prefs.getCharPref(PREF_LOG_LEVEL_DUMP); michael@0: appender.level = Log.Level[level] || Log.Level.Error; michael@0: } catch (e) { michael@0: log.error(e); michael@0: } michael@0: michael@0: return log; michael@0: }); michael@0: michael@0: // A boolean to indicate if personally identifiable information (or anything michael@0: // else sensitive, such as credentials) should be logged. michael@0: XPCOMUtils.defineLazyGetter(this, 'logPII', function() { michael@0: try { michael@0: return Services.prefs.getBoolPref(PREF_LOG_SENSITIVE_DETAILS); michael@0: } catch (_) { michael@0: return false; michael@0: } michael@0: }); michael@0: michael@0: this.DATA_FORMAT_VERSION = 1; michael@0: this.DEFAULT_STORAGE_FILENAME = "signedInUser.json"; michael@0: michael@0: // Token life times. michael@0: // Having this parameter be short has limited security value and can cause michael@0: // spurious authentication values if the client's clock is skewed and michael@0: // we fail to adjust. See Bug 983256. michael@0: this.ASSERTION_LIFETIME = 1000 * 3600 * 24 * 365 * 25; // 25 years michael@0: // This is a time period we want to guarantee that the assertion will be michael@0: // valid after we generate it (e.g., the signed cert won't expire in this michael@0: // period). michael@0: this.ASSERTION_USE_PERIOD = 1000 * 60 * 5; // 5 minutes michael@0: this.CERT_LIFETIME = 1000 * 3600 * 6; // 6 hours michael@0: this.KEY_LIFETIME = 1000 * 3600 * 12; // 12 hours michael@0: michael@0: // Polling timings. michael@0: this.POLL_SESSION = 1000 * 60 * 5; // 5 minutes michael@0: this.POLL_STEP = 1000 * 3; // 3 seconds michael@0: michael@0: // Observer notifications. michael@0: this.ONLOGIN_NOTIFICATION = "fxaccounts:onlogin"; michael@0: this.ONVERIFIED_NOTIFICATION = "fxaccounts:onverified"; michael@0: this.ONLOGOUT_NOTIFICATION = "fxaccounts:onlogout"; michael@0: michael@0: // UI Requests. michael@0: this.UI_REQUEST_SIGN_IN_FLOW = "signInFlow"; michael@0: this.UI_REQUEST_REFRESH_AUTH = "refreshAuthentication"; michael@0: michael@0: // Server errno. michael@0: // From https://github.com/mozilla/fxa-auth-server/blob/master/docs/api.md#response-format michael@0: this.ERRNO_ACCOUNT_ALREADY_EXISTS = 101; michael@0: this.ERRNO_ACCOUNT_DOES_NOT_EXIST = 102; michael@0: this.ERRNO_INCORRECT_PASSWORD = 103; michael@0: this.ERRNO_UNVERIFIED_ACCOUNT = 104; michael@0: this.ERRNO_INVALID_VERIFICATION_CODE = 105; michael@0: this.ERRNO_NOT_VALID_JSON_BODY = 106; michael@0: this.ERRNO_INVALID_BODY_PARAMETERS = 107; michael@0: this.ERRNO_MISSING_BODY_PARAMETERS = 108; michael@0: this.ERRNO_INVALID_REQUEST_SIGNATURE = 109; michael@0: this.ERRNO_INVALID_AUTH_TOKEN = 110; michael@0: this.ERRNO_INVALID_AUTH_TIMESTAMP = 111; michael@0: this.ERRNO_MISSING_CONTENT_LENGTH = 112; michael@0: this.ERRNO_REQUEST_BODY_TOO_LARGE = 113; michael@0: this.ERRNO_TOO_MANY_CLIENT_REQUESTS = 114; michael@0: this.ERRNO_INVALID_AUTH_NONCE = 115; michael@0: this.ERRNO_ENDPOINT_NO_LONGER_SUPPORTED = 116; michael@0: this.ERRNO_INCORRECT_LOGIN_METHOD = 117; michael@0: this.ERRNO_INCORRECT_KEY_RETRIEVAL_METHOD = 118; michael@0: this.ERRNO_INCORRECT_API_VERSION = 119; michael@0: this.ERRNO_INCORRECT_EMAIL_CASE = 120; michael@0: this.ERRNO_SERVICE_TEMP_UNAVAILABLE = 201; michael@0: this.ERRNO_UNKNOWN_ERROR = 999; michael@0: michael@0: // Errors. michael@0: this.ERROR_ACCOUNT_ALREADY_EXISTS = "ACCOUNT_ALREADY_EXISTS"; michael@0: this.ERROR_ACCOUNT_DOES_NOT_EXIST = "ACCOUNT_DOES_NOT_EXIST "; michael@0: this.ERROR_ALREADY_SIGNED_IN_USER = "ALREADY_SIGNED_IN_USER"; michael@0: this.ERROR_ENDPOINT_NO_LONGER_SUPPORTED = "ENDPOINT_NO_LONGER_SUPPORTED"; michael@0: this.ERROR_INCORRECT_API_VERSION = "INCORRECT_API_VERSION"; michael@0: this.ERROR_INCORRECT_EMAIL_CASE = "INCORRECT_EMAIL_CASE"; michael@0: this.ERROR_INCORRECT_KEY_RETRIEVAL_METHOD = "INCORRECT_KEY_RETRIEVAL_METHOD"; michael@0: this.ERROR_INCORRECT_LOGIN_METHOD = "INCORRECT_LOGIN_METHOD"; michael@0: this.ERROR_INVALID_ACCOUNTID = "INVALID_ACCOUNTID"; michael@0: this.ERROR_INVALID_AUDIENCE = "INVALID_AUDIENCE"; michael@0: this.ERROR_INVALID_AUTH_TOKEN = "INVALID_AUTH_TOKEN"; michael@0: this.ERROR_INVALID_AUTH_TIMESTAMP = "INVALID_AUTH_TIMESTAMP"; michael@0: this.ERROR_INVALID_AUTH_NONCE = "INVALID_AUTH_NONCE"; michael@0: this.ERROR_INVALID_BODY_PARAMETERS = "INVALID_BODY_PARAMETERS"; michael@0: this.ERROR_INVALID_PASSWORD = "INVALID_PASSWORD"; michael@0: this.ERROR_INVALID_VERIFICATION_CODE = "INVALID_VERIFICATION_CODE"; michael@0: this.ERROR_INVALID_REFRESH_AUTH_VALUE = "INVALID_REFRESH_AUTH_VALUE"; michael@0: this.ERROR_INVALID_REQUEST_SIGNATURE = "INVALID_REQUEST_SIGNATURE"; michael@0: this.ERROR_INTERNAL_INVALID_USER = "INTERNAL_ERROR_INVALID_USER"; michael@0: this.ERROR_MISSING_BODY_PARAMETERS = "MISSING_BODY_PARAMETERS"; michael@0: this.ERROR_MISSING_CONTENT_LENGTH = "MISSING_CONTENT_LENGTH"; michael@0: this.ERROR_NO_TOKEN_SESSION = "NO_TOKEN_SESSION"; michael@0: this.ERROR_NOT_VALID_JSON_BODY = "NOT_VALID_JSON_BODY"; michael@0: this.ERROR_OFFLINE = "OFFLINE"; michael@0: this.ERROR_REQUEST_BODY_TOO_LARGE = "REQUEST_BODY_TOO_LARGE"; michael@0: this.ERROR_SERVER_ERROR = "SERVER_ERROR"; michael@0: this.ERROR_TOO_MANY_CLIENT_REQUESTS = "TOO_MANY_CLIENT_REQUESTS"; michael@0: this.ERROR_SERVICE_TEMP_UNAVAILABLE = "SERVICE_TEMPORARY_UNAVAILABLE"; michael@0: this.ERROR_UI_ERROR = "UI_ERROR"; michael@0: this.ERROR_UI_REQUEST = "UI_REQUEST"; michael@0: this.ERROR_UNKNOWN = "UNKNOWN_ERROR"; michael@0: this.ERROR_UNVERIFIED_ACCOUNT = "UNVERIFIED_ACCOUNT"; michael@0: michael@0: // Error matching. michael@0: this.SERVER_ERRNO_TO_ERROR = {}; michael@0: SERVER_ERRNO_TO_ERROR[ERRNO_ACCOUNT_ALREADY_EXISTS] = ERROR_ACCOUNT_ALREADY_EXISTS; michael@0: SERVER_ERRNO_TO_ERROR[ERRNO_ACCOUNT_DOES_NOT_EXIST] = ERROR_ACCOUNT_DOES_NOT_EXIST; michael@0: SERVER_ERRNO_TO_ERROR[ERRNO_INCORRECT_PASSWORD] = ERROR_INVALID_PASSWORD; michael@0: SERVER_ERRNO_TO_ERROR[ERRNO_UNVERIFIED_ACCOUNT] = ERROR_UNVERIFIED_ACCOUNT; michael@0: SERVER_ERRNO_TO_ERROR[ERRNO_INVALID_VERIFICATION_CODE] = ERROR_INVALID_VERIFICATION_CODE; michael@0: SERVER_ERRNO_TO_ERROR[ERRNO_NOT_VALID_JSON_BODY] = ERROR_NOT_VALID_JSON_BODY; michael@0: SERVER_ERRNO_TO_ERROR[ERRNO_INVALID_BODY_PARAMETERS] = ERROR_INVALID_BODY_PARAMETERS; michael@0: SERVER_ERRNO_TO_ERROR[ERRNO_MISSING_BODY_PARAMETERS] = ERROR_MISSING_BODY_PARAMETERS; michael@0: SERVER_ERRNO_TO_ERROR[ERRNO_INVALID_REQUEST_SIGNATURE] = ERROR_INVALID_REQUEST_SIGNATURE; michael@0: SERVER_ERRNO_TO_ERROR[ERRNO_INVALID_AUTH_TOKEN] = ERROR_INVALID_AUTH_TOKEN; michael@0: SERVER_ERRNO_TO_ERROR[ERRNO_INVALID_AUTH_TIMESTAMP] = ERROR_INVALID_AUTH_TIMESTAMP; michael@0: SERVER_ERRNO_TO_ERROR[ERRNO_MISSING_CONTENT_LENGTH] = ERROR_MISSING_CONTENT_LENGTH; michael@0: SERVER_ERRNO_TO_ERROR[ERRNO_REQUEST_BODY_TOO_LARGE] = ERROR_REQUEST_BODY_TOO_LARGE; michael@0: SERVER_ERRNO_TO_ERROR[ERRNO_TOO_MANY_CLIENT_REQUESTS] = ERROR_TOO_MANY_CLIENT_REQUESTS; michael@0: SERVER_ERRNO_TO_ERROR[ERRNO_INVALID_AUTH_NONCE] = ERROR_INVALID_AUTH_NONCE; michael@0: SERVER_ERRNO_TO_ERROR[ERRNO_ENDPOINT_NO_LONGER_SUPPORTED] = ERROR_ENDPOINT_NO_LONGER_SUPPORTED; michael@0: SERVER_ERRNO_TO_ERROR[ERRNO_INCORRECT_LOGIN_METHOD] = ERROR_INCORRECT_LOGIN_METHOD; michael@0: SERVER_ERRNO_TO_ERROR[ERRNO_INCORRECT_KEY_RETRIEVAL_METHOD] = ERROR_INCORRECT_KEY_RETRIEVAL_METHOD; michael@0: SERVER_ERRNO_TO_ERROR[ERRNO_INCORRECT_API_VERSION] = ERROR_INCORRECT_API_VERSION; michael@0: SERVER_ERRNO_TO_ERROR[ERRNO_INCORRECT_EMAIL_CASE] = ERROR_INCORRECT_EMAIL_CASE; michael@0: SERVER_ERRNO_TO_ERROR[ERRNO_SERVICE_TEMP_UNAVAILABLE] = ERROR_SERVICE_TEMP_UNAVAILABLE; michael@0: SERVER_ERRNO_TO_ERROR[ERRNO_UNKNOWN_ERROR] = ERROR_UNKNOWN; michael@0: michael@0: // Allow this file to be imported via Components.utils.import(). michael@0: this.EXPORTED_SYMBOLS = Object.keys(this);