🐛 Fixed broken embeds cards when pasting links to Wordpress sites (#12262)

closes https://github.com/TryGhost/Ghost/issues/12260

- if a card type was not explicitly chosen (i.e. a url was pasted into the editor) then abort fetching the oembed endpoint if we detect it's a `wp-json` oembed and return a bookmark card payload instead
- cleaned up an unused argument in the internal `fetchBookmarkData()` method
This commit is contained in:
Kevin Ansfield 2020-10-06 08:44:03 +01:00 committed by GitHub
parent ce4da16edb
commit 9cbeb74db0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 44 additions and 7 deletions

View File

@ -8,7 +8,7 @@ const config = require('../../../shared/config');
const {i18n} = require('../../lib/common'); const {i18n} = require('../../lib/common');
const externalRequest = require('../../lib/request-external'); const externalRequest = require('../../lib/request-external');
async function fetchBookmarkData(url, html) { async function fetchBookmarkData(url) {
const metascraper = require('metascraper')([ const metascraper = require('metascraper')([
require('metascraper-url')(), require('metascraper-url')(),
require('metascraper-title')(), require('metascraper-title')(),
@ -23,11 +23,9 @@ async function fetchBookmarkData(url, html) {
let scraperResponse; let scraperResponse;
try { try {
if (!html) { const cookieJar = new CookieJar();
const cookieJar = new CookieJar(); const response = await externalRequest(url, {cookieJar});
const response = await externalRequest(url, {cookieJar}); const html = response.body;
html = response.body;
}
scraperResponse = await metascraper({html, url}); scraperResponse = await metascraper({html, url});
} catch (err) { } catch (err) {
return Promise.reject(err); return Promise.reject(err);
@ -118,7 +116,7 @@ function isIpOrLocalhost(url) {
} }
} }
function fetchOembedData(_url) { function fetchOembedData(_url, cardType) {
// parse the url then validate the protocol and host to make sure it's // parse the url then validate the protocol and host to make sure it's
// http(s) and not an IP address or localhost to avoid potential access to // http(s) and not an IP address or localhost to avoid potential access to
// internal network endpoints // internal network endpoints
@ -163,6 +161,12 @@ function fetchOembedData(_url) {
return unknownProvider(oembedUrl); return unknownProvider(oembedUrl);
} }
// for standard WP oembed's we want to insert a bookmark card rather than their blockquote+script
// which breaks in the editor and most Ghost themes. Only fallback if card type was not explicitly chosen
if (!cardType && oembedUrl.match(/wp-json\/oembed/)) {
return;
}
// fetch oembed response from embedded rel="alternate" url // fetch oembed response from embedded rel="alternate" url
return externalRequest(oembedUrl, { return externalRequest(oembedUrl, {
method: 'GET', method: 'GET',

View File

@ -598,5 +598,38 @@ describe('Oembed API', function () {
done(); done();
}); });
}); });
it('falls back to bookmark card for WP oembeds', function (done) {
const pageMock = nock('http://test.com')
.get('/')
.twice() // oembed fetch then bookmark fetch
.reply(
200,
'<html><head><link rel="alternate" type="application/json+oembed" href="http://test.com/wp-json/oembed/embed?url=https%3A%2F%2Ftest.com%2F"><title>TESTING</title></head><body></body></html>',
{'content-type': 'text/html'}
);
const oembedMock = nock('http://test.com')
.get('/wp-json/oembed/embed')
.reply(200, {
version: '1.0',
type: 'link'
});
const url = encodeURIComponent('http://test.com');
request.get(localUtils.API.getApiQuery(`oembed/?url=${url}`))
.set('Origin', config.get('url'))
.expect('Content-Type', /json/)
.expect('Cache-Control', testUtils.cacheRules.private)
.expect(200)
.end(function (err, res) {
if (err) {
return done(err);
}
pageMock.isDone().should.be.true();
oembedMock.isDone().should.be.false();
done();
});
});
}); });
}); });