This is a self-hosted connector for PostPipe. It acts as a secure bridge between PostPipe's Ingest API and your private database.
- Zero Trust: This connector never trusts the payload blindly. It verifies the request signature
X-PostPipe-Signatureusing yourJWT_SECRET(orPOSTPIPE_CONNECTOR_SECRET). - Environment Aliasing: Support for project-specific secrets and SMTP settings via a flexible aliasing system.
- No Leaks: Database credentials exist ONLY in this environment. PostPipe never sees them.
- Audit: All security logic is in
src/lib/security.ts. You are encouraged to read it.
npm installCopy .env.example to .env and fill in your details:
POSTPIPE_CONNECTOR_ID=pp_conn_...
JWT_SECRET=... # Keep this secret! (formerly POSTPIPE_CONNECTOR_SECRET)
DB_TYPE=mongodb # mongodb | postgres | supabasenpm run devThe server will listen on port 3000.
Endpoint: POST http://localhost:3000/postpipe/ingest
docker build -t my-connector .
docker run -p 3000:3000 --env-file .env my-connectorThis project is set up as a standard Express app. To deploy to Vercel, simply add a vercel.json:
{
"version": 2,
"builds": [{ "src": "src/server.ts", "use": "@vercel/node" }],
"routes": [{ "src": "/(.*)", "dest": "src/server.ts" }]
}The Postpipe Connector supports a powerful aliasing system. This allows you to deploy a single connector and serve multiple frontends/projects, each with its own configuration, by prefixing environment variables.
The connector prioritizes JWT_SECRET for signing and verifying tokens. If you provide an envFrontendUrlAlias (e.g., APP1) in your dashboard configuration, the connector will search for variables prefixed with that alias first.
Example .env:
# Global
JWT_SECRET="global-secret"
# Project-Specific Overrides
APP1_JWT_SECRET="secret-for-app1"
APP1_FRONTEND_URL="https://app1.com/reset-password"SMTP settings can also be aliased. If a project sends identifying metadata (like envFrontendUrlAlias), the connector will look for SMTP variables with that prefix.
Example .env for alias APP1:
APP1_EMAIL_PROVIDER="nodemailer"
APP1_SMTP_HOST="smtp.gmail.com"
APP1_SMTP_PORT="465"
APP1_SMTP_USER="app1@gmail.com"
APP1_SMTP_PASS="password-for-app1"
APP1_SMTP_SECURE="true"- Signature Validation Failed: Ensure
JWT_SECRETin your connector matches your dashboard settings. If using aliases, verifyALIAS_JWT_SECRET. - Email not sending: If using aliases, verify that
ALIAS_SMTP_HOSTetc. are correctly named in your.env. - Redirects failing: Ensure
ALIAS_FRONTEND_URLis correctly set for password reset routing.
This connector supports routing submissions to different databases based on the Form configuration.
When a payload arrives from PostPipe, the connector inspects the targetDatabase alias. This alias determines where the data goes.
graph TD
A[Form Submission Incoming] --> B{Does Submission have an explicit active Alias defined?}
B -- Yes (e.g., 'second-db') --> C{Is the Alias a Technical/System term?}
C -- No --> D[Use Custom Alias Name]
D --> E[Postgres: Creates table 'public.second_db']
D --> F[MongoDB: Saves to database 'second-db']
C -- Yes (e.g., 'postgres_url', 'mongodb') --> G[Fallback to Defaults]
G --> H[Postgres: Creates table 'public.postpipe_submissions']
G --> I[MongoDB: Saves to database 'postpipe']
B -- No (Default Form Route) --> G
When a form has an explicit Target Database set in the builder (like main-db or second-db), the connector actively prioritizes that exact name.
- MongoDB: It connects to the provided connection string and uses the alias as the database name. (e.g., connects strictly to the
main-dbdatabase). - Postgres: It connects using the provided connection string and generates a valid SQL table name from the alias. (e.g.,
main-dbbecomes thepublic.main_dbtable).
If the form has no target custom database set and falls back to the default project connectors (like MONGODB_URI or POSTGRES_URL environment variables), the system recognizes these are raw connection strings, not human-readable alias labels.
To avoid creating weird databases named "mongodb" or tables named "public.postgres_url", it securely defaults to:
- MongoDB: The
postpipedatabase. - Postgres: The
public.postpipe_submissionstable.
When a form uses Advanced Breakpoints (Conditional Logic) to split data to secondary databases based on submission values, the connector handles the routed data independently of the main form target.
graph TD
A[Breakpoint Rule Triggered] --> B[Data matches Breakpoint Split]
B --> C[Connector reads the Breakpoint's target string]
C --> D{Is the assigned target string a custom Alias?}
D -- Yes (e.g., 'main-db') --> E[Postgres: Table 'public.main_db']
D -- Yes (e.g., 'main-db') --> F[MongoDB: Database 'main-db']
D -- No (It's a .env connection variable like 'POSTGRES_URL') --> G[Fallback to Technical Default]
G --> H[Postgres: Table 'public.postpipe_submissions']
G --> I[MongoDB: Database 'postpipe']
Because Breakpoints are configured dynamically in the builder, they can either securely target a named Database Alias (like main-db) or fall back directly to the base environment variables (POSTGRES_URL).
If a Breakpoint routes strictly to the base variable without a named alias, the connector recognizes this and guarantees the data lands seamlessly in your primary default database/tables (postpipe and public.postpipe_submissions).
The connector is designed to guarantee SQL compatibility in Postgres. You can safely name your databases with hyphens or spaces in the builder UI without breaking the connector.
| Custom Builder Alias | MongoDB Database Name | Postgres Table Name |
|---|---|---|
main-db |
main-db |
public.main_db |
marketing forms |
marketing forms |
public.marketing_forms |
second-db |
second-db |
public.second_db |
(None / MONGODB_URI)* |
postpipe |
public.postpipe_submissions |
In the Form Builder, use the Target Database feature:
- Click [+ Add DB].
- Enter an ID (e.g.,
marketing). - Select this ID for your form.
The connector dynamically looks for an environment variable matching the ID:
# Default DB
MONGODB_URI=mongodb+srv://...
# Secondary DB (ID: "marketing")
MONGODB_URI_MARKETING=mongodb+srv://...
# Another DB (ID: "finance")
MONGODB_URI_FINANCE=mongodb+srv://...Note: The connector automatically maps the ID to uppercase and prepends MONGODB_URI_.
You can fetch submissions directly from the connector (bypassing PostPipe cloud) using the local API:
Endpoint: GET /api/postpipe/forms/:formId/submissions
Parameters:
limit(optional): Number of records (default 50).
CORS: Enabled by default for all origins.