mirror of
https://github.com/TriliumNext/Notes.git
synced 2025-07-27 10:02:59 +08:00
#12: Remove Electron-specific code in db initialization
This commit is contained in:
parent
780f2577c8
commit
80151c2b2f
@ -81,6 +81,10 @@ const app = startTrilium({
|
||||
setupCompleteCallback: () => {
|
||||
windowService.createMainWindow(electron.app);
|
||||
windowService.closeSetupWindow();
|
||||
},
|
||||
|
||||
getInitialTheme() {
|
||||
return electron.nativeTheme.shouldUseDarkColors ? 'dark' : 'light';
|
||||
}
|
||||
});
|
||||
electronRouting(app);
|
@ -6,9 +6,9 @@ import helmet = require('helmet');
|
||||
import compression = require('compression');
|
||||
import sessionParser = require('./routes/session_parser');
|
||||
import utils = require('./services/utils');
|
||||
import { RouteConfig } from './routes/types';
|
||||
import { AppConfig } from './types';
|
||||
|
||||
function buildApp(routeConfig: RouteConfig) {
|
||||
function buildApp(appConfig: AppConfig) {
|
||||
require('./services/handlers');
|
||||
require('./becca/becca_loader');
|
||||
|
||||
@ -40,7 +40,7 @@ function buildApp(routeConfig: RouteConfig) {
|
||||
app.use(favicon(`${__dirname}/../../common/images/app-icons/win/icon.ico`));
|
||||
|
||||
require('./routes/assets').register(app);
|
||||
require('./routes/routes').register(app, routeConfig);
|
||||
require('./routes/routes').register(app, appConfig);
|
||||
require('./routes/custom').register(app);
|
||||
require('./routes/error_handlers').register(app);
|
||||
|
||||
|
@ -3,5 +3,10 @@ import startTrilium = require("./www");
|
||||
startTrilium({
|
||||
setupCompleteCallback: (res) => {
|
||||
res.redirect('.');
|
||||
},
|
||||
|
||||
getInitialTheme() {
|
||||
// default based on the poll in https://github.com/zadam/trilium/issues/2516
|
||||
return "dark";
|
||||
}
|
||||
});
|
@ -5,56 +5,61 @@ import setupService = require('../../services/setup');
|
||||
import log = require('../../services/log');
|
||||
import appInfo = require('../../services/app_info');
|
||||
import { Request } from 'express';
|
||||
import { InitDbOptions } from '../../types';
|
||||
|
||||
function getStatus() {
|
||||
return {
|
||||
isInitialized: sqlInit.isDbInitialized(),
|
||||
schemaExists: sqlInit.schemaExists(),
|
||||
syncVersion: appInfo.syncVersion
|
||||
};
|
||||
}
|
||||
|
||||
async function setupNewDocument() {
|
||||
await sqlInit.createInitialDatabase();
|
||||
}
|
||||
|
||||
function setupSyncFromServer(req: Request) {
|
||||
const { syncServerHost, syncProxy, password } = req.body;
|
||||
|
||||
return setupService.setupSyncFromSyncServer(syncServerHost, syncProxy, password);
|
||||
}
|
||||
|
||||
function saveSyncSeed(req: Request) {
|
||||
const { options, syncVersion } = req.body;
|
||||
|
||||
if (appInfo.syncVersion !== syncVersion) {
|
||||
const message = `Could not setup sync since local sync protocol version is ${appInfo.syncVersion} while remote is ${syncVersion}. To fix this issue, use same Trilium version on all instances.`;
|
||||
|
||||
log.error(message);
|
||||
|
||||
return [400, {
|
||||
error: message
|
||||
}]
|
||||
function buildRoutes(initOptions: InitDbOptions) {
|
||||
function getStatus() {
|
||||
return {
|
||||
isInitialized: sqlInit.isDbInitialized(),
|
||||
schemaExists: sqlInit.schemaExists(),
|
||||
syncVersion: appInfo.syncVersion
|
||||
};
|
||||
}
|
||||
|
||||
log.info("Saved sync seed.");
|
||||
|
||||
sqlInit.createDatabaseForSync(options);
|
||||
}
|
||||
|
||||
function getSyncSeed() {
|
||||
log.info("Serving sync seed.");
|
||||
|
||||
|
||||
async function setupNewDocument() {
|
||||
await sqlInit.createInitialDatabase(initOptions);
|
||||
}
|
||||
|
||||
function setupSyncFromServer(req: Request) {
|
||||
const { syncServerHost, syncProxy, password } = req.body;
|
||||
|
||||
return setupService.setupSyncFromSyncServer(syncServerHost, syncProxy, password, initOptions);
|
||||
}
|
||||
|
||||
function saveSyncSeed(req: Request) {
|
||||
const { options, syncVersion } = req.body;
|
||||
|
||||
if (appInfo.syncVersion !== syncVersion) {
|
||||
const message = `Could not setup sync since local sync protocol version is ${appInfo.syncVersion} while remote is ${syncVersion}. To fix this issue, use same Trilium version on all instances.`;
|
||||
|
||||
log.error(message);
|
||||
|
||||
return [400, {
|
||||
error: message
|
||||
}]
|
||||
}
|
||||
|
||||
log.info("Saved sync seed.");
|
||||
|
||||
sqlInit.createDatabaseForSync(options, initOptions);
|
||||
}
|
||||
|
||||
function getSyncSeed() {
|
||||
log.info("Serving sync seed.");
|
||||
|
||||
return {
|
||||
options: setupService.getSyncSeedOptions(),
|
||||
syncVersion: appInfo.syncVersion
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
options: setupService.getSyncSeedOptions(),
|
||||
syncVersion: appInfo.syncVersion
|
||||
getStatus,
|
||||
setupNewDocument,
|
||||
setupSyncFromServer,
|
||||
getSyncSeed,
|
||||
saveSyncSeed
|
||||
};
|
||||
}
|
||||
|
||||
export = {
|
||||
getStatus,
|
||||
setupNewDocument,
|
||||
setupSyncFromServer,
|
||||
getSyncSeed,
|
||||
saveSyncSeed
|
||||
};
|
||||
export = buildRoutes;
|
@ -38,7 +38,7 @@ import recentNotesRoute = require('./api/recent_notes');
|
||||
import appInfoRoute = require('./api/app_info');
|
||||
import exportRoute = require('./api/export');
|
||||
import importRoute = require('./api/import');
|
||||
import setupApiRoute = require('./api/setup');
|
||||
import buildSetupRoute = require('./api/setup');
|
||||
import sqlRoute = require('./api/sql');
|
||||
import databaseRoute = require('./api/database');
|
||||
import imageRoute = require('./api/image');
|
||||
@ -71,7 +71,7 @@ import etapiSpecialNoteRoutes = require('../etapi/special_notes');
|
||||
import etapiSpecRoute = require('../etapi/spec');
|
||||
import etapiBackupRoute = require('../etapi/backup');
|
||||
import { AppRequest, AppRequestHandler } from './route-interface';
|
||||
import { RouteConfig } from './types';
|
||||
import { AppConfig } from '../types';
|
||||
|
||||
const csrfMiddleware = csurf({
|
||||
cookie: {
|
||||
@ -102,7 +102,7 @@ const uploadMiddlewareWithErrorHandling = function (req: express.Request, res: e
|
||||
});
|
||||
};
|
||||
|
||||
function register(app: express.Application, config: RouteConfig) {
|
||||
function register(app: express.Application, appConfig: AppConfig) {
|
||||
route(GET, '/', [auth.checkAuth, csrfMiddleware], indexRoute.index);
|
||||
route(GET, '/login', [auth.checkAppInitialized, auth.checkPasswordSet], loginRoute.loginPage);
|
||||
route(GET, '/set-password', [auth.checkAppInitialized, auth.checkPasswordNotSet], loginRoute.setPasswordPage);
|
||||
@ -116,7 +116,7 @@ function register(app: express.Application, config: RouteConfig) {
|
||||
route(PST, '/login', [loginRateLimiter], loginRoute.login);
|
||||
route(PST, '/logout', [csrfMiddleware, auth.checkAuth], loginRoute.logout);
|
||||
route(PST, '/set-password', [auth.checkAppInitialized, auth.checkPasswordNotSet], loginRoute.setPassword);
|
||||
route(GET, '/setup', [], setupRoute.buildSetupRoute(config.setupCompleteCallback));
|
||||
route(GET, '/setup', [], setupRoute.buildSetupRoute(appConfig.setupCompleteCallback));
|
||||
|
||||
apiRoute(GET, '/api/tree', treeApiRoute.getTree);
|
||||
apiRoute(PST, '/api/tree/load', treeApiRoute.load);
|
||||
@ -241,6 +241,7 @@ function register(app: express.Application, config: RouteConfig) {
|
||||
route(GET, '/api/health-check', [], () => ({ "status": "ok" }), apiResultHandler);
|
||||
|
||||
// group of the services below are meant to be executed from the outside
|
||||
const setupApiRoute = buildSetupRoute(appConfig);
|
||||
route(GET, '/api/setup/status', [], setupApiRoute.getStatus, apiResultHandler);
|
||||
route(PST, '/api/setup/new-document', [auth.checkAppNotInitialized], setupApiRoute.setupNewDocument, apiResultHandler, false);
|
||||
route(PST, '/api/setup/sync-from-server', [auth.checkAppNotInitialized], setupApiRoute.setupSyncFromServer, apiResultHandler, false);
|
||||
|
@ -5,7 +5,7 @@ import setupService = require('../services/setup');
|
||||
import assetPath = require('../services/asset_path');
|
||||
import appPath = require('../services/app_path');
|
||||
import { Request, Response } from 'express';
|
||||
import { SetupCompleteCallback } from './types';
|
||||
import { SetupCompleteCallback } from '../types';
|
||||
|
||||
function buildSetupRoute(setupCompleteCallback: SetupCompleteCallback) {
|
||||
return (req: Request, res: Response) => {
|
||||
|
@ -1,8 +0,0 @@
|
||||
import { Response } from "express";
|
||||
|
||||
export type SetupCompleteCallback = (res: Response) => void;
|
||||
|
||||
export interface RouteConfig {
|
||||
/** Callback to be invoked when first setup is complete. */
|
||||
setupCompleteCallback: SetupCompleteCallback;
|
||||
}
|
@ -5,6 +5,7 @@ import log = require('./log');
|
||||
import dateUtils = require('./date_utils');
|
||||
import keyboardActions = require('./keyboard_actions');
|
||||
import { KeyboardShortcutWithRequiredActionName } from './keyboard_actions_interface';
|
||||
import { InitDbOptions } from '../types';
|
||||
|
||||
function initDocumentOptions() {
|
||||
optionService.createOption('documentId', utils.randomSecureToken(16), false);
|
||||
@ -16,7 +17,7 @@ interface NotSyncedOpts {
|
||||
syncProxy?: string;
|
||||
}
|
||||
|
||||
function initNotSyncedOptions(initialized: boolean, opts: NotSyncedOpts = {}) {
|
||||
function initNotSyncedOptions(initialized: boolean, opts: NotSyncedOpts = {}, initOptions: InitDbOptions) {
|
||||
optionService.createOption('openNoteContexts', JSON.stringify([
|
||||
{
|
||||
notePath: 'root',
|
||||
@ -32,17 +33,9 @@ function initNotSyncedOptions(initialized: boolean, opts: NotSyncedOpts = {}) {
|
||||
optionService.createOption('initialized', initialized ? 'true' : 'false', false);
|
||||
|
||||
optionService.createOption('lastSyncedPull', '0', false);
|
||||
optionService.createOption('lastSyncedPush', '0', false);
|
||||
optionService.createOption('lastSyncedPush', '0', false);
|
||||
|
||||
let theme = 'dark'; // default based on the poll in https://github.com/zadam/trilium/issues/2516
|
||||
|
||||
if (utils.isElectron()) {
|
||||
const {nativeTheme} = require('electron');
|
||||
|
||||
theme = nativeTheme.shouldUseDarkColors ? 'dark' : 'light';
|
||||
}
|
||||
|
||||
optionService.createOption('theme', theme, false);
|
||||
optionService.createOption('theme', initOptions.getInitialTheme(), false);
|
||||
|
||||
optionService.createOption('syncServerHost', opts.syncServerHost || '', false);
|
||||
optionService.createOption('syncServerTimeout', '120000', false);
|
||||
|
@ -8,6 +8,7 @@ import appInfo = require('./app_info');
|
||||
import utils = require('./utils');
|
||||
import becca = require('../becca/becca');
|
||||
import { SetupStatusResponse, SetupSyncSeedResponse } from './api-interface';
|
||||
import { InitDbOptions } from '../types';
|
||||
|
||||
async function hasSyncServerSchemaAndSeed() {
|
||||
const response = await requestToSyncServer<SetupStatusResponse>('GET', '/api/setup/status');
|
||||
@ -56,7 +57,7 @@ async function requestToSyncServer<T>(method: string, path: string, body?: strin
|
||||
}), timeout) as T;
|
||||
}
|
||||
|
||||
async function setupSyncFromSyncServer(syncServerHost: string, syncProxy: string, password: string) {
|
||||
async function setupSyncFromSyncServer(syncServerHost: string, syncProxy: string, password: string, initOptions: InitDbOptions) {
|
||||
if (sqlInit.isDbInitialized()) {
|
||||
return {
|
||||
result: 'failure',
|
||||
@ -87,7 +88,7 @@ async function setupSyncFromSyncServer(syncServerHost: string, syncProxy: string
|
||||
}
|
||||
}
|
||||
|
||||
sqlInit.createDatabaseForSync(resp.options, syncServerHost, syncProxy);
|
||||
sqlInit.createDatabaseForSync(resp.options, initOptions, syncServerHost, syncProxy);
|
||||
|
||||
triggerSync();
|
||||
|
||||
|
@ -11,6 +11,8 @@ import migrationService = require('./migration');
|
||||
import cls = require('./cls');
|
||||
import config = require('./config');
|
||||
import { OptionRow } from '../becca/entities/rows';
|
||||
import optionsInitService = require("./options_init");
|
||||
import { InitDbOptions } from '../types';
|
||||
|
||||
const dbReady = utils.deferred<void>();
|
||||
|
||||
@ -46,7 +48,7 @@ async function initDbConnection() {
|
||||
dbReady.resolve();
|
||||
}
|
||||
|
||||
async function createInitialDatabase() {
|
||||
async function createInitialDatabase(initOptions: InitDbOptions) {
|
||||
if (isDbInitialized()) {
|
||||
throw new Error("DB is already initialized");
|
||||
}
|
||||
@ -84,10 +86,8 @@ async function createInitialDatabase() {
|
||||
notePosition: 10
|
||||
}).save();
|
||||
|
||||
const optionsInitService = require('./options_init');
|
||||
|
||||
optionsInitService.initDocumentOptions();
|
||||
optionsInitService.initNotSyncedOptions(true, {});
|
||||
optionsInitService.initNotSyncedOptions(true, {}, initOptions);
|
||||
optionsInitService.initStartupOptions();
|
||||
require('./encryption/password').resetPassword();
|
||||
});
|
||||
@ -120,7 +120,7 @@ async function createInitialDatabase() {
|
||||
initDbConnection();
|
||||
}
|
||||
|
||||
function createDatabaseForSync(options: OptionRow[], syncServerHost = '', syncProxy = '') {
|
||||
function createDatabaseForSync(options: OptionRow[], initOptions: InitDbOptions, syncServerHost = '', syncProxy = '') {
|
||||
log.info("Creating database for sync");
|
||||
|
||||
if (isDbInitialized()) {
|
||||
@ -132,7 +132,7 @@ function createDatabaseForSync(options: OptionRow[], syncServerHost = '', syncPr
|
||||
sql.transactional(() => {
|
||||
sql.executeScript(schema);
|
||||
|
||||
require('./options_init').initNotSyncedOptions(false, { syncServerHost, syncProxy });
|
||||
optionsInitService.initNotSyncedOptions(false, { syncServerHost, syncProxy }, initOptions);
|
||||
|
||||
// document options required for sync to kick off
|
||||
for (const opt of options) {
|
||||
|
23
server/src/types.ts
Normal file
23
server/src/types.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { Response } from "express";
|
||||
|
||||
export type InitialThemeCallback = () => "dark" | "light";
|
||||
|
||||
export type SetupCompleteCallback = (res: Response) => void;
|
||||
|
||||
/**
|
||||
* Options needed when the database is first initialized, such as methods to obtain default values.
|
||||
*/
|
||||
export interface InitDbOptions {
|
||||
/**
|
||||
* Called during first setup, in order to determine which theme to set for the user.
|
||||
*/
|
||||
getInitialTheme: InitialThemeCallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles differences between clients, for example allowing different behaviour when running from the web server versus the desktop application.
|
||||
*/
|
||||
export interface AppConfig extends InitDbOptions {
|
||||
/** Callback to be invoked when first setup is complete. */
|
||||
setupCompleteCallback: SetupCompleteCallback;
|
||||
}
|
@ -31,9 +31,9 @@ import port = require('./services/port');
|
||||
import host = require('./services/host');
|
||||
import semver = require('semver');
|
||||
import type { Express } from "express";
|
||||
import { RouteConfig } from './routes/types';
|
||||
import { AppConfig } from './types';
|
||||
|
||||
function startTrilium(routeConfig: RouteConfig) {
|
||||
function startTrilium(appConfig: AppConfig) {
|
||||
if (!semver.satisfies(process.version, ">=10.5.0")) {
|
||||
console.error("Trilium only supports node.js 10.5 and later");
|
||||
process.exit(1);
|
||||
@ -41,7 +41,7 @@ function startTrilium(routeConfig: RouteConfig) {
|
||||
|
||||
log.info(JSON.stringify(appInfo, null, 2));
|
||||
|
||||
const app = buildApp(routeConfig);
|
||||
const app = buildApp(appConfig);
|
||||
|
||||
const cpuInfos = require('os').cpus();
|
||||
if (cpuInfos && cpuInfos[0] !== undefined) { // https://github.com/zadam/trilium/pull/3957
|
||||
|
Loading…
x
Reference in New Issue
Block a user