Merge pull request from GHSA-7pxq-6xx9-xpgm

* fix: fix improper authorization when accessing with third-party application

* refactor: refactor type definitions

* fix: get rid of unnecessary access limitation

* enhance: サードパーティアプリケーションがWebsocket APIを使えるように

* fix: add missing parentheses

* Revert "fix(backend): add missing kind definition for admin endpoints to improve security"

This reverts commit 5150053275.

* frontend: 翻訳の抜けを訂正, read:adminとwrite:adminはアクセス発行トークンのデフォルトでは非表示にする

* enhance(test): misskey-ghsa-7pxq-6xx9-xpgmに関するテストを追加

* enhance(test): Websocket APIに対するテストも追加

* enhance(refactor): `@/misc/api-permissions.ts`を`misskey-js/permissions`に統合

* fix(frontend): アクセストークン発行UIで全ての権限を有効にした際、管理者用APIへのアクセスも許可してしまう問題を修正

* enhance(backend): Websocketの接続に最低限必要な権限を変更

* fix(backend): `/api/admin/meta`をサードパーティアプリケーションからはアクセスできないように

* fix(backend): エンドポイントにアクセスするために必要な権限を変更

* fix(frontend/locale): Add missing type declaration

* chore: update `misskey-js/src/autogen`

---------

Co-authored-by: tamaina <tamaina@hotmail.co.jp>
This commit is contained in:
Chocolate Pie
2023-12-27 15:08:59 +09:00
committed by GitHub
parent d87fecda7f
commit c96bc36fed
148 changed files with 797 additions and 581 deletions

View File

@@ -5,12 +5,13 @@
import { Injectable } from '@nestjs/common';
import { bindThis } from '@/decorators.js';
import Channel from '../channel.js';
import Channel, { type MiChannelService } from '../channel.js';
class AdminChannel extends Channel {
public readonly chName = 'admin';
public static shouldShare = true;
public static requireCredential = true;
public static requireCredential = true as const;
public static kind = 'read:admin:stream';
@bindThis
public async init(params: any) {
@@ -22,9 +23,10 @@ class AdminChannel extends Channel {
}
@Injectable()
export class AdminChannelService {
export class AdminChannelService implements MiChannelService<true> {
public readonly shouldShare = AdminChannel.shouldShare;
public readonly requireCredential = AdminChannel.requireCredential;
public readonly kind = AdminChannel.kind;
constructor(
) {

View File

@@ -8,12 +8,13 @@ import { isUserRelated } from '@/misc/is-user-related.js';
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
import { bindThis } from '@/decorators.js';
import type { GlobalEvents } from '@/core/GlobalEventService.js';
import Channel from '../channel.js';
import Channel, { type MiChannelService } from '../channel.js';
class AntennaChannel extends Channel {
public readonly chName = 'antenna';
public static shouldShare = false;
public static requireCredential = false;
public static requireCredential = true as const;
public static kind = 'read:account';
private antennaId: string;
constructor(
@@ -62,9 +63,10 @@ class AntennaChannel extends Channel {
}
@Injectable()
export class AntennaChannelService {
export class AntennaChannelService implements MiChannelService<true> {
public readonly shouldShare = AntennaChannel.shouldShare;
public readonly requireCredential = AntennaChannel.requireCredential;
public readonly kind = AntennaChannel.kind;
constructor(
private noteEntityService: NoteEntityService,

View File

@@ -8,12 +8,12 @@ import { isUserRelated } from '@/misc/is-user-related.js';
import type { Packed } from '@/misc/json-schema.js';
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
import { bindThis } from '@/decorators.js';
import Channel from '../channel.js';
import Channel, { type MiChannelService } from '../channel.js';
class ChannelChannel extends Channel {
public readonly chName = 'channel';
public static shouldShare = false;
public static requireCredential = false;
public static requireCredential = false as const;
private channelId: string;
constructor(
@@ -65,9 +65,10 @@ class ChannelChannel extends Channel {
}
@Injectable()
export class ChannelChannelService {
export class ChannelChannelService implements MiChannelService<false> {
public readonly shouldShare = ChannelChannel.shouldShare;
public readonly requireCredential = ChannelChannel.requireCredential;
public readonly kind = ChannelChannel.kind;
constructor(
private noteEntityService: NoteEntityService,

View File

@@ -5,12 +5,13 @@
import { Injectable } from '@nestjs/common';
import { bindThis } from '@/decorators.js';
import Channel from '../channel.js';
import Channel, { type MiChannelService } from '../channel.js';
class DriveChannel extends Channel {
public readonly chName = 'drive';
public static shouldShare = true;
public static requireCredential = true;
public static requireCredential = true as const;
public static kind = 'read:account';
@bindThis
public async init(params: any) {
@@ -22,9 +23,10 @@ class DriveChannel extends Channel {
}
@Injectable()
export class DriveChannelService {
export class DriveChannelService implements MiChannelService<true> {
public readonly shouldShare = DriveChannel.shouldShare;
public readonly requireCredential = DriveChannel.requireCredential;
public readonly kind = DriveChannel.kind;
constructor(
) {

View File

@@ -12,12 +12,12 @@ import { MetaService } from '@/core/MetaService.js';
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
import { bindThis } from '@/decorators.js';
import { RoleService } from '@/core/RoleService.js';
import Channel from '../channel.js';
import Channel, { type MiChannelService } from '../channel.js';
class GlobalTimelineChannel extends Channel {
public readonly chName = 'globalTimeline';
public static shouldShare = false;
public static requireCredential = false;
public static requireCredential = false as const;
private withRenotes: boolean;
private withFiles: boolean;
@@ -91,9 +91,10 @@ class GlobalTimelineChannel extends Channel {
}
@Injectable()
export class GlobalTimelineChannelService {
export class GlobalTimelineChannelService implements MiChannelService<false> {
public readonly shouldShare = GlobalTimelineChannel.shouldShare;
public readonly requireCredential = GlobalTimelineChannel.requireCredential;
public readonly kind = GlobalTimelineChannel.kind;
constructor(
private metaService: MetaService,

View File

@@ -9,12 +9,12 @@ import { isUserRelated } from '@/misc/is-user-related.js';
import type { Packed } from '@/misc/json-schema.js';
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
import { bindThis } from '@/decorators.js';
import Channel from '../channel.js';
import Channel, { type MiChannelService } from '../channel.js';
class HashtagChannel extends Channel {
public readonly chName = 'hashtag';
public static shouldShare = false;
public static requireCredential = false;
public static requireCredential = false as const;
private q: string[][];
constructor(
@@ -70,9 +70,10 @@ class HashtagChannel extends Channel {
}
@Injectable()
export class HashtagChannelService {
export class HashtagChannelService implements MiChannelService<false> {
public readonly shouldShare = HashtagChannel.shouldShare;
public readonly requireCredential = HashtagChannel.requireCredential;
public readonly kind = HashtagChannel.kind;
constructor(
private noteEntityService: NoteEntityService,

View File

@@ -10,12 +10,13 @@ import { isInstanceMuted } from '@/misc/is-instance-muted.js';
import type { Packed } from '@/misc/json-schema.js';
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
import { bindThis } from '@/decorators.js';
import Channel from '../channel.js';
import Channel, { type MiChannelService } from '../channel.js';
class HomeTimelineChannel extends Channel {
public readonly chName = 'homeTimeline';
public static shouldShare = false;
public static requireCredential = true;
public static requireCredential = true as const;
public static kind = 'read:account';
private withRenotes: boolean;
private withFiles: boolean;
@@ -99,9 +100,10 @@ class HomeTimelineChannel extends Channel {
}
@Injectable()
export class HomeTimelineChannelService {
export class HomeTimelineChannelService implements MiChannelService<true> {
public readonly shouldShare = HomeTimelineChannel.shouldShare;
public readonly requireCredential = HomeTimelineChannel.requireCredential;
public readonly kind = HomeTimelineChannel.kind;
constructor(
private noteEntityService: NoteEntityService,

View File

@@ -12,12 +12,13 @@ import { MetaService } from '@/core/MetaService.js';
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
import { bindThis } from '@/decorators.js';
import { RoleService } from '@/core/RoleService.js';
import Channel from '../channel.js';
import Channel, { type MiChannelService } from '../channel.js';
class HybridTimelineChannel extends Channel {
public readonly chName = 'hybridTimeline';
public static shouldShare = false;
public static requireCredential = true;
public static requireCredential = true as const;
public static kind = 'read:account';
private withRenotes: boolean;
private withReplies: boolean;
private withFiles: boolean;
@@ -114,9 +115,10 @@ class HybridTimelineChannel extends Channel {
}
@Injectable()
export class HybridTimelineChannelService {
export class HybridTimelineChannelService implements MiChannelService<true> {
public readonly shouldShare = HybridTimelineChannel.shouldShare;
public readonly requireCredential = HybridTimelineChannel.requireCredential;
public readonly kind = HybridTimelineChannel.kind;
constructor(
private metaService: MetaService,

View File

@@ -11,12 +11,12 @@ import { MetaService } from '@/core/MetaService.js';
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
import { bindThis } from '@/decorators.js';
import { RoleService } from '@/core/RoleService.js';
import Channel from '../channel.js';
import Channel, { type MiChannelService } from '../channel.js';
class LocalTimelineChannel extends Channel {
public readonly chName = 'localTimeline';
public static shouldShare = false;
public static requireCredential = false;
public static requireCredential = false as const;
private withRenotes: boolean;
private withReplies: boolean;
private withFiles: boolean;
@@ -90,9 +90,10 @@ class LocalTimelineChannel extends Channel {
}
@Injectable()
export class LocalTimelineChannelService {
export class LocalTimelineChannelService implements MiChannelService<false> {
public readonly shouldShare = LocalTimelineChannel.shouldShare;
public readonly requireCredential = LocalTimelineChannel.requireCredential;
public readonly kind = LocalTimelineChannel.kind;
constructor(
private metaService: MetaService,

View File

@@ -7,12 +7,13 @@ import { Injectable } from '@nestjs/common';
import { isInstanceMuted, isUserFromMutedInstance } from '@/misc/is-instance-muted.js';
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
import { bindThis } from '@/decorators.js';
import Channel from '../channel.js';
import Channel, { type MiChannelService } from '../channel.js';
class MainChannel extends Channel {
public readonly chName = 'main';
public static shouldShare = true;
public static requireCredential = true;
public static requireCredential = true as const;
public static kind = 'read:account';
constructor(
private noteEntityService: NoteEntityService,
@@ -63,9 +64,10 @@ class MainChannel extends Channel {
}
@Injectable()
export class MainChannelService {
export class MainChannelService implements MiChannelService<true> {
public readonly shouldShare = MainChannel.shouldShare;
public readonly requireCredential = MainChannel.requireCredential;
public readonly kind = MainChannel.kind;
constructor(
private noteEntityService: NoteEntityService,

View File

@@ -6,14 +6,14 @@
import Xev from 'xev';
import { Injectable } from '@nestjs/common';
import { bindThis } from '@/decorators.js';
import Channel from '../channel.js';
import Channel, { type MiChannelService } from '../channel.js';
const ev = new Xev();
class QueueStatsChannel extends Channel {
public readonly chName = 'queueStats';
public static shouldShare = true;
public static requireCredential = false;
public static requireCredential = false as const;
constructor(id: string, connection: Channel['connection']) {
super(id, connection);
@@ -53,9 +53,10 @@ class QueueStatsChannel extends Channel {
}
@Injectable()
export class QueueStatsChannelService {
export class QueueStatsChannelService implements MiChannelService<false> {
public readonly shouldShare = QueueStatsChannel.shouldShare;
public readonly requireCredential = QueueStatsChannel.requireCredential;
public readonly kind = QueueStatsChannel.kind;
constructor(
) {

View File

@@ -10,12 +10,12 @@ import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
import { bindThis } from '@/decorators.js';
import { RoleService } from '@/core/RoleService.js';
import type { GlobalEvents } from '@/core/GlobalEventService.js';
import Channel from '../channel.js';
import Channel, { type MiChannelService } from '../channel.js';
class RoleTimelineChannel extends Channel {
public readonly chName = 'roleTimeline';
public static shouldShare = false;
public static requireCredential = false;
public static requireCredential = false as const;
private roleId: string;
constructor(
@@ -67,9 +67,10 @@ class RoleTimelineChannel extends Channel {
}
@Injectable()
export class RoleTimelineChannelService {
export class RoleTimelineChannelService implements MiChannelService<false> {
public readonly shouldShare = RoleTimelineChannel.shouldShare;
public readonly requireCredential = RoleTimelineChannel.requireCredential;
public readonly kind = RoleTimelineChannel.kind;
constructor(
private noteEntityService: NoteEntityService,

View File

@@ -6,14 +6,14 @@
import Xev from 'xev';
import { Injectable } from '@nestjs/common';
import { bindThis } from '@/decorators.js';
import Channel from '../channel.js';
import Channel, { type MiChannelService } from '../channel.js';
const ev = new Xev();
class ServerStatsChannel extends Channel {
public readonly chName = 'serverStats';
public static shouldShare = true;
public static requireCredential = false;
public static requireCredential = false as const;
constructor(id: string, connection: Channel['connection']) {
super(id, connection);
@@ -53,9 +53,10 @@ class ServerStatsChannel extends Channel {
}
@Injectable()
export class ServerStatsChannelService {
export class ServerStatsChannelService implements MiChannelService<false> {
public readonly shouldShare = ServerStatsChannel.shouldShare;
public readonly requireCredential = ServerStatsChannel.requireCredential;
public readonly kind = ServerStatsChannel.kind;
constructor(
) {

View File

@@ -11,12 +11,12 @@ import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
import { DI } from '@/di-symbols.js';
import { bindThis } from '@/decorators.js';
import { isInstanceMuted } from '@/misc/is-instance-muted.js';
import Channel from '../channel.js';
import Channel, { type MiChannelService } from '../channel.js';
class UserListChannel extends Channel {
public readonly chName = 'userList';
public static shouldShare = false;
public static requireCredential = false;
public static requireCredential = false as const;
private listId: string;
private membershipsMap: Record<string, Pick<MiUserListMembership, 'withReplies'> | undefined> = {};
private listUsersClock: NodeJS.Timeout;
@@ -137,9 +137,10 @@ class UserListChannel extends Channel {
}
@Injectable()
export class UserListChannelService {
export class UserListChannelService implements MiChannelService<false> {
public readonly shouldShare = UserListChannel.shouldShare;
public readonly requireCredential = UserListChannel.requireCredential;
public readonly kind = UserListChannel.kind;
constructor(
@Inject(DI.userListsRepository)