diff --git a/classquiz/routers/quiz.py b/classquiz/routers/quiz.py index 60aecc8..b16d290 100644 --- a/classquiz/routers/quiz.py +++ b/classquiz/routers/quiz.py @@ -13,6 +13,7 @@ from classquiz.auth import get_current_user from classquiz.config import redis, settings, storage, meilisearch from classquiz.db.models import Quiz, QuizInput, User, PlayGame from classquiz.kahoot_importer.import_quiz import import_quiz +import html settings = settings() @@ -23,8 +24,8 @@ router = APIRouter() async def create_quiz_lol(quiz_input: QuizInput, user: User = Depends(get_current_user)): imgur_regex = r"^https://i\.imgur\.com\/.{7}.(jpg|png|gif)$" server_regex = rf"^{settings.root_address}/api/v1/storage/download/.{36}--.{36}$" - quiz_input.title = bleach.clean(quiz_input.title, tags=[], strip=True) - quiz_input.description = bleach.clean(quiz_input.description, tags=[], strip=True) + quiz_input.title = html.unescape(bleach.clean(quiz_input.title, tags=[], strip=True)) + quiz_input.description = html.unescape(bleach.clean(quiz_input.description, tags=[], strip=True)) for question in quiz_input.questions: if question.image == "": question.image = None @@ -132,8 +133,8 @@ async def update_quiz(quiz_id: str, quiz_input: QuizInput, user: User = Depends( if quiz is None: return JSONResponse(status_code=404, content={"detail": "quiz not found"}) else: - quiz_input.description = bleach.clean(quiz_input.description, tags=[], strip=True) - quiz_input.title = bleach.clean(quiz_input.title, tags=[], strip=True) + quiz_input.description = html.unescape(bleach.clean(quiz_input.description, tags=[], strip=True)) + quiz_input.title = html.unescape(bleach.clean(quiz_input.title, tags=[], strip=True)) meilisearch.index(settings.meilisearch_index).update_documents([await get_meili_data(quiz)]) if quiz.public and not quiz_input.public: meilisearch.index(settings.meilisearch_index).delete_document(str(quiz.id)) diff --git a/classquiz/routers/users.py b/classquiz/routers/users.py index 507d045..8c64916 100644 --- a/classquiz/routers/users.py +++ b/classquiz/routers/users.py @@ -6,6 +6,7 @@ from datetime import timedelta, datetime from fastapi.background import BackgroundTasks from fastapi.responses import JSONResponse, RedirectResponse from fastapi.security import OAuth2PasswordRequestForm +import html from classquiz.auth import ( get_password_hash, @@ -53,7 +54,7 @@ async def create_user(user: route_user, background_task: BackgroundTasks) -> Use raise HTTPException(status_code=409, detail="User already exists") user.password = get_password_hash(user.password) - user.username = bleach.clean(user.username, tags=[], strip=True) + user.username = html.unescape(bleach.clean(user.username, tags=[], strip=True)) if len(user.username) == 32: return JSONResponse({"details": "Username mustn't be 32 characters long"}, 400) await user.save() diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index dc34aaa..49d2df2 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -1,4 +1,4 @@ -lockfileVersion: 5.3 +lockfileVersion: 5.4 specifiers: '@beyonk/svelte-mapbox': ^8.1.4 @@ -62,23 +62,23 @@ devDependencies: '@fontsource/marck-script': 4.5.5 '@sentry/browser': 6.19.6 '@sentry/tracing': 6.19.6 - '@sveltejs/adapter-auto': 1.0.0-next.34 + '@sveltejs/adapter-auto': 1.0.0-next.38 '@sveltejs/adapter-node': 1.0.0-next.73 - '@sveltejs/kit': 1.0.0-next.314_sass@1.50.0+svelte@3.47.0 + '@sveltejs/kit': 1.0.0-next.320_sass@1.50.0+svelte@3.47.0 '@tailwindcss/typography': 0.5.2_tailwindcss@3.0.24 '@types/cookie': 0.5.0 '@types/js-cookie': 3.0.1 '@types/luxon': 2.3.1 '@types/ua-parser-js': 0.7.36 '@types/yup': 0.29.13 - '@typescript-eslint/eslint-plugin': 5.19.0_f34adc8488d2e4f014fe61432d70cbf2 - '@typescript-eslint/parser': 5.19.0_eslint@8.13.0+typescript@4.6.3 + '@typescript-eslint/eslint-plugin': 5.19.0_6nfnzbei2lspafh6mfbs24gl6i + '@typescript-eslint/parser': 5.19.0_jzhokl4shvj5szf5bgr66kln2a autoprefixer: 10.4.4_postcss@8.4.12 cookie: 0.5.0 cssnano: 5.1.7_postcss@8.4.12 eslint: 8.13.0 eslint-config-prettier: 8.5.0_eslint@8.13.0 - eslint-plugin-svelte3: 3.4.1_eslint@8.13.0+svelte@3.47.0 + eslint-plugin-svelte3: 3.4.1_dlibe5i6mdqr6ijwbd4fluvfsq felte: 1.1.7_svelte@3.47.0 highlight.js: 11.5.1 i18next-browser-languagedetector: 6.1.4 @@ -90,12 +90,12 @@ devDependencies: postcss: 8.4.12 postcss-load-config: 3.1.4_postcss@8.4.12 prettier: 2.6.2 - prettier-plugin-svelte: 2.7.0_prettier@2.6.2+svelte@3.47.0 + prettier-plugin-svelte: 2.7.0_sqtt6dzjlskmywoml5ykunxlce sass: 1.50.0 socket.io-client: 4.4.1 svelte: 3.47.0 - svelte-check: 2.7.0_1b6d41eb44819e98e49be8cacdc96c52 - svelte-preprocess: 4.10.6_f6bc70e70cf1a2fde5bc22fd7000ea23 + svelte-check: 2.7.0_dnwud22eqgpjrze35dfm3slmki + svelte-preprocess: 4.10.6_626hbzym6grp3zn4el6xaahkem svelte-tippy: 1.3.2 swiper: 8.1.0 tailwindcss: 3.0.24 @@ -438,31 +438,31 @@ packages: } dev: true - /@sveltejs/adapter-auto/1.0.0-next.34: + /@sveltejs/adapter-auto/1.0.0-next.38: resolution: { - integrity: sha512-BzZVfy39idFojauroLrE/v9paJ1/HOlS2R857ooCwaLg+RrRy6zJHWwYxNSv5e8AaZiVg7ioZZpU/2g6ZgUpaQ== + integrity: sha512-1//aiV/Wzebj+j5X8VLRs0vJUT3andc/0+IRQwy5ykOwjpNo5/Mj2RX8SA+t5nxBFYyJJf2kj6sszKA8LjRAQQ== } dependencies: - '@sveltejs/adapter-cloudflare': 1.0.0-next.17 - '@sveltejs/adapter-netlify': 1.0.0-next.51 - '@sveltejs/adapter-vercel': 1.0.0-next.47 + '@sveltejs/adapter-cloudflare': 1.0.0-next.18 + '@sveltejs/adapter-netlify': 1.0.0-next.55 + '@sveltejs/adapter-vercel': 1.0.0-next.49 dev: true - /@sveltejs/adapter-cloudflare/1.0.0-next.17: + /@sveltejs/adapter-cloudflare/1.0.0-next.18: resolution: { - integrity: sha512-B2ze5L0LsHFsZctVNy4sw0XxgV2YiVEHyMrWRo3pmpTwpu6GT5V3U2fsEoCMg/RKMazlWkyKTCuUqmcpYjjf2g== + integrity: sha512-iIb7ScN2hnnfVQPhRjw0FYpovYJrw4n22BFAQIg6QvOwmmGz1E3QkyBkm/tRmyY7emDfnljgXtvk4Hsoszp5Ug== } dependencies: esbuild: 0.14.36 worktop: 0.8.0-next.12 dev: true - /@sveltejs/adapter-netlify/1.0.0-next.51: + /@sveltejs/adapter-netlify/1.0.0-next.55: resolution: { - integrity: sha512-P7/cW/0z8zd8J6DOI2yxKZG0+HRMMuzfOf0yzFXX0vRwBePhKlZ/H4qhTOo2NrCmj3Len545o+ugj5gyMXl1+g== + integrity: sha512-LbqupuX8SdvUdCLSLiazPdU+JwwVhWGmoAopwlFkdlGOsGEag6jB+CjEYPmy81SVMSKxtYA2RqNzBPpPbURDtw== } dependencies: '@iarna/toml': 2.2.5 @@ -479,19 +479,19 @@ packages: tiny-glob: 0.2.9 dev: true - /@sveltejs/adapter-vercel/1.0.0-next.47: + /@sveltejs/adapter-vercel/1.0.0-next.49: resolution: { - integrity: sha512-VV3vP8KqL9XOc7xfQLVhXTM5jrTme+r1qJy98u5/dhAhkdjqrGDwAKo/s7MoB3rTYxLb2b8I4QxAaoz2Y2aIBg== + integrity: sha512-Me0Zb10iBv+ySVMc0XgI7rdzwiMmeVHq48iVv3oXORa/et/efJVEknVSVk22q15XRqys7DhoPirf54Mz4jElFQ== } dependencies: esbuild: 0.14.36 dev: true - /@sveltejs/kit/1.0.0-next.314_sass@1.50.0+svelte@3.47.0: + /@sveltejs/kit/1.0.0-next.320_sass@1.50.0+svelte@3.47.0: resolution: { - integrity: sha512-EkXjEd30XO8+AydBLARxAtI6Ak8V0KFSEJ07sNsrkGq9J70sWPL7yGenhGaeq6S852XZAqeyWd6uGQZmQLR4Wg== + integrity: sha512-BDgF+gd73Gxls65rb3H2oacdQUrK8fM0X174t2kMfGS+MeNN6oZ+Kw+j0IJMzMaZSGco89+/wkPeArvDzM/2MQ== } engines: { node: '>=14.13' } hasBin: true @@ -499,6 +499,7 @@ packages: svelte: ^3.44.0 dependencies: '@sveltejs/vite-plugin-svelte': 1.0.0-next.41_svelte@3.47.0+vite@2.9.5 + chokidar: 3.5.3 sade: 1.8.1 svelte: 3.47.0 vite: 2.9.5_sass@1.50.0 @@ -629,7 +630,7 @@ packages: } dev: true - /@typescript-eslint/eslint-plugin/5.19.0_f34adc8488d2e4f014fe61432d70cbf2: + /@typescript-eslint/eslint-plugin/5.19.0_6nfnzbei2lspafh6mfbs24gl6i: resolution: { integrity: sha512-w59GpFqDYGnWFim9p6TGJz7a3qWeENJuAKCqjGSx+Hq/bwq3RZwXYqy98KIfN85yDqz9mq6QXiY5h0FjGQLyEg== @@ -643,10 +644,10 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/parser': 5.19.0_eslint@8.13.0+typescript@4.6.3 + '@typescript-eslint/parser': 5.19.0_jzhokl4shvj5szf5bgr66kln2a '@typescript-eslint/scope-manager': 5.19.0 - '@typescript-eslint/type-utils': 5.19.0_eslint@8.13.0+typescript@4.6.3 - '@typescript-eslint/utils': 5.19.0_eslint@8.13.0+typescript@4.6.3 + '@typescript-eslint/type-utils': 5.19.0_jzhokl4shvj5szf5bgr66kln2a + '@typescript-eslint/utils': 5.19.0_jzhokl4shvj5szf5bgr66kln2a debug: 4.3.4 eslint: 8.13.0 functional-red-black-tree: 1.0.1 @@ -659,7 +660,7 @@ packages: - supports-color dev: true - /@typescript-eslint/parser/5.19.0_eslint@8.13.0+typescript@4.6.3: + /@typescript-eslint/parser/5.19.0_jzhokl4shvj5szf5bgr66kln2a: resolution: { integrity: sha512-yhktJjMCJX8BSBczh1F/uY8wGRYrBeyn84kH6oyqdIJwTGKmzX5Qiq49LRQ0Jh0LXnWijEziSo6BRqny8nqLVQ== @@ -693,7 +694,7 @@ packages: '@typescript-eslint/visitor-keys': 5.19.0 dev: true - /@typescript-eslint/type-utils/5.19.0_eslint@8.13.0+typescript@4.6.3: + /@typescript-eslint/type-utils/5.19.0_jzhokl4shvj5szf5bgr66kln2a: resolution: { integrity: sha512-O6XQ4RI4rQcBGshTQAYBUIGsKqrKeuIOz9v8bckXZnSeXjn/1+BDZndHLe10UplQeJLXDNbaZYrAytKNQO2T4Q== @@ -706,7 +707,7 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/utils': 5.19.0_eslint@8.13.0+typescript@4.6.3 + '@typescript-eslint/utils': 5.19.0_jzhokl4shvj5szf5bgr66kln2a debug: 4.3.4 eslint: 8.13.0 tsutils: 3.21.0_typescript@4.6.3 @@ -747,7 +748,7 @@ packages: - supports-color dev: true - /@typescript-eslint/utils/5.19.0_eslint@8.13.0+typescript@4.6.3: + /@typescript-eslint/utils/5.19.0_jzhokl4shvj5szf5bgr66kln2a: resolution: { integrity: sha512-ZuEckdupXpXamKvFz/Ql8YnePh2ZWcwz7APICzJL985Rp5C2AYcHO62oJzIqNhAMtMK6XvrlBTZeNG8n7gS3lQ== @@ -1741,7 +1742,7 @@ packages: eslint: 8.13.0 dev: true - /eslint-plugin-svelte3/3.4.1_eslint@8.13.0+svelte@3.47.0: + /eslint-plugin-svelte3/3.4.1_dlibe5i6mdqr6ijwbd4fluvfsq: resolution: { integrity: sha512-7p59WG8qV8L6wLdl4d/c3mdjkgVglQCdv5XOTk/iNPBKXuuV+Q0eFP5Wa6iJd/G2M1qR3BkLPEzaANOqKAZczw== @@ -3237,7 +3238,7 @@ packages: engines: { node: '>= 0.8.0' } dev: true - /prettier-plugin-svelte/2.7.0_prettier@2.6.2+svelte@3.47.0: + /prettier-plugin-svelte/2.7.0_sqtt6dzjlskmywoml5ykunxlce: resolution: { integrity: sha512-fQhhZICprZot2IqEyoiUYLTRdumULGRvw0o4dzl5jt0jfzVWdGqeYW27QTWAeXhoupEZJULmNoH3ueJwUWFLIA== @@ -3660,7 +3661,7 @@ packages: engines: { node: '>= 0.4' } dev: true - /svelte-check/2.7.0_1b6d41eb44819e98e49be8cacdc96c52: + /svelte-check/2.7.0_dnwud22eqgpjrze35dfm3slmki: resolution: { integrity: sha512-GrvG24j0+i8AOm0k0KyJ6Dqc+TAR2yzB7rtS4nljHStunVxCTr/1KYlv4EsOeoqtHLzeWMOd5D2O6nDdP/yw4A== @@ -3676,7 +3677,7 @@ packages: sade: 1.8.1 source-map: 0.7.3 svelte: 3.47.0 - svelte-preprocess: 4.10.6_f6bc70e70cf1a2fde5bc22fd7000ea23 + svelte-preprocess: 4.10.6_626hbzym6grp3zn4el6xaahkem typescript: 4.6.3 transitivePeerDependencies: - '@babel/core' @@ -3703,7 +3704,7 @@ packages: svelte: 3.47.0 dev: true - /svelte-preprocess/4.10.6_f6bc70e70cf1a2fde5bc22fd7000ea23: + /svelte-preprocess/4.10.6_626hbzym6grp3zn4el6xaahkem: resolution: { integrity: sha512-I2SV1w/AveMvgIQlUF/ZOO3PYVnhxfcpNyGt8pxpUVhPfyfL/CZBkkw/KPfuFix5FJ9TnnNYMhACK3DtSaYVVQ==