mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-29 22:01:49 +03:00
7b761a8751
no issue Adds new canary api endpoint, currently replicating v2 endpoint but paving way for future updates to new version
98 lines
2.8 KiB
JavaScript
98 lines
2.8 KiB
JavaScript
const common = require('../../lib/common');
|
|
const {extract, hasProvider} = require('oembed-parser');
|
|
const Promise = require('bluebird');
|
|
const request = require('../../lib/request');
|
|
const cheerio = require('cheerio');
|
|
|
|
const findUrlWithProvider = (url) => {
|
|
let provider;
|
|
|
|
// build up a list of URL variations to test against because the oembed
|
|
// providers list is not always up to date with scheme or www vs non-www
|
|
let baseUrl = url.replace(/^\/\/|^https?:\/\/(?:www\.)?/, '');
|
|
let testUrls = [
|
|
`http://${baseUrl}`,
|
|
`https://${baseUrl}`,
|
|
`http://www.${baseUrl}`,
|
|
`https://www.${baseUrl}`
|
|
];
|
|
|
|
for (let testUrl of testUrls) {
|
|
provider = hasProvider(testUrl);
|
|
if (provider) {
|
|
url = testUrl;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return {url, provider};
|
|
};
|
|
|
|
const getOembedUrlFromHTML = (html) => {
|
|
return cheerio('link[type="application/json+oembed"]', html).attr('href');
|
|
};
|
|
|
|
module.exports = {
|
|
docName: 'oembed',
|
|
|
|
read: {
|
|
permissions: false,
|
|
data: [
|
|
'url'
|
|
],
|
|
options: [],
|
|
query({data}) {
|
|
let {url} = data;
|
|
|
|
function unknownProvider() {
|
|
return Promise.reject(new common.errors.ValidationError({
|
|
message: common.i18n.t('errors.api.oembed.unknownProvider'),
|
|
context: url
|
|
}));
|
|
}
|
|
|
|
function knownProvider(url) {
|
|
return extract(url).catch((err) => {
|
|
return Promise.reject(new common.errors.InternalServerError({
|
|
message: err.message
|
|
}));
|
|
});
|
|
}
|
|
|
|
let provider;
|
|
({url, provider} = findUrlWithProvider(url));
|
|
|
|
if (provider) {
|
|
return knownProvider(url);
|
|
}
|
|
|
|
// see if the URL is a redirect to cater for shortened urls
|
|
return request(url, {
|
|
method: 'GET',
|
|
timeout: 2 * 1000,
|
|
followRedirect: true
|
|
}).then((response) => {
|
|
if (response.url !== url) {
|
|
({url, provider} = findUrlWithProvider(response.url));
|
|
return provider ? knownProvider(url) : unknownProvider();
|
|
}
|
|
|
|
const oembedUrl = getOembedUrlFromHTML(response.body);
|
|
|
|
if (!oembedUrl) {
|
|
return unknownProvider();
|
|
}
|
|
|
|
return request(oembedUrl, {
|
|
method: 'GET',
|
|
json: true
|
|
}).then((response) => {
|
|
return response.body;
|
|
});
|
|
}).catch(() => {
|
|
return unknownProvider();
|
|
});
|
|
}
|
|
}
|
|
};
|