This README is intentionally for my future employers. If you want to participate or use this app, please read this.
Contacts Book
Tech stack:
What I have done in this project:
Server-side
- Login by username & password
Client-side
- Use cache by setting HTTP cache header & the service worker
- Form validation by
formik
& yup
Security
- Client hashes password using SHA512 before sending over HTTPS
- Server receives hashed password from client, then encrypt it using
bcrypt
with strongly crypto-randomed salt for each account
- Prevent XSRF attacks using JWT following this & this
- Use
helmet
with its additional middlewares:
- Feature-Policy
- Content-Security-Policy (CSP) (including nonce)
- At the moment report-only mode is used to have an overview of the CSP behavior while testing app in production
- Due to
react-color
is adding inline styles but hasn't support nonce yet, therefore style-src
directive must have 'unsafe-inline'
but cannot have 'nonce-{random}'
- Force SSL (on production)
- Force request's body to be JSON on API routes (via express.json middleware)
- Enable HSTS header
- Note: cannot submit this site to Chrome's HSTS preload list to ensure that it is successfully preloaded (i.e. to get the full protection of the intended configuration) because this app's main domain is a subdomain.
- Validate host to prevent DNS Rebinding
UX (it's important, isn't it? 😊)
- Key press event listeners (Esc, Enter,...) while opening popups, filling in forms,...
Performance
- Improve critical rendering path
- Move Google Fonts from inside CSS (@import) to external link tag in HTML (see f7b478596dd4bddbb099a9a9ab143f04c5f0e50d)
- Reduce bundle's size (tree-shaking, optimize bundling, replace not-really-neccessary heavy modules by lighter ones,...)
- Not transpiling ES6 module with
@babel/preset-env
so webpack
can do its optimization (tree-shaking)
- Use chery-picking when import module (
yup
, jssha
, lodash
, date-fns
, react-router
, react-bootstrap
,...)
- Remove React's
prop-types
validation code in production build
- Replaced modules:
date-fns
instead of luxon
- Code-splitting by using dynamic ESM's
import()
-
Results:
Entrypoints |
Unoptimized |
Optimized |
Main app |
198KB |
133KB |
Sign up |
191KB |
150KB |
Sign in |
181KB |
141KB |
Overview |
screenshoot |
screenshoot |
- Performance: (Google LightHouse's audits in Chrome Dev Tools)