73 lines
6.2 KiB
Plaintext
73 lines
6.2 KiB
Plaintext
Project Description
|
||
What it is
|
||
|
||
A single-file CNC retrofit parts e-commerce application with zero external frameworks. It uses vanilla JavaScript, custom CSS, Web Crypto API, and displays production-grade PHP backend code for reference. The entire security engine runs client-side with no dependencies — no Python, no WebAssembly, no build tools, no npm packages.
|
||
Technology stack (and why each was chosen)
|
||
Layer
|
||
|
||
Technology
|
||
|
||
Rationale
|
||
Layout/CSS Custom CSS with variables Tailwind was removed because every element already used inline styles and custom classes — it was a dead 300KB dependency adding nothing
|
||
Logic Vanilla JS (ES6) No framework needed for a single-page app with five views. IIFE pattern for SecurityEngine to avoid polluting global scope. No let/const in loops to avoid closure bugs. No arrow functions in hot paths for clarity.
|
||
Cryptography crypto.subtle.digest('SHA-256') Uses the operating system's native crypto provider — stronger than any software implementation. Falls back to a 70-line pure-JS SHA-256 on file:// contexts where crypto.subtle is unavailable
|
||
CSRF tokens crypto.getRandomValues() Same CSPRNG the browser uses for TLS. 128 bits of entropy, 1-hour expiry, rotated after every order
|
||
Fonts Space Grotesk + JetBrains Mono Display and monospace. No Inter, no Roboto
|
||
Icons Font Awesome 6 Single CDN, no alternative needed
|
||
Images Picsum (seeded URLs) Placeholder images — production would use real product photography
|
||
|
||
|
||
Security architecture
|
||
|
||
The SecurityEngine class implements seven distinct security functions:
|
||
|
||
1. SHA-256 hash-chained audit log. Every logged event includes a prevHash field pointing to the previous entry's hash. The verifyChain() method walks the entire chain, removes each stored hash, recomputes it from the canonical JSON (keys sorted), and compares. If any entry has been tampered with — even a single character in the details — the chain breaks at that point and reports the index. The chain is persisted to localStorage after every write and restored on page load.
|
||
|
||
2. Input sanitization. Nine regex patterns match <script>, javascript:, on*= event handlers, <iframe>, <object>, <embed>, <form>, <input>, CSS expression(), and @import. Matched content is replaced with [SANITIZED]. Then five HTML entities are encoded (& < > " '). This runs before any field is processed, displayed, or logged.
|
||
|
||
3. CSRF protection. A 128-bit hex token is generated via crypto.getRandomValues(). It's validated on every order submission by comparing against the stored token and checking the 1-hour expiry window. After a successful order, the token is rotated — the old token becomes permanently invalid.
|
||
|
||
4. Rate limiting. A sliding window implementation tracks timestamps per action key (add_to_cart, submit_order). The window is 60 seconds, the limit is 15 requests. Stale timestamps are pruned on each check. Rate-limited actions are logged to the audit trail.
|
||
|
||
5. Order integrity validation. The server-side (Python/JS here, PHP in production) independently recomputes the order total from item prices and quantities, then compares against the client-stated total. If they differ by more than $0.01, the order is rejected. Quantity is bounded to 1–99. Negative prices are rejected.
|
||
|
||
6. Credit card validation. The Luhn algorithm validates the check digit. The card number never leaves the browser session. This is demonstrational — real PCI-DSS compliance requires server-side tokenization through a provider like Stripe.
|
||
|
||
7. Stock enforcement. Cart addition checks p.stock >= 1. Quantity increment checks existing.qty < p.stock. On order placement, stock is decremented in the product array and the grid re-renders with updated counts. Freight-flagged items are blocked entirely from add-to-cart with a toast directing to sales.
|
||
Product catalog structure
|
||
|
||
30 products across 7 categories, each with:
|
||
|
||
sku — Part number (searchable, displayed in cards, cart, and audit log)
|
||
weight — Kilograms (shown in modal for freight awareness)
|
||
freight — Boolean flag (blocks add-to-cart, shows warning badge)
|
||
tiers — Quantity price breaks array [{min:5, p:82.99}, ...]
|
||
params — Parametric filter values {diameter:'20mm', grade:'C3', ...}
|
||
specs — Display tags shown on cards
|
||
|
||
E-commerce features
|
||
|
||
Search — Searches across SKU, name, description, category, and spec tags
|
||
Category filtering — Pill buttons across the top
|
||
Parametric filtering — When a category is selected, spec-based chip filters appear (diameter/lead/grade for ball screws, taper/cooling/power for spindles, etc.). OR within a key, AND between keys
|
||
Sorting — Featured, price asc/desc, rating, name A-Z
|
||
Product detail modal — Full specs, quantity pricing tiers, stock status, freight warning, security info
|
||
Cart sidebar — Unit price updates with tier quantity, quantity controls, running total
|
||
Checkout — Three sections (customer, payment, shipping), loading spinner on submit, field-level error messages
|
||
Order confirmation — Itemized summary with SKUs, customer/shipping info, CSRF validation result, chain verification status
|
||
Stock decrement — Product stock actually decreases on order placement
|
||
|
||
What would be needed for production
|
||
|
||
The PHP architecture tab shows the real backend code. To deploy:
|
||
|
||
PHP 8+ with Laravel or similar — The SecurityMiddleware class maps directly to Laravel middleware. OrderController maps to a controller with parameterized Eloquent queries and lockForUpdate() for stock deduction.
|
||
Database — Products, orders, order_items, audit_log tables. The audit log would use the same SHA-256 chain pattern in PHP (hash('sha256', $canonicalJson)).
|
||
Session storage — Replace localStorage with encrypted server-side sessions. CSRF tokens stored server-side, not client-side.
|
||
Payment — Stripe Elements or similar for PCI-compliant card tokenization. Never handle raw card numbers server-side.
|
||
Static assets — The HTML/CSS/JS file becomes the frontend served by the PHP app. The SecurityEngine class could be compiled out and replaced with API calls to the backend endpoints that perform the same validation.
|
||
Freight calculation — Integration with a shipping API (FedEx/UPS) for weight-based quotes on freight-flagged items.
|
||
|
||
|
||
|