Skip to content
hapara-failPublic

About

The source code for the hapara.fail website, dedicated to exposing the pervasive nature of student surveillance technology used in educational environments.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

4 stars

Watchers

0 watching

Forks

Latest commit

Β 

History

468 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

hapara.fail v3

Deploy to Cloudflare

hapara.fail is dedicated to exposing the pervasive nature of student surveillance technology used in educational environments. We provide technical insights, practical tools, and resources to empower students and advocate for digital privacy. This repository contains the source code for the v3 website, built with Astro and deployed to Cloudflare Workers.

Live Site: https://www.hapara.fail

Better Stack Badge


πŸš€ Project Overview

This iteration of hapara.fail delivers a fast, modern, and privacy-respecting platform featuring:

  • Educational Content: In-depth blog posts and technical write-ups explaining how edtech surveillance works.
  • Privacy Tools: Interactive tools designed to bypass certain restrictions or reveal hidden information (e.g., DNS Service).
  • Community Focus: Resources built by and for the student privacy community.

✨ Key Features

  • Modern & Responsive Design: A sleek, consistent interface optimized for all devices.
  • Edge Powered: Deployed to Cloudflare Workers via the @astrojs/cloudflare adapter. Static assets served from the built dist/ directory.
  • Privacy First: No user tracking, no invasive analytics. We practice what we preach.
  • MDX Blog: Blog posts are written in MDX and support custom Astro components (callouts, timelines, evidence blocks, etc.).
  • Text-to-Speech: Built-in audio player on blog posts using the Web Speech API, implemented as a Svelte component.
  • RSS Feed: Auto-generated RSS feed at /rss.xml via @astrojs/rss.
  • Sitemap: Auto-generated sitemap via @astrojs/sitemap.
  • Open Source: All code is available for review and contribution.

πŸ’» Technology Stack

  • Framework: Astro v6 β€” Static site generator with island architecture.
  • UI Components: Svelte v5 β€” Used for interactive islands (search, cookie notice, text-to-speech).
  • Content: MDX via @astrojs/mdx β€” Blog posts with embedded Astro components.
  • Deployment: Cloudflare Workers via @astrojs/cloudflare adapter.
  • CLI: Wrangler 4 β€” Cloudflare's deployment tool.
  • Package Manager: pnpm v9+
  • Language: TypeScript
  • Icons: Lucide via @lucide/astro and @lucide/svelte.
  • Fonts: Poppins and Fira Code via @fontsource (self-hosted, no external requests).
  • Code Formatter: Prettier
  • SEO: Local metadata tags in src/components/Head.astro

πŸ“ Project Structure

β”œβ”€β”€ public/                         # Static files copied as-is to dist/
β”œβ”€β”€ scripts/
β”‚   └── generate-version.js         # Build-time script to stamp version info
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ assets/                     # Images imported and processed by Astro
β”‚   β”œβ”€β”€ components/
β”‚   β”‚   β”œβ”€β”€ blog/                   # MDX-embeddable Astro components
β”‚   β”‚   β”‚   β”œβ”€β”€ BreachTable.astro
β”‚   β”‚   β”‚   β”œβ”€β”€ CalloutWarning.astro
β”‚   β”‚   β”‚   β”œβ”€β”€ EvidenceBlock.astro
β”‚   β”‚   β”‚   β”œβ”€β”€ PullQuote.astro
β”‚   β”‚   β”‚   β”œβ”€β”€ SectionLabel.astro
β”‚   β”‚   β”‚   β”œβ”€β”€ SourceChip.astro
β”‚   β”‚   β”‚   β”œβ”€β”€ Timeline.astro
β”‚   β”‚   β”‚   └── TimelineItem.astro
β”‚   β”‚   β”œβ”€β”€ svelte/                 # Interactive Svelte island components
β”‚   β”‚   β”‚   β”œβ”€β”€ BlogSearch.svelte   # Client-side blog search
β”‚   β”‚   β”‚   β”œβ”€β”€ CookieNotice.svelte # Cookie/notice banner
β”‚   β”‚   β”‚   └── TextToSpeech.svelte # Text-to-speech audio player
β”‚   β”‚   β”œβ”€β”€ Footer.astro
β”‚   β”‚   β”œβ”€β”€ Head.astro              # SEO meta tags, fonts, shared <head>
β”‚   β”‚   β”œβ”€β”€ Header.astro
β”‚   β”‚   └── Scripts.astro           # Shared script includes
β”‚   β”œβ”€β”€ content/
β”‚   β”‚   └── blog/                   # MDX blog post source files
β”‚   β”‚       β”œβ”€β”€ adguard-home.mdx
β”‚   β”‚       β”œβ”€β”€ age-verification.mdx
β”‚   β”‚       β”œβ”€β”€ chromeos-wifi-password-extractor.mdx
β”‚   β”‚       β”œβ”€β”€ death-of-learning.mdx
β”‚   β”‚       └── dns.mdx
β”‚   β”œβ”€β”€ layouts/
β”‚   β”‚   └── BaseLayout.astro        # Shared page layout wrapper
β”‚   β”œβ”€β”€ pages/
β”‚   β”‚   β”œβ”€β”€ blog/
β”‚   β”‚   β”‚   β”œβ”€β”€ index.astro         # Blog index page
β”‚   β”‚   β”‚   └── [...slug].astro     # Dynamic blog post renderer
β”‚   β”‚   β”œβ”€β”€ services/
β”‚   β”‚   β”‚   └── dns.astro           # DNS service page & tool
β”‚   β”‚   β”œβ”€β”€ 404.astro
β”‚   β”‚   β”œβ”€β”€ about.astro
β”‚   β”‚   β”œβ”€β”€ contribute.astro
β”‚   β”‚   β”œβ”€β”€ index.astro             # Homepage
β”‚   β”‚   β”œβ”€β”€ license.astro
β”‚   β”‚   β”œβ”€β”€ privacy.astro
β”‚   β”‚   β”œβ”€β”€ rss.xml.ts              # RSS feed endpoint
β”‚   β”‚   └── terms.astro
β”‚   β”œβ”€β”€ content.config.ts           # Astro content collection schema
β”‚   └── middleware.ts               # Security headers & HTTP method enforcement
β”œβ”€β”€ astro.config.mjs                # Astro configuration
β”œβ”€β”€ package.json
β”œβ”€β”€ pnpm-workspace.yaml
β”œβ”€β”€ svelte.config.js
β”œβ”€β”€ tsconfig.json
└── wrangler.jsonc                  # Cloudflare Workers configuration

πŸ—ΊοΈ Routes

Primary Pages

Route Description
/ Homepage
/about About page
/contribute Contribute / donate page
/terms Terms of Service
/privacy Privacy Policy
/license License information
/blog Blog index
/blog/[slug] Individual blog posts
/services/dns DNS service page & tool
/rss.xml RSS feed

Blog Posts

Route Title
/blog/dns DNS
/blog/adguard-home AdGuard Home
/blog/age-verification Age Verification
/blog/chromeos-wifi-password-extractor ChromeOS Wi-Fi Password Extractor
/blog/death-of-learning Death of Learning

Blog posts are sourced from src/content/blog/ as MDX files, rendered by the dynamic [...slug].astro route, and can embed any component from src/components/blog/.

Redirects

Configured in astro.config.mjs:

Route Destination
/bypass /services/dns
/dns /services/dns
/discord Discord Invite
/github GitHub Profile

πŸ› οΈ Development

Prerequisites

  • Node.js (v18 or higher recommended)
  • pnpm v9+
  • A Cloudflare account with Wrangler authenticated (wrangler login) β€” only needed for deployment

Local Setup

  1. Clone the repository:

    git clone https://github.com/hapara-fail/website.git
    cd website
  2. Install dependencies:

    pnpm install
  3. Start the local development server:

    pnpm run dev

    This starts the Astro dev server at http://localhost:4321 with hot module reloading.

Available Scripts

Script Description
pnpm run dev Start the Astro development server
pnpm run build Generate version stamp + build the site to dist/
pnpm run preview Build + run Wrangler dev server against the built dist/
pnpm run deploy Build + deploy to Cloudflare Workers
pnpm run format / fmt Format all files with Prettier
pnpm run generate-version Stamp version-data only (called automatically by build)

☁️ Deployment

Ensure you have Wrangler installed and authenticated (wrangler login).

pnpm run deploy

This command generates the version stamp, runs astro build to produce the dist/ directory, then deploys via wrangler deploy to the hapara-fail Worker defined in wrangler.jsonc. Assets are served from the dist/ directory via the Workers Assets binding.


πŸ”’ Security

Security headers are applied to every response via Astro middleware (src/middleware.ts):

  • Content-Security-Policy β€” restricts asset origins; allows connections to monitor.dns2.hapara.fail for DNS status checks, and cdn.jsdelivr.net with raw.githubusercontent.com fallback for blocklist content.
  • Strict-Transport-Security β€” HSTS with includeSubDomains; preload (1 year).
  • X-Content-Type-Options: nosniff
  • X-Frame-Options: SAMEORIGIN
  • Referrer-Policy: strict-origin-when-cross-origin
  • Permissions-Policy β€” disables camera, microphone, geolocation, and payment APIs.

Only GET and HEAD HTTP methods are accepted; all others return 405 Method Not Allowed.


🀝 Contributing

Contributions are welcome! Please review our Contributing Guidelines before submitting.

If you have ideas for improvements, new tools, bug fixes, or blog post topics:

  • Open an Issue on GitHub using our standardized templates.
  • Submit a Pull Request with your proposed changes.
  • Join our Discord server to discuss.

Donation options are available here.


πŸ“„ License

This project is licensed under the terms specified at www.hapara.fail/license.

About

The source code for the hapara.fail website, dedicated to exposing the pervasive nature of student surveillance technology used in educational environments.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

4 stars

Watchers

0 watching

Forks

Sponsor this project

Used by

Contributors

Languages