Vote Sosamala

A self-hostable, open source, secure voting system for small public beauty contests and similar events. Designed for easy deployment, privacy, and fairness, with per-category leaderboards, a user-friendly admin dashboard, and real-time updates.
Screenshot of Courseweb with a cow sticker

Backstory: From Chaos to Code

Classic university moment: it started as a last-minute favor. Three days before a "Miss & Mister" contest, a friend messaged:
“Facebook votes are all bots. Can u build an online voting system... like, now?”
Naturally, I said yes — who needs sleep anyway?
What followed was a blur of Red Bull and React. I barely survived, but the event did too (contestants didn’t kill me, so I’ll take the win). After the dust settled, I cleaned up the worst of the bugs, added proper security, and made it open source.
Introducing: VoteSosamala — a small but powerful tool for fair, privacy-friendly online voting.

Features

  • One vote per email per category (no double dipping)
  • Emails are hashed (SHA256 + salt) — no plain text stored
  • Google login via Supabase Auth — no passwords to worry about
  • Public contestant pages with shareable links
  • Admin dashboard for reviewing/approving contestants
  • Real-time leaderboard and updates
  • Rate limiting and bot protection via Arcjet
  • Backend rules and DB constraints ensure fairness and security
Screenshot of Courseweb with a cow sticker

Tech Stack

  • Frontend: Next.js App Router, Tailwind CSS
  • Backend: Next.js API routes (Edge/serverless-ready)
  • Auth: Supabase Auth (Google OAuth2)
  • Database: Supabase PostgreSQL (RLS enabled)
  • Storage: Supabase Storage CDN
  • Security: Arcjet, Supabase RLS

Security Model

VoteSosamala was built with fairness and privacy in mind:
  • Emails are hashed with salt and never stored in plain text
  • One vote per user per category is enforced at the database level (unique constraint)
  • Only one admin account can manage backend data (configurable via env)
  • All sensitive tables have RLS (Row Level Security)
  • Arcjet protects API routes from bots, abuse, and rate spam
  • No persistent session needed after voting — logout optional

Self-Hosting & Deployment

You’ll need:
  • Supabase (free tier is enough)
  • Vercel or any Next.js-compatible host

Steps:

  • Create your Supabase project
  • Run schema.sql and rls.sql
  • Set up a Supabase Storage bucket for images
  • Clone the repo & configure .env (use .env.example)
  • Deploy to Vercel or run locally with:
git clone https://github.com/NayanthaNethsara/vote-sosamala.git
cd vote-sosamala/
npm install
npm run dev
Detailed setup coming soon in docs/SETUP.md

Customization

Want to brand this for your own contest?
  • Update logo at /public/logo/logo.png
  • Change categories via the database or admin panel
  • Set your admin email in rls.sql and .env
  • Restyle components using Tailwind in /components

Feedback & Collaboration

This project is still in beta. I'd love feedback from:
  • Event organizers using this in the wild
  • Security pros willing to review or suggest improvements
  • Devs who want to contribute or fork for their own use
Ping me on GitHub or drop a message. Contributions, issues, and PRs are all welcome!

License

MIT — use it, modify it, break it, improve it

Credits

  • Built with Next.js, Supabase, Arcjet, and Tailwind CSS
  • Inspired by real-world chaos and the need for fair voting