0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-01-20 22:42:53 -05:00
ghost/core/server/api/themes.js

223 lines
8.2 KiB
JavaScript
Raw Normal View History

// # Themes API
// RESTful API for Themes
✨ New fully-loaded & validated activeTheme concept (#8146) 📡 Add debug for the 3 theme activation methods There are 3 different ways that a theme can be activated in Ghost: A. On boot: we load the active theme from the file system, according to the `activeTheme` setting B. On API "activate": when an /activate/ request is triggered for a theme, we validate & change the `activeTheme` setting C. On API "override": if uploading a theme with the same name, we override. Using a dirty hack to make this work. A: setting is done, should load & validate + next request does mounting B: load is done, should validate & change setting + next request does mounting C: load, validate & setting are all done + a hack is needed to ensure the next request does mounting ✨ Validate w/ gscan when theme activating on boot - use the new gscan validation validate.check() method when activating on boot ✨ New concept of active theme - add ActiveTheme class - make it possible to set a theme to be active, and to get the active theme - call the new themes.activate() method in all 3 cases where we activate a theme 🎨 Use new activeTheme to simplify theme code - make use of the new concept where we can, to reduce & simplify code - use new hasPartials() method so we don't have to do file lookups - use path & name getters to reduce use of getContentPath etc - remove requirement on req.app.get('activeTheme') from static-theme middleware (more on this soon) 🚨 Improve theme unit tests (TODO: fix inter-dep) - The theme unit tests are borked! They all pass because they don't test the right things. - This improves them, but they are still dependent on each-other - configHbsForContext tests don't pass if the activateTheme tests aren't run first - I will fix this in a later PR
2017-03-13 20:13:17 +00:00
var debug = require('debug')('ghost:api:themes'),
Promise = require('bluebird'),
fs = require('fs-extra'),
config = require('../config'),
errors = require('../errors'),
events = require('../events'),
🎨 configurable logging with bunyan (#7431) - 🛠 add bunyan and prettyjson, remove morgan - ✨ add logging module - GhostLogger class that handles setup of bunyan - PrettyStream for stdout - ✨ config for logging - @TODO: testing level fatal? - ✨ log each request via GhostLogger (express middleware) - @TODO: add errors to output - 🔥 remove errors.updateActiveTheme - we can read the value from config - 🔥 remove 15 helper functions in core/server/errors/index.js - all these functions get replaced by modules: 1. logging 2. error middleware handling for html/json 3. error creation (which will be part of PR #7477) - ✨ add express error handler for html/json - one true error handler for express responses - contains still some TODO's, but they are not high priority for first implementation/integration - this middleware only takes responsibility of either rendering html responses or return json error responses - 🎨 use new express error handler in middleware/index - 404 and 500 handling - 🎨 return error instead of error message in permissions/index.js - the rule for error handling should be: if you call a unit, this unit should return a custom Ghost error - 🎨 wrap serve static module - rule: if you call a module/unit, you should always wrap this error - it's always the same rule - so the caller never has to worry about what comes back - it's always a clear error instance - in this case: we return our notfounderror if serve static does not find the resource - this avoid having checks everywhere - 🎨 replace usages of errors/index.js functions and adapt tests - use logging.error, logging.warn - make tests green - remove some usages of logging and throwing api errors -> because when a request is involved, logging happens automatically - 🐛 return errorDetails to Ghost-Admin - errorDetails is used for Theme error handling - 🎨 use 500er error for theme is missing error in theme-handler - 🎨 extend file rotation to 1w
2016-10-04 17:33:43 +02:00
logging = require('../logging'),
storage = require('../storage'),
apiUtils = require('./utils'),
utils = require('./../utils'),
i18n = require('../i18n'),
✨ Themes API activation permissions & validation (#8104) refs #8093 ✨ Add activate theme permission - add permission to activate themes - update tests - also: update tests for invites TODO: change how the active theme setting is updated to reduce extra permissions ✨ Move theme validation to gscan - add a new gscan validation method and use it for upload - update activate endpoint to do validation also using gscan - change to using SettingsModel instead of API so that we don't call validation or permissions on the settings API - remove validation from the settings model - remove the old validation function - add new invalid theme message to translations & remove a bunch of theme validation related unused keys 📖 Planned changes 🚨 Tests for theme activation API endpoint 🐛 Don't allow deleting the active theme 🚫 Prevent activeTheme being set via settings API - We want to control how this happens in future. - We still want to store the information in settings, via the model. - We just don't want to be able to change this info via the settings edit endpoint 🐛 ✨ Fix warnings for uploads & add for activations - warnings for uploads were broken in f8b498d - fix the response + adds tests to cover that warnings are correctly returned - add the same response to activations + more tests - activations now return a single theme object - the theme that was activated + any warnings 🎨 Improve how we generate theme API responses - remove the requirement to pass in the active theme! - move this to a specialist function, away from the list 🎨 Do not load gscan on boot
2017-03-13 11:44:44 +00:00
settingsModel = require('../models/settings').Settings,
settingsCache = require('../settings/cache'),
themeUtils = require('../themes'),
themeList = themeUtils.list,
themes;
/**
* ## Themes API Methods
*
* **See:** [API Methods](index.js.html#api%20methods)
*/
themes = {
browse: function browse(options) {
return apiUtils
// Permissions
.handlePermissions('themes', 'browse')(options)
// Main action
.then(function makeApiResult() {
// Return JSON result
return themeUtils.toJSON();
});
},
activate: function activate(options) {
var themeName = options.name,
newSettings = [{
key: 'activeTheme',
value: themeName
✨ Themes API activation permissions & validation (#8104) refs #8093 ✨ Add activate theme permission - add permission to activate themes - update tests - also: update tests for invites TODO: change how the active theme setting is updated to reduce extra permissions ✨ Move theme validation to gscan - add a new gscan validation method and use it for upload - update activate endpoint to do validation also using gscan - change to using SettingsModel instead of API so that we don't call validation or permissions on the settings API - remove validation from the settings model - remove the old validation function - add new invalid theme message to translations & remove a bunch of theme validation related unused keys 📖 Planned changes 🚨 Tests for theme activation API endpoint 🐛 Don't allow deleting the active theme 🚫 Prevent activeTheme being set via settings API - We want to control how this happens in future. - We still want to store the information in settings, via the model. - We just don't want to be able to change this info via the settings edit endpoint 🐛 ✨ Fix warnings for uploads & add for activations - warnings for uploads were broken in f8b498d - fix the response + adds tests to cover that warnings are correctly returned - add the same response to activations + more tests - activations now return a single theme object - the theme that was activated + any warnings 🎨 Improve how we generate theme API responses - remove the requirement to pass in the active theme! - move this to a specialist function, away from the list 🎨 Do not load gscan on boot
2017-03-13 11:44:44 +00:00
}],
loadedTheme,
checkedTheme;
return apiUtils
// Permissions
✨ Themes API activation permissions & validation (#8104) refs #8093 ✨ Add activate theme permission - add permission to activate themes - update tests - also: update tests for invites TODO: change how the active theme setting is updated to reduce extra permissions ✨ Move theme validation to gscan - add a new gscan validation method and use it for upload - update activate endpoint to do validation also using gscan - change to using SettingsModel instead of API so that we don't call validation or permissions on the settings API - remove validation from the settings model - remove the old validation function - add new invalid theme message to translations & remove a bunch of theme validation related unused keys 📖 Planned changes 🚨 Tests for theme activation API endpoint 🐛 Don't allow deleting the active theme 🚫 Prevent activeTheme being set via settings API - We want to control how this happens in future. - We still want to store the information in settings, via the model. - We just don't want to be able to change this info via the settings edit endpoint 🐛 ✨ Fix warnings for uploads & add for activations - warnings for uploads were broken in f8b498d - fix the response + adds tests to cover that warnings are correctly returned - add the same response to activations + more tests - activations now return a single theme object - the theme that was activated + any warnings 🎨 Improve how we generate theme API responses - remove the requirement to pass in the active theme! - move this to a specialist function, away from the list 🎨 Do not load gscan on boot
2017-03-13 11:44:44 +00:00
.handlePermissions('themes', 'activate')(options)
// Validation
.then(function validateTheme() {
✨ Themes API activation permissions & validation (#8104) refs #8093 ✨ Add activate theme permission - add permission to activate themes - update tests - also: update tests for invites TODO: change how the active theme setting is updated to reduce extra permissions ✨ Move theme validation to gscan - add a new gscan validation method and use it for upload - update activate endpoint to do validation also using gscan - change to using SettingsModel instead of API so that we don't call validation or permissions on the settings API - remove validation from the settings model - remove the old validation function - add new invalid theme message to translations & remove a bunch of theme validation related unused keys 📖 Planned changes 🚨 Tests for theme activation API endpoint 🐛 Don't allow deleting the active theme 🚫 Prevent activeTheme being set via settings API - We want to control how this happens in future. - We still want to store the information in settings, via the model. - We just don't want to be able to change this info via the settings edit endpoint 🐛 ✨ Fix warnings for uploads & add for activations - warnings for uploads were broken in f8b498d - fix the response + adds tests to cover that warnings are correctly returned - add the same response to activations + more tests - activations now return a single theme object - the theme that was activated + any warnings 🎨 Improve how we generate theme API responses - remove the requirement to pass in the active theme! - move this to a specialist function, away from the list 🎨 Do not load gscan on boot
2017-03-13 11:44:44 +00:00
loadedTheme = themeList.get(themeName);
if (!loadedTheme) {
return Promise.reject(new errors.ValidationError({
message: i18n.t('notices.data.validation.index.themeCannotBeActivated', {themeName: themeName}),
context: 'activeTheme'
}));
}
✨ Themes API activation permissions & validation (#8104) refs #8093 ✨ Add activate theme permission - add permission to activate themes - update tests - also: update tests for invites TODO: change how the active theme setting is updated to reduce extra permissions ✨ Move theme validation to gscan - add a new gscan validation method and use it for upload - update activate endpoint to do validation also using gscan - change to using SettingsModel instead of API so that we don't call validation or permissions on the settings API - remove validation from the settings model - remove the old validation function - add new invalid theme message to translations & remove a bunch of theme validation related unused keys 📖 Planned changes 🚨 Tests for theme activation API endpoint 🐛 Don't allow deleting the active theme 🚫 Prevent activeTheme being set via settings API - We want to control how this happens in future. - We still want to store the information in settings, via the model. - We just don't want to be able to change this info via the settings edit endpoint 🐛 ✨ Fix warnings for uploads & add for activations - warnings for uploads were broken in f8b498d - fix the response + adds tests to cover that warnings are correctly returned - add the same response to activations + more tests - activations now return a single theme object - the theme that was activated + any warnings 🎨 Improve how we generate theme API responses - remove the requirement to pass in the active theme! - move this to a specialist function, away from the list 🎨 Do not load gscan on boot
2017-03-13 11:44:44 +00:00
return themeUtils.validate.check(loadedTheme);
})
// Update setting
.then(function changeActiveThemeSetting(_checkedTheme) {
✨ Themes API activation permissions & validation (#8104) refs #8093 ✨ Add activate theme permission - add permission to activate themes - update tests - also: update tests for invites TODO: change how the active theme setting is updated to reduce extra permissions ✨ Move theme validation to gscan - add a new gscan validation method and use it for upload - update activate endpoint to do validation also using gscan - change to using SettingsModel instead of API so that we don't call validation or permissions on the settings API - remove validation from the settings model - remove the old validation function - add new invalid theme message to translations & remove a bunch of theme validation related unused keys 📖 Planned changes 🚨 Tests for theme activation API endpoint 🐛 Don't allow deleting the active theme 🚫 Prevent activeTheme being set via settings API - We want to control how this happens in future. - We still want to store the information in settings, via the model. - We just don't want to be able to change this info via the settings edit endpoint 🐛 ✨ Fix warnings for uploads & add for activations - warnings for uploads were broken in f8b498d - fix the response + adds tests to cover that warnings are correctly returned - add the same response to activations + more tests - activations now return a single theme object - the theme that was activated + any warnings 🎨 Improve how we generate theme API responses - remove the requirement to pass in the active theme! - move this to a specialist function, away from the list 🎨 Do not load gscan on boot
2017-03-13 11:44:44 +00:00
checkedTheme = _checkedTheme;
// We use the model, not the API here, as we don't want to trigger permissions
return settingsModel.edit(newSettings, options);
})
// Call activate
✨ Themes API activation permissions & validation (#8104) refs #8093 ✨ Add activate theme permission - add permission to activate themes - update tests - also: update tests for invites TODO: change how the active theme setting is updated to reduce extra permissions ✨ Move theme validation to gscan - add a new gscan validation method and use it for upload - update activate endpoint to do validation also using gscan - change to using SettingsModel instead of API so that we don't call validation or permissions on the settings API - remove validation from the settings model - remove the old validation function - add new invalid theme message to translations & remove a bunch of theme validation related unused keys 📖 Planned changes 🚨 Tests for theme activation API endpoint 🐛 Don't allow deleting the active theme 🚫 Prevent activeTheme being set via settings API - We want to control how this happens in future. - We still want to store the information in settings, via the model. - We just don't want to be able to change this info via the settings edit endpoint 🐛 ✨ Fix warnings for uploads & add for activations - warnings for uploads were broken in f8b498d - fix the response + adds tests to cover that warnings are correctly returned - add the same response to activations + more tests - activations now return a single theme object - the theme that was activated + any warnings 🎨 Improve how we generate theme API responses - remove the requirement to pass in the active theme! - move this to a specialist function, away from the list 🎨 Do not load gscan on boot
2017-03-13 11:44:44 +00:00
.then(function hasEditedSetting() {
✨ New fully-loaded & validated activeTheme concept (#8146) 📡 Add debug for the 3 theme activation methods There are 3 different ways that a theme can be activated in Ghost: A. On boot: we load the active theme from the file system, according to the `activeTheme` setting B. On API "activate": when an /activate/ request is triggered for a theme, we validate & change the `activeTheme` setting C. On API "override": if uploading a theme with the same name, we override. Using a dirty hack to make this work. A: setting is done, should load & validate + next request does mounting B: load is done, should validate & change setting + next request does mounting C: load, validate & setting are all done + a hack is needed to ensure the next request does mounting ✨ Validate w/ gscan when theme activating on boot - use the new gscan validation validate.check() method when activating on boot ✨ New concept of active theme - add ActiveTheme class - make it possible to set a theme to be active, and to get the active theme - call the new themes.activate() method in all 3 cases where we activate a theme 🎨 Use new activeTheme to simplify theme code - make use of the new concept where we can, to reduce & simplify code - use new hasPartials() method so we don't have to do file lookups - use path & name getters to reduce use of getContentPath etc - remove requirement on req.app.get('activeTheme') from static-theme middleware (more on this soon) 🚨 Improve theme unit tests (TODO: fix inter-dep) - The theme unit tests are borked! They all pass because they don't test the right things. - This improves them, but they are still dependent on each-other - configHbsForContext tests don't pass if the activateTheme tests aren't run first - I will fix this in a later PR
2017-03-13 20:13:17 +00:00
// Activate! (sort of)
debug('Activating theme (method B on API "activate")', themeName);
themeUtils.activate(loadedTheme, checkedTheme);
// Return JSON result
✨ Themes API activation permissions & validation (#8104) refs #8093 ✨ Add activate theme permission - add permission to activate themes - update tests - also: update tests for invites TODO: change how the active theme setting is updated to reduce extra permissions ✨ Move theme validation to gscan - add a new gscan validation method and use it for upload - update activate endpoint to do validation also using gscan - change to using SettingsModel instead of API so that we don't call validation or permissions on the settings API - remove validation from the settings model - remove the old validation function - add new invalid theme message to translations & remove a bunch of theme validation related unused keys 📖 Planned changes 🚨 Tests for theme activation API endpoint 🐛 Don't allow deleting the active theme 🚫 Prevent activeTheme being set via settings API - We want to control how this happens in future. - We still want to store the information in settings, via the model. - We just don't want to be able to change this info via the settings edit endpoint 🐛 ✨ Fix warnings for uploads & add for activations - warnings for uploads were broken in f8b498d - fix the response + adds tests to cover that warnings are correctly returned - add the same response to activations + more tests - activations now return a single theme object - the theme that was activated + any warnings 🎨 Improve how we generate theme API responses - remove the requirement to pass in the active theme! - move this to a specialist function, away from the list 🎨 Do not load gscan on boot
2017-03-13 11:44:44 +00:00
return themeUtils.toJSON(themeName, checkedTheme);
});
},
upload: function upload(options) {
options = options || {};
// consistent filename uploads
options.originalname = options.originalname.toLowerCase();
var storageAdapter = storage.getStorage('themes'),
zip = {
path: options.path,
name: options.originalname,
shortName: storageAdapter.getSanitizedFileName(options.originalname.split('.zip')[0])
✨ Themes API activation permissions & validation (#8104) refs #8093 ✨ Add activate theme permission - add permission to activate themes - update tests - also: update tests for invites TODO: change how the active theme setting is updated to reduce extra permissions ✨ Move theme validation to gscan - add a new gscan validation method and use it for upload - update activate endpoint to do validation also using gscan - change to using SettingsModel instead of API so that we don't call validation or permissions on the settings API - remove validation from the settings model - remove the old validation function - add new invalid theme message to translations & remove a bunch of theme validation related unused keys 📖 Planned changes 🚨 Tests for theme activation API endpoint 🐛 Don't allow deleting the active theme 🚫 Prevent activeTheme being set via settings API - We want to control how this happens in future. - We still want to store the information in settings, via the model. - We just don't want to be able to change this info via the settings edit endpoint 🐛 ✨ Fix warnings for uploads & add for activations - warnings for uploads were broken in f8b498d - fix the response + adds tests to cover that warnings are correctly returned - add the same response to activations + more tests - activations now return a single theme object - the theme that was activated + any warnings 🎨 Improve how we generate theme API responses - remove the requirement to pass in the active theme! - move this to a specialist function, away from the list 🎨 Do not load gscan on boot
2017-03-13 11:44:44 +00:00
},
checkedTheme;
// check if zip name is casper.zip
if (zip.name === 'casper.zip') {
throw new errors.ValidationError({message: i18n.t('errors.api.themes.overrideCasper')});
}
return apiUtils
// Permissions
.handlePermissions('themes', 'add')(options)
// Validation
✨ Themes API activation permissions & validation (#8104) refs #8093 ✨ Add activate theme permission - add permission to activate themes - update tests - also: update tests for invites TODO: change how the active theme setting is updated to reduce extra permissions ✨ Move theme validation to gscan - add a new gscan validation method and use it for upload - update activate endpoint to do validation also using gscan - change to using SettingsModel instead of API so that we don't call validation or permissions on the settings API - remove validation from the settings model - remove the old validation function - add new invalid theme message to translations & remove a bunch of theme validation related unused keys 📖 Planned changes 🚨 Tests for theme activation API endpoint 🐛 Don't allow deleting the active theme 🚫 Prevent activeTheme being set via settings API - We want to control how this happens in future. - We still want to store the information in settings, via the model. - We just don't want to be able to change this info via the settings edit endpoint 🐛 ✨ Fix warnings for uploads & add for activations - warnings for uploads were broken in f8b498d - fix the response + adds tests to cover that warnings are correctly returned - add the same response to activations + more tests - activations now return a single theme object - the theme that was activated + any warnings 🎨 Improve how we generate theme API responses - remove the requirement to pass in the active theme! - move this to a specialist function, away from the list 🎨 Do not load gscan on boot
2017-03-13 11:44:44 +00:00
.then(function validateTheme() {
return themeUtils.validate.check(zip, true);
})
// More validation (existence check)
✨ Themes API activation permissions & validation (#8104) refs #8093 ✨ Add activate theme permission - add permission to activate themes - update tests - also: update tests for invites TODO: change how the active theme setting is updated to reduce extra permissions ✨ Move theme validation to gscan - add a new gscan validation method and use it for upload - update activate endpoint to do validation also using gscan - change to using SettingsModel instead of API so that we don't call validation or permissions on the settings API - remove validation from the settings model - remove the old validation function - add new invalid theme message to translations & remove a bunch of theme validation related unused keys 📖 Planned changes 🚨 Tests for theme activation API endpoint 🐛 Don't allow deleting the active theme 🚫 Prevent activeTheme being set via settings API - We want to control how this happens in future. - We still want to store the information in settings, via the model. - We just don't want to be able to change this info via the settings edit endpoint 🐛 ✨ Fix warnings for uploads & add for activations - warnings for uploads were broken in f8b498d - fix the response + adds tests to cover that warnings are correctly returned - add the same response to activations + more tests - activations now return a single theme object - the theme that was activated + any warnings 🎨 Improve how we generate theme API responses - remove the requirement to pass in the active theme! - move this to a specialist function, away from the list 🎨 Do not load gscan on boot
2017-03-13 11:44:44 +00:00
.then(function checkExists(_checkedTheme) {
checkedTheme = _checkedTheme;
return storageAdapter.exists(utils.url.urlJoin(config.getContentPath('themes'), zip.shortName));
})
// If the theme existed we need to delete it
.then(function removeOldTheme(themeExists) {
// delete existing theme
if (themeExists) {
return storageAdapter.delete(zip.shortName, config.getContentPath('themes'));
}
})
.then(function storeNewTheme() {
events.emit('theme.uploaded', zip.shortName);
// store extracted theme
return storageAdapter.save({
name: zip.shortName,
✨ Themes API activation permissions & validation (#8104) refs #8093 ✨ Add activate theme permission - add permission to activate themes - update tests - also: update tests for invites TODO: change how the active theme setting is updated to reduce extra permissions ✨ Move theme validation to gscan - add a new gscan validation method and use it for upload - update activate endpoint to do validation also using gscan - change to using SettingsModel instead of API so that we don't call validation or permissions on the settings API - remove validation from the settings model - remove the old validation function - add new invalid theme message to translations & remove a bunch of theme validation related unused keys 📖 Planned changes 🚨 Tests for theme activation API endpoint 🐛 Don't allow deleting the active theme 🚫 Prevent activeTheme being set via settings API - We want to control how this happens in future. - We still want to store the information in settings, via the model. - We just don't want to be able to change this info via the settings edit endpoint 🐛 ✨ Fix warnings for uploads & add for activations - warnings for uploads were broken in f8b498d - fix the response + adds tests to cover that warnings are correctly returned - add the same response to activations + more tests - activations now return a single theme object - the theme that was activated + any warnings 🎨 Improve how we generate theme API responses - remove the requirement to pass in the active theme! - move this to a specialist function, away from the list 🎨 Do not load gscan on boot
2017-03-13 11:44:44 +00:00
path: checkedTheme.path
}, config.getContentPath('themes'));
})
.then(function loadNewTheme() {
✨ Themes API activation permissions & validation (#8104) refs #8093 ✨ Add activate theme permission - add permission to activate themes - update tests - also: update tests for invites TODO: change how the active theme setting is updated to reduce extra permissions ✨ Move theme validation to gscan - add a new gscan validation method and use it for upload - update activate endpoint to do validation also using gscan - change to using SettingsModel instead of API so that we don't call validation or permissions on the settings API - remove validation from the settings model - remove the old validation function - add new invalid theme message to translations & remove a bunch of theme validation related unused keys 📖 Planned changes 🚨 Tests for theme activation API endpoint 🐛 Don't allow deleting the active theme 🚫 Prevent activeTheme being set via settings API - We want to control how this happens in future. - We still want to store the information in settings, via the model. - We just don't want to be able to change this info via the settings edit endpoint 🐛 ✨ Fix warnings for uploads & add for activations - warnings for uploads were broken in f8b498d - fix the response + adds tests to cover that warnings are correctly returned - add the same response to activations + more tests - activations now return a single theme object - the theme that was activated + any warnings 🎨 Improve how we generate theme API responses - remove the requirement to pass in the active theme! - move this to a specialist function, away from the list 🎨 Do not load gscan on boot
2017-03-13 11:44:44 +00:00
// Loads the theme from the filesystem
// Sets the theme on the themeList
return themeUtils.loadOne(zip.shortName);
})
.then(function activateAndReturn(loadedTheme) {
✨ New fully-loaded & validated activeTheme concept (#8146) 📡 Add debug for the 3 theme activation methods There are 3 different ways that a theme can be activated in Ghost: A. On boot: we load the active theme from the file system, according to the `activeTheme` setting B. On API "activate": when an /activate/ request is triggered for a theme, we validate & change the `activeTheme` setting C. On API "override": if uploading a theme with the same name, we override. Using a dirty hack to make this work. A: setting is done, should load & validate + next request does mounting B: load is done, should validate & change setting + next request does mounting C: load, validate & setting are all done + a hack is needed to ensure the next request does mounting ✨ Validate w/ gscan when theme activating on boot - use the new gscan validation validate.check() method when activating on boot ✨ New concept of active theme - add ActiveTheme class - make it possible to set a theme to be active, and to get the active theme - call the new themes.activate() method in all 3 cases where we activate a theme 🎨 Use new activeTheme to simplify theme code - make use of the new concept where we can, to reduce & simplify code - use new hasPartials() method so we don't have to do file lookups - use path & name getters to reduce use of getContentPath etc - remove requirement on req.app.get('activeTheme') from static-theme middleware (more on this soon) 🚨 Improve theme unit tests (TODO: fix inter-dep) - The theme unit tests are borked! They all pass because they don't test the right things. - This improves them, but they are still dependent on each-other - configHbsForContext tests don't pass if the activateTheme tests aren't run first - I will fix this in a later PR
2017-03-13 20:13:17 +00:00
// If this is the active theme, we are overriding
// This is a special case of activation
if (zip.shortName === settingsCache.get('activeTheme')) {
// Activate! (sort of)
debug('Activating theme (method C, on API "override")', zip.shortName);
themeUtils.activate(loadedTheme, checkedTheme);
}
✨ Themes API activation permissions & validation (#8104) refs #8093 ✨ Add activate theme permission - add permission to activate themes - update tests - also: update tests for invites TODO: change how the active theme setting is updated to reduce extra permissions ✨ Move theme validation to gscan - add a new gscan validation method and use it for upload - update activate endpoint to do validation also using gscan - change to using SettingsModel instead of API so that we don't call validation or permissions on the settings API - remove validation from the settings model - remove the old validation function - add new invalid theme message to translations & remove a bunch of theme validation related unused keys 📖 Planned changes 🚨 Tests for theme activation API endpoint 🐛 Don't allow deleting the active theme 🚫 Prevent activeTheme being set via settings API - We want to control how this happens in future. - We still want to store the information in settings, via the model. - We just don't want to be able to change this info via the settings edit endpoint 🐛 ✨ Fix warnings for uploads & add for activations - warnings for uploads were broken in f8b498d - fix the response + adds tests to cover that warnings are correctly returned - add the same response to activations + more tests - activations now return a single theme object - the theme that was activated + any warnings 🎨 Improve how we generate theme API responses - remove the requirement to pass in the active theme! - move this to a specialist function, away from the list 🎨 Do not load gscan on boot
2017-03-13 11:44:44 +00:00
// @TODO: unify the name across gscan and Ghost!
return themeUtils.toJSON(zip.shortName, checkedTheme);
})
.finally(function () {
✨ Themes API activation permissions & validation (#8104) refs #8093 ✨ Add activate theme permission - add permission to activate themes - update tests - also: update tests for invites TODO: change how the active theme setting is updated to reduce extra permissions ✨ Move theme validation to gscan - add a new gscan validation method and use it for upload - update activate endpoint to do validation also using gscan - change to using SettingsModel instead of API so that we don't call validation or permissions on the settings API - remove validation from the settings model - remove the old validation function - add new invalid theme message to translations & remove a bunch of theme validation related unused keys 📖 Planned changes 🚨 Tests for theme activation API endpoint 🐛 Don't allow deleting the active theme 🚫 Prevent activeTheme being set via settings API - We want to control how this happens in future. - We still want to store the information in settings, via the model. - We just don't want to be able to change this info via the settings edit endpoint 🐛 ✨ Fix warnings for uploads & add for activations - warnings for uploads were broken in f8b498d - fix the response + adds tests to cover that warnings are correctly returned - add the same response to activations + more tests - activations now return a single theme object - the theme that was activated + any warnings 🎨 Improve how we generate theme API responses - remove the requirement to pass in the active theme! - move this to a specialist function, away from the list 🎨 Do not load gscan on boot
2017-03-13 11:44:44 +00:00
// @TODO we should probably do this as part of saving the theme
// remove zip upload from multer
// happens in background
Promise.promisify(fs.removeSync)(zip.path)
.catch(function (err) {
logging.error(new errors.GhostError({err: err}));
});
✨ Themes API activation permissions & validation (#8104) refs #8093 ✨ Add activate theme permission - add permission to activate themes - update tests - also: update tests for invites TODO: change how the active theme setting is updated to reduce extra permissions ✨ Move theme validation to gscan - add a new gscan validation method and use it for upload - update activate endpoint to do validation also using gscan - change to using SettingsModel instead of API so that we don't call validation or permissions on the settings API - remove validation from the settings model - remove the old validation function - add new invalid theme message to translations & remove a bunch of theme validation related unused keys 📖 Planned changes 🚨 Tests for theme activation API endpoint 🐛 Don't allow deleting the active theme 🚫 Prevent activeTheme being set via settings API - We want to control how this happens in future. - We still want to store the information in settings, via the model. - We just don't want to be able to change this info via the settings edit endpoint 🐛 ✨ Fix warnings for uploads & add for activations - warnings for uploads were broken in f8b498d - fix the response + adds tests to cover that warnings are correctly returned - add the same response to activations + more tests - activations now return a single theme object - the theme that was activated + any warnings 🎨 Improve how we generate theme API responses - remove the requirement to pass in the active theme! - move this to a specialist function, away from the list 🎨 Do not load gscan on boot
2017-03-13 11:44:44 +00:00
// @TODO we should probably do this as part of saving the theme
// remove extracted dir from gscan
// happens in background
✨ Themes API activation permissions & validation (#8104) refs #8093 ✨ Add activate theme permission - add permission to activate themes - update tests - also: update tests for invites TODO: change how the active theme setting is updated to reduce extra permissions ✨ Move theme validation to gscan - add a new gscan validation method and use it for upload - update activate endpoint to do validation also using gscan - change to using SettingsModel instead of API so that we don't call validation or permissions on the settings API - remove validation from the settings model - remove the old validation function - add new invalid theme message to translations & remove a bunch of theme validation related unused keys 📖 Planned changes 🚨 Tests for theme activation API endpoint 🐛 Don't allow deleting the active theme 🚫 Prevent activeTheme being set via settings API - We want to control how this happens in future. - We still want to store the information in settings, via the model. - We just don't want to be able to change this info via the settings edit endpoint 🐛 ✨ Fix warnings for uploads & add for activations - warnings for uploads were broken in f8b498d - fix the response + adds tests to cover that warnings are correctly returned - add the same response to activations + more tests - activations now return a single theme object - the theme that was activated + any warnings 🎨 Improve how we generate theme API responses - remove the requirement to pass in the active theme! - move this to a specialist function, away from the list 🎨 Do not load gscan on boot
2017-03-13 11:44:44 +00:00
if (checkedTheme) {
Promise.promisify(fs.removeSync)(checkedTheme.path)
.catch(function (err) {
logging.error(new errors.GhostError({err: err}));
});
}
});
},
download: function download(options) {
var themeName = options.name,
theme = themeList.get(themeName),
storageAdapter = storage.getStorage('themes');
if (!theme) {
return Promise.reject(new errors.BadRequestError({message: i18n.t('errors.api.themes.invalidRequest')}));
}
return apiUtils
// Permissions
.handlePermissions('themes', 'read')(options)
.then(function sendTheme() {
events.emit('theme.downloaded', themeName);
return storageAdapter.serve({isTheme: true, name: themeName});
});
},
/**
* remove theme zip
* remove theme folder
*/
destroy: function destroy(options) {
var themeName = options.name,
theme,
storageAdapter = storage.getStorage('themes');
return apiUtils
// Permissions
.handlePermissions('themes', 'destroy')(options)
// Validation
.then(function validateTheme() {
if (themeName === 'casper') {
throw new errors.ValidationError({message: i18n.t('errors.api.themes.destroyCasper')});
}
if (themeName === settingsCache.get('activeTheme')) {
✨ Themes API activation permissions & validation (#8104) refs #8093 ✨ Add activate theme permission - add permission to activate themes - update tests - also: update tests for invites TODO: change how the active theme setting is updated to reduce extra permissions ✨ Move theme validation to gscan - add a new gscan validation method and use it for upload - update activate endpoint to do validation also using gscan - change to using SettingsModel instead of API so that we don't call validation or permissions on the settings API - remove validation from the settings model - remove the old validation function - add new invalid theme message to translations & remove a bunch of theme validation related unused keys 📖 Planned changes 🚨 Tests for theme activation API endpoint 🐛 Don't allow deleting the active theme 🚫 Prevent activeTheme being set via settings API - We want to control how this happens in future. - We still want to store the information in settings, via the model. - We just don't want to be able to change this info via the settings edit endpoint 🐛 ✨ Fix warnings for uploads & add for activations - warnings for uploads were broken in f8b498d - fix the response + adds tests to cover that warnings are correctly returned - add the same response to activations + more tests - activations now return a single theme object - the theme that was activated + any warnings 🎨 Improve how we generate theme API responses - remove the requirement to pass in the active theme! - move this to a specialist function, away from the list 🎨 Do not load gscan on boot
2017-03-13 11:44:44 +00:00
throw new errors.ValidationError({message: i18n.t('errors.api.themes.destroyActive')});
}
theme = themeList.get(themeName);
if (!theme) {
throw new errors.NotFoundError({message: i18n.t('errors.api.themes.themeDoesNotExist')});
}
// Actually do the deletion here
return storageAdapter.delete(themeName, config.getContentPath('themes'));
})
// And some extra stuff to maintain state here
.then(function deleteTheme() {
themeList.del(themeName);
events.emit('theme.deleted', themeName);
// Delete returns an empty 204 response
});
}
};
module.exports = themes;