Description and capabilities of CRYSTAL v2.0
October 28
upd: November 18
Contents:
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.
- 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:
|Screenshot 1| Improved UX/UI design, light theme.
|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 (
!isImageExtensionand!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 subsequentisValidGif(fileBuffer), which checks for "Magic Bytes" in the file header (GIF87aorGIF89a). - 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:
|Screenshot 3| Hidden GIF images, light theme.
|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_COUNTandMAX_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#Testis added to thenamefield of thehashtagscollection, 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
toLocaleDateStringandtoLocaleTimeString. 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 viai18n.languageand displays the year only if the date belongs to the previous year. - 20. Database cybersecurity system complies with CRYSTAL v1.0 (Production).
Share
BTC (Network BTC) - 1C2EWWeEXVhg93hJA9KovpkSd3Rn3BkcYm
Ethereum (Network ERC20) - 0x05037ecbd8bcd15631d780c95c3799861182e6b8










Comment on