cleanup(backend): refactor UtilityService (MisskeyIO#858)
This commit is contained in:
parent
cb73368c83
commit
ff195d4f8d
31 changed files with 106 additions and 126 deletions
|
@ -311,7 +311,7 @@ export class CustomEmojiService implements OnApplicationShutdown {
|
|||
: this.utilityService.isSelfHost(src) ? null // 自ホスト指定
|
||||
: (src || noteUserHost); // 指定されたホスト || ノートなどの所有者のホスト (こっちがリアクションにマッチすることはない)
|
||||
|
||||
host = this.utilityService.toPunyNullable(host);
|
||||
host = host ? this.utilityService.normalizeHost(host) : null;
|
||||
|
||||
return host;
|
||||
}
|
||||
|
@ -324,7 +324,7 @@ export class CustomEmojiService implements OnApplicationShutdown {
|
|||
const name = match[1];
|
||||
|
||||
// ホスト正規化
|
||||
const host = this.utilityService.toPunyNullable(this.normalizeHost(match[2], noteUserHost));
|
||||
const host = this.normalizeHost(match[2], noteUserHost);
|
||||
|
||||
return { name, host };
|
||||
}
|
||||
|
|
|
@ -236,7 +236,7 @@ export class EmailService {
|
|||
}
|
||||
|
||||
const emailDomain: string = emailAddress.split('@')[1];
|
||||
const isBanned = this.utilityService.isBlockedHost(meta.bannedEmailDomains, emailDomain);
|
||||
const isBanned = this.utilityService.isItemListedIn(emailDomain, meta.bannedEmailDomains);
|
||||
|
||||
if (isBanned) {
|
||||
return {
|
||||
|
@ -304,7 +304,7 @@ export class EmailService {
|
|||
reason: 'mx',
|
||||
};
|
||||
}
|
||||
if (json.mx_host?.some(host => this.utilityService.isBlockedHost(meta.bannedEmailDomains, host))) {
|
||||
if (json.mx_host?.some(host => this.utilityService.isItemListedIn(host, meta.bannedEmailDomains))) {
|
||||
return {
|
||||
valid: false,
|
||||
reason: 'mx',
|
||||
|
|
|
@ -47,7 +47,7 @@ export class FederatedInstanceService implements OnApplicationShutdown {
|
|||
|
||||
@bindThis
|
||||
public async fetch(host: string): Promise<MiInstance> {
|
||||
host = this.utilityService.toPuny(host);
|
||||
host = this.utilityService.normalizeHost(host);
|
||||
|
||||
const cached = await this.federatedInstanceCache.get(host);
|
||||
if (cached) return cached;
|
||||
|
|
|
@ -285,7 +285,7 @@ export class NoteCreateService implements OnApplicationShutdown {
|
|||
throw new IdentifiableError('689ee33f-f97c-479a-ac49-1b9f8140af99', 'Notes including prohibited words are not allowed.');
|
||||
}
|
||||
|
||||
const inSilencedInstance = this.utilityService.isSilencedHost(meta.silencedHosts, user.host);
|
||||
const inSilencedInstance = this.utilityService.isItemListedIn(user.host, meta.silencedHosts);
|
||||
|
||||
if (data.visibility === 'public' && inSilencedInstance && user.host !== null) {
|
||||
data.visibility = 'home';
|
||||
|
|
|
@ -129,7 +129,7 @@ export class ReactionService {
|
|||
} else if (_reaction) {
|
||||
const custom = reaction.match(isCustomEmojiRegexp);
|
||||
if (custom) {
|
||||
const reacterHost = this.utilityService.toPunyNullable(user.host);
|
||||
const reacterHost = user.host ? this.utilityService.normalizeHost(user.host) : null;
|
||||
|
||||
const name = custom[1];
|
||||
const emoji = reacterHost == null
|
||||
|
|
|
@ -54,9 +54,7 @@ export class RemoteUserResolveService {
|
|||
}) as MiLocalUser;
|
||||
}
|
||||
|
||||
host = this.utilityService.toPuny(host);
|
||||
|
||||
if (host === this.utilityService.toPuny(this.config.host)) {
|
||||
if (this.utilityService.isSelfHost(host)) {
|
||||
this.logger.info(`return local user: ${usernameLower}`);
|
||||
return await this.usersRepository.findOneBy({ usernameLower, host: IsNull() }).then(u => {
|
||||
if (u == null) {
|
||||
|
@ -67,6 +65,8 @@ export class RemoteUserResolveService {
|
|||
}) as MiLocalUser;
|
||||
}
|
||||
|
||||
host = this.utilityService.normalizeHost(host);
|
||||
|
||||
const user = await this.usersRepository.findOneBy({ usernameLower, host }) as MiRemoteUser | null;
|
||||
|
||||
const acctLower = `${usernameLower}@${host}`;
|
||||
|
|
|
@ -141,7 +141,7 @@ export class SignupService {
|
|||
id: this.idService.gen(),
|
||||
username: username,
|
||||
usernameLower: username.toLowerCase(),
|
||||
host: this.utilityService.toPunyNullable(host),
|
||||
host: host ? this.utilityService.normalizeHost(host) : null,
|
||||
token: secret,
|
||||
isRoot: isTheFirstUser,
|
||||
}));
|
||||
|
|
|
@ -173,7 +173,7 @@ export class UserFollowingService implements OnModuleInit {
|
|||
followee.isLocked ||
|
||||
(followeeProfile.carefulBot && follower.isBot) ||
|
||||
(this.userEntityService.isLocalUser(follower) && this.userEntityService.isRemoteUser(followee) && process.env.FORCE_FOLLOW_REMOTE_USER_FOR_TESTING !== 'true') ||
|
||||
(this.userEntityService.isLocalUser(followee) && this.userEntityService.isRemoteUser(follower) && this.utilityService.isSilencedHost((await this.metaService.fetch()).silencedHosts, follower.host))
|
||||
(this.userEntityService.isLocalUser(followee) && this.userEntityService.isRemoteUser(follower) && this.utilityService.isItemListedIn(follower.host, (await this.metaService.fetch()).silencedHosts))
|
||||
) {
|
||||
let autoAccept = false;
|
||||
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
|
||||
import { URL } from 'node:url';
|
||||
import punycode from 'punycode.js';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import RE2 from 're2';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import type { Config } from '@/config.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
|
@ -21,36 +21,26 @@ export class UtilityService {
|
|||
|
||||
@bindThis
|
||||
public getFullApAccount(username: string, host: string | null): string {
|
||||
return host ? `${username}@${this.toPuny(host)}` : `${username}@${this.toPuny(this.config.host)}`;
|
||||
return host ? `${username}@${this.normalizeHost(host)}` : `${username}@${this.normalizeHost(this.config.host)}`;
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public isSelfHost(host: string | null): boolean {
|
||||
if (host == null) return true;
|
||||
return this.toPuny(this.config.host) === this.toPuny(host);
|
||||
return this.normalizeHost(this.config.host) === this.normalizeHost(host);
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public isUriLocal(uri: string): boolean {
|
||||
return this.punyHost(uri) === this.toPuny(this.config.host);
|
||||
return this.normalizeHost(this.config.hostname) === this.extractHost(uri);
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public isBlockedHost(blockedHosts: string[], host: string | null): boolean {
|
||||
if (host == null) return false;
|
||||
return blockedHosts.some(x => `.${host.toLowerCase()}`.endsWith(`.${x}`));
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public isSilencedHost(silencedHosts: string[] | undefined, host: string | null): boolean {
|
||||
if (!silencedHosts || host == null) return false;
|
||||
return silencedHosts.some(x => `.${host.toLowerCase()}`.endsWith(`.${x}`));
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public isSensitiveMediaHost(sensitiveMediaHosts: string[] | undefined, host: string | null): boolean {
|
||||
if (!sensitiveMediaHosts || host == null) return false;
|
||||
return sensitiveMediaHosts.some(x => `.${host.toLowerCase()}`.endsWith(`.${x}`));
|
||||
public isItemListedIn(item: string | null, list: string[] | undefined): boolean {
|
||||
if (!list || !item) return false;
|
||||
list = list.map(x => '.' + this.normalizeHost(x).split(':')[0]);
|
||||
item = '.' + this.normalizeHost(item).split(':')[0];
|
||||
return list.some(x => item.endsWith(x));
|
||||
}
|
||||
|
||||
@bindThis
|
||||
|
@ -93,26 +83,14 @@ export class UtilityService {
|
|||
}
|
||||
|
||||
@bindThis
|
||||
public extractDbHost(uri: string): string {
|
||||
const url = new URL(uri);
|
||||
return this.toPuny(url.host);
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public toPuny(host: string): string {
|
||||
public normalizeHost(host: string): string {
|
||||
return punycode.toASCII(host.toLowerCase());
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public toPunyNullable(host: string | null | undefined): string | null {
|
||||
if (host == null) return null;
|
||||
return punycode.toASCII(host.toLowerCase());
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public punyHost(url: string): string {
|
||||
const urlObj = new URL(url);
|
||||
const host = `${this.toPuny(urlObj.hostname)}${urlObj.port.length > 0 ? ':' + urlObj.port : ''}`;
|
||||
return host;
|
||||
public extractHost(uri: string): string {
|
||||
// ASCII String で返されるので punycode 化はいらない
|
||||
// ref: https://url.spec.whatwg.org/#host-serializing
|
||||
return new URL(uri).host;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,8 +64,9 @@ export class ApDbResolverService implements OnApplicationShutdown {
|
|||
public parseUri(value: string | IObject): UriParseResult {
|
||||
const separator = '/';
|
||||
|
||||
const uri = new URL(getApId(value));
|
||||
if (this.utilityService.toPuny(uri.host) !== this.utilityService.toPuny(this.config.host)) {
|
||||
const apId = getApId(value);
|
||||
const uri = new URL(apId);
|
||||
if (!this.utilityService.isUriLocal(apId)) {
|
||||
return { local: false, uri: uri.href };
|
||||
}
|
||||
|
||||
|
|
|
@ -100,12 +100,12 @@ export class ApInboxService {
|
|||
|
||||
const items = toArray(isCollection(activity) ? activity.items : activity.orderedItems);
|
||||
if (items.length >= resolver.getRecursionLimit()) {
|
||||
throw new Error(`skipping activity: collection would surpass recursion limit: ${this.utilityService.extractDbHost(actor.uri)}`);
|
||||
throw new Error(`skipping activity: collection would surpass recursion limit: ${this.utilityService.extractHost(actor.uri)}`);
|
||||
}
|
||||
|
||||
for (const item of items) {
|
||||
const act = await resolver.resolve(item);
|
||||
if (act.id == null || this.utilityService.extractDbHost(act.id) !== this.utilityService.extractDbHost(actor.uri)) {
|
||||
if (act.id == null || this.utilityService.extractHost(act.id) !== this.utilityService.extractHost(actor.uri)) {
|
||||
this.logger.warn('skipping activity: activity id is null or mismatching');
|
||||
continue;
|
||||
}
|
||||
|
@ -310,7 +310,7 @@ export class ApInboxService {
|
|||
|
||||
// アナウンス先をブロックしてたら中断
|
||||
const meta = await this.metaService.fetch();
|
||||
if (this.utilityService.isBlockedHost(meta.blockedHosts, this.utilityService.extractDbHost(uri))) return 'skip: blocked host';
|
||||
if (this.utilityService.isItemListedIn(this.utilityService.extractHost(uri), meta.blockedHosts)) return 'skip: blocked host';
|
||||
|
||||
const unlock = await this.appLockService.getApLock(uri);
|
||||
|
||||
|
@ -432,7 +432,7 @@ export class ApInboxService {
|
|||
}
|
||||
|
||||
if (typeof note.id === 'string') {
|
||||
if (this.utilityService.extractDbHost(actor.uri) !== this.utilityService.extractDbHost(note.id)) {
|
||||
if (this.utilityService.extractHost(actor.uri) !== this.utilityService.extractHost(note.id)) {
|
||||
return 'skip: host in actor.uri !== note.id';
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -220,7 +220,7 @@ export class ApRequestService {
|
|||
const alternate = fragment.querySelector('head > link[rel="alternate"][type="application/activity+json"]');
|
||||
if (alternate) {
|
||||
const href = alternate.getAttribute('href');
|
||||
if (href && this.utilityService.punyHost(url) === this.utilityService.punyHost(href)) {
|
||||
if (href && this.utilityService.extractHost(url) === this.utilityService.extractHost(href)) {
|
||||
return await this.signedGet(href, user, false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -89,18 +89,18 @@ export class Resolver {
|
|||
}
|
||||
|
||||
if (this.history.size > this.recursionLimit) {
|
||||
throw new Error(`hit recursion limit: ${this.utilityService.extractDbHost(value)}`);
|
||||
throw new Error(`hit recursion limit: ${this.utilityService.extractHost(value)}`);
|
||||
}
|
||||
|
||||
this.history.add(value);
|
||||
|
||||
const host = this.utilityService.extractDbHost(value);
|
||||
const host = this.utilityService.extractHost(value);
|
||||
if (this.utilityService.isSelfHost(host)) {
|
||||
return await this.resolveLocal(value);
|
||||
}
|
||||
|
||||
const meta = await this.metaService.fetch();
|
||||
if (this.utilityService.isBlockedHost(meta.blockedHosts, host)) {
|
||||
if (this.utilityService.isItemListedIn(host, meta.blockedHosts)) {
|
||||
throw new Error('Instance is blocked');
|
||||
}
|
||||
|
||||
|
@ -128,7 +128,7 @@ export class Resolver {
|
|||
throw new Error('invalid AP object: missing id');
|
||||
}
|
||||
|
||||
if (this.utilityService.punyHost(object.id) !== this.utilityService.punyHost(value)) {
|
||||
if (this.utilityService.extractHost(object.id) !== this.utilityService.extractHost(value)) {
|
||||
throw new Error(`invalid AP object ${value}: id ${object.id} has different host`);
|
||||
}
|
||||
|
||||
|
|
|
@ -81,20 +81,21 @@ export class ApNoteService {
|
|||
|
||||
@bindThis
|
||||
public validateNote(object: IObject, uri: string, actor?: MiRemoteUser): Error | null {
|
||||
const expectHost = this.utilityService.extractDbHost(uri);
|
||||
const expectedHost = this.utilityService.extractHost(uri);
|
||||
const apType = getApType(object);
|
||||
|
||||
if (apType == null || !validPost.includes(apType)) {
|
||||
return new IdentifiableError('d450b8a9-48e4-4dab-ae36-f4db763fda7c', `invalid Note: invalid object type ${apType ?? 'undefined'}`);
|
||||
}
|
||||
|
||||
if (object.id && this.utilityService.extractDbHost(object.id) !== expectHost) {
|
||||
return new IdentifiableError('d450b8a9-48e4-4dab-ae36-f4db763fda7c', `invalid Note: id has different host. expected: ${expectHost}, actual: ${this.utilityService.extractDbHost(object.id)}`);
|
||||
let actualHost = object.id && this.utilityService.extractHost(object.id);
|
||||
if (actualHost && expectedHost !== actualHost) {
|
||||
return new IdentifiableError('d450b8a9-48e4-4dab-ae36-f4db763fda7c', `invalid Note: id has different host. expected: ${expectedHost}, actual: ${actualHost}`);
|
||||
}
|
||||
|
||||
const actualHost = object.attributedTo && this.utilityService.extractDbHost(getOneApId(object.attributedTo));
|
||||
if (object.attributedTo && actualHost !== expectHost) {
|
||||
return new IdentifiableError('d450b8a9-48e4-4dab-ae36-f4db763fda7c', `invalid Note: attributedTo has different host. expected: ${expectHost}, actual: ${actualHost}`);
|
||||
actualHost = object.attributedTo && this.utilityService.extractHost(getOneApId(object.attributedTo));
|
||||
if (actualHost && expectedHost !== actualHost) {
|
||||
return new IdentifiableError('d450b8a9-48e4-4dab-ae36-f4db763fda7c', `invalid Note: attributedTo has different host. expected: ${expectedHost}, actual: ${actualHost}`);
|
||||
}
|
||||
|
||||
if (object.published && !this.idService.isSafeT(new Date(object.published).valueOf())) {
|
||||
|
@ -165,8 +166,8 @@ export class ApNoteService {
|
|||
throw new Error('unexpected schema of note url: ' + url);
|
||||
}
|
||||
|
||||
if (this.utilityService.punyHost(url) !== this.utilityService.punyHost(note.id)) {
|
||||
throw new Error(`note url & uri host mismatch: note url: ${url}, note uri: ${note.id}`);
|
||||
if (this.utilityService.extractHost(note.id) !== this.utilityService.extractHost(url)) {
|
||||
throw new Error(`note id and url have different host: ${note.id} - ${url}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -234,7 +235,7 @@ export class ApNoteService {
|
|||
}
|
||||
}
|
||||
|
||||
const isSensitiveMediaHost = this.utilityService.isSensitiveMediaHost(meta.sensitiveMediaHosts, this.utilityService.extractDbHost(note.id ?? entryUri));
|
||||
const isSensitiveMediaHost = this.utilityService.isItemListedIn(this.utilityService.extractHost(note.id ?? entryUri), meta.sensitiveMediaHosts);
|
||||
|
||||
// 添付ファイル
|
||||
const files: MiDriveFile[] = [];
|
||||
|
@ -349,7 +350,7 @@ export class ApNoteService {
|
|||
this.logger.info('The note is already inserted while creating itself, reading again');
|
||||
const duplicate = await this.fetchNote(value);
|
||||
if (!duplicate) {
|
||||
throw new Error('The note creation failed with duplication error even when there is no duplication');
|
||||
throw new Error(`The note creation failed with duplication error even when there is no duplication: ${entryUri}`);
|
||||
}
|
||||
return duplicate;
|
||||
}
|
||||
|
@ -367,7 +368,7 @@ export class ApNoteService {
|
|||
|
||||
// ブロックしていたら中断
|
||||
const meta = await this.metaService.fetch();
|
||||
if (this.utilityService.isBlockedHost(meta.blockedHosts, this.utilityService.extractDbHost(uri))) {
|
||||
if (this.utilityService.isItemListedIn(this.utilityService.extractHost(uri), meta.blockedHosts)) {
|
||||
throw new StatusError('blocked host', 451);
|
||||
}
|
||||
|
||||
|
@ -396,7 +397,7 @@ export class ApNoteService {
|
|||
@bindThis
|
||||
public async extractEmojis(tags: IObject | IObject[], host: string): Promise<MiEmoji[]> {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
host = this.utilityService.toPuny(host);
|
||||
host = this.utilityService.normalizeHost(host);
|
||||
|
||||
const eomjiTags = toArray(tags).filter(isEmoji);
|
||||
|
||||
|
|
|
@ -137,7 +137,7 @@ export class ApPersonService implements OnModuleInit {
|
|||
*/
|
||||
@bindThis
|
||||
private validateActor(x: IObject, uri: string): IActor {
|
||||
const expectHost = this.utilityService.punyHost(uri);
|
||||
const expectedHost = this.utilityService.extractHost(uri);
|
||||
|
||||
if (!isActor(x)) {
|
||||
throw new Error(`invalid Actor type '${x.type}'`);
|
||||
|
@ -151,15 +151,18 @@ export class ApPersonService implements OnModuleInit {
|
|||
throw new Error('invalid Actor: wrong inbox');
|
||||
}
|
||||
|
||||
if (this.utilityService.punyHost(x.inbox) !== expectHost) {
|
||||
throw new Error('invalid Actor: inbox has different host');
|
||||
let actualHost = this.utilityService.extractHost(x.inbox);
|
||||
if (expectedHost !== actualHost) {
|
||||
throw new Error(`invalid Actor: inbox has different host. expected: ${expectedHost}, actual: ${actualHost}`);
|
||||
}
|
||||
|
||||
const sharedInboxObject = x.sharedInbox ?? (x.endpoints ? x.endpoints.sharedInbox : undefined);
|
||||
if (sharedInboxObject != null) {
|
||||
const sharedInbox = getApId(sharedInboxObject);
|
||||
if (!(typeof sharedInbox === 'string' && sharedInbox.length > 0 && this.utilityService.punyHost(sharedInbox) === expectHost)) {
|
||||
throw new Error('invalid Actor: wrong shared inbox');
|
||||
if (!sharedInbox) throw new Error('invalid Actor: wrong shared inbox');
|
||||
actualHost = this.utilityService.extractHost(sharedInbox);
|
||||
if (expectedHost !== actualHost) {
|
||||
throw new Error(`invalid Actor: shared inbox has different host. expected: ${expectedHost}, actual: ${actualHost}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -167,12 +170,10 @@ export class ApPersonService implements OnModuleInit {
|
|||
const xCollection = (x as IActor)[collection];
|
||||
if (xCollection != null) {
|
||||
const collectionUri = getApId(xCollection);
|
||||
if (typeof collectionUri === 'string' && collectionUri.length > 0) {
|
||||
if (this.utilityService.punyHost(collectionUri) !== expectHost) {
|
||||
throw new Error(`invalid Actor: ${collection} has different host`);
|
||||
}
|
||||
} else if (collectionUri != null) {
|
||||
throw new Error(`invalid Actor: wrong ${collection}`);
|
||||
if (!collectionUri) throw new Error(`invalid Actor: wrong ${collection}`);
|
||||
actualHost = this.utilityService.extractHost(collectionUri);
|
||||
if (expectedHost !== actualHost) {
|
||||
throw new Error(`invalid Actor: ${collection} has different host. expected: ${expectedHost}, actual: ${actualHost}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -200,9 +201,9 @@ export class ApPersonService implements OnModuleInit {
|
|||
x.summary = truncate(x.summary, summaryLength);
|
||||
}
|
||||
|
||||
const idHost = this.utilityService.punyHost(x.id);
|
||||
if (idHost !== expectHost) {
|
||||
throw new Error('invalid Actor: id has different host');
|
||||
actualHost = this.utilityService.extractHost(x.id);
|
||||
if (expectedHost !== actualHost) {
|
||||
throw new Error(`invalid Actor: id has different host. expected: ${expectedHost}, actual: ${actualHost}`);
|
||||
}
|
||||
|
||||
if (x.publicKey) {
|
||||
|
@ -210,9 +211,9 @@ export class ApPersonService implements OnModuleInit {
|
|||
throw new Error('invalid Actor: publicKey.id is not a string');
|
||||
}
|
||||
|
||||
const publicKeyIdHost = this.utilityService.punyHost(x.publicKey.id);
|
||||
if (publicKeyIdHost !== expectHost) {
|
||||
throw new Error('invalid Actor: publicKey.id has different host');
|
||||
actualHost = this.utilityService.extractHost(x.publicKey.id);
|
||||
if (expectedHost !== actualHost) {
|
||||
throw new Error(`invalid Actor: publicKey.id has different host. expected: ${expectedHost}, actual: ${actualHost}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -258,7 +259,7 @@ export class ApPersonService implements OnModuleInit {
|
|||
if (Array.isArray(img)) {
|
||||
img = img.find(item => item && item.url) ?? null;
|
||||
}
|
||||
|
||||
|
||||
// if we have an explicitly missing image, return an
|
||||
// explicitly-null set of values
|
||||
if ((img == null) || (typeof img === 'object' && img.url == null)) {
|
||||
|
@ -296,8 +297,7 @@ export class ApPersonService implements OnModuleInit {
|
|||
public async createPerson(uri: string, resolver?: Resolver): Promise<MiRemoteUser> {
|
||||
if (typeof uri !== 'string') throw new Error('uri is not string');
|
||||
|
||||
const host = this.utilityService.punyHost(uri);
|
||||
if (host === this.utilityService.toPuny(this.config.host)) {
|
||||
if (this.utilityService.isUriLocal(uri)) {
|
||||
throw new StatusError('cannot resolve local user', 400, 'cannot resolve local user');
|
||||
}
|
||||
|
||||
|
@ -345,13 +345,14 @@ export class ApPersonService implements OnModuleInit {
|
|||
throw new Error('unexpected schema of person url: ' + url);
|
||||
}
|
||||
|
||||
if (this.utilityService.punyHost(url) !== this.utilityService.punyHost(person.id)) {
|
||||
throw new Error(`person url <> uri host mismatch: ${url} <> ${person.id}`);
|
||||
if (this.utilityService.extractHost(person.id) !== this.utilityService.extractHost(url)) {
|
||||
throw new Error(`person id and url have different host: ${person.id} - ${url}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Create user
|
||||
let user: MiRemoteUser | null = null;
|
||||
const host = this.utilityService.extractHost(uri);
|
||||
|
||||
//#region カスタム絵文字取得
|
||||
const emojis = await this.apNoteService.extractEmojis(person.tag ?? [], host)
|
||||
|
@ -542,8 +543,8 @@ export class ApPersonService implements OnModuleInit {
|
|||
throw new Error('unexpected schema of person url: ' + url);
|
||||
}
|
||||
|
||||
if (this.utilityService.punyHost(url) !== this.utilityService.punyHost(person.id)) {
|
||||
throw new Error(`person url <> uri host mismatch: ${url} <> ${person.id}`);
|
||||
if (this.utilityService.extractHost(person.id) !== this.utilityService.extractHost(url)) {
|
||||
throw new Error(`person id and url have different host: ${person.id} - ${url}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -77,7 +77,7 @@ export default class InstanceChart extends Chart<typeof schema> { // eslint-disa
|
|||
public async requestReceived(host: string): Promise<void> {
|
||||
await this.commit({
|
||||
'requests.received': 1,
|
||||
}, this.utilityService.toPuny(host));
|
||||
}, this.utilityService.normalizeHost(host));
|
||||
}
|
||||
|
||||
@bindThis
|
||||
|
@ -85,7 +85,7 @@ export default class InstanceChart extends Chart<typeof schema> { // eslint-disa
|
|||
await this.commit({
|
||||
'requests.succeeded': isSucceeded ? 1 : 0,
|
||||
'requests.failed': isSucceeded ? 0 : 1,
|
||||
}, this.utilityService.toPuny(host));
|
||||
}, this.utilityService.normalizeHost(host));
|
||||
}
|
||||
|
||||
@bindThis
|
||||
|
@ -93,7 +93,7 @@ export default class InstanceChart extends Chart<typeof schema> { // eslint-disa
|
|||
await this.commit({
|
||||
'users.total': 1,
|
||||
'users.inc': 1,
|
||||
}, this.utilityService.toPuny(host));
|
||||
}, this.utilityService.normalizeHost(host));
|
||||
}
|
||||
|
||||
@bindThis
|
||||
|
@ -106,7 +106,7 @@ export default class InstanceChart extends Chart<typeof schema> { // eslint-disa
|
|||
'notes.diffs.renote': note.renoteId != null ? (isAdditional ? 1 : -1) : 0,
|
||||
'notes.diffs.reply': note.replyId != null ? (isAdditional ? 1 : -1) : 0,
|
||||
'notes.diffs.withFile': note.fileIds.length > 0 ? (isAdditional ? 1 : -1) : 0,
|
||||
}, this.utilityService.toPuny(host));
|
||||
}, this.utilityService.normalizeHost(host));
|
||||
}
|
||||
|
||||
@bindThis
|
||||
|
@ -115,7 +115,7 @@ export default class InstanceChart extends Chart<typeof schema> { // eslint-disa
|
|||
'following.total': isAdditional ? 1 : -1,
|
||||
'following.inc': isAdditional ? 1 : 0,
|
||||
'following.dec': isAdditional ? 0 : 1,
|
||||
}, this.utilityService.toPuny(host));
|
||||
}, this.utilityService.normalizeHost(host));
|
||||
}
|
||||
|
||||
@bindThis
|
||||
|
@ -124,7 +124,7 @@ export default class InstanceChart extends Chart<typeof schema> { // eslint-disa
|
|||
'followers.total': isAdditional ? 1 : -1,
|
||||
'followers.inc': isAdditional ? 1 : 0,
|
||||
'followers.dec': isAdditional ? 0 : 1,
|
||||
}, this.utilityService.toPuny(host));
|
||||
}, this.utilityService.normalizeHost(host));
|
||||
}
|
||||
|
||||
@bindThis
|
||||
|
|
|
@ -158,7 +158,7 @@ export class DriveFileEntityService {
|
|||
public async calcDriveUsageOfHost(host: string): Promise<number> {
|
||||
const { sum } = await this.driveFilesRepository
|
||||
.createQueryBuilder('file')
|
||||
.where('file.userHost = :host', { host: this.utilityService.toPuny(host) })
|
||||
.where('file.userHost = :host', { host: this.utilityService.normalizeHost(host) })
|
||||
.andWhere('file.isLink = FALSE')
|
||||
.select('SUM(file.size)', 'sum')
|
||||
.getRawOne();
|
||||
|
|
|
@ -40,7 +40,7 @@ export class InstanceEntityService {
|
|||
followersCount: instance.followersCount,
|
||||
isNotResponding: instance.isNotResponding,
|
||||
isSuspended: instance.isSuspended,
|
||||
isBlocked: this.utilityService.isBlockedHost(meta.blockedHosts, instance.host),
|
||||
isBlocked: this.utilityService.isItemListedIn(instance.host, meta.blockedHosts),
|
||||
softwareName: instance.softwareName,
|
||||
softwareVersion: instance.softwareVersion,
|
||||
openRegistrations: instance.openRegistrations,
|
||||
|
@ -48,8 +48,8 @@ export class InstanceEntityService {
|
|||
description: instance.description,
|
||||
maintainerName: instance.maintainerName,
|
||||
maintainerEmail: instance.maintainerEmail,
|
||||
isSilenced: this.utilityService.isSilencedHost(meta.silencedHosts, instance.host),
|
||||
isSensitiveMedia: this.utilityService.isSensitiveMediaHost(meta.sensitiveMediaHosts, instance.host),
|
||||
isSilenced: this.utilityService.isItemListedIn(instance.host, meta.silencedHosts),
|
||||
isSensitiveMedia: this.utilityService.isItemListedIn(instance.host, meta.sensitiveMediaHosts),
|
||||
iconUrl: instance.iconUrl,
|
||||
faviconUrl: instance.faviconUrl,
|
||||
themeColor: instance.themeColor,
|
||||
|
|
|
@ -53,7 +53,7 @@ export class DeliverProcessorService {
|
|||
|
||||
// ブロックしてたら中断
|
||||
const meta = await this.metaService.fetch();
|
||||
if (this.utilityService.isBlockedHost(meta.blockedHosts, this.utilityService.toPuny(host))) {
|
||||
if (this.utilityService.isItemListedIn(host, meta.blockedHosts)) {
|
||||
return 'skip (blocked)';
|
||||
}
|
||||
|
||||
|
@ -67,7 +67,7 @@ export class DeliverProcessorService {
|
|||
});
|
||||
this.suspendedHostsCache.set(suspendedHosts);
|
||||
}
|
||||
if (suspendedHosts.map(x => x.host).includes(this.utilityService.toPuny(host))) {
|
||||
if (suspendedHosts.map(x => x.host).includes(this.utilityService.normalizeHost(host))) {
|
||||
return 'skip (suspended)';
|
||||
}
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ export class ImportBlockingProcessorService {
|
|||
host: IsNull(),
|
||||
usernameLower: username.toLowerCase(),
|
||||
}) : await this.usersRepository.findOneBy({
|
||||
host: this.utilityService.toPuny(host),
|
||||
host: this.utilityService.normalizeHost(host),
|
||||
usernameLower: username.toLowerCase(),
|
||||
});
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ export class ImportFollowingProcessorService {
|
|||
host: IsNull(),
|
||||
usernameLower: username.toLowerCase(),
|
||||
}) : await this.usersRepository.findOneBy({
|
||||
host: this.utilityService.toPuny(host),
|
||||
host: this.utilityService.normalizeHost(host),
|
||||
usernameLower: username.toLowerCase(),
|
||||
});
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ export class ImportMutingProcessorService {
|
|||
host: IsNull(),
|
||||
usernameLower: username.toLowerCase(),
|
||||
}) : await this.usersRepository.findOneBy({
|
||||
host: this.utilityService.toPuny(host),
|
||||
host: this.utilityService.normalizeHost(host),
|
||||
usernameLower: username.toLowerCase(),
|
||||
});
|
||||
|
||||
|
|
|
@ -90,7 +90,7 @@ export class ImportUserListsProcessorService {
|
|||
host: IsNull(),
|
||||
usernameLower: username.toLowerCase(),
|
||||
}) : await this.usersRepository.findOneBy({
|
||||
host: this.utilityService.toPuny(host!),
|
||||
host: this.utilityService.normalizeHost(host!),
|
||||
usernameLower: username.toLowerCase(),
|
||||
});
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import { URL } from 'node:url';
|
||||
import { Injectable, OnApplicationShutdown } from '@nestjs/common';
|
||||
import httpSignature from '@peertube/http-signature';
|
||||
import * as Bull from 'bullmq';
|
||||
|
@ -65,11 +64,11 @@ export class InboxProcessorService implements OnApplicationShutdown {
|
|||
this.logger.debug(JSON.stringify(info, null, 2));
|
||||
//#endregion
|
||||
|
||||
const host = this.utilityService.toPuny(new URL(signature.keyId).hostname);
|
||||
const host = this.utilityService.extractHost(signature.keyId);
|
||||
|
||||
// ブロックしてたら中断
|
||||
const meta = await this.metaService.fetch();
|
||||
if (this.utilityService.isBlockedHost(meta.blockedHosts, host)) {
|
||||
if (this.utilityService.isItemListedIn(host, meta.blockedHosts)) {
|
||||
return `Blocked request: ${host}`;
|
||||
}
|
||||
|
||||
|
@ -164,8 +163,8 @@ export class InboxProcessorService implements OnApplicationShutdown {
|
|||
}
|
||||
|
||||
// ブロックしてたら中断
|
||||
const ldHost = this.utilityService.extractDbHost(authUser.user.uri);
|
||||
if (this.utilityService.isBlockedHost(meta.blockedHosts, ldHost)) {
|
||||
const ldHost = this.utilityService.extractHost(authUser.user.uri);
|
||||
if (this.utilityService.isItemListedIn(ldHost, meta.blockedHosts)) {
|
||||
throw new Bull.UnrecoverableError(`Blocked request: ${ldHost}`);
|
||||
}
|
||||
} else {
|
||||
|
@ -175,8 +174,8 @@ export class InboxProcessorService implements OnApplicationShutdown {
|
|||
|
||||
// activity.idがあればホストが署名者のホストであることを確認する
|
||||
if (typeof activity.id === 'string') {
|
||||
const signerHost = this.utilityService.extractDbHost(authUser.user.uri!);
|
||||
const activityIdHost = this.utilityService.extractDbHost(activity.id);
|
||||
const signerHost = this.utilityService.extractHost(authUser.user.uri!);
|
||||
const activityIdHost = this.utilityService.extractHost(activity.id);
|
||||
if (signerHost !== activityIdHost) {
|
||||
throw new Bull.UnrecoverableError(`skip: signerHost(${signerHost}) !== activity.id host(${activityIdHost}`);
|
||||
}
|
||||
|
|
|
@ -94,7 +94,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
if (ps.host == null) {
|
||||
q.andWhere('emoji.host IS NOT NULL');
|
||||
} else {
|
||||
q.andWhere('emoji.host = :host', { host: this.utilityService.toPuny(ps.host) });
|
||||
q.andWhere('emoji.host = :host', { host: this.utilityService.normalizeHost(ps.host) });
|
||||
}
|
||||
|
||||
if (ps.query) {
|
||||
|
|
|
@ -36,7 +36,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
private fetchInstanceMetadataService: FetchInstanceMetadataService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
const instance = await this.instancesRepository.findOneBy({ host: this.utilityService.toPuny(ps.host) });
|
||||
const instance = await this.instancesRepository.findOneBy({ host: this.utilityService.normalizeHost(ps.host) });
|
||||
|
||||
if (instance == null) {
|
||||
throw new Error('instance not found');
|
||||
|
|
|
@ -40,7 +40,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
private moderationLogService: ModerationLogService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
const instance = await this.instancesRepository.findOneBy({ host: this.utilityService.toPuny(ps.host) });
|
||||
const instance = await this.instancesRepository.findOneBy({ host: this.utilityService.normalizeHost(ps.host) });
|
||||
|
||||
if (instance == null) {
|
||||
throw new Error('instance not found');
|
||||
|
|
|
@ -114,7 +114,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
private async fetchAny(uri: string, me: MiLocalUser | null | undefined): Promise<SchemaType<typeof meta['res']> | null> {
|
||||
// ブロックしてたら中断
|
||||
const fetchedMeta = await this.metaService.fetch();
|
||||
if (this.utilityService.isBlockedHost(fetchedMeta.blockedHosts, this.utilityService.extractDbHost(uri))) return null;
|
||||
if (this.utilityService.isItemListedIn(this.utilityService.extractHost(uri), fetchedMeta.blockedHosts)) return null;
|
||||
|
||||
let local = await this.mergePack(me, ...await Promise.all([
|
||||
this.apDbResolverService.getUserFromApId(uri),
|
||||
|
@ -122,7 +122,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
]));
|
||||
if (local != null) return local;
|
||||
|
||||
const host = this.utilityService.extractDbHost(uri);
|
||||
const host = this.utilityService.extractHost(uri);
|
||||
|
||||
// local object, not found in db? fail
|
||||
if (this.utilityService.isSelfHost(host)) return null;
|
||||
|
|
|
@ -41,7 +41,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
const instance = await this.instancesRepository
|
||||
.findOneBy({ host: this.utilityService.toPuny(ps.host) });
|
||||
.findOneBy({ host: this.utilityService.normalizeHost(ps.host) });
|
||||
|
||||
return instance ? await this.instanceEntityService.pack(instance, me) : null;
|
||||
});
|
||||
|
|
|
@ -87,7 +87,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
super(meta, paramDef, async (ps, me) => {
|
||||
const user = await this.usersRepository.findOneBy(ps.userId != null
|
||||
? { id: ps.userId }
|
||||
: { usernameLower: ps.username!.toLowerCase(), host: this.utilityService.toPunyNullable(ps.host) ?? IsNull() });
|
||||
: { usernameLower: ps.username!.toLowerCase(), host: ps.host ? this.utilityService.normalizeHost(ps.host) : IsNull() });
|
||||
|
||||
if (user == null) {
|
||||
throw new ApiError(meta.errors.noSuchUser);
|
||||
|
|
|
@ -99,7 +99,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
super(meta, paramDef, async (ps, me) => {
|
||||
const user = await this.usersRepository.findOneBy(ps.userId != null
|
||||
? { id: ps.userId }
|
||||
: { usernameLower: ps.username!.toLowerCase(), host: this.utilityService.toPunyNullable(ps.host) ?? IsNull() });
|
||||
: { usernameLower: ps.username!.toLowerCase(), host: ps.host ? this.utilityService.normalizeHost(ps.host) : IsNull() });
|
||||
|
||||
if (user == null) {
|
||||
throw new ApiError(meta.errors.noSuchUser);
|
||||
|
|
Loading…
Reference in a new issue