mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 10:26:08 +01:00 
			
		
		
		
	set password from web trilium
This commit is contained in:
		
							
								
								
									
										1
									
								
								db/migrations/0189__delete_username_option.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								db/migrations/0189__delete_username_option.sql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| DELETE FROM options WHERE name = 'username'; | ||||
| @@ -85,14 +85,10 @@ function logoutFromProtectedSession() { | ||||
| } | ||||
|  | ||||
| function token(req) { | ||||
|     const username = req.body.username; | ||||
|     const password = req.body.password; | ||||
|  | ||||
|     const isUsernameValid = username === optionService.getOption('username'); | ||||
|     const isPasswordValid = passwordEncryptionService.verifyPassword(password); | ||||
|  | ||||
|     if (!isUsernameValid || !isPasswordValid) { | ||||
|         return [401, "Incorrect username/password"]; | ||||
|     if (!passwordEncryptionService.verifyPassword(password)) { | ||||
|         return [401, "Incorrect password"]; | ||||
|     } | ||||
|  | ||||
|     const apiToken = new ApiToken({ | ||||
|   | ||||
| @@ -6,7 +6,6 @@ const searchService = require('../../services/search/services/search'); | ||||
|  | ||||
| // options allowed to be updated directly in options dialog | ||||
| const ALLOWED_OPTIONS = new Set([ | ||||
|     'username', // not exposed for update (not harmful anyway), needed for reading | ||||
|     'eraseEntitiesAfterTimeInSeconds', | ||||
|     'protectedSessionTimeout', | ||||
|     'noteRevisionSnapshotTimeInterval', | ||||
|   | ||||
| @@ -18,9 +18,9 @@ async function setupNewDocument() { | ||||
| } | ||||
|  | ||||
| function setupSyncFromServer(req) { | ||||
|     const { syncServerHost, syncProxy, username, password } = req.body; | ||||
|     const { syncServerHost, syncProxy, password } = req.body; | ||||
|  | ||||
|     return setupService.setupSyncFromSyncServer(syncServerHost, syncProxy, username, password); | ||||
|     return setupService.setupSyncFromSyncServer(syncServerHost, syncProxy, password); | ||||
| } | ||||
|  | ||||
| function saveSyncSeed(req) { | ||||
|   | ||||
| @@ -4,21 +4,48 @@ const utils = require('../services/utils'); | ||||
| const optionService = require('../services/options'); | ||||
| const myScryptService = require('../services/my_scrypt'); | ||||
| const log = require('../services/log'); | ||||
| const sqlInit = require("../services/sql_init.js"); | ||||
| const optionsInitService = require("../services/options_init.js"); | ||||
|  | ||||
| function loginPage(req, res) { | ||||
|     res.render('login', { failedAuth: false }); | ||||
| } | ||||
|  | ||||
| function setPasswordPage(req, res) { | ||||
|     res.render('set_password', { failed: false }); | ||||
|     res.render('set_password', { error: false }); | ||||
| } | ||||
|  | ||||
| function setPassword(req, res) { | ||||
|     if (sqlInit.isPasswordSet()) { | ||||
|         return [400, "Password has been already set"]; | ||||
|     } | ||||
|  | ||||
|     let {password1, password2} = req.body; | ||||
|     password1 = password1.trim(); | ||||
|     password2 = password2.trim(); | ||||
|  | ||||
|     let error; | ||||
|  | ||||
|     if (password1 !== password2) { | ||||
|         error = "Entered passwords don't match."; | ||||
|     } else if (password1.length < 4) { | ||||
|         error = "Password must be at least 4 characters long."; | ||||
|     } | ||||
|  | ||||
|     if (error) { | ||||
|         res.render('set_password', { error }); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     optionsInitService.initPassword(password1); | ||||
|  | ||||
|     res.redirect('login'); | ||||
| } | ||||
|  | ||||
| function login(req, res) { | ||||
|     const userName = optionService.getOption('username'); | ||||
|  | ||||
|     const guessedPassword = req.body.password; | ||||
|  | ||||
|     if (req.body.username === userName && verifyPassword(guessedPassword)) { | ||||
|     if (verifyPassword(guessedPassword)) { | ||||
|         const rememberMe = req.body.remember_me; | ||||
|  | ||||
|         req.session.regenerate(() => { | ||||
| @@ -34,7 +61,7 @@ function login(req, res) { | ||||
|     } | ||||
|     else { | ||||
|         // note that logged IP address is usually meaningless since the traffic should come from a reverse proxy | ||||
|         log.info(`WARNING: Wrong username / password from ${req.ip}, rejecting.`); | ||||
|         log.info(`WARNING: Wrong password from ${req.ip}, rejecting.`); | ||||
|  | ||||
|         res.render('login', {'failedAuth': true}); | ||||
|     } | ||||
| @@ -60,6 +87,7 @@ function logout(req, res) { | ||||
| module.exports = { | ||||
|     loginPage, | ||||
|     setPasswordPage, | ||||
|     setPassword, | ||||
|     login, | ||||
|     logout | ||||
| }; | ||||
|   | ||||
| @@ -183,7 +183,7 @@ const uploadMiddleware = multer.single('upload'); | ||||
| function register(app) { | ||||
|     route(GET, '/', [auth.checkAuth, csrfMiddleware], indexRoute.index); | ||||
|     route(GET, '/login', [auth.checkAppInitialized, auth.checkPasswordSet], loginRoute.loginPage); | ||||
|     route(GET, '/set_password', [auth.checkAppInitialized], loginRoute.setPasswordPage); | ||||
|     route(GET, '/set-password', [auth.checkAppInitialized], loginRoute.setPasswordPage); | ||||
|  | ||||
|     const loginRateLimiter = rateLimit({ | ||||
|         windowMs: 15 * 60 * 1000, // 15 minutes | ||||
| @@ -192,6 +192,7 @@ function register(app) { | ||||
|  | ||||
|     route(POST, '/login', [loginRateLimiter], loginRoute.login); | ||||
|     route(POST, '/logout', [csrfMiddleware, auth.checkAuth], loginRoute.logout); | ||||
|     route(POST, '/set-password', [auth.checkAppInitialized], loginRoute.setPassword); | ||||
|     route(GET, '/setup', [], setupRoute.setupPage); | ||||
|  | ||||
|     apiRoute(GET, '/api/tree', treeApiRoute.getTree); | ||||
|   | ||||
| @@ -4,8 +4,8 @@ const build = require('./build'); | ||||
| const packageJson = require('../../package'); | ||||
| const {TRILIUM_DATA_DIR} = require('./data_dir'); | ||||
|  | ||||
| const APP_DB_VERSION = 188; | ||||
| const SYNC_VERSION = 23; | ||||
| const APP_DB_VERSION = 189; | ||||
| const SYNC_VERSION = 24; | ||||
| const CLIPPER_PROTOCOL_VERSION = "1.0"; | ||||
|  | ||||
| module.exports = { | ||||
|   | ||||
| @@ -18,7 +18,7 @@ function checkAuth(req, res, next) { | ||||
|         if (sqlInit.isPasswordSet()) { | ||||
|             res.redirect("login"); | ||||
|         } else { | ||||
|             res.redirect("set_password"); | ||||
|             res.redirect("set-password"); | ||||
|         } | ||||
|     } | ||||
|     else { | ||||
| @@ -57,7 +57,7 @@ function checkAppInitialized(req, res, next) { | ||||
|  | ||||
| function checkPasswordSet(req, res, next) { | ||||
|     if (!utils.isElectron() && !sqlInit.isPasswordSet()) { | ||||
|         res.redirect("set_password"); | ||||
|         res.redirect("set-password"); | ||||
|     } else { | ||||
|         next(); | ||||
|     } | ||||
| @@ -99,10 +99,10 @@ function checkCredentials(req, res, next) { | ||||
|     const auth = new Buffer.from(header, 'base64').toString(); | ||||
|     const [username, password] = auth.split(/:/); | ||||
|  | ||||
|     const dbUsername = optionService.getOption('username'); | ||||
|     // username is ignored | ||||
|  | ||||
|     if (dbUsername !== username || !passwordEncryptionService.verifyPassword(password)) { | ||||
|         res.status(401).send('Incorrect username and/or password'); | ||||
|     if (!passwordEncryptionService.verifyPassword(password)) { | ||||
|         res.status(401).send('Incorrect password'); | ||||
|     } | ||||
|     else { | ||||
|         next(); | ||||
|   | ||||
| @@ -12,7 +12,7 @@ function initDocumentOptions() { | ||||
|     optionService.createOption('documentSecret', utils.randomSecureToken(16), false); | ||||
| } | ||||
|  | ||||
| function initPassword(username, password) { | ||||
| function initPassword(password) { | ||||
|     optionService.createOption('passwordVerificationSalt', utils.randomSecureToken(32), true); | ||||
|     optionService.createOption('passwordDerivedKeySalt', utils.randomSecureToken(32), true); | ||||
|  | ||||
|   | ||||
| @@ -38,7 +38,7 @@ function exec(opts) { | ||||
|             }; | ||||
|  | ||||
|             if (opts.auth) { | ||||
|                 headers['trilium-cred'] = Buffer.from(opts.auth.username + ":" + opts.auth.password).toString('base64'); | ||||
|                 headers['trilium-cred'] = Buffer.from("dummy:" + opts.auth.password).toString('base64'); | ||||
|             } | ||||
|  | ||||
|             const request = client.request({ | ||||
|   | ||||
| @@ -55,7 +55,7 @@ async function requestToSyncServer(method, path, body = null) { | ||||
|     }), timeout); | ||||
| } | ||||
|  | ||||
| async function setupSyncFromSyncServer(syncServerHost, syncProxy, username, password) { | ||||
| async function setupSyncFromSyncServer(syncServerHost, syncProxy, password) { | ||||
|     if (sqlInit.isDbInitialized()) { | ||||
|         return { | ||||
|             result: 'failure', | ||||
| @@ -70,10 +70,7 @@ async function setupSyncFromSyncServer(syncServerHost, syncProxy, username, pass | ||||
|         const resp = await request.exec({ | ||||
|             method: 'get', | ||||
|             url: syncServerHost + '/api/setup/sync-seed', | ||||
|             auth: { | ||||
|                 username, | ||||
|                 password | ||||
|             }, | ||||
|             auth: { password }, | ||||
|             proxy: syncProxy, | ||||
|             timeout: 30000 // seed request should not take long | ||||
|         }); | ||||
|   | ||||
| @@ -31,11 +31,7 @@ function isDbInitialized() { | ||||
| } | ||||
|  | ||||
| function isPasswordSet() { | ||||
|     const value = sql.getValue("SELECT value FROM options WHERE name = 'passwordVerificationHash'"); | ||||
|  | ||||
|     console.log("AAAAAAAAAAAAEEEEEEEEE", value); | ||||
|  | ||||
|     return !!value; | ||||
|     return !!sql.getValue("SELECT value FROM options WHERE name = 'passwordVerificationHash'"); | ||||
| } | ||||
|  | ||||
| async function initDbConnection() { | ||||
|   | ||||
| @@ -20,7 +20,7 @@ | ||||
|                             <a class="nav-link" data-toggle="tab" href="#options-code-notes">Code notes</a> | ||||
|                         </li> | ||||
|                         <li class="nav-item"> | ||||
|                             <a class="nav-link" data-toggle="tab" href="#options-credentials">Username & password</a> | ||||
|                             <a class="nav-link" data-toggle="tab" href="#options-credentials">Password</a> | ||||
|                         </li> | ||||
|                         <li class="nav-item"> | ||||
|                             <a class="nav-link" data-toggle="tab" href="#options-backup">Backup</a> | ||||
|   | ||||
| @@ -14,17 +14,11 @@ | ||||
|  | ||||
|         <% if (failedAuth) { %> | ||||
|             <div class="alert alert-warning"> | ||||
|                 Username and / or password are incorrect. Please try again. | ||||
|                 Password is incorrect. Please try again. | ||||
|             </div> | ||||
|         <% } %> | ||||
|  | ||||
|         <form action="login" method="POST"> | ||||
|             <div class="form-group"> | ||||
|                 <label for="username">Username</label> | ||||
|                 <div class="controls"> | ||||
|                     <input id="username" name="username" placeholder="" class="form-control" type="text"> | ||||
|                 </div> | ||||
|             </div> | ||||
|             <div class="form-group"> | ||||
|                 <label for="password">Password</label> | ||||
|                 <div class="controls"> | ||||
|   | ||||
| @@ -12,15 +12,15 @@ | ||||
|     <div class="col-xs-12 col-sm-10 col-md-6 col-lg-4 col-xl-4 mx-auto" style="padding-top: 25px;"> | ||||
|         <h1>Set password</h1> | ||||
|  | ||||
|         <% if (failed) { %> | ||||
|         <% if (error) { %> | ||||
|             <div class="alert alert-warning"> | ||||
|                 Err | ||||
|                 <%= error %> | ||||
|             </div> | ||||
|         <% } %> | ||||
|  | ||||
|         <p>Before you can start using Trilium from web, you need to set a password first. You will then use this password to login.</p> | ||||
|  | ||||
|         <form action="login" method="POST"> | ||||
|         <form action="set-password" method="POST"> | ||||
|             <div class="form-group"> | ||||
|                 <label for="password">Password</label> | ||||
|                 <div class="controls"> | ||||
|   | ||||
| @@ -118,10 +118,6 @@ | ||||
|  | ||||
|                 <p><strong>Note:</strong> If you leave proxy setting blank, system proxy will be used (applies to desktop/electron build only)</p> | ||||
|             </div> | ||||
|             <div class="form-group"> | ||||
|                 <label for="username">Username</label> | ||||
|                 <input type="text" id="username" class="form-control" data-bind="value: username" placeholder="Username"> | ||||
|             </div> | ||||
|             <div class="form-group"> | ||||
|                 <label for="password1">Password</label> | ||||
|                 <input type="password" id="password1" class="form-control" data-bind="value: password1" placeholder="Password"> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user