refs #10932
Previously we were only applying the cors middleware to the options
preflight request, which meant that if the request errored, the cors
headers would not be applied, resulting in the client being unable to
read response data. This applies the cors middleware to _all_ requests
to the Admin API.
closes#10932
Previously we were only applying the cors middleware to the options
preflight request, which meant that if the request errored, the cors
headers would not be applied, resulting in the client being unable to
read response data. This applies the cors middleware to _all_ requests
to the Content API.
* Installed @tryghost/members-ssr@0.2.1
refs https://github.com/TryGhost/Members/issues/38
This updates allows for dynamic access of the membersApi, which will be
used in future when replacing the membersApi instance with a newly
configured one.
* Set the membersApiInstance logger to use common.logging
refs https://github.com/TryGhost/Members/issues/38
Passes the Ghost logger to the members api, so that we can keep an eye
on errors produced by the api.
* Refactored memberService use to always use getter
refs https://github.com/TryGhost/Members/issues/38
This will allow us to switch out the membersApi and the consumers of it
to have the updated reference by going through a getter.
* Installed @tryghost/members-api@0.3.0
refs https://github.com/TryGhost/Members/issues/38
Adds support for setting the logger
* Uninstalled stripe@7.0.0
refs https://github.com/TryGhost/Members/issues/38
The stripe module is now a dep of members-api, as it should be
* Updated members service to reconfigure settings
refs https://github.com/TryGhost/Members/issues/38
Previously we were unable to stop an invalidly configured members api
instance, now that we create a new instance, we can wait for the ready
or error event and only switch it out then.
* Installed @tryghost/members-api@0.2.0
refs #10886
This will allow us to mount one router rather than having a static and
api router.
* Added members v2 api directory
refs #10886
This brings the members api more inline with how the rest of the apis
work within Ghost.
* Mounted the members api app to the api route
closes#10886
This successfully mounts the api and the static pages to the
/api/v2/members/ URL.
* Installed @tryghost/members-auth-pages@1.0.0
refs #10886
This updates the auth pages to work correctly with the new mount point.
* Changed membersUrl in members.js to use members api
refs #10886
This keeps the membersUrl lined up with the path for the static
members pages.
* Removed old members static mount point
refs #10886
These are no longer used, nor desired.
* Remove superfluous code from members service
refs #10886
This remove the gateway getter which is no longer used, and the fallback
for members not enabled - which is handled within the members app.
* Updated ssoOrigin to use admin url
refs #10886
This ensures that sites running on a separate admin domain have the
correct ssoOrigin, which is used to ensure only the designated auth
pages are used to hit the authentication endpoints.
Since the auth pages are now hosted under the `/ghost` url, they will be
on the admin origin and not the site origin
- allow both uploading and activating themes as experiemental API features
- previously only uploading was allowed, I believe purely due to an oversight
closes#10773
- The refactoring is a substitute for `urlService.utils` used previously throughout the codebase and now extracted into the separate module in Ghost-SDK
- Added url-utils stubbing utility for test suites
- Some tests had to be refactored to avoid double mocks (when url's are being reset inside of rested 'describe' groups)
no issue
- Added new API to delete members
- Added methods to handle e2e member deletion
- Deleting member via Admin leads to
- Removal of member from payment processor and cancelling all active subscriptions immediately
- Removal of member information from DB
no issue
- was unable to revert 9dd7aff9c6, because it contains members changes
- functional calls did not work correctly, because the content and admin ctrl differentiation happend in the web layer
- `isContentAPI` returned true for `api.v2.settings.edit(data, {context: {internal:true{})`
- content & admin API are using different controllers
- we can just tell which ctrl is content API and which is not
- the direction fits for the content & admin API split
refs #10438, refs #10106
* Renamed existing pages ctrl
* Splitted posts & pages for Admin API v2
* Added pages JSON input schema for Admin API v2
* Removed single author for Content & Admin API v2
- single author is not documented
- single author usage is deprecated in v0.1
- single author usage is removed in API v2
* Splitted posts & postsPublic controller for v2
* Removed requirement to send `status=all` from Admin API v2
* Removed `status` option from pages Content API v2
* Removed `status` options from Users Admin API v2
refs #10438
- make /images/ available
- we want to document this endpoint notiation, because it is more specific and fits better, because you can only upload images
- either we drop /uploads/ by the end of the project cycle or we keep both for now
- the Admin API v2 is currently undocumented and allows breaking changes in theory
closes#10174
- Introduced upload middleware that cleans up temporary files stored by mutler after the request is finished
- Removed redundant fs.remove calls as this work is now handled in newly introduced middleware
refs #9865
- Added `auth.authenticate.authenticateAdminApiKey` middleware
- accepts signed JWT in an `Authorization: Ghost [token]` header
- sets `req.api_key` if the token is valid
- Updated `authenticatePrivate` middleware stack for v2 admin routes
* Revert "Removed brute force middleware form content api (#10353)"
This reverts commit 63c8c310fb.
* Updated content api spam prevention to use memory store
* Used TooManyRequestsError instead of InternalServer
* Added spam config for content api key
no-issue
* Created contentApiKey spam prevention method
* Added contentApiKey brute middleware
no-issue
This middleware attaches a listener for when the request has completed,
if the request ends with a successful response code, we reset any spam
prevention data for that ip.
* Added contentApiKey brute middleware to the content api
* Multipled maxWait by 24, to 24 hours
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
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
* 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
no-issue
When trying to use /api/v2/content from a different domain, the requests
were failing with CORS errors. This doesn't use the shared cors middleware,
because it should be open to all hosts, and not locked down via our
whitelist or trusted domains.
closes#10226
- Middleware emits site-changed event used to trigger webhook, was configured to v2 admin api only.
- Change allows all versions of api to emit event in case of cache invalidation
* Added updateLastSeen method to user model
refs #10138
* Refactor codebase to use user.updateLastSeen
refs #10138
This is to ensure all updates go via the same method, meaning any
specific logic can be handled in one place, it also helps with grepping
the codebase to find where this occurs
* Created updateUserLastSeen middleware for v2 admin
refs #10138
This is intended to be used with the v2 admin api and _possibly_ the
content api, to give us an accruate report on thelast time a user access
a ghost instance.
* Wired updateUserLastSeen up to v2 Admin API
closes#10138
* Fixed broken test for v2 admin api
no-issue
This test was broken because it was incorrectly testing for a method to
be called exactly once - this was irrelevant to the functionality being
tested for.
* Updated user check method to set status to active
no-issue
* Debounced the updateUserLastSeen middlware an hour
no-issue
* Resolved some PR comments
no-issue
This is because the Content API will eventually be accessed not just
from Content API keys. The addition of a Content API specific
authorization middleware is because:
1. content api should not authorize based on req.user
2. content api will need separate authorization than admin api
no issue
- webhooks UI requires the ability to edit webhooks
- added `edit` permission for `webhook`
- added `edit` method to v2 webhook controller
- added `PUT /webhooks/:id` route to v2 Admin API routes
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
refs #9865
* Added generic messaging for resource not found
* Ensured integration model uses transaction for writes
* Created POST /integrations endpoint
* Created GET /integrations/:id endpoint
* Created GET /integrations endpoint
* Created PUT /integrations/:id endpoint
* Created DELETE /integrations/:id endpoint
no-issue
- Added spam prevention to POST /session
- This blocks repeated requests the the /session endpoint preventing brute
force password attacks
- Updated session controller to reset brute middleware
- This updates the session controller to reset the brute force protection
on a successful login. This is required so that a user is not locked out
forever :o!!
no-issue
The content API only supports GET requests so has no need for cors
middleware on OPTIONS. This also removes the router.del helper as it's
not used
* 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
refs #9866
- Added logic ensuring page filter is always set to false in posts endpoint for Content API
- Added functional tests to pages and posts
- Added absolute_url logic in pages controller
- Added slugs controller to v2 API
- Added slugs tests to v2 API
- Updated generic validation error message in shared validator to return validation error with sub-message
* Added admin specific auth{enticate,orize} middleware
refs #9865
This middleware will be used by the admin api to authenticate and
authorize requests
* Update v2/admin to use authAdminApi middleware
refs #9865
This changes thh auth middleware to use the adminApi authenticate and
authorize middlewares underneath, it also renames the middleware to be
consistent with the naming of the api.
* Removed oauth specific endpoints from /v2/admin
refs #9865
These are not to be used in v2/admin
* Wired up the session controller to the admin api
refs #9865
These endpoints will be used by ghost admin to login, confirm logged in status and logout
refs #9326, refs #9866
**ATTENTION: This is the first iteration. Bugs are expected.**
Main Goals:
- add support for multiple API versions.
- do not touch v0.1 implementation
- do not break v0.1
## Problems with the existing v0.1 implementation
1. It tried to be generic and helpful, but it was a mixture of generic and explicit logic living in basically two files: utils.js and index.js.
2. Supporting multiple api versions means, you want to have as less as possible code per API version. With v0.1 it is impossible to reduce the API controller implementation.
----
This commit adds three things:
1. The tiny framework with well-defined API stages.
2. An example implementation of serving static pages via /pages for the content v2 API.
3. Unit tests to prove that the API framework works in general.
## API Stages
- validation
- input serialization
- permissions
- query
- output serialization
Each request should go through these stages. It is possible to disable stages, but it's not recommended.
The code for each stage will either live in a shared folder or in the API version itself. It depends how API specific the validation or serialization is. Depends on the use case.
We should add a specific API validator or serializer if the use case is API format specific.
We should put everything else to shared.
The goal is to add as much as possible into the shared API layer to reduce the logic per API version.
---
Serializers and validators can be added:
- for each request
- for specific controllers
- for specific actions
---
There is room for improvements/extensions:
1. Remove http header configuration from the API controller, because the API controller should not know about http - decouple.
2. Put permissions helpers into shared. I've just extracted and capsulated the permissions helpers into a single file for now. It had no priority. The focus was on the framework itself.
etc.
---
You can find more information about it in the API README.md (api/README.md)
- e.g. find more information about the structure
- e.g. example controllers
The docs are not perfect. We will improve the docs in the next two weeks.
---
Upcoming tasks:
- prepare test env to test multiple API versions
- copy over the controllers from v0.1 to v2
- adapt the v2 express app to use the v2 controllers
no issue
- optimised only for web/ folder, because it has used very general namespaces
- the debug namespace must be specific, otherwise i run `DEBUG=ghost:api:*` and i get web debug logs and api folder debug logs
- we can come up with a new namespace system, but for now it must be explicit enough
refs #9866
- req.body is undefined if we don't use the body parser
- the content API only offers "fetch" endpoints, but if a component/module in Ghost relies on req.body being present, it can crash
- e.g. the authentication service checks for the existence of client_id + client_secret in req.query or req.body
- we could theoretically change it from `if (!req.body.client_id` to `if (req.body && !req.body.client_id)`, but that makes the code very hard to read + maintain
- we will use the body parser for the content API now
- req.body will be {}
refs #8576
- adds new API endpoint `/uploads/profile-image` for uploading profile images
- new validation which fails with error message if uploaded image is not square
- Renamed getImageSizeFromFilePath to getImageSizeFromStoragePath, because it's more explicit
- Add new getImageSizeFromPath method, which is used in the new dimensions middleware
- Ensure we use the sharp middleware to auto-resize the uploaded profile pictures
- Ensure the new route get's added to v2
While this makes sure all future profile images uploaded are square, this doesn’t affect any existing non-square profile image. Needs more thought on how to handle existing non-square profile images for the purpose of making theming easier in future.
refs #9866
- Removed `res.isAdmin` flag in v2 express app
- Did not touch v0.1 express app
- Separated url redirect middleware for admin and content API
refs #9866
- Registered Content API under /ghost/api/v2/content/
- Registered Admin API under /ghost/api/v2/admin/
- Moved API v0.1 implementation to web/api/v0.1
- Created web/api/v2 for the new api endpoints
- Started with reducing the implementation for the new Content API (the Content api does not serve admin api endpoints, that's why it was reducible)
- Covered parent-app module with basic test checking correct applications/routes are being mounted
- Added a readme file, which contains a warning using v2, because it's under active development!
- This PR does only make the new endpoints available, we have not:
- optimised the web folder (e.g. res.isAdmin)
- started with different API controllers
- reason: we want to do more preparation tasks before we copy the api controllers
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`.
refs #4453
* On by default
* Added config to disable resizing
* Added basic image optimization processing
* Added dep: sharp (optional dep)
* Added resize middleware
* Take care of rotation based on EXIF information
* Removed all meta data from optimised image
* Added handling if sharp could not get installed
* Do not read ext twice - optimisation
* Do not call sharp if config is disabled
* Do not remove the original image which was uploaded (store 2 images)
* Support of `req.files` for internal logic
* Disabled cache to enable file removal on Windows
refs #9744
- added two new endpoints to upload/download routes.yaml
- reload site express app on successful/valid upload
- reload url service on sucessfuly upload
- force clear cache of pages
- ensure we keep a backup of the routes.yaml file
- this feature was mostly tested manually
- @TODO: i have to write unit tests - will do later
- @TODO: do a memory test to ensure we haven't introduced any memory leaks with this feature
refs https://github.com/TryGhost/Ghost/issues/9623
- add `oembed-parser` module for checking provider availability for a url and fetching data from the provider
- require it in the `overrides.js` file before the general Promise override so that the `promise-wrt` sub-dependency doesn't attempt to extend the Bluebird promise implementation
- add `/oembed` authenticated endpoint
- takes `?url=` query parameter to match against known providers
- adds safeguard against oembed-parser's providers list not recognising http+https and www+non-www
- responds with `ValidationError` if no provider is found
- responds with oembed response from matched provider's oembed endpoint if match is found
refs #9178
- move express apps to one place (called `web`)
- requires https://github.com/TryGhost/Ghost-Admin/pull/923
- any further improvements are not part of this PR
- this PR just moves the files and ensures the paths are up-to-date