update plugin
This commit is contained in:
parent
12d79cdfba
commit
5d09dbad12
@ -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));
|
||||
|
@ -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)
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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}`);
|
||||
|
@ -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 };
|
||||
|
7
plugin/src/obsidian/PluginSettings.ts
Normal file
7
plugin/src/obsidian/PluginSettings.ts
Normal file
@ -0,0 +1,7 @@
|
||||
export interface PluginSettings {
|
||||
serverUrl: string;
|
||||
}
|
||||
|
||||
export const DEFAULT_SETTINGS: PluginSettings = {
|
||||
serverUrl: "http://localhost:8080",
|
||||
};
|
32
plugin/src/obsidian/SettingsTab.ts
Normal file
32
plugin/src/obsidian/SettingsTab.ts
Normal 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();
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
@ -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.
@ -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. */,
|
||||
|
Loading…
Reference in New Issue
Block a user