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
Availablecan be booked (Out of serviceandReserved onlycan'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 |
availabilityis one ofAvailable,Out of serviceorReserved only. OnlyAvailableprinters can be booked.bookings.csvis created (header only) the first time the server starts. Old rows are kept as history.- To add or change a printer, edit
availablePrinters.csvdirectly.
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*.jsonornode_modules. Encoded and../paths are normalised first, so they can't get around this. - Session cookies are
HttpOnlyandSameSite=Lax, and the session id is renewed on every login. - Admin passwords are hashed with
scrypt. - ⚠️ User passwords in
users.csvare still stored as plain text. Don't reuse real passwords, and hash them before using this for real. - ⚠️
admins.csvis committed to the repo. Use your own admin accounts and passwords (node addAdmin.js), and consider addingadmins.csvto.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
- Discord: https://discord.gg/MfaNWUqxAs
- Instagram: @ecofablabdawson
© 2026 EcoFabLab