Merge branch 'develop' into feat_add-link-to-swagger-ui

This commit is contained in:
Elian Doran 2025-02-26 22:46:31 +02:00 committed by GitHub
commit 4df76fafe1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 300 additions and 28 deletions

View File

@ -18,7 +18,7 @@ runs:
# Certificate setup
- name: Import Apple certificates
if: inputs.os == 'macos'
uses: apple-actions/import-codesign-certs@v2
uses: apple-actions/import-codesign-certs@v3
with:
p12-file-base64: ${{ env.APPLE_APP_CERTIFICATE_BASE64 }}
p12-password: ${{ env.APPLE_APP_CERTIFICATE_PASSWORD }}
@ -27,7 +27,7 @@ runs:
- name: Install Installer certificate
if: inputs.os == 'macos'
uses: apple-actions/import-codesign-certs@v2
uses: apple-actions/import-codesign-certs@v3
with:
p12-file-base64: ${{ env.APPLE_INSTALLER_CERTIFICATE_BASE64 }}
p12-password: ${{ env.APPLE_INSTALLER_CERTIFICATE_PASSWORD }}
@ -180,7 +180,7 @@ runs:
dmg_file=$(find out -name "*.dmg" -print -quit)
if [ -n "$dmg_file" ]; then
echo "Found DMG: $dmg_file"
cp "$dmg_file" "upload/TriliumNextNotes-${{ github.ref_name }}-darwin-${{ inputs.arch }}.dmg"
cp "$dmg_file" "upload/TriliumNextNotes-${{ github.ref_name }}-macos-${{ inputs.arch }}.dmg"
else
echo "Warning: No DMG file found"
fi
@ -190,7 +190,7 @@ runs:
zip_file=$(find out -name "*.zip" -print -quit)
if [ -n "$zip_file" ]; then
echo "Found ZIP: $zip_file"
cp "$zip_file" "upload/TriliumNextNotes-${{ github.ref_name }}-darwin-${{ inputs.arch }}.zip"
cp "$zip_file" "upload/TriliumNextNotes-${{ github.ref_name }}-macos-${{ inputs.arch }}.zip"
else
echo "Warning: No ZIP file found"
fi

Binary file not shown.

155
package-lock.json generated
View File

@ -154,6 +154,7 @@
"@types/session-file-store": "1.2.5",
"@types/source-map-support": "0.5.10",
"@types/stream-throttle": "0.1.4",
"@types/supertest": "6.0.2",
"@types/swagger-ui-express": "4.1.8",
"@types/tmp": "0.2.6",
"@types/turndown": "5.0.5",
@ -177,6 +178,7 @@
"rimraf": "6.0.1",
"sass": "1.85.1",
"sass-loader": "16.0.5",
"supertest": "7.0.0",
"swagger-jsdoc": "6.2.8",
"tslib": "2.8.1",
"tsx": "4.19.3",
@ -4089,6 +4091,13 @@
"@types/express": "*"
}
},
"node_modules/@types/cookiejar": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.5.tgz",
"integrity": "sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/d3": {
"version": "7.4.3",
"resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz",
@ -4597,6 +4606,13 @@
"dev": true,
"license": "MIT"
},
"node_modules/@types/methods": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/@types/methods/-/methods-1.1.4.tgz",
"integrity": "sha512-ymXWVrDiCxTBE3+RIrrP533E70eA+9qu7zdWoHuOmGujkYtzf4HQF96b8nwHLqhuf4ykX61IGRIB38CC6/sImQ==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/mime": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz",
@ -4797,6 +4813,30 @@
"@types/node": "*"
}
},
"node_modules/@types/superagent": {
"version": "8.1.9",
"resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-8.1.9.tgz",
"integrity": "sha512-pTVjI73witn+9ILmoJdajHGW2jkSaOzhiFYF1Rd3EQ94kymLqB9PjD9ISg7WaALC7+dCHT0FGe9T2LktLq/3GQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/cookiejar": "^2.1.5",
"@types/methods": "^1.1.4",
"@types/node": "*",
"form-data": "^4.0.0"
}
},
"node_modules/@types/supertest": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/@types/supertest/-/supertest-6.0.2.tgz",
"integrity": "sha512-137ypx2lk/wTQbW6An6safu9hXmajAifU/s7szAHLN/FeIm5w7yR0Wkl9fdJMRSHwOn4HLAI0DaB2TOORuhPDg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/methods": "^1.1.4",
"@types/superagent": "^8.1.0"
}
},
"node_modules/@types/swagger-ui-express": {
"version": "4.1.8",
"resolved": "https://registry.npmjs.org/@types/swagger-ui-express/-/swagger-ui-express-4.1.8.tgz",
@ -5631,6 +5671,13 @@
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
"license": "MIT"
},
"node_modules/asap": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
"integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==",
"dev": true,
"license": "MIT"
},
"node_modules/asar": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/asar/-/asar-3.2.0.tgz",
@ -7017,6 +7064,16 @@
"node": ">=0.10.0"
}
},
"node_modules/component-emitter": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz",
"integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==",
"dev": true,
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/compress-commons": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-6.0.2.tgz",
@ -7184,6 +7241,13 @@
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
"license": "MIT"
},
"node_modules/cookiejar": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz",
"integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==",
"dev": true,
"license": "MIT"
},
"node_modules/core-util-is": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
@ -8320,6 +8384,17 @@
"integrity": "sha512-g8GWBkJLiIDRJfRXEdrd1wMXpNyGId2DkbfuwFahSb4OCvn717hyRJtAcEDISfp3zkwEhZ4Y4woHPA6DeyB3Fw==",
"license": "MIT"
},
"node_modules/dezalgo": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz",
"integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==",
"dev": true,
"license": "ISC",
"dependencies": {
"asap": "^2.0.0",
"wrappy": "1"
}
},
"node_modules/dir-compare": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/dir-compare/-/dir-compare-4.2.0.tgz",
@ -10043,6 +10118,13 @@
"node": ">= 6"
}
},
"node_modules/fast-safe-stringify": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz",
"integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==",
"dev": true,
"license": "MIT"
},
"node_modules/fast-uri": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.3.tgz",
@ -10408,6 +10490,21 @@
"node": ">= 6"
}
},
"node_modules/formidable": {
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/formidable/-/formidable-3.5.2.tgz",
"integrity": "sha512-Jqc1btCy3QzRbJaICGwKcBfGWuLADRerLzDqi2NwSt/UkXLsHJw2TVResiaoBufHVHy9aSgClOHCeJsSsFLTbg==",
"dev": true,
"license": "MIT",
"dependencies": {
"dezalgo": "^1.0.4",
"hexoid": "^2.0.0",
"once": "^1.4.0"
},
"funding": {
"url": "https://ko-fi.com/tunnckoCore/commissions"
}
},
"node_modules/forwarded": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
@ -10970,6 +11067,16 @@
"node": ">=18.0.0"
}
},
"node_modules/hexoid": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/hexoid/-/hexoid-2.0.0.tgz",
"integrity": "sha512-qlspKUK7IlSQv2o+5I7yhUd7TxlOG2Vr5LTa3ve2XSNVKAL/n/u/7KLvKmFNimomDIKvZFXWHv0T12mv7rT8Aw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/history": {
"version": "4.10.1",
"resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz",
@ -16888,6 +16995,54 @@
"node": ">= 8.0"
}
},
"node_modules/superagent": {
"version": "9.0.2",
"resolved": "https://registry.npmjs.org/superagent/-/superagent-9.0.2.tgz",
"integrity": "sha512-xuW7dzkUpcJq7QnhOsnNUgtYp3xRwpt2F7abdRYIpCsAt0hhUqia0EdxyXZQQpNmGtsCzYHryaKSV3q3GJnq7w==",
"dev": true,
"license": "MIT",
"dependencies": {
"component-emitter": "^1.3.0",
"cookiejar": "^2.1.4",
"debug": "^4.3.4",
"fast-safe-stringify": "^2.1.1",
"form-data": "^4.0.0",
"formidable": "^3.5.1",
"methods": "^1.1.2",
"mime": "2.6.0",
"qs": "^6.11.0"
},
"engines": {
"node": ">=14.18.0"
}
},
"node_modules/superagent/node_modules/mime": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz",
"integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==",
"dev": true,
"license": "MIT",
"bin": {
"mime": "cli.js"
},
"engines": {
"node": ">=4.0.0"
}
},
"node_modules/supertest": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/supertest/-/supertest-7.0.0.tgz",
"integrity": "sha512-qlsr7fIC0lSddmA3tzojvzubYxvlGtzumcdHgPwbFWMISQwL22MhM2Y3LNt+6w9Yyx7559VW5ab70dgphm8qQA==",
"dev": true,
"license": "MIT",
"dependencies": {
"methods": "^1.1.2",
"superagent": "^9.0.1"
},
"engines": {
"node": ">=14.18.0"
}
},
"node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",

View File

@ -44,10 +44,11 @@
"docs:build": "npm run docs:build-backend && npm run docs:build-frontend",
"build:webpack": "tsx node_modules/webpack/bin/webpack.js -c webpack.config.ts",
"build:prepare-dist": "npm run build:webpack && rimraf ./dist && tsc && tsx ./bin/copy-dist.ts",
"test": "npm run test:server && npm run test:client",
"test:server": "cross-env TRILIUM_DATA_DIR=./integration-tests/db TRILIUM_INTEGRATION_TEST=memory vitest",
"test:client": "cross-env TRILIUM_DATA_DIR=./integration-tests/db TRILIUM_INTEGRATION_TEST=memory vitest --root src/public/app",
"test:coverage": "cross-env TRILIUM_DATA_DIR=./integration-tests/db vitest --coverage",
"test": "npm run client:test && npm run server:test",
"server:test": "cross-env TRILIUM_ENV=dev TRILIUM_DATA_DIR=./integration-tests/db TRILIUM_INTEGRATION_TEST=memory vitest",
"server:coverage": "cross-env TRILIUM_ENV=dev TRILIUM_DATA_DIR=./integration-tests/db TRILIUM_INTEGRATION_TEST=memory vitest --coverage",
"client:test": "cross-env TRILIUM_ENV=dev TRILIUM_DATA_DIR=./integration-tests/db TRILIUM_INTEGRATION_TEST=memory vitest --root src/public/app",
"client:coverage": "cross-env TRILIUM_ENV=dev TRILIUM_DATA_DIR=./integration-tests/db TRILIUM_INTEGRATION_TEST=memory vitest --root src/public/app --coverage",
"test:playwright": "playwright test",
"test:integration-edit-db": "cross-env TRILIUM_INTEGRATION_TEST=edit TRILIUM_PORT=8081 TRILIUM_ENV=dev TRILIUM_DATA_DIR=./integration-tests/db nodemon src/main.ts",
"test:integration-mem-db": "cross-env TRILIUM_INTEGRATION_TEST=memory TRILIUM_PORT=8082 TRILIUM_DATA_DIR=./integration-tests/db nodemon src/main.ts",
@ -203,6 +204,7 @@
"@types/session-file-store": "1.2.5",
"@types/source-map-support": "0.5.10",
"@types/stream-throttle": "0.1.4",
"@types/supertest": "6.0.2",
"@types/swagger-ui-express": "4.1.8",
"@types/tmp": "0.2.6",
"@types/turndown": "5.0.5",
@ -226,6 +228,7 @@
"rimraf": "6.0.1",
"sass": "1.85.1",
"sass-loader": "16.0.5",
"supertest": "7.0.0",
"swagger-jsdoc": "6.2.8",
"tslib": "2.8.1",
"tsx": "4.19.3",

View File

@ -203,7 +203,7 @@ function renderFile(entity: FNote | FAttachment, type: string, $renderedContent:
// open doesn't work for protected notes since it works through a browser which isn't in protected session
$openButton.toggle(!entity.isProtected);
$content.append($('<div style="display: flex; justify-content: space-evenly; margin-top: 5px;">').append($downloadButton).append($openButton));
$content.append($('<footer class="file-footer">').append($downloadButton).append($openButton));
}
$renderedContent.append($content);

View File

@ -9,7 +9,7 @@ interface CreateNewTasksOpts {
export async function createNewTask({ parentNoteId, title }: CreateNewTasksOpts) {
await server.post(`tasks`, {
parentNoteId,
title
title: title.trim()
});
}

View File

@ -2,6 +2,9 @@ import { defineConfig } from "vitest/config";
export default defineConfig({
test: {
environment: "happy-dom"
environment: "happy-dom",
coverage: {
reporter: [ "text", "html" ]
}
}
});

View File

@ -20,6 +20,10 @@ const TPL = `
.note-list-widget.full-height .note-list-widget-content {
height: 100%;
}
.note-list-widget video {
height: 100%;
}
</style>
<div class="note-list-widget-content">

View File

@ -63,7 +63,7 @@ export default class NoteWrapperWidget extends FlexContainer<BasicWidget> {
return true;
}
if (note.type === "file" && note.mime === "application/pdf") {
if (note.type === "file" && (note.mime === "application/pdf" || note.mime.startsWith("video/"))) {
return true;
}

View File

@ -22,6 +22,10 @@ const TPL = `
padding: 0;
}
.note-split.full-content-width .note-detail-file[data-preview-type="video"] {
overflow: hidden;
}
.file-preview-content {
background-color: var(--accented-background-color);
padding: 15px;
@ -29,6 +33,11 @@ const TPL = `
overflow: auto;
margin: 10px;
}
.note-detail-file > .video-preview {
width: 100%;
height: 100%;
}
</style>
<div class="file-preview-too-big alert alert-info hidden-ext">
@ -85,6 +94,8 @@ export default class FileTypeWidget extends TypeWidget {
this.$videoPreview.hide();
this.$audioPreview.hide();
let previewType: string;
if (blob?.content) {
this.$previewContent.show().scrollTop(0);
const trimmedContent = blob.content.substring(0, TEXT_MAX_NUM_CHARS);
@ -92,23 +103,30 @@ export default class FileTypeWidget extends TypeWidget {
this.$previewTooBig.removeClass("hidden-ext");
}
this.$previewContent.text(trimmedContent);
previewType = "text";
} else if (note.mime === "application/pdf") {
this.$pdfPreview.show().attr("src", openService.getUrlForDownload(`api/notes/${this.noteId}/open`));
previewType = "pdf";
} else if (note.mime.startsWith("video/")) {
this.$videoPreview
.show()
.attr("src", openService.getUrlForDownload(`api/notes/${this.noteId}/open-partial`))
.attr("type", this.note?.mime ?? "")
.css("width", this.$widget.width() ?? 0);
previewType = "video";
} else if (note.mime.startsWith("audio/")) {
this.$audioPreview
.show()
.attr("src", openService.getUrlForDownload(`api/notes/${this.noteId}/open-partial`))
.attr("type", this.note?.mime ?? "")
.css("width", this.$widget.width() ?? 0);
previewType = "audio";
} else {
this.$previewNotAvailable.show();
previewType = "not-available";
}
this.$widget.attr("data-preview-type", previewType ?? "");
}
async entitiesReloadedEvent({ loadResults }: EventData<"entitiesReloaded">) {

View File

@ -6,6 +6,7 @@ import * as taskService from "../../services/tasks.js";
import type { EventData } from "../../components/app_context.js";
import dayjs from "dayjs";
import calendarTime from "dayjs/plugin/calendar.js";
import { t } from "../../services/i18n.js";
dayjs.extend(calendarTime);
const TPL = `
@ -25,7 +26,7 @@ const TPL = `
padding: 10px;
}
.note-detail-task-list header {
.note-detail-task-list > header {
position: sticky;
top: 0;
z-index: 100;
@ -59,15 +60,23 @@ const TPL = `
transition: background 250ms ease-in-out;
}
.note-detail-task-list .task-container li > header {
display: flex;
flex-wrap: wrap;
justify-content: flex-end;
align-items: center;
}
.note-detail-task-list .task-container li .check {
margin-right: 0.5em;
}
.note-detail-task-list .task-container li .title {
flex-grow: 1;
}
.note-detail-task-list .task-container li .due-date {
float: right;
font-size: 0.9rem;
margin-top: 0.1rem;
vertical-align: middle;
}
.note-detail-task-list .task-container li.overdue .due-date {
@ -81,6 +90,7 @@ function buildTasks(tasks: FTask[]) {
let html = '';
const now = dayjs();
const dateFormat = "DD-MM-YYYY";
for (const task of tasks) {
const classes = ["task"];
@ -89,14 +99,25 @@ function buildTasks(tasks: FTask[]) {
}
html += `<li class="${classes.join(" ")}" data-task-id="${task.taskId}">`;
html += "<header>";
html += '<span class="title">';
html += `<input type="checkbox" class="check" ${task.isDone ? "checked" : ""} />`;
html += task.title;
html += `${task.title}</span>`;
html += '</span>';
if (task.dueDate) {
html += `<span class="due-date">`;
html += `<span class="bx bx-calendar"></span> `;
html += dayjs(task.dueDate).calendar();
html += dayjs(task.dueDate).calendar(null, {
sameDay: `[${t("tasks.due.today")}]`,
nextDay: `[${t("tasks.due.tomorrow")}]`,
nextWeek: "dddd",
lastDay: `[${t("tasks.due.yesterday")}]`,
lastWeek: dateFormat,
sameElse: dateFormat
});
html += "</span>";
}
html += "</header>";
html += `<div class="edit-container"></div>`;
html += `</li>`;
}
@ -142,20 +163,19 @@ export default class TaskListWidget extends TypeWidget {
});
this.$taskContainer.on("click", "li", (e) => {
const $target = $(e.target);
// Don't collapse when clicking on an inside element such as the due date dropdown.
if (e.currentTarget !== e.target) {
if ((e.target as HTMLElement).tagName === "INPUT") {
return;
}
const $target = $(e.target);
// Clear existing edit containers.
const $existingContainers = this.$taskContainer.find(".edit-container");
$existingContainers.html("");
// Add the new edit container.
const $editContainer = $target.find(".edit-container");
const $editContainer = $target.closest("li").find(".edit-container");
const task = this.#getCorrespondingTask($target);
if (task) {
$editContainer.html(buildEditContainer(task));
@ -183,7 +203,11 @@ export default class TaskListWidget extends TypeWidget {
}
#getCorrespondingTask($target: JQuery<HTMLElement>) {
const taskId = $target.closest("li")[0].dataset.taskId;
const $parentEl = $target.closest("li");
if (!$parentEl.length) {
return;
}
const taskId = $parentEl[0].dataset.taskId;
if (!taskId) {
return;
}

View File

@ -1685,3 +1685,14 @@ body.zen .note-title-widget input {
font-size: 1rem !important;
background: transparent !important;
}
/* Content renderer */
footer.file-footer {
display: flex;
justify-content: center;
}
footer.file-footer button {
margin: 5px;
}

View File

@ -1560,6 +1560,10 @@ div.bookmark-folder-widget .note-link .bx {
border-bottom-color: var(--card-border-color);
}
.note-list-wrapper .note-book-card footer.file-footer {
border: 1px solid var(--card-border-color);
}
.note-list-wrapper .note-book-card .note-book-header .note-icon {
font-size: 17px;
vertical-align: text-bottom;
@ -1610,7 +1614,8 @@ div.bookmark-folder-widget .note-link .bx {
.note-list-wrapper .note-book-card .note-book-content.type-canvas .rendered-content,
.note-list-wrapper .note-book-card .note-book-content.type-mindMap .rendered-content,
.note-list-wrapper .note-book-card .note-book-content.type-code .rendered-content {
.note-list-wrapper .note-book-card .note-book-content.type-code .rendered-content,
.note-list-wrapper .note-book-card .note-book-content.type-video .rendered-content {
padding: 0;
}

View File

@ -1675,5 +1675,12 @@
"time_selector": {
"invalid_input": "The entered time value is not a valid number.",
"minimum_input": "The entered time value needs to be at least {{minimumSeconds}} seconds."
},
"tasks": {
"due": {
"today": "Today",
"tomorrow": "Tomorrow",
"yesterday": "Yesterday"
}
}
}

View File

@ -1678,5 +1678,12 @@
"redirect_bare_domain_description": "Redirecționează utilizatorii anonimi către pagina de partajare în locul paginii de autentificare",
"redirect_bare_domain": "Redirecționează domeniul principal la pagina de partajare",
"check_share_root": "Verificare stare pagină partajată principală"
},
"tasks": {
"due": {
"today": "Azi",
"tomorrow": "Mâine",
"yesterday": "Ieri"
}
}
}

34
src/share/routes.spec.ts Normal file
View File

@ -0,0 +1,34 @@
import { beforeAll, beforeEach, describe, expect, it } from "vitest";
import supertest from "supertest";
import { initializeTranslations } from "../services/i18n.js";
import type { Application, Request, Response, NextFunction } from "express";
let app: Application;
describe("Share API test", () => {
let cannotSetHeadersCount = 0;
beforeAll(async () => {
initializeTranslations();
app = (await import("../app.js")).default;
app.use((err: any, req: Request, res: Response, next: NextFunction) => {
if (err.message.includes("Cannot set headers after they are sent to the client")) {
cannotSetHeadersCount++;
}
next();
});
});
beforeEach(() => {
cannotSetHeadersCount = 0;
});
it("requests password for password-protected share", async () => {
await supertest(app)
.get("/share/YjlPRj2E9fOV")
.expect("WWW-Authenticate", 'Basic realm="User Visible Realm", charset="UTF-8"');
expect(cannotSetHeadersCount).toBe(0);
});
});

View File

@ -87,7 +87,6 @@ function checkNoteAccess(noteId: string, req: Request, res: Response) {
const header = req.header("Authorization");
if (!header?.startsWith("Basic ")) {
requestCredentials(res);
return false;
}

View File

@ -19,7 +19,9 @@ export default defineConfig({
test: {
exclude: [...configDefaults.exclude, ...customExcludes],
coverage: {
exclude: [...coverageConfigDefaults.exclude, ...customExcludes]
reporter: [ "text", "html" ],
include: ["src/**"],
exclude: ["src/public/**"]
}
}
});