Ghost/ghost/admin/app/routes/signup.js
Kevin Ansfield 4de244974e 🎨 remove usage of ghost's {{asset}} helper in index.html (#574)
refs #8140

🎨 remove usage of ghost's {{asset}} helper in built index.html files

requires https://github.com/TryGhost/Ghost/pull/8142
- switch to hash-location rather than history-location
- remove usage of Ghost's `{{asset}}` helper in index.html
- add `content-for` helpers to `asset-delivery` addon that switch asset urls in index.html to `.min` files in production
- update the `asset-delivery` addon to copy the production `index.min.html` to `default-prod.hbs` so Ghost can serve production assets when in production mode
- change template output path to `core/server/admin/views/`
- enable asset fingerprinting
- remove `ember-cli-sri` dependency - we weren't using it but now that ember is handling assets it was used automatically and could potentially create issues if users have proxy servers that attempt to compress or otherwise modify asset files

 redirect to setup if server says setup isn't finished

refs https://github.com/TryGhost/Ghost/issues/8140
- now we're using hash-location the server no longer knows if we're hitting the /setup route so it's not able to redirect for us
- extends the default ESA `UnauthenticatedRouteMixin` to add a check against the `/authentication/setup` API endpoint and redirects to `/#/setup/one` if setup isn't complete - this works for all routes because the default behaviour when hitting an authenticated route without the right credentials is to force a logout and redirect to `/#/signin` which utilises the `UnauthenticatedRouteMixin`

deps: ember-cli-inject-live-reload@1.6.1
2017-03-14 17:04:46 +01:00

143 lines
5.6 KiB
JavaScript

import Route from 'ember-route';
import RSVP from 'rsvp';
import injectService from 'ember-service/inject';
import EmberObject from 'ember-object';
import {assign} from 'ember-platform';
import {
VersionMismatchError,
isVersionMismatchError
} from 'ghost-admin/services/ajax';
import DS from 'ember-data';
import UnauthenticatedRouteMixin from 'ghost-admin/mixins/unauthenticated-route-mixin';
import styleBody from 'ghost-admin/mixins/style-body';
const {Promise} = RSVP;
const {Errors} = DS;
export default Route.extend(styleBody, UnauthenticatedRouteMixin, {
classNames: ['ghost-signup'],
ghostPaths: injectService(),
notifications: injectService(),
session: injectService(),
ajax: injectService(),
beforeModel() {
if (this.get('session.isAuthenticated')) {
this.get('notifications').showAlert('You need to sign out to register as a new user.', {type: 'warn', delayed: true, key: 'signup.create.already-authenticated'});
}
this._super(...arguments);
},
model(params) {
let model = EmberObject.create();
let re = /^(?:[A-Za-z0-9_\-]{4})*(?:[A-Za-z0-9_\-]{2}|[A-Za-z0-9_\-]{3})?$/;
let email,
tokenText;
return new Promise((resolve) => {
if (!re.test(params.token)) {
this.get('notifications').showAlert('Invalid token.', {type: 'error', delayed: true, key: 'signup.create.invalid-token'});
return resolve(this.transitionTo('signin'));
}
tokenText = atob(params.token);
email = tokenText.split('|')[1];
model.set('email', email);
model.set('token', params.token);
model.set('errors', Errors.create());
let authUrl = this.get('ghostPaths.url').api('authentication', 'invitation');
return this.get('ajax').request(authUrl, {
dataType: 'json',
data: {
email
}
}).then((response) => {
if (response && response.invitation && response.invitation[0].valid === false) {
this.get('notifications').showAlert('The invitation does not exist or is no longer valid.', {type: 'warn', delayed: true, key: 'signup.create.invalid-invitation'});
return resolve(this.transitionTo('signin'));
}
model.set('invitedBy', response.invitation[0].invitedBy);
resolve(model);
}).catch(() => {
resolve(model);
});
});
},
deactivate() {
this._super(...arguments);
// clear the properties that hold the sensitive data from the controller
this.controllerFor('signup').setProperties({email: '', password: '', token: ''});
},
actions: {
authenticateWithGhostOrg() {
let authStrategy = 'authenticator:oauth2-ghost';
let inviteToken = this.get('controller.model.token');
let email = this.get('controller.model.email');
this.toggleProperty('controller.loggingIn');
this.set('controller.flowErrors', '');
this.get('torii')
.open('ghost-oauth2', {email, type: 'invite'})
.then((authentication) => {
let _authentication = assign({}, authentication, {inviteToken});
this.send('authenticate', authStrategy, [_authentication]);
})
.catch(() => {
this.toggleProperty('controller.loggingIn');
this.set('controller.flowErrors', 'Authentication with Ghost.org denied or failed');
});
},
// TODO: this is duplicated with the signin route - maybe extract into a mixin?
authenticate(strategy, authentication) {
// Authentication transitions to posts.index, we can leave spinner running unless there is an error
this.get('session')
.authenticate(strategy, ...authentication)
.catch((error) => {
this.toggleProperty('controller.loggingIn');
if (error && error.errors) {
// we don't get back an ember-data/ember-ajax error object
// back so we need to pass in a null status in order to
// test against the payload
if (isVersionMismatchError(null, error)) {
let versionMismatchError = new VersionMismatchError(error);
return this.get('notifications').showAPIError(versionMismatchError);
}
error.errors.forEach((err) => {
err.message = err.message.htmlSafe();
});
this.set('controller.flowErrors', error.errors[0].message.string);
if (error.errors[0].message.string.match(/user with that email/)) {
this.get('controller.model.errors').add('identification', '');
}
if (error.errors[0].message.string.match(/password is incorrect/)) {
this.get('controller.model.errors').add('password', '');
}
} else {
// Connection errors don't return proper status message, only req.body
this.get('notifications').showAlert('There was a problem on the server.', {type: 'error', key: 'session.authenticate.failed'});
}
});
}
}
});