diff --git a/workflows/Create a Complete User Authentication System with PostgreSQL & Webhooks-10040/readme-10040.md b/workflows/Create a Complete User Authentication System with PostgreSQL & Webhooks-10040/readme-10040.md new file mode 100644 index 000000000..ff6271dbf --- /dev/null +++ b/workflows/Create a Complete User Authentication System with PostgreSQL & Webhooks-10040/readme-10040.md @@ -0,0 +1,381 @@ +Create a Complete User Authentication System with PostgreSQL & Webhooks + +https://n8nworkflows.xyz/workflows/create-a-complete-user-authentication-system-with-postgresql---webhooks-10040 + + +# Create a Complete User Authentication System with PostgreSQL & Webhooks + +### 1. Workflow Overview + +This workflow implements a **Complete User Authentication System** integrating PostgreSQL as the backend database and n8n webhooks as the API entry point. It supports three core functionalities: + +- **User Signup:** Registers new users with bcrypt-hashed passwords. +- **User Login:** Authenticates users by verifying credentials in a case-insensitive manner. +- **Forgot Password:** Resets and returns a new random password for users who forgot theirs. + +The workflow logically divides into these blocks: + +- **1.1 Input Reception:** A webhook node listens for incoming POST requests containing authentication actions. +- **1.2 Request Routing:** A switch node routes the request based on the `path` property (`signup`, `signin`, or `forgot`). +- **1.3 Signup Processing:** Inserts a new user into the PostgreSQL `users` table with hashed password. +- **1.4 Login Verification:** Queries the database to validate credentials and uses an IF node to confirm success. +- **1.5 Forgot Password Handling:** Updates the user's password with a new random string. +- **1.6 Response Generation:** Sends back a structured JSON response indicating success or failure for each operation. +- **1.7 Documentation and Setup Notes:** Sticky notes provide detailed explanations, usage instructions, and prerequisites for the database setup. + +--- + +### 2. Block-by-Block Analysis + +#### 2.1 Input Reception + +- **Overview:** Receives all incoming authentication requests via a POST webhook at `/webhook/auth`. +- **Nodes Involved:** + - `Webhook` + - `Webhook Doc` (Sticky Note) + - `Overview` (Sticky Note) + +- **Node Details:** + + - **Webhook** + - Type: Webhook + - Role: Entry point for all auth requests. + - Config: HTTP POST method, path set to `auth`, response mode configured to use a response node downstream. + - Inputs: HTTP POST request JSON payload with keys: `path`, `email`, `password`, `name`. + - Outputs: JSON data forwarded to Router node. + - Failure Modes: Invalid HTTP method, missing fields in payload, webhook misconfiguration. + - Version: v2.1 + + - **Webhook Doc** + - Type: Sticky Note + - Role: Documents webhook usage, expected JSON input format, and routing logic based on the `path` field. + + - **Overview** + - Type: Sticky Note + - Role: High-level description of workflow purpose, prerequisites, and usage example. + +#### 2.2 Request Routing + +- **Overview:** Routes incoming requests to corresponding processing blocks based on the `path`: `signup`, `signin`, or `forgot`. +- **Nodes Involved:** + - `Router` (Switch node) + - `Switch Doc` (Sticky Note) + +- **Node Details:** + + - **Router** + - Type: Switch + - Role: Checks the `path` field in the JSON payload (case-sensitive string). + - Config: Matches exact strings: `signup`, `signin`, `forgot`. + - Inputs: JSON from Webhook node. + - Outputs: + - Output 1 → `signup` flow + - Output 2 → `signin` flow + - Output 3 → `forgot` flow + - Output 0 (default) → no action + - Failure Modes: Missing or invalid `path` value, case-sensitivity issues. + - Version: v1 + + - **Switch Doc** + - Type: Sticky Note + - Role: Explains routing logic and default behavior for invalid paths. + +#### 2.3 Signup Processing + +- **Overview:** Inserts a new user record into PostgreSQL with bcrypt-hashed password. +- **Nodes Involved:** + - `Signup` (PostgreSQL node) + - `Signup Doc` (Sticky Note) + +- **Node Details:** + + - **Signup** + - Type: PostgreSQL + - Role: Executes an SQL INSERT query to add a new user with hashed password. + - Config: + - Query uses `crypt` with `gen_salt('bf')` (bcrypt) to hash password. + - Inserts `full_name`, `email`, `password_hash`. + - Returns `id`, `full_name`, `email`, `created_at`. + - Inputs: JSON containing `name`, `email`, `password`. + - Outputs: Inserted user data on success. + - Credential: Uses PostgreSQL credential named "Project: Edubot". + - Failure Modes: Email uniqueness violation, DB connection issues, SQL errors. + - Version: v2.6 + + - **Signup Doc** + - Type: Sticky Note + - Role: Documents SQL query, purpose, output, and notes on password hashing and email uniqueness. + +#### 2.4 Login Verification + +- **Overview:** Validates user credentials by comparing input password with stored bcrypt hash, case-insensitive email matching. +- **Nodes Involved:** + - `Login` (PostgreSQL node) + - `Check Login` (IF node) + - `Login Doc` (Sticky Note) + - `IF Doc` (Sticky Note) + +- **Node Details:** + + - **Login** + - Type: PostgreSQL + - Role: Runs SQL SELECT to fetch user fields and verify password with `crypt`. + - Config: + - `WHERE LOWER(email) = LOWER(input_email)` for case-insensitive email match. + - Returns `id`, `full_name`, `email`, and a boolean `isPasswordMatch`. + - Inputs: JSON with `email`, `password`. + - Outputs: User data with password match boolean. + - Credential: "Project: Edubot" PostgreSQL. + - Failure Modes: No user found, password mismatch, DB errors. + - Version: v2.6 + + - **Check Login** + - Type: IF + - Role: Checks if `id` exists and `isPasswordMatch` is `true`. + - Config: Boolean condition that evaluates to true only if both criteria are met. + - Inputs: Output of Login node. + - Outputs: + - True path → successful login response. + - False path → error response (invalid credentials). + - Failure Modes: Expression errors, missing fields. + - Version: v2.2 + + - **Login Doc** + - Type: Sticky Note + - Role: Explains SQL query, case-insensitive email check, and output fields. + + - **IF Doc** + - Type: Sticky Note + - Role: Explains validation logic and conditional response routing. + +#### 2.5 Forgot Password Handling + +- **Overview:** Resets user password to a new random 8-character string and returns it. +- **Nodes Involved:** + - `Reset Password` (PostgreSQL node) + - `Forgot Password Doc` (Sticky Note) + +- **Node Details:** + + - **Reset Password** + - Type: PostgreSQL + - Role: Performs an UPDATE on the `users` table to set a new bcrypt-hashed password generated randomly. + - Config: Uses a CTE (`WITH new_pass AS (...)`) to generate a random 8-character password using `substring(md5(random()::text) from 1 for 8)`. + - Updates password hash with bcrypt and returns email and new plain password. + - Inputs: JSON with `email`. + - Outputs: Email and new password fields. + - Credential: "Project: Edubot" PostgreSQL. + - Failure Modes: No user found with that email, DB errors. + - Version: v2.6 + + - **Forgot Password Doc** + - Type: Sticky Note + - Role: Explains SQL logic, case-insensitive email lookup, and output structure. + +#### 2.6 Response Generation + +- **Overview:** Sends back a uniform JSON response indicating success or failure and relevant data. +- **Nodes Involved:** + - `Respond` (Respond to Webhook node) + - `Response Doc` (Sticky Note) + +- **Node Details:** + + - **Respond** + - Type: Respond to Webhook + - Role: Returns JSON to the client based on upstream node output. + - Config: Default settings, linked to receive output from all main process nodes. + - Inputs: Success or error data from Signup, Login (true or false), or Reset Password nodes. + - Outputs: HTTP JSON response with fields: + - `status`: "success" or "error" + - `message`: descriptive string + - `data`: object with query results or empty. + - Failure Modes: Response generation failure, invalid JSON format. + - Version: v1.4 + + - **Response Doc** + - Type: Sticky Note + - Role: Describes response JSON format and usage notes. + +#### 2.7 Database Setup & Documentation + +- **Overview:** Provides instructions for setting up PostgreSQL/Supabase database schema and extensions. +- **Nodes Involved:** + - `Database Setup` (Sticky Note) + +- **Node Details:** + + - **Database Setup** + - Type: Sticky Note + - Role: Detailed step-by-step for creating Supabase project, enabling required extensions (`uuid-ossp`, `pgcrypto`), creating `users` table with unique email, and adding credentials to n8n. + - Contains example SQL for table creation. + +--- + +### 3. Summary Table + +| Node Name | Node Type | Functional Role | Input Node(s) | Output Node(s) | Sticky Note | +|-----------------|-------------------------|-------------------------------------------|---------------------|------------------------|---------------------------------------------------------------------------------------------------------------------| +| Overview | Sticky Note | Workflow purpose, prereqs, usage example | — | — | Explains purpose, features, usage, prerequisites, example input/output JSON | +| Webhook Doc | Sticky Note | Documents webhook input and routing | — | — | Explains webhook POST endpoint, input JSON structure, routing logic | +| Webhook | Webhook | Receives auth requests via POST | — | Router | | +| Switch Doc | Sticky Note | Documents Router node routing logic | — | — | Describes routing rules based on `path` field | +| Router | Switch | Routes request to signup/login/forgot | Webhook | Signup, Login, Reset Password | | +| Signup Doc | Sticky Note | Documents Signup SQL and logic | — | — | Details INSERT SQL, bcrypt usage, output, unique email requirement | +| Signup | PostgreSQL | Inserts new user with hashed password | Router (signup output) | Respond | | +| Login Doc | Sticky Note | Documents Login SQL and logic | — | — | Explains case-insensitive email check and password verification | +| Login | PostgreSQL | Validates user credentials | Router (signin output) | Check Login | | +| IF Doc | Sticky Note | Explains login validation condition | — | — | Details IF node condition on `id` and `isPasswordMatch` | +| Check Login | IF | Determines login success/failure | Login | Respond (true & false) | | +| Forgot Password Doc | Sticky Note | Documents password reset SQL and logic | — | — | Explains random password generation and update query | +| Reset Password | PostgreSQL | Resets password to random string | Router (forgot output) | Respond | | +| Response Doc | Sticky Note | Documents response JSON format | — | — | Describes success/error response structure | +| Respond | Respond to Webhook | Sends JSON response to client | Signup, Check Login, Reset Password | — | | +| Database Setup | Sticky Note | Guides PostgreSQL/Supabase setup | — | — | Setup instructions for database, extensions, table creation, and credentials | + +--- + +### 4. Reproducing the Workflow from Scratch + +1. **Create a new workflow in n8n.** + +2. **Add a Webhook node:** + - Name: `Webhook` + - HTTP Method: POST + - Path: `auth` + - Response Mode: `Response Node` + - This will be the entry point for all auth requests. + +3. **Add a Switch node:** + - Name: `Router` + - Input: connect from `Webhook` node. + - Property to check: `path` from the incoming JSON. + - Rules (string matching): + - `signup` → Output 1 + - `signin` → Output 2 + - `forgot` → Output 3 + - Default output: 0 (no action) + +4. **Create Signup block:** + - Add a PostgreSQL node named `Signup`. + - Credentials: Set PostgreSQL credentials with access to your database. + - Query: + ```sql + INSERT INTO users (full_name, email, password_hash) + VALUES ( + '{{$json["name"]}}', + '{{$json["email"]}}', + crypt('{{$json["password"]}}', gen_salt('bf')) + ) + RETURNING id, full_name, email, created_at; + ``` + - Connect Router output 1 to Signup input. + +5. **Create Login block:** + - Add a PostgreSQL node named `Login`. + - Credentials: same PostgreSQL credentials. + - Query: + ```sql + SELECT + id, + full_name, + email, + (password_hash = crypt('{{$json["password"]}}', password_hash)) AS "isPasswordMatch" + FROM users + WHERE LOWER(email) = LOWER('{{$json["email"]}}'); + ``` + - Connect Router output 2 to Login input. + + - Add an IF node named `Check Login`. + - Connect Login output to Check Login input. + - Condition: Boolean expression: + `{{$json["id"] !== undefined && $json["isPasswordMatch"] === true}}` equals `true`. + - True output → successful login path. + - False output → invalid credentials path. + +6. **Create Forgot Password block:** + - Add a PostgreSQL node named `Reset Password`. + - Credentials: same PostgreSQL credentials. + - Query: + ```sql + WITH new_pass AS ( + SELECT substring(md5(random()::text) from 1 for 8) AS plain_password + ) + UPDATE users + SET password_hash = crypt(new_pass.plain_password, gen_salt('bf')) + FROM new_pass + WHERE LOWER(email) = LOWER('{{$json["email"]}}') + RETURNING email, new_pass.plain_password AS newPassword; + ``` + - Connect Router output 3 to Reset Password input. + +7. **Add a Respond to Webhook node named `Respond`:** + - Connect outputs from: + - Signup node + - Check Login node (both true and false outputs) + - Reset Password node + - Configure to return JSON responses in the format: + ```json + { + "status": "success" | "error", + "message": "string", + "data": { ... } + } + ``` + - Implement logic in the workflow or via expressions to set `status` and `message` accordingly: + - Signup success → success status with user data + - Login success → success status with user data + - Login failure → error status with message "Invalid credentials" + - Forgot password success → success status with new password + - Any errors → error status with error message + +8. **Setup PostgreSQL database:** + - Create a Supabase project or PostgreSQL database. + - Enable extensions: + ```sql + CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; + CREATE EXTENSION IF NOT EXISTS "pgcrypto"; + ``` + - Create `users` table: + ```sql + CREATE TABLE users ( + id uuid PRIMARY KEY DEFAULT uuid_generate_v4(), + full_name text NOT NULL, + email text UNIQUE NOT NULL, + password_hash text NOT NULL, + created_at timestamptz DEFAULT now() + ); + ``` + - Add PostgreSQL credentials in n8n with appropriate permissions. + +9. **Test the workflow:** + - Send POST requests to `/webhook/auth` with JSON payloads like: + ```json + { + "path": "signup", + "email": "user@example.com", + "password": "pass123", + "name": "John Doe" + } + ``` + - Test with other paths `signin` and `forgot`. + - Confirm expected JSON responses. + +--- + +### 5. General Notes & Resources + +| Note Content | Context or Link | +|--------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------| +| PostgreSQL must have `uuid-ossp` and `pgcrypto` extensions enabled for UUID generation and bcrypt password hashing. | Database setup instructions in sticky note. | +| Supabase is recommended for easy PostgreSQL hosting and management. | https://supabase.com | +| The workflow handles all auth actions via a single webhook endpoint `/webhook/auth` using the `path` field for routing. | Documentation in `Webhook Doc` sticky note. | +| Passwords are hashed securely using bcrypt (`gen_salt('bf')`), and login checks password correctness via PostgreSQL's `crypt` function. | Security best practices documented in Signup/Login Docs. | +| Email uniqueness is enforced by a unique constraint in the `users` table; signup will fail with duplicate emails. | Database schema notes. | +| The forgot password flow returns the new password in the response JSON; additional logic can be added to email the new password to the user securely. | Suggested extension for production systems. | +| Case-insensitive email lookup prevents user errors related to email casing during login and password reset. | Documented in Login and Forgot Password Docs. | +| The response node returns a consistent JSON structure with status, message, and data fields for all flows. | Response formatting notes. | + +--- + +This completes the detailed reference documentation of the "Authentication Panel (Signup/Login/Forgot Password)" n8n workflow, enabling understanding, reproduction, and adaptation for user authentication systems leveraging PostgreSQL and webhooks. \ No newline at end of file