Commit Graph

1074 Commits

Author SHA1 Message Date
Katharina Irrgang
029a2a276c 🐛 Fixed redirects loop if admin url does not equal blog url (#8950)
no issue

- this bug was invented with this commit 25c4e5025a
- the updated logic ensures that
  - only if you have configured a custom admin url and your requested host does not match, we redirect you
  - we still keep the wish of no force redirect if you have only configured a custom blog url and you navigate to /ghost
2017-08-29 10:13:56 +01:00
Hannah Wolfe
688d8c9051 🐛 Downgraded errors to warnings for img_url
refs #8703

- Instead of throwing errors, throw warnings for incorrect usage of the img_url helper
- Differentiate between no attribute passed, and attribute evaluating to undefined
2017-08-29 10:31:00 +02:00
Hannah Wolfe
c49dba12a0 🐛 Added error handling to prev/next post helpers
refs #8703

- On API error, call inverse with a data error, the same as the get helper
2017-08-29 10:31:00 +02:00
Hannah Wolfe
ff15dc1667 Added any & all matching to {{#has}} helper
closes #8901

- Adds support for

```
{{#has any="twitter, facebook, website"}}
{{#has any="author.facebook, author.twitter,author.website"}}
{{#has any="@blog.facebook, @blog.twitter, @labs.subscribers"}}
{{#has all="@labs.subscribers,@labs.publicAPI"}}
```
2017-08-22 11:21:47 +01:00
David Wolfe
c3fcb3105f Add ghost-backup client to trigger export (#8911)
no issue
- adds a ghost-backup client
- adds a client authenticated endpoint to export blog for ghost-backup client only
- allows some additional overrides during import
- allows for an import by file to override locking a user and double hashing the password
2017-08-22 11:15:40 +01:00
Hannah Wolfe
b1cfa6e342 Improved version match logic (#8922)
closes #8821

- Use semver to do constraint matching
- Use client to generate a caret constraint
- E.g. if the client is 1.1, then the constraint ^1.1.0 will match >=1.1.0 <2.0.0
- Updated tests
2017-08-22 10:59:01 +01:00
Hannah Wolfe
553c8d50ac Renamed test file so it gets run in Travis (#8923)
no issue

- Our test match on _spec.js, so this file would not have been run
2017-08-21 11:03:01 +07:00
Aileen Nowak
b086b432ad Dumped icojs and use image-size for .ico (#8888)
refs #8868

The `image-size` library supports now `.ico` files, which means there is no longer need to use the `icojs` library.
- removes unnecessary `icojs` dependency
- refactors `getIconDimensions` fn in blog icon util to fetch image sizes synchronus
- removes unnecessary `getIconDimensions` fn in blog icon validation, as there is no longer need to use different image size fn for different file extensions, and uses `getIconDimensions` from blog util fn instead.
- updates and adds more tests
2017-08-17 17:44:05 +01:00
Hannah Wolfe
8c7d305cd5 🐛 Fixed channel context to be based on res.locals (#8910)
closes #8907, closes #8908

- Add a bunch of tests to detect these breakages!
- Then change all the places where req.channelConfig was still being used
2017-08-16 11:06:30 +01:00
Hannah Wolfe
86e4b7b723 Added slug & id matching to {{#has}} helper (#8903)
refs #8901

- Adds support for

```
{{#has slug="welcome"}}
{{#has slug=../../slug}}
{{#has id=post.id}}
```
2017-08-15 16:25:06 +01:00
Hannah Wolfe
6ee9bb491c Added number & index matching to {{#has}} helper (#8902)
refs #8901

- Adds support for:

    ```
    {{#has number="3"}} // A single number
    {{#has number="3, 6, 9"}} // list the numbers you want to match against
    {{#has number="nth:3"}} // special syntax for nth item
    ```

    And

    ```
    {{#has index="3"}} // A single number
    {{#has index="3, 6, 9"}} // list the numbers you want to match against
    {{#has index="nth:3"}} // special syntax for nth item
    ```
2017-08-15 16:00:17 +01:00
Hannah Wolfe
852155075f 🐛 Added 409 DisabledFeatureError for labs features (#8890)
fixes #8889

- This is a user error, not a system error
- Downgrading to a 4xx status code means it doesn't appear in logs where it shouldn't
- We didn't have a suitable error available so I added DisabledFeatureError with 409 status
- Ref: https://stackoverflow.com/questions/36874263/expected-http-status-code-for-an-action-on-a-disabled-resource
- Also tweaked the error message slightly as it didn't read clearly to me
2017-08-15 10:50:36 +02:00
Hannah Wolfe
bd41dba35b 🦄 Channels: Stored config in res.locals not req (#8884)
refs #5091

- This tiny refactor opens the door for using channel config inside of helpers
- This means that ghost_head, and the next_post/prev_post helpers can be context aware
2017-08-14 10:21:24 +07:00
Hannah Wolfe
1cc4be8010 🦄 Channels: make RSS & Pagination configurable (#8857)
refs #5091

- occurred to me whilst documenting the custom homepage config, that RSS and pagination
need to be optional
- added a very quick if statement & tests
- needs further refactoring & test improvements
- this will not disable the RSS url output in meta data yet 😔
2017-08-10 11:12:09 +02:00
Hannah Wolfe
2e8a8ad88a 🐛 Fixed meta on subscribe page if labs not enabled (#8848)
refs #8597

- Only set the subscribe context if the labs flag is set
- Committed at 38000ft
2017-08-08 09:45:37 +02:00
Hannah Wolfe
dbd7060e69 🦄 Added /edit/ redirect to admin for post previews (#8836)
no issue

- This already works for posts and channels
- It always felt like a bug that it didn't work for previews
- Now it does 😬
2017-08-08 09:32:55 +02:00
Aileen Nowak
cfbb7f6c6b Facebook and Twitter data per post feature (#8827)
closes #8334

- adds title, image and description to structured data to be rendered as open graph and twitter data.
- if meta title and description for a post exists already, the custom structured data will overwrite those for `og:` and `twitter:` data. `JSON-LD` (Schema.org`) is not affected and will stay the same.
- adds tests
- adds new og and twitter fields to schema incl. migration
2017-08-03 15:48:39 +04:00
Aileen Nowak
a63c26a82b 🐛 Fixed custom post excerpt length (#8826)
closes #8823

- if a custom post excerpt is set, the default max length of 50 was used, which was wrong
- adds more tests
2017-08-02 15:09:12 +04:00
Katharina Irrgang
2f866a99f6 🐛 Fixed global and post code injection output (#8824)
no issue

- if a custom post code injection is defined, we output both
2017-08-02 15:06:51 +04:00
Katharina Irrgang
8f39d6cb5f Code Injection per Post feature (#8820)
no issue

- add 1.4 database migration to add two new fields to the database (use type text, because of max row size)
- handle global code injection vs. post code injection
- add tests
2017-08-02 13:38:19 +04:00
Kevin Ansfield
4da94a287f 📝 Correct typos in default welcome posts (#8807)
closes #8806
- `omellete` -> `omelette`
- `sleak` -> `sleek`
2017-08-01 13:04:08 +04:00
Katharina Irrgang
7845617607 Custom Post Excerpt Feature (#8792)
closes #8793

- 1.3 post excerpt migration
  - add 1.3 migration to add `excerpt` to post schema

NOTE:
    - knex-migrator relies on the package.json safe version
    - so right now Ghost is on 1.2
    - the migration script is for 1.3
    - if you pull down the PR (or if we merge this PR into master), you have to run `knex-migrator migrate --v 1.3 --force`
    - knex-migrator will tell you what you have todo

- Bump dependencies
  - knex-migrator@2.1.3
- Soft limit for custom_excerpt
- Extended {{excerpt}} to use custom excerpt
   - when a `custom_excerpt` field exists, the `{{excerpt}}` helper will output this and fall back to autogenerated excerpt if not.
- Refactored behaviour of (meta) description
   - html tag `<meta name="description" />` for posts, tags and author doesn't get rendered if not provided.
        - fallback for `author.bio` removed
        - fallback for `tag.description` removed
   - structured data and schema.org for `post` context takes the following order to render description fields:
        1. custom excerpt
        2. meta description
        3. automated excerpt (50 words)
    - updated and added tests to reflect the changes
2017-08-01 12:39:34 +04:00
John O'Nolan
0b5de14900 🎨 Improved SEO meta titles for paginated archives (#8785)
closes #8575
2017-07-31 13:13:06 +04:00
John O'Nolan
4333604480 Fix fixture typo 2017-07-31 12:43:58 +04:00
Austin Burdine
65d219c29a 🐛 🔗 resolve symlinks before building zip (#8780)
closes #8778

- if folderToZip is a symlink, find the target using fs.realPathSync so we zip the right thing
- add a test
2017-07-31 11:48:00 +04:00
Hannah Wolfe
301696632f 🛠 🙈 Rename ghost-url.js to ghost-sdk.js (#8767)
closes #8605

- This file has already been moved, might as well get the rename out of the way
- Especially as we don't migrate clients - everyone will now need to make just one change
2017-07-28 18:23:32 +04:00
Katharina Irrgang
948c279f60 🔥 fromaddress support (#8753)
refs #8748

- please use `from`
- documentation was already updated
2017-07-27 12:27:38 +04:00
John O'Nolan
0698be503a Site description fixture update (#8763)
No issue
2017-07-27 12:26:31 +04:00
Katharina Irrgang
60558a776f 🐛 be able to serve locked users (#8711)
closes #8645, closes #8710

- locked users were once part of the category "active users", but were moved to the inactive category
  -> we have added a protection of not being able to edit yourself when you are either suspended or locked
- but they are not really active users, they are restricted, because they have no access to the admin panel
- support three categories: active, inactive, restricted

* - revert restricted states
- instead, update permission layer: fallback to `all` by default, because you are able to serve any user status
- add more tests

- ATTENTION: there is a behaviour change, that a blog owner's author page can be served before setting up the blog, see conversation on slack
   -> LTS serves 404
   -> 1.0 would serve 200
2017-07-20 12:45:13 +01:00
John O'Nolan
cb2f754472 Update welcome post fixture (#8672)
Closes #8620

Info about how to delete the default Ghost user and all of the welcome posts along with it
2017-07-10 20:38:03 +07:00
Aileen Nowak
827aa15757 Add new fixture Ghost Author (#8638)
refs #8620

Adds a new Ghost Author user, which is the author of the new welcome blog posts. The user is set to active, so the author slug works (otherwise it would render a 404, when user is suspended). Furthermore, there's one little fix in the user model, which was checking only for `active` user to decide the signup or setup process for the UI. Adding one more conditional to check if the found active user is also the owner, prevents to get redirected to sign in.
2017-07-06 00:18:27 +02:00
Austin Burdine
49c8277390 fix(config): cleanup absolute path config function (#8641)
refs https://github.com/TryGhost/Ghost-CLI/issues/228

- don't try to reinvent path.isAbsolute
2017-07-06 00:04:18 +02:00
Aileen Nowak
c3dbd0e56b 🐛 Remove trailing slash for {{@blog.url}} (#8596)
closes #8569

- remove the trailing slash for `{{@blog.url}}` data in theme middleware
2017-06-19 16:11:53 +02:00
Aileen Nowak
5bc5eca315 🐛 Fix double slash in scheduling API URL (#8574)
closes #8568

- use our `urlJoin` util to concatenate the URL (not the query part of it, as this is not supported in `urlJoin`) and to prevent possible missing or double slashes, as `config.apiUrl` could be with or without trailing slash
2017-06-14 16:26:28 +02:00
Katharina Irrgang
f5ef8dbb52 📖 replace any support.ghost.org link (#8555)
refs #7421
2017-06-08 20:34:20 +01:00
Kevin Ansfield
f675a962cf 📖 new default post content (#8548)
closes #8542
- updates default post fixtures
- adds default logo and cover images to settings fixtures
- update tests due to coupling to dev/prod fixtures
2017-06-08 16:36:14 +01:00
Katharina Irrgang
d6d343865b 🎨 show clearer error for wrong content path (#8535)
no issue
2017-06-07 16:31:01 +07:00
Katharina Irrgang
a61e6e7cc2 🐛 fix settings cache (#8506)
closes #8505

- cache.get(..) auto converted "1" to integer
2017-06-04 17:52:22 +07:00
David Wolfe
b081ae34b5 🎨 Support LTS imports (#8498)
refs #8141

- update importer for LTS fields
- optimise for LTS export fixtures
- add image/language test for LTS import
- ensure post image is mapped to feature_image
- create mobiledoc values from markdown and html
- if mobiledoc is null, use markdown or html to create a mobiledoc markdown card
- update import mapping to use locale
- defaultLang in settings now maps to default_locale
- language for post and user models now maps to locale
- posts are not always loaded in correct same order so we select the posts we want to validate
- ensure if mobiledoc field is not in export we can still import from markdown
- map last_login to last_seen
- for users the importer maps last_login to last_seen
- add warning for legacyActiveTheme
- for export with old activeTheme key provide a warning that theme is not installed
- add importer test for LTS user long email
- add a test for LTS export where email address could be longer than alpha
- fix for importer date tests on mysql
- use valueOf in moment to compare times stored in different formats
- ignore warnings for not found settings in import
- use a flag to ignore NotFound Entries for settings during import
2017-06-04 11:53:00 +02:00
Katharina Irrgang
18b71f32b1 🎨 rename language to locale and use en as default locale (#8490)
no issue
- this PR references indirecty to https://github.com/TryGhost/Ghost/pull/8437
- i would like to have the settings change already in place before we release the beta
- the i18n feature is able to change the locale of Ghost
- most i18n libraries use locale
- adding/changing settings doesn't require a migration file, but it can make the database a bit messy (because you can end up with default_locale and lang)
- furthermore we agreed that the default locale for Ghost should be simply `en`, not `en_US` or `en_GB`
2017-05-31 16:05:49 +01:00
Kevin Ansfield
85496f409a 🔥 remove posts.markdown field (#8497)
closes #8479

- removes `markdown` field from schema
- removes `legacyMarkdown` converter
- updates tests to work with `mobiledoc` field instead of `markdown` and adapt for mobiledoc HTML output where necessary
2017-05-31 16:46:29 +02:00
Katharina Irrgang
25c4e5025a 🔥 revert: force admin url redirect (#8493)
refs #8152
- as long as OAuth is disabled, we can revert the url redirection (see comment)
- the redirect only happens if you configure a specific `admin.url`
- add another test case, which was missing
2017-05-30 10:19:14 +01:00
John O'Nolan
476caa5c2f 🎨 Update fixtures: Ghost owner (#8460)
no issue

- use a better name for default user pre-setup
- make it clear that this email address is an example, not real
2017-05-29 19:25:19 +02:00
Katharina Irrgang
1f37ff6053 🎨 refactor the importer (#8473)
refs #5422

- we can support null titles after this PR if we want
- user model: fix getAuthorRole
- user model: support adding roles by name
- we support this for roles as well, this makes it easier when importing related user roles (because usually roles already exists in the database and the related id's are wrong e.g. roles_users)
- base model: support for null created_at or updated_at values
- post or tag slugs are always safe strings
- enable an import of a null slug, no need to crash or to cover this on import layer
- add new DataImporter logic
    - uses a class inheritance mechanism to achieve an easier readability and maintenance
    - schema validation (happens on model layer) was ignored
    - allow to import unknown user id's (see https://github.com/TryGhost/Ghost/issues/8365)
    - most of the duplication handling happens on model layer (we can use the power of unique fields and errors from the database)
- the import is splitted into three steps:
  - beforeImport
    --> prepares the data to import, sorts out relations (roles, tags), detects fields (for LTS)
  - doImport
    --> does the actual import
  - afterImport
    --> updates the data after successful import e.g. update all user reference fields e.g. published_by (compares the imported data with the current state of the database)
- import images: markdown can be null
- show error message when json handler can't parse file
- do not request gravatar if email is null
- return problems/warnings after successful import
- optimise warnings in importer
- do not return warnings for role duplications, no helpful information
- error handler: return context information of error
- we show the affected json entries as one line in the UI
- show warning for: detected duplicated tag
- schema validation: fix valueMustBeBoolean translation
- remove context property from json parse error
2017-05-23 17:18:13 +01:00
Katharina Irrgang
b22151ac92 🎨 do not ping slack if we import content (#8476)
closes #7275

- forward options for events (post model only for now)
2017-05-22 17:24:59 +09:00
Kevin Ansfield
5d868d14ad replace custom showdown fork with markdown-it (#8451)
refs https://github.com/TryGhost/Ghost-Admin/pull/690, closes #1501, closes #2093, closes #4592, closes #4627, closes #4659, closes #5039, closes #5237, closes #5587, closes #5625, closes #5632, closes #5822, closes #5939, closes #6840, closes #7183, closes #7536

- replace custom showdown fork with markdown-it
- swaps showdown for markdown-it when rendering markdown
- match existing header ID behaviour
- allow headers without a space after the #s
- add duplicate header ID handling
- remove legacy markdown spec
- move markdown-it setup into markdown-converter util
- update mobiledoc specs to match markdown-it newline behaviour
- update data-generator HTML to match markdown-it newline behaviour
- fix Post "converts html to plaintext" test
- update rss spec to match markdown-it newline behaviour
- close almost all related showdown bugs
2017-05-15 18:48:14 +02:00
Rei
e066094044 🐛 https image urls if accessed over SSL (#8373)
closes #8372

- https image urls if accessed over SSL (fix secure option for images)
2017-05-15 13:09:48 +02:00
Aileen Nowak
1b965fab95 🎨 Move scheduling and storage in adapters/ (#8435)
no issue

Move `core/server/scheduling` to `core/server/adapters/scheduling` and
`core/server/storage` to `core/server/adapters/storage`
2017-05-15 12:52:01 +02:00
Katharina Irrgang
524cc4c343 🐛 escape blog title for mail header (#8453)
closes #8436

- this is how the from field looks like "blog title <owner@blog.com>"
- so if you set your blog title with double quotes, it throws a syntax error from the smtp library
2017-05-12 15:09:45 +02:00
Kevin Ansfield
c71cf643e2 update default post to use a single markdown card (#8448)
no issue

- now that we've switched to using a SimpleMDE based editor in Ghost-Admin the default post needs to match the expected single-markdown-card format
2017-05-12 10:08:45 +02:00
Katharina Irrgang
7549473a86 🚑 Disable remote authentication (#8346)
closes #8342
- extend auth validation to deny auth type "ghost" for now
- skip some tests
2017-04-24 18:56:49 +01:00
Katharina Irrgang
4e2474a018 🎨 settings inconsistency (#8381)
no issue
- replace camelCase settings keys with underscore_case for consistency
- discussed here https://github.com/TryGhost/Ghost-Admin/pull/661#discussion_r112939982
2017-04-24 18:41:00 +01:00
Katharina Irrgang
76bd4fdef6 🙀 Image field naming & new img_url helper (#8364)
* 🙀  change database schema for images
    - rename user/post/tag images
    - contains all the required changes from the schema change

* Refactor helper/meta data
    - rename cover to cover_image
    - also rename default settings to match the pattern
    - rename image to profile_image for user
    - rename image to feature_image for tags/posts

* {{image}} >>> {{img_url}}
    - rename
    - change the functionality
    - attr is required
    - e.g. {{img_url feature_image}}

* gscan 1.0.0
    - update yarn.lock

* Update casper reference: 1.0-changes
    - see 5487b4da8d
2017-04-24 18:21:47 +01:00
Aileen Nowak
e19e91044d 🙇 Blog icon utils and publisher.logo for JSON-LD (#8297)
refs #8221, closes #7688, refs #7558

🙇  Improve meta data publisher logo behaviour
This is a follow-up PR for #8285.

Reasons: The code changes of #8285 caused error messages when falling back to the default `favicon.ico`, as the `image-size` tool doesn't support `ico` files.

This PR takes the logic to decide which logo needs to be listed in our schema into a new fn `blog_logo.js`. There we have now three decisions:
1. If we have a publication **logo**, we'll take that one
2. If we have no publication logo, but an **icon** we'll use this one.
3. If we have none of the above things, we fall back to our default `favicon.ico`

Additional, we're hard coding image dimensions for whenever the logo is an `.ico` file and built and extra decision to not call `image-size` when the dimension are already given.

I will create another follow-up PR, which checks the extension type for the file and offers it as a util.

🛠  Blog icon util

refs #7688

Serve functionality around the blog icon in its own util:
- getIconDimensions -> async function that takes the filepath of on ico file and returns its dimensions
- isIcoImageType -> returns true if file has `.ico` extension
- getIconType -> returns icon-type (`x-icon` or `png`)
- getIconUrl -> returns the absolut or relativ URL for the favicon: `[subdirectory or not]favicon.[ico or png]`

📖  Get .ico sizes for meta data & logo improvement

refs #7558
refs #8221

Use the new `blogIconUtil` in meta data to fetch the dimensions of `.ico` files.

Improvements for `publisher.logo`: We're now returning a hard-coded 'faked' image dimensions value to render an `imageObject` and prevent error our schema (Google structured data). As soon as an image (`.ico` or non-`.ico`) is too large, but - in case of non-`.ico` - a square format, be set the image-dimensions to 60px width and height. This reduces the chances of getting constantly error messages from Googles' webmaster tools.

- add getIconPath util
2017-04-11 18:32:06 +02:00
Katharina Irrgang
049b6d9874 add issued_by column to access token (#8284)
closes #6626

- see https://github.com/TryGhost/Ghost/issues/6626#issuecomment-291445977
- adding this column could make our lives easier in the future
2017-04-11 13:12:14 +01:00
Aileen Nowak
a3387adb99 🐝 Add image property to rss (#8289)
refs #7688

Adds an image property to our generated rss data, which links to the favicon (has to be `.png` reg. http://www.rssboard.org/rss-2-0-1#ltimagegtSubelementOfLtchannelgt).
2017-04-11 13:54:52 +02:00
Aileen Nowak
d9d182f7ba 🎨 Blog icon improvements (#8260)
refs #7688

- blog icon error message
- change default favicon to 60px
2017-04-11 13:40:17 +02:00
Aileen Nowak
4ba5cc862a 🐛 Blog icon improvements (#8298)
refs #7688

- renders the correct `/favicon.ico` or `/favcicon.png` in `{{ghost_head}}`
- removes an regex issue in `serve-favicon`
2017-04-10 12:04:46 +01:00
Hannah Wolfe
a413d70313 Asset amends (#8294)
refs #8221

🔥 Remove ghost=true concept from asset url helper

 💯 Introduce CSS minification with cssnano
- add new grunt-cssnano dependency
- wire up grunt task to minify public/ghost.css

🎨 Rename minification config & hash params
- Change minifyInProduction -> hasMinFile
  - this means this asset should have a .min file available
- Change minifyAssets -> useMinFiles
  - this means that in this env we want to serve .min files if available

🎨 Update public/ghost.css to serve .min for prod
- add the new `hasMinFile` property

🎨 Move minified asset handling to asset_url util
- this logic should be in the util, not the asset helper
- updated tests

📖 Error handler always needs asset helper
- this removes the TODO and adds a more sensible comment
- we also need to update our theme documentation around error templates

🔥 Don't use asset helper in ghost head
- use getAssetUrl util instead!
- removed TODO

📖 Update proxy docs
🎨 Simplify asset helper & add tests
- this refactor is a step prior to moving this from metadata to being a url util
- needed to skip some new tests

🐛 Add missing handler for css file
2017-04-10 11:30:21 +02:00
Aileen Nowak
f0f3c2f2a7 👋🏼 Don't use ghosticon.jpg from admin assets (#8285)
refs #8221

Use our default `favicon.ico` instead of `ghosticon.jpg` which is served from the admins' assets.
Adds additionally fake image dimensions for our json-ld data to satisfy Google.
2017-04-07 14:07:47 +01:00
Aileen Nowak
83f084608f 💁🏻 Moveshared/ to server/public (#8273)
refs #8221

Instead of serving our shared assets from a `shared/` folder, we move the file, which are used server side to `server/public`.
Adds a new `config.paths` entry: `publicFilePath` and renames the middleware to serve the files to reflect the changes.
Adds `404-ghost.png` images to be used by the server side rendered default template `error.hbs`.
2017-04-07 13:21:41 +01:00
Katharina Irrgang
38fe4d2842 🐛 subscriber: sanitize email vol. 2 (#8280)
no issue


🐛  subscriber: sanitize email vol. 2
- ensure email get's sanitized for every error case

🐛  validator.isEmptyOrURL doesn't accept non strings
- otherwise it shows a weird error message in the client

  new tests for subscriber app
- routing tests

* change tests for Ghost 1.0
* it took me 15min to find this 😡
2017-04-05 22:02:16 +01:00
Katharina Irrgang
64d2a94073 🐛 fix image size timeout (#8283)
closes #8041

- destroy socket is required, see https://nodejs.org/api/http.html#http_server_settimeout_msecs_callback
- optimise error messages in general
- make timeouts configureable
2017-04-05 21:58:26 +01:00
Katharina Irrgang
587ff6f026 🎨 change last_login to last_seen (#8259)
refs #8258

* 🎨  change last_login to last_seen

- rename the column
- a change in Ghost-Admin is required as well

* test utils: revert export examples

* revert line breaks
2017-04-05 20:45:55 +01:00
Hannah Wolfe
9b3c3943ef Add new plaintext field (#8276)
refs #8275

- this PR only adds the field for now, so we can merge this along with other DB changes
2017-04-05 21:28:13 +02:00
Hannah Wolfe
4b49f39e55 📖 Change the welcome to ghost fixture to be mobiledoc (#8277)
refs #8275

- this switches over the fixture to be mobiledoc based. Most of the content was to do with markdown so it has been replaced with placeholder text
- content will be replaced via #8275
2017-04-05 21:16:28 +02:00
Katharina Irrgang
817b8d09ca 😱 🎨 Refactor storage adapter (#8229)
refs #7687

There are four main changes in this PR:

we have outsourced the base storage adapter to npm, because for storage developers it's annoying to inherit from a script within Ghost
we hacked theme storage handling into the default local storage adapter - this was reverted, instead we have added a static theme storage here
use classes instead of prototyping
optimise the storage adapter in general - everything is explained in each commit

----

* rename local-file-store to LocalFileStorage

I would like to keep the name pattern i have used for scheduling.
If a file is a class, the file name reflects the class name.
We can discuss this, if concerns are raised.

* Transform LocalFileStorage to class and inherit from new base

- inherit from npm ghost-storage-base
- rewrite to class
- no further refactoring, happens later

* Rename core/test/unit/storage/local-file-store_spec.js -> core/test/unit/storage/LocalFileStorage_spec.js

* Fix wrong require in core/test/unit/storage/LocalFileStorage_spec.js

* remove base storage and test

- see https://github.com/kirrg001/Ghost-Storage-Base
- the test has moved to this repo as well

* Use npm ghost-storage-base in storage/index.js

* remove the concept of getStorage('themes')

This concept was added when we added themes as a feature.
Back then, we have changed the local storage adapter to support images and themes.
This has added some hacks into the local storage adapters.
We want to revert this change and add a simple static theme storage.

Will adapt the api/themes layer in the next commits.

* Revert LocalFileStorage

- revert serve
- revert delete

* add storagePath as property to LocalFileStorage

- define one property which holds the storage path
- could be considered to pass from outside, but found that not helpful, as other storage adapters do not need this property
- IMPORTANT: save has no longer a targetDir option, because this was used to pass the alternative theme storage path
- IMPORTANT: exists has now an alternative targetDir, this makes sense, because
  - you can either ask the storage exists('my-file') and it will look in the base storage path
  - or you pass a specific path where to look exists('my-file', /path/to/dir)

* LocalFileStorage: get rid of store pattern

- getUniqueFileName(THIS)
- this doesn't make sense, instances always have access to this by default

* Add static theme storage

- inherits from the local file storage, because they both operate on the file system
- IMPORTANT: added a TODO to consider a merge of themes/loader and themes/storage
- but will be definitely not part of this PR

* Use new static theme storage in api/themes

- storage functions are simplified!

* Add https://github.com/kirrg001/Ghost-Storage-Base as dependency

- tarball for now, as i am still testing
- will release if PR review get's accepted

* Adapt tests and jscs/jshint

* 🐛  fix storage.read in favicon utility

- wrong implementation of error handling

* 🎨  optimise error messages for custom storage adapter errors

* little renaming in the storage utlity

- purpose is to have access to the custom storage instance and to the custom storage class
- see next commit why

* optimise instanceof base storage

- instanceof is always tricky in javascript
- if multiple modules exist, it can happen that instanceof is false

* fix getTargetDir

- the importer uses the `targetDir` option to ensure that images land in the correct folder

* ghost-storage-base@0.0.1 package.json dependency
2017-04-05 15:10:34 +01:00
Hannah Wolfe
243b387063 Helper Proxy & single express-hbs instance (#8225)
refs #8126, #8221, #8223

 New 'Proxy' for all helper requires
- this is not currently enforced, but could be, much like apps
- the proxy object is HUGE
- changed date to use SafeString, this should have been there anyway
- use the proxy for all helpers, including those in apps 😁

 🎨 Single instance of hbs for theme + for errors
- we now have theme/engine instead of requiring express-hbs everywhere
- only error-handler still also requires express-hbs, this is so that we can render errors without extra crud
- TODO: remove the asset helper after #8126 IF it is not needed, or else remove the TODO

🎨 Cleanup visibility utils
🎨 Clean up the proxy a little bit
🚨 Unskip test as it now works!
🎨 Minor amends as per comments
2017-04-04 18:07:35 +02:00
Katharina Irrgang
d4836af18a 🐛 fix owner user slug (#8263)
closes #8067

- this is only a bug present for remote authentication
- right now the remote service does not return the name of the user
- depends on an internal PR
- force regenerating the slug on setup
- override name for signin or invite if needed
2017-04-04 14:56:04 +01:00
Aileen Nowak
e06547ae78 Split css server templates (#8234)
closes #8126

* Remove default template dependency on client side CSS

See Issue #8126

Adds these files under /shared
- normalizer.css
- error.css
- extracted.css (for subscribers.css and private.css)

Also makes these files available as public static content

* Remove default template dependency on client CSS

closes #8126
needs e3acd3c

This is a replacement PR of #8217 (thanks @TienSFU25 for the whole work 🤗), because these changes are needed urgently and blocking other work.

Adds a new `ghost.css` file in `/core/shared/` to be used for server side template rendering (`error.hbs`, `subscribe.hbs` and `private.hbs`).
2017-04-04 10:06:38 +01:00
Katharina Irrgang
be977a55cf 🎨 🚑 do not use testurl.com in tests (#8254)
no issue

- if we are using any random domain in our tests, it could be that the test behaviour changes over time
- in this case: the ghost_head_spec triggers a request for image diminsions (cover image, author image, blog logo)
- if the target blog url/domain can't be reached (connecting....), the timeout would be reached - but the test is not setup to handle longer waiting times
- even with https://github.com/TryGhost/Ghost/pull/8210/files, the default timeout would be 5s, which is not acceptable for a unit test
- that's why, we need to choose a blog url, which definitely is "down" - any long localhost port
2017-04-03 16:29:36 +01:00
Ryan McCarvill
d0dc7c5ee1 📦 Card-Rename (#8218)
no issue
- Renames Cards so they comply with the `card-{{name}}` convention rather than `{{name}}-card`
- Adds an unkonwnCardHandler to the editor.
2017-03-24 10:03:33 +00:00
Hannah Wolfe
3cea203459 🔥 🎨 Cleanup & simplify theme helpers (#8223)
no issue

🔥 Remove adminHbs concept from tests
🔥 Get rid of unnecessary helper test utils
🔥 Remove helper missing code
- this hasn't been registered / used for ages 😱
- gscan no longer allows us to activate themes that have missing helpers, so this wouldn't be used anyway
TODO: consider whether we should make a way to override this?

🎨 Reduce coupling inside of /helpers
🎨 Use settingsCache in ghost_foot
 Labs util for enabling helpers
🎨 Move loadCoreHelpers to blog
- This needs a proper home, but at the very least it doesn't belong
in server/app.js!

🎨 Use settingsCache in ghost_head
2017-03-23 20:00:58 +01:00
Hannah Wolfe
c9500b11ea 🐛 Set timezone in time related tests (#8214)
closes #8017

- set the timezone, and use moment.tz to get the time now
2017-03-23 13:58:50 +01:00
Hannah Wolfe
317daf5549 🎨 🚨 Split theme tests, clean config & add tests (#8205)
refs #7491

- split themes_spec up into several files
- clean up the code for configuration
- ensure its tested
2017-03-22 07:52:58 +01:00
Katharina Irrgang
e903be6679 🐛 fix favicon path (#8190)
closes #8187

- if you start Ghost via the Ghost-CLI, the path to the favicon must be absolute
- because the CLI spawns a Ghost process from the root folder of the CLI folder e.g. node current/index.js
2017-03-21 11:44:39 +00:00
Hannah Wolfe
495eee7747 Use "mounting" concept for active theme (#8193)
no issue

🔥 Remove DIRTY HACK for API
- this is no longer needed, because themes get mounted in every case

 Switch to concept of 'mounted' theme
- check if active theme is mounted
- if not, mount it
- mounting is a function OF the active theme

🎨 Move theme middleware to theme module

🎨 Update theme middleware function names
- update the function names and comments to be more representative of their current functions
- this was pretty old and out of date!

🚨 Fixup tests for middleware
- ensure the objects match what we expect
- based partially on theme docs

Update TODO
2017-03-21 10:03:09 +01:00
Hannah Wolfe
47e00900cc 💄 🐷 Test consistency (#8199)
no issue

- change out should.equal for // jshint ignore:line
- ensure should is the first require in every test, and ALWAYS require
- make sinon the second require, and sandbox the last thing
- ALWAYS use sandbox, futureproofs tests against contributors who don't know it
- change require formatting
2017-03-21 09:24:11 +01:00
Ryan McCarvill
f61aa662c1 Removed ghost editor dependency (#8137)
refs #7429
- ☢️ 👷🏻‍♀️ This PR removes the dependency on Ghost-Editor and replaces it with the Mobiledoc DOM renderer. It includes new DOM based default cards and atoms.
2017-03-14 18:07:33 +00:00
Hannah Wolfe
3416c05064 Posts per page as theme-config (#8149)
closes #8131

- Remove ppp from default-settings.json
- Remove ppp from meta (unused?\!)
-  Basic concept of theme config
- use theme config ppp setting
-  Make @config.posts_per_page helper available
- rather than @blog.posts_per_page, we now have @config.posts_per_page
- 🚨 Test updates
- Adding TODO note
2017-03-14 18:03:36 +01:00
Hannah Wolfe
b8162b15e3 🐛 Move meta description into ghost head (#8150)
closes #4424

- meta description is an optional SEO tag that we can provide when we have sensible output
- in the cases where we have no useful output, we should not output the tag at all
- ghost_head now takes care of this, and themes should not include their own meta description tag
2017-03-14 17:50:35 +01:00
Hannah Wolfe
f52e3e779b 🎨 Allow foreach else inside of get helper (#8160)
closes #7242

- before this, the get helper's else was used for empty resultsets
- the argument was made that we should fall through to a foreach or with helper's else instead
- I agree that this is the more natural, consistent approach, and so would like to change it for Ghost 1.0

E.g. as of this PR we now have:

{{#get "posts" filter="tag:doesnt-exist"}}
  {{#foreach posts}}
  {{else}}
    this ges executed because there are no results
  {{/foreach}}
{{/get}}

instead of

{{#get "posts" filter="tag:doesnt-exist"}}
  {{#foreach posts}}
  {{else}}
  {{/foreach}}
{{each}}
    this ges executed because there are no results
{{/get}}
2017-03-14 17:44:52 +01:00
Hannah Wolfe
4a6f58d8d1 🙅🏽 Admin server split (#8142)
refs #8140

 Support new default-prod.hbs template for admin
 Redirect ghost admin urls without a #
 Update admin urls to include #
🎨 Move the admin templates
🔥 Remove redirect to setup middleware
🚨 Tests for new middleware
2017-03-14 17:03:30 +01:00
Hannah Wolfe
5605c964e4 🔥 Remove legacy content zero hack (#8156)
refs #7491

- this hack is so legacy I almost forgot about it 😈
- in the beginning of Ghost there were no post images
- someone figured out you could do {{content words="0"}} and it would pull out the first image in your post
- this was never documented, but enough theme developers found it that when we upgraded downsize to get rid of the bug
- we needed to add a hack to keep compatibility.
- This has to die in 🔥  for Ghost 1.0
2017-03-14 14:56:46 +01:00
Hannah Wolfe
27ee1dc7b8 Implement custom errors 2.0 (#8148)
closes #8079

- add a new view type of defaultViews, as this is NOTHING to do with the admin!
- rename user-error.hbs to error.hbs, because this can be for any sort of error
- reimplement custom errors, but with a stack like channels & single templates
- change ghost_head to only not output on 500+ server errors, rather than 400+ user errors
- add coverage for the new template functions
2017-03-14 10:06:42 +01:00
Hannah Wolfe
bb3cc8c0f8 Reimplement custom theme templates (#8147)
closes #8082

- Update the `pickTemplate` logic to
  a) rely on getActive().hasTemplate() instead of being passed a list of paths
  b) support the concept of a fallback, which is returned if there is no theme, or if the theme doesn't have a more specific template
- Update every instance of template picking, across the 3 internalApps, and render-channel, to use this new logic
- update the tests
2017-03-14 00:15:50 +01:00
Hannah Wolfe
b06f03b370 New fully-loaded & validated activeTheme concept (#8146)
📡 Add debug for the 3 theme activation methods
There are 3 different ways that a theme can be activated in Ghost:

A. On boot: we load the active theme from the file system, according to the `activeTheme` setting
B. On API "activate": when an /activate/ request is triggered for a theme, we validate & change the `activeTheme` setting
C. On API "override": if uploading a theme with the same name, we override. Using a dirty hack to make this work.

A: setting is done, should load & validate + next request does mounting
B: load is done, should validate & change setting + next request does mounting
C: load, validate & setting are all done + a hack is needed to ensure the next request does mounting

 Validate w/ gscan when theme activating on boot
- use the new gscan validation validate.check() method when activating on boot

 New concept of active theme
- add ActiveTheme class
- make it possible to set a theme to be active, and to get the active theme
- call the new themes.activate() method in all 3 cases where we activate a theme

🎨 Use new activeTheme to simplify theme code
- make use of the new concept where we can, to reduce & simplify code
- use new hasPartials() method so we don't have to do file lookups
- use path & name getters to reduce use of getContentPath etc
- remove requirement on req.app.get('activeTheme') from static-theme middleware (more on this soon)

🚨 Improve theme unit tests (TODO: fix inter-dep)
- The theme unit tests are borked! They all pass because they don't test the right things.
- This improves them, but they are still dependent on each-other
- configHbsForContext tests don't pass if the activateTheme tests aren't run first
- I will fix this in a later PR
2017-03-13 21:13:17 +01:00
Katharina Irrgang
7556e68c48 🎨 Ghost bootstrap: optimise requires (#8121)
* 🎨  Ghost bootstrap: optimise requires

no issue

- require as less as possible on bootstrap

* do not load icojs on bootstrap
2017-03-13 20:07:12 +00:00
Hannah Wolfe
e060a4f811 🎨 🐛 Improve theme lib, middleware & error handling (#8145)
no issue

🎨 simplify loader - use loadOneTheme for init
- use loadOneTheme for init
- move updateThemeList to the one place that it is used
- this just reduces the surface area of the loader

🎨 Move init up to index temporarily
- need to figure out what stuff goes in here as well as loading themes
- will move it again later once I've got it figured out

🎨 Reorder & cleanup theme middleware
- move the order in blog/app.js so that theme middleware isn't called for shared assets
- add comments & cleanup in the middleware itself, for clarity

🎨 Simplify the logic in themes middleware
- Separate out config dependent on settings changing and config dependent on request
- Move blogApp.set('views') - no reason why this isn't in the theme activation method as
  it's actually simpler if it is there, we already know the active theme exists & can remove the if-guard

🎨 Improve error handling for missing theme
- ensure we display a warning
- don't have complex logic for handling errors
- move loading of an empty hbs object into the error-handler as this will support more cases

🐛 Fix assetHash clearing bug on theme switch
- asset hash wasn't correctly being set on theme switch

🎨 Remove themes.read & test loader instead
- Previously, we've simplified loader & improved error handling
- We are now able to completely remove theme.read as it's nothing more than a wrapper for package.read
- This also means we can change our tests from testing the theme reader to loader
2017-03-13 17:30:35 +01:00
Katharina Irrgang
c9f551eb96 suspend user feature (#8114)
refs #8111 
- Ghost returns now all (active+none active) users by default
- protect login with suspended status
- test permissions and add extra protection for suspending myself
- if a user is suspended and tries to activate himself, he won't be able to proceed the login to get a new token
2017-03-13 12:03:26 +00:00
Hannah Wolfe
b2f1d0559b Themes API activation permissions & validation (#8104)
refs #8093

 Add activate theme permission
- add permission to activate themes
- update tests
- also: update tests for invites
TODO: change how the active theme setting is updated to reduce extra permissions

 Move theme validation to gscan
- add a new gscan validation method and use it for upload
- update activate endpoint to do validation also using gscan
- change to using SettingsModel instead of API so that we don't call validation or permissions on the settings API
- remove validation from the settings model
- remove the old validation function
- add new invalid theme message to translations & remove a bunch of theme validation related unused keys

📖  Planned changes

🚨 Tests for theme activation API endpoint
🐛 Don't allow deleting the active theme

🚫 Prevent activeTheme being set via settings API
- We want to control how this happens in future.
- We still want to store the information in settings, via the model.
- We just don't want to be able to change this info via the settings edit endpoint

🐛  Fix warnings for uploads & add for activations
- warnings for uploads were broken in f8b498d
- fix the response + adds tests to cover that warnings are correctly returned
- add the same response to activations + more tests
- activations now return a single theme object - the theme that was activated + any warnings

🎨 Improve how we generate theme API responses
- remove the requirement to pass in the active theme!
- move this to a specialist function, away from the list

🎨 Do not load gscan on boot
2017-03-13 12:44:44 +01:00
Katharina Irrgang
27f17c973d 🎨 handle case: sync email after logout (#8097)
no issue

If the user changes the email in the remote auth service and executes a logout directly afterwards, the user would lock himself out of his blog, because the email sync happens once per hour right now.
For that case, we have to store the ghost auth id.
2017-03-08 14:31:22 +00:00
Katharina Irrgang
27e659a21e 🐛 export database read settings from database (#8103)
* 🐛  export database read settings from database

no issue

- the backup script uses the export database lib and is broken if knex-migrator is called via shell, the settings cache is not loaded
- i have changed the export database lib to read the settings key directly from the db

* use get('value')
2017-03-08 10:26:57 +00:00
Katharina Irrgang
efe24fa9ec 🐛 subscriber: sanitize email (#8078)
no issue
2017-03-03 15:44:07 +01:00
Hannah Wolfe
e3c82c1643 🎨 Use settingsCache in theme handler (#8091)
no issue

- we already have the settingsCache here, makes no sense to call the API
2017-03-02 23:05:35 +01:00
Katharina Irrgang
9fafc38b79 🎨 deny auto switch (#8086)
* 🎨  deny auto switch

no issue

- deny auth switch after the blog was setup
- setup completed depends on the status of the user right now, see comments

* Updates from comments

- re-use statuses in user model
- update error message
2017-03-02 19:50:58 +00:00
Hannah Wolfe
f8b498d6e7 🔥 No more availableThemes (#8085)
no issue

🎨 Switch themes API to use config.availableThemes
- this gets rid of the only places where settings.availableThemes are used

🔥 Get rid of settings.availableThemes
- this is no longer used anywhere
- also get rid of every related call to updateSettingsCache

🔥 Replace config.availableThemes with theme cache
- Creates a tailor-made in-memory cache for themes inside the theme module
- Add methods for getting & setting items on the cache
- Move all references to config.availableThemes to use the new cache
- This can be abstracted later to support other kinds of caches?

🎨 Start improving theme lib's API
Still TODO: simplifying/clarifying:
- what is the structure of the internal list
- what is the difference between a package list, and a theme list?
- what is the difference between reading a theme and loading it?
- how do we update the theme list (add/remove)
- how do we refresh the theme list? (hot reload?!)
- how do we get from an internal list, to one that is sent as part of the API?
- how are we going to handle theme storage: read/write, such that the path is configurable

🎨 Use themeList consistently
🎨 Update list after storage
2017-03-02 17:53:48 +01:00
Hannah Wolfe
c70fbc2c7e 🎨 Collect & simplify package utils (#8080)
closes #8056

🎨 Collect together the package-related utils
- read directory actually reads a directory of packages
- parse package json is very tighly related to this

🎨 Move filterPaths -> packages.filterPackages
- this function is related to packages, not settings
- move the function to the new utils/packages
- add 100% test coverage

🎨 Simplify filterPackages code
🎨 Simplify reading of packages & themes
- This massively reduces all the complex code in the read packages & themes utils
- Added full test coverage

🎨 Improve & clarify active prop in filterPackages
- active is returned from API endpoints to combine data from multiple sources
- see https://github.com/TryGhost/Ghost/pull/8064#discussion_r103514810

🎨 Better error handling
🔥 Temporarily remove custom error templates
- we will reimplement this later when we have got a better concept of loading the active theme in place
- refs #8079
2017-03-01 14:09:31 +01:00
Katharina Irrgang
fa38257170 🐛 🎨 old accesstokens are not cleaned up (#8065)
closes #8035
- create auth/utils
- use authUtils.createTokens for all cases
- decrease the expiry of the old access token before creating a new one
2017-03-01 10:12:03 +00:00
Hannah Wolfe
690ff05588 🔥 🎨 Themes & settings misc cleanup (#8061)
no issue

🔥 remove unused loadThemes API method
🚨 Add tests for themes.readOne
🔥 Don't update settings cache for imports
- this isn't needed as of #8057
- settings.edit fires an event, that will result in the update happening automatically
🎨 Move validation to themes
- slowly collecting all theme-related code together
🔥 Reduce DEBUG output
- all this info is a bit tooooo much!
2017-02-27 23:30:49 +01:00
Hannah Wolfe
63723aa36a 🎨 Move settings cache & cleanup settings API (#8057)
closes #8037

🔥 Remove API-level default settings population
- This is a relic!
- We ALWAYS populate defaults on server start therefore this code could never run.
- This was a lot of complicated code that wasn't even needed!!

🎨 Move settings cache
- Move settings cache to be its own thing
- Update all references
- Adds TODOs for further cleanup

🎨 Create settings initialisation step
- Create new settings library, which will eventually house more code
- Unify the interface for initialising settings (will be more useful later)
- Reduce number of calls to updateSettingsCache
2017-02-27 16:53:04 +01:00
Hannah Wolfe
fe90cf2be2 Theme loading part 1 (#7989)
no issue

*  Add new server start & stop events
* 🔥 Get rid of unused availableApps concept
- when we need an API endpoint for a list of apps, we'll build one 😝
*  Move theme loading into a module
- move loading from API method to a module method and use as needed
- wire up read one vs read all as per LTS
- read one (the active theme) on boot, and read the rest after
- fudge validation - this isn't all that helpful
* Settings API tests need to preload themes
- this used to automatically happen as part of loading settings
- now we need to trigger this to happen specifically for this test
2017-02-22 00:26:19 +01:00
Katharina Irrgang
2e1d7fcc42 🚨 database: change hard limits and field types (#7932)
refs #7432

🚨  database: change hard limits and field types

- we went over all schema fields and decided to decrease/increase the hard limits
- the core goal is to have more flexibility in the future
- we reconsidered string vs. text

There are 5 groups:

- small strings: 50 characters
    - static strings
    - status, visibility, language, role name, permission name, client name etc.
- medium strings: 191 characters
    - all unique fields or fields which can be unique in the future
    - slug, tokens, user name, password, tag name, email
- large strings: 1000-2000 characters
    - these fields need to be very flexible
    - these fields get a soft limit attached (in a different PR)
    - post title, meta title, meta description, urls
- medium text: 64kb characters
    - bio, settings, location, tour
- long text: 1000000000 chars
    - html, amp, mobiledoc, markdown

🙄  sort_order for tests

- sort order was not set for the tests, so it was always 0
- mysql could return a different result

in my case:
- field length 156 returned the following related tags ["bacon", "kitchen"]
- field length 157 returned the following related tags ["kitchen", "kitchen"]

Change client.secret to 191

Tweak field lengths

- Add 24 char limit for ids
- Limited fields are the exact length they need
- Unified 1000 and 2000 char string classes to all be 2000
- Changed descriptions to be either 2000, except user & tag which is text 65535 as these may be used to store HTML later?!
- Updated tests

🛠  Update importer tests

- The old 001-003 tests are kind of less relevant now.
- Rather than worrying about past versions of the data structure, we should check that the importer only imports what we consider to be valid data
- I've changed the tests to treat the title-length check as a length-validation check, rather than a test for each of the old versions

🔥 Remove foreign key from subscribers.post_id

- There's no real need to have an index on this column, it just makes deleting posts hard.
- Same as created_by type columns, we can reference ids without needing keys/indexes
2017-02-17 23:20:59 +01:00
Katharina Irrgang
d9707eb57c public client registration: remember auth url (#7994)
no issue

- we have to remember the auth url in Ghost
- if Ghost starts for the first time, it registers a public client in the defined auth service
- if you change the auth service, Ghost won't recognize
- if Ghost doesn't recognize, you will see a client does not exist error in Ghost Admin
2017-02-14 12:41:28 +00:00
Katharina Irrgang
7bc546c698 🎹 re-work url redirects (#7956)
refs #7488

- we have recently changed our url redirects
- see https://github.com/TryGhost/Ghost/pull/7937
- the url has a canonical meaning and that's why Ghost shouldn't force redirect to the blog url
2017-02-10 11:42:18 +00:00
Katharina Irrgang
f3d16352b1 🎨 😎 config env usages (#7929)
refs #7488

- remove all ugly env checks
- rather use config properties
- replace process.env.NODE_ENV by config.get('env')
2017-02-03 18:25:39 +00:00
Katharina Irrgang
a68592a6b9 🔥 remove forceAdminSSL and urlSSL, add admin url (#7937)
* 🔥  kill apiUrl helper, use urlFor helper instead

More consistency of creating urls.
Creates an easier ability to add config changes.

Attention: urlFor function is getting a little nesty, BUT that is for now wanted to make easier and centralised changes to the configs.
The url util need's refactoring anyway.

* 🔥  urlSSL

Remove all urlSSL usages.
Add TODO's for the next commit to re-add logic for deleted logic.

e.g.

- cors helper generated an array of url's to allow requests from the defined config url's -> will be replaced by the admin url if available
- theme handler prefered the urlSSL in case it was defined -> will be replaced by using the urlFor helper to get the blog url (based on the request secure flag)

The changes in this commit doesn't have to be right, but it helped going step by step.
The next commit is the more interesting one.

* 🔥    remove forceAdminSSL, add new admin url and adapt logic

I wanted to remove the forceAdminSSL as separate commit, but was hard to realise.
That's why both changes are in one commit:

1. remove forceAdminSSL
2. add admin.url option

- fix TODO's from last commits
- rewrite the ssl middleware!
- create some private helper functions in the url helper to realise the changes
- rename some wordings and functions e.g. base === blog (we have so much different wordings)
- i would like to do more, but this would end in a non readable PR
- this commit contains the most important changes to offer admin.url option

* 🤖  adapt tests

IMPORTANT
- all changes in the routing tests were needed, because each routing test did not start the ghost server
- they just required the ghost application, which resulted in a random server port
- having a random server port results in a redirect, caused by the ssl/redirect middleware

* 😎  rename check-ssl middleware

* 🎨  fix theme-handler because of master rebase
2017-02-03 18:13:22 +00:00
Katharina Irrgang
2a52af1d99 🔥 remove imageRelPath (#7927)
refs #7488

- remove imageRelPath
- instead add a static image prefix to the url helper
2017-02-03 14:42:05 +00:00
Katharina Irrgang
0201c431d7 🔥 do not store settings in config (#7924)
* 🎨  🔥  do not store settings in config and make settings cache easier available

- remove remembering settings value in theme config
- if we need a cache value, we are asking the settings cache directly
- instead of settings.getSettingSync we use settings.cache.get

- added TODO:
  - think about moving the settings cache out of api/settings
  - we could create a folder named cache cache/settings
  - this settings cache listens on model changes for settings
  - decoupling

* 🔥  remove timezone from config

- no need to store in overrides config and in defaults settings

* 🎨  context object helper

- replace config.get('theme') by settings cache

* 🎨  replace config.get('theme') by settings.cache.get

* 🎨  adapt tests

* fixes from comments
2017-02-03 13:15:11 +00:00
Katharina Irrgang
16f5d1fdaf 🎨 add urlFor('admin') and increase usage of urlFor helper (#7935)
refs #7488

- to be able to refactor the url configuration in ghost, we need to go step by step making this possible
- reduce the usage of forceAdminSSL
- add a urlFor('admin') helper, which returns the admin url + path e.g. http://my-blog.com/blog/ghost
- increase usage of urlFor helper
- do not expose getBaseUrl, use urlFor('home') (home === blog)
2017-02-02 18:51:35 +00:00
Katharina Irrgang
85c0913d70 🎨 config optimisations (#7921)
refs #7488

- rename file keys for config files, see https://github.com/TryGhost/Ghost/pull/7493/files
- add tests to avoid running into config hierarchy problems again
- overrides.json is the strongest!
- argv/env can override any default
- custom config can override defaults
- reorganise util functions for config again
2017-02-02 12:46:30 +00:00
Aileen Nowak
89d40133a0 💄 Clean up ghost_head test (#7918)
refs #7688

Update the `ghost_head_spec` to reflect the current changes (we're not having a default `icon` setting in our config anymore). Render the link to the default favicon to be relative.
2017-01-30 09:54:40 +01:00
Aileen Nowak
d2f2888da0 Favicon URI (#7700)
closes #7688

- Use `/favicon.ico` and `/favicon.png` in blog app. Depending on type of storage (custom upload = local file storage), serves either from storage adapter with `read()` method or reads the bytes via `fs`.
- Redirects requests for `favicon.ico` to `favicon.png` if custom `png` icon is uploaded and vice versa.
- Redirect requests for `favicon.png` to `favicon.ico` if default icon is used (in `core/shared`).
- Changes the `{{asset}}` helper for favicon to not serve from theme assets anymore. It will either be served the custom blog-icon or the default one.
- The `{{@blog.icon}}` helper renders the url of the **uploaded** blog icon. It won't render the default icon.
2017-01-26 18:01:19 +00:00
Katharina Irrgang
584bd15b76 🔥 remove database version (#7894)
refs #7489

- as we are now using a different migration approach (knex-migrator), we don't need to remember the database version anymore
- it was once used to check the state of a database and based on it we decided to migrate or not
- with knex-migrator everything depends on the migration table entries and the current ghost version you are on
- on current master the leftover usage is to add the db version when exporting the database, which can be replaced by reading the ghost version
- removing this solves also an interesting migration case with knex-migrator:
  - you are on 1.0
  - you update to 1.1, but 1.1 has no migrations
  - the db version would remain in 1.0
  - because the db version was only updated when knex migrator executed a migration
2017-01-26 12:12:00 +00:00
Katharina Irrgang
c070c9722d 🐛 re-run init migrations protection (#7899)
no issue

- if re-running the init scripts (for example: you lost the init rows in the migrations table), then it was throwing errors
- 1. the owner slug and email can change -> no match and it tried to reinsert the user with id 1, which failed
- 2. querying an inactive user is not allowed, because the user model protects against it
2017-01-25 22:08:09 +01:00
Katharina Irrgang
0424c6675c 🐛 fix backup database (#7898)
refs #7489

The require path for the db backup was wrong. The before hook could not execute db backup.
Furthermore, i have replaced the logging in the backup script.
2017-01-25 20:34:31 +01:00
Katharina Irrgang
2d19ae2c6c 🔥 😎 remove old migrations (#7887)
refs #7489

- remove old migration code
- this logic was sourced out to knex-migrator
2017-01-25 13:47:49 +00:00
Aileen Nowak
ca521e234f 🐷 Rename 'favicon' to 'icon' (#7888)
refs TryGhost/Ghost#7688

Just renames `favicon` to `icon` as our usage for it will not be for favicon purposes only.
2017-01-25 11:02:02 +01:00
Katharina Irrgang
78eacb19e9 🛠 use Ignition for logging/errors (#7869)
no issue

- we started implementing logging and error handling in Ghost
- later we outsourced both into a module
- use the module now in Ghost
- this commit basically just removes the logging and error implementation and uses Ignition
2017-01-23 11:04:01 +00:00
Aileen Nowak
7cb57bff3d Find favicon in Ghost (#7713)
refs #7688

Adds logic in theme settings api to either serve an uploaded favicon and give it the type `upload` or use the default settings `default`, which will serve the favicon from our shared directory.

TODOs for #7688:
- [X] Figure out, which favicon should be used (uploaded or default) -> this PR
- [ ] Serve and redirect the favicon for any browser requests, incl. redirects
- [ ] Upload favicon via `general/settings` and implement basic admin validations -> [WIP] TryGhost/Ghost-Admin#397
- [ ] Built server side validations
2017-01-23 10:13:52 +01:00
Aileen Nowak
503148058c More consistant usage of urlFor('home') (#7689)
refs #7666 

Using `urlFor('home')` instead `config.get('url')` in Ghost.
When `urlFor('home', true)` returns the absolute adress of the blog as defined in the config.
Will always return a trailing `/`.
2017-01-23 09:22:37 +01:00
Aileen Nowak
2f3081fa9f Make AMP optional (#7830)
closes #7769

Because Google AMP is bitching around and shows errors in Googles' webmaster tools for missing post images and blog icons, we decided to make AMP optional. It will be enabled by default, but can be disabled in general settings. Once disabled, the `amp` route doesn't work anymore.

This PR contains the back end changes for Ghost-alpha:
- Adds `amp` to settings table incl default setting `true`
- Adds `amp` value to our settings cache
- Changes the route handling of AMP app to check for the `amp` setting first.
- Adds tests to check the route handling and ghost_head output
- Includes changes to `post-lookup.js` as done by @kirrg001 in #7842
2017-01-17 16:40:06 +01:00
Kevin Ansfield
8d88f5b6a5 urlencode navigation URLs rather than HTML escape (#7836)
closes #7826

- expose raw url value inside `{{navigation}}` helper
- modify `{{url}}` helper to urlencode values and mark as HTML-safe to avoid Handlebars additional HTML-escaping
2017-01-17 15:55:19 +01:00
Katharina Irrgang
8031102596 🎨 escape sameAs for structured data (#7833)
closes #7832

- escape output for json-ld
2017-01-10 12:21:37 +00:00
Aileen Nowak
7cd13e6122 🔑 Update Validator to 6.2.1 (#7823)
no issue

Uses new version of [validator](https://github.com/chriso/validator.js) which checks also for in URL embedded script tags.
2017-01-10 13:05:25 +01:00
Marc Bachmann
353330bb8a chore(package): update uuid to version 3.0.0 (#7742) 2017-01-04 17:10:29 +01:00
David Wolfe
e2bbf7d206 Fix brute for token exchanges (#7725)
closes #7722

- fixes issue where token exhanges are logged with an undefined email address causing lockouts
- use more relevant translations for errors
2016-11-17 14:02:56 +01:00
Katharina Irrgang
7eb316b786 replace auto increment id's by object id (#7495)
* 🛠  bookshelf tarball, bson-objectid

* 🎨  schema changes

- change increment type to string
- add a default fallback for string length 191 (to avoid adding this logic to every single column which uses an ID)
- remove uuid, because ID now represents a global resource identifier
- keep uuid for post, because we are using this as preview id
- keep uuid for clients for now - we are using this param for Ghost-Auth

*   base model: generate ObjectId on creating event

- each new resource get's a auto generate ObjectId
- this logic won't work for attached models, this commit comes later

* 🎨  centralised attach method

When attaching models there are two things important two know

1. To be able to attach an ObjectId, we need to register the `onCreating` event the fetched model!This is caused by the Bookshelf design in general. On this target model we are attaching the new model.
2. We need to manually fetch the target model, because Bookshelf has a weird behaviour (which is known as a bug, see see https://github.com/tgriesser/bookshelf/issues/629). The most important property when attaching a model is `parentFk`, which is the foreign key. This can be null when fetching the model with the option `withRelated`. To ensure quality and consistency, the custom attach wrapper always fetches the target model manual. By fetching the target model (again) is a little performance decrease, but it also has advantages: we can register the event, and directly unregister the event again. So very clean code.

Important: please only use the custom attach wrapper in the future.

* 🎨  token model had overriden the onCreating function because of the created_at field

- we need to ensure that the base onCreating hook get's triggered for ALL models
- if not, they don't get an ObjectId assigned
- in this case: be smart and check if the target model has a created_at field

* 🎨  we don't have a uuid field anymore, remove the usages

- no default uuid creation in models
- i am pretty sure we have some more definitions in our tests (for example in the export json files), but that is too much work to delete them all

* 🎨  do not parse ID to Number

- we had various occurances of parsing all ID's to numbers
- we don't need this behaviour anymore
- ID is string
- i will adapt the ID validation in the next commit

* 🎨  change ID regex for validation

- we only allow: ID as ObjectId, ID as 1 and ID as me
- we need to keep ID 1, because our whole software relies on ID 1 (permissions etc)

* 🎨  owner fixture

- roles: [4] does not work anymore
- 4 means -> static id 4
- this worked in an auto increment system (not even in a system with distributed writes)
- with ObjectId we generate each ID automatically (for static and dynamic resources)
- it is possible to define all id's for static resources still, but that means we need to know which ID is already used and for consistency we have to define ObjectId's for these static resources
- so no static id's anymore, except of: id 1 for owner and id 0 for external usage (because this is required from our permission system)
- NOTE: please read through the comment in the user model


* 🎨  tests: DataGenerator and test utils

First of all: we need to ensure using ObjectId's in the tests. When don't, we can't ensure that ObjectId's work properly.
This commit brings lot's of dynamic into all the static defined id's.
In one of the next commits, i will adapt all the tests.

* 🚨  remove counter in Notification API

- no need to add a counter
- we simply generate ObjectId's (they are auto incremental as well)
- our id validator does only allow ObjectId as id,1 and me

* 🎨  extend contextUser in Base Model

- remove isNumber check, because id's are no longer numbers, except of id 0/1
- use existing isExternalUser
- support id 0/1 as string or number

*   Ghost Owner has id 1

- ensure we define this id in the fixtures.json
- doesn't matter if number or string

* 🎨  functional tests adaptions

- use dynamic id's

* 🎨  fix unit tests

* 🎨  integration tests adaptions

* 🎨  change importer utils

- all our export examples (test/fixtures/exports) contain id's as numbers
- fact: but we ignore them anyway when inserting into the database, see https://github.com/TryGhost/Ghost/blob/master/core/server/data/import/utils.js#L249
- in 0e6ed957cd (diff-70f514a06347c048648be464819503c4L67) i removed parsing id's to integers
- i realised that this ^ check just existed, because the userIdToMap was an object key and object keys are always strings!
- i think this logic is a little bit complicated, but i don't want to refactor this now
- this commit ensures when trying to find the user, the id comparison works again
- i've added more documentation to understand this logic ;)
- plus i renamed an attribute to improve readability

* 🎨  Data-Generator: add more defaults to createUser

- if i use the function DataGenerator.forKnex.createUser i would like to get a full set of defaults

* 🎨  test utils: change/extend function set for functional tests

- functional tests work a bit different
- they boot Ghost and seed the database
- some functional tests have mis-used the test setup
- the test setup needs two sections: integration/unit and functional tests
- any functional test is allowed to either add more data or change data in the existing Ghost db
- but what it should not do is: add test fixtures like roles or users from our DataGenerator and cross fingers it will work
- this commit adds a clean method for functional tests to add extra users

* 🎨  functional tests adaptions

- use last commit to insert users for functional tests clean
- tidy up usage of testUtils.setup or testUtils.doAuth

* 🐛  test utils: reset database before init

- ensure we don't have any left data from other tests in the database when starting ghost

* 🐛  fix test (unrelated to this PR)

- fixes a random failure
- return statement was missing

* 🎨  make changes for invites
2016-11-17 09:09:11 +00:00
Hannah Wolfe
4a2ddbe2ae Merge pull request #7701 from kirrg001/1.0.0-dev/fix-brute-schema
🐛  fix brute
2016-11-14 14:34:31 +00:00
Hannah Wolfe
928654bd20 Merge pull request #7699 from kirrg001/1.0.0-dev/read-bytes-storage
  add read method to local file storage
2016-11-14 12:52:52 +00:00
kirrg001
049b26e67c 🐛 err.next is not always present
- see https://github.com/AdamPflug/express-brute/issues/45
- we have to handle two cases ATM: with and without callback
- in case we call the lib synchronous (which we should not actually), we will log the error so we get informed
2016-11-10 12:23:34 +01:00
kirrg001
e97d59cc58 add read method to local file storage
refs #7688

- add a read method to our local file storage
- reads the bytes of a target image
- breaking change to storage adapters
2016-11-09 11:31:56 +01:00
kirrg001
d7c8da7ee8 small error improvements
no issue

- in Ignition we have added keeping the original stack, i copied it over
- i would like to use Ignition in Ghost asap to avoid having inconsistencies
- added support for options.err is a string
- extend tests
2016-11-09 09:22:33 +01:00
Katharina Irrgang
0a744c2781 🎨 public client registration updates (#7690)
* 🎨  use updateClient function to update redirectUri

refs #7654

* 🎨  name instead of clientName
* 🎨  config.get('theme:title') for client name

- initial read can happen from config

*   register public client: client name and description

- no update yet
- for initial client creation
- we forward title/description to Ghost Auth
- TODO: use settings-cache when merged

*   store blog_uri in db
* 🎨  passport logic changes

- use updateClient instead of changeCallbackURL
- be able to update: blog title, blog description, redirectUri and blogUri
- remove retries, they get implemented in passport-ghost soon
- reorder logic a bit

* 🛠  passport-ghost 1.2.0

* 🎨  tests: extend DataGenerator createClient

- set some defaults

* 🎨  tests

- extend tests
- 👻

*   run auth.init in background

- no need to block the bootstrap process
- if client can't be registered, you will see an error
- ensure Ghost-Admin renders correctly

* 🛠   passport-ghost 1.3.0

- retries

* 🎨  use client_uri in Client Schema

- adapt changes
- use blog_uri only when calling the passport-ghost instance
- Ghost uses the client_uri notation to improve readability

*   read blog title/description from settings cache

* 🚨  Ghost Auth returns email instead of email_address

- adapt Ghost
2016-11-08 14:21:25 +00:00
Katharina Irrgang
3aac3ef6de 🎨 make settings cache available (#7692)
* 🎨  settingsCache is available

- do not destroy the object reference
- added TODO to reconsider the config values for theme
- get one or all cached settings

* 🚨  remove api.init

- this functiion has just wrapped a function to update the settings cache
- if we have multiple tasks todo later, we can re-add
- but for now: this is way easier to read
- adapt test

* 🎨  tests
2016-11-08 13:37:19 +00:00
David Wolfe
68af2145a1 Replace memory spam prevention with brute-express (#7579)
no issue

- removes count from user checks model
- uses brute express brute with brute-knex adaptor to store persisted data on spam prevention
- implement brute force protection for password/token exchange, password resets and private blogging
2016-11-08 12:33:19 +01:00
Katharina Irrgang
bae0de6cd5 knex-migrator v2 (#7605)
* 🎨  knex-migrator reset

[ci skip]

*   add migration example

- hooks
- 1.0

[ci skip]

* 🛠  knex-migrator tarball

- remove when released

[ci skip]

* 🎨  jscs/jshint

* 🕵🏻 do not drop the database connection when running tests

- please read the comments in the commit

* 🔥  remove example migration

* 🛠  knex-migrator 0.1.0

* 🛠  knex-migrator 0.1.1

- fix a single test to ensure we catch the error

* 🛠  knex-migrator 0.1.2

* 🎨  make tests green

- added my keyword: kate-migrations
- i will go over all TODO's when removing the old migrations code

* 🛠  knex-migrator update

* 🛠  knex-migrator 0.2.0
2016-11-07 11:39:49 +00:00
Katharina Irrgang
a19fa8d3ac Ghost Auth: register client with blog_uri (#7680)
* 🛠  passport-ghost 1.1.0

*   register client: add blog_uri

refs #7654

- improve readability
- get rid of all the url util usages
- add blog_uri

[ci skip]

* 🎨  tests
2016-11-07 11:38:05 +00:00
Katharina Irrgang
4e7779b783 🎨 remove token logic from user model (#7622)
* 🔥  remove User model functions

- validateToken
- generateToken
- resetPassword
- all this logic will re-appear in a different way

Token logic:
- was already extracted as separate PR, see https://github.com/TryGhost/Ghost/pull/7554
- we will use this logic in the controller, you will see in the next commits

Reset Password:
Was just a wrapper for calling the token logic and change the password.
We can reconsider keeping the function to call: changePassword and activate the status of the user - but i think it's fine to trigger these two actions from the controlling unit.

* 🔥  remove password reset tests from User model

- we already have unit tests for change password and the token logic
- i will re-check at the end if any test case is missing - but for now i will just burn the tests

*   add token logic to controlling unit

generateResetToken endpoint
- the only change here is instead of calling the User model to generate a token, we generate the token via utils
- we fetch the user by email, and generate a hash and return

resetPassword endpoint
- here we have changed a little bit more
- first of all: we have added the validation check if the new passwords match
- a new helper method to extract the token informations
- the brute force security check, which can be handled later from the new bruteforce middleware (see TODO)
- the actual reset function is doing the steps: load me the user, compare the token, change the password and activate the user
- we can think of wrapping these steps into a User model function
- i was not sure about it, because it is actually part of the controlling unit

[ci skip]

* 🎨  tidy up

- jscs
- jshint
- naming functions
- fixes

*   add a test for resetting the password

- there was none
- added a test to reset the password

* 🎨  add more token tests

- ensure quality
- ensure logic we had

* 🔥  remove compare new password check from User Model

- this part of controlling unit

*   compare new passwords for user endpoint

- we deleted the logic in User Model
- we are adding the logic to controlling unit

* 🐛  spam prevention forgotten can crash

- no validation happend before this middleware
- it just assumes that the root key is present
- when we work on our API, we need to ensure that
  1. pre validation happens
  2. we call middlewares
  3. ...

* 🎨  token translation key
2016-11-07 11:18:50 +00:00
Katharina Irrgang
0e13ef8767 🎨 logging improvements (#7597)
* 🎨  rotation config
  - every parameter is configureable
  - increase default number of files to 100
* 🎨  ghost.log location
  - example: content/logs/http___my_ghost_blog_com_ghost.log
  - user can change the path to something custom by setting logging.path
* 🛠   add response-time as dependency
* 🎨  readable PrettyStream
  - tidy up
  - generic handling (was important to support more use cases, for example: logging.info({ anyKey: anyValue }))
  - common log format
  - less code 🕵🏻
* 🎨  GhostLogger cleanup
  - remove setLoggers -> this function had too much of redundant code
  - instead: add smart this.log function
  - remove logging.request (---> GhostLogger just forwards the values, it doesn't matter if that is a request or not a request)
  - make .warn .debug .info .error small and smart
* 🎨  app.js: add response time as middleware and remove logging.request
* 🎨  setStdoutStream and setFileStream
  - redesign GhostLogger to add CustomLoggers very easily

----> Example CustomLogger

function CustomLogger(options) {
  // Base iterates over defined transports
  // EXAMPLE: ['stdout', 'elasticsearch']
  Base.call(this, options);
}
util.inherits(...);

// OVERRIDE default stdout stream and your own!!!
CustomLogger.prototype.setStdoutStream = function() {}

// add a new stream
// get's called automatically when transport elasticsearch is defined
CustomLogger.prototype.setElasticsearchStream = function() {}

* 🎨  log into multiple file by default
  - content/logs/domain.error.log --> contains only the errors
  - content/logs/domain.log --> contains everything
  - rotation for both files
* 🔥  remove logging.debug and use npm debug only
*   shortcuts for mode and level
* 🎨  jshint/jscs
* 🎨  stdout as much as possible for an error
* 🎨  fix tests
* 🎨  remove req.ip from log output, remove response-time dependency
* 🎨  create middleware for logging
  - added TODO to move logging middleware to ignition
2016-10-25 12:17:43 +01:00
Katharina Irrgang
cccd8c4f8f change ghost client redirect_uri (#7595)
closes #7580
2016-10-21 16:08:17 +01:00
Katharina Irrgang
8bcd000829 🐛 GhostError needs to inherit from Error (#7582)
no issue
2016-10-19 15:27:22 +01:00
Katharina Irrgang
fd0a08ae8c 🎨 make sqlite filename absolute (#7585)
no issue

- add tests for makePathsAbsolute
- add support for windows paths

When Ghost-CLI inits the database of the current GhostVersion (in /current), then it uses knex-migrator to do that.
Knex migrator is reading the .knex-migrator file of the current Ghost version. This returns a relative path to the database location.
The problem: knex-migrator will init the database in the root folder of Ghost-CLI /content/data instead of /current/content . And when you start Ghost (ghost start), it always complains that
that database is not initialised, because it expects the database in /current/content...

* 🎨  move config_spec to config/index_spec
- add one more test case
2016-10-18 09:04:44 +01:00
Katharina Irrgang
8d8d7bdb26 knex migrator (#7565)
refs #7489
- remove sephiroth
- use knex migrator npm
- goodbye bootup script
- 🎨  update README
- 🎨  knex migrator @ 0.0.2
2016-10-17 13:50:29 +01:00
Katharina Irrgang
4056a6da4a 🎨 one token endpoint (#7571)
* 🎨  one token endpoint

refs #7562
- delete /authentication/ghost
- Ghost-Admin will use /authentication/token for all use cases (password, refresh token and ghost.org authorization code)
- add new grant_type `authorization_code`

* 🎨  update comment description and remove spamPrevention.resetCounter
2016-10-17 12:45:50 +02:00
Hannah Wolfe
03e4acdb37 🐛 Subscribers: validate urls (#7540)
no issue

- Ensure URLs submitted via form are sanitized so that we only accept real urls
- Add some tests for the isEmptyOrURL validator
2016-10-14 16:31:20 +02:00
Hannah Wolfe
4411f8254f 🎉 🎨 Remove middleware/index.js (#7548)
closes #4172, closes #6948, refs #7491, refs #7488, refs #7542, refs #7484

* 🎨 Co-locate all admin-related code in /admin
- move all the admin related code from controllers, routes and helpers into a single location
- add error handling middleware explicitly to adminApp
- re-order blogApp middleware to ensure the shared middleware is mounted after the adminApp
- TODO: rethink the structure of /admin, this should probably be an internal app

* 💄 Group global middleware together

- There are only a few pieces of middleware which are "global"
- These are needed for the admin, blog and api
- Everything else is only needed in one or two places

*  Introduce a separate blogApp

- create a brand-new blogApp
- mount all blog/theme only middleware etc onto blogApp
- mount error handling on blogApp only

* 🎨 Separate error handling for HTML & API JSON

- split JSON and HTML error handling into separate functions
- re-introduce a way to not output the stack for certain errors
- add more tests around errors & an assertion framework for checking JSON Errors
- TODO: better 404 handling for static assets

Rationale:

The API is very different to the blog/admin panel:
 - It is intended to only ever serve JSON, never HTML responses
 - It is intended to always serve JSON

Meanwhile the blog and admin panel have no need for JSON errors,
when an error happens on those pages, we should serve HTML pages
which are nicely formatted with the error & using the correct template

* 🐛 Fix checkSSL to work for subapps

- in order to make this work on a sub app we need to use the pattern `req.originalUrl || req.url`

* 🔥 Get rid of decide-is-admin (part 1/2)

- delete decide-is-admin & tests
- add two small functions to apiApp and adminApp to set res.isAdmin
- mount checkSSL on all the apps
- TODO: deduplicate the calls to checkSSL by making blogApp a subApp :D
- PART 2/2: finish cleaning this up by removing it from where it's not needed and giving it a more specific name

Rationale:

Now that we have both an adminApp and an apiApp,
we can temporarily replace this weird path-matching middleware
with middleware that sets res.isAdmin for api & admin

* 🎨 Wire up prettyURLs on all Apps

- prettyURLs is needed for all requests
- it cannot be global because it has to live after asset middleware, and before routing
- this does not result in duplicate redirects, but does result in duplicate checks
- TODO: resolve extra middleware in stack by making blogApp a sub app

* ⏱ Add debug to API setup

* 🎨 Rename blogApp -> parentApp in middleware

* 🎨 Co-locate all blog-related code in /blog

- Move all of the blogApp code from middleware/index.js to blog/app.js
- Move routes/frontend.js to blog/routes.js
- Remove the routes/index.js and routes folder, this is empty now!
- @TODO is blog the best name for this? 🤔
- @TODO sort out the big hunk of asset-related mess
- @TODO also separate out the concept of theme from blog

* 🎉 Replace middleware index with server/app.js

- The final piece of the puzzle! 🎉 🎈 🎂
- We no longer have our horrendous middleware/index.js
- Instead, we have a set of app.js files, which all use a familiar pattern

* 💄 Error handling fixups
2016-10-13 17:24:09 +02:00
Katharina Irrgang
4abb9590a1 add token utils (#7554)
no issue
- preperation for User model refactoring
- add independent util to generate reset hash, compare a hash and extract information out of it
- this code is basically a copy/paste of User model (generateResetToken, validateToken)
2016-10-13 13:54:44 +01:00
Katharina Irrgang
5b9c213849 🎨 change gravatar file design (#7553)
no issue
- preperation for User model refactoring
- the rule is:
  --> when calling a unit, this unit should return something new
  --> and NOT modifying an existing object and return it (this is an unexpected behaviour, especially for utils and libs)
2016-10-13 13:52:22 +01:00
Katharina Irrgang
869a35c97d migrations: seeding is part of init db task (#7545)
* 🎨  move heart of fixtures to schema folder and change user model

- add fixtures.json to schema folder
- add fixture utils to schema folder
- keep all the logic!

--> FIXTURE.JSON
- add owner user with roles

--> USER MODEL
- add password as default
- findAll: allow querying inactive users when internal context (defaultFilters)
- findOne: do not remove values from original object!
- add: do not remove values from original object!

* 🔥  remove migrations key from default_settings.json

- this was a temporary invention for an older migration script
- sephiroth keep alls needed information in a migration collection

* 🔥   add code property to errors

- add code property to errors
- IMPORTANT: please share your opinion about that
- this is a copy paste behaviour of how node is doing that (errno, code etc.)
- so code specifies a GhostError

* 🎨  change error handling in versioning

- no need to throw specific database errors anymore (this was just a temporary solution)
- now: we are throwing real DatabaseVersionErrors
- specified by a code
- background: the versioning unit has not idea about seeding and population of the database
- it just throws what it knows --> database version does not exist or settings table does not exist

* 🎨  sephiroth optimisations

- added getPath function to get the path to init scripts and migration scripts
- migrationPath is still hardcoded (see TODO)
- tidy up database naming to transacting

*   migration init scripts are now complete

- 1. add tables
- 2. add fixtures
- 3. add default settings

* 🎨  important: make bootup script smaller!

- remove all TODO'S except of one
- no seeding logic in bootup script anymore 🕵🏻

*   sephiroth: allow params for init command

- param: skip (do not run this script)
- param: only (only run this script)
- very simple way

* 🎨  adapt tests and test env

- do not use migrate.populate anymore
- use sephiroth instead
- jscs/jshint

* 🎨  fix User model status checks
2016-10-12 16:18:57 +01:00