Noundry Forms Platform

A serverless form submission platform. Capture HTML form data from any website, optionally email it, and manage submissions through a modern dashboard. Built with the Noundry tooling ecosystem.

# Quick start
$ git clone https://github.com/noundry/NoundryForms.git
$ cd NoundryForms/src/NoundryForms.Web && dotnet run

How It Works

Three simple steps: create an endpoint, point your HTML form, and receive submissions.

1. Point your form to Noundry Forms

<form action="https://forms.noundry.com/f/contact" method="POST">
 <input type="text" name="name" required>
 <input type="email" name="email" required>
 <textarea name="message" required></textarea>
 <button type="submit">Send</button>
</form>

2. Or use email-based endpoints

<!-- Submissions are emailed directly -->
<form action="https://forms.noundry.com/f/you@example.com" method="POST">
 <!-- Form fields -->
</form>

Features

Dashboard

Statistics, recent forms, submission tracking with IP, domain, and timestamps.

Email Notifications

Optional email delivery via Mailgun for each form submission.

AJAX Support

JavaScript helper for no-redirect submissions with custom success/error messages.

Spam Protection

Built-in honeypot field support. Submissions with filled honeypot fields are silently rejected.

CSV Export

Export form submissions for analysis in spreadsheet applications.

OAuth Login

GitHub authentication plus traditional username/password login.

API Reference

Submit Form

POST /f/{slug}

Content-Type: application/x-www-form-urlencoded

Reserved Fields

Field Description
_redirect_urlCustom URL to redirect after submission
_subjectCustom email subject line
_honeypotSpam protection - submission rejected if filled
_gotchaAlternative honeypot field name

AJAX Response

{
 "success": true,
 "message": "Form submitted successfully.",
 "redirectUrl": "https://...",
 "submissionId": "guid"
}

AJAX is detected via Accept: application/json header or X-Requested-With: XMLHttpRequest.

JavaScript Helper

Include the helper script for AJAX form submissions without page redirects.

<script src="https://forms.noundry.com/js/noundry-forms.js"></script>

<form action="https://forms.noundry.com/f/contact"
 method="POST"
 data-noundry-form
 data-success-message="Thanks! We'll be in touch."
 data-error-message="Oops! Please try again.">
 <!-- Form fields -->
</form>

Data Attributes

Attribute Description
data-noundry-formEnable AJAX submission (required)
data-success-messageCustom success message
data-error-messageCustom error message
data-redirectURL to redirect on success
data-loading-textButton text while submitting (default: "Sending...")
data-on-successGlobal function name to call on success
data-on-errorGlobal function name to call on error

JavaScript Events

form.addEventListener('noundry:success', (e) => {
 console.log('Submission ID:', e.detail.submissionId);
});

form.addEventListener('noundry:error', (e) => {
 console.log('Error:', e.detail.message);
});

Spam Protection

Add a hidden honeypot field to prevent bot submissions. Bots will fill it; humans will not.

<!-- Hidden honeypot - bots will fill this, humans won't -->
<div style="position: absolute; left: -9999px;">
 <input type="text" name="_honeypot" tabindex="-1" autocomplete="off">
</div>

Configuration

Configure via environment variables in a .env file.

# Database (required)
DATABASE_CONNECTION_STRING=Host=localhost;Port=5432;Database=noundryforms;...

# OAuth (optional)
GITHUB_CLIENT_ID=your_github_client_id
GITHUB_CLIENT_SECRET=your_github_client_secret

# Email via Mailgun (optional)
MAILGUN_API_KEY=your_mailgun_api_key
MAILGUN_DOMAIN=your_mailgun_domain
MAIL_FROM_ADDRESS=forms@yourdomain.com

# Application
APP_BASE_URL=https://forms.yourdomain.com

Security Features

BCrypt Password Hashing

Secure password storage using BCrypt.Net-Next.

CSRF Protection

Anti-forgery tokens on all dashboard forms.

Rate Limiting

30 requests/minute per form endpoint, 100/minute global.

Security Headers

X-Content-Type-Options, X-Frame-Options, X-XSS-Protection headers applied.

Built with Noundry

Forms showcases the full Noundry ecosystem in a production application.

Package Purpose
Noundry.TuxedoLightweight ORM for PostgreSQL
Noundry.Tuxedo.BowtieSchema migrations
Noundry.AuthnzOAuth 2.0 authentication (GitHub)
Noundry.DotEnvXEnvironment variable loading
Noundry.GuardianGuard clauses and validation
Noundry.SanquharEmail templating
Noundry.UIPre-built UI components
Noundry.TailbreezeTailwind CSS v4 integration

Project Structure

NoundryForms/
├── src/
│ └── NoundryForms.Web/
│ ├── Configuration/ # Settings classes
│ ├── DTOs/ # API response models
│ ├── Endpoints/ # Minimal API endpoints
│ ├── Models/ # Entity models (Account, Form, Submission)
│ ├── Services/ # Business logic
│ ├── EmailTemplates/ # Razor email templates
│ ├── Pages/ # Razor Pages (Dashboard, Forms, Submissions)
│ └── wwwroot/js/ # noundry-forms.js helper
├── tests/
│ └── NoundryForms.Tests/
├── docker-compose.yml
└── NoundryForms.sln

Docker Deployment

# docker-compose.yml
version: '3.8'
services:
 app:
 build: ./src/NoundryForms.Web
 ports:
 - "5000:8080"
 environment:
 - DATABASE_CONNECTION_STRING=Host=db;Port=5432;...
 depends_on:
 - db

 db:
 image: postgres:16
 environment:
 - POSTGRES_DB=noundryforms
 - POSTGRES_PASSWORD=your_password
 volumes:
 - postgres_data:/var/lib/postgresql/data
$ docker-compose up -d

Related Packages