diff --git a/packages/backend/src/models/repositories/app.ts b/packages/backend/src/models/repositories/app.ts index e08dd6f0e..0ede7be14 100644 --- a/packages/backend/src/models/repositories/app.ts +++ b/packages/backend/src/models/repositories/app.ts @@ -25,6 +25,7 @@ export const AppRepository = db.getRepository(App).extend({ return { id: app.id, name: app.name, + description: app.description, callbackUrl: app.callbackUrl, permission: app.permission, ...(opts.includeSecret ? { secret: app.secret } : {}), diff --git a/packages/backend/src/server/api/endpoints/notes/create.ts b/packages/backend/src/server/api/endpoints/notes/create.ts index 82540f96b..2f3d47c12 100644 --- a/packages/backend/src/server/api/endpoints/notes/create.ts +++ b/packages/backend/src/server/api/endpoints/notes/create.ts @@ -5,11 +5,10 @@ import { Users, DriveFiles, Notes, Channels, Blockings } from '@/models/index.js import { DriveFile } from '@/models/entities/drive-file.js'; import { Note } from '@/models/entities/note.js'; import { Channel } from '@/models/entities/channel.js'; -import { MAX_NOTE_TEXT_LENGTH } from '@/const.js'; +import { MAX_NOTE_TEXT_LENGTH, HOUR } from '@/const.js'; import { noteVisibilities } from '../../../../types.js'; import { ApiError } from '../../error.js'; import define from '../../define.js'; -import { HOUR } from '@/const.js'; import { getNote } from '../../common/getters.js'; export const meta = { @@ -78,13 +77,24 @@ export const meta = { code: 'YOU_HAVE_BEEN_BLOCKED', id: 'b390d7e1-8a5e-46ed-b625-06271cafd3d3', }, + + lessRestrictiveVisibility: { + message: 'The visibility cannot be less restrictive than the parent note.', + code: 'LESS_RESTRICTIVE_VISIBILITY', + id: 'c8ab7a7a-8852-41e2-8b24-079bbaceb585', + }, }, } as const; export const paramDef = { type: 'object', properties: { - visibility: { type: 'string', enum: noteVisibilities, default: 'public' }, + visibility: { + description: 'The visibility of the new note. Must be the same or more restrictive than a replied to or quoted note.', + type: 'string', + enum: noteVisibilities, + default: 'public', + }, visibleUserIds: { type: 'array', uniqueItems: true, items: { type: 'string', format: 'misskey:id', } }, @@ -195,6 +205,11 @@ export default define(meta, paramDef, async (ps, user) => { throw new ApiError(meta.errors.cannotReRenote); } + // check that the visibility is not less restrictive + if (noteVisibilities.indexOf(renote.visibility) > noteVisibilities.indexOf(ps.visibility)) { + throw new ApiError(meta.errors.lessRestrictiveVisibility); + } + // Check blocking if (renote.userId !== user.id) { const block = await Blockings.findOneBy({ @@ -219,6 +234,11 @@ export default define(meta, paramDef, async (ps, user) => { throw new ApiError(meta.errors.cannotReplyToPureRenote); } + // check that the visibility is not less restrictive + if (noteVisibilities.indexOf(reply.visibility) > noteVisibilities.indexOf(ps.visibility)) { + throw new ApiError(meta.errors.lessRestrictiveVisibility); + } + // Check blocking if (reply.userId !== user.id) { const block = await Blockings.findOneBy({ diff --git a/packages/backend/src/services/note/create.ts b/packages/backend/src/services/note/create.ts index 0fce38029..51fcac0b9 100644 --- a/packages/backend/src/services/note/create.ts +++ b/packages/backend/src/services/note/create.ts @@ -170,11 +170,6 @@ export default async (user: { id: User['id']; username: User['username']; host: data.visibility = 'followers'; } - // 返信対象がpublicではないならhomeにする - if (data.reply && data.reply.visibility !== 'public' && data.visibility === 'public') { - data.visibility = 'home'; - } - // ローカルのみをRenoteしたらローカルのみにする if (data.renote && data.renote.localOnly && data.channel == null) { data.localOnly = true; diff --git a/packages/backend/src/types.ts b/packages/backend/src/types.ts index 573e2faf8..5ca4a966a 100644 --- a/packages/backend/src/types.ts +++ b/packages/backend/src/types.ts @@ -1,5 +1,8 @@ export const notificationTypes = ['follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'pollEnded', 'receiveFollowRequest', 'followRequestAccepted', 'groupInvited', 'app'] as const; +/** + * Note visibilities, ordered from most to least open. + */ export const noteVisibilities = ['public', 'home', 'followers', 'specified'] as const; export const mutedNoteReasons = ['word', 'manual', 'spam', 'other'] as const; diff --git a/packages/client/src/components/form/textarea.vue b/packages/client/src/components/form/textarea.vue index cb502a422..e4bd26706 100644 --- a/packages/client/src/components/form/textarea.vue +++ b/packages/client/src/components/form/textarea.vue @@ -26,150 +26,88 @@ - diff --git a/packages/client/src/components/global/error.vue b/packages/client/src/components/global/error.vue index 4e2ba07d3..5e676f8cf 100644 --- a/packages/client/src/components/global/error.vue +++ b/packages/client/src/components/global/error.vue @@ -3,7 +3,7 @@

{{ i18n.ts.somethingHappened }}

- {{ i18n.ts.retry }} + {{ i18n.ts.retry }}
@@ -11,6 +11,16 @@ diff --git a/packages/client/src/pages/follow.vue b/packages/client/src/pages/follow.vue index 0c1cb7733..d754c3412 100644 --- a/packages/client/src/pages/follow.vue +++ b/packages/client/src/pages/follow.vue @@ -1,65 +1,76 @@ - diff --git a/packages/client/src/pages/welcome.timeline.vue b/packages/client/src/pages/welcome.timeline.vue index bec9481ff..9a6388963 100644 --- a/packages/client/src/pages/welcome.timeline.vue +++ b/packages/client/src/pages/welcome.timeline.vue @@ -1,7 +1,7 @@ - diff --git a/packages/client/src/ui/_common_/common.vue b/packages/client/src/ui/_common_/common.vue index 9f7388db5..cddf33a3f 100644 --- a/packages/client/src/ui/_common_/common.vue +++ b/packages/client/src/ui/_common_/common.vue @@ -1,5 +1,6 @@ -