Skip to content
Open
Show file tree
Hide file tree
Changes from 11 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'))"

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

const express= require('express');
const cors = require('cors');


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

app.use(corse());
app.use(express.json());

connectDB();

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


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}`);
});
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 critical server setup issues.

Several critical issues need to be addressed:

  1. app is not initialized before use
  2. Typo in corse()
  3. dotenv should be configured before any environment variable usage
  4. Missing error handling middleware
+require('dotenv').config();
 const connectDB = require('./config/db');
 
 const express= require('express');
 const cors = require('cors');
 
+const app = express();
 
 const authRoutes = require('./routes/auth');
 const scanRoutes= require('./routes/scan');
 
-app.use(corse());
+app.use(cors());
 app.use(express.json());
 
 connectDB();
 
 app.use('/api/auth', authRoutes);
 app.use('/api/scan', scanRoutes);
-require('dotenv').config();
 
+// Error handling middleware
+app.use((err, req, res, next) => {
+    console.error(err.stack);
+    res.status(500).json({ error: 'Something broke!' });
+});
 
 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}`);
 });
📝 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 connectDB = require('./config/db');
const express= require('express');
const cors = require('cors');
const authRoutes = require('./routes/auth');
const scanRoutes= require('./routes/scan');
app.use(corse());
app.use(express.json());
connectDB();
app.use('/api/auth', authRoutes);
app.use('/api/scan', scanRoutes);
require('dotenv').config();
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}`);
});
require('dotenv').config();
const connectDB = require('./config/db');
const express = require('express');
const cors = require('cors');
const app = express();
const authRoutes = require('./routes/auth');
const scanRoutes = require('./routes/scan');
app.use(cors());
app.use(express.json());
connectDB();
app.use('/api/auth', authRoutes);
app.use('/api/scan', scanRoutes);
// Error handling middleware
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).json({ error: 'Something broke!' });
});
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}`);
});

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

const connectDB = async () => {
try {
await mongoose.connect(process.env.MONGO_URI, {
useNewUrlParser: true,
useUnifiedTopology: true
});
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 } = require('../config/auth');

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 }= require('../config/auth');

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);
9 changes: 9 additions & 0 deletions Backend/routes/auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const express= require('express');
const { register, login } = require('../controllers/authController');

const router= express.Router();

router.post('/register', register);
router.post('/login', login);

module.exports = router;
9 changes: 9 additions & 0 deletions Backend/routes/scan.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const express= require('express');
const { scan }= require('../controllers/scanController');
const { authenticate }= require('../middleware/auth');

const router = express.Router();

router.post('/scan', authenticate, scan);

module.exports= router;
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@


## Basic Details
### Team Name: [Name]
### Team Name: NOX


### Team Members
- Member 1: [Name] - [College]
- Member 2: [Name] - [College]
- Member 3: [Name] - [College]
- Member 1: Anagha TR - SCMS School of engineering and technology
- Member 2: Anaya Wilson - SCMS School of engineering and technology
- Member 3: Aneeja J - SCMS School of engineering and technology

### Hosted Project Link
[mention your project hosted project link here]
Expand Down Expand Up @@ -96,4 +96,4 @@ For Hardware:
- [Name 3]: [Specific contributions]

---
Made with ❤️ at TinkerHub
Made with ❤️ at TinkerHub
24 changes: 24 additions & 0 deletions frontend/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
38 changes: 38 additions & 0 deletions frontend/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import js from '@eslint/js'
import globals from 'globals'
import react from 'eslint-plugin-react'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'

export default [
{ ignores: ['dist'] },
{
files: ['**/*.{js,jsx}'],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
Comment on lines +12 to +13
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Align ECMAScript version configurations.

The configuration has inconsistent ECMAScript version settings:

  • Line 12: ecmaVersion: 2020
  • Line 15: ecmaVersion: 'latest'

This might lead to confusion about which ECMAScript features are supported.

     languageOptions: {
-      ecmaVersion: 2020,
+      ecmaVersion: 'latest',
       globals: globals.browser,
       parserOptions: {
-        ecmaVersion: 'latest',
+        ecmaVersion: 2023,
         ecmaFeatures: { jsx: true },
         sourceType: 'module',
       },

Also applies to: 15-18

parserOptions: {
ecmaVersion: 'latest',
ecmaFeatures: { jsx: true },
sourceType: 'module',
},
},
settings: { react: { version: '18.3' } },
plugins: {
react,
'react-hooks': reactHooks,
'react-refresh': reactRefresh,
},
rules: {
...js.configs.recommended.rules,
...react.configs.recommended.rules,
...react.configs['jsx-runtime'].rules,
...reactHooks.configs.recommended.rules,
'react/jsx-no-target-blank': 'off',
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
Comment on lines +31 to +35
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Consider security implications of disabling target="_blank" rule.

The react/jsx-no-target-blank rule is disabled, which could expose the application to security vulnerabilities when using external links.

Instead of disabling the rule completely, consider enabling it with options:

-      'react/jsx-no-target-blank': 'off',
+      'react/jsx-no-target-blank': ['error', {
+        allowReferrer: true,
+        warnOnSpreadAttributes: true,
+      }],
📝 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
'react/jsx-no-target-blank': 'off',
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
'react/jsx-no-target-blank': ['error', {
allowReferrer: true,
warnOnSpreadAttributes: true,
}],
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],

},
},
]
13 changes: 13 additions & 0 deletions frontend/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>
Loading