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

clean up the deep link code #17452

Merged
merged 59 commits into from
Jul 18, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
db996cb
clean up the deep link code
ntdiary Apr 14, 2023
cc48aaf
Add some comments to explain the deep link code
ntdiary Apr 14, 2023
728cc18
Update some comments to explain the deep link code
ntdiary Apr 17, 2023
f1f19a7
Update comment for removing the short-lived auth token
ntdiary Apr 17, 2023
4945eb1
specify the route to redirect
ntdiary Apr 17, 2023
6dc06df
Update comment for removing the short-lived auth token
ntdiary Apr 17, 2023
cff9643
makeRequestWithSideEffects can be removed in the PR 17364
ntdiary Apr 19, 2023
3c73416
rename TRANSITION_FROM_OLD_DOT to TRANSITION
ntdiary Apr 25, 2023
a129009
If the current link is transition from oldDot, we should wait for it …
ntdiary Apr 25, 2023
cb5f434
prevent the popup from appearing repeatedly
ntdiary Apr 26, 2023
1f252d6
rename TRANSITION to TRANSITION_BETWEEN_APPS
ntdiary Apr 26, 2023
5f71937
rename variable and explain the reason for the code.
ntdiary Apr 26, 2023
a737600
correct the condition of variable hasPopupBeenOpenedBefore
ntdiary Apr 26, 2023
c7b323d
Refactor the deeplink logic:
ntdiary Apr 28, 2023
c5ee140
try to improve the transition logic.
ntdiary May 2, 2023
d9a3cbc
add a comment for openRouteInDesktopApp
ntdiary May 2, 2023
5e2a6d9
Merge branch 'main' into clean-up-deep-link-code
ntdiary May 3, 2023
54ee01c
Merge branch 'main' into clean-up-deep-link-code
ntdiary May 3, 2023
0349229
move navigation logic from createWorkspace to createWorkspaceAndNavig…
ntdiary May 4, 2023
d858603
fix lint errors
ntdiary May 4, 2023
65b0f7c
Merge branch 'main' into clean-up-deep-link-code
ntdiary May 5, 2023
4105086
Update src/libs/actions/App.js
ntdiary May 5, 2023
edbae30
Merge branch 'main' into clean-up-deep-link-code
ntdiary May 9, 2023
637af52
Merge branch 'main' into clean-up-deep-link-code
ntdiary May 10, 2023
bb0ddd0
Merge branch 'main' into clean-up-deep-link-code
ntdiary May 11, 2023
8913f88
Merge branch 'main' into clean-up-deep-link-code
ntdiary May 15, 2023
03d69bb
Merge branch 'main' into clean-up-deep-link-code
ntdiary May 16, 2023
bdaf961
Merge branch 'main' into clean-up-deep-link-code
ntdiary May 17, 2023
8758e31
Revert the revert regarding createWorkspaceAndNavigateToIt.
ntdiary May 17, 2023
144abda
fix lint error
ntdiary May 17, 2023
9e7f595
Update src/libs/actions/App.js
ntdiary May 17, 2023
fbdbb7d
Merge branch 'main' into clean-up-deep-link-code
ntdiary May 18, 2023
96be874
casing mistake
ntdiary May 18, 2023
ac8ad4e
Do not call clearAccountMessages on non-home screens.
ntdiary May 19, 2023
f9f89da
add the comment for isFocused
ntdiary May 22, 2023
e465908
Merge branch 'main' into clean-up-deep-link-code
ntdiary May 23, 2023
92faead
add a skipReauthentication param
ntdiary May 23, 2023
5a66cbc
Merge branch 'main' into clean-up-deep-link-code
ntdiary May 23, 2023
b0adfd3
Merge branch 'main' into clean-up-deep-link-code
ntdiary May 24, 2023
3faec2b
Merge branch 'main' into clean-up-deep-link-code
ntdiary May 31, 2023
4ed6c97
Merge branch 'main' into clean-up-deep-link-code
ntdiary Jun 6, 2023
e195537
Merge branch 'main' into clean-up-deep-link-code
ntdiary Jun 7, 2023
e31d0bd
Merge branch 'main' into clean-up-deep-link-code
ntdiary Jun 9, 2023
7d70e7b
Merge branch 'main' into clean-up-deep-link-code
ntdiary Jun 12, 2023
d5937cc
Merge branch 'main' into clean-up-deep-link-code
ntdiary Jun 14, 2023
4a69d1e
Merge branch 'main' into clean-up-deep-link-code
ntdiary Jun 15, 2023
be41317
we still need the currentUserEmail variable.
ntdiary Jun 15, 2023
57ef6bd
Merge branch 'main' into clean-up-deep-link-code
ntdiary Jun 22, 2023
db7a9cb
Merge branch 'main' into clean-up-deep-link-code
ntdiary Jun 28, 2023
0c87306
Merge branch 'main' into clean-up-deep-link-code
ntdiary Jul 4, 2023
8c7c2c4
Merge branch 'main' into clean-up-deep-link-code
ntdiary Jul 5, 2023
b6b672f
Merge branch 'main' into clean-up-deep-link-code
ntdiary Jul 6, 2023
1298b0f
Merge branch 'main' into clean-up-deep-link-code
ntdiary Jul 9, 2023
2bb7f31
keep variable name consistent.
ntdiary Jul 9, 2023
61acb1b
Merge branch 'main' into clean-up-deep-link-code
ntdiary Jul 11, 2023
80101fa
Merge branch 'main' into clean-up-deep-link-code
ntdiary Jul 12, 2023
6d3bdce
Merge branch 'main' into clean-up-deep-link-code
ntdiary Jul 17, 2023
bf37347
Merge branch 'main' into clean-up-deep-link-code
ntdiary Jul 18, 2023
3120a38
Merge branch 'main' into clean-up-deep-link-code
ntdiary Jul 18, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions src/ONYXKEYS.js
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,4 @@ export default {

// Is app in beta version
IS_BETA: 'isBeta',

// Whether the auth token is valid
IS_TOKEN_VALID: 'isTokenValid',
};
69 changes: 33 additions & 36 deletions src/components/DeeplinkWrapper/index.website.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import CONST from '../../CONST';
import CONFIG from '../../CONFIG';
import * as Browser from '../../libs/Browser';
import ONYXKEYS from '../../ONYXKEYS';
import * as Authentication from '../../libs/Authentication';
import * as Session from '../../libs/actions/Session';

const propTypes = {
/** Children to render. */
Expand All @@ -21,13 +21,17 @@ const propTypes = {

/** Currently logged-in user authToken */
authToken: PropTypes.string,

/** The short-lived auth token for navigating to desktop app */
shortLivedAuthToken: PropTypes.string,
}),
};

const defaultProps = {
session: {
email: '',
authToken: '',
shortLivedAuthToken: '',
},
};

Expand All @@ -36,53 +40,48 @@ class DeeplinkWrapper extends PureComponent {
super(props);

this.state = {
appInstallationCheckStatus: (this.isMacOSWeb() && CONFIG.ENVIRONMENT !== CONST.ENVIRONMENT.DEV)
? CONST.DESKTOP_DEEPLINK_APP_STATE.CHECKING : CONST.DESKTOP_DEEPLINK_APP_STATE.NOT_INSTALLED,
isShortLivedAuthTokenLoading: this.isMacOSWeb() && CONFIG.ENVIRONMENT !== CONST.ENVIRONMENT.DEV,
};
this.focused = true;
}

componentDidMount() {
if (!this.isMacOSWeb() || CONFIG.ENVIRONMENT === CONST.ENVIRONMENT.DEV) {
return;
}

window.addEventListener('blur', () => {
this.focused = false;
});
// We need to clear the old short-lived auth token if it exists.
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do we need to do this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We need to ensure that the short-lived auth token doesn't exist, then get the new short-lived auto token from the server, and then the pop-up window can be opened.

Copy link
Contributor

Choose a reason for hiding this comment

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

Please update the code comment to explain the "why" and not just "what" the code is doing. Why do we need to clear out the previous one before fetching a new one?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@tgolen , sorry, my english is not good. I'm not sure how to describe it. Since we open the popup window based on whether there is an short-lived auth token. If we don't clear it first, the popup won't open?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think that's a perfect explanation 👍 Here is how I would write it:

Since there is no way to know if a previous short-lived authToken is still valid, any previous short-lived authToken must be cleared out and a new one must be fetched so that the popup window will only open when we know the short-lived authToken is valid.

Session.removeShortLivedAuthToken();
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't really get this. Why don't we just not use it when the component mounts? Why does it need to be "cleared out"? It will get replaced with a new token and we will only ever check it once because of the this.hasPopupBeenOpenedBefore flag.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This code was based on the above thought. Now thinking back, clearing seems unnecessary. We can also modify the conditions in componentDidUpdate and show the popup window when there is a new shortLivedAuthToken in props.

Index: src/components/DeeplinkWrapper/index.website.js
===================================================================
diff --git a/src/components/DeeplinkWrapper/index.website.js b/src/components/DeeplinkWrapper/index.website.js
--- a/src/components/DeeplinkWrapper/index.website.js	(revision a73760026ada268563f485864b1d24fa18aa64ad)
+++ b/src/components/DeeplinkWrapper/index.website.js	(date 1682668671513)
@@ -65,7 +65,7 @@
     }
 
     componentDidUpdate(prevProps) {
-        if (prevProps.session.shortLivedAuthToken || !this.props.session.shortLivedAuthToken) {
+        if (!this.props.session.shortLivedAuthToken || this.props.session.shortLivedAuthToken === prevProps.session.shortLivedAuthToken) {
             return;
         }


const expensifyUrl = new URL(CONFIG.EXPENSIFY.NEW_EXPENSIFY_URL);
const params = new URLSearchParams();
params.set('exitTo', `${window.location.pathname}${window.location.search}${window.location.hash}`);
if (!this.props.session.authToken) {
const expensifyDeeplinkUrl = `${CONST.DEEPLINK_BASE_URL}${expensifyUrl.host}/transition?${params.toString()}`;
this.openRouteInDesktopApp(expensifyDeeplinkUrl);
this.openRouteInDesktopApp();
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this be higher up in the order of operations?

I'm confused because it looks like we early return here if we don't have an authToken. Which makes sense because we "get one" on the next line. But the previous line is trying to "get" a short lived token as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, If newDot is opened from oldDot, there is no authToken when DeeplinkWrapper mounts only because the sign-in request has not been completed yet. So we need to wait until sign-in is complete before displaying the popup window, so that the desktop app opened by the user can remain logged in.

if (!this.props.session.authToken) {
    this.openRouteInDesktopApp();
    return;
}

This condition is only used when the user is indeed not logged in. And in this case, the user is also not logged in when opening the desktop app.

return;
}
Authentication.getShortLivedAuthToken().then((shortLivedAuthToken) => {
params.set('email', this.props.session.email);
params.set('shortLivedAuthToken', `${shortLivedAuthToken}`);
const expensifyDeeplinkUrl = `${CONST.DEEPLINK_BASE_URL}${expensifyUrl.host}/transition?${params.toString()}`;
this.openRouteInDesktopApp(expensifyDeeplinkUrl);
}).catch(() => {
// If the request is successful, we call the updateAppInstallationCheckStatus before the prompt pops up.
// If not, we only need to make sure that the state will be updated.
this.updateAppInstallationCheckStatus();
});
Session.getShortLivedAuthToken();
}

updateAppInstallationCheckStatus() {
setTimeout(() => {
if (!this.focused) {
this.setState({appInstallationCheckStatus: CONST.DESKTOP_DEEPLINK_APP_STATE.INSTALLED});
} else {
this.setState({appInstallationCheckStatus: CONST.DESKTOP_DEEPLINK_APP_STATE.NOT_INSTALLED});
}
}, 500);
componentDidUpdate(prevProps) {
if (prevProps.session.shortLivedAuthToken || !this.props.session.shortLivedAuthToken) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Are we not handling the errors we were handling before anymore?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, the redirection UI has been removed in PR #16383, there would be no point in updating the appInstallationCheckStatus variable in the error handler.

Copy link
Contributor

Choose a reason for hiding this comment

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

Can you remind me what errors we were handling and why they are not necessary anymore? I looked at the linked PR but I'm not seeing anything about errors or error handling (maybe I missed it).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, the redirection UI has been removed in PR #16383, there would be no point in updating the appInstallationCheckStatus variable in the error handler.

Eh, Error handling was newly added by me in PR #16043. At that time, I just thought that due to the complexity of the network transmission, we could not guarantee that a request would always succeed. And If the request failed (e.g. due to timeouts), we needed to update appInstallationCheckStatus from CHECKING to NOT_INSTALLED to allow sub components to render properly.
In fact, after #16383, we will always render the sub components, so updating appInstallationCheckStatus no longer makes sense, which also means that error handling is no longer needed.

return;
}

// Now that there is a shortLivedAuthToken, the route to the desktop app can be opened.
this.openRouteInDesktopApp();
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you also please add a code comment here explaining something like "Now that there is a shortLivedAuthToken, the route to the desktop app can be opened"?

}

openRouteInDesktopApp(expensifyDeeplinkUrl) {
this.updateAppInstallationCheckStatus();
openRouteInDesktopApp() {
this.setState({
isShortLivedAuthTokenLoading: false,
});

const params = new URLSearchParams();
params.set('exitTo', `${window.location.pathname}${window.location.search}${window.location.hash}`);
const session = this.props.session;
if (session.email && session.shortLivedAuthToken) {
params.set('email', session.email);
params.set('shortLivedAuthToken', session.shortLivedAuthToken);
}
const expensifyUrl = new URL(CONFIG.EXPENSIFY.NEW_EXPENSIFY_URL);
const expensifyDeeplinkUrl = `${CONST.DEEPLINK_BASE_URL}${expensifyUrl.host}/transition?${params.toString()}`;

// This check is necessary for Safari, otherwise, if the user
// does NOT have the Expensify desktop app installed, it's gonna
Expand All @@ -101,9 +100,8 @@ class DeeplinkWrapper extends PureComponent {
if (!iframe.parentNode) {
return;
}

iframe.parentNode.removeChild(iframe);
}, 100);
}, 0);
Copy link
Contributor

@marcaaron marcaaron Apr 14, 2023

Choose a reason for hiding this comment

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

Why do we actually need this setTimeout()? The explanation above is not very satisfying...

we need to give this iframe some time for it to do what it needs to do

What does it mean?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't know the original purpose either, but according to my tests, without this delay, the pop-up window can't appear.

} else {
window.location.href = expensifyDeeplinkUrl;
}
Expand All @@ -119,10 +117,9 @@ class DeeplinkWrapper extends PureComponent {
}

render() {
if (this.state.appInstallationCheckStatus === CONST.DESKTOP_DEEPLINK_APP_STATE.CHECKING) {
if (this.state.isShortLivedAuthTokenLoading) {
return <FullScreenLoadingIndicator style={styles.flex1} />;
}

return this.props.children;
}
}
Expand Down
10 changes: 0 additions & 10 deletions src/libs/Authentication.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,17 +105,7 @@ function reauthenticate(command = '') {
});
}

function getShortLivedAuthToken() {
return Network.post('OpenOldDotLink', {shouldRetry: false}).then((response) => {
if (response && response.shortLivedAuthToken) {
return Promise.resolve(response.shortLivedAuthToken);
}
return Promise.reject();
});
}

export {
reauthenticate,
Authenticate,
getShortLivedAuthToken,
};
42 changes: 20 additions & 22 deletions src/libs/actions/Session/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -241,11 +241,6 @@ function signInWithShortLivedAuthToken(email, authToken) {
isLoading: true,
},
},
{
onyxMethod: CONST.ONYX.METHOD.MERGE,
key: ONYXKEYS.IS_TOKEN_VALID,
value: true,
},
];

const successData = [
Expand All @@ -266,29 +261,13 @@ function signInWithShortLivedAuthToken(email, authToken) {
isLoading: false,
},
},
{
onyxMethod: CONST.ONYX.METHOD.MERGE,
key: ONYXKEYS.IS_TOKEN_VALID,
value: false,
},
];

// If the user is signing in with a different account from the current app, should not pass the auto-generated login as it may be tied to the old account.
// scene 1: the user is transitioning to newDot from a different account on oldDot.
// scene 2: the user is transitioning to desktop app from a different account on web app.
const oldPartnerUserID = credentials.login === email ? credentials.autoGeneratedLogin : '';
// eslint-disable-next-line rulesdir/no-api-side-effects-method
API.makeRequestWithSideEffects(
'SignInWithShortLivedAuthToken',
{authToken, oldPartnerUserID},
{optimisticData, successData, failureData},
null,
).then((response) => {
if (response) {
return;
}
Navigation.navigate();
});
API.read('SignInWithShortLivedAuthToken', {authToken, oldPartnerUserID, shouldRetry: false}, {optimisticData, successData, failureData});
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this be a write()? I think it was originally a write?

Copy link
Contributor Author

@ntdiary ntdiary Apr 14, 2023

Choose a reason for hiding this comment

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

If we use write, and if the token has expired, the request will always be in the networkRequestQueue, and the user can't perform other operations in the future. Is there any good way we can solve this problem?

Scenario: click to open the desktop app one minute after the pop-up appears.

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think we need the shouldRetry here do we? Read requests are not retryable by default IIRC and we have an open issue to remove this param entirely.

}

/**
Expand Down Expand Up @@ -642,6 +621,23 @@ function authenticatePusher(socketID, channelName, callback) {
});
}

function getShortLivedAuthToken() {
// TODO: If we have any way to read the shortLivedAuthToken and save it, we can also no longer call makeRequestWithSideEffects.
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure what "and save it" implies. We are saving it in Onyx, but that isn't enough? Also, TODOs are not allowed in our code. Instead, you should open a GH issue and point to this line of code and then detail what needs to be done.

// eslint-disable-next-line rulesdir/no-api-side-effects-method
API.makeRequestWithSideEffects(
'OpenOldDotLink', {shouldRetry: false}, {},
).then((response) => {
const {shortLivedAuthToken} = response;
Onyx.merge(ONYXKEYS.SESSION, {shortLivedAuthToken});
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't the OpenOldDotLink command be sending Onyx instructions back in the response? That's the way all of our other API commands work.

Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah it looks like this should just be an API.read now. We're just listening for the short lived token to change in Onyx instead of blocking on the request.

});
}

function removeShortLivedAuthToken() {
Onyx.merge(ONYXKEYS.SESSION, {
shortLivedAuthToken: '',
});
}

export {
beginSignIn,
updatePasswordAndSignin,
Expand All @@ -664,4 +660,6 @@ export {
reauthenticatePusher,
invalidateCredentials,
invalidateAuthToken,
getShortLivedAuthToken,
removeShortLivedAuthToken,
};
28 changes: 23 additions & 5 deletions src/pages/LogInWithShortLivedAuthTokenPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import withLocalize, {withLocalizePropTypes} from '../components/withLocalize';
import compose from '../libs/compose';
import TextLink from '../components/TextLink';
import ONYXKEYS from '../ONYXKEYS';
import networkPropTypes from '../components/networkPropTypes';

const propTypes = {
/** The parameters needed to authenticate with a short lived token are in the URL */
Expand All @@ -35,12 +36,23 @@ const propTypes = {

...withLocalizePropTypes,

/** Whether the short lived auth token is valid */
isTokenValid: PropTypes.bool,
/** The details about the account that the user is signing in with */
account: PropTypes.shape({
/** Whether a sign is loading */
isLoading: PropTypes.bool,
}),

/** Props to detect online status */
network: networkPropTypes,
Copy link
Contributor

Choose a reason for hiding this comment

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

It looks like everywhere else in the app it uses .isRequired for this prop. Let's do that here.

};

const defaultProps = {
isTokenValid: true,
account: {
isLoading: false,
},
network: {
isOffline: false,
},
};

class LogInWithShortLivedAuthTokenPage extends Component {
Expand All @@ -62,7 +74,12 @@ class LogInWithShortLivedAuthTokenPage extends Component {
}

render() {
if (this.props.isTokenValid) {
// redirect the user to the login page if there is a sudden disconnection
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm unsure what the exact edge case we're trying to handle is based on this comment. The user hits this page and in between downloading the JS bundle and executing it they somehow become offline? Can you expand on what exactly we are preventing and why we are doing this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Eh, does the desktop app also need to download the js bundle?
After the user clicks Allow button in the popup window to open the desktop app, if the network is disconnected at this time, I'm trying to redirect the user to the login page, prevent them being stuck on the transition page.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Without this condition, the session expired ui will be displayed, if we think this page is also ok, then we can remove this condition.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm sorry I don't think I fully understood the previous comments. I don't think the desktop app needs to download the js bundle because it's an electron app and should be bundled with the app (IIRC).

if the network is disconnected at this time

If they are disconnected then how can they access the page at all 🤔

Without this condition, the session expired ui will be displayed, if we think this page is also ok, then we can remove this condition.

I think it's fine but the message about the session being expired seems wrong?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I thought that event if the user is disconnected the desktop app would still display the page, only the request SignInWithShortLivedAuthToken would fail.
Or maybe we can just remove the condition as this seems like a very edge case?

I think it's fine but the message about the session being expired seems wrong?

Or we can display an appropriate message for this case.

if (this.props.network.isOffline) {
Navigation.navigate();
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we be passing something more explicit here? Calling navigate() with no arguments seems strange to me.

return;
}
if (this.props.account.isLoading) {
return <FullScreenLoadingIndicator />;
}
return (
Expand Down Expand Up @@ -107,6 +124,7 @@ LogInWithShortLivedAuthTokenPage.defaultProps = defaultProps;
export default compose(
withLocalize,
withOnyx({
isTokenValid: {key: ONYXKEYS.IS_TOKEN_VALID},
Copy link
Contributor

Choose a reason for hiding this comment

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

Just curious, but what was it doing before and why are we removing it now?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

When the user clicks Allow to open the desktop app one minute after the pop-up window appears, the token will become invalid, and we will prompt the user that the session has expired.
Based on this #16043 (comment) , we can just use ONYXKEYS.ACCOUNT.isLoading

account: {key: ONYXKEYS.ACCOUNT},
network: {key: ONYXKEYS.NETWORK},
}),
)(LogInWithShortLivedAuthTokenPage);