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