Skip to content

HalcyonVector/Formflow

Repository files navigation

FormFlow β€” Google Forms Replica for College

A Google Forms replica built specifically for college instructors and students. Create, distribute, and analyze forms with advanced features like form templates, role-based access, deadline management, and comprehensive response analytics.

🎯 Features

For Faculty/Instructors

  • Create Custom Forms β€” Build surveys, quizzes, feedback forms, and questionnaires
  • Multiple Question Types β€” Text, textarea, number, email, date, and multiple-choice (MCQ)
  • Form Templates β€” Quick-start with 7 pre-built templates:
    • Event Registration
    • Course Evaluation
    • Faculty Feedback Form
    • Quiz / Internal Test
    • Leave Application
    • Lab Feedback
    • Doubt/Query Submission
  • Access Control β€” Public forms or department-specific group forms
  • Deadline Management β€” Set response deadlines and auto-close expired forms
  • Response Management β€” View, filter, and download responses in real-time
  • Report Release β€” Control when students can see form results
  • Theme Customization β€” Choose theme colors for forms
  • Response Restrictions β€” Allow single or multiple responses per student

For Students

  • Easy Form Access β€” Access forms via unique form codes
  • Fill & Submit β€” Intuitive interface for completing forms
  • Multi-question Support β€” Answer various question types seamlessly
  • Submission Confirmation β€” Get confirmation after submission
  • View Results β€” See form results when instructor releases reports

Technical Highlights

  • Oracle Database β€” Enterprise-grade SQL backend
  • Advanced Triggers & Procedures β€” PL/SQL automation for deadline validation and response tracking
  • Audit Logging β€” Track form creation and response submissions
  • JSON Templates β€” Efficient template storage using CLOB

πŸ› οΈ Tech Stack

Component Technology
Backend Node.js with Express.js (ES6 modules)
Frontend HTML5, CSS3, Vanilla JavaScript, Tailwind CSS
Database Oracle SQL (XEPDB1) with PL/SQL
Server Express.js (v5.2.1)
Auth JWT (jsonwebtoken) + bcryptjs
ORM/Driver oracledb (v6.10.0)

πŸ“‹ Prerequisites

πŸš€ Installation & Setup

1. Clone the Repository

git clone https://github.com/sagnik0606-ux/formflow.git
cd formflow

2. Install Dependencies

npm install

3. Configure Oracle Database

Create/Update .env file:

DB_USER=user
DB_PASSWORD=user_pwd
DB_HOST=localhost
DB_PORT=1521
DB_SERVICE=XEPDB1
NODE_ENV=development
PORT=8000
JWT_SECRET=your_strong_random_secret_here

⚠️ Important: Never commit .env to Git. It's already in .gitignore. The JWT_SECRET must be a long, random string β€” it signs all authentication tokens.

4. Create Database Schema

Run the SQL setup script in your Oracle Database (SQL Developer or SQL*Plus):

# Via SQL Developer, run project_db.sql entirely
# OR via sqlplus:
sqlplus user/user@XEPDB1 @project_db.sql

This creates:

  • 8 tables (users, forms, questions, options, responses, answers, audit_logs, form_templates)
  • 4 PL/SQL triggers (deadline validation, response blocking, audit tracking)
  • 2 PL/SQL procedures (form status toggle, expire forms)
  • 1 PL/SQL function (count responses)
  • 7 pre-loaded form templates (JSON-based)
  • Sample data (2 users, 2 forms, questions, responses)

5. (Optional) Migrate Existing Passwords

If you have existing users with plain-text passwords in the database, run the one-time migration script to hash them without resetting accounts:

node --env-file=.env migrate_passwords.js

6. Start the Server

Development (with auto-reload):

npm run dev

Production:

npm start

Server runs at http://localhost:8000

πŸ“š Project Structure

formflow/
β”œβ”€β”€ public/
β”‚   β”œβ”€β”€ signin.html           # Login page (glass-morphism UI)
β”‚   β”œβ”€β”€ dashboard.html        # Main instructor dashboard
β”‚   β”œβ”€β”€ auth-helper.js        # Client-side JWT storage & auth header utility
β”‚   β”œβ”€β”€ newForm.js            # Create/edit forms + template selection
β”‚   β”œβ”€β”€ myForms.js            # Instructor's form list + management
β”‚   β”œβ”€β”€ fillForm.js           # Student form-filling interface
β”‚   β”œβ”€β”€ myResponses.html      # Student view their responses
β”‚   └── audit.js              # Audit log viewer
β”œβ”€β”€ routes/
β”‚   β”œβ”€β”€ auth.js               # Login/signup/me/change-password endpoints
β”‚   β”œβ”€β”€ forms.js              # Form CRUD + template endpoints (JWT-protected)
β”‚   └── responses.js          # Response submission + retrieval (JWT-protected)
β”œβ”€β”€ middleware/
β”‚   └── auth.js               # requireAuth JWT verification middleware
β”œβ”€β”€ db.js                     # Oracle connection manager
β”œβ”€β”€ server.js                 # Express app entry point
β”œβ”€β”€ package.json              # Dependencies + scripts
β”œβ”€β”€ project_db.sql            # Full database schema + data
β”œβ”€β”€ migrate_passwords.js      # One-time password hashing migration script
β”œβ”€β”€ tmp_db_update.js          # Migration script (run once)
β”œβ”€β”€ .env                      # Database credentials + JWT secret (NEVER commit)
β”œβ”€β”€ .gitignore                # Git ignore rules
└── README.md                 # This file

πŸ”Œ API Endpoints

Authentication

  • POST /auth/login β€” User login

    • Body: { email, password }
    • Response: { ok: true, token: "<jwt>", redirect: "/dashboard.html" }
  • POST /auth/signup β€” User registration

    • Body: { name, email, password, user_type (student|faculty), department, batch? }
  • GET /auth/me β€” Get current user info (requires JWT)

  • POST /auth/change-password β€” Change own password (requires JWT)

    • Body: { current_password, new_password }

All protected endpoints require the header: Authorization: Bearer <token>

Forms

  • POST /forms/create β€” Create new form

    • Body: { title, description, access_type, target_dept?, deadline, theme_color? }
    • Response: { form_id, form_code }
  • GET /forms/all β€” Get all user's forms

    • Returns: Form list with response counts
  • GET /forms/:formId β€” Get form details + questions

    • Returns: Form + questions + options
  • PUT /forms/:formId β€” Update form details

  • DELETE /forms/:formId β€” Delete form

  • GET /forms/by-code/:code β€” Get form by unique code (student access)

  • GET /forms/templates β€” Get all form templates

  • POST /forms/from-template β€” Create form from template

Responses

  • POST /responses/submit β€” Submit form response

    • Body: { form_id, answers: [{ question_id, answer_text|answer_number|option_id }] }
  • GET /responses/form/:formId β€” Get all responses to a form (instructor only)

    • Returns: Aggregate stats + individual responses
  • GET /responses/user/:userId β€” Get responses submitted by user (student view)

πŸ—„οΈ Database Schema Overview

Tables

Table Purpose
users Faculty & student accounts
forms Form definitions + metadata
questions Form questions with types
options MCQ options
responses Form submissions (one per student per form)
answers Individual answers to questions
form_templates JSON-based form templates
audit_logs Action tracking (create, submit, etc.)

Key Constraints

  • Forms cannot have past deadlines (trigger: trg_form_deadline_check)
  • Responses blocked on expired/closed forms (trigger: trg_prevent_invalid_response)
  • Auto-populate response counts via function: fn_get_response_count()

🎨 Frontend Features

Glass-Morphism UI

  • Modern frosted glass design using Tailwind CSS
  • DM Sans font family
  • Toast notifications (error/success)
  • Responsive mobile-first layout

Sign-In Page

  • Email + password authentication
  • Sign-up toggle for new users
  • Remember-me option (optional)

Dashboard (Instructor)

  • Overview: Total forms, responses pending, active forms
  • Create new form or from template
  • Manage existing forms (edit, delete, view responses)
  • Analytics sidebar

Form Creation (newForm.js)

  • Drag-and-drop question reordering
  • Add/remove questions dynamically
  • Rich question customization (required field, help text)
  • Template quick-start
  • Live preview

Form Filling (fillForm.js)

  • Progressive form rendering
  • Type-specific input validation
  • Progress indicator
  • Submit confirmation

πŸ” Security

βœ… Implemented

  1. Password Hashing β€” Passwords are hashed with bcryptjs (cost factor 12) on signup and verified with bcrypt.compare() on login. Plain-text passwords are never stored.
  2. JWT Authentication β€” A signed JWT (userId + userType, 8h expiry) is issued on login and must be sent as a Bearer token on all protected requests.
  3. Auth Middleware β€” middleware/auth.js verifies the JWT and injects req.user on every protected route. The client never supplies a user_id directly.
  4. IDOR Protection β€” All routes in forms.js and responses.js derive ownership from the verified JWT (req.user.id), not from any client-supplied parameter.
  5. Database Credentials β€” Stored in .env, never hardcoded. .env is gitignored.
  6. Input Validation β€” All Oracle queries use bind parameters to prevent SQL injection.
  7. Audit Logs β€” Track all create/submit actions.
  8. Password Migration β€” migrate_passwords.js available to hash any legacy plain-text passwords without resetting accounts.

⚠️ Pending / To Improve

  • Security Headers β€” helmet not yet added; headers like Content-Security-Policy and X-Frame-Options are missing.
  • Rate Limiting β€” express-rate-limit not yet added; login/signup endpoints are still vulnerable to brute-force.
  • HttpOnly Cookies β€” Token is currently stored client-side in JS; switching to HttpOnly cookies would protect against XSS token theft.
  • CORS β€” Enabled globally with no origin restriction; should be locked to known origins in production.

🚦 Running the App

Development

npm run dev
# Auto-reloads on file changes

Production

npm start

Test Data

After running project_db.sql:

  • Faculty Account: email alice.miller@college.edu (password: hashedpw123)
  • Student Account: email Dr. Bob Smith (password: hashedpw456)
  • Sample Forms: "Midsem Feedback" (Form ID: 1), "CS Dept Survey" (Form ID: 2)

πŸ› Troubleshooting

"Cannot connect to database"

# Check Oracle is running
sqlplus /nolog
SQL> connect user/user@XEPDB1

# Check .env credentials match
cat .env

"Module not found" errors

# Reinstall dependencies
rm -rf node_modules package-lock.json
npm install

Port 8000 already in use

# Change in .env: PORT=8001
# Or kill the process:
lsof -i :8000
kill -9 <PID>

Form won't submit

  • Check deadline hasn't passed (DB trigger will reject)
  • Verify all required questions are answered
  • Check audit_logs table for errors

"Invalid or expired token"

  • JWT expires after 8 hours β€” log in again for a fresh token
  • Ensure JWT_SECRET in .env is set and hasn't changed between server restarts

πŸ“ˆ Future Enhancements

  • Bcrypt password hashing
  • JWT authentication
  • JWT refresh tokens
  • helmet security headers
  • Rate limiting on auth endpoints (express-rate-limit)
  • HttpOnly Cookie token storage
  • Conditional branching (skip logic)
  • Email notifications on new responses
  • Advanced analytics charts (Chart.js/D3.js)
  • LMS integration (Canvas, Blackboard)
  • Export to CSV/PDF with formatting
  • Role-based access control (department admin)
  • Form versioning & drafts
  • Real-time collaboration (WebSockets)
  • Mobile app (React Native)

πŸ‘¨β€πŸ’» Author

Vector
GitHub: @HalcyonVector

πŸ™‹ Support

Found a bug or have a feature request?
Open an issue on GitHub.


Made with ❀️ for educators and students everywhere

About

Google Forms replica for college instructors and students

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors