follow allowExternalApRedirect

This commit is contained in:
tamaina 2025-08-30 22:18:41 +09:00
parent 6614c4343f
commit 78ed759528
2 changed files with 36 additions and 7 deletions

View File

@ -7,7 +7,7 @@ import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common';
import * as misskey from 'misskey-js';
import { IsNull } from 'typeorm';
import { DI } from '@/di-symbols.js';
import type { NotesRepository, UserPublickeysRepository, UsersRepository } from '@/models/_.js';
import type { MiMeta, NotesRepository, UserPublickeysRepository, UsersRepository } from '@/models/_.js';
import type { Config } from '@/config.js';
import { MemoryKVCache } from '@/misc/cache.js';
import type { MiUserPublickey } from '@/models/UserPublickey.js';
@ -51,6 +51,9 @@ export class ApDbResolverService implements OnApplicationShutdown {
@Inject(DI.config)
private config: Config,
@Inject(DI.meta)
private meta: MiMeta,
@Inject(DI.usersRepository)
private usersRepository: UsersRepository,
@ -128,14 +131,25 @@ export class ApDbResolverService implements OnApplicationShutdown {
* AP Person => Misskey User in DB
*/
@bindThis
public async getUserFromApId(value: string | IObject, acceptAcct: boolean = false): Promise<MiLocalUser | MiRemoteUser | null> {
public async getUserFromApId(value: string | IObject, acceptAcct = false): Promise<MiLocalUser | MiRemoteUser | null> {
const parsed = this.parseLocalUri(value);
if (acceptAcct && 'acct' in parsed) {
return await this.usersRepository.findOneBy({
usernameLower: parsed.acct.username.toLowerCase(),
host: (parsed.acct.host == null || parsed.local) ? IsNull() : this.utilityService.toPuny(parsed.acct.host),
}) as MiLocalUser | MiRemoteUser | null;
if (parsed.acct.host == null || parsed.local) {
return await this.usersRepository.findOneBy({
usernameLower: parsed.acct.username.toLowerCase(),
host: IsNull(),
}) as MiLocalUser | null;
}
if (this.meta.allowExternalApRedirect) {
return await this.usersRepository.findOneBy({
usernameLower: parsed.acct.username.toLowerCase(),
host: this.utilityService.toPuny(parsed.acct.host),
}) as MiRemoteUser | null;
}
return null;
}
if ('uri' in parsed) {

View File

@ -1,5 +1,5 @@
import { strictEqual, rejects } from 'node:assert';
import { createAccount, resolveRemoteUser, sleep, type LoginUser } from '../../utils.js';
import { createAccount, resolveRemoteUser, sleep, type LoginUser } from '../../uatils.js';
describe('API ap/show', () => {
let alice: LoginUser, bob: LoginUser;
@ -37,15 +37,30 @@ describe('API ap/show', () => {
});
test('resolve a fetched remote user by local profile url (https://a.test/@bob@b.test)', async () => {
await alice.client.request('admin/update-meta', { allowExternalApRedirect: true });
await resolveRemoteUser('b.test', bob.id, alice);
const res = await alice.client.request('ap/show', { uri: `https://a.test/@${bob.username}@b.test` });
strictEqual(res.type, 'User');
strictEqual(res.object.uri, `https://b.test/users/${bob.id}`);
});
test('throws in resolving a fetched remote user by local profile url when allowExternalApRedirect: false', async () => {
await alice.client.request('admin/update-meta', { allowExternalApRedirect: false });
await resolveRemoteUser('b.test', bob.id, alice);
await rejects(
async () => await alice.client.request('ap/show', { uri: `https://a.test/@${bob.username}@b.test` }),
(err: any) => {
strictEqual(err.code, 'NO_SUCH_OBJECT');
return true;
},
);
});
test('throws in resolving a non-fetched remote user by local profile url (https://a.test/@bob@b.test)', async () => {
// ユーザーがこのような問い合わせをすることは、ない!
await alice.client.request('admin/update-meta', { allowExternalApRedirect: true });
await rejects(
async () => await alice.client.request('ap/show', { uri: `https://a.test/@${bob.username}@b.test` }),
(err: any) => {