Added new note type
Better authentication
This commit is contained in:
parent
9e172ef598
commit
a4ebf90586
File diff suppressed because one or more lines are too long
2
dist/index.html
vendored
2
dist/index.html
vendored
@ -1 +1 @@
|
||||
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1"><link rel=icon href=/favicon.ico><title>Menus</title><link href=/css/app.65ce66e5.css rel=preload as=style><link href=/js/app.a4f9d1d7.js rel=preload as=script><link href=/js/chunk-vendors.979cbe79.js rel=preload as=script><link href=/css/app.65ce66e5.css rel=stylesheet></head><body><noscript><strong>We're sorry but vue_menu doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id=app></div><script src=/js/chunk-vendors.979cbe79.js></script><script src=/js/app.a4f9d1d7.js></script></body></html>
|
||||
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1"><link rel=icon href=/favicon.ico><title>Menus</title><link href=/css/app.5fa0b293.css rel=preload as=style><link href=/js/app.53dc46ec.js rel=preload as=script><link href=/js/chunk-vendors.979cbe79.js rel=preload as=script><link href=/css/app.5fa0b293.css rel=stylesheet></head><body><noscript><strong>We're sorry but vue_menu doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id=app></div><script src=/js/chunk-vendors.979cbe79.js></script><script src=/js/app.53dc46ec.js></script></body></html>
|
2
dist/js/app.53dc46ec.js
vendored
Normal file
2
dist/js/app.53dc46ec.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/js/app.53dc46ec.js.map
vendored
Normal file
1
dist/js/app.53dc46ec.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
2
dist/js/app.a4f9d1d7.js
vendored
2
dist/js/app.a4f9d1d7.js
vendored
File diff suppressed because one or more lines are too long
1
dist/js/app.a4f9d1d7.js.map
vendored
1
dist/js/app.a4f9d1d7.js.map
vendored
File diff suppressed because one or more lines are too long
@ -30,7 +30,8 @@ body {
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin: -150px 0 0 -150px;
|
||||
width:300px;
|
||||
min-width: 300px;
|
||||
width:0.5vw;
|
||||
height:300px;
|
||||
}
|
||||
.login h1 { color: #fff; text-shadow: 0 0 10px rgba(0,0,0,0.3); letter-spacing:1px; text-align:center; }
|
||||
@ -42,7 +43,7 @@ input {
|
||||
border: none;
|
||||
outline: none;
|
||||
padding: 10px;
|
||||
font-size: 13px;
|
||||
font-size: 1rem;
|
||||
color: #fff;
|
||||
text-shadow: 1px 1px 1px rgba(0,0,0,0.3);
|
||||
border: 1px solid rgba(0,0,0,0.3);
|
||||
|
@ -2,6 +2,8 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv=X-UA-Compatible content="IE=edge">
|
||||
<meta name=viewport content="width=device-width,initial-scale=1">
|
||||
<title>Login</title>
|
||||
<link href="/css/login.css" rel="stylesheet" type="text/css"/>
|
||||
</head>
|
||||
|
1119
package-lock.json
generated
1119
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -13,6 +13,7 @@
|
||||
"backbone": "^1.4.0",
|
||||
"body-parser": "^1.19.0",
|
||||
"cors": "^2.8.5",
|
||||
"dateformat": "^3.0.3",
|
||||
"dotenv": "^8.2.0",
|
||||
"express": "^4.17.1",
|
||||
"express-session": "^1.17.0",
|
||||
@ -21,10 +22,16 @@
|
||||
"lodash": "^4.17.15",
|
||||
"markdown": "^0.5.0",
|
||||
"minibus": "^3.1.0",
|
||||
"node-cron": "^2.0.3",
|
||||
"nosql": "^6.1.0",
|
||||
"pug": "^2.0.4",
|
||||
"schema-check": "0.0.7",
|
||||
"short-hash": "^1.0.0",
|
||||
"sqlite3": "^4.1.1"
|
||||
"smtp-email-sender": "^1.0.0",
|
||||
"sqlite3": "^4.1.1",
|
||||
"tape": "^4.13.2",
|
||||
"tape-promise": "^4.0.0",
|
||||
"ultrases": "^0.1.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"browserify": "^16.5.0",
|
||||
|
10
pug/email.jade
Normal file
10
pug/email.jade
Normal file
@ -0,0 +1,10 @@
|
||||
html(lang="en")
|
||||
head
|
||||
meta(charset='utf-8')
|
||||
title
|
||||
Suggestions
|
||||
body
|
||||
h1 Suggestions for !{ts}
|
||||
ol
|
||||
each item in suggestions
|
||||
li: a(href=item.url)= item.name
|
10
pug/email.pug
Normal file
10
pug/email.pug
Normal file
@ -0,0 +1,10 @@
|
||||
html(lang="en")
|
||||
head
|
||||
meta(charset='utf-8')
|
||||
title
|
||||
Suggestions
|
||||
body
|
||||
h1 Suggestions for !{ts}
|
||||
ol
|
||||
each item in suggestions
|
||||
li: a(href=item.url)= item.name
|
34
server.js
34
server.js
@ -1,3 +1,4 @@
|
||||
require('dotenv').config();
|
||||
const express = require('express');
|
||||
const bodyParser = require('body-parser');
|
||||
const session = require('express-session');
|
||||
@ -7,6 +8,9 @@ const cors = require('cors');
|
||||
|
||||
const db = require('./server/lib/loginmanager');
|
||||
|
||||
const doJob = require('./server/lib/job');
|
||||
const checkAuth = require('./server/middle/checkAuth');
|
||||
|
||||
// create express app
|
||||
const app = express();
|
||||
require('dotenv').config();
|
||||
@ -24,12 +28,17 @@ app.use(session({
|
||||
'saveUninitialized': true
|
||||
}));
|
||||
|
||||
app.get('/', function(request, response) {
|
||||
if (request.session.loggedin !== true)
|
||||
response.sendFile(path.join(`${__dirname }/server/static/login.html`));
|
||||
else
|
||||
response.redirect('/recipes.html');
|
||||
app.get('/', (request, response) => {
|
||||
if (request.session.auth)
|
||||
response.redirect('/menu');
|
||||
else
|
||||
response.sendFile(path.join(`${__dirname}/server/static/login.html`));
|
||||
});
|
||||
|
||||
app.get('/menu', checkAuth, (req, res) => {
|
||||
res.sendFile(path.join(`${__dirname }/dist/index.html`));
|
||||
});
|
||||
|
||||
app.use(express.static(path.join(__dirname, sitePath)));
|
||||
|
||||
// parse requests of content-type - application/x-www-form-urlencoded
|
||||
@ -38,7 +47,7 @@ app.use(bodyParser.urlencoded({ 'extended': true }));
|
||||
// parse requests of content-type - application/json
|
||||
app.use(bodyParser.json());
|
||||
|
||||
app.post('/auth', function(request, response) {
|
||||
app.post('/auth', (request, response) => {
|
||||
const username = request.body.u;
|
||||
const password = request.body.p;
|
||||
|
||||
@ -47,12 +56,12 @@ app.post('/auth', function(request, response) {
|
||||
db.getOne(username, password)
|
||||
.then((data) => {
|
||||
if (!data)
|
||||
response.send('Incorrect Username and/or Password!');
|
||||
|
||||
// response.send('Incorrect Username and/or Password!');
|
||||
response.redirect('/');
|
||||
else {
|
||||
request.session.loggedin = true;
|
||||
request.session.username = username;
|
||||
response.redirect('/recipes.html');
|
||||
request.session.auth = 'jhgkjgkjhgkjhgjkhgjkhgfhghfjgfjhgf';
|
||||
response.redirect('/menu');
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
@ -75,3 +84,8 @@ require('./server/routes/view.routes')(app);
|
||||
app.listen(serverPort, () => {
|
||||
console.log(`Server is listening on port ${serverPort}`);
|
||||
});
|
||||
|
||||
((() => {
|
||||
console.log('Menuizer started');
|
||||
// doJob();
|
||||
})());
|
||||
|
39
server/lib/FoodObj.js
Normal file
39
server/lib/FoodObj.js
Normal file
@ -0,0 +1,39 @@
|
||||
class FoodObj {
|
||||
|
||||
constructor(limit) {
|
||||
this.limit = limit;
|
||||
this.store = [];
|
||||
this.types = [0, 0, 0, 0, 0, 0, 0];
|
||||
}
|
||||
|
||||
get () {
|
||||
return this.store;
|
||||
}
|
||||
|
||||
getFirstFive() {
|
||||
return (this.store.slice(0, 5));
|
||||
}
|
||||
|
||||
getFirstFiveIDs() {
|
||||
const outVal = this.store.slice(0, 5).map((item) => {
|
||||
return item._id;
|
||||
});
|
||||
|
||||
return (outVal);
|
||||
}
|
||||
|
||||
add(item) {
|
||||
// console.log('>>', item);
|
||||
item.url = `https://menu.silvrtree.co.uk/view/${item.short}`;
|
||||
if (this.types[item.meat] < this.limit) {
|
||||
this.store.push(item);
|
||||
this.types[item.meat]++;
|
||||
}
|
||||
}
|
||||
|
||||
count() {
|
||||
return (this.store.slice(0, 5).length);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = FoodObj;
|
@ -106,3 +106,50 @@ exports.updateOne = (data) => {
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
exports.getRandom = (timestamp) => {
|
||||
const sql = 'SELECT _id, short, hash, name, meat, mealtype FROM menu where mealtype =1 and lastused<? order by RANDOM()';
|
||||
|
||||
const sqlTimestamp = ~~(timestamp / 1000);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
db.all(sql, [sqlTimestamp], (err, rows) => {
|
||||
if (err)
|
||||
reject(err);
|
||||
|
||||
if (!err) {
|
||||
const outgoing = [...rows];
|
||||
|
||||
resolve(outgoing) ;
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
exports.updateTimestamps = (newTimestamp, items) => {
|
||||
const sqlTimestamp = ~~(newTimestamp / 1000);
|
||||
|
||||
console.log('>> items', items);
|
||||
|
||||
const sql = 'UPDATE menu SET lastused = $lastused WHERE _id = $in';
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
db.serialize(() => {
|
||||
const stmt = db.prepare(sql);
|
||||
|
||||
items.forEach((item) => {
|
||||
console.log(item);
|
||||
const newData = { '$lastused':sqlTimestamp, '$in':item };
|
||||
|
||||
stmt.run(newData);
|
||||
});
|
||||
|
||||
stmt.finalize((err) => {
|
||||
if (err)
|
||||
reject(err);
|
||||
|
||||
resolve({ 'msg':'Row updateds' });
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
61
server/lib/job.js
Normal file
61
server/lib/job.js
Normal file
@ -0,0 +1,61 @@
|
||||
const dbmanager = require('./dbmanager');
|
||||
const FoodObj = require('./FoodObj');
|
||||
|
||||
const pug = require('pug');
|
||||
const dateFormat = require('dateformat');
|
||||
|
||||
const email = require('smtp-email-sender')({
|
||||
'host': 'mail.caliban.io',
|
||||
'port': '465',
|
||||
'auth': {
|
||||
'user': 'aida@caliban.io',
|
||||
'pass': 'WaF#E+5am7.)\\csD',
|
||||
'type': 'LOGIN' // PLAIN, LOGIN, MD5 etc...
|
||||
},
|
||||
'secure': 'secure'
|
||||
});
|
||||
|
||||
function sendSMTP(data, newPath) {
|
||||
const now = new Date();
|
||||
|
||||
const html = pug.renderFile(`${newPath}/` + 'pug/email.pug', data);
|
||||
email({
|
||||
'from': 'Aida <aida@caliban.io>',
|
||||
'to': 'Aida <aida@caliban.io>',
|
||||
// 'bcc': 'Martin <martind2000@gmail.com>, Jessica <ing.arvid@gmail.com>',
|
||||
'bcc': 'Martin <martind2000@gmail.com>',
|
||||
'subject': `Suggestions 🍽️ - ${dateFormat(now, 'dddd, mmmm dS, yyyy')}`,
|
||||
'html': html
|
||||
});
|
||||
}
|
||||
|
||||
function pugTest(data, newpath) {
|
||||
console.log(pug.renderFile(`${newpath}/` + 'pug/email.pug', data));
|
||||
}
|
||||
|
||||
async function doJob() {
|
||||
console.log('Doing job...');
|
||||
const now = new Date();
|
||||
const currentTS = ~~(now.getTime() / 86400000) * 86400000;
|
||||
const pastTS = currentTS - (86400000 * 28);
|
||||
|
||||
const fo = new FoodObj(2);
|
||||
|
||||
await dbmanager.getRandom(pastTS).then((r) => {
|
||||
// console.log(r);
|
||||
|
||||
for(const item of r)
|
||||
fo.add(item);
|
||||
});
|
||||
|
||||
if (fo.count() === 5) {
|
||||
sendSMTP({ 'suggestions':fo.getFirstFive() }, './');
|
||||
await dbmanager.updateTimestamps(currentTS, fo.getFirstFiveIDs()).then((r) => {
|
||||
console.log(r);
|
||||
});
|
||||
} else {
|
||||
console.log(`Not enough items, only got ${fo.count()}`);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = doJob;
|
15
server/middle/checkAuth.js
Normal file
15
server/middle/checkAuth.js
Normal file
@ -0,0 +1,15 @@
|
||||
function checkAuth(req, res, next) {
|
||||
if (!req.session.auth)
|
||||
// res.send('You are not authorized to view this page');
|
||||
res.redirect('/');
|
||||
else {
|
||||
res.header('Cache-Control', 'no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0');
|
||||
next();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = checkAuth;
|
||||
|
||||
// https://stackoverflow.com/questions/7990890/how-to-implement-login-auth-in-node-js
|
||||
|
||||
// look aT JWT BIT AT BOTTOM
|
@ -2,6 +2,8 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv=X-UA-Compatible content="IE=edge">
|
||||
<meta name=viewport content="width=device-width,initial-scale=1">
|
||||
<title>Login</title>
|
||||
<style>
|
||||
@import url(https://fonts.googleapis.com/css?family=Open+Sans);
|
||||
@ -32,12 +34,13 @@
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#3E1D6D', endColorstr='#092756',GradientType=1 );
|
||||
}
|
||||
.login {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin: -150px 0 0 -150px;
|
||||
width:300px;
|
||||
height:300px;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin: -150px 0 0 -150px;
|
||||
min-width: 300px;
|
||||
width:300px;
|
||||
height:300px;
|
||||
}
|
||||
.login h1 { color: #fff; text-shadow: 0 0 10px rgba(0,0,0,0.3); letter-spacing:1px; text-align:center; }
|
||||
|
||||
|
35
tests/db.js
Normal file
35
tests/db.js
Normal file
@ -0,0 +1,35 @@
|
||||
const tape = require('tape');
|
||||
const _test = require('tape-promise').default; // <---- notice 'default'
|
||||
const test = _test(tape); // decorate tape
|
||||
|
||||
const dbmanager = require('../server/lib/dbmanager');
|
||||
const FoodObj = require('../server/lib/FoodObj');
|
||||
|
||||
test('DB tests', async function(t) {
|
||||
const now = new Date();
|
||||
const currentTS = ~~(now.getTime() / 86400000) * 86400000;
|
||||
const pastTS = currentTS - (86400000 * 28);
|
||||
|
||||
console.log(currentTS);
|
||||
|
||||
const fo = new FoodObj(2);
|
||||
|
||||
await dbmanager.getRandom(pastTS).then((r) => {
|
||||
// console.log(r);
|
||||
|
||||
for(const item of r)
|
||||
fo.add(item);
|
||||
|
||||
console.log(fo.getFirstFive());
|
||||
|
||||
console.log(fo.getFirstFiveIDs());
|
||||
});
|
||||
|
||||
await dbmanager.updateTimestamps(currentTS, fo.getFirstFiveIDs()).then((r) => {
|
||||
console.log(r);
|
||||
});
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
// 1209600000
|
Loading…
Reference in New Issue
Block a user