/** @module ember-simple-auth/authenticators/oauth2-implicit-grant **/
import RSVP from 'rsvp';
import { isEmpty } from '@ember/utils';
import BaseAuthenticator from './base';
/**
Parses the location hash (as received from `window.location.hash`) into an
object, e.g.:
```js
parseResponse('/routepath#access_token=secret-token&scope=something'); // => { access_token: 'secret-token', scope: 'something' }
```
@function parseResponse
@param {String} locationHash The location hash (as received from `window.location.hash`)
@return {Object} An obect with individual properties and values for the data parsed from the location hash
@memberof module:ember-simple-auth/authenticators/oauth2-implicit-grant
*/
export function parseResponse(locationHash) {
let params = {};
const query = locationHash.substring(locationHash.indexOf('?'));
const regex = /([^#?&=]+)=([^&]*)/g;
let match;
// decode all parameter pairs
while ((match = regex.exec(query)) !== null) {
params[decodeURIComponent(match[1])] = decodeURIComponent(match[2]);
}
return params;
}
/**
Authenticator that conforms to OAuth 2
([RFC 6749](http://tools.ietf.org/html/rfc6749)), specifically the _"Implicit
Grant Type"_.
Use {@linkplain SessionService.authenticate} in your
OAuth 2.0 redirect route to parse authentication parameters from location
hash string into an object.
@class OAuth2ImplicitGrantAuthenticator
@extends BaseAuthenticator
@public
*/
export default BaseAuthenticator.extend({
/**
Restores the session from a session data object; __will return a resolving
promise when there is a non-empty `access_token` in the session data__ and
a rejecting promise otherwise.
@memberof OAuth2ImplicitGrantAuthenticator
@method restore
@param {Object} data The data to restore the session from
@return {Ember.RSVP.Promise} A promise that when it resolves results in the session becoming or remaining authenticated
@public
*/
restore(data) {
return new RSVP.Promise((resolve, reject) => {
if (!this._validateData(data)) {
return reject('Could not restore session - "access_token" missing.');
}
return resolve(data);
});
},
/**
Authenticates the session using the specified location `hash`
(see https://tools.ietf.org/html/rfc6749#section-4.2.2).
__If the access token is valid and thus authentication succeeds, a promise that
resolves with the access token is returned__, otherwise a promise that rejects
with the error code as returned by the server is returned
(see https://tools.ietf.org/html/rfc6749#section-4.2.2.1).
@memberof OAuth2ImplicitGrantAuthenticator
@method authenticate
@param {Object} hash The location hash
@return {Ember.RSVP.Promise} A promise that when it resolves results in the session becoming authenticated
@public
*/
authenticate(hash) {
return new RSVP.Promise((resolve, reject) => {
if (hash.error) {
reject(hash.error);
} else if (!this._validateData(hash)) {
reject('Invalid auth params - "access_token" missing.');
} else {
resolve(hash);
}
});
},
/**
This method simply returns a resolving promise.
@memberof OAuth2ImplicitGrantAuthenticator
@method invalidate
@return {Ember.RSVP.Promise} A promise that when it resolves results in the session being invalidated
@public
*/
invalidate() {
return RSVP.Promise.resolve();
},
_validateData(data) {
// see https://tools.ietf.org/html/rfc6749#section-4.2.2
return !isEmpty(data) && !isEmpty(data.access_token);
},
});
Source