mirror of
https://github.com/misskey-dev/summaly.git
synced 2025-07-02 16:19:59 +09:00
feat: add oEmbed support
This commit is contained in:
3
test/htmls/oembed-and-og-video.html
Normal file
3
test/htmls/oembed-and-og-video.html
Normal file
@ -0,0 +1,3 @@
|
||||
<!DOCTYPE html>
|
||||
<meta property="og:video:url" content="https://example.com/embedurl" />
|
||||
<link type="application/json+oembed" href="http://localhost:3060/oembed.json" />
|
3
test/htmls/oembed-and-og.html
Normal file
3
test/htmls/oembed-and-og.html
Normal file
@ -0,0 +1,3 @@
|
||||
<!DOCTYPE html>
|
||||
<meta property="og:description" content="blobcats rule the world">
|
||||
<link type="application/json+oembed" href="http://localhost:3060/oembed.json" />
|
2
test/htmls/oembed-nonexistent-path.html
Normal file
2
test/htmls/oembed-nonexistent-path.html
Normal file
@ -0,0 +1,2 @@
|
||||
<!DOCTYPE html>
|
||||
<link type="application/json+oembed" href="http://localhost:3060/oembe.json" />
|
2
test/htmls/oembed-relative.html
Normal file
2
test/htmls/oembed-relative.html
Normal file
@ -0,0 +1,2 @@
|
||||
<!DOCTYPE html>
|
||||
<link type="application/json+oembed" href="oembed.json" />
|
2
test/htmls/oembed-wrong.html
Normal file
2
test/htmls/oembed-wrong.html
Normal file
@ -0,0 +1,2 @@
|
||||
<!DOCTYPE html>
|
||||
<link type="application/json+oembed" href="http://localhost+:3060/oembed.json" />
|
2
test/htmls/oembed.html
Normal file
2
test/htmls/oembed.html
Normal file
@ -0,0 +1,2 @@
|
||||
<!DOCTYPE html>
|
||||
<link type="application/json+oembed" href="http://localhost:3060/oembed.json" />
|
@ -6,13 +6,13 @@
|
||||
|
||||
/* dependencies below */
|
||||
|
||||
import fs from 'node:fs';
|
||||
import fs, { readdirSync } from 'node:fs';
|
||||
import process from 'node:process';
|
||||
import fastify from 'fastify';
|
||||
import { summaly } from '../src/index.js';
|
||||
import { dirname } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import {expect, jest, test, describe, beforeEach, afterEach} from '@jest/globals';
|
||||
import { expect, jest, test, describe, beforeEach, afterEach } from '@jest/globals';
|
||||
import { Agent as httpAgent } from 'node:http';
|
||||
import { Agent as httpsAgent } from 'node:https';
|
||||
import { StatusError } from '../src/utils/status-error.js';
|
||||
@ -237,3 +237,93 @@ describe('TwitterCard', () => {
|
||||
expect(summary.thumbnail).toBe('https://example.com/imageurl');
|
||||
});
|
||||
});
|
||||
|
||||
describe("oEmbed", () => {
|
||||
const setUpFastify = async (oEmbedPath: string, htmlPath = 'htmls/oembed.html') => {
|
||||
app = fastify();
|
||||
app.get('/', (request, reply) => {
|
||||
return reply.send(fs.createReadStream(new URL(htmlPath, import.meta.url)));
|
||||
});
|
||||
app.get('/oembed.json', (request, reply) => {
|
||||
return reply.send(fs.createReadStream(
|
||||
new URL(oEmbedPath, new URL('oembed/', import.meta.url))
|
||||
));
|
||||
});
|
||||
await app.listen({ port });
|
||||
}
|
||||
|
||||
for (const filename of readdirSync(new URL('oembed/invalid', import.meta.url))) {
|
||||
test(`Invalidity test: ${filename}`, async () => {
|
||||
await setUpFastify(`invalid/${filename}`);
|
||||
const summary = await summaly(host);
|
||||
expect(summary.oEmbed).toBe(null);
|
||||
});
|
||||
}
|
||||
|
||||
test('src', async () => {
|
||||
await setUpFastify('oembed.json');
|
||||
const summary = await summaly(host);
|
||||
expect(summary.oEmbed?.src).toBe('https://example.com/');
|
||||
});
|
||||
|
||||
test('max height', async () => {
|
||||
await setUpFastify('oembed-too-tall.json');
|
||||
const summary = await summaly(host);
|
||||
expect(summary.oEmbed?.height).toBe(1024);
|
||||
});
|
||||
|
||||
test('children are ignored', async () => {
|
||||
await setUpFastify('oembed-iframe-child.json');
|
||||
const summary = await summaly(host);
|
||||
expect(summary.oEmbed?.src).toBe('https://example.com/');
|
||||
});
|
||||
|
||||
test('allows fullscreen', async () => {
|
||||
await setUpFastify('oembed-allow-fullscreen.json');
|
||||
const summary = await summaly(host);
|
||||
expect(summary.oEmbed?.src).toBe('https://example.com/');
|
||||
});
|
||||
|
||||
test('allows safelisted features', async () => {
|
||||
await setUpFastify('oembed-allow-safelisted-features.json');
|
||||
const summary = await summaly(host);
|
||||
expect(summary.oEmbed?.src).toBe('https://example.com/');
|
||||
});
|
||||
|
||||
test('oEmbed with relative path', async () => {
|
||||
await setUpFastify('oembed.json', 'htmls/oembed-relative.html');
|
||||
const summary = await summaly(host);
|
||||
expect(summary.oEmbed?.src).toBe('https://example.com/');
|
||||
});
|
||||
|
||||
test('oEmbed with nonexistent path', async () => {
|
||||
await setUpFastify('oembed.json', 'htmls/oembed-nonexistent-path.html');
|
||||
await expect(summaly(host)).rejects.toThrow('404 Not Found');
|
||||
});
|
||||
|
||||
test('oEmbed with wrong path', async () => {
|
||||
await setUpFastify('oembed.json', 'htmls/oembed-wrong-path.html');
|
||||
await expect(summaly(host)).rejects.toThrow();
|
||||
});
|
||||
|
||||
test('oEmbed with OpenGraph', async () => {
|
||||
await setUpFastify('oembed.json', 'htmls/oembed-and-og.html');
|
||||
const summary = await summaly(host);
|
||||
expect(summary.oEmbed?.src).toBe('https://example.com/');
|
||||
expect(summary.description).toBe('blobcats rule the world');
|
||||
});
|
||||
|
||||
test('Invalid oEmbed with valid OpenGraph', async () => {
|
||||
await setUpFastify('invalid/oembed-insecure.json', 'htmls/oembed-and-og.html');
|
||||
const summary = await summaly(host);
|
||||
expect(summary.oEmbed).toBe(null);
|
||||
expect(summary.description).toBe('blobcats rule the world');
|
||||
});
|
||||
|
||||
test('oEmbed with og:video', async () => {
|
||||
await setUpFastify('oembed.json', 'htmls/oembed-and-og-video.html');
|
||||
const summary = await summaly(host);
|
||||
expect(summary.oEmbed).toBe(null);
|
||||
expect(summary.player.url).toBe('https://example.com/embedurl');
|
||||
});
|
||||
});
|
||||
|
6
test/oembed/invalid/oembed-child-iframe.json
Normal file
6
test/oembed/invalid/oembed-child-iframe.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"version": "1.0",
|
||||
"type": "rich",
|
||||
"html": "<div><iframe src='https://example.com/'></iframe>",
|
||||
"height": 300
|
||||
}
|
6
test/oembed/invalid/oembed-double-iframes.json
Normal file
6
test/oembed/invalid/oembed-double-iframes.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"version": "1.0",
|
||||
"type": "rich",
|
||||
"html": "<iframe src='https://example.com/'></iframe><iframe src='https://example.com/'></iframe>",
|
||||
"height": 300
|
||||
}
|
6
test/oembed/invalid/oembed-future.json
Normal file
6
test/oembed/invalid/oembed-future.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"version": "11.0",
|
||||
"type": "rich",
|
||||
"html": "<iframe src='https://example.com/'></iframe>",
|
||||
"height": 300
|
||||
}
|
6
test/oembed/invalid/oembed-insecure.json
Normal file
6
test/oembed/invalid/oembed-insecure.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"version": "1.0",
|
||||
"type": "rich",
|
||||
"html": "<iframe src='http://example.com/'></iframe>",
|
||||
"height": 300
|
||||
}
|
6
test/oembed/invalid/oembed-invalid-height.json
Normal file
6
test/oembed/invalid/oembed-invalid-height.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"version": "1.0",
|
||||
"type": "rich",
|
||||
"html": "<iframe src='https://example.com/'></iframe>",
|
||||
"height": "blobcat"
|
||||
}
|
5
test/oembed/invalid/oembed-no-height.json
Normal file
5
test/oembed/invalid/oembed-no-height.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"version": "1.0",
|
||||
"type": "rich",
|
||||
"html": "<iframe src='https://example.com/'></iframe>"
|
||||
}
|
5
test/oembed/invalid/oembed-no-version.json
Normal file
5
test/oembed/invalid/oembed-no-version.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"type": "rich",
|
||||
"html": "<iframe src='https://example.com/'></iframe>",
|
||||
"height": 300
|
||||
}
|
6
test/oembed/invalid/oembed-old.json
Normal file
6
test/oembed/invalid/oembed-old.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"version": "0.1",
|
||||
"type": "rich",
|
||||
"html": "<iframe src='https://example.com/'></iframe>",
|
||||
"height": 300
|
||||
}
|
7
test/oembed/invalid/oembed-photo.json
Normal file
7
test/oembed/invalid/oembed-photo.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"version": "1.0",
|
||||
"type": "photo",
|
||||
"url": "https://example.com/example.avif",
|
||||
"width": 300,
|
||||
"height": 300
|
||||
}
|
6
test/oembed/invalid/oembed-too-powerful.json
Normal file
6
test/oembed/invalid/oembed-too-powerful.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"version": "1.0",
|
||||
"type": "rich",
|
||||
"html": "<iframe src='https://example.com/' allow='camera'></iframe>",
|
||||
"height": 300
|
||||
}
|
6
test/oembed/invalid/oembed-too-powerful2.json
Normal file
6
test/oembed/invalid/oembed-too-powerful2.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"version": "1.0",
|
||||
"type": "rich",
|
||||
"html": "<iframe src='https://example.com/' allow='fullscreen camera'></iframe>",
|
||||
"height": 300
|
||||
}
|
6
test/oembed/oembed-allow-fullscreen.json
Normal file
6
test/oembed/oembed-allow-fullscreen.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"version": "1.0",
|
||||
"type": "rich",
|
||||
"html": "<iframe src='https://example.com/' allow='fullscreen'></iframe>",
|
||||
"height": 300
|
||||
}
|
6
test/oembed/oembed-allow-safelisted-features.json
Normal file
6
test/oembed/oembed-allow-safelisted-features.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"version": "1.0",
|
||||
"type": "rich",
|
||||
"html": "<iframe src='https://example.com/' allow='fullscreen encrypted-media picture-in-picture'></iframe>",
|
||||
"height": 300
|
||||
}
|
6
test/oembed/oembed-iframe-child.json
Normal file
6
test/oembed/oembed-iframe-child.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"version": "1.0",
|
||||
"type": "rich",
|
||||
"html": "<iframe src='https://example.com/'><script>alert('Hahaha I take this world')</script></iframe>",
|
||||
"height": 300
|
||||
}
|
6
test/oembed/oembed-too-tall.json
Normal file
6
test/oembed/oembed-too-tall.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"version": "1.0",
|
||||
"type": "rich",
|
||||
"html": "<iframe src='https://example.com/'></iframe>",
|
||||
"height": 3000
|
||||
}
|
6
test/oembed/oembed.json
Normal file
6
test/oembed/oembed.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"version": "1.0",
|
||||
"type": "rich",
|
||||
"html": "<iframe src='https://example.com/'></iframe>",
|
||||
"height": 300
|
||||
}
|
Reference in New Issue
Block a user