-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Ensure accounts with a private domain secondary login can create a workspace #5037
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
369003b
2364a5d
9e3c033
fc260d9
33f5ef4
8b7c1fb
58ae918
2ca78a0
d780736
24f79f6
917c4f7
dab1faf
4283ec3
a50ab75
6b15611
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -660,6 +660,15 @@ function updateReportPinnedState(reportID, isPinned) { | |||||||
| Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`, {isPinned}); | ||||||||
| } | ||||||||
|
|
||||||||
| /** | ||||||||
| * Updates isFromPublicDomain in Onyx. | ||||||||
| * | ||||||||
| * @param {Boolean} isFromPublicDomain | ||||||||
| */ | ||||||||
| function setIsFromPublicDomain(isFromPublicDomain) { | ||||||||
| Onyx.merge(ONYXKEYS.USER, {isFromPublicDomain}); | ||||||||
| } | ||||||||
|
|
||||||||
| /** | ||||||||
| * Get the private pusher channel name for a Report. | ||||||||
| * | ||||||||
|
|
@@ -741,6 +750,26 @@ function subscribeToUserEvents() { | |||||||
| {error, pusherChannelName, eventName: Pusher.TYPE.REPORT_TOGGLE_PINNED}, | ||||||||
| ); | ||||||||
| }); | ||||||||
|
|
||||||||
| // Live-update if a user has private domains listed as primary or secondary logins. | ||||||||
| Pusher.subscribe(pusherChannelName, Pusher.TYPE.ACCOUNT_VALIDATED, (pushJSON) => { | ||||||||
| Log.info( | ||||||||
| `[Report] Handled ${Pusher.TYPE.ACCOUNT_VALIDATED} event sent by Pusher`, | ||||||||
| false, | ||||||||
| {isFromPublicDomain: pushJSON.isFromPublicDomain}, | ||||||||
| ); | ||||||||
| setIsFromPublicDomain(pushJSON.isFromPublicDomain); | ||||||||
| }, false, | ||||||||
| () => { | ||||||||
| NetworkConnection.triggerReconnectionCallbacks('pusher re-subscribed to private user channel'); | ||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there some reason we must call this here ? Looks like we also do it here App/src/libs/actions/Report.js Line 744 in 57eed8b
and here App/src/libs/actions/Report.js Line 724 in 57eed8b
and here App/src/libs/actions/Report.js Line 704 in 57eed8b
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just a bad example copied over? We already call
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah ok, maybe or we can create a follow up to look into a better way. Probably shouldn't need to block these changes. Just thought it was worth mentioning. |
||||||||
| }) | ||||||||
| .catch((error) => { | ||||||||
| Log.info( | ||||||||
| '[Report] Failed to subscribe to Pusher channel', | ||||||||
| false, | ||||||||
| {error, pusherChannelName, eventName: Pusher.TYPE.ACCOUNT_VALIDATED}, | ||||||||
| ); | ||||||||
| }); | ||||||||
| } | ||||||||
|
|
||||||||
| /** | ||||||||
|
|
||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -65,6 +65,56 @@ function getBetas() { | |||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||
| * Fetch the public domain info for the current user (includes secondary logins). | ||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||
| * 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. | ||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||
| * @param {String} loginList | ||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||
| function getDomainInfo(loginList) { | ||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am probably just not seeing why it's necessary but we can access the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The idea is that we would filter the |
||||||||||||||||||||||||||||||||||||
| // 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; | ||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. NAB: Could use a numeric seperator here:
Suggested change
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, not your code anyway
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. TIL about numeric separators |
||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| // First we filter out any domains that are in the list of common public domains | ||||||||||||||||||||||||||||||||||||
| const emailList = _.filter(loginList, email => ( | ||||||||||||||||||||||||||||||||||||
| !_.contains(COMMON_PUBLIC_DOMAINS, Str.extractEmailDomain(email)) | ||||||||||||||||||||||||||||||||||||
| )); | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| // If there are no emails left, we have a public domain | ||||||||||||||||||||||||||||||||||||
| if (!emailList.length) { | ||||||||||||||||||||||||||||||||||||
| Onyx.merge(ONYXKEYS.USER, {isFromPublicDomain: true}); | ||||||||||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| // Check the API for the remaining uncommon domains | ||||||||||||||||||||||||||||||||||||
| API.User_IsFromPublicDomain({emailList: emailList.join(',')}) | ||||||||||||||||||||||||||||||||||||
| .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(loginList), RETRY_TIMEOUT); | ||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's not great to leave timers running because it can lead to stuff like this function getting called when a user is logged out. This should help -> Lines 11 to 27 in 57eed8b
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. TIL |
||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||
| * Fetches the data needed for user settings | ||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||
|
|
@@ -90,6 +140,10 @@ function getUserDetails() { | |||||||||||||||||||||||||||||||||||
| const blockedFromConcierge = lodashGet(response, `nameValuePairs.${CONST.NVP.BLOCKED_FROM_CONCIERGE}`, {}); | ||||||||||||||||||||||||||||||||||||
| Onyx.merge(ONYXKEYS.NVP_BLOCKED_FROM_CONCIERGE, blockedFromConcierge); | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| // Get domainInfo for user | ||||||||||||||||||||||||||||||||||||
| const emailList = _.map(loginList, userLogin => userLogin.partnerUserID); | ||||||||||||||||||||||||||||||||||||
| getDomainInfo(emailList); | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| const preferredSkinTone = lodashGet(response, `nameValuePairs.${CONST.NVP.PREFERRED_EMOJI_SKIN_TONE}`, {}); | ||||||||||||||||||||||||||||||||||||
| Onyx.merge(ONYXKEYS.PREFERRED_EMOJI_SKIN_TONE, | ||||||||||||||||||||||||||||||||||||
| getSkinToneEmojiFromIndex(preferredSkinTone).skinTone); | ||||||||||||||||||||||||||||||||||||
|
|
@@ -207,49 +261,6 @@ function isBlockedFromConcierge(expiresAt) { | |||||||||||||||||||||||||||||||||||
| 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); | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||
| * Initialize our pusher subscription to listen for user changes | ||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Am I mistaken in thinking that
User_IsFromPublicDomainexpects a comma-separated list of emails instead of an array? Should this be something like:Or perhaps more simply:
The second is better as long as we want
requireCertaintyto always betrue, which I think we do.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right! In fact, I'm a bit confused by that too because even though we're passing an array, the request is actually sent as a comma separated list! I can't seem to find where it's being converted though 🤔
Anyway, I updated the call to
User_IsFromPublicDomaininUser.jsto make it clearer.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NAB but I think it would be a bit cleaner to do the
.joinin here and have it take an array.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pretty sure this happens when you use
FormDataBut fun fact last time I checked it did not work this way on iOS 😃
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TIL