Add test for securityChecks

Only covers simple cases. Administrator is responsible to secure that
 the user that runs the webserver is not allowed to access files that
 are not within the shared folder.

Add jest to picture-gallery-server
This commit is contained in:
Stefan Forstenlechner 2022-06-18 15:41:43 +02:00
parent f9df91cbc8
commit 09ff5ff5e7
11 changed files with 5653 additions and 206 deletions

View File

@ -1,36 +1,36 @@
FROM node:16.14.2-alpine as client-builder FROM node:16.14.2-alpine as client-builder
COPY picture-gallery-client/package*.json /usr/src/app/picture-gallery-client/ COPY picture-gallery-client/package*.json /usr/src/app/picture-gallery-client/
WORKDIR /usr/src/app/picture-gallery-client WORKDIR /usr/src/app/picture-gallery-client
RUN npm ci --only=production RUN npm ci --only=production
COPY picture-gallery-client . COPY picture-gallery-client .
RUN npm run build-client RUN npm run client:build
RUN mkdir built && \ RUN mkdir built && \
mv build built && \ mv build built && \
mv package.minimize.docker.json built/package.json && \ mv package.minimize.docker.json built/package.json && \
cp package-lock.json built && \ cp package-lock.json built && \
npm ci --prefix ./built --only=production npm ci --prefix ./built --only=production
FROM node:16.14.2-alpine as server-builder FROM node:16.14.2-alpine as server-builder
COPY picture-gallery-server/package*.json /usr/src/app/picture-gallery-server/ COPY picture-gallery-server/package*.json /usr/src/app/picture-gallery-server/
WORKDIR /usr/src/app/picture-gallery-server WORKDIR /usr/src/app/picture-gallery-server
RUN npm ci RUN npm ci
COPY picture-gallery-server . COPY picture-gallery-server .
RUN npm run build-server RUN npm run server:build
RUN mkdir built && \ RUN mkdir built && \
mv dist node_modules built mv dist node_modules built
FROM node:16.14.2-alpine FROM node:16.14.2-alpine
COPY --from=client-builder --chown=node:node /usr/src/app/picture-gallery-client/built /usr/src/app/picture-gallery-client/ COPY --from=client-builder --chown=node:node /usr/src/app/picture-gallery-client/built /usr/src/app/picture-gallery-client/
COPY --from=server-builder --chown=node:node /usr/src/app/picture-gallery-server/built /usr/src/app/picture-gallery-server/ COPY --from=server-builder --chown=node:node /usr/src/app/picture-gallery-server/built /usr/src/app/picture-gallery-server/
VOLUME /usr/src/app/public VOLUME /usr/src/app/public
EXPOSE 3001 EXPOSE 3001
USER node USER node
WORKDIR /usr/src/app/picture-gallery-server WORKDIR /usr/src/app/picture-gallery-server
CMD npm run --prefix ../picture-gallery-client/ set-environment && node dist/app.js CMD npm run --prefix ../picture-gallery-client/ set-environment && node dist/app.js

View File

@ -9,9 +9,9 @@
"install:client": "cd picture-gallery-client && npm i", "install:client": "cd picture-gallery-client && npm i",
"install:server": "cd picture-gallery-server && npm i", "install:server": "cd picture-gallery-server && npm i",
"start-all": "npm run build:client && concurrently npm:start:client npm:run:server", "start-all": "npm run build:client && concurrently npm:start:client npm:run:server",
"build:client": "npm run --prefix picture-gallery-client build-client", "build:client": "npm run --prefix picture-gallery-client client:build",
"start:client": "npm run --prefix picture-gallery-client start-client", "start:client": "npm run --prefix picture-gallery-client client:start",
"run:server": "npm run --prefix picture-gallery-server run-server", "run:server": "npm run --prefix picture-gallery-server server:run",
"docker:buildImage": "docker build . -t simple-picture-gallery" "docker:buildImage": "docker build . -t simple-picture-gallery"
} }
} }

View File

@ -5,7 +5,6 @@
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "picture-gallery-client",
"version": "0.1.0", "version": "0.1.0",
"dependencies": { "dependencies": {
"@emotion/react": "11.9.0", "@emotion/react": "11.9.0",
@ -13,6 +12,18 @@
"@mui/icons-material": "5.6.0", "@mui/icons-material": "5.6.0",
"@mui/lab": "5.0.0-alpha.76", "@mui/lab": "5.0.0-alpha.76",
"@mui/material": "5.6.0", "@mui/material": "5.6.0",
"@types/jest": "27.4.1",
"@types/node": "16.11.26",
"@types/react": "18.0.0",
"@types/react-dom": "18.0.0",
"eslint": "8.13.0",
"eslint-config-prettier": "8.5.0",
"eslint-import-resolver-typescript": "2.7.1",
"eslint-plugin-import": "2.26.0",
"eslint-plugin-jsx-a11y": "6.5.1",
"eslint-plugin-prettier": "4.0.0",
"eslint-plugin-react": "7.29.4",
"eslint-plugin-react-hooks": "4.4.0",
"react": "18.0.0", "react": "18.0.0",
"react-dom": "18.0.0", "react-dom": "18.0.0",
"react-inject-env": "2.1.0", "react-inject-env": "2.1.0",
@ -26,21 +37,8 @@
"@testing-library/jest-dom": "5.16.4", "@testing-library/jest-dom": "5.16.4",
"@testing-library/react": "12.1.4", "@testing-library/react": "12.1.4",
"@testing-library/user-event": "13.5.0", "@testing-library/user-event": "13.5.0",
"@types/jest": "27.4.1",
"@types/node": "16.11.26",
"@types/react": "18.0.0",
"@types/react-dom": "18.0.0",
"@typescript-eslint/eslint-plugin": "5.18.0", "@typescript-eslint/eslint-plugin": "5.18.0",
"@typescript-eslint/parser": "5.18.0", "@typescript-eslint/parser": "5.18.0",
"eslint": "8.13.0",
"eslint-config-airbnb": "19.0.4",
"eslint-config-prettier": "8.5.0",
"eslint-import-resolver-typescript": "2.7.1",
"eslint-plugin-import": "2.26.0",
"eslint-plugin-jsx-a11y": "6.5.1",
"eslint-plugin-prettier": "4.0.0",
"eslint-plugin-react": "7.29.4",
"eslint-plugin-react-hooks": "4.4.0",
"prettier": "2.6.2" "prettier": "2.6.2"
} }
}, },
@ -4171,7 +4169,6 @@
"version": "27.4.1", "version": "27.4.1",
"resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.4.1.tgz", "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.4.1.tgz",
"integrity": "sha512-23iPJADSmicDVrWk+HT58LMJtzLAnB2AgIzplQuq/bSrGaxCrlvRFjGbXmamnnk/mAmCdLStiGqggu28ocUyiw==", "integrity": "sha512-23iPJADSmicDVrWk+HT58LMJtzLAnB2AgIzplQuq/bSrGaxCrlvRFjGbXmamnnk/mAmCdLStiGqggu28ocUyiw==",
"dev": true,
"dependencies": { "dependencies": {
"jest-matcher-utils": "^27.0.0", "jest-matcher-utils": "^27.0.0",
"pretty-format": "^27.0.0" "pretty-format": "^27.0.0"
@ -4241,7 +4238,6 @@
"version": "18.0.0", "version": "18.0.0",
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.0.tgz", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.0.tgz",
"integrity": "sha512-49897Y0UiCGmxZqpC8Blrf6meL8QUla6eb+BBhn69dTXlmuOlzkfr7HHY/O8J25e1lTUMs+YYxSlVDAaGHCOLg==", "integrity": "sha512-49897Y0UiCGmxZqpC8Blrf6meL8QUla6eb+BBhn69dTXlmuOlzkfr7HHY/O8J25e1lTUMs+YYxSlVDAaGHCOLg==",
"dev": true,
"dependencies": { "dependencies": {
"@types/react": "*" "@types/react": "*"
} }
@ -5038,9 +5034,9 @@
"integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=" "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0="
}, },
"node_modules/async": { "node_modules/async": {
"version": "2.6.3", "version": "2.6.4",
"resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz",
"integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==",
"dependencies": { "dependencies": {
"lodash": "^4.17.14" "lodash": "^4.17.14"
} }
@ -6877,11 +6873,11 @@
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
}, },
"node_modules/ejs": { "node_modules/ejs": {
"version": "3.1.6", "version": "3.1.8",
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.6.tgz", "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.8.tgz",
"integrity": "sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw==", "integrity": "sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==",
"dependencies": { "dependencies": {
"jake": "^10.6.1" "jake": "^10.8.5"
}, },
"bin": { "bin": {
"ejs": "bin/cli.js" "ejs": "bin/cli.js"
@ -7166,60 +7162,10 @@
"url": "https://opencollective.com/eslint" "url": "https://opencollective.com/eslint"
} }
}, },
"node_modules/eslint-config-airbnb": {
"version": "19.0.4",
"resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-19.0.4.tgz",
"integrity": "sha512-T75QYQVQX57jiNgpF9r1KegMICE94VYwoFQyMGhrvc+lB8YF2E/M/PYDaQe1AJcWaEgqLE+ErXV1Og/+6Vyzew==",
"dev": true,
"dependencies": {
"eslint-config-airbnb-base": "^15.0.0",
"object.assign": "^4.1.2",
"object.entries": "^1.1.5"
},
"engines": {
"node": "^10.12.0 || ^12.22.0 || ^14.17.0 || >=16.0.0"
},
"peerDependencies": {
"eslint": "^7.32.0 || ^8.2.0",
"eslint-plugin-import": "^2.25.3",
"eslint-plugin-jsx-a11y": "^6.5.1",
"eslint-plugin-react": "^7.28.0",
"eslint-plugin-react-hooks": "^4.3.0"
}
},
"node_modules/eslint-config-airbnb-base": {
"version": "15.0.0",
"resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz",
"integrity": "sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==",
"dev": true,
"dependencies": {
"confusing-browser-globals": "^1.0.10",
"object.assign": "^4.1.2",
"object.entries": "^1.1.5",
"semver": "^6.3.0"
},
"engines": {
"node": "^10.12.0 || >=12.0.0"
},
"peerDependencies": {
"eslint": "^7.32.0 || ^8.2.0",
"eslint-plugin-import": "^2.25.2"
}
},
"node_modules/eslint-config-airbnb-base/node_modules/semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true,
"bin": {
"semver": "bin/semver.js"
}
},
"node_modules/eslint-config-prettier": { "node_modules/eslint-config-prettier": {
"version": "8.5.0", "version": "8.5.0",
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz", "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz",
"integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==", "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==",
"dev": true,
"bin": { "bin": {
"eslint-config-prettier": "bin/cli.js" "eslint-config-prettier": "bin/cli.js"
}, },
@ -7275,7 +7221,6 @@
"version": "2.7.1", "version": "2.7.1",
"resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-2.7.1.tgz", "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-2.7.1.tgz",
"integrity": "sha512-00UbgGwV8bSgUv34igBDbTOtKhqoRMy9bFjNehT40bXg6585PNIct8HhXZ0SybqB9rWtXj9crcku8ndDn/gIqQ==", "integrity": "sha512-00UbgGwV8bSgUv34igBDbTOtKhqoRMy9bFjNehT40bXg6585PNIct8HhXZ0SybqB9rWtXj9crcku8ndDn/gIqQ==",
"dev": true,
"dependencies": { "dependencies": {
"debug": "^4.3.4", "debug": "^4.3.4",
"glob": "^7.2.0", "glob": "^7.2.0",
@ -7491,7 +7436,6 @@
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.0.0.tgz", "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.0.0.tgz",
"integrity": "sha512-98MqmCJ7vJodoQK359bqQWaxOE0CS8paAz/GgjaZLyex4TTk3g9HugoO89EqWCrFiOqn9EVvcoo7gZzONCWVwQ==", "integrity": "sha512-98MqmCJ7vJodoQK359bqQWaxOE0CS8paAz/GgjaZLyex4TTk3g9HugoO89EqWCrFiOqn9EVvcoo7gZzONCWVwQ==",
"dev": true,
"dependencies": { "dependencies": {
"prettier-linter-helpers": "^1.0.0" "prettier-linter-helpers": "^1.0.0"
}, },
@ -7994,8 +7938,7 @@
"node_modules/fast-diff": { "node_modules/fast-diff": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz",
"integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w=="
"dev": true
}, },
"node_modules/fast-glob": { "node_modules/fast-glob": {
"version": "3.2.11", "version": "3.2.11",
@ -8091,11 +8034,30 @@
} }
}, },
"node_modules/filelist": { "node_modules/filelist": {
"version": "1.0.2", "version": "1.0.4",
"resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.2.tgz", "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz",
"integrity": "sha512-z7O0IS8Plc39rTCq6i6iHxk43duYOn8uFJiWSewIq0Bww1RNybVHSCjahmcC87ZqAm4OTvFzlzeGu3XAzG1ctQ==", "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==",
"dependencies": { "dependencies": {
"minimatch": "^3.0.4" "minimatch": "^5.0.1"
}
},
"node_modules/filelist/node_modules/brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"dependencies": {
"balanced-match": "^1.0.0"
}
},
"node_modules/filelist/node_modules/minimatch": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz",
"integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==",
"dependencies": {
"brace-expansion": "^2.0.1"
},
"engines": {
"node": ">=10"
} }
}, },
"node_modules/filesize": { "node_modules/filesize": {
@ -9518,11 +9480,11 @@
} }
}, },
"node_modules/jake": { "node_modules/jake": {
"version": "10.8.4", "version": "10.8.5",
"resolved": "https://registry.npmjs.org/jake/-/jake-10.8.4.tgz", "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz",
"integrity": "sha512-MtWeTkl1qGsWUtbl/Jsca/8xSoK3x0UmS82sNbjqxxG/de/M/3b1DntdjHgPMC50enlTNwXOCRqPXLLt5cCfZA==", "integrity": "sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==",
"dependencies": { "dependencies": {
"async": "0.9.x", "async": "^3.2.3",
"chalk": "^4.0.2", "chalk": "^4.0.2",
"filelist": "^1.0.1", "filelist": "^1.0.1",
"minimatch": "^3.0.4" "minimatch": "^3.0.4"
@ -9549,9 +9511,9 @@
} }
}, },
"node_modules/jake/node_modules/async": { "node_modules/jake/node_modules/async": {
"version": "0.9.2", "version": "3.2.4",
"resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz",
"integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=" "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ=="
}, },
"node_modules/jake/node_modules/chalk": { "node_modules/jake/node_modules/chalk": {
"version": "4.1.2", "version": "4.1.2",
@ -13578,7 +13540,6 @@
"version": "2.6.2", "version": "2.6.2",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz", "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz",
"integrity": "sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==", "integrity": "sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==",
"dev": true,
"bin": { "bin": {
"prettier": "bin-prettier.js" "prettier": "bin-prettier.js"
}, },
@ -13593,7 +13554,6 @@
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz",
"integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==",
"dev": true,
"dependencies": { "dependencies": {
"fast-diff": "^1.1.2" "fast-diff": "^1.1.2"
}, },
@ -19814,7 +19774,6 @@
"version": "27.4.1", "version": "27.4.1",
"resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.4.1.tgz", "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.4.1.tgz",
"integrity": "sha512-23iPJADSmicDVrWk+HT58LMJtzLAnB2AgIzplQuq/bSrGaxCrlvRFjGbXmamnnk/mAmCdLStiGqggu28ocUyiw==", "integrity": "sha512-23iPJADSmicDVrWk+HT58LMJtzLAnB2AgIzplQuq/bSrGaxCrlvRFjGbXmamnnk/mAmCdLStiGqggu28ocUyiw==",
"dev": true,
"requires": { "requires": {
"jest-matcher-utils": "^27.0.0", "jest-matcher-utils": "^27.0.0",
"pretty-format": "^27.0.0" "pretty-format": "^27.0.0"
@ -19884,7 +19843,6 @@
"version": "18.0.0", "version": "18.0.0",
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.0.tgz", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.0.tgz",
"integrity": "sha512-49897Y0UiCGmxZqpC8Blrf6meL8QUla6eb+BBhn69dTXlmuOlzkfr7HHY/O8J25e1lTUMs+YYxSlVDAaGHCOLg==", "integrity": "sha512-49897Y0UiCGmxZqpC8Blrf6meL8QUla6eb+BBhn69dTXlmuOlzkfr7HHY/O8J25e1lTUMs+YYxSlVDAaGHCOLg==",
"dev": true,
"requires": { "requires": {
"@types/react": "*" "@types/react": "*"
} }
@ -20484,9 +20442,9 @@
"integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=" "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0="
}, },
"async": { "async": {
"version": "2.6.3", "version": "2.6.4",
"resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz",
"integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==",
"requires": { "requires": {
"lodash": "^4.17.14" "lodash": "^4.17.14"
} }
@ -21838,11 +21796,11 @@
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
}, },
"ejs": { "ejs": {
"version": "3.1.6", "version": "3.1.8",
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.6.tgz", "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.8.tgz",
"integrity": "sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw==", "integrity": "sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==",
"requires": { "requires": {
"jake": "^10.6.1" "jake": "^10.8.5"
} }
}, },
"electron-to-chromium": { "electron-to-chromium": {
@ -22130,42 +22088,10 @@
} }
} }
}, },
"eslint-config-airbnb": {
"version": "19.0.4",
"resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-19.0.4.tgz",
"integrity": "sha512-T75QYQVQX57jiNgpF9r1KegMICE94VYwoFQyMGhrvc+lB8YF2E/M/PYDaQe1AJcWaEgqLE+ErXV1Og/+6Vyzew==",
"dev": true,
"requires": {
"eslint-config-airbnb-base": "^15.0.0",
"object.assign": "^4.1.2",
"object.entries": "^1.1.5"
}
},
"eslint-config-airbnb-base": {
"version": "15.0.0",
"resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz",
"integrity": "sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==",
"dev": true,
"requires": {
"confusing-browser-globals": "^1.0.10",
"object.assign": "^4.1.2",
"object.entries": "^1.1.5",
"semver": "^6.3.0"
},
"dependencies": {
"semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true
}
}
},
"eslint-config-prettier": { "eslint-config-prettier": {
"version": "8.5.0", "version": "8.5.0",
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz", "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz",
"integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==", "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==",
"dev": true,
"requires": {} "requires": {}
}, },
"eslint-config-react-app": { "eslint-config-react-app": {
@ -22212,7 +22138,6 @@
"version": "2.7.1", "version": "2.7.1",
"resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-2.7.1.tgz", "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-2.7.1.tgz",
"integrity": "sha512-00UbgGwV8bSgUv34igBDbTOtKhqoRMy9bFjNehT40bXg6585PNIct8HhXZ0SybqB9rWtXj9crcku8ndDn/gIqQ==", "integrity": "sha512-00UbgGwV8bSgUv34igBDbTOtKhqoRMy9bFjNehT40bXg6585PNIct8HhXZ0SybqB9rWtXj9crcku8ndDn/gIqQ==",
"dev": true,
"requires": { "requires": {
"debug": "^4.3.4", "debug": "^4.3.4",
"glob": "^7.2.0", "glob": "^7.2.0",
@ -22366,7 +22291,6 @@
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.0.0.tgz", "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.0.0.tgz",
"integrity": "sha512-98MqmCJ7vJodoQK359bqQWaxOE0CS8paAz/GgjaZLyex4TTk3g9HugoO89EqWCrFiOqn9EVvcoo7gZzONCWVwQ==", "integrity": "sha512-98MqmCJ7vJodoQK359bqQWaxOE0CS8paAz/GgjaZLyex4TTk3g9HugoO89EqWCrFiOqn9EVvcoo7gZzONCWVwQ==",
"dev": true,
"requires": { "requires": {
"prettier-linter-helpers": "^1.0.0" "prettier-linter-helpers": "^1.0.0"
} }
@ -22634,8 +22558,7 @@
"fast-diff": { "fast-diff": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz",
"integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w=="
"dev": true
}, },
"fast-glob": { "fast-glob": {
"version": "3.2.11", "version": "3.2.11",
@ -22711,11 +22634,29 @@
} }
}, },
"filelist": { "filelist": {
"version": "1.0.2", "version": "1.0.4",
"resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.2.tgz", "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz",
"integrity": "sha512-z7O0IS8Plc39rTCq6i6iHxk43duYOn8uFJiWSewIq0Bww1RNybVHSCjahmcC87ZqAm4OTvFzlzeGu3XAzG1ctQ==", "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==",
"requires": { "requires": {
"minimatch": "^3.0.4" "minimatch": "^5.0.1"
},
"dependencies": {
"brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"requires": {
"balanced-match": "^1.0.0"
}
},
"minimatch": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz",
"integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==",
"requires": {
"brace-expansion": "^2.0.1"
}
}
} }
}, },
"filesize": { "filesize": {
@ -23712,11 +23653,11 @@
} }
}, },
"jake": { "jake": {
"version": "10.8.4", "version": "10.8.5",
"resolved": "https://registry.npmjs.org/jake/-/jake-10.8.4.tgz", "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz",
"integrity": "sha512-MtWeTkl1qGsWUtbl/Jsca/8xSoK3x0UmS82sNbjqxxG/de/M/3b1DntdjHgPMC50enlTNwXOCRqPXLLt5cCfZA==", "integrity": "sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==",
"requires": { "requires": {
"async": "0.9.x", "async": "^3.2.3",
"chalk": "^4.0.2", "chalk": "^4.0.2",
"filelist": "^1.0.1", "filelist": "^1.0.1",
"minimatch": "^3.0.4" "minimatch": "^3.0.4"
@ -23731,9 +23672,9 @@
} }
}, },
"async": { "async": {
"version": "0.9.2", "version": "3.2.4",
"resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz",
"integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=" "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ=="
}, },
"chalk": { "chalk": {
"version": "4.1.2", "version": "4.1.2",
@ -26508,14 +26449,12 @@
"prettier": { "prettier": {
"version": "2.6.2", "version": "2.6.2",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz", "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz",
"integrity": "sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==", "integrity": "sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew=="
"dev": true
}, },
"prettier-linter-helpers": { "prettier-linter-helpers": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz",
"integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==",
"dev": true,
"requires": { "requires": {
"fast-diff": "^1.1.2" "fast-diff": "^1.1.2"
} }

View File

@ -31,15 +31,15 @@
"web-vitals": "2.1.4" "web-vitals": "2.1.4"
}, },
"scripts": { "scripts": {
"start-client": "react-scripts start", "format": "prettier --write \"**/*.+(ts|tsx)\"",
"build-client": "react-scripts build && npm run set-environment", "format:check": "prettier --check \"**/*.+(ts|tsx)\"",
"test-client": "react-scripts test",
"eject-client": "react-scripts eject",
"set-environment": "npx react-inject-env set",
"lint": "eslint src/**", "lint": "eslint src/**",
"lint:fix": "eslint --fix src/**", "lint:fix": "eslint --fix src/**",
"format": "prettier --write \"**/*.+(ts|tsx)\"", "client:build": "react-scripts build && npm run set-environment",
"format:check": "prettier --check \"**/*.+(ts|tsx)\"" "client:eject": "react-scripts eject",
"client:start": "react-scripts start",
"client:test": "react-scripts test",
"set-environment": "npx react-inject-env set"
}, },
"eslintConfig": { "eslintConfig": {
"extends": [ "extends": [

View File

@ -1,7 +1,8 @@
{ {
"env": { "env": {
"browser": true, "browser": true,
"es2021": true "es2021": true,
"jest/globals": true
}, },
"extends": [ "extends": [
"airbnb-base", "airbnb-base",
@ -13,7 +14,8 @@
"sourceType": "module" "sourceType": "module"
}, },
"plugins": [ "plugins": [
"@typescript-eslint" "@typescript-eslint",
"jest"
], ],
"rules": { "rules": {
"import/extensions": [ "import/extensions": [

View File

@ -0,0 +1,12 @@
import type { Config } from "@jest/types";
export default async (): Promise<Config.InitialOptions> => {
return {
preset: "ts-jest",
testEnvironment: "node",
rootDir: "src",
clearMocks: true,
resetMocks: true,
restoreMocks: true,
};
};

File diff suppressed because it is too large Load Diff

View File

@ -4,20 +4,22 @@
"description": "", "description": "",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"test": "echo \"Error: no test specified\" && exit 1", "format": "prettier --write \"**/*.+(ts|tsx)\"",
"build-server": "npx tsc",
"start-server": "node dist/app.js",
"watch-server": "npx nodemon src/app.ts",
"run-server": "npm run build-server && npm run start-server",
"lint": "eslint src/**", "lint": "eslint src/**",
"lint:fix": "eslint --fix src/**", "lint:fix": "eslint --fix src/**",
"format": "prettier --write \"**/*.+(ts|tsx)\"" "server:build": "npx tsc",
"server:start": "node dist/app.js",
"server:run": "npm run build-server && npm run start-server",
"server:watch": "npx nodemon src/app.ts",
"test": "jest",
"test:watch": "jest --watch"
}, },
"keywords": [], "keywords": [],
"author": "", "author": "",
"license": "ISC", "license": "ISC",
"devDependencies": { "devDependencies": {
"@types/express": "4.17.13", "@types/express": "4.17.13",
"@types/jest": "28.1.2",
"@types/node": "16.11.7", "@types/node": "16.11.7",
"@types/sharp": "0.30.1", "@types/sharp": "0.30.1",
"@typescript-eslint/eslint-plugin": "5.18.0", "@typescript-eslint/eslint-plugin": "5.18.0",
@ -27,9 +29,12 @@
"eslint-config-prettier": "8.5.0", "eslint-config-prettier": "8.5.0",
"eslint-import-resolver-typescript": "2.7.1", "eslint-import-resolver-typescript": "2.7.1",
"eslint-plugin-import": "2.26.0", "eslint-plugin-import": "2.26.0",
"eslint-plugin-jest": "26.5.3",
"eslint-plugin-prettier": "4.0.0", "eslint-plugin-prettier": "4.0.0",
"jest": "28.1.1",
"nodemon": "2.0.15", "nodemon": "2.0.15",
"prettier": "2.6.2", "prettier": "2.6.2",
"ts-jest": "28.0.5",
"ts-node": "10.7.0", "ts-node": "10.7.0",
"typescript": "4.6.3" "typescript": "4.6.3"
}, },

View File

@ -0,0 +1,22 @@
import { securityValidation } from "../securityChecks";
describe("securityValidation", () => {
const validPaths: string[] = ["", "some/path", "folder"];
it.each(validPaths)("should allow valid path: %s", (validPath: string) => {
expect(() => securityValidation(validPath)).not.toThrow();
});
// `avoidTraversalInGeneral` includes actually allowed paths, but are excluded to avoid traversal all together
const avoidTraversalInGeneral = ["some/path/../to/here", "some/path/../.."];
const invalidPaths: string[] = avoidTraversalInGeneral.concat([
"..",
"../evil",
"evil/path/../../..",
"evil/path/../../../here",
]);
it.each(invalidPaths)("should not allow invalid path: %s", (invalidPath) => {
expect(() => securityValidation(invalidPath)).toThrow();
});
});

View File

@ -1,7 +1,7 @@
import path from "path"; import path from "path";
import { consoleLogger } from "../logging"; import { consoleLogger } from "../logging";
// in case the requested path starts with ".." and tries to traverse outside of the image directory // in case the requested path starts with ".." and tries to traverse outside the image directory
const dirToCheckAccessViolation = "anyDir"; const dirToCheckAccessViolation = "anyDir";
export const securityValidation = (requestedPath: string) => { export const securityValidation = (requestedPath: string) => {

View File

@ -7,5 +7,10 @@
"sourceMap": true, "sourceMap": true,
"outDir": "dist" "outDir": "dist"
}, },
"lib": ["es2015"] "lib": ["es2015"],
"exclude": [
"src/**/*.test.ts",
"**/__test__",
"jest.config.ts"
]
} }