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:
Ben Gotow 2016-09-28 11:29:22 -07:00
parent 306a5010fd
commit 6ddca404f5
6 changed files with 48 additions and 51 deletions

View file

@ -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});
});
}

View file

@ -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", () => {

View file

@ -83,7 +83,7 @@ class PreferencesIdentity extends React.Component {
_onRefresh = () => {
this.setState({refreshing: true});
IdentityStore.refreshStatus().finally(() => {
IdentityStore.refreshIdentityAndAccounts().finally(() => {
this.setState({refreshing: false});
});
}

View file

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

View file

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

View file

@ -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));