Skip to content

Commit

Permalink
Merge branch 'feat/show-remote-user-required-login' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
4ster1sk committed Dec 30, 2024
2 parents 2f14920 + 88ed2e7 commit 3827cb0
Show file tree
Hide file tree
Showing 18 changed files with 278 additions and 6 deletions.
4 changes: 4 additions & 0 deletions locales/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10644,6 +10644,10 @@ export interface Locale extends ILocale {
* Signupの無効化
*/
"disableSignup": string;
/**
* リモートユーザーの表示はログインを必須にする
*/
"requireSigninToViewRemoteUsers": string;
};
"_remoteLookupErrors": {
"_federationNotAllowed": {
Expand Down
1 change: 1 addition & 0 deletions locales/ja-JP.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2839,6 +2839,7 @@ _followRequest:
_customizeFeature:
title: "独自機能"
disableSignup: "Signupの無効化"
requireSigninToViewRemoteUsers: "リモートユーザーの表示はログインを必須にする"

_remoteLookupErrors:
_federationNotAllowed:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* SPDX-FileCopyrightText: 4sterisk
* SPDX-License-Identifier: AGPL-3.0-only
*/
export class RequireSigninToViewRemoteUsers1735564157872 {
name = 'RequireSigninToViewRemoteUsers1735564157872'

async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "meta" ADD "requireSigninToViewRemoteUsers" boolean NOT NULL DEFAULT false`);
}

async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "requireSigninToViewRemoteUsers"`);
}
}
61 changes: 61 additions & 0 deletions packages/backend/src/core/chart/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -727,4 +727,65 @@ export default abstract class Chart<T extends Schema> {
}
return object as Unflatten<ChartResult<T>>;
}

@bindThis
public async getEmptyRaw(span: 'hour' | 'day', amount: number, cursor: Date | null, group: string | null = null): Promise<ChartResult<T>> {
const [y, m, d, h, _m, _s, _ms] = cursor ? Chart.parseDate(subtractTime(addTime(cursor, 1, span), 1)) : Chart.getCurrentDate();
const repository =
span === 'hour' ? this.repositoryForHour :
span === 'day' ? this.repositoryForDay :
new Error('not happen') as never;

// ログ取得
const logs = [] as RawRecord<T>[];
const chart: KVs<T>[] = [];

for (let i = (amount - 1); i >= 0; i--) {
const current =
span === 'hour' ? subtractTime(dateUTC([y, m, d, h]), i, 'hour') :
span === 'day' ? subtractTime(dateUTC([y, m, d]), i, 'day') :
new Error('not happen') as never;

const log = logs.find(l => isTimeSame(new Date(l.date * 1000), current));

if (log) {
chart.unshift(this.convertRawRecord(log));
} else {
// 補間
const latest = logs.find(l => isTimeBefore(new Date(l.date * 1000), current));
const data = latest ? this.convertRawRecord(latest) : null;
chart.unshift(this.getNewLog(data));
}
}

const res = {} as ChartResult<T>;

/**
* [{ foo: 1, bar: 5 }, { foo: 2, bar: 6 }, { foo: 3, bar: 7 }]
* を
* { foo: [1, 2, 3], bar: [5, 6, 7] }
* にする
*/
for (const record of chart) {
for (const [k] of Object.entries(record) as ([keyof typeof record, number])[]) {
if (res[k]) {
res[k].push(0);
} else {
res[k] = [0];
}
}
}

return res;
}

@bindThis
public async getEmpty(span: 'hour' | 'day', amount: number): Promise<Unflatten<ChartResult<T>>> {
const result = await this.getEmptyRaw(span, amount, null, null);
const object = {};
for (const [k, v] of Object.entries(result)) {
nestedProperty.set(object, k, v);
}
return object as Unflatten<ChartResult<T>>;
}
}
1 change: 1 addition & 0 deletions packages/backend/src/core/entities/MetaEntityService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ export class MetaEntityService {
swPublickey: instance.swPublicKey,
themeColor: instance.themeColor,
disableSignup: instance.disableSignup,
requireSigninToViewRemoteUsers: instance.requireSigninToViewRemoteUsers,
mascotImageUrl: instance.mascotImageUrl ?? '/assets/ai.png',
bannerUrl: instance.bannerUrl,
infoImageUrl: instance.infoImageUrl,
Expand Down
5 changes: 5 additions & 0 deletions packages/backend/src/models/Meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -668,4 +668,9 @@ export class MiMeta {
default: false,
})
public disableSignup: boolean;

@Column('boolean', {
default: false,
})
public requireSigninToViewRemoteUsers: boolean;
}
4 changes: 4 additions & 0 deletions packages/backend/src/models/json-schema/meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ export const packedMetaLiteSchema = {
type: 'boolean',
optional: false, nullable: false,
},
requireSigninToViewRemoteUsers: {
type: 'boolean',
optional: false, nullable: false,
},
emailRequiredForSignup: {
type: 'boolean',
optional: false, nullable: false,
Expand Down
5 changes: 5 additions & 0 deletions packages/backend/src/server/api/endpoints/admin/meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ export const meta = {
type: 'boolean',
optional: false, nullable: false,
},
requireSigninToViewRemoteUsers: {
type: 'boolean',
optional: false, nullable: false,
},
cacheRemoteFiles: {
type: 'boolean',
optional: false, nullable: false,
Expand Down Expand Up @@ -572,6 +576,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
privacyPolicyUrl: instance.privacyPolicyUrl,
inquiryUrl: instance.inquiryUrl,
disableSignup: instance.disableSignup,
requireSigninToViewRemoteUsers: instance.requireSigninToViewRemoteUsers,
disableRegistration: instance.disableRegistration,
emailRequiredForSignup: instance.emailRequiredForSignup,
enableHcaptcha: instance.enableHcaptcha,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ export const paramDef = {
},
},
disableSignup: { type: 'boolean' },
requireSigninToViewRemoteUsers: { type: 'boolean' },
mismatchUriHosts: {
type: 'array',
items: {
Expand Down Expand Up @@ -318,6 +319,10 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
set.disableSignup = ps.disableSignup;
}

if (ps.requireSigninToViewRemoteUsers !== undefined) {
set.requireSigninToViewRemoteUsers = ps.requireSigninToViewRemoteUsers;
}

if (ps.cacheRemoteSensitiveFiles !== undefined) {
set.cacheRemoteSensitiveFiles = ps.cacheRemoteSensitiveFiles;
}
Expand Down
14 changes: 13 additions & 1 deletion packages/backend/src/server/api/endpoints/charts/user/drive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/

import { Injectable } from '@nestjs/common';
import { Inject, Injectable } from '@nestjs/common';
import { getJsonSchema } from '@/core/chart/core.js';
import { Endpoint } from '@/server/api/endpoint-base.js';
import PerUserDriveChart from '@/core/chart/charts/per-user-drive.js';
import { schema } from '@/core/chart/charts/entities/per-user-drive.js';
import { DI } from '@/di-symbols.js';
import { MiMeta } from '@/models/Meta.js';
import { CacheService } from '@/core/CacheService.js';

export const meta = {
tags: ['charts', 'drive', 'users'],
Expand All @@ -32,9 +35,18 @@ export const paramDef = {
@Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
constructor(
@Inject(DI.meta)
private serverSettings: MiMeta,
private cacheService: CacheService,
private perUserDriveChart: PerUserDriveChart,
) {
super(meta, paramDef, async (ps, me) => {
if (me == null && this.serverSettings.requireSigninToViewRemoteUsers) {
const user = await this.cacheService.findUserById(ps.userId);
if (user.host != null) {
return await this.perUserDriveChart.getEmpty(ps.span, ps.limit);
}
}
return await this.perUserDriveChart.getChart(ps.span, ps.limit, ps.offset ? new Date(ps.offset) : null, ps.userId);
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/

import { Injectable } from '@nestjs/common';
import { Inject, Injectable } from '@nestjs/common';
import { Endpoint } from '@/server/api/endpoint-base.js';
import { getJsonSchema } from '@/core/chart/core.js';
import PerUserFollowingChart from '@/core/chart/charts/per-user-following.js';
import { schema } from '@/core/chart/charts/entities/per-user-following.js';
import { CacheService } from '@/core/CacheService.js';
import { MiMeta } from '@/models/Meta.js';
import { DI } from '@/di-symbols.js';

export const meta = {
tags: ['charts', 'users', 'following'],
Expand All @@ -32,9 +35,19 @@ export const paramDef = {
@Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
constructor(
@Inject(DI.meta)
private serverSettings: MiMeta,
private cacheService: CacheService,
private perUserFollowingChart: PerUserFollowingChart,
) {
super(meta, paramDef, async (ps, me) => {
if (me == null && this.serverSettings.requireSigninToViewRemoteUsers) {
const user = await this.cacheService.findUserById(ps.userId);
if (user.host != null) {
return await this.perUserFollowingChart.getEmpty(ps.span, ps.limit);
}
}

return await this.perUserFollowingChart.getChart(ps.span, ps.limit, ps.offset ? new Date(ps.offset) : null, ps.userId);
});
}
Expand Down
15 changes: 14 additions & 1 deletion packages/backend/src/server/api/endpoints/charts/user/notes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/

import { Injectable } from '@nestjs/common';
import { Inject, Injectable } from '@nestjs/common';
import { getJsonSchema } from '@/core/chart/core.js';
import { Endpoint } from '@/server/api/endpoint-base.js';
import PerUserNotesChart from '@/core/chart/charts/per-user-notes.js';
import { schema } from '@/core/chart/charts/entities/per-user-notes.js';
import { CacheService } from '@/core/CacheService.js';
import { DI } from '@/di-symbols.js';
import { MiMeta } from '@/models/Meta.js';

export const meta = {
tags: ['charts', 'users', 'notes'],
Expand All @@ -32,9 +35,19 @@ export const paramDef = {
@Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
constructor(
@Inject(DI.meta)
private serverSettings: MiMeta,
private cacheService: CacheService,
private perUserNotesChart: PerUserNotesChart,
) {
super(meta, paramDef, async (ps, me) => {
if (me == null && this.serverSettings.requireSigninToViewRemoteUsers) {
const user = await this.cacheService.findUserById(ps.userId);
if (user.host != null) {
return await this.perUserNotesChart.getEmpty(ps.span, ps.limit);
}
}

return await this.perUserNotesChart.getChart(ps.span, ps.limit, ps.offset ? new Date(ps.offset) : null, ps.userId);
});
}
Expand Down
15 changes: 14 additions & 1 deletion packages/backend/src/server/api/endpoints/charts/user/pv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/

import { Injectable } from '@nestjs/common';
import { Inject, Injectable } from '@nestjs/common';
import { getJsonSchema } from '@/core/chart/core.js';
import { Endpoint } from '@/server/api/endpoint-base.js';
import PerUserPvChart from '@/core/chart/charts/per-user-pv.js';
import { schema } from '@/core/chart/charts/entities/per-user-pv.js';
import { CacheService } from '@/core/CacheService.js';
import { DI } from '@/di-symbols.js';
import { MiMeta } from '@/models/Meta.js';

export const meta = {
tags: ['charts', 'users'],
Expand All @@ -32,9 +35,19 @@ export const paramDef = {
@Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
constructor(
@Inject(DI.meta)
private serverSettings: MiMeta,
private cacheService: CacheService,
private perUserPvChart: PerUserPvChart,
) {
super(meta, paramDef, async (ps, me) => {
if (me == null && this.serverSettings.requireSigninToViewRemoteUsers) {
const user = await this.cacheService.findUserById(ps.userId);
if (user.host != null) {
return await this.perUserPvChart.getEmpty(ps.span, ps.limit);
}
}

return await this.perUserPvChart.getChart(ps.span, ps.limit, ps.offset ? new Date(ps.offset) : null, ps.userId);
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/

import { Injectable } from '@nestjs/common';
import { Inject, Injectable } from '@nestjs/common';
import { getJsonSchema } from '@/core/chart/core.js';
import { Endpoint } from '@/server/api/endpoint-base.js';
import PerUserReactionsChart from '@/core/chart/charts/per-user-reactions.js';
import { schema } from '@/core/chart/charts/entities/per-user-reactions.js';
import { DI } from '@/di-symbols.js';
import { MiMeta } from '@/models/Meta.js';
import { CacheService } from '@/core/CacheService.js';

export const meta = {
tags: ['charts', 'users', 'reactions'],
Expand All @@ -32,9 +35,18 @@ export const paramDef = {
@Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
constructor(
@Inject(DI.meta)
private serverSettings: MiMeta,
private cacheService: CacheService,
private perUserReactionsChart: PerUserReactionsChart,
) {
super(meta, paramDef, async (ps, me) => {
if (me == null && this.serverSettings.requireSigninToViewRemoteUsers) {
const user = await this.cacheService.findUserById(ps.userId);
if (user.host != null) {
return await this.perUserReactionsChart.getEmpty(ps.span, ps.limit);
}
}
return await this.perUserReactionsChart.getChart(ps.span, ps.limit, ps.offset ? new Date(ps.offset) : null, ps.userId);
});
}
Expand Down
7 changes: 7 additions & 0 deletions packages/backend/src/server/api/endpoints/users/notes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,13 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
}
}

if (me == null && this.serverSettings.requireSigninToViewRemoteUsers) {
const user = await this.cacheService.findUserById(ps.userId);
if (user.host != null) {
return [];
}
}

if (!this.serverSettings.enableFanoutTimeline) {
const timeline = await this.getFromDb({
untilId,
Expand Down
5 changes: 5 additions & 0 deletions packages/frontend/src/pages/admin/settings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,9 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkSwitch v-model="customFeatureForm.state.disableSignup">
<template #label>{{ i18n.ts._customizeFeature.disableSignup }}<span v-if="customFeatureForm.modifiedStates.disableSignup" class="_modified">{{ i18n.ts.modified }}</span></template>
</MkSwitch>
<MkSwitch v-model="customFeatureForm.state.requireSigninToViewRemoteUsers">
<template #label>{{ i18n.ts._customizeFeature.requireSigninToViewRemoteUsers }}<span v-if="customFeatureForm.modifiedStates.requireSigninToViewRemoteUsers" class="_modified">{{ i18n.ts.modified }}</span></template>
</MkSwitch>
</div>
</MkFolder>
</div>
Expand Down Expand Up @@ -345,9 +348,11 @@ const filesForm = useForm({

const customFeatureForm = useForm({
disableSignup: meta.disableSignup,
requireSigninToViewRemoteUsers: meta.requireSigninToViewRemoteUsers,
}, async (state) => {
await os.apiWithDialog('admin/update-meta', {
disableSignup: state.disableSignup,
requireSigninToViewRemoteUsers: state.requireSigninToViewRemoteUsers,
});
fetchInstance(true);
});
Expand Down
2 changes: 2 additions & 0 deletions packages/misskey-js/src/autogen/entities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,8 @@ export type UsersSearchRequest = operations['users___search']['requestBody']['co
export type UsersSearchResponse = operations['users___search']['responses']['200']['content']['application/json'];
export type UsersShowRequest = operations['users___show']['requestBody']['content']['application/json'];
export type UsersShowResponse = operations['users___show']['responses']['200']['content']['application/json'];
export type UsersStatsRequest = operations['users___stats']['requestBody']['content']['application/json'];
export type UsersStatsResponse = operations['users___stats']['responses']['200']['content']['application/json'];
export type UsersAchievementsRequest = operations['users___achievements']['requestBody']['content']['application/json'];
export type UsersAchievementsResponse = operations['users___achievements']['responses']['200']['content']['application/json'];
export type UsersUpdateMemoRequest = operations['users___update-memo']['requestBody']['content']['application/json'];
Expand Down
Loading

0 comments on commit 3827cb0

Please sign in to comment.