
Pin The Place is a website centered around my passions of travelling and geography. It is a geography quiz web app that you can either play or create quizzes. The premise is that every question’s answer corresponds to a location on the map. What makes it unique is that your questions can include YouTube videos, audio files, images, or text.
https://pinthe.place
Setup
Most of this website has been created using Google AI Studio for the frontend. I am using Node JS Express for the backend and a Postgres database provider. I have a test environment where the backend runs locally on my machine. Once I approve the fix on the test environment, then I deploy it to production.
- Frontend: Google Cloud
- Backend: AWS
- Postgres Database: Neon Tech
- Storage: Cloudflare
- Domain: Porkbun
- Domain DNS: Cloudflare
Security
This was a learning process while I was building this app — I continually strove to harden all components independently.
- Multi-Tier Architecture (Frontend, Backend, Database)
- HTTPS Enforcement with Certificates
- Cross-Origin Resource Sharing Policy
- Cross-Site Scripting Prevention
- Security Headers with Helmet
- Rate Limiting on all API endpoints
- reCAPTCHA for Contact or Reporting Forms
- Authentication & Authorization
- Secure JWT in HttpOnly Cookies
- Role-Based Access Control
- Google OAuth 2 (With Policy and Terms of Use included)
- After verifying a JWT, authentication middleware performs an additional database check
- Sanitization
- SQL Injection Prevention (parameterized queries)
- DOMPurify for anything being rendered
- Secure File Uploads
- Whitelisted MIME types and file size limits
- Image re-processing
- SVG tag whitelisting
- Unique, randomized filenames (UUID appended)
SEO
This is an ongoing effort to improve Search Engine Optimization (SEO).
- Meta tags
- Open Graph & Twitter Cards
- JSON-LD Schema Markup
- robots.txt and sitemap.xml
- H1 tags, alt text for images
- Descriptive URLs
- Static Site Generation, React + Vite to prerender index.html files on Cloudflare
- Static files so that Google Crawlers can consistently read all the content
- Dynamic Meta Tags for pages that are not prerendered by SSG