mirror of
https://github.com/Foundry376/Mailspring.git
synced 2025-03-06 21:17:09 +08:00
fix(identity): Always refresh accounts after identity
This fixes an issue where changing your Nylas ID didn’t refresh your accounts, and N1 would still think they were invalid.
This commit is contained in:
parent
306a5010fd
commit
6ddca404f5
6 changed files with 48 additions and 51 deletions
|
@ -51,16 +51,13 @@ export default class AccountErrorHeader extends React.Component {
|
|||
}
|
||||
|
||||
_onCheckAgain = (event) => {
|
||||
const errorAccounts = this.state.accounts.filter(a => a.hasSyncStateError());
|
||||
this.setState({refreshing: true});
|
||||
|
||||
event.stopPropagation();
|
||||
|
||||
IdentityStore.refreshStatus().finally(() => {
|
||||
AccountStore.refreshHealthOfAccounts(errorAccounts.map(a => a.id)).finally(() => {
|
||||
if (!this.mounted) { return; }
|
||||
this.setState({refreshing: false});
|
||||
});
|
||||
IdentityStore.refreshIdentityAndAccounts().finally(() => {
|
||||
if (!this.mounted) { return; }
|
||||
this.setState({refreshing: false});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -20,12 +20,9 @@ describe("AccountErrorHeader", function AccountErrorHeaderTests() {
|
|||
|
||||
it("allows the user to refresh the account", () => {
|
||||
const header = mount(<AccountErrorHeader />);
|
||||
spyOn(IdentityStore, 'refreshStatus').andReturn(Promise.resolve());
|
||||
spyOn(AccountStore, 'refreshHealthOfAccounts').andReturn(Promise.resolve());
|
||||
spyOn(IdentityStore, 'refreshIdentityAndAccounts').andReturn(Promise.resolve());
|
||||
header.find('.action.refresh').simulate('click');
|
||||
expect(IdentityStore.refreshStatus).toHaveBeenCalled();
|
||||
advanceClock();
|
||||
expect(AccountStore.refreshHealthOfAccounts).toHaveBeenCalledWith(['A']);
|
||||
expect(IdentityStore.refreshIdentityAndAccounts).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("allows the user to reconnect the account", () => {
|
||||
|
@ -53,12 +50,9 @@ describe("AccountErrorHeader", function AccountErrorHeaderTests() {
|
|||
|
||||
it("allows the user to refresh the accounts", () => {
|
||||
const header = mount(<AccountErrorHeader />);
|
||||
spyOn(IdentityStore, 'refreshStatus').andReturn(Promise.resolve());
|
||||
spyOn(AccountStore, 'refreshHealthOfAccounts').andReturn(Promise.resolve());
|
||||
spyOn(IdentityStore, 'refreshIdentityAndAccounts').andReturn(Promise.resolve());
|
||||
header.find('.action.refresh').simulate('click');
|
||||
expect(IdentityStore.refreshStatus).toHaveBeenCalled();
|
||||
advanceClock();
|
||||
expect(AccountStore.refreshHealthOfAccounts).toHaveBeenCalledWith(['A', 'B']);
|
||||
expect(IdentityStore.refreshIdentityAndAccounts).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("allows the user to open preferences", () => {
|
||||
|
|
|
@ -83,7 +83,7 @@ class PreferencesIdentity extends React.Component {
|
|||
|
||||
_onRefresh = () => {
|
||||
this.setState({refreshing: true});
|
||||
IdentityStore.refreshStatus().finally(() => {
|
||||
IdentityStore.refreshIdentityAndAccounts().finally(() => {
|
||||
this.setState({refreshing: false});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -79,21 +79,6 @@ describe "AccountStore", ->
|
|||
expect(@instance.tokenForAccountId('A')).toEqual('A-TOKEN')
|
||||
expect(@instance.tokenForAccountId('B')).toEqual('B-TOKEN')
|
||||
|
||||
describe "in the work window and running on production", ->
|
||||
it "should refresh the accounts", ->
|
||||
spyOn(NylasEnv, 'isWorkWindow').andReturn(true)
|
||||
@instance = new @constructor
|
||||
spyOn(@instance, 'refreshHealthOfAccounts')
|
||||
advanceClock(10000)
|
||||
expect(@instance.refreshHealthOfAccounts).toHaveBeenCalledWith(['A', 'B'])
|
||||
|
||||
describe "in the main window", ->
|
||||
it "should not refresh the accounts", ->
|
||||
@instance = new @constructor
|
||||
spyOn(@instance, 'refreshHealthOfAccounts')
|
||||
advanceClock(10000)
|
||||
expect(@instance.refreshHealthOfAccounts).not.toHaveBeenCalled()
|
||||
|
||||
describe "accountForEmail", ->
|
||||
beforeEach ->
|
||||
@instance = new @constructor
|
||||
|
|
|
@ -26,11 +26,6 @@ class AccountStore extends NylasStore
|
|||
@listenTo Actions.updateAccount, @_onUpdateAccount
|
||||
@listenTo Actions.reorderAccount, @_onReorderAccount
|
||||
|
||||
if NylasEnv.isWorkWindow() and ['staging', 'production'].includes(NylasEnv.config.get('env'))
|
||||
setTimeout( =>
|
||||
@refreshHealthOfAccounts(@_accounts.map((a) -> a.id))
|
||||
, 2000)
|
||||
|
||||
NylasEnv.config.onDidChange configVersionKey, (change) =>
|
||||
# If we already have this version of the accounts config, it means we
|
||||
# are the ones who saved the change, and we don't need to reload.
|
||||
|
|
|
@ -7,6 +7,7 @@ import Moment from 'moment-timezone';
|
|||
|
||||
import Actions from '../actions';
|
||||
import AccountStore from './account-store';
|
||||
import Utils from '../models/utils';
|
||||
|
||||
const configIdentityKey = "nylas.identity";
|
||||
const keytarServiceName = 'Nylas';
|
||||
|
@ -35,13 +36,16 @@ class IdentityStore extends NylasStore {
|
|||
NylasEnv.config.onDidChange(configIdentityKey, () => {
|
||||
this._loadIdentity();
|
||||
this.trigger();
|
||||
if (NylasEnv.isMainWindow()) {
|
||||
this.refreshAccounts();
|
||||
}
|
||||
});
|
||||
|
||||
this._loadIdentity();
|
||||
|
||||
if (NylasEnv.isMainWindow() && ['staging', 'production'].includes(NylasEnv.config.get('env'))) {
|
||||
setInterval(this.refreshStatus, 1000 * 60 * 60);
|
||||
this.refreshStatus();
|
||||
setInterval(this.refreshIdentityAndAccounts, 1000 * 60 * 60); // 1 hour
|
||||
this.refreshIdentityAndAccounts();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -102,20 +106,28 @@ class IdentityStore extends NylasStore {
|
|||
return Math.max(0, requiredDayOfEpoch - nowDayOfEpoch);
|
||||
}
|
||||
|
||||
refreshStatus = () => {
|
||||
return Promise.all([
|
||||
this.fetchIdentity(),
|
||||
Promise.all(AccountStore.accounts().map((a) =>
|
||||
this.fetchSubscriptionRequiredDate(a))
|
||||
).then((subscriptionRequiredDates) => {
|
||||
this._subscriptionRequiredAfter = subscriptionRequiredDates.sort().shift();
|
||||
this.trigger();
|
||||
}),
|
||||
]).catch((err) => {
|
||||
refreshIdentityAndAccounts = () => {
|
||||
return this.fetchIdentity().then(() =>
|
||||
this.refreshAccounts()
|
||||
).catch((err) => {
|
||||
console.error(`Unable to refresh IdentityStore status: ${err.message}`)
|
||||
});
|
||||
}
|
||||
|
||||
refreshAccounts = () => {
|
||||
const accountIds = AccountStore.accounts().map((a) => a.id);
|
||||
AccountStore.refreshHealthOfAccounts(accountIds);
|
||||
|
||||
return Promise.all(AccountStore.accounts().map((a) =>
|
||||
this.fetchSubscriptionRequiredDate(a))
|
||||
).then((subscriptionRequiredDates) => {
|
||||
this._subscriptionRequiredAfter = subscriptionRequiredDates.sort().shift();
|
||||
this.trigger();
|
||||
}).catch((err) => {
|
||||
console.error(`Unable to refresh IdentityStore accounts: ${err.message}`)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* This passes utm_source, utm_campaign, and utm_content params to the
|
||||
* N1 billing site. Please reference:
|
||||
|
@ -184,15 +196,29 @@ class IdentityStore extends NylasStore {
|
|||
|
||||
fetchPath = (path) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
request({
|
||||
const requestId = Utils.generateTempId();
|
||||
const options = {
|
||||
method: 'GET',
|
||||
url: `${this.URLRoot}${path}`,
|
||||
startTime: Date.now(),
|
||||
auth: {
|
||||
username: this._identity.token,
|
||||
password: '',
|
||||
sendImmediately: true,
|
||||
},
|
||||
}, (error, response = {}, body) => {
|
||||
};
|
||||
|
||||
Actions.willMakeAPIRequest({
|
||||
request: options,
|
||||
requestId: requestId,
|
||||
});
|
||||
request(options, (error, response = {}, body) => {
|
||||
Actions.didMakeAPIRequest({
|
||||
request: options,
|
||||
statusCode: response.statusCode,
|
||||
error: error,
|
||||
requestId: requestId,
|
||||
});
|
||||
if (response.statusCode === 200) {
|
||||
try {
|
||||
return resolve(JSON.parse(body));
|
||||
|
|
Loading…
Reference in a new issue