chore: port auth addon from demo branch
This commit is contained in:
14 files changed
+558
-5
No files matched your search
Whitespace-only changes.
@@ -0,0 +1,87 @@
|
||||
import BaseAuthenticator from 'ember-simple-auth/authenticators/base';
|
||||
import { resolve, reject } from 'rsvp';
|
||||
import fetch from 'fetch';
|
||||
|
||||
/**
|
||||
*
|
||||
* This authenticator is intended for use with Ember Simple Auth.
|
||||
*
|
||||
* Simple id/password base authenticator sends credentials to an endpoint
|
||||
* specified in the `authEndpoint` URL. If the HTTP response code is in the
|
||||
* success range, authentication resolves. Otherwise it rejects.
|
||||
*
|
||||
* Upon session invalidation, deauthentication is attempted at the
|
||||
* `deauthEndpoint`, but is not guaranteed.
|
||||
*
|
||||
* This authenticator should not be used directly because it does not specify
|
||||
* an `authEndpoint` or `deauthEndpoint` of its own. To use, generate an
|
||||
* application authenticator in your app `authenticators/application.js` and
|
||||
* extend this class.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* import PasswordAuthenticator from 'auth/authenticators/password';
|
||||
* export default class ApplicationAuthenticator extends PasswordAuthenticator {
|
||||
* authEndpoint = '/api/authenticate';
|
||||
* deauthEndpoint = '/api/deauthenticate';
|
||||
* }
|
||||
*
|
||||
*/
|
||||
export default class PasswordAuthenticator extends BaseAuthenticator {
|
||||
// =methods
|
||||
|
||||
/**
|
||||
* Restores the session if data is present. Otherwise rejects.
|
||||
* @override
|
||||
* @param {object} data
|
||||
* @return {Promise}
|
||||
*/
|
||||
restore(data) {
|
||||
return data ? resolve(data) : reject();
|
||||
}
|
||||
|
||||
/**
|
||||
* Posts credentials to the URL specified in `authEndpoint` and resolves
|
||||
* if a success HTTP status code is received, otherwise rejects.
|
||||
*
|
||||
* If requesting cookies, be sure to use the cookie session store. Otherwise
|
||||
* use the local storage session store.
|
||||
*
|
||||
* @override
|
||||
* @param {object} creds
|
||||
* @param {string} creds.identification is sent to server as `name`
|
||||
* @param {string} creds.password
|
||||
* @param {string} authMethodId ID of the auth method to use
|
||||
* @param {boolean} requestCookies request cookie tokens (default `true`)
|
||||
* @return {Promise}
|
||||
*/
|
||||
async authenticate(
|
||||
{ identification: name, password },
|
||||
authMethodID,
|
||||
requestCookies = true
|
||||
) {
|
||||
const body = JSON.stringify({
|
||||
auth_method_id: authMethodID,
|
||||
token_type: requestCookies ? 'cookie' : null,
|
||||
credentials: { name, password },
|
||||
});
|
||||
const response = await fetch(this.authEndpoint, { method: 'post', body });
|
||||
const json = await response.json();
|
||||
return response.status < 400 ? resolve(json) : reject();
|
||||
}
|
||||
|
||||
/**
|
||||
* Posts to the `deauthEntpoint` on a best-effort basis and then returns.
|
||||
* Deauthentication with the server is not guaranteed and request failures
|
||||
* are ignored.
|
||||
*
|
||||
* @override
|
||||
* @return {Promise}
|
||||
*/
|
||||
invalidate() {
|
||||
fetch(this.deauthEndpoint, { method: 'post' }).catch(() => {
|
||||
/* no op */
|
||||
});
|
||||
return super.invalidate(...arguments);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
import BaseSessionStore from 'ember-simple-auth/session-stores/base';
|
||||
import { resolve, reject } from 'rsvp';
|
||||
import { get } from '@ember/object';
|
||||
import { inject as service } from '@ember/service';
|
||||
|
||||
/**
|
||||
*
|
||||
* This session store is intended for use with Ember Simple Auth when requesting
|
||||
* that the server send cookies (see authenticators).
|
||||
*
|
||||
* The cookie session store is used to maintain session state for auth servers
|
||||
* that send cookies. In this strategy, the server sets any cookies needed for
|
||||
* future authorization. This store determines if a session is authenticated
|
||||
* by looking for the presence of a cookie with name specified in `cookieName`.
|
||||
*
|
||||
* This session store should not be used directly because it does not specify
|
||||
* `cookiePath` or `cookieName`. To use, create an application session store
|
||||
* and extend this class, being sure to specify these attributes.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* import CookieSessionStore from 'auth/session-stores/cookie';
|
||||
* export default class ApplicationSessionStore extends CookieSessionStore {
|
||||
* cookiePath = '/';
|
||||
* cookieName = 'auth-token';
|
||||
* }
|
||||
*
|
||||
*/
|
||||
export default class CookieSessionStore extends BaseSessionStore {
|
||||
// =services
|
||||
|
||||
@service cookies;
|
||||
|
||||
// =attributes
|
||||
|
||||
/**
|
||||
* The name of the cookie that stores the name of the authenticator, derived
|
||||
* from the name of the session cookie. The authenticator name is used
|
||||
* internally by Ember Simple Auth, since it supports simultaneous
|
||||
* authentication schemes within a single application.
|
||||
* @type {string}
|
||||
*/
|
||||
get authenticatorCookieName() {
|
||||
return `${this.cookieName}-authenticator`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Name of the authenticator used, if any.
|
||||
* @type {?string}
|
||||
*/
|
||||
get authenticatorName() {
|
||||
return this.cookies.read(this.authenticatorCookieName);
|
||||
}
|
||||
|
||||
/**
|
||||
* True if both session and authenticator cookies are present.
|
||||
* False otherwise.
|
||||
* @type {boolean}
|
||||
*/
|
||||
get sessionExists() {
|
||||
const tokenExists = this.cookies.exists(this.cookieName);
|
||||
const authenticatorExists = this.cookies.exists(
|
||||
this.authenticatorCookieName
|
||||
);
|
||||
return tokenExists && authenticatorExists;
|
||||
}
|
||||
|
||||
// =methods
|
||||
|
||||
/**
|
||||
* This method is called automatically on initialization to perform cleanup
|
||||
* if necessary.
|
||||
*
|
||||
* Sessions exist only if both the session and authenticator cookies are
|
||||
* present. If either one is missing, we want to cleanup to be sure they
|
||||
* are both absent.
|
||||
*/
|
||||
init() {
|
||||
if (!this.sessionExists) this.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* While the primary session cookie is persisted by the server, not the
|
||||
* application, we still need to "remember" the name of the authenticator
|
||||
* used to authenticate to properly restore a session. Thus when this method
|
||||
* is called with an authenticator name, we save it into a cookie with name
|
||||
* `authenticatorCookieName`. If this method is called without an
|
||||
* authenticator, all related cookies are cleared.
|
||||
* @param {object} data
|
||||
* @return {Promise}
|
||||
*/
|
||||
persist(data) {
|
||||
const authenticator = get(data, 'authenticated.authenticator');
|
||||
const path = this.cookiePath;
|
||||
if (authenticator) {
|
||||
this.cookies.write(this.authenticatorCookieName, authenticator, { path });
|
||||
} else {
|
||||
this.clear();
|
||||
}
|
||||
return resolve();
|
||||
}
|
||||
|
||||
/**
|
||||
* If a session exists (as reported by `sessionExists`), then this method
|
||||
* resolves with the authentication object expected by Ember Simple Auth,
|
||||
* which must specify the name of the authenticator used to authenticate.
|
||||
*
|
||||
* If the session does not exist, all related cookies are cleared and this
|
||||
* method rejects.
|
||||
*
|
||||
* @return {Promise}
|
||||
*/
|
||||
restore() {
|
||||
if (this.sessionExists) {
|
||||
return resolve({
|
||||
authenticated: {
|
||||
authenticator: this.authenticatorName,
|
||||
},
|
||||
});
|
||||
}
|
||||
this.clear();
|
||||
return reject();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears both cookies related to the session: the server specified session
|
||||
* cookie as well as the authenticator name cookie.
|
||||
*/
|
||||
clear() {
|
||||
const path = this.cookiePath;
|
||||
this.cookies.clear(this.cookieName, { path });
|
||||
this.cookies.clear(this.authenticatorCookieName, { path });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import LocalStorageSessionStore from 'ember-simple-auth/session-stores/local-storage';
|
||||
|
||||
/**
|
||||
*
|
||||
* This session store is intended for use with Ember Simple Auth when requesting
|
||||
* that the server send a full token (e.g. cookies are not requested,
|
||||
* see authenticators).
|
||||
*
|
||||
* NOTE: when using a local storage scheme, authorization is not provided
|
||||
* automatically. In order to achieve authorization... TODO
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* import LocalStorageSessionStore from 'auth/session-stores/local-storage';
|
||||
* export default class ApplicationSessionStore extends LocalStorageSessionStore {
|
||||
*
|
||||
* }
|
||||
*
|
||||
*/
|
||||
export default class AuthLocalStorageSessionStore extends LocalStorageSessionStore {}
|
||||
Reference in new issue
Block a user