Skip to content

Commit

Permalink
予約投稿の権限
Browse files Browse the repository at this point in the history
  • Loading branch information
kozakura913 committed Sep 29, 2024
1 parent 38e9c51 commit 4919bf0
Show file tree
Hide file tree
Showing 14 changed files with 60 additions and 8 deletions.
8 changes: 8 additions & 0 deletions locales/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7676,6 +7676,10 @@ export interface Locale extends ILocale {
* ノートの編集
*/
"canEditNote": string;
/**
* ノートの予約投稿
*/
"canScheduleNote": string;
/**
* ノート内の最大メンション数
*/
Expand Down Expand Up @@ -9331,6 +9335,10 @@ export interface Locale extends ILocale {
* ノートを作成・削除する
*/
"write:notes": string;
/**
* 予約投稿を見る
*/
"read:notes-schedule": string;
/**
* 通知を見る
*/
Expand Down
2 changes: 2 additions & 0 deletions locales/ja-JP.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1993,6 +1993,7 @@ _role:
ltlAvailable: "ローカルタイムラインの閲覧"
canPublicNote: "パブリック投稿の許可"
canEditNote: "ノートの編集"
canScheduleNote: "ノートの予約投稿"
mentionMax: "ノート内の最大メンション数"
canInvite: "サーバー招待コードの発行"
inviteLimit: "招待コードの作成可能数"
Expand Down Expand Up @@ -2455,6 +2456,7 @@ _permissions:
"read:mutes": "ミュートを見る"
"write:mutes": "ミュートを操作する"
"write:notes": "ノートを作成・削除する"
"read:notes-schedule": "予約投稿を見る"
"read:notifications": "通知を見る"
"write:notifications": "通知を操作する"
"read:reactions": "リアクションを見る"
Expand Down
3 changes: 3 additions & 0 deletions packages/backend/src/core/RoleService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export type RolePolicies = {
ltlAvailable: boolean;
canPublicNote: boolean;
canEditNote: boolean;
canScheduleNote: boolean;
mentionLimit: number;
canInvite: boolean;
inviteLimit: number;
Expand Down Expand Up @@ -70,6 +71,7 @@ export const DEFAULT_POLICIES: RolePolicies = {
ltlAvailable: true,
canPublicNote: true,
canEditNote: true,
canScheduleNote: true,
mentionLimit: 20,
canInvite: false,
inviteLimit: 0,
Expand Down Expand Up @@ -377,6 +379,7 @@ export class RoleService implements OnApplicationShutdown, OnModuleInit {
ltlAvailable: calc('ltlAvailable', vs => vs.some(v => v === true)),
canPublicNote: calc('canPublicNote', vs => vs.some(v => v === true)),
canEditNote: calc('canEditNote', vs => vs.some(v => v === true)),
canScheduleNote: calc('canScheduleNote', vs => vs.some(v => v === true)),
mentionLimit: calc('mentionLimit', vs => Math.max(...vs)),
canInvite: calc('canInvite', vs => vs.some(v => v === true)),
inviteLimit: calc('inviteLimit', vs => Math.max(...vs)),
Expand Down
4 changes: 4 additions & 0 deletions packages/backend/src/models/json-schema/role.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,10 @@ export const packedRolePoliciesSchema = {
type: 'boolean',
optional: false, nullable: false,
},
canScheduleNote: {
type: 'boolean',
optional: false, nullable: false,
},
mutualLinkSectionLimit: {
type: 'integer',
optional: false, nullable: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export const meta = {
tags: ['notes'],

requireCredential: true,
requireRolePolicy: 'canScheduleNote',

prohibitMoved: true,

Expand Down Expand Up @@ -211,7 +212,10 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
private queueService: QueueService,
private idService: IdService,
) {
super(meta, paramDef, async (ps, me) => {
super({
...meta,
requireRolePolicy: 'canScheduleNote',
}, paramDef, async (ps, me) => {
let visibleUsers: MiUser[] = [];
if (ps.visibleUserIds) {
visibleUsers = await this.usersRepository.findBy({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export const meta = {
tags: ['notes'],

requireCredential: true,
kind: 'read:account',
kind: 'read:notes-schedule',
res: {
type: 'array',
optional: false, nullable: false,
Expand Down
2 changes: 1 addition & 1 deletion packages/cherrypick-js/etc/cherrypick-js.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -2900,7 +2900,7 @@ type PartialRolePolicyOverride = Partial<{
}>;

// @public (undocumented)
export const permissions: readonly ["read:account", "write:account", "read:blocks", "write:blocks", "read:drive", "write:drive", "read:favorites", "write:favorites", "read:following", "write:following", "read:messaging", "write:messaging", "read:mutes", "write:mutes", "write:notes", "read:notifications", "write:notifications", "read:reactions", "write:reactions", "write:votes", "read:pages", "write:pages", "write:page-likes", "read:page-likes", "read:user-groups", "write:user-groups", "read:gallery", "write:gallery", "read:gallery-likes", "write:gallery-likes", "read:flash", "write:flash", "read:flash-likes", "write:flash-likes", "read:admin:abuse-user-reports", "write:admin:delete-account", "write:admin:delete-all-files-of-a-user", "read:admin:index-stats", "read:admin:table-stats", "read:admin:user-ips", "read:admin:meta", "write:admin:reset-password", "write:admin:resolve-abuse-user-report", "write:admin:send-email", "read:admin:server-info", "read:admin:show-moderation-log", "read:admin:show-user", "write:admin:suspend-user", "write:admin:unset-user-avatar", "write:admin:unset-user-banner", "write:admin:unsuspend-user", "write:admin:meta", "write:admin:user-note", "write:admin:roles", "read:admin:roles", "write:admin:relays", "read:admin:relays", "write:admin:invite-codes", "read:admin:invite-codes", "write:admin:announcements", "read:admin:announcements", "write:admin:avatar-decorations", "read:admin:avatar-decorations", "write:admin:federation", "write:admin:account", "read:admin:account", "write:admin:emoji", "read:admin:emoji", "write:admin:queue", "read:admin:queue", "write:admin:promo", "write:admin:drive", "read:admin:drive", "write:admin:ad", "read:admin:ad", "write:invite-codes", "read:invite-codes", "write:clip-favorite", "read:clip-favorite", "read:federation", "write:report-abuse", "write:admin:official-tags", "write:admin:reindex"];
export const permissions: readonly ["read:account", "write:account", "read:blocks", "write:blocks", "read:drive", "write:drive", "read:favorites", "write:favorites", "read:following", "write:following", "read:messaging", "write:messaging", "read:mutes", "write:mutes", "write:notes", "read:notes-schedule", "read:notifications", "write:notifications", "read:reactions", "write:reactions", "write:votes", "read:pages", "write:pages", "write:page-likes", "read:page-likes", "read:user-groups", "write:user-groups", "read:gallery", "write:gallery", "read:gallery-likes", "write:gallery-likes", "read:flash", "write:flash", "read:flash-likes", "write:flash-likes", "read:admin:abuse-user-reports", "write:admin:delete-account", "write:admin:delete-all-files-of-a-user", "read:admin:index-stats", "read:admin:table-stats", "read:admin:user-ips", "read:admin:meta", "write:admin:reset-password", "write:admin:resolve-abuse-user-report", "write:admin:send-email", "read:admin:server-info", "read:admin:show-moderation-log", "read:admin:show-user", "write:admin:suspend-user", "write:admin:unset-user-avatar", "write:admin:unset-user-banner", "write:admin:unsuspend-user", "write:admin:meta", "write:admin:user-note", "write:admin:roles", "read:admin:roles", "write:admin:relays", "read:admin:relays", "write:admin:invite-codes", "read:admin:invite-codes", "write:admin:announcements", "read:admin:announcements", "write:admin:avatar-decorations", "read:admin:avatar-decorations", "write:admin:federation", "write:admin:account", "read:admin:account", "write:admin:emoji", "read:admin:emoji", "write:admin:queue", "read:admin:queue", "write:admin:promo", "write:admin:drive", "read:admin:drive", "write:admin:ad", "read:admin:ad", "write:invite-codes", "read:invite-codes", "write:clip-favorite", "read:clip-favorite", "read:federation", "write:report-abuse", "write:admin:official-tags", "write:admin:reindex"];

// @public (undocumented)
type PingResponse = operations['ping']['responses']['200']['content']['application/json'];
Expand Down
2 changes: 1 addition & 1 deletion packages/cherrypick-js/src/autogen/apiClientJSDoc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3125,7 +3125,7 @@ declare module '../api.js' {
/**
* No description provided.
*
* **Credential required**: *Yes* / **Permission**: *read:account*
* **Credential required**: *Yes* / **Permission**: *read:notes-schedule*
*/
request<E extends 'notes/schedule/list', P extends Endpoints[E]['req']>(
endpoint: E,
Expand Down
5 changes: 3 additions & 2 deletions packages/cherrypick-js/src/autogen/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2704,7 +2704,7 @@ export type paths = {
* notes/schedule/list
* @description No description provided.
*
* **Credential required**: *Yes* / **Permission**: *read:account*
* **Credential required**: *Yes* / **Permission**: *read:notes-schedule*
*/
post: operations['notes___schedule___list'];
};
Expand Down Expand Up @@ -5167,6 +5167,7 @@ export type components = {
avatarDecorationLimit: number;
fileSizeLimit: number;
canEditNote: boolean;
canScheduleNote: boolean;
mutualLinkSectionLimit: number;
mutualLinkLimit: number;
};
Expand Down Expand Up @@ -22214,7 +22215,7 @@ export type operations = {
* notes/schedule/list
* @description No description provided.
*
* **Credential required**: *Yes* / **Permission**: *read:account*
* **Credential required**: *Yes* / **Permission**: *read:notes-schedule*
*/
notes___schedule___list: {
requestBody: {
Expand Down
1 change: 1 addition & 0 deletions packages/cherrypick-js/src/consts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export const permissions = [
'read:mutes',
'write:mutes',
'write:notes',
'read:notes-schedule',
'read:notifications',
'write:notifications',
'read:reactions',
Expand Down
4 changes: 2 additions & 2 deletions packages/frontend/src/components/MkPostForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ SPDX-License-Identifier: AGPL-3.0-only
</button>
</div>
<div :class="$style.headerRight">
<button v-tooltip="i18n.ts.schedulePost" class="_button" :class="[$style.headerRightItem, { [$style.headerRightButtonActive]: schedule }]" @click="toggleSchedule"><i class="ti ti-calendar-time"></i></button>
<button v-tooltip="i18n.ts.schedulePostList" class="_button" :class="[$style.headerRightItem]" @click="listSchedulePost"><i class="ti ti-calendar-event"></i></button>
<button v-if="$i.policies.canScheduleNote" v-tooltip="i18n.ts.schedulePost" class="_button" :class="[$style.headerRightItem, { [$style.headerRightButtonActive]: schedule }]" @click="toggleSchedule"><i class="ti ti-calendar-time"></i></button>
<button v-if="$i.policies.canScheduleNote" v-tooltip="i18n.ts.schedulePostList" class="_button" :class="[$style.headerRightItem]" @click="listSchedulePost"><i class="ti ti-calendar-event"></i></button>
<template v-if="!(channel != null && fixed)">
<button v-if="channel == null" ref="visibilityButton" v-click-anime v-tooltip="i18n.ts.visibility" :class="['_button', $style.headerRightItem, $style.visibility]" @click="setVisibility">
<span v-if="visibility === 'public'"><i class="ti ti-world"></i></span>
Expand Down
1 change: 1 addition & 0 deletions packages/frontend/src/const.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ export const ROLE_POLICIES = [
'ltlAvailable',
'canPublicNote',
'canEditNote',
'canScheduleNote',
'mentionLimit',
'canInvite',
'inviteLimit',
Expand Down
20 changes: 20 additions & 0 deletions packages/frontend/src/pages/admin/roles.editor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,26 @@ SPDX-License-Identifier: AGPL-3.0-only
</div>
</MkFolder>

<MkFolder v-if="matchQuery([i18n.ts._role._options.canScheduleNote, 'canScheduleNote'])">
<template #label>{{ i18n.ts._role._options.canScheduleNote }}</template>
<template #suffix>
<span v-if="role.policies.canScheduleNote.useDefault" :class="$style.useDefaultLabel">{{ i18n.ts._role.useBaseValue }}</span>
<span v-else>{{ role.policies.canScheduleNote.value ? i18n.ts.yes : i18n.ts.no }}</span>
<span :class="$style.priorityIndicator"><i :class="getPriorityIcon(role.policies.canScheduleNote)"></i></span>
</template>
<div class="_gaps">
<MkSwitch v-model="role.policies.canScheduleNote.useDefault" :readonly="readonly">
<template #label>{{ i18n.ts._role.useBaseValue }}</template>
</MkSwitch>
<MkSwitch v-model="role.policies.canScheduleNote.value" :disabled="role.policies.canScheduleNote.useDefault" :readonly="readonly">
<template #label>{{ i18n.ts.enable }}</template>
</MkSwitch>
<MkRange v-model="role.policies.canScheduleNote.priority" :min="0" :max="2" :step="1" easing :textConverter="(v) => v === 0 ? i18n.ts._role._priority.low : v === 1 ? i18n.ts._role._priority.middle : v === 2 ? i18n.ts._role._priority.high : ''">
<template #label>{{ i18n.ts._role.priority }}</template>
</MkRange>
</div>
</MkFolder>

<MkFolder v-if="matchQuery([i18n.ts._role._options.mentionMax, 'mentionLimit'])">
<template #label>{{ i18n.ts._role._options.mentionMax }}</template>
<template #suffix>
Expand Down
8 changes: 8 additions & 0 deletions packages/frontend/src/pages/admin/roles.vue
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@ SPDX-License-Identifier: AGPL-3.0-only
</MkSwitch>
</MkFolder>

<MkFolder v-if="matchQuery([i18n.ts._role._options.canScheduleNote, 'canScheduleNote'])">
<template #label>{{ i18n.ts._role._options.canScheduleNote }}</template>
<template #suffix>{{ policies.canScheduleNote ? i18n.ts.yes : i18n.ts.no }}</template>
<MkSwitch v-model="policies.canScheduleNote">
<template #label>{{ i18n.ts.enable }}</template>
</MkSwitch>
</MkFolder>

<MkFolder v-if="matchQuery([i18n.ts._role._options.mentionMax, 'mentionLimit'])">
<template #label>{{ i18n.ts._role._options.mentionMax }}</template>
<template #suffix>{{ policies.mentionLimit }}</template>
Expand Down

0 comments on commit 4919bf0

Please sign in to comment.