Ru

Description and capabilities of CRYSTAL v2.0


Architecture:

SPA, REST API, FSD.


Building:

Full code | Package.json: frontend | backend


Structure:

  • MongoDB v8.0.4.
  • Express.js v4.21.2.
  • React v19.0.0.
  • Node.js v24.0.2.
  • NPM v11.3.0.
  • PM2 v5.4.3.
  • Vite v6.1.0.

Description and features

Functionally, this version is almost completely identical to CRYSTAL v1.0, but has a number of key improvements:

  • 1. Mongoose has been removed and replaced by the native MongoDB driver.
  • 2. Data schemas for all collections (users, posts, likes, hashtags), are defined using the JSON Schema standard and initialized in MongoDB using the $jsonSchema. This approach ensures consistency and a unified structure for documents in collections.
  • 3. Separate collections with denormalization and indexing have been created for hashtags and likes, ensuring better performance with large data volumes.
  • 4. To search through post content, MongoDB Full-Text Search is used based on the $text operator. Frontend (SearchPage.jsx, Search.jsx) | Backend (searchPosts):
    Demonstration of the search engine

    Demonstration of the search engine.

  • 5. UX/UI design has been improved for larger tablet screens (iPad Pro and similar devices). The side navigation bar has become more compact, increasing the display area of ​​the main content:
    screen 1

    |Screenshot 1| Improved UX/UI design, light theme.

    screen 2

    |Screenshot 2| Improved UX/UI design, dark theme.

  • 6. Added user status (online/offline). The logic is implemented using WebSocket (frontend | backend).
  • 7. The user status (when offline) now displays the time of their last visit to the site.
  • 8. Multer has been replaced by Sharp. The following image upload management and cybersecurity features have been added to sharp-upload.js:

    — Limiting simultaneous image processing (Semaphore)

    To prevent processor overload during resource-intensive image processing, a semaphore mechanism is used.

    — Request rate limiting (Rate Limiting)

    To protect against DDoS attacks and spam, a limit on the number of download requests from a single IP address is used.

    — Limiting the size of the uploaded file

    Checking limit occurs early in the upload process to avoid reading excessively large files into memory.

    — Uploaded file validation process

    After passing the initial checks (Semaphore and Rate Limiting), the uploaded file undergoes a double check (!isImageExtension and !isImageMime) to ensure that it is indeed a safe image. The system simultaneously checks two independent characteristics of the file: the extension (checking the file name for one of the allowed extensions: jpe?g|png|webp|gif) and the MIME type, which must match: image\/(jpeg|png|webp|gif). If any of these checks fail, the file goes to a special GIF check, and the subsequent isValidGif(fileBuffer), which checks for "Magic Bytes" in the file header (GIF87a or GIF89a).

  • 9. GIFs are sanitized via special logic. All images except GIFs are converted to WebP.
  • 10. Added an interface setting that allows you to hide all GIF images on the site:
    screen 3

    |Screenshot 3| Hidden GIF images, light theme.

    screen 4

    |Screenshot 4| Hidden GIF images, dark theme.

  • 11. Added the ability to specify user gender.
  • 12. On the user page, a section with detailed user information has been added: gender, registration date.
  • 13. Added a privacy setting that allows you to hide gender.
  • 14. To increase productivity, offset pagination was replaced with cursor pagination in the sections for displaying user likes, posts with a specific hashtag, and searching for posts.
  • 15. Added a 'Back' button.
  • 16. Added logic for deleting old images from posts and users: after deleting/replacing images, after deleting a user or post.
  • 17. Added validation for hashtags in the backend, which prevents saving hashtags like: ##Test, #Te#st, #Te?st, etc. The check is performed using a regular expression — /^[\p{L}0-9_-]+$/u (allows any Unicode letters, numbers, hyphens, and underscores). You can also set the allowed number of hashtags in one post and the hashtag length using constants: MAX_HASHTAGS_COUNT and MAX_HASHTAG_LENGTH. If a hashtag fails validation, it is not added to the database, but the post is still created and its text will contain an invalid hashtag — #Te#st. After successful verification, the hashtag #Test is added to the name field of the hashtags collection, in lowercase — test.
  • 18. Added validation for hashtags in the frontend. To be displayed as a clickable link, the hashtag must be validated using a regular expression — /^[\p{L}0-9_-]+$/u (Allows any Unicode letters, numbers, hyphens, and underscores).
  • 19. Added more informative display of post creation and update dates in the full and preview versions. Date formatting occurs in a special hook — useFormattedPostDate, which performs localized date and time formatting in two languages ​​(Russian and English) using toLocaleDateString and toLocaleTimeString. For the English locale, a 12-hour clock is used (Jul 4, 2025 ∙ 10:45 PM), and for the Russian locale, a 24-hour clock (4 июля 2025 ∙ 22:45). The hook automatically detects the current interface language via i18n.language and displays the year only if the date belongs to the previous year.
  • 20. Database cybersecurity system complies with CRYSTAL v1.0 (Production).

CRYSTAL is tested on

BrowserStack

Share

Copy

BTC (Network BTC) - 1C2EWWeEXVhg93hJA9KovpkSd3Rn3BkcYm

Ethereum (Network ERC20) - 0x05037ecbd8bcd15631d780c95c3799861182e6b8

Similar posts

This website uses cookies. By clicking the 'Accept' button or continuing to use the website, you agree to the use of cookies.