mirror of
https://github.com/zadam/trilium.git
synced 2025-06-06 18:08:33 +02:00
node authentication
This commit is contained in:
parent
cc3a621324
commit
649dc0fbbb
28
node/app.js
28
node/app.js
@ -4,9 +4,15 @@ const favicon = require('serve-favicon');
|
|||||||
const logger = require('morgan');
|
const logger = require('morgan');
|
||||||
const cookieParser = require('cookie-parser');
|
const cookieParser = require('cookie-parser');
|
||||||
const bodyParser = require('body-parser');
|
const bodyParser = require('body-parser');
|
||||||
|
const helmet = require('helmet');
|
||||||
|
const session = require('express-session');
|
||||||
|
|
||||||
const appRoute = require('./routes/app');
|
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 treeRoute = require('./routes/tree');
|
||||||
const notesRoute = require('./routes/notes');
|
const notesRoute = require('./routes/notes');
|
||||||
const notesMoveRoute = require('./routes/notes_move');
|
const notesMoveRoute = require('./routes/notes_move');
|
||||||
@ -28,16 +34,30 @@ const app = express();
|
|||||||
app.set('views', path.join(__dirname, 'views'));
|
app.set('views', path.join(__dirname, 'views'));
|
||||||
app.set('view engine', 'ejs');
|
app.set('view engine', 'ejs');
|
||||||
|
|
||||||
// uncomment after placing your favicon in /public
|
app.use(helmet());
|
||||||
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
|
|
||||||
app.use(logger('dev'));
|
app.use(logger('dev'));
|
||||||
app.use(bodyParser.json());
|
app.use(bodyParser.json());
|
||||||
app.use(bodyParser.urlencoded({extended: false}));
|
app.use(bodyParser.urlencoded({extended: false}));
|
||||||
app.use(cookieParser());
|
app.use(cookieParser());
|
||||||
app.use(express.static(path.join(__dirname, '../static')));
|
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('/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/tree', treeRoute);
|
||||||
app.use('/api/notes', notesRoute);
|
app.use('/api/notes', notesRoute);
|
||||||
app.use('/api/notes', notesMoveRoute);
|
app.use('/api/notes', notesMoveRoute);
|
||||||
|
20
node/auth.js
Normal file
20
node/auth.js
Normal 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
|
||||||
|
};
|
@ -11,7 +11,10 @@
|
|||||||
"debug": "~3.1.0",
|
"debug": "~3.1.0",
|
||||||
"ejs": "~2.5.7",
|
"ejs": "~2.5.7",
|
||||||
"express": "~4.16.2",
|
"express": "~4.16.2",
|
||||||
|
"express-session": "^1.15.6",
|
||||||
|
"express-sessions": "^1.0.6",
|
||||||
"fs-extra": "^4.0.2",
|
"fs-extra": "^4.0.2",
|
||||||
|
"helmet": "^3.9.0",
|
||||||
"ini": "^1.3.4",
|
"ini": "^1.3.4",
|
||||||
"morgan": "~1.9.0",
|
"morgan": "~1.9.0",
|
||||||
"scrypt": "^6.0.3",
|
"scrypt": "^6.0.3",
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
const auth = require('../auth');
|
||||||
|
|
||||||
router.get('', function(req, res, next) {
|
router.get('', auth.checkAuth, (req, res, next) => {
|
||||||
res.render('app', {});
|
res.render('app', {});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
const sql = require('../sql');
|
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 fullLoadTime = req.params.full_load_time;
|
||||||
|
|
||||||
const browserId = req.get('x-browser-id');
|
const browserId = req.get('x-browser-id');
|
||||||
|
37
node/routes/login.js
Normal file
37
node/routes/login.js
Normal 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
10
node/routes/logout.js
Normal 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
9
node/routes/migration.js
Normal 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;
|
@ -1,8 +1,9 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
const sql = require('../sql');
|
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 noteId = req.params.noteId;
|
||||||
|
|
||||||
const history = await sql.getResults("select * from notes_history where note_id = ? order by date_modified desc", [noteId]);
|
const history = await sql.getResults("select * from notes_history where note_id = ? order by date_modified desc", [noteId]);
|
||||||
|
@ -3,8 +3,9 @@ const router = express.Router();
|
|||||||
const sql = require('../sql');
|
const sql = require('../sql');
|
||||||
const utils = require('../utils');
|
const utils = require('../utils');
|
||||||
const audit_category = require('../audit_category');
|
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;
|
let noteId = req.params.noteId;
|
||||||
|
|
||||||
await sql.execute("update options set opt_value = ? where opt_name = 'start_node'", [noteId]);
|
await sql.execute("update options set opt_value = ? where opt_name = 'start_node'", [noteId]);
|
||||||
|
@ -3,8 +3,9 @@ const router = express.Router();
|
|||||||
const sql = require('../sql');
|
const sql = require('../sql');
|
||||||
const utils = require('../utils');
|
const utils = require('../utils');
|
||||||
const audit_category = require('../audit_category');
|
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 noteId = req.params.noteId;
|
||||||
let parentId = req.params.parentId;
|
let parentId = req.params.parentId;
|
||||||
|
|
||||||
|
@ -2,8 +2,9 @@ const express = require('express');
|
|||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
const sql = require('../sql');
|
const sql = require('../sql');
|
||||||
const changePassword = require('../change_password');
|
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']);
|
const result = await changePassword.changePassword(req.body['current_password'], req.body['new_password']);
|
||||||
|
|
||||||
res.send(result);
|
res.send(result);
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
const sql = require('../sql');
|
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");
|
const recentChanges = await sql.getResults("select * from notes_history order by date_modified desc limit 1000");
|
||||||
|
|
||||||
res.send(recentChanges);
|
res.send(recentChanges);
|
||||||
|
@ -2,10 +2,11 @@ const express = require('express');
|
|||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
const sql = require('../sql');
|
const sql = require('../sql');
|
||||||
const audit_category = require('../audit_category');
|
const audit_category = require('../audit_category');
|
||||||
|
const auth = require('../auth');
|
||||||
|
|
||||||
const ALLOWED_OPTIONS = ['encryption_session_timeout', 'history_snapshot_time_interval'];
|
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 dict = {};
|
||||||
|
|
||||||
const settings = await sql.getResults("SELECT opt_name, opt_value FROM options WHERE opt_name IN ("
|
const settings = await sql.getResults("SELECT opt_name, opt_value FROM options WHERE opt_name IN ("
|
||||||
|
@ -3,8 +3,9 @@ const router = express.Router();
|
|||||||
const sql = require('../sql');
|
const sql = require('../sql');
|
||||||
const utils = require('../utils');
|
const utils = require('../utils');
|
||||||
const backup = require('../backup');
|
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();
|
await backup.regularBackup();
|
||||||
|
|
||||||
const notes = await sql.getResults("select "
|
const notes = await sql.getResults("select "
|
||||||
|
@ -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;
|
|
@ -10,11 +10,11 @@
|
|||||||
<div class="col-md-4 col-md-offset-4">
|
<div class="col-md-4 col-md-offset-4">
|
||||||
<h1>Trilium login</h1>
|
<h1>Trilium login</h1>
|
||||||
|
|
||||||
{% if failedAuth %}
|
<% if (failedAuth) { %>
|
||||||
<div class="alert alert-warning">
|
<div class="alert alert-warning">
|
||||||
Username and / or password are incorrect. Please try again.
|
Username and / or password are incorrect. Please try again.
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
<% } %>
|
||||||
|
|
||||||
<form action="login" method="POST">
|
<form action="login" method="POST">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
@ -44,7 +44,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<link href="stat/lib/bootstrap/css/bootstrap.css" rel="stylesheet">
|
<link href="lib/bootstrap/css/bootstrap.css" rel="stylesheet">
|
||||||
<script src="stat/lib/bootstrap/js/bootstrap.js"></script>
|
<script src="lib/bootstrap/js/bootstrap.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
@ -32,7 +32,7 @@
|
|||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="checkbox">
|
<div class="checkbox">
|
||||||
<label>
|
<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>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user