project started
This commit is contained in:
commit
a2e0c40391
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
|
||||
node_modules/
|
||||
deb
|
||||
echo
|
6
Dockerfile
Normal file
6
Dockerfile
Normal file
|
@ -0,0 +1,6 @@
|
|||
FROM node:12.2.0-alpine
|
||||
WORKDIR app
|
||||
COPY . .
|
||||
RUN npm install
|
||||
EXPOSE 8000
|
||||
CMD ["node","app.js"]
|
10
README.md
Normal file
10
README.md
Normal file
|
@ -0,0 +1,10 @@
|
|||
# node-todo-cicd
|
||||
|
||||
sudo apt install nodejs
|
||||
sudo apt install npm
|
||||
|
||||
|
||||
sudo npm install
|
||||
|
||||
node app.js
|
||||
|
88
app.js
Normal file
88
app.js
Normal file
|
@ -0,0 +1,88 @@
|
|||
const express = require('express'),
|
||||
bodyParser = require('body-parser'),
|
||||
// In order to use PUT HTTP verb to edit item
|
||||
methodOverride = require('method-override'),
|
||||
// Mitigate XSS using sanitizer
|
||||
sanitizer = require('sanitizer'),
|
||||
app = express(),
|
||||
port = 8000
|
||||
|
||||
app.use(bodyParser.urlencoded({
|
||||
extended: false
|
||||
}));
|
||||
// https: //github.com/expressjs/method-override#custom-logic
|
||||
app.use(methodOverride(function (req, res) {
|
||||
if (req.body && typeof req.body === 'object' && '_method' in req.body) {
|
||||
// look in urlencoded POST bodies and delete it
|
||||
let method = req.body._method;
|
||||
delete req.body._method;
|
||||
return method
|
||||
}
|
||||
}));
|
||||
|
||||
|
||||
let todolist = [];
|
||||
|
||||
/* The to do list and the form are displayed */
|
||||
app.get('/todo', function (req, res) {
|
||||
res.render('todo.ejs', {
|
||||
todolist,
|
||||
clickHandler: "func1();"
|
||||
});
|
||||
})
|
||||
|
||||
/* Adding an item to the to do list */
|
||||
.post('/todo/add/', function (req, res) {
|
||||
// Escapes HTML special characters in attribute values as HTML entities
|
||||
let newTodo = sanitizer.escape(req.body.newtodo);
|
||||
if (req.body.newtodo != '') {
|
||||
todolist.push(newTodo);
|
||||
}
|
||||
res.redirect('/todo');
|
||||
})
|
||||
|
||||
/* Deletes an item from the to do list */
|
||||
.get('/todo/delete/:id', function (req, res) {
|
||||
if (req.params.id != '') {
|
||||
todolist.splice(req.params.id, 1);
|
||||
}
|
||||
res.redirect('/todo');
|
||||
})
|
||||
|
||||
// Get a single todo item and render edit page
|
||||
.get('/todo/:id', function (req, res) {
|
||||
let todoIdx = req.params.id;
|
||||
let todo = todolist[todoIdx];
|
||||
|
||||
if (todo) {
|
||||
res.render('edititem.ejs', {
|
||||
todoIdx,
|
||||
todo,
|
||||
clickHandler: "func1();"
|
||||
});
|
||||
} else {
|
||||
res.redirect('/todo');
|
||||
}
|
||||
})
|
||||
|
||||
// Edit item in the todo list
|
||||
.put('/todo/edit/:id', function (req, res) {
|
||||
let todoIdx = req.params.id;
|
||||
// Escapes HTML special characters in attribute values as HTML entities
|
||||
let editTodo = sanitizer.escape(req.body.editTodo);
|
||||
if (todoIdx != '' && editTodo != '') {
|
||||
todolist[todoIdx] = editTodo;
|
||||
}
|
||||
res.redirect('/todo');
|
||||
})
|
||||
/* Redirects to the to do list if the page requested is not found */
|
||||
.use(function (req, res, next) {
|
||||
res.redirect('/todo');
|
||||
})
|
||||
|
||||
.listen(port, function () {
|
||||
// Logging to console
|
||||
console.log(`Todolist running on http://0.0.0.0:${port}`)
|
||||
});
|
||||
// Export app
|
||||
module.exports = app;
|
5692
package-lock.json
generated
Normal file
5692
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
23
package.json
Normal file
23
package.json
Normal file
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"name": "my-todolist",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"body-parser": "^1.16.0",
|
||||
"ejs": "^2.5.5",
|
||||
"express": "^4.14.0",
|
||||
"method-override": "^3.0.0",
|
||||
"sanitizer": "^0.1.3"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "node app.js",
|
||||
"test": "nyc --reporter=html --reporter=text mocha --exit"
|
||||
},
|
||||
"author": "riaan@entersekt.com",
|
||||
"description": "Basic to do list exercise",
|
||||
"devDependencies": {
|
||||
"chai": "^4.2.0",
|
||||
"mocha": "^6.2.1",
|
||||
"nyc": "^14.1.1",
|
||||
"supertest": "^4.0.2"
|
||||
}
|
||||
}
|
28
views/edititem.ejs
Normal file
28
views/edititem.ejs
Normal file
|
@ -0,0 +1,28 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>Edit <%- todo %></title>
|
||||
<style>
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: black;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Edit <%- todo %>:</h1>
|
||||
<form action="/todo/edit/<%= todoIdx %>" method="post">
|
||||
<p>
|
||||
<label for="editTodo">Change to:</label>
|
||||
<input type="hidden" name="_method" value="PUT">
|
||||
<input type="text" name="editTodo" id="editTodo" autofocus placeholder="<%- todo %>" />
|
||||
<input type="submit" value="Save" />
|
||||
</p>
|
||||
</form>
|
||||
</body>
|
||||
|
||||
</html>
|
37
views/todo.ejs
Normal file
37
views/todo.ejs
Normal file
|
@ -0,0 +1,37 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title> To DO LIST# </title>
|
||||
<style>
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: black;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1> 12 FACTOR APP!!! </h1>
|
||||
<ul>
|
||||
<% todolist.forEach(function(todo, index) { %>
|
||||
<li>
|
||||
<a href="/todo/delete/<%= index %>">✘</a>
|
||||
<a href="/todo/<%= index %>">✎</a>
|
||||
<%- todo %>
|
||||
</li>
|
||||
<% }); %>
|
||||
</ul>
|
||||
|
||||
<form action="/todo/add/" method="post">
|
||||
<p>
|
||||
<label for="newtodo">What shoud I do?</label>
|
||||
<input type="text" name="newtodo" id="newtodo" autofocus />
|
||||
<input type="submit" value="Add" />
|
||||
</p>
|
||||
</form>
|
||||
</body>
|
||||
|
||||
</html>
|
Loading…
Reference in a new issue