import config from 'travis/config/environment'; import Ember from 'ember'; export default Ember.Service.extend({ store: Ember.inject.service(), storage: Ember.inject.service(), sessionStorage: Ember.inject.service(), ajax: Ember.inject.service(), state: "signed-out", receivingEnd: location.protocol + "//" + location.host, init: function() { return window.addEventListener('message', (e) => { return this.receiveMessage(e); }); }, token() { return this.get('sessionStorage').getItem('travis.token'); }, endpoint: function() { return config.authEndpoint || config.apiEndpoint; }.property(), signOut: function() { var user; this.get('storage').removeItem('travis.user'); this.get('storage').removeItem('travis.token'); this.get('sessionStorage').clear(); this.set('state', 'signed-out'); this.set('user', void 0); if (user = this.get('currentUser')) { this.get('store').unloadAll('user'); } this.set('currentUser', null); this.sendToApp('afterSignOut'); return Travis.trigger('user:signed_out'); }, signIn(data) { var url; if (data) { return this.autoSignIn(data); } else { this.set('state', 'signing-in'); url = (this.get('endpoint')) + "/auth/post_message?origin=" + this.receivingEnd; return $('<iframe id="auth-frame" />').hide().appendTo('body').attr('src', url); } }, autoSignIn(data) { if(!data) { data = this.userDataFrom(this.get('sessionStorage')) || this.userDataFrom(this.get('storage')); } if (data) { this.setData(data); } }, userDataFrom(storage) { var token, user, userJSON; userJSON = storage.getItem('travis.user'); if (userJSON != null) { user = JSON.parse(userJSON); } if (user != null ? user.user : void 0) { user = user.user; } token = storage.getItem('travis.token'); if (user && token && this.validateUser(user)) { return { user: user, token: token }; } else { storage.removeItem('travis.user'); storage.removeItem('travis.token'); return null; } }, validateUser(user) { var fieldsToValidate, isTravisBecome; fieldsToValidate = ['id', 'login', 'token']; isTravisBecome = this.get('sessionStorage').getItem('travis.become'); if (!isTravisBecome) { fieldsToValidate.push('correct_scopes'); } if (config.pro) { fieldsToValidate.push('channels'); } return fieldsToValidate.every((function(_this) { return function(field) { return _this.validateHas(field, user); }; })(this)) && (isTravisBecome || user.correct_scopes); }, validateHas(field, user) { if (user[field]) { return true; } else { return false; } }, setData(data) { var user; this.storeData(data, this.get('sessionStorage')); if (!this.userDataFrom(this.get('storage'))) { this.storeData(data, this.get('storage')); } user = this.loadUser(data.user); this.set('currentUser', user); this.set('state', 'signed-in'); Travis.trigger('user:signed_in', data.user); return this.sendToApp('afterSignIn'); }, refreshUserData(user) { var data; if (!user) { if (data = this.userDataFrom(this.get('sessionStorage')) || this.userDataFrom(this.get('storage'))) { user = data.user; } } if (user) { return this.get('ajax').get("/users/" + user.id).then( (data) => { var userRecord; if (data.user.correct_scopes) { userRecord = this.loadUser(data.user); userRecord.get('permissions'); if (this.get('signedIn')) { data.user.token = user.token; this.storeData(data, this.get('sessionStorage')); this.storeData(data, this.get('storage')); return Travis.trigger('user:refreshed', data.user); } } else { return Ember.RSVP.Promise.reject(); } }); } else { return Ember.RSVP.Promise.resolve(); } }, signedIn: function() { return this.get('state') === 'signed-in'; }.property('state'), signedOut: function() { return this.get('state') === 'signed-out'; }.property('state'), signingIn: function() { return this.get('state') === 'signing-in'; }.property('state'), storeData(data, storage) { if (data.token) { storage.setItem('travis.token', data.token); } return storage.setItem('travis.user', JSON.stringify(data.user)); }, loadUser(user) { var store = this.get('store'), adapter = store.adapterFor('user'), userClass = store.modelFor('user'), serializer = store.serializerFor('user'), normalized = serializer.normalizeResponse(store, userClass, user, null, 'findRecord'); store.push(normalized); return store.recordForId('user', user.id); }, receiveMessage(event) { if (event.origin === this.expectedOrigin()) { if (event.data === 'redirect') { return window.location = (this.get('endpoint')) + "/auth/handshake?redirect_uri=" + location; } else if (event.data.user != null) { if (event.data.travis_token) { event.data.user.token = event.data.travis_token; } return this.setData(event.data); } } }, expectedOrigin() { var endpoint; endpoint = this.get('endpoint'); if (endpoint[0] === '/') { return this.receivingEnd; } else { return endpoint.match(/^https?:\/\/[^\/]*/)[0]; } }, sendToApp(name) { var error, router; // TODO: this is an ugly solution, we need to do one of 2 things: // * find a way to check if we can already send an event to remove try/catch // * remove afterSignIn and afterSignOut events by replacing them in a more // straightforward code - we can do what's needed on a routes/controller level // as a direct response to either manual sign in or autoSignIn (right now // we treat both cases behave the same in terms of sent events which I think // makes it more complicated than it should be). router = this.container.lookup('router:main'); try { return router.send(name); } catch (error1) { error = error1; if (!(error.message.match(/Can't trigger action/))) { throw error; } } }, userName: function() { return this.get('currentUser.name') || this.get('currentUser.login'); }.property('currentUser.login', 'currentUser.name'), gravatarUrl: function() { return location.protocol + "//www.gravatar.com/avatar/" + (this.get('currentUser.gravatarId')) + "?s=48&d=mm"; }.property('currentUser.gravatarId'), permissions: Ember.computed.alias('currentUser.permissions') });