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='
|
2014-06-30 22:16:26 -04: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 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:
|
2014-08-27 15:24:03 -04:00
|
|
|
'auth:logged-in-with-gplus':'onGPlusLogin'
|
|
|
|
'auth:gplus-api-loaded':'onGPlusLoaded'
|
2014-01-03 13:32:13 -05:00
|
|
|
|
2014-03-23 12:30:01 -04:00
|
|
|
onGPlusLoaded: ->
|
|
|
|
session_state = null
|
2014-11-14 14:04:17 -05:00
|
|
|
if @accessToken and me.get('gplusID')
|
2014-03-23 12:30:01 -04:00
|
|
|
# We need to check the current state, given our access token
|
|
|
|
gapi.auth.setToken 'token', @accessToken
|
|
|
|
session_state = @accessToken.session_state
|
2014-06-30 22:16:26 -04:00
|
|
|
gapi.auth.checkSessionState({client_id: clientID, session_state: session_state}, @onCheckedSessionState)
|
2014-03-23 12:30:01 -04: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 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
|
2014-11-14 14:04:17 -05:00
|
|
|
try
|
|
|
|
# Without removing this, we sometimes get a cross-domain error
|
|
|
|
d = JSON.stringify(_.omit(e, 'g-oauth-window'))
|
|
|
|
storage.save(GPLUS_TOKEN_KEY, d)
|
|
|
|
catch e
|
|
|
|
console.error 'Unable to save G+ token key', e
|
2014-03-23 12:30:01 -04:00
|
|
|
@accessToken = e
|
|
|
|
@trigger 'logged-in'
|
2014-11-14 14:04:17 -05:00
|
|
|
|
|
|
|
loginCodeCombat: ->
|
2014-01-03 13:32:13 -05:00
|
|
|
# email and profile data loaded separately
|
2014-06-30 22:16:26 -04:00
|
|
|
gapi.client.request(path: plusURL, callback: @onPersonEntityReceived)
|
2014-01-03 13:32:13 -05:00
|
|
|
gapi.client.load('oauth2', 'v2', =>
|
|
|
|
gapi.client.oauth2.userinfo.get().execute(@onEmailReceived))
|
|
|
|
|
|
|
|
shouldSave: false
|
|
|
|
|
|
|
|
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
|
2014-11-14 14:04:17 -05:00
|
|
|
@personLoaded = true
|
|
|
|
@trigger 'person-loaded'
|
2014-01-03 13:32:13 -05:00
|
|
|
@saveIfAllDone()
|
|
|
|
|
|
|
|
onEmailReceived: (r) =>
|
|
|
|
newEmail = r.email and r.email isnt me.get('email')
|
2014-11-14 14:04:17 -05:00
|
|
|
return unless newEmail or me.get('anonymous', true)
|
2014-01-03 13:32:13 -05:00
|
|
|
me.set('email', r.email)
|
|
|
|
@shouldSave = true
|
2014-11-14 14:04:17 -05:00
|
|
|
@emailLoaded = true
|
|
|
|
@trigger 'email-loaded'
|
2014-01-03 13:32:13 -05:00
|
|
|
@saveIfAllDone()
|
|
|
|
|
|
|
|
saveIfAllDone: =>
|
2014-11-14 14:04:17 -05:00
|
|
|
return unless @personLoaded and @emailLoaded
|
2014-01-03 13:32:13 -05:00
|
|
|
return unless me.get('email') and me.get('gplusID')
|
|
|
|
|
2014-08-27 15:24:03 -04:00
|
|
|
Backbone.Mediator.publish 'auth:logging-in-with-gplus', {}
|
2014-01-03 13:32:13 -05:00
|
|
|
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-11-14 14:04:17 -05:00
|
|
|
@trigger 'logging-into-codecombat'
|
2014-01-08 17:57:42 -05:00
|
|
|
me.save(patch, {
|
|
|
|
patch: true
|
2014-10-27 19:09:52 -04:00
|
|
|
type: 'PUT'
|
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-06-30 22:16:26 -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()
|