node authentication

This commit is contained in:
azivner 2017-10-15 16:32:49 -04:00
parent cc3a621324
commit 649dc0fbbb
18 changed files with 126 additions and 26 deletions

View File

@ -4,9 +4,15 @@ const favicon = require('serve-favicon');
const logger = require('morgan');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
const helmet = require('helmet');
const session = require('express-session');
const appRoute = require('./routes/app');
const usersRoute = require('./routes/users');
const loginRoute = require('./routes/login');
const logoutRoute = require('./routes/logout');
const migrationRoute = require('./routes/migration');
// API routes
const treeRoute = require('./routes/tree');
const notesRoute = require('./routes/notes');
const notesMoveRoute = require('./routes/notes_move');
@ -28,16 +34,30 @@ const app = express();
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(helmet());
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, '../static')));
app.use(session({
secret: "sdhkjhdsklajf", // FIXME: need to use the DB one
resave: false, // true forces the session to be saved back to the session store, even if the session was never modified during the request.
saveUninitialized: false, // true forces a session that is "uninitialized" to be saved to the store. A session is uninitialized when it is new but not modified.
cookie: {
// path: "/",
httpOnly: true,
maxAge: 1800000
}
}));
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use('/app', appRoute);
app.use('/users', usersRoute);
app.use('/login', loginRoute);
app.use('/logout', logoutRoute);
app.use('/migration', migrationRoute);
app.use('/api/tree', treeRoute);
app.use('/api/notes', notesRoute);
app.use('/api/notes', notesMoveRoute);

20
node/auth.js Normal file
View File

@ -0,0 +1,20 @@
function checkAuth(req, res, next) {
if (!req.session.loggedIn) {
res.redirect("login");
} else {
next();
}
}
function checkApiAuth(req, res, next) {
if (!req.session.loggedIn) {
res.sendStatus(401);
} else {
next();
}
}
module.exports = {
checkAuth,
checkApiAuth
};

View File

@ -11,7 +11,10 @@
"debug": "~3.1.0",
"ejs": "~2.5.7",
"express": "~4.16.2",
"express-session": "^1.15.6",
"express-sessions": "^1.0.6",
"fs-extra": "^4.0.2",
"helmet": "^3.9.0",
"ini": "^1.3.4",
"morgan": "~1.9.0",
"scrypt": "^6.0.3",

View File

@ -1,7 +1,8 @@
const express = require('express');
const router = express.Router();
const auth = require('../auth');
router.get('', function(req, res, next) {
router.get('', auth.checkAuth, (req, res, next) => {
res.render('app', {});
});

View File

@ -1,8 +1,9 @@
const express = require('express');
const router = express.Router();
const sql = require('../sql');
const auth = require('../auth');
router.get('/:full_load_time', async (req, res, next) => {
router.get('/:full_load_time', auth.checkApiAuth, async (req, res, next) => {
const fullLoadTime = req.params.full_load_time;
const browserId = req.get('x-browser-id');

37
node/routes/login.js Normal file
View File

@ -0,0 +1,37 @@
const express = require('express');
const router = express.Router();
const utils = require('../utils');
const sql = require('../sql');
const my_scrypt = require('../my_scrypt');
router.get('', (req, res, next) => {
res.render('login', { 'failedAuth': false });
});
router.post('', async (req, res, next) => {
const userName = await sql.getOption('username');
const guessedPassword = req.body.password;
if (req.body.username === userName && await verifyPassword(guessedPassword)) {
const rememberMe = req.body.rememberme;
req.session.loggedIn = true;
return res.redirect('app');
}
else {
res.render('login', {'failedAuth': true});
}
});
async function verifyPassword(guessed_password) {
const hashed_password = utils.fromBase64(await sql.getOption('password_verification_hash'));
const guess_hashed = await my_scrypt.getVerificationHash(guessed_password);
return guess_hashed.equals(hashed_password);
}
module.exports = router;

10
node/routes/logout.js Normal file
View File

@ -0,0 +1,10 @@
const express = require('express');
const router = express.Router();
router.post('', async (req, res, next) => {
req.session.loggedIn = false;
res.redirect('login');
});
module.exports = router;

9
node/routes/migration.js Normal file
View File

@ -0,0 +1,9 @@
const express = require('express');
const router = express.Router();
const auth = require('../auth');
router.get('', auth.checkAuth, (req, res, next) => {
res.render('migration', {});
});
module.exports = router;

View File

@ -1,8 +1,9 @@
const express = require('express');
const router = express.Router();
const sql = require('../sql');
const auth = require('../auth');
router.get('/:noteId', async (req, res, next) => {
router.get('/:noteId', auth.checkApiAuth, async (req, res, next) => {
const noteId = req.params.noteId;
const history = await sql.getResults("select * from notes_history where note_id = ? order by date_modified desc", [noteId]);

View File

@ -3,8 +3,9 @@ const router = express.Router();
const sql = require('../sql');
const utils = require('../utils');
const audit_category = require('../audit_category');
const auth = require('../auth');
router.get('/:noteId', async (req, res, next) => {
router.get('/:noteId', auth.checkApiAuth, async (req, res, next) => {
let noteId = req.params.noteId;
await sql.execute("update options set opt_value = ? where opt_name = 'start_node'", [noteId]);

View File

@ -3,8 +3,9 @@ const router = express.Router();
const sql = require('../sql');
const utils = require('../utils');
const audit_category = require('../audit_category');
const auth = require('../auth');
router.put('/:noteId/moveTo/:parentId', async (req, res, next) => {
router.put('/:noteId/moveTo/:parentId', auth.checkApiAuth, async (req, res, next) => {
let noteId = req.params.noteId;
let parentId = req.params.parentId;

View File

@ -2,8 +2,9 @@ const express = require('express');
const router = express.Router();
const sql = require('../sql');
const changePassword = require('../change_password');
const auth = require('../auth');
router.post('/change', async (req, res, next) => {
router.post('/change', auth.checkApiAuth, async (req, res, next) => {
const result = await changePassword.changePassword(req.body['current_password'], req.body['new_password']);
res.send(result);

View File

@ -1,8 +1,9 @@
const express = require('express');
const router = express.Router();
const sql = require('../sql');
const auth = require('../auth');
router.get('/', async (req, res, next) => {
router.get('/', auth.checkApiAuth, async (req, res, next) => {
const recentChanges = await sql.getResults("select * from notes_history order by date_modified desc limit 1000");
res.send(recentChanges);

View File

@ -2,10 +2,11 @@ const express = require('express');
const router = express.Router();
const sql = require('../sql');
const audit_category = require('../audit_category');
const auth = require('../auth');
const ALLOWED_OPTIONS = ['encryption_session_timeout', 'history_snapshot_time_interval'];
router.get('/', async (req, res, next) => {
router.get('/', auth.checkApiAuth, async (req, res, next) => {
const dict = {};
const settings = await sql.getResults("SELECT opt_name, opt_value FROM options WHERE opt_name IN ("

View File

@ -3,8 +3,9 @@ const router = express.Router();
const sql = require('../sql');
const utils = require('../utils');
const backup = require('../backup');
const auth = require('../auth');
router.get('/', async (req, res, next) => {
router.get('/', auth.checkApiAuth, async (req, res, next) => {
await backup.regularBackup();
const notes = await sql.getResults("select "

View File

@ -1,8 +0,0 @@
const express = require('express');
const router = express.Router();
router.get('/', function(req, res, next) {
res.send('respond with a resource');
});
module.exports = router;

View File

@ -10,11 +10,11 @@
<div class="col-md-4 col-md-offset-4">
<h1>Trilium login</h1>
{% if failedAuth %}
<% if (failedAuth) { %>
<div class="alert alert-warning">
Username and / or password are incorrect. Please try again.
</div>
{% endif %}
<% } %>
<form action="login" method="POST">
<div class="form-group">
@ -44,7 +44,7 @@
</div>
</div>
<link href="stat/lib/bootstrap/css/bootstrap.css" rel="stylesheet">
<script src="stat/lib/bootstrap/js/bootstrap.js"></script>
<link href="lib/bootstrap/css/bootstrap.css" rel="stylesheet">
<script src="lib/bootstrap/js/bootstrap.js"></script>
</body>
</html>

View File

@ -32,7 +32,7 @@
<div class="form-group">
<div class="checkbox">
<label>
<input id="remember-me" name="remember-me" value="1" type="checkbox"> Remember me
<input id="remember-me" name="rememberme" value="1" type="checkbox"> Remember me
</label>
</div>
</div>