Skip to content

Commit

Permalink
Merge branch 'develop' into fix-14170-1
Browse files Browse the repository at this point in the history
  • Loading branch information
syuilo authored Aug 10, 2024
2 parents bacfac8 + 01a815f commit 8305582
Show file tree
Hide file tree
Showing 26 changed files with 310 additions and 67 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/release-edit-with-push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:
- develop
paths:
- 'CHANGELOG.md'
# - .github/workflows/release-edit-with-push.yml

env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Expand Down
14 changes: 11 additions & 3 deletions .github/workflows/release-with-dispatch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ on:
type: boolean
description: 'MERGE RELEASE BRANCH TO MAIN'
default: false
start-rc:
type: boolean
description: 'Start Release Candidate'
default: false

env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand Down Expand Up @@ -56,13 +60,13 @@ jobs:
### General
-
### Client
-
### Server
-
use_external_app_to_release: ${{ vars.USE_RELEASE_APP == 'true' }}
indent: ${{ vars.INDENT }}
secrets:
Expand All @@ -79,6 +83,9 @@ jobs:
package_jsons_to_rewrite: ${{ vars.PACKAGE_JSONS_TO_REWRITE }}
use_external_app_to_release: ${{ vars.USE_RELEASE_APP == 'true' }}
indent: ${{ vars.INDENT }}
draft_prerelease_channel: alpha
ready_start_prerelease_channel: beta
prerelease_channel: ${{ inputs.start-rc && 'rc' || '' }}
secrets:
RELEASE_APP_ID: ${{ secrets.RELEASE_APP_ID }}
RELEASE_APP_PRIVATE_KEY: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
Expand Down Expand Up @@ -122,6 +129,7 @@ jobs:
use_external_app_to_release: ${{ vars.USE_RELEASE_APP == 'true' }}
indent: ${{ vars.INDENT }}
stable_branch: ${{ vars.STABLE_BRANCH }}
draft_prerelease_channel: alpha
secrets:
RELEASE_APP_ID: ${{ secrets.RELEASE_APP_ID }}
RELEASE_APP_PRIVATE_KEY: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
2 changes: 2 additions & 0 deletions .github/workflows/release-with-ready.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ jobs:
package_jsons_to_rewrite: ${{ vars.PACKAGE_JSONS_TO_REWRITE }}
use_external_app_to_release: ${{ vars.USE_RELEASE_APP == 'true' }}
indent: ${{ vars.INDENT }}
draft_prerelease_channel: alpha
ready_start_prerelease_channel: beta
secrets:
RELEASE_APP_ID: ${{ secrets.RELEASE_APP_ID }}
RELEASE_APP_PRIVATE_KEY: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
13 changes: 9 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
## Unreleased

### General
-
- Fix: リモートユーザのフォロー・フォロワーの一覧が非公開設定の場合も表示できてしまう問題を修正
- Enhance: モデレーターはすべてのユーザーのフォロー・フォロワーの一覧を見られるように

### Client
- ページ遷移に失敗することがある問題を修正
- Enhance: 「自分のPlay」ページにおいてPlayが非公開かどうかが一目でわかるように
- Fix: Play編集時に公開範囲が「パブリック」にリセットされる問題を修正
- Fix: ページ遷移に失敗することがある問題を修正

### Server
-

- Fix: WSの`readAllNotifications` メッセージが `body` を持たない場合に動作しない問題 #14374
- 通知ページや通知カラム(デッキ)を開いている状態において、新たに発生した通知が既読されない問題が修正されます。
- これにより、プッシュ通知が有効な同条件下の環境において、プッシュ通知が常に発生してしまう問題も修正されます。
- Fix: Play各種エンドポイントの返り値に`visibility`が含まれていない問題を修正

## 2024.7.0

Expand Down
3 changes: 2 additions & 1 deletion packages/backend/src/core/ModerationLogService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import type { ModerationLogsRepository } from '@/models/_.js';
import type { MiUser } from '@/models/User.js';
import { IdService } from '@/core/IdService.js';
import { bindThis } from '@/decorators.js';
import { ModerationLogPayloads, moderationLogTypes } from '@/types.js';
import type { ModerationLogPayloads } from '@/types.js';
import { moderationLogTypes } from '@/types.js';

@Injectable()
export class ModerationLogService {
Expand Down
50 changes: 49 additions & 1 deletion packages/backend/src/core/activitypub/models/ApPersonService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ import type { ApResolverService, Resolver } from '../ApResolverService.js';
import type { ApLoggerService } from '../ApLoggerService.js';
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
import type { ApImageService } from './ApImageService.js';
import type { IActor, IObject } from '../type.js';
import type { IActor, ICollection, IObject, IOrderedCollection } from '../type.js';

const nameLength = 128;
const summaryLength = 2048;
Expand Down Expand Up @@ -296,6 +296,21 @@ export class ApPersonService implements OnModuleInit {

const isBot = getApType(object) === 'Service' || getApType(object) === 'Application';

const [followingVisibility, followersVisibility] = await Promise.all(
[
this.isPublicCollection(person.following, resolver),
this.isPublicCollection(person.followers, resolver),
].map((p): Promise<'public' | 'private'> => p
.then(isPublic => isPublic ? 'public' : 'private')
.catch(err => {
if (!(err instanceof StatusError) || err.isRetryable) {
this.logger.error('error occurred while fetching following/followers collection', { stack: err });
}
return 'private';
})
)
);

const bday = person['vcard:bday']?.match(/^\d{4}-\d{2}-\d{2}/);

const url = getOneApHrefNullable(person.url);
Expand Down Expand Up @@ -357,6 +372,8 @@ export class ApPersonService implements OnModuleInit {
description: _description,
url,
fields,
followingVisibility,
followersVisibility,
birthday: bday?.[0] ?? null,
location: person['vcard:Address'] ?? null,
userHost: host,
Expand Down Expand Up @@ -464,6 +481,23 @@ export class ApPersonService implements OnModuleInit {

const tags = extractApHashtags(person.tag).map(normalizeForSearch).splice(0, 32);

const [followingVisibility, followersVisibility] = await Promise.all(
[
this.isPublicCollection(person.following, resolver),
this.isPublicCollection(person.followers, resolver),
].map((p): Promise<'public' | 'private' | undefined> => p
.then(isPublic => isPublic ? 'public' : 'private')
.catch(err => {
if (!(err instanceof StatusError) || err.isRetryable) {
this.logger.error('error occurred while fetching following/followers collection', { stack: err });
// Do not update the visibiility on transient errors.
return undefined;
}
return 'private';
})
)
);

const bday = person['vcard:bday']?.match(/^\d{4}-\d{2}-\d{2}/);

const url = getOneApHrefNullable(person.url);
Expand Down Expand Up @@ -532,6 +566,8 @@ export class ApPersonService implements OnModuleInit {
url,
fields,
description: _description,
followingVisibility,
followersVisibility,
birthday: bday?.[0] ?? null,
location: person['vcard:Address'] ?? null,
});
Expand Down Expand Up @@ -703,4 +739,16 @@ export class ApPersonService implements OnModuleInit {

return 'ok';
}

@bindThis
private async isPublicCollection(collection: string | ICollection | IOrderedCollection | undefined, resolver: Resolver): Promise<boolean> {
if (collection) {
const resolved = await resolver.resolveCollection(collection);
if (resolved.first || (resolved as ICollection).items || (resolved as IOrderedCollection).orderedItems) {
return true;
}
}

return false;
}
}
6 changes: 4 additions & 2 deletions packages/backend/src/core/activitypub/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,15 @@ export interface IActivity extends IObject {
export interface ICollection extends IObject {
type: 'Collection';
totalItems: number;
items: ApObject;
first?: IObject | string;
items?: ApObject;
}

export interface IOrderedCollection extends IObject {
type: 'OrderedCollection';
totalItems: number;
orderedItems: ApObject;
first?: IObject | string;
orderedItems?: ApObject;
}

export const validPost = ['Note', 'Question', 'Article', 'Audio', 'Document', 'Image', 'Page', 'Video', 'Event'];
Expand Down
1 change: 1 addition & 0 deletions packages/backend/src/core/entities/FlashEntityService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export class FlashEntityService {
title: flash.title,
summary: flash.summary,
script: flash.script,
visibility: flash.visibility,
likedCount: flash.likedCount,
isLiked: meId ? await this.flashLikesRepository.exists({ where: { flashId: flash.id, userId: meId } }) : undefined,
});
Expand Down
4 changes: 2 additions & 2 deletions packages/backend/src/core/entities/UserEntityService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -454,12 +454,12 @@ export class UserEntityService implements OnModuleInit {
}

const followingCount = profile == null ? null :
(profile.followingVisibility === 'public') || isMe ? user.followingCount :
(profile.followingVisibility === 'public') || isMe || iAmModerator ? user.followingCount :
(profile.followingVisibility === 'followers') && (relation && relation.isFollowing) ? user.followingCount :
null;

const followersCount = profile == null ? null :
(profile.followersVisibility === 'public') || isMe ? user.followersCount :
(profile.followersVisibility === 'public') || isMe || iAmModerator ? user.followersCount :
(profile.followersVisibility === 'followers') && (relation && relation.isFollowing) ? user.followersCount :
null;

Expand Down
4 changes: 4 additions & 0 deletions packages/backend/src/misc/json-value.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,7 @@
export type JsonValue = JsonArray | JsonObject | string | number | boolean | null;
export type JsonObject = {[K in string]?: JsonValue};
export type JsonArray = JsonValue[];

export function isJsonObject(value: JsonValue | undefined): value is JsonObject {
return typeof value === 'object' && value !== null && !Array.isArray(value);
}
5 changes: 5 additions & 0 deletions packages/backend/src/models/json-schema/flash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ export const packedFlashSchema = {
type: 'string',
optional: false, nullable: false,
},
visibility: {
type: 'string',
optional: false, nullable: false,
enum: ['private', 'public'],
},
likedCount: {
type: 'number',
optional: false, nullable: true,
Expand Down
34 changes: 19 additions & 15 deletions packages/backend/src/server/api/endpoints/users/followers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down Expand Up @@ -81,6 +82,7 @@ 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
Expand All @@ -93,22 +95,24 @@ 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);
}
}
}
}
Expand Down
34 changes: 19 additions & 15 deletions packages/backend/src/server/api/endpoints/users/following.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down Expand Up @@ -90,6 +91,7 @@ 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
Expand All @@ -102,22 +104,24 @@ 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);
}
}
}
}
Expand Down
Loading

0 comments on commit 8305582

Please sign in to comment.