mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-23 23:58:02 -05:00
131 lines
4.6 KiB
CoffeeScript
131 lines
4.6 KiB
CoffeeScript
CocoClass = require 'lib/CocoClass'
|
|
{me} = require 'lib/auth'
|
|
{backboneFailure} = require 'lib/errors'
|
|
storage = require 'lib/storage'
|
|
GPLUS_TOKEN_KEY = 'gplusToken'
|
|
|
|
# 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'
|
|
scope = 'https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/userinfo.email'
|
|
|
|
module.exports = GPlusHandler = class GPlusHandler extends CocoClass
|
|
constructor: ->
|
|
@accessToken = storage.load GPLUS_TOKEN_KEY
|
|
super()
|
|
|
|
subscriptions:
|
|
'auth:logged-in-with-gplus':'onGPlusLogin'
|
|
'auth:gplus-api-loaded':'onGPlusLoaded'
|
|
|
|
onGPlusLoaded: ->
|
|
session_state = null
|
|
if @accessToken and me.get('gplusID')
|
|
# 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'
|
|
|
|
reauthorize: ->
|
|
params =
|
|
'client_id' : clientID
|
|
'scope' : scope
|
|
gapi.auth.authorize params, @onGPlusLogin
|
|
|
|
onGPlusLogin: (e) =>
|
|
@loggedIn = true
|
|
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
|
|
@accessToken = e
|
|
@trigger 'logged-in'
|
|
|
|
loginCodeCombat: ->
|
|
# email and profile data loaded separately
|
|
gapi.client.request(path: plusURL, callback: @onPersonEntityReceived)
|
|
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
|
|
@personLoaded = true
|
|
@trigger 'person-loaded'
|
|
@saveIfAllDone()
|
|
|
|
onEmailReceived: (r) =>
|
|
newEmail = r.email and r.email isnt me.get('email')
|
|
return unless newEmail or me.get('anonymous', true)
|
|
me.set('email', r.email)
|
|
@shouldSave = true
|
|
@emailLoaded = true
|
|
@trigger 'email-loaded'
|
|
@saveIfAllDone()
|
|
|
|
saveIfAllDone: =>
|
|
console.debug 'Save if all done. Person loaded:', @personLoaded, 'and email loaded:', @emailLoaded
|
|
return unless @personLoaded and @emailLoaded
|
|
console.debug 'Email, gplusID:', me.get('email'), me.get('gplusID')
|
|
return unless me.get('email') and me.get('gplusID')
|
|
|
|
Backbone.Mediator.publish 'auth:logging-in-with-gplus', {}
|
|
gplusID = me.get('gplusID')
|
|
window.tracker?.trackEvent 'Google Login'
|
|
window.tracker?.identify()
|
|
patch = {}
|
|
patch[key] = me.get(key) for gplusKey, key of userPropsToSave
|
|
patch._id = me.id
|
|
patch.email = me.get('email')
|
|
wasAnonymous = me.get('anonymous')
|
|
@trigger 'logging-into-codecombat'
|
|
console.debug('Logging into GPlus.')
|
|
me.save(patch, {
|
|
patch: true
|
|
type: 'PUT'
|
|
error: ->
|
|
console.debug('Logging into GPlus fail.', arguments)
|
|
backboneFailure(arguments...)
|
|
url: "/db/user?gplusID=#{gplusID}&gplusAccessToken=#{@accessToken.access_token}"
|
|
success: (model) ->
|
|
console.debug('GPLus login success!')
|
|
window.location.reload() if wasAnonymous and not model.get('anonymous')
|
|
})
|
|
|
|
loadFriends: (friendsCallback) ->
|
|
return friendsCallback() unless @loggedIn
|
|
expiresIn = if @accessToken then parseInt(@accessToken.expires_at) - new Date().getTime()/1000 else -1
|
|
onReauthorized = => gapi.client.request({path: '/plus/v1/people/me/people/visible', callback: friendsCallback})
|
|
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.
|
|
@reauthorize()
|
|
@listenToOnce(@, 'logged-in', onReauthorized)
|
|
else
|
|
onReauthorized()
|