feat: Requiring credential to view local timeline
Some checks failed
/ test-build (push) Has been cancelled
Some checks failed
/ test-build (push) Has been cancelled
This commit is contained in:
parent
486e4279af
commit
708a8d28a6
20 changed files with 69 additions and 5 deletions
|
|
@ -2181,3 +2181,4 @@ _wellness:
|
|||
newPostsButton: "Enable new posts alert button"
|
||||
newPostsGlowOpacity: "New posts glow opacity"
|
||||
immediacy: "Immediacy"
|
||||
localTimelineRequiresCredential: Disable local timeline for non-logged in users
|
||||
|
|
@ -1972,3 +1972,4 @@ _cwStyle:
|
|||
alternative: 代替(Firefish-like)
|
||||
cwStyle: 閲覧注意投稿の表示スタイル
|
||||
searchNotLoggedIn_2: しかし、ハッシュタグ検索とユーザー検索は利用できます。
|
||||
localTimelineRequiresCredential: 非ログインユーザーにローカルタイムラインを非公開
|
||||
|
|
@ -1899,3 +1899,4 @@ removeMember: 멤버 삭제하기
|
|||
searchEmptyQuery: 검색할 내용을 입력해주세요.
|
||||
searchNotLoggedIn_1: 전체 텍스트 검색을 하려면 먼저 로그인해야 합니다.
|
||||
searchNotLoggedIn_2: 대신, 해시태그나 유저를 검색할 수 있습니다.
|
||||
localTimelineRequiresCredential: 비로그인 상태의 로컬 타임라인 열람 제한
|
||||
|
|
@ -1887,3 +1887,4 @@ removeMember: 멤버 삭제하기
|
|||
searchEmptyQuery: 검색할 내용을 입력해달라냥.
|
||||
searchNotLoggedIn_1: 전체 텍스트 검색을 하려면 먼저 로그인해야 한다냥.
|
||||
searchNotLoggedIn_2: 대신, 해시태그나 유저를 검색할 수 있다냥.
|
||||
localTimelineRequiresCredential: 비로그인 상태의 로컬 타임라인 열람 제한
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||
|
||||
export class AddLocalTimelineRequiresCredential1735271639334 implements MigrationInterface {
|
||||
name = 'AddLocalTimelineRequiresCredential1735271639334'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER TABLE "meta" ADD "localTimelineRequiresCredential" boolean;`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "localTimelineRequiresCredential"`);
|
||||
}
|
||||
}
|
||||
|
|
@ -45,6 +45,11 @@ export class Meta {
|
|||
default: false,
|
||||
})
|
||||
public disableRegistration: boolean;
|
||||
|
||||
@Column("boolean", {
|
||||
default: false,
|
||||
})
|
||||
public localTimelineRequiresCredential: boolean;
|
||||
|
||||
@Column("boolean", {
|
||||
default: false,
|
||||
|
|
|
|||
|
|
@ -425,6 +425,7 @@ export default define(meta, paramDef, async (ps, me) => {
|
|||
repositoryUrl: instance.repositoryUrl,
|
||||
feedbackUrl: instance.feedbackUrl,
|
||||
disableRegistration: instance.disableRegistration,
|
||||
localTimelineRequiresCredential: instance.localTimelineRequiresCredential,
|
||||
disableLocalTimeline: instance.disableLocalTimeline,
|
||||
disableRecommendedTimeline: instance.disableRecommendedTimeline,
|
||||
disableGlobalTimeline: instance.disableGlobalTimeline,
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ export const paramDef = {
|
|||
type: "object",
|
||||
properties: {
|
||||
disableRegistration: { type: "boolean", nullable: true },
|
||||
localTimelineRequiresCredential: { type: "boolean", nullable: true },
|
||||
disableLocalTimeline: { type: "boolean", nullable: true },
|
||||
disableRecommendedTimeline: { type: "boolean", nullable: true },
|
||||
disableGlobalTimeline: { type: "boolean", nullable: true },
|
||||
|
|
@ -178,6 +179,10 @@ export default define(meta, paramDef, async (ps, me) => {
|
|||
set.disableRegistration = ps.disableRegistration;
|
||||
}
|
||||
|
||||
if (typeof ps.localTimelineRequiresCredential === "boolean") {
|
||||
set.localTimelineRequiresCredential = ps.localTimelineRequiresCredential;
|
||||
}
|
||||
|
||||
if (typeof ps.disableLocalTimeline === "boolean") {
|
||||
set.disableLocalTimeline = ps.disableLocalTimeline;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,6 +98,11 @@ export const meta = {
|
|||
optional: false,
|
||||
nullable: false,
|
||||
},
|
||||
localTimelineRequiresCredential: {
|
||||
type: "boolean",
|
||||
optional: false,
|
||||
nullable: false,
|
||||
},
|
||||
disableLocalTimeline: {
|
||||
type: "boolean",
|
||||
optional: false,
|
||||
|
|
@ -409,6 +414,7 @@ export default define(meta, paramDef, async (ps, me) => {
|
|||
privateMode: instance.privateMode,
|
||||
|
||||
disableRegistration: instance.disableRegistration,
|
||||
localTimelineRequiresCredential: instance.localTimelineRequiresCredential,
|
||||
disableLocalTimeline: instance.disableLocalTimeline,
|
||||
disableRecommendedTimeline: instance.disableRecommendedTimeline,
|
||||
disableGlobalTimeline: instance.disableGlobalTimeline,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
import { fetchMeta } from "@/misc/fetch-meta.js";
|
||||
import { Notes } from "@/models/index.js";
|
||||
import define from "../../define.js";
|
||||
import { ApiError } from "../../error.js";
|
||||
import { generateMutedUserQuery } from "../../common/generate-muted-user-query.js";
|
||||
import { generateBlockedUserQuery } from "../../common/generate-block-query.js";
|
||||
|
||||
|
|
@ -20,6 +22,14 @@ export const meta = {
|
|||
ref: "Note",
|
||||
},
|
||||
},
|
||||
|
||||
errors: {
|
||||
ltlDisabled: {
|
||||
message: "Local timeline has been disabled.",
|
||||
code: "LTL_DISABLED",
|
||||
id: "45a6eb02-7695-4393-b023-dd3be9aaaefd",
|
||||
},
|
||||
}
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
|
@ -38,6 +48,13 @@ export const paramDef = {
|
|||
} as const;
|
||||
|
||||
export default define(meta, paramDef, async (ps, user) => {
|
||||
const m = await fetchMeta();
|
||||
if (m.disableLocalTimeline || m.localTimelineRequiresCredential) {
|
||||
if (user == null || !(user.isAdmin || user.isModerator)) {
|
||||
throw new ApiError(meta.errors.ltlDisabled);
|
||||
}
|
||||
}
|
||||
|
||||
const max = 30;
|
||||
const day = 1000 * 60 * 60 * 24 * ps.days;
|
||||
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ export const paramDef = {
|
|||
|
||||
export default define(meta, paramDef, async (ps, user) => {
|
||||
const m = await fetchMeta();
|
||||
if (m.disableLocalTimeline) {
|
||||
if (m.disableLocalTimeline || m.localTimelineRequiresCredential) {
|
||||
if (user == null || !(user.isAdmin || user.isModerator)) {
|
||||
throw new ApiError(meta.errors.ltlDisabled);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ export default class extends Channel {
|
|||
|
||||
public async init(params: any) {
|
||||
const meta = await fetchMeta();
|
||||
if (meta.disableLocalTimeline) {
|
||||
if (meta.disableLocalTimeline || meta.localTimelineRequiresCredential && this.user == null) {
|
||||
if (this.user == null || !(this.user.isAdmin || this.user.isModerator))
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ const nodeinfo2 = async () => {
|
|||
repositoryUrl: meta.repositoryUrl,
|
||||
feedbackUrl: meta.feedbackUrl,
|
||||
disableRegistration: meta.disableRegistration,
|
||||
localTimelineRequiresCredential: meta.localTimelineRequiresCredential,
|
||||
disableLocalTimeline: meta.disableLocalTimeline,
|
||||
disableRecommendedTimeline: meta.disableRecommendedTimeline,
|
||||
disableGlobalTimeline: meta.disableGlobalTimeline,
|
||||
|
|
|
|||
|
|
@ -221,7 +221,7 @@ import { $i } from "@/account";
|
|||
import { instance } from "@/instance";
|
||||
|
||||
const isLocalTimelineAvailable =
|
||||
!instance.disableLocalTimeline ||
|
||||
(!instance.disableLocalTimeline && (!instance.localTimelineRequiresCredential || $i != null)) ||
|
||||
($i != null && ($i.isModerator || $i.isAdmin));
|
||||
const isRecommendedTimelineAvailable =
|
||||
!instance.disableRecommendedTimeline ||
|
||||
|
|
|
|||
|
|
@ -123,6 +123,12 @@
|
|||
class="_formBlock"
|
||||
>{{ i18n.ts.enableLocalTimeline }}</FormSwitch
|
||||
>
|
||||
<FormSwitch
|
||||
v-if="enableLocalTimeline"
|
||||
v-model="localTimelineRequiresCredential"
|
||||
class="_formBlock"
|
||||
>{{ i18n.ts.localTimelineRequiresCredential }}</FormSwitch
|
||||
>
|
||||
<FormSwitch
|
||||
v-model="enableGlobalTimeline"
|
||||
class="_formBlock"
|
||||
|
|
@ -433,6 +439,7 @@ let backgroundImageUrl: string | null = $ref(null);
|
|||
let themeColor: any = $ref(null);
|
||||
let defaultLightTheme: any = $ref(null);
|
||||
let defaultDarkTheme: any = $ref(null);
|
||||
let localTimelineRequiresCredential: boolean = $ref(false);
|
||||
let enableLocalTimeline: boolean = $ref(false);
|
||||
let enableGlobalTimeline: boolean = $ref(false);
|
||||
let enableRecommendedTimeline: boolean = $ref(false);
|
||||
|
|
@ -471,6 +478,7 @@ async function init() {
|
|||
maintainerName = meta.maintainerName;
|
||||
maintainerEmail = meta.maintainerEmail;
|
||||
donationLink = meta.donationLink;
|
||||
localTimelineRequiresCredential = meta.localTimelineRequiresCredential;
|
||||
enableLocalTimeline = !meta.disableLocalTimeline;
|
||||
enableGlobalTimeline = !meta.disableGlobalTimeline;
|
||||
enableRecommendedTimeline = !meta.disableRecommendedTimeline;
|
||||
|
|
@ -516,6 +524,7 @@ function save() {
|
|||
maintainerName,
|
||||
maintainerEmail,
|
||||
donationLink,
|
||||
localTimelineRequiresCredential: localTimelineRequiresCredential,
|
||||
disableLocalTimeline: !enableLocalTimeline,
|
||||
disableGlobalTimeline: !enableGlobalTimeline,
|
||||
disableRecommendedTimeline: !enableRecommendedTimeline,
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ if (defaultStore.reactiveState.tutorial.value !== -1) {
|
|||
}
|
||||
|
||||
const isLocalTimelineAvailable =
|
||||
!instance.disableLocalTimeline ||
|
||||
(!instance.disableLocalTimeline && (!instance.localTimelineRequiresCredential || $i != null)) ||
|
||||
($i != null && ($i.isModerator || $i.isAdmin));
|
||||
const isRecommendedTimelineAvailable = !instance.disableRecommendedTimeline;
|
||||
const isGlobalTimelineAvailable =
|
||||
|
|
|
|||
|
|
@ -7687,7 +7687,7 @@
|
|||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "{\n maintainerName: string | null;\n maintainerEmail: string | null;\n version: string;\n name: string | null;\n uri: string;\n description: string | null;\n tosUrl: string | null;\n disableRegistration: boolean;\n disableLocalTimeline: boolean;\n disableRecommendedTimeline: boolean;\n disableGlobalTimeline: boolean;\n driveCapacityPerLocalUserMb: number;\n driveCapacityPerRemoteUserMb: number;\n enableHcaptcha: boolean;\n hcaptchaSiteKey: string | null;\n enableRecaptcha: boolean;\n recaptchaSiteKey: string | null;\n swPublickey: string | null;\n maxNoteTextLength: number;\n enableEmail: boolean;\n enableGithubIntegration: boolean;\n enableDiscordIntegration: boolean;\n searchEngine: string;\n emojis: "
|
||||
"text": "{\n maintainerName: string | null;\n maintainerEmail: string | null;\n version: string;\n name: string | null;\n uri: string;\n description: string | null;\n tosUrl: string | null;\n disableRegistration: boolean;\n localTimelineRequiresCredential: boolean;\n disableLocalTimeline: boolean;\n disableRecommendedTimeline: boolean;\n disableGlobalTimeline: boolean;\n driveCapacityPerLocalUserMb: number;\n driveCapacityPerRemoteUserMb: number;\n enableHcaptcha: boolean;\n hcaptchaSiteKey: string | null;\n enableRecaptcha: boolean;\n recaptchaSiteKey: string | null;\n swPublickey: string | null;\n maxNoteTextLength: number;\n enableEmail: boolean;\n enableGithubIntegration: boolean;\n enableDiscordIntegration: boolean;\n searchEngine: string;\n emojis: "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
|
|
|
|||
|
|
@ -2291,6 +2291,7 @@ type LiteInstanceMetadata = {
|
|||
description: string | null;
|
||||
tosUrl: string | null;
|
||||
disableRegistration: boolean;
|
||||
localTimelineRequiresCredential: boolean;
|
||||
disableLocalTimeline: boolean;
|
||||
disableRecommendedTimeline: boolean;
|
||||
disableGlobalTimeline: boolean;
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ export type LiteInstanceMetadata = {
|
|||
description: string | null;
|
||||
tosUrl: string | null;
|
||||
disableRegistration: boolean;
|
||||
localTimelineRequiresCredential: boolean;
|
||||
disableLocalTimeline: boolean;
|
||||
disableRecommendedTimeline: boolean;
|
||||
disableGlobalTimeline: boolean;
|
||||
|
|
|
|||
|
|
@ -285,6 +285,7 @@ export type LiteInstanceMetadata = {
|
|||
description: string | null;
|
||||
tosUrl: string | null;
|
||||
disableRegistration: boolean;
|
||||
localTimelineRequiresCredential: boolean;
|
||||
disableLocalTimeline: boolean;
|
||||
disableRecommendedTimeline: boolean;
|
||||
disableGlobalTimeline: boolean;
|
||||
|
|
|
|||
Loading…
Reference in a new issue