diff --git a/CHANGELOG_CHERRYPICK.md b/CHANGELOG_CHERRYPICK.md index cefb614d46..436a7f43c0 100644 --- a/CHANGELOG_CHERRYPICK.md +++ b/CHANGELOG_CHERRYPICK.md @@ -47,6 +47,7 @@ - 이벤트 기능 (misskey-dev/misskey#10628) - Play에 API Token을 요청할 수 있는 기능 추가 (misskey-dev/misskey#10949) - 절대 시간 표기 (sakura-tel/milkey#69) +- 초대 코드 해지 기능 ([atsu1125/groundpolis@2da90e7](https://github.com/atsu1125/groundpolis/commit/2da90e7241d2f88390a7713e76a86f26e158248e)) ### Client - (Friendly) 일부 페이지를 제외하고 플로팅 버튼을 표시하지 않음 diff --git a/locales/index.d.ts b/locales/index.d.ts index 4e3cf165d0..14ba6e9741 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -1118,6 +1118,8 @@ export interface Locale { "doYouWantToAllowThisPlayToAccessYourAccount": string; "translateProfile": string; "enableAbsoluteTime": string; + "inviteRevoke": string; + "inviteRevokeConfirm": string; "_group": { "leader": string; "banish": string; diff --git a/locales/ko-KR.yml b/locales/ko-KR.yml index 24a4bc2865..ed2c11a6cd 100644 --- a/locales/ko-KR.yml +++ b/locales/ko-KR.yml @@ -1115,6 +1115,8 @@ thisFlashRequiresTheFollowingPermissions: "이 Play는 다음 권한을 요구 doYouWantToAllowThisPlayToAccessYourAccount: "이 Play가 계정에 접근하도록 허용할까요?" translateProfile: "프로필 번역하기" enableAbsoluteTime: "절대 시간 표기 사용" +inviteRevoke: "모든 초대 코드 무효화" +inviteRevokeConfirm: "정말로 모든 초대 코드를 무효화 할까요?" _group: leader: "그룹 주인" banish: "추방" diff --git a/packages/backend/src/server/api/EndpointsModule.ts b/packages/backend/src/server/api/EndpointsModule.ts index 6e10aa0142..11b8ea3818 100644 --- a/packages/backend/src/server/api/EndpointsModule.ts +++ b/packages/backend/src/server/api/EndpointsModule.ts @@ -39,6 +39,7 @@ import * as ep___admin_getIndexStats from './endpoints/admin/get-index-stats.js' import * as ep___admin_getTableStats from './endpoints/admin/get-table-stats.js'; import * as ep___admin_getUserIps from './endpoints/admin/get-user-ips.js'; import * as ep___invite from './endpoints/invite.js'; +import * as ep___inviteRevoke from './endpoints/invite-revoke.js'; import * as ep___admin_promo_create from './endpoints/admin/promo/create.js'; import * as ep___admin_queue_clear from './endpoints/admin/queue/clear.js'; import * as ep___admin_queue_deliverDelayed from './endpoints/admin/queue/deliver-delayed.js'; @@ -402,6 +403,7 @@ const $admin_getIndexStats: Provider = { provide: 'ep:admin/get-index-stats', us const $admin_getTableStats: Provider = { provide: 'ep:admin/get-table-stats', useClass: ep___admin_getTableStats.default }; const $admin_getUserIps: Provider = { provide: 'ep:admin/get-user-ips', useClass: ep___admin_getUserIps.default }; const $invite: Provider = { provide: 'ep:invite', useClass: ep___invite.default }; +const $inviteRevoke: Provider = { provide: 'ep:invite-revoke', useClass: ep___inviteRevoke.default }; const $admin_promo_create: Provider = { provide: 'ep:admin/promo/create', useClass: ep___admin_promo_create.default }; const $admin_queue_clear: Provider = { provide: 'ep:admin/queue/clear', useClass: ep___admin_queue_clear.default }; const $admin_queue_deliverDelayed: Provider = { provide: 'ep:admin/queue/deliver-delayed', useClass: ep___admin_queue_deliverDelayed.default }; @@ -769,6 +771,7 @@ const $retention: Provider = { provide: 'ep:retention', useClass: ep___retention $admin_getTableStats, $admin_getUserIps, $invite, + $inviteRevoke, $admin_promo_create, $admin_queue_clear, $admin_queue_deliverDelayed, @@ -1130,6 +1133,7 @@ const $retention: Provider = { provide: 'ep:retention', useClass: ep___retention $admin_getTableStats, $admin_getUserIps, $invite, + $inviteRevoke, $admin_promo_create, $admin_queue_clear, $admin_queue_deliverDelayed, diff --git a/packages/backend/src/server/api/endpoints.ts b/packages/backend/src/server/api/endpoints.ts index de713a94f6..36682129ad 100644 --- a/packages/backend/src/server/api/endpoints.ts +++ b/packages/backend/src/server/api/endpoints.ts @@ -39,6 +39,7 @@ import * as ep___admin_getIndexStats from './endpoints/admin/get-index-stats.js' import * as ep___admin_getTableStats from './endpoints/admin/get-table-stats.js'; import * as ep___admin_getUserIps from './endpoints/admin/get-user-ips.js'; import * as ep___invite from './endpoints/invite.js'; +import * as ep___inviteRevoke from './endpoints/invite-revoke.js'; import * as ep___admin_promo_create from './endpoints/admin/promo/create.js'; import * as ep___admin_queue_clear from './endpoints/admin/queue/clear.js'; import * as ep___admin_queue_deliverDelayed from './endpoints/admin/queue/deliver-delayed.js'; @@ -400,6 +401,7 @@ const eps = [ ['admin/get-table-stats', ep___admin_getTableStats], ['admin/get-user-ips', ep___admin_getUserIps], ['invite', ep___invite], + ['invite-revoke', ep___inviteRevoke], ['admin/promo/create', ep___admin_promo_create], ['admin/queue/clear', ep___admin_queue_clear], ['admin/queue/deliver-delayed', ep___admin_queue_deliverDelayed], diff --git a/packages/backend/src/server/api/endpoints/invite-revoke.ts b/packages/backend/src/server/api/endpoints/invite-revoke.ts new file mode 100644 index 0000000000..87f8a96a7f --- /dev/null +++ b/packages/backend/src/server/api/endpoints/invite-revoke.ts @@ -0,0 +1,31 @@ +import { Inject, Injectable } from '@nestjs/common'; +import { Endpoint } from '@/server/api/endpoint-base.js'; +import type { RegistrationTicketsRepository } from '@/models/index.js'; +import { DI } from '@/di-symbols.js'; + +export const meta = { + tags: ['admin'], + + requireCredential: true, + requireRolePolicy: 'canInvite', + requireModerator: true, +} as const; + +export const paramDef = { + type: 'object', + properties: {}, + required: [], +} as const; + +@Injectable() +export default class extends Endpoint { + constructor( + @Inject(DI.registrationTicketsRepository) + private registrationTicketsRepository: RegistrationTicketsRepository, + ) { + super(meta, paramDef, async () => { + await this.registrationTicketsRepository.delete({ + }); + }); + } +} diff --git a/packages/frontend/src/pages/admin/index.vue b/packages/frontend/src/pages/admin/index.vue index d002d9159f..ff3d9e7455 100644 --- a/packages/frontend/src/pages/admin/index.vue +++ b/packages/frontend/src/pages/admin/index.vue @@ -82,6 +82,11 @@ const menuDef = $computed(() => [{ icon: 'ti ti-user-plus', text: i18n.ts.invite, action: invite, + }, { + type: 'button', + icon: 'ti ti-user-cancel', + text: i18n.ts.inviteRevoke, + action: inviteRevoke, }] : [])], }, { title: i18n.ts.administration, @@ -253,6 +258,16 @@ const invite = () => { }); }; +const inviteRevoke = () => { + os.confirm({ + type: 'warning', + text: i18n.ts.inviteRevokeConfirm, + }).then(({ canceled }) => { + if (canceled) return; + os.apiWithDialog('invite-revoke'); + }); +}; + const lookup = (ev) => { os.popupMenu([{ text: i18n.ts.user, diff --git a/src/server/api/endpoints/admin/invite-revoke.ts b/src/server/api/endpoints/admin/invite-revoke.ts deleted file mode 100644 index abca4ce03e..0000000000 --- a/src/server/api/endpoints/admin/invite-revoke.ts +++ /dev/null @@ -1,20 +0,0 @@ -import define from '../../define'; -import { RegistrationTickets } from '../../../../models'; - -export const meta = { - desc: { - 'ja-JP': '招待コードを失効します。' - }, - - tags: ['admin'], - - requireCredential: true as const, - requireModerator: true, - - params: {} -}; - -export default define(meta, async () => { - await RegistrationTickets.delete({ - }); -});