138 lines
4.3 KiB
JavaScript
138 lines
4.3 KiB
JavaScript
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.
|
|
*/
|
|
// The base class is a classic Ember class, but the linter doesn't know that.
|
|
// That's why this rule is disabled here.
|
|
/* eslint-disable-next-line ember/classic-decorator-hooks */
|
|
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 });
|
|
}
|
|
}
|