mirror of
https://github.com/zadam/trilium.git
synced 2025-03-01 14:22:32 +01:00
Merge pull request #44 from TriliumNext/feature/typescript_backend_8
Convert backend to TypeScript (80% -> 81%)
This commit is contained in:
commit
625d935f08
57
package-lock.json
generated
57
package-lock.json
generated
@ -91,12 +91,15 @@
|
|||||||
"@types/archiver": "^6.0.2",
|
"@types/archiver": "^6.0.2",
|
||||||
"@types/better-sqlite3": "^7.6.9",
|
"@types/better-sqlite3": "^7.6.9",
|
||||||
"@types/cls-hooked": "^4.3.8",
|
"@types/cls-hooked": "^4.3.8",
|
||||||
|
"@types/csurf": "^1.11.5",
|
||||||
"@types/escape-html": "^1.0.4",
|
"@types/escape-html": "^1.0.4",
|
||||||
"@types/express": "^4.17.21",
|
"@types/express": "^4.17.21",
|
||||||
|
"@types/express-session": "^1.18.0",
|
||||||
"@types/html": "^1.0.4",
|
"@types/html": "^1.0.4",
|
||||||
"@types/ini": "^4.1.0",
|
"@types/ini": "^4.1.0",
|
||||||
"@types/jsdom": "^21.1.6",
|
"@types/jsdom": "^21.1.6",
|
||||||
"@types/mime-types": "^2.1.4",
|
"@types/mime-types": "^2.1.4",
|
||||||
|
"@types/multer": "^1.4.11",
|
||||||
"@types/node": "^20.11.19",
|
"@types/node": "^20.11.19",
|
||||||
"@types/sanitize-html": "^2.11.0",
|
"@types/sanitize-html": "^2.11.0",
|
||||||
"@types/sax": "^1.2.7",
|
"@types/sax": "^1.2.7",
|
||||||
@ -1233,6 +1236,15 @@
|
|||||||
"@types/node": "*"
|
"@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": {
|
"node_modules/@types/d3-scale": {
|
||||||
"version": "4.0.8",
|
"version": "4.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz",
|
||||||
@ -1315,6 +1327,15 @@
|
|||||||
"@types/send": "*"
|
"@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": {
|
"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",
|
||||||
@ -1459,6 +1480,15 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.32.tgz",
|
"resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.32.tgz",
|
||||||
"integrity": "sha512-xPSg0jm4mqgEkNhowKgZFBNtwoEwF6gJ4Dhww+GFpm3IgtNseHQZ5IqdNwnquZEoANxyDAKDRAdVo4Z72VvD/g=="
|
"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": {
|
"node_modules/@types/node": {
|
||||||
"version": "20.11.19",
|
"version": "20.11.19",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.19.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.19.tgz",
|
||||||
@ -14211,6 +14241,15 @@
|
|||||||
"@types/node": "*"
|
"@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": {
|
"@types/d3-scale": {
|
||||||
"version": "4.0.8",
|
"version": "4.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz",
|
||||||
@ -14293,6 +14332,15 @@
|
|||||||
"@types/send": "*"
|
"@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": {
|
"@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",
|
||||||
@ -14430,6 +14478,15 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.32.tgz",
|
"resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.32.tgz",
|
||||||
"integrity": "sha512-xPSg0jm4mqgEkNhowKgZFBNtwoEwF6gJ4Dhww+GFpm3IgtNseHQZ5IqdNwnquZEoANxyDAKDRAdVo4Z72VvD/g=="
|
"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": {
|
"@types/node": {
|
||||||
"version": "20.11.19",
|
"version": "20.11.19",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.19.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.19.tgz",
|
||||||
|
@ -112,12 +112,15 @@
|
|||||||
"@types/archiver": "^6.0.2",
|
"@types/archiver": "^6.0.2",
|
||||||
"@types/better-sqlite3": "^7.6.9",
|
"@types/better-sqlite3": "^7.6.9",
|
||||||
"@types/cls-hooked": "^4.3.8",
|
"@types/cls-hooked": "^4.3.8",
|
||||||
|
"@types/csurf": "^1.11.5",
|
||||||
"@types/escape-html": "^1.0.4",
|
"@types/escape-html": "^1.0.4",
|
||||||
"@types/express": "^4.17.21",
|
"@types/express": "^4.17.21",
|
||||||
|
"@types/express-session": "^1.18.0",
|
||||||
"@types/html": "^1.0.4",
|
"@types/html": "^1.0.4",
|
||||||
"@types/ini": "^4.1.0",
|
"@types/ini": "^4.1.0",
|
||||||
"@types/jsdom": "^21.1.6",
|
"@types/jsdom": "^21.1.6",
|
||||||
"@types/mime-types": "^2.1.4",
|
"@types/mime-types": "^2.1.4",
|
||||||
|
"@types/multer": "^1.4.11",
|
||||||
"@types/node": "^20.11.19",
|
"@types/node": "^20.11.19",
|
||||||
"@types/sanitize-html": "^2.11.0",
|
"@types/sanitize-html": "^2.11.0",
|
||||||
"@types/sax": "^1.2.7",
|
"@types/sax": "^1.2.7",
|
||||||
|
@ -4,7 +4,7 @@ const favicon = require('serve-favicon');
|
|||||||
const cookieParser = require('cookie-parser');
|
const cookieParser = require('cookie-parser');
|
||||||
const helmet = require('helmet');
|
const helmet = require('helmet');
|
||||||
const compression = require('compression');
|
const compression = require('compression');
|
||||||
const sessionParser = require('./routes/session_parser.js');
|
const sessionParser = require('./routes/session_parser');
|
||||||
const utils = require('./services/utils');
|
const utils = require('./services/utils');
|
||||||
|
|
||||||
require('./services/handlers');
|
require('./services/handlers');
|
||||||
@ -37,10 +37,10 @@ app.use(`/robots.txt`, express.static(path.join(__dirname, 'public/robots.txt'))
|
|||||||
app.use(sessionParser);
|
app.use(sessionParser);
|
||||||
app.use(favicon(`${__dirname}/../images/app-icons/win/icon.ico`));
|
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/routes.js').register(app);
|
||||||
require('./routes/custom.js').register(app);
|
require('./routes/custom').register(app);
|
||||||
require('./routes/error_handlers.js').register(app);
|
require('./routes/error_handlers').register(app);
|
||||||
|
|
||||||
// triggers sync timer
|
// triggers sync timer
|
||||||
require('./services/sync');
|
require('./services/sync');
|
||||||
|
@ -14,11 +14,12 @@ import ValidationError = require('../../errors/validation_error');
|
|||||||
import { Request, Response } from 'express';
|
import { Request, Response } from 'express';
|
||||||
import BNote = require('../../becca/entities/bnote');
|
import BNote = require('../../becca/entities/bnote');
|
||||||
import BAttachment = require('../../becca/entities/battachment');
|
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 note = becca.getNoteOrThrow(req.params.noteId);
|
||||||
|
|
||||||
const file = (req as any).file;
|
const file = req.file;
|
||||||
note.saveRevision();
|
note.saveRevision();
|
||||||
|
|
||||||
note.mime = file.mimetype.toLowerCase();
|
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 attachment = becca.getAttachmentOrThrow(req.params.attachmentId);
|
||||||
const file = (req as any).file;
|
const file = req.file;
|
||||||
|
|
||||||
attachment.getNote().saveRevision();
|
attachment.getNote().saveRevision();
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ import fs = require('fs');
|
|||||||
import { Request, Response } from 'express';
|
import { Request, Response } from 'express';
|
||||||
import BNote = require('../../becca/entities/bnote');
|
import BNote = require('../../becca/entities/bnote');
|
||||||
import BRevision = require('../../becca/entities/brevision');
|
import BRevision = require('../../becca/entities/brevision');
|
||||||
|
import { AppRequest } from '../route-interface';
|
||||||
|
|
||||||
function returnImageFromNote(req: Request, res: Response) {
|
function returnImageFromNote(req: Request, res: Response) {
|
||||||
const image = becca.getNote(req.params.noteId);
|
const image = becca.getNote(req.params.noteId);
|
||||||
@ -81,9 +82,9 @@ function returnAttachedImage(req: Request, res: Response) {
|
|||||||
res.send(attachment.getContent());
|
res.send(attachment.getContent());
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateImage(req: Request) {
|
function updateImage(req: AppRequest) {
|
||||||
const {noteId} = req.params;
|
const {noteId} = req.params;
|
||||||
const {file} = (req as any);
|
const {file} = req;
|
||||||
|
|
||||||
const note = becca.getNoteOrThrow(noteId);
|
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);
|
imageService.updateImage(noteId, file.buffer, file.originalname);
|
||||||
|
|
||||||
return { uploaded: true };
|
return { uploaded: true };
|
||||||
|
@ -13,8 +13,9 @@ import TaskContext = require('../../services/task_context');
|
|||||||
import ValidationError = require('../../errors/validation_error');
|
import ValidationError = require('../../errors/validation_error');
|
||||||
import { Request } from 'express';
|
import { Request } from 'express';
|
||||||
import BNote = require('../../becca/entities/bnote');
|
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 { parentNoteId } = req.params;
|
||||||
const { taskId, last } = req.body;
|
const { taskId, last } = req.body;
|
||||||
|
|
||||||
@ -27,7 +28,7 @@ async function importNotesToBranch(req: Request) {
|
|||||||
replaceUnderscoresWithSpaces: req.body.replaceUnderscoresWithSpaces !== 'false'
|
replaceUnderscoresWithSpaces: req.body.replaceUnderscoresWithSpaces !== 'false'
|
||||||
};
|
};
|
||||||
|
|
||||||
const file = (req as any).file;
|
const file = req.file;
|
||||||
|
|
||||||
if (!file) {
|
if (!file) {
|
||||||
throw new ValidationError("No file has been uploaded");
|
throw new ValidationError("No file has been uploaded");
|
||||||
@ -49,7 +50,7 @@ async function importNotesToBranch(req: Request) {
|
|||||||
const taskContext = TaskContext.getInstance(taskId, 'importNotes', options);
|
const taskContext = TaskContext.getInstance(taskId, 'importNotes', options);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (extension === '.zip' && options.explodeArchives) {
|
if (extension === '.zip' && options.explodeArchives && typeof file.buffer !== "string") {
|
||||||
note = await zipImportService.importZip(taskContext, file.buffer, parentNote);
|
note = await zipImportService.importZip(taskContext, file.buffer, parentNote);
|
||||||
} else if (extension === '.opml' && options.explodeArchives) {
|
} else if (extension === '.opml' && options.explodeArchives) {
|
||||||
const importResult = await opmlImportService.importOpml(taskContext, file.buffer, parentNote);
|
const importResult = await opmlImportService.importOpml(taskContext, file.buffer, parentNote);
|
||||||
@ -96,7 +97,7 @@ async function importNotesToBranch(req: Request) {
|
|||||||
return note.getPojo();
|
return note.getPojo();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function importAttachmentsToNote(req: Request) {
|
async function importAttachmentsToNote(req: AppRequest) {
|
||||||
const { parentNoteId } = req.params;
|
const { parentNoteId } = req.params;
|
||||||
const { taskId, last } = req.body;
|
const { taskId, last } = req.body;
|
||||||
|
|
||||||
@ -104,7 +105,7 @@ async function importAttachmentsToNote(req: Request) {
|
|||||||
shrinkImages: req.body.shrinkImages !== 'false',
|
shrinkImages: req.body.shrinkImages !== 'false',
|
||||||
};
|
};
|
||||||
|
|
||||||
const file = (req as any).file;
|
const file = req.file;
|
||||||
|
|
||||||
if (!file) {
|
if (!file) {
|
||||||
throw new ValidationError("No file has been uploaded");
|
throw new ValidationError("No file has been uploaded");
|
||||||
|
@ -13,8 +13,9 @@ import sql = require('../../services/sql');
|
|||||||
import ws = require('../../services/ws');
|
import ws = require('../../services/ws');
|
||||||
import etapiTokenService = require('../../services/etapi_tokens');
|
import etapiTokenService = require('../../services/etapi_tokens');
|
||||||
import { Request } from 'express';
|
import { Request } from 'express';
|
||||||
|
import { AppRequest } from '../route-interface';
|
||||||
|
|
||||||
function loginSync(req: Request) {
|
function loginSync(req: AppRequest) {
|
||||||
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." }];
|
||||||
}
|
}
|
||||||
@ -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." }];
|
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 {
|
return {
|
||||||
instanceId: instanceId,
|
instanceId: instanceId,
|
||||||
|
@ -6,13 +6,17 @@ import noteService = require('../../services/notes');
|
|||||||
import sanitize_attribute_name = require('../../services/sanitize_attribute_name');
|
import sanitize_attribute_name = require('../../services/sanitize_attribute_name');
|
||||||
import specialNotesService = require('../../services/special_notes');
|
import specialNotesService = require('../../services/special_notes');
|
||||||
import { Request } from 'express';
|
import { Request } from 'express';
|
||||||
|
import { AppRequest } from '../route-interface';
|
||||||
|
|
||||||
function uploadImage(req: Request) {
|
function uploadImage(req: AppRequest) {
|
||||||
const file = (req as any).file;
|
const file = req.file;
|
||||||
|
|
||||||
if (!["image/png", "image/jpeg", "image/gif", "image/webp", "image/svg+xml"].includes(file.mimetype)) {
|
if (!["image/png", "image/jpeg", "image/gif", "image/webp", "image/svg+xml"].includes(file.mimetype)) {
|
||||||
return [400, `Unknown image type: ${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);
|
const uploadedImageType = imageType(file.buffer);
|
||||||
if (!uploadedImageType) {
|
if (!uploadedImageType) {
|
||||||
@ -20,14 +24,10 @@ function uploadImage(req: Request) {
|
|||||||
}
|
}
|
||||||
const originalName = `Sender image.${uploadedImageType.ext}`;
|
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"];
|
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 parentNote = specialNotesService.getInboxNote(req.headers['x-local-date']);
|
||||||
|
|
||||||
const { note, noteId } = imageService.saveImage(parentNote.noteId, file.buffer, originalName, true);
|
const { note, noteId } = imageService.saveImage(parentNote.noteId, file.buffer, originalName, true);
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
const assetPath = require('../services/asset_path');
|
import assetPath = require('../services/asset_path');
|
||||||
const path = require("path");
|
import path = require("path");
|
||||||
const express = require("express");
|
import express = require("express");
|
||||||
const env = require('../services/env');
|
import env = require('../services/env');
|
||||||
|
import serveStatic = require('serve-static');
|
||||||
|
|
||||||
const persistentCacheStatic = (root, options) => {
|
const persistentCacheStatic = (root: string, options?: serveStatic.ServeStaticOptions<express.Response<any, Record<string, any>>>) => {
|
||||||
if (!env.isDev()) {
|
if (!env.isDev()) {
|
||||||
options = {
|
options = {
|
||||||
maxAge: '1y',
|
maxAge: '1y',
|
||||||
@ -13,7 +14,7 @@ const persistentCacheStatic = (root, options) => {
|
|||||||
return express.static(root, options);
|
return express.static(root, options);
|
||||||
};
|
};
|
||||||
|
|
||||||
function register(app) {
|
function register(app: express.Application) {
|
||||||
const srcRoot = path.join(__dirname, '..');
|
const srcRoot = path.join(__dirname, '..');
|
||||||
app.use(`/${assetPath}/app`, persistentCacheStatic(path.join(srcRoot, 'public/app')));
|
app.use(`/${assetPath}/app`, persistentCacheStatic(path.join(srcRoot, 'public/app')));
|
||||||
app.use(`/${assetPath}/app-dist`, persistentCacheStatic(path.join(srcRoot, 'public/app-dist')));
|
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/')));
|
app.use(`/${assetPath}/node_modules/panzoom/dist/`, persistentCacheStatic(path.join(srcRoot, '..', 'node_modules/panzoom/dist/')));
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
export = {
|
||||||
register
|
register
|
||||||
};
|
};
|
@ -1,21 +1,22 @@
|
|||||||
const log = require('../services/log');
|
import log = require('../services/log');
|
||||||
const fileService = require('./api/files');
|
import fileService = require('./api/files');
|
||||||
const scriptService = require('../services/script');
|
import scriptService = require('../services/script');
|
||||||
const cls = require('../services/cls');
|
import cls = require('../services/cls');
|
||||||
const sql = require('../services/sql');
|
import sql = require('../services/sql');
|
||||||
const becca = require('../becca/becca');
|
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
|
// express puts content after first slash into 0 index element
|
||||||
|
|
||||||
const path = req.params.path + req.params[0];
|
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<string>("SELECT attributeId FROM attributes WHERE isDeleted = 0 AND type = 'label' AND name IN ('customRequestHandler', 'customResourceProvider')");
|
||||||
|
|
||||||
const attrs = attributeIds.map(attrId => becca.getAttribute(attrId));
|
const attrs = attributeIds.map(attrId => becca.getAttribute(attrId));
|
||||||
|
|
||||||
for (const attr of attrs) {
|
for (const attr of attrs) {
|
||||||
if (!attr.value.trim()) {
|
if (!attr?.value.trim()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,7 +26,7 @@ function handleRequest(req, res) {
|
|||||||
try {
|
try {
|
||||||
match = path.match(regex);
|
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}`);
|
log.error(`Testing path for label '${attr.attributeId}', regex '${attr.value}' failed with error: ${e.message}, stack: ${e.stack}`);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -46,7 +47,7 @@ function handleRequest(req, res) {
|
|||||||
res
|
res
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e: any) {
|
||||||
log.error(`Custom handler '${note.noteId}' failed with: ${e.message}, ${e.stack}`);
|
log.error(`Custom handler '${note.noteId}' failed with: ${e.message}, ${e.stack}`);
|
||||||
|
|
||||||
res.setHeader("Content-Type", "text/plain")
|
res.setHeader("Content-Type", "text/plain")
|
||||||
@ -72,10 +73,10 @@ function handleRequest(req, res) {
|
|||||||
.send(message);
|
.send(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
function register(router) {
|
function register(router: Router) {
|
||||||
// explicitly no CSRF middleware since it's meant to allow integration from external services
|
// 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(req);
|
||||||
cls.namespace.bindEmitter(res);
|
cls.namespace.bindEmitter(res);
|
||||||
|
|
||||||
@ -83,6 +84,6 @@ function register(router) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
export = {
|
||||||
register
|
register
|
||||||
};
|
};
|
@ -1,6 +1,17 @@
|
|||||||
|
import { Application } from "express";
|
||||||
|
|
||||||
const ipcMain = require('electron').ipcMain;
|
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) => {
|
ipcMain.on('server-request', (event, arg) => {
|
||||||
const req = {
|
const req = {
|
||||||
url: arg.url,
|
url: arg.url,
|
||||||
@ -12,9 +23,9 @@ function init(app) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const respHeaders = {};
|
const respHeaders: Record<string, string> = {};
|
||||||
|
|
||||||
const res = {
|
const res: Response = {
|
||||||
statusCode: 200,
|
statusCode: 200,
|
||||||
getHeader: name => respHeaders[name],
|
getHeader: name => respHeaders[name],
|
||||||
setHeader: (name, value) => {
|
setHeader: (name, value) => {
|
||||||
@ -45,4 +56,4 @@ function init(app) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = init;
|
export = init;
|
@ -1,7 +1,8 @@
|
|||||||
const log = require('../services/log');
|
import { Application, NextFunction, Request, Response } from 'express';
|
||||||
|
import log = require('../services/log');
|
||||||
|
|
||||||
function register(app) {
|
function register(app: Application) {
|
||||||
app.use((err, req, res, next) => {
|
app.use((err: any, req: Request, res: Response, next: NextFunction) => {
|
||||||
if (err.code !== 'EBADCSRFTOKEN') {
|
if (err.code !== 'EBADCSRFTOKEN') {
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
@ -16,12 +17,12 @@ function register(app) {
|
|||||||
// catch 404 and forward to error handler
|
// catch 404 and forward to error handler
|
||||||
app.use((req, res, next) => {
|
app.use((req, res, next) => {
|
||||||
const err = new Error(`Router not found for request ${req.method} ${req.url}`);
|
const err = new Error(`Router not found for request ${req.method} ${req.url}`);
|
||||||
err.status = 404;
|
(err as any).status = 404;
|
||||||
next(err);
|
next(err);
|
||||||
});
|
});
|
||||||
|
|
||||||
// error handler
|
// error handler
|
||||||
app.use((err, req, res, next) => {
|
app.use((err: any, req: Request, res: Response, next: NextFunction) => {
|
||||||
if (err && err.message && (
|
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(".js.map"))
|
||||||
|| (err.message.includes("Router not found for request") && err.message.includes(".css.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
|
register
|
||||||
};
|
};
|
@ -1,18 +1,19 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const sql = require('../services/sql');
|
import sql = require('../services/sql');
|
||||||
const attributeService = require('../services/attributes');
|
import attributeService = require('../services/attributes');
|
||||||
const config = require('../services/config');
|
import config = require('../services/config');
|
||||||
const optionService = require('../services/options');
|
import optionService = require('../services/options');
|
||||||
const log = require('../services/log');
|
import log = require('../services/log');
|
||||||
const env = require('../services/env');
|
import env = require('../services/env');
|
||||||
const utils = require('../services/utils');
|
import utils = require('../services/utils');
|
||||||
const protectedSessionService = require('../services/protected_session');
|
import protectedSessionService = require('../services/protected_session');
|
||||||
const packageJson = require('../../package.json');
|
import packageJson = require('../../package.json');
|
||||||
const assetPath = require('../services/asset_path');
|
import assetPath = require('../services/asset_path');
|
||||||
const appPath = require('../services/app_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 options = optionService.getOptionMap();
|
||||||
|
|
||||||
const view = (!utils.isElectron() && req.cookies['trilium-device'] === 'mobile')
|
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') {
|
if (theme === 'light') {
|
||||||
return false; // light theme is always loaded as baseline
|
return false; // light theme is always loaded as baseline
|
||||||
} else if (theme === 'dark') {
|
} else if (theme === 'dark') {
|
||||||
@ -63,6 +64,6 @@ function getAppCssNoteIds() {
|
|||||||
return attributeService.getNotesWithLabel('appCss').map(note => note.noteId);
|
return attributeService.getNotesWithLabel('appCss').map(note => note.noteId);
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
export = {
|
||||||
index
|
index
|
||||||
};
|
};
|
@ -1,15 +1,17 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const utils = require('../services/utils');
|
import utils = require('../services/utils');
|
||||||
const optionService = require('../services/options');
|
import optionService = require('../services/options');
|
||||||
const myScryptService = require('../services/encryption/my_scrypt');
|
import myScryptService = require('../services/encryption/my_scrypt');
|
||||||
const log = require('../services/log');
|
import log = require('../services/log');
|
||||||
const passwordService = require('../services/encryption/password');
|
import passwordService = require('../services/encryption/password');
|
||||||
const assetPath = require('../services/asset_path');
|
import assetPath = require('../services/asset_path');
|
||||||
const appPath = require('../services/app_path');
|
import appPath = require('../services/app_path');
|
||||||
const ValidationError = require('../errors/validation_error');
|
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', {
|
res.render('login', {
|
||||||
failedAuth: false,
|
failedAuth: false,
|
||||||
assetPath: assetPath,
|
assetPath: assetPath,
|
||||||
@ -17,7 +19,7 @@ function loginPage(req, res) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function setPasswordPage(req, res) {
|
function setPasswordPage(req: Request, res: Response) {
|
||||||
res.render('set_password', {
|
res.render('set_password', {
|
||||||
error: false,
|
error: false,
|
||||||
assetPath: assetPath,
|
assetPath: assetPath,
|
||||||
@ -25,7 +27,7 @@ function setPasswordPage(req, res) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function setPassword(req, res) {
|
function setPassword(req: Request, res: Response) {
|
||||||
if (passwordService.isPasswordSet()) {
|
if (passwordService.isPasswordSet()) {
|
||||||
throw new ValidationError("Password has been already set");
|
throw new ValidationError("Password has been already set");
|
||||||
}
|
}
|
||||||
@ -55,7 +57,7 @@ function setPassword(req, res) {
|
|||||||
res.redirect('login');
|
res.redirect('login');
|
||||||
}
|
}
|
||||||
|
|
||||||
function login(req, res) {
|
function login(req: AppRequest, res: Response) {
|
||||||
const guessedPassword = req.body.password;
|
const guessedPassword = req.body.password;
|
||||||
|
|
||||||
if (verifyPassword(guessedPassword)) {
|
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 hashed_password = utils.fromBase64(optionService.getOption('passwordVerificationHash'));
|
||||||
|
|
||||||
const guess_hashed = myScryptService.getVerificationHash(guessedPassword);
|
const guess_hashed = myScryptService.getVerificationHash(guessedPassword);
|
||||||
@ -91,7 +93,7 @@ function verifyPassword(guessedPassword) {
|
|||||||
return guess_hashed.equals(hashed_password);
|
return guess_hashed.equals(hashed_password);
|
||||||
}
|
}
|
||||||
|
|
||||||
function logout(req, res) {
|
function logout(req: AppRequest, res: Response) {
|
||||||
req.session.regenerate(() => {
|
req.session.regenerate(() => {
|
||||||
req.session.loggedIn = false;
|
req.session.loggedIn = false;
|
||||||
|
|
||||||
@ -100,7 +102,7 @@ function logout(req, res) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
export = {
|
||||||
loginPage,
|
loginPage,
|
||||||
setPasswordPage,
|
setPasswordPage,
|
||||||
setPassword,
|
setPassword,
|
20
src/routes/route-interface.ts
Normal file
20
src/routes/route-interface.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
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;
|
||||||
|
cookie: {
|
||||||
|
maxAge: number;
|
||||||
|
expires: boolean
|
||||||
|
};
|
||||||
|
regenerate: (callback: () => void) => void;
|
||||||
|
}
|
||||||
|
file: File;
|
||||||
|
}
|
@ -18,8 +18,8 @@ const ValidationError = require('../errors/validation_error');
|
|||||||
|
|
||||||
// page routes
|
// page routes
|
||||||
const setupRoute = require('./setup');
|
const setupRoute = require('./setup');
|
||||||
const loginRoute = require('./login.js');
|
const loginRoute = require('./login');
|
||||||
const indexRoute = require('./index.js');
|
const indexRoute = require('./index');
|
||||||
|
|
||||||
// API routes
|
// API routes
|
||||||
const treeApiRoute = require('./api/tree');
|
const treeApiRoute = require('./api/tree');
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
const session = require("express-session");
|
import session = require("express-session");
|
||||||
const sessionSecret = require('../services/session_secret');
|
import sessionSecret = require('../services/session_secret');
|
||||||
const dataDir = require('../services/data_dir');
|
import dataDir = require('../services/data_dir');
|
||||||
const FileStore = require('session-file-store')(session);
|
const FileStore = require('session-file-store')(session);
|
||||||
|
|
||||||
const sessionParser = session({
|
const sessionParser = session({
|
||||||
@ -19,4 +19,4 @@ const sessionParser = session({
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = sessionParser;
|
export = sessionParser;
|
@ -1,12 +1,13 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const sqlInit = require('../services/sql_init');
|
import sqlInit = require('../services/sql_init');
|
||||||
const setupService = require('../services/setup');
|
import setupService = require('../services/setup');
|
||||||
const utils = require('../services/utils');
|
import utils = require('../services/utils');
|
||||||
const assetPath = require('../services/asset_path');
|
import assetPath = require('../services/asset_path');
|
||||||
const appPath = require('../services/app_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 (sqlInit.isDbInitialized()) {
|
||||||
if (utils.isElectron()) {
|
if (utils.isElectron()) {
|
||||||
const windowService = require('../services/window');
|
const windowService = require('../services/window');
|
||||||
@ -37,6 +38,6 @@ function setupPage(req, res) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
export = {
|
||||||
setupPage
|
setupPage
|
||||||
};
|
};
|
@ -8,19 +8,10 @@ import passwordEncryptionService = require('./encryption/password_encryption');
|
|||||||
import config = require('./config');
|
import config = require('./config');
|
||||||
import passwordService = require('./encryption/password');
|
import passwordService = require('./encryption/password');
|
||||||
import type { NextFunction, Request, Response } from 'express';
|
import type { NextFunction, Request, Response } from 'express';
|
||||||
|
import { AppRequest } from '../routes/route-interface';
|
||||||
|
|
||||||
const noAuthentication = config.General && config.General.noAuthentication === true;
|
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) {
|
function checkAuth(req: AppRequest, res: Response, next: NextFunction) {
|
||||||
if (!sqlInit.isDbInitialized()) {
|
if (!sqlInit.isDbInitialized()) {
|
||||||
res.redirect("setup");
|
res.redirect("setup");
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
|
import { Request, Response } from "express";
|
||||||
import AbstractBeccaEntity = require("../becca/entities/abstract_becca_entity");
|
import AbstractBeccaEntity = require("../becca/entities/abstract_becca_entity");
|
||||||
import BNote = require("../becca/entities/bnote");
|
import BNote = require("../becca/entities/bnote");
|
||||||
|
|
||||||
export interface ApiParams {
|
export interface ApiParams {
|
||||||
startNote?: BNote;
|
startNote?: BNote;
|
||||||
originEntity?: AbstractBeccaEntity<any>;
|
originEntity?: AbstractBeccaEntity<any>;
|
||||||
|
pathParams?: string[],
|
||||||
|
req?: Request,
|
||||||
|
res?: Response
|
||||||
}
|
}
|
@ -28,7 +28,7 @@ interface OpmlOutline {
|
|||||||
outline: 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<OpmlXml>(function(resolve, reject)
|
const xml = await new Promise<OpmlXml>(function(resolve, reject)
|
||||||
{
|
{
|
||||||
parseString(fileBuffer, function (err: any, result: OpmlXml) {
|
parseString(fileBuffer, function (err: any, result: OpmlXml) {
|
||||||
|
@ -7,7 +7,7 @@ import log = require('./log');
|
|||||||
|
|
||||||
const sessionSecretPath = `${dataDir.TRILIUM_DATA_DIR}/session_secret.txt`;
|
const sessionSecretPath = `${dataDir.TRILIUM_DATA_DIR}/session_secret.txt`;
|
||||||
|
|
||||||
let sessionSecret;
|
let sessionSecret: string;
|
||||||
|
|
||||||
const ENCODING = "ascii";
|
const ENCODING = "ascii";
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user