diff --git a/README.md b/README.md index 21c6f3d..aaf9012 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ import { summaly } from 'summaly'; summaly(url[, opts]) ``` -As Fastify plugin: +As Fastify plugin: (will listen `GET` of `/`) ```javascript @@ -60,27 +60,39 @@ interface IPlugin { A Promise of an Object that contains properties below: -※ Almost all values are nullable. player shoud not be null. +※ Almost all values are nullable. player should not be null. #### Root -| Property | Type | Description | -| :-------------- | :------- | :--------------------------------------- | -| **description** | *string* | The description of the web page | -| **icon** | *string* | The url of the icon of the web page | -| **sitename** | *string* | The name of the web site | -| **thumbnail** | *string* | The url of the thumbnail of the web page | -| **player** | *Player* | The player of the web page | -| **title** | *string* | The title of the web page | -| **url** | *string* | The url of the web page | +| Property | Type | Description | +| :-------------- | :------- | :------------------------------------------ | +| **description** | *string* | The description of the web page | +| **icon** | *string* | The url of the icon of the web page | +| **sitename** | *string* | The name of the web site | +| **thumbnail** | *string* | The url of the thumbnail of the web page | +| **oEmbed** | *OEmbedRichIframe* | The oEmbed rich iframe info of the web page | +| **player** | *Player* | The player of the web page | +| **title** | *string* | The title of the web page | +| **url** | *string* | The url of the web page | #### Player -| Property | Type | Description | -| :-------------- | :------- | :--------------------------------------- | -| **url** | *string* | The url of the player | -| **width** | *number* | The width of the player | -| **height** | *number* | The height of the player | +| Property | Type | Description | +| :-------------- | :--------- | :---------------------------------------------- | +| **url** | *string* | The url of the player | +| **width** | *number* | The width of the player | +| **height** | *number* | The height of the player | +| **allow** | *string[]* | The names of the allowed permissions for iframe | + +Currently the possible items in `allow` are: + +* `autoplay` +* `clipboard-write` +* `fullscreen` +* `encrypted-media` +* `picture-in-picture` + +See [Permissions Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Permissions_Policy) in MDN for details of them. ### Example diff --git a/src/general.ts b/src/general.ts index c352498..495998c 100644 --- a/src/general.ts +++ b/src/general.ts @@ -5,7 +5,7 @@ import cleanupTitle from './utils/cleanup-title.js'; import { decode as decodeHtml } from 'html-entities'; import { get, head, scpaping } from './utils/got.js'; -import type { default as Summary, OEmbedRichIframe } from './summary.js'; +import type { default as Summary, Player } from './summary.js'; import * as cheerio from 'cheerio'; /** @@ -14,7 +14,7 @@ import * as cheerio from 'cheerio'; * * Width should always be 100%. */ -async function getOEmbedRich($: cheerio.CheerioAPI, pageUrl: string): Promise { +async function getOEmbedPlayer($: cheerio.CheerioAPI, pageUrl: string): Promise { const href = $('link[type="application/json+oembed"]').attr('href'); if (!href) { return null; @@ -29,7 +29,7 @@ async function getOEmbedRich($: cheerio.CheerioAPI, pageUrl: string): Promise { player: { url: playerUrl || null, width: playerWidth ? parseInt(playerWidth) : null, - height: playerHeight ? parseInt(playerHeight) : null + height: playerHeight ? parseInt(playerHeight) : null, + allow: playerUrl ? ['fullscreen', 'encrypted-media'] : [], }, sitename: 'Amazon', - oEmbed: null, }; } diff --git a/src/plugins/wikipedia.ts b/src/plugins/wikipedia.ts index f531108..f7d086e 100644 --- a/src/plugins/wikipedia.ts +++ b/src/plugins/wikipedia.ts @@ -38,9 +38,9 @@ export async function summarize(url: URL.Url): Promise { player: { url: null, width: null, - height: null + height: null, + allow: [], }, sitename: 'Wikipedia', - oEmbed: null, }; } diff --git a/src/summary.ts b/src/summary.ts index 4c75387..cc580cc 100644 --- a/src/summary.ts +++ b/src/summary.ts @@ -33,11 +33,6 @@ type Summary = { * Possibly sensitive */ sensitive?: boolean; - - /** - * The iframe information of oEmbed data from that web page - */ - oEmbed: OEmbedRichIframe | null; }; export default Summary; @@ -57,25 +52,9 @@ export type Player = { * The height of the player */ height: number | null; -}; - -/** - * Extracted iframe information from OEmbed html field. - * `width` is omitted here as it should always be 100%. - */ -export type OEmbedRichIframe = { - /** - * The src of the iframe - */ - src: string, - - /** - * The height of the iframe - */ - height: number, - - /** - * The allowed feature list of the iframe - */ - allow: string[], + + /** + * The allowed permissions of the iframe + */ + allow: string[]; }; diff --git a/test/index.ts b/test/index.ts index 2f01b87..4d18730 100644 --- a/test/index.ts +++ b/test/index.ts @@ -213,6 +213,7 @@ describe('TwitterCard', () => { const summary = await summaly(host); expect(summary.player.url).toBe('https://example.com/embedurl'); + expect(summary.player.allow).toStrictEqual(['fullscreen', 'encrypted-media']); }); test('Player detection - Pleroma:video => video', async () => { @@ -224,6 +225,7 @@ describe('TwitterCard', () => { const summary = await summaly(host); expect(summary.player.url).toBe('https://example.com/embedurl'); + expect(summary.player.allow).toStrictEqual(['fullscreen', 'encrypted-media']); }); test('Player detection - Pleroma:image => image', async () => { @@ -256,44 +258,44 @@ describe("oEmbed", () => { test(`Invalidity test: ${filename}`, async () => { await setUpFastify(`invalid/${filename}`); const summary = await summaly(host); - expect(summary.oEmbed).toBe(null); + expect(summary.player.url).toBe(null); }); } test('src', async () => { await setUpFastify('oembed.json'); const summary = await summaly(host); - expect(summary.oEmbed?.src).toBe('https://example.com/'); + expect(summary.player.url).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); + expect(summary.player.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/'); + expect(summary.player.url).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/'); + expect(summary.player.url).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/'); + expect(summary.player.url).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/'); + expect(summary.player.url).toBe('https://example.com/'); }); test('oEmbed with nonexistent path', async () => { @@ -309,21 +311,21 @@ describe("oEmbed", () => { 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.player.url).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.player.url).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'); + expect(summary.player.url).toBe('https://example.com/'); + expect(summary.player.allow).toStrictEqual([]); }); });