Seemed to fix old stuff but breaks initilizing an instance? Idk whats going on
Some checks are pending
API report (misskey.js) / report (push) Waiting to run

This commit is contained in:
Leah 2025-01-09 22:04:41 +01:00
parent 49650a1382
commit 1224033142
18 changed files with 325 additions and 49 deletions

View file

@ -148,6 +148,7 @@ unsuspend: "Unsuspend"
blockConfirm: "Are you sure that you want to block this account?"
unblockConfirm: "Are you sure that you want to unblock this account?"
suspendConfirm: "Are you sure that you want to suspend this account?"
approveConfirm: "Are you sure that you want to approve this account?"
unsuspendConfirm: "Are you sure that you want to unsuspend this account?"
selectList: "Select a list"
editList: "Edit list"
@ -904,6 +905,7 @@ itsOff: "Disabled"
on: "On"
off: "Off"
emailRequiredForSignup: "Require email address for sign-up"
approvalRequiredForSignup: "Require approval for new users"
unread: "Unread"
filter: "Filter"
controlPanel: "Control Panel"
@ -964,6 +966,11 @@ requireAdminForView: "You must log in with an administrator account to view this
isSystemAccount: "An account created and automatically operated by the system."
typeToConfirm: "Please enter {x} to confirm"
deleteAccount: "Delete account"
approveAccount: "Approve"
denyAccount: "Deny & Delete"
approved: "Approved"
notApproved: "Not Approved"
approvalStatus: "Approval Status"
document: "Documentation"
numberOfPageCache: "Number of cached pages"
numberOfPageCacheDescription: "Increasing this number will improve convenience for but cause more load as more memory usage on the user's device."
@ -1056,6 +1063,7 @@ disableFederationConfirm: "Really disable federation?"
disableFederationConfirmWarn: "Even if defederated, posts will continue to be public unless set otherwise. You usually do not need to do this."
disableFederationOk: "Disable"
invitationRequiredToRegister: "This instance is invite-only. You must enter a valid invite code sign up."
approvalRequiredToRegister: "This instance is only accepting users who specify a reason for registration."
emailNotSupported: "This instance does not support sending emails"
postToTheChannel: "Post to channel"
cannotBeChangedLater: "This cannot be changed later."
@ -1864,6 +1872,8 @@ _signup:
almostThere: "Almost there"
emailAddressInfo: "Please enter your email address. It will not be made public."
emailSent: "A confirmation email has been sent to your email address ({email}). Please click the included link to complete account creation."
approvalPending: "Your account has been created and is awaiting approval."
reasonInfo: "Please enter a reason as to why you want to join the instance."
_accountDelete:
accountDelete: "Delete account"
mayTakeTime: "As account deletion is a resource-heavy process, it may take some time to complete depending on how much content you have created and how many files you have uploaded."

40
locales/index.d.ts vendored
View file

@ -620,6 +620,10 @@ export interface Locale extends ILocale {
*
*/
"suspendConfirm": string;
/**
*
*/
"approveConfirm": string;
/**
*
*/
@ -3640,6 +3644,10 @@ export interface Locale extends ILocale {
*
*/
"emailRequiredForSignup": string;
/**
*
*/
"approvalRequiredForSignup": string;
/**
*
*/
@ -3883,6 +3891,26 @@ export interface Locale extends ILocale {
*
*/
"deleteAccount": string;
/**
*
*/
"approveAccount": string;
/**
*
*/
"denyAccount": string;
/**
*
*/
"approved": string;
/**
*
*/
"notApproved": string;
/**
*
*/
"approvalStatus": string;
/**
*
*/
@ -4251,6 +4279,10 @@ export interface Locale extends ILocale {
*
*/
"invitationRequiredToRegister": string;
/**
*
*/
"approvalRequiredToRegister": string;
/**
*
*/
@ -7290,6 +7322,14 @@ export interface Locale extends ILocale {
* ({email})30
*/
"emailSent": ParameterizedString<"email">;
/**
*
*/
"approvalPending": string;
/**
*
*/
"reasonInfo": string;
};
"_accountDelete": {
/**

View file

@ -151,6 +151,7 @@ unsuspend: "解凍"
blockConfirm: "ブロックしますか?"
unblockConfirm: "ブロック解除しますか?"
suspendConfirm: "凍結しますか?"
approveConfirm: "このアカウントを承認してもよろしいですか?"
unsuspendConfirm: "解凍しますか?"
selectList: "リストを選択"
editList: "リストを編集"
@ -906,6 +907,7 @@ itsOff: "オフになっています"
on: "オン"
off: "オフ"
emailRequiredForSignup: "アカウント登録にメールアドレスを必須にする"
approvalRequiredForSignup: "新規ユーザーの承認が必要"
unread: "未読"
filter: "フィルタ"
controlPanel: "コントロールパネル"
@ -966,6 +968,11 @@ requireAdminForView: "閲覧するには管理者アカウントでログイン
isSystemAccount: "システムにより自動で作成・管理されているアカウントです。"
typeToConfirm: "この操作を行うには {x} と入力してください"
deleteAccount: "アカウント削除"
approveAccount: "承認する"
denyAccount: "拒否と削除"
approved: "承認済み"
notApproved: "承認されていない"
approvalStatus: "承認状況"
document: "ドキュメント"
numberOfPageCache: "ページキャッシュ数"
numberOfPageCacheDescription: "多くすると利便性が向上しますが、負荷とメモリ使用量が増えます。"
@ -1058,6 +1065,7 @@ disableFederationConfirm: "連合なしにしますか?"
disableFederationConfirmWarn: "連合なしにしても投稿は非公開になりません。ほとんどの場合、連合なしにする必要はありません。"
disableFederationOk: "連合なしにする"
invitationRequiredToRegister: "現在このサーバーは招待制です。招待コードをお持ちの方のみ登録できます。"
approvalRequiredToRegister: "このインスタンスは、登録理由を指定したユーザーのみを受け入れています。"
emailNotSupported: "このサーバーではメール配信はサポートされていません"
postToTheChannel: "チャンネルに投稿"
cannotBeChangedLater: "後から変更できません。"
@ -1882,6 +1890,8 @@ _signup:
almostThere: "ほとんど完了です"
emailAddressInfo: "あなたが使っているメールアドレスを入力してください。メールアドレスが公開されることはありません。"
emailSent: "入力されたメールアドレス({email})宛に確認のメールが送信されました。メールに記載されたリンクにアクセスすると、アカウントの作成が完了します。メールに記載されているリンクの有効期限は30分です。"
approvalPending: "アカウントが作成され、承認待ちの状態です。"
reasonInfo: "インスタンスに参加したい理由を入力してください。"
_accountDelete:
accountDelete: "アカウントの削除"

View file

@ -706,8 +706,6 @@ export class UserEntityService implements OnModuleInit {
}
}
return (await Promise.allSettled(_users.map(u => this.pack(u, me, { ...options, userProfile: profilesMap.get(u.id), userRelations: userRelations, userMemos: userMemos, pinNotes: pinNotes }))))
.filter(result => result.status === 'fulfilled')
.map(result => (result as PromiseFulfilledResult<Packed<S>>).value);
return (await Promise.allSettled(_users.map(u => this.pack(u, me, { ...options, userProfile: profilesMap?.get(u.id), userRelations: userRelations, userMemos: userMemos, pinNotes: pinNotes }))))
}
}

View file

@ -242,21 +242,18 @@ export class SignupApiService {
reply.code(204);
return;
} else {
if (instance.approvalRequiredForSignup) {
await this.signupService.signup({
username, password, host, reason,
try {
const { account, secret } = await this.signupService.signup({
username, password, host, reason
});
if (instance.approvalRequiredForSignup) {
if (emailAddress) {
this.emailService.sendEmail(emailAddress, 'Approval pending',
'Congratulations! Your account is now pending approval. You will get notified when you have been accepted.',
'Congratulations! Your account is now pending approval. You will get notified when you have been accepted.');
}
}
try {
const { account, secret } = await this.signupService.signup({
username, password, host,
});
const res = await this.userEntityService.pack(account, account, {
schema: 'MeDetailed',

View file

@ -45,6 +45,10 @@ SPDX-License-Identifier: AGPL-3.0-only
<span v-else-if="emailState === 'error'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.error }}</span>
</template>
</MkInput>
<MkInput v-if="instance.approvalRequiredForSignup" v-model="reason" type="text" :spellcheck="false" required data-cy-signup-reason>
<template #label>Reason <div v-tooltip:dialog="i18n.ts._signup.reasonInfo" class="_button _help"><i class="ph-question ph-bold ph-lg"></i></div></template>
<template #prefix><i class="ti ti-comment-alt"></i></template>
</MkInput>
<MkNewPassword ref="password" :label="i18n.ts.password"/>
<MkCaptcha v-if="instance.enableHcaptcha" ref="hcaptcha" v-model="hCaptchaResponse" :class="$style.captcha" provider="hcaptcha" :sitekey="instance.hcaptchaSiteKey"/>
<MkCaptcha v-if="instance.enableMcaptcha" ref="mcaptcha" v-model="mCaptchaResponse" :class="$style.captcha" provider="mcaptcha" :sitekey="instance.mcaptchaSiteKey" :instanceUrl="instance.mcaptchaInstanceUrl"/>
@ -85,6 +89,7 @@ const props = withDefaults(defineProps<{
const emit = defineEmits<{
(ev: 'signup', user: Misskey.entities.SigninResponse): void;
(ev: 'signupEmailPending'): void;
(ev: 'approvalPending'): void;
}>();
const host = toUnicode(config.host);
@ -97,6 +102,7 @@ const turnstile = ref<Captcha | undefined>();
const username = ref<string>('');
const password = shallowRef<InstanceType<typeof MkNewPassword> | null>(null);
const invitationCode = ref<string>('');
let reason = ref<string>('');
const email = ref('');
const usernameState = ref<null | 'wait' | 'ok' | 'unavailable' | 'error' | 'invalid-format' | 'min-range' | 'max-range'>(null);
const emailState = ref<null | 'wait' | 'ok' | 'unavailable:used' | 'unavailable:format' | 'unavailable:disposable' | 'unavailable:banned' | 'unavailable:mx' | 'unavailable:smtp' | 'unavailable' | 'error'>(null);
@ -195,6 +201,7 @@ async function onSubmit(): Promise<void> {
password: password.value.password,
emailAddress: email.value,
invitationCode: invitationCode.value,
reason: reason.value,
'hcaptcha-response': hCaptchaResponse.value,
'm-captcha-response': mCaptchaResponse.value,
'g-recaptcha-response': reCaptchaResponse.value,
@ -207,6 +214,13 @@ async function onSubmit(): Promise<void> {
text: i18n.tsx._signup.emailSent({ email: email.value }),
});
emit('signupEmailPending');
} else if (instance.approvalRequiredForSignup) {
os.alert({
type: 'success',
title: i18n.ts._signup.almostThere,
text: i18n.ts._signup.approvalPending,
});
emit('approvalPending');
} else {
emit('signup', { id: res.id, i: res.token });

View file

@ -25,7 +25,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<XServerRules @done="isAcceptedServerRule = true" @cancel="onClose"/>
</template>
<template v-else>
<XSignup :autoSet="autoSet" @signup="onSignup" @signupEmailPending="onSignupEmailPending"/>
<XSignup :autoSet="autoSet" @signup="onSignup" @signupEmailPending="onSignupEmailPending" @approvalPending="onApprovalPending"/>
</template>
</Transition>
</div>
@ -69,6 +69,10 @@ function onSignup(res: Misskey.entities.SignupResponse) {
function onSignupEmailPending() {
dialog.value?.close();
}
function onApprovalPending() {
dialog.value?.close();
}
</script>
<style lang="scss" module>

View file

@ -22,6 +22,9 @@ SPDX-License-Identifier: AGPL-3.0-only
<div v-if="instance.disableRegistration" :class="$style.mainWarn">
<MkInfo warn>{{ i18n.ts.invitationRequiredToRegister }}</MkInfo>
</div>
<div v-if="instance.approvalRequiredForSignup" :class="$style.mainWarn">
<MkInfo warn>{{ i18n.ts.approvalRequiredToRegister }}</MkInfo>
</div>
<div class="_gaps_s" :class="$style.mainActions">
<MkButton :class="$style.mainAction" full rounded gradate data-cy-signup style="margin-right: 12px;" @click="signup()">{{ i18n.ts.joinThisServer }}</MkButton>
<MkButton :class="$style.mainAction" full rounded @click="exploreOtherServers()">{{ i18n.ts.exploreOtherServers }}</MkButton>

View file

@ -15,6 +15,8 @@ SPDX-License-Identifier: AGPL-3.0-only
<span class="name"><MkUserName class="name" :user="user"/></span>
<span class="sub"><span class="acct _monospace">@{{ acct(user) }}</span></span>
<span class="state">
<span v-if="!approved" class="silenced">{{ i18n.ts.notApproved }}</span>
<span v-if="approved" class="moderator">{{ i18n.ts.approved }}</span>
<span v-if="admin" class="admin">Admin</span>
<span v-if="moderator" class="moderator">Moderator</span>
<span v-if="silenced" class="silenced">Silenced</span>
@ -219,6 +221,20 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkObjectView tall :value="user">
</MkObjectView>
</div>
<div v-else-if="tab === 'approval'" class="_gaps_m">
<MkKeyValue oneline>
<template #key>{{ i18n.ts.approvalStatus }}</template>
<template #value><span class="_monospace">{{ approved ? i18n.ts.approved : i18n.ts.notApproved }}</span></template>
</MkKeyValue>
<MkTextarea v-model="signupReason" readonly>
<template #label>Reason</template>
</MkTextarea>
<MkButton v-if="$i.isAdmin" inline success @click="approveAccount">{{ i18n.ts.approveAccount }}</MkButton>
<MkButton v-if="$i.isAdmin" inline danger @click="deleteAccount">{{ i18n.ts.denyAccount }}</MkButton>
</div>
</FormSuspense>
</MkSpacer>
</MkStickyContainer>
@ -267,10 +283,13 @@ const ap = ref<any>(null);
const admin = ref(false);
const moderator = ref(false);
const silenced = ref(false);
const approved = ref(false);
const limited = ref(false);
const suspended = ref(false);
const deleted = ref(false);
const moderationNote = ref('');
const signupReason = ref('');
const filesPagination = {
endpoint: 'admin/drive/files' as const,
limit: 10,
@ -303,10 +322,12 @@ function createFetcher() {
admin.value = info.value.isAdmin;
moderator.value = info.value.isModerator;
silenced.value = info.value.isSilenced;
approved.value = info.value.approved;
limited.value = info.value.isLimited;
suspended.value = info.value.isSuspended;
deleted.value = info.value.isDeleted;
moderationNote.value = info.value.moderationNote;
signupReason.value = info.value.signupReason;
watch(moderationNote, async () => {
await misskeyApi('admin/update-user-note', {
@ -470,6 +491,21 @@ async function deleteAccount(soft: boolean) {
}
}
async function approveAccount() {
const confirm = await os.confirm({
type: 'warning',
text: i18n.ts.approveConfirm,
});
if (confirm.canceled) return;
await os.apiWithDialog('admin/approve-user', {
type: 'warning',
text: i18n.ts.approveConfirm,
userId: user.value.id,
});
await refreshUser();
}
async function assignRole() {
const roles = await misskeyApi('admin/roles/list');
@ -573,35 +609,79 @@ watch(user, () => {
const headerActions = computed(() => []);
const headerTabs = computed(() => [{
const headerTabs = computed(() => iAmAdmin && !approved.value ?
[
{
key: 'overview',
title: i18n.ts.overview,
icon: 'ti ti-info-circle',
}, {
},
{
key: 'roles',
title: i18n.ts.roles,
icon: 'ti ti-badges',
}, {
},
{
key: 'announcements',
title: i18n.ts.announcements,
icon: 'ti ti-speakerphone',
}, {
},
{
key: 'drive',
title: i18n.ts.drive,
icon: 'ti ti-cloud',
}, {
},
{
key: 'chart',
title: i18n.ts.charts,
icon: 'ti ti-chart-line',
}, {
},
{
key: 'activitypub',
title: 'ActivityPub',
icon: 'ti ti-share',
}, {
},
{
key: 'raw',
title: 'Raw',
icon: 'ti ti-code',
}]);
},
{
key: 'approval',
title: 'Approval',
icon: 'ph-eye ph-bold pg-lg',
}
] : [
{
key: 'overview',
title: i18n.ts.overview,
icon: 'ti ti-info-circle',
}, {
key: 'roles',
title: i18n.ts.roles,
icon: 'ti ti-badges',
}, {
key: 'announcements',
title: i18n.ts.announcements,
icon: 'ti ti-speakerphone',
}, {
key: 'drive',
title: i18n.ts.drive,
icon: 'ti ti-cloud',
}, {
key: 'chart',
title: i18n.ts.charts,
icon: 'ti ti-chart-line',
}, {
key: 'activitypub',
title: 'ActivityPub',
icon: 'ti ti-share',
}, {
key: 'raw',
title: 'Raw',
icon: 'ti ti-code',
},
]);
definePageMetadata(() => ({
title: user.value ? acct(user.value) : i18n.ts.userInfo,
@ -769,4 +849,16 @@ definePageMetadata(() => ({
border-bottom: none;
}
}
.casdwq {
.silenced {
color: var(--warn);
border-color: var(--warn);
}
.moderator {
color: var(--success);
border-color: var(--success);
}
}
</style>

View file

@ -18,6 +18,10 @@ SPDX-License-Identifier: AGPL-3.0-only
<template #label>{{ i18n.ts.emailRequiredForSignup }}</template>
</MkSwitch>
<MkSwitch v-model="approvalRequiredForSignup">
<template #label>{{ i18n.ts.approvalRequiredForSignup }}</template>
</MkSwitch>
<FormLink to="/admin/server-rules">{{ i18n.ts.serverRules }}</FormLink>
<MkInput v-model="tosUrl" type="url">
@ -90,6 +94,7 @@ import FormLink from '@/components/form/link.vue';
const enableRegistration = ref<boolean>(false);
const emailRequiredForSignup = ref<boolean>(false);
const approvalRequiredForSignup: boolean = ref<boolean>(false);
const sensitiveWords = ref<string>('');
const prohibitedWords = ref<string>('');
const hiddenTags = ref<string>('');
@ -103,6 +108,7 @@ async function init() {
const meta = await misskeyApi('admin/meta');
enableRegistration.value = !meta.disableRegistration;
emailRequiredForSignup.value = meta.emailRequiredForSignup;
approvalRequiredForSignup.value = meta.approvalRequiredForSignup;
sensitiveWords.value = meta.sensitiveWords.join('\n');
prohibitedWords.value = meta.prohibitedWords.join('\n');
hiddenTags.value = meta.hiddenTags.join('\n');
@ -117,6 +123,7 @@ function save() {
os.apiWithDialog('admin/update-meta', {
disableRegistration: !enableRegistration.value,
emailRequiredForSignup: emailRequiredForSignup.value,
approvalRequiredForSignup: approvalRequiredForSignup.value,
tosUrl: tosUrl.value,
privacyPolicyUrl: privacyPolicyUrl.value,
sensitiveWords: sensitiveWords.value.split('\n'),

View file

@ -10,7 +10,7 @@ SPDX-License-Identifier: AGPL-3.0-only
:class="{
[$style.logGreen]: ['createRole', 'addCustomEmoji', 'createGlobalAnnouncement', 'createUserAnnouncement', 'createAd', 'createInvitation', 'createAvatarDecoration'].includes(log.type),
[$style.logYellow]: ['markSensitiveDriveFile', 'resetPassword', 'regenerateUserToken', 'updateUserName', 'unsetUserAvatar', 'unsetUserBanner', 'unsetUserMutualLink'].includes(log.type),
[$style.logRed]: ['suspend', 'deleteRole', 'suspendRemoteInstance', 'deleteGlobalAnnouncement', 'deleteUserAnnouncement', 'deleteCustomEmoji', 'deleteNote', 'deleteDriveFile', 'deleteAd', 'deleteAvatarDecoration'].includes(log.type)
[$style.logRed]: ['suspend', 'approve', 'deleteRole', 'suspendRemoteInstance', 'deleteGlobalAnnouncement', 'deleteUserAnnouncement', 'deleteCustomEmoji', 'deleteNote', 'deleteDriveFile', 'deleteAd', 'deleteAvatarDecoration'].includes(log.type)
}"
>{{ i18n.ts._moderationLogTypes[log.type] }}</b>
<span v-if="log.type === 'updateUserNote'">: @{{ log.info.userUsername }}{{ log.info.userHost ? '@' + log.info.userHost : '' }}</span>
@ -19,6 +19,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<span v-else-if="log.type === 'unsetUserBanner'">: @{{ log.info.userUsername }}{{ log.info.userHost ? '@' + log.info.userHost : '' }}</span>
<span v-else-if="log.type === 'unsetUserMutualLink'">: @{{ log.info.userUsername }}{{ log.info.userHost ? '@' + log.info.userHost : '' }}</span>
<span v-else-if="log.type === 'suspend'">: @{{ log.info.userUsername }}{{ log.info.userHost ? '@' + log.info.userHost : '' }}</span>
<span v-else-if="log.type === 'approve'">: @{{ log.info.userUsername }}{{ log.info.userHost ? '@' + log.info.userHost : '' }}</span>
<span v-else-if="log.type === 'unsuspend'">: @{{ log.info.userUsername }}{{ log.info.userHost ? '@' + log.info.userHost : '' }}</span>
<span v-else-if="log.type === 'resetPassword'">: @{{ log.info.userUsername }}{{ log.info.userHost ? '@' + log.info.userHost : '' }}</span>
<span v-else-if="log.type === 'regenerateUserToken'">: @{{ log.info.userUsername }}{{ log.info.userHost ? '@' + log.info.userHost : '' }}</span>
@ -79,6 +80,9 @@ SPDX-License-Identifier: AGPL-3.0-only
<template v-else-if="log.type === 'suspend'">
<div>{{ i18n.ts.user }}: <MkA :to="`/admin/user/${log.info.userId}`" class="_link">@{{ log.info.userUsername }}{{ log.info.userHost ? '@' + log.info.userHost : '' }}</MkA></div>
</template>
<template v-else-if="log.type === 'approve'">
<div>{{ i18n.ts.user }}: <MkA :to="`/admin/user/${log.info.userId}`" class="_link">@{{ log.info.userUsername }}{{ log.info.userHost ? '@' + log.info.userHost : '' }}</MkA></div>
</template>
<template v-else-if="log.type === 'unsuspend'">
<div>{{ i18n.ts.user }}: <MkA :to="`/admin/user/${log.info.userId}`" class="_link">@{{ log.info.userUsername }}{{ log.info.userHost ? '@' + log.info.userHost : '' }}</MkA></div>
</template>

View file

@ -46,6 +46,13 @@ function submit() {
misskeyApi('signup-pending', {
code: props.code,
}).then(res => {
if (res.pendingApproval) {
return os.alert({
type: 'success',
title: i18n.ts._signup.almostThere,
text: i18n.ts._signup.approvalPending,
});
}
return login(res.i, '/');
}).catch(() => {
submitting.value = false;

View file

@ -116,6 +116,9 @@ type AdminAnnouncementsListResponse = operations['admin___announcements___list']
// @public (undocumented)
type AdminAnnouncementsUpdateRequest = operations['admin___announcements___update']['requestBody']['content']['application/json'];
// @public (undocumented)
type AdminApproveUserRequest = operations['admin___approve-user']['requestBody']['content']['application/json'];
// @public (undocumented)
type AdminAvatarDecorationsCreateRequest = operations['admin___avatar-decorations___create']['requestBody']['content']['application/json'];
@ -1325,6 +1328,7 @@ declare namespace entities {
AdminShowUsersRequest,
AdminShowUsersResponse,
AdminSuspendUserRequest,
AdminApproveUserRequest,
AdminUnsuspendUserRequest,
AdminUpdateMetaRequest,
AdminUpdateUserNameRequest,
@ -2544,7 +2548,7 @@ type ModerationLog = {
});
// @public (undocumented)
export const moderationLogTypes: readonly ["updateServerSettings", "suspend", "unsuspend", "updateUserName", "updateUserNote", "addCustomEmoji", "updateCustomEmoji", "deleteCustomEmoji", "assignRole", "unassignRole", "createRole", "updateRole", "deleteRole", "clearQueue", "promoteQueue", "deleteDriveFile", "deleteNote", "createGlobalAnnouncement", "createUserAnnouncement", "updateGlobalAnnouncement", "updateUserAnnouncement", "deleteGlobalAnnouncement", "deleteUserAnnouncement", "resetPassword", "regenerateUserToken", "suspendRemoteInstance", "unsuspendRemoteInstance", "updateRemoteInstanceNote", "markSensitiveDriveFile", "unmarkSensitiveDriveFile", "resolveAbuseReport", "createInvitation", "createAd", "updateAd", "deleteAd", "createIndieAuthClient", "updateIndieAuthClient", "deleteIndieAuthClient", "createSSOServiceProvider", "updateSSOServiceProvider", "deleteSSOServiceProvider", "createAvatarDecoration", "updateAvatarDecoration", "deleteAvatarDecoration", "unsetUserAvatar", "unsetUserBanner", "unsetUserMutualBanner"];
export const moderationLogTypes: readonly ["updateServerSettings", "suspend", "approve", "unsuspend", "updateUserName", "updateUserNote", "addCustomEmoji", "updateCustomEmoji", "deleteCustomEmoji", "assignRole", "unassignRole", "createRole", "updateRole", "deleteRole", "clearQueue", "promoteQueue", "deleteDriveFile", "deleteNote", "createGlobalAnnouncement", "createUserAnnouncement", "updateGlobalAnnouncement", "updateUserAnnouncement", "deleteGlobalAnnouncement", "deleteUserAnnouncement", "resetPassword", "regenerateUserToken", "suspendRemoteInstance", "unsuspendRemoteInstance", "updateRemoteInstanceNote", "markSensitiveDriveFile", "unmarkSensitiveDriveFile", "resolveAbuseReport", "createInvitation", "createAd", "updateAd", "deleteAd", "createIndieAuthClient", "updateIndieAuthClient", "deleteIndieAuthClient", "createSSOServiceProvider", "updateSSOServiceProvider", "deleteSSOServiceProvider", "createAvatarDecoration", "updateAvatarDecoration", "deleteAvatarDecoration", "unsetUserAvatar", "unsetUserBanner", "unsetUserMutualBanner"];
// @public (undocumented)
type MuteCreateRequest = operations['mute___create']['requestBody']['content']['application/json'];
@ -2796,7 +2800,7 @@ type PagesUpdateRequest = operations['pages___update']['requestBody']['content']
function parse(acct: string): Acct;
// @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:channels", "write:channels", "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", "read:admin:abuse-report-resolvers", "write:admin:abuse-report-resolvers", "read:admin:index-stats", "read:admin:table-stats", "read:admin:user-ips", "read:admin:meta", "write:admin:reset-password", "write:admin:regenerate-user-token", "write:admin:resolve-abuse-user-report", "write:admin:send-email", "read:admin:server-info", "read:admin:show-moderation-log", "read:admin:show-account-move-log", "read:admin:show-user", "read:admin:show-users", "write:admin:suspend-user", "write:admin:unsuspend-user", "write:admin:meta", "write:admin:user-name", "write:admin:user-note", "write:admin:user-avatar", "write:admin:user-banner", "write:admin:user-mutual-link", "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:indie-auth", "read:admin:indie-auth", "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:sso", "read:admin:sso", "write:admin:ad", "read:admin:ad", "write:invite-codes", "read:invite-codes", "write:clip-favorite", "read:clip-favorite", "read:federation", "write:report-abuse"];
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:channels", "write:channels", "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", "read:admin:abuse-report-resolvers", "write:admin:abuse-report-resolvers", "read:admin:index-stats", "read:admin:table-stats", "read:admin:user-ips", "read:admin:meta", "write:admin:reset-password", "write:admin:regenerate-user-token", "write:admin:resolve-abuse-user-report", "write:admin:send-email", "read:admin:server-info", "read:admin:show-moderation-log", "read:admin:show-account-move-log", "read:admin:show-user", "read:admin:show-users", "write:admin:suspend-user", "write:admin:approve-user", "write:admin:unsuspend-user", "write:admin:meta", "write:admin:user-name", "write:admin:user-note", "write:admin:user-avatar", "write:admin:user-banner", "write:admin:user-mutual-link", "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:indie-auth", "read:admin:indie-auth", "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:sso", "read:admin:sso", "write:admin:ad", "read:admin:ad", "write:invite-codes", "read:invite-codes", "write:clip-favorite", "read:clip-favorite", "read:federation", "write:report-abuse"];
// @public (undocumented)
type PingResponse = operations['ping']['responses']['200']['content']['application/json'];

View file

@ -840,6 +840,17 @@ declare module '../api.js' {
credential?: string | null,
): Promise<SwitchCaseResponseType<E, P>>;
/**
* No description provided.
*
* **Credential required**: *Yes* / **Permission**: *write:admin:approve-user*
*/
request<E extends 'admin/approve-user', P extends Endpoints[E]['req']>(
endpoint: E,
params: P,
credential?: string | null,
): Promise<SwitchCaseResponseType<E, P>>;
/**
* No description provided.
*

View file

@ -103,6 +103,7 @@ import type {
AdminShowUsersRequest,
AdminShowUsersResponse,
AdminSuspendUserRequest,
AdminApproveUserRequest,
AdminUnsuspendUserRequest,
AdminUpdateMetaRequest,
AdminUpdateUserNameRequest,
@ -667,6 +668,7 @@ export type Endpoints = {
'admin/show-user': { req: AdminShowUserRequest; res: AdminShowUserResponse };
'admin/show-users': { req: AdminShowUsersRequest; res: AdminShowUsersResponse };
'admin/suspend-user': { req: AdminSuspendUserRequest; res: EmptyResponse };
'admin/approve-user': { req: AdminApproveUserRequest; res: EmptyResponse };
'admin/unsuspend-user': { req: AdminUnsuspendUserRequest; res: EmptyResponse };
'admin/update-meta': { req: AdminUpdateMetaRequest; res: EmptyResponse };
'admin/update-user-name': { req: AdminUpdateUserNameRequest; res: EmptyResponse };

View file

@ -106,6 +106,7 @@ export type AdminShowUserResponse = operations['admin___show-user']['responses']
export type AdminShowUsersRequest = operations['admin___show-users']['requestBody']['content']['application/json'];
export type AdminShowUsersResponse = operations['admin___show-users']['responses']['200']['content']['application/json'];
export type AdminSuspendUserRequest = operations['admin___suspend-user']['requestBody']['content']['application/json'];
export type AdminApproveUserRequest = operations['admin___approve-user']['requestBody']['content']['application/json'];
export type AdminUnsuspendUserRequest = operations['admin___unsuspend-user']['requestBody']['content']['application/json'];
export type AdminUpdateMetaRequest = operations['admin___update-meta']['requestBody']['content']['application/json'];
export type AdminUpdateUserNameRequest = operations['admin___update-user-name']['requestBody']['content']['application/json'];

View file

@ -697,6 +697,15 @@ export type paths = {
*/
post: operations['admin___suspend-user'];
};
'/admin/approve-user': {
/**
* admin/approve-user
* @description No description provided.
*
* **Credential required**: *Yes* / **Permission**: *write:admin:approve-user*
*/
post: operations['admin___approve-user'];
};
'/admin/unsuspend-user': {
/**
* admin/unsuspend-user
@ -5111,6 +5120,7 @@ export type components = {
defaultLightTheme: string | null;
disableRegistration: boolean;
emailRequiredForSignup: boolean;
approvalRequiredForSignup: boolean;
enableHcaptcha: boolean;
hcaptchaSiteKey: string | null;
enableMcaptcha: boolean;
@ -5166,6 +5176,7 @@ export type components = {
features?: {
registration: boolean;
emailRequiredForSignup: boolean;
approvalRequiredForSignup: boolean;
localTimeline: boolean;
globalTimeline: boolean;
hCaptcha: boolean;
@ -5258,6 +5269,7 @@ export type operations = {
cacheRemoteFiles: boolean;
cacheRemoteSensitiveFiles: boolean;
emailRequiredForSignup: boolean;
approvalRequiredForSignup: boolean;
enableHcaptcha: boolean;
hcaptchaSiteKey: string | null;
enableMcaptcha: boolean;
@ -9887,7 +9899,7 @@ export type operations = {
* @default all
* @enum {string}
*/
state?: 'all' | 'alive' | 'available' | 'admin' | 'moderator' | 'adminOrModerator' | 'suspended';
state?: 'all' | 'alive' | 'available' | 'admin' | 'moderator' | 'adminOrModerator' | 'suspended' | 'approved';
/**
* @default combined
* @enum {string}
@ -9994,6 +10006,58 @@ export type operations = {
};
};
};
/**
* admin/approve-user
* @description No description provided.
*
* **Credential required**: *Yes* / **Permission**: *write:admin:approve-user*
*/
'admin___approve-user': {
requestBody: {
content: {
'application/json': {
/** Format: misskey:id */
userId: string;
};
};
};
responses: {
/** @description OK (without any results) */
204: {
content: never;
};
/** @description Client error */
400: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description Authentication error */
401: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description Forbidden error */
403: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description I'm Ai */
418: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description Internal server error */
500: {
content: {
'application/json': components['schemas']['Error'];
};
};
};
};
/**
* admin/unsuspend-user
* @description No description provided.
@ -10081,6 +10145,7 @@ export type operations = {
cacheRemoteFiles?: boolean;
cacheRemoteSensitiveFiles?: boolean;
emailRequiredForSignup?: boolean;
approvalRequiredForSignup?: boolean;
enableHcaptcha?: boolean;
hcaptchaSiteKey?: string | null;
hcaptchaSecretKey?: string | null;

View file

@ -62,6 +62,7 @@ export const permissions = [
'read:admin:show-user',
'read:admin:show-users',
'write:admin:suspend-user',
'write:admin:approve-user',
'write:admin:unsuspend-user',
'write:admin:meta',
'write:admin:user-name',
@ -106,6 +107,7 @@ export const permissions = [
export const moderationLogTypes = [
'updateServerSettings',
'suspend',
'approve',
'unsuspend',
'updateUserName',
'updateUserNote',
@ -163,6 +165,11 @@ export type ModerationLogPayloads = {
userUsername: string;
userHost: string | null;
};
approve: {
userId: string;
userUsername: string;
userHost: string | null;
};
unsuspend: {
userId: string;
userUsername: string;