initial commit
This commit is contained in:
commit
fa7cb177bf
24 changed files with 1813 additions and 0 deletions
13
.gitignore
vendored
Normal file
13
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
# Node build artifacts
|
||||||
|
node_modules
|
||||||
|
npm-debug.log
|
||||||
|
|
||||||
|
# Local development
|
||||||
|
*.env
|
||||||
|
*.dev
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# Docker
|
||||||
|
Dockerfile
|
||||||
|
docker-compose.yml
|
||||||
|
.idea
|
||||||
1
Procfile
Normal file
1
Procfile
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
web: node index.js
|
||||||
39
README.md
Normal file
39
README.md
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
# node-js-getting-started
|
||||||
|
|
||||||
|
A barebones Node.js app using [Express 4](http://expressjs.com/).
|
||||||
|
|
||||||
|
This application supports the [Getting Started with Node on Heroku](https://devcenter.heroku.com/articles/getting-started-with-nodejs) article - check it out.
|
||||||
|
|
||||||
|
## Running Locally
|
||||||
|
|
||||||
|
Make sure you have [Node.js](http://nodejs.org/) and the [Heroku CLI](https://cli.heroku.com/) installed.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ git clone https://github.com/heroku/node-js-getting-started.git # or clone your own fork
|
||||||
|
$ cd node-js-getting-started
|
||||||
|
$ npm install
|
||||||
|
$ npm start
|
||||||
|
```
|
||||||
|
|
||||||
|
Your app should now be running on [localhost:5000](http://localhost:5000/).
|
||||||
|
|
||||||
|
## Deploying to Heroku
|
||||||
|
|
||||||
|
```
|
||||||
|
$ heroku create
|
||||||
|
$ git push heroku master
|
||||||
|
$ heroku open
|
||||||
|
```
|
||||||
|
or
|
||||||
|
|
||||||
|
[](https://heroku.com/deploy)
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
For more information about using Node.js on Heroku, see these Dev Center articles:
|
||||||
|
|
||||||
|
- [Getting Started with Node.js on Heroku](https://devcenter.heroku.com/articles/getting-started-with-nodejs)
|
||||||
|
- [Heroku Node.js Support](https://devcenter.heroku.com/articles/nodejs-support)
|
||||||
|
- [Node.js on Heroku](https://devcenter.heroku.com/categories/nodejs)
|
||||||
|
- [Best Practices for Node.js Development](https://devcenter.heroku.com/articles/node-best-practices)
|
||||||
|
- [Using WebSockets on Heroku with Node.js](https://devcenter.heroku.com/articles/node-websockets)
|
||||||
8
app.json
Normal file
8
app.json
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"name": "stoplicht",
|
||||||
|
"description": "A Node.js app using Express 4",
|
||||||
|
"repository": "https://github.com/shautvast/stoplicht.git",
|
||||||
|
"logo": "",
|
||||||
|
"keywords": ["node", "express", "heroku"],
|
||||||
|
"image": "heroku/nodejs"
|
||||||
|
}
|
||||||
0
dat
Normal file
0
dat
Normal file
20
encrypt
Normal file
20
encrypt
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
const bcrypt = require('bcrypt');
|
||||||
|
|
||||||
|
if (process.argv.length === 0) {
|
||||||
|
console.log("Usage: encrypt <password>");
|
||||||
|
} else {
|
||||||
|
let plain= process.argv[2];
|
||||||
|
let hash=cryptPassword(plain);
|
||||||
|
console.log(hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
function cryptPassword(password) {
|
||||||
|
let salt = bcrypt.genSaltSync(10);
|
||||||
|
return bcrypt.hashSync(password, salt);
|
||||||
|
};
|
||||||
|
|
||||||
|
function comparePassword(plainPass, hashword) {
|
||||||
|
return bcrypt.compareSync(plainPass, hashword);
|
||||||
|
};
|
||||||
52
index.js
Normal file
52
index.js
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
const express = require('express')
|
||||||
|
const fs = require('fs');
|
||||||
|
const bodyParser = require('body-parser')
|
||||||
|
const path = require('path')
|
||||||
|
var bcrypt = require('bcrypt');
|
||||||
|
const PORT = process.env.PORT || 5000
|
||||||
|
|
||||||
|
const logins = new Map();
|
||||||
|
logins.set("sander", "$2b$10$6P.6pE7M/6C9l/xXKDxJFucTL313GwESnhZ3aAqtVnv.ouLca/y6a");
|
||||||
|
|
||||||
|
|
||||||
|
express()
|
||||||
|
.use(express.urlencoded())
|
||||||
|
.use(express.static(path.join(__dirname, '/public')))
|
||||||
|
.set('views', path.join(__dirname, 'views'))
|
||||||
|
.set('view engine', 'ejs')
|
||||||
|
.get("/data", (req, res) => sendData(req, res))
|
||||||
|
.get('/', (req, res) => res.render('pages/index'))
|
||||||
|
.post('/submit-form', (req, res) => appendToStorage(req, res))
|
||||||
|
.listen(PORT, () => console.log(`Listening on ${PORT}`));
|
||||||
|
|
||||||
|
function appendToStorage(req, res) {
|
||||||
|
if (req.body.username === '' || req.body.password === '') {
|
||||||
|
res.render('pages/error');
|
||||||
|
} else {
|
||||||
|
if (!correctCredentials(req.body.username, req.body.password)) {
|
||||||
|
res.render('pages/error');
|
||||||
|
} else {
|
||||||
|
fs.appendFile("dat", req.body.timestamp + ", " + req.body.username + ", " + req.body.emotion + "\n", err => {
|
||||||
|
if (err) {
|
||||||
|
return console.log(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
res.render('pages/thanks');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendData(req, res) {
|
||||||
|
fs.readFile("dat", (err, data) => {
|
||||||
|
if (err) {
|
||||||
|
console.error(err);
|
||||||
|
res.render('pages/error');
|
||||||
|
} else {
|
||||||
|
return res.send(data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function correctCredentials(username, password) {
|
||||||
|
return bcrypt.compareSync(password, logins.get(username));
|
||||||
|
}
|
||||||
1416
package-lock.json
generated
Normal file
1416
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
32
package.json
Normal file
32
package.json
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
{
|
||||||
|
"name": "node-js-getting-started",
|
||||||
|
"version": "0.3.0",
|
||||||
|
"description": "A sample Node.js app using Express 4",
|
||||||
|
"engines": {
|
||||||
|
"node": "12.x"
|
||||||
|
},
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"start": "node index.js",
|
||||||
|
"test": "node test.js"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"bcrypt": "^3.0.7",
|
||||||
|
"ejs": "^2.5.6",
|
||||||
|
"express": "^4.15.2"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"request": "^2.81.0",
|
||||||
|
"tape": "^4.7.0"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/heroku/node-js-getting-started"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"node",
|
||||||
|
"heroku",
|
||||||
|
"express"
|
||||||
|
],
|
||||||
|
"license": "MIT"
|
||||||
|
}
|
||||||
BIN
public/img/disappointed-face.png
Normal file
BIN
public/img/disappointed-face.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 23 KiB |
BIN
public/img/grinning-face-with-smiling-eyes.png
Normal file
BIN
public/img/grinning-face-with-smiling-eyes.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 27 KiB |
BIN
public/img/neutral-face.png
Normal file
BIN
public/img/neutral-face.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
66
public/js/stoplicht.js
Normal file
66
public/js/stoplicht.js
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
get("#happy").addEventListener('click', happy);
|
||||||
|
get('#unsure').addEventListener('click', unsure);
|
||||||
|
get('#sad').addEventListener('click', sad);
|
||||||
|
get('#username').addEventListener("keydown", event => {
|
||||||
|
checkError();
|
||||||
|
if (event.which == 13) {
|
||||||
|
get('#password').focus();
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
get('#password').addEventListener("keydown", event => {
|
||||||
|
checkError();
|
||||||
|
if (event.which == 13) {
|
||||||
|
get('#username').focus();
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function handle(event, next) {
|
||||||
|
if (event.which == 13) {
|
||||||
|
get(next).focus;
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function happy() {
|
||||||
|
emotion().value = "happy";
|
||||||
|
submit();
|
||||||
|
}
|
||||||
|
|
||||||
|
function unsure() {
|
||||||
|
emotion().value = "unsure"
|
||||||
|
submit();
|
||||||
|
}
|
||||||
|
|
||||||
|
function sad() {
|
||||||
|
emotion().value = "sad";
|
||||||
|
submit();
|
||||||
|
}
|
||||||
|
|
||||||
|
function emotion() {
|
||||||
|
return get('#emotion');
|
||||||
|
}
|
||||||
|
|
||||||
|
function submit() {
|
||||||
|
get('#timestamp').value = Date.now();
|
||||||
|
get('#emotionsForm').submit;
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkError(){
|
||||||
|
if (getValue("#username") != '' && getValue("#password") !=''){
|
||||||
|
setHtml("#errorMessage",'');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function get(element){
|
||||||
|
return document.querySelector(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getValue(element) {
|
||||||
|
return get(element).value;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setHtml(element, innerHtml) {
|
||||||
|
return get(element).innerHTML=innerHtml;
|
||||||
|
}
|
||||||
BIN
public/lang-logo.png
Normal file
BIN
public/lang-logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.2 KiB |
17
public/node.svg
Normal file
17
public/node.svg
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve">
|
||||||
|
<path fill="#8CC84B" d="M255.5,495.4c-6.4,0-12.8-1.7-18.4-4.9l-58.5-34.6c-8.7-4.9-4.5-6.6-1.6-7.6c11.7-4,14-5,26.5-12
|
||||||
|
c1.3-0.7,3-0.5,4.4,0.3l45,26.7c1.6,0.9,3.9,0.9,5.4,0L433.6,362c1.6-0.9,2.7-2.8,2.7-4.7V154.9c0-2-1-3.8-2.7-4.8L258.3,49
|
||||||
|
c-1.6-0.9-3.8-0.9-5.4,0L77.7,150.1c-1.7,1-2.8,2.9-2.8,4.8v202.3c0,1.9,1.1,3.8,2.8,4.7l48,27.7c26.1,13,42-2.3,42-17.7V172.2
|
||||||
|
c0-2.8,2.3-5.1,5.1-5.1H195c2.8,0,5.1,2.2,5.1,5.1V372c0,34.8-18.9,54.7-51.9,54.7c-10.1,0-18.1,0-40.4-11l-46-26.5
|
||||||
|
c-11.4-6.6-18.4-18.8-18.4-32V154.9c0-13.1,7-25.4,18.4-32L237.1,21.7c11.1-6.3,25.8-6.3,36.8,0L449.3,123
|
||||||
|
c11.4,6.6,18.4,18.8,18.4,32v202.3c0,13.1-7.1,25.4-18.4,32L274,490.5C268.4,493.7,262,495.4,255.5,495.4z"/>
|
||||||
|
<path fill="#8CC84B" d="M309.7,356c-76.7,0-92.8-35.2-92.8-64.8c0-2.8,2.3-5.1,5.1-5.1h22.7c2.5,0,4.6,1.8,5,4.3
|
||||||
|
c3.4,23.1,13.6,34.7,60,34.7c36.9,0,52.7-8.4,52.7-28c0-11.3-4.5-19.7-61.9-25.3c-48-4.7-77.6-15.3-77.6-53.7
|
||||||
|
c0-35.4,29.8-56.5,79.8-56.5c56.2,0,84,19.5,87.5,61.3c0.1,1.4-0.4,2.8-1.3,3.9c-1,1-2.3,1.6-3.7,1.6h-22.8c-2.4,0-4.4-1.7-4.9-4
|
||||||
|
c-5.5-24.3-18.7-32-54.8-32c-40.3,0-45,14-45,24.6c0,12.8,5.5,16.5,60,23.7c53.9,7.1,79.5,17.2,79.5,55.1
|
||||||
|
C397.1,334.1,365.3,356,309.7,356z"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.6 KiB |
40
public/stylesheets/stoplicht.css
Normal file
40
public/stylesheets/stoplicht.css
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
body{
|
||||||
|
font-family: Arial;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1{
|
||||||
|
font-size: 80px;
|
||||||
|
}
|
||||||
|
.signin{
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
button{
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emotions{
|
||||||
|
text-align: center;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
button{
|
||||||
|
background: white;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="text"] {
|
||||||
|
font-size:24px;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="password"] {
|
||||||
|
font-size:24px;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error{
|
||||||
|
font-size: 24px;
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
23
views/pages/db.ejs
Normal file
23
views/pages/db.ejs
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<% include ../partials/header.ejs %>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<% include ../partials/nav.ejs %>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<h2>Database Results</h2>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<% results.forEach(function(r) { %>
|
||||||
|
<li><%= r.id %> - <%= r.name %></li>
|
||||||
|
<% }); %>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
13
views/pages/error.ejs
Normal file
13
views/pages/error.ejs
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<% include ../partials/header.ejs %>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<form id="emotionsForm" method="POST" action="/submit-form">
|
||||||
|
<% include ../partials/signin.ejs %>
|
||||||
|
<p id="errorMessage" class="error">Vul je naam/wachtwoord in</p>
|
||||||
|
<% include ../partials/body.ejs %>
|
||||||
|
</form>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
12
views/pages/index.ejs
Normal file
12
views/pages/index.ejs
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<% include ../partials/header.ejs %>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<form id="emotionsForm" method="POST" action="/submit-form">
|
||||||
|
<% include ../partials/signin.ejs %>
|
||||||
|
<% include ../partials/body.ejs %>
|
||||||
|
</form>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
9
views/pages/thanks.ejs
Normal file
9
views/pages/thanks.ejs
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<% include ../partials/header.ejs %>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Dankje!</h1>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
13
views/partials/body.ejs
Normal file
13
views/partials/body.ejs
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
<div class="emotions">
|
||||||
|
<h1>Wat is je gevoel vandaag?</h1>
|
||||||
|
<input type="hidden" id="emotion" name="emotion">
|
||||||
|
<input type="hidden" id="timestamp" name="timestamp">
|
||||||
|
<button id="happy"><img src="img/grinning-face-with-smiling-eyes.png" title="Blij!"></button>
|
||||||
|
<button id="unsure"><img src="img/neutral-face.png" title="Neutraal"></button>
|
||||||
|
<button id="sad"><img src="img/disappointed-face.png" title="Niet blij!"></button>
|
||||||
|
<p>Vul je naam en wachtwoord in en kies een emoji</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<script type="text/javascript" src="js/stoplicht.js"></script>
|
||||||
|
|
||||||
2
views/partials/header.ejs
Normal file
2
views/partials/header.ejs
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
<link rel="stylesheet" type="text/css" href="/stylesheets/stoplicht.css" />
|
||||||
|
<title>Bisons stoplicht</title>
|
||||||
33
views/partials/nav.ejs
Normal file
33
views/partials/nav.ejs
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
<nav class="navbar navbar-default navbar-static-top navbar-inverse">
|
||||||
|
<div class="container">
|
||||||
|
<ul class="nav navbar-nav">
|
||||||
|
<li class="active">
|
||||||
|
<a href="/"><span class="glyphicon glyphicon-home"></span> Home</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://devcenter.heroku.com/articles/how-heroku-works"><span class="glyphicon glyphicon-user"></span> How Heroku Works</a>
|
||||||
|
</li>
|
||||||
|
<li class="dropdown">
|
||||||
|
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"><span class="glyphicon glyphicon-info-sign"></span> Getting Started Guides <span class="caret"></span></a>
|
||||||
|
<ul class="dropdown-menu" role="menu">
|
||||||
|
<li><a href="https://devcenter.heroku.com/articles/getting-started-with-ruby">Getting Started with Ruby on Heroku</a></li>
|
||||||
|
<li><a href="https://devcenter.heroku.com/articles/getting-started-with-nodejs">Getting Started with Node on Heroku</a></li>
|
||||||
|
<li><a href="https://devcenter.heroku.com/articles/getting-started-with-php">Getting Started with PHP on Heroku</a></li>
|
||||||
|
<li><a href="https://devcenter.heroku.com/articles/getting-started-with-python">Getting Started with Python on Heroku</a></li>
|
||||||
|
<li><a href="https://devcenter.heroku.com/articles/getting-started-with-java">Getting Started with Java on Heroku</a></li>
|
||||||
|
<li><a href="https://devcenter.heroku.com/articles/getting-started-with-go">Getting Started with Go on Heroku</a></li>
|
||||||
|
<li><a href="https://devcenter.heroku.com/articles/getting-started-with-clojure">Getting Started with Clojure on Heroku</a></li>
|
||||||
|
<li><a href="https://devcenter.heroku.com/articles/getting-started-with-scala">Getting Started with Scala on Heroku</a></li>
|
||||||
|
<li class="divider"></li>
|
||||||
|
<li><a href="https://devcenter.heroku.com/articles/getting-started-with-heroku-and-connect-without-local-dev">Getting Started on Heroku with Heroku Connect</a></li>
|
||||||
|
<li><a href="https://devcenter.heroku.com/articles/getting-started-with-jruby">Getting Started with Ruby on Heroku (Microsoft Windows)</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul class="nav navbar-nav navbar-right">
|
||||||
|
<li class="navbar-right">
|
||||||
|
<a href="https://devcenter.heroku.com"><span class="glyphicon glyphicon-book"></span> Heroku Dev Center</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
4
views/partials/signin.ejs
Normal file
4
views/partials/signin.ejs
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
<div class="signin">
|
||||||
|
<h2>Naam: <input id="username" name="username" type="text" autofocus></h2>
|
||||||
|
<h2>Wachtwoord: <input id="password" name="password" type="password"></h2>
|
||||||
|
</div>
|
||||||
Loading…
Add table
Reference in a new issue