Skip to content

Commit 324a8b5

Browse files
author
x1arch
committed
accessor fix; typo fix;
1 parent 60d16cb commit 324a8b5

File tree

4 files changed

+22
-19
lines changed

4 files changed

+22
-19
lines changed

apps/server/src/share/content_renderer.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ interface Subroot {
4040

4141
type GetNoteFunction = (id: string) => SNote | BNote | null;
4242

43-
function addContentAccessQuery(note: any, secondEl?:boolean) {
44-
if ((note as SNote).contentAccessor && (note as SNote).contentAccessor?.type === "query") {
43+
function addContentAccessQuery(note: SNote | BNote, secondEl?:boolean) {
44+
if (!(note instanceof BNote) && note.contentAccessor && note.contentAccessor?.type === "query") {
4545
return secondEl ? `&cat=${note.contentAccessor.getToken()}` : `?cat=${note.contentAccessor.getToken()}`;
4646
}
4747
return ""
@@ -447,7 +447,7 @@ function renderMermaid(result: Result, note: SNote | BNote) {
447447
}
448448

449449
function renderImage(result: Result, note: SNote | BNote) {
450-
result.content = `<img src="../api/images/${note.noteId}/${note.encodedTitle}?${note.utcDateModified}${addContentAccessQuery(note, true)}">`;
450+
result.content = `<img src="api/images/${note.noteId}/${note.encodedTitle}?${note.utcDateModified}${addContentAccessQuery(note, true)}">`;
451451
}
452452

453453
function renderFile(note: SNote | BNote, result: Result) {

apps/server/src/share/routes.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,10 @@ function checkNoteAccess(noteId: string, req: Request, res: Response) {
6161

6262
if (!header?.startsWith("Basic ")) {
6363
if (req.path.startsWith("/share/api") && note.contentAccessor) {
64-
const contentAccessToken = "" + (note.contentAccessor.type === "cookie" ? req.cookies["trilium.cat"] || "" : note.contentAccessor.type === "query" ? req.query['cat'] || "" : "")
64+
let contentAccessToken = ""
65+
if (note.contentAccessor.type === "cookie") contentAccessToken += req.cookies["trilium.cat"] || ""
66+
else if (note.contentAccessor.type === "query") contentAccessToken += req.query['cat'] || ""
67+
6568
if (contentAccessToken){
6669
if (note.contentAccessor.isTokenValid(contentAccessToken)){
6770
return note

apps/server/src/share/shaca/entities/content_accessor.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,22 @@ import crypto from "crypto";
22
import SNote from "./snote";
33
import utils from "../../../services/utils";
44

5-
export const DefultAccessTimeoutSec = 10 * 60; // 10 minutes
6-
5+
const DefaultAccessTimeoutSec = 10 * 60; // 10 minutes
76

87
export class ContentAccessor {
98
note: SNote;
109
token: string;
1110
timestamp: number;
1211
type: string;
1312
timeout: number;
14-
key: NonSharedBuffer;
15-
iv: NonSharedBuffer;
13+
key: Buffer;
1614

1715
constructor(note: SNote) {
1816
this.note = note;
1917
this.key = crypto.randomBytes(32);
20-
this.iv = crypto.randomBytes(16);
2118
this.token = "";
2219
this.timestamp = 0;
23-
this.timeout = Number(this.note.getAttributeValue("label", "shareAccessTokenTimeout") || DefultAccessTimeoutSec)
20+
this.timeout = Number(this.note.getAttributeValue("label", "shareAccessTokenTimeout") || DefaultAccessTimeoutSec)
2421

2522
switch (this.note.getAttributeValue("label", "shareContentAccess")) {
2623
case "basic": this.type = "basic"; break
@@ -31,18 +28,20 @@ export class ContentAccessor {
3128
}
3229

3330
__encrypt(text: string) {
34-
const cipher = crypto.createCipheriv('aes-256-cbc', this.key, this.iv);
35-
let encrypted = cipher.update(text);
36-
encrypted = Buffer.concat([encrypted, cipher.final()]);
37-
return encrypted.toString('hex');
31+
const iv = crypto.randomBytes(16);
32+
const cipher = crypto.createCipheriv('aes-256-cbc', this.key, iv);
33+
let encrypted = cipher.update(text, 'utf8', 'hex');
34+
encrypted += cipher.final('hex');
35+
return iv.toString('hex') + encrypted;
3836
}
3937

4038
__decrypt(encryptedText: string) {
4139
try {
42-
const decipher = crypto.createDecipheriv('aes-256-cbc', this.key, this.iv);
43-
let decrypted = decipher.update(Buffer.from(encryptedText, 'hex'));
44-
decrypted = Buffer.concat([decrypted, decipher.final()]);
45-
return decrypted.toString();
40+
const iv = Buffer.from(encryptedText.slice(0, 32), 'hex');
41+
const decipher = crypto.createDecipheriv('aes-256-cbc', this.key, iv);
42+
let decrypted = decipher.update(encryptedText.slice(32), 'hex', 'utf8');
43+
decrypted += decipher.final('utf8');
44+
return decrypted;
4645
} catch {
4746
return ""
4847
}
@@ -55,6 +54,7 @@ export class ContentAccessor {
5554
update() {
5655
if (new Date().getTime() < this.timestamp + this.getTimeout() * 1000) return
5756
this.token = utils.randomString(36);
57+
this.key = crypto.randomBytes(32);
5858
this.timestamp = new Date().getTime();
5959
}
6060

docs/User Guide/User Guide/Advanced Usage/Sharing.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ To do so, create a shared text note and apply the `shareIndex` label. When viewe
131131

132132
## Attribute reference
133133

134-
<table class="ck-table-resized"><colgroup><col style="width:18.38%;"><col style="width:81.62%;"></colgroup><thead><tr><th>Attribute</th><th>Description</th></tr></thead><tbody><tr><td><code>#shareHiddenFromTree</code></td><td>this note is hidden from left navigation tree, but still accessible with its URL</td></tr><tr><td><code>#shareTemplateNoPrevNext</code></td><td>hide bottom page navigation prev and next page.</td></tr><tr><td><code>#shareTemplateNoLeftPanel</code></td><td>hide left panel fully.</td></tr><tr><td><code>#shareExclude</code></td><td>this note will be excluded from share, not accessible via direct URL (implemented to hide scripts from share)</td></tr><tr><td><code>#shareContentAccess</code></td><td>method for attachments authorization in case when note protected with login and password (#shareCredentials). Could be cookie (the cookie will provided when page loads) / query (every url will be updated with token) / basic (only basic header authorization)). By default for browser used cookie.</td></tr><tr><td><code>#shareAccessTokenTimeout</code></td><td>token expiration timeout in seconds, by default 10 minutes. While token not expired user couls download attachment, after that he will get message `Access is expired. Return back and update the page.`</td></tr><tr><td><code>#shareExternalLink</code></td><td>note will act as a link to an external website in the share tree</td></tr><tr><td><code>#shareAlias</code></td><td>define an alias using which the note will be available under <code>https://your_trilium_host/share/[your_alias]</code></td></tr><tr><td><code>#shareOmitDefaultCss</code></td><td>default share page CSS will be omitted. Use when you make extensive styling changes.</td></tr><tr><td><code>#shareRoot</code></td><td>marks note which is served on /share root.</td></tr><tr><td><code>#shareDescription</code></td><td>define text to be added to the HTML meta tag for description</td></tr><tr><td><code>#shareRaw</code></td><td>Note will be served in its raw format, without HTML wrapper. See also&nbsp;<a class="reference-link" href="Sharing/Serving%20directly%20the%20content%20o.md">Serving directly the content of a note</a>&nbsp;for an alternative method without setting an attribute.</td></tr><tr><td><code>#shareDisallowRobotIndexing</code></td><td><p>Indicates to web crawlers that the page should not be indexed of this note by:</p><ul><li data-list-item-id="e6baa9f60bf59d085fd31aa2cce07a0e7">Setting the <code>X-Robots-Tag: noindex</code> HTTP header.</li><li data-list-item-id="ec0d067db136ef9794e4f1033405880b7">Setting the <code>noindex, follow</code> meta tag.</li></ul></td></tr><tr><td><code>#shareCredentials</code></td><td>require credentials to access this shared note. Value is expected to be in format <code>username:password</code>. Don't forget to make this inheritable to apply to child-notes/images.</td></tr><tr><td><code>#shareIndex</code></td><td>Note with this label will list all roots of shared notes.</td></tr><tr><td><code>#shareHtmlLocation</code></td><td>defines where custom HTML injected via <code>~shareHtml</code> relation should be placed. Applied to the HTML snippet note itself. Format: <code>location:position</code> where location is <code>head</code>, <code>body</code>, or <code>content</code> and position is <code>start</code> or <code>end</code>. Defaults to <code>content:end</code>.</td></tr></tbody></table>
134+
<table class="ck-table-resized"><colgroup><col style="width:18.38%;"><col style="width:81.62%;"></colgroup><thead><tr><th>Attribute</th><th>Description</th></tr></thead><tbody><tr><td><code>#shareHiddenFromTree</code></td><td>this note is hidden from left navigation tree, but still accessible with its URL</td></tr><tr><td><code>#shareTemplateNoPrevNext</code></td><td>hide bottom page navigation prev and next page.</td></tr><tr><td><code>#shareTemplateNoLeftPanel</code></td><td>hide left panel fully.</td></tr><tr><td><code>#shareExclude</code></td><td>this note will be excluded from share, not accessible via direct URL (implemented to hide scripts from share)</td></tr><tr><td><code>#shareContentAccess</code></td><td>method for attachments authorization in case when note protected with login and password (#shareCredentials). Could be cookie (the cookie will be provided when page loads) / query (every url will be updated with token) / basic (only basic header authorization)). By default for browser used cookie.</td></tr><tr><td><code>#shareAccessTokenTimeout</code></td><td>token expiration timeout in seconds, by default 10 minutes. While token not expired user could download attachment, after that he will get message `Access is expired. Return back and update the page.`</td></tr><tr><td><code>#shareExternalLink</code></td><td>note will act as a link to an external website in the share tree</td></tr><tr><td><code>#shareAlias</code></td><td>define an alias using which the note will be available under <code>https://your_trilium_host/share/[your_alias]</code></td></tr><tr><td><code>#shareOmitDefaultCss</code></td><td>default share page CSS will be omitted. Use when you make extensive styling changes.</td></tr><tr><td><code>#shareRoot</code></td><td>marks note which is served on /share root.</td></tr><tr><td><code>#shareDescription</code></td><td>define text to be added to the HTML meta tag for description</td></tr><tr><td><code>#shareRaw</code></td><td>Note will be served in its raw format, without HTML wrapper. See also&nbsp;<a class="reference-link" href="Sharing/Serving%20directly%20the%20content%20o.md">Serving directly the content of a note</a>&nbsp;for an alternative method without setting an attribute.</td></tr><tr><td><code>#shareDisallowRobotIndexing</code></td><td><p>Indicates to web crawlers that the page should not be indexed of this note by:</p><ul><li data-list-item-id="e6baa9f60bf59d085fd31aa2cce07a0e7">Setting the <code>X-Robots-Tag: noindex</code> HTTP header.</li><li data-list-item-id="ec0d067db136ef9794e4f1033405880b7">Setting the <code>noindex, follow</code> meta tag.</li></ul></td></tr><tr><td><code>#shareCredentials</code></td><td>require credentials to access this shared note. Value is expected to be in format <code>username:password</code>. Don't forget to make this inheritable to apply to child-notes/images.</td></tr><tr><td><code>#shareIndex</code></td><td>Note with this label will list all roots of shared notes.</td></tr><tr><td><code>#shareHtmlLocation</code></td><td>defines where custom HTML injected via <code>~shareHtml</code> relation should be placed. Applied to the HTML snippet note itself. Format: <code>location:position</code> where location is <code>head</code>, <code>body</code>, or <code>content</code> and position is <code>start</code> or <code>end</code>. Defaults to <code>content:end</code>.</td></tr></tbody></table>
135135

136136
### Customizing logo
137137

0 commit comments

Comments
 (0)