From 4e450993260b533ec12e39893d7e98df806ea7c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Taupin?= Date: Wed, 6 Aug 2025 09:46:52 +0200 Subject: [PATCH] BC4-TP03 --- .gitignore | 3 + app.js | 49 +++++++++++++++ bin/www | 114 +++++++++++++++++++++++++++++++++++ bootstrapdb.js | 60 ++++++++++++++++++ db/vulny.db | Bin 0 -> 16384 bytes package.json | 19 ++++++ public/stylesheets/style.css | 8 +++ routes/api.js | 21 +++++++ routes/index.js | 9 +++ routes/search.js | 22 +++++++ service/search.js | 29 +++++++++ views/error.pug | 6 ++ views/index.pug | 7 +++ views/layout.pug | 7 +++ views/search.pug | 7 +++ views/searchResult.pug | 16 +++++ 16 files changed, 377 insertions(+) create mode 100644 .gitignore create mode 100644 app.js create mode 100755 bin/www create mode 100644 bootstrapdb.js create mode 100644 db/vulny.db create mode 100644 package.json create mode 100644 public/stylesheets/style.css create mode 100644 routes/api.js create mode 100644 routes/index.js create mode 100644 routes/search.js create mode 100644 service/search.js create mode 100644 views/error.pug create mode 100644 views/index.pug create mode 100644 views/layout.pug create mode 100644 views/search.pug create mode 100644 views/searchResult.pug diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..727fd03 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.idea/ +*.iml +node_modules/ \ No newline at end of file diff --git a/app.js b/app.js new file mode 100644 index 0000000..5fa47d1 --- /dev/null +++ b/app.js @@ -0,0 +1,49 @@ +var createError = require('http-errors'); +var express = require('express'); +var path = require('path'); +var cookieParser = require('cookie-parser'); +var logger = require('morgan'); + +var indexRouter = require('./routes/index'); +var searchRouter = require('./routes/search'); +var apiRouter = require('./routes/api'); +const robots = require('express-robots-txt') + +var app = express(); + +app.use(robots({ + UserAgent: '*', + Disallow: [ '/', '/search' ] +})); + +// view engine setup +app.set('views', path.join(__dirname, 'views')); +app.set('view engine', 'pug'); + +app.use(logger('dev')); +app.use(express.json()); +app.use(express.urlencoded({ extended: false })); +app.use(cookieParser()); +app.use(express.static(path.join(__dirname, 'public'))); + +app.use('/', indexRouter); +app.use('/search', searchRouter); +app.use('/api', apiRouter); + +// catch 404 and forward to error handler +app.use(function(req, res, next) { + next(createError(404)); +}); + +// error handler +app.use(function(err, req, res, next) { + // set locals, only providing error in development + res.locals.message = err.message; + res.locals.error = req.app.get('env') === 'development' ? err : {}; + + // render the error page + res.status(err.status || 500); + res.render('error'); +}); + +module.exports = app; diff --git a/bin/www b/bin/www new file mode 100755 index 0000000..06f590c --- /dev/null +++ b/bin/www @@ -0,0 +1,114 @@ +#!/usr/bin/env node + +/** + * Module dependencies. + */ + +var app = require('../app'); +var debug = require('debug')('nodeexpressvulny:server'); +var http = require('http'); + +/** + * Get port from environment and store in Express. + */ + +var port = normalizePort(process.env.PORT || '3000'); +app.set('port', port); + +/** + * Create HTTP server. + */ + +var server = http.createServer(app); + +/** + * Listen on provided port, on all network interfaces. + */ + +server.listen(port); +server.on('error', onError); +server.on('listening', onListening); + +/** + * Normalize a port into a number, string, or false. + */ + +function normalizePort(val) { + var port = parseInt(val, 10); + + if (isNaN(port)) { + // named pipe + return val; + } + + if (port >= 0) { + // port number + return port; + } + + return false; +} + +/** + * Event listener for HTTP server "error" event. + */ + +function onError(error) { + if (error.syscall !== 'listen') { + throw error; + } + + var bind = typeof port === 'string' + ? 'Pipe ' + port + : 'Port ' + port; + + // handle specific listen errors with friendly messages + switch (error.code) { + case 'EACCES': + console.error(bind + ' requires elevated privileges'); + process.exit(1); + break; + case 'EADDRINUSE': + console.error(bind + ' is already in use'); + process.exit(1); + break; + default: + throw error; + } +} + +/** + * Event listener for HTTP server "listening" event. + */ + +function onListening() { + var addr = server.address(); + var bind = typeof addr === 'string' + ? 'pipe ' + addr + : 'port ' + addr.port; + debug('Listening on ' + bind); +} + +// Borrowed from https://medium.com/@becintec/building-graceful-node-applications-in-docker-4d2cd4d5d392 +// The signals we want to handle +// NOTE: although it is tempting, the SIGKILL signal (9) cannot be intercepted and handled +var signals = { + 'SIGHUP': 1, + 'SIGINT': 2, + 'SIGTERM': 15 +}; +// Do any necessary shutdown logic for our application here +const shutdown = (signal, value) => { + console.log("shutdown!"); + server.close(() => { + console.log(`server stopped by ${signal} with value ${value}`); + process.exit(128 + value); + }); +}; +// Create a listener for each of the signals that we want to handle +Object.keys(signals).forEach((signal) => { + process.on(signal, () => { + console.log(`process received a ${signal} signal`); + shutdown(signal, signals[signal]); + }); +}); diff --git a/bootstrapdb.js b/bootstrapdb.js new file mode 100644 index 0000000..1760ad0 --- /dev/null +++ b/bootstrapdb.js @@ -0,0 +1,60 @@ +const sqlite3 = require('sqlite3').verbose(); +const db = new sqlite3.Database('./db/vulny.db'); + +db.serialize(function () { + db.run('CREATE TABLE item (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, name NVARCHAR(1024) NOT NULL, description TEXT)', function (err) { + if (err) { + console.error(err); + } else { + const itemTbl = db.prepare('INSERT INTO item VALUES (null, ?, ?)', function (err) { + if (err) { + console.error(err) + } + }); + + for (var i = 0; i < 3; i++) { + itemTbl.run('item-' + i, 'item-' + i + ' is the great item evar'); + } + + itemTbl.finalize(function (err) { + if (err) { + console.error(err) + } else { + db.close(function (err) { + if (err) { + console.error(err) + } + }); + } + }); + } + }); + + + db.run('CREATE TABLE user (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, username NVARCHAR(1024) NOT NULL, password TEXT NOT NULL)', function (err) { + if (err) { + console.error(err); + } else { + const userTbl = db.prepare('INSERT INTO user VALUES (null, ?, ?)', function (err) { + if (err) { + console.error(err) + } + }); + userTbl.run('admin', 'S3cr37P@$$w0rD!'); + userTbl.run('user1', 'bad_password'); + userTbl.run('user2', 'worse'); + userTbl.run('user3', 'fail'); + userTbl.finalize(function (err) { + if (err) { + console.error(err) + } else { + db.close(function (err) { + if (err) { + console.error(err) + } + }); + } + }); + } + }); +}); diff --git a/db/vulny.db b/db/vulny.db new file mode 100644 index 0000000000000000000000000000000000000000..0c0a3f71572cb15b0ad079deb200904eac98cf97 GIT binary patch literal 16384 zcmeI(&raJg90zdck63#s<`QMQc@l_LWmEqk?Mh$~t5!l6!nB@HXbg+gKad1^?xelI z9%R}Z>=Aa{3!oi$+<8BHDgz{tcBppwT5=paKRfZ~=EOO8(@hI0PA1tXE<~HHFvDP5 zLNLb4lx@oMWYWpax-q}-Kv`zbH${a4tmRLPPx%@ZNDzPk1Rwwb2tWV=5P$##AOHap zn5|fkT*om!SVeq1loz?oRJM0Q--~<^dD~rIs1{L86VVAGf7cI1FYN4jVPCxV`@%bn z_B#Q^@A*L_f_=(|-R_3&G>%771aG}?=am;$n~m0H?MB2|oafU?mWarI_qS)QXD+$* zy3yAUl%Ef2#e9^@^9wm1$U9Z*)??neSXFo5pq{nalA$L#o9HoVz>&)4t=_8TpC|e7 z1QVGLvh=J-Cu2RwnqHgpkBookpQ%8C00bZa0SG_<0uX=z1Rwwb2tZ&_0_&E|p6sgS z{>Yi{C|eWv>m{$$H^!iAG8Nq`$cbSb#>avUOxQ|B4@+0 literal 0 HcmV?d00001 diff --git a/package.json b/package.json new file mode 100644 index 0000000..449e243 --- /dev/null +++ b/package.json @@ -0,0 +1,19 @@ +{ + "name": "nodeexpressvulny", + "version": "0.0.0", + "private": true, + "scripts": { + "start": "node ./bin/www" + }, + "dependencies": { + "cookie-parser": "~1.4.4", + "debug": "~2.6.9", + "express": "~4.16.1", + "express-list-endpoints": "^4.0.1", + "http-errors": "~1.6.3", + "morgan": "~1.9.1", + "pug": "^2.0.4", + "sqlite": "^3.0.3", + "express-robots-txt": "1.0.0" + } +} diff --git a/public/stylesheets/style.css b/public/stylesheets/style.css new file mode 100644 index 0000000..9453385 --- /dev/null +++ b/public/stylesheets/style.css @@ -0,0 +1,8 @@ +body { + padding: 50px; + font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; +} + +a { + color: #00B7FF; +} diff --git a/routes/api.js b/routes/api.js new file mode 100644 index 0000000..54059bb --- /dev/null +++ b/routes/api.js @@ -0,0 +1,21 @@ +const express = require('express'); +const router = express.Router(); +const searchService = require('../service/search'); + +router.get('/search', function (req, res, next) { + + const searchText = req.query.searchText !== undefined ? req.query.searchText : ''; + console.log(req.query); + console.log('search text: ' + searchText); + searchService.searchByName(searchText, function (err, ret) { + if (err) { + res.json(err); + } else { + delete ret.searchText; + res.json(ret); + } + }); + +}); + +module.exports = router; \ No newline at end of file diff --git a/routes/index.js b/routes/index.js new file mode 100644 index 0000000..8faab3f --- /dev/null +++ b/routes/index.js @@ -0,0 +1,9 @@ +var express = require('express'); +var router = express.Router(); + +/* GET home page. */ +router.get('/', function(req, res, next) { + res.render('index', { title: 'VulnyJS' }); +}); + +module.exports = router; diff --git a/routes/search.js b/routes/search.js new file mode 100644 index 0000000..3623f1e --- /dev/null +++ b/routes/search.js @@ -0,0 +1,22 @@ +const express = require('express'); +const router = express.Router(); +const searchService = require('../service/search'); + +/* GET search listing. */ +router.get('/', function (req, res, next) { + res.render('search', {title: 'Search for items'}); +}); + +router.post('/', function (req, res, next) { + const searchText = req.body.searchText; + + searchService.searchByName(searchText, function (err, ret) { + if (err) { + res.redirect('/search') + } else { + res.render('searchResult', ret) + } + }); +}); + +module.exports = router; diff --git a/service/search.js b/service/search.js new file mode 100644 index 0000000..9422eca --- /dev/null +++ b/service/search.js @@ -0,0 +1,29 @@ +const sqlite3 = require('sqlite3').verbose(); +const db = new sqlite3.Database('./db/vulny.db'); + +const searchByName = function (searchText, cb) { + + db.all("select id,name,description from item where name like '%" + searchText + "%'", [], function (err, rows) { + //db.all("select id,name,description from item where name like '%?%'", [searchText], function (err, rows) { + if (err) { + console.log('error ' + err); + cb(err); + //res.redirect('/search') + } else { + //console.log(req.body); + console.log('rows? ' + rows); + console.log('got ' + rows.length + ' rows'); + const ret = { + searchText: searchText, + rows: rows + }; + cb(null, ret); + //res.render('searchResult', ret) + } + }); + +}; + +module.exports = { + searchByName: searchByName +}; \ No newline at end of file diff --git a/views/error.pug b/views/error.pug new file mode 100644 index 0000000..51ec12c --- /dev/null +++ b/views/error.pug @@ -0,0 +1,6 @@ +extends layout + +block content + h1= message + h2= error.status + pre #{error.stack} diff --git a/views/index.pug b/views/index.pug new file mode 100644 index 0000000..a08ad66 --- /dev/null +++ b/views/index.pug @@ -0,0 +1,7 @@ +extends layout + +block content + h1= title + p Welcome to #{title} + h3 + a(href='/search') Search diff --git a/views/layout.pug b/views/layout.pug new file mode 100644 index 0000000..15af079 --- /dev/null +++ b/views/layout.pug @@ -0,0 +1,7 @@ +doctype html +html + head + title= title + link(rel='stylesheet', href='/stylesheets/style.css') + body + block content diff --git a/views/search.pug b/views/search.pug new file mode 100644 index 0000000..045382b --- /dev/null +++ b/views/search.pug @@ -0,0 +1,7 @@ +extends layout + +block content + h1= 'Find some items' + form(action='/search', method='post') + input(type='text', name='searchText') + input(type='submit', name='Search') \ No newline at end of file diff --git a/views/searchResult.pug b/views/searchResult.pug new file mode 100644 index 0000000..12895bb --- /dev/null +++ b/views/searchResult.pug @@ -0,0 +1,16 @@ +extends layout + +block content + h1!= 'Search Results for: ' + searchText + table + tr + th Id + th Name + th Description + each item in rows + tr + td= item.id + td= item.name + td= item.description + h3 + a(href='/search') Search \ No newline at end of file