enhance(backend): 連合する必要のないプロフィール項目しか更新されなかった場合にはUpdateアクティビティを発行しないように
This commit is contained in:
parent
32651aba67
commit
8af13a6502
|
@ -9,7 +9,8 @@ import { In } from 'typeorm';
|
|||
import * as mfm from 'mfm-js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import type { Config } from '@/config.js';
|
||||
import type { MiPartialLocalUser, MiLocalUser, MiPartialRemoteUser, MiRemoteUser, MiUser } from '@/models/User.js';
|
||||
import type { MiPartialLocalUser, MiLocalUser, MiPartialRemoteUser, MiRemoteUser, MiUser, MiLocalUserForApPersonRender } from '@/models/User.js';
|
||||
import type { MiUserProfileForApPersonRender } from '@/models/UserProfile.js';
|
||||
import type { IMentionedRemoteUsers, MiNote } from '@/models/Note.js';
|
||||
import type { MiBlocking } from '@/models/Blocking.js';
|
||||
import type { MiRelay } from '@/models/Relay.js';
|
||||
|
@ -251,7 +252,7 @@ export class ApRendererService {
|
|||
}
|
||||
|
||||
@bindThis
|
||||
public renderKey(user: MiLocalUser, key: MiUserKeypair, postfix?: string): IKey {
|
||||
public renderKey(user: { id: MiUser['id'] }, key: MiUserKeypair, postfix?: string): IKey {
|
||||
return {
|
||||
id: `${this.config.url}/users/${user.id}${postfix ?? '/publickey'}`,
|
||||
type: 'Key',
|
||||
|
@ -449,14 +450,14 @@ export class ApRendererService {
|
|||
}
|
||||
|
||||
@bindThis
|
||||
public async renderPerson(user: MiLocalUser) {
|
||||
public async renderPerson(user: MiLocalUserForApPersonRender) {
|
||||
const id = this.userEntityService.genLocalUserUri(user.id);
|
||||
const isSystem = user.username.includes('.');
|
||||
|
||||
const [avatar, banner, profile] = await Promise.all([
|
||||
user.avatarId ? this.driveFilesRepository.findOneBy({ id: user.avatarId }) : undefined,
|
||||
user.bannerId ? this.driveFilesRepository.findOneBy({ id: user.bannerId }) : undefined,
|
||||
this.userProfilesRepository.findOneByOrFail({ userId: user.id }),
|
||||
(this.userProfilesRepository.findOneByOrFail({ userId: user.id }) as Promise<MiUserProfileForApPersonRender>),
|
||||
]);
|
||||
|
||||
const attachment = profile.fields.map(field => ({
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
export function keys<T extends { [x: string]: unknown }>(obj: T): (keyof T)[] {
|
||||
return Object.keys(obj);
|
||||
}
|
|
@ -285,6 +285,24 @@ export type MiPartialRemoteUser = Partial<MiUser> & {
|
|||
uri: string;
|
||||
}
|
||||
|
||||
export const miLocalUserKeysUsedForApPersonRender = [
|
||||
'id',
|
||||
'username',
|
||||
'avatarId',
|
||||
'bannerId',
|
||||
'emojis',
|
||||
'tags',
|
||||
'isBot',
|
||||
'isCat',
|
||||
'name',
|
||||
'isLocked',
|
||||
'isExplorable',
|
||||
'movedToUri',
|
||||
'alsoKnownAs',
|
||||
] as const satisfies (keyof MiLocalUser)[];
|
||||
|
||||
export type MiLocalUserForApPersonRender = Pick<MiLocalUser, typeof miLocalUserKeysUsedForApPersonRender[number]>;
|
||||
|
||||
export const localUsernameSchema = { type: 'string', pattern: /^\w{1,20}$/.toString().slice(1, -1) } as const;
|
||||
export const passwordSchema = { type: 'string', minLength: 1 } as const;
|
||||
export const nameSchema = { type: 'string', minLength: 1, maxLength: 50 } as const;
|
||||
|
|
|
@ -287,3 +287,12 @@ export class MiUserProfile {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const miUserProfileKeysUsedForApPersonRender = [
|
||||
'fields',
|
||||
'description',
|
||||
'birthday',
|
||||
'location',
|
||||
] as const satisfies (keyof MiUserProfile)[];
|
||||
|
||||
export type MiUserProfileForApPersonRender = Pick<MiUserProfile, typeof miUserProfileKeysUsedForApPersonRender[number]>;
|
||||
|
|
|
@ -11,6 +11,7 @@ import { JSDOM } from 'jsdom';
|
|||
import { extractCustomEmojisFromMfm } from '@/misc/extract-custom-emojis-from-mfm.js';
|
||||
import { extractHashtags } from '@/misc/extract-hashtags.js';
|
||||
import * as Acct from '@/misc/acct.js';
|
||||
import { keys } from '@/misc/prelude/object.js';
|
||||
import type { UsersRepository, DriveFilesRepository, UserProfilesRepository, PagesRepository } from '@/models/_.js';
|
||||
import type { MiLocalUser, MiUser } from '@/models/User.js';
|
||||
import { birthdaySchema, descriptionSchema, locationSchema, nameSchema } from '@/models/User.js';
|
||||
|
@ -34,6 +35,8 @@ import type { Config } from '@/config.js';
|
|||
import { safeForSql } from '@/misc/safe-for-sql.js';
|
||||
import { AvatarDecorationService } from '@/core/AvatarDecorationService.js';
|
||||
import { notificationRecieveConfig } from '@/models/json-schema/user.js';
|
||||
import { miLocalUserKeysUsedForApPersonRender } from '@/models/User.js';
|
||||
import { miUserProfileKeysUsedForApPersonRender } from '@/models/UserProfile.js';
|
||||
import { ApiLoggerService } from '../../ApiLoggerService.js';
|
||||
import { ApiError } from '../../error.js';
|
||||
|
||||
|
@ -501,8 +504,13 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
this.userFollowingService.acceptAllFollowRequests(user);
|
||||
}
|
||||
|
||||
// フォロワーにUpdateを配信
|
||||
this.accountUpdateService.publishToFollowers(user.id);
|
||||
// 連合する必要があるプロパティが変更されている場合はフォロワーにUpdateを配信
|
||||
if (
|
||||
miLocalUserKeysUsedForApPersonRender.some(k => keys(updates).includes(k)) ||
|
||||
miUserProfileKeysUsedForApPersonRender.some(k => keys(profileUpdates).includes(k))
|
||||
) {
|
||||
this.accountUpdateService.publishToFollowers(user.id);
|
||||
}
|
||||
|
||||
const urls = updatedProfile.fields.filter(x => x.value.startsWith('https://'));
|
||||
for (const url of urls) {
|
||||
|
|
Loading…
Reference in New Issue