2014-01-03 10:32:13 -08:00
CocoClass = require ' lib/CocoClass '
2014-04-02 13:12:24 -07:00
{ me } = require ' lib/auth '
2014-01-03 10:32:13 -08:00
{ backboneFailure } = require ' lib/errors '
2014-01-26 14:44:08 -08:00
storage = require ' lib/storage '
2014-03-23 09:30:01 -07:00
GPLUS_TOKEN_KEY = ' gplusToken '
2014-01-03 10:32:13 -08: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= '
2014-07-01 10:16:26 +08:00
clientID = ' 800329290710-j9sivplv2gpcdgkrsis9rff3o417mlfa.apps.googleusercontent.com '
scope = ' https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/userinfo.email '
2014-01-03 10:32:13 -08:00
module.exports = GPlusHandler = class GPlusHandler extends CocoClass
constructor: ->
2014-03-23 09:30:01 -07:00
@accessToken = storage . load GPLUS_TOKEN_KEY
2014-01-03 10:32:13 -08:00
super ( )
subscriptions:
' gplus-logged-in ' : ' onGPlusLogin '
2014-03-23 09:30:01 -07:00
' gapi-loaded ' : ' onGPlusLoaded '
2014-01-03 10:32:13 -08:00
2014-03-23 09:30:01 -07: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
2014-07-01 10:16:26 +08:00
gapi . auth . checkSessionState ( { client_id: clientID , session_state: session_state } , @ onCheckedSessionState )
2014-03-23 09:30:01 -07:00
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 10:32:13 -08:00
2014-03-23 09:30:01 -07:00
reauthorize: ->
params =
' client_id ' : clientID
' scope ' : scope
gapi . auth . authorize params , @ onGPlusLogin
2014-04-13 14:48:36 -07:00
2014-03-23 09:30:01 -07:00
onGPlusLogin: (e) =>
@loggedIn = true
storage . save ( GPLUS_TOKEN_KEY , e )
@accessToken = e
@ trigger ' logged-in '
2014-04-13 14:48:36 -07:00
return if ( not me ) or me . get ' gplusID ' # so only get more data
2014-01-03 10:32:13 -08:00
# email and profile data loaded separately
@responsesComplete = 0
2014-07-01 10:16:26 +08:00
gapi . client . request ( path: plusURL , callback: @ onPersonEntityReceived )
2014-01-03 10:32:13 -08:00
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 14:57:42 -08:00
patch = { }
patch [ key ] = me . get ( key ) for gplusKey , key of userPropsToSave
patch._id = me . id
patch.email = me . get ( ' email ' )
2014-03-23 09:30:01 -07:00
wasAnonymous = me . get ( ' anonymous ' )
2014-01-08 14:57:42 -08:00
me . save ( patch , {
patch: true
2014-01-03 10:32:13 -08:00
error: backboneFailure ,
2014-03-23 09:30:01 -07:00
url: " /db/user?gplusID= #{ gplusID } &gplusAccessToken= #{ @ accessToken . access_token } "
2014-01-03 10:32:13 -08:00
success: (model) ->
2014-03-23 09:30:01 -07:00
window . location . reload ( ) if wasAnonymous and not model . get ( ' anonymous ' )
2014-01-03 10:32:13 -08:00
} )
2014-04-13 14:48:36 -07:00
2014-03-23 09:30:01 -07:00
loadFriends: (friendsCallback) ->
return friendsCallback ( ) unless @ loggedIn
2014-04-13 14:48:36 -07:00
expiresIn = if @ accessToken then parseInt ( @ accessToken . expires_at ) - new Date ( ) . getTime ( ) / 1000 else - 1
2014-07-01 10:16:26 +08:00
onReauthorized = => gapi . client . request ( { path: ' /plus/v1/people/me/people/visible ' , callback: friendsCallback } )
2014-04-13 14:48:36 -07: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 09:30:01 -07:00
@ reauthorize ( )
@ listenToOnce ( @ , ' logged-in ' , onReauthorized )
else
onReauthorized ( )