Commit Graph

158 Commits

Author SHA1 Message Date
Naz Gargol
df1ba8aee1
Added ability to notify and update url service about changes in related resources (#10336)
refs https://github.com/TryGhost/Ghost/issues/10124

- This PR introduced additional db calls in URL service due to the need for a model recalculation (we can't rely on the objects that come with events)
2019-01-08 09:48:53 +00:00
Hannah Wolfe
da17b2c82b Settings API should return null instead of ""
refs #10345

- We are standardising on returning null from the Content API for any empty values
2019-01-07 15:02:24 +00:00
Katharina Irrgang
6b758bda79
Refactored routing config for multiple api versions (#10333)
refs #10124

- one clean v0.1 and v2 config file for routing!
- solves one underlying bug reported in #10124
- the alias handling was just a hotfix to support v2 for the site
- but it was hard to read, ugly
- now we have two clean configs
- we'll see how useful it is
- need to do proper manual testing on Monday
2019-01-04 21:59:39 +01:00
Katharina Irrgang
6448c7bdc8
Fixed site using API v2 (#10332)
no issue

- See explanation: ef98c65040 (r31840536)
- that should not break anything, because resource consumption is based on resource type
- the alias pattern was only invented to make v2 work, it was a little dirty. i wanted to refactor that out anyway
2019-01-04 18:24:00 +01:00
Hannah Wolfe
652e818cae Used settingsCache.getPublic() in theme middleware
- Use the new getPublic function which does the same thing as this code
- This removes the inclusion of the amp property, but this is undocumented and should not be there anyway!
- This also adds the ghost_head and ghost_foot property, which are public settings
2019-01-04 12:17:32 +00:00
Hannah Wolfe
5d977f23d4 Added Settings endpoint to V2 Content API
refs #10318

- This settings endpoint returns the commonly used, public information from our settings.
- The values are whitelisted each with a custom name for returning from the endpoint
2019-01-04 12:17:32 +00:00
Naz Gargol
d3f3b3dc20
Added plugin based author and public tag models in API v2 (#10284)
refs #10124

- Author model returns only users that have published non-page posts
- Added a public controller for tags (should be extracted to separate Content API controller https://github.com/TryGhost/Ghost/issues/10106)
- Made resource configuration dynamic based on current theme engine
- This needs a follow-up PR with fixes to the problems described in the PR
2019-01-03 20:30:35 +01:00
Fabien O'Carroll
c2275ed131
Added size attribute support to img_url helper (#10182)
refs #10181 

Adds support to request a size in the img_url helper using syntax like:
    <img src="{{img_url profile_image size="small"}}"/>

Requires the image_sizes config to be defined in the themes package.json
2018-12-13 19:14:08 +07:00
Fabien O'Carroll
48923ac327
Wired members service up to api and app (#10262)
* Updated auth service members middleware

refs #10213

* Wired up members api router to the ghost api endpoints

refs #10213

* Created members app for the static pages

refs #10213

* Wired up the members app

refs #10213
2018-12-11 15:18:07 +07:00
Katharina Irrgang
fc21b25895
🐛Fixed auto redirect for extra data queries on post and page resources (#9828)
closes #9791

- we only made use of the redirect middleware, who detects if a redirect should happen, for taxonomies (tags, authors)
- `data: page.team` will now redirect too
- `data: post.team` will now redirect too
- you can disable the redirect using the long form
2018-12-03 20:31:48 +01:00
Katharina Irrgang
e48c28b98f 🐛 Protected Ghost blog against invalid uploaded routes.yaml (#10100)
* 🐛  Protected Ghost blog against invalid uploaded routes.yaml

no issue

- e.g. you upload `filter:tag=this is a wrong filter value`
- ask the url service if it has finished it's work to ensure the upload was successful
- wait 5 seconds till Ghost will bring back the last uploaded valid version

* fixed test
2018-11-26 16:28:22 +07:00
Sumedh Nimkarde
f3e9218ee3 🎨 Modified slack webhook payload, added info about published post (#9850)
closes #8936

- Modified the slack webhook payload to provide more info about a published post
2018-11-12 13:04:50 +01:00
Fabien O'Carroll
2a6e9aac55 🚧 Created members auth middleware
closes #10110
2018-11-08 13:32:09 +07:00
Katharina Irrgang
ff6bf5f318 Renamed /users to /authors for Content API V2 (#10096)
refs #10061

- Made /authors endpoint available in Content API V2
2018-11-07 15:29:37 +01:00
Katharina Irrgang
1b9c61eed1
Returned relative paths in html for Content API V2 by default (#10091)
refs #10083

- you can send `?absolute_urls=true` and Ghost will also transform the paths in the content (this is optional/conditional)
2018-11-05 18:07:45 +01:00
Rishabh Garg
e2d0b2e543 Updated webhook request header and last triggered error mssg (#10035)
refs #9942

- Added error message if unknown status code on request failure
- Added event to payload
2018-10-19 14:11:03 +01:00
Rishabh Garg
8ad951d7f3
Added new site.changed event and webhook trigger service (#10019)
refs #9942

* Added new middleware to trigger events

* Refactored webhooks service
- added new trigger service, moved listen service to its own file
- started listening to new site.changed event
- cleaned up trigger service to work with new webhook fields
- cleaned up tests
- removed redundant trigger method in v0.1 controller
2018-10-19 00:01:30 +05:30
kirrg001
e302be2749 Changed preview controller to support v0.1 and v2
refs #9866

- invent preview api, but only used internally
  - the idea of a preview api is definitiely reaslistic and came up in the past a couple of times
- by that we don't have to differentiate between pages or posts controller
- still support v0.1
- preview controller is not registered for http, only internal handling
2018-10-18 19:41:07 +02:00
kirrg001
12ff70497f Changed entry lookup helper to respect the resource type
refs #9866

- the entry helper is used for static pages and post lookups
- now that we support changing the api version, we have to respect the resource type
- for v2: we ask the pages controller for static pages
- in v0.1: pages and posts lived on the same route
- we are talking about the content API (!) - not admin api
2018-10-18 19:41:07 +02:00
kirrg001
803a325ade Renamed post-lookup to entry-lookup
refs #9866

- the static pages router uses the entry controller
- and the entry controller uses the lookup helper
- the lookup helper needs to either fetch static pages or posts
- v2 uses pages and posts controller
2018-10-18 19:41:07 +02:00
kirrg001
640290c31b Updated blog site components to respect the api version
refs #9866

- the api call must be dynamic based on the api version information
2018-10-18 19:41:07 +02:00
kirrg001
3f9d0f51f5 Changed how we determine if a resource is owned by an url generator
refs #9601

- api v2 returns absolute urls
- api v0.1 returns relative urls
- it's easier if we compare by id
2018-10-18 19:41:07 +02:00
kirrg001
1f55c90037 Supported reading ghost api engine
refs #9866

- we fallback to v0.1 by default
- we support different formats
- this opens the box to switch the ghost api version for the whole blog site
- i had to add a different notation for overrides.json, because the structure is not optimal (i only want the versions, not the shortcuts)
2018-10-18 19:41:07 +02:00
Rishabh Garg
51dde1e38c
Refactored config to handle direct calls for specific version (#10012)
refs #9866

- Refactored overrides config to include direct version configs(v0.1, v2), supported versions map to direct version
- Refactored `getApiPath` to handle direct versions as well as mappings of supported version
2018-10-16 15:20:51 +05:30
Fabien O'Carroll
3db102a776
Added API Key auth middleware to v2 content API (#10005)
* Added API Key auth middleware to v2 content API

refs #9865

- add `auth.authenticate.authenticateContentApiKey` middleware
  - accepts `?key=` query param, sets `req.api_key` if it's a known Content API key
- add `requiresAuthorizedUserOrApiKey` authorization middleware
  - passes if either `req.user` or `req.api_key` exists
- update `authenticatePublic` middleware stack for v2 content routes

* Fixed functional content api tests

no-issue

This fixes the functional content api tests so they use the content api
auth.

* Fixed context check and removed skip

* Updated cors middleware for content api

* Removed client_id from frame.context

no-issue

The v2 api doesn't have a notion of clients as we do not use oauth for it

* Fixed tests for posts input serializer
2018-10-15 16:23:34 +07:00
Fabien O'Carroll
3516b15f9e
Updated session middleware to support node v6 (#9980)
closes #9972

* Added breaking test for node v6 session auth
* Updated session middleware to support node v6

This uses the legacy url to obtain the origin rather than the WHATWG
URL class in order to support node <6.14.4
2018-10-10 20:07:31 +07:00
Katharina Irrgang
d2baf80d58
Optimised test folder structure (#9958)
refs #9866

- test/functional/
- test/functional/api
- test/functional/api/v0.1
- test/functional/api/v0.1/utils
- test/functional/api/v2
- test/functional/api/v2/admin
- test/functional/api/v2/admin/utils
- test/functional/api/v2/content
- test/functional/api/v2/content/utils

- updated grunt file
- instead of `grunt test-routes`, you now need to use `grunt test-functional` (docs are updated)

You can use `localUtils.API.getApiQuery('posts/')` and it will generate the correct API url.
2018-10-07 16:36:02 +02:00
kirrg001
b855f2d8f0 Removed testUtils.API.getApiPath
refs #9866

- the global utility should for now not generate API urls
- we only have one test which generates the API url
- for now it will live in this test file
- if we have multiple cases, we can reconsider this
2018-10-05 16:49:46 +02:00
Rishabh Garg
f78d9d3914
Refactored hardcoded v0.1 url unit tests to support multiple versions (#9945)
refs #9866

- Added test util method for api path based on version
- Updated all hardcoded v0.1 tests strings to use dynamic string from util method
- Updated hardcoded v0.1 tests using regex match to use string equal with new util method
2018-10-04 21:43:12 +05:30
Rish
dd151f3713 Refactored method urlFor to use versionType instead of admin: true
no issue

- Updated urlFor to work with versionType instead of admin:true
- Updated tests to use the correct method call
2018-10-04 16:49:55 +05:30
Nazar Gargol
82b7aea641
Refactor URL generation from models (#9917)
Moved URL attributes logic from the model into API layer 

refs #9866

- Moved URL related attribute calculation for posts, users, and tags into API layer
- Added test coverage for url attributes in tags/authors/primary_tags/primary_authors
2018-10-03 15:44:30 +02:00
Fabien O'Carroll
cb0c5dc582
Session auth service (#9910)
refs #9865

* This service handles the session store and exporting middleware to be
used for creating and managing sessions

* Updates the auth service index.js file in line with how we do things elsewhere

* After wrapping the exports in a getter, the usage of rewire had broken
the authenticate tests, this commit _removes_ rewire from the tests, calls `init` on
the models before the tests (needed because rewire isn't there) and also
cleans up the use of var.
2018-10-02 15:35:23 +07:00
Fabien O'Carroll
6cd1dc8005 🐛Fixed blog not responding when uploading routes.yaml with unknown taxonomy (#9926)
closes #9870

Instead of 500'ing when uploading a routes.yaml with an invalid taxonomy
we will now send back an error saying it's invalid.
2018-10-01 20:40:29 +02:00
Rishabh Garg
6163d1f128 Updated overrides config for api versions with v0.1 to deprecated (#9921)
refs #9866

- v0.1 == deprecated
- v2 == active
2018-09-27 19:34:12 +02:00
Rishabh Garg
9624c88f3e Refactored url utility to generate multiple API version URLs (#9897)
refs #9866

- added api version config to overrides, which makes it possible to have a centralized api versioning configuration
- the next PR will use this config in the web folder
- make api url generation in url service flexible and dynamic
- remove hardcoded API_PATH
- updated all places which used `urlFor('api'..)` -> we now ask for explicit api version
2018-09-24 21:49:20 +02:00
Rishabh Garg
fcd275f6c0 Refactored web/middleware and web/utils to web/shared (#9892)
refs #9866

- Moved web/middleware to web/shared/middlewares
- Moved util file to web/shared/utils
2018-09-20 20:04:34 +02:00
Fabien O'Carroll
c9b8ddde4b 🎨Added absolute_url flag to public api (#9833)
closes #9832

The API _should_ be returning absolute URLs for everything, 3rd party applications require absolute urls to read and display ghost data correctly. Currently they have to concat the blog url and the resource url, which is very uncomfortable.

Changing the public api like this would be considered a breaking change however so we've opted to put it behind a query parameter named `absolute_urls`.
2018-08-31 11:02:39 +01:00
Fabien O'Carroll
2376c614b3 Fixed RPC pings (#9816)
closes #9644

- Removed google blogsearch from pingList, because it's dead (https://plus.google.com/+GoogleWebmasters/posts/46W7ZwVrwqg)
- Updated pingomatic method weblogUpdate -> weblogUpdates
- Updated RPC response handler to check for errors, log improvement
- the pingomatic service sends back a 200 even when it errors, so we
check the xml response to see if it's good, it throws and passes of to
the catch handler already in place
- Avoid multiline XML error message strings, but
includes a catch in case our regex stops working with a fallback to
multiline XML error message
- we check for arbitrary whitespace between different XML tags,
which I haven't seen in any of the responses - but it could change I
guess. I haven't added support of whitespace between the tags, as I
believe that would be a different value with XML spec. And we wanna
match on exact values here.
2018-08-23 15:20:29 +02:00
Katharina Irrgang
cd690efad1 🐛 Dynamic Routing Beta: Disallow using author resource and author data key name (#9790)
* 🐛 Dynamic Routing Beta: Shortform `author.foo` is not allowed

refs #9601

- otherwise you get access to {{author}} in the theme, which is deprecated & causes errors
- recommend not using {{author}} as data longform name in the yaml validator
- (internal usage is still allowed)
- also warn against using reserved data key names like filter, resource, limit etc - maybe remove this restriction later but seems like a sensible validation right now.
2018-08-16 12:13:24 +02:00
kirrg001
bbde22a687 Fixed tests
no issue

- replace test themes
  - otherwise they are all invalid with the new GScan version
- fix general tests because of Ghost 2.0 logic
2018-08-16 12:13:24 +02:00
kirrg001
17833a669b 🎨 Dynamic Routing Beta: Enabled redirect by default when using data key
refs #9601

- when using the short form `data: tag.welcome` the redirect is enabled by default
  - /tag/welcome/ will redirect to the channel/collection which makes use of the data key
- you can disable the redirect by using the long form
  e.g. data:
	tag:
	  resource: tags
          type: read
          slug: welcome
          redirect: false
2018-08-16 12:13:24 +02:00
kirrg001
8bb7088ba0 🔥 Removed permalink setting
refs #9742

- removed usage of single permalink setting
  - with dynamic routing this configuration does no longer makes sense
  - because you can configure your permalinks in the routes.yaml
  - furthermore you can have multiple collections with multiple permalinks
- removed @blog.permalinks
- do not export permalink setting
- do not import permalink setting
- permalink setting UI will be removed soon
- get rid of {globals.permalink} completely
- remove yaml in-built migration
- do not expose settings.permalinks via the private API
- do not allow to edit this setting
- keep phyiscal value in case a blog needs to rollback from v2 to v1
- sorted out when the routers should be created
  - ensure routes.yaml file doesn't get validated before Ghost is fully ready to start
2018-08-16 12:13:24 +02:00
Katharina Irrgang
c39df004dc Changes for Koenig and Ghost 2.0 (#9750)
refs #9742, refs #9724

- handle König Editor format for 2.0
- adapted importer to be able to import 1.0 and 2.0 exports
- added migration scripts
  - remove labs flag for Koenig
  - migrate all old editor posts to new editor format
- ensure we protect the code against mobiledoc or html field being null
- ensure we create a blank mobiledoc structure if mobiledoc field is null (model layer)
- ensure you can fully rollback 2.0 to 1.0
- keep mobiledoc/markdown version 1 logic to be able to rollback (deprecated code)
2018-08-16 12:13:24 +02:00
kirrg001
d518f23b48 Updated docs links
refs #9742

- rebase against master updated some docs links again
- go over code base again and double check that all docs links are correct
- 2.0 will become the latest version on our readme pages
2018-08-16 12:13:24 +02:00
kirrg001
860718f584 Minimized cached data on resource add/update
refs #9601

- on resource update/add we have cached mobiledoc, html etc
- we have to ensure we exclude the fields (same procdure happens on bootstrap)
- these excluded fields don't have to be cached
- otherwise memory usage is higher in general
- ensure we cache relations with a minimal field set on resource update/add
2018-08-12 14:23:32 +02:00
kirrg001
132df78940 Updated docs links
refs #9742

- Ghost 2.0 is coming
- all doc links in 1.0 must use concrete links e.g. docs.ghost.org/v1 or themes.ghost.org/v1.23.0/
- if we release Ghost 2.0, docs.ghost.org will show 2.0 docs
2018-07-20 23:49:16 +02:00
kirrg001
b335002269 🐛 Fixed Disqus comments on post preview pages
closes #9727

- this is a short term fix to proof that Disqus comments on preview pages no longer appear on other threads
- this is not a full solution to the problem
- the private API still returns /404/, which is right now inconsistent, but not critical in any way
- the url helper will now output the post preview url if you serve a draft/scheduled post
- this should register unique page urls at Disqus and ensure uniquness for threads
  - i still don't understand why the cross posting happens at all, because we also pass an unique identifier to Disqus (the post ID)
- it could be that comments, which are added on the preview page, won't appear on the published urls, because
  the published url !== preview url. I wasn't able to figure this out via testing or reading their docs
2018-07-11 00:20:55 +02:00
kirrg001
c5bad55d6f Dynamic Routing Beta: StaticRoutesRouter has to respect the route name
refs #9601

- this was already working for collections or channels
- but the `routeName` was not parsed for static routes
- ensure we push the route name into the context object

e.g. /about/: about

-> name of the route is "about"
2018-06-26 19:06:42 +02:00
kirrg001
af58de0490 🐛 Fixed dated urls when timezone changes
no issue

- discovered while testing (issue doesn't exist)
- with dynamic routing we have introduced a bug
- we pre-generate urls and if your permalink contains a date (dated permalink),
  we have to regenerate the urls, otherwise the dated urls do not respect your blog timezone
- collection router has to subscribe to the timezone event
- collection router must trigger an update on it's url generator if the timezone changes and the it's permalink is dated
- ensure we also update the urls on import
2018-06-26 18:18:11 +02:00
Katharina Irrgang
7027980ad2
Dynamic Routing Beta: Filter collections with NQL (#9704)
refs #9601

- replace jsonpath with [NQL](https://github.com/NexesJS/NQL)
- jsonpath was just a temporary solution (a short-term fix)
- with NQL we are able to filter collections more powerful in the near future
- NQL is not feature complete
- we still support `featured:true` for collections
2018-06-26 01:54:51 +02:00
Katharina Irrgang
fc9da07025
Dynamic Routing Beta: Added ability to disable+override rss (#9693)
refs #9601

- you can now use `rss:false`
- ability to define a custom rss url with a target template (+ content_type)
- ability to disable rss for channel or collection
2018-06-26 01:33:29 +02:00
Katharina Irrgang
13cccfa9ee
Dynamic Routing Beta: Refactor res.routerOptions (#9705)
refs #9601

- sort out `res._route` vs. `res.locals.routerOptions`
- it was super hard to maintain two different objects
2018-06-26 01:12:50 +02:00
kirrg001
07c72d735e Dynamic Routing Beta: Render default.hbs as fallback for static routes
refs refs #9601

- instead of index.hbs (that doesn't make sense)
2018-06-24 02:06:58 +02:00
kirrg001
c2fa469c4d Dynamic Routing Beta: Channels
refs #9601

- refactor architecture of routing so you can define a channel
- a channel is a different way of looking at your posts (a view)
- a channel does not change the url of a resource

Example channel

```
routes:
  /worldcup-2018-russia/:
    controller: channel
    filter: tag:football18
    data: tag.football18
```

- added ability to redirect resources to a channel/static route
- support templates for channels
- ensure we still support static routes (e.g. /about/: home)
- ensure pagination + rss works out of the box
2018-06-24 02:06:58 +02:00
kirrg001
4ed10aa76a 🎨 Dynamic Routing Beta: Extended collection feature (limit, order, data)
refs #9601

- support data, limit and order for collections
- limit definition in routes.yaml is stronger than theme package.json limit configuration
- ensure we update hbs template options
2018-06-24 02:06:58 +02:00
kirrg001
51e6286924 Dynamic Routing Beta: Added redirect middleware to ParentRouter
refs #9601

- middleware to control dominant router redirects
2018-06-24 02:06:58 +02:00
kirrg001
1952c55d33 Dynamic Routing Beta: Added redirect helper to ParentRouter
refs #9601

- this function will help us to determine if a redirect should happen or not
2018-06-24 02:06:58 +02:00
kirrg001
935f064357 Dynamic Routing Beta: Added yaml validation for data key
refs #9601

- support short and long form of data key
- always return the expanded version (long) to the routers
2018-06-24 02:06:58 +02:00
Katharina Irrgang
5a61f99467
Dynamic Routing: Added migration for routes.yaml file (#9692)
refs #9601

- the home.hbs behaviour for the index collection (`/`) is hardcoded in Ghost
- we would like to migrate all existing routes.yaml files
- we only replace the file if the contents of the routes.yaml file equals the old routes.yaml format (with home.hbs as template)
- updated README of settings folder
- if we don't remove the home.hbs template from the default routes.yaml file, home.hbs will be rendered for any page of the index collection
  - the backwards compatible behaviour was different
  - only render home.hbs for page 1
- remember: the default routes.yaml file reflects how Ghost was working without dynamic routing
2018-06-22 20:28:01 +02:00
kirrg001
a1b55509df Dynamic Routing Beta: collection name behaviour
refs #9601

Example:

```
collections:
  /podcast/:
    permalink: /{slug}/
```

- the name of the collection is remembered as `routerName` (in the case above: "podcast")
- the name of the collection is important for two things
  1. context value
  2. template name
- the context value is available for specific theme helpers e.g. is helper, body_class helper
- we auto-lookup the collection name in your theme e.g. podcast.hbs
- this logic does not apply to static routes
- if you define templates on your collection, they are stronger than the collection name
2018-06-21 20:59:43 +02:00
kirrg001
0046dce39f Dynamic Routing Beta: Better template support
refs #9601

- single or multiple template definition
- possible formats:

```
routes:
  /about/: about
```

```
routes:
  /about/:
    template: about
```

```
routes:
  /about/:
    template:
      - about
      - me
```

```
collections
  /posts/:
    template:
      - posts
      - general
```

```
collections
  /posts/:
    template: posts
```
2018-06-21 16:22:45 +02:00
kirrg001
1a79aac673 Fixed collection ownership if a published post status changes to featured
refs #9601

- implementation of resource listener updated
- if you define two collections: `featured:true` (1) and `page:false` (2) you can run into the following bug:
  - you create a published post (owned by (2))
  - you change the status to featured
  - still owned by (2), because the filter still matches (it's still not a static page)
- this adaption fixes the behaviour
- less smart logic, but less error prone
2018-06-17 10:41:05 +02:00
kirrg001
87c01c131b 🐛 Fixed {{#is "index"}}
closes https://github.com/TryGhost/Ghost/issues/9674

- with dynamic routing the first collection get's the "index" context attached
- the index context signalises the main post listening route (first collection)
- this behaviour was present < 1.24 - we have to keep this behaviour
2018-06-14 11:53:13 +02:00
Katharina Irrgang
835fd6c45b
Removed knex mock (#9685)
no issue

- this mock eat already too much of my/our time
- the idea of adding a knex mock was definitely a failed approach/try
- it's too much to maintaince and have not found a module which does this already
  - we have to support any query format
  - this is too crazy
- the idea was to use the knex mock for model unit tests, because if we want to unit test models we have to
  run through bookshelf, because the whole model layer depends on bookshelf e.g. events
- for now we simply use the real database
  - we could use the sqlite3 memory mode, but that would mean every unit test runs on sqlite3
  - something to consider for later e.g. run unit tests on one matrix
  - run the rest on another matrix for sqlite + mysql
2018-06-12 20:26:16 +02:00
Katharina Irrgang
7b0d5d465b 🐛 Fixed preview url and Zapier on subdirectory (#9683)
closes #9675

- with dynamic routing we have introduced a breaking change, which we have overseen
- Ghost does not return absolute urls, that's why the clients need to concat the blog url and the resource url
- with 1.24.0 Ghost returned resource urls including the subdirectory
- this caused trouble for e.g. zapier or the preview feature in the admin client
- revert breaking change and ensure we only expose resource urls without subdirectory
2018-06-12 16:36:58 +01:00
kirrg001
f25f7ac54b 🐛 Fixed slug template for tags and authors
no issue

- was introduced with dynamic routing beta: https://github.com/TryGhost/Ghost/releases/tag/1.24.0
- the slug param wasn't forwarded correctly
- you were not able to render a custom tag or author template e.g. `tag-news.hbs`
2018-06-11 22:06:47 +02:00
kirrg001
e4807a779c 🐛 Fixed default theme context
closes #9674

- the collection router had a hardcoded default context "home"
  - this is wrong
- the context array get's automatically filled for the collection
  - if you are serving a page e.g. /page/2/ -> it's "paged"
  - if you are serving / -> it's "home"
    - same for {{body_class}}, it outputs "home-template" on "/"
    - this is the same behaviour as in 1.23.x
2018-06-08 15:11:47 +02:00
kirrg001
2d70b8fe20 🐛 Fixed template order not being respected after refresh
no issue

- reverse must happen once in the constructor
- otherwise we reverse the array on each request
  - Ghost would randomly pick the first and then the second template
2018-06-08 15:11:43 +02:00
kirrg001
839d82b398 🐛 Fixed post redirect with query params
no issue

- reported here: https://forum.ghost.org/t/best-practice-for-appending-a-query-string-to-a-post/1535
- there was a bug that query params were not respected and this ended in a 301 redirect losing them
2018-06-07 09:52:51 +02:00
kirrg001
3155ea2aa7 🐛 Fixed urls being /404/ after starting the Ghost server
no issue

- there was a timing bug in Ghost
- we do operations in parallel on bootstrap
  - 1) we fetch the resources as early as possible
  - 2) we do all the rest (express bootstrapping, theme loading, router registration) etc.
- it can happen that (2) happens too slow and ends in the situation that the queue, which is responsible
  to handle both parallel actions, does not wait for the routers and closes the event
- this is a short term fix
- i need to reconsider if there is a better long term fix
2018-06-07 09:27:24 +02:00
Katharina Irrgang
b392d1925a
Dynamic Routing Beta (#9596)
refs #9601

### Dynamic Routing

This is the beta version of dynamic routing. 

- we had a initial implementation of "channels" available in the codebase
- we have removed and moved this implementation 
- there is now a centralised place for dynamic routing - server/services/routing
- each routing component is represented by a router type e.g. collections, routes, static pages, taxonomies, rss, preview of posts
- keep as much as possible logic of routing helpers, middlewares and controllers
- ensure test coverage
- connect all the things together
  - yaml file + validation
  - routing + routers
  - url service
  - sitemaps
  - url access
- deeper implementation of yaml validations
  - e.g. hard require slashes
- ensure routing hierarchy/order
  - e.g. you enable the subscriber app
  - you have a custom static page, which lives under the same slug /subscribe
  - static pages are stronger than apps
  - e.g. the first collection owns the post it has filtered
  - a post cannot live in two collections
- ensure apps are still working and hook into the routers layer (or better said: and register in the routing service)
- put as much as possible comments to the code base for better understanding
- ensure a clean debug log
- ensure we can unmount routes
  - e.g. you have a collection permalink of /:slug/ represented by {globals.permalink}
  - and you change the permalink in the admin to dated permalink
  - the express route get's refreshed from /:slug/ to /:year/:month/:day/:slug/
  - unmount without server restart, yey
- ensure we are backwards compatible
  - e.g. render home.hbs for collection index if collection route is /
  - ensure you can access your configured permalink from the settings table with {globals.permalink}

### Render 503 if url service did not finish

- return 503 if the url service has not finished generating the resource urls

### Rewrite sitemaps

- we have rewritten the sitemaps "service", because the url generator does no longer happen on runtime
- we generate all urls on bootstrap
- the sitemaps service will consume created resource and router urls
- these urls will be shown on the xml pages
- we listen on url events
- we listen on router events
- we no longer have to fetch the resources, which is nice
  - the urlservice pre-fetches resources and emits their urls
- the urlservice is the only component who knows which urls are valid
- i made some ES6 adaptions
- we keep the caching logic -> only regenerate xml if there is a change
- updated tests
- checked test coverage (100%)

### Re-work usage of Url utility

- replace all usages of `urlService.utils.urlFor` by `urlService.getByResourceId`
  - only for resources e.g. post, author, tag
- this is important, because with dynamic routing we no longer create static urls based on the settings permalink on runtime
- adapt url utility
- adapt tests
2018-06-05 19:02:20 +02:00
kirrg001
0ccc24bf11 Removed old jshint/jscs rules
refs bcf5a1bc34

- leftovers
2018-06-02 21:48:23 +02:00
kirrg001
dd668892d7 Removed more 'use strict' usages
no issue

- after we have dropped node 4, we have removed all 'use strict' usages
- but they came back from older pull requests
2018-06-02 21:38:11 +02:00
Kevin Ansfield
6c1e5511fc 🐛 Fixed infinite redirect when subdirectory equals top level domain (#9621)
closes https://github.com/TryGhost/Ghost/issues/9620

- adjust the `deduplicateSubDir` function's regex to only match duplicate subdirectories when the `url` is only a path rather than full url or the duplicate match starts with a `/`
2018-05-28 12:18:34 +02:00
Aileen Nowak
6e117e63fb 🐛 Fixed gscan errors not caught for corrupted zips
closes TryGhost/Support#426
refs TryGhost/gscan#106
needs TryGhost/gscan#107

GScan can return errors, which was not handled in our theme validator and caused Ghost to crash completely. GScan will now return an Ignition error when its not able to read the `.zip` file.

e. g.: `{"errors":[{"message":"Failed to read zip file","context":"tife.zip","errorType":"ValidationError","errorDetails":"invalid relative path: ../tife/"}]}`
2018-05-16 10:20:30 +08:00
kirrg001
5f5f0021db 🔥 Drop Node v4 Support
no issue

- support ends today
- see https://github.com/nodejs/Release
- removed `use strict`
2018-05-01 14:06:18 +02:00
kirrg001
ab5199267b Renamed urlService.getUrl to urlService.getUrlByResourceId
no issue

- explicit function naming
- no functional change, only renaming
2018-04-25 19:37:39 +02:00
kirrg001
6ac00255e3 Renamed resources to taxonomies in default routes yaml file
refs https://github.com/TryGhost/Team/issues/65

- this was incorrect
- we don't use the wording `resources` in the routes yaml file
2018-04-21 01:17:52 +02:00
kirrg001
0ac19dcf84 Load yaml settings files synchronously
refs https://github.com/TryGhost/Team/issues/65

- it's easier for the architecture if we read the setting files synchronously,
  because the dynamic routing component is part of the express bootstrap and
  the whole routing bootstrap is synchronously
- for now: we only read one file anyway
- it's for now easier to read the file synchronously, then i don't have to change
  any existing express bootstrap architecture
2018-04-20 15:25:06 +02:00
kirrg001
097e1d1fac Url Service: trigger url event with relative/absolute urls
refs https://github.com/TryGhost/Team/issues/65

- this is just the first optimisation regarding relative/absolute urls
- the full strike will happen when i start with the url utility re-write
- for now: there will be only one subscriber of url events -> the sitemaps service
- the sitemaps service outputs absolute urls
  - we don't want to receive an url event and ask the url service again to get an absolute version of the url
2018-04-18 11:33:46 +02:00
kirrg001
79c790c891 Fixed url service did not respect subdirectory setup's
refs https://github.com/TryGhost/Team/issues/65

- currently we generate a relative resource url
- if you configure a subdirectory, the urls have to respect that
  - e.g. you configure `localhost:2368/blog`, your url results in e.g. `/blog/my-post/`
- this is not yet a critical bug, because the url service is not connected yet

- @TODO: consider absolute vs. relative urls in the url service
2018-04-17 15:52:57 +02:00
Katharina Irrgang
6a4af1f465
Rewrite url service (#9550)
refs https://github.com/TryGhost/Team/issues/65

We are currently work on dynamic routing (aka channels).
An important piece of this feature is the url service, which always knows the url of a resource at any time.
Resources can belong to collections or taxonomies, which can be defined in a [routing yaml file](https://github.com/TryGhost/Ghost/issues/9528). We are currently shipping portions, which will at end form the full dynamic routing feature.

### Key Notes

- each routing type (collections, taxonomies, static pages) is registered in order - depending on the yaml routes file configuration
- static pages are an internal concept - they sit at the end of the subscriber queue
- we make use of a temporary [`Channels2`](https://github.com/TryGhost/Ghost/pull/9550/files#diff-9e7251409844521470c9829013cd1563) file, which simulates the current static routing in Ghost (this file will be modified, removed or whatever - this is one of the next steps)
- two way binding: you can ask for a resource url based on the resource id, you can ask for the resource based on the url
- in theory it's possible that multiple resources generate the same url: we don't handle this with collision (because this is error prone), we handle this with the order of serving content. if you ask the service for a resource, which lives behind e.g. /test/, you will get the resource which is served
- loose error handling -> log errors and handle instead of throw error and do nothing (we log the errors with a specific code, so we can react in case there is a bug)
- the url services fetches all resources on bootstrap. we only fetch and keep a reduced set of attributes (basically the main body of a resource)
- the bootstrap time will decrease a very little (depending on the amount of resources you have in your database)
- we still offer the option to disable url preloading (in your config `disableUrlPreload: true`) - this option will be removed as soon as the url service is connected. You can disable the service in case you encounter a problem
- **the url service is not yet connected, we will connect the service step by step. The first version should be released to pre-catch bugs. The next version will add 503 handling if the url service is not ready and it will consume urls for resources.**


----

- the url service generates urls based on resources (posts, pages, users, tags)
- the url service keeps track of resource changes
- the url service keeps track of resource removal/insert
- the architecture:
  - each routing type is represented by a url generator
    - a routing type is a collection, a taxonomiy or static pages
  - a queue which ensures that urls are unique and can be owned by one url generator
    - the hierarchy of registration defines that
  - we query knex, because bookshelf is too slow
- removed old url service files + logic
- added temp channels alternative (Channels2) -> this file will look different soon, it's for now the temporary connector to the url service. Also the name of the file is not optimal, but that is not really important right now.
2018-04-17 11:29:04 +02:00
Aileen Nowak
63642fd8ad YAML settings loader and parser
closes #9528

These code changes introduce a YAML parser which will load and parse YAML files from the `/content/settings` directory. There are three major parts involved:

1. `ensure-settings.js`: this fn takes care that on bootstrap, the supported files are present in the `/content/settings` directory. If the files are not present, they get copied back from our default files. The default files to copy from are located in `core/server/services/settings`.

2. `loader.js`: the settings loader reads the requested `yaml` file from the disk and passes it to the yaml parser, which returns a `json` object of the file. The settings loader throws an error, if the file is not accessible, e. g. because of permission errors.

3. `yaml-parser`: gets passed a `yaml` file and returns a `json` object. If the file is not parseable, it returns a clear error that contains the information, what and where the parsing error occurred (e. g. line number and reason).

- added a `get()` fn to settings services, that returns the settings object that's asked for. e. g. `settings.get('routes').then(()...` will return the `routes` settings.
- added a `getAll()` fn to settings services, that returns all available settings in an object. The object looks like: `{routes: {routes: {}, collections: {}, resources: {}}, globals: {value: {}}`, assuming that we have to supported settings `routes` and `globals`.

Further additions:
- config `contentPath` for `settings`
- config overrides for default `yaml` files location in `/core/server/services/settings`

**Important**: These code changes are in preparation for Dynamic Routing and not yet used. The process of copying the supported `yaml` files (in this first step, the `routes.yaml` file) is not yet activated.
2018-04-15 19:40:22 +02: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
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
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
Katharina Irrgang
a5af7d6384 Used request lib in xmlrpc (#9333)
refs #9178, refs https://github.com/TryGhost/Ghost/pull/8980
2017-12-15 16:50:18 +07:00
kirrg001
991ccb1d35 Moved make-absolute-urls to url service
refs #9178

- this util uses the url services (!)
- moving this file into lib would not make sense right now
  - that would mean a module requires first ../lib/url, which then requires ../services/url
- the url service definitely need a clean up 😃
2017-12-14 22:34:37 +01:00
kirrg001
64626dedd1 Moved social utility to lib/social
refs #9178

- not 100% sure about this, but i think it makes right now the most sense
- we have already a url service and creating another lib/url is confusing at the moment
- i'll copy the last utility `makeAbsoluteUrls` to the url service for now
- see next commit for explanation (!)
2017-12-14 22:34:05 +01:00
kirrg001
1a9a10c82b Moved zip folder, read csv and package-json to lib/fs
refs #9178, refs 849e97640f

- i've reconsidered, these modules belong to lib
- prettify package-json module
2017-12-14 22:07:53 +01:00
kirrg001
849e97640f Moved zip folder utility to services/themes
refs #9178

- it's only used for themes currently
- this is definitely a util which could be useful lib
- if we have a second use case, we can move it
2017-12-14 21:02:47 +01:00
Katharina Irrgang
18e15934fd Used request lib in slack service (#9335)
refs #9178

- tested with slack
2017-12-14 22:08:48 +07:00
Katharina Irrgang
50b65bca0c Moved default-cards app to lib/mobiledoc (#9341)
refs #9178, refs https://github.com/TryGhost/Ghost/pull/9338
2017-12-14 14:44:01 +00:00
kirrg001
a3091a3012 Moved utils constants to lib/constants
refs #9178
2017-12-14 14:13:40 +01:00
kirrg001
c5169e23c4 Moved unique identifier generation to lib/security
refs #9178
2017-12-14 13:52:20 +01:00
Katharina Irrgang
192ebb1739
Moved labs, auth, permissions, settings, mail, themes to services (#9339)
refs #9178

- move tests as well
2017-12-14 03:01:23 +01:00
kirrg001
6f6c8f4521 Import lib/common only
refs #9178

- avoid importing 4 modules (logging, errors, events and i18n)
- simply require common in each file
2017-12-12 10:28:13 +01:00
kirrg001
ac2578b419 Moved errors,logging,i18n and events to lib/common
refs #9178
2017-12-12 10:28:13 +01:00
kirrg001
4265afe580 Moved utils/url.js to UrlService
refs #9178

- we have to take care that we don't end up in circular dependencies
  - e.g. API requires UrlService and UrlService needs to require the API (for requesting data)
- update the references
- we would like to get rid of the utils folder, this is/was the most complicated change
2017-12-11 20:05:33 +01:00
Katharina Irrgang
b4b5da2a75
Bump sinon to version 4.1.2 (#9283)
refs #9178

- adapt major changes
2017-11-28 18:19:23 +01:00