Fix issue 51 (#99)

Please test if this passes security check, modified
server/src/api/routes/index.js
This commit is contained in:
Lin, Hung-Shin authored and GitHub committed 2024-02-09 14:26:28 +08:00
commit 4f9b275211
8 files changed
+111 -46

No files matched your search

+3
View File
@@ -135,3 +135,6 @@ dist
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*
#screenshots
tests/cypress/screenshots
+2 -1
View File
@@ -1,4 +1,5 @@
{
"editor.tabSize": 2,
"editor.defaultFormatter": "esbenp.prettier-vscode"
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true
}
-1
View File
@@ -7,5 +7,4 @@ const api = axios.create({
},
withCredentials: true,
})
export default api
+2
View File
@@ -20,6 +20,7 @@
"bcrypt": "^5.1.1",
"commander": "^11.0.0",
"connect-mongo": "^5.0.0",
"cookie-parser": "^1.4.6",
"dockerode": "^3.3.5",
"dotenv": "^16.4.1",
"express": "^4.18.2",
@@ -27,6 +28,7 @@
"express-session": "^1.17.3",
"express-validator": "^7.0.1",
"jsonwebtoken": "^9.0.1",
"lusca": "^1.7.0",
"minimist": "^1.2.8",
"mongodb": "^6.3.0",
"mongoose": "^8.0.3",
+18 -6
View File
@@ -1,5 +1,7 @@
import { Router } from 'express'
import passport from 'passport'
import lusca from 'lusca'
import cookieParser from 'cookie-parser'
import sessions from './sessionRouter.js'
import quests from './questRouter.js'
import commands from './commandRouter.js'
@@ -10,7 +12,7 @@ import config from '../../config.js'
import leaderboardController from '../controllers/leaderboardController.js'
const router = Router()
router.use(cookieParser())
if (!config.isProduction) {
router.get('/', (req, res) => {
res.send('Hello API!')
@@ -21,17 +23,27 @@ if (!config.isProduction) {
})
}
router.use('/auth', authRouter)
router.use('/quests', quests)
router.use('/users', userRouter)
router.use('/sessions', authRequired, sessions)
router.use(
'/commands',
passport.authenticate('jwt', { session: false }),
authRequired,
commands
)
router.use('/auth', authRouter)
router.use('/sessions', authRequired, sessions)
router.use(
lusca({
csrf: {
cookie: { name: '_csrf' },
header: 'x-csrf-token',
secret: config.secret,
},
hsts: { maxAge: 31536000, includeSubDomains: true, preload: true },
})
)
router.use('/quests', quests)
router.use('/users', userRouter)
router.get('/survey', (req, res) => {
if (!config.surveyUrl) {
+48 -36
View File
@@ -23,46 +23,58 @@ function getUrl(key) {
return ''
}
const config = {
host: get('HOST', 'localhost'),
port: get('PORT', 3000),
db: get('MONGO_URL', 'mongodb://localhost:27017/odyssey-test'),
secret: get('SECRET_KEY', ''),
isProduction: process.env.NODE_ENV === 'production',
containerExpiry: get('EXPIRY', 1000 * 60 * 60),
sessionMaxAge: get('SESSION_MAX_AGE', 1000 * 60 * 60 * 24 * 7),
google: {
clientID: get('GOOGLE_CLIENT_ID', ''),
clientSecret: get('GOOGLE_CLIENT_SECRET', ''),
},
github: {
clientID: get('GITHUB_CLIENT_ID', ''),
clientSecret: get('GITHUB_CLIENT_SECRET', ''),
},
trustedProxies: getTrustProxies('TRUSTED_PROXIES'),
surveyUrl: getUrl('SURVEY_URL', ''),
bugReportUrl: getUrl('BUG_REPORT_URL', ''),
function createConfig() {
const isProduction = process.env.NODE_ENV === 'production'
const host = get('HOST', 'localhost')
const port = Number(get('PORT', 3000))
const baseUrl = get('BASE_URL', `http://${host}:${port}`)
const url = new URL(baseUrl)
return {
host,
port,
baseUrl,
domain: url.hostname,
protocol: url.protocol,
backendUrl: get('BACKEND_URL', baseUrl),
db: get('MONGO_URL', 'mongodb://localhost:27017/odyssey-test'),
secret: get('SECRET_KEY', ''),
isProduction: process.env.NODE_ENV === 'production',
containerExpiry: get('EXPIRY', 1000 * 60 * 60),
sessionMaxAge: get('SESSION_MAX_AGE', 1000 * 60 * 60 * 24 * 7),
google: {
clientID: get('GOOGLE_CLIENT_ID', ''),
clientSecret: get('GOOGLE_CLIENT_SECRET', ''),
},
github: {
clientID: get('GITHUB_CLIENT_ID', ''),
clientSecret: get('GITHUB_CLIENT_SECRET', ''),
},
trustedProxies: getTrustProxies('TRUSTED_PROXIES'),
surveyUrl: getUrl('SURVEY_URL', ''),
bugReportUrl: getUrl('BUG_REPORT_URL', ''),
docker: {
network: get('DOCKER_NETWORK', 'host'),
defaultImage: get('QUEST_IMAGE', 'linuxodyssey/quest-base'),
imagePrefix: get('DOCKER_PREFIX', 'linuxodyssey/quest-'),
mountQuest: get('MOUNT_QUEST', ''),
hostPwd: get('HOST_PWD', ''),
},
docker: {
network: get('DOCKER_NETWORK', 'host'),
defaultImage: get('QUEST_IMAGE', 'linuxodyssey/quest-base'),
imagePrefix: get('DOCKER_PREFIX', 'linuxodyssey/quest-'),
mountQuest: get('MOUNT_QUEST', ''),
hostPwd: get('HOST_PWD', ''),
},
log: {
path: get('LOG_PATH', '../logs'),
},
log: {
path: get('LOG_PATH', '../logs'),
},
testing: {
enabled: !isProduction && process.env.TESTING === 'true',
username: get('TESTING_USERNAME', ''),
password: get('TESTING_PASSWORD', ''),
},
}
}
config.baseUrl = get('BASE_URL', `http://${config.host}:${config.port}`)
config.backendUrl = get('BACKEND_URL', config.baseUrl)
config.testing = {
enabled: !config.isProduction && process.env.TESTING === 'true',
username: get('TESTING_USERNAME', ''),
password: get('TESTING_PASSWORD', ''),
}
const config = createConfig()
console.log(config)
export function getQuestImage(id) {
return `${config.docker.imagePrefix}${id}`
+3 -2
View File
@@ -9,9 +9,10 @@ export default session({
saveUninitialized: false,
rolling: true,
cookie: {
domain: config.domain,
httpOnly: true,
secure: false,
sameSite: 'lax',
secure: config.protocol === 'https:',
sameSite: 'strict',
maxAge: config.sessionMaxAge,
},
store: MongoStore.create({
+35
View File
@@ -3146,6 +3146,16 @@ __metadata:
languageName: node
linkType: hard
"cookie-parser@npm:^1.4.6":
version: 1.4.6
resolution: "cookie-parser@npm:1.4.6"
dependencies:
cookie: "npm:0.4.1"
cookie-signature: "npm:1.0.6"
checksum: 10c0/9c2ade5459290802cd472a2d2a6e46fbd7de3e8514e02bfed5edfde892d77733c7f89d9d2015f752a9087680429b416972d7aba748bf6824e21eb680c8556383
languageName: node
linkType: hard
"cookie-signature@npm:1.0.6":
version: 1.0.6
resolution: "cookie-signature@npm:1.0.6"
@@ -3160,6 +3170,13 @@ __metadata:
languageName: node
linkType: hard
"cookie@npm:0.4.1":
version: 0.4.1
resolution: "cookie@npm:0.4.1"
checksum: 10c0/4d7bc798df3d0f34035977949cd6b7d05bbab47d7dcb868667f460b578a550cd20dec923832b8a3a107ef35aba091a3975e14f79efacf6e39282dc0fed6db4a1
languageName: node
linkType: hard
"cookie@npm:0.5.0":
version: 0.5.0
resolution: "cookie@npm:0.5.0"
@@ -6709,6 +6726,15 @@ __metadata:
languageName: node
linkType: hard
"lusca@npm:^1.7.0":
version: 1.7.0
resolution: "lusca@npm:1.7.0"
dependencies:
tsscmp: "npm:^1.0.5"
checksum: 10c0/73b49c9289bbdff73298421bdafc0633f958d97bef51a0fe747bbd1ec5a8c6bb2ff9ada37e84d3a8e23703ae2db1fcf8e3d1fbea366559e3b7261467c66fbe2e
languageName: node
linkType: hard
"luxon@npm:^3.2.1":
version: 3.4.4
resolution: "luxon@npm:3.4.4"
@@ -8413,6 +8439,7 @@ __metadata:
commander: "npm:^11.0.0"
concurrently: "npm:^8.2.2"
connect-mongo: "npm:^5.0.0"
cookie-parser: "npm:^1.4.6"
dockerode: "npm:^3.3.5"
dotenv: "npm:^16.4.1"
express: "npm:^4.18.2"
@@ -8421,6 +8448,7 @@ __metadata:
express-validator: "npm:^7.0.1"
jest: "npm:^29.6.1"
jsonwebtoken: "npm:^9.0.1"
lusca: "npm:^1.7.0"
minimist: "npm:^1.2.8"
mongodb: "npm:^6.3.0"
mongoose: "npm:^8.0.3"
@@ -9354,6 +9382,13 @@ __metadata:
languageName: node
linkType: hard
"tsscmp@npm:^1.0.5":
version: 1.0.6
resolution: "tsscmp@npm:1.0.6"
checksum: 10c0/2f79a9455e7e3e8071995f98cdf3487ccfc91b760bec21a9abb4d90519557eafaa37246e87c92fa8bf3fef8fd30cfd0cc3c4212bb929baa9fb62494bfa4d24b2
languageName: node
linkType: hard
"tunnel-agent@npm:^0.6.0":
version: 0.6.0
resolution: "tunnel-agent@npm:0.6.0"