Skip to content

Commit 2d6a5d5

Browse files
committed
fix: database UI alignment and redis caching stability
1 parent a9a759e commit 2d6a5d5

8 files changed

Lines changed: 198 additions & 14 deletions

File tree

backend/config/redis.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
const Redis = require("ioredis");
2+
const dotenv = require("dotenv");
3+
dotenv.config()
4+
5+
if (!process.env.REDIS_URL) {
6+
throw new Error("REDIS_URL is not defined in .env");
7+
}
8+
9+
const redis = new Redis(process.env.REDIS_URL);
10+
11+
// Listen for events
12+
redis.on('ready', () => {
13+
console.log('ioredis client is connected and ready.');
14+
});
15+
16+
redis.on('error', (err) => {
17+
console.error('ioredis Client Error:', err);
18+
});
19+
20+
if (redis.status === 'ready') {
21+
console.log('Current status is ready.');
22+
} else {
23+
console.log(`Current status is: ${redis.status}`);
24+
}
25+
26+
module.exports = redis;

backend/controllers/project.controller.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const { URL } = require('url');
1111
const { getConnection } = require("../utils/connection.manager");
1212
const { getCompiledModel } = require("../utils/injectModel")
1313
const { storageRegistry } = require("../utils/registry");
14+
const { deleteProjectByApiKeyCache } = require("../services/redisCaching");
1415

1516

1617

@@ -54,7 +55,10 @@ module.exports.createProject = async (req, res) => {
5455

5556
module.exports.getAllProject = async (req, res) => {
5657
try {
57-
const projects = await Project.find({ owner: req.user._id }).select('-apiKey -jwtSecret');
58+
const projects = await Project.find({ owner: req.user._id })
59+
.select('name description')
60+
.lean();
61+
5862
res.status(200).json(projects);
5963
} catch (err) {
6064
res.status(500).json({ error: err.message });
@@ -81,6 +85,7 @@ module.exports.regenerateApiKey = async (req, res) => {
8185
const newApiKey = generateApiKey();
8286
const hashed = hashApiKey(newApiKey);
8387

88+
8489
const project = await Project.findOneAndUpdate(
8590
{ _id: req.params.projectId, owner: req.user._id },
8691
{ $set: { apiKey: hashed } },

backend/middleware/verifyApiKey.js

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,46 @@
11
const Project = require('../models/Project');
22
const { hashApiKey } = require('../utils/api');
3+
const {
4+
setProjectByApiKeyCache,
5+
getProjectByApiKeyCache
6+
} = require("../services/redisCaching");
37

48
module.exports = async (req, res, next) => {
59
try {
610
const apiKey = req.header('x-api-key');
7-
8-
if (!apiKey) return res.status(401).json({ error: 'API key not found' });
11+
if (!apiKey) {
12+
return res.status(401).json({ error: 'API key not found' });
13+
}
914

1015
const hashedApi = hashApiKey(apiKey);
1116

17+
let project = await getProjectByApiKeyCache(hashedApi);
18+
19+
if (!project) {
20+
project = await Project.findOne({ apiKey: hashedApi })
21+
.populate('owner', 'isVerified')
22+
.lean();
1223

13-
const project = await Project.findOne({ apiKey: hashedApi })
14-
.populate('owner', 'isVerified');
15-
if (!project) return res.status(401).json(
16-
{
17-
"error": "API key is expired or invalid.",
18-
"action": "Please use a valid API key or regenerate a new one from the dashboard."
24+
if (!project) {
25+
return res.status(401).json({
26+
error: "API key is expired or invalid.",
27+
action: "Please use a valid API key or regenerate a new one from the dashboard."
28+
});
1929
}
20-
);
2130

22-
if (!project.owner.isVerified) return res.status(401).json({ error: 'Owner not verified', fix: 'Verify your account on https://urbackend.bitbros.in/dashboard' });
31+
await setProjectByApiKeyCache(hashedApi, project);
32+
}
33+
34+
if (!project.owner.isVerified) {
35+
return res.status(401).json({
36+
error: 'Owner not verified',
37+
fix: 'Verify your account on https://urbackend.bitbros.in/dashboard'
38+
});
39+
}
40+
2341
req.project = project;
2442
next();
2543
} catch (err) {
2644
res.status(500).json({ error: err.message });
2745
}
28-
};
46+
};

backend/models/Project.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,7 @@ const projectSchema = new mongoose.Schema({
6161
}
6262
}, { timestamps: true });
6363

64+
projectSchema.index({ owner: 1 });
65+
66+
6467
module.exports = mongoose.model('Project', projectSchema);

backend/package-lock.json

Lines changed: 89 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

backend/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"dotenv": "^17.2.3",
1717
"express": "^5.1.0",
1818
"express-rate-limit": "^8.2.1",
19+
"ioredis": "^5.9.2",
1920
"jsonwebtoken": "^9.0.2",
2021
"mongoose": "^8.19.2",
2122
"multer": "^2.0.2",
@@ -28,4 +29,4 @@
2829
"jest": "^30.2.0",
2930
"supertest": "^7.1.4"
3031
}
31-
}
32+
}

backend/services/redisCaching.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
const redis = require("../config/redis");
2+
3+
async function setProjectByApiKeyCache(api, project) {
4+
try {
5+
await redis.set(
6+
`project:apikey:${api}`,
7+
JSON.stringify(project),
8+
'EX',
9+
60 * 60 * 2
10+
);
11+
} catch (err) {
12+
console.log(err);
13+
}
14+
}
15+
16+
async function getProjectByApiKeyCache(api) {
17+
try {
18+
const data = await redis.get(`project:apikey:${api}`);
19+
if (!data) return null;
20+
return JSON.parse(data);
21+
} catch (err) {
22+
console.log(err);
23+
return null;
24+
}
25+
}
26+
27+
async function deleteProjectByApiKeyCache(api) {
28+
try {
29+
await redis.del(`project:apikey:${api}`);
30+
} catch (err) {
31+
console.log(err);
32+
}
33+
}
34+
35+
module.exports = {
36+
setProjectByApiKeyCache,
37+
getProjectByApiKeyCache,
38+
deleteProjectByApiKeyCache
39+
};

frontend/src/index.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,10 @@ body {
343343
flex: 1;
344344
}
345345

346+
.main-content.full-width {
347+
margin-left: 0;
348+
}
349+
346350
/* Mobile Response for Layout */
347351
@media (max-width: 768px) {
348352
.sidebar {

0 commit comments

Comments
 (0)