CORS-Problem beim Posten auf Discourse von Obsidian

Ich benutze jetzt Obsidian zum Schreiben und dachte mir, ich erstelle ein Obsidian-Plugin, um auf mein Discourse-Forum zu posten. Theoretisch ist das einfach zu machen, aber die Antwort auf meinen ersten Versuch war:

Access to fetch at 'http://localhost:4200/posts.json' from origin 'app://obsidian.md' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

Die Anfrage kommt vom Client, aber der Client ist das Gerät des Benutzers. Wenn ich das richtig verstehe, ist das sicher:

import DiscoursePlugin from "./main";
import { TFile } from "obsidian";

export async function publishToDiscourse(
	plugin: DiscoursePlugin,
	activeFile: TFile
): Promise<{ message: string }> {
	try {
		const content = await plugin.app.vault.read(activeFile);
		const baseUrl = plugin.settings.baseUrl;
		const apiKey = plugin.settings.apiKey;

		const headers = new Headers({
			"Content-Type": "application/json",
			"Api-Key": apiKey,
			"Api-Username": "scossar", // dies muss eine Einstellung sein
		});
		const body = JSON.stringify({
			title: activeFile.name,
			raw: content, // TODO: den Inhalt parsen, um interne Links zu korrigieren
			category: 1, // dies muss eine Einstellung sein
		});
		// TODO: prüfen, ob die Notiz bereits veröffentlicht wurde
		const url = `${baseUrl}/posts.json`;

		const response = await fetch(url, { method: "POST", headers, body });

		if (!response.ok) {
			console.error("Fehler beim Veröffentlichen auf Discourse:", response.status);
			return { message: "Fehler beim Veröffentlichen auf Discourse" };
		}
        
		const jsonResponse = await response.json();
		// TODO: die Antwort verwenden, um eine discoursePostId-Dateieigenschaft hinzuzufügen
		console.log(`jsonResponse: ${JSON.stringify(jsonResponse, null, 2)}`);
		return { message: "success" };
	} catch (error) {
		console.error("Fehler beim Veröffentlichen auf Discourse:", error);
		return { message: `Fehler: ${error.message}` };
	}
}

Es ist möglich, dass es eine offensichtliche Umgehung gibt, die ich übersehe. Wenn nicht, gibt es irgendeine Möglichkeit, wie Discourse es zulassen könnte? Ein Obsidian-Discourse-Plugin scheint nützlich zu sein. (Eine richtige Implementierung wäre komplexer als das, was ich oben gepostet habe.)

3 „Gefällt mir“

Ich war anfangs verwirrt, aber jetzt verstehe ich, dass Sie Ihre eigene Obsidian-App mit Ihrem Schlüssel konfiguriert haben und nur Sie darauf Zugriff haben. Dies geschieht nicht in einem Browser, sodass Personen im Internet nicht Ihren Schlüssel haben.

Ich habe ein Discourse-Plugin, das beliebige Formulare verarbeitet (Sie können es unter https://www.formhoster.com/ verwenden). Ich wollte es so einrichten, dass es als aktueller Benutzer funktioniert, wenn der Benutzer bei der Website, die das Formular verarbeitet, angemeldet war, und stieß auf dasselbe CORS-Problem, das ich ziemlich schnell aufgab. Meins war in einem Browser und nicht in einer App wie Obsidian, aber ich denke, das Problem könnte ähnlich sein.

Alles in allem glaube ich nicht, dass ich gute Ideen habe, aber ich hoffe, jemand anderes wird welche haben. :person_shrugging:

1 „Gefällt mir“

Richtig, Obsidian ist eine Electron-App, die lokal läuft. Sie verwendet lokalen Speicher, sodass der API-Schlüssel auf dem Gerät des Benutzers verbleibt.

Es gibt eine Lösung für das CORS-Problem. Ich habe sie bisher nur auf meinem Desktop-Computer getestet. Außerdem ist Discourse großartig!

Der Code, den ich oben gepostet habe, musste geändert werden zu:

import DiscoursePlugin from "./main";
import { requestUrl, TFile } from "obsidian";

//...

		const response = await requestUrl({
			url: url,
			method: "POST",
			contentType: "application/json",
			body,
			headers,
		});
//...

Die nächste Frage wird sich darum drehen, ob Benutzer User-API-Schlüssel von der App anfordern können, aber das ist ein separates Problem.

3 „Gefällt mir“

Ist das ein Plugin, an dem Sie arbeiten? Ich habe einen Benutzer (und mich selbst), der dies gerne verwenden würde. Ich kann versuchen, das nachzubilden, was Sie getan haben, aber wenn es einen einfacheren Weg gibt…

Es war der Anfang von etwas. Für meine eigenen Zwecke bin ich mehr an einer CLI-Anwendung (Kommandozeile) interessiert, die es ermöglicht, ein Obsidian Vault mit einem Discourse-Forum zu synchronisieren. Eine CLI-App erleichtert die Synchronisation eines gesamten Vaults oder Unterverzeichnisses, die Handhabung interner Links in Notizen, den Umgang mit Uploads usw. Der CLI-App-Ansatz passt auch zu einigen anderen Arbeiten, die ich gerade durchführe, sodass ich daraus etwas Nützliches lerne.

Der große Nachteil der CLI-App ist, dass jeder, der sie benutzt, Ruby auf seinem Computer installiert haben muss. Sie wird auch nur auf Desktop-Computern funktionieren. Es gäbe einige technische Herausforderungen bei der Verwendung auf Windows-Computern.

Ich werde hier einen Link zur App posten, sobald sie zum Teilen bereit ist.

Wenn ein Obsidian Discourse-Plugin, im Gegensatz zu einer CLI-App, etwas ist, an dem die Leute interessiert sind, werde ich es in Zukunft noch einmal ansehen. Es ist möglich, dass jemand anderes es vor mir schafft. Ich habe es nicht viel weiter als das obige Codebeispiel entwickelt.

1 „Gefällt mir“

Wenn das alles ist, was Sie bisher haben, sieht es ziemlich einfach aus. Ich frage mich, wie es mit Bildern umgehen würde. Ich wäre bereit, es zu versuchen. Ich habe noch nie ein Plugin für Obsidian geschrieben, aber nach dem, was ich mir angesehen habe (flüchtige Blicke auf andere Plugins), sieht es nicht besonders kompliziert aus.

1 „Gefällt mir“

Hier ist der Ausgangspunkt: Build a plugin - Developer Documentation. Ich würde gerne auf das verlinken, was ich getan habe, aber es ist eines der wenigen (hoffentlich einzigen) Projekte, die ich nicht auf Github hochgeladen habe, bevor ich letzte Woche das Betriebssystem auf meinem Computer neu installiert habe.

Sie müssen herausfinden, wie Sie es mit Node machen können. Hier ist ein gutes Ruby-Beispiel: discourse_api/examples/upload_file.rb at main · discourse/discourse_api · GitHub. Es ruft auf: discourse_api/lib/discourse_api/api/uploads.rb at main · discourse/discourse_api · GitHub.

Können Sie diesen Teil teilen?

Nun, das war ziemlich rücksichtslos, diesen Code zu verlieren. Soweit ich mich erinnere, habe ich DiscoursePlugin aus main.ts in eine Datei importiert, die einen Aufruf an this.addCommand behandelte. Um anzufangen, können Sie alles in main.ts machen. Ich würde einfach dem Leitfaden für den Einstieg mit dem Beispiel-Plugin folgen. Fangen Sie an, damit herumzuspielen und zu versuchen, etwas zu bewirken. Ich weiß, dass ich dieses Plugin als Vorlage für meines verwendet habe.

Hier gibt es auch einige gute Beispiele: obsidian-wordpress/src at main · devbean/obsidian-wordpress · GitHub.

1 „Gefällt mir“

Nun, ich werde das vorerst auf Eis legen. Ich habe ziemlich gute Fortschritte gemacht, aber es gibt ein paar Dinge, die mir nicht gefallen.

  • Der API-Schlüssel wird im Klartext gespeichert (SEHR SCHLECHT)
  • Bilder werden nicht hochgeladen, es gibt einige Konfigurationseinstellungen, die ich noch nicht erkundet habe. Aber ich bin kein Fan davon, einen AWS S3-Bucket einzurichten. Das werde ich mir später ansehen.
  • Einige stilistische Entscheidungen könnten besser sein, aber ich wollte etwas Funktionales
  • Die README muss aktualisiert werden. Aber auch hier wollte ich nur etwas Funktionales und habe es gepostet.
1 „Gefällt mir“

Ich frage mich, ob es einen Ausweg gibt. In der CLI-App verschlüssele ich sie mit einem Passwort. Der Benutzer muss das Passwort angeben, bevor eine Operation durchgeführt wird, die den API-Schlüssel verwendet.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.