mirror of
				https://github.com/TriliumNext/Notes.git
				synced 2025-11-04 15:11:31 +08:00 
			
		
		
		
	Merge pull request #635 from TriliumNext/renovate/express-5.x
chore(deps): update dependency @types/express to v5
This commit is contained in:
		
						commit
						c6e8a2a459
					
				
							
								
								
									
										23
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										23
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							@ -120,7 +120,7 @@
 | 
				
			|||||||
        "@types/ejs": "3.1.5",
 | 
					        "@types/ejs": "3.1.5",
 | 
				
			||||||
        "@types/electron-squirrel-startup": "1.0.2",
 | 
					        "@types/electron-squirrel-startup": "1.0.2",
 | 
				
			||||||
        "@types/escape-html": "1.0.4",
 | 
					        "@types/escape-html": "1.0.4",
 | 
				
			||||||
        "@types/express": "4.17.21",
 | 
					        "@types/express": "5.0.0",
 | 
				
			||||||
        "@types/express-session": "1.18.1",
 | 
					        "@types/express-session": "1.18.1",
 | 
				
			||||||
        "@types/html": "1.0.4",
 | 
					        "@types/html": "1.0.4",
 | 
				
			||||||
        "@types/ini": "4.1.1",
 | 
					        "@types/ini": "4.1.1",
 | 
				
			||||||
@ -3788,13 +3788,14 @@
 | 
				
			|||||||
      "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="
 | 
					      "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "node_modules/@types/express": {
 | 
					    "node_modules/@types/express": {
 | 
				
			||||||
      "version": "4.17.21",
 | 
					      "version": "5.0.0",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.0.tgz",
 | 
				
			||||||
      "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==",
 | 
					      "integrity": "sha512-DvZriSMehGHL1ZNLzi6MidnsDhUZM/x2pRdDIKdwbUNqqwHxMlRdkxtn6/EPKyqKpHqTl/4nRZsRNLpZxZRpPQ==",
 | 
				
			||||||
      "dev": true,
 | 
					      "dev": true,
 | 
				
			||||||
 | 
					      "license": "MIT",
 | 
				
			||||||
      "dependencies": {
 | 
					      "dependencies": {
 | 
				
			||||||
        "@types/body-parser": "*",
 | 
					        "@types/body-parser": "*",
 | 
				
			||||||
        "@types/express-serve-static-core": "^4.17.33",
 | 
					        "@types/express-serve-static-core": "^5.0.0",
 | 
				
			||||||
        "@types/qs": "*",
 | 
					        "@types/qs": "*",
 | 
				
			||||||
        "@types/serve-static": "*"
 | 
					        "@types/serve-static": "*"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
@ -3821,18 +3822,6 @@
 | 
				
			|||||||
        "@types/express": "*"
 | 
					        "@types/express": "*"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "node_modules/@types/express/node_modules/@types/express-serve-static-core": {
 | 
					 | 
				
			||||||
      "version": "4.19.6",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==",
 | 
					 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "dependencies": {
 | 
					 | 
				
			||||||
        "@types/node": "*",
 | 
					 | 
				
			||||||
        "@types/qs": "*",
 | 
					 | 
				
			||||||
        "@types/range-parser": "*",
 | 
					 | 
				
			||||||
        "@types/send": "*"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/@types/fs-extra": {
 | 
					    "node_modules/@types/fs-extra": {
 | 
				
			||||||
      "version": "9.0.13",
 | 
					      "version": "9.0.13",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz",
 | 
				
			||||||
 | 
				
			|||||||
@ -160,7 +160,7 @@
 | 
				
			|||||||
    "@types/ejs": "3.1.5",
 | 
					    "@types/ejs": "3.1.5",
 | 
				
			||||||
    "@types/electron-squirrel-startup": "1.0.2",
 | 
					    "@types/electron-squirrel-startup": "1.0.2",
 | 
				
			||||||
    "@types/escape-html": "1.0.4",
 | 
					    "@types/escape-html": "1.0.4",
 | 
				
			||||||
    "@types/express": "4.17.21",
 | 
					    "@types/express": "5.0.0",
 | 
				
			||||||
    "@types/express-session": "1.18.1",
 | 
					    "@types/express-session": "1.18.1",
 | 
				
			||||||
    "@types/html": "1.0.4",
 | 
					    "@types/html": "1.0.4",
 | 
				
			||||||
    "@types/ini": "4.1.1",
 | 
					    "@types/ini": "4.1.1",
 | 
				
			||||||
 | 
				
			|||||||
@ -5,8 +5,8 @@ import becca from "../becca/becca.js";
 | 
				
			|||||||
import etapiTokenService from "../services/etapi_tokens.js";
 | 
					import etapiTokenService from "../services/etapi_tokens.js";
 | 
				
			||||||
import config from "../services/config.js";
 | 
					import config from "../services/config.js";
 | 
				
			||||||
import { NextFunction, Request, RequestHandler, Response, Router } from 'express';
 | 
					import { NextFunction, Request, RequestHandler, Response, Router } from 'express';
 | 
				
			||||||
import { AppRequest, AppRequestHandler } from '../routes/route-interface.js';
 | 
					 | 
				
			||||||
import { ValidatorMap } from './etapi-interface.js';
 | 
					import { ValidatorMap } from './etapi-interface.js';
 | 
				
			||||||
 | 
					import { ApiRequestHandler } from "../routes/routes.js";
 | 
				
			||||||
const GENERIC_CODE = "GENERIC";
 | 
					const GENERIC_CODE = "GENERIC";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type HttpMethod = "all" | "get" | "post" | "put" | "delete" | "patch" | "options" | "head";
 | 
					type HttpMethod = "all" | "get" | "post" | "put" | "delete" | "patch" | "options" | "head";
 | 
				
			||||||
@ -48,7 +48,7 @@ function checkEtapiAuth(req: Request, res: Response, next: NextFunction) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function processRequest(req: Request, res: Response, routeHandler: AppRequestHandler, next: NextFunction, method: string, path: string) {
 | 
					function processRequest(req: Request, res: Response, routeHandler: ApiRequestHandler, next: NextFunction, method: string, path: string) {
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
        cls.namespace.bindEmitter(req);
 | 
					        cls.namespace.bindEmitter(req);
 | 
				
			||||||
        cls.namespace.bindEmitter(res);
 | 
					        cls.namespace.bindEmitter(res);
 | 
				
			||||||
@ -57,7 +57,7 @@ function processRequest(req: Request, res: Response, routeHandler: AppRequestHan
 | 
				
			|||||||
            cls.set('componentId', "etapi");
 | 
					            cls.set('componentId', "etapi");
 | 
				
			||||||
            cls.set('localNowDateTime', req.headers['trilium-local-now-datetime']);
 | 
					            cls.set('localNowDateTime', req.headers['trilium-local-now-datetime']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            const cb = () => routeHandler(req as AppRequest, res, next);
 | 
					            const cb = () => routeHandler(req, res, next);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return sql.transactional(cb);
 | 
					            return sql.transactional(cb);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
@ -72,7 +72,7 @@ function processRequest(req: Request, res: Response, routeHandler: AppRequestHan
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function route(router: Router, method: HttpMethod, path: string, routeHandler: AppRequestHandler) {
 | 
					function route(router: Router, method: HttpMethod, path: string, routeHandler: ApiRequestHandler) {
 | 
				
			||||||
    router[method](path, checkEtapiAuth, (req: Request, res: Response, next: NextFunction) => processRequest(req, res, routeHandler, next, method, path));
 | 
					    router[method](path, checkEtapiAuth, (req: Request, res: Response, next: NextFunction) => processRequest(req, res, routeHandler, next, method, path));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -9,8 +9,7 @@ import searchService from "../services/search/services/search.js";
 | 
				
			|||||||
import SearchContext from "../services/search/search_context.js";
 | 
					import SearchContext from "../services/search/search_context.js";
 | 
				
			||||||
import zipExportService from "../services/export/zip.js";
 | 
					import zipExportService from "../services/export/zip.js";
 | 
				
			||||||
import zipImportService from "../services/import/zip.js";
 | 
					import zipImportService from "../services/import/zip.js";
 | 
				
			||||||
import { Router } from 'express';
 | 
					import { Request, Router } from 'express';
 | 
				
			||||||
import { AppRequest } from '../routes/route-interface.js';
 | 
					 | 
				
			||||||
import { ParsedQs } from 'qs';
 | 
					import { ParsedQs } from 'qs';
 | 
				
			||||||
import { NoteParams } from '../services/note-interface.js';
 | 
					import { NoteParams } from '../services/note-interface.js';
 | 
				
			||||||
import { SearchParams } from '../services/search/services/types.js';
 | 
					import { SearchParams } from '../services/search/services/types.js';
 | 
				
			||||||
@ -192,7 +191,7 @@ function register(router: Router) {
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function parseSearchParams(req: AppRequest) {
 | 
					function parseSearchParams(req: Request) {
 | 
				
			||||||
    const rawSearchParams: SearchParams = {
 | 
					    const rawSearchParams: SearchParams = {
 | 
				
			||||||
        fastSearch: parseBoolean(req.query, 'fastSearch'),
 | 
					        fastSearch: parseBoolean(req.query, 'fastSearch'),
 | 
				
			||||||
        includeArchivedNotes: parseBoolean(req.query, 'includeArchivedNotes'),
 | 
					        includeArchivedNotes: parseBoolean(req.query, 'includeArchivedNotes'),
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										21
									
								
								src/express.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								src/express.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,21 @@
 | 
				
			|||||||
 | 
					import { Session } from "express-session";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export declare module "express-serve-static-core" {
 | 
				
			||||||
 | 
					    interface Request {
 | 
				
			||||||
 | 
					        session: Session & {
 | 
				
			||||||
 | 
					            loggedIn: boolean;
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        headers: {
 | 
				
			||||||
 | 
					            "x-local-date"?: string;
 | 
				
			||||||
 | 
					            "x-labels"?: string;
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            "authorization"?: string;
 | 
				
			||||||
 | 
					            "trilium-cred"?: string;
 | 
				
			||||||
 | 
					            "x-csrf-token"?: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            "trilium-component-id"?: string;
 | 
				
			||||||
 | 
					            "trilium-local-now-datetime"?: string;
 | 
				
			||||||
 | 
					            "trilium-hoisted-note-id"?: string;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -14,9 +14,8 @@ import ValidationError from "../../errors/validation_error.js";
 | 
				
			|||||||
import { Request, Response } from 'express';
 | 
					import { Request, Response } from 'express';
 | 
				
			||||||
import BNote from "../../becca/entities/bnote.js";
 | 
					import BNote from "../../becca/entities/bnote.js";
 | 
				
			||||||
import BAttachment from "../../becca/entities/battachment.js";
 | 
					import BAttachment from "../../becca/entities/battachment.js";
 | 
				
			||||||
import { AppRequest } from '../route-interface.js';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
function updateFile(req: AppRequest) {
 | 
					function updateFile(req: Request) {
 | 
				
			||||||
    const note = becca.getNoteOrThrow(req.params.noteId);
 | 
					    const note = becca.getNoteOrThrow(req.params.noteId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const file = req.file;
 | 
					    const file = req.file;
 | 
				
			||||||
@ -43,7 +42,7 @@ function updateFile(req: AppRequest) {
 | 
				
			|||||||
    };
 | 
					    };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function updateAttachment(req: AppRequest) {
 | 
					function updateAttachment(req: Request) {
 | 
				
			||||||
    const attachment = becca.getAttachmentOrThrow(req.params.attachmentId);
 | 
					    const attachment = becca.getAttachmentOrThrow(req.params.attachmentId);
 | 
				
			||||||
    const file = req.file;
 | 
					    const file = req.file;
 | 
				
			||||||
    if (!file) {
 | 
					    if (!file) {
 | 
				
			||||||
 | 
				
			|||||||
@ -6,7 +6,6 @@ import fs from "fs";
 | 
				
			|||||||
import { Request, Response } from 'express';
 | 
					import { Request, Response } from 'express';
 | 
				
			||||||
import BNote from "../../becca/entities/bnote.js";
 | 
					import BNote from "../../becca/entities/bnote.js";
 | 
				
			||||||
import BRevision from "../../becca/entities/brevision.js";
 | 
					import BRevision from "../../becca/entities/brevision.js";
 | 
				
			||||||
import { AppRequest } from '../route-interface.js';
 | 
					 | 
				
			||||||
import { RESOURCE_DIR } from "../../services/resource_dir.js";
 | 
					import { RESOURCE_DIR } from "../../services/resource_dir.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function returnImageFromNote(req: Request, res: Response) {
 | 
					function returnImageFromNote(req: Request, res: Response) {
 | 
				
			||||||
@ -82,7 +81,7 @@ function returnAttachedImage(req: Request, res: Response) {
 | 
				
			|||||||
    res.send(attachment.getContent());
 | 
					    res.send(attachment.getContent());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function updateImage(req: AppRequest) {
 | 
					function updateImage(req: Request) {
 | 
				
			||||||
    const {noteId} = req.params;
 | 
					    const {noteId} = req.params;
 | 
				
			||||||
    const {file} = req;
 | 
					    const {file} = req;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -13,9 +13,8 @@ import TaskContext from "../../services/task_context.js";
 | 
				
			|||||||
import ValidationError from "../../errors/validation_error.js";
 | 
					import ValidationError from "../../errors/validation_error.js";
 | 
				
			||||||
import { Request } from 'express';
 | 
					import { Request } from 'express';
 | 
				
			||||||
import BNote from "../../becca/entities/bnote.js";
 | 
					import BNote from "../../becca/entities/bnote.js";
 | 
				
			||||||
import { AppRequest } from '../route-interface.js';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
async function importNotesToBranch(req: AppRequest) {
 | 
					async function importNotesToBranch(req: Request) {
 | 
				
			||||||
    const { parentNoteId } = req.params;
 | 
					    const { parentNoteId } = req.params;
 | 
				
			||||||
    const { taskId, last } = req.body;
 | 
					    const { taskId, last } = req.body;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -97,7 +96,7 @@ async function importNotesToBranch(req: AppRequest) {
 | 
				
			|||||||
    return note.getPojo();
 | 
					    return note.getPojo();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async function importAttachmentsToNote(req: AppRequest) {
 | 
					async function importAttachmentsToNote(req: Request) {
 | 
				
			||||||
    const { parentNoteId } = req.params;
 | 
					    const { parentNoteId } = req.params;
 | 
				
			||||||
    const { taskId, last } = req.body;
 | 
					    const { taskId, last } = req.body;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -13,9 +13,8 @@ import sql from "../../services/sql.js";
 | 
				
			|||||||
import ws from "../../services/ws.js";
 | 
					import ws from "../../services/ws.js";
 | 
				
			||||||
import etapiTokenService from "../../services/etapi_tokens.js";
 | 
					import etapiTokenService from "../../services/etapi_tokens.js";
 | 
				
			||||||
import { Request } from 'express';
 | 
					import { Request } from 'express';
 | 
				
			||||||
import { AppRequest } from '../route-interface.js';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
function loginSync(req: AppRequest) {
 | 
					function loginSync(req: Request) {
 | 
				
			||||||
    if (!sqlInit.schemaExists()) {
 | 
					    if (!sqlInit.schemaExists()) {
 | 
				
			||||||
        return [500, { message: "DB schema does not exist, can't sync." }];
 | 
					        return [500, { message: "DB schema does not exist, can't sync." }];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -6,9 +6,8 @@ import noteService from "../../services/notes.js";
 | 
				
			|||||||
import sanitize_attribute_name from "../../services/sanitize_attribute_name.js";
 | 
					import sanitize_attribute_name from "../../services/sanitize_attribute_name.js";
 | 
				
			||||||
import specialNotesService from "../../services/special_notes.js";
 | 
					import specialNotesService from "../../services/special_notes.js";
 | 
				
			||||||
import { Request } from 'express';
 | 
					import { Request } from 'express';
 | 
				
			||||||
import { AppRequest } from '../route-interface.js';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
function uploadImage(req: AppRequest) {
 | 
					function uploadImage(req: Request) {
 | 
				
			||||||
    const file = req.file;
 | 
					    const file = req.file;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!file) {
 | 
					    if (!file) {
 | 
				
			||||||
 | 
				
			|||||||
@ -9,7 +9,6 @@ import assetPath from "../services/asset_path.js";
 | 
				
			|||||||
import appPath from "../services/app_path.js";
 | 
					import appPath from "../services/app_path.js";
 | 
				
			||||||
import ValidationError from "../errors/validation_error.js";
 | 
					import ValidationError from "../errors/validation_error.js";
 | 
				
			||||||
import { Request, Response } from 'express';
 | 
					import { Request, Response } from 'express';
 | 
				
			||||||
import { AppRequest } from './route-interface.js';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
function loginPage(req: Request, res: Response) {
 | 
					function loginPage(req: Request, res: Response) {
 | 
				
			||||||
    res.render('login', {
 | 
					    res.render('login', {
 | 
				
			||||||
@ -57,7 +56,7 @@ function setPassword(req: Request, res: Response) {
 | 
				
			|||||||
    res.redirect('login');
 | 
					    res.redirect('login');
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function login(req: AppRequest, res: Response) {
 | 
					function login(req: Request, res: Response) {
 | 
				
			||||||
    const guessedPassword = req.body.password;
 | 
					    const guessedPassword = req.body.password;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (verifyPassword(guessedPassword)) {
 | 
					    if (verifyPassword(guessedPassword)) {
 | 
				
			||||||
@ -93,7 +92,7 @@ function verifyPassword(guessedPassword: string) {
 | 
				
			|||||||
    return guess_hashed.equals(hashed_password);
 | 
					    return guess_hashed.equals(hashed_password);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function logout(req: AppRequest, res: Response) {
 | 
					function logout(req: Request, res: Response) {
 | 
				
			||||||
    req.session.regenerate(() => {
 | 
					    req.session.regenerate(() => {
 | 
				
			||||||
        req.session.loggedIn = false;
 | 
					        req.session.loggedIn = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,21 +0,0 @@
 | 
				
			|||||||
import { NextFunction, Request, Response } from "express";
 | 
					 | 
				
			||||||
import { Session, SessionData } from "express-session";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export interface AppRequest extends Request {
 | 
					 | 
				
			||||||
    headers: {
 | 
					 | 
				
			||||||
        authorization?: string;
 | 
					 | 
				
			||||||
        "trilium-cred"?: string;
 | 
					 | 
				
			||||||
        "x-local-date"?: string;
 | 
					 | 
				
			||||||
        "x-labels"?: string;
 | 
					 | 
				
			||||||
        "trilium-local-now-datetime"?: string;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    session: Session & Partial<SessionData> & {
 | 
					 | 
				
			||||||
        loggedIn: boolean;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export type AppRequestHandler = (
 | 
					 | 
				
			||||||
    req: AppRequest,
 | 
					 | 
				
			||||||
    res: Response,
 | 
					 | 
				
			||||||
    next: NextFunction
 | 
					 | 
				
			||||||
) => void;
 | 
					 | 
				
			||||||
@ -70,7 +70,6 @@ import etapiNoteRoutes from "../etapi/notes.js";
 | 
				
			|||||||
import etapiSpecialNoteRoutes from "../etapi/special_notes.js";
 | 
					import etapiSpecialNoteRoutes from "../etapi/special_notes.js";
 | 
				
			||||||
import etapiSpecRoute from "../etapi/spec.js";
 | 
					import etapiSpecRoute from "../etapi/spec.js";
 | 
				
			||||||
import etapiBackupRoute from "../etapi/backup.js";
 | 
					import etapiBackupRoute from "../etapi/backup.js";
 | 
				
			||||||
import { AppRequest, AppRequestHandler } from './route-interface.js';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const csrfMiddleware = csurf({
 | 
					const csrfMiddleware = csurf({
 | 
				
			||||||
    cookie: {
 | 
					    cookie: {
 | 
				
			||||||
@ -81,7 +80,8 @@ const csrfMiddleware = csurf({
 | 
				
			|||||||
const MAX_ALLOWED_FILE_SIZE_MB = 250;
 | 
					const MAX_ALLOWED_FILE_SIZE_MB = 250;
 | 
				
			||||||
const GET = 'get', PST = 'post', PUT = 'put', PATCH = 'patch', DEL = 'delete';
 | 
					const GET = 'get', PST = 'post', PUT = 'put', PATCH = 'patch', DEL = 'delete';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ApiResultHandler = (req: express.Request, res: express.Response, result: unknown) => number;
 | 
					export type ApiResultHandler = (req: express.Request, res: express.Response, result: unknown) => number;
 | 
				
			||||||
 | 
					export type ApiRequestHandler = (req: express.Request, res: express.Response, next: express.NextFunction) => unknown;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// TODO: Deduplicate with etapi_utils.ts afterwards.
 | 
					// TODO: Deduplicate with etapi_utils.ts afterwards.
 | 
				
			||||||
type HttpMethod = "all" | "get" | "post" | "put" | "delete" | "patch" | "options" | "head";
 | 
					type HttpMethod = "all" | "get" | "post" | "put" | "delete" | "patch" | "options" | "head";
 | 
				
			||||||
@ -438,11 +438,11 @@ function send(res: express.Response, statusCode: number, response: unknown) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function apiRoute(method: HttpMethod, path: string, routeHandler: express.Handler) {
 | 
					function apiRoute(method: HttpMethod, path: string, routeHandler: ApiRequestHandler) {
 | 
				
			||||||
    route(method, path, [auth.checkApiAuth, csrfMiddleware], routeHandler, apiResultHandler);
 | 
					    route(method, path, [auth.checkApiAuth, csrfMiddleware], routeHandler, apiResultHandler);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function route(method: HttpMethod, path: string, middleware: (express.Handler | AppRequestHandler)[], routeHandler: AppRequestHandler, resultHandler: ApiResultHandler | null = null, transactional = true) {
 | 
					function route(method: HttpMethod, path: string, middleware: express.Handler[], routeHandler: ApiRequestHandler, resultHandler: ApiResultHandler | null = null, transactional = true) {
 | 
				
			||||||
    router[method](path, ...(middleware as express.Handler[]), (req: express.Request, res: express.Response, next: express.NextFunction) => {
 | 
					    router[method](path, ...(middleware as express.Handler[]), (req: express.Request, res: express.Response, next: express.NextFunction) => {
 | 
				
			||||||
        const start = Date.now();
 | 
					        const start = Date.now();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -455,7 +455,7 @@ function route(method: HttpMethod, path: string, middleware: (express.Handler |
 | 
				
			|||||||
                cls.set('localNowDateTime', req.headers['trilium-local-now-datetime']);
 | 
					                cls.set('localNowDateTime', req.headers['trilium-local-now-datetime']);
 | 
				
			||||||
                cls.set('hoistedNoteId', req.headers['trilium-hoisted-note-id'] || 'root');
 | 
					                cls.set('hoistedNoteId', req.headers['trilium-hoisted-note-id'] || 'root');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                const cb = () => routeHandler(req as AppRequest, res, next);
 | 
					                const cb = () => routeHandler(req, res, next);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                return transactional ? sql.transactional(cb) : cb();
 | 
					                return transactional ? sql.transactional(cb) : cb();
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
 | 
				
			|||||||
@ -8,11 +8,10 @@ import passwordEncryptionService from "./encryption/password_encryption.js";
 | 
				
			|||||||
import config from "./config.js";
 | 
					import config from "./config.js";
 | 
				
			||||||
import passwordService from "./encryption/password.js";
 | 
					import passwordService from "./encryption/password.js";
 | 
				
			||||||
import type { NextFunction, Request, Response } from 'express';
 | 
					import type { NextFunction, Request, Response } from 'express';
 | 
				
			||||||
import { AppRequest } from '../routes/route-interface.js';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const noAuthentication = config.General && config.General.noAuthentication === true;
 | 
					const noAuthentication = config.General && config.General.noAuthentication === true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function checkAuth(req: AppRequest, res: Response, next: NextFunction) {
 | 
					function checkAuth(req: Request, res: Response, next: NextFunction) {
 | 
				
			||||||
    if (!sqlInit.isDbInitialized()) {
 | 
					    if (!sqlInit.isDbInitialized()) {
 | 
				
			||||||
        res.redirect("setup");
 | 
					        res.redirect("setup");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -26,7 +25,7 @@ function checkAuth(req: AppRequest, res: Response, next: NextFunction) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// for electron things which need network stuff
 | 
					// for electron things which need network stuff
 | 
				
			||||||
//  currently, we're doing that for file upload because handling form data seems to be difficult
 | 
					//  currently, we're doing that for file upload because handling form data seems to be difficult
 | 
				
			||||||
function checkApiAuthOrElectron(req: AppRequest, res: Response, next: NextFunction) {
 | 
					function checkApiAuthOrElectron(req: Request, res: Response, next: NextFunction) {
 | 
				
			||||||
    if (!req.session.loggedIn && !utils.isElectron() && !noAuthentication) {
 | 
					    if (!req.session.loggedIn && !utils.isElectron() && !noAuthentication) {
 | 
				
			||||||
        reject(req, res, "Logged in session not found");
 | 
					        reject(req, res, "Logged in session not found");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -35,7 +34,7 @@ function checkApiAuthOrElectron(req: AppRequest, res: Response, next: NextFuncti
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function checkApiAuth(req: AppRequest, res: Response, next: NextFunction) {
 | 
					function checkApiAuth(req: Request, res: Response, next: NextFunction) {
 | 
				
			||||||
    if (!req.session.loggedIn && !noAuthentication) {
 | 
					    if (!req.session.loggedIn && !noAuthentication) {
 | 
				
			||||||
        reject(req, res, "Logged in session not found");
 | 
					        reject(req, res, "Logged in session not found");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -44,7 +43,7 @@ function checkApiAuth(req: AppRequest, res: Response, next: NextFunction) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function checkAppInitialized(req: AppRequest, res: Response, next: NextFunction) {
 | 
					function checkAppInitialized(req: Request, res: Response, next: NextFunction) {
 | 
				
			||||||
    if (!sqlInit.isDbInitialized()) {
 | 
					    if (!sqlInit.isDbInitialized()) {
 | 
				
			||||||
        res.redirect("setup");
 | 
					        res.redirect("setup");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -53,7 +52,7 @@ function checkAppInitialized(req: AppRequest, res: Response, next: NextFunction)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function checkPasswordSet(req: AppRequest, res: Response, next: NextFunction) {
 | 
					function checkPasswordSet(req: Request, res: Response, next: NextFunction) {
 | 
				
			||||||
    if (!utils.isElectron() && !passwordService.isPasswordSet()) {
 | 
					    if (!utils.isElectron() && !passwordService.isPasswordSet()) {
 | 
				
			||||||
        res.redirect("set-password");
 | 
					        res.redirect("set-password");
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
@ -61,7 +60,7 @@ function checkPasswordSet(req: AppRequest, res: Response, next: NextFunction) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function checkPasswordNotSet(req: AppRequest, res: Response, next: NextFunction) {
 | 
					function checkPasswordNotSet(req: Request, res: Response, next: NextFunction) {
 | 
				
			||||||
    if (!utils.isElectron() && passwordService.isPasswordSet()) {
 | 
					    if (!utils.isElectron() && passwordService.isPasswordSet()) {
 | 
				
			||||||
        res.redirect("login");
 | 
					        res.redirect("login");
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
@ -69,7 +68,7 @@ function checkPasswordNotSet(req: AppRequest, res: Response, next: NextFunction)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function checkAppNotInitialized(req: AppRequest, res: Response, next: NextFunction) {
 | 
					function checkAppNotInitialized(req: Request, res: Response, next: NextFunction) {
 | 
				
			||||||
    if (sqlInit.isDbInitialized()) {
 | 
					    if (sqlInit.isDbInitialized()) {
 | 
				
			||||||
        reject(req, res, "App already initialized.");
 | 
					        reject(req, res, "App already initialized.");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -78,7 +77,7 @@ function checkAppNotInitialized(req: AppRequest, res: Response, next: NextFuncti
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function checkEtapiToken(req: AppRequest, res: Response, next: NextFunction) {
 | 
					function checkEtapiToken(req: Request, res: Response, next: NextFunction) {
 | 
				
			||||||
    if (etapiTokenService.isValidAuthHeader(req.headers.authorization)) {
 | 
					    if (etapiTokenService.isValidAuthHeader(req.headers.authorization)) {
 | 
				
			||||||
        next();
 | 
					        next();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -87,7 +86,7 @@ function checkEtapiToken(req: AppRequest, res: Response, next: NextFunction) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function reject(req: AppRequest, res: Response, message: string) {
 | 
					function reject(req: Request, res: Response, message: string) {
 | 
				
			||||||
    log.info(`${req.method} ${req.path} rejected with 401 ${message}`);
 | 
					    log.info(`${req.method} ${req.path} rejected with 401 ${message}`);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    res.setHeader("Content-Type", "text/plain")
 | 
					    res.setHeader("Content-Type", "text/plain")
 | 
				
			||||||
@ -95,7 +94,7 @@ function reject(req: AppRequest, res: Response, message: string) {
 | 
				
			|||||||
        .send(message);
 | 
					        .send(message);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function checkCredentials(req: AppRequest, res: Response, next: NextFunction) {
 | 
					function checkCredentials(req: Request, res: Response, next: NextFunction) {
 | 
				
			||||||
    if (!sqlInit.isDbInitialized()) {
 | 
					    if (!sqlInit.isDbInitialized()) {
 | 
				
			||||||
        res.setHeader("Content-Type", "text/plain")
 | 
					        res.setHeader("Content-Type", "text/plain")
 | 
				
			||||||
            .status(400)
 | 
					            .status(400)
 | 
				
			||||||
@ -111,6 +110,13 @@ function checkCredentials(req: AppRequest, res: Response, next: NextFunction) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const header = req.headers['trilium-cred'] || '';
 | 
					    const header = req.headers['trilium-cred'] || '';
 | 
				
			||||||
 | 
					    if (typeof header !== "string") {
 | 
				
			||||||
 | 
					        res.setHeader("Content-Type", "text/plain")
 | 
				
			||||||
 | 
					            .status(400)
 | 
				
			||||||
 | 
					            .send('Invalid data type for trilium-cred.');
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const auth = Buffer.from(header, 'base64').toString();
 | 
					    const auth = Buffer.from(header, 'base64').toString();
 | 
				
			||||||
    const colonIndex = auth.indexOf(':');
 | 
					    const colonIndex = auth.indexOf(':');
 | 
				
			||||||
    const password = colonIndex === -1 ? "" : auth.substr(colonIndex + 1);
 | 
					    const password = colonIndex === -1 ? "" : auth.substr(colonIndex + 1);
 | 
				
			||||||
 | 
				
			|||||||
@ -209,8 +209,9 @@ function register(router: Router) {
 | 
				
			|||||||
        shacaLoader.ensureLoad();
 | 
					        shacaLoader.ensureLoad();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!shaca.shareRootNote) {
 | 
					        if (!shaca.shareRootNote) {
 | 
				
			||||||
            return res.status(404)
 | 
					            res.status(404)
 | 
				
			||||||
                .json({ message: "Share root note not found" });
 | 
					                .json({ message: "Share root note not found" });
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        renderNote(shaca.shareRootNote, req, res);
 | 
					        renderNote(shaca.shareRootNote, req, res);
 | 
				
			||||||
@ -282,7 +283,7 @@ function register(router: Router) {
 | 
				
			|||||||
        } else if (image.type === "mindMap") {
 | 
					        } else if (image.type === "mindMap") {
 | 
				
			||||||
            renderImageAttachment(image, res, 'mindmap-export.svg');
 | 
					            renderImageAttachment(image, res, 'mindmap-export.svg');
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            return res.status(400)
 | 
					            res.status(400)
 | 
				
			||||||
                .json({ message: "Requested note is not a shareable image" });
 | 
					                .json({ message: "Requested note is not a shareable image" });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
@ -302,7 +303,7 @@ function register(router: Router) {
 | 
				
			|||||||
            addNoIndexHeader(attachment.note, res);
 | 
					            addNoIndexHeader(attachment.note, res);
 | 
				
			||||||
            res.send(attachment.getContent());
 | 
					            res.send(attachment.getContent());
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            return res.status(400)
 | 
					            res.status(400)
 | 
				
			||||||
                .json({ message: "Requested attachment is not a shareable image" });
 | 
					                .json({ message: "Requested attachment is not a shareable image" });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
@ -354,7 +355,8 @@ function register(router: Router) {
 | 
				
			|||||||
        let note;
 | 
					        let note;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (typeof ancestorNoteId !== "string") {
 | 
					        if (typeof ancestorNoteId !== "string") {
 | 
				
			||||||
            return res.status(400).json({ message: "'ancestorNoteId' parameter is mandatory." });
 | 
					            res.status(400).json({ message: "'ancestorNoteId' parameter is mandatory." });
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // This will automatically return if no ancestorNoteId is provided and there is no shareIndex
 | 
					        // This will automatically return if no ancestorNoteId is provided and there is no shareIndex
 | 
				
			||||||
@ -365,7 +367,8 @@ function register(router: Router) {
 | 
				
			|||||||
        const { search } = req.query;
 | 
					        const { search } = req.query;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (typeof search !== "string" || !search?.trim()) {
 | 
					        if (typeof search !== "string" || !search?.trim()) {
 | 
				
			||||||
            return res.status(400).json({ message: "'search' parameter is mandatory." });
 | 
					            res.status(400).json({ message: "'search' parameter is mandatory." });
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const searchContext = new SearchContext({ ancestorNoteId: ancestorNoteId });
 | 
					        const searchContext = new SearchContext({ ancestorNoteId: ancestorNoteId });
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user