mirror of
https://github.com/koreanbots/core.git
synced 2025-12-15 14:10:22 +00:00
feat: camo images in bot desc
This commit is contained in:
parent
ef160e89aa
commit
57569bd298
@ -36,7 +36,7 @@ const TextArea = dynamic(() => import('@components/Form/TextArea'))
|
|||||||
const Modal = dynamic(() => import('@components/Modal'))
|
const Modal = dynamic(() => import('@components/Modal'))
|
||||||
const NSFW = dynamic(() => import('@components/NSFW'))
|
const NSFW = dynamic(() => import('@components/NSFW'))
|
||||||
|
|
||||||
const Bots: NextPage<BotsProps> = ({ data, date, user, theme, csrfToken }) => {
|
const Bots: NextPage<BotsProps> = ({ data, desc, date, user, theme, csrfToken }) => {
|
||||||
const bg = checkBotFlag(data?.flags, 'trusted') && data?.banner
|
const bg = checkBotFlag(data?.flags, 'trusted') && data?.banner
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const [ nsfw, setNSFW ] = useState<boolean>()
|
const [ nsfw, setNSFW ] = useState<boolean>()
|
||||||
@ -305,7 +305,7 @@ const Bots: NextPage<BotsProps> = ({ data, date, user, theme, csrfToken }) => {
|
|||||||
}
|
}
|
||||||
<div className='markdown-body pt-4 w-full'>
|
<div className='markdown-body pt-4 w-full'>
|
||||||
<Segment className='my-4'>
|
<Segment className='my-4'>
|
||||||
<Markdown text={data.desc}/>
|
<Markdown text={desc}/>
|
||||||
</Segment>
|
</Segment>
|
||||||
<Advertisement />
|
<Advertisement />
|
||||||
</div>
|
</div>
|
||||||
@ -320,10 +320,12 @@ const Bots: NextPage<BotsProps> = ({ data, date, user, theme, csrfToken }) => {
|
|||||||
export const getServerSideProps = async (ctx: Context) => {
|
export const getServerSideProps = async (ctx: Context) => {
|
||||||
const parsed = parseCookie(ctx.req)
|
const parsed = parseCookie(ctx.req)
|
||||||
const data = await get.bot.load(ctx.query.id) ?? { id: '' }
|
const data = await get.bot.load(ctx.query.id) ?? { id: '' }
|
||||||
|
const desc = await get.botDescSafe(data.id)
|
||||||
const user = await get.Authorization(parsed?.token)
|
const user = await get.Authorization(parsed?.token)
|
||||||
return {
|
return {
|
||||||
props: {
|
props: {
|
||||||
data,
|
data,
|
||||||
|
desc,
|
||||||
date: SnowflakeUtil.deconstruct(data.id ?? '0').date.toJSON(),
|
date: SnowflakeUtil.deconstruct(data.id ?? '0').date.toJSON(),
|
||||||
user: await get.user.load(user || ''),
|
user: await get.user.load(user || ''),
|
||||||
csrfToken: getToken(ctx.req, ctx.res)
|
csrfToken: getToken(ctx.req, ctx.res)
|
||||||
@ -335,6 +337,7 @@ export default Bots
|
|||||||
|
|
||||||
interface BotsProps {
|
interface BotsProps {
|
||||||
data: Bot
|
data: Bot
|
||||||
|
desc: string
|
||||||
date: Date
|
date: Date
|
||||||
user: User
|
user: User
|
||||||
theme: Theme
|
theme: Theme
|
||||||
|
|||||||
@ -122,6 +122,12 @@ export const reportCats = [
|
|||||||
'기타',
|
'기타',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
export const imageSafeHost = [
|
||||||
|
'koreanbots.dev',
|
||||||
|
'githubusercontent.com',
|
||||||
|
'cdn.discordapp.com'
|
||||||
|
]
|
||||||
|
|
||||||
export const MessageColor = {
|
export const MessageColor = {
|
||||||
success: 'bg-green-200 text-green-800',
|
success: 'bg-green-200 text-green-800',
|
||||||
error: 'bg-red-200 text-red-800',
|
error: 'bg-red-200 text-red-800',
|
||||||
@ -131,7 +137,8 @@ export const MessageColor = {
|
|||||||
|
|
||||||
export const BASE_URLs = {
|
export const BASE_URLs = {
|
||||||
api: 'https://discord.com/api',
|
api: 'https://discord.com/api',
|
||||||
cdn: 'https://cdn.discordapp.com'
|
cdn: 'https://cdn.discordapp.com',
|
||||||
|
camo: 'https://camo.koreanbots.dev'
|
||||||
}
|
}
|
||||||
|
|
||||||
export const BotBadgeType = (data: Bot) => {
|
export const BotBadgeType = (data: Bot) => {
|
||||||
|
|||||||
@ -4,13 +4,14 @@ import DataLoader from 'dataloader'
|
|||||||
import { User as DiscordUser } from 'discord.js'
|
import { User as DiscordUser } from 'discord.js'
|
||||||
|
|
||||||
import { Bot, User, ListType, BotList, TokenRegister, BotFlags, DiscordUserFlags, SubmittedBot } from '@types'
|
import { Bot, User, ListType, BotList, TokenRegister, BotFlags, DiscordUserFlags, SubmittedBot } from '@types'
|
||||||
import { categories, SpecialEndPoints } from './Constants'
|
import { categories, imageSafeHost, SpecialEndPoints } from './Constants'
|
||||||
|
|
||||||
import knex from './Knex'
|
import knex from './Knex'
|
||||||
import { DiscordBot, getMainGuild } from './DiscordBot'
|
import { DiscordBot, getMainGuild } from './DiscordBot'
|
||||||
import { sign, verify } from './Jwt'
|
import { sign, verify } from './Jwt'
|
||||||
import { formData, serialize } from './Tools'
|
import { camoUrl, formData, serialize } from './Tools'
|
||||||
import { AddBotSubmit, ManageBot } from './Yup'
|
import { AddBotSubmit, ManageBot } from './Yup'
|
||||||
|
import { markdownImage } from './Regex'
|
||||||
|
|
||||||
export const imageRateLimit = new TLRU<unknown, number>({ maxAgeMs: 60000 })
|
export const imageRateLimit = new TLRU<unknown, number>({ maxAgeMs: 60000 })
|
||||||
|
|
||||||
@ -43,7 +44,6 @@ async function getBot(id: string, owners=true):Promise<Bot> {
|
|||||||
.orWhere({ vanity: id, trusted: true })
|
.orWhere({ vanity: id, trusted: true })
|
||||||
.orWhere({ vanity: id, partnered: true })
|
.orWhere({ vanity: id, partnered: true })
|
||||||
if (res[0]) {
|
if (res[0]) {
|
||||||
|
|
||||||
const discordBot = await get.discord.user.load(res[0].id)
|
const discordBot = await get.discord.user.load(res[0].id)
|
||||||
await getMainGuild()?.members?.fetch(res[0].id).catch(e=> e)
|
await getMainGuild()?.members?.fetch(res[0].id).catch(e=> e)
|
||||||
if(!discordBot) return null
|
if(!discordBot) return null
|
||||||
@ -353,6 +353,17 @@ export const get = {
|
|||||||
async (ids: string[]) =>
|
async (ids: string[]) =>
|
||||||
(await Promise.all(ids.map(async (el: string) => await getBot(el, false)))).map(row => serialize(row))
|
(await Promise.all(ids.map(async (el: string) => await getBot(el, false)))).map(row => serialize(row))
|
||||||
, { cacheMap: new TLRU({ maxStoreSize: 50, maxAgeMs: 60000 }) }),
|
, { cacheMap: new TLRU({ maxStoreSize: 50, maxAgeMs: 60000 }) }),
|
||||||
|
botDescSafe: async (id: string) => {
|
||||||
|
const bot = await get.bot.load(id)
|
||||||
|
return bot?.desc.replace(markdownImage, (matches: string, alt: string|undefined, link: string|undefined, description: string|undefined): string => {
|
||||||
|
try {
|
||||||
|
const url = new URL(link)
|
||||||
|
return `) ? link : camoUrl(link) })`
|
||||||
|
} catch {
|
||||||
|
return matches
|
||||||
|
}
|
||||||
|
}) || null
|
||||||
|
},
|
||||||
user: new DataLoader(
|
user: new DataLoader(
|
||||||
async (ids: string[]) =>
|
async (ids: string[]) =>
|
||||||
(await Promise.all(ids.map(async (el: string) => await getUser(el)))).map(row => serialize(row))
|
(await Promise.all(ids.map(async (el: string) => await getUser(el)))).map(row => serialize(row))
|
||||||
|
|||||||
@ -11,3 +11,4 @@ export const Emoji =
|
|||||||
export const Heading = '<h\\d id="(.+?)">(.*?)<\\/h(\\d)>'
|
export const Heading = '<h\\d id="(.+?)">(.*?)<\\/h(\\d)>'
|
||||||
export const EmojiSyntax = ':(\\w+):'
|
export const EmojiSyntax = ':(\\w+):'
|
||||||
export const ImageTag = /<img\s[^>]*?alt\s*=\s*['"]([^'"]*?)['"][^>]*?>/
|
export const ImageTag = /<img\s[^>]*?alt\s*=\s*['"]([^'"]*?)['"][^>]*?>/
|
||||||
|
export const markdownImage = /!\[([^\]]*)\]\((.*?)\s*("(?:.*[^"])")?\s*\)/g
|
||||||
@ -5,7 +5,7 @@ import { KoreanbotsEmoji } from './Constants'
|
|||||||
export const anchorHeader = {
|
export const anchorHeader = {
|
||||||
type: 'output',
|
type: 'output',
|
||||||
regex: Heading,
|
regex: Heading,
|
||||||
replace: function (__match: string, id:string, title:string, level:number) {
|
replace: function (__match: string, id:string, title:string, level:number): string {
|
||||||
|
|
||||||
// github anchor style
|
// github anchor style
|
||||||
const href = id.replace(ImageTag, '$1').replace(/"/gi, '')
|
const href = id.replace(ImageTag, '$1').replace(/"/gi, '')
|
||||||
@ -33,7 +33,7 @@ export const twemoji = {
|
|||||||
export const customEmoji = {
|
export const customEmoji = {
|
||||||
type: 'output',
|
type: 'output',
|
||||||
regex: EmojiSyntax,
|
regex: EmojiSyntax,
|
||||||
replace: function(__match: string, name: string) {
|
replace: function(__match: string, name: string): string {
|
||||||
const result = KoreanbotsEmoji.find(el => el.short_names.includes(name))
|
const result = KoreanbotsEmoji.find(el => el.short_names.includes(name))
|
||||||
if(!name || !result) return `:${name}:`
|
if(!name || !result) return `:${name}:`
|
||||||
return `<img class="emoji special" draggable="false" alt="${name}" src="${result.imageUrl}"/>`
|
return `<img class="emoji special" draggable="false" alt="${name}" src="${result.imageUrl}"/>`
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
|
import { createHmac } from 'crypto'
|
||||||
import { Readable } from 'stream'
|
import { Readable } from 'stream'
|
||||||
import cookie from 'cookie'
|
import cookie from 'cookie'
|
||||||
|
|
||||||
import { BotFlags, ImageOptions, UserFlags } from '@types'
|
import { BotFlags, ImageOptions, UserFlags } from '@types'
|
||||||
import { KoreanbotsEndPoints, Oauth } from './Constants'
|
import { BASE_URLs, KoreanbotsEndPoints, Oauth } from './Constants'
|
||||||
import { NextRouter } from 'next/router'
|
import { NextRouter } from 'next/router'
|
||||||
|
|
||||||
export function formatNumber(value: number):string {
|
export function formatNumber(value: number):string {
|
||||||
@ -121,4 +122,21 @@ export function cleanObject<T extends Record<any, any>>(obj: T): T {
|
|||||||
return obj
|
return obj
|
||||||
}
|
}
|
||||||
|
|
||||||
export { anchorHeader, twemoji, customEmoji } from './ShowdownExtensions'
|
export function camoUrl(url: string): string {
|
||||||
|
return BASE_URLs.camo + `/${HMAC(url)}/${toHex(url)}`
|
||||||
|
}
|
||||||
|
|
||||||
|
export function HMAC(value: string, secret=process.env.CAMO_SECRET):string|null {
|
||||||
|
try {
|
||||||
|
return createHmac('sha1', secret).update(value, 'utf8').digest('hex')
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function toHex(value: string): string {
|
||||||
|
return Buffer.from(value).toString('hex')
|
||||||
|
}
|
||||||
|
|
||||||
|
export * from './ShowdownExtensions'
|
||||||
Loading…
x
Reference in New Issue
Block a user