expensify-common 2.0.188 → 2.0.190
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Logger.js +11 -1
- package/dist/esm/API.d.ts +11 -0
- package/dist/esm/API.js +786 -0
- package/dist/esm/APIDeferred.d.ts +7 -0
- package/dist/esm/APIDeferred.js +216 -0
- package/dist/esm/BrowserDetect.d.ts +19 -0
- package/dist/esm/BrowserDetect.js +105 -0
- package/dist/esm/CLI.js +37 -29
- package/dist/esm/CONST.d.ts +1727 -0
- package/dist/esm/CONST.js +1847 -0
- package/dist/esm/Cookie.d.ts +68 -0
- package/dist/esm/Cookie.js +159 -0
- package/dist/esm/CredentialsWrapper.d.ts +32 -0
- package/dist/esm/CredentialsWrapper.js +46 -0
- package/dist/esm/Device.d.ts +8 -0
- package/dist/esm/Device.js +24 -0
- package/dist/esm/ExpenseRule.d.ts +39 -0
- package/dist/esm/ExpenseRule.js +77 -0
- package/dist/esm/ExpensiMark.d.ts +197 -0
- package/dist/esm/ExpensiMark.js +1374 -0
- package/dist/esm/Func.d.ts +40 -0
- package/dist/esm/Func.js +69 -0
- package/dist/esm/Log.d.ts +3 -0
- package/dist/esm/Log.js +35 -0
- package/dist/esm/Logger.d.ts +82 -0
- package/dist/esm/Logger.js +148 -0
- package/dist/esm/Network.d.ts +6 -0
- package/dist/esm/Network.js +168 -0
- package/dist/esm/Num.d.ts +95 -0
- package/dist/esm/Num.js +190 -0
- package/dist/esm/PageEvent.d.ts +25 -0
- package/dist/esm/PageEvent.js +22 -0
- package/dist/esm/PubSub.d.ts +2 -0
- package/dist/esm/PubSub.js +111 -0
- package/dist/esm/ReportHistoryStore.d.ts +8 -0
- package/dist/esm/ReportHistoryStore.js +199 -0
- package/dist/esm/SafeString.js +2 -2
- package/dist/esm/Templates.d.ts +58 -0
- package/dist/esm/Templates.js +196 -0
- package/dist/esm/Url.d.ts +10 -0
- package/dist/esm/Url.js +15 -0
- package/dist/esm/components/CopyText.d.ts +45 -0
- package/dist/esm/components/CopyText.js +56 -0
- package/dist/esm/components/StepProgressBar.d.ts +26 -0
- package/dist/esm/components/StepProgressBar.js +40 -0
- package/dist/esm/components/form/element/combobox.d.ts +231 -0
- package/dist/esm/components/form/element/combobox.js +812 -0
- package/dist/esm/components/form/element/dropdown.d.ts +35 -0
- package/dist/esm/components/form/element/dropdown.js +61 -0
- package/dist/esm/components/form/element/dropdownItem.d.ts +55 -0
- package/dist/esm/components/form/element/dropdownItem.js +113 -0
- package/dist/esm/components/form/element/onOffSwitch.d.ts +94 -0
- package/dist/esm/components/form/element/onOffSwitch.js +167 -0
- package/dist/esm/components/form/element/switch.d.ts +58 -0
- package/dist/esm/components/form/element/switch.js +98 -0
- package/dist/esm/fastMerge.d.ts +9 -0
- package/dist/esm/fastMerge.js +58 -0
- package/dist/esm/index.d.ts +22 -0
- package/dist/esm/index.js +22 -0
- package/dist/esm/jquery.expensifyIframify.d.ts +9 -0
- package/dist/esm/jquery.expensifyIframify.js +397 -0
- package/dist/esm/md5.d.ts +2 -0
- package/dist/esm/md5.js +170 -0
- package/dist/esm/mixins/PubSub.d.ts +20 -0
- package/dist/esm/mixins/PubSub.js +47 -0
- package/dist/esm/mixins/extraClasses.d.ts +8 -0
- package/dist/esm/mixins/extraClasses.js +37 -0
- package/dist/esm/mixins/validationClasses.d.ts +12 -0
- package/dist/esm/mixins/validationClasses.js +30 -0
- package/dist/esm/str.d.ts +604 -0
- package/dist/esm/str.js +1036 -0
- package/dist/esm/tlds.d.ts +2 -0
- package/dist/esm/tlds.js +2 -0
- package/dist/esm/utils.d.ts +30 -0
- package/dist/esm/utils.js +65 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +8 -1
- package/package.json +221 -4
package/dist/esm/API.js
ADDED
|
@@ -0,0 +1,786 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ----------------------------------------------------------------------------------------------
|
|
3
|
+
* WIP, This is in the process of migration from web-e. Please add methods to this as is needed.|
|
|
4
|
+
* ----------------------------------------------------------------------------------------------
|
|
5
|
+
*/
|
|
6
|
+
// Use this deferred lib so we don't have a dependency on jQuery (so we can use this module in mobile)
|
|
7
|
+
import { Deferred } from 'simply-deferred';
|
|
8
|
+
import has from 'lodash/has';
|
|
9
|
+
import ExpensifyAPIDeferred from './APIDeferred';
|
|
10
|
+
import * as Utils from './utils';
|
|
11
|
+
/**
|
|
12
|
+
* @param {Network} network
|
|
13
|
+
* @param {Object} [args]
|
|
14
|
+
* @param {Function} [args.enhanceParameters] A function that takes the existing command parameters and returns a
|
|
15
|
+
* modified version of them (for things like adding CSRF tokens)
|
|
16
|
+
*
|
|
17
|
+
* @returns {Object}
|
|
18
|
+
*/
|
|
19
|
+
export default function API(network, args) {
|
|
20
|
+
/**
|
|
21
|
+
* @private
|
|
22
|
+
*
|
|
23
|
+
* Maps jsonCode => array of callback functions
|
|
24
|
+
*/
|
|
25
|
+
const defaultHandlers = {};
|
|
26
|
+
/**
|
|
27
|
+
* This allows us to track when the version of JS has changed on the server and then let programs treat the
|
|
28
|
+
* situation appropriately.
|
|
29
|
+
*/
|
|
30
|
+
let codeVersionChanged = false;
|
|
31
|
+
if (!network) {
|
|
32
|
+
throw new Error('Cannot instantiate API without a Network object');
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Returns a promise that is rejected if a change is detected
|
|
36
|
+
* Otherwise, it is resolved successfully
|
|
37
|
+
*
|
|
38
|
+
* @returns {Object} Deferred
|
|
39
|
+
*/
|
|
40
|
+
function isRunningLatestVersionOfCode() {
|
|
41
|
+
const promise = new Deferred();
|
|
42
|
+
network
|
|
43
|
+
.get('/revision.txt')
|
|
44
|
+
.done((codeRevision) => {
|
|
45
|
+
if (Utils.isWindowAvailable() && codeRevision.trim() === window.CODE_REVISION) {
|
|
46
|
+
console.debug('Code revision is up to date');
|
|
47
|
+
promise.resolve();
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
console.debug('Code revision change detected');
|
|
51
|
+
codeVersionChanged = true;
|
|
52
|
+
promise.resolve();
|
|
53
|
+
}
|
|
54
|
+
})
|
|
55
|
+
.fail(() => {
|
|
56
|
+
// If we can't read the code revision, we will assume it hasn't changed
|
|
57
|
+
console.debug('Code revision cannot be read at this time');
|
|
58
|
+
promise.resolve();
|
|
59
|
+
});
|
|
60
|
+
return promise;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* @private
|
|
64
|
+
*
|
|
65
|
+
* Attaches the callbacks to the promise for each JSON code
|
|
66
|
+
*
|
|
67
|
+
* @param {String} apiDeferred
|
|
68
|
+
*/
|
|
69
|
+
function attachJSONCodeCallbacks(apiDeferred) {
|
|
70
|
+
for (const [code, callbacks] of Object.entries(defaultHandlers)) {
|
|
71
|
+
// The key, `code`, is returned as a string, so we must cast it to an Integer
|
|
72
|
+
const jsonCode = parseInt(code, 10);
|
|
73
|
+
for (const callback of callbacks) {
|
|
74
|
+
if (jsonCode === 200) {
|
|
75
|
+
apiDeferred.done(callback);
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
apiDeferred.handle([jsonCode], callback);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* @private
|
|
85
|
+
*
|
|
86
|
+
* @param {String} command Name of the command to run
|
|
87
|
+
* @param {Object} [parameters] A map of parameter names to their values
|
|
88
|
+
* @param {String} [returnedPropertyName] The value of the property that you want to return if you don't want to
|
|
89
|
+
* return the whole response JSON
|
|
90
|
+
* @param {Boolean} [keepalive] Whether or not the request should be kept alive if the browser is closed in the
|
|
91
|
+
* middle of the request
|
|
92
|
+
* @param {Boolean} [checkCodeRevision] Whether or not the code revision should be validated
|
|
93
|
+
*
|
|
94
|
+
* @returns {APIDeferred} An APIDeferred representing the promise of this request
|
|
95
|
+
*/
|
|
96
|
+
function performPOSTRequest(command, parameters, returnedPropertyName, keepalive, checkCodeRevision) {
|
|
97
|
+
let newParameters = Object.assign(Object.assign({}, parameters), { command });
|
|
98
|
+
// If there was an enhanceParameters() method supplied in our args, then we will call that here
|
|
99
|
+
if (args && Utils.isFunction(args.enhanceParameters)) {
|
|
100
|
+
newParameters = args.enhanceParameters(newParameters);
|
|
101
|
+
}
|
|
102
|
+
// We need to setup multiple promises here depending on our arguments. If there is no argument, then we will just
|
|
103
|
+
// use an immediately resolved promise for sake of code readability (ie. the promise will always exist and code
|
|
104
|
+
// will be treated the same way regardless of the arguments).
|
|
105
|
+
// This promise is to check to see if we are running the latest version of code
|
|
106
|
+
const codeRevisionPromise = checkCodeRevision ? isRunningLatestVersionOfCode : () => new Deferred().resolve();
|
|
107
|
+
// This is a dummy promise that will perform the actions from our network POST. We have to create it here
|
|
108
|
+
// because we need the final APIDeferred object to return immediately, and then have all this async code run.
|
|
109
|
+
const networkRequestPromise = new Deferred();
|
|
110
|
+
// This is the final APIDeferred which gets returned from the API lib.
|
|
111
|
+
const finalApiDeferred = new ExpensifyAPIDeferred(networkRequestPromise, returnedPropertyName);
|
|
112
|
+
// Check that our code is running the latest version
|
|
113
|
+
codeRevisionPromise().done(() => {
|
|
114
|
+
// We are done checking the code version, so now we can make our network request. We then use our
|
|
115
|
+
// dummy promise here in done() and fail() because that was the promise attached to our APIDeferred.
|
|
116
|
+
if (keepalive) {
|
|
117
|
+
network.keepalive(newParameters).done(networkRequestPromise.resolve).fail(networkRequestPromise.reject);
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
network.post(newParameters).done(networkRequestPromise.resolve).fail(networkRequestPromise.reject);
|
|
121
|
+
}
|
|
122
|
+
// Finally, we can attach any JSONCode callbacks to our APIDeferred because we know that at this point
|
|
123
|
+
// we're making a real network request.
|
|
124
|
+
attachJSONCodeCallbacks(finalApiDeferred);
|
|
125
|
+
});
|
|
126
|
+
return finalApiDeferred;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* @throws {Error} If the "parameters" object has a null or undefined value for any of the given parameterNames
|
|
130
|
+
*
|
|
131
|
+
* @private
|
|
132
|
+
*
|
|
133
|
+
* @param {String[]} parameterNames Array of the required parameter names
|
|
134
|
+
* @param {Object} parameters A map from available parameter names to their values
|
|
135
|
+
* @param {String} commandName The name of the API command
|
|
136
|
+
*/
|
|
137
|
+
function requireParameters(parameterNames, parameters, commandName) {
|
|
138
|
+
for (const parameterName of parameterNames) {
|
|
139
|
+
if (has(parameters, parameterName) && parameters[parameterName] !== null && parameters[parameterName] !== undefined) {
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
const parametersCopy = Object.assign({}, parameters);
|
|
143
|
+
if (has(parametersCopy, 'authToken')) {
|
|
144
|
+
parametersCopy.authToken = '<redacted>';
|
|
145
|
+
}
|
|
146
|
+
if (has(parametersCopy, 'password')) {
|
|
147
|
+
parametersCopy.password = '<redacted>';
|
|
148
|
+
}
|
|
149
|
+
const keys = Object.keys(parametersCopy).join(', ') || 'none';
|
|
150
|
+
throw new Error(`Parameter ${parameterName} is required for "${commandName}". Supplied parameters: ${keys}`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return {
|
|
154
|
+
/**
|
|
155
|
+
* @param {Number[]} jsonCodes
|
|
156
|
+
* @param {Function} callback
|
|
157
|
+
*/
|
|
158
|
+
registerDefaultHandler(jsonCodes, callback) {
|
|
159
|
+
if (!Utils.isFunction(callback)) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
for (const jsonCode of jsonCodes) {
|
|
163
|
+
if (!defaultHandlers[jsonCode]) {
|
|
164
|
+
defaultHandlers[jsonCode] = [];
|
|
165
|
+
}
|
|
166
|
+
defaultHandlers[jsonCode].push(callback);
|
|
167
|
+
}
|
|
168
|
+
},
|
|
169
|
+
/**
|
|
170
|
+
* Whether or not the JS code version has changed on the server compared to what was loaded on the page.
|
|
171
|
+
*
|
|
172
|
+
* @returns {Boolean}
|
|
173
|
+
*/
|
|
174
|
+
hasChangedCodeVersion() {
|
|
175
|
+
return codeVersionChanged;
|
|
176
|
+
},
|
|
177
|
+
/**
|
|
178
|
+
* Forces an update of the stored latest code version without firing off an additional POST request
|
|
179
|
+
*
|
|
180
|
+
* @returns {exports.Deferred}
|
|
181
|
+
*/
|
|
182
|
+
updateCodeVersion() {
|
|
183
|
+
return isRunningLatestVersionOfCode();
|
|
184
|
+
},
|
|
185
|
+
/**
|
|
186
|
+
* Used to extend an API instance with new methods.
|
|
187
|
+
*
|
|
188
|
+
* @example
|
|
189
|
+
*
|
|
190
|
+
* conciergeAPI.chatbot.getNew = (parameters) => conciergeAPI.extendMethod({
|
|
191
|
+
* commandName: 'ChatBot_Escalate_GetNextChat',
|
|
192
|
+
* requireParameters: ['queueList'],
|
|
193
|
+
* checkCodeRevision: true,
|
|
194
|
+
* })(parameters);
|
|
195
|
+
*
|
|
196
|
+
* @param {Object} data
|
|
197
|
+
* @param {String} data.commandName
|
|
198
|
+
* @param {Function} [data.validate]
|
|
199
|
+
* @param {String[]} [data.requireParameters]
|
|
200
|
+
* @param {String} [data.returnedPropertyType]
|
|
201
|
+
* @param {Boolean} [data.checkCodeRevision]
|
|
202
|
+
*
|
|
203
|
+
* @returns {Function}
|
|
204
|
+
*/
|
|
205
|
+
extendMethod: (data) => {
|
|
206
|
+
if (!data.commandName) {
|
|
207
|
+
throw new Error('Must pass commandName to API.extendMethod');
|
|
208
|
+
}
|
|
209
|
+
return (parameters, keepalive = false) => {
|
|
210
|
+
// Optional validate function for required logic before making the call. e.g. validating params in the front-end etc.
|
|
211
|
+
if (Utils.isFunction(data.validate)) {
|
|
212
|
+
data.validate(parameters);
|
|
213
|
+
}
|
|
214
|
+
requireParameters(data.requireParameters || [], parameters, data.commandName);
|
|
215
|
+
return performPOSTRequest(data.commandName, parameters, data.returnedPropertyName || false, keepalive, data.checkCodeRevision || false);
|
|
216
|
+
};
|
|
217
|
+
},
|
|
218
|
+
/**
|
|
219
|
+
* @returns {Network}
|
|
220
|
+
*/
|
|
221
|
+
getNetwork() {
|
|
222
|
+
return network;
|
|
223
|
+
},
|
|
224
|
+
/**
|
|
225
|
+
* @param {Object} parameters
|
|
226
|
+
* @returns {ExpensifyAPIDeferred}
|
|
227
|
+
*/
|
|
228
|
+
logToServer(parameters) {
|
|
229
|
+
const commandName = 'Log';
|
|
230
|
+
return performPOSTRequest(commandName, parameters);
|
|
231
|
+
},
|
|
232
|
+
/**
|
|
233
|
+
* @param {Object} parameters
|
|
234
|
+
* @param {String} parameters.email
|
|
235
|
+
* @returns {ExpensifyAPIDeferred}
|
|
236
|
+
*/
|
|
237
|
+
getAccountStatus(parameters) {
|
|
238
|
+
const commandName = 'GetAccountStatus';
|
|
239
|
+
requireParameters(['email'], parameters, commandName);
|
|
240
|
+
// Tell the API not to set cookies for this request
|
|
241
|
+
const newParameters = Object.assign(Object.assign({}, parameters), { api_setCookie: false });
|
|
242
|
+
return performPOSTRequest(commandName, newParameters);
|
|
243
|
+
},
|
|
244
|
+
/**
|
|
245
|
+
* @param {Object} parameters
|
|
246
|
+
* @param {String} parameters.email
|
|
247
|
+
* @returns {ExpensifyAPIDeferred}
|
|
248
|
+
*/
|
|
249
|
+
Domain_RequestAccess(parameters) {
|
|
250
|
+
const commandName = 'Domain_RequestAccess';
|
|
251
|
+
requireParameters(['email'], parameters, commandName);
|
|
252
|
+
return performPOSTRequest(commandName, parameters);
|
|
253
|
+
},
|
|
254
|
+
/**
|
|
255
|
+
* @param {Object} parameters
|
|
256
|
+
* @param {String[]} parameters.emailList
|
|
257
|
+
*
|
|
258
|
+
* @returns {ExpensifyAPIDeferred}
|
|
259
|
+
*/
|
|
260
|
+
personalDetails_GetForEmails(parameters) {
|
|
261
|
+
const commandName = 'PersonalDetails_GetForEmails';
|
|
262
|
+
requireParameters(['emailList'], parameters, commandName);
|
|
263
|
+
return performPOSTRequest(commandName, parameters);
|
|
264
|
+
},
|
|
265
|
+
/**
|
|
266
|
+
* @param {Object} parameters
|
|
267
|
+
* @param {String[]} parameters.emailList
|
|
268
|
+
*
|
|
269
|
+
* @returns {ExpensifyAPIDeferred}
|
|
270
|
+
*/
|
|
271
|
+
getKnownPersonalDetailsForEmails(parameters) {
|
|
272
|
+
const commandName = 'GetKnownPersonalDetailsForEmails';
|
|
273
|
+
requireParameters(['emailList'], parameters, commandName);
|
|
274
|
+
return performPOSTRequest(commandName, parameters);
|
|
275
|
+
},
|
|
276
|
+
/**
|
|
277
|
+
* @param {Object} parameters
|
|
278
|
+
* @param {String[]} parameters.emailList
|
|
279
|
+
*
|
|
280
|
+
* @returns {ExpensifyAPIDeferred}
|
|
281
|
+
*/
|
|
282
|
+
getAvatarsForEmail(parameters) {
|
|
283
|
+
const commandName = 'GetAvatarsForEmail';
|
|
284
|
+
requireParameters(['emailList'], parameters, commandName);
|
|
285
|
+
return performPOSTRequest(commandName, parameters);
|
|
286
|
+
},
|
|
287
|
+
/**
|
|
288
|
+
* Performs API command "Get"
|
|
289
|
+
*
|
|
290
|
+
* @param {Object} parameters The API call parameters, must contain "returnValueList". May also include "domain" and "domainMember".
|
|
291
|
+
*
|
|
292
|
+
* @returns {APIDeferred} An APIDeferred representing the promise of this request
|
|
293
|
+
*/
|
|
294
|
+
get(parameters) {
|
|
295
|
+
const commandName = 'Get';
|
|
296
|
+
requireParameters(['returnValueList'], parameters, commandName);
|
|
297
|
+
return performPOSTRequest(commandName, parameters);
|
|
298
|
+
},
|
|
299
|
+
/**
|
|
300
|
+
* @param {Object} parameters
|
|
301
|
+
* @param {String} parameters.email
|
|
302
|
+
* @param {String} [parameters.password]
|
|
303
|
+
* @param {String} [parameters.promoCode]
|
|
304
|
+
* @param {String} [parameters.validateCode]
|
|
305
|
+
* @returns {APIDeferred}
|
|
306
|
+
*/
|
|
307
|
+
signIn(parameters) {
|
|
308
|
+
const commandName = 'SignIn';
|
|
309
|
+
requireParameters(['email'], parameters, commandName);
|
|
310
|
+
return performPOSTRequest(commandName, parameters);
|
|
311
|
+
},
|
|
312
|
+
/**
|
|
313
|
+
* Perform API command 'SignOut'
|
|
314
|
+
*
|
|
315
|
+
* @param {Object} [parameters]
|
|
316
|
+
* @param {Boolean} [parameters.clean] clear the 'email' cookie
|
|
317
|
+
* @returns {APIDeferred} An APIDeferred representing the promise of this request
|
|
318
|
+
*/
|
|
319
|
+
signOut(parameters) {
|
|
320
|
+
return performPOSTRequest('SignOut', parameters);
|
|
321
|
+
},
|
|
322
|
+
/**
|
|
323
|
+
* @param {Object} parameters
|
|
324
|
+
* @param {String} parameters.email
|
|
325
|
+
* @param {String} parameters.token
|
|
326
|
+
* @param {String} [parameters.promoCode]
|
|
327
|
+
* @returns {APIDeferred}
|
|
328
|
+
*/
|
|
329
|
+
signInGoogle(parameters) {
|
|
330
|
+
const commandName = 'SignInGoogle';
|
|
331
|
+
requireParameters(['email', 'token'], parameters, commandName);
|
|
332
|
+
return performPOSTRequest(commandName, parameters);
|
|
333
|
+
},
|
|
334
|
+
/**
|
|
335
|
+
* @param {Object} parameters Must contain email, May contain:
|
|
336
|
+
* @param {String} parameters.email
|
|
337
|
+
* @param {String} [parameters.initialReferer]
|
|
338
|
+
* @param {Number} [parameters.inviterID]
|
|
339
|
+
* @param {String} [parameters.landingPage]
|
|
340
|
+
* @param {String} [parameters.promoCode]
|
|
341
|
+
*
|
|
342
|
+
* @returns {APIDeferred}
|
|
343
|
+
*/
|
|
344
|
+
signUp(parameters) {
|
|
345
|
+
const commandName = 'User_SignUp';
|
|
346
|
+
requireParameters(['email'], parameters, commandName);
|
|
347
|
+
return performPOSTRequest(commandName, parameters);
|
|
348
|
+
},
|
|
349
|
+
/**
|
|
350
|
+
* Resends the validate code.
|
|
351
|
+
*
|
|
352
|
+
* @param {Object} parameters
|
|
353
|
+
* @param {String} [parameters.email]
|
|
354
|
+
*
|
|
355
|
+
* @returns {ExpensifyAPIDeferred}
|
|
356
|
+
*/
|
|
357
|
+
resendValidateCode(parameters = {}) {
|
|
358
|
+
const commandName = 'ResendValidateCode';
|
|
359
|
+
return performPOSTRequest(commandName, Object.assign(Object.assign({}, parameters), { api_setCookie: false }));
|
|
360
|
+
},
|
|
361
|
+
/**
|
|
362
|
+
* Reopen a closed account.
|
|
363
|
+
*
|
|
364
|
+
* @param {Object} parameters
|
|
365
|
+
* @param {String} parameters.email
|
|
366
|
+
*
|
|
367
|
+
* @returns {ExpensifyAPIDeferred}
|
|
368
|
+
*/
|
|
369
|
+
reopenAccount(parameters) {
|
|
370
|
+
const commandName = 'User_ReopenAccount';
|
|
371
|
+
requireParameters(['email'], parameters, commandName);
|
|
372
|
+
return performPOSTRequest(commandName, parameters);
|
|
373
|
+
},
|
|
374
|
+
/**
|
|
375
|
+
* Resets the password for an account
|
|
376
|
+
* @param {Object} parameters
|
|
377
|
+
* @param {String} parameters.email
|
|
378
|
+
* @returns {ExpensifyAPIDeferred}
|
|
379
|
+
*/
|
|
380
|
+
resetPassword(parameters) {
|
|
381
|
+
const commandName = 'ResetPassword';
|
|
382
|
+
requireParameters(['email'], parameters, commandName);
|
|
383
|
+
const newParameters = Object.assign(Object.assign({}, parameters), { api_setCookie: false });
|
|
384
|
+
return performPOSTRequest(commandName, newParameters);
|
|
385
|
+
},
|
|
386
|
+
/**
|
|
387
|
+
* Sets the password for an account
|
|
388
|
+
*
|
|
389
|
+
* @param {Object} parameters
|
|
390
|
+
* @param {String} parameters.email
|
|
391
|
+
* @param {String} parameters.password
|
|
392
|
+
* @param {String} parameters.validateCode
|
|
393
|
+
* @returns {ExpensifyAPIDeferred}
|
|
394
|
+
*/
|
|
395
|
+
setPassword(parameters) {
|
|
396
|
+
const commandName = 'SetPassword';
|
|
397
|
+
requireParameters(['email', 'password', 'validateCode'], parameters, commandName);
|
|
398
|
+
return performPOSTRequest(commandName, parameters);
|
|
399
|
+
},
|
|
400
|
+
/**
|
|
401
|
+
* Validate a user
|
|
402
|
+
*
|
|
403
|
+
* @param {Object} parameters Must contain validateCode and accountID
|
|
404
|
+
* @returns {ExpensifyAPIDeferred}
|
|
405
|
+
*/
|
|
406
|
+
validateEmail(parameters) {
|
|
407
|
+
const commandName = 'ValidateEmail';
|
|
408
|
+
requireParameters(['validateCode', 'accountID'], parameters, commandName);
|
|
409
|
+
return performPOSTRequest(commandName, parameters);
|
|
410
|
+
},
|
|
411
|
+
/**
|
|
412
|
+
* Retrieves a short lived auth token for transitions to NewDot
|
|
413
|
+
*
|
|
414
|
+
* @returns {APIDeferred}
|
|
415
|
+
*/
|
|
416
|
+
getShortLivedAuthToken() {
|
|
417
|
+
const commandName = 'GetShortLivedAuthToken';
|
|
418
|
+
return performPOSTRequest(commandName);
|
|
419
|
+
},
|
|
420
|
+
/**
|
|
421
|
+
* Sets the value of an NVP
|
|
422
|
+
*
|
|
423
|
+
* @param {Object} parameters
|
|
424
|
+
* @param {String} parameters.name
|
|
425
|
+
* @param {Mixed} parameters.value
|
|
426
|
+
* @returns {APIDeferred}
|
|
427
|
+
*/
|
|
428
|
+
setNameValuePair(parameters) {
|
|
429
|
+
const commandName = 'SetNameValuePair';
|
|
430
|
+
requireParameters(['name', 'value'], parameters, commandName);
|
|
431
|
+
return performPOSTRequest(commandName, parameters);
|
|
432
|
+
},
|
|
433
|
+
/**
|
|
434
|
+
* Send something to be logged into graphite
|
|
435
|
+
*
|
|
436
|
+
* @param {Object} parameters
|
|
437
|
+
* @param {String} parameters.type This can be one of ['timer', 'counter']
|
|
438
|
+
* @param {String} parameters.statName
|
|
439
|
+
* @param {Number} parameters.value
|
|
440
|
+
* @param {Boolean} [keepalive] whether or not the request can complete after the browser is closed
|
|
441
|
+
* @returns {APIDeferred}
|
|
442
|
+
*/
|
|
443
|
+
graphite(parameters, keepalive) {
|
|
444
|
+
const commandName = 'Graphite';
|
|
445
|
+
requireParameters(['type', 'statName', 'value'], parameters, commandName);
|
|
446
|
+
return performPOSTRequest(commandName, parameters, null, keepalive);
|
|
447
|
+
},
|
|
448
|
+
/**
|
|
449
|
+
* Performs API command Report_GetHistory
|
|
450
|
+
* @param {Object} parameters
|
|
451
|
+
* @param {Number} parameters.reportID
|
|
452
|
+
* @param {Number} [parameters.offset] - optional offset (inclusive defaults to 0)
|
|
453
|
+
* @returns {APIDeferred}
|
|
454
|
+
*/
|
|
455
|
+
Report_GetHistory(parameters) {
|
|
456
|
+
const commandName = 'Report_GetHistory';
|
|
457
|
+
requireParameters(['reportID'], parameters, commandName);
|
|
458
|
+
return performPOSTRequest(commandName, parameters, 'history');
|
|
459
|
+
},
|
|
460
|
+
/**
|
|
461
|
+
* Performs API command Report_AddComment
|
|
462
|
+
* @param {Object} parameters The API call parameters. Must contain reportID and reportComment
|
|
463
|
+
* @param {Number} parameters.reportID
|
|
464
|
+
* @param {String} parameters.reportComment
|
|
465
|
+
* @returns {APIDeferred} An APIDeferred representing the promise of this request
|
|
466
|
+
*/
|
|
467
|
+
Report_AddComment(parameters) {
|
|
468
|
+
const commandName = 'Report_AddComment';
|
|
469
|
+
requireParameters(['reportID', 'reportComment'], parameters, commandName);
|
|
470
|
+
return performPOSTRequest(commandName, parameters);
|
|
471
|
+
},
|
|
472
|
+
/**
|
|
473
|
+
* Performs API command GetRequestCountryCode
|
|
474
|
+
* Fetches the country code based on the location of the request
|
|
475
|
+
*
|
|
476
|
+
* @returns {APIDeferred}
|
|
477
|
+
*/
|
|
478
|
+
getRequestCountryCode() {
|
|
479
|
+
const commandName = 'GetRequestCountryCode';
|
|
480
|
+
return performPOSTRequest(commandName, {});
|
|
481
|
+
},
|
|
482
|
+
/**
|
|
483
|
+
* Performs API command Github_Close
|
|
484
|
+
*
|
|
485
|
+
* @param {Object} parameters
|
|
486
|
+
* @param {String} parameters.githubLink
|
|
487
|
+
* @param {Boolean} [parameters.reopen] True by default. If false, we will not reopen the Concierge chats linked in the Github
|
|
488
|
+
*
|
|
489
|
+
* @returns {APIDeferred}
|
|
490
|
+
*/
|
|
491
|
+
githubClose(parameters) {
|
|
492
|
+
const commandName = 'Github_Close';
|
|
493
|
+
requireParameters(['githubLink'], parameters, commandName);
|
|
494
|
+
return performPOSTRequest(commandName, parameters);
|
|
495
|
+
},
|
|
496
|
+
/**
|
|
497
|
+
* Performs API command Expense_Create
|
|
498
|
+
*
|
|
499
|
+
* @param {Object} parameters
|
|
500
|
+
* @param {Number} parameters.chatID
|
|
501
|
+
* @param {String} parameters.file
|
|
502
|
+
*
|
|
503
|
+
* @returns {APIDeferred}
|
|
504
|
+
*/
|
|
505
|
+
forwardTravelDocument(parameters) {
|
|
506
|
+
const commandName = 'ForwardTravelDocument';
|
|
507
|
+
requireParameters(['chatID', 'file'], parameters, commandName);
|
|
508
|
+
return performPOSTRequest(commandName, parameters);
|
|
509
|
+
},
|
|
510
|
+
/**
|
|
511
|
+
* Performs API command Expense_Create
|
|
512
|
+
*
|
|
513
|
+
* @param {Object} parameters API parameters. Must contain 'transactionList'
|
|
514
|
+
*
|
|
515
|
+
* @returns {APIDeferred}
|
|
516
|
+
*/
|
|
517
|
+
Expense_Create(parameters) {
|
|
518
|
+
const commandName = 'Expense_Create';
|
|
519
|
+
requireParameters(['transactionList'], parameters, commandName);
|
|
520
|
+
return performPOSTRequest(commandName, parameters);
|
|
521
|
+
},
|
|
522
|
+
/**
|
|
523
|
+
* Performs API command Domain_AddNote
|
|
524
|
+
*
|
|
525
|
+
* @param {Object} parameters
|
|
526
|
+
* @param {String} parameters.note-html
|
|
527
|
+
* @param {String} parameters.targetEmail
|
|
528
|
+
* @param {String} [parameters.domainName]
|
|
529
|
+
*
|
|
530
|
+
* @returns {APIDeferred}
|
|
531
|
+
*/
|
|
532
|
+
Domain_Add_Note(parameters) {
|
|
533
|
+
const commandName = 'Domain_AddNote';
|
|
534
|
+
requireParameters(['note-html', 'targetEmail'], parameters, commandName);
|
|
535
|
+
return performPOSTRequest(commandName, parameters);
|
|
536
|
+
},
|
|
537
|
+
/**
|
|
538
|
+
* Performs API command Domain_DeleteNote
|
|
539
|
+
*
|
|
540
|
+
* @param {Object} parameters
|
|
541
|
+
* @param {String} parameters.note-html
|
|
542
|
+
* @param {String} [parameters.domainName]
|
|
543
|
+
*
|
|
544
|
+
* @returns {APIDeferred}
|
|
545
|
+
*/
|
|
546
|
+
Domain_Delete_Note(parameters) {
|
|
547
|
+
const commandName = 'Domain_DeleteNote';
|
|
548
|
+
requireParameters(['note-html'], parameters, commandName);
|
|
549
|
+
return performPOSTRequest(commandName, parameters);
|
|
550
|
+
},
|
|
551
|
+
/**
|
|
552
|
+
* Performs API command CreateLogin
|
|
553
|
+
* This method gets called to add a new login method to the Logins table
|
|
554
|
+
*
|
|
555
|
+
* @param {Object} parameters
|
|
556
|
+
* @param {String} parameters.partnerName
|
|
557
|
+
* @param {String} parameters.partnerPassword
|
|
558
|
+
* @param {String} parameters.partnerUserID
|
|
559
|
+
* @param {String} parameters.partnerUserSecret
|
|
560
|
+
*
|
|
561
|
+
* @returns {APIDeferred}
|
|
562
|
+
*/
|
|
563
|
+
createLogin(parameters) {
|
|
564
|
+
const commandName = 'CreateLogin';
|
|
565
|
+
requireParameters(['partnerName', 'partnerPassword', 'partnerUserID', 'partnerUserSecret'], parameters, commandName);
|
|
566
|
+
return performPOSTRequest(commandName, parameters);
|
|
567
|
+
},
|
|
568
|
+
/**
|
|
569
|
+
* Performs API command Authenticate
|
|
570
|
+
* This method gets called when existing token are expired
|
|
571
|
+
* which helps in having an infinite session
|
|
572
|
+
*
|
|
573
|
+
* @param {Object} parameters
|
|
574
|
+
* @param {String} parameters.partnerName
|
|
575
|
+
* @param {String} parameters.partnerPassword
|
|
576
|
+
* @param {String} parameters.partnerUserID
|
|
577
|
+
* @param {String} parameters.partnerUserSecret
|
|
578
|
+
*
|
|
579
|
+
* @returns {APIDeferred}
|
|
580
|
+
*/
|
|
581
|
+
authenticate(parameters) {
|
|
582
|
+
const commandName = 'Authenticate';
|
|
583
|
+
requireParameters(['partnerName', 'partnerPassword', 'partnerUserID', 'partnerUserSecret'], parameters, commandName);
|
|
584
|
+
return performPOSTRequest(commandName, parameters);
|
|
585
|
+
},
|
|
586
|
+
expensiworks: {
|
|
587
|
+
/**
|
|
588
|
+
* Get the logged in agent's accuracy fields
|
|
589
|
+
*
|
|
590
|
+
* @returns {APIDeferred}
|
|
591
|
+
*/
|
|
592
|
+
getAgentAccuracy() {
|
|
593
|
+
const commandName = 'Expensiworks_GetAgentAccuracy';
|
|
594
|
+
return performPOSTRequest(commandName);
|
|
595
|
+
},
|
|
596
|
+
/**
|
|
597
|
+
* Get a job to work on
|
|
598
|
+
*
|
|
599
|
+
* @param {Object} parameters
|
|
600
|
+
* @param {String} [parameters.jobName] optional the name of a job to get (used for debugging)
|
|
601
|
+
* @param {Boolean} [parameters.prefetching] Lets the server know that this is a prefetch request
|
|
602
|
+
*
|
|
603
|
+
* @returns {APIDeferred}
|
|
604
|
+
*/
|
|
605
|
+
getJob(parameters) {
|
|
606
|
+
const commandName = 'Expensiworks_GetJob';
|
|
607
|
+
return performPOSTRequest(commandName, parameters, null, null, true);
|
|
608
|
+
},
|
|
609
|
+
/**
|
|
610
|
+
* Submit a job for processing
|
|
611
|
+
*
|
|
612
|
+
* @param {Object} parameters
|
|
613
|
+
* @param {Number} parameters.jobID
|
|
614
|
+
* @param {String} parameters.answers
|
|
615
|
+
* @param {String} parameters.startedAt
|
|
616
|
+
*
|
|
617
|
+
* @returns {APIDeferred}
|
|
618
|
+
*/
|
|
619
|
+
processJob(parameters) {
|
|
620
|
+
const commandName = 'Expensiworks_ProcessJob';
|
|
621
|
+
requireParameters(['jobID', 'jobName', 'answers', 'duration'], parameters, commandName);
|
|
622
|
+
return performPOSTRequest(commandName, parameters);
|
|
623
|
+
},
|
|
624
|
+
/**
|
|
625
|
+
* Reject and return a job that needs to be retried by someone else
|
|
626
|
+
*
|
|
627
|
+
* @param {Object} parameters
|
|
628
|
+
* @param {Number} parameters.jobID
|
|
629
|
+
* @param {Array} parameters.jobData
|
|
630
|
+
* @param {Number} parameters.startedAt
|
|
631
|
+
* @param {Boolean} [keepalive] Whether or not the request can complete after the page is closed
|
|
632
|
+
*
|
|
633
|
+
* @returns {APIDeferred}
|
|
634
|
+
*/
|
|
635
|
+
returnJob(parameters, keepalive) {
|
|
636
|
+
const commandName = 'Expensiworks_ReturnJob';
|
|
637
|
+
requireParameters(['jobID', 'jobData', 'startedAt'], parameters, commandName);
|
|
638
|
+
return performPOSTRequest(commandName, parameters, null, keepalive);
|
|
639
|
+
},
|
|
640
|
+
},
|
|
641
|
+
ssdos: {
|
|
642
|
+
/**
|
|
643
|
+
* Get the currency list for SSDos
|
|
644
|
+
*
|
|
645
|
+
* @returns {APIDeferred}
|
|
646
|
+
*/
|
|
647
|
+
getCurrencyList() {
|
|
648
|
+
const commandName = 'SSDos_GetCurrencyList';
|
|
649
|
+
return performPOSTRequest(commandName);
|
|
650
|
+
},
|
|
651
|
+
},
|
|
652
|
+
user: {
|
|
653
|
+
/**
|
|
654
|
+
* Get the travel details for a
|
|
655
|
+
*
|
|
656
|
+
* @param {Object} parameters
|
|
657
|
+
* @param {String} parameters.chatID
|
|
658
|
+
* @param {String} [parameters.password] only needed if we don't have it stored in the cookie
|
|
659
|
+
*
|
|
660
|
+
* @returns {APIDeferred}
|
|
661
|
+
*/
|
|
662
|
+
getUserTravelDetails(parameters) {
|
|
663
|
+
const commandName = 'GetTravelDetails';
|
|
664
|
+
requireParameters(['chatID'], parameters, commandName);
|
|
665
|
+
return performPOSTRequest(commandName, parameters);
|
|
666
|
+
},
|
|
667
|
+
/**
|
|
668
|
+
* Save the travel details for a user
|
|
669
|
+
*
|
|
670
|
+
* @param {Object} parameters
|
|
671
|
+
* @param {String} parameters.chatID
|
|
672
|
+
* @param {String} parameters.details
|
|
673
|
+
*
|
|
674
|
+
* @returns {APIDeferred}
|
|
675
|
+
*/
|
|
676
|
+
setUserTravelDetails(parameters) {
|
|
677
|
+
const commandName = 'SetTravelDetails';
|
|
678
|
+
requireParameters(['chatID', 'details'], parameters, commandName);
|
|
679
|
+
return performPOSTRequest(commandName, parameters);
|
|
680
|
+
},
|
|
681
|
+
/**
|
|
682
|
+
* Get the lounge details for a user
|
|
683
|
+
*
|
|
684
|
+
* @param {Object} parameters
|
|
685
|
+
* @param {String} parameters.chatID
|
|
686
|
+
*
|
|
687
|
+
* @returns {APIDeferred}
|
|
688
|
+
*/
|
|
689
|
+
getUserLoungeDetails(parameters) {
|
|
690
|
+
const commandName = 'GetLoungeDetails';
|
|
691
|
+
requireParameters(['chatID'], parameters, commandName);
|
|
692
|
+
return performPOSTRequest(commandName, parameters);
|
|
693
|
+
},
|
|
694
|
+
/**
|
|
695
|
+
* Set the lounge details for a user
|
|
696
|
+
*
|
|
697
|
+
* @param {Object} parameters
|
|
698
|
+
* @param {String} parameters.chatID
|
|
699
|
+
* @param {String} parameters.details
|
|
700
|
+
*
|
|
701
|
+
* @returns {APIDeferred}
|
|
702
|
+
*/
|
|
703
|
+
setUserLoungeDetails(parameters) {
|
|
704
|
+
const commandName = 'SetLoungeDetails';
|
|
705
|
+
requireParameters(['chatID', 'details'], parameters, commandName);
|
|
706
|
+
return performPOSTRequest(commandName, parameters);
|
|
707
|
+
},
|
|
708
|
+
/**
|
|
709
|
+
* Checks if the domain is public
|
|
710
|
+
*
|
|
711
|
+
* @param {Object} parameters
|
|
712
|
+
* @param {String} parameters.email
|
|
713
|
+
*
|
|
714
|
+
* @returns {APIDeferred}
|
|
715
|
+
*/
|
|
716
|
+
isFromPublicDomain(parameters) {
|
|
717
|
+
const commandName = 'User_IsFromPublicDomain';
|
|
718
|
+
requireParameters(['email'], parameters, commandName);
|
|
719
|
+
return performPOSTRequest(commandName, parameters);
|
|
720
|
+
},
|
|
721
|
+
},
|
|
722
|
+
card: {
|
|
723
|
+
/**
|
|
724
|
+
* Set the limit of an expensify card.
|
|
725
|
+
*
|
|
726
|
+
* @param {Object} parameters
|
|
727
|
+
* @param {String} parameters.cardUserEmail who the card is assigned to
|
|
728
|
+
* @param {Boolean} parameters.hasCustomLimit whether or not the card has a custom limit
|
|
729
|
+
* @param {Number} [parameters.cardID]
|
|
730
|
+
* @param {Number} [parameters.limit] should be in positive cents
|
|
731
|
+
* @param {String} [parameters.domainName] The domain of the card
|
|
732
|
+
*
|
|
733
|
+
* @returns {APIDeferred}
|
|
734
|
+
*/
|
|
735
|
+
setLimit(parameters) {
|
|
736
|
+
const commandName = 'Card_setLimit';
|
|
737
|
+
requireParameters(['cardUserEmail', 'hasCustomLimit', 'domainName'], parameters, commandName);
|
|
738
|
+
return performPOSTRequest(commandName, parameters);
|
|
739
|
+
},
|
|
740
|
+
/**
|
|
741
|
+
* Create an admin issued virtual card
|
|
742
|
+
*
|
|
743
|
+
* @param {Object} parameters
|
|
744
|
+
* @param {string} parameters.cardTitle
|
|
745
|
+
* @param {string} parameters.assigneeEmail
|
|
746
|
+
* @param {number} parameters.cardLimit
|
|
747
|
+
* @param {string} parameters.cardLimitType
|
|
748
|
+
* @param {string} parameters.domainName
|
|
749
|
+
*
|
|
750
|
+
* @returns {APIDeferred}
|
|
751
|
+
*/
|
|
752
|
+
createAdminIssuedVirtualCard(parameters) {
|
|
753
|
+
const commandName = 'Card_CreateAdminIssuedVirtualCard';
|
|
754
|
+
requireParameters(['cardTitle', 'assigneeEmail', 'cardLimit', 'cardLimitType', 'domainName'], parameters, commandName);
|
|
755
|
+
return performPOSTRequest(commandName, parameters);
|
|
756
|
+
},
|
|
757
|
+
/**
|
|
758
|
+
* Edit an admin issued virtual card
|
|
759
|
+
*
|
|
760
|
+
* @param {Object} parameters
|
|
761
|
+
* @param {string} parameters.domainName
|
|
762
|
+
* @param {number} parameters.cardID
|
|
763
|
+
* @param {string} parameters.cardTitle
|
|
764
|
+
* @param {string} parameters.assigneeEmail
|
|
765
|
+
* @param {number} parameters.cardLimit
|
|
766
|
+
* @param {string} parameters.cardLimitType
|
|
767
|
+
*
|
|
768
|
+
* @returns {APIDeferred}
|
|
769
|
+
*/
|
|
770
|
+
editAdminIssuedVirtualCard(parameters) {
|
|
771
|
+
const commandName = 'Card_EditAdminIssuedVirtualCard';
|
|
772
|
+
requireParameters(['domainName', 'cardID', 'cardTitle', 'assigneeEmail', 'cardLimit', 'cardLimitType'], parameters, commandName);
|
|
773
|
+
return performPOSTRequest(commandName, parameters);
|
|
774
|
+
},
|
|
775
|
+
},
|
|
776
|
+
JSON_CODES: {
|
|
777
|
+
AUTH_FAILURES: [
|
|
778
|
+
403, // CSRF Token is invalid (expired, absent or mal-formed)
|
|
779
|
+
407, // AuthToken Invalid/Expired
|
|
780
|
+
408, // Account Deleted
|
|
781
|
+
411, // AuthToken has insufficient privileges
|
|
782
|
+
500, // Server Error
|
|
783
|
+
],
|
|
784
|
+
},
|
|
785
|
+
};
|
|
786
|
+
}
|