Commit Graph

5844 Commits

Author SHA1 Message Date
kirrg001
61be92e3f9 Tests: balance featured and none featured posts
no issue

- `featured:true` was default
- featured is by default disabled in Ghost
- balance featured and none featured posts
- update tests
2018-04-14 10:32:03 +02:00
kirrg001
699beb9172 Updated Ghost-Admin to 1.22.2 2018-04-11 22:35:59 +02:00
CriticalRespawn
6b9f9a0ece 🐛Fixed author page has only shown primary author posts
closes #9545

- posts only showed on an author page when the author was primary
2018-04-10 22:56:25 +02:00
Kevin Ansfield
3a27e557ed Protect generated post.html and post.plaintext fields (#9559)
closes https://github.com/TryGhost/Ghost/issues/9512

- loop through list of generated fields in `Post.onSaving` and reset their values if a new value was passed in via attributes
2018-04-10 22:45:31 +02:00
kirrg001
d209a4d013 🐛 Fixed importer bug: can't resolve authors relation
closes #9547

- you setup a blog with the following owner:
  - email: test@ghost.org
  - name: test
  - slug: test
- now you import a JSON db file, which holds the exact same owner
  - this owner won't be imported, because it's a duplicate
  - but the slug is different (!)
- the importer tries to find a matching existing user, but won't find anything
- the importer then send an empty authors array `post.authors=[]` into the model layer
- this is not allowed -> this would mean, you are actively trying to unset all authors
2018-04-10 01:10:06 +02:00
kirrg001
aecca28257 Optimised emitChange for destroyed resources
no issue

- see comment in code base
2018-04-06 19:10:59 +02:00
Katharina Irrgang
fb79f24316
Fixed model events and transactions (#9524)
no issue

- if multiple queries run in a transaction, the model events are triggered before the txn finished
- if the txn rolls back, the events are anyway emitted
- the events are triggered too early
- solution:
  - `emitChange` needs to detect that a transaction is happening
  - it listens on a txn event to determine if events should be triggered
2018-04-06 18:19:45 +02:00
kirrg001
25cd7c7756 Simplify destroy post API endpoint implementation
no issue

- no need to fetch the post before
- the model implementation does that already
2018-04-06 15:49:25 +02:00
kirrg001
c8f2dd11ba Fixed post.unpublished when deleting all content
no issue

- if you delete all content, we expect two events
  - `post.deleted` and `post.unpublished`
- `post.unpublished` was never triggered, because the api implementation made use of `collection.invoke(`destroy`)`
- what happened?
  - you fetch all posts (columns:id)
  - you destroy the post (only id column is available)
  - the model events are triggered
  - but you have no access to a default set of data
  - the result is that the event handler can't even tell if this is a post or a page
- added a proper test to ensure which events are triggered
2018-04-06 15:49:25 +02:00
kirrg001
0ae6cbe34d Fixed transactions for Tag.destroy
no issue

- if you pass a transaction to `Tag.destroy`, it would freeze
- because `detach(null, options)` was missing
- added a new test
2018-04-06 15:49:25 +02:00
kirrg001
e7529de773 Tests: tidied up integration/models/model_posts_spec.js
no issue

- simple cleanup
- no functional change
2018-04-06 15:31:00 +02:00
kirrg001
f114f45740 Added a post unit test to proof a bug
no issue

- permalink: /:primary_tag/:slug/, columns: [title,url]
- will be auto resolved with channels
- the test should fail if we add channels
2018-04-06 13:36:03 +02:00
kirrg001
fa4e2cf286 Extended our knex mock to only return specific fields/columns
no issue
2018-04-06 13:35:38 +02:00
kirrg001
89e4201b67 Clarify the behaviour of defaultColumnsToFetch in the post model
no issue

- add a big comment
- describe:
  - how this works
  - why this is in place
  - what does currently not work
  - and why it will work with channels
- @TODO:
  - figure out how to disallow:
  - `models.Post.findAll({columns: id})`
  - `post.save(data)`
  - this will trigger bookshelf events and model events
  - url generation currently needs a set of attributes (e.g. slug, published_at)
    - will be auto-fixed with channels, because you can call `urlService.getUrl(post.id)`
  - but what doesn't get solved is our model events
    - e.g. `emitChange` needs `post.get('page')` to determine if it's a page
2018-04-06 13:32:10 +02:00
kirrg001
5a2155f814 Added tests for event behaviour: updating resources with or without updating it's relations
closes #9548

- unit test to proof which events are triggered
2018-04-05 18:51:58 +02:00
kirrg001
f90a454014 Tests: knex mock can resolve post tags relations
no issue

- nothing to describe here :)
2018-04-05 18:51:58 +02:00
kirrg001
5928a5b240 Extended check for updated_at on model update
no issue

- ensure the schema type has a key `updated_at`, otherwise ignore
2018-04-05 18:51:58 +02:00
kirrg001
da80019aca Removed taking care of bookshelf's changed model keys
no issue

- this is no longer needed for now
- it was anyway a little bit ugly to modify bookshelf's `changed` object
- if we want to change something about figuring out if a model has changed (including relations)
  -> we probably need to override bookshelf
2018-04-05 18:51:58 +02:00
kirrg001
853b518a51 Sanitize incoming model relation data
refs #9548

- we always receive date strings from the client in ISO format
- we ensure that we transform these strings into JS dates for comparison
- when the client sends relations, we need to ensure that relations are checked as well
- will only work for the post model for now, because this is the only model which uses `bookshelf-relations`
- added unit tests
- removed some model tests, which do the same
2018-04-05 18:51:58 +02:00
kirrg001
5c5ecfd61d A bit of ES6 for models/base/index.js
no issue
2018-04-05 18:51:58 +02:00
kirrg001
19596dcf42 Tests: Added missing attrs to DataGenerator
no issue

- `createUser` did not return `updated_at` and `updated_by`
- heyyyy 🤠
2018-04-05 18:51:58 +02:00
kirrg001
bda76acba6 Extended the API object validation
refs #9548

- do not forward `tag.parent` to the model layer
  - the model layer should only know `tag.parent_id`
  - and the API should only expose `tag.parent` (this is an API feature)
  - currently Ghost has a mixture of using `toJSON` and the API validation layer for this
  - we just continue with this for now (no time to fix this)
- disallow sending nested-nested relations
  - unsupported
  - see comment for more information
  - this can cause problems with calling `hasChanged` on relations
- add unit tests
2018-04-05 18:51:58 +02:00
kirrg001
2f8dc97286 Updated Ghost-Admin: API request without updated_by/created_by
refs https://github.com/TryGhost/Ghost/issues/9548

- the Ghost-admin had sent booleans for `updated_by` and `created_by`
- the easiest fix for now was just to remove the attrs at all
- they are anyway not used on the server, because you can't update these attrs
- only the server has the permission
2018-04-05 18:51:58 +02:00
kirrg001
9a43f36d44 Updated Ghost-Admin to 1.22.1 2018-04-02 12:31:28 +02:00
kirrg001
5dc2dddfc2 Fixed migration script 1.22 for invalid authors
no issue

- the previous commit will insert two post author relations if the author id of a post is invalid
- if a blog has an invalid author_id (which should be an edge case), we update the author id to the owner id
  - `posts_authors` are auto inserted in this case
2018-04-02 12:27:06 +02:00
Katharina Irrgang
7bbde460af
Speed up 1.22 migration script (#9541)
no issue

- insert `posts_authors` relation via knex
- massive speed improvement

e.g. 1500 posts

- before: ~1min
- after: ~10sec
2018-04-02 12:00:00 +02:00
Kevin Ansfield
e1ce8eff31 Updated Ghost-Admin to 1.22.0 2018-03-27 21:08:21 +01:00
Katharina Irrgang
40d0a745df Multiple authors (#9426)
no issue

This PR adds the server side logic for multiple authors. This adds the ability to add multiple authors per post. We keep and support single authors (maybe till the next major - this is still in discussion)

### key notes

- `authors` are not fetched by default, only if we need them
- the migration script iterates over all posts and figures out if an author_id is valid and exists (in master we can add invalid author_id's) and then adds the relation (falls back to owner if invalid)
- ~~i had to push a fork of bookshelf to npm because we currently can't bump bookshelf + the two bugs i discovered are anyway not yet merged (https://github.com/kirrg001/bookshelf/commits/master)~~ replaced by new bookshelf release
- the implementation of single & multiple authors lives in a single place (introduction of a new concept: model relation)
- if you destroy an author, we keep the behaviour for now -> remove all posts where the primary author id matches. furthermore, remove all relations in posts_authors (e.g. secondary author)
- we make re-use of the `excludeAttrs` concept which was invented in the contributors PR (to protect editing authors as author/contributor role) -> i've added a clear todo that we need a logic to make a diff of the target relation -> both for tags and authors
- `authors` helper available (same as `tags` helper)
- `primary_author` computed field available
- `primary_author` functionality available (same as `primary_tag` e.g. permalinks, prev/next helper etc)
2018-03-27 15:16:15 +01:00
Kevin Ansfield
3a48ab3330 Updated Ghost-Admin to 1.21.7 2018-03-26 15:32:46 +01:00
Katharina Irrgang
7c6f690eb5 🐛 Fixed updated_at not being updated (#9532)
closes #9520

- it contains a dependency bump of the latest Bookshelf release
- Bookshelf introduced a bug in the last release
  - see https://github.com/bookshelf/bookshelf/pull/1583
  - see https://github.com/bookshelf/bookshelf/pull/1798
- this has caused trouble in Ghost
  - the `updated_at` attribute was not automatically set anymore

---

The bookshelf added one breaking change: it's allow to pass custom `updated_at` and `created_at`.
We already have a protection for not being able to override the `created_at` date on update.
We had to add another protection to now allow to only change the `updated_at` property.
You can only change `updated_at` if you actually change something else e.g. the title of a post.

To be able to implement this check i discovered that Bookshelfs `model.changed` object has a tricky behaviour.
It remembers **all** attributes, which where changed, doesn't matter if they are valid or invalid model properties.
We had to add a line of code to avoid remembering none valid model attributes in this object.

e.g. you change `tag.parent` (no valid model attribute). The valid property is `tag.parent_id`.
     If you pass `tag.parent` but the value has **not** changed (`tag.parent` === `tag.parent_id`), it will output you `tag.changed.parent`. But this is wrong.
     Bookshelf detects `changed` attributes too early. Or if you think the other way around, Ghost detects valid attributes too late.
     But the current earliest possible stage is the `onSaving` event, there is no earlier way to pick valid attributes (except of `.forge`, but we don't use this fn ATM).
     Later: the API should transform `tag.parent` into `tag.parent_id`, but we are not using it ATM, so no need to pre-optimise.
     The API already transforms `post.author` into `post.author_id`.
2018-03-26 14:12:02 +01:00
CriticalRespawn
60386dbba5 🐛Fixed misspelled schema.org type for WebSite (#9526)
closes #9525

- updated the schema type to 'WebSite' as it is the correct spelling according to schema.org. See [here](http://schema.org/WebSite)
2018-03-23 10:50:28 +07:00
Rosco Kalis
4013023d60 🐛Added more language support to {{reading_time}} helper (#9509)
closes #9507

- Changed the utils.wordCount implementation to the one used by simpleMDE
- Added extra À-ÿ to the regex to support diacritics characters
- Added corresponding text with Chinese text mentioned in the issue
2018-03-22 10:27:02 +07:00
kirrg001
f0c8e3c95a Fixed wrong i18n key
refs #9519

- `errors.models.posts.postNotFound` -> wrong
- `errors.models.post.postNotFound`  -> correct
- the i18n lib just logs the error and falls back to a valid error key
- wrong i18n keys will never break Ghost
2018-03-21 08:41:05 +01:00
kirrg001
ce8838ae9f Updated Ghost-Admin to 1.21.6 2018-03-19 16:39:05 +01:00
Katharina Irrgang
95423ea8fa
Bump dependencies (#9513)
no issue

- knex@0.14.4
- bookshelf@0.13.0
- knex-migrator@3.1.4
- brute-knex@4feff38ad2
- bookshelf-relations@0.2.0

### Fixes for Bookshelf 0.13

- they introduced some breaking changes
- https://github.com/bookshelf/bookshelf/blob/master/CHANGELOG.md#breaking-changes
- adapt event handling in Ghost and in bookshelf-relations
2018-03-19 16:27:06 +01:00
Rosco Kalis
3d8bf02a8d Redirected /amp links to original post when AMP is disabled (#9496)
closes #9495

- Added a clause for amp being disabled
- In this clause, we strip the final 'amp/' part of the url, and redirect
- Changed corresponding test in frontend_spec.js
- Used `urlService.utils.redirect301()` instead of `res.redirect()`
2018-03-19 16:11:48 +07:00
Mante Bridts
7ed822cc0c 🐛Fixed i18n for the {{meta_title}} helper (#9468)
closes #9466

- make 'page' in the meta title translatable through subexpression in the meta title helper
- e.g. `{{meta_title page=(t....)}}`
2018-03-19 09:48:07 +01:00
Vikas Potluri
63aeebb144 🐛 Fixed escaping < in reading time helper (#9508)
no issue

Using the < character raw isn't w3 complaint
2018-03-19 09:47:58 +07:00
CriticalRespawn
735d9775ee 🐛Fixed data-* attributes from being stripped in AMP HTML (#9501)
closes #9500

- Added `data-*` to `allowedAMPAttributes`, so it will not get stripped out.
2018-03-16 09:45:07 +07:00
CriticalRespawn
25b94bba75 🐛Fixed <br> tag from duplicating in AMP transform (#9502)
closes #9499 

- added `br` to self closing tags option for `sanitize-html` when cleaning the ampified HTML
2018-03-16 09:39:29 +07:00
Kevin Ansfield
df1188d25a
Fix Node.js 4.x compatibility (#9503)
no issue
- fixes compatibility issue introduced in 7548ace32d
2018-03-15 09:50:25 +00:00
Kevin Ansfield
7548ace32d Koenig - Output captions for image and embed cards
refs https://github.com/TryGhost/Ghost/issues/9311
- very basic implementation, still needs proper classes and default stylesheet implementation
- change image card output to a `<figure>` with optional `<figcaption>`
- add optional `<p>` caption output to the html card
2018-03-14 18:21:30 +00:00
Kevin Ansfield
c98327a9a5 Updated Ghost-Admin to 1.21.5 2018-03-13 13:55:26 +00:00
Kevin Ansfield
7146805320 Updated Ghost-Admin to 1.21.4 2018-03-06 16:13:43 +00:00
Rosco Kalis
301e1b2419 🎨Improved image counting for the {{reading_time}} helper (#9366)
refs #9200

- We have not yet counted the images within your html, this commit counts images based on the this algorithm: https://blog.medium.com/read-time-and-you-bc2048ab620c
- Added imageCount utility, which counts images using an img-tag regex, amended from the general tag-regex found in wordCount
- Added this imageCount to the {{reading_time}} helper, adding 12 seconds to the reading time for every image
- The feature image is still counted as before
- The first image adds 12 seconds, the second 11, the third 10, and so on
- Images from the tenth onwards add 3 seconds to the reading time
2018-03-05 09:30:15 +01:00
Aileen Nowak
1da2eec915 🐛Fixed image properties to be reset to null after removal (#9432)
closes #9085

Fixes an issue, where the client sets image properties to `""` after deleting the image. This causes problems with the query filter (see https://github.com/TryGhost/GQL/issues/24), as they have to be `null`.

Added a check in the model layer saving method to set value  to `null`, when the property is empty.

Affected models and properties:
- `posts`:
	- `feature_image`
	- `og_image`
	- `twitter_image`
- `users`:
	- `profile_image`
	- `cover_image`
- `tags`:
	- `feature_image`
2018-03-05 09:10:27 +01:00
kirrg001
f692e27a59 Fixed wrong authentication test
no issue

- the tests were failing since beginning of March
- this was caused by a wrong assertion in one of our authentication tests
- we work with a static 6 month ms number for token expiry
- this static ms number is based on 30 days per month
2018-03-04 10:42:49 +01:00
kirrg001
415ff2cf20 Extended test mocks: express & knex
no issue

- extended functionality
- the knex mock simply parses the sql statements and serves data from memory
- i've tested the memory mode of sqlite, but could not get it working
  - but maybe for the future to test again
2018-02-22 00:37:40 +01:00
kirrg001
3dedfc7d61 Fixed default mobiledoc handling in our data generator
no issue

- the handling here was not correct
- if you've passed no mobiledoc, it wasn't adding mobiledoc and an undefined html value
- we need a default mobiledoc+html value in case you don't pass the values within the test cases
2018-02-21 23:53:37 +01:00
kirrg001
d32cea479e Fixed incorrect test in functional/routes/api/posts_spec.js
no issue

- `post.author_id` has no reference to any table currently, see https://github.com/TryGhost/Ghost/blob/1.21.3/core/server/data/schema/schema.js#L19
- that's why it is right now possible to insert none existent author id's
- with multiple authors, this get's protected (see https://github.com/TryGhost/Ghost/pull/9426)
  - you would get a proper error message
  - it is not allowed to insert invalid author id's
  - as soon as you do `include=author` you would receive an error
- fixed one test case where we inserted an invalid author id via the API
2018-02-21 18:39:56 +01:00
kirrg001
789895b3de Consistent function names in test utility
no issue

- just discovered that we had confusing function names in our test utility
  - e.g. `posts` -> default posts from the data generator
  - e.g. `users` -> extra users not from our data generator
- now:
  - e.g. `posts` -> default posts from the data generator
  - e.g. `users` -> default users from the data generator
  - e.g. `users:extra` -> extra users not from our data generator
2018-02-21 17:48:46 +01:00
kirrg001
e01b61dcf4 Proper error handling for permissible implementations
no issue

- currently if you would like to edit a resource (e.g. post) and you pass an invalid model id, the following happens
  - permission check calls `Post.permissible`
  - the Post could not find the post, but ignored it and returned `userPermissions:true`
  - then the model layer is queried again and figured out that the post does not exist
- A: there is no need to query the model twice
- B: we needed proper error handling for post and role model
2018-02-21 16:59:48 +01:00
Aileen Nowak
a587a5a772 Updated Ghost-Admin to 1.21.3 2018-02-21 08:19:52 +07:00
kirrg001
45176534a3 Renamed comments in importer test
no issue

- just making it clear, that we are talking about the `author_id` (single author)
- no JS change, only comments
2018-02-20 17:45:56 +01:00
kirrg001
68d8154d4f Imported nested tags by foreign key
no issue

- replace logic for preparing nested tags
- if you have nested tags in your file, we won't update or update the target tag
- we simply would like to add the relationship to the database
- use same approach as base class
  - add `posts_tags` to target post model
  - update identifiers
  - insert relation by foreign key `tag_id`
- bump bookshelf-relations to 0.1.10
2018-02-20 09:56:45 +01:00
kirrg001
5a4dd6b792 Increased speed of importer
no issue

- change behaviour from updating user references after the actual import to update the user reference before the actual import
  - updating user references after the import is way less case intense
  - that was the initial decision for updating the references afterwards
  - but that does not play well with adding nested relations by identifier
- the refactoring is required for multiple authors
  - if we e.g. store invalid author id's, we won't be able to add a belongs-to-many relation for multiple authors
  - bookshelf-relations is generic and always tries to find a matching target before attching a model
  - invalid user references won't work anymore
- this change has a very good side affect
  - 17mb takes on master ~1,5seconds
    - on this branch it takes ~45seconds
  - also the memory usage is way lower and stabler
  - 40mb takes 1,6s (times out on master)
2018-02-20 09:56:45 +01:00
kirrg001
12724df8e4 Define belongsToMany foreign keys for tags in the model layer
no issue

- otherwise we will have trouble in the future fetching relations by foreign key
  - e.g. `tag_id: {id}`
  - this won't work if we don't explicitly define the name of the keys
  - bookshelf can't fulfil the request
- this does not change any behaviour, it just makes use of the ability to define the names of your foreign keys
2018-02-20 08:49:00 +01:00
kirrg001
b204d5874e Added missing test cases for post.author
no issue

- Ghost does not support adding an author by relation (`post.author = {id: '..'}`)
- Ghost does not support editing an author by relation (`post.author = {id: '..'}`)
- only `author_id` is allowed
2018-02-17 15:57:24 +01:00
Katharina Irrgang
0aff9f33d9
Improved validation layer (#9427)
refs https://github.com/TryGhost/Ghost/issues/3658

- the `validateSchema` helper was a bit broken
  - if you add a user without email, you will receive a database error
  - but the validation error should catch that email is passed with null
- it was broken, because:
  - A: it called `toJSON` -> this can remove properties from the output (e.g. password)
  - B: we only validated fields, which were part of the JSON data (model.hasOwnProperty)
- we now differentiate between schema validation for update and insert
- fixed one broken import test
  - if you import a post without a status, it should not error
  - it falls back to the default value
- removed user model `onValidate`
  - the user model added a custom implementation of `onValidate`, because of a bug which we experienced (see https://github.com/TryGhost/Ghost/issues/3638)
  - with the refactoring this is no longer required - we only validate fields which have changed when updating resources
  - also, removed extra safe catch when logging in (no longer needed - unit tested)
- add lot's of unit tests to proof the code change
- always call the base class, except you have a good reason
2018-02-16 00:49:15 +01:00
kirrg001
71ba76b99b Extended knex mock: be able to fetch all resources
no issue

- the case was simply missing
- if no where clause is present, we return all models
2018-02-15 23:31:01 +01:00
kirrg001
355ef54702 Removed isNew usages in model layer
no issue

- `isNew` does not work in Ghost, because Ghost does not use auto increment id's
- see https://github.com/bookshelf/bookshelf/issues/1265
- see https://github.com/bookshelf/bookshelf/blob/0.10.3/src/base/model.js#L211
- we only had one occurance, which was anyway redundant
  - if you add a user, `hasChanged('password') is true
  - if you edit a user and the password has changed, `hasChanged('password')` is true as well

NOTE #1:

1. We can't override `isNew` and throw an error, because bookshelf makes use of `isNew` as well, but it's a fallback if `options.method` is not set.
2. It's hard to re-implement `isNew` based on `options.method`, because then we need to ensure that this value is always set (requires a couple of changes)

NOTE #2:
If we need to differentiate if a model is new or edited, we should manually check for `options.method === insert`.

NOTE #3:
The unit tests are much faster compared to the model integration tests.
I did a comparision with the same test assertion:
  - unit test takes 70ms
  - integration test takes 190ms
2018-02-15 22:11:49 +01:00
kirrg001
0b5cfd933f Added knex mock for unit testing
no issue

- added https://github.com/colonyamerican/mock-knex as dev dependency
- the mock serves our data generator test data by default
  - but you can define your own if you want
- we need a proper mock for unit testing
- we should not mock bookshelf if possible, otherwise we can't test event flows
2018-02-15 22:11:49 +01:00
kirrg001
2b76d7a492 Added lib.security.password lib
no issue

- move password hashing and password comparison to lib/security/password
- added two unit test
- FYI: password hashing takes ~100ms
  - we could probably mock password hashing in certain cases when unit testing
2018-02-15 21:13:04 +01:00
Katharina Irrgang
c6a95c6478
Sorted out the mixed usages of include and withRelated (#9425)
no issue

- this commit cleans up the usages of `include` and `withRelated`.

### API layer (`include`)
- as request parameter e.g. `?include=roles,tags`
- as theme API parameter e.g. `{{get .... include="author"}}`
- as internal API access e.g. `api.posts.browse({include: 'author,tags'})`
- the `include` notation is more readable than `withRelated`
- and it allows us to use a different easier format (comma separated list)
- the API utility transforms these more readable properties into model style (or into Ghost style)

### Model access (`withRelated`)
- e.g. `models.Post.findPage({withRelated: ['tags']})`
- driven by bookshelf

---

Commits explained.

* Reorder the usage of `convertOptions`

- 1. validation
- 2. options convertion
- 3. permissions
- the reason is simple, the permission layer access the model layer
  - we have to prepare the options before talking to the model layer
- added `convertOptions` where it was missed (not required, but for consistency reasons)

* Use `withRelated` when accessing the model layer and use `include` when accessing the API layer

* Change `convertOptions` API utiliy

- API Usage
  - ghost.api(..., {include: 'tags,authors'})
  - `include` should only be used when calling the API (either via request or via manual usage)
  - `include` is only for readability and easier format
- Ghost (Model Layer Usage)
  - models.Post.findOne(..., {withRelated: ['tags', 'authors']})
  - should only use `withRelated`
  - model layer cannot read 'tags,authors`
  - model layer has no idea what `include` means, speaks a different language
  - `withRelated` is bookshelf
  - internal usage

* include-count plugin: use `withRelated` instead of `include`

- imagine you outsource this plugin to git and publish it to npm
- `include` is an unknown option in bookshelf

* Updated `permittedOptions` in base model

- `include` is no longer a known option

* Remove all occurances of `include` in the model layer

* Extend `filterOptions` base function

- this function should be called as first action
- we clone the unfiltered options
- check if you are using `include` (this is a protection which could help us in the beginning)
- check for permitted and (later on default `withRelated`) options
- the usage is coming in next commit

* Ensure we call `filterOptions` as first action

- use `ghostBookshelf.Model.filterOptions` as first action
- consistent naming pattern for incoming options: `unfilteredOptions`
- re-added allowed options for `toJSON`
- one unsolved architecture problem:
  - if you override a function e.g. `edit`
  - then you should call `filterOptions` as first action
  - the base implementation of e.g. `edit` will call it again
  - future improvement

* Removed `findOne` from Invite model

- no longer needed, the base implementation is the same
2018-02-15 10:53:53 +01:00
Kevin Ansfield
8fe73d9867 Updated Ghost-Admin to 1.21.2 2018-02-14 18:24:03 +00:00
Hannah Wolfe
fe0197b226 🐛Fixed {{get}} helper's date comparison (#9454)
no issue

- Date comparisons are possible via API, but there's no way to inject a valid date into the get helper
- JavaScript's Date.toString() function outputs dates in a useless format
- Swap to using Date.toISOString() and now the format can be understood anywhere!
- {{#get "posts" filter="published_at:<='{{published_at}}'"}}{{/get}} works now as expected
2018-02-14 18:33:07 +01:00
Katharina Irrgang
9ede5905f6
Reduce toJSON implementation: use the power of bookshelf (#9423)
refs #6103

- simplify `toJSON`
- `baseKey` was not used - have not find a single use case
- all the functionality of our `toJSON` is offered in bookshelf
- `omitPivot` does remove pivot elements from the JSON obj (bookshelf feature)
- `shallow` allows you to not return relations
- make use of `serialize`, see http://bookshelfjs.org/docs/src_base_model.js.html#line260
- fetching nested relations e.g. `users.roles` still works (unrelated to this refactoring)

> pick('shallow', 'baseKey', 'include', 'context')

We will re-add options validation in https://github.com/TryGhost/Ghost/pull/9427, but then with the official way: use `filterOptions`.

---

We return all fetched relations (pre-defined with `withRelated`) by default.
You can disable it with `shallow:true`.
2018-02-14 17:32:11 +01:00
Katharina Irrgang
58157b1411
🐛Fixed asset redirects (#9455)
closes #9445

- redirects all asset requests if https is configured (theme, core, images)
- re-use and extend our url-redirect middleware
- add proper integration tests for our express site app (no db interaction, component testing required for such important use cases)
- i added some more general tests
- should avoid mixed content warnings in the browser
2018-02-14 17:21:31 +01:00
kirrg001
2822d725d8 Updated Ghost-Admin to 1.21.1 2018-02-07 12:35:33 +01:00
kirrg001
ed4fde4f00 🐛 Fixed migrating from < 1.13 to 1.21
no issue

- discovered while testing
- the fixture utility needed a protection against non existent roles in the database
  - it tries to fetch the contributor role from the database, which does not exist yet
2018-02-07 12:31:21 +01:00
kirrg001
c6ec2777ed Updated Ghost-Admin to 1.21.0 2018-02-07 10:51:41 +01:00
Austin Burdine
777247cbc7 Contributor Role (#9315)
closes #9314 

* added fixtures for contributor role
* update post api tests to prevent contributor publishing post
* update permissible function in role/user model
* fix additional author code in invites
* update contributor role migration for knex-migrator v3
* fix paths in contrib migration
* ensure contributors can't edit or delete published posts, fix routing tests [ci skip]
* update db fixtures hash
* strip tags from post if contributor
* cleanup post permissible function
* excludedAttrs to ignore tag updates for now (might be removed later)
* ensure contributors can't edit another's post
* migration script for 1.21
2018-02-07 10:46:22 +01:00
Katharina Irrgang
a274d61a8c Removed html usage in error messages (#9444)
no issue

- all of the error message keys were unused
- the only html anchor i found was for mail, but this doesn't change anything, because the admin does only show the message and not the context at the moment
2018-02-07 09:35:48 +01:00
Kevin Ansfield
fb973dbbf2 Fixed missing export of card-markdown card and broken tests
no issue
- fixes rendering bug introduced in 0833b28557
- updates test generators/fixtures to use new card names
2018-02-01 16:26:56 +01:00
Kevin Ansfield
05bcf7ee6a Fixed missing export of card-markdown card
no issue
- fixes the bug introduced in 0833b28557
2018-02-01 15:50:43 +01:00
Kevin Ansfield
0833b28557 Koenig - Rename server-side cards
refs https://github.com/TryGhost/Ghost/issues/9311
- match card names to the new generic Koenig card names introduced in 95a068615d
2018-02-01 12:40:49 +01:00
Kevin Ansfield
6f4e112c87 Updated Ghost-Admin: fix Warning: Task "setup" not found. Use --force to continue.
Aborted due to warnings.
2018-01-29 08:49:47 +00:00
Chuck Lam
ffc6088c7a Fixed comment in facebook_url helper (#9430)
no issue
2018-01-28 18:25:06 +01:00
kirrg001
39ee95cc07 Make use of ES6 arrow functions in our data importer
no issue

- reduces the usage of `self`
2018-01-28 15:48:24 +01:00
kirrg001
2a10c83d92 Improved memory usage in importer
no issue

- returning and remembering the data, which was imported, is...
  - not required when using the API
  - not required when importing via script
  - required for tests
  - added an option to have control over it
- make more usage of local variables
  - the GC cannot tidy up variables, which are defined outside of a loop, but used in the loop
- try to keep less memory in process
  - reduce the number of properties we have to remember
2018-01-28 14:26:38 +01:00
kirrg001
5f9c3b92bd Improved Base importer constructor readability
no issue

- better differentiation between options and data
- better readability how to access required data from file
2018-01-28 13:35:21 +01:00
kirrg001
82bb3aaea1 Do not import unknown author id, fallback to owner id
no issue

- if you import a JSON file with a post, which has an unknown author,
  the target user was removed from the blog
- Ghost can handle this case and still succeeds with import
  - but we have stored an `author_id` in the database, which does not map to any user and won't map in the future
- this can trouble if we add support for multiple authors
  - currently, we only return the `author_id` to the client and the client can map with `author_id` with users fetched by the API
    - if it does not find a user, it just falls back to a different user
  - but multiple authors have to be included explicit (`include=authors`) and we will return a mapped (author_id => user) result
  - it won't be able to find the user, because we lookup the database
  - this would result in an error
- there is in general no reason to import (or store) an unknown/invalid `author_id` into the database
- on import, we show you a warning and you can choose a different author if you want
- solution: fallback to owner user and extend warning
  - it's not a behaviour change, you still can import unknown author id's and the import won't fail
  - but we ensure valid author id's
- updated test
- further more: returning `author={}` when requesting `include=author` could trouble with ember currently
  - it expects the author to be returned
2018-01-27 12:54:36 +01:00
kirrg001
c6f30a46d2 Avoid knex warning when destroying a user
no issue

- the warning is "Transaction was already complete"
- destroying a user happens in a transaction, but the event is not asynchronous
  - so we have to ensure that we don't operate on a finished transaction
2018-01-27 12:31:51 +01:00
kirrg001
b4f355f713 Removed the usages of this.forge(null, {context: options.context})
no issue

- refs fe461da110
- the access plugin was removed
- no need to pass `context` as parameter for `.forge`
2018-01-26 00:35:39 +01:00
kirrg001
fe461da110 Deleted bookshelf access plugin
refs #9127

- permission checks can happen everywhere in the code base
  - we would like to create a context class
- global access to `options.context.is(...)`
- please read more about the access plugin in #9127 section "Model layer and the access plugin".
- removed the plugin and use direct context checks
2018-01-25 17:54:28 +01:00
kirrg001
20d1f86fb6 Fixed broken payload in posts_spec.js
no issue

- the affected test had a wrong payload, but passed anyway because the previous test edited the same title ;)
- this routing test does currently truncate the tables after each test case
  - the test can run faster
  - if we achieve reducing the routing tests, we can reconsider truncating the db
2018-01-25 01:05:59 +01:00
Kevin Ansfield
1ba834f078 Updated Ghost-Admin to 1.20.3 2018-01-23 16:26:10 +00:00
Kevin Ansfield
69d5fac61e
Resurrect the old alpha Koenig editor (#9277)
requires https://github.com/TryGhost/Ghost-Admin/pull/916
- add "enableDeveloperExperiments" config flag
- allow any HTML payload through in the HTML mobiledoc card
  - same approach as taken in the markdown card, running the markup through SimpleDOM isn't necessary and is prone to breaking because of it's limited parsing and error handling abilities

To use Koenig modify your `config.development.json` file and add the following flag to the top-level object:

```
"enableDeveloperExperiments": true
```

If you restart the dev server you will then see a new section on the Labs screen with a Koenig Editor checkbox to enable/disable the editor.

⚠️ The editor is in a _very_ broken state, it's there for developer testing and on-going development. _Do not_ try to use this on any production data!
2018-01-18 15:43:22 +00:00
kirrg001
357ea3dffd 🐛 Fixed showing old release notifications in the about page
no issue

- reported in slack (https://ghost.slack.com/files/U8QV8DXQB/F8TSBQ532/image.png)
- do not expose old release notification
  - e.g. you are on 1.20.0
  - you receive a notification for 1.20.1 to update
  - you update to 1.20.1
- ensure we protect exposing the release notification (compare against blog version)
- protect against wrong formats
- @TODO: the notifications could store a `version` property
  - by that we could use `notification.version` and don't have to match the version in the message
2018-01-18 12:19:55 +01:00
kirrg001
1fd9b2cbd6 Updated Ghost-Admin to 1.20.2 2018-01-17 18:13:44 +01:00
Peter Garland
35fbba3bcb Fixed bad references to common.i18n (#9402)
no issue

- happened during refactoring (search+replace)
2018-01-17 17:28:42 +01:00
kirrg001
b5a4160578 Updated Ghost-Admin to 1.20.1 2018-01-16 14:36:25 +01:00
Katharina Irrgang
c062114e47
Increased cache-control for ghost-sdk.min.js and ghost.min.css (#9399)
no issue

- we increase the client in-memory expiry for production built assets
- as soon as there will be another release, a new asset hash is generated and the client cache is invalidated automatically (doesn't matter how long we store the file in the client)
- the next step is to get rid of having asset hashs part as query params
  - ghost-sdk.min.js?v=1234 is becoming e.g. ghost-sdk-1234.min.js
  - reasons:
    - A: performance tools complain about it
    - B: we no longer invalidate the asset hashs for built assets if the theme changes
2018-01-16 12:22:29 +01:00
Katharina Irrgang
e480c7c50d 🐛 Reload translations if active theme get's overridden (#9392)
no issue

- discovered while testing
  - activate theme
  - download theme
  - modify theme
  - upload theme
  - override? yes
  - translation files are not reloaded, because the database is up-to-date
- remove un-used events in theme api layer
- trigger event from theme service
2018-01-12 09:19:28 +00:00
Hugo Marisco
ccb5fd837e Fixed wrong status code for incorrect token requests (#9374)
closes #9346

- server returned 500, happened when you send an empty username/password
- return 400 instead
- error message is/was correct
2018-01-11 16:17:03 +01:00
David Wolfe
b69b9780a9 Backup endpoint improvements (#9365)
closes #9297

- backup endpoint returns JSON
- allows setting of export filename
- DRY up code
- the endpoint is not documented, no breaking change
2018-01-11 16:03:21 +01:00
kirrg001
bf31d562a1 Updated Ghost-Admin to 1.20.0 2018-01-09 21:42:08 +01:00
kirrg001
ccb3b3de38 Fixed 1.20 migration script
no issue

- `models.Settings.destroy` only accepts one argument
2018-01-09 21:38:13 +01:00
Katharina Irrgang
5b77f052d9
Update Notification improvements (#9123)
closes #5071

- Remove hardcoded notification in admin controller
  - NOTE: update check notifications are no longer blocking the admin rendering
  - this is one of the most import changes
  - we remove the hardcoded release message
  - we also remove adding a notification manually in here, because this will work differently from now on
    -> you receive a notification (release or custom) in the update check module and this module adds the notification as is to our database

- Change default core settings keys
  - remove displayUpdateNotification
    -> this was used to store the release version number send from the UCS
    -> based on this value, Ghost creates a notification container with self defined values
    -> not needed anymore

- rename seenNotifications to notifications
  -> the new notifications key will hold both
     1. the notification from the USC
     2. the information about if a notification was seen or not
  - this key hold only one release notification
  - and n custom notifications

- Update Check Module: Request to the USC depends on the privacy configuration
  - useUpdateCheck: true -> does a checkin in the USC (exposes data)
  - useUpdateCheck: false -> does only a GET query to the USC (does not expose any data)
  - make the request handling dynamic, so it depends on the flag
  - add an extra logic to be able to define a custom USC endpoint (helpful for testing)
  - add an extra logic to be able to force the request to the service (helpful for testing)

- Update check module: re-work condition when a check should happen
  - only if the env is not correct
  - remove deprecated config.updateCheck
  - remove isPrivacyDisabled check (handled differently now, explained in last commit)

- Update check module: remove `showUpdateNotification` and readability
  - showUpdateNotification was used in the admin controller to fetch the latest release version number from the db
  - no need to check against semver in general, the USC takes care of that (no need to double check)
  - improve readability of `nextUpdateCheck` condition

- Update check module: refactor `updateCheckResponse`
  - remove db call to displayUpdateNotification, not used anymore
  - support receiving multiple custom notifications
  - support custom notification groups
  - the default group is `all` - this will always be consumed
  - groups can be extended via config e.g. `notificationGroups: ['migration']`

- Update check module: refactor createCustomNotification helper
  - get rid of taking over notification duplication handling (this is not the task of the update check module)
  - ensure we have good fallback values for non present attributes in a notification
  - get rid of semver check (happens in the USC) - could be reconsidered later if LTS is gone

- Refactor notification API
  - reason: get rid of in process notification store
    -> this was an object hold in process
    -> everything get's lost after restart
    -> not helpful anymore, because imagine the following case
      -> you get a notification
      -> you store it in process
      -> you mark this notification as seen
      -> you restart Ghost, you will receive the same notification on the next check again
      -> because we are no longer have a separate seen notifications object
  - use database settings key `notification` instead
  - refactor all api endpoints to support reading and storing into the `notifications` object
  - most important: notification deletion happens via a `seen` property (the notification get's physically deleted 3 month automatically)
    -> we have to remember a seen property, because otherwise you don't know which notification was already received/seen

- Add listener to remove seen notifications automatically after 3 month
  - i just decided for 3 month (we can decrease?)
  - at the end it doesn't really matter, as long as the windows is not tooooo short
  - listen on updates for the notifications settings
  - check if notification was seen and is older than 3 month
  - ignore release notification

- Updated our privacy document
- Updated docs.ghost.org for privacy config behaviour
- contains a migration script to remove old settings keys
2018-01-09 15:20:00 +01:00
juan-g
f671f9d2c9 Theme translations and blog localisation (#8437)
refs #5345, refs #3801

- Blog localisation
  - default is `en` (English)
  - you can change the language code in the admin panel, see https://github.com/TryGhost/Ghost-Admin/pull/703
  - blog behaviour changes depending on the language e.g. date helper format
  - theme translation get's loaded if available depending on the language setting
  - falls back to english if not available

- Theme translation
  - complete automatic translation of Ghost's frontend for site visitors (themes, etc.), to quickly deploy a site in a non-English language
  - added {{t}} and {{lang}} helper
  - no backend or admin panel translations (!)
  - easily readable translation keys - very simple translation
  - server restart required when adding new language files or changing existing files in the theme
  - no language code validation for now (will be added soon)
  - a full theme translation requires to translate Ghost core templates (e.g. subscriber form)
  - when activating a different theme, theme translations are auto re-loaded
  - when switching language of blog, theme translations are auto re-loaded

- Bump gscan to version 1.3.0 to support more known helpers

**Documentation can be found at https://themes.ghost.org/v1.20.0/docs/i18n.**
2018-01-09 14:50:57 +01:00