update plugin

This commit is contained in:
Maxime Cannoodt 2022-06-26 22:46:39 +02:00
parent 12d79cdfba
commit 5d09dbad12
9 changed files with 144 additions and 122 deletions

View File

@ -1,52 +1,54 @@
import esbuild from "esbuild";
import process from "process";
import builtins from 'builtin-modules'
import builtins from "builtin-modules";
const banner =
`/*
const banner = `/*
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
if you want to view the source, please visit the github repository of this plugin
*/
`;
const prod = (process.argv[2] === 'production');
const prod = process.argv[2] === "production";
esbuild.build({
banner: {
js: banner,
},
entryPoints: ['main.ts'],
bundle: true,
external: [
'obsidian',
'electron',
'@codemirror/autocomplete',
'@codemirror/closebrackets',
'@codemirror/collab',
'@codemirror/commands',
'@codemirror/comment',
'@codemirror/fold',
'@codemirror/gutter',
'@codemirror/highlight',
'@codemirror/history',
'@codemirror/language',
'@codemirror/lint',
'@codemirror/matchbrackets',
'@codemirror/panel',
'@codemirror/rangeset',
'@codemirror/rectangular-selection',
'@codemirror/search',
'@codemirror/state',
'@codemirror/stream-parser',
'@codemirror/text',
'@codemirror/tooltip',
'@codemirror/view',
...builtins],
format: 'cjs',
watch: !prod,
target: 'es2016',
logLevel: "info",
sourcemap: prod ? false : 'inline',
treeShaking: true,
outfile: 'main.js',
}).catch(() => process.exit(1));
esbuild
.build({
banner: {
js: banner,
},
entryPoints: ["main.ts"],
bundle: true,
external: [
"obsidian",
"electron",
"@codemirror/autocomplete",
"@codemirror/closebrackets",
"@codemirror/collab",
"@codemirror/commands",
"@codemirror/comment",
"@codemirror/fold",
"@codemirror/gutter",
"@codemirror/highlight",
"@codemirror/history",
"@codemirror/language",
"@codemirror/lint",
"@codemirror/matchbrackets",
"@codemirror/panel",
"@codemirror/rangeset",
"@codemirror/rectangular-selection",
"@codemirror/search",
"@codemirror/state",
"@codemirror/stream-parser",
"@codemirror/text",
"@codemirror/tooltip",
"@codemirror/view",
...builtins,
],
format: "cjs",
watch: !prod,
target: "es2016",
logLevel: "info",
sourcemap: prod ? false : "inline",
treeShaking: true,
outfile: "main.js",
})
.catch(() => process.exit(1));

View File

@ -1,20 +1,21 @@
import { App, MarkdownView, Plugin, PluginSettingTab, Setting } from "obsidian";
import { encryptMarkdown } from "src/encryption";
import {
EventRef,
MarkdownView,
Menu,
Plugin,
TAbstractFile,
TFile,
} from "obsidian";
import { NoteSharingService } from "src/NoteSharingService";
import { DEFAULT_SETTINGS, PluginSettings } from "src/obsidian/PluginSettings";
import SettingsTab from "src/obsidian/SettingsTab";
// Remember to rename these classes and interfaces!
interface MyPluginSettings {
serverUrl: string;
}
const DEFAULT_SETTINGS: MyPluginSettings = {
serverUrl: "http://localhost:8080",
};
export default class MyPlugin extends Plugin {
settings: MyPluginSettings;
noteSharingService: NoteSharingService;
export default class NoteSharingPlugin extends Plugin {
private settings: PluginSettings;
private noteSharingService: NoteSharingService;
private eventRef: EventRef;
async onload() {
await this.loadSettings();
@ -22,25 +23,28 @@ export default class MyPlugin extends Plugin {
this.settings.serverUrl
);
// This adds a settings tab so the user can configure various aspects of the plugin
// Init settings tab
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
// Add note sharing command
this.addCommand({
id: "obsidian-note-sharing-share-note",
name: "Create share link",
checkCallback: (checking: boolean) => {
// Conditions to check
const markdownView =
// Only works on Markdown views
const activeView =
this.app.workspace.getActiveViewOfType(MarkdownView);
if (markdownView) {
if (!checking) {
this.noteSharingService.shareNote(markdownView);
}
return true;
}
if (!activeView) return false;
if (checking) return true;
this.noteSharingService.shareNote(activeView.getViewData());
},
});
this.eventRef = this.app.workspace.on(
"file-menu",
(menu, file, source) => this.onMenuOpenCallback(menu, file, source)
);
this.registerEvent(this.eventRef);
}
onunload() {}
@ -57,34 +61,19 @@ export default class MyPlugin extends Plugin {
await this.saveData(this.settings);
this.noteSharingService.serverUrl = this.settings.serverUrl;
}
}
class SettingsTab extends PluginSettingTab {
plugin: MyPlugin;
constructor(app: App, plugin: MyPlugin) {
super(app, plugin);
this.plugin = plugin;
}
display(): void {
const { containerEl } = this;
containerEl.empty();
containerEl.createEl("h2", { text: "Obsidian Note Sharing" });
new Setting(containerEl)
.setName("Server URL")
.setDesc("Server URL hosting the encrypted notes.")
.addText((text) =>
text
.setPlaceholder("enter URL")
.setValue(this.plugin.settings.serverUrl)
.onChange(async (value) => {
this.plugin.settings.serverUrl = value;
await this.plugin.saveSettings();
})
);
// https://github.dev/platers/obsidian-linter/blob/c30ceb17dcf2c003ca97862d94cbb0fd47b83d52/src/main.ts#L139-L149
onMenuOpenCallback(menu: Menu, file: TAbstractFile, source: string) {
if (file instanceof TFile && file.extension === "md") {
menu.addItem((item) => {
item.setIcon("paper-plane-glyph");
item.setTitle("Share note");
item.onClick(async (evt) => {
this.noteSharingService.shareNote(
await this.app.vault.read(file)
);
});
});
}
}
}

View File

@ -1,4 +1,4 @@
import { MarkdownView, requestUrl } from "obsidian";
import { requestUrl } from "obsidian";
import { encryptMarkdown } from "./encryption";
export class NoteSharingService {
@ -12,8 +12,8 @@ export class NoteSharingService {
* @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);
public async shareNote(mdText: string): Promise<string> {
const cryptData = encryptMarkdown(mdText);
let url = await this.postNote(cryptData.ciphertext, cryptData.hmac);
url += `#${cryptData.key}`;
console.log(`Note shared: ${url}`);

View File

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

View File

@ -0,0 +1,7 @@
export interface PluginSettings {
serverUrl: string;
}
export const DEFAULT_SETTINGS: PluginSettings = {
serverUrl: "http://localhost:8080",
};

View File

@ -0,0 +1,32 @@
import NoteSharingPlugin from "main";
import { App, PluginSettingTab, Setting } from "obsidian";
export default class SettingsTab extends PluginSettingTab {
plugin: NoteSharingPlugin;
constructor(app: App, plugin: NoteSharingPlugin) {
super(app, plugin);
this.plugin = plugin;
}
display(): void {
const { containerEl } = this;
containerEl.empty();
containerEl.createEl("h2", { text: "Obsidian Note Sharing" });
new Setting(containerEl)
.setName("Server URL")
.setDesc("Server URL hosting the encrypted notes.")
.addText((text) =>
text
.setPlaceholder("enter URL")
.setValue(this.plugin.settings.serverUrl)
.onChange(async (value) => {
this.plugin.settings.serverUrl = value;
await this.plugin.saveSettings();
})
);
}
}

View File

@ -1,23 +1,17 @@
{
"compilerOptions": {
"baseUrl": ".",
"inlineSourceMap": true,
"inlineSources": true,
"module": "ESNext",
"target": "ES6",
"allowJs": true,
"noImplicitAny": true,
"moduleResolution": "node",
"importHelpers": true,
"isolatedModules": true,
"lib": [
"DOM",
"ES5",
"ES6",
"ES7"
]
},
"include": [
"**/*.ts"
]
"compilerOptions": {
"baseUrl": ".",
"inlineSourceMap": true,
"inlineSources": true,
"module": "ESNext",
"target": "ES6",
"allowJs": true,
"noImplicitAny": true,
"moduleResolution": "node",
"importHelpers": true,
"isolatedModules": true,
"outDir": "./build" /* Specify an output folder for all emitted files. */,
"lib": ["DOM", "ES5", "ES6", "ES7"]
},
"include": ["**/*.ts"]
}

Binary file not shown.

View File

@ -4,7 +4,6 @@
"lib": ["esnext"],
"target": "es2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
"module": "commonjs" /* Specify what module code is generated. */,
"outDir": "./build" /* Specify an output folder for all emitted files. */,
"esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */,
"forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
"strict": true /* Enable all strict type-checking options. */,