Skip to content
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

Ensure accounts with a private domain secondary login can create a workspace #5037

Merged
merged 15 commits into from
Sep 14, 2021

Conversation

luacmartins
Copy link
Contributor

@luacmartins luacmartins commented Sep 2, 2021

Details

Ensure accounts with a private domain secondary login can create a workspace via the "Get Started" button in workspace configuration.

Related Web-E PR: https://github.com/Expensify/Web-Expensify/pull/31862

cc @roryabraham

Fixed Issues

$ https://github.com/Expensify/Expensify/issues/176225

Tests

  1. Create an account with a public domain. e.g. @gmail.com.
  2. Login to NewDot and navigate to + > New Workspace and verify that you see Add Email in the card page.
  3. Click on Add email.
  4. Add a private domain secondary login to your account, e.g. @expensify.com.
  5. Validate the secondary login by following the instructions in this SO to generate a link. Note: Don't use the clitools script! It does not hit the API endpoint and will not trigger the pusher event to update NewDot.
  6. Go back to NewDot and verify that the button now says Get Started and clicking it starts the VBA flow.

QA Steps

Steps above.

Tested On

  • Web
  • Mobile Web
  • Desktop
  • iOS
  • Android

Screenshots

Web

web.mov

Mobile Web

Desktop

desktop.mov

iOS

Android

@luacmartins luacmartins self-assigned this Sep 2, 2021
@luacmartins luacmartins changed the title Ensure accounts with a private domain secondary login can create a workspace [Hold Web-E #31862] Ensure accounts with a private domain secondary login can create a workspace Sep 10, 2021
@luacmartins luacmartins changed the title [Hold Web-E #31862] Ensure accounts with a private domain secondary login can create a workspace [Hold Web-E #31862][InternalQA] Ensure accounts with a private domain secondary login can create a workspace Sep 10, 2021
@luacmartins luacmartins changed the title [Hold Web-E #31862][InternalQA] Ensure accounts with a private domain secondary login can create a workspace [InternalQA] Ensure accounts with a private domain secondary login can create a workspace Sep 10, 2021
@luacmartins luacmartins changed the title [InternalQA] Ensure accounts with a private domain secondary login can create a workspace [Hold Web-E #31862][InternalQA] Ensure accounts with a private domain secondary login can create a workspace Sep 10, 2021
@luacmartins luacmartins changed the title [Hold Web-E #31862][InternalQA] Ensure accounts with a private domain secondary login can create a workspace [Hold Web-E #31862] Ensure accounts with a private domain secondary login can create a workspace Sep 10, 2021
@luacmartins luacmartins marked this pull request as ready for review September 10, 2021 23:47
@luacmartins luacmartins requested a review from a team as a code owner September 10, 2021 23:47
@MelvinBot MelvinBot requested review from yuwenmemon and removed request for a team September 10, 2021 23:48
@luacmartins luacmartins changed the title [Hold Web-E #31862] Ensure accounts with a private domain secondary login can create a workspace Ensure accounts with a private domain secondary login can create a workspace Sep 13, 2021
@luacmartins
Copy link
Contributor Author

No longer on hold!

*
* @param {Boolean} isFromPublicDomain
*/
function updateIsFromPublicDomain(isFromPublicDomain) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
function updateIsFromPublicDomain(isFromPublicDomain) {
function setIsFromPublicDomain(isFromPublicDomain) {

* @param {String} email
* @returns {String}
*/
function getDomainFromEmail(email) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for this – use Str.extractEmailDomain from expensify-common.

Copy link
Contributor Author

@luacmartins luacmartins Sep 13, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oooh didn't know about this... TIL! Thanks!

* @param {Boolean} [parameters.requireCertainty]
* @returns {Promise}
*/
function User_IsFromPublicDomain(parameters) {
const commandName = 'User_IsFromPublicDomain';
requireParameters(['email'], parameters, commandName);
requireParameters(['emailList'], parameters, commandName);
return Network.post(commandName, {
...{requireCertainty: true},
...parameters,
Copy link
Contributor

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_IsFromPublicDomain expects a comma-separated list of emails instead of an array? Should this be something like:

return Network.post(commandName, {
    ...{
        requireCertainty: true,
        emailList: parameters.emailList.join(','),
    },
    ...(_.omit(parameters, 'emailList')),
});

Or perhaps more simply:

return Network.post(commandName, {
    ...parameters,
    ...{
        requireCertainty: true,
        emailList: parameters.emailList.join(','),
    },
});

The second is better as long as we want requireCertainty to always be true, which I think we do.

Copy link
Contributor Author

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_IsFromPublicDomain in User.js to make it clearer.

Copy link
Contributor

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 .join in here and have it take an array.

Copy link
Contributor

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 FormData

2021-09-15_14-08-01

But fun fact last time I checked it did not work this way on iOS 😃

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TIL

@luacmartins
Copy link
Contributor Author

Updated!

* @param {Boolean} [parameters.requireCertainty]
* @returns {Promise}
*/
function User_IsFromPublicDomain(parameters) {
const commandName = 'User_IsFromPublicDomain';
requireParameters(['email'], parameters, commandName);
requireParameters(['emailList'], parameters, commandName);
return Network.post(commandName, {
...{requireCertainty: true},
...parameters,
Copy link
Contributor

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 .join in here and have it take an array.

function getDomainInfo(loginList) {
// 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;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NAB: Could use a numeric seperator here:

Suggested change
const RETRY_TIMEOUT = 600000;
const RETRY_TIMEOUT = 600_000;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, not your code anyway

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TIL about numeric separators

@yuwenmemon yuwenmemon merged commit 478e9cf into main Sep 14, 2021
@yuwenmemon yuwenmemon deleted the cmartins-isSecondaryLoginFromPublicDomain branch September 14, 2021 05:33
@OSBotify
Copy link
Contributor

✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release.

@OSBotify
Copy link
Contributor

🚀 Deployed to staging by @yuwenmemon in version: 1.0.98-2 🚀

platform result
🤖 android 🤖 success ✅
🖥 desktop 🖥 success ✅
🍎 iOS 🍎 success ✅
🕸 web 🕸 success ✅

Copy link
Contributor

@marcaaron marcaaron left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leaving random comments as I look at what this PR is doing.

setIsFromPublicDomain(pushJSON.isFromPublicDomain);
}, false,
() => {
NetworkConnection.triggerReconnectionCallbacks('pusher re-subscribed to private user channel');
Copy link
Contributor

Choose a reason for hiding this comment

The 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

NetworkConnection.triggerReconnectionCallbacks('pusher re-subscribed to private user channel');

and here

NetworkConnection.triggerReconnectionCallbacks('pusher re-subscribed to private user channel');

and here

NetworkConnection.triggerReconnectionCallbacks('pusher re-subscribed to private user channel');

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a bad example copied over? We already call triggerReconnectionCallbacks when a user comes back online in listenForReconnect. All these calls seem unnecessary then. I can refactor that on v2 of this PR.

Copy link
Contributor

Choose a reason for hiding this comment

The 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.

*
* @param {String} loginList
*/
function getDomainInfo(loginList) {
Copy link
Contributor

Choose a reason for hiding this comment

The 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 loginList from Web-Expensify so I'm confused about why we pass it as a parameter here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea is that we would filter the loginList on the frontend and only make API calls with logins that are not in the common domain list. So for example, if the loginList was ['[email protected]', '[email protected]', '[email protected]'] we would only call the API to check [email protected]. If we were to access the loginList in Web-E, we would have to filter the list again.

} 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);
Copy link
Contributor

Choose a reason for hiding this comment

The 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 ->

App/src/libs/Timers.js

Lines 11 to 27 in 57eed8b

function register(timerID) {
timers.push(timerID);
return timerID;
}
/**
* Clears all timers that we have registered. Use for long running tasks that may begin once logged out.
*/
function clearAll() {
_.each(timers, (timer) => {
// We don't know whether it's a setTimeout or a setInterval, but it doesn't really matter. If the id doesn't
// exist nothing bad happens.
clearTimeout(timer);
clearInterval(timer);
});
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TIL

@luacmartins luacmartins mentioned this pull request Sep 16, 2021
5 tasks
luacmartins added a commit that referenced this pull request Sep 16, 2021
github-actions bot pushed a commit that referenced this pull request Sep 16, 2021
@OSBotify
Copy link
Contributor

🚀 Deployed to production by @Jag96 in version: 1.0.99-4 🚀

platform result
🤖 android 🤖 success ✅
🖥 desktop 🖥 success ✅
🍎 iOS 🍎 success ✅
🕸 web 🕸 success ✅

@luacmartins luacmartins restored the cmartins-isSecondaryLoginFromPublicDomain branch October 5, 2021 18:27
@roryabraham roryabraham deleted the cmartins-isSecondaryLoginFromPublicDomain branch June 8, 2023 01:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants