Ghost/ghost/admin/app/authenticators/oauth2.js
2016-10-07 17:32:30 +01:00

91 lines
3.3 KiB
JavaScript

import computed from 'ember-computed';
import injectService from 'ember-service/inject';
import Authenticator from 'ember-simple-auth/authenticators/oauth2-password-grant';
import run from 'ember-runloop';
import RSVP from 'rsvp';
import {wrap} from 'ember-array/utils';
import {isEmpty} from 'ember-utils';
import {assign} from 'ember-platform';
export default Authenticator.extend({
ajax: injectService(),
session: injectService(),
config: injectService(),
ghostPaths: injectService(),
init() {
this._super(...arguments);
let handler = run.bind(this, () => {
this.onOnline();
});
window.addEventListener('online', handler);
},
serverTokenEndpoint: computed('ghostPaths.apiRoot', function () {
return `${this.get('ghostPaths.apiRoot')}/authentication/token`;
}),
serverTokenRevocationEndpoint: computed('ghostPaths.apiRoot', function () {
return `${this.get('ghostPaths.apiRoot')}/authentication/revoke`;
}),
makeRequest(url, data) {
/* jscs:disable requireCamelCaseOrUpperCaseIdentifiers */
data.client_id = this.get('config.clientId');
data.client_secret = this.get('config.clientSecret');
/* jscs:enable requireCamelCaseOrUpperCaseIdentifiers */
let options = {
data,
dataType: 'json',
contentType: 'application/x-www-form-urlencoded'
};
return this.get('ajax').post(url, options);
},
/**
* Invoked when "navigator.online" event is trigerred.
* This is a helper function to handle intermittent internet connectivity. Token is refreshed
* when browser status becomes "online".
*/
onOnline() {
if (this.get('session.isAuthenticated')) {
let autoRefresh = this.get('refreshAccessTokens');
if (autoRefresh) {
let expiresIn = this.get('session.data.authenticated.expires_in');
let token = this.get('session.data.authenticated.refresh_token');
return this._refreshAccessToken(expiresIn, token);
}
}
},
authenticate(identification, password, scope = [], headers = {}) {
return new RSVP.Promise((resolve, reject) => {
let data = {'grant_type': 'password', username: identification, password};
let serverTokenEndpoint = this.get('serverTokenEndpoint');
let scopesString = wrap(scope).join(' ');
if (!isEmpty(scopesString)) {
data.scope = scopesString;
}
this.makeRequest(serverTokenEndpoint, data, headers).then((response) => {
run(() => {
/* jscs:disable requireCamelCaseOrUpperCaseIdentifiers */
let expiresAt = this._absolutizeExpirationTime(response.expires_in);
this._scheduleAccessTokenRefresh(response.expires_in, expiresAt, response.refresh_token);
/* jscs:enable requireCamelCaseOrUpperCaseIdentifiers */
if (!isEmpty(expiresAt)) {
response = assign(response, {'expires_at': expiresAt});
}
resolve(response);
});
}, (error) => {
reject(error);
});
});
}
});