sharing v1

This commit is contained in:
Maxime Cannoodt 2022-06-19 22:49:37 +02:00
parent 1000c4efc0
commit 07f4800d34
4 changed files with 69 additions and 29 deletions

47
main.ts
View File

@ -1,51 +1,46 @@
import { App, MarkdownView, Plugin, PluginSettingTab, Setting } from "obsidian";
import { encryptMarkdown } from "src/encryption";
import { NoteSharingService } from "src/NoteSharingService";
// Remember to rename these classes and interfaces!
interface MyPluginSettings {
mySetting: string;
serverUrl: string;
}
const DEFAULT_SETTINGS: MyPluginSettings = {
mySetting: "default",
serverUrl: "http://localhost:8080",
};
export default class MyPlugin extends Plugin {
settings: MyPluginSettings;
noteSharingService: NoteSharingService;
async onload() {
await this.loadSettings();
this.noteSharingService = new NoteSharingService(
this.settings.serverUrl
);
// This adds a settings tab so the user can configure various aspects of the plugin
this.addSettingTab(new SettingsTab(this.app, this));
// This adds a complex command that can check whether the current state of the app allows execution of the command
this.addCommand({
id: "open-sample-modal-complex",
name: "Open sample modal (complex)",
id: "obsidian-note-sharing-share-note",
name: "Create share link",
checkCallback: (checking: boolean) => {
// Conditions to check
const markdownView =
this.app.workspace.getActiveViewOfType(MarkdownView);
if (markdownView) {
// If checking is true, we're simply "checking" if the command can be run.
// If checking is false, then we want to actually perform the operation.
if (!checking) {
this.shareNote(markdownView);
this.noteSharingService.shareNote(markdownView);
}
// This command will only show up in Command Palette when the check function returns true
return true;
}
},
});
// This adds a settings tab so the user can configure various aspects of the plugin
this.addSettingTab(new SampleSettingTab(this.app, this));
}
// ENCRYPT AND SHARE MD NOTE
private shareNote(mdView: MarkdownView) {
const cryptData = encryptMarkdown(mdView);
console.log(cryptData);
}
onunload() {}
@ -60,10 +55,11 @@ export default class MyPlugin extends Plugin {
async saveSettings() {
await this.saveData(this.settings);
this.noteSharingService.serverUrl = this.settings.serverUrl;
}
}
class SampleSettingTab extends PluginSettingTab {
class SettingsTab extends PluginSettingTab {
plugin: MyPlugin;
constructor(app: App, plugin: MyPlugin) {
@ -76,18 +72,17 @@ class SampleSettingTab extends PluginSettingTab {
containerEl.empty();
containerEl.createEl("h2", { text: "Settings for my awesome plugin." });
containerEl.createEl("h2", { text: "Obsidian Note Sharing" });
new Setting(containerEl)
.setName("Setting #1")
.setDesc("It's a secret")
.setName("Server URL")
.setDesc("Server URL hosting the encrypted notes.")
.addText((text) =>
text
.setPlaceholder("Enter your secret")
.setValue(this.plugin.settings.mySetting)
.setPlaceholder("enter URL")
.setValue(this.plugin.settings.serverUrl)
.onChange(async (value) => {
console.log("Secret: " + value);
this.plugin.settings.mySetting = value;
this.plugin.settings.serverUrl = value;
await this.plugin.saveSettings();
})
);

View File

@ -1,6 +1,6 @@
{
"id": "obsidian-sample-plugin",
"name": "Obsidian Note Sharing (working title)",
"name": "Obsidian Note Sharing",
"version": "1.0.1",
"minAppVersion": "0.12.0",
"description": "This is a sample plugin for Obsidian. This plugin demonstrates some of the capabilities of the Obsidian API.",

45
src/NoteSharingService.ts Normal file
View File

@ -0,0 +1,45 @@
import { MarkdownView, requestUrl } from "obsidian";
import { encryptMarkdown } from "./encryption";
export class NoteSharingService {
private _url: string;
constructor(serverUrl: string) {
this.serverUrl = serverUrl;
}
/**
* @param mdView Markdown file to share.
* @returns link to shared note with attached decryption key.
*/
public async shareNote(mdView: MarkdownView): Promise<string> {
const cryptData = encryptMarkdown(mdView);
let url = await this.postNote(cryptData.ciphertext, cryptData.hmac);
url += `#${cryptData.key}`;
console.log(`Note shared: ${url}`);
return url;
}
private async postNote(ciphertext: string, hmac: string): Promise<string> {
const res = await requestUrl({
url: `${this._url}/note`,
method: "POST",
contentType: "application/json",
body: JSON.stringify({ ciphertext, hmac }),
});
if (res.status == 200 && res.json != null) {
const id = res.json.id;
return `${this._url}/note/${id}`;
}
throw Error("Did not get expected response from server on note POST.");
}
public set serverUrl(newUrl: string) {
newUrl = newUrl.replace(/([^:]\/)\/+/g, "$1");
if (newUrl[newUrl.length - 1] == "/") {
newUrl = newUrl.substring(0, newUrl.length - 1);
}
this._url = newUrl;
}
}

View File

@ -1,13 +1,13 @@
import { MarkdownView, moment } from "obsidian";
import { generateKey, encryptString } from "./crypto";
interface encryptedMarkdown {
export interface EncryptedMarkdown {
ciphertext: string;
hmac: string;
key: string;
}
export function encryptMarkdown(mdView: MarkdownView): encryptedMarkdown {
export function encryptMarkdown(mdView: MarkdownView): EncryptedMarkdown {
const plaintext = mdView.getViewData();
const key = generateKey(moment.now() + plaintext);
const { ciphertext, hmac } = encryptString(plaintext, key);