diff --git a/package-lock.json b/package-lock.json
index 798a1729c..c462596b3 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "trilium",
- "version": "0.48.8",
+ "version": "0.49.1-beta",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "trilium",
- "version": "0.48.8",
+ "version": "0.49.1-beta",
"license": "AGPL-3.0-only",
"dependencies": {
"@electron/remote": "2.0.1",
diff --git a/src/public/app/dialogs/options/credentials.js b/src/public/app/dialogs/options/credentials.js
index ce8c1a85c..cc2ebe2fb 100644
--- a/src/public/app/dialogs/options/credentials.js
+++ b/src/public/app/dialogs/options/credentials.js
@@ -3,10 +3,6 @@ import protectedSessionHolder from "../../services/protected_session_holder.js";
import toastService from "../../services/toast.js";
const TPL = `
-
@@ -36,7 +32,6 @@ export default class ChangePasswordOptions {
constructor() {
$("#options-credentials").html(TPL);
- this.$username = $("#credentials-username");
this.$form = $("#change-password-form");
this.$oldPassword = $("#old-password");
this.$newPassword1 = $("#new-password1");
@@ -46,7 +41,6 @@ export default class ChangePasswordOptions {
}
optionsLoaded(options) {
- this.$username.text(options.username);
}
save() {
diff --git a/src/routes/login.js b/src/routes/login.js
index b5837059a..e2e670007 100644
--- a/src/routes/login.js
+++ b/src/routes/login.js
@@ -9,6 +9,10 @@ function loginPage(req, res) {
res.render('login', { failedAuth: false });
}
+function setPasswordPage(req, res) {
+ res.render('set_password', { failed: false });
+}
+
function login(req, res) {
const userName = optionService.getOption('username');
@@ -55,6 +59,7 @@ function logout(req, res) {
module.exports = {
loginPage,
+ setPasswordPage,
login,
logout
};
diff --git a/src/routes/routes.js b/src/routes/routes.js
index 1b65257c4..473048a7d 100644
--- a/src/routes/routes.js
+++ b/src/routes/routes.js
@@ -182,7 +182,8 @@ const uploadMiddleware = multer.single('upload');
function register(app) {
route(GET, '/', [auth.checkAuth, csrfMiddleware], indexRoute.index);
- route(GET, '/login', [auth.checkAppInitialized], loginRoute.loginPage);
+ route(GET, '/login', [auth.checkAppInitialized, auth.checkPasswordSet], loginRoute.loginPage);
+ route(GET, '/set_password', [auth.checkAppInitialized], loginRoute.setPasswordPage);
const loginRateLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
diff --git a/src/services/auth.js b/src/services/auth.js
index 2e6c6bfe9..d2ca55eff 100644
--- a/src/services/auth.js
+++ b/src/services/auth.js
@@ -15,7 +15,11 @@ function checkAuth(req, res, next) {
res.redirect("setup");
}
else if (!req.session.loggedIn && !utils.isElectron() && !noAuthentication) {
- res.redirect("login");
+ if (sqlInit.isPasswordSet()) {
+ res.redirect("login");
+ } else {
+ res.redirect("set_password");
+ }
}
else {
next();
@@ -51,6 +55,14 @@ function checkAppInitialized(req, res, next) {
}
}
+function checkPasswordSet(req, res, next) {
+ if (!utils.isElectron() && !sqlInit.isPasswordSet()) {
+ res.redirect("set_password");
+ } else {
+ next();
+ }
+}
+
function checkAppNotInitialized(req, res, next) {
if (sqlInit.isDbInitialized()) {
reject(req, res, "App already initialized.");
@@ -101,6 +113,7 @@ module.exports = {
checkAuth,
checkApiAuth,
checkAppInitialized,
+ checkPasswordSet,
checkAppNotInitialized,
checkApiAuthOrElectron,
checkToken,
diff --git a/src/services/sql.js b/src/services/sql.js
index 76ebb52ef..7b5ed8bc0 100644
--- a/src/services/sql.js
+++ b/src/services/sql.js
@@ -14,6 +14,8 @@ const cls = require('./cls');
const dbConnection = new Database(dataDir.DOCUMENT_PATH);
dbConnection.pragma('journal_mode = WAL');
+const LOG_ALL_QUERIES = false;
+
[`exit`, `SIGINT`, `SIGUSR1`, `SIGUSR2`, `SIGTERM`].forEach(eventType => {
process.on(eventType, () => {
if (dbConnection) {
@@ -135,6 +137,10 @@ function getRawRows(query, params = []) {
}
function iterateRows(query, params = []) {
+ if (LOG_ALL_QUERIES) {
+ console.log(query);
+ }
+
return stmt(query).iterate(params);
}
@@ -157,11 +163,11 @@ function execute(query, params = []) {
return wrap(query, s => s.run(params));
}
-function executeWithoutTransaction(query, params = []) {
- dbConnection.run(query, params);
-}
-
function executeMany(query, params) {
+ if (LOG_ALL_QUERIES) {
+ console.log(query);
+ }
+
while (params.length > 0) {
const curParams = params.slice(0, Math.min(params.length, PARAM_LIMIT));
params = params.slice(curParams.length);
@@ -182,6 +188,10 @@ function executeMany(query, params) {
}
function executeScript(query) {
+ if (LOG_ALL_QUERIES) {
+ console.log(query);
+ }
+
return dbConnection.exec(query);
}
@@ -189,6 +199,10 @@ function wrap(query, func) {
const startTimestamp = Date.now();
let result;
+ if (LOG_ALL_QUERIES) {
+ console.log(query);
+ }
+
try {
result = func(stmt(query));
}
@@ -331,7 +345,6 @@ module.exports = {
* @param {object[]} [params] - array of params if needed
*/
execute,
- executeWithoutTransaction,
executeMany,
executeScript,
transactional,
diff --git a/src/services/sql_init.js b/src/services/sql_init.js
index 658fd9515..6412cceec 100644
--- a/src/services/sql_init.js
+++ b/src/services/sql_init.js
@@ -30,6 +30,14 @@ function isDbInitialized() {
return initialized === 'true';
}
+function isPasswordSet() {
+ const value = sql.getValue("SELECT value FROM options WHERE name = 'passwordVerificationHash'");
+
+ console.log("AAAAAAAAAAAAEEEEEEEEE", value);
+
+ return !!value;
+}
+
async function initDbConnection() {
if (!isDbInitialized()) {
log.info(`DB not initialized, please visit setup page` +
@@ -169,8 +177,8 @@ module.exports = {
dbReady,
schemaExists,
isDbInitialized,
- initDbConnection,
createInitialDatabase,
createDatabaseForSync,
- setDbAsInitialized
+ setDbAsInitialized,
+ isPasswordSet
};
diff --git a/src/views/set_password.ejs b/src/views/set_password.ejs
new file mode 100644
index 000000000..57e4137f9
--- /dev/null
+++ b/src/views/set_password.ejs
@@ -0,0 +1,50 @@
+
+
+
+
+
+
Login
+
+
+
+
+
+
+
Set password
+
+ <% if (failed) { %>
+
+ Err
+
+ <% } %>
+
+
Before you can start using Trilium from web, you need to set a password first. You will then use this password to login.
+
+
+
+
+
+
+
+
+
+