mirror of
https://github.com/zadam/trilium.git
synced 2025-06-06 18:08:33 +02:00
implemented initial setup of the app
This commit is contained in:
parent
a3f57622ff
commit
6546548848
3
export-schema.sh
Executable file
3
export-schema.sh
Executable file
@ -0,0 +1,3 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
sqlite3 ~/trilium-data/document.db .schema > schema.sql
|
34
public/javascripts/setup.js
Normal file
34
public/javascripts/setup.js
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
$("#setup-form").submit(() => {
|
||||||
|
const username = $("#username").val();
|
||||||
|
const password1 = $("#password1").val();
|
||||||
|
const password2 = $("#password2").val();
|
||||||
|
|
||||||
|
if (!username) {
|
||||||
|
showAlert("Username can't be empty");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!password1) {
|
||||||
|
showAlert("Password can't be empty");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (password1 !== password2) {
|
||||||
|
showAlert("Both password fields need be identical.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
server.post('setup', {
|
||||||
|
username: username,
|
||||||
|
password: password1
|
||||||
|
}).then(() => {
|
||||||
|
window.location.replace("/");
|
||||||
|
});
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
function showAlert(message) {
|
||||||
|
$("#alert").html(message);
|
||||||
|
$("#alert").show();
|
||||||
|
}
|
@ -9,6 +9,7 @@ const source_id = require('../../services/source_id');
|
|||||||
const auth = require('../../services/auth');
|
const auth = require('../../services/auth');
|
||||||
const password_encryption = require('../../services/password_encryption');
|
const password_encryption = require('../../services/password_encryption');
|
||||||
const protected_session = require('../../services/protected_session');
|
const protected_session = require('../../services/protected_session');
|
||||||
|
const app_info = require('../../services/app_info');
|
||||||
|
|
||||||
router.post('/sync', async (req, res, next) => {
|
router.post('/sync', async (req, res, next) => {
|
||||||
const timestamp = req.body.timestamp;
|
const timestamp = req.body.timestamp;
|
||||||
@ -22,9 +23,9 @@ router.post('/sync', async (req, res, next) => {
|
|||||||
|
|
||||||
const dbVersion = req.body.dbVersion;
|
const dbVersion = req.body.dbVersion;
|
||||||
|
|
||||||
if (dbVersion !== migration.APP_DB_VERSION) {
|
if (dbVersion !== app_info.db_version) {
|
||||||
res.status(400);
|
res.status(400);
|
||||||
res.send({ message: 'Non-matching db versions, local is version ' + migration.APP_DB_VERSION });
|
res.send({ message: 'Non-matching db versions, local is version ' + app_info.db_version });
|
||||||
}
|
}
|
||||||
|
|
||||||
const documentSecret = await options.getOption('document_secret');
|
const documentSecret = await options.getOption('document_secret');
|
||||||
|
@ -5,11 +5,12 @@ const router = express.Router();
|
|||||||
const auth = require('../../services/auth');
|
const auth = require('../../services/auth');
|
||||||
const options = require('../../services/options');
|
const options = require('../../services/options');
|
||||||
const migration = require('../../services/migration');
|
const migration = require('../../services/migration');
|
||||||
|
const app_info = require('../../services/app_info');
|
||||||
|
|
||||||
router.get('', auth.checkApiAuthForMigrationPage, async (req, res, next) => {
|
router.get('', auth.checkApiAuthForMigrationPage, async (req, res, next) => {
|
||||||
res.send({
|
res.send({
|
||||||
db_version: parseInt(await options.getOption('db_version')),
|
db_version: parseInt(await options.getOption('db_version')),
|
||||||
app_db_version: migration.APP_DB_VERSION
|
app_db_version: app_info.db_version
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
32
routes/api/setup.js
Normal file
32
routes/api/setup.js
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
const express = require('express');
|
||||||
|
const router = express.Router();
|
||||||
|
const auth = require('../../services/auth');
|
||||||
|
const options = require('../../services/options');
|
||||||
|
const sql = require('../../services/sql');
|
||||||
|
const utils = require('../../services/utils');
|
||||||
|
const my_scrypt = require('../../services/my_scrypt');
|
||||||
|
const password_encryption = require('../../services/password_encryption');
|
||||||
|
|
||||||
|
router.post('', auth.checkAppNotInitialized, async (req, res, next) => {
|
||||||
|
const { username, password } = req.body;
|
||||||
|
|
||||||
|
await sql.doInTransaction(async () => {
|
||||||
|
await options.setOption('username', username);
|
||||||
|
|
||||||
|
await options.setOption('password_verification_salt', utils.randomSecureToken(32));
|
||||||
|
await options.setOption('password_derived_key_salt', utils.randomSecureToken(32));
|
||||||
|
|
||||||
|
const passwordVerificationKey = utils.toBase64(await my_scrypt.getVerificationHash(password));
|
||||||
|
await options.setOption('password_verification_hash', passwordVerificationKey);
|
||||||
|
|
||||||
|
await password_encryption.setDataKey(password, utils.randomSecureToken(16));
|
||||||
|
});
|
||||||
|
|
||||||
|
sql.setDbReadyAsResolved();
|
||||||
|
|
||||||
|
res.send({});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = router;
|
@ -2,6 +2,7 @@ const indexRoute = require('./index');
|
|||||||
const loginRoute = require('./login');
|
const loginRoute = require('./login');
|
||||||
const logoutRoute = require('./logout');
|
const logoutRoute = require('./logout');
|
||||||
const migrationRoute = require('./migration');
|
const migrationRoute = require('./migration');
|
||||||
|
const setupRoute = require('./setup');
|
||||||
|
|
||||||
// API routes
|
// API routes
|
||||||
const treeApiRoute = require('./api/tree');
|
const treeApiRoute = require('./api/tree');
|
||||||
@ -19,12 +20,14 @@ const recentNotesRoute = require('./api/recent_notes');
|
|||||||
const appInfoRoute = require('./api/app_info');
|
const appInfoRoute = require('./api/app_info');
|
||||||
const exportRoute = require('./api/export');
|
const exportRoute = require('./api/export');
|
||||||
const importRoute = require('./api/import');
|
const importRoute = require('./api/import');
|
||||||
|
const setupApiRoute = require('./api/setup');
|
||||||
|
|
||||||
function register(app) {
|
function register(app) {
|
||||||
app.use('/', indexRoute);
|
app.use('/', indexRoute);
|
||||||
app.use('/login', loginRoute);
|
app.use('/login', loginRoute);
|
||||||
app.use('/logout', logoutRoute);
|
app.use('/logout', logoutRoute);
|
||||||
app.use('/migration', migrationRoute);
|
app.use('/migration', migrationRoute);
|
||||||
|
app.use('/setup', setupRoute);
|
||||||
|
|
||||||
app.use('/api/tree', treeApiRoute);
|
app.use('/api/tree', treeApiRoute);
|
||||||
app.use('/api/notes', notesApiRoute);
|
app.use('/api/notes', notesApiRoute);
|
||||||
@ -41,6 +44,7 @@ function register(app) {
|
|||||||
app.use('/api/app-info', appInfoRoute);
|
app.use('/api/app-info', appInfoRoute);
|
||||||
app.use('/api/export', exportRoute);
|
app.use('/api/export', exportRoute);
|
||||||
app.use('/api/import', importRoute);
|
app.use('/api/import', importRoute);
|
||||||
|
app.use('/api/setup', setupApiRoute);
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
11
routes/setup.js
Normal file
11
routes/setup.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
const express = require('express');
|
||||||
|
const router = express.Router();
|
||||||
|
const auth = require('../services/auth');
|
||||||
|
|
||||||
|
router.get('', auth.checkAppNotInitialized, (req, res, next) => {
|
||||||
|
res.render('setup', {});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = router;
|
92
schema.sql
Normal file
92
schema.sql
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
CREATE TABLE `migrations` (
|
||||||
|
`id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||||
|
`name` TEXT NOT NULL,
|
||||||
|
`version` INTEGER NOT NULL,
|
||||||
|
`success` INTEGER NOT NULL,
|
||||||
|
`error` TEXT
|
||||||
|
);
|
||||||
|
CREATE TABLE `sync` (
|
||||||
|
`id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||||
|
`entity_name` TEXT NOT NULL,
|
||||||
|
`entity_id` TEXT NOT NULL,
|
||||||
|
`sync_date` INTEGER NOT NULL
|
||||||
|
, source_id TEXT);
|
||||||
|
CREATE UNIQUE INDEX `IDX_sync_entity_name_id` ON `sync` (
|
||||||
|
`entity_name`,
|
||||||
|
`entity_id`
|
||||||
|
);
|
||||||
|
CREATE INDEX `IDX_sync_sync_date` ON `sync` (
|
||||||
|
`sync_date`
|
||||||
|
);
|
||||||
|
CREATE TABLE IF NOT EXISTS "options" (
|
||||||
|
`opt_name` TEXT NOT NULL PRIMARY KEY,
|
||||||
|
`opt_value` TEXT,
|
||||||
|
`date_modified` INT
|
||||||
|
);
|
||||||
|
CREATE TABLE `event_log` (
|
||||||
|
`id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||||
|
`note_id` TEXT,
|
||||||
|
`comment` TEXT,
|
||||||
|
`date_added` INTEGER NOT NULL
|
||||||
|
);
|
||||||
|
CREATE INDEX `IDX_event_log_date_added` ON `event_log` (
|
||||||
|
`date_added`
|
||||||
|
);
|
||||||
|
CREATE TABLE IF NOT EXISTS "notes" (
|
||||||
|
`note_id` TEXT NOT NULL,
|
||||||
|
`note_title` TEXT,
|
||||||
|
`note_text` TEXT,
|
||||||
|
`date_created` INT,
|
||||||
|
`date_modified` INT,
|
||||||
|
`is_protected` INT NOT NULL DEFAULT 0,
|
||||||
|
`is_deleted` INT NOT NULL DEFAULT 0,
|
||||||
|
PRIMARY KEY(`note_id`)
|
||||||
|
);
|
||||||
|
CREATE INDEX `IDX_notes_is_deleted` ON `notes` (
|
||||||
|
`is_deleted`
|
||||||
|
);
|
||||||
|
CREATE TABLE IF NOT EXISTS "notes_history" (
|
||||||
|
`note_history_id` TEXT NOT NULL PRIMARY KEY,
|
||||||
|
`note_id` TEXT NOT NULL,
|
||||||
|
`note_title` TEXT,
|
||||||
|
`note_text` TEXT,
|
||||||
|
`is_protected` INT,
|
||||||
|
`date_modified_from` INT,
|
||||||
|
`date_modified_to` INT
|
||||||
|
);
|
||||||
|
CREATE INDEX `IDX_notes_history_note_id` ON `notes_history` (
|
||||||
|
`note_id`
|
||||||
|
);
|
||||||
|
CREATE INDEX `IDX_notes_history_note_date_modified_from` ON `notes_history` (
|
||||||
|
`date_modified_from`
|
||||||
|
);
|
||||||
|
CREATE INDEX `IDX_notes_history_note_date_modified_to` ON `notes_history` (
|
||||||
|
`date_modified_to`
|
||||||
|
);
|
||||||
|
CREATE TABLE `source_ids` (
|
||||||
|
`source_id` TEXT NOT NULL,
|
||||||
|
`date_created` INTEGER NOT NULL,
|
||||||
|
PRIMARY KEY(`source_id`)
|
||||||
|
);
|
||||||
|
CREATE TABLE IF NOT EXISTS "notes_tree" (
|
||||||
|
[note_tree_id] VARCHAR(30) PRIMARY KEY NOT NULL,
|
||||||
|
[note_id] VARCHAR(30) NOT NULL,
|
||||||
|
[note_pid] VARCHAR(30) NOT NULL,
|
||||||
|
[note_pos] INTEGER NOT NULL,
|
||||||
|
[is_expanded] BOOLEAN NULL ,
|
||||||
|
date_modified INTEGER NOT NULL DEFAULT 0,
|
||||||
|
is_deleted INTEGER NOT NULL DEFAULT 0
|
||||||
|
, `prefix` TEXT);
|
||||||
|
CREATE INDEX `IDX_notes_tree_note_tree_id` ON `notes_tree` (
|
||||||
|
`note_tree_id`
|
||||||
|
);
|
||||||
|
CREATE INDEX `IDX_notes_tree_note_id_note_pid` ON `notes_tree` (
|
||||||
|
`note_id`,
|
||||||
|
`note_pid`
|
||||||
|
);
|
||||||
|
CREATE TABLE `recent_notes` (
|
||||||
|
'note_tree_id'TEXT NOT NULL PRIMARY KEY,
|
||||||
|
`note_path` TEXT NOT NULL,
|
||||||
|
`date_accessed` INTEGER NOT NULL ,
|
||||||
|
is_deleted INT
|
||||||
|
);
|
@ -2,11 +2,12 @@
|
|||||||
|
|
||||||
const build = require('./build');
|
const build = require('./build');
|
||||||
const packageJson = require('../package');
|
const packageJson = require('../package');
|
||||||
const migration = require('./migration');
|
|
||||||
|
const APP_DB_VERSION = 48;
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
app_version: packageJson.version,
|
app_version: packageJson.version,
|
||||||
db_version: migration.APP_DB_VERSION,
|
db_version: APP_DB_VERSION,
|
||||||
build_date: build.build_date,
|
build_date: build.build_date,
|
||||||
build_revision: build.build_revision
|
build_revision: build.build_revision
|
||||||
};
|
};
|
@ -2,16 +2,22 @@
|
|||||||
|
|
||||||
const migration = require('./migration');
|
const migration = require('./migration');
|
||||||
const utils = require('./utils');
|
const utils = require('./utils');
|
||||||
|
const options = require('./options');
|
||||||
|
|
||||||
async function checkAuth(req, res, next) {
|
async function checkAuth(req, res, next) {
|
||||||
if (!req.session.loggedIn && !utils.isElectron()) {
|
const username = await options.getOption('username');
|
||||||
|
|
||||||
|
if (!username) {
|
||||||
|
res.redirect("setup");
|
||||||
|
}
|
||||||
|
else if (!req.session.loggedIn && !utils.isElectron()) {
|
||||||
res.redirect("login");
|
res.redirect("login");
|
||||||
}
|
}
|
||||||
else if (await migration.isDbUpToDate()) {
|
else if (!await migration.isDbUpToDate()) {
|
||||||
next();
|
res.redirect("migration");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
res.redirect("migration");
|
next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,9 +51,21 @@ async function checkApiAuthForMigrationPage(req, res, next) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function checkAppNotInitialized(req, res, next) {
|
||||||
|
const username = await options.getOption('username');
|
||||||
|
|
||||||
|
if (username) {
|
||||||
|
res.status(400).send("App already initialized.");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
checkAuth,
|
checkAuth,
|
||||||
checkAuthForMigrationPage,
|
checkAuthForMigrationPage,
|
||||||
checkApiAuth,
|
checkApiAuth,
|
||||||
checkApiAuthForMigrationPage
|
checkApiAuthForMigrationPage,
|
||||||
|
checkAppNotInitialized
|
||||||
};
|
};
|
@ -3,8 +3,8 @@ const sql = require('./sql');
|
|||||||
const options = require('./options');
|
const options = require('./options');
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const log = require('./log');
|
const log = require('./log');
|
||||||
|
const app_info = require('./app_info');
|
||||||
|
|
||||||
const APP_DB_VERSION = 48;
|
|
||||||
const MIGRATIONS_DIR = "migrations";
|
const MIGRATIONS_DIR = "migrations";
|
||||||
|
|
||||||
async function migrate() {
|
async function migrate() {
|
||||||
@ -84,11 +84,10 @@ async function migrate() {
|
|||||||
async function isDbUpToDate() {
|
async function isDbUpToDate() {
|
||||||
const dbVersion = parseInt(await options.getOption('db_version'));
|
const dbVersion = parseInt(await options.getOption('db_version'));
|
||||||
|
|
||||||
return dbVersion >= APP_DB_VERSION;
|
return dbVersion >= app_info.db_version;
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
migrate,
|
migrate,
|
||||||
isDbUpToDate,
|
isDbUpToDate
|
||||||
APP_DB_VERSION
|
|
||||||
};
|
};
|
@ -1,6 +1,7 @@
|
|||||||
const sql = require('./sql');
|
const sql = require('./sql');
|
||||||
const utils = require('./utils');
|
const utils = require('./utils');
|
||||||
const sync_table = require('./sync_table');
|
const sync_table = require('./sync_table');
|
||||||
|
const app_info = require('./app_info');
|
||||||
|
|
||||||
const SYNCED_OPTIONS = [ 'username', 'password_verification_hash', 'encrypted_data_key', 'protected_session_timeout',
|
const SYNCED_OPTIONS = [ 'username', 'password_verification_hash', 'encrypted_data_key', 'protected_session_timeout',
|
||||||
'history_snapshot_time_interval' ];
|
'history_snapshot_time_interval' ];
|
||||||
@ -20,21 +21,38 @@ async function setOption(optName, optValue) {
|
|||||||
await sync_table.addOptionsSync(optName);
|
await sync_table.addOptionsSync(optName);
|
||||||
}
|
}
|
||||||
|
|
||||||
await sql.execute("UPDATE options SET opt_value = ?, date_modified = ? WHERE opt_name = ?",
|
await sql.replace("options", {
|
||||||
[optValue, utils.nowTimestamp(), optName]);
|
opt_name: optName,
|
||||||
|
opt_value: optValue,
|
||||||
|
date_modified: utils.nowTimestamp()
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
sql.dbReady.then(async () => {
|
async function initOptions() {
|
||||||
if (!await getOption('document_id') || !await getOption('document_secret')) {
|
|
||||||
await sql.doInTransaction(async () => {
|
|
||||||
await setOption('document_id', utils.randomSecureToken(16));
|
await setOption('document_id', utils.randomSecureToken(16));
|
||||||
await setOption('document_secret', utils.randomSecureToken(16));
|
await setOption('document_secret', utils.randomSecureToken(16));
|
||||||
});
|
|
||||||
|
await setOption('username', '');
|
||||||
|
await setOption('password_verification_hash', '');
|
||||||
|
await setOption('password_verification_salt', '');
|
||||||
|
await setOption('password_derived_key_salt', '');
|
||||||
|
await setOption('encrypted_data_key', '');
|
||||||
|
await setOption('encrypted_data_key_iv', '');
|
||||||
|
|
||||||
|
await setOption('start_note_tree_id', '');
|
||||||
|
await setOption('protected_session_timeout', 600);
|
||||||
|
await setOption('history_snapshot_time_interval', 600);
|
||||||
|
await setOption('last_backup_date', utils.nowTimestamp());
|
||||||
|
await setOption('db_version', app_info.db_version);
|
||||||
|
|
||||||
|
await setOption('last_synced_pull', app_info.db_version);
|
||||||
|
await setOption('last_synced_push', 0);
|
||||||
|
await setOption('last_synced_push', 0);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
getOption,
|
getOption,
|
||||||
setOption,
|
setOption,
|
||||||
|
initOptions,
|
||||||
SYNCED_OPTIONS
|
SYNCED_OPTIONS
|
||||||
};
|
};
|
@ -11,15 +11,33 @@ async function createConnection() {
|
|||||||
|
|
||||||
const dbConnected = createConnection();
|
const dbConnected = createConnection();
|
||||||
|
|
||||||
|
let dbReadyResolve = null;
|
||||||
const dbReady = new Promise((resolve, reject) => {
|
const dbReady = new Promise((resolve, reject) => {
|
||||||
dbConnected.then(async db => {
|
dbConnected.then(async db => {
|
||||||
|
dbReadyResolve = () => resolve(db);
|
||||||
|
|
||||||
const tableResults = await getResults("SELECT name FROM sqlite_master WHERE type='table' AND name='notes'");
|
const tableResults = await getResults("SELECT name FROM sqlite_master WHERE type='table' AND name='notes'");
|
||||||
if (tableResults.length !== 1) {
|
if (tableResults.length !== 1) {
|
||||||
console.log("No connection to initialized DB.");
|
log.info("Connected to db, but schema doesn't exist. Initializing schema ...");
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
const schema = fs.readFileSync('schema.sql', 'UTF-8');
|
||||||
|
|
||||||
|
await doInTransaction(async () => {
|
||||||
|
await executeScript(schema);
|
||||||
|
|
||||||
|
await require('./options').initOptions();
|
||||||
|
});
|
||||||
|
|
||||||
|
// we don't resolve dbReady promise because user needs to setup the username and password to initialize
|
||||||
|
// the database
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const username = await getSingleValue("SELECT opt_value FROM options WHERE opt_name = 'username'");
|
||||||
|
|
||||||
|
if (username) {
|
||||||
resolve(db);
|
resolve(db);
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.catch(e => {
|
.catch(e => {
|
||||||
console.log("Error connecting to DB.", e);
|
console.log("Error connecting to DB.", e);
|
||||||
@ -27,6 +45,10 @@ const dbReady = new Promise((resolve, reject) => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function setDbReadyAsResolved() {
|
||||||
|
dbReadyResolve();
|
||||||
|
}
|
||||||
|
|
||||||
async function insert(table_name, rec, replace = false) {
|
async function insert(table_name, rec, replace = false) {
|
||||||
const keys = Object.keys(rec);
|
const keys = Object.keys(rec);
|
||||||
if (keys.length === 0) {
|
if (keys.length === 0) {
|
||||||
@ -181,5 +203,6 @@ module.exports = {
|
|||||||
getFlattenedResults,
|
getFlattenedResults,
|
||||||
execute,
|
execute,
|
||||||
executeScript,
|
executeScript,
|
||||||
doInTransaction
|
doInTransaction,
|
||||||
|
setDbReadyAsResolved
|
||||||
};
|
};
|
@ -13,6 +13,7 @@ const syncUpdate = require('./sync_update');
|
|||||||
const content_hash = require('./content_hash');
|
const content_hash = require('./content_hash');
|
||||||
const event_log = require('./event_log');
|
const event_log = require('./event_log');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
|
const app_info = require('./app_info');
|
||||||
|
|
||||||
const SYNC_SERVER = config['Sync']['syncServerHost'];
|
const SYNC_SERVER = config['Sync']['syncServerHost'];
|
||||||
const isSyncSetup = !!SYNC_SERVER;
|
const isSyncSetup = !!SYNC_SERVER;
|
||||||
@ -94,7 +95,7 @@ async function login() {
|
|||||||
|
|
||||||
const resp = await syncRequest(syncContext, 'POST', '/api/login/sync', {
|
const resp = await syncRequest(syncContext, 'POST', '/api/login/sync', {
|
||||||
timestamp: timestamp,
|
timestamp: timestamp,
|
||||||
dbVersion: migration.APP_DB_VERSION,
|
dbVersion: app_info.db_version,
|
||||||
hash: hash
|
hash: hash
|
||||||
});
|
});
|
||||||
|
|
||||||
|
48
views/setup.ejs
Normal file
48
views/setup.ejs
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Setup</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div style="width: 500px; margin: auto;">
|
||||||
|
<h1>Trilium setup</h1>
|
||||||
|
|
||||||
|
<div class="alert alert-warning" id="alert" style="display: none;">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form id="setup-form">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="username">Username</label>
|
||||||
|
<input type="text" class="form-control" id="username" placeholder="Arbitrary string">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="password1">Password</label>
|
||||||
|
<input type="password" class="form-control" id="password1" placeholder="Password">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="password2">Repeat password</label>
|
||||||
|
<input type="password" class="form-control" id="password2" placeholder="Password">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="submit" class="btn btn-default">Save</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
const baseApiUrl = 'api/';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- Required for correct loading of scripts in Electron -->
|
||||||
|
<script>if (typeof module === 'object') {window.module = module; module = undefined;}</script>
|
||||||
|
|
||||||
|
<script src="libraries/jquery.min.js"></script>
|
||||||
|
|
||||||
|
<link href="libraries/bootstrap/css/bootstrap.css" rel="stylesheet">
|
||||||
|
<script src="libraries/bootstrap/js/bootstrap.js"></script>
|
||||||
|
|
||||||
|
<script src="javascripts/setup.js"></script>
|
||||||
|
<script src="javascripts/utils.js"></script>
|
||||||
|
<script src="javascripts/server.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
x
Reference in New Issue
Block a user