closes#8760
- we have to remember the old post id's when migrating a blog from LTS to 1.0
- otherwise we would break disqus comments, because they rely on the post id
- this should fix the discovered situation
closes#8645, closes#8710
- locked users were once part of the category "active users", but were moved to the inactive category
-> we have added a protection of not being able to edit yourself when you are either suspended or locked
- but they are not really active users, they are restricted, because they have no access to the admin panel
- support three categories: active, inactive, restricted
* - revert restricted states
- instead, update permission layer: fallback to `all` by default, because you are able to serve any user status
- add more tests
- ATTENTION: there is a behaviour change, that a blog owner's author page can be served before setting up the blog, see conversation on slack
-> LTS serves 404
-> 1.0 would serve 200
closes#8691
There was a condition added when i've refactored the importer.
> if (models.User.isOwnerUser(obj[key])) {
This condition is absolutely wrong! If you import an owner user, this owner user get's imported as administrator. But the original owner user id reference must be updated as well, so that the reference points to the new administrator id ✌🏻
no issue
- if you delete an active user, Ghost logs an error message (Ghost does not crash!)
- but the event logic is not triggered, that means we don't delete the users tokens
- token deletion happens on: suspend a user and delete a user
closes#8601
- This makes sure that when you do an import, you still get the LATEST
default settings for labs. Even if you had a different value before.
- LTS -> 1.0 is an upgrade, and Public API should be on by default, even if you
had deliberately turned it off before.
- Cheeky test added
refs #8620
Adds a new Ghost Author user, which is the author of the new welcome blog posts. The user is set to active, so the author slug works (otherwise it would render a 404, when user is suspended). Furthermore, there's one little fix in the user model, which was checking only for `active` user to decide the signup or setup process for the UI. Adding one more conditional to check if the found active user is also the owner, prevents to get redirected to sign in.
closes#8601
- this doesn't take the feature out of beta, but does enable it by default
- no need to enable the public api in the test anymore
- because public api is enabled by default
closes#8565
- isPasswordCorrect fn returns a specific error, which we simply forward
- no need to wrap a custom error into a new custom error
- the rule is always: if you are using a Ghost unit/function, you can expect that this unit returns a custom error
closes#8568
- use our `urlJoin` util to concatenate the URL (not the query part of it, as this is not supported in `urlJoin`) and to prevent possible missing or double slashes, as `config.apiUrl` could be with or without trailing slash
closes#8542
- updates default post fixtures
- adds default logo and cover images to settings fixtures
- update tests due to coupling to dev/prod fixtures
refs #8222
- differentiate between errors and fatal errors
- use gscan errors in theme middleware
- Adds a new `error()` method to `currentActiveTheme` constructor which will return the errors we receive from gscan
- In middleware, if a theme couldn't be activated because it's invalid, we'll fetch the erros and send them to our error handler. We also use a new property `hideStack` to control, if the stack (in dev mode and if available) should be shown or the gscan errors (in prod mode, or in dev if no stack error)
- In our error handler we use this conditional to send a new property `gscan` to our error theme
- In `error.hbs` we'll iterate through possible `gscan` error objects and render them.
- remove stack printing
- stack for theme developers in development mode doesn't make sense
- stack in production doesn't make sense
- the stack is usually hard to read
- if you are developer you can read the error stack on the server log
- utils.packages: transform native error into Ghost error
- use `onlyFatalErrors` for gscan format and differeniate fatal errors vo.2
- optimise bootstrap error handling
- transform theme is missing into an error
- add new translation key
- show html tags for error.hbs template: rule
refs #8141
- update importer for LTS fields
- optimise for LTS export fixtures
- add image/language test for LTS import
- ensure post image is mapped to feature_image
- create mobiledoc values from markdown and html
- if mobiledoc is null, use markdown or html to create a mobiledoc markdown card
- update import mapping to use locale
- defaultLang in settings now maps to default_locale
- language for post and user models now maps to locale
- posts are not always loaded in correct same order so we select the posts we want to validate
- ensure if mobiledoc field is not in export we can still import from markdown
- map last_login to last_seen
- for users the importer maps last_login to last_seen
- add warning for legacyActiveTheme
- for export with old activeTheme key provide a warning that theme is not installed
- add importer test for LTS user long email
- add a test for LTS export where email address could be longer than alpha
- fix for importer date tests on mysql
- use valueOf in moment to compare times stored in different formats
- ignore warnings for not found settings in import
- use a flag to ignore NotFound Entries for settings during import
no issue
- this PR references indirecty to https://github.com/TryGhost/Ghost/pull/8437
- i would like to have the settings change already in place before we release the beta
- the i18n feature is able to change the locale of Ghost
- most i18n libraries use locale
- adding/changing settings doesn't require a migration file, but it can make the database a bit messy (because you can end up with default_locale and lang)
- furthermore we agreed that the default locale for Ghost should be simply `en`, not `en_US` or `en_GB`
closes#8479
- removes `markdown` field from schema
- removes `legacyMarkdown` converter
- updates tests to work with `mobiledoc` field instead of `markdown` and adapt for mobiledoc HTML output where necessary
refs #8152
- as long as OAuth is disabled, we can revert the url redirection (see comment)
- the redirect only happens if you configure a specific `admin.url`
- add another test case, which was missing
refs #5422
- we can support null titles after this PR if we want
- user model: fix getAuthorRole
- user model: support adding roles by name
- we support this for roles as well, this makes it easier when importing related user roles (because usually roles already exists in the database and the related id's are wrong e.g. roles_users)
- base model: support for null created_at or updated_at values
- post or tag slugs are always safe strings
- enable an import of a null slug, no need to crash or to cover this on import layer
- add new DataImporter logic
- uses a class inheritance mechanism to achieve an easier readability and maintenance
- schema validation (happens on model layer) was ignored
- allow to import unknown user id's (see https://github.com/TryGhost/Ghost/issues/8365)
- most of the duplication handling happens on model layer (we can use the power of unique fields and errors from the database)
- the import is splitted into three steps:
- beforeImport
--> prepares the data to import, sorts out relations (roles, tags), detects fields (for LTS)
- doImport
--> does the actual import
- afterImport
--> updates the data after successful import e.g. update all user reference fields e.g. published_by (compares the imported data with the current state of the database)
- import images: markdown can be null
- show error message when json handler can't parse file
- do not request gravatar if email is null
- return problems/warnings after successful import
- optimise warnings in importer
- do not return warnings for role duplications, no helpful information
- error handler: return context information of error
- we show the affected json entries as one line in the UI
- show warning for: detected duplicated tag
- schema validation: fix valueMustBeBoolean translation
- remove context property from json parse error
refs https://github.com/TryGhost/Ghost-Admin/pull/690, closes#1501, closes#2093, closes#4592, closes#4627, closes#4659, closes#5039, closes#5237, closes#5587, closes#5625, closes#5632, closes#5822, closes#5939, closes#6840, closes#7183, closes#7536
- replace custom showdown fork with markdown-it
- swaps showdown for markdown-it when rendering markdown
- match existing header ID behaviour
- allow headers without a space after the #s
- add duplicate header ID handling
- remove legacy markdown spec
- move markdown-it setup into markdown-converter util
- update mobiledoc specs to match markdown-it newline behaviour
- update data-generator HTML to match markdown-it newline behaviour
- fix Post "converts html to plaintext" test
- update rss spec to match markdown-it newline behaviour
- close almost all related showdown bugs
closes#8354
- i thought about transforming scheduled posts into drafts on export, but this has two disadvantages:
1. existing exports with scheduled posts won't import
2. if you schedule a post for next week and you export/import earlier, the post is back to draft
- by this we ensure that we can simply import the post back to a scheduled post
- if the published_at is already in the past, the scheduler will care and instantly publish the post
closes#8436
- this is how the from field looks like "blog title <owner@blog.com>"
- so if you set your blog title with double quotes, it throws a syntax error from the smtp library
no issue
- now that we've switched to using a SimpleMDE based editor in Ghost-Admin the default post needs to match the expected single-markdown-card format
* 🙀 change database schema for images
- rename user/post/tag images
- contains all the required changes from the schema change
* Refactor helper/meta data
- rename cover to cover_image
- also rename default settings to match the pattern
- rename image to profile_image for user
- rename image to feature_image for tags/posts
* {{image}} >>> {{img_url}}
- rename
- change the functionality
- attr is required
- e.g. {{img_url feature_image}}
* gscan 1.0.0
- update yarn.lock
* Update casper reference: 1.0-changes
- see 5487b4da8d
closes#5599
If two users edit the same post, it can happen that they override each others content or post settings. With this change this won't happen anymore.
✨ Update collision for posts
- add a new bookshelf plugin to detect these changes
- use the `changed` object of bookshelf -> we don't have to create our own diff
- compare client and server updated_at field
- run editing posts in a transaction (see comments in code base)
🙀 update collision for tags
- `updateTags` for adding posts on `onCreated` - happens after the post was inserted
--> it's "okay" to attach the tags afterwards on insert
--> there is no need to add collision for inserting data
--> it's very hard to move the updateTags call to `onCreating`, because the `updateTags` function queries the database to look up the affected post
- `updateTags` while editing posts on `onSaving` - all operations run in a transactions and are rolled back if something get's rejected
- Post model edit: if we push a transaction from outside, take this one
✨ introduce options.forUpdate
- if two queries happening in a transaction we have to signalise knex/mysql that we select for an update
- otherwise the following case happens:
>> you fetch posts for an update
>> a user requests comes in and updates the post (e.g. sets title to "X")
>> you update the fetched posts, title would get overriden to the old one
use options.forUpdate and protect internal post updates: model listeners
- use a transaction for listener updates
- signalise forUpdate
- write a complex test
use options.forUpdate and protect internal post updates: scheduling
- publish endpoint runs in a transaction
- add complex test
- @TODO: right now scheduling api uses posts api, therefor we had to extend the options for api's
>> allowed to pass transactions through it
>> but these are only allowed if defined from outside {opts: [...]}
>> so i think this is fine and not dirty
>> will wait for opinions
>> alternatively we have to re-write the scheduling endpoint to use the models directly
no issue
- the UTC offset diff of the current and previous timezone must switch
- i have added more tests and more example case descriptions to understand why
refs #8221, closes#7688, refs #7558🙇 Improve meta data publisher logo behaviour
This is a follow-up PR for #8285.
Reasons: The code changes of #8285 caused error messages when falling back to the default `favicon.ico`, as the `image-size` tool doesn't support `ico` files.
This PR takes the logic to decide which logo needs to be listed in our schema into a new fn `blog_logo.js`. There we have now three decisions:
1. If we have a publication **logo**, we'll take that one
2. If we have no publication logo, but an **icon** we'll use this one.
3. If we have none of the above things, we fall back to our default `favicon.ico`
Additional, we're hard coding image dimensions for whenever the logo is an `.ico` file and built and extra decision to not call `image-size` when the dimension are already given.
I will create another follow-up PR, which checks the extension type for the file and offers it as a util.
🛠 Blog icon util
refs #7688
Serve functionality around the blog icon in its own util:
- getIconDimensions -> async function that takes the filepath of on ico file and returns its dimensions
- isIcoImageType -> returns true if file has `.ico` extension
- getIconType -> returns icon-type (`x-icon` or `png`)
- getIconUrl -> returns the absolut or relativ URL for the favicon: `[subdirectory or not]favicon.[ico or png]`
📖 Get .ico sizes for meta data & logo improvement
refs #7558
refs #8221
Use the new `blogIconUtil` in meta data to fetch the dimensions of `.ico` files.
Improvements for `publisher.logo`: We're now returning a hard-coded 'faked' image dimensions value to render an `imageObject` and prevent error our schema (Google structured data). As soon as an image (`.ico` or non-`.ico`) is too large, but - in case of non-`.ico` - a square format, be set the image-dimensions to 60px width and height. This reduces the chances of getting constantly error messages from Googles' webmaster tools.
- add getIconPath util
refs #8275
- If the HTML field has changed, update the plaintext field
- Use html-to-text to generate a plaintext version of the HTML which retains some structure
- Add a couple of tests - although there's much to do here!
refs #8221🔥 Remove ghost=true concept from asset url helper
✨💯 Introduce CSS minification with cssnano
- add new grunt-cssnano dependency
- wire up grunt task to minify public/ghost.css
🎨 Rename minification config & hash params
- Change minifyInProduction -> hasMinFile
- this means this asset should have a .min file available
- Change minifyAssets -> useMinFiles
- this means that in this env we want to serve .min files if available
🎨 Update public/ghost.css to serve .min for prod
- add the new `hasMinFile` property
🎨 Move minified asset handling to asset_url util
- this logic should be in the util, not the asset helper
- updated tests
📖 Error handler always needs asset helper
- this removes the TODO and adds a more sensible comment
- we also need to update our theme documentation around error templates
🔥 Don't use asset helper in ghost head
- use getAssetUrl util instead!
- removed TODO
📖 Update proxy docs
🎨 Simplify asset helper & add tests
- this refactor is a step prior to moving this from metadata to being a url util
- needed to skip some new tests
🐛 Add missing handler for css file
refs #8221
Use our default `favicon.ico` instead of `ghosticon.jpg` which is served from the admins' assets.
Adds additionally fake image dimensions for our json-ld data to satisfy Google.
refs #8221
Instead of serving our shared assets from a `shared/` folder, we move the file, which are used server side to `server/public`.
Adds a new `config.paths` entry: `publicFilePath` and renames the middleware to serve the files to reflect the changes.
Adds `404-ghost.png` images to be used by the server side rendered default template `error.hbs`.