* 🐛 fix direct update
closes#7297
- move sitemap initialisation into sitemap handler
- initialise sitemap on first request to sitemap
* 🐛 fix how we pass options to migration files
refs #7317
- clone options when passing them into the migration/fixture files
- do not use default sequence, because it does not clone the arguments
no issue
This PR takes the existing function `processUrls` in `data/xml/rss` and refactors it to be a stand-alone util.
The change is needed, as this functionality will be accessed from `apps/amp` to convert relative URLs.
closes#7186
- Add a concept of validity to each generator
- Refactor base generator to handle invalid (empty) nodes for both events & the initial generation
- Update the tests a bit, to fix some bugs in the tests
- Ensure the homepage is always present
closes#6588, #7095
* `ImageObject` with image dimensions (#7152, #7151, #7153)
- Returns meta data as promise
- returns a new Promise from meta data
- uses `Promise.props()` to resolve `getClient()` and `getMetaData()`
- Adds 'image-size' util
The util returns an object like this
```
{
height: 50,
url: 'http://myblog.com/images/cat.jpg',
width: 50
};
```
if the dimensions can be fetched and rejects with error, if not.
In case we get a locally stored image or a not complete url (like `//www.gravatar.com/andsoon`), we add the protocol to the incomplete one and use `urlFor()` to get the absolute URL. If the request fails or `image-size` is not able to read the file, we reject with error.
- adds 'image-size' module to dependencies
- adds `getImageSizeFromUrl` function that returns image dimensions
- In preparation of AMP support and to improve our schema.org JSON-LD and structured data, I made the following changes:
- Changes the following properties to be `Objects`, which have a `url` property by default and a `dimensions` property, if `width` and `height` are available:
- `metaData.coverImage`
- `metaData.authorImage`
- `metaData.blog.logo`
- Checks cache by calling `getCachedImageSizeFromUrl`. If image dimensions were fetched already, returns them from cache instead of fetching them again.
- If we have image dimensions on hand, the output in our JSON-LD changes from normal urls to be full `ImageObjects`. Applies to all images and logos.
- Special case for `publisher.logo` as it has size restrictions: if the image doesn't fulfil the restrictions (<=600 width and <=60 height), we simply output the url instead, so like before.
- Adds new property for schema.org JSON-LD: `mainEntityOfPage` as an Object.
- Adds additional Open Graph data (if we have the image size): `og:image:width` and `og:image:height`
- Adds/updates tests
* AMP router and controller (#7171, #7157)
Implements AMP in `/apps/`:
- renders `amp.hbs` if route is `/:slug/amp/`
- updates `setResponseContext` to set context to `['amp', 'post']` for a amp post and `['amp', 'page']` for a page, but will not render amp template for a page
- updates `context_spec`
- registers 'amp' as new internal app
- adds the `amp.hbs` template to `core/server/apps/amp` which will be the default template for AMP posts.
- adds `isAmpURL` to `post-lookup`
* 🎨 Use `context` in meta as array (#7205)
Instead of reading the first value of the context array, we're checking if it includes certain context values.
This is a preparation change for AMP, where the context will be delivered as `['amp', 'post']`.
* ✨ AMP helpers (#7174, #7216, #7215, #7223)
- Adds AMP helpers `{{amp_content}}`, `{{amp_component}}` and `{{amp_ghost_head}}` to support AMP:
- `{{amp_content}}`:
- Adds `Amperize` as dependency
- AMP app uses new helper `{{amp_content}}` to render AMP HTML
- `Amperize` transforms regular HTML into AMP HTML
- Adds test for `{{amp_content}}` helper
- Adds 'Sanitize-HTML` as dependendy
- After the HTML get 'amperized' we still might have some HTML tags, which are prohibited in AMP HTML, so we use `sanitize-html` to remove those. With every update, `Amperize` gets and it is able to transform more HTML tags, they valid AMP HTML tags (e. g. `video` and `amp-video`) and will therefore not be removed.
- `{{amp_ghost_head}}`:
- registers `{{amp_ghost_head}}` helper, but uses `{{ghost_head}}` code
- uses `{{amp_ghost_head}}` in `amp.hbs` instead of `{{ghost_head}}`
- `{{ghost_head}}`:
- Render `amphtml` link in metadata for post, which links to the amp post (`getAmpUrl`)
- Updates all test in metadata to support `amp` context
- Changes context conditionals to work with full array instead of first array value
- Adds conditionals, so no additional javascript gets rendered in `{{ghost_head}}`
- Removes trailing `/amp/` in URLs, so only `amphtml` link on regular post renders it
- Adds a conditional, so no code injection will be included, for an `amp` context.
- `{{amp_components}}`:
- AMP app uses new helper `{{amp_components}}` to render necessary script tags for AMP extended components as `amp-iframe`, `amp-anime` and `amp-form`
- Adds test for `{{amp_components}}`
no issue
- Source out validation logic into a upload validation middleware for all upload types (csv, image, subscribers). This unit can be later used for Ghost 1.0 as a pre validation core unit.
- More usage of route tests than controller tests. These are use case tests, a use case only changes if the product changes
no issue
- sets `settings.activeTimezone` to best-guess based on current server time when performing the timezones migration in order to prevent unexpected changes in timezone when upgrading
closes#5071
- Send application/json requests to UpdateCheck service. New UpdateCheck service accepts JSON request
- If UpdateCheck service respponse has messages[] array, iterate over the array and create custom notifications intended for current version
- Save custom notification if its not already in the store AND its uuid is not in seenNotifications array
- When a custom notification is dismissed, store its uuid in seenNotifications array
- setup test fixtures to trigger tests properly
- api_notification_spec test to ensure custom notification can be added to store and added to seenNotifications when dismissed
- update_check_spec test to ensure custom notification can be displayed for a specific Ghost version
- added test to ensure messages meant for other versions don't create notifications
no issue
- changes xmlrcp & slack `init` function to be `listen`
- update the code to use `listen` instead of `init`
- changes the tests to make sure that event listeners are not wired up
- adds 100% test coverage
Since we added slack event listeners, the xmlrpc event tests have been throwing an error:
> Unhandled rejection Error
See: http://puu.sh/phvjZ.png
This is because both xmlrpc & slack are listening to `post.published` events.
xmlrpc didn't require any extra stubbing, but the slack listener did
By turning the listeners off after the tests, we reset the environment to not impact the next event test
We probably need to do more work like this to improve the systems around event handling and
make them more robust
refs #6933
Some hard timezones of the hard coded list where shown (`label`-property) with a `GMT`-offset incl. DST. All offsets are now without DST.
Removes `offset` property as it is not used and `Greenwich Mean Time` from label.
issues #6406#6399
- all dates are stored as UTC with this commit
- use moment.tz.setDefault('UTC')
- add migration file to recalculate local datetimes to UTC
- store all dates in same format into our three supported databases
- add option to remeber migrations inside settings (core)
- support DST offset for migration
- ensure we force UTC in test env
- run whole migration as transaction
- extend: Settings.findOne function
- add NODE_LEVEL to print errors while running tests
- try/catch while parsing translations file
- run setup/teardown as promise or callback
- some general error improvements
closes#6406
- adding timeZone Service to get the offset (=timezone reg. moment-timezone) overall available
- new publishedAtOffset date as CP using timeZone service and moment-timezone to calculate offset incl. DST
- removing timezone-obj transform as it became obsolete with moment-timezone
- reading timezones from configuration/timezones api endpoint
- adding a moment-utc transform to only work with utc times in backend
- when switching the timezone in the select box, the user will be shown the local time of the selected timezone
- added clock service to show actual time ticking below select box
- default timezone is '(GMT) Greenwich Mean Time : Dublin, Edinburgh, London'
- if no timezone is saved in the settings yet, the default value will be used
- showing local time in 'Publish Date' when it's a draft and no actual publishedAt value exists
- Removed the format 'DD MMM YY @ HH:mm (UTC Z)' which resolves to '01 Jan 16 @ 14:00 (UTC +02:00)'
- Changing the date.js helper in core/server for moment-timezone
- Fix timezone select: updates `selectedTimezone` to return the matching object from `availableTimezones`
- Including timezones in test for date-helper
- update to moment-timezone 0.5.1
- moving form-group of 'selectTimezone' further up so
- Tests:
- Set except for clock service in test env
- adding fixtures to mirage
- adding 'service.ajax' to navigation-test.js
- adding 'service:ghostPaths' to navigation-test.js
- Code improvements
- Changing clockservice to ES6
closes#6826
- refactors the validation of facebook and twitter input field in `general.js` and `user.js` controller
- Example validations for facebook:
- `facebook.com/username` will be corrected to the full URL
- `user` will show error `Your Page name is not a valid Facebook Page name' for `general.js` and `Your Username is not a valid Facebook Username` for `user.js` as the username in facebook has to be at least 5 characters long
- `twitter.com/username` will be autocorrected to the valid facebook URL incl. the `username`
- Example validations for twitter:
- `twitter.com/user_` will be corrected to the full URL
- `user:99` will show error `Your Username is not a valid Twitter Username`
- `facebook.com/username` will be autocorrected to the valid twitter URL incl. the `username`
- updates both acceptance tests
- adds further validation for facebook pages in general settings and user. Submitting a url which incl. `/page/` or `/pages/` will now accept any username followed incl. further `/`.
- adds a custom transform `facebook-url-user` which will extract the username (if it's a facebook page, incl. `pages/`) to store only this in the backend
- uses the `twitter-url-user` transform now also for user
refs #6534
- twitter & facebook fields are changing to store usernames only
- use the new social url util to generate urls where necessary
- update tests
refs #6534
- don't output publisher for the 'People' type on the author page
- change publisher to a full 'Organisation' for the 'Article' type on posts
Note:
Google's structured data validator also wants image & publisher.logo inside of Article to be full 'ImageObject's.
Currently, it output's an error for them: 'The attribute itemtype has an invalid value.'
However, the spec on Schema.org says a url is valid: https://schema.org/Article,
which is slightly different to Google's spec here: https://developers.google.com/structured-data/rich-snippets/articles#article_markup_properties
Ideally, we would output a full 'ImageObject', however we don't currently have the width & height info required.
Therefore, I think what we have is valid strictly speaking, but we should aim to fix this when we have better image tools.
no issue
- minor optical fix for schema.org metadata
- sameAs property was showing `null` value in array, if no data was provided
- instead of showing `null`, it will be empty, if no data (author website, facebook or twitter) it will be an empty array
closes#6534
- new input fields in general settings incl. validation
- facebook and twitter as new models in settings.js
- adds values for facebook and twitter to default-settings.js
- adds blog helpers for facebook and twittter
- rather than saving the whole URL, the Twitter username incl. '@' will be extracted from URL and saved in the settings. The User will still input the full URL. After saving the blog setting, the stored Twitter username will be parsed again as the full URL and available in the input field. A custom transform is used for this.
- adding meta fields to be rendered in {{ghost_head}}:
- '<meta property="article:publisher" content="https://www.facebook.com/page" />' and
- '<meta name="twitter:site" content="@user"/>'
- adds facebook and twitter to unit test for structured data
- adds unit test for general settings
- adds acceptance test for new input fields in general settings
- adds a custom transform for twitter model to save only the username to the server
- adds unit test for transform
closes#6584
- Frontend Changes:
- adds 'Apps' to Navigation Menu
- adds 'Slack' as nested page to Apps
- adds `apps.css`
- adds `slack-integration` model and uses `slack-settings` custom transform to parse JSON file
- adds validation for `slack` model
- adds fixtures and `slack/test` API endpoint to Mirage
- adds acceptance tests for `apps-test` and `slack-test`
- adds unit tests for `slack-settings` and `slack-integration`
- Backend Changes:
- adds API endpoint `slack/test` to send Test Notification
- adds default-values for slack model
- sends payload to slack:
- text: the url of the blogpost / test message
- icon_url: url to ghost logo
- username: Ghost
- adds `slack/index.js` to send webhook to slack if
- a new post is published (if slack webhook url is saved in settings)
- user clicks on 'Send Test Notification' in UI
- adds `slack.init()` to `server.index.js` to add event listener
- adds unit test for `slack/index`
closes#6462
- monkey-patch validator.extends() since it was dropped by validator @5.0.0
- coerce input to string prior to validation (custom toString func)
- need to handle boolean validation based on column type not isIn()
- use `lodash.tostring` to convert input values to strings
refs #6301, #4176
Add migration for:
- 5 new client permissions
- 15 relations between the admin, editor & author role and the 5 new permissions
- updates to tests to show that permissions get updated properly
refs #6301, #6399
- new scheduler client will be used by any web app that handles time and calls back to the scheduling API at the right time
- new scheduler client will need to be confidential, rather than public, hence the 'web' type instead of 'ua'
- adds validation to client type that it must have a type of 'ua', 'web', or 'native'
refs #6301
- move the temporary `fixClientSecret` function from migration.init into being a proper fixture migration task
- update the tests accordingly
refs #6301
- bump the default version & update corresponding test
- add empty task folders for 005 data & fixture migrations
- update tests to cover the new 005 upgrades
refs #6301, #4176
- always check existence of items before attempting to create them, in order to prevent duplicates
- provide stats on how many object creations are expected vs done
- split out and improve fixture utils tests (100% covers utils)
refs #6301
- The order of model fixtures matters, so they should be in an array
- By splitting out the population code into a utils file, it'll be possible to use this to do updates as well
- This should make it much easier to do permissions updates in future
refs #6621, #6622
- remove unneeded `return new Promise.resolve()` lines
- reduce code in tests
- improve quality of tests checking that all task functions are executed
- add missing test coverage
refs #6623
- automatically set useNullAsDefault to false for sqlite3 so that we don't get a warning
- we should *not* be relying on the behaviour of interpretting undefined anywhere, so it is correct that an error should be output if this happens so that we can fix the bad behaviour
refs #6301
- fix messages that joined with comma and therefore missed outputting version no
- change `logInfo` to `logger` that has both an info and a warn method
- add new warn method to errors
- add a warn message everytime a migration (data or fixture) gets skipped over
- update logger everywhere, including tests
- update tests to check logger.warn gets called
refs #6301
- Make sure that every fixture operation has a check to ensure that it hasn't already run
- E.g. The update of sort_order on posts_tags should only happen if there are no values which aren't a zero
- This makes sure that we don't accidentally overwrite data on FORCE_MIGRATE
- No need to try to set settings types if they are already correct
- Only update the admin client if it needs it, else we're regenerating secrets each time
refs #5091, #6612
- unify getNextUrl & getPrevUrl into getPaginatedUrl
- ensure that it can generate a prev, next or exact page no url
- ensure that it can figure out the base url
- use the same code from the page_url helper
- refactor the tests to ensure there's 100% coverage
Following on from #6612, this ensures that pagination always works regardless of whether the channel is default or custom
refs #6301
- Replace builder & automated database upgrade with a set of explicit tasks
- Ensure the tasks can only happen if they need to
- Remove some duplicate code between fixture & db upgrades (more to do)
- Add tests
refs #6301
- changes createTable to use createTableIfNotExists, this is consistent with deletion
- splits out backup, reset, update and populate functions from migration/index into their own files
- moves the wrapped function for populatingDefaultSettings to fixtures.ensureDefaultSettings
- moves `modelOptions` down to the fixture files that actually use it
- adds test coverage for backup, reset and populate, but not for update as that needs refactoring
refs #6301
- `currentVersion` was leftover from before the first public release of Ghost!
- simplified the code for `getDatabaseVersion`
- improved & made consistent how errors are handled in `getDatabaseVersion`
- migration error handling updated to reflect the changes in `getDatabaseVersion`
- added tests for both `getDatabaseVersion` and `setDatabaseVersion`
refs #6301
- change knex getter def to be configurable, else it is not testable
- remove exportPath and lang from config - neither are used
- add client_trusted_domains to tables which shouldn't be exported as there are no clients in the export
- change export signature to be an object with `doExport` function consistent with import & easier to test
- cleanup export code so it is clearer, easier to read & to test:
- use mapSeries instead of sequence
- use Promise.props instead of Promise.join
- split functionality into smaller functions
- add test coverage
refs #6301
Fixtures:
- Removed all the old (and now broken) 003 fixture upgrades
- Split the 004 fixture upgrade tasks out, each into their own file
- Improved the versioning code that figured out which upgrades we should do
- Added lots of test coverage to make sure all the fixtures are still being run correctly.
Permissions fixtures:
- Changed the code that was populating permissions fixtures to be more automated & based only on what is in the permissions.json file.
- Added lots of test coverage to make sure all the permissions are still being created correctly.
Merging the two things:
- Merged the content of permissions.json and fixtures.json into fixtures.json, but using the new structure from permissions.json.
- Changed to use the new automated model & relation creation for all fixtures, not just permissions.
- The only thing that can't be auto-populated just now is the owner creation, I think that's important enough to do separately.
- There were (so far) never any permission updates, so code for updating fixtures stays the same through the merge.
- This results in two clear code paths: populate (fill out a brand new DB) and update (make any changes since the last version)
Test coverage is now 100% across both updates and populations.
closes#6361
- Updated bluebird dependency to latest 3.1.2.
- Updated update check to handle promises not resolving to arrays.
- Reviewed all other promise code and it looks good.
- Updated code using settle to use the new reflect function.
refs #6406
- endpoint configuration/timezones refers to timezones.json file in data
- added route for endpoint in api.js to use method read in configuration.js
refs #6534
- fixes a bug where published_at was incorrectly falling back to the created_at date
- updated meta index to get author name
- add written by & filed under labels + data if the values are present (only on posts/pages)
- updated tests
no issue
- In Ghost, 'context' means the page or section of a blog we're currently within
when rendering a theme, e.g. 'post' or 'tag' or 'home'.
- In handlebars 'context' refers to the blob of JSON that is tied to a template.
- These two uses of the word 'context' have gotten very confusing, so I've removed all usage of 'context' within the Ghost handlebars helpers, EXCEPT where they actually refer to the current context (e.g. the is helper)
refs #5345
- As discussed in #5345, this is effectively debug output.
- It currently only appears on the console, and console output should be in English
- If we add a UI later, this should be translated, but console/debug output should not
refs #6301
- Move secret generation logic to the model defaults, so there's no need to handle this in fixtures
- Tested upgrades from 003 & fresh installs -> all is well
refs #6534
- this is an initial fix for having no description at all unless a meta description is provided
- we may need to tweak the lengths / provide different lengths for different values in future
closes#6186
- Refactored ghost head helper to use the new metadata functions.
- Fix issue where tag should output description if missing meta description.
- Add test for tag description.
- Updated tests to look for author urls with a tailing backslash
- Fix author to output meta description first and then bio if missing.
refs #6301
- In the migration folder, commands.js changed to builder.js to resolve conflict with the 'commands' inside data/utils/clients/.
- a new data/schema/ folder has been added to hold all the code related to the database schema
- data/utils/clients have been moved to data/schema/clients
- data/utils/index.js has become data/schema/commands.js
- data/schema.js has been split, the definition of the DB schema stays put, the additional checks have moved to data/schema/checks.js
- data/validation/index.js has become data/schema/versioning.js
- data/fixtures has moved to data/migration/fixtures
- data/default-settings.json has moved to data/schema/default-settings.json
issue #6186
- Moved asset helper logic to a asset url function.
- Created author image function to be used in ghost_head helper.
- Created author url function to be used in the ghost_head helper.
- Created canonical url function to be used in the ghost_head helper.
- Moved meta_description helper logic to a function.
- Moved excerpt helper logic to a function.
- Created an index in data/meta to be used in ghost_head helper to get all data.
- Created keyword function to be used in the ghost_head helper.
- Created modified data function to be used in the ghost_head helper.
- Created next url function to be used in the ghost_head helper.
- Created ogType function to be used in the ghost_head helper.
- Created previous url function to be used in the ghost_head helper.
- Created published data function to be used in the ghost_head helper.
- Created rss url function to be used in the ghost_head helper.
- Created schema function to be used in the ghost_head helper.
- Created structured data function to be used in the ghost_head helper.
- Moved meta_title helper logic to a title function.
- Moved url helper logic to a url function.
- Wrote tests for all the new functions
This is just the first step. I plan on refactoring the ghost head to use these new functions.
fixes#6292
- Added createImageNodeFromDatum to BaseSiteMapGenerator
- Refactor some defaults code that was unnecessary
- Add tests for posts, tags, users and posts with images
no issue
- Cache the permalinks & postsPerPage settings on the config.theme object
- Use the config.theme cache to reference these items throughout the frontend of a blog
- Removes the need for workarounds and extra code to handle async fetches
- Makes these values accessible to all themes, which is very useful now we have the API stuff
refs #5943, #5091
- split out channel config
- use config.theme instead of api calls to grab title & desc
- wrap rss call in a function which sets channel config for RSS feeds
- change rss `getData` function to use the new multiple-query-handling fetchData functionality
- make sure channelConfig is set in all tests
refs #5923
- add read-themes module to get a list of themes
- replace readDirectory() usage with readThemes(), where only themes are needed
- test read-themes
- test read-directory
- test validate-themes
- test parse-package-json
- add tempfile testing utility to generate temporary paths
closes#5492
- remove core/server/require-tree.js and split it into modules
- add read-directory module to recursively read directories
- add validate-themes module to scan themes and return errors/warnings
- add parse-package-json module to parse json and validate requirements
- rewrite core/server/models/index.js to manually require models
refs #5909, #4577
- removes accidental '.only' which was hiding issues with the findAll changes
- deleteAllContent and importer still need to use a hard 'findAll' as findPage({limit: 'all'}) doesn't have the same behaviour
closes#5872
- added random secret for new databases
- added temporary fix for existing databases
- secret is still static (`not_available`) during tests
- fixed fork mechanism to keep active environment (never change
NODE_ENV!!!)
refs #5808
- Fix the API to return a single 422 error when an invalid value is passed
- Only affects Browse, and not Read at present due to differences in how they are handled
- Frontend was changed to always 404 in #5851
- Adds tests to ensure all cases are covered
refs #5727, #5602
- Add new 'order' column to posts_tags table
- Migrate all existing posts_tags to have a correct value for 'order'
- Rewrite updateTags to not remove all tags, and to correctly maintain order
- Add transaction support for tag operations
- Many tests
no issue
- added ghost-admin client_id to admin
- added ghost-admin client_secret to admin
- added client.read() api endpoint
- added random generation of client_secret to migration
- removed addClientSecret method
- updated tests
closes#5692, refs felixrieseberg/Ghost-Azure#1
- fix broken promise code
- fix incorrect handling of hash in user.add which causes 'Error: Invalid salt version 2' if owner user fixture is not present
refs #5685, #5709
- cycle through all tags, removing leading commas and trim spaces
- if the string is empty, change to 'tag' - the slug base for this model
- if there is a change, save it
refs #5614 and #5503
- update private blog type, including update to settings.edit
- switch order of populate settings & update fixtures + populate all settings
Private blog settings should not be returned by public endpoints
therefore they need a type which is not `blog` or `theme`.
`core` doesn't suit either, as those settings don't usually have UI
To resolve this, I created a new type `private` which can be used
for any setting which has a UI but should not be public data
closes#5298
- remove all harcoded instances of jQuery throughout the front-end of the blog
- add migration function to add cdn link to ghost_foot code injection when migrating up from version 003
- migration version bump
closes#4174
- Added columns to client table in schema.js
- Bumped database version in default-settings.json
- Updated tests to support new schema version
closes#5685
- Adds client and server-side validation for tag names starting with commas
- Trim tag names before adding in PSM (tag attributes are already trimmed before saving in TSM)
closes#5567
- Fixed an issue with protocol relative URLs in the RSS feed
- Such URLs should be kept as-is and not prefixed with baseUrl
- Added corresponding test to cover this case
refs #2758
- add a set of default options to utils
- update validation function to only pass through permitted options
- pass permitted options into validate where necessary
- setup basic validation for each known option, and generic validation for the remainder
- change slug to treat 'name' as data, rather than an option
refs #1833
- move RSS tests to be in rss_spec.js
- improve RSS test coverage
- fix a bug with RSS title generation for tag RSS feeds
- replace custom code in processUrls with urlJoin
no issue
- I noticed this in CodeClimate, it was reporting errors for this file because of a dodgy char.
- Removed it and named the functions whilst I was in there :)
refs #5344
- As a result of #5344, context are pretty broken.
- This PR removes all dependence on req.route.path, and uses res.locals.relativeUrl
- res.locals.relativeUrl is used for many things and is dependable
refs #5091
- This is step one of several steps towards ending up with dynamic routes for channels
- Refactoring this way makes the similarities between all the routes clearer to see
closes#4778
- If import contains an owner that does not match original owner they are downgraded to admin
- Change error message for locked users to more generic message to account for imported users
- Adds duplicated user test
- Process Roles and maps import roles to db roles
- reduces export files in test fixtures
temp commit
refs #2330
- Pass through `options` to all toJSON calls on posts, tags, and users
- Use options.context.user to determine whether it's OK to return user.email
- Remove author.email handling code from frontend.js
refs #5091, refs #2263
- Move rss handling out of the frontend controller and into its own module
- Separate the code into logical blocks
- Wrap the generation code in a in-memory cache to prevent it being regenerated on every request
fixes#5104, refs #4348, #2263
- Create a centralised event module
- Hook it up for posts, pages, tags and users
- Use it in sitemaps instead of direct method calls
- Use it for xmlrpc calls
- Check events are fired in model tests
- Update sitemap tests to work with new code
- Fix a bug where invited users were appearing in sitemaps
- Move sitemaps and xmlrpc into a directory together
Closes#4540
- Implements drag & drop to reorder navigation items
- Adds a `sort` property to navigation items
- Adds a tiny library to enable touch events for drag & drop. It hooks onto jQuery UI.
- Sort nav items before being saved
- Adds `settings-view-navigation` to route for body class
needed for #4852
Before this, calling `{{url}}` with a nav context from #4541 would
output `/`. This adds a check in `urlFor` that looks for keys in a
nav context object, namely `slug`, `current`, `label`, & `url`.
This change allows for a url to pass through if used in a nav context.
* adds `schema.isNav()`
* adds tests to `url_spec.js`
* handles absolute urls correctly even if `absolute=true`
Closes#4792
- Made priority be 0.8 (as it currently is) for standard posts
- Made featured posts have a priority of 0.9
- Split the current test into two to check both above scenarios
closes#4691
- adds a file handler for markdown file (.md and .markdown)
- handles titles and featured images
- gets status, date, and slug from the filename
- has a test suite
ref #4608, #4609, #4690
- fix errors with cleaning up files
- improve handling of base directories, and introduce a simple valid format for zips (must contain importable files or folders, and may contain up to one base directory)
- vastly improve test coverage
closes#4608, #4609
- image handler loads in any image files & figures out where they'll get stored
- image importer has a preprocessor which replaces image paths in
pertinent spots of post, tag and user models
- image importer stores images, keeping the path where it makes sense
- basic test for the preprocessor
refs #4605, #4479
- Removes versioning from the importer
- Fixes an issue with SQLITE errors not being thrown properly for posts
- Ensures that posts have a created_at date
- Makes sure that the API wrapper is properly handled
refs #4605
- Move as much code as possible out of the DB API
- Split the importer into 2 concepts, code which handles different
filetypes and code which takes the content of files and imports it into
Ghost in some way
- Split the import process into 4 steps, load the file into a useful
format, preprocess the data, do the import, generate a report
- Reporting is currently a no-op
- Adds a basic level of testing
Closes#4611
Refactored generateXmlFromNodes to pull the urlElements itself from
sorted values in the lookup
Added some checks to existing unit tests to validate ordering.
fixes#4555
- There's no easy way to declare an XSL with the node xml module, so I
needed to move the declarations to both be strings
- Ideally the code to serve the XSL would also be inside the sitemap
module, but I think we need to refactor a bit to get there easily
- Added the XSL from #4559, with minor amends to make the tables and urls
display correctly
closes#4498
- remove toJSON code which returns only IDs from objects
- don't auto-include tags & fields in post responses
- don't auto-include roles in user responses
- fix #allthethings that made assumptions about the auto-includes, or otherwise were only working because of the auto-include
Closes#623
- Add basic init and eventing scaffold
- Add sitemap-index.xml generation
- Broke out generators to individual files, added request handler
- Add page, author and tag xml files; add index mapping
- Add SiteMapManager unit tests
- Add Generators tests
- Cache invalidation headers for sitemap-*.xml
- Redirect sitemap.xml to index and rename to sitemap-index
- Handle page convert and publish/draft changes
- Add very basic functional test for route existence
- Add cache headers to sitemap routes
No Issue
- Fix exception being thrown when updateConfigTheme called before
settingsCache fully populated.
- Remove unnecessary check in a conditional in the migration command
builder.
Issue #806
- Modify sanitize to check for duplicate posts and tags
- Update posts_tags when referencing removed duplicate tags
- Return both data and problems from importData
- Add tests for duplicate posts and tags with fixtures
Closes#4225
- If a theme is symlinked in the themes directory, follow
the symlink so that the theme object is populated correctly.
- Only do the fallback loading of theme data in the validations
module if it doesn't exist in config.
Closes#1977, Refs #3473
- Ensure that import operations are run in sequence.
Previously the operations were started in order but subsequent
ops were allowed to begin before the previous finished, which would
result in out-of-order execution.
- Fix bug in attach() where a model property was being passed in
instead of a transaction object. If the call was made when a
transaction was in process, it could cause bookshelf/knex to
hang and never finish the transaction.
Closes#3844
- Before importing, all data is checked for incorrect UUIDs. If check
fails, data is sanitized and outfitted with correct UUIDS.
- Scaffolding allows for easy implementation of additional
sanitization, should that be required in the future.
- Test included, old tests updated.
fixes#3716
- change the importer to not override any user details
- only set published_by if it is not already set
- import users before anything else
- process the import and map user ids to existing users
- test fix - owner should have owner role
- test fix - catch invalid success in importer
closes#3285
- remove apps stuff for now
- if there is a single user, behave the same as before, overriding
non-critical properties of the single owner user
- if there are multiple users, import them like normal resource
No Issue
- The method that generates a filename for the export during
a migration returns a promise, not the filename directly,
so the export file was being named [object Object].
Closes#3242
- Add checks for valid fields in tags and posts
- Add unit test with empty tag export data file
- Add unit test with empty post export data file
closes#3426
- added transfer ownership endpoint
- added owner to roles.permissible
- manually removed owner from roles.browse
- removed hard coded author role
- fixed tests that were passing due to hard coded author role
- added testUtils.setup(‚roles‘)
Closes#3281
- Add the missing return to populateDefault
- Wrap defaultSetting in [] when passing to readSettingsResult
- Populate default value of dbHash in parseDefaultSettings
- Modify migrations.init to only load databaseVersion for export_spec test
- Fix spacing in test util file and null reference error in test
- Uncomment user tests (but add .skip) and remove settings from testUtils.setup()
closes#3274
- Ensure that validation errors are always handled by moving them into the
importer
- Ensure that db errors are handled consistently across sqlite and mysql
- Change the errors to be output in a table, with a short failure notification
- Add tests for 003 importing bad files
no issue
- Refactor all integration tests to specify and load ONLY the fixtures
they require to run, rather than initialising the whole kit-and-kaboodle
for every single test which takes FOREVER.
- Refactor the route tests to share a doAuth function, and also specify
additional fixtures required
- Move import and export unit tests, which are actually integration tests
(they touch the DB)
- Comment out most of the permissions unit tests for now as they need more
stubs/mocks so as to not touch the DB
Still todo:
- prevent default DB initialisation in route tests, and specify all
fixtures requires as per the integration tests
- fix up the unit/permissions_spec
migration from usage of config() to just an object of config.
no relevant issue
- Change 'loadConfig' task to 'ensureConfig' to more accurately reflect
what it is actually doing. Its sole purpose is to make sure a `config.js`
file exists, and as such the name now reflects that purpose.
- Update config/index.js to export the ghostConfig object directly
so that it can be accessed from other modules
- Update all references of config(). to config.
This was a blind global find all and replace, treat it as such.
- Fixes to tests to support new config access method
- Allow each test to still work when invoked invidually
Closes#3196
* adds `/roles/` endpoint
* is given the current user as context
* wraps everything in a canthis.browse.role
* gets all the available roles (should "Owner" be filtered out?)
* optional parameter: `permission=assign`. Gets all roles authenticated user could assign
* if we're not signed in, gives a "please sign in" (standard) error
* if we're signed in, but user is not in the context, gives a "there was no user in the context" error
* if the user is an "Author", gives a "there are no available roles to assign" error
* implemented hacky filter because when.js produces heisenbugs past 3.2.3 (when.filter not available)
* added extra fixtures to `permissions.json`. Might need a migration.
Caveats:
* there are no tests
* for some reason the setup functional test was failing for me locally
closes#2600
- adds 2 new columns to tags, for the soon-to-land tag management UI
- fixes validation for the active bool in app_fields
- adds missing return to addColumn command
- cleanup in addTableColumn util
fixes#3275, fixes#3290, ref #3086, ref #3084
- Ensure that we use the current logged in user and not just user 1 when
- removing hard coded user: 1 except where absolutely necessary
- passing context, rather than user to models
- base model has a new function to determine what id to use for created_by etc
refs #3283, refs #2739, refs #3096
- Renames permissions which didn't follow bread
- Adds permissions for notifications, mail and tags
Still todo:
- wire up the new permissions where they are needed
- add permissions for roles
refs #2600
One day in the future it would be nice to have a CLI for Ghost
In the meantime, lets have an easy way to force migrations to run
This is for development, or dead end situations only
It will at least do a DB backup ;)
refs #2600
- fixed issue with defaults not being populated on upgrade
- added logging to all actions in the migration process to help debugging
in future
- did a little bit of refactoring
Closes#3271
- Change validations on both server and client to allow the
Website field to be empty or a valid URL.
- Add new schema validation helper isEmptyOrURL.
- Remove duplicate call to UserValidator in the save action
of the SettingsUser controller.
- User.last_login and User.created_at are already Moment objects
so Moment#fromNow can be called on them directly.
refs #2600, refs #2379
Refactoring fixtures to make permission management a little easier
- Separate fixtures into JSON file and split permissions fixtures from other fixtures
- make fixture migrations more robust by fetching objects, not relying on
ids and checking before adding
- changed owner fixture slightly to remove any confusion between the 'Owner' role and 'Ghost Owner' user.
- moved 003 fixture versions out of config into logic, possibly not a good
idea
- refactored permissions fixtures and added permissions_roles fixtures to
make it easier to read / add
This frees us up to enforce one single point of access, thus paving
the way towards allowing us to initialize the models at are request,
and not when it's require().
addresses #2170
closes#3073
- added fixture for owner role
- added fixture for initial user (new db)
- added conversion administrator -> owner (existing db)
- changed tests to take over owner user
- removed some functional tests until /setup works with owner user
Closes#3226
- Remove dependent property from the computed content property
that is used to build the active theme selector.
- Add validation to the Settings model so that it rejects
attempts to set an activeTheme that is not installed.
Closes#3122
-Fix validation so that all values are validated instead
of just values that evaluate to true.
-Ensure validation methods consistently return promises
and switch error handling from try/catch to promise.catch
to get rid of unhandled rejection warnings.
-Add 0 and 1 to list of acceptable values in boolean validation.
closes#2759closes#3027
- added oauth2orize library for server side oAuth handling
- added ember-simple-auth library for admin oAuth handling
- added tables for client, accesstoken and refreshtoken
- implemented RFC6749 4.3 Ressouce Owner Password Credentials Grant
- updated api tests with oAuth
- removed session, authentication is now token based
Known issues:
- Restore spam prevention #3128
- Signin after Signup #3125
- Signin validation #3125
**Attention**
- oldClient doesn't work with this PR anymore, session authentication
was
removed
closes#2822
- added destroy user method
- added remove user permission
- added API end point for get reset token
- added API end point for reset password
- added API end point for change password
Closes#2061
- Lazy load the defaultSettings value in Settings model
- Populate individual defaults before read/edit
- Populate all defaults before first browse call
- Remove populateDefaults calls from init code
closes#2354
refs #1641
- added addUnique()
- added dropUnique()
- added addColumn() -> needed for #2330
- dropColumn() is missing due to lack of knex support
- further cleanup of the migrations module
Closes#2927
-refactor exporter to export tables that exist in the
database instead of keying off of schema.js
-move some shared database utility functions into their
own module
Closes#847
- Added logic to export database to the `core\server\data\` folder prior
to beginning a migration.
- Factored out versioning logic from migration to prevent circular
references
Closes#2601
- Removed slug generation from the post API
- Added new, self-contained slug API
- Fixed slug permissions in the fixtures files
- Added a HTTP route for the new API method
- Added integrational tests
closes#2610, refs #2697
- cleanup API index.js, and add docs
- all API methods take consistent arguments: object & options
- browse, read, destroy take options, edit and add take object and options
- the context is passed as part of options, meaning no more .call
everywhere
- destroy expects an object, rather than an id all the way down to the model layer
- route params such as :id, :slug, and :key are passed as an option & used
to perform reads, updates and deletes where possible - settings / themes
may need work here still
- HTTP posts api can find a post by slug
- Add API utils for checkData
closes#2643
- added error type
- added error property for validations
- wrapped errors in an array
- returns multiple errors for validation
- updated tests and admin
Closes#2606
- Refactor settings api responses to { settings: [ ] } format
- Update all code using api.settings to handle new response format
- Update test stubs to return new format
- Update client site settings model to parse new format into one object of key/value pairs
- Refactor to include all setting values
- Remove unused settingsCollection method
- Update settingsCache to store all attributes
- Update settingsResult to send all attributes
- Remove unnecessary when() wraps
- Reject if editing a setting that doesn't exist
- Reject earlier if setting key is empty
- Update tests with new error messages
- Use setting.add instead of edit that was incorrectly adding
- Update importer to properly import activePlugins and installedPlugins
- Update expected setting result fields
- Fix a weird situation where hasOwnProperty didn't exist 🤷
closes#2058
- fixed apiContext as suggested in the issue
- added user to options object for models
- added api.users.register() for public registration
- changed models to use options.user for created_by, updated_by,
author_id and published_by
- added override to session model to avoid created_by and updated_by
values
- added user (id: 1) to tests
- added user (id: 1) for registration
- added user (id: 1) for import, fixtures and default settings
- added user (id: 1) for user update
- added user (id: 1) for settings update (dbHash, installedApps, update
check)
- updated bookshelf to version 0.6.8
closes#2138
- Adds new models for AppField and AppSetting
- Removed permitted attributes from App model (handled by base)
- Added reference from Post to AppFields
- Added fixture data to DataGenerator
- Added integration tests for Apps, AppSettings, AppFields
- Added import for Apps
- Added app_fields to default fixtures
- Pass permissions loading to buildObjectTypeHandlers to eliminate
shared state
- Load both app and user permissions to check
- Check app permissions if present
- Create apps table and App model
- Move effectiveUserPermissions to permissions/effective
- Change permissable interface to take context; user and app.
- Add unit tests for app canThis checks and effective permissions
issue #2305
- changed validation for 'page' to expect '0' or '1', rather than 'true' or
'false'
- Added a 'can change a post to static page' test
- Added a 'can change a static page to a post' test
Closes#1379
- Convert to new api usage for both server-side and client-side
- Provide way require a negative response for boolean methods in
default-settings.json
- Add field validation functional tests
- Settings (General)
- Title length validation
- Description length validation
- postsPerPage, numeric, min, max
- Settings (User)
- Bio Length validation
- Location length validation
- Url validation
- Login
- Email validation
- Editor
- Title required validation
fixes#2112
refs #1833
- modified config.urlFor to handle tag pages
- modified {{#tags}} handlebars helper to autolink to
tag pages. Additional autolink="false" parameter can
be used to deactivate autolinking
- modified url handlebars helper to handle tags
- added isTag function to schema
- added unit test for additional urlFor functionality
- added unit test for {{#tags}} helper modifications
- added unit test for url handlebards helper
fixes#2057
- uses express’ Route object to create RegExp’s
that we use to check the incoming path
- refactored structure of fronted controller single
tests to be easier to read
- amend regex to incorporate new allowed permalink
structure
closes#1947
- added fieldtype: medium for posts.html
- changed fieldtype: medium for posts.markdown
- added method to fix databases created with wrong field type
- added tests for database version 002
closes#1932
- added showUpdateNotification with version check
- added temp workaround for boolean values in database
- changed default value from false to null
- updated tests
closes#1464
- adds opt-out via updateCheck:false in config.js
- update check is done on admin index, but doesn't interfere with rendering
- adds update check module, which gets the usage data, makes the request and handles the response
- adds two new settings to default-settings, one for next check time, and one for whether to show the notification
- adds a new rejectError method to errorHandling
- adds a new helper for displaying the notification
Conflicts:
core/server/helpers/index.js
core/test/unit/server_helpers_index_spec.js
fixes#1765fixes#1811
issue #1833
New UrlFor functions
- moved body of url helper to config.path.urlFor, which can generate a URL for various scenarios
- urlFor can take a string (name) or object (relativeUrl: '/') as the first
argument - this is the first step towards issue #1833
- also added config.path.urlForPost which is async and handles getting
permalink setting
- frontend controller, ghost_head helper, cache invalidation all now use
urlFor or urlForPost all urls should be correct and consistent
URL Consistency Improvements
- refactored invalidateCache into cacheInvalidationHeader which returns a
promise so that url can be generated properly by urlForPost
- moved isPost from models to schema, and refactored schema to have a tables object
- deleted posts now return the whole object, not just id and slug,
ensuring cache invalidation header can be set on delete
- frontend controller rss and archive page redirects work properly with subdirectory
- removes {{url}} helper from admin and client, and replaced with adminUrl
helper which also uses urlFor
- in res.locals ghostRoot becomes relativeUrl, and path is removed
closes#1681
- import doesn't override user credentials
- import doesn't override theme
- import doesn't kill session
- import does refresh the settings cache
- updated tests, they now use a fixture instead of a generated export
- tests check to ensure import is safe
fixes#1696
- this is a temp workaround until full fledged support
is added directly to bookshelfjs
- when importing we use the import json blob’s timestamps
as the value that’s set in the DB
- added tests for this change
closes#1561
- altered perspective of intro paragraph to reading from the blog
instead of from the content page
- added copy directing users to sign in to the admin area at /ghost/ and
edit the post before reading the 'Getting Started' section
- this should give the Markdown lessons better context and avoid users
getting confused as to what 'the left hand panel of Ghost' is
- changed cookieSession to session
- added session.regenerate for login and logout
- added bookshelf session store
- added session table to database
- added import for databaseVersion 001
- added grunt task test-api
- cleanup of gruntfile to start express when needed only
- moved api tests to functional tests
closes#1398closes#1399closes#1400
- added schema.js with database version '000'
- refactored migration to use schema.js
- if new table is added to schema.js and databaseVersion is increased, table will be added
- if new table is deleted to schema.js and databaseVersion is increased, table will be deleted
- alter table from issue #1400 is delayed until knex supports column modification
- changed import pre checks to work again (will be refactored separately)
- added basic PostgreSQL support (Attention: not supported/tested)
- changed error handling in server.js
closes#952
- moved api.js to api/index.js
- added api/db.js for import and export functions
- moved /ghost/debug/db/export to GET /api/v0.1/db
- moved /ghost/debug/db/import to POST /api/v0.1/db
- removed /ghost/debug/db/reset
- added validation for import
- added constraints object to migration
issue #977
- As of the addition of when/monitor/console we now get errors about unhandled promises
- This fixes one which appeared when starting up without a DB
- Add new 003.js in import based on 000.js
- Change importPosts and importUsers from the 000.js for new / default values
- Add language setting to black list
closes#734
- use models instead of knex so that we know we get correct data
- preprocesses post_tags, adds the right tags back to the posts
TODO
- deduplicate posts (if they have the same title and slug?)
closes#733
- Exporter will read meta data to determine the tables which are present and export all data from those tables
- Exporter figures out which version to export, rather than requiring that information
- deleted old exporters
closes#172
- added type to ghost.settings()
- added /api/settings?type=<filter>
- added availableThemes to settingsCache
- removed cachedSettingsRequestHandler
- removed /api/themes (including front end)
- changed activePlugins to type "plugin" in default-settings.json
closes#748
- Removed the alpha software warning
- Better error message output for the whole app - can now specify an error, a context, and a help message
- Improved invalid node version, start and stop messaging
- Listens for Ctrl+C and exits nicely
- Minor improvements to handling and errors with old DBs (temporary)
closes#731, closes#732
- fixtures are imported using the models, rather than knex
- migration treats fresh installs differently
- migration throws errors for un-initialisable databases
- small amount of extra code to deal with old DBs still using currentVersion & give them a nice error message
issue #632
- removed old schemas
- updated base model to reflect all of the consistent behaviours and properties across the models
- updated all models to match the new schema
TODO
- no fixtures are currently loaded except settings
- need to rename properties across the codebase
closes#625
- removed defaultLang, forceI18n and activePlugins from config
- added values to default-settings.json
- updated to use values from settings
closes#593
- added default setting of 6 posts per page
- added posts per page to settings page
- added limit to frontend.js (setting does not change API behavior)
Closes#364
- Confirmed integration with local mysql installation works.
- Updated fixtures and migration with appropriate schema-conforming
values.
- Updated schema with appropriate defaults and nullable columns.
- Updated fixDates function on model base to appropriately deserialize
values coming from SQLite now that dates are stored as actual DateTime
objects/ISO strings.
- Updated default language to be 'en_US'.
- added line to index.js to set node_env to development if it is not set
- fixed a small bug with the persistent notifications and used them on debug page from server side
- added 002 files to manage export and import for 002
- 002 import is somewhat smarter than 001, merging settings (except version), replacing user & clearing primary keys
- added reset to models and migration, which does the down operation the same way that init does the up operation
- import and reset clear session & redirect to login / signup
- additional unit tests
closes#171, closes#314, closes#315
- added settings for blog logo and icon
- all other settings will need to be added as needed as it's impossible to guess what the default value should be
- added tables for post tags
- added tables for post custom data
- added location column to users
- fixeed minor bug in migrations
- This is a first pass at getting a more logical structure. The focus is on moving from admin/frontend to client/server.
- The location of the databases is highly important, this isn't expected to change again
In the future
- client/assets should probably become public/
- more stuff should be shared (helpers etc)
- cleanup some confusion around tpl and views