refs #10790
- Moved /core/apps into core/frontend
- Moved /core/server/helpers to /core/frontend/helpers along with /core/server/services/themes
- Changed helper location in overrides
- Moved /core/server/services/routing to /core/frontend/services
- Moved /core/server/services/url to /core/frontend/services
- Moved /core/server/data/meta to /core/frontend/meta
- Moved /core/server/services/rss to /core/frontend/services
- Moved /core/server/data/xml to /core/frontend/services
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)
closes#10776
When the "to" property of the redirect includes a host (implying an external or fully qualified url) we skip replacing any paths and redirect straight to it, rather than modifying the URL with the sites sub-directory.
refs #10618
- Visibility methods don't belong on model, but are generic utils
- Used directly from ghost helper's visibility methods, cleans up core
- Removes direct model dependency of theme helper
- Updated `foreach_spec` to correct test data as per schema - visibility property cannot be empty
no issue
- `{{#get}}` can slow down requests a lot if not used carefully, typically by using `limit="all"` or similar which can force a lot of data to be fetched and processed
- adds a warning log if we detect any `{{#get}}` helper call which takes longer than a certain threshold (default 200ms)
- allow log level and threshold to be configured via config to allow for different environments behaviours and requirements
New config options:
```
{
"logging": {
"slowHelper": {
"level": "warn",
"threshold": 200
}
}
}
```
Example output for `{{#get "tags" limit="all" order="name asc"}}` with a lot of tags:
```
[2019-06-07 10:35:52] WARN {{#get}} helper took 453ms to complete
{{#get}} helper took 453ms to complete
Error ID:
062daed0-8910-11e9-8185-3b615ad8677d
Error Code:
SLOW_GET_HELPER
Details:
api: v2.tagsPublic.browse
apiOptions:
order: name asc
limit: all
returnedRows: 1698
```
refs https://github.com/TryGhost/Ghost/issues/9414
refs c9b95b4bbd
- Removed package version from asset hash calculation
- Package version doesn't introduce any value when calculating a hash because Date.now() provides enough randomization on its own
no issue
- by default the `/ghost/` route will add an `x-frame-options: sameorigin` header to the response to help protect the admin area against clickjacking
- the header can be disabled by adding `"adminFrameProtection": false` to the `config.{env}.json` configuration file
Credits: Muhammad Fawwad Obaida
refs https://github.com/TryGhost/Team/issues/211
Previous code was creating a new ajv instance for each call, as well as
loading the schemas, which are cached. This was causing a memory leak as
ajv caches all schemas.
We've replaced it with one instance of ajv, and conditionally
loading/compiling the schemas if they haven't been seen before.
* Installed `@tryghost/members-{api,auth-pages}`
no-issue
* Used @tryghost/members-auth-pages in member service
no-issue
* Used @tryghost/members-api in members service
no-issue
* Deleted core/server/lib/members
no-issue
* Fixed parent app tests
no-issue
Requiring the members api (via the `gateway` getter) was throwing an
error, so we stub out the members service getters
closes#10709
- Only transform a canonical URL that is identical with the Blog URL to a relative URL when the protocol matches as well
- Leave the canonical URL absolute for all other cases
- Use case for this is e. g. when users want to port over their Facebook comments/shares/likes after a move from `http` to `https`
closes#10706
- Fixed a bug where we weren't assigning `summary_large_image` as Twitter card property when no feature image is provided, but a dedicated Twitter image
- Updated test to reflect this case to be tested better
no issue
- case: restart Ghost and while having a scheduled post
- caused by 4acc375fb6 (diff-4726ce3c4d18d41afad4b46cb0aa7dd3)
- the bug exists since 2.12
- Bookshelf added support (or better said fixed a bug) for accessing previous attributes
- `object.updated('published_at')` always returned "undefined", because the self-implementation < 2.12 only remembered previous attributes after update (see https://github.com/TryGhost/Ghost/blob/2.11.0/core/server/models/base/index.js#L234)
- but `object.previous('published_at')` returns the current value (object.get('published_at') === object.previous('published_at') -> and that's why rescheduling on bootstrap never worked
- might fix https://forum.ghost.org/t/scheduled-posts-never-publish/6873/10
- reduced timeouts on scheduling unit tests
no-issue
It turned out that due to the mismatch between `"members"` and
`"member"`, that not a single row was added to the database via this
migration. Clearing the file for simplicity.
no-issue
The original migration read data from the fixtures, and ensured the
relations were made. Now the fixtures have been corrected, we can use
the same migration for 2.22
no-issue
The previous relations were setup to match against "members", which is
plural, but the object_type on the permission is "member". This was
causing the permissions to not be added as a relation to the role.
* Added caption support to code card renderer
refs https://github.com/TryGhost/Ghost-Admin/pull/1181
- when a caption for a code card is provided, render the contents inside a `<figure>` element with a `<figcaption class="kg-card kg-code-card">` to match other caption-enabled cards
no-issue
Plans are distinct from subscriptions, as in theory a subscription could
have many plans. These moves the construction of the plans array into
the getMember function so that every consumer has access to the same
data.
no-issue
This file is copied across on install, making it easy to update via
package.json, tbh we could not commit it to the repo - but it makes
sense to be able to see it when browing the file explorer. Any bumps in
package.json will update the file, so that it is prompted to be
commited.
no-issue
The current public file middleware handles route matching itself, which
means it is applied to express via the use method. Due to use being a
"global" application of middleware, this means it is not possible to
apply a labs middleware before the public file serving middleware
without it affecting the entire route stack.
This commit exports a piece of raw middleware that can be used with the
get method of express, so that we can attach middleware beforehand.
This will be used to conditionally serve the members specific public
files, based on the labs flag for members.
refs #10571
- Removes dependency on 'context' property being set in error when
checking a theme
- Refactoring was needed to be able to avoid passing checked theme as a
part of thrown error (logic was relying on error having this specific
data in context property). This created a problem where we controlled
the logic flow with data in error object.
- Introduced 2 different types of theme check handling, one behaves the
same way as before, the other gives more granulac control to the caller
to decide what to do with returned errors.
refs #9589
* updated encode helper to use newer code standards
* updated facebook_url helper to use newer code standards
* updated foreach helper to use newer code standards
closes#10649
- `resourceType` in API v0.1 is only of 'post' type. Because in admin we now distinguish between 2 types of editable resources: 'posts' and 'page' the redirect has to be based on 'entry.page' flag
refs #10656
- To make sure more users see important updates or announcements
notification dismissal now works per user instead of globally
- Expanded acceptance test for notification deletion
- Expanded regression test covering multiuser dismissal of notification
- Added clarifying comment about destroyAll method use in API
* Members: disabled signup button during signup
* Members: disabled non-Stripe signup button during signup
* Members: added check to Log in button logged in state
no issue
### Context
As part of updating the theme layer to use members-ssr [here](f9899cb8c4), we introduced a case where if `enableDeveloperExperiments` is not switched on, the whole theme loading will crash due to unavailability of `ssr` property on members service [here](https://github.com/TryGhost/Ghost/blob/master/core/server/services/members/index.js#L12). Since we switch on `enableDeveloperExperiments` by default on master now, the issue won't be reproducible locally until explicitly switched off.
This PR includes a patch fix which adds dummy `ssr` object to members service `api` object and members middleware check on APIs to ensure no crash in case developer flags is not switched on.
Longer term it will be definitely useful to upgrade the dummy `api` object to trigger on member labs than the developer flag.
* Updated close animation speed for members pages
* Updated responsive styles for members mobile screens
* Adding spinner CSS to members pages
* Adding members signup complete page
* Removed support for cookies in members auth middleware
no-issue
The members middleware will no longer be supporting cookies, the cookie
will be handled by a new middleware specific for serverside rendering,
more informations can be found here:
https://paper.dropbox.com/doc/Members-Auth-II-4WP4vF6coMqDYbSMIajo5
* Removed members auth middleware from site app
no-issue
The site app no longer needs the members auth middleware as it doesn't
support cookies, and will be replaced by ssr specific middleware.
https://paper.dropbox.com/doc/Members-Auth-II-4WP4vF6coMqDYbSMIajo5
* Added comment for session_secret setting
no-issue
We are going to have multiple concepts of sessions, so adding a comment
here to be specific that this is for the Ghost Admin client
* Added theme_session_secret setting dynamic default
no-issue
Sessions for the theme layer will be signed, so we generate a random hex
string to use as a signing key
* Added getPublicConfig method
* Replaced export of httpHandler with POJO apiInstance
no-issue
This is mainly to reduce the public api, so it's easier to document.
* Renamed memberUserObject -> members
no-issue
Simplifies the interface, and is more inline with what we would want to export as an api library.
* Removed use of require options inside members
no-issue
This was too tight of a coupling between Ghost and Members
* Simplified apiInstance definition
no-issue
* Added getMember method to members api
* Added MembersSSR instance to members service
* Wired up routes for members ssr
* Updated members auth middleware to use getPublicConfig
* Removed publicKey static export from members service
* Used real session secret
no-issue
* Added DELETE /members/ssr handler
no-issue
This allows users to log out of the theme layer
* Fixed missing code property
no-issue
Ignition uses the statusCode property to forward status codes to call sites
* Removed superfluous error middleware
no-issue
Before we used generic JWT middleware which would reject, now the
middleware catches it's own error and doesn't error, thus this
middleware is unecessary.
* Removed console.logs
no-issue
* Updated token expirty to hardcoded 20 minutes
no-issue
This returns to our previous state of using short lived tokens, both for
security and simplicity.
* Removed hardcoded default member settings
no-issue
This is no longer needed, as defaults are in default-settings.json
* Removed stripe from default payment processor
no-issue
* Exported `getSiteUrl` method from url utils
no-issue
This keeps inline with newer naming conventions
* Updated how audience access control works
no-issue
Rather than being passed a function, members api now receives an object
which describes which origins have access to which audiences, and how
long those tokens should be allowed to work for. It also allows syntax
for default tokens where audience === origin requesting it. This can be
set to undefined or null to disable this functionality.
{
"http://site.com": {
"http://site.com": {
tokenLength: '5m'
},
"http://othersite.com": {
tokenLength: '1h'
}
},
"*": {
tokenLength: '30m'
}
}
* Updated members service to use access control feature
no-issue
This also cleans up a lot of unecessary variable definitions, and some
other minor cleanups.
* Added status code to auth pages html response
no-issue
This was missing, probably default but better to be explicit
* Updated gateway to have membersApiUrl from config
no-issue
Previously we were parsing the url, this was not very safe as we can
have Ghost hosted on a subdomain, and this would have failed.
* Added issuer to public config for members
no-issue
This can be used to request SSR tokens in the client
* Fixed path for gateway bundle
no-issue
* Updated settings model tests
no-issue
* Revert "Removed stripe from default payment processor"
This reverts commit 1d88d9b6d73a10091070bcc1b7f5779d071c7845.
* Revert "Removed hardcoded default member settings"
This reverts commit 9d899048ba7d4b272b9ac65a95a52af66b30914a.
* Installed @tryghost/members-ssr
* Fixed tests for settings model
no-issue
Previously it was possible to fetch the private key and session secret
for the members service, this is a security issue as we do not have
specific permissions for individual settings yet, and could have
possibly exposed secrets to admin integrations.
- closes#10555
- Added a check to the user modal that the new owner is active
- Had to refactor Owner->Author unit test (also renamed it)
- Based on the first 2 lines, owner->editor change is attempted (hence the rename)
- Since both stubs return a 'modal' with owner role which means owner->owner change is actually attempted
- Now that there's a user status check, added the `status` property to the user receiving owernship
no-issue
This is so that someone with empty defaults for installed_apps and
active_apps, or someone without the defaults at all, will not see the
warning message when importing.
no-issue
As we're deprecating apps, filters are no longer used.
- Removed use of filters in helpers
- Removed use of filters from routing service
- Removed use of filters from rss service
- Removed use of filters in base model
no-issue
The instansiation of a Module object was only used so that we could
override the require method inside external apps, now we have no support
for them, we are free to require the internal apps directly. This has no
functionality change.
no-issue
Rather than creating a whole instance, we can replace it with a helper
method - his is less memory intensive and a little easier to parse for
something this small.
no-issue
The permissions module is no longer necessary as we only suppot internal
apps, which have all permissions. This allowed us to delete the module,
but required that we update the loader to remove references to it.
no issue
- the `{active,installed}_apps` settings related to a very old, minimally implemented, unreleased, and problematic approach to custom apps
- this is the first step towards full removal of the old "apps" concept
Credits: Kacper Szurek
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
closes#10640
- Updated sitemap resources data to include certain fields
- Fixes sitemap date and images value
- Updated date handling for sitemap nodes
no issue
- the conditional for removal of trailing blank paragraphs was not sufficient to handle paragraphs where the first child element was not a text node such as when the content of the last paragraph is italic
- switched to a method that fully walks the DOM of the last paragraph node to extract its equivalent `.textContent` value for use in the "last para is blank?" check
no issue
- when the page is missing the context can be undefined, this defaults it to an empty array so that later `context.includes()` calls don't error
refs #9589
* updated body_class helper to use newer code standards
* updated content helper to use newer code standards
* updated date helper to use newer code standards
no issue
- Admin API v2 returned /404/, see comment in code base:
/**
* CASE: admin api should serve preview urls
*
* @NOTE
* The url service has no clue of the draft/scheduled concept. It only generates urls for published resources.
* Adding a hardcoded fallback into the url service feels wrong IMO.
*
* Imagine the site won't be part of core and core does not serve urls anymore.
* Core needs to offer a preview API, which returns draft posts.
* That means the url is no longer /p/:uuid, it's e.g. GET /api/v2/content/preview/:uuid/.
* /p/ is a concept of the site, not of core.
*
* The site is not aware of existing drafts. It won't be able to get the uuid.
*
* Needs further discussion.
*/
no-issue
The 2.17 migration included a bug which set the `is_private`, `amp` and `force_i18n` setting values to `'false'` when they should have been `'true'`
We've reverted these changes by reading the most recent backup file, and setting the value to `'true'` if the backup has it set to `'true'` AND the current db has it set to false.
We've also amended the broken migration, so that it does not cause this issue for future installs
no-issue
Currently if you run two migrations on the same day, the backup is overwritten. This change adds the `HH-mm-ss` to the file name, meaning that you get a unique backup for each migration.
refs #10599
- meta_description output wrong meta description
Only solves meta_description for this use case:
```
routes:
/:
data: page.{slug}
template: t
```
refs #10082
```
routes:
/news/:
data: post.news
```
The twitter_image was not available, because the context is [news, post] and the data is in `data.post`.
The context helper was incorrect. I think it is still not fully correct, but only focused on this use case.
The meta layer needs a full refactoring.
refs #10593
- Added `canonical_url` field to post&pages resources in Admin & Content APIs
- Support for canonical URL on metadata layer (used in {{ghost_head}} helper)
- Made sure the new field is not accessible from API v0.1
- Added handling same domain relative and absolute URLs
refs #10582
- I don't think this is a good idea
- If a user passses "null", we should treat it as a string
- I am not aware of a use case why people have "null" in their database
- If people send "null" via the API, we should respect this and accept a string
refs #10582
- otherwise we will forward string booleans to model layer
- causes trouble if we trigger events
- causes trouble if we want to add conditions to the model e.g. setting.get('value') ?
no issue
- e.g. /feed.xml/ was showing a 422
- any other none slug site requests showed a 422
- should be a 404
- context: site is talking to Content API
- it can happen that the API returns a 422
- the routing layer needs to handle this and always show a 404
- catched error in routing error handling
- need to see if there are more cases
closes#10595
* Added breaking test for img-url helper
Input from the content API was absolute, adding this test to verify my fix
* Updated existing test to breaking test for img-url
Had made a dumb assumption when building images sizes, this updates the
test to fail so we can verify the fix
* Refactored img-url to return as early as possible
This makes it a little easier to parse what's going on, and it also
allows us to remove the check for existence of the image url in the
getImageSizes function
* Refactored img-url config parsing to clean up core logic
Superficial refactor to make future changes able to focus on what rather
than how.
* Refactored internal image detection into helper
We're gonna need to know if the image is internal or not, when we force
the path to relative, if we pull this out now, we have access in the top
level logic
* Removed duplicate checks for internal image
Cleaning up and moving "higher-level" logic into the main function of
the module
* Renamed attr -> requestedImageUrl
Superficial refactor, trying to be more explicit about identifiers
* 🐛 Fixed img-url to output relative url by default
Includes a check to isInternalImage as we never want to make external
images relative.
* Returned early if img-url recieves external url
After realising we never want to deal with external urls, we can
continue to return as early as possible, letting us remove checks and
simplify the more complex logic for internal images.
* Cleaned up the internal image logic
Defining the three functions in order helps to see what operations are
going to happen and in which order, we can then return the result of
each operation applied to the next operation.
refs #5162
- allow pagination and navigation partial helpers to have attributes passed through to them
- e.g. {{navigation header=true}} -> {{#if header}} will now work
- allows styling navigation to be done differently for different sections of the page
- properly create a data frame, and pass through "this" context
- means {{navigation header=true}} is the same as {{> navigation header=true navigation=@site.navigation}}
- our partial helpers, have the same behaviour exactly as if the partial was called directly
- this is additive, and improves behaviour
closes#10580
- The validation was failing because boolean values in settings can also be "0" and "1". 04c60b4ce1 explains the reason why these 2 new values are allowed
no issue
- Additional JSON.stringify call is redundant because it is already happening internally in Ignition (https://github.com/TryGhost/Ignition/blob/master/lib/logging/GhostLogger.js#L241)
- Left stringification in importer as is, because the use case there is also
putting errors into 'problems' array and seems like those values have to
be stringified
no issue
- Reported here: https://forum.ghost.org/t/in-version-2-16-3-found-bug/6065/3
---
Admin Client sends false or true booleans for `is_private` key.
The settings table has two columns "key" and "value". And "value" is always type TEXT.
If you pass value=false, the db will transform this value into "0".
`settingsCache.get('is_private')` is then always true, even though the value is meant to be false.
We should add a migration in v3 and normalize all setting values to ensure consistent database values. Furthermore, we should improve the handling around settings values in general.
For now, we protect parsing values from DB, which we anyway need to transform the values into the correct data type, because we always save strings. This will protect values being stored as "false" or "1" or whatever.
closes#10570
Added a conditional to only run makePathsAbsolute when database:client
is sqlite3, which keeps expected behaviour (make the
"database:connection:filename" path absolute when running SQLite) while
not breaking MySQL behaviour.
no issue
- trying to use the v0.1 Public API when it was disabled led to a confusing error message, see https://forum.ghost.org/t/403-forbidden-error-on-postman-api-call/6017
- adds an explicit check for the Public API being enabled in the client authentication step and throws a useful error message if client auth is attempted when it's disabled
closes#10512
- Removed field filtering in blog owner fetching because it didn't work before (fields weren't reduced) and now broke generated sql queries (ambiguous id field)
refs #10512
- Fixed ability to fetch specific fields when fetching tag resource by id
- Also only returning `url` field when specified in `fields` parameter
closes#10518
- we had a very generic logic to remove "unwanted" null values
- copied from v0.1
- originally added in 7d4107fec4
- this logic transformed: settings = [{key: 'key', value: null}] to [{key: 'key'}], which is wrong
- i've removed this generic logic completely, because i don't know which purpose it serves
- if there a specific case where we want to remove null values, we should either use the JSON schema or use a specific serializer for the target resource
- added tests to proof that settings API behaves as it should
- one test failed because we removed the isNull logic -> if you send published_at = null on a published post
- the model layer has a piece of logic to force a date if you set published_at to null if the status is published
- protected
closes https://github.com/TryGhost/Ghost/issues/10558
- added conditional to explicitly set `excerpt` to `null` in the API output serializer when a post has no `plaintext` or `custom_excerpt` value
no issue
- Migrated default scheduling adapter to use Got via the request proxy
- SchedulingDefault is the only module that was using superagent so removed it as a dependency
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
no issue
- throwing an object from a catch handler is not a good idea
- unexpected and broke functional call to API (always returned a 500, because API returned {err: err, method: ...}
* Required kid be a header claim as according to spec
https://tools.ietf.org/html/rfc7515#section-4.1.4 (JWT is an extension of JWS)
* Updated error message for missing kid
* Fixed admin-api key unit tests
* Fixed regression and acceptance tests
no-issue
- Added member auth middleware to siteApp
- Passed member as context in routing service
- set Cache-Control: private for member requests
- fucked up some tests
- Added member as global template variable
- Updated tokens to have expiry of subscription_period_end
no issue
We're creating tooling to convert HTML to Ghost flavoured mobiledoc, however we have cards that allow arbitrary content without a wrapper element which means that we're unable to do a 1:1 mapping of mobiledoc->html->mobiledoc. To work around this problem we now output HTML comments before/after the output of each card so that our converter can extract card content correctly when parsing HTML.
- added `createCard` method which wraps a card's `render()` method to add begin/end comments and updated all cards to use it
- only takes affect for newly added or re-saved posts/pages
refs #10438
- "null" means the resource does not exist (it was sett to "null"), which is not true
- we won't serve primary_tag and primary_author by default
- TODO: add the same change to the Content API v2 (raise issue)
no issue
- Content API v2 served primary_tag by default if members flag is enabled
- reference: b2201d4179
- it's safe to remove, because members is behind the dev flag
no issue
- if you html is NULL e.g. you create a draft post, we always set "html" to ""
- this get's marked as changed
- !this.get('html') was added for the 2.0 migration, because some posts had custom mobiledoc, but no html value
refs #9299
- `contextUser` returns a number and if the previous x_by is "1", then bookshelf marks it as changed ("1" !== 1)
- this is a left over from 0.x, because we still owner as id 1
- as soon as we fix 9299, we don't have to worry about this anymore, because we will fetch the owner id if we need it
no-issue
* Corrected function names for rpc methods
* Updated gateway to store tokens locally
* Fixed lint
* Added hardcoded 30 minute expiry for member tokens
* Added default contentApiAccess config;
* Updated validateAudience method
This is required for security, we need to restrict which domains can access
tokens meant for the content api
refs #10438
- To make response structure future proof and conform to the rest of API responses /images* now returns an object with url property instead of plain url string
no issue
- make use of filter instead of status=all or data.page
- nql was designed to filter data on database layer
- do not break v0.1
- we just got rid of the "status" query param, you should use the filter instead
- get rid of the ugly condition to remove page field if "fields" param was used
- allow filtering on model layer for "findOne"
- do not allow filtering for "findOne" on API layer for now
- the API controller defines what is allowed
- the model layer can allow more by default
- we can re-use the powerful filter logic without adding hacks
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
no issue
- this is either documented, not does it work
- the Content API returns authors independing on the status
- filtering by status should not work, because otherwise you could guess the status of a user
- we do not expose the status (!)
refs #10438
- the `updated_at` functions as version control value
- it is required for collision detection
- we might redesign this feature at some point
no issue
A new Zapier app will be released that uses the v2 Admin API which means it will require an ApiKey that is linked to an Integration.
- adds a `type` column to the `integrations` table with the following types allowed:
- `custom` (default) used by custom integrations added by users
- `builtin` used by built-in integrations that have their own UI and won't show up in the "Custom Integrations" list
- `internal` used by "internal" integrations such as the scheduler
- adds a `zapier` "builtin" integration to the fixtures
no-issue
* Refactored hideMembersOnlyContent to 3 "stages"
* Exported paymentConfigured flag from members service
* Updated Content-API to check members service for paymentConfigured
* Updated members content output serializer to remove content if plan required and no plan
* Updated isContentAPI method
* Moved api util test
refs #10438
- we now try to match by slug or id or email
- fallback to owner
- you cannot create a user via post endpoint
- Ghost uses the invite flow to add users
- get rid of `id` restriction on API level
refs #10438
refs #9100
- Added 'strip' attributes to properties that need to be ignored
- Relaxed 'uri' format to 'uri-reference'
- Made input array for posts more restrictive
Added JSON Schema validations for /tags endpoints
refs #10438
refs #9100
- Added JSON Schemas for POST/PUT /tags endpoints
- Added 'strip' keyword definition schema allowing to strip data and not throw errors on further validation stages
refs #10438
- these fields are not used
- no need to expose them in v2
- we will either remove them in the next major or use them for new features (will see)
no-issue
* Added getPublicConfig method to stripe payment processor
* Added getPublicConfig method to subscriptions service
* Added initial config endpoint for members api
* Added getConfig method to members gateway
refs #10438
- Additional check for present 'name' property before generating a
'slug'. Setting slug should not succeed and throw validation error in later
stages.
refs #10472
- Moved config related variable into function scope, so it can be reset by unit tests
- e47d1e275f broke the build and is being fixed by this commit
refs #10438
- Added validation helper based on JSON schema
- Added schema validation for POST/PUT in /posts endpoints
- Refactored existing authors validation test suite
- Extended test coverage with a minimally required structure of post.add validator
refs #10461
- do not break the existing webhooks by keeping both payload formats for subscribers events
- refactored webhooks service to run models through target API version
- added new events described in the target issue reference
- this refactoring & enhancement is undocumented, further breaking changes will happen because we are actively working on: https://github.com/TryGhost/Ghost/issues/10438
refs #10461
- the model layer (only post & user) fetches the model after update
- i assume it was added to ensure a response with all fields
- quick fixing it for now to ensure API layer can access ".wasChanged" to be able to decide if a request modified a resource or not
@NOTE: Bookshelf does not physically update a resource if nothing has changed.
no issue
- the model & api layer suffered from missing fields when creating resources
- usually there is only a handful of fields which are required to insert a resource
- the other fields are nullable and/or get defaults assigned
- the API only returned the configured default fields and the fields you have sent to the API
- this resulted in a response with missing fields
- if you have listend on "created" event, the same happend
- you received a model with missing fields
- we now set the undefined fields to null on purpose to ensure a full model for both cases
@NOTE:
There is no endpoint to serve webhooks (not for v0.1, not for v2).
Exposing the secret is required if an integration fetches it's api keys and it's webhooks.
The secret is currently un-used and not implemented.
no issue
- the event chain works like this:
- if a model registers an event, it get's triggered, because it's stronger than the base model
- but you have to call the base model to agree on a contract, because base model implements generic logic in event handlers
- this was inconsistently used
These changes introduce a new "service" to the members api, which handles getting and creating subscriptions.
This is wired up to get subscription information when creating tokens, and attaching information to the token, so that the Content API can allow/deny access.
Behind the subscription service we have a Stripe "payment processor", this holds the logic for creating subscriptions etc... in Stripe.
The logic for getting items out of stripe uses a hash of the relevant data as the id to search for, this allows us to forgo keeping stripe data in a db, so that this feature can get out quicker.
no-issue
* Used camelCase for gateway method calls
* Added some components for building blocks of forms
* Added input specific components
* Added Form component
This handles collecting the data to submit and sharing state between forms
* Added Pages component to handle urls
* Added the pages for the popup
* Added MembersProvider component
This is designed to give its children access to gateway methods
* Added Modal component
This wraps the pages and handles dispatching form submissions to the members gateway
* Refactored index.js to use new components/pages
* Fixed default page from Signup -> Signin
refs #10431
- the model layer triggers a couple of events on resource update
e.g. post to page -> post.deleted, post.added
- the resource_type must be always "post", because "page" is not an official model (Bookshelf won't be able to resolve the resource anymore)
- the action streams looks very confusion if you see deleted and added actions when toggling the post to a static page
- therefor the easiest approach for now is to only store actions for: added, edited, deleted
- and we will add the context information asap
- e.g. you will see that status was changed from "draft" to "published"
- we can also introduce extra published actions if we want
- relying on the internal event system right now makes things just more complicated and we want to keep it simple
refs #10431
- migration script to add permissions for actions
- restricted to owner & admin & integration role for now
- we will add permissions for other rules too, but we need add more granular restrictions
- e.g. contributors can only read actions for posts which he created
no issue
- With the changes in 79ca6c575c we removed old unused events
- The theme upload event is still used and needed to be put back
- Added the event emit right after the successful upload of the theme
- Renamed analytics events for more consistency
- We need to add the same event emitter to the v0.1 API as it's not deprecated
- emits a `theme.uploaded` event after the theme was successfully uploaded and saved
closes#10447
- Get helper message talks about the old API, but upgrading is the best way to solve the problem
- Had to create a way to add a custom message to a labs enabled helper to achieve this
closes#10448
- using @site.lang to read posts is a valid use case for the get helper filters
- get helper filters have special treatment of anything wrapped in {{}}, in the form of resolvePaths
- resolvePaths uses some custom logic + jsonpath to find the right bit of data to inject
- this function had no handling for globals starting with `@`, and also didn't have access to them
refs #9248
- Bookshelf gives access to ".changed" before the update
- Discussion: https://github.com/bookshelf/bookshelf/issues/1943
- We also need to know what has changed after the update to be able to decide if we should trigger events
- Furthermore: Bookshelf cannot handle relation updates, it always marks relations as changed even though they did not change
- Bumped bookshelf-relations to be able to
- know if relations were updated
- ensure we unset relations on bookshelf's ".changed"
refs #10438
- integrations != users
- Ghost's assumption is: if you create a post, the primary author becomes the logged in user
- we have to require authors for integrations
- short fix and needs some more thoughts later
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
refs #10174
- Improved importer cleanUp method usage, so the cleanup is called in cases when there is an error during an import stage
- Simplified files to clean up tracking as removal of files is now partially handled in uploader middleware
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
no-issue
- revert the migration because migrations that (potentially) touch every row should be kept to major releases where possible
- the migration was safe to run and won't cause any problems for anyone who has already upgraded
- reversion keeps the migration file but changes the contents to a no-op so that `migrations` table state is the same for all users whether they migrated with the full migration or the no-op version
closes#10388
This migration finds all tables with nullable columns, it then loops through the tables and their nullable columns, updating each column to a null when its current value is an empty string.
no-issue
Currently the `user-agent` header is the for outgoing webhook calls is the `got` default: `User-Agent: got/8.3.2 (https://github.com/sindresorhus/got)`.
This is pretty unfriendly to the receiver of the webhook who may wish to perform analytics on calling systems, implement security features based on calling system or take action based on different versions of a client.
This PR sets the header to: `User-Agent: Ghost/2.12.0 (https://github.com/TryGhost/Ghost)` which is much more descriptive.
refs #10388
This updates the base model to retrieve column information, and explicitly set every property whose column is `nullable` and content is the empty string (`""`) to `null`
refs #9865
- Changed id passed for api_key to an object to be able to differenciate between admin and content api requests
- Added integration id to frame context
- Small refactoring of frame context initialization
refs #9865
- Changed key format to {id}:{secret} so API consumer only has to worry about copying a single value during setup
- Updated key expiration time in getValidAdminToken test helper to match server side expiration check
refs #9389
- eslint@5.12.1, eslint-plugin-ghost@0.1.0, grunt-contrib-clean@2.0.0, grunt-contrib-uglify@4.0.0, grunt-eslint@21.0.0, grunt-mocha-cli@4.0.0, grunt-shell@3.0.1, mocha@5.2
.0, nock@10.0.6, rewire@4.0.1
All of them dropped Node v4. I was not able to find any other big breaking changes, which affect us right now.
refs #10286
- this is just a hotfix for v0.1
- we keep the x_by fields for now and deprecate them
- as soon as an integration updates/inserts a resource, we just store the owner ID
- we currently work on a new concept for v2
- v2 no longer exposes or uses x_by, see https://github.com/TryGhost/Ghost/pull/10294
- we need to iterate on this change, because we currently use the naming `context.api_key_id` in the auth/API layer
closes#10391
- We use "relative protocol" urls for gravatar images, which were
incorrectly getting treated as relative path urls.
- Refactored getBlogUrl calls into const
refs #9865
- small refactoring to make both session and admin api key handling similar
- admin api key authentication is still disabled, but easy to enable
- added proof test how to authenticate using admin api keys
refs #9865
- the outer authentication layer wants a consistent interface of each authentication package
- admin.authenticate
- session.authenticate
- furthermore, there is no need to put the full feature into the exposed function name
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
refs #9865
This updates all current permissible methods to use the new function
signature which includes the hasApiKeyPermissions parameter. It also
makes sure that the hasApiKeyPermissions argument is taken into account
whenever checking before returning a resolved promise.
To be continued. This is just a tiny part of the big picture. None of these changes are fully committed to stay as they are.
refs #9865
- Enabled the permissions module to lookup permissions based on an api_key id.
- Updated the "can this" part of the permissions service to load permissions for any api key in the context, and correctly use that to determine whether an action is permissible. It also updates the permissible interface that models can implement to pass in the hasApiKeyPermissions param.
* Updated docs links to best equivalents
- Our documentation has been overhauled, this updates the all the old links sprinkled through Ghost
* Update integrity hash
no issue
- Fixes a case where a post that doesn't belong to a collection throws a 500 Resource Not Found Error
- This should be a 404 Resource Not Found error
- 500 suggests something went very wrong and is our fault,
- but this is a user error where the collections or posts are misconfigured, and some content doesn't have a home
closes#10383
- Upgrades got to 8.3.2, which contains better error handling and resolves the issue with uncaught exceptions
- Note: Got 9.x stream doesn't support Node v6
- Requires us to hardcode http:// for xmlrpc because there is a breaking change where got now defaults to https instead of http
closes#10373
- ghost_head & ghost_foot are deprecated from now on
- we want to remove them in v3
- this short fix is dirty (!)
- we return codeinjection_* for admin & content api
- this is a consistentency change e.g. posts return `post.codeinjection_*`
- need to raise a decoupling refactoring issue for the code comments
* 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 clause in validation for include to not error
refs #10337
Here we forgo erroring when an invalid property for include is sent, and
instead remove the invalid properties.
* Fixed authors test
* Fixed validators tests
closes#10283
Updated middleware for dynamic image sizes to attempt to read the unoptimized image first, taking into account the `-n` suffix for duplicate image names, by using a regex.
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)
* 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 #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
closes#10062
- return `post.excerpt` for Content API v2
- do not use `downsize`, because we might want to get rid of it if we drop v0.1 (downsize does not create good excerpts)
- simple substring of the plaintext field
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
- 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
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 #10318
- cheap and dirty way of removing settings we don't use
- rewritten the settingsFilter function as that was unnecessarily complex
- aslo fixed the require of default-settings in the importer
* Removed unused fields from v2 Content API
- We want to ship the v2 Content API as clean and lean as we can
- Many fields in the DB aren't actually used, we shouldn't return these values
- Other values aren't useful outside of Admin clients, and shouldn't be returned either
Fields removed:
- tags: created_at, updated_at, parent
- authors: locale, accessibility, tour
- posts: locale, author status, page
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
refs #10286
- v2 no longer exposes x_by fields (published_by, updated_by, created_by)
- we will add a brand new concept called activity stream/actions soon
closes#10301
* Redirected to original image for gifs & svgs
* Created canTransformFileExtension method
* Updated image middlewares to use canTransformFileExtension
no issue
- This change is a follow up to this bugfix https://github.com/TryGhost/Ghost/pull/10299
- Added default export JSON to keep the state of db test suite intact
- Small typo fixe that noticed while debugging