diff --git a/backend/constants.py b/backend/constants.py new file mode 100644 index 0000000..b9dfac2 --- /dev/null +++ b/backend/constants.py @@ -0,0 +1 @@ +MAX_BLOOM_LENGTH = 280 \ No newline at end of file diff --git a/backend/endpoints.py b/backend/endpoints.py index 0e177a0..892478e 100644 --- a/backend/endpoints.py +++ b/backend/endpoints.py @@ -1,3 +1,4 @@ +from constants import MAX_BLOOM_LENGTH from typing import Dict, Union from data import blooms from data.follows import follow, get_followed_usernames, get_inverse_followed_usernames @@ -157,6 +158,10 @@ def send_bloom(): return type_check_error user = get_current_user() + # Check server-side length + content=request.json["content"] + if len(content)>MAX_BLOOM_LENGTH : + return jsonify({"success": False, "error": f"Bloom must be {MAX_BLOOM_LENGTH} characters or less"}), 400 blooms.add_bloom(sender=user, content=request.json["content"]) diff --git a/front-end/lib/api.mjs b/front-end/lib/api.mjs index f4b5339..5018ecf 100644 --- a/front-end/lib/api.mjs +++ b/front-end/lib/api.mjs @@ -1,5 +1,8 @@ import {state} from "../index.mjs"; import {handleErrorDialog} from "../components/error.mjs"; +import { MAX_BLOOM_LENGTH } from "./constants.mjs"; + + // === ABOUT THE STATE // state gives you these two functions only @@ -194,10 +197,18 @@ async function getBloomsByHashtag(hashtag) { } async function postBloom(content) { + // Check client-side length first + if (content.length>MAX_BLOOM_LENGTH){ + handleErrorDialog( + new Error(`Bloom must be ${MAX_BLOOM_LENGTH} characters or less`), + ); + return { success: false }; + + } try { const data = await _apiRequest("/bloom", { method: "POST", - body: JSON.stringify({content}), + body: JSON.stringify({ content }), }); if (data.success) { @@ -208,7 +219,7 @@ async function postBloom(content) { return data; } catch (error) { // Error already handled by _apiRequest - return {success: false}; + return { success: false }; } } diff --git a/front-end/lib/constants.mjs b/front-end/lib/constants.mjs new file mode 100644 index 0000000..dc4099f --- /dev/null +++ b/front-end/lib/constants.mjs @@ -0,0 +1 @@ +export const MAX_BLOOM_LENGTH = 280; diff --git a/front-end/tests/bloom-length.spec.js b/front-end/tests/bloom-length.spec.js new file mode 100644 index 0000000..73442a9 --- /dev/null +++ b/front-end/tests/bloom-length.spec.js @@ -0,0 +1,36 @@ +import { test, expect } from "@playwright/test"; +import { loginAsSample } from "./test-utils"; +import { MAX_BLOOM_LENGTH } from "../lib/constants.mjs"; + + + +test(`server should reject blooms longer than ${MAX_BLOOM_LENGTH} characters`, async ({ + page, +}) => { + await loginAsSample(page); + + const longBloom = "A".repeat(MAX_BLOOM_LENGTH + 1); + + const result = await page.evaluate(async (content) => { + const res = await fetch("/bloom", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + credentials: "include", + body: JSON.stringify({ content }), + }); + + if (!res.ok) { + try { + return await res.json(); + } catch { + return { success: false }; + } + } + + return await res.json(); + }, longBloom); + + expect(result.success).toBe(false); +});