sharing v1
This commit is contained in:
parent
1000c4efc0
commit
07f4800d34
47
main.ts
47
main.ts
@ -1,51 +1,46 @@
|
|||||||
import { App, MarkdownView, Plugin, PluginSettingTab, Setting } from "obsidian";
|
import { App, MarkdownView, Plugin, PluginSettingTab, Setting } from "obsidian";
|
||||||
import { encryptMarkdown } from "src/encryption";
|
import { encryptMarkdown } from "src/encryption";
|
||||||
|
import { NoteSharingService } from "src/NoteSharingService";
|
||||||
|
|
||||||
// Remember to rename these classes and interfaces!
|
// Remember to rename these classes and interfaces!
|
||||||
|
|
||||||
interface MyPluginSettings {
|
interface MyPluginSettings {
|
||||||
mySetting: string;
|
serverUrl: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const DEFAULT_SETTINGS: MyPluginSettings = {
|
const DEFAULT_SETTINGS: MyPluginSettings = {
|
||||||
mySetting: "default",
|
serverUrl: "http://localhost:8080",
|
||||||
};
|
};
|
||||||
|
|
||||||
export default class MyPlugin extends Plugin {
|
export default class MyPlugin extends Plugin {
|
||||||
settings: MyPluginSettings;
|
settings: MyPluginSettings;
|
||||||
|
noteSharingService: NoteSharingService;
|
||||||
|
|
||||||
async onload() {
|
async onload() {
|
||||||
await this.loadSettings();
|
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 adds a complex command that can check whether the current state of the app allows execution of the command
|
||||||
this.addCommand({
|
this.addCommand({
|
||||||
id: "open-sample-modal-complex",
|
id: "obsidian-note-sharing-share-note",
|
||||||
name: "Open sample modal (complex)",
|
name: "Create share link",
|
||||||
checkCallback: (checking: boolean) => {
|
checkCallback: (checking: boolean) => {
|
||||||
// Conditions to check
|
// Conditions to check
|
||||||
const markdownView =
|
const markdownView =
|
||||||
this.app.workspace.getActiveViewOfType(MarkdownView);
|
this.app.workspace.getActiveViewOfType(MarkdownView);
|
||||||
if (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) {
|
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;
|
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() {}
|
onunload() {}
|
||||||
@ -60,10 +55,11 @@ export default class MyPlugin extends Plugin {
|
|||||||
|
|
||||||
async saveSettings() {
|
async saveSettings() {
|
||||||
await this.saveData(this.settings);
|
await this.saveData(this.settings);
|
||||||
|
this.noteSharingService.serverUrl = this.settings.serverUrl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SampleSettingTab extends PluginSettingTab {
|
class SettingsTab extends PluginSettingTab {
|
||||||
plugin: MyPlugin;
|
plugin: MyPlugin;
|
||||||
|
|
||||||
constructor(app: App, plugin: MyPlugin) {
|
constructor(app: App, plugin: MyPlugin) {
|
||||||
@ -76,18 +72,17 @@ class SampleSettingTab extends PluginSettingTab {
|
|||||||
|
|
||||||
containerEl.empty();
|
containerEl.empty();
|
||||||
|
|
||||||
containerEl.createEl("h2", { text: "Settings for my awesome plugin." });
|
containerEl.createEl("h2", { text: "Obsidian Note Sharing" });
|
||||||
|
|
||||||
new Setting(containerEl)
|
new Setting(containerEl)
|
||||||
.setName("Setting #1")
|
.setName("Server URL")
|
||||||
.setDesc("It's a secret")
|
.setDesc("Server URL hosting the encrypted notes.")
|
||||||
.addText((text) =>
|
.addText((text) =>
|
||||||
text
|
text
|
||||||
.setPlaceholder("Enter your secret")
|
.setPlaceholder("enter URL")
|
||||||
.setValue(this.plugin.settings.mySetting)
|
.setValue(this.plugin.settings.serverUrl)
|
||||||
.onChange(async (value) => {
|
.onChange(async (value) => {
|
||||||
console.log("Secret: " + value);
|
this.plugin.settings.serverUrl = value;
|
||||||
this.plugin.settings.mySetting = value;
|
|
||||||
await this.plugin.saveSettings();
|
await this.plugin.saveSettings();
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"id": "obsidian-sample-plugin",
|
"id": "obsidian-sample-plugin",
|
||||||
"name": "Obsidian Note Sharing (working title)",
|
"name": "Obsidian Note Sharing",
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"minAppVersion": "0.12.0",
|
"minAppVersion": "0.12.0",
|
||||||
"description": "This is a sample plugin for Obsidian. This plugin demonstrates some of the capabilities of the Obsidian API.",
|
"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
45
src/NoteSharingService.ts
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
@ -1,13 +1,13 @@
|
|||||||
import { MarkdownView, moment } from "obsidian";
|
import { MarkdownView, moment } from "obsidian";
|
||||||
import { generateKey, encryptString } from "./crypto";
|
import { generateKey, encryptString } from "./crypto";
|
||||||
|
|
||||||
interface encryptedMarkdown {
|
export interface EncryptedMarkdown {
|
||||||
ciphertext: string;
|
ciphertext: string;
|
||||||
hmac: string;
|
hmac: string;
|
||||||
key: string;
|
key: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function encryptMarkdown(mdView: MarkdownView): encryptedMarkdown {
|
export function encryptMarkdown(mdView: MarkdownView): EncryptedMarkdown {
|
||||||
const plaintext = mdView.getViewData();
|
const plaintext = mdView.getViewData();
|
||||||
const key = generateKey(moment.now() + plaintext);
|
const key = generateKey(moment.now() + plaintext);
|
||||||
const { ciphertext, hmac } = encryptString(plaintext, key);
|
const { ciphertext, hmac } = encryptString(plaintext, key);
|
||||||
|
Loading…
Reference in New Issue
Block a user