2022-03-18 20:05:46 +03:00
|
|
|
const assert = require('assert');
|
🐛 Updated support email verification flow (#15029)
refs https://github.com/TryGhost/Team/issues/584
The current support email verification flow uses an API endpoint as verification URL inside the emails. This is a bad pattern, and also has the side effect that it shows a JSON error if something goes wrong.
To fix this, this commit updates the whole flow to use the same pattern as newsletters:
- You can update the `members_support_address` setting directly via the edit endpoint of settings.
- Changes to that (and future 'guarded' email properties) are blocked and generate verification emails automatically.
- When an email verification has been sent, the meta property `sent_email_verification` is set.
Other changes:
- Underlying, the implementation of email verificaton has moved from the (old) members service to the settings BREAD service. This makes it easier to add extra email addresses in settings later on that are not related to 'members'.
- Now you can update the `members_support_address` by updating the settings directly, so the `updateMembersEmail` endpoint has been deprecated and is mapped to the new behaviour.
- The SingleUseTokenProvider threw a `UnauthorizedError` error if a token was expired or invalid. Those errors are caught by the admin app, and causes it to do a page reload (making the error message and modals invisible). To fix that, I've swapped it with a validation error.
Future changes:
- Existing emails that have been sent 24h before this change is applied, still use the `validateMembersEmailUpdate` API endpoint. This endpoint has not been removed for now, to not break those emails. In a future release, we should remove this.
Changes to admin: https://github.com/TryGhost/Admin/pull/2426
2022-07-15 15:43:52 +03:00
|
|
|
const SingleUseTokenProvider = require('../../../core/server/services/members/SingleUseTokenProvider');
|
|
|
|
const settingsService = require('../../../core/server/services/settings/settings-service');
|
🎨 Reduced favicon requirements and added image formatting (#14918)
fixes https://github.com/TryGhost/Team/issues/1652
fixes https://github.com/TryGhost/Ghost/issues/13319
**Image formatting**
Added support for changing the format of images via the `handle-image-sizes` middleware (e.g. format SVG to png, jpeg, webp)
This change was required:
- Not all browsers support SVG favicons, so we need to convert them to PNGs
- We can't fit image resizing and formatting in the `serve-favicon` middleware: we need to store the resized image to avoid resizing on every request. This system was already present in the `handle-image-sizes` middleware.
To format an uploaded image:
- Original URL: https://localhost/blog/content/images/2022/05/giphy.gif
- To resize: https://localhost/blog/content/images/size/w256h256/2022/05/giphy.gif (already supported)
- To resize and format to webp: https://localhost/blog/content/images/size/w256h256/format/webp/2022/05/giphy.gif
- Animations are preserved when converting Gifs to Webp and in reverse, and also when only resizing (https://github.com/TryGhost/Ghost/issues/13319)
**Favicons**
- Custom favicons are no longer served via `/favicon.png` or `/favicon.ico` (only for default favicon), but use their full path
- Added support for uploading more image extensions in Ghost as a favicon: .jpg, .jpeg, .gif, .webp and .svg are now supported (already supported .png and .ico).
- File extensions other than jpg/jpeg, png, or ico will always get transformed to the image/png format to guarantee browser support (webp and svg images are not yet supported as favicons by all browsers).
For all image formats, other than .ico files:
- Allowed to upload images larger than 1000px in width and height, they will get cropped to 256x256px.
- Allowed uploading favicons that are not square. They will get cropped automatically.
- Allowed to upload larger files, up to 20MB (will get served at a lower file size after being resized)
For .svg files:
- The minimum size of 60x60px is no longer required.
For .ico files:
- The file size limit is increased to 200kb (coming from 100kb)
2022-05-27 17:36:53 +03:00
|
|
|
const settingsCache = require('../../../core/shared/settings-cache');
|
2022-03-18 20:05:46 +03:00
|
|
|
const {agentProvider, fixtureManager, mockManager, matchers} = require('../../utils/e2e-framework');
|
2022-10-05 12:34:17 +03:00
|
|
|
const {stringMatching, anyEtag, anyUuid, anyContentLength} = matchers;
|
🐛 Updated support email verification flow (#15029)
refs https://github.com/TryGhost/Team/issues/584
The current support email verification flow uses an API endpoint as verification URL inside the emails. This is a bad pattern, and also has the side effect that it shows a JSON error if something goes wrong.
To fix this, this commit updates the whole flow to use the same pattern as newsletters:
- You can update the `members_support_address` setting directly via the edit endpoint of settings.
- Changes to that (and future 'guarded' email properties) are blocked and generate verification emails automatically.
- When an email verification has been sent, the meta property `sent_email_verification` is set.
Other changes:
- Underlying, the implementation of email verificaton has moved from the (old) members service to the settings BREAD service. This makes it easier to add extra email addresses in settings later on that are not related to 'members'.
- Now you can update the `members_support_address` by updating the settings directly, so the `updateMembersEmail` endpoint has been deprecated and is mapped to the new behaviour.
- The SingleUseTokenProvider threw a `UnauthorizedError` error if a token was expired or invalid. Those errors are caught by the admin app, and causes it to do a page reload (making the error message and modals invisible). To fix that, I've swapped it with a validation error.
Future changes:
- Existing emails that have been sent 24h before this change is applied, still use the `validateMembersEmailUpdate` API endpoint. This endpoint has not been removed for now, to not break those emails. In a future release, we should remove this.
Changes to admin: https://github.com/TryGhost/Admin/pull/2426
2022-07-15 15:43:52 +03:00
|
|
|
const models = require('../../../core/server/models');
|
|
|
|
const {anyErrorId} = matchers;
|
2018-10-12 20:44:02 +03:00
|
|
|
|
2022-10-27 19:11:33 +03:00
|
|
|
const CURRENT_SETTINGS_COUNT = 69;
|
2018-10-12 20:44:02 +03:00
|
|
|
|
2022-05-16 11:12:47 +03:00
|
|
|
const settingsMatcher = {};
|
2018-10-12 20:44:02 +03:00
|
|
|
|
2022-03-18 22:41:18 +03:00
|
|
|
const publicHashSettingMatcher = {
|
2022-05-16 11:12:47 +03:00
|
|
|
value: stringMatching(/[a-z0-9]{30}/)
|
2022-03-18 22:41:18 +03:00
|
|
|
};
|
2018-10-12 20:44:02 +03:00
|
|
|
|
2022-08-15 17:36:14 +03:00
|
|
|
const labsSettingMatcher = {
|
|
|
|
value: stringMatching(/\{[^\s]+\}/)
|
|
|
|
};
|
|
|
|
|
2022-03-18 22:41:18 +03:00
|
|
|
const matchSettingsArray = (length) => {
|
|
|
|
const settingsArray = new Array(length).fill(settingsMatcher);
|
2018-10-12 20:44:02 +03:00
|
|
|
|
2022-10-27 19:11:33 +03:00
|
|
|
if (length > 26) {
|
|
|
|
// Added a setting that is alphabetically before 'public_hash'? then you need to increment this counter.
|
|
|
|
// Item at index x is the public hash, which is always different
|
|
|
|
settingsArray[26] = publicHashSettingMatcher;
|
2022-03-18 22:41:18 +03:00
|
|
|
}
|
2018-10-12 20:44:02 +03:00
|
|
|
|
2022-10-27 19:11:33 +03:00
|
|
|
if (length > 58) {
|
|
|
|
// Added a setting that is alphabetically before 'labs'? then you need to increment this counter.
|
|
|
|
// Item at index x is the lab settings, which changes as we add and remove features
|
|
|
|
settingsArray[58] = labsSettingMatcher;
|
2022-08-15 17:36:14 +03:00
|
|
|
}
|
|
|
|
|
2022-03-18 22:41:18 +03:00
|
|
|
return settingsArray;
|
|
|
|
};
|
2018-10-12 20:44:02 +03:00
|
|
|
|
2022-03-18 22:41:18 +03:00
|
|
|
describe('Settings API', function () {
|
2022-03-18 20:05:46 +03:00
|
|
|
let agent, membersService;
|
2018-10-12 20:44:02 +03:00
|
|
|
|
2022-03-18 22:41:18 +03:00
|
|
|
before(async function () {
|
|
|
|
agent = await agentProvider.getAdminAPIAgent();
|
|
|
|
await fixtureManager.init();
|
|
|
|
await agent.loginAsOwner();
|
2022-03-18 20:05:46 +03:00
|
|
|
|
|
|
|
membersService = require('../../../core/server/services/members');
|
|
|
|
});
|
|
|
|
|
|
|
|
beforeEach(function () {
|
|
|
|
mockManager.mockMail();
|
|
|
|
});
|
|
|
|
|
|
|
|
afterEach(function () {
|
|
|
|
mockManager.restore();
|
2022-03-18 22:41:18 +03:00
|
|
|
});
|
2018-10-12 20:44:02 +03:00
|
|
|
|
2022-05-15 16:09:53 +03:00
|
|
|
describe('Browse', function () {
|
|
|
|
it('Can request all settings', async function () {
|
|
|
|
await agent
|
|
|
|
.get('settings/')
|
|
|
|
.expectStatus(200)
|
|
|
|
.matchBodySnapshot({
|
|
|
|
settings: matchSettingsArray(CURRENT_SETTINGS_COUNT)
|
|
|
|
})
|
|
|
|
.matchHeaderSnapshot({
|
2022-08-19 12:51:43 +03:00
|
|
|
etag: anyEtag,
|
|
|
|
// Special rule for this test, as the labs setting changes a lot
|
2022-10-05 12:34:17 +03:00
|
|
|
'content-length': anyContentLength
|
2022-05-15 16:09:53 +03:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('Can request settings by group', async function () {
|
|
|
|
await agent
|
|
|
|
.get('settings/?group=theme')
|
|
|
|
.expectStatus(200)
|
|
|
|
.matchBodySnapshot({
|
|
|
|
settings: matchSettingsArray(1)
|
|
|
|
})
|
|
|
|
.matchHeaderSnapshot({
|
|
|
|
etag: anyEtag
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('Requesting core settings by group ignores the parameter and returns no settings', async function () {
|
|
|
|
await agent
|
|
|
|
.get('settings/?group=core')
|
|
|
|
.expectStatus(200)
|
|
|
|
.matchBodySnapshot()
|
|
|
|
.matchHeaderSnapshot({
|
|
|
|
etag: anyEtag
|
|
|
|
});
|
|
|
|
});
|
2018-10-12 20:44:02 +03:00
|
|
|
});
|
|
|
|
|
2022-05-15 16:09:53 +03:00
|
|
|
describe('Edit', function () {
|
|
|
|
it('Can edit a setting', async function () {
|
|
|
|
const settingsToChange = [
|
|
|
|
{
|
|
|
|
key: 'title',
|
|
|
|
value: []
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: 'codeinjection_head',
|
|
|
|
value: null
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: 'navigation',
|
|
|
|
value: JSON.stringify([{
|
|
|
|
label: 'label1'
|
|
|
|
}])
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: 'slack_username',
|
|
|
|
value: 'New Slack Username'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: 'is_private',
|
|
|
|
value: false
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: 'meta_title',
|
|
|
|
value: 'SEO title'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: 'meta_description',
|
|
|
|
value: 'SEO description'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: 'og_image',
|
|
|
|
value: '/content/images/2019/07/facebook.png'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: 'og_title',
|
|
|
|
value: 'facebook title'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: 'og_description',
|
|
|
|
value: 'facebook description'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: 'twitter_image',
|
|
|
|
value: '/content/images/2019/07/twitter.png'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: 'twitter_title',
|
|
|
|
value: 'twitter title'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: 'twitter_description',
|
|
|
|
value: 'twitter description'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: 'locale',
|
|
|
|
value: 'ua'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: 'labs',
|
|
|
|
value: JSON.stringify({})
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: 'timezone',
|
|
|
|
value: 'Pacific/Auckland'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: 'unsplash',
|
|
|
|
value: false
|
|
|
|
}
|
|
|
|
];
|
|
|
|
|
|
|
|
await agent.put('settings/')
|
|
|
|
.body({
|
|
|
|
settings: settingsToChange
|
|
|
|
})
|
|
|
|
.expectStatus(200)
|
|
|
|
.matchBodySnapshot({
|
2022-05-24 17:42:15 +03:00
|
|
|
settings: matchSettingsArray(CURRENT_SETTINGS_COUNT)
|
2022-05-15 16:09:53 +03:00
|
|
|
})
|
|
|
|
.matchHeaderSnapshot({
|
|
|
|
etag: anyEtag
|
|
|
|
});
|
2022-07-19 16:13:29 +03:00
|
|
|
|
|
|
|
mockManager.assert.sentEmailCount(0);
|
2022-05-15 16:09:53 +03:00
|
|
|
});
|
2022-05-16 15:23:26 +03:00
|
|
|
|
🎨 Reduced favicon requirements and added image formatting (#14918)
fixes https://github.com/TryGhost/Team/issues/1652
fixes https://github.com/TryGhost/Ghost/issues/13319
**Image formatting**
Added support for changing the format of images via the `handle-image-sizes` middleware (e.g. format SVG to png, jpeg, webp)
This change was required:
- Not all browsers support SVG favicons, so we need to convert them to PNGs
- We can't fit image resizing and formatting in the `serve-favicon` middleware: we need to store the resized image to avoid resizing on every request. This system was already present in the `handle-image-sizes` middleware.
To format an uploaded image:
- Original URL: https://localhost/blog/content/images/2022/05/giphy.gif
- To resize: https://localhost/blog/content/images/size/w256h256/2022/05/giphy.gif (already supported)
- To resize and format to webp: https://localhost/blog/content/images/size/w256h256/format/webp/2022/05/giphy.gif
- Animations are preserved when converting Gifs to Webp and in reverse, and also when only resizing (https://github.com/TryGhost/Ghost/issues/13319)
**Favicons**
- Custom favicons are no longer served via `/favicon.png` or `/favicon.ico` (only for default favicon), but use their full path
- Added support for uploading more image extensions in Ghost as a favicon: .jpg, .jpeg, .gif, .webp and .svg are now supported (already supported .png and .ico).
- File extensions other than jpg/jpeg, png, or ico will always get transformed to the image/png format to guarantee browser support (webp and svg images are not yet supported as favicons by all browsers).
For all image formats, other than .ico files:
- Allowed to upload images larger than 1000px in width and height, they will get cropped to 256x256px.
- Allowed uploading favicons that are not square. They will get cropped automatically.
- Allowed to upload larger files, up to 20MB (will get served at a lower file size after being resized)
For .svg files:
- The minimum size of 60x60px is no longer required.
For .ico files:
- The file size limit is increased to 200kb (coming from 100kb)
2022-05-27 17:36:53 +03:00
|
|
|
it('removes image size prefixes when setting the icon', async function () {
|
|
|
|
const settingsToChange = [
|
|
|
|
{
|
|
|
|
key: 'icon',
|
|
|
|
value: '/content/images/size/w256h256/2019/07/icon.png'
|
|
|
|
}
|
|
|
|
];
|
|
|
|
|
|
|
|
const {body} = await agent.put('settings/')
|
|
|
|
.body({
|
|
|
|
settings: settingsToChange
|
|
|
|
})
|
|
|
|
.expectStatus(200)
|
|
|
|
.matchBodySnapshot({
|
|
|
|
settings: matchSettingsArray(CURRENT_SETTINGS_COUNT)
|
|
|
|
})
|
|
|
|
.matchHeaderSnapshot({
|
2022-08-24 21:45:20 +03:00
|
|
|
etag: anyEtag,
|
|
|
|
// Special rule for this test, as the labs setting changes a lot
|
2022-10-05 12:34:17 +03:00
|
|
|
'content-length': anyContentLength
|
🎨 Reduced favicon requirements and added image formatting (#14918)
fixes https://github.com/TryGhost/Team/issues/1652
fixes https://github.com/TryGhost/Ghost/issues/13319
**Image formatting**
Added support for changing the format of images via the `handle-image-sizes` middleware (e.g. format SVG to png, jpeg, webp)
This change was required:
- Not all browsers support SVG favicons, so we need to convert them to PNGs
- We can't fit image resizing and formatting in the `serve-favicon` middleware: we need to store the resized image to avoid resizing on every request. This system was already present in the `handle-image-sizes` middleware.
To format an uploaded image:
- Original URL: https://localhost/blog/content/images/2022/05/giphy.gif
- To resize: https://localhost/blog/content/images/size/w256h256/2022/05/giphy.gif (already supported)
- To resize and format to webp: https://localhost/blog/content/images/size/w256h256/format/webp/2022/05/giphy.gif
- Animations are preserved when converting Gifs to Webp and in reverse, and also when only resizing (https://github.com/TryGhost/Ghost/issues/13319)
**Favicons**
- Custom favicons are no longer served via `/favicon.png` or `/favicon.ico` (only for default favicon), but use their full path
- Added support for uploading more image extensions in Ghost as a favicon: .jpg, .jpeg, .gif, .webp and .svg are now supported (already supported .png and .ico).
- File extensions other than jpg/jpeg, png, or ico will always get transformed to the image/png format to guarantee browser support (webp and svg images are not yet supported as favicons by all browsers).
For all image formats, other than .ico files:
- Allowed to upload images larger than 1000px in width and height, they will get cropped to 256x256px.
- Allowed uploading favicons that are not square. They will get cropped automatically.
- Allowed to upload larger files, up to 20MB (will get served at a lower file size after being resized)
For .svg files:
- The minimum size of 60x60px is no longer required.
For .ico files:
- The file size limit is increased to 200kb (coming from 100kb)
2022-05-27 17:36:53 +03:00
|
|
|
});
|
2022-08-15 17:36:14 +03:00
|
|
|
|
🎨 Reduced favicon requirements and added image formatting (#14918)
fixes https://github.com/TryGhost/Team/issues/1652
fixes https://github.com/TryGhost/Ghost/issues/13319
**Image formatting**
Added support for changing the format of images via the `handle-image-sizes` middleware (e.g. format SVG to png, jpeg, webp)
This change was required:
- Not all browsers support SVG favicons, so we need to convert them to PNGs
- We can't fit image resizing and formatting in the `serve-favicon` middleware: we need to store the resized image to avoid resizing on every request. This system was already present in the `handle-image-sizes` middleware.
To format an uploaded image:
- Original URL: https://localhost/blog/content/images/2022/05/giphy.gif
- To resize: https://localhost/blog/content/images/size/w256h256/2022/05/giphy.gif (already supported)
- To resize and format to webp: https://localhost/blog/content/images/size/w256h256/format/webp/2022/05/giphy.gif
- Animations are preserved when converting Gifs to Webp and in reverse, and also when only resizing (https://github.com/TryGhost/Ghost/issues/13319)
**Favicons**
- Custom favicons are no longer served via `/favicon.png` or `/favicon.ico` (only for default favicon), but use their full path
- Added support for uploading more image extensions in Ghost as a favicon: .jpg, .jpeg, .gif, .webp and .svg are now supported (already supported .png and .ico).
- File extensions other than jpg/jpeg, png, or ico will always get transformed to the image/png format to guarantee browser support (webp and svg images are not yet supported as favicons by all browsers).
For all image formats, other than .ico files:
- Allowed to upload images larger than 1000px in width and height, they will get cropped to 256x256px.
- Allowed uploading favicons that are not square. They will get cropped automatically.
- Allowed to upload larger files, up to 20MB (will get served at a lower file size after being resized)
For .svg files:
- The minimum size of 60x60px is no longer required.
For .ico files:
- The file size limit is increased to 200kb (coming from 100kb)
2022-05-27 17:36:53 +03:00
|
|
|
// Check returned WITH prefix
|
|
|
|
const val = body.settings.find(setting => setting.key === 'icon');
|
|
|
|
assert.ok(val);
|
|
|
|
assert.equal(val.value, 'http://127.0.0.1:2369/content/images/size/w256h256/2019/07/icon.png');
|
|
|
|
|
|
|
|
// Check if not changed (also check internal ones)
|
|
|
|
const afterValue = settingsCache.get('icon');
|
|
|
|
assert.equal(afterValue, 'http://127.0.0.1:2369/content/images/2019/07/icon.png');
|
2022-07-19 16:13:29 +03:00
|
|
|
|
|
|
|
mockManager.assert.sentEmailCount(0);
|
🎨 Reduced favicon requirements and added image formatting (#14918)
fixes https://github.com/TryGhost/Team/issues/1652
fixes https://github.com/TryGhost/Ghost/issues/13319
**Image formatting**
Added support for changing the format of images via the `handle-image-sizes` middleware (e.g. format SVG to png, jpeg, webp)
This change was required:
- Not all browsers support SVG favicons, so we need to convert them to PNGs
- We can't fit image resizing and formatting in the `serve-favicon` middleware: we need to store the resized image to avoid resizing on every request. This system was already present in the `handle-image-sizes` middleware.
To format an uploaded image:
- Original URL: https://localhost/blog/content/images/2022/05/giphy.gif
- To resize: https://localhost/blog/content/images/size/w256h256/2022/05/giphy.gif (already supported)
- To resize and format to webp: https://localhost/blog/content/images/size/w256h256/format/webp/2022/05/giphy.gif
- Animations are preserved when converting Gifs to Webp and in reverse, and also when only resizing (https://github.com/TryGhost/Ghost/issues/13319)
**Favicons**
- Custom favicons are no longer served via `/favicon.png` or `/favicon.ico` (only for default favicon), but use their full path
- Added support for uploading more image extensions in Ghost as a favicon: .jpg, .jpeg, .gif, .webp and .svg are now supported (already supported .png and .ico).
- File extensions other than jpg/jpeg, png, or ico will always get transformed to the image/png format to guarantee browser support (webp and svg images are not yet supported as favicons by all browsers).
For all image formats, other than .ico files:
- Allowed to upload images larger than 1000px in width and height, they will get cropped to 256x256px.
- Allowed uploading favicons that are not square. They will get cropped automatically.
- Allowed to upload larger files, up to 20MB (will get served at a lower file size after being resized)
For .svg files:
- The minimum size of 60x60px is no longer required.
For .ico files:
- The file size limit is increased to 200kb (coming from 100kb)
2022-05-27 17:36:53 +03:00
|
|
|
});
|
|
|
|
|
2022-05-16 15:23:26 +03:00
|
|
|
it('cannot edit uneditable settings', async function () {
|
|
|
|
await agent.put('settings/')
|
|
|
|
.body({
|
2022-05-24 17:42:15 +03:00
|
|
|
settings: [{key: 'email_verification_required', value: true}]
|
2022-05-16 15:23:26 +03:00
|
|
|
})
|
|
|
|
.expectStatus(200)
|
2022-05-24 17:42:15 +03:00
|
|
|
.matchBodySnapshot({
|
|
|
|
settings: matchSettingsArray(CURRENT_SETTINGS_COUNT)
|
|
|
|
})
|
2022-05-16 15:23:26 +03:00
|
|
|
.matchHeaderSnapshot({
|
2022-08-24 21:45:20 +03:00
|
|
|
etag: anyEtag,
|
|
|
|
// Special rule for this test, as the labs setting changes a lot
|
2022-10-05 12:34:17 +03:00
|
|
|
'content-length': anyContentLength
|
2022-05-24 17:42:15 +03:00
|
|
|
})
|
|
|
|
.expect(({body}) => {
|
|
|
|
const emailVerificationRequired = body.settings.find(setting => setting.key === 'email_verification_required');
|
|
|
|
assert.strictEqual(emailVerificationRequired.value, false);
|
2022-05-16 15:23:26 +03:00
|
|
|
});
|
2022-07-19 16:13:29 +03:00
|
|
|
mockManager.assert.sentEmailCount(0);
|
2022-05-16 15:23:26 +03:00
|
|
|
});
|
🐛 Updated support email verification flow (#15029)
refs https://github.com/TryGhost/Team/issues/584
The current support email verification flow uses an API endpoint as verification URL inside the emails. This is a bad pattern, and also has the side effect that it shows a JSON error if something goes wrong.
To fix this, this commit updates the whole flow to use the same pattern as newsletters:
- You can update the `members_support_address` setting directly via the edit endpoint of settings.
- Changes to that (and future 'guarded' email properties) are blocked and generate verification emails automatically.
- When an email verification has been sent, the meta property `sent_email_verification` is set.
Other changes:
- Underlying, the implementation of email verificaton has moved from the (old) members service to the settings BREAD service. This makes it easier to add extra email addresses in settings later on that are not related to 'members'.
- Now you can update the `members_support_address` by updating the settings directly, so the `updateMembersEmail` endpoint has been deprecated and is mapped to the new behaviour.
- The SingleUseTokenProvider threw a `UnauthorizedError` error if a token was expired or invalid. Those errors are caught by the admin app, and causes it to do a page reload (making the error message and modals invisible). To fix that, I've swapped it with a validation error.
Future changes:
- Existing emails that have been sent 24h before this change is applied, still use the `validateMembersEmailUpdate` API endpoint. This endpoint has not been removed for now, to not break those emails. In a future release, we should remove this.
Changes to admin: https://github.com/TryGhost/Admin/pull/2426
2022-07-15 15:43:52 +03:00
|
|
|
|
|
|
|
it('editing members_support_address triggers email verification flow', async function () {
|
|
|
|
await agent.put('settings/')
|
|
|
|
.body({
|
|
|
|
settings: [{key: 'members_support_address', value: 'support@example.com'}]
|
|
|
|
})
|
|
|
|
.expectStatus(200)
|
|
|
|
.matchBodySnapshot({
|
|
|
|
settings: matchSettingsArray(CURRENT_SETTINGS_COUNT)
|
|
|
|
})
|
|
|
|
.matchHeaderSnapshot({
|
2022-08-24 21:45:20 +03:00
|
|
|
etag: anyEtag,
|
|
|
|
// Special rule for this test, as the labs setting changes a lot
|
2022-10-05 12:34:17 +03:00
|
|
|
'content-length': anyContentLength
|
🐛 Updated support email verification flow (#15029)
refs https://github.com/TryGhost/Team/issues/584
The current support email verification flow uses an API endpoint as verification URL inside the emails. This is a bad pattern, and also has the side effect that it shows a JSON error if something goes wrong.
To fix this, this commit updates the whole flow to use the same pattern as newsletters:
- You can update the `members_support_address` setting directly via the edit endpoint of settings.
- Changes to that (and future 'guarded' email properties) are blocked and generate verification emails automatically.
- When an email verification has been sent, the meta property `sent_email_verification` is set.
Other changes:
- Underlying, the implementation of email verificaton has moved from the (old) members service to the settings BREAD service. This makes it easier to add extra email addresses in settings later on that are not related to 'members'.
- Now you can update the `members_support_address` by updating the settings directly, so the `updateMembersEmail` endpoint has been deprecated and is mapped to the new behaviour.
- The SingleUseTokenProvider threw a `UnauthorizedError` error if a token was expired or invalid. Those errors are caught by the admin app, and causes it to do a page reload (making the error message and modals invisible). To fix that, I've swapped it with a validation error.
Future changes:
- Existing emails that have been sent 24h before this change is applied, still use the `validateMembersEmailUpdate` API endpoint. This endpoint has not been removed for now, to not break those emails. In a future release, we should remove this.
Changes to admin: https://github.com/TryGhost/Admin/pull/2426
2022-07-15 15:43:52 +03:00
|
|
|
})
|
|
|
|
.expect(({body}) => {
|
|
|
|
const membersSupportAddress = body.settings.find(setting => setting.key === 'members_support_address');
|
|
|
|
assert.strictEqual(membersSupportAddress.value, 'noreply');
|
|
|
|
|
|
|
|
assert.deepEqual(body.meta, {
|
|
|
|
sent_email_verification: ['members_support_address']
|
|
|
|
});
|
|
|
|
});
|
2022-07-19 16:13:29 +03:00
|
|
|
|
2022-08-15 17:36:14 +03:00
|
|
|
mockManager.assert.sentEmailCount(1);
|
🐛 Updated support email verification flow (#15029)
refs https://github.com/TryGhost/Team/issues/584
The current support email verification flow uses an API endpoint as verification URL inside the emails. This is a bad pattern, and also has the side effect that it shows a JSON error if something goes wrong.
To fix this, this commit updates the whole flow to use the same pattern as newsletters:
- You can update the `members_support_address` setting directly via the edit endpoint of settings.
- Changes to that (and future 'guarded' email properties) are blocked and generate verification emails automatically.
- When an email verification has been sent, the meta property `sent_email_verification` is set.
Other changes:
- Underlying, the implementation of email verificaton has moved from the (old) members service to the settings BREAD service. This makes it easier to add extra email addresses in settings later on that are not related to 'members'.
- Now you can update the `members_support_address` by updating the settings directly, so the `updateMembersEmail` endpoint has been deprecated and is mapped to the new behaviour.
- The SingleUseTokenProvider threw a `UnauthorizedError` error if a token was expired or invalid. Those errors are caught by the admin app, and causes it to do a page reload (making the error message and modals invisible). To fix that, I've swapped it with a validation error.
Future changes:
- Existing emails that have been sent 24h before this change is applied, still use the `validateMembersEmailUpdate` API endpoint. This endpoint has not been removed for now, to not break those emails. In a future release, we should remove this.
Changes to admin: https://github.com/TryGhost/Admin/pull/2426
2022-07-15 15:43:52 +03:00
|
|
|
mockManager.assert.sentEmail({
|
|
|
|
subject: 'Verify email address',
|
|
|
|
to: 'support@example.com'
|
2022-08-15 17:36:14 +03:00
|
|
|
});
|
🐛 Updated support email verification flow (#15029)
refs https://github.com/TryGhost/Team/issues/584
The current support email verification flow uses an API endpoint as verification URL inside the emails. This is a bad pattern, and also has the side effect that it shows a JSON error if something goes wrong.
To fix this, this commit updates the whole flow to use the same pattern as newsletters:
- You can update the `members_support_address` setting directly via the edit endpoint of settings.
- Changes to that (and future 'guarded' email properties) are blocked and generate verification emails automatically.
- When an email verification has been sent, the meta property `sent_email_verification` is set.
Other changes:
- Underlying, the implementation of email verificaton has moved from the (old) members service to the settings BREAD service. This makes it easier to add extra email addresses in settings later on that are not related to 'members'.
- Now you can update the `members_support_address` by updating the settings directly, so the `updateMembersEmail` endpoint has been deprecated and is mapped to the new behaviour.
- The SingleUseTokenProvider threw a `UnauthorizedError` error if a token was expired or invalid. Those errors are caught by the admin app, and causes it to do a page reload (making the error message and modals invisible). To fix that, I've swapped it with a validation error.
Future changes:
- Existing emails that have been sent 24h before this change is applied, still use the `validateMembersEmailUpdate` API endpoint. This endpoint has not been removed for now, to not break those emails. In a future release, we should remove this.
Changes to admin: https://github.com/TryGhost/Admin/pull/2426
2022-07-15 15:43:52 +03:00
|
|
|
});
|
2022-07-19 16:13:29 +03:00
|
|
|
|
|
|
|
it('does not trigger email verification flow if members_support_address remains the same', async function () {
|
|
|
|
await models.Settings.edit({
|
|
|
|
key: 'members_support_address',
|
|
|
|
value: 'support@example.com'
|
|
|
|
});
|
|
|
|
|
|
|
|
await agent.put('settings/')
|
|
|
|
.body({
|
|
|
|
settings: [{key: 'members_support_address', value: 'support@example.com'}]
|
|
|
|
})
|
|
|
|
.expectStatus(200)
|
|
|
|
.matchBodySnapshot({
|
|
|
|
settings: matchSettingsArray(CURRENT_SETTINGS_COUNT)
|
|
|
|
})
|
|
|
|
.matchHeaderSnapshot({
|
2022-08-24 21:45:20 +03:00
|
|
|
etag: anyEtag,
|
|
|
|
// Special rule for this test, as the labs setting changes a lot
|
2022-10-05 12:34:17 +03:00
|
|
|
'content-length': anyContentLength
|
2022-07-19 16:13:29 +03:00
|
|
|
})
|
|
|
|
.expect(({body}) => {
|
|
|
|
const membersSupportAddress = body.settings.find(setting => setting.key === 'members_support_address');
|
|
|
|
assert.strictEqual(membersSupportAddress.value, 'support@example.com');
|
|
|
|
|
|
|
|
assert.deepEqual(body.meta, {});
|
|
|
|
});
|
|
|
|
|
|
|
|
mockManager.assert.sentEmailCount(0);
|
|
|
|
});
|
🐛 Updated support email verification flow (#15029)
refs https://github.com/TryGhost/Team/issues/584
The current support email verification flow uses an API endpoint as verification URL inside the emails. This is a bad pattern, and also has the side effect that it shows a JSON error if something goes wrong.
To fix this, this commit updates the whole flow to use the same pattern as newsletters:
- You can update the `members_support_address` setting directly via the edit endpoint of settings.
- Changes to that (and future 'guarded' email properties) are blocked and generate verification emails automatically.
- When an email verification has been sent, the meta property `sent_email_verification` is set.
Other changes:
- Underlying, the implementation of email verificaton has moved from the (old) members service to the settings BREAD service. This makes it easier to add extra email addresses in settings later on that are not related to 'members'.
- Now you can update the `members_support_address` by updating the settings directly, so the `updateMembersEmail` endpoint has been deprecated and is mapped to the new behaviour.
- The SingleUseTokenProvider threw a `UnauthorizedError` error if a token was expired or invalid. Those errors are caught by the admin app, and causes it to do a page reload (making the error message and modals invisible). To fix that, I've swapped it with a validation error.
Future changes:
- Existing emails that have been sent 24h before this change is applied, still use the `validateMembersEmailUpdate` API endpoint. This endpoint has not been removed for now, to not break those emails. In a future release, we should remove this.
Changes to admin: https://github.com/TryGhost/Admin/pull/2426
2022-07-15 15:43:52 +03:00
|
|
|
});
|
|
|
|
|
|
|
|
describe('verify key update', function () {
|
|
|
|
it('can update members_support_address via token', async function () {
|
|
|
|
const token = await (new SingleUseTokenProvider(models.SingleUseToken, 24 * 60 * 60 * 1000)).create({key: 'members_support_address', value: 'support@example.com'});
|
|
|
|
await agent.put('settings/verifications/')
|
|
|
|
.body({
|
|
|
|
token
|
|
|
|
})
|
|
|
|
.expectStatus(200)
|
|
|
|
.matchBodySnapshot({
|
|
|
|
settings: matchSettingsArray(CURRENT_SETTINGS_COUNT)
|
|
|
|
})
|
|
|
|
.matchHeaderSnapshot({
|
2022-08-24 21:45:20 +03:00
|
|
|
etag: anyEtag,
|
|
|
|
// Special rule for this test, as the labs setting changes a lot
|
2022-10-05 12:34:17 +03:00
|
|
|
'content-length': anyContentLength
|
🐛 Updated support email verification flow (#15029)
refs https://github.com/TryGhost/Team/issues/584
The current support email verification flow uses an API endpoint as verification URL inside the emails. This is a bad pattern, and also has the side effect that it shows a JSON error if something goes wrong.
To fix this, this commit updates the whole flow to use the same pattern as newsletters:
- You can update the `members_support_address` setting directly via the edit endpoint of settings.
- Changes to that (and future 'guarded' email properties) are blocked and generate verification emails automatically.
- When an email verification has been sent, the meta property `sent_email_verification` is set.
Other changes:
- Underlying, the implementation of email verificaton has moved from the (old) members service to the settings BREAD service. This makes it easier to add extra email addresses in settings later on that are not related to 'members'.
- Now you can update the `members_support_address` by updating the settings directly, so the `updateMembersEmail` endpoint has been deprecated and is mapped to the new behaviour.
- The SingleUseTokenProvider threw a `UnauthorizedError` error if a token was expired or invalid. Those errors are caught by the admin app, and causes it to do a page reload (making the error message and modals invisible). To fix that, I've swapped it with a validation error.
Future changes:
- Existing emails that have been sent 24h before this change is applied, still use the `validateMembersEmailUpdate` API endpoint. This endpoint has not been removed for now, to not break those emails. In a future release, we should remove this.
Changes to admin: https://github.com/TryGhost/Admin/pull/2426
2022-07-15 15:43:52 +03:00
|
|
|
})
|
|
|
|
.expect(({body}) => {
|
|
|
|
const membersSupportAddress = body.settings.find(setting => setting.key === 'members_support_address');
|
|
|
|
assert.strictEqual(membersSupportAddress.value, 'support@example.com');
|
|
|
|
});
|
2022-08-24 21:45:20 +03:00
|
|
|
|
2022-07-19 16:13:29 +03:00
|
|
|
mockManager.assert.sentEmailCount(0);
|
🐛 Updated support email verification flow (#15029)
refs https://github.com/TryGhost/Team/issues/584
The current support email verification flow uses an API endpoint as verification URL inside the emails. This is a bad pattern, and also has the side effect that it shows a JSON error if something goes wrong.
To fix this, this commit updates the whole flow to use the same pattern as newsletters:
- You can update the `members_support_address` setting directly via the edit endpoint of settings.
- Changes to that (and future 'guarded' email properties) are blocked and generate verification emails automatically.
- When an email verification has been sent, the meta property `sent_email_verification` is set.
Other changes:
- Underlying, the implementation of email verificaton has moved from the (old) members service to the settings BREAD service. This makes it easier to add extra email addresses in settings later on that are not related to 'members'.
- Now you can update the `members_support_address` by updating the settings directly, so the `updateMembersEmail` endpoint has been deprecated and is mapped to the new behaviour.
- The SingleUseTokenProvider threw a `UnauthorizedError` error if a token was expired or invalid. Those errors are caught by the admin app, and causes it to do a page reload (making the error message and modals invisible). To fix that, I've swapped it with a validation error.
Future changes:
- Existing emails that have been sent 24h before this change is applied, still use the `validateMembersEmailUpdate` API endpoint. This endpoint has not been removed for now, to not break those emails. In a future release, we should remove this.
Changes to admin: https://github.com/TryGhost/Admin/pull/2426
2022-07-15 15:43:52 +03:00
|
|
|
});
|
|
|
|
|
|
|
|
it('cannot update invalid keys via token', async function () {
|
|
|
|
const token = await (new SingleUseTokenProvider(models.SingleUseToken, 24 * 60 * 60 * 1000)).create({key: 'members_support_address_invalid', value: 'support@example.com'});
|
|
|
|
await agent.put('settings/verifications/')
|
|
|
|
.body({
|
|
|
|
token
|
|
|
|
})
|
|
|
|
.expectStatus(400)
|
|
|
|
.matchBodySnapshot({
|
|
|
|
errors: [
|
|
|
|
{
|
|
|
|
id: anyErrorId
|
|
|
|
}
|
|
|
|
]
|
|
|
|
})
|
|
|
|
.matchHeaderSnapshot({
|
|
|
|
etag: anyEtag
|
|
|
|
});
|
|
|
|
});
|
2018-10-12 20:44:02 +03:00
|
|
|
});
|
2022-03-18 20:05:46 +03:00
|
|
|
|
2022-05-15 16:09:53 +03:00
|
|
|
describe('stripe connect', function () {
|
|
|
|
it('can do disconnectStripeConnectIntegration', async function () {
|
|
|
|
await agent
|
|
|
|
.delete('/settings/stripe/connect/')
|
|
|
|
.expectStatus(204)
|
|
|
|
.expectEmptyBody()
|
|
|
|
.matchHeaderSnapshot({
|
|
|
|
etag: anyEtag
|
|
|
|
});
|
2022-03-18 20:05:46 +03:00
|
|
|
|
2022-05-15 16:09:53 +03:00
|
|
|
const stripeSettings = [
|
|
|
|
'stripe_connect_publishable_key',
|
|
|
|
'stripe_connect_secret_key',
|
|
|
|
'stripe_connect_livemode',
|
|
|
|
'stripe_connect_display_name',
|
|
|
|
'stripe_connect_account_id',
|
|
|
|
'members_stripe_webhook_id',
|
|
|
|
'members_stripe_webhook_secret'
|
|
|
|
];
|
|
|
|
|
|
|
|
// Assert that the settings are changed as a side effect
|
|
|
|
await agent.get('settings/')
|
|
|
|
.expect(({body}) => {
|
|
|
|
body.settings.forEach((setting) => {
|
|
|
|
if (stripeSettings.includes(setting.key)) {
|
|
|
|
assert.equal(setting.value, null);
|
|
|
|
}
|
|
|
|
});
|
2022-03-18 20:05:46 +03:00
|
|
|
});
|
2022-05-15 16:09:53 +03:00
|
|
|
});
|
2022-05-18 15:27:50 +03:00
|
|
|
|
|
|
|
it('Can attempt to connect to stripe', async function () {
|
|
|
|
const settingsToChange = [
|
|
|
|
{
|
|
|
|
key: 'stripe_connect_integration_token',
|
|
|
|
value: JSON.stringify({
|
|
|
|
s: 'session_state',
|
|
|
|
p: 'public_key',
|
|
|
|
a: 'secret_key',
|
|
|
|
l: true,
|
|
|
|
n: 'Display Name',
|
|
|
|
i: 'account_id'
|
|
|
|
|
|
|
|
})
|
|
|
|
}
|
|
|
|
];
|
|
|
|
|
|
|
|
await agent.put('settings/')
|
|
|
|
.body({
|
|
|
|
settings: settingsToChange
|
|
|
|
})
|
|
|
|
.expectStatus(400)
|
|
|
|
.matchBodySnapshot({
|
|
|
|
errors: [{
|
|
|
|
id: anyUuid
|
|
|
|
}]
|
|
|
|
})
|
|
|
|
.matchHeaderSnapshot({
|
|
|
|
etag: anyEtag
|
|
|
|
});
|
|
|
|
});
|
2022-03-18 20:05:46 +03:00
|
|
|
});
|
2018-10-12 20:44:02 +03:00
|
|
|
});
|