Merge upstream

This commit is contained in:
ASTRO:? 2024-12-30 23:28:39 +09:00
commit 5f931855be
No known key found for this signature in database
GPG key ID: 8947F3AF5B0B4BFE
147 changed files with 1778 additions and 1044 deletions

View file

@ -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) {

View file

@ -51,14 +51,14 @@ 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 ApiError(meta.errors.instanceNotFound);
}
const followingCount = await this.followingsRepository.countBy({ followerHost: this.utilityService.toPuny(ps.host) });
const followersCount = await this.followingsRepository.countBy({ followeeHost: this.utilityService.toPuny(ps.host) });
const followingCount = await this.followingsRepository.countBy({ followerHost: this.utilityService.normalizeHost(ps.host) });
const followersCount = await this.followingsRepository.countBy({ followeeHost: this.utilityService.normalizeHost(ps.host) });
await this.federatedInstanceService.update(instance.id, {
followingCount: followingCount,

View file

@ -51,7 +51,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
private utilityService: UtilityService,
) {
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 ApiError(meta.errors.instanceNotFound);

View file

@ -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');

View file

@ -49,6 +49,7 @@ export const paramDef = {
properties: {
roleId: { type: 'string', format: 'misskey:id' },
userId: { type: 'string', format: 'misskey:id' },
memo: { type: 'string' },
expiresAt: {
type: 'integer',
nullable: true,
@ -90,7 +91,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
return;
}
await this.roleService.assign(user.id, role.id, ps.expiresAt ? new Date(ps.expiresAt) : null, me);
await this.roleService.assign(user.id, role.id, ps.memo, ps.expiresAt ? new Date(ps.expiresAt) : null, me);
});
}
}

View file

@ -36,6 +36,7 @@ export const meta = {
id: { type: 'string', format: 'misskey:id' },
createdAt: { type: 'string', format: 'date-time' },
user: { ref: 'UserDetailed' },
memo: { type: 'string', nullable: true },
expiresAt: { type: 'string', format: 'date-time', nullable: true },
},
required: ['id', 'createdAt', 'user'],
@ -93,6 +94,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
id: assign.id,
createdAt: this.idService.parse(assign.id).date.toISOString(),
user: await this.userEntityService.pack(assign.user!, me, { schema: 'UserDetailed' }),
memo: assign.memo,
expiresAt: assign.expiresAt?.toISOString() ?? null,
})));
});

View file

@ -177,6 +177,10 @@ export const meta = {
type: 'string',
optional: false, nullable: false,
},
memo: {
type: 'string',
optional: false, nullable: true,
}
},
},
},
@ -262,6 +266,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
createdAt: this.idService.parse(a.id).date.toISOString(),
expiresAt: a.expiresAt ? a.expiresAt.toISOString() : null,
roleId: a.roleId,
memo: a.memo,
})),
};
});

View file

@ -11,6 +11,7 @@ import { ApResolverService } from '@/core/activitypub/ApResolverService.js';
export const meta = {
tags: ['federation'],
requireAdmin: true,
requireCredential: true,
kind: 'read:federation',

View file

@ -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,6 +122,11 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
]));
if (local != null) return local;
const host = this.utilityService.extractHost(uri);
// local object, not found in db? fail
if (this.utilityService.isSelfHost(host)) return null;
// リモートから一旦オブジェクトフェッチ
const resolver = this.apResolverService.createResolver();
const object = await resolver.resolve(uri) as any;
@ -136,10 +141,11 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
if (local != null) return local;
}
// 同一ユーザーの情報を再度処理するので、使用済みのresolverを再利用してはいけない
return await this.mergePack(
me,
isActor(object) ? await this.apPersonService.createPerson(getApId(object)) : null,
isPost(object) ? await this.apNoteService.createNote(getApId(object), undefined, true) : null,
isPost(object) ? await this.apNoteService.createNote(getApId(object), undefined, undefined, true) : null,
);
}

View file

@ -44,7 +44,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;
});

View file

@ -11,6 +11,7 @@ import { QueryService } from '@/core/QueryService.js';
import { FollowingEntityService } from '@/core/entities/FollowingEntityService.js';
import { UtilityService } from '@/core/UtilityService.js';
import { DI } from '@/di-symbols.js';
import { RoleService } from '@/core/RoleService.js';
import { ApiError } from '../../error.js';
export const meta = {
@ -81,11 +82,12 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
private utilityService: UtilityService,
private followingEntityService: FollowingEntityService,
private queryService: QueryService,
private roleService: RoleService,
) {
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);
@ -93,23 +95,25 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
const profile = await this.userProfilesRepository.findOneByOrFail({ userId: user.id });
if (profile.followersVisibility === 'private') {
if (me == null || (me.id !== user.id)) {
throw new ApiError(meta.errors.forbidden);
}
} else if (profile.followersVisibility === 'followers') {
if (me == null) {
throw new ApiError(meta.errors.forbidden);
} else if (me.id !== user.id) {
const isFollowing = await this.followingsRepository.exists({
where: {
followeeId: user.id,
followerId: me.id,
},
});
if (!isFollowing) {
if (profile.followersVisibility !== 'public' && !await this.roleService.isModerator(me)) {
if (profile.followersVisibility === 'private') {
if (me == null || (me.id !== user.id)) {
throw new ApiError(meta.errors.forbidden);
}
} else if (profile.followersVisibility === 'followers') {
if (me == null) {
throw new ApiError(meta.errors.forbidden);
} else if (me.id !== user.id) {
const isFollowing = await this.followingsRepository.exists({
where: {
followeeId: user.id,
followerId: me.id,
},
});
if (!isFollowing) {
throw new ApiError(meta.errors.forbidden);
}
}
}
}

View file

@ -12,6 +12,7 @@ import { QueryService } from '@/core/QueryService.js';
import { FollowingEntityService } from '@/core/entities/FollowingEntityService.js';
import { UtilityService } from '@/core/UtilityService.js';
import { DI } from '@/di-symbols.js';
import { RoleService } from '@/core/RoleService.js';
import { ApiError } from '../../error.js';
export const meta = {
@ -93,11 +94,12 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
private utilityService: UtilityService,
private followingEntityService: FollowingEntityService,
private queryService: QueryService,
private roleService: RoleService,
) {
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);
@ -105,23 +107,25 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
const profile = await this.userProfilesRepository.findOneByOrFail({ userId: user.id });
if (profile.followingVisibility === 'private') {
if (me == null || (me.id !== user.id)) {
throw new ApiError(meta.errors.forbidden);
}
} else if (profile.followingVisibility === 'followers') {
if (me == null) {
throw new ApiError(meta.errors.forbidden);
} else if (me.id !== user.id) {
const isFollowing = await this.followingsRepository.exists({
where: {
followeeId: user.id,
followerId: me.id,
},
});
if (!isFollowing) {
if (profile.followingVisibility !== 'public' && !await this.roleService.isModerator(me)) {
if (profile.followingVisibility === 'private') {
if (me == null || (me.id !== user.id)) {
throw new ApiError(meta.errors.forbidden);
}
} else if (profile.followingVisibility === 'followers') {
if (me == null) {
throw new ApiError(meta.errors.forbidden);
} else if (me.id !== user.id) {
const isFollowing = await this.followingsRepository.exists({
where: {
followeeId: user.id,
followerId: me.id,
},
});
if (!isFollowing) {
throw new ApiError(meta.errors.forbidden);
}
}
}
}