EcoFabLab

Cluster and in-house recycling at Dawson College.

EcoFabLab is a small web app for a recycling and fabrication lab on the Dawson College campus. Students bring in recyclable waste (PET bottles, textiles, wood, bolts and nails, …) and earn points. They can spend those points on lab services, such as 3D-printer time, or send them to other students.

The project also shows and evaluates how effective cluster recycling and in-house recycling are in urban environments. The goal is for as little of our recyclable waste as possible to leave the neighbourhood.

Features

Everyone

  • Home page: what the project is, why it matters, and the 4-step PET recycling process: Collecting → Cleaning → Reshaping → Processing (melted into 3D-printer filament).
  • Sign up / log in with a username and password.

Logged-in users

  • Points page: your current balance, plus a personal QR code that holds your username, first name and last name (as JSON). Show it to an admin to receive points.
  • Booking: book a 3D printer for today.
    • Pick a printer, a start time and a duration of 15, 30 or 45 minutes (45 max).
    • Cost = the printer's credits_per_hour, prorated by the minutes booked and rounded up.
    • One active booking per person. You can book again once your slot has ended.
    • Printers are shared by time slot: others can book the same printer at times that don't overlap. The page shows which slots are already taken.
    • Only printers marked Available can be booked (Out of service and Reserved only can't).
  • Transfer: send points to another user.
    • Search users by username, first name or last name, and pick one from the suggestions.
    • The amount must be a whole number, no more than your balance, and you can't send to yourself.

Admins

  • A separate admin login ("Sign in as admin" on the login page).
  • The admin page does one thing: add points to a user. Choose the user by:
    • picking them from the list of all users (type to filter),
    • typing their username,
    • scanning their QR code with the live camera, or
    • taking or uploading a photo of their QR code.
  • Admins can only see the admin page and Logout. Every other page sends them back.

Tech stack

Part What we use
Server Node.js + Express 5
Sessions express-session (in memory)
QR codes qrcode (generate) · jsQR (scan)
Front end Plain HTML, CSS and JavaScript (no framework)
Data CSV files (no database)

Getting started

Requirements: Node.js 18 or newer and npm.

git clone https://gitlab.com/pamfignole07/ecofablab.git
cd ecofablab
npm install
node server.js

Then open http://localhost:3000. It redirects to the home page.

Create an admin account

Admin accounts are stored separately from users, with hashed passwords (Node's built-in scrypt). To create an admin, or change an existing admin's password:

node addAdmin.js <username> <password>

This works while the server is running; there's no need to restart.

Optional settings

Variable Purpose
SESSION_SECRET Secret used to sign session cookies. If it isn't set, a random one is generated each time the server starts.

Sessions are kept in memory, so restarting the server logs everyone out.

Project structure

ecofablab/
├── server.js              # Express server: pages, access control and all API routes
├── addAdmin.js            # Admin password hashing + `node addAdmin.js <user> <pass>`
├── script.js              # Login / sign-up / admin-login forms (sign.html)
├── points.js              # Points balance (points.html)
├── bookingScript.js       # Printer list, time slots and booking (booking.html)
├── transfer.js            # Balance, user search and transfers (transfer.html)
├── admin.js               # User picker, QR scanning and add points (admin.html)
├── templates/
│   ├── home.html          # Public home page
│   ├── sign.html          # Log in, sign up, admin log in
│   ├── points.html        # Balance + personal QR code
│   ├── booking.html       # Book a printer
│   ├── transfer.html      # Send points
│   ├── admin.html         # Admin: add points
│   └── old/               # Earlier versions of the pages (not used)
├── static/
│   ├── stylesheet.css     # The site's single stylesheet
│   ├── nav.js             # Shared nav: Login ↔ Logout, Services / Admin links
│   └── images/            # Logo, step icons, social icons
├── users.csv              # User accounts and points
├── admins.csv             # Admin accounts (hashed passwords)
├── availablePrinters.csv  # Printers, their status and price
└── bookings.csv           # Booking history (created automatically)

Data files

All data is stored in CSV files in the project root. The server reads them by header name and rewrites them whole when something changes. Commas and line breaks are stripped from any value before it's saved.

File Columns
users.csv username,first_name,last_name,points,password,email
admins.csv username,password_hash
availablePrinters.csv printer_name,location,availability,credits_per_hour
bookings.csv username,printer_name,date,start,end,cost
  • availability is one of Available, Out of service or Reserved only. Only Available printers can be booked.
  • bookings.csv is created (header only) the first time the server starts. Old rows are kept as history.
  • To add or change a printer, edit availablePrinters.csv directly.

Pages and access

Page Who can open it
/templates/home.html Everyone
/templates/sign.html Visitors who aren't logged in (?admin=1 opens the admin login)
/templates/points.html, booking.html, transfer.html Logged-in users
/templates/admin.html Admins only

Visitors who aren't logged in are sent to the login page and come back to the page they wanted after logging in. Admins are always sent to the admin page.

API

All routes take and return JSON. The logged-in user or admin always comes from the session cookie, never from the request body.

Method Route Who Purpose
POST /signup anyone Create an account (0 points) and log in
POST /login anyone Log in as a user
POST /logout anyone End the session
GET /session anyone `{ type: 'user' \
GET /me user Username, first name and points
GET /me/qr user Your QR code (SVG)
GET /users/search?q= user Find other users (for transfers)
GET /bookings/today user Today's taken slots and your active booking
POST /book user { printer, start: "HH:MM", duration }
POST /transfer user { receiver, amount }
POST /admin/login anyone Log in as an admin
GET /admin/users?q= admin List and filter all users
GET /admin/user?username= admin Look up one user
POST /admin/points admin { username, amount }: add points (1 to 1,000,000)

Security notes

  • The server never sends users.csv, admins.csv, bookings.csv, server.js, addAdmin.js, package*.json or node_modules. Encoded and ../ paths are normalised first, so they can't get around this.
  • Session cookies are HttpOnly and SameSite=Lax, and the session id is renewed on every login.
  • Admin passwords are hashed with scrypt.
  • ⚠️ User passwords in users.csv are still stored as plain text. Don't reuse real passwords, and hash them before using this for real.
  • ⚠️ admins.csv is committed to the repo. Use your own admin accounts and passwords (node addAdmin.js), and consider adding admins.csv to .gitignore.
  • The live camera scanner only works on https or localhost (a browser rule). On a phone over plain http on the local network, use Photo of QR code instead.

Test accounts

users.csv comes with demo users, for example:

Username Password Points
alex_g pass1 25000
mia_t pass2 18500
noah_l pass5 4000

(Balances change as you test bookings, transfers and admin top-ups.)

Team

Made by Alexandre F., Peyton M., Francisco A. and Deniz K.

Contact

© 2026 EcoFabLab

Share this project:

Updates

Submission history