diff --git a/CHANGELOG.md b/CHANGELOG.md index 766e30fb4..c0c766c58 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,35 @@ # Mailspring Changelog +### 1.0.2 (10/6/2017) + +Fixes: + +- During authentication, you can now view a "Raw Log" of the IMAP and SMTP communication with your servers for easy debugging of connection issues. + +- During authentication, Mailspring will warn you if you connect Gmail via IMAP. + +- The "Install Theme...", "Install a Plugin Manually..." and "Create a Plugin..." menu items now work. Note that Nylas Mail / N1 themes require some modifications to work with Mailspring! + +- On Windows and Linux, Mailspring can now make itself the default mail client. + +- The contact sidebar in the app now works reliably and is rate-limited for free users (The Clearbit API is very expensive!) + +- On Windows, Mailspring now displays emails with encoded subject lines (often containing emoji or foreign characters) correctly. + +- On Windows, you can now resize and maximize the Mailspring window. + +- Mailspring now skips folders it can't sync rather than stopping the entire account. + +### 1.0.1 (10/4/2017) + +Fixes: + +- On Linux, Mailspring now syncs mail reliably thanks to fixed builds of curl and mailcore2. + +- On Windows, the app's icon now includes all the required resolutions. + +- Many other minor fixes and sync improvements. + ### 1.0.0 (10/3/2017) Features: diff --git a/app/src/components/oauth-signin-page.jsx b/app/src/components/oauth-signin-page.jsx deleted file mode 100644 index d8f60e864..000000000 --- a/app/src/components/oauth-signin-page.jsx +++ /dev/null @@ -1,211 +0,0 @@ -import { ipcRenderer, shell } from 'electron'; -import { React, PropTypes, Actions } from 'mailspring-exports'; -import { RetinaImg } from 'mailspring-component-kit'; - -const clipboard = require('electron').clipboard; - -export default class OAuthSignInPage extends React.Component { - static displayName = 'OAuthSignInPage'; - - static propTypes = { - /** - * Step 1: Open a webpage in the user's browser letting them login on - * the native provider's website. We pass along a key and a redirect - * url to a Nylas-owned server - */ - providerAuthPageUrl: PropTypes.string, - - /** - * Step 2: Poll a Nylas server with this function looking for the key. - * Once users complete the auth successfully, Nylas servers will get - * the token and vend it back to us via this url. We need to poll - * since we don't know how long it'll take users to log in on their - * provider's website. - */ - tokenRequestPollFn: PropTypes.func, - - /** - * Once we have the token, we can use that to retrieve the full - * account credentials or establish a direct connection ourselves. - * Some Nylas backends vend all account credentials along with the - * token making this function unnecessary and a no-op. Mailspring - * local sync needs to use the returned OAuth token to establish an - * IMAP connection directly that may have its own set of failure - * cases. - */ - accountFromTokenFn: PropTypes.func, - - /** - * Called once we have successfully received the account data from - * `accountFromTokenFn` - */ - onSuccess: PropTypes.func, - - onTryAgain: PropTypes.func, - iconName: PropTypes.string, - sessionKey: PropTypes.string, - serviceName: PropTypes.string, - }; - - constructor() { - super(); - this.state = { - authStage: 'initial', - showAlternative: false, - }; - } - - componentDidMount() { - // Show the "Sign in to ..." prompt for a moment before bouncing - // to URL. (400msec animation + 200msec to read) - this._pollTimer = null; - this._startTimer = setTimeout(() => { - shell.openExternal(this.props.providerAuthPageUrl); - this.startPollingForResponse(); - }, 600); - setTimeout(() => { - this.setState({ showAlternative: true }); - }, 1500); - } - - componentWillUnmount() { - if (this._startTimer) clearTimeout(this._startTimer); - if (this._pollTimer) clearTimeout(this._pollTimer); - } - - _handleError(err) { - this.setState({ authStage: 'error', errorMessage: err.message }); - AppEnv.reportError(err); - Actions.recordUserEvent('Email Account Auth Failed', { - errorMessage: err.message, - provider: 'gmail', - }); - } - - startPollingForResponse() { - let delay = 1000; - let onWindowFocused = null; - let poll = null; - this.setState({ authStage: 'polling' }); - - onWindowFocused = () => { - delay = 1000; - if (this._pollTimer) { - clearTimeout(this._pollTimer); - this._pollTimer = setTimeout(poll, delay); - } - }; - - poll = async () => { - clearTimeout(this._pollTimer); - try { - const tokenData = await this.props.tokenRequestPollFn(this.props.sessionKey); - ipcRenderer.removeListener('browser-window-focus', onWindowFocused); - this.fetchAccountDataWithToken(tokenData); - } catch (err) { - if (err.statusCode === 404) { - delay = Math.min(delay * 1.1, 3000); - this._pollTimer = setTimeout(poll, delay); - } else { - ipcRenderer.removeListener('browser-window-focus', onWindowFocused); - this._handleError(err); - } - } - }; - - ipcRenderer.on('browser-window-focus', onWindowFocused); - this._pollTimer = setTimeout(poll, 3000); - } - - async fetchAccountDataWithToken(tokenData) { - try { - this.setState({ authStage: 'fetchingAccount' }); - const accountData = await this.props.accountFromTokenFn(tokenData); - this.props.onSuccess(accountData); - this.setState({ authStage: 'accountSuccess' }); - } catch (err) { - this._handleError(err); - } - } - - _renderHeader() { - const authStage = this.state.authStage; - if (authStage === 'initial' || authStage === 'polling') { - return ( -
{this.state.errorMessage}
-- Please try again. If you continue to see this - error contact support@getmailspring.com -
-