From 79c9d7e3056e2712d95ee76e71b044f1ae9523e0 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sun, 7 Apr 2024 14:02:52 +0300 Subject: [PATCH 01/10] server-ts: Convert routes/assets --- src/app.js | 2 +- src/routes/{assets.js => assets.ts} | 15 ++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) rename src/routes/{assets.js => assets.ts} (91%) diff --git a/src/app.js b/src/app.js index 601ed0ece..01cc83760 100644 --- a/src/app.js +++ b/src/app.js @@ -37,7 +37,7 @@ app.use(`/robots.txt`, express.static(path.join(__dirname, 'public/robots.txt')) app.use(sessionParser); app.use(favicon(`${__dirname}/../images/app-icons/win/icon.ico`)); -require('./routes/assets.js').register(app); +require('./routes/assets').register(app); require('./routes/routes.js').register(app); require('./routes/custom.js').register(app); require('./routes/error_handlers.js').register(app); diff --git a/src/routes/assets.js b/src/routes/assets.ts similarity index 91% rename from src/routes/assets.js rename to src/routes/assets.ts index b6b46332c..6ebfd8313 100644 --- a/src/routes/assets.js +++ b/src/routes/assets.ts @@ -1,9 +1,10 @@ -const assetPath = require('../services/asset_path'); -const path = require("path"); -const express = require("express"); -const env = require('../services/env'); +import assetPath = require('../services/asset_path'); +import path = require("path"); +import express = require("express"); +import env = require('../services/env'); +import serveStatic = require('serve-static'); -const persistentCacheStatic = (root, options) => { +const persistentCacheStatic = (root: string, options?: serveStatic.ServeStaticOptions>>) => { if (!env.isDev()) { options = { maxAge: '1y', @@ -13,7 +14,7 @@ const persistentCacheStatic = (root, options) => { return express.static(root, options); }; -function register(app) { +function register(app: express.Application) { const srcRoot = path.join(__dirname, '..'); app.use(`/${assetPath}/app`, persistentCacheStatic(path.join(srcRoot, 'public/app'))); app.use(`/${assetPath}/app-dist`, persistentCacheStatic(path.join(srcRoot, 'public/app-dist'))); @@ -70,6 +71,6 @@ function register(app) { app.use(`/${assetPath}/node_modules/panzoom/dist/`, persistentCacheStatic(path.join(srcRoot, '..', 'node_modules/panzoom/dist/'))); } -module.exports = { +export = { register }; From 4940207b15836e46eb9114969d3df374e782844a Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sun, 7 Apr 2024 14:05:50 +0300 Subject: [PATCH 02/10] server-ts: Convert routes/custom --- src/app.js | 2 +- src/routes/{custom.js => custom.ts} | 29 ++++++++++---------- src/services/backend_script_api_interface.ts | 4 +++ 3 files changed, 20 insertions(+), 15 deletions(-) rename src/routes/{custom.js => custom.ts} (72%) diff --git a/src/app.js b/src/app.js index 01cc83760..ba4d2da87 100644 --- a/src/app.js +++ b/src/app.js @@ -39,7 +39,7 @@ app.use(favicon(`${__dirname}/../images/app-icons/win/icon.ico`)); require('./routes/assets').register(app); require('./routes/routes.js').register(app); -require('./routes/custom.js').register(app); +require('./routes/custom').register(app); require('./routes/error_handlers.js').register(app); // triggers sync timer diff --git a/src/routes/custom.js b/src/routes/custom.ts similarity index 72% rename from src/routes/custom.js rename to src/routes/custom.ts index 2e32e5446..1bdb94ac0 100644 --- a/src/routes/custom.js +++ b/src/routes/custom.ts @@ -1,21 +1,22 @@ -const log = require('../services/log'); -const fileService = require('./api/files'); -const scriptService = require('../services/script'); -const cls = require('../services/cls'); -const sql = require('../services/sql'); -const becca = require('../becca/becca'); +import log = require('../services/log'); +import fileService = require('./api/files'); +import scriptService = require('../services/script'); +import cls = require('../services/cls'); +import sql = require('../services/sql'); +import becca = require('../becca/becca'); +import { Request, Response, Router } from 'express'; -function handleRequest(req, res) { +function handleRequest(req: Request, res: Response) { // express puts content after first slash into 0 index element const path = req.params.path + req.params[0]; - const attributeIds = sql.getColumn("SELECT attributeId FROM attributes WHERE isDeleted = 0 AND type = 'label' AND name IN ('customRequestHandler', 'customResourceProvider')"); + const attributeIds = sql.getColumn("SELECT attributeId FROM attributes WHERE isDeleted = 0 AND type = 'label' AND name IN ('customRequestHandler', 'customResourceProvider')"); const attrs = attributeIds.map(attrId => becca.getAttribute(attrId)); for (const attr of attrs) { - if (!attr.value.trim()) { + if (!attr?.value.trim()) { continue; } @@ -25,7 +26,7 @@ function handleRequest(req, res) { try { match = path.match(regex); } - catch (e) { + catch (e: any) { log.error(`Testing path for label '${attr.attributeId}', regex '${attr.value}' failed with error: ${e.message}, stack: ${e.stack}`); continue; } @@ -46,7 +47,7 @@ function handleRequest(req, res) { res }); } - catch (e) { + catch (e: any) { log.error(`Custom handler '${note.noteId}' failed with: ${e.message}, ${e.stack}`); res.setHeader("Content-Type", "text/plain") @@ -72,10 +73,10 @@ function handleRequest(req, res) { .send(message); } -function register(router) { +function register(router: Router) { // explicitly no CSRF middleware since it's meant to allow integration from external services - router.all('/custom/:path*', (req, res, next) => { + router.all('/custom/:path*', (req: Request, res: Response, next) => { cls.namespace.bindEmitter(req); cls.namespace.bindEmitter(res); @@ -83,6 +84,6 @@ function register(router) { }); } -module.exports = { +export = { register }; diff --git a/src/services/backend_script_api_interface.ts b/src/services/backend_script_api_interface.ts index 7031d1bc3..f74b65ad7 100644 --- a/src/services/backend_script_api_interface.ts +++ b/src/services/backend_script_api_interface.ts @@ -1,7 +1,11 @@ +import { Request, Response } from "express"; import AbstractBeccaEntity = require("../becca/entities/abstract_becca_entity"); import BNote = require("../becca/entities/bnote"); export interface ApiParams { startNote?: BNote; originEntity?: AbstractBeccaEntity; + pathParams?: string[], + req?: Request, + res?: Response } \ No newline at end of file From 202fda3c3082fc48674d1f86cdaa852e35d2d873 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sun, 7 Apr 2024 14:09:37 +0300 Subject: [PATCH 03/10] server-ts: Convert routes/electron --- src/routes/{electron.js => electron.ts} | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) rename src/routes/{electron.js => electron.ts} (73%) diff --git a/src/routes/electron.js b/src/routes/electron.ts similarity index 73% rename from src/routes/electron.js rename to src/routes/electron.ts index b356dd942..8a869d935 100644 --- a/src/routes/electron.js +++ b/src/routes/electron.ts @@ -1,6 +1,17 @@ +import { Application } from "express"; + const ipcMain = require('electron').ipcMain; -function init(app) { +interface Response { + statusCode: number; + getHeader: (name: string) => string; + setHeader: (name: string, value: string) => Response; + header: (name: string, value: string) => Response; + status: (statusCode: number) => Response; + send: (obj: {}) => void; +} + +function init(app: Application) { ipcMain.on('server-request', (event, arg) => { const req = { url: arg.url, @@ -12,9 +23,9 @@ function init(app) { } }; - const respHeaders = {}; + const respHeaders: Record = {}; - const res = { + const res: Response = { statusCode: 200, getHeader: name => respHeaders[name], setHeader: (name, value) => { @@ -45,4 +56,4 @@ function init(app) { }); } -module.exports = init; +export = init; From c2eefad28766c1a194e5b897db05a593d598bab5 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sun, 7 Apr 2024 14:13:57 +0300 Subject: [PATCH 04/10] server-ts: Convert routes/error_handlers --- src/app.js | 2 +- src/routes/{error_handlers.js => error_handlers.ts} | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) rename src/routes/{error_handlers.js => error_handlers.ts} (73%) diff --git a/src/app.js b/src/app.js index ba4d2da87..8c812dafe 100644 --- a/src/app.js +++ b/src/app.js @@ -40,7 +40,7 @@ app.use(favicon(`${__dirname}/../images/app-icons/win/icon.ico`)); require('./routes/assets').register(app); require('./routes/routes.js').register(app); require('./routes/custom').register(app); -require('./routes/error_handlers.js').register(app); +require('./routes/error_handlers').register(app); // triggers sync timer require('./services/sync'); diff --git a/src/routes/error_handlers.js b/src/routes/error_handlers.ts similarity index 73% rename from src/routes/error_handlers.js rename to src/routes/error_handlers.ts index 4d17b0d5d..96d326bd9 100644 --- a/src/routes/error_handlers.js +++ b/src/routes/error_handlers.ts @@ -1,7 +1,8 @@ -const log = require('../services/log'); +import { Application, NextFunction, Request, Response } from 'express'; +import log = require('../services/log'); -function register(app) { - app.use((err, req, res, next) => { +function register(app: Application) { + app.use((err: any, req: Request, res: Response, next: NextFunction) => { if (err.code !== 'EBADCSRFTOKEN') { return next(err); } @@ -16,12 +17,12 @@ function register(app) { // catch 404 and forward to error handler app.use((req, res, next) => { const err = new Error(`Router not found for request ${req.method} ${req.url}`); - err.status = 404; + (err as any).status = 404; next(err); }); // error handler - app.use((err, req, res, next) => { + app.use((err: any, req: Request, res: Response, next: NextFunction) => { if (err && err.message && ( (err.message.includes("Router not found for request") && err.message.includes(".js.map")) || (err.message.includes("Router not found for request") && err.message.includes(".css.map")) @@ -38,6 +39,6 @@ function register(app) { }); } -module.exports = { +export = { register }; From 7fe6d1ab4d479f6bfad0638a95d6514e100b7c08 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sun, 7 Apr 2024 14:22:01 +0300 Subject: [PATCH 05/10] server-ts: Convert routes/login --- src/routes/{login.js => login.ts} | 32 ++++++++++++++++--------------- src/routes/route-interface.ts | 16 ++++++++++++++++ src/routes/routes.js | 2 +- src/services/auth.ts | 11 +---------- 4 files changed, 35 insertions(+), 26 deletions(-) rename src/routes/{login.js => login.ts} (71%) create mode 100644 src/routes/route-interface.ts diff --git a/src/routes/login.js b/src/routes/login.ts similarity index 71% rename from src/routes/login.js rename to src/routes/login.ts index 649e9b854..a4c13ca90 100644 --- a/src/routes/login.js +++ b/src/routes/login.ts @@ -1,15 +1,17 @@ "use strict"; -const utils = require('../services/utils'); -const optionService = require('../services/options'); -const myScryptService = require('../services/encryption/my_scrypt'); -const log = require('../services/log'); -const passwordService = require('../services/encryption/password'); -const assetPath = require('../services/asset_path'); -const appPath = require('../services/app_path'); -const ValidationError = require('../errors/validation_error'); +import utils = require('../services/utils'); +import optionService = require('../services/options'); +import myScryptService = require('../services/encryption/my_scrypt'); +import log = require('../services/log'); +import passwordService = require('../services/encryption/password'); +import assetPath = require('../services/asset_path'); +import appPath = require('../services/app_path'); +import ValidationError = require('../errors/validation_error'); +import { Request, Response } from 'express'; +import { AppRequest } from './route-interface'; -function loginPage(req, res) { +function loginPage(req: Request, res: Response) { res.render('login', { failedAuth: false, assetPath: assetPath, @@ -17,7 +19,7 @@ function loginPage(req, res) { }); } -function setPasswordPage(req, res) { +function setPasswordPage(req: Request, res: Response) { res.render('set_password', { error: false, assetPath: assetPath, @@ -25,7 +27,7 @@ function setPasswordPage(req, res) { }); } -function setPassword(req, res) { +function setPassword(req: Request, res: Response) { if (passwordService.isPasswordSet()) { throw new ValidationError("Password has been already set"); } @@ -55,7 +57,7 @@ function setPassword(req, res) { res.redirect('login'); } -function login(req, res) { +function login(req: AppRequest, res: Response) { const guessedPassword = req.body.password; if (verifyPassword(guessedPassword)) { @@ -83,7 +85,7 @@ function login(req, res) { } } -function verifyPassword(guessedPassword) { +function verifyPassword(guessedPassword: string) { const hashed_password = utils.fromBase64(optionService.getOption('passwordVerificationHash')); const guess_hashed = myScryptService.getVerificationHash(guessedPassword); @@ -91,7 +93,7 @@ function verifyPassword(guessedPassword) { return guess_hashed.equals(hashed_password); } -function logout(req, res) { +function logout(req: AppRequest, res: Response) { req.session.regenerate(() => { req.session.loggedIn = false; @@ -100,7 +102,7 @@ function logout(req, res) { } -module.exports = { +export = { loginPage, setPasswordPage, setPassword, diff --git a/src/routes/route-interface.ts b/src/routes/route-interface.ts new file mode 100644 index 000000000..969b4be5f --- /dev/null +++ b/src/routes/route-interface.ts @@ -0,0 +1,16 @@ +import { Request } from "express"; + +export interface AppRequest extends Request { + headers: { + authorization?: string; + "trilium-cred"?: string; + } + session: { + loggedIn: boolean; + cookie: { + maxAge: number; + expires: boolean + }; + regenerate: (callback: () => void) => void; + } +} \ No newline at end of file diff --git a/src/routes/routes.js b/src/routes/routes.js index 2e53e4546..7c0df5fcf 100644 --- a/src/routes/routes.js +++ b/src/routes/routes.js @@ -18,7 +18,7 @@ const ValidationError = require('../errors/validation_error'); // page routes const setupRoute = require('./setup'); -const loginRoute = require('./login.js'); +const loginRoute = require('./login'); const indexRoute = require('./index.js'); // API routes diff --git a/src/services/auth.ts b/src/services/auth.ts index d54a1ea96..39f2b430e 100644 --- a/src/services/auth.ts +++ b/src/services/auth.ts @@ -8,19 +8,10 @@ import passwordEncryptionService = require('./encryption/password_encryption'); import config = require('./config'); import passwordService = require('./encryption/password'); import type { NextFunction, Request, Response } from 'express'; +import { AppRequest } from '../routes/route-interface'; const noAuthentication = config.General && config.General.noAuthentication === true; -interface AppRequest extends Request { - headers: { - authorization?: string; - "trilium-cred"?: string; - } - session: { - loggedIn: boolean; - } -} - function checkAuth(req: AppRequest, res: Response, next: NextFunction) { if (!sqlInit.isDbInitialized()) { res.redirect("setup"); From 34cd2eba9129383cb2537165b743a9a7beef800a Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sun, 7 Apr 2024 14:29:08 +0300 Subject: [PATCH 06/10] server-ts: Remove use of (req as any) --- src/routes/api/files.ts | 9 +++++---- src/routes/api/image.ts | 12 ++++++++++-- src/routes/api/import.ts | 11 ++++++----- src/routes/api/login.ts | 5 +++-- src/routes/api/sender.ts | 14 +++++++------- src/routes/route-interface.ts | 4 ++++ src/services/import/opml.ts | 2 +- 7 files changed, 36 insertions(+), 21 deletions(-) diff --git a/src/routes/api/files.ts b/src/routes/api/files.ts index 4a536954b..44cd1dacf 100644 --- a/src/routes/api/files.ts +++ b/src/routes/api/files.ts @@ -14,11 +14,12 @@ import ValidationError = require('../../errors/validation_error'); import { Request, Response } from 'express'; import BNote = require('../../becca/entities/bnote'); import BAttachment = require('../../becca/entities/battachment'); +import { AppRequest } from '../route-interface'; -function updateFile(req: Request) { +function updateFile(req: AppRequest) { const note = becca.getNoteOrThrow(req.params.noteId); - const file = (req as any).file; + const file = req.file; note.saveRevision(); note.mime = file.mimetype.toLowerCase(); @@ -35,9 +36,9 @@ function updateFile(req: Request) { }; } -function updateAttachment(req: Request) { +function updateAttachment(req: AppRequest) { const attachment = becca.getAttachmentOrThrow(req.params.attachmentId); - const file = (req as any).file; + const file = req.file; attachment.getNote().saveRevision(); diff --git a/src/routes/api/image.ts b/src/routes/api/image.ts index 1a2750195..a0ee6140c 100644 --- a/src/routes/api/image.ts +++ b/src/routes/api/image.ts @@ -7,6 +7,7 @@ import fs = require('fs'); import { Request, Response } from 'express'; import BNote = require('../../becca/entities/bnote'); import BRevision = require('../../becca/entities/brevision'); +import { AppRequest } from '../route-interface'; function returnImageFromNote(req: Request, res: Response) { const image = becca.getNote(req.params.noteId); @@ -81,9 +82,9 @@ function returnAttachedImage(req: Request, res: Response) { res.send(attachment.getContent()); } -function updateImage(req: Request) { +function updateImage(req: AppRequest) { const {noteId} = req.params; - const {file} = (req as any); + const {file} = req; const note = becca.getNoteOrThrow(noteId); @@ -94,6 +95,13 @@ function updateImage(req: Request) { }; } + if (typeof file.buffer === "string") { + return { + uploaded: false, + message: "Invalid image content." + }; + } + imageService.updateImage(noteId, file.buffer, file.originalname); return { uploaded: true }; diff --git a/src/routes/api/import.ts b/src/routes/api/import.ts index 6062ae37f..f4e0b446e 100644 --- a/src/routes/api/import.ts +++ b/src/routes/api/import.ts @@ -13,8 +13,9 @@ import TaskContext = require('../../services/task_context'); import ValidationError = require('../../errors/validation_error'); import { Request } from 'express'; import BNote = require('../../becca/entities/bnote'); +import { AppRequest } from '../route-interface'; -async function importNotesToBranch(req: Request) { +async function importNotesToBranch(req: AppRequest) { const { parentNoteId } = req.params; const { taskId, last } = req.body; @@ -27,7 +28,7 @@ async function importNotesToBranch(req: Request) { replaceUnderscoresWithSpaces: req.body.replaceUnderscoresWithSpaces !== 'false' }; - const file = (req as any).file; + const file = req.file; if (!file) { throw new ValidationError("No file has been uploaded"); @@ -49,7 +50,7 @@ async function importNotesToBranch(req: Request) { const taskContext = TaskContext.getInstance(taskId, 'importNotes', options); try { - if (extension === '.zip' && options.explodeArchives) { + if (extension === '.zip' && options.explodeArchives && typeof file.buffer !== "string") { note = await zipImportService.importZip(taskContext, file.buffer, parentNote); } else if (extension === '.opml' && options.explodeArchives) { const importResult = await opmlImportService.importOpml(taskContext, file.buffer, parentNote); @@ -96,7 +97,7 @@ async function importNotesToBranch(req: Request) { return note.getPojo(); } -async function importAttachmentsToNote(req: Request) { +async function importAttachmentsToNote(req: AppRequest) { const { parentNoteId } = req.params; const { taskId, last } = req.body; @@ -104,7 +105,7 @@ async function importAttachmentsToNote(req: Request) { shrinkImages: req.body.shrinkImages !== 'false', }; - const file = (req as any).file; + const file = req.file; if (!file) { throw new ValidationError("No file has been uploaded"); diff --git a/src/routes/api/login.ts b/src/routes/api/login.ts index a4c41c460..a769c4627 100644 --- a/src/routes/api/login.ts +++ b/src/routes/api/login.ts @@ -13,8 +13,9 @@ import sql = require('../../services/sql'); import ws = require('../../services/ws'); import etapiTokenService = require('../../services/etapi_tokens'); import { Request } from 'express'; +import { AppRequest } from '../route-interface'; -function loginSync(req: Request) { +function loginSync(req: AppRequest) { if (!sqlInit.schemaExists()) { return [500, { message: "DB schema does not exist, can't sync." }]; } @@ -45,7 +46,7 @@ function loginSync(req: Request) { return [400, { message: "Sync login credentials are incorrect. It looks like you're trying to sync two different initialized documents which is not possible." }]; } - (req as any).session.loggedIn = true; + req.session.loggedIn = true; return { instanceId: instanceId, diff --git a/src/routes/api/sender.ts b/src/routes/api/sender.ts index dc31c42f6..515011739 100644 --- a/src/routes/api/sender.ts +++ b/src/routes/api/sender.ts @@ -6,13 +6,17 @@ import noteService = require('../../services/notes'); import sanitize_attribute_name = require('../../services/sanitize_attribute_name'); import specialNotesService = require('../../services/special_notes'); import { Request } from 'express'; +import { AppRequest } from '../route-interface'; -function uploadImage(req: Request) { - const file = (req as any).file; +function uploadImage(req: AppRequest) { + const file = req.file; if (!["image/png", "image/jpeg", "image/gif", "image/webp", "image/svg+xml"].includes(file.mimetype)) { return [400, `Unknown image type: ${file.mimetype}`]; } + if (typeof file.buffer === "string") { + return [400, "Invalid image content type."]; + } const uploadedImageType = imageType(file.buffer); if (!uploadedImageType) { @@ -20,14 +24,10 @@ function uploadImage(req: Request) { } const originalName = `Sender image.${uploadedImageType.ext}`; - if (!req.headers["x-local-date"] || Array.isArray(req.headers["x-local-date"])) { + if (!req.headers["x-local-date"]) { return [400, "Invalid local date"]; } - if (Array.isArray(req.headers["x-labels"])) { - return [400, "Invalid value type."]; - } - const parentNote = specialNotesService.getInboxNote(req.headers['x-local-date']); const { note, noteId } = imageService.saveImage(parentNote.noteId, file.buffer, originalName, true); diff --git a/src/routes/route-interface.ts b/src/routes/route-interface.ts index 969b4be5f..acf86cbe5 100644 --- a/src/routes/route-interface.ts +++ b/src/routes/route-interface.ts @@ -1,9 +1,12 @@ import { Request } from "express"; +import { File } from "../services/import/common"; export interface AppRequest extends Request { headers: { authorization?: string; "trilium-cred"?: string; + "x-local-date"?: string; + "x-labels"?: string; } session: { loggedIn: boolean; @@ -13,4 +16,5 @@ export interface AppRequest extends Request { }; regenerate: (callback: () => void) => void; } + file: File; } \ No newline at end of file diff --git a/src/services/import/opml.ts b/src/services/import/opml.ts index 66d2e944b..78da6764c 100644 --- a/src/services/import/opml.ts +++ b/src/services/import/opml.ts @@ -28,7 +28,7 @@ interface OpmlOutline { outline: OpmlOutline[]; } -async function importOpml(taskContext: TaskContext, fileBuffer: Buffer, parentNote: BNote) { +async function importOpml(taskContext: TaskContext, fileBuffer: string | Buffer, parentNote: BNote) { const xml = await new Promise(function(resolve, reject) { parseString(fileBuffer, function (err: any, result: OpmlXml) { From 2e906af77d144bedc046199193ba70a65a9f8344 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sun, 7 Apr 2024 14:32:08 +0300 Subject: [PATCH 07/10] server-ts: Convert routes/session_parser --- package-lock.json | 19 +++++++++++++++++++ package.json | 1 + src/app.js | 2 +- .../{session_parser.js => session_parser.ts} | 8 ++++---- src/services/session_secret.ts | 2 +- 5 files changed, 26 insertions(+), 6 deletions(-) rename src/routes/{session_parser.js => session_parser.ts} (78%) diff --git a/package-lock.json b/package-lock.json index 6adfcaed4..3c5e38812 100644 --- a/package-lock.json +++ b/package-lock.json @@ -93,6 +93,7 @@ "@types/cls-hooked": "^4.3.8", "@types/escape-html": "^1.0.4", "@types/express": "^4.17.21", + "@types/express-session": "^1.18.0", "@types/html": "^1.0.4", "@types/ini": "^4.1.0", "@types/jsdom": "^21.1.6", @@ -1315,6 +1316,15 @@ "@types/send": "*" } }, + "node_modules/@types/express-session": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/@types/express-session/-/express-session-1.18.0.tgz", + "integrity": "sha512-27JdDRgor6PoYlURY+Y5kCakqp5ulC0kmf7y+QwaY+hv9jEFuQOThgkjyA53RP3jmKuBsH5GR6qEfFmvb8mwOA==", + "dev": true, + "dependencies": { + "@types/express": "*" + } + }, "node_modules/@types/fs-extra": { "version": "9.0.13", "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz", @@ -14293,6 +14303,15 @@ "@types/send": "*" } }, + "@types/express-session": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/@types/express-session/-/express-session-1.18.0.tgz", + "integrity": "sha512-27JdDRgor6PoYlURY+Y5kCakqp5ulC0kmf7y+QwaY+hv9jEFuQOThgkjyA53RP3jmKuBsH5GR6qEfFmvb8mwOA==", + "dev": true, + "requires": { + "@types/express": "*" + } + }, "@types/fs-extra": { "version": "9.0.13", "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz", diff --git a/package.json b/package.json index eead6dea0..106b21964 100644 --- a/package.json +++ b/package.json @@ -114,6 +114,7 @@ "@types/cls-hooked": "^4.3.8", "@types/escape-html": "^1.0.4", "@types/express": "^4.17.21", + "@types/express-session": "^1.18.0", "@types/html": "^1.0.4", "@types/ini": "^4.1.0", "@types/jsdom": "^21.1.6", diff --git a/src/app.js b/src/app.js index 8c812dafe..30daf58ea 100644 --- a/src/app.js +++ b/src/app.js @@ -4,7 +4,7 @@ const favicon = require('serve-favicon'); const cookieParser = require('cookie-parser'); const helmet = require('helmet'); const compression = require('compression'); -const sessionParser = require('./routes/session_parser.js'); +const sessionParser = require('./routes/session_parser'); const utils = require('./services/utils'); require('./services/handlers'); diff --git a/src/routes/session_parser.js b/src/routes/session_parser.ts similarity index 78% rename from src/routes/session_parser.js rename to src/routes/session_parser.ts index afe99fa2f..431476f15 100644 --- a/src/routes/session_parser.js +++ b/src/routes/session_parser.ts @@ -1,6 +1,6 @@ -const session = require("express-session"); -const sessionSecret = require('../services/session_secret'); -const dataDir = require('../services/data_dir'); +import session = require("express-session"); +import sessionSecret = require('../services/session_secret'); +import dataDir = require('../services/data_dir'); const FileStore = require('session-file-store')(session); const sessionParser = session({ @@ -19,4 +19,4 @@ const sessionParser = session({ }) }); -module.exports = sessionParser; +export = sessionParser; diff --git a/src/services/session_secret.ts b/src/services/session_secret.ts index 3721cf63f..20b35efb2 100644 --- a/src/services/session_secret.ts +++ b/src/services/session_secret.ts @@ -7,7 +7,7 @@ import log = require('./log'); const sessionSecretPath = `${dataDir.TRILIUM_DATA_DIR}/session_secret.txt`; -let sessionSecret; +let sessionSecret: string; const ENCODING = "ascii"; From a18b054dbba8dfe9373d5c5085ea2c9c7a4a343a Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sun, 7 Apr 2024 14:33:41 +0300 Subject: [PATCH 08/10] server-ts: Convert routes/setup --- src/routes/{setup.js => setup.ts} | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) rename src/routes/{setup.js => setup.ts} (70%) diff --git a/src/routes/setup.js b/src/routes/setup.ts similarity index 70% rename from src/routes/setup.js rename to src/routes/setup.ts index f99bc8c51..1d3521f4a 100644 --- a/src/routes/setup.js +++ b/src/routes/setup.ts @@ -1,12 +1,13 @@ "use strict"; -const sqlInit = require('../services/sql_init'); -const setupService = require('../services/setup'); -const utils = require('../services/utils'); -const assetPath = require('../services/asset_path'); -const appPath = require('../services/app_path'); +import sqlInit = require('../services/sql_init'); +import setupService = require('../services/setup'); +import utils = require('../services/utils'); +import assetPath = require('../services/asset_path'); +import appPath = require('../services/app_path'); +import { Request, Response } from 'express'; -function setupPage(req, res) { +function setupPage(req: Request, res: Response) { if (sqlInit.isDbInitialized()) { if (utils.isElectron()) { const windowService = require('../services/window'); @@ -37,6 +38,6 @@ function setupPage(req, res) { }); } -module.exports = { +export = { setupPage }; From 10c21d34039c7e7feacf7f923bc5ff61e50ab84a Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sun, 7 Apr 2024 14:36:47 +0300 Subject: [PATCH 09/10] server-ts: Convert routes/index --- package-lock.json | 19 +++++++++++++++++++ package.json | 1 + src/routes/{index.js => index.ts} | 29 +++++++++++++++-------------- src/routes/routes.js | 2 +- 4 files changed, 36 insertions(+), 15 deletions(-) rename src/routes/{index.js => index.ts} (72%) diff --git a/package-lock.json b/package-lock.json index 3c5e38812..5976c203c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -91,6 +91,7 @@ "@types/archiver": "^6.0.2", "@types/better-sqlite3": "^7.6.9", "@types/cls-hooked": "^4.3.8", + "@types/csurf": "^1.11.5", "@types/escape-html": "^1.0.4", "@types/express": "^4.17.21", "@types/express-session": "^1.18.0", @@ -1234,6 +1235,15 @@ "@types/node": "*" } }, + "node_modules/@types/csurf": { + "version": "1.11.5", + "resolved": "https://registry.npmjs.org/@types/csurf/-/csurf-1.11.5.tgz", + "integrity": "sha512-5rw87+5YGixyL2W8wblSUl5DSZi5YOlXE6Awwn2ofLvqKr/1LruKffrQipeJKUX44VaxKj8m5es3vfhltJTOoA==", + "dev": true, + "dependencies": { + "@types/express-serve-static-core": "*" + } + }, "node_modules/@types/d3-scale": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz", @@ -14221,6 +14231,15 @@ "@types/node": "*" } }, + "@types/csurf": { + "version": "1.11.5", + "resolved": "https://registry.npmjs.org/@types/csurf/-/csurf-1.11.5.tgz", + "integrity": "sha512-5rw87+5YGixyL2W8wblSUl5DSZi5YOlXE6Awwn2ofLvqKr/1LruKffrQipeJKUX44VaxKj8m5es3vfhltJTOoA==", + "dev": true, + "requires": { + "@types/express-serve-static-core": "*" + } + }, "@types/d3-scale": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz", diff --git a/package.json b/package.json index 106b21964..efb6aae02 100644 --- a/package.json +++ b/package.json @@ -112,6 +112,7 @@ "@types/archiver": "^6.0.2", "@types/better-sqlite3": "^7.6.9", "@types/cls-hooked": "^4.3.8", + "@types/csurf": "^1.11.5", "@types/escape-html": "^1.0.4", "@types/express": "^4.17.21", "@types/express-session": "^1.18.0", diff --git a/src/routes/index.js b/src/routes/index.ts similarity index 72% rename from src/routes/index.js rename to src/routes/index.ts index 44c609834..2ede70f42 100644 --- a/src/routes/index.js +++ b/src/routes/index.ts @@ -1,18 +1,19 @@ "use strict"; -const sql = require('../services/sql'); -const attributeService = require('../services/attributes'); -const config = require('../services/config'); -const optionService = require('../services/options'); -const log = require('../services/log'); -const env = require('../services/env'); -const utils = require('../services/utils'); -const protectedSessionService = require('../services/protected_session'); -const packageJson = require('../../package.json'); -const assetPath = require('../services/asset_path'); -const appPath = require('../services/app_path'); +import sql = require('../services/sql'); +import attributeService = require('../services/attributes'); +import config = require('../services/config'); +import optionService = require('../services/options'); +import log = require('../services/log'); +import env = require('../services/env'); +import utils = require('../services/utils'); +import protectedSessionService = require('../services/protected_session'); +import packageJson = require('../../package.json'); +import assetPath = require('../services/asset_path'); +import appPath = require('../services/app_path'); +import { Request, Response } from 'express'; -function index(req, res) { +function index(req: Request, res: Response) { const options = optionService.getOptionMap(); const view = (!utils.isElectron() && req.cookies['trilium-device'] === 'mobile') @@ -43,7 +44,7 @@ function index(req, res) { }); } -function getThemeCssUrl(theme) { +function getThemeCssUrl(theme: string) { if (theme === 'light') { return false; // light theme is always loaded as baseline } else if (theme === 'dark') { @@ -63,6 +64,6 @@ function getAppCssNoteIds() { return attributeService.getNotesWithLabel('appCss').map(note => note.noteId); } -module.exports = { +export = { index }; diff --git a/src/routes/routes.js b/src/routes/routes.js index 7c0df5fcf..182639b84 100644 --- a/src/routes/routes.js +++ b/src/routes/routes.js @@ -19,7 +19,7 @@ const ValidationError = require('../errors/validation_error'); // page routes const setupRoute = require('./setup'); const loginRoute = require('./login'); -const indexRoute = require('./index.js'); +const indexRoute = require('./index'); // API routes const treeApiRoute = require('./api/tree'); From b8eb301f34abd59dbd24b9c47b2fadf1a00b5023 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sun, 7 Apr 2024 14:38:51 +0300 Subject: [PATCH 10/10] server-ts: Add types for multer --- package-lock.json | 19 +++++++++++++++++++ package.json | 1 + 2 files changed, 20 insertions(+) diff --git a/package-lock.json b/package-lock.json index 5976c203c..e80b41f85 100644 --- a/package-lock.json +++ b/package-lock.json @@ -99,6 +99,7 @@ "@types/ini": "^4.1.0", "@types/jsdom": "^21.1.6", "@types/mime-types": "^2.1.4", + "@types/multer": "^1.4.11", "@types/node": "^20.11.19", "@types/sanitize-html": "^2.11.0", "@types/sax": "^1.2.7", @@ -1479,6 +1480,15 @@ "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.32.tgz", "integrity": "sha512-xPSg0jm4mqgEkNhowKgZFBNtwoEwF6gJ4Dhww+GFpm3IgtNseHQZ5IqdNwnquZEoANxyDAKDRAdVo4Z72VvD/g==" }, + "node_modules/@types/multer": { + "version": "1.4.11", + "resolved": "https://registry.npmjs.org/@types/multer/-/multer-1.4.11.tgz", + "integrity": "sha512-svK240gr6LVWvv3YGyhLlA+6LRRWA4mnGIU7RcNmgjBYFl6665wcXrRfxGp5tEPVHUNm5FMcmq7too9bxCwX/w==", + "dev": true, + "dependencies": { + "@types/express": "*" + } + }, "node_modules/@types/node": { "version": "20.11.19", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.19.tgz", @@ -14468,6 +14478,15 @@ "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.32.tgz", "integrity": "sha512-xPSg0jm4mqgEkNhowKgZFBNtwoEwF6gJ4Dhww+GFpm3IgtNseHQZ5IqdNwnquZEoANxyDAKDRAdVo4Z72VvD/g==" }, + "@types/multer": { + "version": "1.4.11", + "resolved": "https://registry.npmjs.org/@types/multer/-/multer-1.4.11.tgz", + "integrity": "sha512-svK240gr6LVWvv3YGyhLlA+6LRRWA4mnGIU7RcNmgjBYFl6665wcXrRfxGp5tEPVHUNm5FMcmq7too9bxCwX/w==", + "dev": true, + "requires": { + "@types/express": "*" + } + }, "@types/node": { "version": "20.11.19", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.19.tgz", diff --git a/package.json b/package.json index efb6aae02..89ccc993c 100644 --- a/package.json +++ b/package.json @@ -120,6 +120,7 @@ "@types/ini": "^4.1.0", "@types/jsdom": "^21.1.6", "@types/mime-types": "^2.1.4", + "@types/multer": "^1.4.11", "@types/node": "^20.11.19", "@types/sanitize-html": "^2.11.0", "@types/sax": "^1.2.7",