From 441726d322c72c7a53394487fb487da5daf76588 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?100016217-Enzo=20Ding=C2=A0?= <563131211@qq.com> Date: Wed, 25 Mar 2026 13:56:23 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E9=87=8D=E6=9E=84search?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/user/search.js | 112 +++++++++++++++++++++++++++++---------------- 1 file changed, 72 insertions(+), 40 deletions(-) diff --git a/src/user/search.js b/src/user/search.js index 7edfeb73ca..296c41f8ba 100644 --- a/src/user/search.js +++ b/src/user/search.js @@ -41,35 +41,7 @@ module.exports = function (User) { } else if (searchBy === 'uid') { uids = [query]; } else { - if (!data.findUids && data.uid) { - const handle = activitypub.helpers.isWebfinger(data.query); - if (handle || activitypub.helpers.isUri(data.query)) { - const local = await activitypub.helpers.resolveLocalId(data.query); - if (local.type === 'user' && utils.isNumber(local.id)) { - uids = [local.id]; - } else { - const assertion = await activitypub.actors.assert([handle || data.query]); - if (assertion === true) { - uids = [handle ? await User.getUidByUserslug(handle) : query]; - } else if (Array.isArray(assertion) && assertion.length) { - uids = assertion.map(u => u.id); - } - } - } - } - - if (!uids.length) { - const searchMethod = data.findUids || findUids; - uids = await searchMethod(query, searchBy, data.hardCap); - - const mapping = { - username: 'ap.preferredUsername', - fullname: 'ap.name', - }; - if (meta.config.activitypubEnabled && mapping.hasOwnProperty(searchBy)) { - uids = uids.concat(await searchMethod(query, mapping[searchBy], data.hardCap)); - } - } + uids = await resolveDefaultSearchUids(data, query, searchBy); } uids = await filterAndSortUids(uids, data); @@ -111,6 +83,54 @@ module.exports = function (User) { return searchResult; }; + async function resolveDefaultSearchUids(data, query, searchBy) { + const fromActivityPub = await tryActivityPubUidsFromQuery(data); + if (fromActivityPub.length) { + return fromActivityPub; + } + return findUidsWithOptionalApLexSearch(data, query, searchBy); + } + + async function tryActivityPubUidsFromQuery(data) { + if (data.findUids || !data.uid) { + return []; + } + const handle = activitypub.helpers.isWebfinger(data.query); + if (!handle && !activitypub.helpers.isUri(data.query)) { + return []; + } + const local = await activitypub.helpers.resolveLocalId(data.query); + if (local.type === 'user' && utils.isNumber(local.id)) { + return [local.id]; + } + return uidsFromActorAssertion(data, handle); + } + + async function uidsFromActorAssertion(data, handle) { + const assertion = await activitypub.actors.assert([handle || data.query]); + if (assertion === true) { + const uid = handle ? await User.getUidByUserslug(handle) : data.query; + return [uid]; + } + if (Array.isArray(assertion) && assertion.length) { + return assertion.map(u => u.id); + } + return []; + } + + async function findUidsWithOptionalApLexSearch(data, query, searchBy) { + const searchMethod = data.findUids || findUids; + let uids = await searchMethod(query, searchBy, data.hardCap); + const mapping = { + username: 'ap.preferredUsername', + fullname: 'ap.name', + }; + if (meta.config.activitypubEnabled && mapping.hasOwnProperty(searchBy)) { + uids = uids.concat(await searchMethod(query, mapping[searchBy], data.hardCap)); + } + return uids; + } + async function findUids(query, searchBy, hardCap) { if (!query) { return []; @@ -133,21 +153,37 @@ module.exports = function (User) { return uids; } - async function filterAndSortUids(uids, data) { - uids = uids.filter(uid => parseInt(uid, 10) || activitypub.helpers.isUri(uid)); - let filters = data.filters || []; - filters = Array.isArray(filters) ? filters : [data.filters]; - const fields = []; + function normalizeFilters(data) { + const filters = data.filters || []; + return Array.isArray(filters) ? filters : [data.filters]; + } + function collectFilterAndSortFields(filters, data) { + const fields = []; if (data.sortBy) { fields.push(data.sortBy); } - filters.forEach((filter) => { if (filterFieldMap[filter]) { fields.push(...filterFieldMap[filter]); } }); + return fields; + } + + async function filterUidsByBannedState(uids, filters) { + if (!filters.includes('banned') && !filters.includes('notbanned')) { + return uids; + } + const isMembersOfBanned = await groups.isMembers(uids, groups.BANNED_USERS); + const wantBanned = filters.includes('banned'); + return uids.filter((uid, index) => (wantBanned ? isMembersOfBanned[index] : !isMembersOfBanned[index])); + } + + async function filterAndSortUids(uids, data) { + uids = uids.filter(uid => parseInt(uid, 10) || activitypub.helpers.isUri(uid)); + const filters = normalizeFilters(data); + const fields = collectFilterAndSortFields(filters, data); if (data.groupName) { const isMembers = await groups.isMembers(uids, data.groupName); @@ -158,11 +194,7 @@ module.exports = function (User) { return uids; } - if (filters.includes('banned') || filters.includes('notbanned')) { - const isMembersOfBanned = await groups.isMembers(uids, groups.BANNED_USERS); - const checkBanned = filters.includes('banned'); - uids = uids.filter((uid, index) => (checkBanned ? isMembersOfBanned[index] : !isMembersOfBanned[index])); - } + uids = await filterUidsByBannedState(uids, filters); fields.push('uid'); let userData = await User.getUsersFields(uids, fields); From 5d35032ddfde790a9e7b9b4fb35c2f27adaa125f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?100016217-Enzo=20Ding=C2=A0?= <563131211@qq.com> Date: Wed, 25 Mar 2026 14:30:15 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E9=87=8D=E6=9E=84search=20done?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- eslint.config.mjs | 57 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 54 insertions(+), 3 deletions(-) diff --git a/eslint.config.mjs b/eslint.config.mjs index 47cfa158f5..714413ba37 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -9,6 +9,57 @@ import stylisticJs from '@stylistic/eslint-plugin' import js from '@eslint/js'; import globals from 'globals'; +function normalizeQuotesRule(rule) { + if (!Array.isArray(rule) || typeof rule[2] !== 'object' || rule[2] === null) { + return rule; + } + + const options = rule[2]; + if (typeof options.allowTemplateLiterals !== 'boolean') { + return rule; + } + + return [ + rule[0], + rule[1], + { + ...options, + allowTemplateLiterals: options.allowTemplateLiterals ? 'always' : 'never', + }, + ]; +} + +function normalizeQuotesInRules(rules = {}) { + const normalizedRules = { + ...rules, + }; + + if (Object.hasOwn(rules, '@stylistic/js/quotes')) { + normalizedRules['@stylistic/js/quotes'] = normalizeQuotesRule(rules['@stylistic/js/quotes']); + } + + if (Object.hasOwn(rules, 'quotes')) { + normalizedRules.quotes = normalizeQuotesRule(rules.quotes); + } + + return normalizedRules; +} + +function normalizeConfigQuotes(config) { + if (!config || typeof config !== 'object' || !config.rules) { + return config; + } + + return { + ...config, + rules: normalizeQuotesInRules(config.rules), + }; +} + +const normalizedCommonRules = normalizeQuotesInRules(commonRules); +const normalizedPublicConfig = publicConfig.map(normalizeConfigQuotes); +const normalizedServerConfig = serverConfig.map(normalizeConfigQuotes); + export default defineConfig([ { ignores: [ @@ -54,12 +105,12 @@ export default defineConfig([ }, }, rules: { - ...commonRules, + ...normalizedCommonRules, 'no-unused-vars': 'off', 'no-prototype-builtins': 'off', } }, - ...publicConfig, - ...serverConfig + ...normalizedPublicConfig, + ...normalizedServerConfig ]);