-
Notifications
You must be signed in to change notification settings - Fork 34
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #400 from bluewave-labs/397-create-ip-check
397 create ip check
- Loading branch information
Showing
5 changed files
with
122 additions
and
36 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
const getIpFromRequest = (req) => { | ||
const forwardedFor = req.headers["x-forwarded-for"]; | ||
const remoteAddress = req.connection.remoteAddress; | ||
return (forwardedFor || remoteAddress).replace("::ffff:", ""); | ||
}; | ||
|
||
const parseIpRange = (allowedIpsEnv) => { | ||
if (!allowedIpsEnv) return []; | ||
|
||
const ranges = allowedIpsEnv.split(", ").map((range) => range.trim()); | ||
return ranges.map((range) => { | ||
const [baseIp, endRange] = range.split("/"); | ||
if (!baseIp || !endRange) throw new Error("Invalid IP range format"); | ||
const rangeParts = endRange.split("-"); | ||
return { | ||
baseIp, | ||
rangeStart: parseInt(rangeParts[0]), | ||
rangeEnd: parseInt(rangeParts[1]), | ||
}; | ||
}); | ||
}; | ||
|
||
const isIpAllowed = (currentIp, allowedRanges) => { | ||
const ipParts = currentIp.split("."); | ||
const startIp = ipParts.slice(0, 3).join("."); | ||
const lastOctet = parseInt(ipParts[3], 10); | ||
|
||
for (const range of allowedRanges) { | ||
if ( | ||
startIp === range.baseIp && | ||
lastOctet >= range.rangeStart && | ||
lastOctet <= range.rangeEnd | ||
) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
}; | ||
|
||
const ipFilter = async (req, res, next) => { | ||
try { | ||
const currentIp = getIpFromRequest(req); | ||
const allowedIpsEnv = process.env.ALLOWED_IPS; | ||
const allowedRanges = parseIpRange(process.env.ALLOWED_IP_RANGE); | ||
if (!allowedIpsEnv && !allowedRanges.length) { | ||
next(); | ||
return; | ||
} else if (!allowedIpsEnv) { | ||
if (!isIpAllowed(currentIp, allowedRanges)) { | ||
return res.status(401).json({ error: "Unauthorized" }); | ||
} | ||
next(); | ||
return; | ||
} | ||
|
||
const allowedIps = allowedIpsEnv.split(", ").map((ip) => ip.trim()); | ||
|
||
if (!allowedIps.includes(currentIp)) { | ||
return res.status(401).json({ error: "Unauthorized" }); | ||
} | ||
|
||
next(); | ||
} catch (err) { | ||
console.error("IP Filter Error:", err.message); | ||
return res.status(500).json({ error: "Internal Server Error" }); | ||
} | ||
}; | ||
|
||
module.exports = ipFilter; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,64 +1,66 @@ | ||
const express = require('express'); | ||
const cors = require('cors'); | ||
const helmet = require('helmet'); | ||
const dotenv = require('dotenv'); | ||
const bodyParser = require('body-parser'); | ||
const jsonErrorMiddleware = require('./middleware/jsonError.middleware'); | ||
const fileSizeValidator = require('./middleware/fileSizeValidator.middleware'); | ||
const { MAX_FILE_SIZE } = require('./utils/constants.helper'); | ||
const express = require("express"); | ||
const cors = require("cors"); | ||
const helmet = require("helmet"); | ||
const dotenv = require("dotenv"); | ||
const bodyParser = require("body-parser"); | ||
const jsonErrorMiddleware = require("./middleware/jsonError.middleware"); | ||
const fileSizeValidator = require("./middleware/fileSizeValidator.middleware"); | ||
const { MAX_FILE_SIZE } = require("./utils/constants.helper"); | ||
const ipFilter = require("./middleware/ipFilter.middleware"); | ||
|
||
// Load environment variables from .env file | ||
dotenv.config(); | ||
|
||
const authRoutes = require('./routes/auth.routes'); | ||
const userRoutes = require('./routes/user.routes'); | ||
const mocks = require('./routes/mocks.routes'); | ||
const popup = require('./routes/popup.routes'); | ||
const guide_log = require('./routes/guidelog.routes'); | ||
const banner = require('./routes/banner.routes'); | ||
const teamRoutes = require('./routes/team.routes'); | ||
const hint = require('./routes/hint.routes'); | ||
const tourRoutes = require('./routes/tour.routes'); | ||
const linkRoutes = require('./routes/link.routes'); | ||
const helperLinkRoutes = require('./routes/helperLink.routes'); | ||
const guideRoutes = require('./routes/guide.routes'); | ||
const authRoutes = require("./routes/auth.routes"); | ||
const userRoutes = require("./routes/user.routes"); | ||
const mocks = require("./routes/mocks.routes"); | ||
const popup = require("./routes/popup.routes"); | ||
const guide_log = require("./routes/guidelog.routes"); | ||
const banner = require("./routes/banner.routes"); | ||
const teamRoutes = require("./routes/team.routes"); | ||
const hint = require("./routes/hint.routes"); | ||
const tourRoutes = require("./routes/tour.routes"); | ||
const linkRoutes = require("./routes/link.routes"); | ||
const helperLinkRoutes = require("./routes/helperLink.routes"); | ||
const guideRoutes = require("./routes/guide.routes"); | ||
|
||
const app = express(); | ||
|
||
app.use(cors()); | ||
app.use(helmet()); | ||
app.use(bodyParser.json({ limit: MAX_FILE_SIZE })); | ||
app.use(jsonErrorMiddleware); | ||
app.use(ipFilter); | ||
// app.use(fileSizeValidator); | ||
|
||
const { sequelize } = require("./models"); | ||
|
||
sequelize | ||
.authenticate() | ||
.then(() => console.log('Database connected...')) | ||
.catch((err) => console.log('Error: ' + err)); | ||
.then(() => console.log("Database connected...")) | ||
.catch((err) => console.log("Error: " + err)); | ||
|
||
sequelize | ||
.sync({ force: false }) | ||
.then(() => console.log("Models synced with the database...")) | ||
.catch((err) => console.log("Error syncing models: " + err)); | ||
|
||
app.use('/api/auth', authRoutes); | ||
app.use('/api/users', userRoutes); | ||
app.use('/api/mock/', mocks); | ||
app.use('/api/popup', popup); | ||
app.use('/api/guide_log', guide_log); | ||
app.use('/api/banner', banner); | ||
app.use('/api/team', teamRoutes); | ||
app.use('/api/guide', guideRoutes); | ||
app.use('/api/hint', hint); | ||
app.use('/api/tour', tourRoutes); | ||
app.use('/api/link', linkRoutes); | ||
app.use('/api/helper-link', helperLinkRoutes); | ||
app.use("/api/auth", authRoutes); | ||
app.use("/api/users", userRoutes); | ||
app.use("/api/mock/", mocks); | ||
app.use("/api/popup", popup); | ||
app.use("/api/guide_log", guide_log); | ||
app.use("/api/banner", banner); | ||
app.use("/api/team", teamRoutes); | ||
app.use("/api/guide", guideRoutes); | ||
app.use("/api/hint", hint); | ||
app.use("/api/tour", tourRoutes); | ||
app.use("/api/link", linkRoutes); | ||
app.use("/api/helper-link", helperLinkRoutes); | ||
|
||
app.use((err, req, res, next) => { | ||
console.error(err.stack); | ||
res.status(500).json({ message: 'Internal Server Error' }); | ||
res.status(500).json({ message: "Internal Server Error" }); | ||
}); | ||
|
||
module.exports = app; | ||
module.exports = app; |