fix(auth): Merge but temporarily disable encrpytion during Gmail Oauth

This commit is contained in:
Ben Gotow 2015-10-05 03:27:28 -07:00
parent c1b4596bbe
commit 0a891ba8c6
3 changed files with 57 additions and 17 deletions

View file

@ -61,15 +61,33 @@ class AccountChoosePage extends React.Component
, 600
OnboardingActions.moveToPage("account-settings", {provider})
_base64url: (buf) ->
# Python-style urlsafe_b64encode
buf.toString('base64')
.replace(/\+/g, '-') # Convert '+' to '-'
.replace(/\//g, '_') # Convert '/' to '_'
_onBounceToGmail: (provider) =>
provider.clientKey = Utils.generateTempId()[6..]+'-'+Utils.generateTempId()[6..]
shell = require 'shell'
crypto = require 'crypto'
# Client key is used for polling. Requirements are that it not be guessable
# and that it never collides with an active key (keys are active only between
# initiating gmail auth and successfully requesting the account data once.
provider.clientKey = @_base64url(crypto.randomBytes(40))
# Encryption key is used to AES encrypt the account data during storage on the
# server.
provider.encryptionKey = crypto.randomBytes(24)
provider.encryptionIv = crypto.randomBytes(16)
code = atom.config.get('edgehill.token') || ''
state = [provider.clientKey,@_base64url(provider.encryptionKey),@_base64url(provider.encryptionIv),code].join(',')
googleUrl = url.format({
protocol: 'https'
host: 'accounts.google.com/o/oauth2/auth'
query:
response_type: 'code'
state: provider.clientKey
state: state
client_id: '372024217839-cdsnrrqfr4d6b4gmlqepd7v0n0l0ip9q.apps.googleusercontent.com'
redirect_uri: "#{EdgehillAPI.APIRoot}/oauth/google/callback"
access_type: 'offline'
@ -80,6 +98,7 @@ class AccountChoosePage extends React.Component
https://www.googleapis.com/auth/calendar'
approval_prompt: 'force'
})
shell = require 'shell'
shell.openExternal(googleUrl)
module.exports = AccountChoosePage

View file

@ -1,14 +1,15 @@
React = require 'react'
remote = require 'remote'
dialog = remote.require 'dialog'
Crypto = require 'crypto'
ipc = require 'ipc'
{RetinaImg} = require 'nylas-component-kit'
{EdgehillAPI, NylasAPI, APIError} = require 'nylas-exports'
OnboardingActions = require './onboarding-actions'
NylasApiEnvironmentStore = require './nylas-api-environment-store'
Providers = require './account-types'
remote = require('remote')
dialog = remote.require('dialog')
class AccountSettingsPage extends React.Component
@displayName: "AccountSettingsPage"
@ -27,8 +28,10 @@ class AccountSettingsPage extends React.Component
if field.default?
@state.settings[field.name] = field.default
# Special case for gmail. Rather than showing a form, we poll in the
# background for completion of the gmail auth on the server.
if @state.provider.name is 'gmail'
poll_attempt_id = 0
pollAttemptId = 0
done = false
# polling with capped exponential backoff
delay = 1000
@ -36,22 +39,34 @@ class AccountSettingsPage extends React.Component
poll = (id,initial_delay) =>
_retry = =>
tries++
@_pollForGmailAccount((account) ->
if account?
@_pollForGmailAccount((account_data) =>
if account_data?
done = true
{data} = account_data
# accountJson = @_decrypt(data, @state.provider.encryptionKey, @state.provider.encryptionIv)
account = JSON.parse(data)
OnboardingActions.accountJSONReceived(account)
else if tries < 10 and id is poll_attempt_id
else if tries < 20 and id is pollAttemptId
setTimeout(_retry, delay)
delay *= 1.5 # exponential backoff
delay *= 1.2 # exponential backoff
)
setTimeout(_retry,initial_delay)
ipc.on('browser-window-focus', ->
if not done # hack to deactivate this listener when done
poll_attempt_id++
poll(poll_attempt_id,0)
pollAttemptId++
poll(pollAttemptId,0)
)
poll(poll_attempt_id,2000)
poll(pollAttemptId,5000)
_decrypt: (encrypted, key, iv) ->
decipher = Crypto.createDecipheriv('aes-192-cbc', key, iv)
# The server pads the cyphertext with an extra block of all spaces at the end,
# to avoid having to call .final() here which seems to be broken...
dec = decipher.update(encrypted,'hex','utf8')
#dec += decipher.final('utf8');
return dec
componentDidMount: ->
@ -226,15 +241,21 @@ class AccountSettingsPage extends React.Component
pass: ''
sendImmediately: true
.then (json) =>
json.invite_code = atom.config.get('edgehill.token')
invite_code = atom.config.get('edgehill.token')
json.invite_code = invite_code
json.email = data.email
EdgehillAPI.request
path: "/connect/nylas"
method: "POST"
timeout: 30000
body: json
success: (json) =>
OnboardingActions.accountJSONReceived(json)
OnboardingActions.accountJSONReceived({
code: json.code,
invite_code: invite_code
})
error: @_onNetworkError
.catch(@_onNetworkError)

View file

@ -18,7 +18,7 @@ class EdgehillAPI
_onConfigChanged: =>
env = atom.config.get('env')
if env is 'development'
@APIRoot = "https://edgehill-dev.nylas.com"
@APIRoot = "http://localhost:5009"
else if env is 'experimental'
@APIRoot = "https://edgehill-experimental.nylas.com"
else if env is 'staging'