diff --git a/packages/client-app/internal_packages/onboarding/lib/decorators/create-page-for-form.jsx b/packages/client-app/internal_packages/onboarding/lib/decorators/create-page-for-form.jsx index afb3d66e8..8f26e48a2 100644 --- a/packages/client-app/internal_packages/onboarding/lib/decorators/create-page-for-form.jsx +++ b/packages/client-app/internal_packages/onboarding/lib/decorators/create-page-for-form.jsx @@ -2,7 +2,7 @@ import {shell} from 'electron' import React from 'react'; import ReactDOM from 'react-dom'; import {RetinaImg} from 'nylas-component-kit'; -import {NylasAPI, Actions} from 'nylas-exports'; +import {NylasAPIRequest, Actions} from 'nylas-exports'; import OnboardingActions from '../onboarding-actions'; import {runAuthValidation} from '../onboarding-helpers'; @@ -135,7 +135,7 @@ const CreatePageForForm = (FormComponent) => { errorFieldNames.push('email'); errorFieldNames.push('username'); } - if (NylasAPI.TimeoutErrorCodes.includes(err.statusCode)) { // timeout + if (NylasAPIRequest.TimeoutErrorCodes.includes(err.statusCode)) { // timeout errorMessage = "We were unable to reach your mail provider. Please try again." } diff --git a/packages/client-app/internal_packages/onboarding/lib/onboarding-actions.es6 b/packages/client-app/internal_packages/onboarding/lib/onboarding-actions.es6 index c2602e76f..33904dfdd 100644 --- a/packages/client-app/internal_packages/onboarding/lib/onboarding-actions.es6 +++ b/packages/client-app/internal_packages/onboarding/lib/onboarding-actions.es6 @@ -5,7 +5,7 @@ const OnboardingActions = Reflux.createActions([ "setAccountType", "moveToPreviousPage", "moveToPage", - "authenticationJSONReceived", + "identityJSONReceived", "accountJSONReceived", ]); diff --git a/packages/client-app/internal_packages/onboarding/lib/onboarding-helpers.es6 b/packages/client-app/internal_packages/onboarding/lib/onboarding-helpers.es6 index 9dafc09cf..0bc738957 100644 --- a/packages/client-app/internal_packages/onboarding/lib/onboarding-helpers.es6 +++ b/packages/client-app/internal_packages/onboarding/lib/onboarding-helpers.es6 @@ -3,14 +3,12 @@ import crypto from 'crypto'; import {CommonProviderSettings} from 'imap-provider-settings'; import { - N1CloudAPI, - NylasAPI, NylasAPIRequest, RegExpUtils, - Utils, MailsyncProcess, } from 'nylas-exports'; +const {makeRequest, rootURLForServer} = NylasAPIRequest; const IMAP_FIELDS = new Set([ "imap_host", @@ -41,40 +39,32 @@ function base64url(inBuffer) { .replace(/\//g, '_'); // Convert '/' to '_' } -const NO_AUTH = { user: '', pass: '', sendImmediately: true }; - -export async function makeGmailOAuthRequest(sessionKey) { - const remoteRequest = new NylasAPIRequest({ - api: N1CloudAPI, - options: { - path: `/auth/gmail/token?key=${sessionKey}`, - method: 'GET', - auth: NO_AUTH, - }, +export function makeGmailOAuthRequest(sessionKey) { + return makeRequest({ + server: 'accounts', + path: `/auth/gmail/token?key=${sessionKey}`, + method: 'GET', + auth: false, }); - return remoteRequest.run() } export async function authIMAPForGmail(tokenData) { - const localRequest = new NylasAPIRequest({ - api: NylasAPI, - options: { - path: `/auth`, - method: 'POST', - auth: NO_AUTH, - timeout: 1000 * 90, // Connecting to IMAP could take up to 90 seconds, so we don't want to hang up too soon - body: { - email: tokenData.email_address, - name: tokenData.name, - provider: 'gmail', - settings: { - xoauth2: tokenData.resolved_settings.xoauth2, - expiry_date: tokenData.resolved_settings.expiry_date, - }, + const localJSON = await makeRequest({ + server: 'accounts', + path: `/auth`, + method: 'POST', + auth: false, + timeout: 1000 * 90, // Connecting to IMAP could take up to 90 seconds, so we don't want to hang up too soon + body: { + email: tokenData.email_address, + name: tokenData.name, + provider: 'gmail', + settings: { + xoauth2: tokenData.resolved_settings.xoauth2, + expiry_date: tokenData.resolved_settings.expiry_date, }, }, }) - const localJSON = await localRequest.run() const account = Object.assign({}, localJSON); account.localToken = localJSON.account_token; account.cloudToken = tokenData.account_token; @@ -86,14 +76,14 @@ export function buildGmailSessionKey() { } export function buildGmailAuthURL(sessionKey) { - return `${N1CloudAPI.APIRoot}/auth/gmail?state=${sessionKey}`; + return `${rootURLForServer('accounts')}/auth/gmail?state=${sessionKey}`; } -export function runAuthValidation(accountInfo) { +export async function runAuthValidation(accountInfo) { const {username, type, email, name} = accountInfo; const data = { - id: Utils.generateTempId(), // TODO BG: Server will decide account ids + id: 'temp', provider: type, name: name, emailAddress: email, @@ -123,32 +113,23 @@ export function runAuthValidation(accountInfo) { // If this succeeds, send the received code to N1 server to register the account // Otherwise process the error message from the server and highlight UI as needed const proc = new MailsyncProcess(NylasEnv.getLoadSettings(), data); - return proc.test().then((accountJSON) => { - return accountJSON; - }); + const {account} = await proc.test(); - // TODO BG Re-enable cloud services - // return n1CloudIMAPAuthRequest.run().then((remoteJSON) => { - // const localSyncIMAPAuthRequest = new NylasAPIRequest({ - // api: NylasAPI, - // options: { - // path: `/auth`, - // method: 'POST', - // timeout: 1000 * 180, // Same timeout as server timeout (most requests are faster than 90s, but server validation can be slow in some cases) - // body: data, - // auth: { - // user: '', - // pass: '', - // sendImmediately: true, - // }, - // }, - // }) - // return localSyncIMAPAuthRequest.run().then((localJSON) => { - // const accountWithTokens = Object.assign({}, localJSON); - // accountWithTokens.localToken = localJSON.account_token; - // accountWithTokens.cloudToken = '';//remoteJSON.account_token; - // return accountWithTokens - // }) + delete data.id; + + const {id, account_token} = await makeRequest({ + server: 'accounts', + path: `/auth`, + method: 'POST', + timeout: 1000 * 180, // Same timeout as server timeout (most requests are faster than 90s, but server validation can be slow in some cases) + body: data, + auth: false, + }) + + return { + account: Object.assign({}, account, {id}), + cloudToken: account_token, + }; } export function isValidHost(value) { diff --git a/packages/client-app/internal_packages/onboarding/lib/onboarding-store.es6 b/packages/client-app/internal_packages/onboarding/lib/onboarding-store.es6 index 3b38af44b..7c86f23bc 100644 --- a/packages/client-app/internal_packages/onboarding/lib/onboarding-store.es6 +++ b/packages/client-app/internal_packages/onboarding/lib/onboarding-store.es6 @@ -18,13 +18,10 @@ class OnboardingStore extends NylasStore { constructor() { super(); - NylasEnv.config.onDidChange('env', this._onEnvChanged); - this._onEnvChanged(); - this.listenTo(OnboardingActions.moveToPreviousPage, this._onMoveToPreviousPage) this.listenTo(OnboardingActions.moveToPage, this._onMoveToPage) this.listenTo(OnboardingActions.accountJSONReceived, this._onAccountJSONReceived) - this.listenTo(OnboardingActions.authenticationJSONReceived, this._onAuthenticationJSONReceived) + this.listenTo(OnboardingActions.identityJSONReceived, this._onIdentityJSONReceived) this.listenTo(OnboardingActions.setAccountInfo, this._onSetAccountInfo); this.listenTo(OnboardingActions.setAccountType, this._onSetAccountType); ipcRenderer.on('set-account-type', (e, type) => { @@ -80,19 +77,6 @@ class OnboardingStore extends NylasStore { } } - _onEnvChanged = () => { - const env = NylasEnv.config.get('env') - if (['development', 'local'].includes(env)) { - this.welcomeRoot = "http://0.0.0.0:5555"; - } else if (env === 'experimental') { - this.welcomeRoot = "https://www-experimental.nylas.com"; - } else if (env === 'staging') { - this.welcomeRoot = "https://www-staging.nylas.com"; - } else { - this.welcomeRoot = "https://nylas.com"; - } - } - _onOnboardingComplete = () => { // When account JSON is received, we want to notify external services // that it succeeded. Unfortunately in this case we're likely to @@ -137,7 +121,7 @@ class OnboardingStore extends NylasStore { this.trigger(); } - _onAuthenticationJSONReceived = async (json) => { + _onIdentityJSONReceived = async (json) => { const isFirstAccount = AccountStore.accounts().length === 0; await IdentityStore.saveIdentity(json); @@ -145,8 +129,8 @@ class OnboardingStore extends NylasStore { setTimeout(() => { if (isFirstAccount) { this._onSetAccountInfo(Object.assign({}, this._accountInfo, { - name: `${json.firstname || ""} ${json.lastname || ""}`, - email: json.email, + name: `${json.firstName || ""} ${json.lastName || ""}`, + email: json.emailAddress, })); OnboardingActions.moveToPage('account-choose'); } else { diff --git a/packages/client-app/internal_packages/onboarding/lib/page-authenticate.jsx b/packages/client-app/internal_packages/onboarding/lib/page-authenticate.jsx index 1045ace3d..f4ff34e65 100644 --- a/packages/client-app/internal_packages/onboarding/lib/page-authenticate.jsx +++ b/packages/client-app/internal_packages/onboarding/lib/page-authenticate.jsx @@ -1,5 +1,5 @@ import React from 'react'; -import {IdentityStore} from 'nylas-exports'; +import {NylasAPIRequest} from 'nylas-exports'; import {Webview} from 'nylas-component-kit'; import OnboardingActions from './onboarding-actions'; @@ -12,18 +12,18 @@ export default class AuthenticatePage extends React.Component { _src() { const n1Version = NylasEnv.getVersion(); - return `${IdentityStore.URLRoot}/onboarding?utm_medium=N1&utm_source=OnboardingPage&N1_version=${n1Version}&client_edition=basic` + return `${NylasAPIRequest.rootURLForServer('identity')}/onboarding?utm_medium=N1&utm_source=OnboardingPage&N1_version=${n1Version}&client_edition=basic` } _onDidFinishLoad = (webview) => { const receiveUserInfo = ` - var a = document.querySelector('#pro-account'); + var a = document.querySelector('#identity-result'); result = a ? a.innerText : null; `; webview.executeJavaScript(receiveUserInfo, false, (result) => { this.setState({ready: true, webviewLoading: false}); if (result !== null) { - OnboardingActions.authenticationJSONReceived(JSON.parse(result)); + OnboardingActions.identityJSONReceived(JSON.parse(atob(result))); } }); diff --git a/packages/client-app/internal_packages/onboarding/lib/page-initial-preferences.cjsx b/packages/client-app/internal_packages/onboarding/lib/page-initial-preferences.cjsx index 510c657ea..55389539e 100644 --- a/packages/client-app/internal_packages/onboarding/lib/page-initial-preferences.cjsx +++ b/packages/client-app/internal_packages/onboarding/lib/page-initial-preferences.cjsx @@ -3,7 +3,7 @@ path = require 'path' fs = require 'fs' _ = require 'underscore' {RetinaImg, Flexbox, ConfigPropContainer, NewsletterSignup} = require 'nylas-component-kit' -{EdgehillAPI, AccountStore} = require 'nylas-exports' +{AccountStore} = require 'nylas-exports' OnboardingActions = require('./onboarding-actions').default # NOTE: Temporarily copied from preferences module diff --git a/packages/client-app/internal_packages/participant-profile/lib/clearbit-data-source.coffee b/packages/client-app/internal_packages/participant-profile/lib/clearbit-data-source.coffee index 523a6de3c..f6626e5e7 100644 --- a/packages/client-app/internal_packages/participant-profile/lib/clearbit-data-source.coffee +++ b/packages/client-app/internal_packages/participant-profile/lib/clearbit-data-source.coffee @@ -1,5 +1,5 @@ # This file is in coffeescript just to use the existential operator! -{AccountStore, LegacyEdgehillAPI} = require 'nylas-exports' +{AccountStore} = require 'nylas-exports' MAX_RETRY = 10 @@ -12,7 +12,7 @@ module.exports = class ClearbitDataSource return Promise.resolve(null) new Promise (resolve, reject) => return; # TODO BG - req = LegacyEdgehillAPI.makeRequest({ + req = LegacyEdXgehillAPI.makeRequest({ authWithNylasAPI: true path: "/proxy/clearbit/#{@clearbitAPI()}/find?email=#{email}", }) diff --git a/packages/client-app/internal_packages/preferences/lib/tabs/preferences-identity.jsx b/packages/client-app/internal_packages/preferences/lib/tabs/preferences-identity.jsx index 2d6aed4ca..6a8280c45 100644 --- a/packages/client-app/internal_packages/preferences/lib/tabs/preferences-identity.jsx +++ b/packages/client-app/internal_packages/preferences/lib/tabs/preferences-identity.jsx @@ -67,7 +67,7 @@ class PreferencesIdentity extends React.Component { render() { const {identity} = this.state; - const {firstname, lastname, email} = identity; + const {firstName, lastName, emailAddress} = identity; const logout = () => Actions.logoutNylasIdentity() @@ -83,8 +83,8 @@ class PreferencesIdentity extends React.Component { />
-
{firstname} {lastname}
-
{email}
+
{firstName} {lastName}
+
{emailAddress}
Sign Out
diff --git a/packages/client-app/package.json b/packages/client-app/package.json index 4622d29e9..e6b5a2a50 100644 --- a/packages/client-app/package.json +++ b/packages/client-app/package.json @@ -35,9 +35,10 @@ "enzyme": "2.9.1", "event-kit": "^1.0.2", "fs-plus": "^2.3.2", + "getmac": "^1.2.1", "he": "1.1.0", - "is-online": "7.0.0", "imap-provider-settings": "github:nylas/imap-provider-settings#2fdcd34d59b", + "is-online": "7.0.0", "jasmine-json": "~0.0", "jasmine-react-helpers": "^0.2", "jasmine-reporters": "1.x.x", diff --git a/packages/client-app/spec/stores/identity-store-spec.es6 b/packages/client-app/spec/stores/identity-store-spec.es6 index 6caccae3f..a637a79fa 100644 --- a/packages/client-app/spec/stores/identity-store-spec.es6 +++ b/packages/client-app/spec/stores/identity-store-spec.es6 @@ -1,6 +1,7 @@ import {ipcRenderer} from 'electron'; import {Utils, KeyManager, DatabaseWriter, SendFeatureUsageEventTask} from 'nylas-exports' import IdentityStore from '../../src/flux/stores/identity-store' +import * as NylasAPIRequest from '../../src/flux/nylas-api-request' const TEST_NYLAS_ID = "icihsnqh4pwujyqihlrj70vh" const TEST_TOKEN = "test-token" @@ -67,13 +68,13 @@ describe("IdentityStore", function identityStoreSpec() { it("can log a feature usage event", async () => { spyOn(IdentityStore, "saveIdentity").andReturn(Promise.resolve()); - spyOn(IdentityStore, "nylasIDRequest"); + spyOn(NylasAPIRequest, "makeRequest"); IdentityStore._identity = this.identityJSON IdentityStore._identity.token = TEST_TOKEN; IdentityStore._onEnvChanged() const t = new SendFeatureUsageEventTask("snooze"); await t.performRemote() - const opts = IdentityStore.nylasIDRequest.calls[0].args[0] + const opts = NylasAPIRequest.makeRequest.calls[0].args[0] expect(opts).toEqual({ method: "POST", url: "https://billing.nylas.com/api/feature_usage_event", @@ -104,7 +105,7 @@ describe("IdentityStore", function identityStoreSpec() { }); }); - describe("_fetchIdentity", () => { + describe("fetchIdentity", () => { beforeEach(() => { IdentityStore._identity = this.identityJSON; spyOn(IdentityStore, "saveIdentity") @@ -115,12 +116,12 @@ describe("IdentityStore", function identityStoreSpec() { it("saves the identity returned", async () => { const resp = Utils.deepClone(this.identityJSON); resp.feature_usage.feat.quota = 5 - spyOn(IdentityStore, "nylasIDRequest").andCallFake(() => { + spyOn(NylasAPIRequest, "makeRequest").andCallFake(() => { return Promise.resolve(resp) }) - await IdentityStore._fetchIdentity(); - expect(IdentityStore.nylasIDRequest).toHaveBeenCalled(); - const options = IdentityStore.nylasIDRequest.calls[0].args[0] + await IdentityStore.fetchIdentity(); + expect(NylasAPIRequest.makeRequest).toHaveBeenCalled(); + const options = NylasAPIRequest.makeRequest.calls[0].args[0] expect(options.url).toMatch(/\/n1\/user/) expect(IdentityStore.saveIdentity).toHaveBeenCalled() const newIdent = IdentityStore.saveIdentity.calls[0].args[0] @@ -129,10 +130,10 @@ describe("IdentityStore", function identityStoreSpec() { }); it("errors if the json is invalid", async () => { - spyOn(IdentityStore, "nylasIDRequest").andCallFake(() => { + spyOn(NylasAPIRequest, "makeRequest").andCallFake(() => { return Promise.resolve({}) }) - await IdentityStore._fetchIdentity(); + await IdentityStore.fetchIdentity(); expect(NylasEnv.reportError).toHaveBeenCalled() expect(IdentityStore.saveIdentity).not.toHaveBeenCalled() }); @@ -140,10 +141,10 @@ describe("IdentityStore", function identityStoreSpec() { it("errors if the json doesn't match the ID", async () => { const resp = Utils.deepClone(this.identityJSON); resp.id = "THE WRONG ID" - spyOn(IdentityStore, "nylasIDRequest").andCallFake(() => { + spyOn(NylasAPIRequest, "makeRequest").andCallFake(() => { return Promise.resolve(resp) }) - await IdentityStore._fetchIdentity(); + await IdentityStore.fetchIdentity(); expect(NylasEnv.reportError).toHaveBeenCalled() expect(IdentityStore.saveIdentity).not.toHaveBeenCalled() }); diff --git a/packages/client-app/spec/tasks/change-folder-task-spec.coffee b/packages/client-app/spec/tasks/change-folder-task-spec.coffee index cf5b05004..a9a7a74c6 100644 --- a/packages/client-app/spec/tasks/change-folder-task-spec.coffee +++ b/packages/client-app/spec/tasks/change-folder-task-spec.coffee @@ -3,7 +3,6 @@ Folder = require('../../src/flux/models/folder').default Thread = require('../../src/flux/models/thread').default Message = require('../../src/flux/models/message').default Actions = require('../../src/flux/actions').default -NylasAPI = require('../../src/flux/nylas-api').default Query = require('../../src/flux/models/query').default DatabaseStore = require('../../src/flux/stores/database-store').default ChangeFolderTask = require('../../src/flux/tasks/change-folder-task').default diff --git a/packages/client-app/spec/tasks/change-labels-task-spec.coffee b/packages/client-app/spec/tasks/change-labels-task-spec.coffee index ca525fa6d..317b42b98 100644 --- a/packages/client-app/spec/tasks/change-labels-task-spec.coffee +++ b/packages/client-app/spec/tasks/change-labels-task-spec.coffee @@ -3,7 +3,6 @@ Label = require('../../src/flux/models/label').default Thread = require('../../src/flux/models/thread').default Message = require('../../src/flux/models/message').default Actions = require('../../src/flux/actions').default -NylasAPI = require('../../src/flux/nylas-api').default DatabaseStore = require('../../src/flux/stores/database-store').default ChangeLabelsTask = require('../../src/flux/tasks/change-labels-task').default ChangeMailTask = require('../../src/flux/tasks/change-mail-task').default diff --git a/packages/client-app/spec/tasks/send-draft-task-spec.es6 b/packages/client-app/spec/tasks/send-draft-task-spec.es6 index 89bbcca10..10ad47073 100644 --- a/packages/client-app/spec/tasks/send-draft-task-spec.es6 +++ b/packages/client-app/spec/tasks/send-draft-task-spec.es6 @@ -8,8 +8,6 @@ import { Contact, Task, SendDraftTask, - NylasAPI, - NylasAPIHelpers, NylasAPIRequest, SoundRegistry, SyncbackMetadataTask, diff --git a/packages/client-app/src/components/evented-iframe.cjsx b/packages/client-app/src/components/evented-iframe.cjsx index a5061924c..259029422 100644 --- a/packages/client-app/src/components/evented-iframe.cjsx +++ b/packages/client-app/src/components/evented-iframe.cjsx @@ -3,12 +3,15 @@ ReactDOM = require 'react-dom' {Utils, RegExpUtils, IdentityStore, + NylasAPIRequest, SearchableComponentMaker, - SearchableComponentStore}= require 'nylas-exports' + SearchableComponentStore} = require 'nylas-exports' IFrameSearcher = require('../searchable-components/iframe-searcher').default url = require 'url' _ = require "underscore" +{rootURLForServer} = NylasAPIRequest + ### Public: EventedIFrame is a thin wrapper around the DOM's standard `