Merge branch 'develop' into feat-12997
This commit is contained in:
commit
f84d9fdcc8
50 changed files with 1793 additions and 395 deletions
|
|
@ -170,7 +170,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
|
||||
const instances = await query.limit(ps.limit).offset(ps.offset).getMany();
|
||||
|
||||
return await this.instanceEntityService.packMany(instances);
|
||||
return await this.instanceEntityService.packMany(instances, me);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -107,9 +107,9 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
const gotPubCount = topPubInstances.map(x => x.followingCount).reduce((a, b) => a + b, 0);
|
||||
|
||||
return await awaitAll({
|
||||
topSubInstances: this.instanceEntityService.packMany(topSubInstances),
|
||||
topSubInstances: this.instanceEntityService.packMany(topSubInstances, me),
|
||||
otherFollowersCount: Math.max(0, allSubCount - gotSubCount),
|
||||
topPubInstances: this.instanceEntityService.packMany(topPubInstances),
|
||||
topPubInstances: this.instanceEntityService.packMany(topPubInstances, me),
|
||||
otherFollowingCount: Math.max(0, allPubCount - gotPubCount),
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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,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
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 = {
|
||||
|
|
@ -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
|
||||
|
|
@ -102,23 +104,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,8 @@ import { CacheService } from '@/core/CacheService.js';
|
|||
import { MiFollowing, MiUserProfile } from '@/models/_.js';
|
||||
import type { StreamEventEmitter, GlobalEvents } from '@/core/GlobalEventService.js';
|
||||
import { ChannelFollowingService } from '@/core/ChannelFollowingService.js';
|
||||
import type { JsonObject } from '@/misc/json-value.js';
|
||||
import { isJsonObject } from '@/misc/json-value.js';
|
||||
import type { JsonObject, JsonValue } from '@/misc/json-value.js';
|
||||
import type { ChannelsService } from './ChannelsService.js';
|
||||
import type { EventEmitter } from 'events';
|
||||
import type Channel from './channel.js';
|
||||
|
|
@ -112,8 +113,6 @@ export default class Connection {
|
|||
|
||||
const { type, body } = obj;
|
||||
|
||||
if (typeof body !== 'object' || body === null || Array.isArray(body)) return;
|
||||
|
||||
switch (type) {
|
||||
case 'readNotification': this.onReadNotification(body); break;
|
||||
case 'subNote': this.onSubscribeNote(body); break;
|
||||
|
|
@ -154,7 +153,8 @@ export default class Connection {
|
|||
}
|
||||
|
||||
@bindThis
|
||||
private readNote(body: JsonObject) {
|
||||
private readNote(body: JsonValue | undefined) {
|
||||
if (!isJsonObject(body)) return;
|
||||
const id = body.id;
|
||||
|
||||
const note = this.cachedNotes.find(n => n.id === id);
|
||||
|
|
@ -166,7 +166,7 @@ export default class Connection {
|
|||
}
|
||||
|
||||
@bindThis
|
||||
private onReadNotification(payload: JsonObject) {
|
||||
private onReadNotification(payload: JsonValue | undefined) {
|
||||
this.notificationService.readAllNotification(this.user!.id);
|
||||
}
|
||||
|
||||
|
|
@ -174,7 +174,8 @@ export default class Connection {
|
|||
* 投稿購読要求時
|
||||
*/
|
||||
@bindThis
|
||||
private onSubscribeNote(payload: JsonObject) {
|
||||
private onSubscribeNote(payload: JsonValue | undefined) {
|
||||
if (!isJsonObject(payload)) return;
|
||||
if (!payload.id || typeof payload.id !== 'string') return;
|
||||
|
||||
const current = this.subscribingNotes[payload.id] ?? 0;
|
||||
|
|
@ -190,7 +191,8 @@ export default class Connection {
|
|||
* 投稿購読解除要求時
|
||||
*/
|
||||
@bindThis
|
||||
private onUnsubscribeNote(payload: JsonObject) {
|
||||
private onUnsubscribeNote(payload: JsonValue | undefined) {
|
||||
if (!isJsonObject(payload)) return;
|
||||
if (!payload.id || typeof payload.id !== 'string') return;
|
||||
|
||||
const current = this.subscribingNotes[payload.id];
|
||||
|
|
@ -216,12 +218,13 @@ export default class Connection {
|
|||
* チャンネル接続要求時
|
||||
*/
|
||||
@bindThis
|
||||
private onChannelConnectRequested(payload: JsonObject) {
|
||||
private onChannelConnectRequested(payload: JsonValue | undefined) {
|
||||
if (!isJsonObject(payload)) return;
|
||||
const { channel, id, params, pong } = payload;
|
||||
if (typeof id !== 'string') return;
|
||||
if (typeof channel !== 'string') return;
|
||||
if (typeof pong !== 'boolean' && typeof pong !== 'undefined' && pong !== null) return;
|
||||
if (typeof params !== 'undefined' && (typeof params !== 'object' || params === null || Array.isArray(params))) return;
|
||||
if (typeof params !== 'undefined' && !isJsonObject(params)) return;
|
||||
this.connectChannel(id, params, channel, pong ?? undefined);
|
||||
}
|
||||
|
||||
|
|
@ -229,7 +232,8 @@ export default class Connection {
|
|||
* チャンネル切断要求時
|
||||
*/
|
||||
@bindThis
|
||||
private onChannelDisconnectRequested(payload: JsonObject) {
|
||||
private onChannelDisconnectRequested(payload: JsonValue | undefined) {
|
||||
if (!isJsonObject(payload)) return;
|
||||
const { id } = payload;
|
||||
if (typeof id !== 'string') return;
|
||||
this.disconnectChannel(id);
|
||||
|
|
@ -297,7 +301,8 @@ export default class Connection {
|
|||
* @param data メッセージ
|
||||
*/
|
||||
@bindThis
|
||||
private onChannelMessageRequested(data: JsonObject) {
|
||||
private onChannelMessageRequested(data: JsonValue | undefined) {
|
||||
if (!isJsonObject(data)) return;
|
||||
if (typeof data.id !== 'string') return;
|
||||
if (typeof data.type !== 'string') return;
|
||||
if (typeof data.body === 'undefined') return;
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
import Xev from 'xev';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { isJsonObject } from '@/misc/json-value.js';
|
||||
import type { JsonObject, JsonValue } from '@/misc/json-value.js';
|
||||
import Channel, { type MiChannelService } from '../channel.js';
|
||||
|
||||
|
|
@ -36,7 +37,7 @@ class QueueStatsChannel extends Channel {
|
|||
public onMessage(type: string, body: JsonValue) {
|
||||
switch (type) {
|
||||
case 'requestLog':
|
||||
if (typeof body !== 'object' || body === null || Array.isArray(body)) return;
|
||||
if (!isJsonObject(body)) return;
|
||||
if (typeof body.id !== 'string') return;
|
||||
if (typeof body.length !== 'number') return;
|
||||
ev.once(`queueStatsLog:${body.id}`, statsLog => {
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import { DI } from '@/di-symbols.js';
|
|||
import { bindThis } from '@/decorators.js';
|
||||
import { ReversiService } from '@/core/ReversiService.js';
|
||||
import { ReversiGameEntityService } from '@/core/entities/ReversiGameEntityService.js';
|
||||
import { isJsonObject } from '@/misc/json-value.js';
|
||||
import type { JsonObject, JsonValue } from '@/misc/json-value.js';
|
||||
import Channel, { type MiChannelService } from '../channel.js';
|
||||
|
||||
|
|
@ -44,16 +45,16 @@ class ReversiGameChannel extends Channel {
|
|||
this.ready(body);
|
||||
break;
|
||||
case 'updateSettings':
|
||||
if (typeof body !== 'object' || body === null || Array.isArray(body)) return;
|
||||
if (!isJsonObject(body)) return;
|
||||
if (typeof body.key !== 'string') return;
|
||||
if (typeof body.value !== 'object' || body.value === null || Array.isArray(body.value)) return;
|
||||
if (!isJsonObject(body.value)) return;
|
||||
this.updateSettings(body.key, body.value);
|
||||
break;
|
||||
case 'cancel':
|
||||
this.cancelGame();
|
||||
break;
|
||||
case 'putStone':
|
||||
if (typeof body !== 'object' || body === null || Array.isArray(body)) return;
|
||||
if (!isJsonObject(body)) return;
|
||||
if (typeof body.pos !== 'number') return;
|
||||
if (typeof body.id !== 'string') return;
|
||||
this.putStone(body.pos, body.id);
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
import Xev from 'xev';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { isJsonObject } from '@/misc/json-value.js';
|
||||
import type { JsonObject, JsonValue } from '@/misc/json-value.js';
|
||||
import Channel, { type MiChannelService } from '../channel.js';
|
||||
|
||||
|
|
@ -36,7 +37,7 @@ class ServerStatsChannel extends Channel {
|
|||
public onMessage(type: string, body: JsonValue) {
|
||||
switch (type) {
|
||||
case 'requestLog':
|
||||
if (typeof body !== 'object' || body === null || Array.isArray(body)) return;
|
||||
if (!isJsonObject(body)) return;
|
||||
ev.once(`serverStatsLog:${body.id}`, statsLog => {
|
||||
this.send('statsLog', statsLog);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ html
|
|||
meta(property='og:site_name' content= instanceName || 'Misskey')
|
||||
meta(property='instance_url' content= instanceUrl)
|
||||
meta(name='viewport' content='width=device-width, initial-scale=1')
|
||||
meta(name='format-detection' content='telephone=no,date=no,address=no,email=no,url=no')
|
||||
link(rel='icon' href= icon || '/favicon.ico')
|
||||
link(rel='apple-touch-icon' href= appleTouchIcon || '/apple-touch-icon.png')
|
||||
link(rel='manifest' href='/manifest.json')
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue