Compare commits

..

2 Commits

Author SHA1 Message Date
skinmaker1345
bb7e283218 chore: bump version 2025-04-13 13:29:11 +09:00
skinmaker1345
5132c2243a fix: seperate schema depending on perks 2025-04-13 13:28:58 +09:00
4 changed files with 84 additions and 75 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "koreanbots", "name": "koreanbots",
"version": "2.10.0", "version": "2.10.1",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "next dev", "dev": "next dev",

View File

@ -10,8 +10,8 @@ import {
AddBotSubmit, AddBotSubmit,
AddBotSubmitSchema, AddBotSubmitSchema,
CsrfCaptcha, CsrfCaptcha,
getManageBotSchema,
ManageBot, ManageBot,
ManageBotSchema,
} from '@utils/Yup' } from '@utils/Yup'
import RequestHandler from '@utils/RequestHandler' import RequestHandler from '@utils/RequestHandler'
import { User } from '@types' import { User } from '@types'
@ -197,6 +197,10 @@ const Bots = RequestHandler()
if (!bot) return ResponseWrapper(res, { code: 404, message: '존재하지 않는 봇입니다.' }) if (!bot) return ResponseWrapper(res, { code: 404, message: '존재하지 않는 봇입니다.' })
const user = await get.Authorization(req.cookies.token) const user = await get.Authorization(req.cookies.token)
if (!user) return ResponseWrapper(res, { code: 401 }) if (!user) return ResponseWrapper(res, { code: 401 })
const isPerkAvailable =
checkBotFlag(bot.flags, 'partnered') || checkBotFlag(bot.flags, 'trusted')
const userInfo = await get.user.load(user) const userInfo = await get.user.load(user)
if ( if (
['reported', 'blocked', 'archived'].includes(bot.state) && ['reported', 'blocked', 'archived'].includes(bot.state) &&
@ -215,7 +219,7 @@ const Bots = RequestHandler()
const csrfValidated = checkToken(req, res, req.body._csrf) const csrfValidated = checkToken(req, res, req.body._csrf)
if (!csrfValidated) return if (!csrfValidated) return
const validated: ManageBot = await ManageBotSchema.validate(req.body, { abortEarly: false }) const validated: ManageBot = await getManageBotSchema(isPerkAvailable).validate(req.body, { abortEarly: false })
.then((el) => el) .then((el) => el)
.catch((e) => { .catch((e) => {
ResponseWrapper(res, { code: 400, errors: e.errors }) ResponseWrapper(res, { code: 400, errors: e.errors })
@ -223,11 +227,7 @@ const Bots = RequestHandler()
}) })
if (!validated) return if (!validated) return
if ( if (!isPerkAvailable && (validated.vanity || validated.banner || validated.bg))
!checkBotFlag(bot.flags, 'trusted') &&
!checkBotFlag(bot.flags, 'partnered') &&
(validated.vanity || validated.banner || validated.bg)
)
return ResponseWrapper(res, { return ResponseWrapper(res, {
code: 403, code: 403,
message: '해당 봇은 특전을 이용할 권한이 없습니다.', message: '해당 봇은 특전을 이용할 권한이 없습니다.',
@ -260,7 +260,7 @@ const Bots = RequestHandler()
}, },
], ],
color: Colors.Blue, color: Colors.Blue,
} },
], ],
}) })
} }

View File

@ -10,7 +10,7 @@ import { getJosaPicker } from 'josa'
import { get } from '@utils/Query' import { get } from '@utils/Query'
import { checkBotFlag, checkUserFlag, cleanObject, makeBotURL, parseCookie, redirectTo } from '@utils/Tools' import { checkBotFlag, checkUserFlag, cleanObject, makeBotURL, parseCookie, redirectTo } from '@utils/Tools'
import { ManageBot, ManageBotSchema } from '@utils/Yup' import { ManageBot, getManageBotSchema } from '@utils/Yup'
import { botCategories, botCategoryDescription, library } from '@utils/Constants' import { botCategories, botCategoryDescription, library } from '@utils/Constants'
import { Bot, Theme, User } from '@types' import { Bot, Theme, User } from '@types'
import { getToken } from '@utils/Csrf' import { getToken } from '@utils/Csrf'
@ -93,7 +93,7 @@ const ManageBotPage: NextPage<ManageBotProps> = ({ bot, user, csrfToken, theme }
bg: isPerkAvailable && bot.bg, bg: isPerkAvailable && bot.bg,
_csrf: csrfToken, _csrf: csrfToken,
})} })}
validationSchema={ManageBotSchema} validationSchema={getManageBotSchema(isPerkAvailable)}
onSubmit={submitBot} onSubmit={submitBot}
> >
{({ errors, touched, values, setFieldTouched, setFieldValue }) => ( {({ errors, touched, values, setFieldTouched, setFieldValue }) => (

View File

@ -263,70 +263,79 @@ export interface Report {
_csrf: string _csrf: string
} }
export const ManageBotSchema: Yup.SchemaOf<ManageBot> = Yup.object({ export function getManageBotSchema(perkAvailable = false) {
prefix: Yup.string() const common = {
.matches(Prefix, '접두사는 띄어쓰기로 시작할 수 없습니다.') prefix: Yup.string()
.min(1, '접두사는 최소 1자여야합니다.') .matches(Prefix, '접두사는 띄어쓰기로 시작할 수 없습니다.')
.max(32, '접두사는 최대 32자까지만 가능합니다.') .min(1, '접두사는 최소 1자여야합니다.')
.required('접두사는 필수 항목입니다.'), .max(32, '접두사는 최대 32자까지만 가능합니다.')
library: Yup.string().oneOf(library).required('라이브러리는 필수 항목입니다.'), .required('접두사는 필수 항목입니다.'),
website: Yup.string() library: Yup.string().oneOf(library).required('라이브러리는 필수 항목입니다.'),
.matches(HTTPProtocol, 'http:// 또는 https:// 로 시작해야합니다.') website: Yup.string()
.matches(Url, '올바른 웹사이트 URL을 입력해주세요.') .matches(HTTPProtocol, 'http:// 또는 https:// 로 시작해야합니다.')
.max(64, 'URL은 최대 64자까지만 가능합니다.') .matches(Url, '올바른 웹사이트 URL을 입력해주세요.')
.nullable(), .max(64, 'URL은 최대 64자까지만 가능합니다.')
url: Yup.string() .nullable(),
.matches(HTTPProtocol, 'http:// 또는 https:// 로 시작해야합니다.') url: Yup.string()
.matches(Url, '올바른 초대링크 URL을 입력해주세요.') .matches(HTTPProtocol, 'http:// 또는 https:// 로 시작해야합니다.')
.max(612, 'URL은 최대 612자까지만 가능합니다.') .matches(Url, '올바른 초대링크 URL을 입력해주세요.')
.nullable(), .max(612, 'URL은 최대 612자까지만 가능합니다.')
git: Yup.string() .nullable(),
.matches(HTTPProtocol, 'http:// 또는 https:// 로 시작해야합니다.') git: Yup.string()
.matches(Url, '올바른 깃 URL을 입력해주세요.') .matches(HTTPProtocol, 'http:// 또는 https:// 로 시작해야합니다.')
.max(64, 'URL은 최대 64자까지만 가능합니다.') .matches(Url, '올바른 깃 URL을 입력해주세요.')
.nullable(), .max(64, 'URL은 최대 64자까지만 가능합니다.')
discord: Yup.string() .nullable(),
.matches(Vanity, '디스코드 초대코드 형식을 지켜주세요.') discord: Yup.string()
.min(2, '지원 디스코드는 최소 2자여야합니다.') .matches(Vanity, '디스코드 초대코드 형식을 지켜주세요.')
.max(32, '지원 디스코드는 최대 32자까지만 가능합니다.') .min(2, '지원 디스코드는 최소 2자여야합니다.')
.nullable(), .max(32, '지원 디스코드는 최대 32자까지만 가능합니다.')
category: Yup.array(Yup.string().oneOf(botCategories)) .nullable(),
.min(1, '최소 한 개의 카테고리를 선택해주세요.') category: Yup.array(Yup.string().oneOf(botCategories))
.unique('카테고리는 중복될 수 없습니다.') .min(1, '최소 한 개의 카테고리를 선택해주세요.')
.required('카테고리는 필수 항목입니다.'), .unique('카테고리는 중복될 수 없습니다.')
intro: Yup.string() .required('카테고리는 필수 항목입니다.'),
.min(2, '봇 소개는 최소 2자여야합니다.') intro: Yup.string()
.max(60, '봇 소개는 최대 60자여야합니다.') .min(2, '봇 소개는 최소 2자여야합니다.')
.required('봇 소개는 필수 항목입니다.'), .max(60, '봇 소개는 최대 60자여야합니다.')
desc: Yup.string() .required('봇 소개는 필수 항목입니다.'),
.min(100, '봇 설명은 최소 100자여야합니다.') desc: Yup.string()
.max(1500, '봇 설명은 최대 1500자여야합니다.') .min(100, '봇 설명은 최소 100자여야합니다.')
.required('봇 설명은 필수 항목입니다.'), .max(1500, '봇 설명은 최대 1500자여야합니다.')
vanity: Yup.string() .required('봇 설명은 필수 항목입니다.'),
.matches(Vanity, '커스텀 URL은 영문만 포함할 수 있습니다.') _csrf: Yup.string().required(),
.when('id', { }
is: (id: string) => reservedVanityBypass.includes(id),
then: Yup.string(), const perk = {
otherwise: Yup.string().matches( vanity: Yup.string()
reservedVanity, .matches(Vanity, '커스텀 URL은 영문만 포함할 수 있습니다.')
'예약어가 포함되었거나 사용할 수 없는 커스텀 URL입니다.' .when('id', {
), is: (id: string) => reservedVanityBypass.includes(id),
}) then: Yup.string(),
.min(2, '커스텀 URL은 최소 2자여야합니다.') otherwise: Yup.string().matches(
.max(32, '커스텀 URL은 최대 32자여야합니다.') reservedVanity,
.nullable(), '예약어가 포함되었거나 사용할 수 없는 커스텀 URL입니다.'
banner: Yup.string() ),
.matches(HTTPProtocol, 'http:// 또는 https:// 로 시작해야합니다.') })
.matches(Url, '올바른 배너 URL을 입력해주세요.') .min(2, '커스텀 URL은 최소 2자여야합니다.')
.max(612, 'URL은 최대 612자까지만 가능합니다.') .max(32, '커스텀 URL은 최대 32자여야합니다.')
.nullable(), .nullable(),
bg: Yup.string() banner: Yup.string()
.matches(HTTPProtocol, 'http:// 또는 https:// 로 시작해야합니다.') .matches(HTTPProtocol, 'http:// 또는 https:// 로 시작해야합니다.')
.matches(Url, '올바른 배경 URL을 입력해주세요.') .matches(Url, '올바른 배너 URL을 입력해주세요.')
.max(612, 'URL은 최대 612자까지만 가능합니다.') .max(612, 'URL은 최대 612자까지만 가능합니다.')
.nullable(), .nullable(),
_csrf: Yup.string().required(), bg: Yup.string()
}) .matches(HTTPProtocol, 'http:// 또는 https:// 로 시작해야합니다.')
.matches(Url, '올바른 배경 URL을 입력해주세요.')
.max(612, 'URL은 최대 612자까지만 가능합니다.')
.nullable(),
}
return Yup.object({
...common,
...(perkAvailable ? perk : {}),
}) as Yup.SchemaOf<ManageBot>
}
export interface ManageBot { export interface ManageBot {
prefix: string prefix: string