mirror of
				https://github.com/zadam/trilium.git
				synced 2025-11-03 11:56:01 +01:00 
			
		
		
		
	node authentication
This commit is contained in:
		
							
								
								
									
										28
									
								
								node/app.js
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								node/app.js
									
									
									
									
									
								
							@@ -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
									
								
							
							
						
						
									
										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",
 | 
			
		||||
    "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",
 | 
			
		||||
 
 | 
			
		||||
@@ -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', {});
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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
									
								
							
							
						
						
									
										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 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]);
 | 
			
		||||
 
 | 
			
		||||
@@ -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]);
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
@@ -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 ("
 | 
			
		||||
 
 | 
			
		||||
@@ -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 "
 | 
			
		||||
 
 | 
			
		||||
@@ -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">
 | 
			
		||||
                <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>
 | 
			
		||||
@@ -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>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user