mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-24 03:14:03 +03:00
Made session.user
a synchronous property rather than a promise
no issue Having `session.user` return a promise made dealing with it in components difficult because you always had to remember it returned a promise rather than a model and had to handle the async behaviour. It also meant that you couldn't use any current user properties directly inside getters which made refactors to Glimmer/Octane idioms harder to reason about. `session.user` was a cached computed property so it really made no sense for it to be a promise - it was loaded on first access and then always returned instantly but with a fulfilled promise rather than the underlying model. Refactoring to a synchronous property that is loaded as part of the authentication flows (we load the current user to check that we're logged in - we may as well make use of that!) means one less thing to be aware of/remember and provides a nicer migration process to Glimmer components. As part of the refactor, the auth flows and pre-load of required data across other services was also simplified to make it easier to find and follow. - refactored app setup and `session.user` - added `session.populateUser()` that fetches a user model from the current user endpoint and sets it on `session.user` - removed knowledge of app setup from the `cookie` authenticator and moved it into = `session.postAuthPreparation()`, this means we have the same post-authentication setup no matter which authenticator is used so we have more consistent behaviour in tests which don't use the `cookie` authenticator - switched `session` service to native class syntax to get the expected `super()` behaviour - updated `handleAuthentication()` so it populate's `session.user` and performs post-auth setup before transitioning (handles sign-in after app load) - updated `application` route to remove duplicated knowledge of app preload behaviour that now lives in `session.postAuthPreparation()` (handles already-authed app load) - removed out-of-date attempt at pre-loading data from setup controller as that's now handled automatically via `session.handleAuthentication` - updated app code to not treat `session.user` as a promise - predominant usage was router `beforeModel` hooks that transitioned users without valid permissions, this sets us up for an easier removal of the `current-user-settings` mixin in the future
This commit is contained in:
parent
cc25b2348a
commit
c646e78fff
@ -5,11 +5,7 @@ import {inject as service} from '@ember/service';
|
||||
|
||||
export default Authenticator.extend({
|
||||
ajax: service(),
|
||||
config: service(),
|
||||
feature: service(),
|
||||
ghostPaths: service(),
|
||||
settings: service(),
|
||||
whatsNew: service(),
|
||||
|
||||
sessionEndpoint: computed('ghostPaths.apiRoot', function () {
|
||||
return `${this.ghostPaths.apiRoot}/session`;
|
||||
@ -28,23 +24,7 @@ export default Authenticator.extend({
|
||||
dataType: 'text'
|
||||
};
|
||||
|
||||
return this.ajax.post(this.sessionEndpoint, options).then((authResult) => {
|
||||
// TODO: remove duplication with application.afterModel
|
||||
let preloadPromises = [
|
||||
this.config.fetchAuthenticated(),
|
||||
this.feature.fetch(),
|
||||
this.settings.fetch()
|
||||
];
|
||||
|
||||
// kick off background update of "whats new"
|
||||
// - we don't want to block the router for this
|
||||
// - we need the user details to know what the user has seen
|
||||
this.whatsNew.fetchLatest.perform();
|
||||
|
||||
return RSVP.all(preloadPromises).then(() => {
|
||||
return authResult;
|
||||
});
|
||||
});
|
||||
return this.ajax.post(this.sessionEndpoint, options);
|
||||
},
|
||||
|
||||
invalidate() {
|
||||
|
@ -12,7 +12,7 @@
|
||||
<div class="gh-post-preview-email-footer">
|
||||
<span class="mr3 nowrap fw6 f8 darkgrey">Send a test newsletter</span>
|
||||
|
||||
<div class="gh-post-preview-email-input {{if this.sendPreviewEmailError "error"}}" {{did-insert this.initPreviewEmailAddress}}>
|
||||
<div class="gh-post-preview-email-input {{if this.sendPreviewEmailError "error"}}">
|
||||
<Input
|
||||
@value={{this.previewEmailAddress}}
|
||||
class="gh-input gh-post-preview-email-input"
|
||||
|
@ -28,7 +28,7 @@ export default class ModalPostPreviewEmailComponent extends Component {
|
||||
|
||||
@tracked html = '';
|
||||
@tracked subject = '';
|
||||
@tracked previewEmailAddress = '';
|
||||
@tracked previewEmailAddress = this.session.user.email;
|
||||
@tracked sendPreviewEmailError = '';
|
||||
|
||||
get mailgunIsEnabled() {
|
||||
@ -49,12 +49,6 @@ export default class ModalPostPreviewEmailComponent extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
async initPreviewEmailAddress() {
|
||||
const user = await this.session.user;
|
||||
this.previewEmailAddress = user.email;
|
||||
}
|
||||
|
||||
@task({drop: true})
|
||||
*sendPreviewEmailTask() {
|
||||
try {
|
||||
|
@ -22,7 +22,7 @@ export default Controller.extend({
|
||||
ui: service(),
|
||||
|
||||
showBilling: computed.reads('config.hostSettings.billing.enabled'),
|
||||
showNavMenu: computed('router.currentRouteName', 'session.{isAuthenticated,user.isFulfilled}', 'ui.isFullScreen', function () {
|
||||
showNavMenu: computed('router.currentRouteName', 'session.{isAuthenticated,user}', 'ui.isFullScreen', function () {
|
||||
let {router, session, ui} = this;
|
||||
|
||||
// if we're in fullscreen mode don't show the nav menu
|
||||
@ -31,8 +31,8 @@ export default Controller.extend({
|
||||
}
|
||||
|
||||
// we need to defer showing the navigation menu until the session.user
|
||||
// promise has fulfilled so that gh-user-can-admin has the correct data
|
||||
if (!session.isAuthenticated || !session.user.isFulfilled) {
|
||||
// is populated so that gh-user-can-admin has the correct data
|
||||
if (!session.isAuthenticated || !session.user) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -115,7 +115,7 @@ export default Controller.extend({
|
||||
// https://github.com/emberjs/data/issues/4963
|
||||
run.schedule('destroy', this, () => {
|
||||
// Reload currentUser and set session
|
||||
this.set('session.user', store.findRecord('user', currentUserId));
|
||||
this.session.populateUser({id: currentUserId});
|
||||
|
||||
// TODO: keep as notification, add link to view content
|
||||
notifications.showNotification('Import successful', {key: 'import.upload.success'});
|
||||
|
@ -1,6 +1,5 @@
|
||||
/* eslint-disable camelcase, ghost/ember/alias-model-in-controller */
|
||||
import Controller, {inject as controller} from '@ember/controller';
|
||||
import RSVP from 'rsvp';
|
||||
import ValidationEngine from 'ghost-admin/mixins/validation-engine';
|
||||
import {get} from '@ember/object';
|
||||
import {isInvalidError} from 'ember-ajax/errors';
|
||||
@ -15,7 +14,6 @@ export default Controller.extend(ValidationEngine, {
|
||||
ghostPaths: service(),
|
||||
notifications: service(),
|
||||
session: service(),
|
||||
settings: service(),
|
||||
|
||||
// ValidationEngine settings
|
||||
validationType: 'setup',
|
||||
@ -51,7 +49,7 @@ export default Controller.extend(ValidationEngine, {
|
||||
|
||||
authenticate: task(function* (authStrategy, authentication) {
|
||||
// we don't want to redirect after sign-in during setup
|
||||
this.set('session.skipAuthSuccessHandler', true);
|
||||
this.session.skipAuthSuccessHandler = true;
|
||||
|
||||
try {
|
||||
let authResult = yield this.session
|
||||
@ -141,15 +139,13 @@ export default Controller.extend(ValidationEngine, {
|
||||
}
|
||||
|
||||
// Don't call the success handler, otherwise we will be redirected to admin
|
||||
this.set('session.skipAuthSuccessHandler', true);
|
||||
this.session.skipAuthSuccessHandler = true;
|
||||
|
||||
return this.session.authenticate('authenticator:cookie', data.email, data.password).then(() => {
|
||||
this.set('blogCreated', true);
|
||||
return this._afterAuthentication(result);
|
||||
}).catch((error) => {
|
||||
this._handleAuthenticationError(error);
|
||||
}).finally(() => {
|
||||
this.set('session.skipAuthSuccessHandler', undefined);
|
||||
});
|
||||
}).catch((error) => {
|
||||
this._handleSaveError(error);
|
||||
@ -179,20 +175,14 @@ export default Controller.extend(ValidationEngine, {
|
||||
},
|
||||
|
||||
_afterAuthentication(result) {
|
||||
// fetch settings and private config for synchronous access before transitioning
|
||||
let fetchSettingsAndConfig = RSVP.all([
|
||||
this.settings.fetch()
|
||||
]);
|
||||
|
||||
if (this.profileImage) {
|
||||
return this._sendImage(result.users[0])
|
||||
.then(() => (fetchSettingsAndConfig))
|
||||
.then(() => (this.transitionToRoute('setup.three')))
|
||||
.catch((resp) => {
|
||||
this.notifications.showAPIError(resp, {key: 'setup.blog-details'});
|
||||
});
|
||||
} else {
|
||||
return fetchSettingsAndConfig.then(() => this.transitionToRoute('setup.three'));
|
||||
return this.transitionToRoute('setup.three');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -105,7 +105,7 @@ export default Controller.extend({
|
||||
formData.append('file', imageFile, imageFile.name);
|
||||
formData.append('purpose', 'profile_image');
|
||||
|
||||
let user = yield this.get('session.user');
|
||||
let user = this.session.user;
|
||||
let response = yield this.ajax.post(uploadUrl, {
|
||||
data: formData,
|
||||
processData: false,
|
||||
|
@ -1,23 +1,15 @@
|
||||
import Mixin from '@ember/object/mixin';
|
||||
|
||||
export default Mixin.create({
|
||||
transitionAuthor() {
|
||||
return (user) => {
|
||||
if (user.get('isAuthorOrContributor')) {
|
||||
return this.transitionTo('staff.user', user);
|
||||
}
|
||||
|
||||
return user;
|
||||
};
|
||||
transitionAuthor(user) {
|
||||
if (user.isAuthorOrContributor) {
|
||||
return this.transitionTo('staff.user', user);
|
||||
}
|
||||
},
|
||||
|
||||
transitionEditor() {
|
||||
return (user) => {
|
||||
if (user.get('isEditor')) {
|
||||
return this.transitionTo('staff');
|
||||
}
|
||||
|
||||
return user;
|
||||
};
|
||||
transitionEditor(user) {
|
||||
if (user.isEditor) {
|
||||
return this.transitionTo('staff');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -1,11 +1,9 @@
|
||||
import AuthConfiguration from 'ember-simple-auth/configuration';
|
||||
import RSVP from 'rsvp';
|
||||
import Route from '@ember/routing/route';
|
||||
import ShortcutsRoute from 'ghost-admin/mixins/shortcuts-route';
|
||||
import ctrlOrCmd from 'ghost-admin/utils/ctrl-or-cmd';
|
||||
import windowProxy from 'ghost-admin/utils/window-proxy';
|
||||
import {InitSentryForEmber} from '@sentry/ember';
|
||||
import {configureScope} from '@sentry/browser';
|
||||
import {
|
||||
isAjaxError,
|
||||
isNotFoundError,
|
||||
@ -51,57 +49,14 @@ export default Route.extend(ShortcutsRoute, {
|
||||
},
|
||||
|
||||
beforeModel() {
|
||||
return this.config.fetchUnauthenticated()
|
||||
.then(() => {
|
||||
// init Sentry here rather than app.js so that we can use API-supplied
|
||||
// sentry_dsn and sentry_env rather than building it into release assets
|
||||
if (this.config.get('sentry_dsn')) {
|
||||
InitSentryForEmber({
|
||||
dsn: this.config.get('sentry_dsn'),
|
||||
environment: this.config.get('sentry_env'),
|
||||
release: `ghost@${this.config.get('version')}`
|
||||
});
|
||||
}
|
||||
});
|
||||
return this.prepareApp();
|
||||
},
|
||||
|
||||
afterModel(model, transition) {
|
||||
async afterModel(model, transition) {
|
||||
this._super(...arguments);
|
||||
|
||||
if (this.get('session.isAuthenticated')) {
|
||||
this.session.appLoadTransition = transition;
|
||||
this.session.loadServerNotifications();
|
||||
|
||||
// return the feature/settings load promises so that we block until
|
||||
// they are loaded to enable synchronous access everywhere
|
||||
return RSVP.all([
|
||||
this.config.fetchAuthenticated(),
|
||||
this.feature.fetch(),
|
||||
this.settings.fetch()
|
||||
]).then((results) => {
|
||||
this._appLoaded = true;
|
||||
|
||||
// update Sentry with the full Ghost version which we only get after authentication
|
||||
if (this.config.get('sentry_dsn')) {
|
||||
configureScope((scope) => {
|
||||
scope.addEventProcessor((event) => {
|
||||
return new Promise((resolve) => {
|
||||
resolve({
|
||||
...event,
|
||||
release: `ghost@${this.config.get('version')}`
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// kick off background update of "whats new"
|
||||
// - we don't want to block the router for this
|
||||
// - we need the user details to know what the user has seen
|
||||
this.whatsNew.fetchLatest.perform();
|
||||
|
||||
return results;
|
||||
});
|
||||
}
|
||||
|
||||
this._appLoaded = true;
|
||||
@ -186,5 +141,30 @@ export default Route.extend(ShortcutsRoute, {
|
||||
// fallback to 500 error page
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
async prepareApp() {
|
||||
await this.config.fetchUnauthenticated();
|
||||
|
||||
// init Sentry here rather than app.js so that we can use API-supplied
|
||||
// sentry_dsn and sentry_env rather than building it into release assets
|
||||
if (this.config.get('sentry_dsn')) {
|
||||
InitSentryForEmber({
|
||||
dsn: this.config.get('sentry_dsn'),
|
||||
environment: this.config.get('sentry_env'),
|
||||
release: `ghost@${this.config.get('version')}`
|
||||
});
|
||||
}
|
||||
|
||||
if (this.session.isAuthenticated) {
|
||||
try {
|
||||
await this.session.populateUser();
|
||||
} catch (e) {
|
||||
await this.session.invalidate();
|
||||
}
|
||||
|
||||
await this.session.postAuthPreparation();
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -3,11 +3,9 @@ import AuthenticatedRoute from 'ghost-admin/routes/authenticated';
|
||||
export default class DashboardRoute extends AuthenticatedRoute {
|
||||
beforeModel() {
|
||||
super.beforeModel(...arguments);
|
||||
return this.session.user.then((user) => {
|
||||
if (!user.isOwnerOrAdmin) {
|
||||
return this.transitionTo('site');
|
||||
}
|
||||
});
|
||||
if (!this.session.user.isOwnerOrAdmin) {
|
||||
return this.transitionTo('site');
|
||||
}
|
||||
}
|
||||
|
||||
buildRouteInfoMetadata() {
|
||||
|
@ -37,18 +37,17 @@ export default AuthenticatedRoute.extend({
|
||||
afterModel(post) {
|
||||
this._super(...arguments);
|
||||
|
||||
return this.get('session.user').then((user) => {
|
||||
let returnRoute = pluralize(post.constructor.modelName);
|
||||
const user = this.session.user;
|
||||
const returnRoute = pluralize(post.constructor.modelName);
|
||||
|
||||
if (user.get('isAuthorOrContributor') && !post.isAuthoredByUser(user)) {
|
||||
return this.replaceWith(returnRoute);
|
||||
}
|
||||
if (user.isAuthorOrContributor && !post.isAuthoredByUser(user)) {
|
||||
return this.replaceWith(returnRoute);
|
||||
}
|
||||
|
||||
// If the post is not a draft and user is contributor, redirect to index
|
||||
if (user.get('isContributor') && !post.get('isDraft')) {
|
||||
return this.replaceWith(returnRoute);
|
||||
}
|
||||
});
|
||||
// If the post is not a draft and user is contributor, redirect to index
|
||||
if (user.isContributor && !post.isDraft) {
|
||||
return this.replaceWith(returnRoute);
|
||||
}
|
||||
},
|
||||
|
||||
serialize(model) {
|
||||
|
@ -9,9 +9,7 @@ export default AuthenticatedRoute.extend({
|
||||
return this.replaceWith('error404', {path, status: 404});
|
||||
}
|
||||
|
||||
return this.get('session.user').then(user => (
|
||||
this.store.createRecord(modelName, {authors: [user]})
|
||||
));
|
||||
this.store.createRecord(modelName, {authors: [this.session.user]});
|
||||
},
|
||||
|
||||
// there's no specific controller for this route, instead all editor
|
||||
|
@ -18,9 +18,8 @@ export default AuthenticatedRoute.extend(CurrentUserSettings, {
|
||||
|
||||
beforeModel() {
|
||||
this._super(...arguments);
|
||||
return this.get('session.user')
|
||||
.then(this.transitionAuthor())
|
||||
.then(this.transitionEditor());
|
||||
this.transitionAuthor(this.session.user);
|
||||
this.transitionEditor(this.session.user);
|
||||
},
|
||||
|
||||
model(params, transition) {
|
||||
|
@ -7,9 +7,8 @@ export default AuthenticatedRoute.extend(CurrentUserSettings, {
|
||||
|
||||
beforeModel() {
|
||||
this._super(...arguments);
|
||||
return this.get('session.user')
|
||||
.then(this.transitionAuthor())
|
||||
.then(this.transitionEditor());
|
||||
this.transitionAuthor(this.session.user);
|
||||
this.transitionEditor(this.session.user);
|
||||
},
|
||||
|
||||
setupController(controller) {
|
||||
|
@ -7,10 +7,10 @@ export default AuthenticatedRoute.extend(CurrentUserSettings, {
|
||||
|
||||
beforeModel() {
|
||||
this._super(...arguments);
|
||||
return this.get('session.user')
|
||||
.then(this.transitionAuthor())
|
||||
.then(this.transitionEditor())
|
||||
.then(this.settings.reload());
|
||||
this.transitionAuthor(this.session.user);
|
||||
this.transitionEditor(this.session.user);
|
||||
|
||||
return this.settings.reload();
|
||||
},
|
||||
|
||||
actions: {
|
||||
|
@ -7,10 +7,10 @@ export default AuthenticatedRoute.extend(CurrentUserSettings, {
|
||||
|
||||
beforeModel() {
|
||||
this._super(...arguments);
|
||||
return this.get('session.user')
|
||||
.then(this.transitionAuthor())
|
||||
.then(this.transitionEditor())
|
||||
.then(this.settings.reload());
|
||||
this.transitionAuthor(this.session.user);
|
||||
this.transitionEditor(this.session.user);
|
||||
|
||||
return this.settings.reload();
|
||||
},
|
||||
|
||||
actions: {
|
||||
|
@ -7,10 +7,10 @@ export default AuthenticatedRoute.extend(CurrentUserSettings, {
|
||||
|
||||
beforeModel() {
|
||||
this._super(...arguments);
|
||||
return this.get('session.user')
|
||||
.then(this.transitionAuthor())
|
||||
.then(this.transitionEditor())
|
||||
.then(this.settings.reload());
|
||||
this.transitionAuthor(this.session.user);
|
||||
this.transitionEditor(this.session.user);
|
||||
|
||||
return this.settings.reload();
|
||||
},
|
||||
|
||||
actions: {
|
||||
|
@ -7,10 +7,10 @@ export default AuthenticatedRoute.extend(CurrentUserSettings, {
|
||||
|
||||
beforeModel() {
|
||||
this._super(...arguments);
|
||||
return this.get('session.user')
|
||||
.then(this.transitionAuthor())
|
||||
.then(this.transitionEditor())
|
||||
.then(this.settings.reload());
|
||||
this.transitionAuthor(this.session.user);
|
||||
this.transitionEditor(this.session.user);
|
||||
|
||||
return this.settings.reload();
|
||||
},
|
||||
|
||||
actions: {
|
||||
|
@ -24,10 +24,9 @@ export default AuthenticatedRoute.extend(CurrentUserSettings, {
|
||||
beforeModel() {
|
||||
this._super(...arguments);
|
||||
|
||||
return this.get('session.user')
|
||||
.then(this.transitionDisabled())
|
||||
.then(this.transitionAuthor())
|
||||
.then(this.transitionEditor());
|
||||
this.transitionDisabled();
|
||||
this.transitionAuthor(this.session.user);
|
||||
this.transitionEditor(this.session.user);
|
||||
},
|
||||
|
||||
model(params, transition) {
|
||||
|
@ -6,10 +6,8 @@ export default class LaunchRoute extends AuthenticatedRoute {
|
||||
|
||||
beforeModel() {
|
||||
super.beforeModel(...arguments);
|
||||
return this.session.user.then((user) => {
|
||||
if (!user.isOwner) {
|
||||
return this.transitionTo('home');
|
||||
}
|
||||
});
|
||||
if (!this.session.user.isOwner) {
|
||||
return this.transitionTo('home');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,11 +18,9 @@ export default class MembersRoute extends AuthenticatedRoute {
|
||||
|
||||
beforeModel() {
|
||||
super.beforeModel(...arguments);
|
||||
return this.session.user.then((user) => {
|
||||
if (!user.isOwnerOrAdmin) {
|
||||
return this.transitionTo('home');
|
||||
}
|
||||
});
|
||||
if (!this.session.user.isOwnerOrAdmin) {
|
||||
return this.transitionTo('home');
|
||||
}
|
||||
}
|
||||
|
||||
model(params) {
|
||||
|
@ -16,11 +16,9 @@ export default class MembersRoute extends AuthenticatedRoute {
|
||||
// - logged in user isn't owner/admin
|
||||
beforeModel() {
|
||||
super.beforeModel(...arguments);
|
||||
return this.session.user.then((user) => {
|
||||
if (!user.isOwnerOrAdmin) {
|
||||
return this.transitionTo('home');
|
||||
}
|
||||
});
|
||||
if (!this.session.user.isOwnerOrAdmin) {
|
||||
return this.transitionTo('home');
|
||||
}
|
||||
}
|
||||
|
||||
model(params) {
|
||||
|
@ -38,45 +38,44 @@ export default AuthenticatedRoute.extend({
|
||||
},
|
||||
|
||||
model(params) {
|
||||
return this.session.user.then((user) => {
|
||||
let queryParams = {};
|
||||
let filterParams = {tag: params.tag, visibility: params.visibility};
|
||||
let paginationParams = {
|
||||
perPageParam: 'limit',
|
||||
totalPagesParam: 'meta.pagination.pages'
|
||||
};
|
||||
const user = this.session.user;
|
||||
let queryParams = {};
|
||||
let filterParams = {tag: params.tag, visibility: params.visibility};
|
||||
let paginationParams = {
|
||||
perPageParam: 'limit',
|
||||
totalPagesParam: 'meta.pagination.pages'
|
||||
};
|
||||
|
||||
assign(filterParams, this._getTypeFilters(params.type));
|
||||
assign(filterParams, this._getTypeFilters(params.type));
|
||||
|
||||
if (params.type === 'featured') {
|
||||
filterParams.featured = true;
|
||||
}
|
||||
if (params.type === 'featured') {
|
||||
filterParams.featured = true;
|
||||
}
|
||||
|
||||
if (user.isAuthor) {
|
||||
// authors can only view their own posts
|
||||
filterParams.authors = user.slug;
|
||||
} else if (user.isContributor) {
|
||||
// Contributors can only view their own draft posts
|
||||
filterParams.authors = user.slug;
|
||||
filterParams.status = 'draft';
|
||||
} else if (params.author) {
|
||||
filterParams.authors = params.author;
|
||||
}
|
||||
if (user.isAuthor) {
|
||||
// authors can only view their own posts
|
||||
filterParams.authors = user.slug;
|
||||
} else if (user.isContributor) {
|
||||
// Contributors can only view their own draft posts
|
||||
filterParams.authors = user.slug;
|
||||
filterParams.status = 'draft';
|
||||
} else if (params.author) {
|
||||
filterParams.authors = params.author;
|
||||
}
|
||||
|
||||
let filter = this._filterString(filterParams);
|
||||
if (!isBlank(filter)) {
|
||||
queryParams.filter = filter;
|
||||
}
|
||||
let filter = this._filterString(filterParams);
|
||||
if (!isBlank(filter)) {
|
||||
queryParams.filter = filter;
|
||||
}
|
||||
|
||||
if (!isBlank(params.order)) {
|
||||
queryParams.order = params.order;
|
||||
}
|
||||
if (!isBlank(params.order)) {
|
||||
queryParams.order = params.order;
|
||||
}
|
||||
|
||||
let perPage = this.perPage;
|
||||
let paginationSettings = assign({perPage, startingPage: 1}, paginationParams, queryParams);
|
||||
let perPage = this.perPage;
|
||||
let paginationSettings = assign({perPage, startingPage: 1}, paginationParams, queryParams);
|
||||
|
||||
return this.infinity.model(this.modelName, paginationSettings);
|
||||
});
|
||||
return this.infinity.model(this.modelName, paginationSettings);
|
||||
},
|
||||
|
||||
// trigger a background load of all tags, authors, and snipps for use in filter dropdowns and card menu
|
||||
@ -89,13 +88,11 @@ export default AuthenticatedRoute.extend({
|
||||
});
|
||||
}
|
||||
|
||||
this.session.user.then((user) => {
|
||||
if (!user.isAuthorOrContributor && !controller._hasLoadedAuthors) {
|
||||
this.store.query('user', {limit: 'all'}).then(() => {
|
||||
controller._hasLoadedAuthors = true;
|
||||
});
|
||||
}
|
||||
});
|
||||
if (!this.session.user.isAuthorOrContributor && !controller._hasLoadedAuthors) {
|
||||
this.store.query('user', {limit: 'all'}).then(() => {
|
||||
controller._hasLoadedAuthors = true;
|
||||
});
|
||||
}
|
||||
|
||||
if (!controller._hasLoadedSnippets) {
|
||||
this.store.query('snippet', {limit: 'all'}).then(() => {
|
||||
|
@ -13,13 +13,11 @@ export default AuthenticatedRoute.extend({
|
||||
beforeModel(transition) {
|
||||
this._super(...arguments);
|
||||
|
||||
return this.session.user.then((user) => {
|
||||
if (!user.isOwner) {
|
||||
return this.transitionTo('home');
|
||||
}
|
||||
if (!this.session.user.isOwner) {
|
||||
return this.transitionTo('home');
|
||||
}
|
||||
|
||||
this.billing.set('previousTransition', transition);
|
||||
});
|
||||
this.billing.set('previousTransition', transition);
|
||||
},
|
||||
|
||||
model(params) {
|
||||
|
@ -4,8 +4,7 @@ import CurrentUserSettings from 'ghost-admin/mixins/current-user-settings';
|
||||
export default AuthenticatedRoute.extend(CurrentUserSettings, {
|
||||
beforeModel() {
|
||||
this._super(...arguments);
|
||||
return this.get('session.user')
|
||||
.then(this.transitionAuthor())
|
||||
.then(this.transitionEditor());
|
||||
this.transitionAuthor(this.session.user);
|
||||
this.transitionEditor(this.session.user);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -7,9 +7,8 @@ export default AuthenticatedRoute.extend(CurrentUserSettings, {
|
||||
|
||||
beforeModel() {
|
||||
this._super(...arguments);
|
||||
return this.get('session.user')
|
||||
.then(this.transitionAuthor())
|
||||
.then(this.transitionEditor());
|
||||
this.transitionAuthor(this.session.user);
|
||||
this.transitionEditor(this.session.user);
|
||||
},
|
||||
|
||||
model() {
|
||||
|
@ -9,9 +9,8 @@ export default AuthenticatedRoute.extend(CurrentUserSettings, {
|
||||
|
||||
beforeModel() {
|
||||
this._super(...arguments);
|
||||
return this.get('session.user')
|
||||
.then(this.transitionAuthor())
|
||||
.then(this.transitionEditor());
|
||||
this.transitionAuthor(this.session.user);
|
||||
this.transitionEditor(this.session.user);
|
||||
},
|
||||
|
||||
model() {
|
||||
|
@ -8,9 +8,8 @@ export default AuthenticatedRoute.extend(CurrentUserSettings, {
|
||||
|
||||
beforeModel() {
|
||||
this._super(...arguments);
|
||||
return this.get('session.user')
|
||||
.then(this.transitionAuthor())
|
||||
.then(this.transitionEditor());
|
||||
this.transitionAuthor(this.session.user);
|
||||
this.transitionEditor(this.session.user);
|
||||
},
|
||||
|
||||
model() {
|
||||
|
@ -8,22 +8,21 @@ export default AuthenticatedRoute.extend(CurrentUserSettings, {
|
||||
|
||||
beforeModel(transition) {
|
||||
this._super(...arguments);
|
||||
return this.get('session.user')
|
||||
.then(this.transitionAuthor())
|
||||
.then(this.transitionEditor())
|
||||
.then(() => {
|
||||
if (transition.to.queryParams?.fromAddressUpdate === 'success') {
|
||||
this.notifications.showAlert(
|
||||
`Newsletter email address has been updated`.htmlSafe(),
|
||||
{type: 'success', key: 'members.settings.from-address.updated'}
|
||||
);
|
||||
} else if (transition.to.queryParams?.supportAddressUpdate === 'success') {
|
||||
this.notifications.showAlert(
|
||||
`Support email address has been updated`.htmlSafe(),
|
||||
{type: 'success', key: 'members.settings.support-address.updated'}
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
this.transitionAuthor(this.session.user);
|
||||
this.transitionEditor(this.session.user);
|
||||
|
||||
if (transition.to.queryParams?.fromAddressUpdate === 'success') {
|
||||
this.notifications.showAlert(
|
||||
`Newsletter email address has been updated`.htmlSafe(),
|
||||
{type: 'success', key: 'members.settings.from-address.updated'}
|
||||
);
|
||||
} else if (transition.to.queryParams?.supportAddressUpdate === 'success') {
|
||||
this.notifications.showAlert(
|
||||
`Support email address has been updated`.htmlSafe(),
|
||||
{type: 'success', key: 'members.settings.support-address.updated'}
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
model() {
|
||||
|
@ -9,8 +9,7 @@ export default AuthenticatedRoute.extend(CurrentUserSettings, {
|
||||
|
||||
beforeModel() {
|
||||
this._super(...arguments);
|
||||
return this.get('session.user')
|
||||
.then(this.transitionAuthor());
|
||||
this.transitionAuthor(this.session.user);
|
||||
},
|
||||
|
||||
model() {
|
||||
|
@ -25,11 +25,9 @@ export default class ProductRoute extends AuthenticatedRoute {
|
||||
|
||||
beforeModel() {
|
||||
super.beforeModel(...arguments);
|
||||
return this.session.user.then((user) => {
|
||||
if (!user.isOwnerOrAdmin) {
|
||||
return this.transitionTo('home');
|
||||
}
|
||||
});
|
||||
if (!this.session.user.isOwnerOrAdmin) {
|
||||
return this.transitionTo('home');
|
||||
}
|
||||
}
|
||||
|
||||
setupController(controller, product) {
|
||||
|
@ -8,8 +8,7 @@ export default AuthenticatedRoute.extend(CurrentUserSettings, {
|
||||
|
||||
beforeModel() {
|
||||
this._super(...arguments);
|
||||
return this.get('session.user')
|
||||
.then(this.transitionAuthor());
|
||||
this.transitionAuthor(this.session.user);
|
||||
},
|
||||
|
||||
model() {
|
||||
|
@ -10,24 +10,24 @@ export default AuthenticatedRoute.extend(CurrentUserSettings, {
|
||||
afterModel(user) {
|
||||
this._super(...arguments);
|
||||
|
||||
return this.get('session.user').then((currentUser) => {
|
||||
let isOwnProfile = user.get('id') === currentUser.get('id');
|
||||
let isAuthorOrContributor = currentUser.get('isAuthorOrContributor');
|
||||
let isEditor = currentUser.get('isEditor');
|
||||
const currentUser = this.session.user;
|
||||
|
||||
if (isAuthorOrContributor && !isOwnProfile) {
|
||||
this.transitionTo('staff.user', currentUser);
|
||||
} else if (isEditor && !isOwnProfile && !user.get('isAuthorOrContributor')) {
|
||||
this.transitionTo('staff');
|
||||
}
|
||||
let isOwnProfile = user.get('id') === currentUser.get('id');
|
||||
let isAuthorOrContributor = currentUser.get('isAuthorOrContributor');
|
||||
let isEditor = currentUser.get('isEditor');
|
||||
|
||||
if (isOwnProfile) {
|
||||
this.store.queryRecord('api-key', {id: 'me'}).then((apiKey) => {
|
||||
this.controller.set('personalToken', apiKey.id + ':' + apiKey.secret);
|
||||
this.controller.set('personalTokenRegenerated', false);
|
||||
});
|
||||
}
|
||||
});
|
||||
if (isAuthorOrContributor && !isOwnProfile) {
|
||||
this.transitionTo('staff.user', currentUser);
|
||||
} else if (isEditor && !isOwnProfile && !user.get('isAuthorOrContributor')) {
|
||||
this.transitionTo('staff');
|
||||
}
|
||||
|
||||
if (isOwnProfile) {
|
||||
this.store.queryRecord('api-key', {id: 'me'}).then((apiKey) => {
|
||||
this.controller.set('personalToken', apiKey.id + ':' + apiKey.secret);
|
||||
this.controller.set('personalTokenRegenerated', false);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
serialize(model) {
|
||||
|
@ -17,8 +17,7 @@ export default AuthenticatedRoute.extend(CurrentUserSettings, {
|
||||
|
||||
beforeModel() {
|
||||
this._super(...arguments);
|
||||
return this.get('session.user')
|
||||
.then(this.transitionAuthor());
|
||||
this.transitionAuthor(this.session.user);
|
||||
},
|
||||
|
||||
model(params) {
|
||||
|
@ -23,8 +23,7 @@ export default AuthenticatedRoute.extend(CurrentUserSettings, ShortcutsRoute, {
|
||||
beforeModel() {
|
||||
this._super(...arguments);
|
||||
|
||||
return this.get('session.user')
|
||||
.then(this.transitionAuthor());
|
||||
this.transitionAuthor(this.session.user);
|
||||
},
|
||||
|
||||
// set model to a live array so all tags are shown and created/deleted tags
|
||||
|
@ -116,13 +116,13 @@ export default class CustomViewsService extends Service {
|
||||
}
|
||||
|
||||
// eslint-disable-next-line ghost/ember/no-observers
|
||||
@observes('settings.sharedViews', 'session.isAuthenticated')
|
||||
@observes('settings.sharedViews', 'session.{isAuthenticated,user}')
|
||||
async updateViewList() {
|
||||
let {settings, session} = this;
|
||||
|
||||
// avoid fetching user before authenticated otherwise the 403 can fire
|
||||
// during authentication and cause errors during setup/signin
|
||||
if (!session.isAuthenticated) {
|
||||
if (!session.isAuthenticated || !session.user) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
import $ from 'jquery';
|
||||
import Ember from 'ember';
|
||||
import EmberError from '@ember/error';
|
||||
import RSVP from 'rsvp';
|
||||
import Service, {inject as service} from '@ember/service';
|
||||
import {computed} from '@ember/object';
|
||||
import {set} from '@ember/object';
|
||||
@ -81,11 +80,8 @@ export default Service.extend({
|
||||
}),
|
||||
|
||||
fetch() {
|
||||
return RSVP.hash({
|
||||
settings: this.settings.fetch(),
|
||||
user: this.get('session.user')
|
||||
}).then(({user}) => {
|
||||
this.set('_user', user);
|
||||
return this.settings.fetch().then(() => {
|
||||
this.set('_user', this.session.user);
|
||||
return this._setAdminTheme().then(() => true);
|
||||
});
|
||||
},
|
||||
|
@ -25,7 +25,7 @@ export default class MembersCountCacheService extends Service {
|
||||
}
|
||||
|
||||
async countString(filter = '', {knownCount} = {}) {
|
||||
const user = await this.session.user;
|
||||
const user = this.session.user;
|
||||
|
||||
const basicFilter = filter.replace(/^subscribed:true\+\((.*)\)$/, '$1');
|
||||
const filterParts = basicFilter.split(',');
|
||||
|
@ -23,16 +23,15 @@ export default class NavigationService extends Service {
|
||||
}
|
||||
|
||||
// eslint-disable-next-line ghost/ember/no-observers
|
||||
@observes('session.isAuthenticated', 'session.user.accessibility')
|
||||
@observes('session.{isAuthenticated,user}', 'session.user.accessibility')
|
||||
async updateSettings() {
|
||||
// avoid fetching user before authenticated otherwise the 403 can fire
|
||||
// during authentication and cause errors during setup/signin
|
||||
if (!this.session.isAuthenticated) {
|
||||
if (!this.session.isAuthenticated || !this.session.user) {
|
||||
return;
|
||||
}
|
||||
|
||||
let user = await this.session.user;
|
||||
let userSettings = JSON.parse(user.get('accessibility')) || {};
|
||||
let userSettings = JSON.parse(this.session.user.accessibility || '{}') || {};
|
||||
this.settings = userSettings.navigation || Object.assign({}, DEFAULT_SETTINGS);
|
||||
}
|
||||
|
||||
@ -51,7 +50,7 @@ export default class NavigationService extends Service {
|
||||
}
|
||||
|
||||
async _saveNavigationSettings() {
|
||||
let user = await this.session.user;
|
||||
let user = this.session.user;
|
||||
let userSettings = JSON.parse(user.get('accessibility')) || {};
|
||||
userSettings.navigation = this.settings;
|
||||
user.set('accessibility', JSON.stringify(userSettings));
|
||||
|
@ -1,40 +1,76 @@
|
||||
import SessionService from 'ember-simple-auth/services/session';
|
||||
import {computed} from '@ember/object';
|
||||
import ESASessionService from 'ember-simple-auth/services/session';
|
||||
import RSVP from 'rsvp';
|
||||
import {configureScope} from '@sentry/browser';
|
||||
import {getOwner} from '@ember/application';
|
||||
import {run} from '@ember/runloop';
|
||||
import {inject as service} from '@ember/service';
|
||||
import {tracked} from '@glimmer/tracking';
|
||||
|
||||
export default SessionService.extend({
|
||||
dataStore: service('store'), // SessionService.store already exists
|
||||
notifications: service(),
|
||||
router: service(),
|
||||
upgradeStatus: service(),
|
||||
export default class SessionService extends ESASessionService {
|
||||
@service config;
|
||||
@service('store') dataStore;
|
||||
@service feature;
|
||||
@service notifications;
|
||||
@service router;
|
||||
@service settings;
|
||||
@service upgradeStatus;
|
||||
@service whatsNew;
|
||||
|
||||
user: computed(function () {
|
||||
return this.dataStore.queryRecord('user', {id: 'me'});
|
||||
}),
|
||||
@tracked user = null;
|
||||
|
||||
authenticate() {
|
||||
// ensure any cached this.user value is removed and re-fetched
|
||||
this.notifyPropertyChange('user');
|
||||
skipAuthSuccessHandler = false;
|
||||
|
||||
return this._super(...arguments);
|
||||
},
|
||||
|
||||
handleAuthentication() {
|
||||
if (this.skipAuthSuccessHandler) {
|
||||
async populateUser(options = {}) {
|
||||
if (this.user) {
|
||||
return;
|
||||
}
|
||||
|
||||
// standard ESA post-sign-in redirect
|
||||
this._super('home');
|
||||
const id = options.id || 'me';
|
||||
const user = await this.dataStore.queryRecord('user', {id});
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
// trigger post-sign-in background behaviour
|
||||
this.user.then(() => {
|
||||
this.notifications.clearAll();
|
||||
this.loadServerNotifications();
|
||||
});
|
||||
},
|
||||
async postAuthPreparation() {
|
||||
await RSVP.all([
|
||||
this.config.fetchAuthenticated(),
|
||||
this.feature.fetch(),
|
||||
this.settings.fetch()
|
||||
]);
|
||||
|
||||
// update Sentry with the full Ghost version which we only get after authentication
|
||||
if (this.config.get('sentry_dsn')) {
|
||||
configureScope((scope) => {
|
||||
scope.addEventProcessor((event) => {
|
||||
return new Promise((resolve) => {
|
||||
resolve({
|
||||
...event,
|
||||
release: `ghost@${this.config.get('version')}`
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
this.loadServerNotifications();
|
||||
this.whatsNew.fetchLatest.perform();
|
||||
}
|
||||
|
||||
async handleAuthentication() {
|
||||
try {
|
||||
await this.populateUser();
|
||||
} catch (err) {
|
||||
await this.invalidate();
|
||||
}
|
||||
|
||||
await this.postAuthPreparation();
|
||||
|
||||
if (this.skipAuthSuccessHandler) {
|
||||
this.skipAuthSuccessHandler = false;
|
||||
return;
|
||||
}
|
||||
|
||||
super.handleAuthentication('home');
|
||||
}
|
||||
|
||||
handleInvalidation() {
|
||||
let transition = this.appLoadTransition;
|
||||
@ -44,28 +80,26 @@ export default SessionService.extend({
|
||||
} else {
|
||||
run.scheduleOnce('routerTransitions', this, 'triggerAuthorizationFailed');
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
// TODO: this feels hacky, find a better way than using .send
|
||||
triggerAuthorizationFailed() {
|
||||
getOwner(this).lookup(`route:${this.router.currentRouteName}`).send('authorizationFailed');
|
||||
},
|
||||
}
|
||||
|
||||
loadServerNotifications() {
|
||||
if (this.isAuthenticated) {
|
||||
this.user.then((user) => {
|
||||
if (!user.isAuthorOrContributor) {
|
||||
this.dataStore.findAll('notification', {reload: true}).then((serverNotifications) => {
|
||||
serverNotifications.forEach((notification) => {
|
||||
if (notification.top || notification.custom) {
|
||||
this.notifications.handleNotification(notification);
|
||||
} else {
|
||||
this.upgradeStatus.handleUpgradeNotification(notification);
|
||||
}
|
||||
});
|
||||
if (!this.user.isAuthorOrContributor) {
|
||||
this.dataStore.findAll('notification', {reload: true}).then((serverNotifications) => {
|
||||
serverNotifications.forEach((notification) => {
|
||||
if (notification.top || notification.custom) {
|
||||
this.notifications.handleNotification(notification);
|
||||
} else {
|
||||
this.upgradeStatus.handleUpgradeNotification(notification);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -12,16 +12,13 @@ export default EphemeralStore.extend({
|
||||
// session cookie or not so we can use that as an indication of the session
|
||||
// being authenticated
|
||||
restore() {
|
||||
return this.session.user.then(() => {
|
||||
return this.session.populateUser().then(() => {
|
||||
// provide the necessary data for internal-session to mark the
|
||||
// session as authenticated
|
||||
let data = {authenticated: {authenticator: 'authenticator:cookie'}};
|
||||
this.persist(data);
|
||||
return data;
|
||||
}).catch(() => {
|
||||
// ensure the session.user doesn't return the same rejected promise
|
||||
// after a succussful login
|
||||
this.session.notifyPropertyChange('user');
|
||||
return RSVP.reject();
|
||||
});
|
||||
}
|
||||
|
@ -84,12 +84,15 @@ describe('Integration: Service: feature', function () {
|
||||
server.shutdown();
|
||||
});
|
||||
|
||||
it('loads labs and user settings correctly', function () {
|
||||
it('loads labs and user settings correctly', async function () {
|
||||
stubSettings(server, {testFlag: true});
|
||||
stubUser(server, {testUserFlag: true});
|
||||
|
||||
addTestFlag();
|
||||
|
||||
let session = this.owner.lookup('service:session');
|
||||
await session.populateUser();
|
||||
|
||||
let service = this.owner.lookup('service:feature');
|
||||
|
||||
return service.fetch().then(() => {
|
||||
@ -98,12 +101,15 @@ describe('Integration: Service: feature', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('returns false for set flag with config false and labs false', function () {
|
||||
it('returns false for set flag with config false and labs false', async function () {
|
||||
stubSettings(server, {testFlag: false});
|
||||
stubUser(server, {});
|
||||
|
||||
addTestFlag();
|
||||
|
||||
let session = this.owner.lookup('service:session');
|
||||
await session.populateUser();
|
||||
|
||||
let service = this.owner.lookup('service:feature');
|
||||
service.get('config').set('testFlag', false);
|
||||
|
||||
@ -113,12 +119,15 @@ describe('Integration: Service: feature', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('returns true for set flag with config true and labs false', function () {
|
||||
it('returns true for set flag with config true and labs false', async function () {
|
||||
stubSettings(server, {testFlag: false});
|
||||
stubUser(server, {});
|
||||
|
||||
addTestFlag();
|
||||
|
||||
let session = this.owner.lookup('service:session');
|
||||
await session.populateUser();
|
||||
|
||||
let service = this.owner.lookup('service:feature');
|
||||
service.get('config').set('testFlag', true);
|
||||
|
||||
@ -128,12 +137,15 @@ describe('Integration: Service: feature', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('returns true for set flag with config false and labs true', function () {
|
||||
it('returns true for set flag with config false and labs true', async function () {
|
||||
stubSettings(server, {testFlag: true});
|
||||
stubUser(server, {});
|
||||
|
||||
addTestFlag();
|
||||
|
||||
let session = this.owner.lookup('service:session');
|
||||
await session.populateUser();
|
||||
|
||||
let service = this.owner.lookup('service:feature');
|
||||
service.get('config').set('testFlag', false);
|
||||
|
||||
@ -143,12 +155,15 @@ describe('Integration: Service: feature', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('returns true for set flag with config true and labs true', function () {
|
||||
it('returns true for set flag with config true and labs true', async function () {
|
||||
stubSettings(server, {testFlag: true});
|
||||
stubUser(server, {});
|
||||
|
||||
addTestFlag();
|
||||
|
||||
let session = this.owner.lookup('service:session');
|
||||
await session.populateUser();
|
||||
|
||||
let service = this.owner.lookup('service:feature');
|
||||
service.get('config').set('testFlag', true);
|
||||
|
||||
@ -158,12 +173,15 @@ describe('Integration: Service: feature', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('returns false for set flag with accessibility false', function () {
|
||||
it('returns false for set flag with accessibility false', async function () {
|
||||
stubSettings(server, {});
|
||||
stubUser(server, {testUserFlag: false});
|
||||
|
||||
addTestFlag();
|
||||
|
||||
let session = this.owner.lookup('service:session');
|
||||
await session.populateUser();
|
||||
|
||||
let service = this.owner.lookup('service:feature');
|
||||
|
||||
return service.fetch().then(() => {
|
||||
@ -172,12 +190,15 @@ describe('Integration: Service: feature', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('returns true for set flag with accessibility true', function () {
|
||||
it('returns true for set flag with accessibility true', async function () {
|
||||
stubSettings(server, {});
|
||||
stubUser(server, {testUserFlag: true});
|
||||
|
||||
addTestFlag();
|
||||
|
||||
let session = this.owner.lookup('service:session');
|
||||
await session.populateUser();
|
||||
|
||||
let service = this.owner.lookup('service:feature');
|
||||
|
||||
return service.fetch().then(() => {
|
||||
@ -186,12 +207,15 @@ describe('Integration: Service: feature', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('saves labs setting correctly', function () {
|
||||
it('saves labs setting correctly', async function () {
|
||||
stubSettings(server, {testFlag: false});
|
||||
stubUser(server, {testUserFlag: false});
|
||||
|
||||
addTestFlag();
|
||||
|
||||
let session = this.owner.lookup('service:session');
|
||||
await session.populateUser();
|
||||
|
||||
let service = this.owner.lookup('service:feature');
|
||||
service.get('config').set('testFlag', false);
|
||||
|
||||
@ -209,12 +233,15 @@ describe('Integration: Service: feature', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('saves accessibility setting correctly', function () {
|
||||
it('saves accessibility setting correctly', async function () {
|
||||
stubSettings(server, {});
|
||||
stubUser(server, {testUserFlag: false});
|
||||
|
||||
addTestFlag();
|
||||
|
||||
let session = this.owner.lookup('service:session');
|
||||
await session.populateUser();
|
||||
|
||||
let service = this.owner.lookup('service:feature');
|
||||
|
||||
return service.fetch().then(() => {
|
||||
@ -231,12 +258,15 @@ describe('Integration: Service: feature', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('notifies for server errors on labs save', function () {
|
||||
it('notifies for server errors on labs save', async function () {
|
||||
stubSettings(server, {testFlag: false}, false);
|
||||
stubUser(server, {});
|
||||
|
||||
addTestFlag();
|
||||
|
||||
let session = this.owner.lookup('service:session');
|
||||
await session.populateUser();
|
||||
|
||||
let service = this.owner.lookup('service:feature');
|
||||
service.get('config').set('testFlag', false);
|
||||
|
||||
@ -263,12 +293,15 @@ describe('Integration: Service: feature', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('notifies for server errors on accessibility save', function () {
|
||||
it('notifies for server errors on accessibility save', async function () {
|
||||
stubSettings(server, {});
|
||||
stubUser(server, {testUserFlag: false}, false);
|
||||
|
||||
addTestFlag();
|
||||
|
||||
let session = this.owner.lookup('service:session');
|
||||
await session.populateUser();
|
||||
|
||||
let service = this.owner.lookup('service:feature');
|
||||
|
||||
return service.fetch().then(() => {
|
||||
@ -294,12 +327,15 @@ describe('Integration: Service: feature', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('notifies for validation errors', function () {
|
||||
it('notifies for validation errors', async function () {
|
||||
stubSettings(server, {testFlag: false}, true, false);
|
||||
stubUser(server, {});
|
||||
|
||||
addTestFlag();
|
||||
|
||||
let session = this.owner.lookup('service:session');
|
||||
await session.populateUser();
|
||||
|
||||
let service = this.owner.lookup('service:feature');
|
||||
service.get('config').set('testFlag', false);
|
||||
|
||||
|
@ -61,10 +61,6 @@ describe('Unit: Authenticator: cookie', () => {
|
||||
let authenticator = this.owner.lookup('authenticator:cookie');
|
||||
let post = authenticator.ajax.post;
|
||||
|
||||
let config = this.owner.lookup('service:config');
|
||||
let feature = this.owner.lookup('service:feature');
|
||||
let settings = this.owner.lookup('service:settings');
|
||||
|
||||
return authenticator.authenticate('AzureDiamond', 'hunter2').then(() => {
|
||||
expect(post.args[0][0]).to.equal(`${ghostPaths().apiRoot}/session`);
|
||||
expect(post.args[0][1]).to.deep.include({
|
||||
@ -79,11 +75,6 @@ describe('Unit: Authenticator: cookie', () => {
|
||||
expect(post.args[0][1]).to.deep.include({
|
||||
contentType: 'application/json;charset=utf-8'
|
||||
});
|
||||
|
||||
// ensure our pre-loading calls have been made
|
||||
expect(config.fetchAuthenticated.calledOnce, 'config.fetchAuthenticated called').to.be.true;
|
||||
expect(feature.fetch.calledOnce, 'feature.fetch called').to.be.true;
|
||||
expect(settings.fetch.calledOnce, 'settings.fetch called').to.be.true;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user