Compare commits

..

No commits in common. "bb7e283218367acfdd0f00f7b5c93a67f454826d" and "5382fd334b0deac22e9a7f00b4638ad8cbceffa8" have entirely different histories.

4 changed files with 75 additions and 84 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "koreanbots", "name": "koreanbots",
"version": "2.10.1", "version": "2.10.0",
"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,10 +197,6 @@ 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) &&
@ -219,7 +215,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 getManageBotSchema(isPerkAvailable).validate(req.body, { abortEarly: false }) const validated: ManageBot = await ManageBotSchema.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 })
@ -227,7 +223,11 @@ const Bots = RequestHandler()
}) })
if (!validated) return if (!validated) return
if (!isPerkAvailable && (validated.vanity || validated.banner || validated.bg)) if (
!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, getManageBotSchema } from '@utils/Yup' import { ManageBot, ManageBotSchema } 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={getManageBotSchema(isPerkAvailable)} validationSchema={ManageBotSchema}
onSubmit={submitBot} onSubmit={submitBot}
> >
{({ errors, touched, values, setFieldTouched, setFieldValue }) => ( {({ errors, touched, values, setFieldTouched, setFieldValue }) => (

View File

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