Skip to content
fosscealPublic

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

ย 

History

38 Commits

Folders and files

Repository files navigation

๐Ÿ“ KumoFumi โ€“ Serverless Form Builder

Cloudflare Workers Cloudflare D1 JavaScript License: MIT

A production-grade, serverless form builder inspired by Google Forms. Built for the modern web using Cloudflare Workers, D1 (SQLite), and Cloudflare Pages. It features a secure, themeable admin panel and a lightning-fast public form renderer.


โœจ Key Features

  • ๐Ÿ”จ Powerful Builder: Drag-and-drop-style form creation with support for multiple input types (Text, Email, Radio, Checkbox, File Uploads).
  • ๐ŸŽจ Themeable UI: Instant dark mode support, customizable theme colors, and logo uploads.
  • ๐Ÿ›ก๏ธ SaaS-Grade Security: JWT-based authentication, server-side validation, and Cloudflare Turnstile integration.
  • ๐Ÿ“Š Response Management: Real-time response tracking with CSV/XLSX/PDF export capabilities.
  • โ˜๏ธ Cloud Asset Storage: Direct Cloudinary integration for handling file uploads.
  • ๐Ÿš€ Edge-Powered: Globally distributed serverless architecture for sub-100ms response times.

๐Ÿ› ๏ธ Tech Stack

Frontend

  • Vanilla JS & CSS3: Zero-dependency, lightweight, and blazing fast.
  • Cloudflare Pages: High-performance static hosting at the edge.
  • Font Awesome: Professional iconography.

Backend

  • Cloudflare Workers: High-performance serverless environment.
  • Cloudflare D1: SQL database for reliable data storage.
  • Cloudflare KV: High-speed key-value storage for rate limiting.

Security

  • JWT Auth: Secure admin session management.
  • Cloudflare Secrets: Zero-exposure secret management.
  • CORS Hardening: Strict origin-based access control.

๐Ÿ“ Project Structure

KumoFumi /
โ”œโ”€โ”€ api/               # Cloudflare Worker (Backend)
โ”‚   โ”œโ”€โ”€ src/           # Business logic & authentication
โ”‚   โ”œโ”€โ”€ schema.sql     # D1 database initialization
โ”‚   โ””โ”€โ”€ wrangler.toml  # Worker configuration
โ”œโ”€โ”€ css/               # Modular frontend styles
โ”œโ”€โ”€ js/                # Client-side logic (Admin & Form)
โ”œโ”€โ”€ index.html         # Authentication Portal (Sign In & Sign Up)
โ”œโ”€โ”€ builder.html       # Form Builder & Dashboard
โ””โ”€โ”€ form.html          # Public Form Renderer

๐Ÿ”’ Security & Architecture

This project follows a Backend-First Security Model. All sensitive logic is isolated in the Worker, ensuring the frontend remains thin and secure.

Secret Management

Important

Secrets are NEVER stored in GitHub or the source code. They are injected at runtime via Cloudflare Environment Variables.

๐Ÿ”‘ View Production Secret Commands
# How to set production secrets
wrangler secret put ADMIN_PASSWORD
wrangler secret put JWT_SECRET
wrangler secret put TURNSTILE_SECRET

Validation Flow

  1. Frontend: UX-focused validation (immediate feedback).
  2. Backend: Strict schema validation (Zod-like logic), rate limiting, and size enforcement.
  3. Database: SQL-level integrity checks.

๐Ÿ—„๏ธ Role-Based Storage Architecture

Zeon Forms enforces strict server-side storage access control to ensure free/public-signup users never consume platform Cloudinary resources.

Storage Policy Matrix

Account Type Allowed Storage Backend Enforcement
Superadmin Cloudinary Server-signed upload parameters or server-proxied upload.
Admin (assigned by superadmin) Cloudinary Verified against D1 storage_provider = 'cloudinary'.
Admin (unassigned) Google Drive or None Cloudinary blocked (HTTP 403 STORAGE_PROVIDER_NOT_ALLOWED).
Free / Public-Signup User Personal Google Drive only Cloudinary blocked (HTTP 403). Must connect Drive for image/file uploads.
R2 Storage Disabled Gated behind R2_STORAGE_ENABLED !== 'true'.

Public Form Submissions

  • Anonymous respondents never log into Google.
  • Response attachments and payload backups are stored in the form owner's connected Google Drive (or Cloudinary if permitted) via server-side routing (POST /api/forms/:slug/upload).
  • If the form owner's Drive quota or token expires, the backend returns HTTP 503 STORAGE_UNAVAILABLE with a reconnect notification for the owner, preventing silent data loss or Cloudinary fallback.
  • Submissions are deduplicated via Idempotency-Key headers stored in submission_idempotency.

Google OAuth 2.0 Setup Guide

  1. Go to the Google Cloud Console.
  2. Create or select a Project (e.g. Zeon Forms).
  3. Navigate to APIs & Services > Enabled APIs & Services and enable the Google Drive API.
  4. Go to APIs & Services > OAuth consent screen:
    • Choose External user type.
    • Fill in App Name, Support Email, and Developer Contact.
    • In Scopes, add https://www.googleapis.com/auth/drive.file (per-app file access only; avoids full Drive access).
  5. Go to APIs & Services > Credentials:
    • Click Create Credentials > OAuth client ID.
    • Application type: Web application.
    • Authorized JavaScript origins: http://localhost:3000, http://127.0.0.1:3000, https://forms.ceal.in.
    • Authorized redirect URIs:
      • Local: http://127.0.0.1:8787/api/storage/google/callback
      • Production: https://forms.ceal.in/api/storage/google/callback (or your worker domain).
  6. Note down the Client ID and Client Secret.

Environment Variables & Secrets Checklist

Local Development (api/.dev.vars)

ADMIN_PASSWORD=your_local_admin_password
JWT_SECRET=your_local_jwt_secret
DRIVE_ENCRYPTION_KEY=32_byte_random_master_key_for_aes_gcm
GOOGLE_CLIENT_ID=your_google_client_id.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=your_google_client_secret
GOOGLE_REDIRECT_URI=http://127.0.0.1:8787/api/storage/google/callback
CLOUDINARY_CLOUD_NAME=your_cloudinary_cloud_name
CLOUDINARY_API_KEY=your_cloudinary_api_key
CLOUDINARY_API_SECRET=your_cloudinary_api_secret

Production Cloudflare Worker Secrets

npx --prefix api wrangler secret put ADMIN_PASSWORD --env production
npx --prefix api wrangler secret put JWT_SECRET --env production
npx --prefix api wrangler secret put DRIVE_ENCRYPTION_KEY --env production
npx --prefix api wrangler secret put GOOGLE_CLIENT_ID --env production
npx --prefix api wrangler secret put GOOGLE_CLIENT_SECRET --env production
npx --prefix api wrangler secret put CLOUDINARY_CLOUD_NAME --env production
npx --prefix api wrangler secret put CLOUDINARY_API_KEY --env production
npx --prefix api wrangler secret put CLOUDINARY_API_SECRET --env production

D1 Database Schema

Initialize or update the database schema:

# Local D1 database:
npx --prefix api wrangler d1 execute custom-forms-db --local --file=./schema.sql --persist-to=.wrangler/state

# Production D1 database:
npx --prefix api wrangler d1 execute custom-forms-db --remote --env production --file=./schema.sql

Legacy Cloudinary Migration Guide

  • Existing assets for free users are marked as storage_provider = 'legacy_cloudinary'.
  • Legacy Cloudinary images continue to render seamlessly.
  • New Cloudinary uploads are blocked for free users.
  • Users can click Migrate Assets in the Form Builder Storage settings to copy legacy Cloudinary assets to their connected Google Drive.

๐Ÿš€ Environments & Development Modes

Mode Command Frontend Worker Database
Local npm run dev Local (http://127.0.0.1:3000) Local Wrangler (http://127.0.0.1:8787) Local D1 (.wrangler/state)
Remote Test npm run dev:remote Local (http://127.0.0.1:3000) Remote Mode (http://127.0.0.1:8787) Production D1 (Cloudflare)
Production npm run deploy:api Hosted (https://forms.ceal.in) Cloudflare Edge Worker Production D1 (Cloudflare)

๐Ÿ’ป Local Development Workflow

1. First-Time Local Setup

  1. Install dependencies:

    npm install
    npm --prefix api install
  2. Configure local development secrets: Copy the example file to .dev.vars inside the api/ directory:

    cp api/.dev.vars.example api/.dev.vars

    Edit api/.dev.vars with your preferred local password (e.g. ADMIN_PASSWORD=your_local_password).

  3. Initialize local D1 database schema:

    npm --prefix api run db:init:local

2. Normal Local Development

Start both the frontend static dev server and the local Cloudflare Worker simultaneously:

npm run dev
  • Frontend: Accessible at http://127.0.0.1:3000 (or http://localhost:3000)
  • Backend Worker: Running locally via Wrangler at http://127.0.0.1:8787
  • Database: Strictly local SQLite instance persisted inside api/.wrangler/state.
  • Stopping: Press Ctrl + C in your terminal to cleanly terminate both processes concurrently.

Important

Data Isolation: Local D1 data is completely isolated from the hosted Cloudflare database. Forms and responses created locally will NEVER appear on the hosted website, and creating local records does NOT deploy them.

3. Inspecting the Local Database

Query the local SQLite database without touching production:

npm --prefix api run db:query:local -- "SELECT name FROM sqlite_master WHERE type='table';"
npm --prefix api run db:query:local -- "SELECT id, slug, name, status FROM forms;"

โš ๏ธ Remote Mode Testing (Caution)

Warning

DANGER: npm run dev:remote connects your local development instance directly to PRODUCTION Cloudflare resources. Any form edits, submissions, or deletions in this mode WILL MUTATE REAL PRODUCTION DATA.

Only run this mode when intentionally verifying production integration:

npm run dev:remote

Inspecting Remote Production D1 Safely

Warning

Remote queries run directly against your live production database. Never run DROP, DELETE, or untested UPDATE queries remotely.

npm --prefix api run db:query:remote -- "SELECT id, slug, name, status FROM forms LIMIT 10;"

๐ŸŒ Production Deployment

1. Deploy the Backend Worker

Deploy code to the Cloudflare production environment:

npm run deploy:api

(Runs wrangler deploy --env production inside api/)

2. Configure Production Secrets

Production secrets must never be committed to Git. Set them securely via Wrangler:

npx --prefix api wrangler secret put ADMIN_PASSWORD --env production
npx --prefix api wrangler secret put JWT_SECRET --env production
npx --prefix api wrangler secret put TURNSTILE_SECRET --env production

3. Deploy the Frontend (Cloudflare Pages)

Build the minified production bundle:

npm run build

Push the repository to GitHub connected to Cloudflare Pages (Build output directory: dist/), or deploy via CLI:

npx wrangler pages deploy dist --project-name=forms

๐Ÿ—บ๏ธ Roadmap

  • PDF Export: Generate professional PDF reports for each submission.
  • Analytics: Visual charts for data distribution.
  • Webhooks: Direct integration with Discord/Slack.
  • Multi-Admin: RBAC support for larger teams.
  • Scheduling: Auto-close forms based on timestamps.

๐Ÿ“œ License

Distributed under the MIT License. See LICENSE for more information.


Tip

This architecture is designed to scale to millions of requests at near-zero cost. Itโ€™s not just a toolโ€”it's a production-ready serverless platform.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages