-
Notifications
You must be signed in to change notification settings - Fork 2.9k
/
User.js
249 lines (223 loc) · 8.21 KB
/
User.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
import _ from 'underscore';
import lodashGet from 'lodash/get';
import Onyx from 'react-native-onyx';
import Str from 'expensify-common/lib/str';
import {PUBLIC_DOMAINS as COMMON_PUBLIC_DOMAINS} from 'expensify-common/lib/CONST';
import moment from 'moment';
import ONYXKEYS from '../../ONYXKEYS';
import * as API from '../API';
import CONST from '../../CONST';
import Navigation from '../Navigation/Navigation';
import ROUTES from '../../ROUTES';
let sessionAuthToken = '';
let sessionEmail = '';
Onyx.connect({
key: ONYXKEYS.SESSION,
callback: (val) => {
sessionAuthToken = lodashGet(val, 'authToken', '');
sessionEmail = lodashGet(val, 'email', '');
},
});
let currentlyViewedReportID = '';
Onyx.connect({
key: ONYXKEYS.CURRENTLY_VIEWED_REPORTID,
callback: val => currentlyViewedReportID = val || '',
});
/**
* Changes a password for a given account
*
* @param {String} oldPassword
* @param {String} password
* @returns {Promise}
*/
function changePassword(oldPassword, password) {
Onyx.merge(ONYXKEYS.ACCOUNT, {...CONST.DEFAULT_ACCOUNT_DATA, loading: true});
return API.ChangePassword({oldPassword, password})
.then((response) => {
if (response.jsonCode !== 200) {
const error = lodashGet(response, 'message', 'Unable to change password. Please try again.');
Onyx.merge(ONYXKEYS.ACCOUNT, {error});
}
return response;
})
.finally((response) => {
Onyx.merge(ONYXKEYS.ACCOUNT, {loading: false});
return response;
});
}
function getBetas() {
API.User_GetBetas().then((response) => {
if (response.jsonCode === 200) {
Onyx.set(ONYXKEYS.BETAS, response.betas);
}
});
}
/**
* Fetches the data needed for user settings
*/
function getUserDetails() {
API.Get({
returnValueList: 'account, loginList, nameValuePairs',
nvpNames: CONST.NVP.BLOCKED_FROM_CONCIERGE,
})
.then((response) => {
// Update the User onyx key
const loginList = _.where(response.loginList, {partnerName: 'expensify.com'});
const expensifyNewsStatus = lodashGet(response, 'account.subscribed', true);
Onyx.merge(ONYXKEYS.USER, {loginList, expensifyNewsStatus: !!expensifyNewsStatus});
// Update the nvp_payPalMeAddress NVP
const payPalMeAddress = lodashGet(response, `nameValuePairs.${CONST.NVP.PAYPAL_ME_ADDRESS}`, '');
Onyx.merge(ONYXKEYS.NVP_PAYPAL_ME_ADDRESS, payPalMeAddress);
// Update the blockedFromConcierge NVP
const blockedFromConcierge = lodashGet(response, `nameValuePairs.${CONST.NVP.BLOCKED_FROM_CONCIERGE}`, {});
Onyx.merge(ONYXKEYS.NVP_BLOCKED_FROM_CONCIERGE, blockedFromConcierge);
});
}
/**
* Resends a validation link to a given login
*
* @param {String} login
*/
function resendValidateCode(login) {
API.ResendValidateCode({email: login});
}
/**
* Sets whether or not the user is subscribed to Expensify news
*
* @param {Boolean} subscribed
*/
function setExpensifyNewsStatus(subscribed) {
Onyx.merge(ONYXKEYS.USER, {expensifyNewsStatus: subscribed});
API.UpdateAccount({subscribed})
.then((response) => {
if (response.jsonCode !== 200) {
Onyx.merge(ONYXKEYS.USER, {expensifyNewsStatus: !subscribed});
}
})
.catch(() => {
Onyx.merge(ONYXKEYS.USER, {expensifyNewsStatus: !subscribed});
});
}
/**
* Adds a secondary login to a user's account
*
* @param {String} login
* @param {String} password
* @returns {Promise}
*/
function setSecondaryLogin(login, password) {
Onyx.merge(ONYXKEYS.ACCOUNT, {...CONST.DEFAULT_ACCOUNT_DATA, loading: true});
return API.User_SecondaryLogin_Send({
email: login,
password,
}).then((response) => {
if (response.jsonCode === 200) {
const loginList = _.where(response.loginList, {partnerName: 'expensify.com'});
Onyx.merge(ONYXKEYS.USER, {loginList});
} else {
let error = lodashGet(response, 'message', 'Unable to add secondary login. Please try again.');
// Replace error with a friendlier message
if (error.includes('already belongs to an existing Expensify account.')) {
error = 'This login already belongs to an existing Expensify account.';
}
Onyx.merge(ONYXKEYS.USER, {error});
}
return response;
}).finally((response) => {
Onyx.merge(ONYXKEYS.ACCOUNT, {loading: false});
return response;
});
}
/**
* Validates a login given an accountID and validation code
*
* @param {Number} accountID
* @param {String} validateCode
*/
function validateLogin(accountID, validateCode) {
const isLoggedIn = !_.isEmpty(sessionAuthToken);
const redirectRoute = isLoggedIn ? ROUTES.getReportRoute(currentlyViewedReportID) : ROUTES.HOME;
Onyx.merge(ONYXKEYS.ACCOUNT, {...CONST.DEFAULT_ACCOUNT_DATA, loading: true});
API.ValidateEmail({
accountID,
validateCode,
}).then((response) => {
if (response.jsonCode === 200) {
const {email} = response;
if (isLoggedIn) {
getUserDetails();
} else {
// Let the user know we've successfully validated their login
const success = lodashGet(response, 'message', `Your secondary login ${email} has been validated.`);
Onyx.merge(ONYXKEYS.ACCOUNT, {success});
}
} else {
const error = lodashGet(response, 'message', 'Unable to validate login.');
Onyx.merge(ONYXKEYS.ACCOUNT, {error});
}
}).finally(() => {
Onyx.merge(ONYXKEYS.ACCOUNT, {loading: false});
Navigation.navigate(redirectRoute);
});
}
/**
* Checks if the expiresAt date of a user's ban is before right now
*
* @param {String} expiresAt
* @returns {boolean}
*/
function isBlockedFromConcierge(expiresAt) {
if (!expiresAt) {
return false;
}
return moment().isBefore(moment(expiresAt), 'day');
}
/**
* Fetch the public domain info for the current user.
*
* This API is a bit weird in that it sometimes depends on information being cached in bedrock.
* If the info for the domain is not in bedrock, then it creates an asynchronous bedrock job to gather domain info.
* If that happens, this function will automatically retry itself in 10 minutes.
*/
function getDomainInfo() {
// If this command fails, we'll retry again in 10 minutes,
// arbitrarily chosen giving Bedrock time to resolve the ClearbitCheckPublicEmail job for this email.
const RETRY_TIMEOUT = 600000;
// First check list of common public domains
if (_.contains(COMMON_PUBLIC_DOMAINS, sessionEmail)) {
Onyx.merge(ONYXKEYS.USER, {isFromPublicDomain: true});
return;
}
// If it is not a common public domain, check the API
API.User_IsFromPublicDomain({email: sessionEmail})
.then((response) => {
if (response.jsonCode === 200) {
const {isFromPublicDomain} = response;
Onyx.merge(ONYXKEYS.USER, {isFromPublicDomain});
// If the user is not on a public domain we'll want to know whether they are on a domain that has
// already provisioned the Expensify card
if (isFromPublicDomain) {
return;
}
API.User_IsUsingExpensifyCard()
.then(({isUsingExpensifyCard}) => {
Onyx.merge(ONYXKEYS.USER, {isUsingExpensifyCard});
});
} else {
// eslint-disable-next-line max-len
console.debug(`Command User_IsFromPublicDomain returned error code: ${response.jsonCode}. Most likely, this means that the domain ${Str.extractEmail(sessionEmail)} is not in the bedrock cache. Retrying in ${RETRY_TIMEOUT / 1000 / 60} minutes`);
setTimeout(getDomainInfo, RETRY_TIMEOUT);
}
});
}
export {
changePassword,
getBetas,
getUserDetails,
resendValidateCode,
setExpensifyNewsStatus,
setSecondaryLogin,
validateLogin,
isBlockedFromConcierge,
getDomainInfo,
};