mirror of
				https://github.com/TriliumNext/Notes.git
				synced 2025-10-31 21:11:30 +08:00 
			
		
		
		
	Merge branch 'feature/typescript_backend_3' into feature/typescript_backend_4
This commit is contained in:
		
						commit
						ed47c23e23
					
				| @ -11,7 +11,7 @@ import protectedSessionService = require('../../services/protected_session'); | |||||||
| import blobService = require('../../services/blob'); | import blobService = require('../../services/blob'); | ||||||
| import Becca, { ConstructorData } from '../becca-interface'; | import Becca, { ConstructorData } from '../becca-interface'; | ||||||
| 
 | 
 | ||||||
| let becca: Becca | null = null; | let becca: Becca; | ||||||
| 
 | 
 | ||||||
| interface ContentOpts { | interface ContentOpts { | ||||||
|     forceSave?: boolean; |     forceSave?: boolean; | ||||||
| @ -92,7 +92,9 @@ abstract class AbstractBeccaEntity<T extends AbstractBeccaEntity<T>> { | |||||||
| 
 | 
 | ||||||
|     abstract getPojo(): {}; |     abstract getPojo(): {}; | ||||||
| 
 | 
 | ||||||
|     abstract init(): void; |     init() { | ||||||
|  |         // Do nothing by default, can be overriden in derived classes.
 | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     abstract updateFromRow(row: unknown): void; |     abstract updateFromRow(row: unknown): void; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -83,10 +83,6 @@ class BAttachment extends AbstractBeccaEntity<BAttachment> { | |||||||
|         this.contentLength = row.contentLength; |         this.contentLength = row.contentLength; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     init(): void { |  | ||||||
|         // Do nothing.
 |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     copy(): BAttachment { |     copy(): BAttachment { | ||||||
|         return new BAttachment({ |         return new BAttachment({ | ||||||
|             ownerId: this.ownerId, |             ownerId: this.ownerId, | ||||||
|  | |||||||
| @ -26,10 +26,6 @@ class BBlob extends AbstractBeccaEntity<BBlob> { | |||||||
|         this.utcDateModified = row.utcDateModified; |         this.utcDateModified = row.utcDateModified; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     init() { |  | ||||||
|         // Nothing to do.
 |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     getPojo() { |     getPojo() { | ||||||
|         return { |         return { | ||||||
|             blobId: this.blobId, |             blobId: this.blobId, | ||||||
|  | |||||||
| @ -32,10 +32,6 @@ class BOption extends AbstractBeccaEntity<BOption> { | |||||||
|         this.utcDateModified = row.utcDateModified; |         this.utcDateModified = row.utcDateModified; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     init(): void { |  | ||||||
|         // Do nothing.
 |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     beforeSaving() { |     beforeSaving() { | ||||||
|         super.beforeSaving(); |         super.beforeSaving(); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -29,10 +29,6 @@ class BRecentNote extends AbstractBeccaEntity<BRecentNote> { | |||||||
|         this.utcDateCreated = row.utcDateCreated || dateUtils.utcNowDateTime(); |         this.utcDateCreated = row.utcDateCreated || dateUtils.utcNowDateTime(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     init(): void { |  | ||||||
|         // Do nothing.
 |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     getPojo() { |     getPojo() { | ||||||
|         return { |         return { | ||||||
|             noteId: this.noteId, |             noteId: this.noteId, | ||||||
|  | |||||||
| @ -68,10 +68,6 @@ class BRevision extends AbstractBeccaEntity<BRevision> { | |||||||
|         this.contentLength = row.contentLength; |         this.contentLength = row.contentLength; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     init() { |  | ||||||
|         // Do nothing.
 |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     getNote() { |     getNote() { | ||||||
|         return becca.notes[this.noteId]; |         return becca.notes[this.noteId]; | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -5,7 +5,7 @@ export interface AttachmentRow { | |||||||
|     ownerId?: string; |     ownerId?: string; | ||||||
|     role: string; |     role: string; | ||||||
|     mime: string; |     mime: string; | ||||||
|     title?: string; |     title: string; | ||||||
|     position?: number; |     position?: number; | ||||||
|     blobId?: string; |     blobId?: string; | ||||||
|     isProtected?: boolean; |     isProtected?: boolean; | ||||||
|  | |||||||
| @ -153,7 +153,7 @@ function buildRewardMap(note: BNote) { | |||||||
| 
 | 
 | ||||||
| const mimeCache: Record<string, string> = {}; | const mimeCache: Record<string, string> = {}; | ||||||
| 
 | 
 | ||||||
| function trimMime(mime?: string) { | function trimMime(mime: string) { | ||||||
|     if (!mime || mime === 'text/html') { |     if (!mime || mime === 'text/html') { | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -7,13 +7,11 @@ import utils = require('./utils'); | |||||||
| import passwordEncryptionService = require('./encryption/password_encryption'); | 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'; | ||||||
| 
 | 
 | ||||||
| const noAuthentication = config.General && config.General.noAuthentication === true; | const noAuthentication = config.General && config.General.noAuthentication === true; | ||||||
| 
 | 
 | ||||||
| // TODO: We are using custom types for request & response because couldn't extract those pesky express types.
 | interface AppRequest extends Request { | ||||||
| interface Request { |  | ||||||
|     method: string; |  | ||||||
|     path: string; |  | ||||||
|     headers: { |     headers: { | ||||||
|         authorization?: string; |         authorization?: string; | ||||||
|         "trilium-cred"?: string; |         "trilium-cred"?: string; | ||||||
| @ -23,14 +21,7 @@ interface Request { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| interface Response { | function checkAuth(req: AppRequest, res: Response, next: NextFunction) { | ||||||
|     redirect(url: string): void; |  | ||||||
|     setHeader(key: string, value: string): any |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type Callback = () => void; |  | ||||||
| 
 |  | ||||||
| function checkAuth(req: Request, res: Response, next: Callback) { |  | ||||||
|     if (!sqlInit.isDbInitialized()) { |     if (!sqlInit.isDbInitialized()) { | ||||||
|         res.redirect("setup"); |         res.redirect("setup"); | ||||||
|     } |     } | ||||||
| @ -44,7 +35,7 @@ function checkAuth(req: Request, res: Response, next: Callback) { | |||||||
| 
 | 
 | ||||||
| // 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: Request, res: Response, next: Callback) { | function checkApiAuthOrElectron(req: AppRequest, 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"); | ||||||
|     } |     } | ||||||
| @ -53,7 +44,7 @@ function checkApiAuthOrElectron(req: Request, res: Response, next: Callback) { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function checkApiAuth(req: Request, res: Response, next: Callback) { | function checkApiAuth(req: AppRequest, 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"); | ||||||
|     } |     } | ||||||
| @ -62,7 +53,7 @@ function checkApiAuth(req: Request, res: Response, next: Callback) { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function checkAppInitialized(req: Request, res: Response, next: Callback) { | function checkAppInitialized(req: AppRequest, res: Response, next: NextFunction) { | ||||||
|     if (!sqlInit.isDbInitialized()) { |     if (!sqlInit.isDbInitialized()) { | ||||||
|         res.redirect("setup"); |         res.redirect("setup"); | ||||||
|     } |     } | ||||||
| @ -71,7 +62,7 @@ function checkAppInitialized(req: Request, res: Response, next: Callback) { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function checkPasswordSet(req: Request, res: Response, next: Callback) { | function checkPasswordSet(req: AppRequest, res: Response, next: NextFunction) { | ||||||
|     if (!utils.isElectron() && !passwordService.isPasswordSet()) { |     if (!utils.isElectron() && !passwordService.isPasswordSet()) { | ||||||
|         res.redirect("set-password"); |         res.redirect("set-password"); | ||||||
|     } else { |     } else { | ||||||
| @ -79,7 +70,7 @@ function checkPasswordSet(req: Request, res: Response, next: Callback) { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function checkPasswordNotSet(req: Request, res: Response, next: Callback) { | function checkPasswordNotSet(req: AppRequest, res: Response, next: NextFunction) { | ||||||
|     if (!utils.isElectron() && passwordService.isPasswordSet()) { |     if (!utils.isElectron() && passwordService.isPasswordSet()) { | ||||||
|         res.redirect("login"); |         res.redirect("login"); | ||||||
|     } else { |     } else { | ||||||
| @ -87,7 +78,7 @@ function checkPasswordNotSet(req: Request, res: Response, next: Callback) { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function checkAppNotInitialized(req: Request, res: Response, next: Callback) { | function checkAppNotInitialized(req: AppRequest, res: Response, next: NextFunction) { | ||||||
|     if (sqlInit.isDbInitialized()) { |     if (sqlInit.isDbInitialized()) { | ||||||
|         reject(req, res, "App already initialized."); |         reject(req, res, "App already initialized."); | ||||||
|     } |     } | ||||||
| @ -96,7 +87,7 @@ function checkAppNotInitialized(req: Request, res: Response, next: Callback) { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function checkEtapiToken(req: Request, res: Response, next: Callback) { | function checkEtapiToken(req: AppRequest, res: Response, next: NextFunction) { | ||||||
|     if (etapiTokenService.isValidAuthHeader(req.headers.authorization)) { |     if (etapiTokenService.isValidAuthHeader(req.headers.authorization)) { | ||||||
|         next(); |         next(); | ||||||
|     } |     } | ||||||
| @ -105,7 +96,7 @@ function checkEtapiToken(req: Request, res: Response, next: Callback) { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function reject(req: Request, res: Response, message: string) { | function reject(req: AppRequest, 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") | ||||||
| @ -113,7 +104,7 @@ function reject(req: Request, res: Response, message: string) { | |||||||
|         .send(message); |         .send(message); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function checkCredentials(req: Request, res: Response, next: Callback) { | function checkCredentials(req: AppRequest, 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) | ||||||
|  | |||||||
| @ -80,7 +80,7 @@ function validateLocalDateTime(str: string | null | undefined) { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function validateUtcDateTime(str?: string) { | function validateUtcDateTime(str: string | undefined) { | ||||||
|     if (!str) { |     if (!str) { | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -25,7 +25,7 @@ function createToken(tokenName: string) { | |||||||
|     }; |     }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function parseAuthToken(auth?: string | null) { | function parseAuthToken(auth: string | undefined) { | ||||||
|     if (!auth) { |     if (!auth) { | ||||||
|         return null; |         return null; | ||||||
|     } |     } | ||||||
| @ -64,7 +64,7 @@ function parseAuthToken(auth?: string | null) { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function isValidAuthHeader(auth?: string | null) { | function isValidAuthHeader(auth: string | undefined) { | ||||||
|     const parsed = parseAuthToken(auth); |     const parsed = parseAuthToken(auth); | ||||||
| 
 | 
 | ||||||
|     if (!parsed) { |     if (!parsed) { | ||||||
|  | |||||||
| @ -615,7 +615,7 @@ function getKeyboardActions() { | |||||||
| 
 | 
 | ||||||
|     for (const option of optionService.getOptions()) { |     for (const option of optionService.getOptions()) { | ||||||
|         if (option.name.startsWith('keyboardShortcuts')) { |         if (option.name.startsWith('keyboardShortcuts')) { | ||||||
|             let actionName = option.name.substr(17); |             let actionName = option.name.substring(17); | ||||||
|             actionName = actionName.charAt(0).toLowerCase() + actionName.slice(1); |             actionName = actionName.charAt(0).toLowerCase() + actionName.slice(1); | ||||||
| 
 | 
 | ||||||
|             const action = actions.find(ea => ea.actionName === actionName); |             const action = actions.find(ea => ea.actionName === actionName); | ||||||
|  | |||||||
| @ -745,7 +745,7 @@ function saveRevisionIfNeeded(note: BNote) { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function updateNoteData(noteId: string, content: string, attachments: BAttachment[] = []) { | function updateNoteData(noteId: string, content: string, attachments: AttachmentRow[] = []) { | ||||||
|     const note = becca.getNote(noteId); |     const note = becca.getNote(noteId); | ||||||
| 
 | 
 | ||||||
|     if (!note || !note.isContentAvailable()) { |     if (!note || !note.isContentAvailable()) { | ||||||
| @ -761,11 +761,7 @@ function updateNoteData(noteId: string, content: string, attachments: BAttachmen | |||||||
|     if (attachments?.length > 0) { |     if (attachments?.length > 0) { | ||||||
|         const existingAttachmentsByTitle = utils.toMap(note.getAttachments({includeContentLength: false}), 'title'); |         const existingAttachmentsByTitle = utils.toMap(note.getAttachments({includeContentLength: false}), 'title'); | ||||||
| 
 | 
 | ||||||
|         for (const attachment of attachments) { |         for (const {attachmentId, role, mime, title, position, content} of attachments) { | ||||||
|             // TODO: The content property was extracted directly instead of `getContent`. To investigate.
 |  | ||||||
|             const {attachmentId, role, mime, title, position} = attachment; |  | ||||||
|             const content = attachment.getContent(); |  | ||||||
| 
 |  | ||||||
|             if (attachmentId || !(title in existingAttachmentsByTitle)) { |             if (attachmentId || !(title in existingAttachmentsByTitle)) { | ||||||
|                 note.saveAttachment({attachmentId, role, mime, title, content, position}); |                 note.saveAttachment({attachmentId, role, mime, title, content, position}); | ||||||
|             } else { |             } else { | ||||||
| @ -773,11 +769,13 @@ function updateNoteData(noteId: string, content: string, attachments: BAttachmen | |||||||
|                 existingAttachment.role = role; |                 existingAttachment.role = role; | ||||||
|                 existingAttachment.mime = mime; |                 existingAttachment.mime = mime; | ||||||
|                 existingAttachment.position = position; |                 existingAttachment.position = position; | ||||||
|  |                 if (content) { | ||||||
|                     existingAttachment.setContent(content, {forceSave: true}); |                     existingAttachment.setContent(content, {forceSave: true}); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| function undeleteNote(noteId: string, taskContext: TaskContext) { | function undeleteNote(noteId: string, taskContext: TaskContext) { | ||||||
|     const noteRow = sql.getRow<NoteRow>("SELECT * FROM notes WHERE noteId = ?", [noteId]); |     const noteRow = sql.getRow<NoteRow>("SELECT * FROM notes WHERE noteId = ?", [noteId]); | ||||||
| @ -876,7 +874,7 @@ function getUndeletedParentBranchIds(noteId: string, deleteId: string) { | |||||||
|                       AND parentNote.isDeleted = 0`, [noteId, deleteId]);
 |                       AND parentNote.isDeleted = 0`, [noteId, deleteId]);
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function scanForLinks(note: BNote | null, content: string) { | function scanForLinks(note: BNote, content: string) { | ||||||
|     if (!note || !['text', 'relationMap'].includes(note.type)) { |     if (!note || !['text', 'relationMap'].includes(note.type)) { | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -144,7 +144,7 @@ function getRows<T>(query: string, params: Params = []): T[] { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function getRawRows<T extends {} | unknown[]>(query: string, params: Params = []): T[] { | function getRawRows<T extends {} | unknown[]>(query: string, params: Params = []): T[] { | ||||||
|     return (wrap(query, s => s.raw().all(params)) as T[] | null) || []; |     return (wrap(query, s => s.raw().all(params)) as T[]) || []; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function iterateRows<T>(query: string, params: Params = []): IterableIterator<T> { | function iterateRows<T>(query: string, params: Params = []): IterableIterator<T> { | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Elian Doran
						Elian Doran