|
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 const { interfaces: Ci, utils: Cu } = Components; |
|
6 |
|
7 Cu.import("resource://gre/modules/XPCOMUtils.jsm"); |
|
8 Cu.import("resource://gre/modules/Services.jsm"); |
|
9 Cu.import("resource://gre/modules/Log.jsm"); |
|
10 |
|
11 // loglevel should be one of "Fatal", "Error", "Warn", "Info", "Config", |
|
12 // "Debug", "Trace" or "All". If none is specified, "Debug" will be used by |
|
13 // default. Note "Debug" is usually appropriate so that when this log is |
|
14 // included in the Sync file logs we get verbose output. |
|
15 const PREF_LOG_LEVEL = "identity.fxaccounts.loglevel"; |
|
16 // The level of messages that will be dumped to the console. If not specified, |
|
17 // "Error" will be used. |
|
18 const PREF_LOG_LEVEL_DUMP = "identity.fxaccounts.log.appender.dump"; |
|
19 |
|
20 // A pref that can be set so "sensitive" information (eg, personally |
|
21 // identifiable info, credentials, etc) will be logged. |
|
22 const PREF_LOG_SENSITIVE_DETAILS = "identity.fxaccounts.log.sensitive"; |
|
23 |
|
24 XPCOMUtils.defineLazyGetter(this, 'log', function() { |
|
25 let log = Log.repository.getLogger("FirefoxAccounts"); |
|
26 // We set the log level to debug, but the default dump appender is set to |
|
27 // the level reflected in the pref. Other code that consumes FxA may then |
|
28 // choose to add another appender at a different level. |
|
29 log.level = Log.Level.Debug; |
|
30 let appender = new Log.DumpAppender(); |
|
31 appender.level = Log.Level.Error; |
|
32 |
|
33 log.addAppender(appender); |
|
34 try { |
|
35 // The log itself. |
|
36 let level = |
|
37 Services.prefs.getPrefType(PREF_LOG_LEVEL) == Ci.nsIPrefBranch.PREF_STRING |
|
38 && Services.prefs.getCharPref(PREF_LOG_LEVEL); |
|
39 log.level = Log.Level[level] || Log.Level.Debug; |
|
40 |
|
41 // The appender. |
|
42 level = |
|
43 Services.prefs.getPrefType(PREF_LOG_LEVEL_DUMP) == Ci.nsIPrefBranch.PREF_STRING |
|
44 && Services.prefs.getCharPref(PREF_LOG_LEVEL_DUMP); |
|
45 appender.level = Log.Level[level] || Log.Level.Error; |
|
46 } catch (e) { |
|
47 log.error(e); |
|
48 } |
|
49 |
|
50 return log; |
|
51 }); |
|
52 |
|
53 // A boolean to indicate if personally identifiable information (or anything |
|
54 // else sensitive, such as credentials) should be logged. |
|
55 XPCOMUtils.defineLazyGetter(this, 'logPII', function() { |
|
56 try { |
|
57 return Services.prefs.getBoolPref(PREF_LOG_SENSITIVE_DETAILS); |
|
58 } catch (_) { |
|
59 return false; |
|
60 } |
|
61 }); |
|
62 |
|
63 this.DATA_FORMAT_VERSION = 1; |
|
64 this.DEFAULT_STORAGE_FILENAME = "signedInUser.json"; |
|
65 |
|
66 // Token life times. |
|
67 // Having this parameter be short has limited security value and can cause |
|
68 // spurious authentication values if the client's clock is skewed and |
|
69 // we fail to adjust. See Bug 983256. |
|
70 this.ASSERTION_LIFETIME = 1000 * 3600 * 24 * 365 * 25; // 25 years |
|
71 // This is a time period we want to guarantee that the assertion will be |
|
72 // valid after we generate it (e.g., the signed cert won't expire in this |
|
73 // period). |
|
74 this.ASSERTION_USE_PERIOD = 1000 * 60 * 5; // 5 minutes |
|
75 this.CERT_LIFETIME = 1000 * 3600 * 6; // 6 hours |
|
76 this.KEY_LIFETIME = 1000 * 3600 * 12; // 12 hours |
|
77 |
|
78 // Polling timings. |
|
79 this.POLL_SESSION = 1000 * 60 * 5; // 5 minutes |
|
80 this.POLL_STEP = 1000 * 3; // 3 seconds |
|
81 |
|
82 // Observer notifications. |
|
83 this.ONLOGIN_NOTIFICATION = "fxaccounts:onlogin"; |
|
84 this.ONVERIFIED_NOTIFICATION = "fxaccounts:onverified"; |
|
85 this.ONLOGOUT_NOTIFICATION = "fxaccounts:onlogout"; |
|
86 |
|
87 // UI Requests. |
|
88 this.UI_REQUEST_SIGN_IN_FLOW = "signInFlow"; |
|
89 this.UI_REQUEST_REFRESH_AUTH = "refreshAuthentication"; |
|
90 |
|
91 // Server errno. |
|
92 // From https://github.com/mozilla/fxa-auth-server/blob/master/docs/api.md#response-format |
|
93 this.ERRNO_ACCOUNT_ALREADY_EXISTS = 101; |
|
94 this.ERRNO_ACCOUNT_DOES_NOT_EXIST = 102; |
|
95 this.ERRNO_INCORRECT_PASSWORD = 103; |
|
96 this.ERRNO_UNVERIFIED_ACCOUNT = 104; |
|
97 this.ERRNO_INVALID_VERIFICATION_CODE = 105; |
|
98 this.ERRNO_NOT_VALID_JSON_BODY = 106; |
|
99 this.ERRNO_INVALID_BODY_PARAMETERS = 107; |
|
100 this.ERRNO_MISSING_BODY_PARAMETERS = 108; |
|
101 this.ERRNO_INVALID_REQUEST_SIGNATURE = 109; |
|
102 this.ERRNO_INVALID_AUTH_TOKEN = 110; |
|
103 this.ERRNO_INVALID_AUTH_TIMESTAMP = 111; |
|
104 this.ERRNO_MISSING_CONTENT_LENGTH = 112; |
|
105 this.ERRNO_REQUEST_BODY_TOO_LARGE = 113; |
|
106 this.ERRNO_TOO_MANY_CLIENT_REQUESTS = 114; |
|
107 this.ERRNO_INVALID_AUTH_NONCE = 115; |
|
108 this.ERRNO_ENDPOINT_NO_LONGER_SUPPORTED = 116; |
|
109 this.ERRNO_INCORRECT_LOGIN_METHOD = 117; |
|
110 this.ERRNO_INCORRECT_KEY_RETRIEVAL_METHOD = 118; |
|
111 this.ERRNO_INCORRECT_API_VERSION = 119; |
|
112 this.ERRNO_INCORRECT_EMAIL_CASE = 120; |
|
113 this.ERRNO_SERVICE_TEMP_UNAVAILABLE = 201; |
|
114 this.ERRNO_UNKNOWN_ERROR = 999; |
|
115 |
|
116 // Errors. |
|
117 this.ERROR_ACCOUNT_ALREADY_EXISTS = "ACCOUNT_ALREADY_EXISTS"; |
|
118 this.ERROR_ACCOUNT_DOES_NOT_EXIST = "ACCOUNT_DOES_NOT_EXIST "; |
|
119 this.ERROR_ALREADY_SIGNED_IN_USER = "ALREADY_SIGNED_IN_USER"; |
|
120 this.ERROR_ENDPOINT_NO_LONGER_SUPPORTED = "ENDPOINT_NO_LONGER_SUPPORTED"; |
|
121 this.ERROR_INCORRECT_API_VERSION = "INCORRECT_API_VERSION"; |
|
122 this.ERROR_INCORRECT_EMAIL_CASE = "INCORRECT_EMAIL_CASE"; |
|
123 this.ERROR_INCORRECT_KEY_RETRIEVAL_METHOD = "INCORRECT_KEY_RETRIEVAL_METHOD"; |
|
124 this.ERROR_INCORRECT_LOGIN_METHOD = "INCORRECT_LOGIN_METHOD"; |
|
125 this.ERROR_INVALID_ACCOUNTID = "INVALID_ACCOUNTID"; |
|
126 this.ERROR_INVALID_AUDIENCE = "INVALID_AUDIENCE"; |
|
127 this.ERROR_INVALID_AUTH_TOKEN = "INVALID_AUTH_TOKEN"; |
|
128 this.ERROR_INVALID_AUTH_TIMESTAMP = "INVALID_AUTH_TIMESTAMP"; |
|
129 this.ERROR_INVALID_AUTH_NONCE = "INVALID_AUTH_NONCE"; |
|
130 this.ERROR_INVALID_BODY_PARAMETERS = "INVALID_BODY_PARAMETERS"; |
|
131 this.ERROR_INVALID_PASSWORD = "INVALID_PASSWORD"; |
|
132 this.ERROR_INVALID_VERIFICATION_CODE = "INVALID_VERIFICATION_CODE"; |
|
133 this.ERROR_INVALID_REFRESH_AUTH_VALUE = "INVALID_REFRESH_AUTH_VALUE"; |
|
134 this.ERROR_INVALID_REQUEST_SIGNATURE = "INVALID_REQUEST_SIGNATURE"; |
|
135 this.ERROR_INTERNAL_INVALID_USER = "INTERNAL_ERROR_INVALID_USER"; |
|
136 this.ERROR_MISSING_BODY_PARAMETERS = "MISSING_BODY_PARAMETERS"; |
|
137 this.ERROR_MISSING_CONTENT_LENGTH = "MISSING_CONTENT_LENGTH"; |
|
138 this.ERROR_NO_TOKEN_SESSION = "NO_TOKEN_SESSION"; |
|
139 this.ERROR_NOT_VALID_JSON_BODY = "NOT_VALID_JSON_BODY"; |
|
140 this.ERROR_OFFLINE = "OFFLINE"; |
|
141 this.ERROR_REQUEST_BODY_TOO_LARGE = "REQUEST_BODY_TOO_LARGE"; |
|
142 this.ERROR_SERVER_ERROR = "SERVER_ERROR"; |
|
143 this.ERROR_TOO_MANY_CLIENT_REQUESTS = "TOO_MANY_CLIENT_REQUESTS"; |
|
144 this.ERROR_SERVICE_TEMP_UNAVAILABLE = "SERVICE_TEMPORARY_UNAVAILABLE"; |
|
145 this.ERROR_UI_ERROR = "UI_ERROR"; |
|
146 this.ERROR_UI_REQUEST = "UI_REQUEST"; |
|
147 this.ERROR_UNKNOWN = "UNKNOWN_ERROR"; |
|
148 this.ERROR_UNVERIFIED_ACCOUNT = "UNVERIFIED_ACCOUNT"; |
|
149 |
|
150 // Error matching. |
|
151 this.SERVER_ERRNO_TO_ERROR = {}; |
|
152 SERVER_ERRNO_TO_ERROR[ERRNO_ACCOUNT_ALREADY_EXISTS] = ERROR_ACCOUNT_ALREADY_EXISTS; |
|
153 SERVER_ERRNO_TO_ERROR[ERRNO_ACCOUNT_DOES_NOT_EXIST] = ERROR_ACCOUNT_DOES_NOT_EXIST; |
|
154 SERVER_ERRNO_TO_ERROR[ERRNO_INCORRECT_PASSWORD] = ERROR_INVALID_PASSWORD; |
|
155 SERVER_ERRNO_TO_ERROR[ERRNO_UNVERIFIED_ACCOUNT] = ERROR_UNVERIFIED_ACCOUNT; |
|
156 SERVER_ERRNO_TO_ERROR[ERRNO_INVALID_VERIFICATION_CODE] = ERROR_INVALID_VERIFICATION_CODE; |
|
157 SERVER_ERRNO_TO_ERROR[ERRNO_NOT_VALID_JSON_BODY] = ERROR_NOT_VALID_JSON_BODY; |
|
158 SERVER_ERRNO_TO_ERROR[ERRNO_INVALID_BODY_PARAMETERS] = ERROR_INVALID_BODY_PARAMETERS; |
|
159 SERVER_ERRNO_TO_ERROR[ERRNO_MISSING_BODY_PARAMETERS] = ERROR_MISSING_BODY_PARAMETERS; |
|
160 SERVER_ERRNO_TO_ERROR[ERRNO_INVALID_REQUEST_SIGNATURE] = ERROR_INVALID_REQUEST_SIGNATURE; |
|
161 SERVER_ERRNO_TO_ERROR[ERRNO_INVALID_AUTH_TOKEN] = ERROR_INVALID_AUTH_TOKEN; |
|
162 SERVER_ERRNO_TO_ERROR[ERRNO_INVALID_AUTH_TIMESTAMP] = ERROR_INVALID_AUTH_TIMESTAMP; |
|
163 SERVER_ERRNO_TO_ERROR[ERRNO_MISSING_CONTENT_LENGTH] = ERROR_MISSING_CONTENT_LENGTH; |
|
164 SERVER_ERRNO_TO_ERROR[ERRNO_REQUEST_BODY_TOO_LARGE] = ERROR_REQUEST_BODY_TOO_LARGE; |
|
165 SERVER_ERRNO_TO_ERROR[ERRNO_TOO_MANY_CLIENT_REQUESTS] = ERROR_TOO_MANY_CLIENT_REQUESTS; |
|
166 SERVER_ERRNO_TO_ERROR[ERRNO_INVALID_AUTH_NONCE] = ERROR_INVALID_AUTH_NONCE; |
|
167 SERVER_ERRNO_TO_ERROR[ERRNO_ENDPOINT_NO_LONGER_SUPPORTED] = ERROR_ENDPOINT_NO_LONGER_SUPPORTED; |
|
168 SERVER_ERRNO_TO_ERROR[ERRNO_INCORRECT_LOGIN_METHOD] = ERROR_INCORRECT_LOGIN_METHOD; |
|
169 SERVER_ERRNO_TO_ERROR[ERRNO_INCORRECT_KEY_RETRIEVAL_METHOD] = ERROR_INCORRECT_KEY_RETRIEVAL_METHOD; |
|
170 SERVER_ERRNO_TO_ERROR[ERRNO_INCORRECT_API_VERSION] = ERROR_INCORRECT_API_VERSION; |
|
171 SERVER_ERRNO_TO_ERROR[ERRNO_INCORRECT_EMAIL_CASE] = ERROR_INCORRECT_EMAIL_CASE; |
|
172 SERVER_ERRNO_TO_ERROR[ERRNO_SERVICE_TEMP_UNAVAILABLE] = ERROR_SERVICE_TEMP_UNAVAILABLE; |
|
173 SERVER_ERRNO_TO_ERROR[ERRNO_UNKNOWN_ERROR] = ERROR_UNKNOWN; |
|
174 |
|
175 // Allow this file to be imported via Components.utils.import(). |
|
176 this.EXPORTED_SYMBOLS = Object.keys(this); |