mirror of
https://github.com/zadam/trilium.git
synced 2026-01-16 03:24:24 +01:00
chore(core): integrate some more utils
This commit is contained in:
parent
299c06c1a6
commit
c6197e520d
@ -55,8 +55,7 @@
|
||||
"@types/express-session": "1.18.2",
|
||||
"@types/fs-extra": "11.0.4",
|
||||
"@types/html": "1.0.4",
|
||||
"@types/ini": "4.1.1",
|
||||
"@types/mime-types": "3.0.1",
|
||||
"@types/ini": "4.1.1",
|
||||
"@types/multer": "2.0.0",
|
||||
"@types/safe-compare": "1.1.2",
|
||||
"@types/sax": "1.2.7",
|
||||
@ -108,14 +107,12 @@
|
||||
"jimp": "1.6.0",
|
||||
"lorem-ipsum": "2.0.8",
|
||||
"marked": "17.0.1",
|
||||
"mime-types": "3.0.2",
|
||||
"multer": "2.0.2",
|
||||
"normalize-strings": "1.1.1",
|
||||
"ollama": "0.6.3",
|
||||
"openai": "6.15.0",
|
||||
"rand-token": "1.0.1",
|
||||
"safe-compare": "1.1.4",
|
||||
"sanitize-filename": "1.6.3",
|
||||
"safe-compare": "1.1.4",
|
||||
"sax": "1.4.3",
|
||||
"serve-favicon": "2.5.1",
|
||||
"stream-throttle": "0.1.3",
|
||||
|
||||
@ -5,11 +5,8 @@ import chardet from "chardet";
|
||||
import crypto from "crypto";
|
||||
import escape from "escape-html";
|
||||
import { t } from "i18next";
|
||||
import mimeTypes from "mime-types";
|
||||
import { release as osRelease } from "os";
|
||||
import path from "path";
|
||||
import { generator } from "rand-token";
|
||||
import sanitize from "sanitize-filename";
|
||||
import stripBom from "strip-bom";
|
||||
import unescape from "unescape";
|
||||
|
||||
@ -140,12 +137,12 @@ export async function crash(message: string) {
|
||||
}
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
export function getContentDisposition(filename: string) {
|
||||
const sanitizedFilename = sanitize(filename).trim() || "file";
|
||||
const uriEncodedFilename = encodeURIComponent(sanitizedFilename);
|
||||
return `file; filename="${uriEncodedFilename}"; filename*=UTF-8''${uriEncodedFilename}`;
|
||||
return coreUtils.getContentDisposition(filename);
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
export function isStringNote(type: string | undefined, mime: string) {
|
||||
return coreUtils.isStringNote(type, mime);
|
||||
}
|
||||
@ -160,30 +157,9 @@ export function replaceAll(string: string, replaceWhat: string, replaceWith: str
|
||||
return coreUtils.replaceAll(string, replaceWhat, replaceWith);
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
export function formatDownloadTitle(fileName: string, type: string | null, mime: string) {
|
||||
const fileNameBase = !fileName ? "untitled" : sanitize(fileName);
|
||||
|
||||
const getExtension = () => {
|
||||
if (type === "text") return ".html";
|
||||
if (type === "relationMap" || type === "canvas" || type === "search") return ".json";
|
||||
if (!mime) return "";
|
||||
|
||||
const mimeLc = mime.toLowerCase();
|
||||
|
||||
// better to just return the current name without a fake extension
|
||||
// it's possible that the title still preserves the correct extension anyways
|
||||
if (mimeLc === "application/octet-stream") return "";
|
||||
|
||||
// if fileName has an extension matching the mime already - reuse it
|
||||
const mimeTypeFromFileName = mimeTypes.lookup(fileName);
|
||||
if (mimeTypeFromFileName === mimeLc) return "";
|
||||
|
||||
// as last resort try to get extension from mimeType
|
||||
const extensions = mimeTypes.extension(mime);
|
||||
return extensions ? `.${extensions}` : "";
|
||||
};
|
||||
|
||||
return `${fileNameBase}${getExtension()}`;
|
||||
return coreUtils.formatDownloadTitle(fileName, type, mime);
|
||||
}
|
||||
|
||||
export function removeTextFileExtension(filePath: string) {
|
||||
|
||||
@ -8,8 +8,13 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@triliumnext/commons": "workspace:*",
|
||||
"sanitize-html": "2.17.0",
|
||||
"sanitize-html": "2.17.0",
|
||||
"@braintree/sanitize-url": "7.1.1",
|
||||
"sanitize-filename": "1.6.3",
|
||||
"mime-types": "3.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/sanitize-html": "2.16.0",
|
||||
"@braintree/sanitize-url": "7.1.1"
|
||||
"@types/mime-types": "3.0.1"
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ import AbstractBeccaEntity from "./abstract_becca_entity.js";
|
||||
import type BBranch from "./bbranch.js";
|
||||
import type BNote from "./bnote.js";
|
||||
import { getSql } from "../../services/sql/index.js";
|
||||
import { isStringNote, replaceAll } from "../../services/utils";
|
||||
import { formatDownloadTitle, isStringNote, replaceAll } from "../../services/utils";
|
||||
|
||||
const attachmentRoleToNoteTypeMapping = {
|
||||
image: "image",
|
||||
@ -201,7 +201,7 @@ class BAttachment extends AbstractBeccaEntity<BAttachment> {
|
||||
getFileName() {
|
||||
const type = this.role === "image" ? "image" : "file";
|
||||
|
||||
return utils.formatDownloadTitle(this.title, type, this.mime);
|
||||
return formatDownloadTitle(this.title, type, this.mime);
|
||||
}
|
||||
|
||||
override beforeSaving() {
|
||||
|
||||
@ -19,7 +19,7 @@ import BAttribute from "./battribute.js";
|
||||
import type BBranch from "./bbranch.js";
|
||||
import BRevision from "./brevision.js";
|
||||
import { getSql } from "../../services/sql/index.js";
|
||||
import { isStringNote, normalize, randomString, replaceAll } from "../../services/utils";
|
||||
import { formatDownloadTitle, isStringNote, normalize, randomString, replaceAll } from "../../services/utils";
|
||||
|
||||
const LABEL = "label";
|
||||
const RELATION = "relation";
|
||||
@ -1654,7 +1654,7 @@ class BNote extends AbstractBeccaEntity<BNote> {
|
||||
}
|
||||
|
||||
getFileName() {
|
||||
return utils.formatDownloadTitle(this.title, this.type, this.mime);
|
||||
return formatDownloadTitle(this.title, this.type, this.mime);
|
||||
}
|
||||
|
||||
override beforeSaving() {
|
||||
|
||||
@ -2,10 +2,10 @@ import type { BlobRow, EntityChange } from "@triliumnext/commons";
|
||||
|
||||
import becca from "../becca/becca.js";
|
||||
import dateUtils from "./utils/date.js";
|
||||
import { getLog } from "./log.js";
|
||||
import { getLog } from "./log.js";
|
||||
import { randomString } from "./utils/index.js";
|
||||
import { getSql } from "./sql/index.js";
|
||||
import { getComponentId } from "./context.js";
|
||||
import * as cls from "./context.js";
|
||||
import events from "./events.js";
|
||||
import blobService from "./blob.js";
|
||||
import getInstanceId from "./instance_id.js";
|
||||
@ -33,7 +33,7 @@ function putEntityChange(origEntityChange: EntityChange) {
|
||||
ec.changeId = randomString(12);
|
||||
}
|
||||
|
||||
ec.componentId = ec.componentId || getComponentId() || "NA"; // NA = not available
|
||||
ec.componentId = ec.componentId || cls.getComponentId() || "NA"; // NA = not available
|
||||
ec.instanceId = ec.instanceId || getInstanceId();
|
||||
ec.isSynced = ec.isSynced ? 1 : 0;
|
||||
ec.isErased = ec.isErased ? 1 : 0;
|
||||
|
||||
@ -3,6 +3,7 @@ import { ALLOWED_PROTOCOLS, SANITIZER_DEFAULT_ALLOWED_TAGS } from "@triliumnext/
|
||||
|
||||
import optionService from "./options.js";
|
||||
import sanitize from "sanitize-html";
|
||||
import sanitizeFileNameInternal from "sanitize-filename";
|
||||
|
||||
// intended mainly as protection against XSS via import
|
||||
// secondarily, it (partly) protects against "CSS takeover"
|
||||
@ -88,3 +89,7 @@ export function sanitizeHtmlCustom(dirtyHtml: string, config: sanitize.IOptions)
|
||||
export function sanitizeUrl(url: string) {
|
||||
return sanitizeUrlInternal(url).trim();
|
||||
}
|
||||
|
||||
export function sanitizeFileName(fileName: string) {
|
||||
return sanitizeFileNameInternal(fileName);
|
||||
}
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
import { getCrypto } from "../encryption/crypto";
|
||||
import { sanitizeFileName } from "../sanitizer";
|
||||
import { encodeBase64 } from "./binary";
|
||||
import mimeTypes from "mime-types";
|
||||
|
||||
// render and book are string note in the sense that they are expected to contain empty string
|
||||
const STRING_NOTE_TYPES = new Set(["text", "code", "relationMap", "search", "render", "book", "mermaid", "canvas", "webView"]);
|
||||
@ -65,3 +67,35 @@ export function sanitizeAttributeName(origName: string) {
|
||||
|
||||
return fixedName;
|
||||
}
|
||||
|
||||
export function getContentDisposition(filename: string) {
|
||||
const sanitizedFilename = sanitizeFileName(filename).trim() || "file";
|
||||
const uriEncodedFilename = encodeURIComponent(sanitizedFilename);
|
||||
return `file; filename="${uriEncodedFilename}"; filename*=UTF-8''${uriEncodedFilename}`;
|
||||
}
|
||||
|
||||
export function formatDownloadTitle(fileName: string, type: string | null, mime: string) {
|
||||
const fileNameBase = !fileName ? "untitled" : sanitizeFileName(fileName);
|
||||
|
||||
const getExtension = () => {
|
||||
if (type === "text") return ".html";
|
||||
if (type === "relationMap" || type === "canvas" || type === "search") return ".json";
|
||||
if (!mime) return "";
|
||||
|
||||
const mimeLc = mime.toLowerCase();
|
||||
|
||||
// better to just return the current name without a fake extension
|
||||
// it's possible that the title still preserves the correct extension anyways
|
||||
if (mimeLc === "application/octet-stream") return "";
|
||||
|
||||
// if fileName has an extension matching the mime already - reuse it
|
||||
const mimeTypeFromFileName = mimeTypes.lookup(fileName);
|
||||
if (mimeTypeFromFileName === mimeLc) return "";
|
||||
|
||||
// as last resort try to get extension from mimeType
|
||||
const extensions = mimeTypes.extension(mime);
|
||||
return extensions ? `.${extensions}` : "";
|
||||
};
|
||||
|
||||
return `${fileNameBase}${getExtension()}`;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user