mirror of
https://github.com/misskey-dev/misskey.git
synced 2024-12-28 01:30:23 +01:00
fix
This commit is contained in:
parent
ce7f2054c8
commit
ddbb0a4c01
8 changed files with 105 additions and 114 deletions
|
@ -421,7 +421,7 @@ const eps = [
|
|||
['admin/avatar-decorations/delete', ep___admin_avatarDecorations_delete],
|
||||
['admin/avatar-decorations/list', ep___admin_avatarDecorations_list],
|
||||
['admin/avatar-decorations/update', ep___admin_avatarDecorations_update],
|
||||
['admin/captcha/test', ep___admin_captcha_save],
|
||||
['admin/captcha/save', ep___admin_captcha_save],
|
||||
['admin/delete-all-files-of-a-user', ep___admin_deleteAllFilesOfAUser],
|
||||
['admin/unset-user-avatar', ep___admin_unsetUserAvatar],
|
||||
['admin/unset-user-banner', ep___admin_unsetUserBanner],
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import { CaptchaService, supportedCaptchaProviders } from '@/core/CaptchaService.js';
|
||||
import { captchaErrorCodes, CaptchaService, supportedCaptchaProviders } from '@/core/CaptchaService.js';
|
||||
import { ApiError } from '@/server/api/error.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['admin', 'captcha'],
|
||||
|
@ -16,25 +17,42 @@ export const meta = {
|
|||
|
||||
kind: 'read:admin:captcha',
|
||||
|
||||
res: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
success: {
|
||||
type: 'boolean',
|
||||
},
|
||||
error: {
|
||||
type: 'object',
|
||||
nullable: true,
|
||||
optional: false,
|
||||
properties: {
|
||||
code: {
|
||||
type: 'string',
|
||||
},
|
||||
message: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
},
|
||||
errors: {
|
||||
invalidProvider: {
|
||||
message: 'Invalid provider.',
|
||||
code: 'INVALID_PROVIDER',
|
||||
id: '14BF7AE1-80CC-4363-ACB2-4FD61D086AF0',
|
||||
httpStatusCode: 400,
|
||||
},
|
||||
invalidParameters: {
|
||||
message: 'Invalid parameters.',
|
||||
code: 'INVALID_PARAMETERS',
|
||||
id: '26654194-410E-44E2-B42E-460FF6F92476',
|
||||
httpStatusCode: 400,
|
||||
},
|
||||
noResponseProvided: {
|
||||
message: 'No response provided.',
|
||||
code: 'NO_RESPONSE_PROVIDED',
|
||||
id: '40ACBBA8-0937-41FB-BB3F-474514D40AFE',
|
||||
httpStatusCode: 400,
|
||||
},
|
||||
requestFailed: {
|
||||
message: 'Request failed.',
|
||||
code: 'REQUEST_FAILED',
|
||||
id: '0F4FE2F1-2C15-4D6E-B714-EFBFCDE231CD',
|
||||
httpStatusCode: 500,
|
||||
},
|
||||
verificationFailed: {
|
||||
message: 'Verification failed.',
|
||||
code: 'VERIFICATION_FAILED',
|
||||
id: 'C41C067F-24F3-4150-84B2-B5A3AE8C2214',
|
||||
httpStatusCode: 400,
|
||||
},
|
||||
unknown: {
|
||||
message: 'unknown',
|
||||
code: 'UNKNOWN',
|
||||
id: 'F868D509-E257-42A9-99C1-42614B031A97',
|
||||
httpStatusCode: 500,
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
@ -68,22 +86,43 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
private captchaService: CaptchaService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps) => {
|
||||
const result = await this.captchaService.save(ps.provider, ps.captchaResult, {
|
||||
const result = await this.captchaService.save(ps.provider, {
|
||||
sitekey: ps.sitekey,
|
||||
secret: ps.secret,
|
||||
instanceUrl: ps.instanceUrl,
|
||||
captchaResult: ps.captchaResult,
|
||||
});
|
||||
|
||||
if (result.success) {
|
||||
return { success: true, error: null };
|
||||
} else {
|
||||
return {
|
||||
success: false,
|
||||
error: {
|
||||
code: result.error.code.toString(),
|
||||
message: result.error.message,
|
||||
},
|
||||
};
|
||||
if (!result.success) {
|
||||
switch (result.error.code) {
|
||||
case captchaErrorCodes.invalidProvider:
|
||||
throw new ApiError({
|
||||
...meta.errors.invalidProvider,
|
||||
message: result.error.message,
|
||||
});
|
||||
case captchaErrorCodes.invalidParameters:
|
||||
throw new ApiError({
|
||||
...meta.errors.invalidParameters,
|
||||
message: result.error.message,
|
||||
});
|
||||
case captchaErrorCodes.noResponseProvided:
|
||||
throw new ApiError({
|
||||
...meta.errors.noResponseProvided,
|
||||
message: result.error.message,
|
||||
});
|
||||
case captchaErrorCodes.requestFailed:
|
||||
throw new ApiError({
|
||||
...meta.errors.requestFailed,
|
||||
message: result.error.message,
|
||||
});
|
||||
case captchaErrorCodes.verificationFailed:
|
||||
throw new ApiError({
|
||||
...meta.errors.verificationFailed,
|
||||
message: result.error.message,
|
||||
});
|
||||
default:
|
||||
throw new ApiError(meta.errors.unknown);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -142,10 +142,6 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<MkCaptcha v-model="captchaResult" provider="testcaptcha" :sitekey="null"/>
|
||||
</FormSlot>
|
||||
</template>
|
||||
|
||||
<MkInfo v-if="!verifyResult && verifyErrorText" warn>
|
||||
{{ verifyErrorText }}
|
||||
</MkInfo>
|
||||
</div>
|
||||
</MkFolder>
|
||||
</template>
|
||||
|
@ -170,16 +166,14 @@ const MkCaptcha = defineAsyncComponent(() => import('@/components/MkCaptcha.vue'
|
|||
const meta = await misskeyApi('admin/meta');
|
||||
|
||||
const captchaResult = ref<string | null>(null);
|
||||
const verifyResult = ref<boolean>(false);
|
||||
const verifyErrorText = ref<string | null>(null);
|
||||
|
||||
const canSaving = computed((): boolean => {
|
||||
return (botProtectionForm.state.provider === null) ||
|
||||
(botProtectionForm.state.provider === 'hcaptcha' && verifyResult.value) ||
|
||||
(botProtectionForm.state.provider === 'mcaptcha' && verifyResult.value) ||
|
||||
(botProtectionForm.state.provider === 'recaptcha' && verifyResult.value) ||
|
||||
(botProtectionForm.state.provider === 'turnstile' && verifyResult.value) ||
|
||||
(botProtectionForm.state.provider === 'testcaptcha' && verifyResult.value);
|
||||
(botProtectionForm.state.provider === 'hcaptcha' && !!captchaResult.value) ||
|
||||
(botProtectionForm.state.provider === 'mcaptcha' && !!captchaResult.value) ||
|
||||
(botProtectionForm.state.provider === 'recaptcha' && !!captchaResult.value) ||
|
||||
(botProtectionForm.state.provider === 'turnstile' && !!captchaResult.value) ||
|
||||
(botProtectionForm.state.provider === 'testcaptcha' && !!captchaResult.value);
|
||||
});
|
||||
|
||||
const botProtectionForm = useForm({
|
||||
|
@ -204,36 +198,6 @@ const botProtectionForm = useForm({
|
|||
turnstileSiteKey: meta.turnstileSiteKey,
|
||||
turnstileSecretKey: meta.turnstileSecretKey,
|
||||
}, async (state) => {
|
||||
await os.apiWithDialog('admin/update-meta', {
|
||||
enableHcaptcha: state.provider === 'hcaptcha',
|
||||
hcaptchaSiteKey: state.hcaptchaSiteKey,
|
||||
hcaptchaSecretKey: state.hcaptchaSecretKey,
|
||||
enableMcaptcha: state.provider === 'mcaptcha',
|
||||
mcaptchaSiteKey: state.mcaptchaSiteKey,
|
||||
mcaptchaSecretKey: state.mcaptchaSecretKey,
|
||||
mcaptchaInstanceUrl: state.mcaptchaInstanceUrl,
|
||||
enableRecaptcha: state.provider === 'recaptcha',
|
||||
recaptchaSiteKey: state.recaptchaSiteKey,
|
||||
recaptchaSecretKey: state.recaptchaSecretKey,
|
||||
enableTurnstile: state.provider === 'turnstile',
|
||||
turnstileSiteKey: state.turnstileSiteKey,
|
||||
turnstileSecretKey: state.turnstileSecretKey,
|
||||
enableTestcaptcha: state.provider === 'testcaptcha',
|
||||
});
|
||||
fetchInstance(true);
|
||||
});
|
||||
|
||||
watch(botProtectionForm.state, () => {
|
||||
captchaResult.value = null;
|
||||
if (botProtectionForm.state.provider === null) {
|
||||
verifyResult.value = true;
|
||||
} else {
|
||||
verifyResult.value = false;
|
||||
verifyErrorText.value = null;
|
||||
}
|
||||
});
|
||||
|
||||
watch(captchaResult, async () => {
|
||||
const provider = botProtectionForm.state.provider;
|
||||
|
||||
const sitekey = provider === 'hcaptcha'
|
||||
|
@ -256,22 +220,24 @@ watch(captchaResult, async () => {
|
|||
: null;
|
||||
|
||||
if (captchaResult.value) {
|
||||
const result = await misskeyApi('admin/captcha/test', {
|
||||
provider: provider as Misskey.entities.AdminCaptchaTestRequest['provider'],
|
||||
sitekey: sitekey,
|
||||
secret: secret,
|
||||
instanceUrl: botProtectionForm.state.mcaptchaInstanceUrl,
|
||||
captchaResult: captchaResult.value,
|
||||
});
|
||||
await os.apiWithDialog(
|
||||
'admin/captcha/save',
|
||||
{
|
||||
provider: provider as Misskey.entities.AdminCaptchaSaveRequest['provider'],
|
||||
sitekey: sitekey,
|
||||
secret: secret,
|
||||
instanceUrl: botProtectionForm.state.mcaptchaInstanceUrl,
|
||||
captchaResult: captchaResult.value,
|
||||
},
|
||||
);
|
||||
|
||||
verifyResult.value = result.success;
|
||||
verifyErrorText.value = result.error
|
||||
? result.error.message
|
||||
: null;
|
||||
} else {
|
||||
verifyResult.value = false;
|
||||
await fetchInstance(true);
|
||||
}
|
||||
});
|
||||
|
||||
watch(botProtectionForm.state, () => {
|
||||
captchaResult.value = null;
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" module>
|
||||
|
|
|
@ -137,10 +137,7 @@ type AdminAvatarDecorationsListResponse = operations['admin___avatar-decorations
|
|||
type AdminAvatarDecorationsUpdateRequest = operations['admin___avatar-decorations___update']['requestBody']['content']['application/json'];
|
||||
|
||||
// @public (undocumented)
|
||||
type AdminCaptchaTestRequest = operations['admin___captcha___test']['requestBody']['content']['application/json'];
|
||||
|
||||
// @public (undocumented)
|
||||
type AdminCaptchaTestResponse = operations['admin___captcha___test']['responses']['200']['content']['application/json'];
|
||||
type AdminCaptchaSaveRequest = operations['admin___captcha___save']['requestBody']['content']['application/json'];
|
||||
|
||||
// @public (undocumented)
|
||||
type AdminDeleteAccountRequest = operations['admin___delete-account']['requestBody']['content']['application/json'];
|
||||
|
@ -1267,8 +1264,7 @@ declare namespace entities {
|
|||
AdminAvatarDecorationsListRequest,
|
||||
AdminAvatarDecorationsListResponse,
|
||||
AdminAvatarDecorationsUpdateRequest,
|
||||
AdminCaptchaTestRequest,
|
||||
AdminCaptchaTestResponse,
|
||||
AdminCaptchaSaveRequest,
|
||||
AdminDeleteAllFilesOfAUserRequest,
|
||||
AdminUnsetUserAvatarRequest,
|
||||
AdminUnsetUserBannerRequest,
|
||||
|
|
|
@ -256,7 +256,7 @@ declare module '../api.js' {
|
|||
* **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties.
|
||||
* **Credential required**: *Yes* / **Permission**: *read:admin:captcha*
|
||||
*/
|
||||
request<E extends 'admin/captcha/test', P extends Endpoints[E]['req']>(
|
||||
request<E extends 'admin/captcha/save', P extends Endpoints[E]['req']>(
|
||||
endpoint: E,
|
||||
params: P,
|
||||
credential?: string | null,
|
||||
|
|
|
@ -36,8 +36,7 @@ import type {
|
|||
AdminAvatarDecorationsListRequest,
|
||||
AdminAvatarDecorationsListResponse,
|
||||
AdminAvatarDecorationsUpdateRequest,
|
||||
AdminCaptchaTestRequest,
|
||||
AdminCaptchaTestResponse,
|
||||
AdminCaptchaSaveRequest,
|
||||
AdminDeleteAllFilesOfAUserRequest,
|
||||
AdminUnsetUserAvatarRequest,
|
||||
AdminUnsetUserBannerRequest,
|
||||
|
@ -606,7 +605,7 @@ export type Endpoints = {
|
|||
'admin/avatar-decorations/delete': { req: AdminAvatarDecorationsDeleteRequest; res: EmptyResponse };
|
||||
'admin/avatar-decorations/list': { req: AdminAvatarDecorationsListRequest; res: AdminAvatarDecorationsListResponse };
|
||||
'admin/avatar-decorations/update': { req: AdminAvatarDecorationsUpdateRequest; res: EmptyResponse };
|
||||
'admin/captcha/test': { req: AdminCaptchaTestRequest; res: AdminCaptchaTestResponse };
|
||||
'admin/captcha/save': { req: AdminCaptchaSaveRequest; res: EmptyResponse };
|
||||
'admin/delete-all-files-of-a-user': { req: AdminDeleteAllFilesOfAUserRequest; res: EmptyResponse };
|
||||
'admin/unset-user-avatar': { req: AdminUnsetUserAvatarRequest; res: EmptyResponse };
|
||||
'admin/unset-user-banner': { req: AdminUnsetUserBannerRequest; res: EmptyResponse };
|
||||
|
|
|
@ -39,8 +39,7 @@ export type AdminAvatarDecorationsDeleteRequest = operations['admin___avatar-dec
|
|||
export type AdminAvatarDecorationsListRequest = operations['admin___avatar-decorations___list']['requestBody']['content']['application/json'];
|
||||
export type AdminAvatarDecorationsListResponse = operations['admin___avatar-decorations___list']['responses']['200']['content']['application/json'];
|
||||
export type AdminAvatarDecorationsUpdateRequest = operations['admin___avatar-decorations___update']['requestBody']['content']['application/json'];
|
||||
export type AdminCaptchaTestRequest = operations['admin___captcha___test']['requestBody']['content']['application/json'];
|
||||
export type AdminCaptchaTestResponse = operations['admin___captcha___test']['responses']['200']['content']['application/json'];
|
||||
export type AdminCaptchaSaveRequest = operations['admin___captcha___save']['requestBody']['content']['application/json'];
|
||||
export type AdminDeleteAllFilesOfAUserRequest = operations['admin___delete-all-files-of-a-user']['requestBody']['content']['application/json'];
|
||||
export type AdminUnsetUserAvatarRequest = operations['admin___unset-user-avatar']['requestBody']['content']['application/json'];
|
||||
export type AdminUnsetUserBannerRequest = operations['admin___unset-user-banner']['requestBody']['content']['application/json'];
|
||||
|
|
|
@ -215,15 +215,15 @@ export type paths = {
|
|||
*/
|
||||
post: operations['admin___avatar-decorations___update'];
|
||||
};
|
||||
'/admin/captcha/test': {
|
||||
'/admin/captcha/save': {
|
||||
/**
|
||||
* admin/captcha/test
|
||||
* admin/captcha/save
|
||||
* @description No description provided.
|
||||
*
|
||||
* **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties.
|
||||
* **Credential required**: *Yes* / **Permission**: *read:admin:captcha*
|
||||
*/
|
||||
post: operations['admin___captcha___test'];
|
||||
post: operations['admin___captcha___save'];
|
||||
};
|
||||
'/admin/delete-all-files-of-a-user': {
|
||||
/**
|
||||
|
@ -6575,13 +6575,13 @@ export type operations = {
|
|||
};
|
||||
};
|
||||
/**
|
||||
* admin/captcha/test
|
||||
* admin/captcha/save
|
||||
* @description No description provided.
|
||||
*
|
||||
* **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties.
|
||||
* **Credential required**: *Yes* / **Permission**: *read:admin:captcha*
|
||||
*/
|
||||
admin___captcha___test: {
|
||||
admin___captcha___save: {
|
||||
requestBody: {
|
||||
content: {
|
||||
'application/json': {
|
||||
|
@ -6595,17 +6595,9 @@ export type operations = {
|
|||
};
|
||||
};
|
||||
responses: {
|
||||
/** @description OK (with results) */
|
||||
200: {
|
||||
content: {
|
||||
'application/json': {
|
||||
success: boolean;
|
||||
error: {
|
||||
code: string;
|
||||
message: string;
|
||||
} | null;
|
||||
};
|
||||
};
|
||||
/** @description OK (without any results) */
|
||||
204: {
|
||||
content: never;
|
||||
};
|
||||
/** @description Client error */
|
||||
400: {
|
||||
|
|
Loading…
Reference in a new issue