2014-01-03 13:32:13 -05:00
|
|
|
CocoClass = require 'lib/CocoClass'
|
2014-04-02 16:12:24 -04:00
|
|
|
{me} = require 'lib/auth'
|
2014-01-03 13:32:13 -05:00
|
|
|
{backboneFailure} = require 'lib/errors'
|
2014-01-26 17:44:08 -05:00
|
|
|
storage = require 'lib/storage'
|
2014-03-23 12:30:01 -04:00
|
|
|
GPLUS_TOKEN_KEY = 'gplusToken'
|
2014-01-03 13:32:13 -05:00
|
|
|
|
|
|
|
# gplus user object props to
|
|
|
|
userPropsToSave =
|
|
|
|
'name.givenName': 'firstName'
|
|
|
|
'name.familyName': 'lastName'
|
|
|
|
'gender': 'gender'
|
|
|
|
'id': 'gplusID'
|
|
|
|
|
|
|
|
fieldsToFetch = 'displayName,gender,image,name(familyName,givenName),id'
|
|
|
|
plusURL = '/plus/v1/people/me?fields='+fieldsToFetch
|
|
|
|
revokeUrl = 'https://accounts.google.com/o/oauth2/revoke?token='
|
|
|
|
clientID = "800329290710-j9sivplv2gpcdgkrsis9rff3o417mlfa.apps.googleusercontent.com"
|
2014-03-23 12:30:01 -04:00
|
|
|
scope = "https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/userinfo.email"
|
2014-01-03 13:32:13 -05:00
|
|
|
|
|
|
|
module.exports = GPlusHandler = class GPlusHandler extends CocoClass
|
|
|
|
constructor: ->
|
2014-03-23 12:30:01 -04:00
|
|
|
@accessToken = storage.load GPLUS_TOKEN_KEY
|
2014-01-03 13:32:13 -05:00
|
|
|
super()
|
|
|
|
|
|
|
|
subscriptions:
|
|
|
|
'gplus-logged-in':'onGPlusLogin'
|
2014-03-23 12:30:01 -04:00
|
|
|
'gapi-loaded':'onGPlusLoaded'
|
2014-01-03 13:32:13 -05:00
|
|
|
|
2014-03-23 12:30:01 -04:00
|
|
|
onGPlusLoaded: ->
|
|
|
|
session_state = null
|
|
|
|
if @accessToken
|
|
|
|
# We need to check the current state, given our access token
|
|
|
|
gapi.auth.setToken 'token', @accessToken
|
|
|
|
session_state = @accessToken.session_state
|
|
|
|
gapi.auth.checkSessionState({client_id:clientID, session_state:session_state}, @onCheckedSessionState)
|
|
|
|
else
|
|
|
|
# If we ran checkSessionState, it might return true, that the user is logged into Google, but has not authorized us
|
|
|
|
@loggedIn = false
|
|
|
|
func = => @trigger 'checked-state'
|
|
|
|
setTimeout func, 1
|
|
|
|
|
|
|
|
onCheckedSessionState: (@loggedIn) =>
|
|
|
|
@trigger 'checked-state'
|
2014-01-03 13:32:13 -05:00
|
|
|
|
2014-03-23 12:30:01 -04:00
|
|
|
reauthorize: ->
|
|
|
|
params =
|
|
|
|
'client_id' : clientID
|
|
|
|
'scope' : scope
|
|
|
|
gapi.auth.authorize params, @onGPlusLogin
|
2014-04-13 17:48:36 -04:00
|
|
|
|
2014-03-23 12:30:01 -04:00
|
|
|
onGPlusLogin: (e) =>
|
|
|
|
@loggedIn = true
|
|
|
|
storage.save(GPLUS_TOKEN_KEY, e)
|
|
|
|
@accessToken = e
|
|
|
|
@trigger 'logged-in'
|
2014-04-13 17:48:36 -04:00
|
|
|
return if (not me) or me.get 'gplusID' # so only get more data
|
|
|
|
|
2014-01-03 13:32:13 -05:00
|
|
|
# email and profile data loaded separately
|
|
|
|
@responsesComplete = 0
|
|
|
|
gapi.client.request(path:plusURL, callback:@onPersonEntityReceived)
|
|
|
|
gapi.client.load('oauth2', 'v2', =>
|
|
|
|
gapi.client.oauth2.userinfo.get().execute(@onEmailReceived))
|
|
|
|
|
|
|
|
shouldSave: false
|
|
|
|
responsesComplete: 0
|
|
|
|
|
|
|
|
onPersonEntityReceived: (r) =>
|
|
|
|
for gpProp, userProp of userPropsToSave
|
|
|
|
keys = gpProp.split('.')
|
|
|
|
value = r
|
|
|
|
value = value[key] for key in keys
|
|
|
|
if value and not me.get(userProp)
|
|
|
|
@shouldSave = true
|
|
|
|
me.set(userProp, value)
|
|
|
|
|
|
|
|
@responsesComplete += 1
|
|
|
|
@saveIfAllDone()
|
|
|
|
|
|
|
|
onEmailReceived: (r) =>
|
|
|
|
newEmail = r.email and r.email isnt me.get('email')
|
|
|
|
return unless newEmail or me.get('anonymous')
|
|
|
|
me.set('email', r.email)
|
|
|
|
@shouldSave = true
|
|
|
|
@responsesComplete += 1
|
|
|
|
@saveIfAllDone()
|
|
|
|
|
|
|
|
saveIfAllDone: =>
|
|
|
|
return unless @responsesComplete is 2
|
|
|
|
return unless me.get('email') and me.get('gplusID')
|
|
|
|
|
|
|
|
Backbone.Mediator.publish('logging-in-with-gplus')
|
|
|
|
gplusID = me.get('gplusID')
|
|
|
|
window.tracker?.trackEvent 'Google Login'
|
|
|
|
window.tracker?.identify()
|
2014-01-08 17:57:42 -05:00
|
|
|
patch = {}
|
|
|
|
patch[key] = me.get(key) for gplusKey, key of userPropsToSave
|
|
|
|
patch._id = me.id
|
|
|
|
patch.email = me.get('email')
|
2014-03-23 12:30:01 -04:00
|
|
|
wasAnonymous = me.get('anonymous')
|
2014-01-08 17:57:42 -05:00
|
|
|
me.save(patch, {
|
|
|
|
patch: true
|
2014-01-03 13:32:13 -05:00
|
|
|
error: backboneFailure,
|
2014-03-23 12:30:01 -04:00
|
|
|
url: "/db/user?gplusID=#{gplusID}&gplusAccessToken=#{@accessToken.access_token}"
|
2014-01-03 13:32:13 -05:00
|
|
|
success: (model) ->
|
2014-03-23 12:30:01 -04:00
|
|
|
window.location.reload() if wasAnonymous and not model.get('anonymous')
|
2014-01-03 13:32:13 -05:00
|
|
|
})
|
2014-04-13 17:48:36 -04:00
|
|
|
|
2014-03-23 12:30:01 -04:00
|
|
|
loadFriends: (friendsCallback) ->
|
|
|
|
return friendsCallback() unless @loggedIn
|
2014-04-13 17:48:36 -04:00
|
|
|
expiresIn = if @accessToken then parseInt(@accessToken.expires_at) - new Date().getTime()/1000 else -1
|
2014-03-23 12:30:01 -04:00
|
|
|
onReauthorized = => gapi.client.request({path:'/plus/v1/people/me/people/visible', callback: friendsCallback})
|
2014-04-13 17:48:36 -04:00
|
|
|
if expiresIn < 0
|
|
|
|
# TODO: this tries to open a popup window, which might not ever finish or work, so the callback may never be called.
|
2014-03-23 12:30:01 -04:00
|
|
|
@reauthorize()
|
|
|
|
@listenToOnce(@, 'logged-in', onReauthorized)
|
|
|
|
else
|
|
|
|
onReauthorized()
|