mirror of
https://github.com/Foundry376/Mailspring.git
synced 2024-11-11 10:12:00 +08:00
fix(auth): Merge but temporarily disable encrpytion during Gmail Oauth
This commit is contained in:
parent
c1b4596bbe
commit
0a891ba8c6
3 changed files with 57 additions and 17 deletions
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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'
|
||||
|
|
Loading…
Reference in a new issue