mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-03-11 02:12:21 -05:00
Merged v5.17.2 into main
v5.17.2
This commit is contained in:
commit
c4981a71a2
6 changed files with 72 additions and 19 deletions
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "ghost-admin",
|
"name": "ghost-admin",
|
||||||
"version": "5.17.1",
|
"version": "5.17.2",
|
||||||
"description": "Ember.js admin client for Ghost",
|
"description": "Ember.js admin client for Ghost",
|
||||||
"author": "Ghost Foundation",
|
"author": "Ghost Foundation",
|
||||||
"homepage": "http://ghost.org",
|
"homepage": "http://ghost.org",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "ghost",
|
"name": "ghost",
|
||||||
"version": "5.17.1",
|
"version": "5.17.2",
|
||||||
"description": "The professional publishing platform",
|
"description": "The professional publishing platform",
|
||||||
"author": "Ghost Foundation",
|
"author": "Ghost Foundation",
|
||||||
"homepage": "https://ghost.org",
|
"homepage": "https://ghost.org",
|
||||||
|
|
|
@ -32,6 +32,15 @@ describe('sendMagicLink', function () {
|
||||||
mockManager.restore();
|
mockManager.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Errors when passed multiple emails', async function () {
|
||||||
|
await membersAgent.post('/api/send-magic-link')
|
||||||
|
.body({
|
||||||
|
email: 'one@test.com,two@test.com',
|
||||||
|
emailType: 'signup'
|
||||||
|
})
|
||||||
|
.expectStatus(400);
|
||||||
|
});
|
||||||
|
|
||||||
it('Throws an error when logging in to a email that does not exist', async function () {
|
it('Throws an error when logging in to a email that does not exist', async function () {
|
||||||
const email = 'this-member-does-not-exist@test.com';
|
const email = 'this-member-does-not-exist@test.com';
|
||||||
await membersAgent.post('/api/send-magic-link')
|
await membersAgent.post('/api/send-magic-link')
|
||||||
|
|
|
@ -1,4 +1,9 @@
|
||||||
const {IncorrectUsageError} = require('@tryghost/errors');
|
const {IncorrectUsageError, BadRequestError} = require('@tryghost/errors');
|
||||||
|
const {isEmail} = require('@tryghost/validator');
|
||||||
|
const tpl = require('@tryghost/tpl');
|
||||||
|
const messages = {
|
||||||
|
invalidEmail: 'Email is not valid'
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef { import('nodemailer').Transporter } MailTransporter
|
* @typedef { import('nodemailer').Transporter } MailTransporter
|
||||||
|
@ -52,6 +57,11 @@ class MagicLink {
|
||||||
* @returns {Promise<{token: Token, info: SentMessageInfo}>}
|
* @returns {Promise<{token: Token, info: SentMessageInfo}>}
|
||||||
*/
|
*/
|
||||||
async sendMagicLink(options) {
|
async sendMagicLink(options) {
|
||||||
|
if (!isEmail(options.email)) {
|
||||||
|
throw new BadRequestError({
|
||||||
|
message: tpl(messages.invalidEmail)
|
||||||
|
});
|
||||||
|
}
|
||||||
const token = await this.tokenProvider.create(options.tokenData);
|
const token = await this.tokenProvider.create(options.tokenData);
|
||||||
|
|
||||||
const type = options.type || 'signin';
|
const type = options.type || 'signin';
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tryghost/errors": "1.2.17",
|
"@tryghost/errors": "1.2.17",
|
||||||
|
"@tryghost/tpl": "0.1.18",
|
||||||
|
"@tryghost/validator": "0.1.29",
|
||||||
"jsonwebtoken": "8.5.1"
|
"jsonwebtoken": "8.5.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
const should = require('should');
|
const assert = require('assert');
|
||||||
const sinon = require('sinon');
|
const sinon = require('sinon');
|
||||||
const MagicLink = require('../');
|
const MagicLink = require('../');
|
||||||
const crypto = require('crypto');
|
const crypto = require('crypto');
|
||||||
|
@ -8,10 +8,42 @@ const secret = crypto.randomBytes(64);
|
||||||
|
|
||||||
describe('MagicLink', function () {
|
describe('MagicLink', function () {
|
||||||
it('Exports a function', function () {
|
it('Exports a function', function () {
|
||||||
should.equal(typeof MagicLink, 'function');
|
assert.equal(typeof MagicLink, 'function');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#sendMagicLink', function () {
|
describe('#sendMagicLink', function () {
|
||||||
|
it('Throws when passed comma separated emails', async function () {
|
||||||
|
const options = {
|
||||||
|
tokenProvider: new MagicLink.JWTTokenProvider(secret),
|
||||||
|
getSigninURL: sandbox.stub().returns('FAKEURL'),
|
||||||
|
getText: sandbox.stub().returns('SOMETEXT'),
|
||||||
|
getHTML: sandbox.stub().returns('SOMEHTML'),
|
||||||
|
getSubject: sandbox.stub().returns('SOMESUBJECT'),
|
||||||
|
transporter: {
|
||||||
|
sendMail: sandbox.stub().resolves()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const service = new MagicLink(options);
|
||||||
|
|
||||||
|
const args = {
|
||||||
|
email: 'one@email.com,two@email.com',
|
||||||
|
tokenData: {
|
||||||
|
id: '420'
|
||||||
|
},
|
||||||
|
type: 'blazeit',
|
||||||
|
referrer: 'https://whatever.com'
|
||||||
|
};
|
||||||
|
|
||||||
|
let errored = false;
|
||||||
|
try {
|
||||||
|
await service.sendMagicLink(args);
|
||||||
|
} catch (err) {
|
||||||
|
errored = true;
|
||||||
|
} finally {
|
||||||
|
assert(errored, 'sendMagicLink should error when given comma separated emails');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
it('Sends an email to the user with a link generated from getSigninURL(token, type)', async function () {
|
it('Sends an email to the user with a link generated from getSigninURL(token, type)', async function () {
|
||||||
const options = {
|
const options = {
|
||||||
tokenProvider: new MagicLink.JWTTokenProvider(secret),
|
tokenProvider: new MagicLink.JWTTokenProvider(secret),
|
||||||
|
@ -35,23 +67,23 @@ describe('MagicLink', function () {
|
||||||
};
|
};
|
||||||
const {token} = await service.sendMagicLink(args);
|
const {token} = await service.sendMagicLink(args);
|
||||||
|
|
||||||
should.ok(options.getSigninURL.calledOnce);
|
assert(options.getSigninURL.calledOnce);
|
||||||
should.ok(options.getSigninURL.firstCall.calledWithExactly(token, 'blazeit', 'https://whatever.com'));
|
assert(options.getSigninURL.firstCall.calledWithExactly(token, 'blazeit', 'https://whatever.com'));
|
||||||
|
|
||||||
should.ok(options.getText.calledOnce);
|
assert(options.getText.calledOnce);
|
||||||
should.ok(options.getText.firstCall.calledWithExactly('FAKEURL', 'blazeit', 'test@example.com'));
|
assert(options.getText.firstCall.calledWithExactly('FAKEURL', 'blazeit', 'test@example.com'));
|
||||||
|
|
||||||
should.ok(options.getHTML.calledOnce);
|
assert(options.getHTML.calledOnce);
|
||||||
should.ok(options.getHTML.firstCall.calledWithExactly('FAKEURL', 'blazeit', 'test@example.com'));
|
assert(options.getHTML.firstCall.calledWithExactly('FAKEURL', 'blazeit', 'test@example.com'));
|
||||||
|
|
||||||
should.ok(options.getSubject.calledOnce);
|
assert(options.getSubject.calledOnce);
|
||||||
should.ok(options.getSubject.firstCall.calledWithExactly('blazeit'));
|
assert(options.getSubject.firstCall.calledWithExactly('blazeit'));
|
||||||
|
|
||||||
should.ok(options.transporter.sendMail.calledOnce);
|
assert(options.transporter.sendMail.calledOnce);
|
||||||
should.equal(options.transporter.sendMail.firstCall.args[0].to, args.email);
|
assert.equal(options.transporter.sendMail.firstCall.args[0].to, args.email);
|
||||||
should.equal(options.transporter.sendMail.firstCall.args[0].subject, options.getSubject.firstCall.returnValue);
|
assert.equal(options.transporter.sendMail.firstCall.args[0].subject, options.getSubject.firstCall.returnValue);
|
||||||
should.equal(options.transporter.sendMail.firstCall.args[0].text, options.getText.firstCall.returnValue);
|
assert.equal(options.transporter.sendMail.firstCall.args[0].text, options.getText.firstCall.returnValue);
|
||||||
should.equal(options.transporter.sendMail.firstCall.args[0].html, options.getHTML.firstCall.returnValue);
|
assert.equal(options.transporter.sendMail.firstCall.args[0].html, options.getHTML.firstCall.returnValue);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -78,7 +110,7 @@ describe('MagicLink', function () {
|
||||||
const {token} = await service.sendMagicLink(args);
|
const {token} = await service.sendMagicLink(args);
|
||||||
const data = await service.getDataFromToken(token);
|
const data = await service.getDataFromToken(token);
|
||||||
|
|
||||||
should.deepEqual(data.id, args.tokenData.id);
|
assert.deepEqual(data.id, args.tokenData.id);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Reference in a new issue