Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Backend/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
MONGO_URI=mongodb://localhost:27017/digital-mess-card
JWT_SECRET=your-secret-key
PORT=5000
Comment on lines +1 to +3
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Security: Update configuration and follow environment file best practices.

  1. The JWT secret is using a weak placeholder value

  2. MongoDB connection lacks authentication

  3. Environment files should not be committed to version control

  4. Create a .env.example file instead:

-MONGO_URI=mongodb://localhost:27017/digital-mess-card
-JWT_SECRET=your-secret-key
-PORT=5000
+MONGO_URI=mongodb://<username>:<password>@localhost:27017/digital-mess-card
+JWT_SECRET=<your-strong-secret-key>
+PORT=5000
  1. Add .env to .gitignore:
+.env
  1. Update MongoDB connection to use authentication:
# Create admin user
mongosh
use admin
db.createUser({
  user: "admin",
  pwd: "secure_password",
  roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
})

# Create application user
use digital-mess-card
db.createUser({
  user: "app_user",
  pwd: "secure_password",
  roles: [ { role: "readWrite", db: "digital-mess-card" } ]
})
  1. Generate a strong JWT secret:
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"

136 changes: 136 additions & 0 deletions Backend/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage
*.lcov

# nyc test coverage
.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# Snowpack dependency directory (https://snowpack.dev/)
web_modules/

# TypeScript cache
*.tsbuildinfo

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional stylelint cache
.stylelintcache

# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local

# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache

# Next.js build output
.next
out

# Nuxt.js build / generate output
.nuxt
dist

# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public

# vuepress build output
.vuepress/dist

# vuepress v2.x temp and cache directory
.temp
.cache

# vitepress build output
**/.vitepress/dist

# vitepress cache directory
**/.vitepress/cache

# Docusaurus cache and generated files
.docusaurus

# Serverless directories
.serverless/

# FuseBox cache
.fusebox/

# DynamoDB Local files
.dynamodb/

# TernJS port file
.tern-port

# Stores VSCode versions used for testing VSCode extensions
.vscode-test

# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*
27 changes: 27 additions & 0 deletions Backend/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
require('dotenv').config();
const express= require('express');
const app = express();
const cors = require('cors');
const connectDB = require('./config/db');
Comment on lines +1 to +5
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Configure CORS with specific options for security.

The current CORS setup allows requests from any origin. For security, configure CORS with specific options.

Apply this diff:

-const express= require('express');
+const express = require('express');
 const app = express();
 const cors = require('cors');
+const corsOptions = {
+  origin: process.env.ALLOWED_ORIGINS?.split(',') || 'http://localhost:3000',
+  methods: ['GET', 'POST'],
+  credentials: true,
+  optionsSuccessStatus: 204
+};
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
require('dotenv').config();
const express= require('express');
const app = express();
const cors = require('cors');
const connectDB = require('./config/db');
require('dotenv').config();
const express = require('express');
const app = express();
const cors = require('cors');
const corsOptions = {
origin: process.env.ALLOWED_ORIGINS?.split(',') || 'http://localhost:3000',
methods: ['GET', 'POST'],
credentials: true,
optionsSuccessStatus: 204
};
const connectDB = require('./config/db');


const authRoutes = require('./routes/auth');
const scanRoutes= require('./routes/scan');

app.use(cors());
app.use(express.json());
Comment on lines +10 to +11
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add essential security middleware.

Add security middleware and update CORS configuration.

Apply this diff:

-app.use(cors());
+app.use(cors(corsOptions));
 app.use(express.json());
+app.use(express.urlencoded({ extended: true }));
+app.use(require('helmet')());
+app.use(require('express-rate-limit')({
+  windowMs: 15 * 60 * 1000, // 15 minutes
+  max: 100 // limit each IP to 100 requests per windowMs
+}));

Don't forget to install the required packages:

npm install helmet express-rate-limit


connectDB();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add error handling for database connection.

The database connection should be handled with proper error management.

Apply this diff:

-connectDB();
+connectDB().catch(err => {
+  console.error('Failed to connect to database:', err);
+  process.exit(1);
+});
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
connectDB();
connectDB().catch(err => {
console.error('Failed to connect to database:', err);
process.exit(1);
});


app.use('/api/auth', authRoutes);
app.use('/api/scan', scanRoutes);



app.get('/',(req,res)=>{
res.send('Digital MESS Card'); //Route
});

const PORT= process.env.PORT || 5000;
app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
});
Comment on lines +24 to +27
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add graceful shutdown handling and improve logging.

Implement proper server shutdown handling and enhance logging.

Apply this diff:

 const PORT = process.env.PORT || 5000;
-app.listen(PORT, () => {
-    console.log(`Server running on http://localhost:${PORT}`);
+const server = app.listen(PORT, () => {
+  console.log(`Server running on http://localhost:${PORT}`);
+});
+
+// Graceful shutdown handling
+process.on('SIGTERM', () => {
+  console.log('SIGTERM signal received: closing HTTP server');
+  server.close(() => {
+    console.log('HTTP server closed');
+    process.exit(0);
+  });
 });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const PORT= process.env.PORT || 5000;
app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
});
const PORT = process.env.PORT || 5000;
const server = app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
});
// Graceful shutdown handling
process.on('SIGTERM', () => {
console.log('SIGTERM signal received: closing HTTP server');
server.close(() => {
console.log('HTTP server closed');
process.exit(0);
});
});

13 changes: 13 additions & 0 deletions Backend/config/db.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const mongoose= require('mongoose');

const connectDB = async () => {
try {
await mongoose.connect(process.env.MONGO_URI);
console.log('MongoDB connected');
} catch (err) {
console.error('MongoDB connection error:', err);
process.exit(1);
}
};

module.exports = connectDB;
30 changes: 30 additions & 0 deletions Backend/controllers/authController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const User = require('../models/User');
const jwtSecret = process.env.JWT_SECRET;

exports.register = async (req, res) => { //to register new user
const { username, password } = req.body;
try {
const hashedPassword = await bcrypt.hash(password, 10);
const user = new User({ username, password: hashedPassword });
await user.save();
res.status(201).json({ message: 'User registered successfully' });
} catch (err) {
res.status(500).json({ error: 'Error registering user' });
}
};
Comment on lines +6 to +16
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add input validation and security measures to registration.

The registration endpoint needs several security improvements:

  1. Input validation
  2. Password complexity requirements
  3. Rate limiting
  4. Secure error handling
+const { body, validationResult } = require('express-validator');
+const rateLimit = require('express-rate-limit');
+
+const registerLimiter = rateLimit({
+    windowMs: 60 * 60 * 1000, // 1 hour
+    max: 5 // limit each IP to 5 registration requests per hour
+});
+
-exports.register = async (req, res) => {
+exports.register = [
+    registerLimiter,
+    body('username').trim().isLength({ min: 3 }).escape(),
+    body('password')
+        .isLength({ min: 8 })
+        .matches(/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z0-9]).{8,}$/),
+    async (req, res) => {
     const { username, password } = req.body;
+    
+    const errors = validationResult(req);
+    if (!errors.isEmpty()) {
+        return res.status(400).json({ errors: errors.array() });
+    }
+    
     try {
         const hashedPassword = await bcrypt.hash(password, 10);
         const user = new User({ username, password: hashedPassword });
         await user.save();
         res.status(201).json({ message: 'User registered successfully' });
     } catch (err) {
-        res.status(500).json({ error: 'Error registering user' });
+        if (err.code === 11000) {
+            return res.status(400).json({ error: 'Username already exists' });
+        }
+        console.error('Registration error:', err);
+        res.status(500).json({ error: 'Internal server error' });
     }
-};
+}];
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
exports.register = async (req, res) => { //to register new user
const { username, password } = req.body;
try {
const hashedPassword = await bcrypt.hash(password, 10);
const user = new User({ username, password: hashedPassword });
await user.save();
res.status(201).json({ message: 'User registered successfully' });
} catch (err) {
res.status(500).json({ error: 'Error registering user' });
}
};
const { body, validationResult } = require('express-validator');
const rateLimit = require('express-rate-limit');
const registerLimiter = rateLimit({
windowMs: 60 * 60 * 1000, // 1 hour
max: 5 // limit each IP to 5 registration requests per hour
});
exports.register = [
registerLimiter,
body('username').trim().isLength({ min: 3 }).escape(),
body('password')
.isLength({ min: 8 })
.matches(/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z0-9]).{8,}$/),
async (req, res) => {
const { username, password } = req.body;
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
try {
const hashedPassword = await bcrypt.hash(password, 10);
const user = new User({ username, password: hashedPassword });
await user.save();
res.status(201).json({ message: 'User registered successfully' });
} catch (err) {
if (err.code === 11000) {
return res.status(400).json({ error: 'Username already exists' });
}
console.error('Registration error:', err);
res.status(500).json({ error: 'Internal server error' });
}
}
];


exports.login = async (req, res) => { //Authenticate access
const { username, password } = req.body;
try {
const user= await User.findOne({ username });
if (!user || !(await bcrypt.compare(password, user.password))) { // //to check whether the login details are valid
return res.status(400).json({ error: 'Invalid credentials' });
}
const token= jwt.sign({ userId: user._id }, jwtSecret, { expiresIn: '1h' });
res.json({ token });
} catch (err) {
res.status(500).json({ error: 'Error logging in' });
}
};
Comment on lines +18 to +30
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Enhance login security with rate limiting and secure error handling.

The login endpoint needs similar security improvements:

  1. Rate limiting to prevent brute force attacks
  2. Secure error handling
  3. Constant-time comparison
+const loginLimiter = rateLimit({
+    windowMs: 15 * 60 * 1000, // 15 minutes
+    max: 5 // limit each IP to 5 login attempts per 15 minutes
+});
+
-exports.login = async (req, res) => {
+exports.login = [
+    loginLimiter,
+    body('username').trim().escape(),
+    body('password').trim(),
+    async (req, res) => {
     const { username, password } = req.body;
+    
+    const errors = validationResult(req);
+    if (!errors.isEmpty()) {
+        return res.status(400).json({ errors: errors.array() });
+    }
+    
     try {
         const user= await User.findOne({ username });
-        if (!user || !(await bcrypt.compare(password, user.password))) {
+        // Use constant-time comparison to prevent timing attacks
+        const isValid = user ? await bcrypt.compare(password, user.password) : false;
+        if (!isValid) {
             return res.status(400).json({ error: 'Invalid credentials' });
         }
         const token= jwt.sign({ userId: user._id }, jwtSecret, { expiresIn: '1h' });
         res.json({ token });
     } catch (err) {
-        res.status(500).json({ error: 'Error logging in' });
+        console.error('Login error:', err);
+        res.status(500).json({ error: 'Internal server error' });
     }
-};
+}];
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
exports.login = async (req, res) => { //Authenticate access
const { username, password } = req.body;
try {
const user= await User.findOne({ username });
if (!user || !(await bcrypt.compare(password, user.password))) { // //to check whether the login details are valid
return res.status(400).json({ error: 'Invalid credentials' });
}
const token= jwt.sign({ userId: user._id }, jwtSecret, { expiresIn: '1h' });
res.json({ token });
} catch (err) {
res.status(500).json({ error: 'Error logging in' });
}
};
const loginLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 5 // limit each IP to 5 login attempts per 15 minutes
});
exports.login = [
loginLimiter,
body('username').trim().escape(),
body('password').trim(),
async (req, res) => {
const { username, password } = req.body;
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
try {
const user = await User.findOne({ username });
// Use constant-time comparison to prevent timing attacks
const isValid = user ? await bcrypt.compare(password, user.password) : false;
if (!isValid) {
return res.status(400).json({ error: 'Invalid credentials' });
}
const token = jwt.sign({ userId: user._id }, jwtSecret, { expiresIn: '1h' });
res.json({ token });
} catch (err) {
console.error('Login error:', err);
res.status(500).json({ error: 'Internal server error' });
}
}
];

31 changes: 31 additions & 0 deletions Backend/controllers/scanController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const Scan= require('../models/Scan');

exports.scan= async (req, res) => { //to get info about user and the current time
const { type } = req.body;
const userId = req.userId;
Comment on lines +4 to +5
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add input validation and improve error handling.

The current implementation lacks input validation and uses generic error handling:

  • Missing validation for required type field
  • Missing validation for valid scan types
  • Generic error message doesn't help with debugging

Apply this diff to add input validation and improve error handling:

     const { type } = req.body;
     const userId = req.userId;
 
+    if (!type) {
+        return res.status(400).json({ error: 'Scan type is required' });
+    }
+
+    if (!['lunch', 'snack'].includes(type)) {
+        return res.status(400).json({ error: 'Invalid scan type' });
+    }

     try {
         const existingScan = await Scan.findOne({ userId, type, date: { $gte: new Date().setHours(0, 0, 0, 0) } });
         if (existingScan) {
             return res.status(400).json({ error: 'Already scanned today' });
         }

         const scan = new Scan({ userId, type });
         await scan.save();
         res.json({ message: 'Scan successful' });
     } catch (err) {
-        res.status(500).json({ error: 'Error processing scan' });
+        console.error('Scan error:', err);
+        res.status(500).json({ 
+            error: 'Error processing scan',
+            details: process.env.NODE_ENV === 'development' ? err.message : undefined
+        });
     }

Also applies to: 19-30


const now = new Date();
const hours = now.getHours();
const minutes = now.getMinutes();

if (type === 'lunch' && !(hours >= 11 && minutes >= 30 && hours < 14)) { //to check whether scanning of lunch time is valid
return res.status(400).json({ error: 'Lunch scanning is only allowed between 11:30 AM and 2:00 PM' });
}
Comment on lines +11 to +13
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix time window validation logic.

The current time window checks have logical errors that could allow scans outside the intended windows:

  • For lunch (11:30 AM - 2:00 PM), hours >= 11 && minutes >= 30 fails at 11:00-11:29
  • For snacks (3:30 PM - 5:00 PM), similar issue with hours >= 15 && minutes >= 30

Apply this diff to fix the time window validation:

-    if (type === 'lunch' && !(hours >= 11 && minutes >= 30 && hours < 14)) {
+    if (type === 'lunch' && (hours < 11 || (hours === 11 && minutes < 30) || hours >= 14)) {
         return res.status(400).json({ error: 'Lunch scanning is only allowed between 11:30 AM and 2:00 PM' });
     }

-    if (type === 'snack' && !(hours >= 15 && minutes >= 30 && hours < 17)) {
+    if (type === 'snack' && (hours < 15 || (hours === 15 && minutes < 30) || hours >= 17)) {
         return res.status(400).json({ error: 'Snack scanning is only allowed between 3:30 PM and 5:00 PM' });
     }

Also applies to: 15-17


if (type === 'snack' && !(hours >= 15 && minutes >= 30 && hours < 17)) { //to check whether scanning of snack time is valid
return res.status(400).json({ error: 'Snack scanning is only allowed between 3:30 PM and 5:00 PM' });
}

try {
const existingScan = await Scan.findOne({ userId, type, date: { $gte: new Date().setHours(0, 0, 0, 0) } });
if (existingScan) {
return res.status(400).json({ error: 'Already scanned today' }); //to check whether a scanning already occured in the given time
}

const scan = new Scan({ userId, type });
await scan.save(); //to save current scan
res.json({ message: 'Scan successful' });
} catch (err) {
res.status(500).json({ error: 'Error processing scan' });
}
};
15 changes: 15 additions & 0 deletions Backend/middleware/auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const jwt= require('jsonwebtoken');
const jwtSecret = process.env.JWT_SECRET;

exports.authenticate= (req,res,next) => {
const token=req.header('Authorization');
if (!token) return res.status(401).json({ error: 'Access denied' });

try{
const decoded= jwt.verify(token, jwtSecret);
req.userId= decoded.userId;
next();
} catch (err) {
res.status(400).json({ error: 'Invalid token' });
}
};
Comment on lines +4 to +15
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Enhance JWT authentication security.

Several security improvements are recommended:

  1. Validate Bearer scheme
  2. Add explicit token expiration check
  3. Use specific error messages
-exports.authenticate= (req,res,next) => {            
-    const token=req.header('Authorization');
-    if (!token) return res.status(401).json({ error: 'Access denied' });
+exports.authenticate = (req, res, next) => {            
+    const authHeader = req.header('Authorization');
+    if (!authHeader) {
+        return res.status(401).json({ error: 'No authorization header' });
+    }
+    
+    if (!authHeader.startsWith('Bearer ')) {
+        return res.status(401).json({ error: 'Invalid authorization scheme' });
+    }
+    
+    const token = authHeader.split(' ')[1];
 
     try{
-        const decoded= jwt.verify(token, jwtSecret);
-        req.userId= decoded.userId;
+        const decoded = jwt.verify(token, jwtSecret);
+        
+        // Check token expiration
+        if (decoded.exp < Date.now() / 1000) {
+            return res.status(401).json({ error: 'Token has expired' });
+        }
+        
+        req.userId = decoded.userId;
         next();
     } catch (err) {
-        res.status(400).json({ error: 'Invalid token' });
+        if (err.name === 'JsonWebTokenError') {
+            return res.status(401).json({ error: 'Invalid token signature' });
+        }
+        res.status(500).json({ error: 'Internal server error' });
     }
 };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
exports.authenticate= (req,res,next) => {
const token=req.header('Authorization');
if (!token) return res.status(401).json({ error: 'Access denied' });
try{
const decoded= jwt.verify(token, jwtSecret);
req.userId= decoded.userId;
next();
} catch (err) {
res.status(400).json({ error: 'Invalid token' });
}
};
exports.authenticate = (req, res, next) => {
const authHeader = req.header('Authorization');
if (!authHeader) {
return res.status(401).json({ error: 'No authorization header' });
}
if (!authHeader.startsWith('Bearer ')) {
return res.status(401).json({ error: 'Invalid authorization scheme' });
}
const token = authHeader.split(' ')[1];
try{
const decoded = jwt.verify(token, jwtSecret);
// Check token expiration
if (decoded.exp < Date.now() / 1000) {
return res.status(401).json({ error: 'Token has expired' });
}
req.userId = decoded.userId;
next();
} catch (err) {
if (err.name === 'JsonWebTokenError') {
return res.status(401).json({ error: 'Invalid token signature' });
}
res.status(500).json({ error: 'Internal server error' });
}
};

8 changes: 8 additions & 0 deletions Backend/models/Scan.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const mongoose= require('mongoose');
const scanSchema =new mongoose.Schema({ //Scan date update in db
userId: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true },
type: { type: String, enum: ['lunch', 'snack'], required: true },
date :{ type: Date, default: Date.now},
});

module.exports= mongoose.model('Scan', scanSchema);
8 changes: 8 additions & 0 deletions Backend/models/User.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const mongoose= require('mongoose');

const userSchema= new mongoose.Schema({ //login details connected to db
username:{ type: String, required: true, unique: true },
password:{ type: String, required: true, match:/^[a-zA-Z0-9]+$/,
}
});
module.exports= mongoose.model('User', userSchema);
Loading