From ae47f741b89eba80e9fa18445b50f4ab195ae38c Mon Sep 17 00:00:00 2001 From: Junseo Park Date: Thu, 27 May 2021 22:25:29 +0900 Subject: [PATCH] v2 Release (#154) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore(deps): update dependency typescript to v4.2.4 (#314) Co-authored-by: Renovate Bot * fix(deps): update dependency core-js to v3.10.1 (#315) Co-authored-by: Renovate Bot * feat: camo images in bot desc * chore: added bot delete api * feat: delete button working * feat: added bot remove method * chore: added csrfCaptchaSchema * deps: update * fix: some error at callback * fix(deps): pin dependency abort-controller to 3.0.0 (#313) Co-authored-by: Renovate Bot * chore(deps): update dependency @types/node-fetch to v2.5.10 (#316) Co-authored-by: Renovate Bot * chore(deps): update dependency eslint-plugin-react to v7.23.2 (#317) Co-authored-by: Renovate Bot * style: fixed for deepscan * chore: improved user login interaction * fix(deps): update dependency @sentry/webpack-plugin to v1.15.0 (#318) * chore(deps): update dependency eslint to v7.24.0 (#320) * fix(deps): update dependency postcss to v8.2.10 (#321) Co-authored-by: Renovate Bot * ci: updated ci stuff * style: removed unnecessary script * fix: not using SENTRY_RELEASE env * chore: defaulting mysql password * chore: added sentry_dsn env and only uploading for master * ci: updated trigger * ci: passing source branch env only at push * chore(deps): update typescript-eslint monorepo to v4.22.0 (#322) Co-authored-by: Renovate Bot * chore(deps): update dependency eslint-config-prettier to v8.2.0 (#323) Co-authored-by: Renovate Bot * chore(deps): update dependency @types/react-select to v4.0.15 (#325) Co-authored-by: Renovate Bot * chore(deps): update dependency eslint-plugin-prettier to v3.4.0 (#326) Co-authored-by: Renovate Bot * chore(deps): update dependency @types/sanitize-html to v2 (#328) Co-authored-by: Renovate Bot * chore(deps): update dependency @types/node to v14.14.41 (#324) Co-authored-by: Renovate Bot * chore(deps): update dependency ts-jest to v26.5.5 (#327) Co-authored-by: Renovate Bot * ci: debugging * Update components/DeveloperLayout.tsx Co-authored-by: zero734kr * Update components/Loader.tsx Co-authored-by: zero734kr * Update components/ColorCard.tsx Co-authored-by: zero734kr * Update components/ColorCard.tsx Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * fix(deps): update dependency core-js to v3.11.0 (#329) Co-authored-by: Renovate Bot * chore(deps): update dependency @types/sanitize-html to v2.3.1 (#330) Co-authored-by: Renovate Bot * fix(deps): update dependency postcss to v8.2.13 (#333) Co-authored-by: Renovate Bot * fix(deps): update dependency tailwindcss to v2.1.2 (#334) Co-authored-by: Renovate Bot * chore(deps): update dependency eslint to v7.25.0 (#335) Co-authored-by: Renovate Bot * fix(deps): update dependency @sentry/webpack-plugin to v1.15.1 (#332) Co-authored-by: Renovate Bot * chore(deps): update dependency @types/node to v14.14.43 (#339) Co-authored-by: Renovate Bot * chore(deps): update dependency @types/jest to v26.0.23 (#337) Co-authored-by: Renovate Bot * chore(deps): update dependency eslint-config-prettier to v8.3.0 (#336) Co-authored-by: Renovate Bot * chore(deps): update dependency @types/react to v17.0.4 (#338) Co-authored-by: Renovate Bot * Update utils/ShowdownExtensions.ts Co-authored-by: zero734kr * style: fixed some styles * chore: updated api-docs git * refactor: made change on sentry * style: removed debug code * deps: removed node-mock * ci: removed env * style: code style * test: module names * chore: docker using python * chore: docker using build-base * ci: fixed syntax error * chore: changed sql type * feat: added vote * fix: version for v1 * feat: added v1 bot vote check * feat: clearing cache for deleted bot * chore: delete bot real working IMPORTANT: NOW DELETE BOT REAL WORKS! * fix: router called at non-client * style: removed space * feat: added vote check endpoint * fix: router called at non-client * fix(deps): update sentry monorepo to v6.3.5 (#331) Co-authored-by: Renovate Bot * fix(deps): update dependency core-js to v3.11.2 (#340) Co-authored-by: Renovate Bot * chore(deps): update dependency @types/react to v17.0.5 (#345) Co-authored-by: Renovate Bot * chore(deps): update typescript-eslint monorepo to v4.22.1 (#343) Co-authored-by: Renovate Bot * fix: BotCard button component rendered as Tag * feat: update docs * feat: using koreanbots cdn for og image * fix: missing querystring label * docs: some text change https://github.com/koreanbots/v2-testing/issues/72#issuecomment-807929228 * fix: removed unexpected char close: https://github.com/koreanbots/v2-testing/issues/76 * fix: redirecting at serverside * fix(deps): pin dependencies (#342) Co-authored-by: Renovate Bot * chore(deps): update dependency ts-jest to v26.5.6 (#347) Co-authored-by: Renovate Bot * fix(deps): update dependency postcss to v8.2.14 (#349) Co-authored-by: Renovate Bot * fix(deps): update dependency core-js to v3.11.3 (#348) Co-authored-by: Renovate Bot * fix: router instance called at serverside while rendering * Merge branch 'master' of https://github.com/koreanbots/koreanbots * feat: Sentry enabled only at production * fix: menu not closing close: https://github.com/koreanbots/v2-testing/issues/50 * chore: improved mobile design * fix: tooltip overflows screen close: https://github.com/koreanbots/v2-testing/issues/28 * fix: router called at server-side close: https://github.com/koreanbots/v2-testing/issues/77 * typo: fixed typo issue * typo: improved typo * fix: router called at serverside * chore: removed custom scrollbar style * style: fixed null checks * feat: added owner transfer and edit * chore: clearing cache for updates * chore: redirecting on update * chore: added button margin * feat: disabled webhook * chore: added some spaces * feat: added padding for ad * feat: remove wave * feat: added security page * chore: some margin * feat: added bug reporters * style: fixed eslint * fix(developers): https://github.com/koreanbots/v2-testing/issues/74 * chore: improved ad * feat: migrated to @sentry/nextjs * fix: card invite button fixed * chore: not releasing * chore: debugging * chore: skiping sentry auto release * feat: added docker hub build hook * fix: docker hook * fix: docker hook geting sentry dsn as build-arg * chore: added sentry envs * chore(docker): cleanup * fix: bugs at card * typo: fixed * chore: margin top at message * fix: card building weird * fix: sentry disabled * fix: query string invalid fix: https://github.com/koreanbots/v2-testing/issues/92 * fix: https://github.com/koreanbots/v2-testing/issues/94 * chore: improved style close: https://github.com/koreanbots/v2-testing/issues/83 * fix: scrollbar shown even its not overflowed fix: https://github.com/koreanbots/v2-testing/issues/86 * fix: home not displayed at dev portal fix: https://github.com/koreanbots/v2-testing/issues/84 * types: searchParams is optional prop * feat: added required field notice close: https://github.com/koreanbots/v2-testing/issues/90 * typo: fixed typo issues For https://github.com/koreanbots/v2-testing/issues/79 * fix: causing error on other git url ISSUE: https://sentry.io/share/issue/a13341dc1aab4e5aa994fee8857afff7/ * fix: handle AbortError * chore(deps): update dependency eslint to v7.26.0 (#353) Co-authored-by: Renovate Bot * fix(deps): update dependency core-js to v3.12.1 (#350) Co-authored-by: Renovate Bot * chore: reordered bot section * typo: fixed typo issue from https://github.com/koreanbots/v2-testing/issues/79 * feat: opening new tab for discord link close: https://github.com/koreanbots/v2-testing/issues/99 * feat: added opensearch * Update renovate.json * chore: prevent clickjacking * chore: added moz SearchForm for opensearch xml * fix(deps): update dependency rc-tooltip to v5 (#351) Co-authored-by: Renovate Bot * fix(deps): update sentry monorepo to v6.3.6 (#354) Co-authored-by: Renovate Bot * chore(deps): update dependency prettier to v2.3.0 (#355) Co-authored-by: Renovate Bot * chore(deps): update typescript-eslint monorepo to v4.23.0 (#356) Co-authored-by: Renovate Bot * fix(deps): update dependency postcss to v8.2.15 (#357) Co-authored-by: Renovate Bot * fix(deps): update dependency react-select to v4.3.1 (#358) Co-authored-by: Renovate Bot * fix(deps): update dependency knex to v0.95.5 (#359) Co-authored-by: Renovate Bot * style: added space * feat: added get botSubmits list api * chore: updated endpoint * typo: fixed and improved typo issues * chore: improved message for empty category close: https://github.com/koreanbots/v2-testing/issues/100 * feat: support pwa * types: added missing typing * chore: changed manifest * fix: catching error for ga blocked * fix: added missing argument * chore: made some changes * style: could be null * chore: improved pwa * fix: https://github.com/koreanbots/v2-testing/issues/105 * feat: added staff missing permission * fix: https://github.com/koreanbots/v2-testing/issues/104 * feat: added width style * Update pages/_app.tsx Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * style: suggestions at review * feat: updated api-docs * chore: added dest option * chore: changed icon path * feat: just commiting service worker * feat: added bug bounty group * ci: removed reviewdog * feat: added google optimize * chore: added maskable icon and changed short_name * ci: made some changes on renovate * Create SECURITY.md * feat: fetching docs from github * feat: added tos at footer * feat(iOS): added pwa splash screen * types: improved component typing * feat: discord rebranded * ci: configured renovate ignore * [TYPO] 기여 규칙 링크 수정 (#367) * fix(deps): update sentry monorepo to v6.4.0 (#364) * feat: added logging * style: reordered import * feat: improved logging * feat: private api changes * feat: added OG * chore: updated migrate.sql * ci: updated renovate * fix: seo * feat: added approve api * chore: some changes at deny * feat: added approve * refactor: using next-seo for seo * ci(renovate): removed unused option * chore: not passing pwa at navbar * style: removed line break * fix: https://github.com/koreanbots/v2-testing/issues/89 * feat: directly fetching from discord * feat: support searching with index * style: fix deepscan * fix: invalid avatar url * fix: https://github.com/koreanbots/v2-testing/issues/110 reopen: https://github.com/koreanbots/v2-testing/issues/89 * feat: added error message at submit button * fix: https://github.com/koreanbots/v2-testing/issues/89 * feat: added deny presets article * feat: added query aliases * chore: update docs * chore: remvoed empty file * feat: increased ratelimit * feat: added bot lists * style: removed unused variable * fix(deps): update dependency knex to v0.95.6 (#365) * chore(deps): update typescript-eslint monorepo to v4.24.0 (#366) * chore(deps): update dependency @types/react to v17.0.6 (#368) * fix(deps): update dependency formik to v2.2.8 (#369) * fix(deps): update dependency next to v10.2.2 (#370) * fix(deps): update sentry monorepo to v6.4.1 (#371) * fix(deps): update dependency sanitize-html to v2.4.0 (#372) * fix(deps): update dependency postcss to v8.3.0 (#373) * docs: updated license * feat: added refresh data * feat: better image size close: https://github.com/koreanbots/v2-testing/issues/81 * chore: changed slogan * fix: invalid v1 api * fix: forbidden error * feat: added char count at textarea close: https://github.com/koreanbots/v2-testing/issues/112 * feat: changed edit page route * fix(deps): update dependency next to v10.2.3 (#376) Co-authored-by: Renovate Bot * chore(deps): update dependency typescript to v4.3.2 (#383) Co-authored-by: Renovate Bot * chore(deps): update dependency eslint to v7.27.0 (#374) Co-authored-by: Renovate Bot * deps: removed core-js * deps: lock updated * feat: added stable docker compose file Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Renovate Bot Co-authored-by: zero734kr Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: MintyU --- .all-contributorsrc | 35 + .dockerignore | 8 + .env.demo.local | 15 + .eslintrc.js | 41 + .github/CONTRIBUTING.md | 78 + .../ISSUE_TEMPLATE/{bug.md => bug_report.md} | 12 +- .github/assets/koreanbots-en.png | Bin 0 -> 4600 bytes .github/assets/koreanbots-ko.png | Bin 0 -> 15583 bytes .github/renovate.json | 7 + .github/workflows/testing.yml | 92 + .gitignore | 46 + .gitmodules | 4 + .prettierignore | 2 + .prettierrc.js | 11 + .vscode/settings.json | 7 + Dockerfile | 36 + LICENSE | 677 + README.en.md | 85 + README.md | 102 +- SECURITY.md | 9 + api-docs | 1 + app.css | 192 + components/Advertisement.tsx | 49 + components/Application.tsx | 22 + components/BotCard.tsx | 124 + components/Button.tsx | 47 + components/Captcha.tsx | 15 + components/ColorCard.tsx | 21 + components/Container.tsx | 27 + components/DeveloperLayout.tsx | 104 + components/DiscordAvatar.tsx | 60 + components/Divider.tsx | 17 + components/Docs.tsx | 38 + components/Footer.tsx | 118 + components/Forbidden.tsx | 26 + components/Form/CheckBox.tsx | 12 + components/Form/CsrfToken.tsx | 11 + components/Form/Input.tsx | 18 + components/Form/Label.tsx | 44 + components/Form/Select.tsx | 43 + components/Form/Selects.tsx | 74 + components/Form/TextArea.tsx | 69 + components/Hero.tsx | 44 + components/Loader.tsx | 20 + components/Login.tsx | 17 + components/LongButton.tsx | 38 + components/Markdown.tsx | 127 + components/Message.tsx | 19 + components/Modal.tsx | 43 + components/NSFW.tsx | 33 + components/Navbar.tsx | 219 + components/Notice.tsx | 21 + components/Owner.tsx | 26 + components/Paginator.tsx | 83 + components/PlatformDisplay.tsx | 13 + components/Redirect.tsx | 31 + components/ResponsiveGrid.tsx | 7 + components/SEO.tsx | 21 + components/Search.tsx | 180 + components/Segment.tsx | 18 + components/SubmittedBotCard.tsx | 47 + components/Tag.tsx | 107 + components/Toggle.tsx | 28 + components/Tooltip.tsx | 115 + components/Wave.tsx | 17 + docker-compose-stable.yml | 23 + docker-compose.yml | 27 + eco.config.js | 14 + github-markdown.css | 1069 ++ hooks/build | 3 + jest.config.js | 10 + migrate.sql | 72 +- next-env.d.ts | 2 + next.config.js | 28 + package.json | 101 + pages/404.tsx | 24 + pages/_app.tsx | 188 + pages/_document.tsx | 90 + pages/_error.tsx | 31 + pages/_offline.tsx | 29 + pages/about.tsx | 78 + pages/addbot.tsx | 222 + pages/api/[...404].ts | 8 + pages/api/_custom/429.ts | 13 + pages/api/auth/discord/callback.ts | 77 + pages/api/auth/discord/index.ts | 12 + pages/api/auth/discord/logout.ts | 15 + pages/api/auth/github/callback.ts | 48 + pages/api/auth/github/index.ts | 30 + pages/api/image/discord/avatars/[id].ts | 64 + pages/api/index.ts | 1 + pages/api/v1/[[...deprecated]].ts | 12 + pages/api/v1/bots/servers.ts | 51 + pages/api/v1/bots/voted/[id].ts | 27 + pages/api/v2/applications/bots/[id]/index.ts | 38 + pages/api/v2/applications/bots/[id]/reset.ts | 39 + pages/api/v2/bots/[id]/index.ts | 171 + pages/api/v2/bots/[id]/owners.ts | 50 + pages/api/v2/bots/[id]/report.ts | 53 + pages/api/v2/bots/[id]/stats.ts | 88 + pages/api/v2/bots/[id]/vote.ts | 57 + pages/api/v2/index.ts | 10 + pages/api/v2/list/bots/new.ts | 12 + pages/api/v2/list/bots/votes.ts | 19 + .../bots/submits/[id]/[date]/approve.ts | 37 + .../bots/submits/[id]/[date]/deny.ts | 36 + .../bots/submits/[id]/[date]/index.ts | 24 + .../v2/management/bots/submits/[id]/index.ts | 23 + pages/api/v2/management/bots/submits/index.ts | 14 + pages/api/v2/management/index.ts | 9 + pages/api/v2/search/bots.ts | 39 + pages/api/v2/users/@me.ts | 19 + pages/api/v2/users/[id]/index.ts | 20 + pages/api/v2/users/[id]/report.ts | 52 + pages/api/widget/bots/[type]/[id].ts | 65 + pages/bots/[id]/edit.tsx | 350 + pages/bots/[id]/index.tsx | 381 + pages/bots/[id]/vote.tsx | 127 + pages/bots/koreanbots.tsx | 10 + pages/calculator.tsx | 125 + pages/callback/discord.tsx | 28 + pages/categories/[category].tsx | 81 + pages/categories/index.tsx | 35 + pages/debug.tsx | 88 + pages/developers/applications/bots/[id].tsx | 155 + pages/developers/applications/index.tsx | 42 + pages/developers/docs/[first]/[second].tsx | 97 + pages/developers/docs/[first]/index.tsx | 1 + pages/developers/docs/index.tsx | 15 + pages/developers/index.tsx | 15 + pages/discord.tsx | 11 + pages/guidelines.tsx | 37 + pages/index.tsx | 72 + pages/iu.tsx | 12 + pages/license.tsx | 71 + pages/list/new.tsx | 41 + pages/list/votes.tsx | 63 + pages/panel.tsx | 91 + pages/pendingBots/[id]/[date].tsx | 224 + pages/privacy.tsx | 32 + pages/profile.tsx | 10 + pages/search.tsx | 76 + pages/security.tsx | 79 + pages/tos.tsx | 37 + pages/users/[id].tsx | 215 + pages/verification.tsx | 63 + postcss.config.js | 17 + public/ads.txt | 1 + public/browserconfig.xml | 2 + public/emojis/discord.svg | 1 + public/emojis/javascript.png | Bin 0 -> 24040 bytes public/emojis/python.png | Bin 0 -> 32180 bytes public/fallback-development.js | 36 + public/favicon-16x16.png | Bin 0 -> 1112 bytes public/favicon-32x32.png | Bin 0 -> 1731 bytes public/favicon-96x96.png | Bin 0 -> 5073 bytes public/favicon.ico | Bin 0 -> 1150 bytes public/img/default.png | Bin 0 -> 3522 bytes public/img/heart.svg | 10 + public/logo.png | Bin 0 -> 3256 bytes public/logofont.otf | Bin 0 -> 113772 bytes public/manifest.json | 61 + public/opensearch.xml | 8 + public/robots.txt | 1 + public/static/android-icon-144x144.png | Bin 0 -> 7286 bytes public/static/android-icon-192x192.png | Bin 0 -> 8183 bytes public/static/android-icon-36x36.png | Bin 0 -> 1852 bytes public/static/android-icon-48x48.png | Bin 0 -> 2239 bytes public/static/android-icon-512x512.png | Bin 0 -> 19449 bytes public/static/android-icon-72x72.png | Bin 0 -> 3918 bytes public/static/android-icon-96x96.png | Bin 0 -> 5073 bytes public/static/apple-icon-114x114.png | Bin 0 -> 5926 bytes public/static/apple-icon-120x120.png | Bin 0 -> 6061 bytes public/static/apple-icon-144x144.png | Bin 0 -> 7286 bytes public/static/apple-icon-152x152.png | Bin 0 -> 7811 bytes public/static/apple-icon-180x180.png | Bin 0 -> 9390 bytes public/static/apple-icon-256x256.png | Bin 0 -> 8561 bytes public/static/apple-icon-512x512.png | Bin 0 -> 19449 bytes public/static/apple-icon-57x57.png | Bin 0 -> 3017 bytes public/static/apple-icon-60x60.png | Bin 0 -> 3122 bytes public/static/apple-icon-72x72.png | Bin 0 -> 3918 bytes public/static/apple-icon-76x76.png | Bin 0 -> 4005 bytes public/static/apple-icon-precomposed.png | Bin 0 -> 8757 bytes public/static/apple-icon.png | Bin 0 -> 8757 bytes public/static/ipad_splash.png | Bin 0 -> 97271 bytes public/static/ipadpro1_splash.png | Bin 0 -> 107940 bytes public/static/ipadpro2_splash.png | Bin 0 -> 143065 bytes public/static/ipadpro3_splash.png | Bin 0 -> 113061 bytes public/static/iphone5_splash.png | Bin 0 -> 43801 bytes public/static/iphone6_splash.png | Bin 0 -> 52380 bytes public/static/iphoneplus_splash.png | Bin 0 -> 89955 bytes public/static/iphonex_splash.png | Bin 0 -> 97081 bytes public/static/iphonexr_splash.png | Bin 0 -> 63276 bytes public/static/iphonexsmax_splash.png | Bin 0 -> 102399 bytes public/static/maskable-icon-192x192.png | Bin 0 -> 8015 bytes public/static/ms-icon-144x144.png | Bin 0 -> 7286 bytes public/static/ms-icon-150x150.png | Bin 0 -> 7653 bytes public/static/ms-icon-310x310.png | Bin 0 -> 19531 bytes public/static/ms-icon-70x70.png | Bin 0 -> 3747 bytes public/sw.js | 136 + public/workbox.js | 2700 ++++ sentry.client.config.js | 16 + sentry.properties | 5 + sentry.server.config.js | 16 + tailwind.config.js | 51 + tests/utils.test.ts | 27 + tsconfig.json | 25 + types/global.d.ts | 24 + types/index.ts | 252 + utils/Constants.ts | 446 + utils/Csrf.ts | 40 + utils/Day.ts | 10 + utils/DiscordBot.ts | 32 + utils/Fetch.ts | 25 + utils/Jwt.ts | 26 + utils/Knex.ts | 12 + utils/Logger.ts | 20 + utils/Query.ts | 509 + utils/RateLimitHandler.ts | 23 + utils/Regex.ts | 14 + utils/RequestHandler.ts | 34 + utils/ResponseWrapper.ts | 25 + utils/ShowdownExtensions.ts | 41 + utils/Tools.ts | 188 + utils/Yup.ts | 323 + utils/useOutsideClick.ts | 19 + yarn.lock | 10243 ++++++++++++++++ 227 files changed, 24915 insertions(+), 105 deletions(-) create mode 100644 .all-contributorsrc create mode 100644 .dockerignore create mode 100644 .env.demo.local create mode 100644 .eslintrc.js create mode 100644 .github/CONTRIBUTING.md rename .github/ISSUE_TEMPLATE/{bug.md => bug_report.md} (93%) create mode 100644 .github/assets/koreanbots-en.png create mode 100644 .github/assets/koreanbots-ko.png create mode 100644 .github/renovate.json create mode 100644 .github/workflows/testing.yml create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 .prettierignore create mode 100644 .prettierrc.js create mode 100644 .vscode/settings.json create mode 100644 Dockerfile create mode 100644 LICENSE create mode 100644 README.en.md create mode 100644 SECURITY.md create mode 160000 api-docs create mode 100644 app.css create mode 100644 components/Advertisement.tsx create mode 100644 components/Application.tsx create mode 100644 components/BotCard.tsx create mode 100644 components/Button.tsx create mode 100644 components/Captcha.tsx create mode 100644 components/ColorCard.tsx create mode 100644 components/Container.tsx create mode 100644 components/DeveloperLayout.tsx create mode 100644 components/DiscordAvatar.tsx create mode 100644 components/Divider.tsx create mode 100644 components/Docs.tsx create mode 100644 components/Footer.tsx create mode 100644 components/Forbidden.tsx create mode 100644 components/Form/CheckBox.tsx create mode 100644 components/Form/CsrfToken.tsx create mode 100644 components/Form/Input.tsx create mode 100644 components/Form/Label.tsx create mode 100644 components/Form/Select.tsx create mode 100644 components/Form/Selects.tsx create mode 100644 components/Form/TextArea.tsx create mode 100644 components/Hero.tsx create mode 100644 components/Loader.tsx create mode 100644 components/Login.tsx create mode 100644 components/LongButton.tsx create mode 100644 components/Markdown.tsx create mode 100644 components/Message.tsx create mode 100644 components/Modal.tsx create mode 100644 components/NSFW.tsx create mode 100644 components/Navbar.tsx create mode 100644 components/Notice.tsx create mode 100644 components/Owner.tsx create mode 100644 components/Paginator.tsx create mode 100644 components/PlatformDisplay.tsx create mode 100644 components/Redirect.tsx create mode 100644 components/ResponsiveGrid.tsx create mode 100644 components/SEO.tsx create mode 100644 components/Search.tsx create mode 100644 components/Segment.tsx create mode 100644 components/SubmittedBotCard.tsx create mode 100644 components/Tag.tsx create mode 100644 components/Toggle.tsx create mode 100644 components/Tooltip.tsx create mode 100644 components/Wave.tsx create mode 100644 docker-compose-stable.yml create mode 100644 docker-compose.yml create mode 100644 eco.config.js create mode 100644 github-markdown.css create mode 100644 hooks/build create mode 100644 jest.config.js create mode 100644 next-env.d.ts create mode 100644 next.config.js create mode 100644 package.json create mode 100644 pages/404.tsx create mode 100644 pages/_app.tsx create mode 100644 pages/_document.tsx create mode 100644 pages/_error.tsx create mode 100644 pages/_offline.tsx create mode 100644 pages/about.tsx create mode 100644 pages/addbot.tsx create mode 100644 pages/api/[...404].ts create mode 100644 pages/api/_custom/429.ts create mode 100644 pages/api/auth/discord/callback.ts create mode 100644 pages/api/auth/discord/index.ts create mode 100644 pages/api/auth/discord/logout.ts create mode 100644 pages/api/auth/github/callback.ts create mode 100644 pages/api/auth/github/index.ts create mode 100644 pages/api/image/discord/avatars/[id].ts create mode 100644 pages/api/index.ts create mode 100644 pages/api/v1/[[...deprecated]].ts create mode 100644 pages/api/v1/bots/servers.ts create mode 100644 pages/api/v1/bots/voted/[id].ts create mode 100644 pages/api/v2/applications/bots/[id]/index.ts create mode 100644 pages/api/v2/applications/bots/[id]/reset.ts create mode 100644 pages/api/v2/bots/[id]/index.ts create mode 100644 pages/api/v2/bots/[id]/owners.ts create mode 100644 pages/api/v2/bots/[id]/report.ts create mode 100644 pages/api/v2/bots/[id]/stats.ts create mode 100644 pages/api/v2/bots/[id]/vote.ts create mode 100644 pages/api/v2/index.ts create mode 100644 pages/api/v2/list/bots/new.ts create mode 100644 pages/api/v2/list/bots/votes.ts create mode 100644 pages/api/v2/management/bots/submits/[id]/[date]/approve.ts create mode 100644 pages/api/v2/management/bots/submits/[id]/[date]/deny.ts create mode 100644 pages/api/v2/management/bots/submits/[id]/[date]/index.ts create mode 100644 pages/api/v2/management/bots/submits/[id]/index.ts create mode 100644 pages/api/v2/management/bots/submits/index.ts create mode 100644 pages/api/v2/management/index.ts create mode 100644 pages/api/v2/search/bots.ts create mode 100644 pages/api/v2/users/@me.ts create mode 100644 pages/api/v2/users/[id]/index.ts create mode 100644 pages/api/v2/users/[id]/report.ts create mode 100644 pages/api/widget/bots/[type]/[id].ts create mode 100644 pages/bots/[id]/edit.tsx create mode 100644 pages/bots/[id]/index.tsx create mode 100644 pages/bots/[id]/vote.tsx create mode 100644 pages/bots/koreanbots.tsx create mode 100644 pages/calculator.tsx create mode 100644 pages/callback/discord.tsx create mode 100644 pages/categories/[category].tsx create mode 100644 pages/categories/index.tsx create mode 100644 pages/debug.tsx create mode 100644 pages/developers/applications/bots/[id].tsx create mode 100644 pages/developers/applications/index.tsx create mode 100644 pages/developers/docs/[first]/[second].tsx create mode 100644 pages/developers/docs/[first]/index.tsx create mode 100644 pages/developers/docs/index.tsx create mode 100644 pages/developers/index.tsx create mode 100644 pages/discord.tsx create mode 100644 pages/guidelines.tsx create mode 100644 pages/index.tsx create mode 100644 pages/iu.tsx create mode 100644 pages/license.tsx create mode 100644 pages/list/new.tsx create mode 100644 pages/list/votes.tsx create mode 100644 pages/panel.tsx create mode 100644 pages/pendingBots/[id]/[date].tsx create mode 100644 pages/privacy.tsx create mode 100644 pages/profile.tsx create mode 100644 pages/search.tsx create mode 100644 pages/security.tsx create mode 100644 pages/tos.tsx create mode 100644 pages/users/[id].tsx create mode 100644 pages/verification.tsx create mode 100644 postcss.config.js create mode 100644 public/ads.txt create mode 100644 public/browserconfig.xml create mode 100644 public/emojis/discord.svg create mode 100644 public/emojis/javascript.png create mode 100644 public/emojis/python.png create mode 100644 public/fallback-development.js create mode 100644 public/favicon-16x16.png create mode 100644 public/favicon-32x32.png create mode 100644 public/favicon-96x96.png create mode 100644 public/favicon.ico create mode 100644 public/img/default.png create mode 100644 public/img/heart.svg create mode 100644 public/logo.png create mode 100644 public/logofont.otf create mode 100644 public/manifest.json create mode 100644 public/opensearch.xml create mode 100644 public/robots.txt create mode 100644 public/static/android-icon-144x144.png create mode 100644 public/static/android-icon-192x192.png create mode 100644 public/static/android-icon-36x36.png create mode 100644 public/static/android-icon-48x48.png create mode 100644 public/static/android-icon-512x512.png create mode 100644 public/static/android-icon-72x72.png create mode 100644 public/static/android-icon-96x96.png create mode 100644 public/static/apple-icon-114x114.png create mode 100644 public/static/apple-icon-120x120.png create mode 100644 public/static/apple-icon-144x144.png create mode 100644 public/static/apple-icon-152x152.png create mode 100644 public/static/apple-icon-180x180.png create mode 100644 public/static/apple-icon-256x256.png create mode 100644 public/static/apple-icon-512x512.png create mode 100644 public/static/apple-icon-57x57.png create mode 100644 public/static/apple-icon-60x60.png create mode 100644 public/static/apple-icon-72x72.png create mode 100644 public/static/apple-icon-76x76.png create mode 100644 public/static/apple-icon-precomposed.png create mode 100644 public/static/apple-icon.png create mode 100644 public/static/ipad_splash.png create mode 100644 public/static/ipadpro1_splash.png create mode 100644 public/static/ipadpro2_splash.png create mode 100644 public/static/ipadpro3_splash.png create mode 100644 public/static/iphone5_splash.png create mode 100644 public/static/iphone6_splash.png create mode 100644 public/static/iphoneplus_splash.png create mode 100644 public/static/iphonex_splash.png create mode 100644 public/static/iphonexr_splash.png create mode 100644 public/static/iphonexsmax_splash.png create mode 100644 public/static/maskable-icon-192x192.png create mode 100644 public/static/ms-icon-144x144.png create mode 100644 public/static/ms-icon-150x150.png create mode 100644 public/static/ms-icon-310x310.png create mode 100644 public/static/ms-icon-70x70.png create mode 100644 public/sw.js create mode 100644 public/workbox.js create mode 100644 sentry.client.config.js create mode 100644 sentry.properties create mode 100644 sentry.server.config.js create mode 100644 tailwind.config.js create mode 100644 tests/utils.test.ts create mode 100644 tsconfig.json create mode 100644 types/global.d.ts create mode 100644 types/index.ts create mode 100644 utils/Constants.ts create mode 100644 utils/Csrf.ts create mode 100644 utils/Day.ts create mode 100644 utils/DiscordBot.ts create mode 100644 utils/Fetch.ts create mode 100644 utils/Jwt.ts create mode 100644 utils/Knex.ts create mode 100644 utils/Logger.ts create mode 100644 utils/Query.ts create mode 100644 utils/RateLimitHandler.ts create mode 100644 utils/Regex.ts create mode 100644 utils/RequestHandler.ts create mode 100644 utils/ResponseWrapper.ts create mode 100644 utils/ShowdownExtensions.ts create mode 100644 utils/Tools.ts create mode 100644 utils/Yup.ts create mode 100644 utils/useOutsideClick.ts create mode 100644 yarn.lock diff --git a/.all-contributorsrc b/.all-contributorsrc new file mode 100644 index 0000000..67102c1 --- /dev/null +++ b/.all-contributorsrc @@ -0,0 +1,35 @@ +{ + "files": [ + "README.md" + ], + "imageSize": 100, + "commit": false, + badgeTemplate: "", + "contributors": [ + { + "login": "wonderlandpark", + "name": "Junseo Park", + "avatar_url": "https://avatars.githubusercontent.com/u/31924512?v=4", + "profile": "https://wonder.im", + "contributions": [ + "maintenance", + "business" + ] + }, + { + "login": "zero734kr", + "name": "zero734kr", + "avatar_url": "https://avatars.githubusercontent.com/u/51540538?v=4", + "profile": "https://github.com/zero734kr", + "contributions": [ + "review" + ] + } + ], + "contributorsPerLine": 7, + "projectName": "koreanbots", + "projectOwner": "koreanbots", + "repoType": "github", + "repoHost": "https://github.com", + "skipCi": true +} diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..a839ed0 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,8 @@ +.next/ +node_modules/ +Dockerfile +yarn-error.log +.dockerignore +.git +.gitignore +.github \ No newline at end of file diff --git a/.env.demo.local b/.env.demo.local new file mode 100644 index 0000000..ea834e5 --- /dev/null +++ b/.env.demo.local @@ -0,0 +1,15 @@ +KOREANBOTS_URL=http://localhost:3000 +MYSQL_HOST=mysql +MYSQL_USER=root +MYSQL_PASSWORD=YOUSHALLNOTPASS +MYSQL_DATABASE=discordbots + +DISCORD_CLIENT_ID=CLIENT_ID +DISCORD_CLIENT_SECRET=CLIENT_SECRET +DISCORD_SCOPE=SCOPE +DISCORD_TOKEN=BOT_TOKEN + +GITHUB_CLIENT_ID=GH_CLIENT_ID +GITHUB_CLIENT_SECRET=GH_CLIENT_SECRET + +CSRF_SECRET=CSRF_SECRET \ No newline at end of file diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..1c198f9 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,41 @@ +module.exports = { + root: true, + env: { + node: true, + es6: true, + browser: true, + es2021: true, + }, + ignorePatterns: ['node_modules/*', '.next/*', '.out/*', '!.prettierrc.js'], + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', + 'plugin:react/recommended', + 'plugin:react-hooks/recommended', + 'plugin:jsx-a11y/recommended', + ], + parser: '@typescript-eslint/parser', + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + ecmaVersion: 12, + sourceType: 'module', + }, + plugins: ['react', '@typescript-eslint'], + rules: { + 'jsx-quotes': ['error', 'prefer-single'], + 'react/no-unescaped-entities': 'off', + 'react/prop-types': 'off', + 'react/react-in-jsx-scope': 'off', + 'jsx-a11y/anchor-is-valid': 'off', + 'jsx-a11y/no-noninteractive-element-interactions': 'off', + 'jsx-a11y/no-static-element-interactions': 'off', + '@typescript-eslint/explicit-function-return-type': 'off', + '@typescript-eslint/explicit-module-boundary-types': 'off', + '@typescript-eslint/no-unused-vars': ['warn'], + indent: ['error', 'tab'], + quotes: ['error', 'single'], + semi: ['error', 'never'], + }, +} diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 0000000..6ab880d --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,78 @@ +# 기여하기 + +## 이슈를 등록하기 전에 + +### 버그 + +먼저 지원하는 기기인지 확인합니다. + +#### 지원하지 않는 기기 + +```md +- 어떠한 확장프로그램 (AdBlock, Darkmode etc.) +- 브라우저: IE, Pre 17 Edge. +- Windows 7 이전의 Windows +- 10.10 버전 이하의 macOS +- 10.0 버전 이하의 iOS +- 5.0 버전 이하의 안드로이드 +- 3.5" 아이폰 +- 모든 VM +- 탈옥 또는 루팅된 기기 +- 공식 지원 종료된 모든 리눅스 버전 +- 보안 이슈 (보안과 관련된 문제는 비공개적이게 개발자에게 전달해주세요) +- 정식빌드에서는 발생하지 않는 Canary혹은 PTB와 같은 베타 버전의 브라우저/OS에서 발생하는 버그 +- 이외 개발자가 지원 종료 선언한 모든 플랫폼혹은 기기 +``` + +그 다음 이슈를 등록합니다. +[등록하기](https://github.com/koreanbots/koreanbots/issues/new/choose) + +**이슈에서는 빠른 소통을 위해 약자를 사용합니다.** +이슈를 보신다면 댓글을 남겨주세요. + +- `CR` **Can Reproduce** 의 약자로 재현 가능한 버그라는 뜻입니다. +- `CNR` **Can Not Reproduce** 의 약자로 재현이 불가능하다는 뜻입니다. +- `NAB` **Not a Bug** 의 약자로 버그에 해당하지 않는다는 뜻입니다. + +#### 승인과 거부 + +버그는 2개의 재현가능 여부에 대한 승인(Approve) 또는 거부(Deny)를 받게되면, 승인과 거부가 결정됩니다. + +##### 승인 + +버그가 재현 가능하다고 2명 이상의 유저에게 승인이 된다면, 해당 버그는 개발자의 확인을 기다리며, `approved` 라벨을 획득합니다. + +##### 거부 + +버그가 재현 가능하지않다고 2명 이상의 유저에게 거부가 된다면, 해당 버그는 `deny` 라벨을 획득하며, 이슈는 `Closed` 처리됩니다. + +### 제안 + +제안은 [Discussions](https://github.com/koreanbots/koreanbots/discussions)에서 자유롭게 해주세요! + +## 관리 + +이슈는 관리자와 버그 헌터분들이 관리합니다. + +### 버그 헌터란? + +버그 헌터는 버그를 열심히 찾아주시거나, 해당 레포지토리에 활발하게 참여하여, 특정 기준 이상을 참여해주신 유저분들에게 지급해드리는 권한입니다. + +버그헌터는 이슈를 닫거나, 라벨을 추가할 수 있으며 `Approve`와 `Deny`와 같은 상태를 관리합니다. + +### 처벌 + +이슈에서 장난식 발언을 하거나, 관련성이 없는 말 또는 스팸을 게시한다면, 통보없이 처벌되실 수 있습니다. + +## 기여 + +기여는 언제든 환영입니다 커밋메세지는 다음 규칙을 따라주시면 감사하겠습니다! + +[Conventional Commits](https://www.conventionalcommits.org/ko/v1.0.0/) + +--- + +### 기존 레포들 + +- [client](https://github.com/koreanbots/client) +- [api](https://github.com/koreanbots/api) diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug_report.md similarity index 93% rename from .github/ISSUE_TEMPLATE/bug.md rename to .github/ISSUE_TEMPLATE/bug_report.md index acccc8a..57c9b96 100644 --- a/.github/ISSUE_TEMPLATE/bug.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,32 +1,40 @@ --- -name: 🐛 버그 제보 +name: "\U0001F41B 버그 제보" about: 버그를 제보해주세요! title: "[버그] " -labels: 'bug' +labels: bug assignees: '' --- ## 재현방법 + > 어떻게하면 발생시킬 수 있나요? ## 예상되는 정상적인 동작 + > 정상이라면 어떻게 되야하나요? ## 발생한 문제 + > 어떤 문제가 발생하나요? ## 클라이언트 버전 + > 클라이언트 버전을 알려주세요! + + ## 사양 + > OS 정보와 브라우저의 버전을 알려주세요! ## 확인 + - [ ] 중복되는 이슈는 없나요? - [ ] 해당 버그를 다시 발생시킬 수 있나요? diff --git a/.github/assets/koreanbots-en.png b/.github/assets/koreanbots-en.png new file mode 100644 index 0000000000000000000000000000000000000000..d67d19e57b6dd53c1314ef8bd5471f20ae4fc3b0 GIT binary patch literal 4600 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 L_;Sfb`;h+u`xfKE literal 0 HcmV?d00001 diff --git a/.github/renovate.json b/.github/renovate.json new file mode 100644 index 0000000..c084aec --- /dev/null +++ b/.github/renovate.json @@ -0,0 +1,7 @@ +{ + "labels": ["meta: dependencies"], + "reviewers": ["team:core-developer"], + "schedule": ["before 8am"], + "extends": ["config:base"], + "timezone": "Asia/Seoul" +} diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml new file mode 100644 index 0000000..80a1b01 --- /dev/null +++ b/.github/workflows/testing.yml @@ -0,0 +1,92 @@ +name: CI +on: + push: + branches: + - 'master' + - 'stable' + pull_request: + branches: + - '*' +jobs: + eslint: + name: ESLint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: install node v14 + uses: actions/setup-node@v2 + with: + node-version: 14 + - name: yarn install + run: yarn install + - name: run eslint + run: yarn lint + env: + CI: true + test: + name: Run Test + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: install node v14 + uses: actions/setup-node@v2 + with: + node-version: 14 + - name: yarn install + run: yarn install + - name: Setup MySQL + uses: getong/mariadb-action@v1.1 + with: + mysql database: 'discordbots' + mysql root password: 'test' + - name: Wait for MySQL + run: | + while ! mysqladmin ping --host=127.0.0.1 --password=test --silent; do + sleep 1 + done + - name: Run Jest + run: yarn test + - name: Generate RSA Key Pair + run: | + ssh-keygen -b 2048 -t rsa -f key -q -P "" + ssh-keygen -b 2048 -e -m pem -f key -q -P "" > private.key + mv key public.pem + rm key.pub + - name: Setup environments + run: | + mv .env.demo.local .env.production.local + printf 'MARIADB_ROOT_PASSWORD=YOUSHALLNOTPASS\nCOMMIT_HASH=${{ github.sha }}' > .env + - name: Create needed files + run: echo '{"tester":"DEMO_KEY"}' > secret.json + - name: Build + run: yarn build + env: + CI: true + + # docker: + # needs: + # - eslint + # - build + # - test + # name: Docker Image CI + # runs-on: ubuntu-latest + # steps: + # - uses: actions/checkout@v2 + # - name: install node v14 + # uses: actions/setup-node@v1 + # with: + # node-version: 14 + # - name: Generate RSA Key Pair + # run: | + # ssh-keygen -b 2048 -t rsa -f key -q -P "" + # ssh-keygen -b 2048 -e -m pem -f key -q -P "" > private.key + # mv key public.pem + # rm key.pub + # - name: Setup environments + # run: | + # mv .env.demo.local .env.production.local + # printf 'MARIADB_ROOT_PASSWORD=YOUSHALLNOTPASS\nCOMMIT_HASH=${{ github.sha }}' > .env + # - name: Create needed files + # run: echo '{"tester":"DEMO_KEY"}' > secret.json + # - name: Docker Compose + # run: docker-compose up -d diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4939a0a --- /dev/null +++ b/.gitignore @@ -0,0 +1,46 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem +*.key + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# docker env file +.env + +# local env files +.env.local +.env.development.local +.env.test.local +.env.production.local +.env.*.production.local +.env.mysql.local + +# vercel +.vercel + +# Prevent commiting lock file. +package-lock.json + +# sub module +api-docs/ \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..e2f7d2c --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "api-docs"] + path = api-docs + url = https://github.com/koreanbots/api-docs + branch = master diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..9b76e35 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,2 @@ +.next/ +node_modules/ \ No newline at end of file diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 0000000..c41c7fd --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1,11 @@ +module.exports = { + // Change your rules accordingly to your coding style preferences. + // https://prettier.io/docs/en/options.html + semi: false, + trailingComma: 'es5', + singleQuote: true, + printWidth: 100, + tabWidth: 2, + useTabs: true, + plugins: ['prettier-plugin-tailwind'] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..eca599f --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "editor.formatOnSave": false, + "editor.tabSize": 2, + "editor.codeActionsOnSave": { + "source.fixAll.eslint": true + } +} diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..ff86cd6 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,36 @@ +FROM node:14.16-alpine + +# install packages +RUN apk update && apk upgrade && \ + apk add --no-cache bash git openssh python3 py3-pip build-base + +# Create app directory +RUN mkdir -p /usr/src/app +WORKDIR /usr/src/app + +# Get Argument +ARG NEXT_PUBLIC_SENTRY_DSN +ARG SENTRY_DSN +ARG SENTRY_AUTH_TOKEN + +ENV NEXT_PUBLIC_SENTRY_DSN $NEXT_PUBLIC_SENTRY_DSN +ENV SENTRY_DSN $SENTRY_DSN +ENV SENTRY_AUTH_TOKEN $SENTRY_AUTH_TOKEN +ENV SENTRY_ORG koreanbots +ENV SENTRY_PROJECT api +# Installing dependencies +COPY package*.json /usr/src/app/ +COPY yarn.lock /usr/src/app/ +RUN yarn install + +# Copying source files +COPY . /usr/src/app + + +RUN printf "NEXT_PUBLIC_TESTER_KEY=9f9c4a7ae9afeb045fe818ed8b741c70b1d25ec236b189566a0db020c5596441\nNEXT_PUBLIC_COMMIT_HASH=$(git rev-parse HEAD)\nNEXT_PUBLIC_BRANCH=$(git branch | sed -n -e 's/^\* \(.*\)/\1/p')" > .env.local + +# Building app +RUN yarn build + +# Running the app +CMD yarn start \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3a81e3b --- /dev/null +++ b/LICENSE @@ -0,0 +1,677 @@ +GNU AFFERO GENERAL PUBLIC LICENSE + +Version 3, 19 November 2007 + +Copyright (C) Koreanbots + +Everyone is permitted to copy and distribute verbatim copies of +this license document, but changing it is not allowed. + +Preamble + +The GNU Affero +General Public License is a free, copyleft license for software and other kinds +of works, specifically designed to ensure cooperation with the community in the +case of network server software. + +The licenses for most software and other +practical works are designed to take away your freedom to share and change the +works. By contrast, our General Public Licenses are intended to guarantee your +freedom to share and change all versions of a program--to make sure it remains +free software for all its users. + +When we speak of free software, we are +referring to freedom, not price. Our General Public Licenses are designed to make +sure that you have the freedom to distribute copies of free software (and charge +for them if you wish), that you receive source code or can get it if you want it, +that you can change the software or use pieces of it in new free programs, and +that you know you can do these things. + +Developers that use our General Public +Licenses protect your rights with two steps: (1) assert copyright on the +software, and (2) offer you this License which gives you legal permission to +copy, distribute and/or modify the software. + +A secondary benefit of defending +all users' freedom is that improvements made in alternate versions of the +program, if they receive widespread use, become available for other developers to +incorporate. Many developers of free software are heartened and encouraged by the +resulting cooperation. However, in the case of software used on network servers, +this result may fail to come about. The GNU General Public License permits making +a modified version and letting the public access it on a server without ever +releasing its source code to the public. + +The GNU Affero General Public License +is designed specifically to ensure that, in such cases, the modified source code +becomes available to the community. It requires the operator of a network server +to provide the source code of the modified version running there to the users of +that server. Therefore, public use of a modified version, on a publicly +accessible server, gives the public access to the source code of the modified +version. + +An older license, called the Affero General Public License and +published by Affero, was designed to accomplish similar goals. This is a +different license, not a version of the Affero GPL, but Affero has released a new +version of the Affero GPL which permits relicensing under this license. + +The +precise terms and conditions for copying, distribution and modification +follow. + +TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to +version 3 of the GNU Affero General Public License. + + "Copyright" also means +copyright-like laws that apply to other kinds of works, such as semiconductor +masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and "recipients" may be +individuals or organizations. + + To "modify" a work means to copy from or adapt +all or part of the work in a fashion requiring copyright permission, other than +the making of an exact copy. The resulting work is called a "modified version" of +the earlier work or a work "based on" the earlier work. + + A "covered work" +means either the unmodified Program or a work based on the Program. + + To +"propagate" a work means to do anything with it that, without permission, would +make you directly or secondarily liable for infringement under applicable +copyright law, except executing it on a computer or modifying a private copy. +Propagation includes copying, distribution (with or without modification), making +available to the public, and in some countries other activities as well. + + To +"convey" a work means any kind of propagation that enables other parties to make +or receive copies. Mere interaction with a user through a computer network, with +no transfer of a copy, is not conveying. + + An interactive user interface +displays "Appropriate Legal Notices" to the extent that it includes a convenient +and prominently visible feature that (1) displays an appropriate copyright +notice, and (2) tells the user that there is no warranty for the work (except to +the extent that warranties are provided), that licensees may convey the work +under this License, and how to view a copy of this License. If the interface +presents a list of user commands or options, such as a menu, a prominent item in +the list meets this criterion. + + 1. Source Code. + + The "source code" for a +work means the preferred form of the work for making modifications to it. "Object +code" means any non-source form of a work. + + A "Standard Interface" means an +interface that either is an official standard defined by a recognized standards +body, or, in the case of interfaces specified for a particular programming +language, one that is widely used among developers working in that language. + + +The "System Libraries" of an executable work include anything, other than the +work as a whole, that (a) is included in the normal form of packaging a Major +Component, but which is not part of that Major Component, and (b) serves only to +enable use of the work with that Major Component, or to implement a Standard +Interface for which an implementation is available to the public in source code +form. A "Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system (if any) on +which the executable work runs, or a compiler used to produce the work, or an +object code interpreter used to run it. + + The "Corresponding Source" for a work +in object code form means all the source code needed to generate, install, and +(for an executable work) run the object code and to modify the work, including +scripts to control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free programs +which are used unmodified in performing those activities but which are not part +of the work. For example, Corresponding Source includes interface definition +files associated with source files for the work, and the source code for shared +libraries and dynamically linked subprograms that the work is specifically +designed to require, such as by intimate data communication or control flow +between those + + subprograms and other parts of the work. + + The Corresponding +Source need not include anything that users can regenerate automatically from +other parts of the Corresponding Source. + + The Corresponding Source for a work +in source code form is that same work. + + 2. Basic Permissions. + + All rights +granted under this License are granted for the term of copyright on the Program, +and are irrevocable provided the stated conditions are met. This License +explicitly affirms your unlimited permission to run the unmodified Program. The +output from running a covered work is covered by this License only if the output, +given its content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may +make, run and propagate covered works that you do not convey, without conditions +so long as your license otherwise remains in force. You may convey covered works +to others for the sole purpose of having them make modifications exclusively for +you, or provide you with facilities for running those works, provided that you +comply with the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works for you +must do so exclusively on your behalf, under your direction and control, on terms +that prohibit them from making any copies of your copyrighted material outside +their relationship with you. + + Conveying under any other circumstances is +permitted solely under the conditions stated below. Sublicensing is not allowed; +section 10 makes it unnecessary. + + 3. Protecting Users' Legal Rights From +Anti-Circumvention Law. + + No covered work shall be deemed part of an effective +technological measure under any applicable law fulfilling obligations under +article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar +laws prohibiting or restricting circumvention of such measures. + + When you +convey a covered work, you waive any legal power to forbid circumvention of +technological measures to the extent such circumvention is effected by exercising +rights under this License with respect to the covered work, and you disclaim any +intention to limit operation or modification of the work as a means of enforcing, +against the work's users, your or third parties' legal rights to forbid +circumvention of technological measures. + + 4. Conveying Verbatim Copies. + + +You may convey verbatim copies of the Program's source code as you receive it, in +any medium, provided that you conspicuously and appropriately publish on each +copy an appropriate copyright notice; keep intact all notices stating that this +License and any non-permissive terms added in accord with section 7 apply to the +code; keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any +price or no price for each copy that you convey, and you may offer support or +warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You +may convey a work based on the Program, or the modifications to produce it from +the Program, in the form of source code under the terms of section 4, provided +that you also meet all of these conditions: + + a) The work must carry +prominent notices stating that you modified it, and giving a relevant date. + + +b) The work must carry prominent notices stating that it is released under this +License and any conditions added under section 7. This requirement modifies the +requirement in section 4 to "keep intact all notices". + + c) You must license +the entire work, as a whole, under this License to anyone who comes into +possession of a copy. This License will therefore apply, along with any +applicable section 7 additional terms, to the whole of the work, and all its +parts, regardless of how they are packaged. This License gives no permission to +license the work in any other way, but it does not invalidate such permission if +you have separately received it. + + d) If the work has interactive user +interfaces, each must display Appropriate Legal Notices; however, if the Program +has interactive interfaces that do not display Appropriate Legal Notices, your +work need not make them do so. + + A compilation of a covered work with other +separate and independent works, which are not by their nature extensions of the +covered work, and which are not combined with it such as to form a larger +program, in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not used to limit +the access or legal rights of the compilation's users beyond what the individual +works permit. Inclusion of a covered work in an aggregate does not cause this +License to apply to the other parts of the aggregate. + + 6. Conveying Non-Source +Forms. + + You may convey a covered work in object code form under the terms of +sections 4 and 5, provided that you also convey the machine-readable +Corresponding Source under the terms of this License, in one of these ways: + + +a) Convey the object code in, or embodied in, a physical product (including a +physical distribution medium), accompanied by the Corresponding Source fixed on a +durable physical medium customarily used for software interchange. + + b) +Convey the object code in, or embodied in, a physical product (including a +physical distribution medium), accompanied by a written offer, valid for at least +three years and valid for as long as you offer spare parts or customer support +for that product model, to give anyone who possesses the object code either (1) a +copy of the Corresponding Source for all the software in the product that is +covered by this License, on a durable physical medium customarily used for +software interchange, for a price no more than your reasonable cost of physically +performing this conveying of source, or (2) access to copy the Corresponding +Source from a network server at no charge. + + c) Convey individual copies of +the object code with a copy of the written offer to provide the Corresponding +Source. This alternative is allowed only occasionally and noncommercially, and +only if you received the object code with such an offer, in accord with +subsection 6b. + + d) Convey the object code by offering access from a +designated place (gratis or for a charge), and offer equivalent access to the +Corresponding Source in the same way through the same place at no further charge. +You need not require recipients to copy the Corresponding Source along with the +object code. If the place to copy the object code is a network server, the +Corresponding Source may be on a different server (operated by you or a third +party) that supports equivalent copying facilities, provided you maintain clear +directions next to the object code saying where to find the Corresponding Source. +Regardless of what server hosts the Corresponding Source, you remain obligated to +ensure that it is available for as long as needed to satisfy these +requirements. + + e) Convey the object code using peer-to-peer transmission, +provided you inform other peers where the object code and Corresponding Source of +the work are being offered to the general public at no charge under subsection +6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be included in +conveying the object code work. + + A "User Product" is either (1) a "consumer +product", which means any tangible personal property which is normally used for +personal, family, or household purposes, or (2) anything designed or sold for +incorporation into a dwelling. In determining whether a product is a consumer +product, doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a typical or +common use of that class of product, regardless of the status of the particular +user or of the way in which the particular user actually uses, or expects or is +expected to use, the product. A product is a consumer product regardless of +whether the product has substantial commercial, industrial or non-consumer uses, +unless such uses represent the only significant mode of use of the product. + + +"Installation Information" for a User Product means any methods, procedures, +authorization keys, or other information required to install and execute modified +versions of a covered work in that User Product from a modified version of its +Corresponding Source. The information must suffice to ensure that the continued +functioning of the modified object code is in no case prevented or interfered +with solely because modification has been made. + + If you convey an object code +work under this section in, or with, or specifically for use in, a User Product, +and the conveying occurs as part of a transaction in which the right of +possession and use of the User Product is transferred to the recipient in +perpetuity or for a fixed term (regardless of how the transaction is +characterized), the Corresponding Source conveyed under this section must be +accompanied by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install modified object +code on the User Product (for example, the work has been installed in ROM). + + +The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates for a +work that has been modified or installed by the recipient, or for the User +Product in which it has been modified or installed. Access to a network may be +denied when the modification itself materially and adversely affects the +operation of the network or violates the rules and protocols for communication +across the network. + + Corresponding Source conveyed, and Installation +Information provided, in accord with this section must be in a format that is +publicly documented (and with an implementation available to the public in source +code form), and must require no special password or key for unpacking, reading or +copying. + + 7. Additional Terms. + + "Additional permissions" are terms that +supplement the terms of this License by making exceptions from one or more of its +conditions. Additional permissions that are applicable to the entire Program +shall be treated as though they were included in this License, to the extent that +they are valid under applicable law. If additional permissions apply only to part +of the Program, that part may be used separately under those permissions, but the +entire Program remains governed by this License without regard to the additional +permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of it. +(Additional permissions may be written to require their own removal in certain +cases when you modify the work.) You may place additional permissions on +material, added by you to a covered work, for which you have or can give +appropriate copyright permission. + + Notwithstanding any other provision of this +License, for material you add to a covered work, you may (if authorized by the +copyright holders of that material) supplement the terms of this License with +terms: + + a) Disclaiming warranty or limiting liability differently from the +terms of sections 15 and 16 of this License; or + + b) Requiring preservation +of specified reasonable legal notices or author attributions in that material or +in the Appropriate Legal Notices displayed by works containing it; or + + c) +Prohibiting misrepresentation of the origin of that material, or requiring that +modified versions of such material be marked in reasonable ways as different from +the original version; or + + d) Limiting the use for publicity purposes of +names of licensors or authors of the material; or + + e) Declining to grant +rights under trademark law for use of some trade names, trademarks, or service +marks; or + + f) Requiring indemnification of licensors and authors of that +material by anyone who conveys the material (or modified versions of it) with +contractual assumptions of liability to the recipient, for any liability that +these contractual assumptions directly impose on those licensors and authors. + + +All other non-permissive additional terms are considered "further restrictions" +within the meaning of section 10. If the Program as you received it, or any part +of it, contains a notice stating that it is governed by this License along with a +term that is a further restriction, you may remove that term. If a license +document contains a further restriction but permits relicensing or conveying +under this License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does not survive +such relicensing or conveying. + + If you add terms to a covered work in accord +with this section, you must place, in the relevant source files, a statement of +the additional terms that apply to those files, or a notice indicating where to +find the applicable terms. + + Additional terms, permissive or non-permissive, +may be stated in the form of a separately written license, or stated as +exceptions; the above requirements apply either way. + + 8. Termination. + + You +may not propagate or modify a covered work except as expressly provided under +this License. Any attempt otherwise to propagate or modify it is void, and will +automatically terminate your rights under this License (including any patent +licenses granted under the third paragraph of section 11). + + However, if you +cease all violation of this License, then your license from a particular +copyright holder is reinstated (a) provisionally, unless and until the copyright +holder explicitly and finally terminates your license, and (b) permanently, if +the copyright holder fails to notify you of the violation by some reasonable +means prior to 60 days after the cessation. + + Moreover, your license from a +particular copyright holder is reinstated permanently if the copyright holder +notifies you of the violation by some reasonable means, this is the first time +you have received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after your receipt +of the notice. + + Termination of your rights under this section does not +terminate the licenses of parties who have received copies or rights from you +under this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same material +under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are +not required to accept this License in order to receive or run a copy of the +Program. Ancillary propagation of a covered work occurring solely as a +consequence of using peer-to-peer transmission to receive a copy likewise does +not require acceptance. However, nothing other than this License grants you +permission to propagate or modify any covered work. These actions infringe +copyright if you do not accept this License. Therefore, by modifying or +propagating a covered work, you indicate your acceptance of this License to do +so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you +convey a covered work, the recipient automatically receives a license from the +original licensors, to run, modify and propagate that work, subject to this +License. You are not responsible for enforcing compliance by third parties with +this License. + + An "entity transaction" is a transaction transferring control +of an organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered work results +from an entity transaction, each party to that transaction who receives a copy of +the work also receives whatever licenses to the work the party's predecessor in +interest had or could give under the previous paragraph, plus a right to +possession of the Corresponding Source of the work from the predecessor in +interest, if the predecessor has it or can get it with reasonable efforts. + + +You may not impose any further restrictions on the exercise of the rights granted +or affirmed under this License. For example, you may not impose a license fee, +royalty, or other charge for exercise of rights granted under this License, and +you may not initiate litigation (including a cross-claim or counterclaim in a +lawsuit) alleging that any patent claim is infringed by making, using, selling, +offering for sale, or importing the Program or any portion of it. + + 11. +Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The work thus +licensed is called the contributor's "contributor version". + + A contributor's +"essential patent claims" are all patent claims owned or controlled by the +contributor, whether already acquired or hereafter acquired, that would be +infringed by some manner, permitted by this License, of making, using, or selling +its contributor version, but do not include claims that would be infringed only +as a consequence of further modification of the contributor version. For purposes +of this definition, "control" includes the right to grant patent sublicenses in a +manner consistent with the requirements of this License. + + Each contributor +grants you a non-exclusive, worldwide, royalty-free patent license under the +contributor's essential patent claims, to make, use, sell, offer for sale, import +and otherwise run, modify and propagate the contents of its contributor +version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent (such as an +express permission to practice a patent or covenant not to s ue for patent +infringement). To "grant" such a patent license to a party means to make such an +agreement or commitment not to enforce a patent against the party. + + If you +convey a covered work, knowingly relying on a patent license, and the +Corresponding Source of the work is not available for anyone to copy, free of +charge and under the terms of this License, through a publicly available network +server or other readily accessible means, then you must either (1) cause the +Corresponding Source to be so available, or (2) arrange to deprive yourself of +the benefit of the patent license for this particular work, or (3) arrange, in a +manner consistent with the requirements of this License, to extend the patent + + +license to downstream recipients. "Knowingly relying" means you have actual +knowledge that, but for the patent license, your conveying the covered work in a +country, or your recipient's use of the covered work in a country, would infringe +one or more identifiable patents in that country that you have reason to believe +are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a covered work, +and grant a patent license to some of the parties receiving the covered work +authorizing them to use, propagate, modify or convey a specific copy of the +covered work, then the patent license you grant is automatically extended to all +recipients of the covered work and works based on it. + + A patent license is +"discriminatory" if it does not include within the scope of its coverage, +prohibits the exercise of, or is conditioned on the non-exercise of one or more +of the rights that are specifically granted under this License. You may not +convey a covered work if you are a party to an arrangement with a third party +that is in the business of distributing software, under which you make payment to +the third party based on the extent of your activity of conveying the work, and +under which the third party grants, to any of the parties who would receive the +covered work from you, a discriminatory patent license (a) in connection with +copies of the covered work conveyed by you (or copies made from those copies), or +(b) primarily for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, or that +patent license was granted, prior to 28 March 2007. + + Nothing in this License +shall be construed as excluding or limiting any implied license or other defenses +to infringement that may otherwise be available to you under applicable patent +law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on +you (whether by court order, agreement or otherwise) that contradict the +conditions of this License, they do not excuse you from the conditions of this +License. If you cannot convey a covered work so as to satisfy simultaneously your +obligations under this License and any other pertinent obligations, then as a +consequence you may + + not convey it at all. For example, if you agree to terms +that obligate you to collect a royalty for further conveying from those to whom +you convey the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Remote +Network Interaction; Use with the GNU General Public License. + + Notwithstanding +any other provision of this License, if you modify the Program, your modified +version must prominently offer all users interacting with it remotely through a +computer network (if your version supports such interaction) an opportunity to +receive the Corresponding Source of your version by providing access to the +Corresponding Source from a network server at no charge, through some standard or +customary means of facilitating copying of software. This Corresponding Source +shall include the Corresponding Source for any work covered by version 3 of the +GNU General Public License that is incorporated pursuant to the following +paragraph. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed under version +3 of the GNU General Public License into a single combined work, and to convey +the resulting work. The terms of this License will continue to apply to the part +which is the covered work, but the work with which it is combined will remain +governed by version 3 of the GNU General Public License. + + 14. Revised Versions +of this License. + + The Free Software Foundation may publish revised and/or new +versions of the GNU Affero General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may differ in +detail to address new problems or concerns. + + Each version is given a +distinguishing version number. If the Program specifies that a certain numbered +version of the GNU Affero General Public License "or any later version" applies +to it, you have the option of following the terms and conditions either of that +numbered version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the GNU Affero +General Public License, you may choose any version ever published by the Free +Software Foundation. + + If the Program specifies that a proxy can decide which +future versions of the GNU Affero General Public License can be used, that +proxy's public statement of acceptance of a version permanently authorizes you to +choose that version for the Program. + + Later license versions may give you +additional or different permissions. However, no additional obligations are +imposed on any author or copyright holder as a result of your choosing to follow +a later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE +PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED +IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" +WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY +COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS +PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, +INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE +THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED +INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE +PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY +HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + + 17. Interpretation of +Sections 15 and 16. + +If the disclaimer of warranty and limitation of liability +provided above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates an absolute +waiver of all civil liability in connection with the Program, unless a warranty +or assumption of liability accompanies a copy of the Program in return for a fee. +END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Programs + +If +you develop a new program, and you want it to be of the greatest possible use to +the public, the best way to achieve this is to make it free software which +everyone can redistribute and change under these terms. + +To do so, attach the +following notices to the program. It is safest to attach them to the start of +each source file to most effectively state the exclusion of warranty; and each +file should have at least the "copyright" line and a pointer to where the full +notice is found. + + + +Copyright (C) 2021 + +This program is free software: +you can redistribute it and/or modify it under the terms of the GNU Affero +General Public License as published by the Free Software Foundation, either +version 3 of the License, or (at your option) any later version. + +This program is +distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU Affero General Public License for more details. + +You should have +received a copy of the GNU Affero General Public License along with this program. +If not, see . + +Also add information on how to +contact you by electronic and paper mail. + +If your software can interact with +users remotely through a computer network, you should also make sure that it +provides a way for users to get its source. For example, if your program is a web +application, its interface could display a "Source" link that leads users to an +archive of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the specific +requirements. + +You should also get your employer (if you work as a programmer) or +school, if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU AGPL, see +. \ No newline at end of file diff --git a/README.en.md b/README.en.md new file mode 100644 index 0000000..bc16687 --- /dev/null +++ b/README.en.md @@ -0,0 +1,85 @@ +
+ +
+ +![Tests](https://github.com/koreanbots/koreanbots/workflows/Tests/badge.svg) +![Deploy](https://github.com/koreanbots/koreanbots/workflows/Deploy/badge.svg) +[![DeepScan grade](https://deepscan.io/api/teams/12468/projects/15503/branches/310734/badge/grade.svg)](https://deepscan.io/dashboard#view=project&tid=12468&pid=15503&bid=310734) + +> Korean Discord Bots in one place. + +# SNS + +- [Twitter](https://twitter.com/koreanbots) +- [Instagram](https://instagram.com/koreanbots) + +# Contact + +- [Developer Email](mailto:wonderlandpark@callisto.team) +- [Discord](https://discord.gg/JEh53MQ) + +# Contributing + +Issues and PRs are always welcomed. + +## Before submitting an Issue + +### Bug + +First, check if the device supports it. + +### Devices not supported + +```md +- Any extension program (AdBlock, Darkmode etc.) +- Browser: IE, Pre 17 Edge. +- Windows prior to Windows 7 +- MacOS version 10.10 or lower +- iOS version 10.0 or lower +- Android version 5.0 or lower +- 3.5" iPhone +- All VMs +- Jailbroken or rooted device +- All Linux versions that have ended official support +- Security issues (Please forward security-related issues to the developer privately) +- Bugs that do not occur in the official build, occur in the browser/OS of beta versions such as Canary or PTB +- All platforms or devices that other developers have declared end of support +``` + +Then register the issue. +[Submit](https://github.com/koreanbots/koreanbots/issues/new/choose) + +If you see an issue, please leave a comment like these. + +- `CR` Means **Can Reproduce** +- `CNR` Means **Can Not Reproduce** +- `NAB` Means **Not a Bug** + +### Approval and deny + +When a bug receives two reproducible approvals or denial, the approval and rejection are decided. + +#### Approve + +If a bug is approved by more than two user as reproducible, the bug waits for confirmation from the developer and obtains a `approved` label. + +#### Deny + +If a bug is rejected by more than one user because it is not reproducible, the bug gets a `deny` label and the issue is `Closed`. + +### Suggestions + +Please feel free to make suggestions at [Discussions](https://github.com/koreanbots/koreanbots/discussions)! + +## Submit Pull Request + +Contributions are always welcome. We appreciate your commit messages if you follow the rules below! + +[Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) + +--- + +### Old Repositories + +- [client](https://github.com/koreanbots/client) +- [api](https://github.com/koreanbots/api) diff --git a/README.md b/README.md index ba5d826..74a16c5 100644 --- a/README.md +++ b/README.md @@ -1,82 +1,46 @@ -# koreanbots +
+ + + +
+ +![Tests](https://github.com/koreanbots/koreanbots/workflows/Tests/badge.svg) +![Deploy](https://github.com/koreanbots/koreanbots/workflows/Deploy/badge.svg) +[![DeepScan grade](https://deepscan.io/api/teams/12468/projects/15503/branches/310734/badge/grade.svg)](https://deepscan.io/dashboard#view=project&tid=12468&pid=15503&bid=310734) + +[Introduced in English](./README.en.md) > 국내 디스코드봇을 한곳에서. -## 여긴 뭔가요? +# SNS -이 공간은 버그와 제안을 관리하기 위한 공간입니다. +- [Twitter](https://twitter.com/koreanbots) +- [Instagram](https://instagram.com/koreanbots) -## 이슈를 등록하기 전에 +# 문의 -### 버그 +- [개발자 이메일](mailto:wonderlandpark@callisto.team) +- [디스코드](https://discord.gg/JEh53MQ) -먼저 지원하는 기기인지 확인합니다. +# 기여하기 -#### 지원하지 않는 기기 +이슈와 PR은 언제든지 환영입니다. -```md -- 어떠한 확장프로그램 (AdBlock, Darkmode etc.) -- 브라우저: IE, Pre 17 Edge. -- Windows 7 이전의 Windows -- 10.10 버전 이하의 macOS -- 10.0 버전 이하의 iOS -- 5.0 버전 이하의 안드로이드 -- 3.5" 아이폰 -- 모든 VM -- 탈옥 또는 루팅된 기기 -- 공식 지원 종료된 모든 리눅스 버전 -- 보안 이슈 (보안과 관련된 문제는 비공개적이게 개발자에게 전달해주세요) -- 정식빌드에서는 발생하지 않는 Canary혹은 PTB와 같은 베타 버전의 브라우저/OS에서 발생하는 버그 -- 이외 개발자가 지원 종료 선언한 모든 플랫폼혹은 기기 -``` +[기여 규칙](./.github/CONTRIBUTING.md) -그 다음 이슈를 등록합니다. -[등록하기](https://github.com/koreanbots/koreanbots/issues/new/choose) +## 기여자 -**이슈에서는 빠른 소통을 위해 약자를 사용합니다.** -이슈를 보신다면 댓글을 남겨주세요. + + + + + + + + +

Junseo Park

🚧 💼

zero734kr

👀
-- `CR` **Can Reproduce** 의 약자로 재현 가능한 버그라는 뜻입니다. -- `CNR` **Can Not Reproduce** 의 약자로 재현이 불가능하다는 뜻입니다. -- `NAB` **Not a Bug** 의 약자로 버그에 해당하지 않는다는 뜻입니다. + + -#### 승인과 거부 - -버그는 2개의 재현가능 여부에 대한 승인(Approve) 또는 거부(Deny)를 받게되면, 승인과 거부가 결정됩니다. - -##### 승인 - -버그가 재현 가능하다고 2명 이상의 유저에게 승인이 된다면, 해당 버그는 개발자의 확인을 기다리며, `approved` 라벨을 획득합니다. - -##### 거부 - -버그가 재현 가능하지않다고 2명 이상의 유저에게 거부가 된다면, 해당 버그는 `deny` 라벨을 획득하며, 이슈는 `Closed` 처리됩니다. - -### 제안 - -제안은 자유롭게 해주셔도 됩니다! - -## 관리 - -이슈는 관리자와 버그 헌터분들이 관리합니다. - -### 버그 헌터란? - -버그 헌터는 버그를 열심히 찾아주시거나, 해당 레포지토리에 활발하게 참여하여, 특정 기준 이상을 참여해주신 유저분들에게 지급해드리는 권한입니다. - -버그헌터는 이슈를 닫거나, 라벨을 추가할 수 있으며 `Approve`와 `Deny`와 같은 상태를 관리합니다. - -### 처벌 - -이슈에서 장난식 발언을 하거나, 관련성이 없는 말 또는 스팸을 게시한다면, 통보없이 처벌되실 수 있습니다. - -## 사이트 레포들 - -- [client](https://github.com/koreanbots/client) -- [api](https://github.com/koreanbots/api) - -### 기여 - -기여는 언제든 환영입니다 커밋메세지는 다음 규칙을 따라주시면 감사하겠습니다! - -[Conventional Commits](https://www.conventionalcommits.org/ko/v1.0.0/) \ No newline at end of file + diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..fbe4860 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,9 @@ +# Security Policy + +## Korean + +[버그 바운티 프로그램](https://beta.koreanbots.dev/security) + +## English + +Please [mail](mailto:koreanbots.dev@gmail.com) us! diff --git a/api-docs b/api-docs new file mode 160000 index 0000000..effc22e --- /dev/null +++ b/api-docs @@ -0,0 +1 @@ +Subproject commit effc22ea2b191f7cfd35e08a4545bc7879e61d24 diff --git a/app.css b/app.css new file mode 100644 index 0000000..5829e09 --- /dev/null +++ b/app.css @@ -0,0 +1,192 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +html { + scroll-behavior: smooth; + min-height: 100%; + overflow-x: hidden; + width: 100%; +} + +body { + min-height: 100vh; + width: 100%; +} + +body * { + outline: none; +} + +@font-face { + font-family: 'Uni Sans Heavy CAPS'; + src: url('/logofont.otf'); + font-display: swap; +} + +.logofont { + font-family: 'Uni Sans Heavy CAPS'; +} + +.animation-dropdown { + animation: dropdown 0.1s linear; +} + +.iu-is-the-best { + min-height: 100vh; +} + +.__control--is-focused { + border: none !important; + box-shadow: none !important; +} + +i { + width: 20px; +} + +/* html * ::-webkit-scrollbar { + -webkit-appearance: none; + width: 8px; + height: 8px; +} + +html * ::-webkit-scrollbar-thumb { + cursor: pointer; + border-radius: 5px; + background: #ccc; + -webkit-transition: color 0.2s ease; + transition: color 0.2s ease; +} + +html .dark * ::-webkit-scrollbar-thumb { + cursor: pointer; + border-radius: 5px; + background: #202225; + -webkit-transition: color 0.2s ease; + transition: color 0.2s ease; +} + +html * ::-webkit-scrollbar-track { + background: #f2f2f2; + border-radius: 0; + border: 4px solid transparent; + border-radius: 8px; +} + +html .dark * ::-webkit-scrollbar-track { + background: #2e3338; + border-radius: 0; +} */ + +.dark .__multi-value, +.dark .__multi-value__label, +.dark .__multi-value__remove { + background: #2e3338 !important; +} + +.scroll-none { + -ms-overflow-style: none; + scrollbar-width: none; +} + +.scroll-none ::-webkit-scrollbar { + display: none; +} + +button { + outline: none !important; +} + +.emoji-selector-button { + width: 24px; + height: 24px; + display: inline-block; + background-image: url('https://unpkg.com/emoji-datasource-twitter@5.0.1/img/twitter/sheets-256/64.png'); + background-size: 5700% 5700%; + background-position: 53.5714% 62.5%; + filter: grayscale(100%); +} + +.emoji-selector-button:hover { + filter: grayscale(0%); + transform: scale(1.1, 1.1); + opacity: 90%; + transition: ease-in 100ms; + cursor: pointer; +} + +.emoji-mart-category-list > *, +.emoji-mart-emoji > span { + cursor: pointer; +} + +.cursor-heart { + cursor: url("/img/heart.svg"), auto; +} + +/* NProgress */ + +#nprogress { + pointer-events: none; +} + +#nprogress .bar { + background: #3366FF; + + position: fixed; + z-index: 1031; + top: 0; + left: 0; + + width: 100%; + height: 1.5px; +} + +/* Fancy blur effect */ +#nprogress .peg { + display: block; + position: absolute; + right: 0px; + width: 100px; + height: 100%; + box-shadow: 0 0 10px #3366FF, 0 0 5px #3366FF; + opacity: 1.0; + transform: rotate(3deg) translate(0px, -4px); +} + +/* Remove these to get rid of the spinner */ +#nprogress .spinner { + display: block; + position: fixed; + z-index: 1031; + top: 15px; + right: 15px; +} + +#nprogress .spinner-icon { + width: 18px; + height: 18px; + box-sizing: border-box; + + border: solid 2px transparent; + border-top-color: #3366FF; + border-left-color: #3366FF; + border-radius: 50%; + animation: nprogress-spinner 400ms linear infinite; +} + +.nprogress-custom-parent { + overflow: hidden; + position: relative; +} + +.nprogress-custom-parent #nprogress .spinner, +.nprogress-custom-parent #nprogress .bar { + position: absolute; +} + +@keyframes nprogress-spinner { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} \ No newline at end of file diff --git a/components/Advertisement.tsx b/components/Advertisement.tsx new file mode 100644 index 0000000..d770ecb --- /dev/null +++ b/components/Advertisement.tsx @@ -0,0 +1,49 @@ +import { useEffect } from 'react' +import Logger from '@utils/Logger' + +const Advertisement: React.FC = ({ size = 'short' }) => { + useEffect(() => { + if (process.env.NODE_ENV === 'production') { + window.adsbygoogle = window.adsbygoogle || [] + window.adsbygoogle.push({}) + } + Logger.debug('Ads Pushed') + }, []) + + return ( +
+ {process.env.NODE_ENV === 'production' ? ( + + ) : ( + 'Advertisement' + )} +
+ ) +} + +declare global { + interface Window { + adsbygoogle: { + loaded?: boolean + push(obj: unknown): void + } + } +} + +interface AdvertisementProps { + size?: 'short' | 'tall' +} + +export default Advertisement diff --git a/components/Application.tsx b/components/Application.tsx new file mode 100644 index 0000000..9409bae --- /dev/null +++ b/components/Application.tsx @@ -0,0 +1,22 @@ +import dynamic from 'next/dynamic' +import Link from 'next/link' + +const DiscordAvatar = dynamic(() => import('@components/DiscordAvatar')) + +const Application: React.FC = ({ type, id, name }) => { + return +
+ +

{name}

+
+ + +} + +interface ApplicationProps { + type: 'bot' + id: string + name: string +} + +export default Application diff --git a/components/BotCard.tsx b/components/BotCard.tsx new file mode 100644 index 0000000..fd90048 --- /dev/null +++ b/components/BotCard.tsx @@ -0,0 +1,124 @@ +import Link from 'next/link' +import dynamic from 'next/dynamic' + +import { checkBotFlag, formatNumber, makeBotURL } from '@utils/Tools' +import { Status } from '@utils/Constants' +import { Bot } from '@types' + +const Divider = dynamic(() => import('@components/Divider')) +const Tag = dynamic(() => import('@components/Tag')) +const DiscordAvatar = dynamic(() => import('@components/DiscordAvatar')) + +const BotCard: React.FC = ({ manage = false, bot }) => { + return
+
+
+
+
+ +
+
+
+
+ +
+ +
+

+ + {Status[bot.status]?.text} +

+

{bot.name}

+
+
+
+ + {formatNumber(bot.votes)} + + } + dark + /> + {formatNumber(bot.servers)} 서버 : 'N/A'} + dark + /> +
+
+

+ {bot.intro} +

+
+
+ {bot.category.slice(0, 3).map(el => ( + + ))}{' '} + {bot.category.length > 3 && } +
+
+
+ + +
+
+ + + 보기 + + + {manage ? ( + + + 관리하기 + + + ) : bot.state !== 'ok' ? + 초대하기 + : + + 초대하기 + + } +
+
+
+
+
+
+
+ +} + +interface BotCardProps { + manage?: boolean + bot: Bot +} + +export default BotCard \ No newline at end of file diff --git a/components/Button.tsx b/components/Button.tsx new file mode 100644 index 0000000..7a588d9 --- /dev/null +++ b/components/Button.tsx @@ -0,0 +1,47 @@ +import Link from 'next/link' +import { ReactNode } from 'react' + +const Button: React.FC = ({ + type = 'button', + className, + children, + href, + disabled=false, + onClick, +}) => { + return href ? + + {children} + + + : onClick ? + : + +} + +interface ButtonProps { + type?: 'button' | 'submit' | 'reset' + className?: string + children: ReactNode + href?: string + disabled?: boolean + onClick?: () => void +} + +export default Button diff --git a/components/Captcha.tsx b/components/Captcha.tsx new file mode 100644 index 0000000..b04755c --- /dev/null +++ b/components/Captcha.tsx @@ -0,0 +1,15 @@ +import { Ref } from 'react' +import HCaptcha from '@hcaptcha/react-hcaptcha' + + +const Captcha: React.FC = ({ dark, onVerify }) => { + return +} + +interface CaptchaProps { + dark: boolean + onVerify(token: string, eKey?: string): void + ref?: Ref +} + +export default Captcha \ No newline at end of file diff --git a/components/ColorCard.tsx b/components/ColorCard.tsx new file mode 100644 index 0000000..66f6c32 --- /dev/null +++ b/components/ColorCard.tsx @@ -0,0 +1,21 @@ +const ColorCard: React.FC = ({ header, first, second, className }) => { + return ( +
+

{header}

+

+ {first} +
+ {second} +

+
+ ) +} + +interface ColorCardProps { + header: string + first: string + second: string + className: string +} + +export default ColorCard diff --git a/components/Container.tsx b/components/Container.tsx new file mode 100644 index 0000000..414be2f --- /dev/null +++ b/components/Container.tsx @@ -0,0 +1,27 @@ +import { ReactNode } from 'react' + +const Container: React.FC = ({ + ignoreColor, + className, + paddingTop = false, + children, +}) => { + return ( +
+
{children}
+
+ ) +} + +interface ContainerProps { + ignoreColor?: boolean + className?: string + paddingTop?: boolean + children: ReactNode +} + +export default Container diff --git a/components/DeveloperLayout.tsx b/components/DeveloperLayout.tsx new file mode 100644 index 0000000..169d536 --- /dev/null +++ b/components/DeveloperLayout.tsx @@ -0,0 +1,104 @@ +/* eslint-disable jsx-a11y/click-events-have-key-events */ +import dynamic from 'next/dynamic' +import Link from 'next/link' +import { ReactNode, useState } from 'react' + +import { DocsData } from '@types' +import { NextSeo } from 'next-seo' + +const Container = dynamic(() => import('@components/Container')) +const Divider = dynamic(() => import('@components/Divider')) + +const DeveloperLayout: React.FC = ({ children, enabled, docs, currentDoc }:DeveloperLayout) => { + const [ navbarEnabled, setNavbarOpen ] = useState(false) + + return
+ +
+
+
    +
  • + +
  • +
  • + +
  • + { + enabled === 'docs' && <> + +
  • setNavbarOpen(true)} onClick={() => setNavbarOpen(true)}> + +
  • + } +
+
+
+
+
+
    +
  • setNavbarOpen(false)} onClick={() => setNavbarOpen(false)}>닫기
  • + + +
  • + 나의 봇 +
  • + + +
  • + 문서 +
  • + +
+ { + enabled === 'docs' && <> + +
    +
  • setNavbarOpen(false)} className='lg:hidden cursor-pointer py-1 px-4 rounded-md mb-2'> + 닫기 +
  • + + { + docs?.map(el => { + if(el.list) return
    + {el.name} +
      + { + el.list.map(e => + +
    • setNavbarOpen(false)} className={`cursor-pointer px-4 py-2 rounded-md ${currentDoc === e.name ? 'bg-discord-blurple text-white' : 'hover:text-gray-500 dark:hover:text-white'}`}> + {e.name} +
    • + + ) + } +
    +
    + + return +
  • setNavbarOpen(false)} className={`cursor-pointer py-2 px-4 rounded-md ${currentDoc === el.name ? 'bg-discord-blurple text-white' : 'hover:text-gray-500 dark:hover:text-white'}`}> + {el.name} +
  • + + }) + } +
+ + } +
+
+
+ + {children} + +
+
+} + +interface DeveloperLayout { + children: ReactNode + enabled: 'applications' | 'docs' + docs?: DocsData[] + currentDoc?: string +} + +export default DeveloperLayout diff --git a/components/DiscordAvatar.tsx b/components/DiscordAvatar.tsx new file mode 100644 index 0000000..d248950 --- /dev/null +++ b/components/DiscordAvatar.tsx @@ -0,0 +1,60 @@ +import { SyntheticEvent, useEffect, useState } from 'react' +import { KoreanbotsEndPoints } from '@utils/Constants' +import { supportsWebP } from '@utils/Tools' +import Logger from '@utils/Logger' + +const DiscordAvatar: React.FC = props => { + const fallback = '/img/default.png' + const [ webpUnavailable, setWebpUnavailable ] = useState() + + useEffect(()=> { + setWebpUnavailable(localStorage.webp === 'false') + }, []) + + return {props.alt)=> { + if(webpUnavailable) { + (e.target as ImageTarget).onerror = (event) => { + // All Fails + (event.target as ImageTarget).onerror = ()=> { Logger.warn('FALLBACK IMAGE LOAD FAIL') } + (event.target as ImageTarget).src = fallback + + } + } + else { + (e.target as ImageTarget).onerror = (event) => { + // All Fails + (event.target as ImageTarget).onerror = ()=> { Logger.warn('FALLBACK IMAGE LOAD FAIL') } + (event.target as ImageTarget).src = fallback + } + // Webp Load Fail + (e.target as ImageTarget).src = KoreanbotsEndPoints.CDN.avatar(props.userID, { size: props.size ?? 256}) + if(!supportsWebP()) localStorage.setItem('webp', 'false') + } + }} + /> +} + +interface DiscordAvatarProps { + alt?: string + userID: string + className?: string + size? : 128 | 256 | 512 +} + +interface ImageEvent extends Event { + target: ImageTarget +} + +interface ImageTarget extends EventTarget { + src: string + onerror: (event: SyntheticEvent) => void +} + +export default DiscordAvatar diff --git a/components/Divider.tsx b/components/Divider.tsx new file mode 100644 index 0000000..1d116aa --- /dev/null +++ b/components/Divider.tsx @@ -0,0 +1,17 @@ +const Divider: React.FC = ({ className }) => { + return ( +
+ ) +} + +interface DividerProps { + className?: string +} + +export default Divider diff --git a/components/Docs.tsx b/components/Docs.tsx new file mode 100644 index 0000000..8cb455d --- /dev/null +++ b/components/Docs.tsx @@ -0,0 +1,38 @@ +import { NextSeo } from 'next-seo' +import dynamic from 'next/dynamic' + +const Container = dynamic(() => import('@components/Container')) + +const Docs: React.FC = ({ title, header, description, subheader, children }) => { + return ( + <> + +
+ +

+ {header} +

+

+ {description} +

+

+ {subheader} +

+
+
+ +
{children}
+
+ + ) +} + +export default Docs + +interface DocsProps { + header: string | React.ReactNode + title?: string + description?: string + subheader?: string + children: React.ReactNode +} diff --git a/components/Footer.tsx b/components/Footer.tsx new file mode 100644 index 0000000..fe01537 --- /dev/null +++ b/components/Footer.tsx @@ -0,0 +1,118 @@ +import Link from 'next/link' +import dynamic from 'next/dynamic' + +import { Theme } from '@types' + +const Container = dynamic(() => import('@components/Container')) +const Toggle = dynamic(() => import('@components/Toggle')) + +const Footer: React.FC = ({ theme, setTheme }) => { + return ( +
+
+ +
+

국내 디스코드 봇을 한 곳에서.

+ 2020-2021 Koreanbots, All rights reserved. +
+ + + + + + + + + + + +
+
+
+
+

한국 디스코드봇 리스트

+ +
+
+

정책

+ +
+
+

커뮤니티

+ +
+
+

기타

+
+ 다크모드 + { + const t = theme === 'dark' ? 'light' : 'dark' + setTheme(t) + localStorage.setItem('theme', t) + }} + /> +
+
+
+
+
+
+ ) +} + +interface FooterProps { + theme: Theme + setTheme(value: Theme): void +} + +export default Footer diff --git a/components/Forbidden.tsx b/components/Forbidden.tsx new file mode 100644 index 0000000..72232a8 --- /dev/null +++ b/components/Forbidden.tsx @@ -0,0 +1,26 @@ +import dynamic from 'next/dynamic' +import { useRouter } from 'next/router' +import { NextSeo } from 'next-seo' + +import { ErrorText } from '@utils/Constants' + +const Button = dynamic(() => import('@components/Button')) + +const Forbidden:React.FC = () => { + const router = useRouter() + return <> + +
+
+

403

+

+ {ErrorText[403]} +

+ +

해당 작업을 수행할 수 있는 권한이 없습니다. 무언가 잘못된 것 같다면 문의해주세요.

+
+
+ +} + +export default Forbidden diff --git a/components/Form/CheckBox.tsx b/components/Form/CheckBox.tsx new file mode 100644 index 0000000..f72350b --- /dev/null +++ b/components/Form/CheckBox.tsx @@ -0,0 +1,12 @@ +import { Field } from 'formik' + +const CheckBox: React.FC = ({ name, ...props }) => { + return +} + +interface CheckBoxProps { + name: string + [key: string]: unknown +} + +export default CheckBox diff --git a/components/Form/CsrfToken.tsx b/components/Form/CsrfToken.tsx new file mode 100644 index 0000000..be1c609 --- /dev/null +++ b/components/Form/CsrfToken.tsx @@ -0,0 +1,11 @@ +import { Field } from 'formik' + +const CsrfToken: React.FC = ({ token }) => { + return