Skip to content

Commit

Permalink
Fix: PersonのserchableByが正しく連合できていないのを修正 (#556)
Browse files Browse the repository at this point in the history
  • Loading branch information
penginn-net authored Nov 30, 2024
1 parent f918b11 commit e6eec4c
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 31 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG_YOJO.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
## 1.2.0

### General
- Fix: ノートを編集する時に検索許可範囲を記憶する [#558](https://github.com/yojo-art/cherrypick/pull/558)

### Server
- Fix: PersonのserchableByが正しく連合できていないのを修正[#556](https://github.com/yojo-art/cherrypick/pull/556)
- Enhance: `/users/${id}``Accept: application/ld+json`ではないリクエストが来たとき`/@${username}`にリダイレクトするように [#554](https://github.com/yojo-art/cherrypick/pull/554)

## 1.1.0
Expand Down
18 changes: 1 addition & 17 deletions packages/backend/src/core/activitypub/ApAudienceService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import promiseLimit from 'promise-limit';
import type { MiRemoteUser, MiUser } from '@/models/User.js';
import { concat, unique } from '@/misc/prelude/array.js';
import { bindThis } from '@/decorators.js';
import { searchableTypes } from '@/types.js';
import { getApIds } from './type.js';
import { ApPersonService } from './models/ApPersonService.js';
import type { ApObject } from './type.js';
Expand Down Expand Up @@ -73,22 +72,7 @@ export class ApAudienceService {
visibleUsers: mentionedUsers,
};
}
public async parseSearchableBy (actor: MiRemoteUser, searchableBy?: string[]): Promise<'public' | 'followersAndReacted' | 'reactedOnly' | 'private' | null> {
if (!searchableBy) {
return null;
}
console.log(searchableBy);
if (searchableBy.includes('https://www.w3.org/ns/activitystreams#Public')) {
return 'public';
} else if (actor.followersUri && searchableBy.includes(actor.followersUri)) {
return 'followersAndReacted';
} else if (searchableBy.includes(actor.uri)) {
return 'reactedOnly';
} else if (searchableBy.includes('as:Limited') || searchableBy.includes('kmyblue:Limited')) {
return 'private';
}
return null;
}

@bindThis
private groupingAudience(ids: string[], actor: MiRemoteUser): GroupedAudience {
const groups: GroupedAudience = {
Expand Down
4 changes: 3 additions & 1 deletion packages/backend/src/core/activitypub/ApRendererService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import { searchableTypes } from '@/types.js';
import { JsonLdService } from './JsonLdService.js';
import { ApMfmService } from './ApMfmService.js';
import { CONTEXT } from './misc/contexts.js';
import { toSerchableByProperty } from './misc/searchableBy.js';
import type { IAccept, IActivity, IAdd, IAnnounce, IApDocument, IApEmoji, IApHashtag, IApImage, IApMention, IApReversi, IBlock, ICreate, IDelete, IFlag, IFollow, IInvite, IJoin, IKey, ILeave, ILike, IMove, IObject, IPost, IQuestion, IRead, IReject, IRemove, ITombstone, IUndo, IUpdate } from './type.js';

@Injectable()
Expand Down Expand Up @@ -541,6 +542,7 @@ export class ApRendererService {
];

const keypair = await this.userKeypairService.getUserKeypair(user.id);
const searchableByData = toSerchableByProperty(this.config.url, user.id, user.searchableBy);

const person: any = {
type: isSystem ? 'Application' : user.isBot ? 'Service' : 'Person',
Expand All @@ -564,7 +566,7 @@ export class ApRendererService {
manuallyApprovesFollowers: user.isLocked,
discoverable: user.isExplorable,
indexable: user.isIndexable,
searchableBy: [`${this.config.url}/users/${user.id}`],
...( searchableByData ? { searchableBy: searchableByData } : {}),
publicKey: this.renderKey(user, keypair, '#main-key'),
isCat: user.isCat,
attachment: attachment.length ? attachment : undefined,
Expand Down
44 changes: 44 additions & 0 deletions packages/backend/src/core/activitypub/misc/searchableBy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project, yojo-art team
* SPDX-License-Identifier: AGPL-3.0-only
*/

export function parseSearchableByFromTags(tags: string[]): 'public' | 'followersAndReacted' | 'reactedOnly' | 'private' | null {
if (tags.includes('searchable_by_all_users')) return 'public';
if (tags.includes('searchable_by_followers_only')) return 'followersAndReacted';
if (tags.includes('searchable_by_reacted_users_only')) return 'followersAndReacted';
if (tags.includes('searchable_by_nobody')) return 'private';
return null;
}

export function parseSearchableByFromProperty (uri: string, followersUri?: string, searchableBy?: string[]): 'public' | 'followersAndReacted' | 'reactedOnly' | 'private' | null {
if (!searchableBy) {
return null;
}

if (searchableBy.includes('https://www.w3.org/ns/activitystreams#Public')) {
return 'public';
} else if (followersUri && searchableBy.includes(followersUri)) {
return 'followersAndReacted';
} else if (searchableBy.includes(uri)) {
return 'reactedOnly';
} else if (searchableBy.includes('as:Limited') || searchableBy.includes('kmyblue:Limited')) {
return 'private';
}
return null;
}

export function toSerchableByProperty (configUrl: string, userId: string, serchableType: 'public' | 'followersAndReacted' | 'reactedOnly' | 'private' | null) : string[] | null {
switch (serchableType) {
case 'public' :
return ['https://www.w3.org/ns/activitystreams#Public'];
case 'followersAndReacted' :
return [`${configUrl}/${userId}/followers`];
case 'reactedOnly' :
return [`${configUrl}/users/${userId}`];
case 'private' :
return ['as:Limited', 'kmyblue:Limited'];
default :
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { ApMfmService } from '../ApMfmService.js';
import { ApDbResolverService } from '../ApDbResolverService.js';
import { ApResolverService } from '../ApResolverService.js';
import { ApAudienceService } from '../ApAudienceService.js';
import { parseSearchableByFromProperty } from '../misc/searchableBy.js';
import { ApPersonService } from './ApPersonService.js';
import { extractApHashtags } from './tag.js';
import { ApMentionService } from './ApMentionService.js';
Expand Down Expand Up @@ -209,7 +210,7 @@ export class ApNoteService {
}

const noteAudience = await this.apAudienceService.parseAudience(actor, note.to, note.cc, resolver);
const searchableBy = await this.apAudienceService.parseSearchableBy(actor, note.searchableBy);
const searchableBy = parseSearchableByFromProperty(actor.uri, actor.followersUri ?? undefined, note.searchableBy);
let visibility = noteAudience.visibility;
const visibleUsers = noteAudience.visibleUsers;

Expand Down
19 changes: 7 additions & 12 deletions packages/backend/src/core/activitypub/models/ApPersonService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.j
import type { AccountMoveService } from '@/core/AccountMoveService.js';
import { checkHttps } from '@/misc/check-https.js';
import { AvatarDecorationService } from '@/core/AvatarDecorationService.js';
import { searchableTypes } from '@/types.js';
import { getApId, getApType, getOneApHrefNullable, isActor, isCollection, isCollectionOrOrderedCollection, isPropertyValue } from '../type.js';
import { parseSearchableByFromTags, parseSearchableByFromProperty } from '../misc/searchableBy.js';
import { extractApHashtags } from './tag.js';
import type { OnModuleInit } from '@nestjs/common';
import type { ApNoteService } from './ApNoteService.js';
Expand Down Expand Up @@ -410,7 +410,9 @@ export class ApPersonService implements OnModuleInit {
alsoKnownAs: person.alsoKnownAs,
isExplorable: person.discoverable,
isIndexable: person.indexable ?? true,
searchableBy: this.getSearchableType(tags),
searchableBy: person.searchableBy ?
parseSearchableByFromProperty(uri, person.followers ? getApId(person.followers) : undefined, person.searchableBy) :
parseSearchableByFromTags(tags),
username: person.preferredUsername,
usernameLower: person.preferredUsername?.toLowerCase(),
host,
Expand Down Expand Up @@ -656,7 +658,9 @@ export class ApPersonService implements OnModuleInit {
const role_policy = await this.roleService.getUserPolicies(exist.id);
const updates = {
lastFetchedAt: new Date(),
searchableBy: this.getSearchableType(tags),
searchableBy: person.searchableBy ?
parseSearchableByFromProperty(uri, person.followers ? getApId(person.followers) : undefined, person.searchableBy) :
parseSearchableByFromTags(tags),
inbox: person.inbox,
sharedInbox: person.sharedInbox ?? person.endpoints?.sharedInbox,
outbox: typeof person.outbox === 'string' ? person.outbox : null,
Expand Down Expand Up @@ -1006,13 +1010,4 @@ export class ApPersonService implements OnModuleInit {

return false;
}

@bindThis
private getSearchableType(tags: string[]): 'public' | 'followersAndReacted' | 'reactedOnly' | 'private' | null {
if (tags.includes('searchable_by_all_users')) return 'public';
if (tags.includes('searchable_by_followers_only')) return 'followersAndReacted';
if (tags.includes('searchable_by_reacted_users_only')) return 'followersAndReacted';
if (tags.includes('searchable_by_nobody')) return 'private';
return null;
}
}
1 change: 1 addition & 0 deletions packages/backend/src/core/activitypub/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ export interface IActor extends IObject {
alsoKnownAs?: string[];
discoverable?: boolean;
indexable?: boolean;
searchableBy?: string[];
inbox: string;
sharedInbox?: string; // 後方互換性のため
publicKey?: {
Expand Down

0 comments on commit e6eec4c

Please sign in to comment.