perf(backend): use node-html-parser instead of microformats-parser (#16907)

* perf(backend): use node-html-parser instead of microformats-parser

microformats-parser は内部的に parse5 に依存していて無駄

* Update OAuth2ProviderService.ts

* Add 'id' parameter to parseMicroformats function

* Update OAuth2ProviderService.ts

* Update OAuth2ProviderService.ts
This commit is contained in:
syuilo 2025-11-30 18:45:56 +09:00 committed by GitHub
parent dfd479bec5
commit 5e2a6021ae
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 83 additions and 146 deletions

View File

@ -134,7 +134,6 @@
"juice": "11.0.3",
"meilisearch": "0.54.0",
"mfm-js": "0.25.0",
"microformats-parser": "2.0.4",
"mime-types": "3.0.2",
"misskey-js": "workspace:*",
"misskey-reversi": "workspace:*",

View File

@ -17,7 +17,6 @@ import pug from 'pug';
import bodyParser from 'body-parser';
import fastifyExpress from '@fastify/express';
import { verifyChallenge } from 'pkce-challenge';
import { mf2 } from 'microformats-parser';
import { permissions as kinds } from 'misskey-js';
import { secureRndstr } from '@/misc/secure-rndstr.js';
import { HttpRequestService } from '@/core/HttpRequestService.js';
@ -98,6 +97,32 @@ interface ClientInformation {
logo: string | null;
}
function parseMicroformats(doc: htmlParser.HTMLElement, baseUrl: string, id: string): { name: string | null; logo: string | null; } {
let name: string | null = null;
let logo: string | null = null;
const hApp = doc.querySelector('.h-app');
if (hApp == null) return { name, logo };
const nameEl = hApp.querySelector('.p-name');
if (nameEl != null) {
const href = nameEl.attributes.href || nameEl.attributes.src;
if (href != null && new URL(href, baseUrl).toString() === new URL(id).toString()) {
name = nameEl.textContent.trim();
}
}
const logoEl = hApp.querySelector('.u-logo');
if (logoEl != null) {
const href = logoEl.attributes.href || logoEl.attributes.src;
if (href != null) {
logo = new URL(href, baseUrl).toString();
}
}
return { name, logo };
}
// https://indieauth.spec.indieweb.org/#client-information-discovery
// "Authorization servers SHOULD support parsing the [h-app] Microformat from the client_id,
// and if there is an [h-app] with a url property matching the client_id URL,
@ -120,24 +145,19 @@ async function discoverClientInformation(logger: Logger, httpRequestService: Htt
}
const text = await res.text();
const fragment = htmlParser.parse(`<div>${text}</div>`);
const doc = htmlParser.parse(`<div>${text}</div>`);
redirectUris.push(...[...fragment.querySelectorAll('link[rel=redirect_uri][href]')].map(el => el.attributes.href));
redirectUris.push(...[...doc.querySelectorAll('link[rel=redirect_uri][href]')].map(el => el.attributes.href));
let name = id;
let logo: string | null = null;
if (text) {
const microformats = mf2(text, { baseUrl: res.url });
const correspondingProperties = microformats.items.find(item => item.type?.includes('h-app') && item.properties.url.includes(id));
if (correspondingProperties) {
const nameProperty = correspondingProperties.properties.name?.[0];
if (typeof nameProperty === 'string') {
name = nameProperty;
}
const logoProperty = correspondingProperties.properties.logo?.[0];
if (typeof logoProperty === 'string') {
logo = logoProperty;
}
const microformats = parseMicroformats(doc, res.url, id);
if (typeof microformats.name === 'string') {
name = microformats.name;
}
if (typeof microformats.logo === 'string') {
logo = microformats.logo;
}
}

View File

@ -288,9 +288,6 @@ importers:
mfm-js:
specifier: 0.25.0
version: 0.25.0
microformats-parser:
specifier: 2.0.4
version: 2.0.4
mime-types:
specifier: 3.0.2
version: 3.0.2
@ -6208,11 +6205,6 @@ packages:
csstype@3.2.3:
resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
cypress@15.6.0:
resolution: {integrity: sha512-Vqo66GG1vpxZ7H1oDX9umfmzA3nF7Wy80QAc3VjwPREO5zTY4d1xfQFNPpOWleQl9vpdmR2z1liliOcYlRX6rQ==}
engines: {node: ^20.1.0 || ^22.0.0 || >=24.0.0}
hasBin: true
cypress@15.7.0:
resolution: {integrity: sha512-1C81zKxnQckYm2XGi37rPV4rN0bzUoWhydhKdOyshJn5gJKszEx5as9VLSZI0jp0ye49QxmnbU4TtMpcD+OmGQ==}
engines: {node: ^20.1.0 || ^22.0.0 || >=24.0.0}
@ -8295,10 +8287,6 @@ packages:
mfm-js@0.25.0:
resolution: {integrity: sha512-JoK5TOtswXIvZSZ9hUEL+ZkcNV4onu/DtkaKeXK846+sJBBF8DvxYmPutt7nPaRDsUMmJGr64PNVMFpMGdk3hw==}
microformats-parser@2.0.4:
resolution: {integrity: sha512-DA2yt3uz2JjupBGoNvaG9ngBP5vSTI1ky2yhxBai/RnQrlzo+gEzuCdvwIIjj2nh3uVPDybTP5u7uua7pOa6LA==}
engines: {node: '>=18'}
micromark-core-commonmark@2.0.3:
resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==}
@ -10115,11 +10103,6 @@ packages:
standard-as-callback@2.1.0:
resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==}
start-server-and-test@2.1.2:
resolution: {integrity: sha512-OIjfo3G6QV9Sh6IlMqj58oZwVhPVuU/l6uVACG7YNE9kAfDvcYoPThtb0NNT3tZMMC3wOYbXnC15yiCSNFkdRg==}
engines: {node: '>=16'}
hasBin: true
start-server-and-test@2.1.3:
resolution: {integrity: sha512-k4EcbNjeg0odaDkAMlIeDVDByqX9PIgL4tivgP2tES6Zd8o+4pTq/HgbWCyA3VHIoZopB+wGnNPKYGGSByNriQ==}
engines: {node: '>=16'}
@ -11078,11 +11061,6 @@ packages:
resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==}
engines: {node: '>=18'}
wait-on@8.0.5:
resolution: {integrity: sha512-J3WlS0txVHkhLRb2FsmRg3dkMTCV1+M6Xra3Ho7HzZDHpE7DCOnoSoCJsZotrmW3uRMhvIJGSKUKrh/MeF4iag==}
engines: {node: '>=12.0.0'}
hasBin: true
wait-on@9.0.3:
resolution: {integrity: sha512-13zBnyYvFDW1rBvWiJ6Av3ymAaq8EDQuvxZnPIw3g04UqGi4TyoIJABmfJ6zrvKo9yeFQExNkOk7idQbDJcuKA==}
engines: {node: '>=20.0.0'}
@ -11374,7 +11352,7 @@ snapshots:
'@apm-js-collab/tracing-hooks@0.3.1':
dependencies:
'@apm-js-collab/code-transformer': 0.8.2
debug: 4.4.3(supports-color@10.2.2)
debug: 4.4.3(supports-color@5.5.0)
module-details-from-path: 1.0.4
transitivePeerDependencies:
- supports-color
@ -11956,7 +11934,7 @@ snapshots:
'@babel/types': 7.28.5
'@jridgewell/remapping': 2.3.5
convert-source-map: 2.0.0
debug: 4.4.3(supports-color@10.2.2)
debug: 4.4.3(supports-color@5.5.0)
gensync: 1.0.0-beta.2
json5: 2.2.3
semver: 6.3.1
@ -12115,7 +12093,7 @@ snapshots:
'@babel/parser': 7.28.5
'@babel/template': 7.27.2
'@babel/types': 7.28.5
debug: 4.4.3(supports-color@10.2.2)
debug: 4.4.3(supports-color@5.5.0)
transitivePeerDependencies:
- supports-color
@ -12447,7 +12425,7 @@ snapshots:
'@eslint/config-array@0.21.1':
dependencies:
'@eslint/object-schema': 2.1.7
debug: 4.4.3(supports-color@10.2.2)
debug: 4.4.3(supports-color@5.5.0)
minimatch: 3.1.2
transitivePeerDependencies:
- supports-color
@ -12467,7 +12445,7 @@ snapshots:
'@eslint/eslintrc@3.3.1':
dependencies:
ajv: 6.12.6
debug: 4.4.3(supports-color@10.2.2)
debug: 4.4.3(supports-color@5.5.0)
espree: 10.4.0
globals: 14.0.0
ignore: 5.3.2
@ -13305,7 +13283,7 @@ snapshots:
dependencies:
agent-base: 7.1.4
http-proxy-agent: 7.0.2
https-proxy-agent: 7.0.6(supports-color@10.2.2)
https-proxy-agent: 7.0.6
lru-cache: 10.4.3
socks-proxy-agent: 8.0.5
transitivePeerDependencies:
@ -15015,7 +14993,7 @@ snapshots:
'@tokenizer/inflate@0.2.7':
dependencies:
debug: 4.4.3(supports-color@10.2.2)
debug: 4.4.3(supports-color@5.5.0)
fflate: 0.8.2
token-types: 6.1.1
transitivePeerDependencies:
@ -15023,7 +15001,7 @@ snapshots:
'@tokenizer/inflate@0.3.1':
dependencies:
debug: 4.4.3(supports-color@10.2.2)
debug: 4.4.3(supports-color@5.5.0)
fflate: 0.8.2
token-types: 6.1.1
transitivePeerDependencies:
@ -15031,7 +15009,7 @@ snapshots:
'@tokenizer/inflate@0.4.1':
dependencies:
debug: 4.4.3(supports-color@10.2.2)
debug: 4.4.3(supports-color@5.5.0)
token-types: 6.1.1
transitivePeerDependencies:
- supports-color
@ -15424,7 +15402,7 @@ snapshots:
'@typescript-eslint/types': 8.47.0
'@typescript-eslint/typescript-estree': 8.47.0(typescript@5.9.3)
'@typescript-eslint/visitor-keys': 8.47.0
debug: 4.4.3(supports-color@10.2.2)
debug: 4.4.3(supports-color@5.5.0)
eslint: 9.39.1
typescript: 5.9.3
transitivePeerDependencies:
@ -15434,7 +15412,7 @@ snapshots:
dependencies:
'@typescript-eslint/tsconfig-utils': 8.47.0(typescript@5.9.3)
'@typescript-eslint/types': 8.47.0
debug: 4.4.3(supports-color@10.2.2)
debug: 4.4.3(supports-color@5.5.0)
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
@ -15453,7 +15431,7 @@ snapshots:
'@typescript-eslint/types': 8.47.0
'@typescript-eslint/typescript-estree': 8.47.0(typescript@5.9.3)
'@typescript-eslint/utils': 8.47.0(eslint@9.39.1)(typescript@5.9.3)
debug: 4.4.3(supports-color@10.2.2)
debug: 4.4.3(supports-color@5.5.0)
eslint: 9.39.1
ts-api-utils: 2.1.0(typescript@5.9.3)
typescript: 5.9.3
@ -15468,7 +15446,7 @@ snapshots:
'@typescript-eslint/tsconfig-utils': 8.47.0(typescript@5.9.3)
'@typescript-eslint/types': 8.47.0
'@typescript-eslint/visitor-keys': 8.47.0
debug: 4.4.3(supports-color@10.2.2)
debug: 4.4.3(supports-color@5.5.0)
fast-glob: 3.3.3
is-glob: 4.0.3
minimatch: 9.0.5
@ -15937,7 +15915,7 @@ snapshots:
agent-base@6.0.2:
dependencies:
debug: 4.4.3(supports-color@10.2.2)
debug: 4.4.3(supports-color@5.5.0)
transitivePeerDependencies:
- supports-color
optional: true
@ -16229,7 +16207,7 @@ snapshots:
axios@0.24.0:
dependencies:
follow-redirects: 1.15.11(debug@4.4.3)
follow-redirects: 1.15.11
transitivePeerDependencies:
- debug
@ -16363,7 +16341,7 @@ snapshots:
dependencies:
bytes: 3.1.2
content-type: 1.0.5
debug: 4.4.3(supports-color@10.2.2)
debug: 4.4.3(supports-color@5.5.0)
http-errors: 2.0.0
iconv-lite: 0.6.3
on-finished: 2.4.1
@ -16962,52 +16940,6 @@ snapshots:
csstype@3.2.3: {}
cypress@15.6.0:
dependencies:
'@cypress/request': 3.0.9
'@cypress/xvfb': 1.2.4(supports-color@8.1.1)
'@types/sinonjs__fake-timers': 8.1.1
'@types/sizzle': 2.3.10
'@types/tmp': 0.2.6
arch: 2.2.0
blob-util: 2.0.2
bluebird: 3.7.2
buffer: 5.7.1
cachedir: 2.4.0
chalk: 4.1.2
ci-info: 4.3.1
cli-cursor: 3.1.0
cli-table3: 0.6.1
commander: 6.2.1
common-tags: 1.8.2
dayjs: 1.11.19
debug: 4.4.3(supports-color@8.1.1)
enquirer: 2.4.1
eventemitter2: 6.4.7
execa: 4.1.0
executable: 4.1.1
extract-zip: 2.0.1(supports-color@8.1.1)
figures: 3.2.0
fs-extra: 9.1.0
hasha: 5.2.2
is-installed-globally: 0.4.0
listr2: 3.14.0(enquirer@2.4.1)
lodash: 4.17.21
log-symbols: 4.1.0
minimist: 1.2.8
ospath: 1.2.2
pretty-bytes: 5.6.0
process: 0.11.10
proxy-from-env: 1.0.0
request-progress: 3.0.0
semver: 7.7.3
supports-color: 8.1.1
systeminformation: 5.27.7
tmp: 0.2.5
tree-kill: 1.2.2
untildify: 4.0.0
yauzl: 2.10.0
cypress@15.7.0:
dependencies:
'@cypress/request': 3.0.9
@ -17093,6 +17025,10 @@ snapshots:
dependencies:
ms: 2.0.0
debug@3.2.7:
dependencies:
ms: 2.1.3
debug@3.2.7(supports-color@8.1.1):
dependencies:
ms: 2.1.3
@ -17575,7 +17511,7 @@ snapshots:
eslint-import-resolver-node@0.3.9:
dependencies:
debug: 3.2.7(supports-color@8.1.1)
debug: 3.2.7
is-core-module: 2.16.1
resolve: 1.22.11
transitivePeerDependencies:
@ -17583,7 +17519,7 @@ snapshots:
eslint-module-utils@2.12.1(@typescript-eslint/parser@8.47.0(eslint@9.39.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.1):
dependencies:
debug: 3.2.7(supports-color@8.1.1)
debug: 3.2.7
optionalDependencies:
'@typescript-eslint/parser': 8.47.0(eslint@9.39.1)(typescript@5.9.3)
eslint: 9.39.1
@ -17598,7 +17534,7 @@ snapshots:
array.prototype.findlastindex: 1.2.6
array.prototype.flat: 1.3.3
array.prototype.flatmap: 1.3.3
debug: 3.2.7(supports-color@8.1.1)
debug: 3.2.7
doctrine: 2.1.0
eslint: 9.39.1
eslint-import-resolver-node: 0.3.9
@ -17662,7 +17598,7 @@ snapshots:
ajv: 6.12.6
chalk: 4.1.2
cross-spawn: 7.0.6
debug: 4.4.3(supports-color@10.2.2)
debug: 4.4.3(supports-color@5.5.0)
escape-string-regexp: 4.0.0
eslint-scope: 8.4.0
eslint-visitor-keys: 4.2.1
@ -17857,7 +17793,7 @@ snapshots:
content-type: 1.0.5
cookie: 0.7.1
cookie-signature: 1.2.2
debug: 4.4.3(supports-color@10.2.2)
debug: 4.4.3(supports-color@5.5.0)
encodeurl: 2.0.0
escape-html: 1.0.3
etag: 1.8.1
@ -18061,7 +17997,7 @@ snapshots:
finalhandler@2.1.0:
dependencies:
debug: 4.4.3(supports-color@10.2.2)
debug: 4.4.3(supports-color@5.5.0)
encodeurl: 2.0.0
escape-html: 1.0.3
on-finished: 2.4.1
@ -18110,6 +18046,8 @@ snapshots:
async: 0.2.10
which: 1.3.1
follow-redirects@1.15.11: {}
follow-redirects@1.15.11(debug@4.4.3):
optionalDependencies:
debug: 4.4.3(supports-color@10.2.2)
@ -18506,7 +18444,7 @@ snapshots:
http-proxy-agent@7.0.2:
dependencies:
agent-base: 7.1.4
debug: 4.4.3(supports-color@10.2.2)
debug: 4.4.3(supports-color@5.5.0)
transitivePeerDependencies:
- supports-color
@ -18526,7 +18464,7 @@ snapshots:
https-proxy-agent@2.2.4:
dependencies:
agent-base: 4.3.0
debug: 3.2.7(supports-color@8.1.1)
debug: 3.2.7
transitivePeerDependencies:
- supports-color
optional: true
@ -18534,11 +18472,18 @@ snapshots:
https-proxy-agent@5.0.1:
dependencies:
agent-base: 6.0.2
debug: 4.4.3(supports-color@10.2.2)
debug: 4.4.3(supports-color@5.5.0)
transitivePeerDependencies:
- supports-color
optional: true
https-proxy-agent@7.0.6:
dependencies:
agent-base: 7.1.4
debug: 4.4.3(supports-color@5.5.0)
transitivePeerDependencies:
- supports-color
https-proxy-agent@7.0.6(supports-color@10.2.2):
dependencies:
agent-base: 7.1.4
@ -18638,7 +18583,7 @@ snapshots:
dependencies:
'@ioredis/commands': 1.4.0
cluster-key-slot: 1.1.2
debug: 4.4.3(supports-color@10.2.2)
debug: 4.4.3(supports-color@5.5.0)
denque: 2.1.0
lodash.defaults: 4.2.0
lodash.isarguments: 3.1.0
@ -18875,7 +18820,7 @@ snapshots:
istanbul-lib-source-maps@4.0.1:
dependencies:
debug: 4.4.3(supports-color@10.2.2)
debug: 4.4.3(supports-color@5.5.0)
istanbul-lib-coverage: 3.2.2
source-map: 0.6.1
transitivePeerDependencies:
@ -19724,10 +19669,6 @@ snapshots:
dependencies:
'@twemoji/parser': 16.0.0
microformats-parser@2.0.4:
dependencies:
parse5: 7.3.0
micromark-core-commonmark@2.0.3:
dependencies:
decode-named-character-reference: 1.2.0
@ -20120,7 +20061,7 @@ snapshots:
needle@2.9.1:
dependencies:
debug: 3.2.7(supports-color@8.1.1)
debug: 3.2.7
iconv-lite: 0.4.24
sax: 1.4.3
transitivePeerDependencies:
@ -21217,7 +21158,7 @@ snapshots:
require-in-the-middle@7.5.2:
dependencies:
debug: 4.4.3(supports-color@10.2.2)
debug: 4.4.3(supports-color@5.5.0)
module-details-from-path: 1.0.4
resolve: 1.22.11
transitivePeerDependencies:
@ -21308,7 +21249,7 @@ snapshots:
router@2.2.0:
dependencies:
debug: 4.4.3(supports-color@10.2.2)
debug: 4.4.3(supports-color@5.5.0)
depd: 2.0.0
is-promise: 4.0.0
parseurl: 1.3.3
@ -21432,7 +21373,7 @@ snapshots:
send@1.2.0:
dependencies:
debug: 4.4.3(supports-color@10.2.2)
debug: 4.4.3(supports-color@5.5.0)
encodeurl: 2.0.0
escape-html: 1.0.3
etag: 1.8.1
@ -21583,7 +21524,7 @@ snapshots:
dependencies:
'@hapi/hoek': 11.0.7
'@hapi/wreck': 18.1.0
debug: 4.4.3(supports-color@10.2.2)
debug: 4.4.3(supports-color@5.5.0)
joi: 17.13.3
transitivePeerDependencies:
- supports-color
@ -21683,7 +21624,7 @@ snapshots:
socks-proxy-agent@8.0.5:
dependencies:
agent-base: 7.1.4
debug: 4.4.3(supports-color@10.2.2)
debug: 4.4.3(supports-color@5.5.0)
socks: 2.8.7
transitivePeerDependencies:
- supports-color
@ -21775,19 +21716,6 @@ snapshots:
standard-as-callback@2.1.0: {}
start-server-and-test@2.1.2:
dependencies:
arg: 5.0.2
bluebird: 3.7.2
check-more-types: 2.24.0
debug: 4.4.3(supports-color@10.2.2)
execa: 5.1.1
lazy-ass: 1.6.0
ps-tree: 1.2.0
wait-on: 8.0.5(debug@4.4.3)
transitivePeerDependencies:
- supports-color
start-server-and-test@2.1.3:
dependencies:
arg: 5.0.2
@ -21985,7 +21913,7 @@ snapshots:
dependencies:
component-emitter: 1.3.1
cookiejar: 2.1.4
debug: 4.4.3(supports-color@10.2.2)
debug: 4.4.3(supports-color@5.5.0)
fast-safe-stringify: 2.1.1
form-data: 4.0.5
formidable: 3.5.4
@ -22334,7 +22262,7 @@ snapshots:
app-root-path: 3.1.0
buffer: 6.0.3
dayjs: 1.11.19
debug: 4.4.3(supports-color@10.2.2)
debug: 4.4.3(supports-color@5.5.0)
dedent: 1.7.0
dotenv: 16.6.1
glob: 10.5.0
@ -22731,16 +22659,6 @@ snapshots:
xml-name-validator: 5.0.0
optional: true
wait-on@8.0.5(debug@4.4.3):
dependencies:
axios: 1.13.2(debug@4.4.3)
joi: 18.0.1
lodash: 4.17.21
minimist: 1.2.8
rxjs: 7.8.2
transitivePeerDependencies:
- debug
wait-on@9.0.3(debug@4.4.3):
dependencies:
axios: 1.13.2(debug@4.4.3)
@ -22765,7 +22683,7 @@ snapshots:
dependencies:
asn1.js: 5.4.1
http_ece: 1.2.0
https-proxy-agent: 7.0.6(supports-color@10.2.2)
https-proxy-agent: 7.0.6
jws: 4.0.0
minimist: 1.2.8
transitivePeerDependencies: