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