Compare commits

...

9 commits

Author SHA1 Message Date
Ell 9359ff3571 0.1.2 2023-08-18 13:04:06 +02:00
Ell 3c59ee5de9 prevent directory traversal on server 2023-08-18 13:03:03 +02:00
Ell d852b61a67 bleh type checks 2023-08-18 12:58:43 +02:00
Ell 46cfbdfd36 don't cast blindly 2023-08-18 12:55:07 +02:00
Ell c7be82d5fa don't use titlecase for settings names 2023-08-18 12:51:56 +02:00
Ell 6a3303bacb removed settings header 2023-08-18 12:51:00 +02:00
Ell 0c6d1f286b 0.1.1 2023-08-18 10:19:18 +02:00
Ell f8bdde10a3 display full path in view if required 2023-08-18 10:13:57 +02:00
Ell babb0ea22f improved paths 2023-08-18 10:01:18 +02:00
10 changed files with 109 additions and 44 deletions

View file

@ -1,7 +1,7 @@
{
"id": "just-share-please",
"name": "Just Share Please",
"version": "0.1.0",
"version": "0.1.2",
"minAppVersion": "1.3.7",
"description": "Quickly and easily share individual notes online using an anonymized link. Also easy to self-host!",
"author": "Ellpeck",

4
package-lock.json generated
View file

@ -1,12 +1,12 @@
{
"name": "just-share-please",
"version": "0.1.0",
"version": "0.1.2",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "just-share-please",
"version": "0.1.0",
"version": "0.1.2",
"license": "MIT",
"devDependencies": {
"@types/node": "^16.11.6",

View file

@ -1,6 +1,6 @@
{
"name": "just-share-please",
"version": "0.1.0",
"version": "0.1.2",
"description": "Quickly and easily share individual notes online using an anonymized link. Also easy to self-host!",
"main": "main.js",
"scripts": {

View file

@ -114,13 +114,14 @@ function get_markdown_content(): ?string {
}
function get_markdown_path(string $id): string {
return get_data_path() . $id . ".md";
return get_id_base_path($id) . ".md";
}
function get_meta_path(string $id): string {
return get_data_path() . $id . ".json";
return get_id_base_path($id) . ".json";
}
function get_data_path(): string {
return dirname(getcwd()) . "/data/";
function get_id_base_path(string $id): string {
// ensure id can't be used to traverse into other directories
return dirname(getcwd()) . "/data/" . basename($id);
}

View file

@ -1,7 +1,6 @@
import {arrayBufferToBase64, Notice, Plugin, requestUrl, TFile} from "obsidian";
import {defaultSettings, JSPSettings, SharedItem} from "./settings";
import {JSPSettingsTab} from "./settings-tab";
import {basename, extname} from "path";
import {JSPView} from "./view";
export default class JustSharePleasePlugin extends Plugin {
@ -194,7 +193,7 @@ export default class JustSharePleasePlugin extends Plugin {
}
async deleteFile(item: SharedItem, notice = true): Promise<boolean> {
let name = basename(item.path, extname(item.path));
let name = removeExtension(item.path);
try {
await requestUrl({
url: `${this.settings.url}/share.php?id=${item.id}`,
@ -221,7 +220,7 @@ export default class JustSharePleasePlugin extends Plugin {
async copyShareLink(item: SharedItem, notice = true): Promise<void> {
await navigator.clipboard.writeText(`${this.settings.url}#${item.id}`);
if (notice)
new Notice(`Copied link to ${basename(item.path, extname(item.path))} to clipboard`);
new Notice(`Copied link to ${removeExtension(item.path)} to clipboard`);
}
async preProcessMarkdown(file: TFile): Promise<string> {
@ -247,7 +246,7 @@ export default class JustSharePleasePlugin extends Plugin {
let resolved = this.app.metadataCache.getFirstLinkpathDest(url, file.path).path;
let attachment = this.app.vault.getAbstractFileByPath(resolved);
let data = arrayBufferToBase64(await this.app.vault.readBinary(attachment as TFile));
let img = `<img src="data:image/${extname(resolved).substring(1)};base64, ${data}" alt="${alt}">`;
let img = `<img src="data:image/${resolved.split(".").pop()};base64, ${data}" alt="${alt}">`;
text = text.substring(0, match.index) + img + text.substring(match.index + match[0].length);
} catch (e) {
console.log(`Error embedding attachment ${url}: ${e}`);
@ -263,4 +262,11 @@ export default class JustSharePleasePlugin extends Plugin {
leaf.view.refresh();
}
}
}
export function removeExtension(file: string): string {
let split = file.split(".");
split.pop();
return split.join(".");
}

View file

@ -13,9 +13,8 @@ export class JSPSettingsTab extends PluginSettingTab {
display(): void {
this.containerEl.empty();
this.containerEl.createEl("h2", {text: "Just Share Please Settings"});
new Setting(this.containerEl)
.setName("Just Share Please Server")
.setName("Just Share Please server")
.setDesc(createFragment(f => {
f.createSpan({text: "URL for the Just Share Please server to upload to and share links for. Defaults to the official site "});
f.createEl("a", {text: "jsp.ellpeck.de", href: defaultSettings.url});
@ -31,7 +30,7 @@ export class JSPSettingsTab extends PluginSettingTab {
});
});
new Setting(this.containerEl)
.setName("Strip Frontmatter")
.setName("Strip frontmatter")
.setDesc("Whether document frontmatter (also known as properties) should be removed from the uploaded share.")
.addToggle(t => {
t.setValue(this.plugin.settings.stripFrontmatter);
@ -41,7 +40,7 @@ export class JSPSettingsTab extends PluginSettingTab {
});
});
new Setting(this.containerEl)
.setName("Include Note Name")
.setName("Include note name")
.setDesc("Whether the name of the shared note should be included in the share as a heading.")
.addToggle(t => {
t.setValue(this.plugin.settings.includeNoteName);
@ -51,7 +50,7 @@ export class JSPSettingsTab extends PluginSettingTab {
});
});
new Setting(this.containerEl)
.setName("Unshare Deleted Files")
.setName("Unshare deleted files")
.setDesc("Whether shares of files should be removed automatically when they are deleted. Only supported when deleting from within Obsidian.")
.addToggle(t => {
t.setValue(this.plugin.settings.unshareDeletedFiles);
@ -61,7 +60,7 @@ export class JSPSettingsTab extends PluginSettingTab {
});
});
new Setting(this.containerEl)
.setName("Automatically Update Shares")
.setName("Automatically update shares")
.setDesc("Whether a file's share should automatically be updated when the file is changed from within Obsidian.")
.addToggle(t => {
t.setValue(this.plugin.settings.autoUpdateShares);

View file

@ -1,6 +1,5 @@
import {ButtonComponent, ItemView, TFile, WorkspaceLeaf} from "obsidian";
import {basename, extname} from "path";
import JustSharePleasePlugin from "./main";
import JustSharePleasePlugin, {removeExtension} from "./main";
export class JSPView extends ItemView {
@ -18,35 +17,40 @@ export class JSPView extends ItemView {
let content = this.contentEl.createDiv({cls: "just-share-please-view"});
if (this.plugin.settings.shared.length > 0) {
for (let shared of this.plugin.settings.shared) {
let file = this.plugin.app.vault.getAbstractFileByPath(shared.path) as TFile;
let div = content.createDiv({cls: "just-share-please-shared-item"});
div.createSpan({cls: "just-share-please-shared-name", text: basename(shared.path, extname(shared.path))});
new ButtonComponent(div)
.setClass("clickable-icon")
.setTooltip("Copy JSP link")
.setIcon("link")
.onClick(async () => this.plugin.copyShareLink(shared));
if (file) {
let abstractFile = this.plugin.app.vault.getAbstractFileByPath(shared.path);
if (abstractFile instanceof TFile) {
let file = abstractFile;
let div = content.createDiv({cls: "just-share-please-shared-item"});
div.createSpan({cls: "just-share-please-shared-name", text: removeExtension(shared.path).split(/[/\\]/g).pop()});
if (file?.path.match(/[/\\]/))
div.createSpan({cls: "just-share-please-shared-path", text: removeExtension(file.path)});
new ButtonComponent(div)
.setClass("clickable-icon")
.setTooltip("Open in Obsidian")
.setIcon("edit")
.onClick(async e => {
let leaf = this.app.workspace.getLeaf(e.ctrlKey);
await leaf.openFile(file);
this.app.workspace.setActiveLeaf(leaf, {focus: true});
});
.setTooltip("Copy JSP link")
.setIcon("link")
.onClick(async () => this.plugin.copyShareLink(shared));
if (file) {
new ButtonComponent(div)
.setClass("clickable-icon")
.setTooltip("Open in Obsidian")
.setIcon("edit")
.onClick(async e => {
let leaf = this.app.workspace.getLeaf(e.ctrlKey);
await leaf.openFile(file);
this.app.workspace.setActiveLeaf(leaf, {focus: true});
});
new ButtonComponent(div)
.setClass("clickable-icon")
.setTooltip("Update in JSP")
.setIcon("share")
.onClick(async () => this.plugin.updateFile(shared, file));
}
new ButtonComponent(div)
.setClass("clickable-icon")
.setTooltip("Update in JSP")
.setIcon("share")
.onClick(async () => this.plugin.updateFile(shared, file));
.setTooltip("Delete from JSP")
.setIcon("trash")
.onClick(async () => this.plugin.deleteFile(shared));
}
new ButtonComponent(div)
.setClass("clickable-icon")
.setTooltip("Delete from JSP")
.setIcon("trash")
.onClick(async () => this.plugin.deleteFile(shared));
}
} else {
content.createSpan({text: "You have not shared any items yet."});

View file

@ -14,6 +14,12 @@
padding-bottom: 5px;
}
.just-share-please-shared-path {
display: block;
padding-bottom: 5px;
font-size: 13px;
}
.just-share-please-shared-item {
margin-bottom: 20px;
}

View file

@ -5,6 +5,11 @@
"id": "234df7b7",
"password": "0ef1504bfe83cd9ca812434caa7aacf4",
"path": "Cool Test Note.md"
},
{
"id": "014b266c",
"password": "1c9459d7cdac804f72272c8f6d4a9abc",
"path": "dir/Cool Test Note.md"
}
],
"stripFrontmatter": true,

View file

@ -0,0 +1,44 @@
---
test: yes
---
this is the SECOND cool test note!!
> How are you?
```js
$.ajax({
method: "get",
url: id ? `share.php?id=${id}` : "index.md",
success: t => {
main.html(DOMPurify.sanitize(md.render(t)));
// scroll to anchor
let element = $(window.location.hash);
if (element.length)
$(window).scrollTop(element.offset().top);
},
error: (r, s, e) => main.html(`<div class="error"><p>Error loading shared note with id <code>${id}</code>: ${e}</p><p><a href="#">Home</a></p></div>`)
});
```
cool!!
blah blah i added and removed this
The following is $x^2 = 7$, but more complicated!
$$
x^2 + \sum_{i = 1}^{10000} x^2 \cdot 0 = 7
$$
## Some images
image!
![this is an image my friends, and this is my alt text](Obsidian_TtC7w4GA86.png)
wikilink image!
![[Pasted image 20230816130420.png]]
nice