Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/meenalsingh0/GradGather/llms.txt

Use this file to discover all available pages before exploring further.

GradGather centralises all runtime configuration through environment variables loaded by the dotenv package. When the Express server starts, src/index.js calls require("dotenv").config() before any routes are registered, making every variable defined in a root-level .env file available on process.env throughout the application.

Environment Variables

The table below documents every environment variable GradGather reads at runtime. Create a .env file in the project root and populate the variables relevant to your deployment.
PORT
number
The TCP port the Express HTTP server binds to. Defaults to 3000 if not set — equivalent to the fallback process.env.PORT || 3000 in src/index.js. Change this if port 3000 is already occupied on your machine or host.
PAYPAL_MODE
string
required
Controls which PayPal environment the REST SDK targets. Accepted values are sandbox (for development and testing with simulated transactions) and live (for real monetary transactions in production). This variable is required whenever the donation feature is used — omitting it will cause PayPal API calls to fail.
PAYPAL_CLIENT_KEY
string
required
The Client ID of your PayPal REST application. Obtain this from the PayPal Developer Dashboard under My Apps & Credentials. Use the sandbox Client ID when PAYPAL_MODE=sandbox, and the live Client ID when PAYPAL_MODE=live.
PAYPAL_SECRET_KEY
string
required
The Secret Key (client secret) of your PayPal REST application. Keep this value confidential — never commit it to version control. Rotate it from the PayPal Developer Dashboard if it is ever exposed.
GradGather does not read a MONGODB_URI environment variable. The MongoDB connection string is hard-coded in src/mongo.js as mongodb://localhost:27017/LoginFormPractice. To change the database connection you must edit that file directly.

MongoDB Connection

GradGather connects to MongoDB using Mongoose, a schema-based ODM for Node.js. The connection is established in src/mongo.js, which is require-d by src/index.js at startup. The connection string is hard-coded in that file and targets a local MongoDB instance:
// src/mongo.js
const mongoose = require("mongoose")

mongoose.connect("mongodb://localhost:27017/LoginFormPractice")
  .then(() => {
    console.log('mongoose connected');
  })
  .catch((e) => {
    console.log('failed');
  })
The database name is LoginFormPractice. MongoDB must be running locally on the default port 27017 for the application to connect successfully. There is no environment-variable override for the connection string in the current source — any change requires editing src/mongo.js directly.

LogInCollection Schema

src/mongo.js defines a single Mongoose model, LogInCollection, used to persist user credentials:
// src/mongo.js
const logInSchema = new mongoose.Schema({
  username: {
    type: String,
    required: true
  },
  password: {
    type: String,
    required: true
  }
})

const LogInCollection = new mongoose.model('LogInCollection', logInSchema)

module.exports = LogInCollection
The schema declares username and password as required String fields.
Schema / handler field mismatch. The POST /signup and POST /login handlers in src/index.js read req.body.name and write { name, password } to the database — they use the field key name, not username. Because the Mongoose schema defines username (not name), the name field is written to MongoDB outside of schema validation, while the declared username field is never populated. This means the schema and the route handlers are inconsistent in the current source. Be aware of this discrepancy if you extend the authentication logic or add schema-level validation.
Passwords are stored in plaintext. The default implementation writes the password field to MongoDB exactly as submitted by the user — no hashing or salting is applied. This is not suitable for any production or publicly accessible deployment. Before going live, integrate a password hashing library such as bcrypt and store only the resulting hash in the database.

Authentication Routes

The two active POST routes in src/index.js handle account creation and login: POST /signup — reads req.body.name and req.body.password, saves { name, password } via LogInCollection.insertMany(), and renders the landing view on success. If a document with the same name and password already exists, it responds with "User details already exist". On any error, it redirects to /. POST /login — queries LogInCollection.findOne({ name: req.body.name }) and compares check.password against req.body.password. On a match it renders landing with the naming template variable; on a mismatch it responds "incorrect password"; on a thrown error (e.g. user not found) it responds "wrong details".
// src/index.js — POST /signup
app.post("/signup", async (req, res) => {
  const data = {
    name: req.body.name,
    password: req.body.password,
  };

  try {
    const checking = await LogInCollection.findOne({ name: req.body.name });

    if (
      checking &&
      checking.name === req.body.name &&
      checking.password === req.body.password
    ) {
      res.send("User details already exist");
    } else {
      await LogInCollection.insertMany([data]);
      res.status(201).render("landing", { naming: req.body.name });
    }
  } catch (error) {
    res.redirect("/");
  }
});

// src/index.js — POST /login
app.post("/login", async (req, res) => {
  try {
    const check = await LogInCollection.findOne({ name: req.body.name });

    if (check.password === req.body.password) {
      res
        .status(201)
        .render("landing", { naming: `${req.body.password}+${req.body.name}` });
    } else {
      res.send("incorrect password");
    }
  } catch (e) {
    res.send("wrong details");
  }
});

PayPal Integration

Donation payments flow through the PayPal REST SDK. The SDK is configured in src/controllers/paymentController.js by reading the three PayPal environment variables described above:
// src/controllers/paymentController.js
const paypal = require('paypal-rest-sdk');

const { PAYPAL_MODE, PAYPAL_CLIENT_KEY, PAYPAL_SECRET_KEY } = process.env;

paypal.configure({
  'mode': PAYPAL_MODE,           // 'sandbox' or 'live'
  'client_id': PAYPAL_CLIENT_KEY,
  'client_secret': PAYPAL_SECRET_KEY
});
paypal.configure() is called once when the module is first loaded, so the credentials are set for the lifetime of the process. To switch between sandbox and live without redeploying, update PAYPAL_MODE and the corresponding credential variables in .env and restart the server.
The payment controller (src/controllers/paymentController.js) defines the PayPal logic, but the route that mounts it (/paymentGateway) is commented out in src/index.js. The GET routes for /paymentGateway, /success, and /cancel render their respective views, but the controller’s payProduct and successPage functions are not actively wired to routes in the current source.

Sandbox vs. Live Mode

ModeWhen to useCredential source
sandboxLocal development, QA, and testing with simulated PayPal accountsPayPal Developer Sandbox
liveReal donations from real PayPal accountsPayPal Live App Credentials
The payment flow creates a sale intent through paypal.payment.create(), redirects the user to PayPal for approval, and then executes the payment via paypal.payment.execute() on the return callback. A cancelled transaction routes to GET /cancel.

Template Engine

GradGather uses HBS — a lightweight Express integration for Handlebars — as its server-side rendering engine. The view engine is configured in src/index.js:
// src/index.js
const tempelatePath = path.join(__dirname, "../tempelates");
const publicPath = path.join(__dirname, "../public");

app.set("view engine", "hbs");
app.set("views", tempelatePath);
app.use(express.static(publicPath));
Key points about the template configuration:
  • Views directorytempelates/ (note: the directory name contains a deliberate typo — tempelates rather than templates — which matches the source repository exactly and must be preserved for the app to find its views).
  • Static assets — CSS stylesheets and images are served from public/. Templates reference these assets with paths such as css/home.css and images/Assets/BridgeULogo.png, which Express resolves relative to the public/ root.
  • Rendering — Each route calls res.render("<view-name>"), where <view-name> maps to a .hbs file in the tempelates/ directory (e.g., res.render("home") renders tempelates/home.hbs).

Build docs developers (and LLMs) love