diff --git a/locales/en-US.yml b/locales/en-US.yml index c489ec4d7..77ea22e1c 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -2000,6 +2000,8 @@ _time: minute: "Minute(s)" hour: "Hour(s)" day: "Day(s)" + month: "Month(s)" + year: "Year(s)" _2fa: alreadyRegistered: "You have already registered a 2-factor authentication device." registerTOTP: "Register authenticator app" diff --git a/packages/backend/migration/1709530777533-noteSelfDestructInterval.js b/packages/backend/migration/1709530777533-noteSelfDestructInterval.js new file mode 100644 index 000000000..370eed516 --- /dev/null +++ b/packages/backend/migration/1709530777533-noteSelfDestructInterval.js @@ -0,0 +1,13 @@ +export class NoteSelfDestructInterval1709530777533 { + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE user_profile ADD "noteSelfDestructInterval" interval NOT NULL DEFAULT '1 months';`); + await queryRunner.query(`ALTER TABLE user_profile ADD "noteSelfDestructEnable" boolean NOT NULL DEFAULT false;`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE user_profile DROP COLUMN "noteSelfDestructInterval";`); + await queryRunner.query(`ALTER TABLE user_profile DROP COLUMN "noteSelfDestructEnable";`); + } + +} diff --git a/packages/backend/src/core/entities/UserEntityService.ts b/packages/backend/src/core/entities/UserEntityService.ts index 8f5d986fa..f9d006681 100644 --- a/packages/backend/src/core/entities/UserEntityService.ts +++ b/packages/backend/src/core/entities/UserEntityService.ts @@ -509,6 +509,8 @@ export class UserEntityService implements OnModuleInit { mutedWords: profile!.mutedWords, hardMutedWords: profile!.hardMutedWords, mutedInstances: profile!.mutedInstances, + noteSelfDestructInterval: profile!.noteSelfDestructInterval, + noteSelfDestructEnable: profile!.noteSelfDestructEnable, mutingNotificationTypes: [], // 後方互換性のため notificationRecieveConfig: profile!.notificationRecieveConfig, emailNotificationTypes: profile!.emailNotificationTypes, diff --git a/packages/backend/src/models/User.ts b/packages/backend/src/models/User.ts index b0910133c..407b7e5e2 100644 --- a/packages/backend/src/models/User.ts +++ b/packages/backend/src/models/User.ts @@ -343,3 +343,4 @@ export const descriptionSchema = { type: 'string', minLength: 1, maxLength: 1500 export const locationSchema = { type: 'string', minLength: 1, maxLength: 50 } as const; export const listenbrainzSchema = { type: "string", minLength: 1, maxLength: 128 } as const; export const birthdaySchema = { type: 'string', pattern: /^([0-9]{4})-([0-9]{2})-([0-9]{2})$/.toString().slice(1, -1) } as const; +export const selfDestructIntervalSchema = { type: 'string', pattern: /^[1-9][0-9]+ (years|months|days|hours|minutes)$/.toString().slice(1, -1) } as const; diff --git a/packages/backend/src/models/UserProfile.ts b/packages/backend/src/models/UserProfile.ts index 40ea26f61..8a6cd096b 100644 --- a/packages/backend/src/models/UserProfile.ts +++ b/packages/backend/src/models/UserProfile.ts @@ -277,6 +277,17 @@ export class MiUserProfile { unlockedAt: number; }[]; + @Column('interval', { + default: '1 months', + }) + public noteSelfDestructInterval: string; + + @Column('boolean', { + default: false, + }) + public noteSelfDestructEnable: string; + + //#region Denormalized fields @Index() @Column('varchar', { diff --git a/packages/backend/src/models/json-schema/user.ts b/packages/backend/src/models/json-schema/user.ts index 33a3efd45..f334bc520 100644 --- a/packages/backend/src/models/json-schema/user.ts +++ b/packages/backend/src/models/json-schema/user.ts @@ -605,6 +605,14 @@ export const packedMeDetailedOnlySchema = { nullable: false, optional: false, }, }, + noteSelfDestructInterval: { + type: 'string', + nullable: false, optional: false, + }, + noteSelfDestructEnable: { + type: 'boolean', + nullable: false, optional: false, + }, notificationRecieveConfig: { type: 'object', nullable: false, optional: false, diff --git a/packages/backend/src/server/api/endpoints/admin/show-user.ts b/packages/backend/src/server/api/endpoints/admin/show-user.ts index 9cdca0222..c88a62695 100644 --- a/packages/backend/src/server/api/endpoints/admin/show-user.ts +++ b/packages/backend/src/server/api/endpoints/admin/show-user.ts @@ -88,6 +88,14 @@ export const meta = { type: 'string', }, }, + noteSelfDestructInterval: { + type: 'string', + optional: false, nullable: false, + }, + noteSelfDestructEnable: { + type: 'boolean', + optional: false, nullable: false, + }, notificationRecieveConfig: { type: 'object', optional: false, nullable: false, @@ -239,6 +247,8 @@ export default class extends Endpoint { // eslint- receiveAnnouncementEmail: profile.receiveAnnouncementEmail, mutedWords: profile.mutedWords, mutedInstances: profile.mutedInstances, + noteSelfDestructInterval: profile.noteSelfDestructInterval, + noteSelfDestructEnable: profile.noteSelfDestructEnable, notificationRecieveConfig: profile.notificationRecieveConfig, isModerator: isModerator, isSilenced: isSilenced, diff --git a/packages/backend/src/server/api/endpoints/i/update.ts b/packages/backend/src/server/api/endpoints/i/update.ts index cb413de9e..2143d58ee 100644 --- a/packages/backend/src/server/api/endpoints/i/update.ts +++ b/packages/backend/src/server/api/endpoints/i/update.ts @@ -13,7 +13,7 @@ import { extractHashtags } from '@/misc/extract-hashtags.js'; import * as Acct from '@/misc/acct.js'; import type { UsersRepository, DriveFilesRepository, UserProfilesRepository, PagesRepository } from '@/models/_.js'; import type { MiLocalUser, MiUser } from '@/models/User.js'; -import { birthdaySchema, listenbrainzSchema, descriptionSchema, locationSchema, nameSchema } from '@/models/User.js'; +import { birthdaySchema, listenbrainzSchema, descriptionSchema, locationSchema, nameSchema, selfDestructIntervalSchema } from '@/models/User.js'; import type { MiUserProfile } from '@/models/UserProfile.js'; import { notificationTypes } from '@/types.js'; import { normalizeForSearch } from '@/misc/normalize-for-search.js'; @@ -202,6 +202,8 @@ export const paramDef = { mutedInstances: { type: 'array', items: { type: 'string', } }, + noteSelfDestructInterval: { ...selfDestructIntervalSchema, nullable: false }, + noteSelfDestructEnable: { type: 'boolean', nullable: false }, notificationRecieveConfig: { type: 'object', nullable: false, @@ -319,6 +321,8 @@ export default class extends Endpoint { // eslint- profileUpdates.hardMutedWords = ps.hardMutedWords; } if (ps.mutedInstances !== undefined) profileUpdates.mutedInstances = ps.mutedInstances; + if (ps.noteSelfDestructInterval !== undefined) profileUpdates.noteSelfDestructInterval = ps.noteSelfDestructInterval; + if (ps.noteSelfDestructEnable !== undefined) profileUpdates.noteSelfDestructEnable = ps.noteSelfDestructEnable; if (ps.notificationRecieveConfig !== undefined) profileUpdates.notificationRecieveConfig = ps.notificationRecieveConfig; if (typeof ps.isLocked === 'boolean') updates.isLocked = ps.isLocked; if (typeof ps.isExplorable === 'boolean') updates.isExplorable = ps.isExplorable; diff --git a/packages/frontend/src/pages/settings/privacy.vue b/packages/frontend/src/pages/settings/privacy.vue index 86cf5ab24..69bd6d6eb 100644 --- a/packages/frontend/src/pages/settings/privacy.vue +++ b/packages/frontend/src/pages/settings/privacy.vue @@ -68,13 +68,41 @@ SPDX-License-Identifier: AGPL-3.0-only {{ i18n.ts.keepCw }} + + +
+ + +
+ {{ i18n.ts.save }} + + + {{ i18n.ts.enable }} + + + + + + + + + + + +
+
+
+