mirror of
https://github.com/nathonius/obsidian-github-link.git
synced 2026-07-22 09:20:25 +00:00
209 lines
6.5 KiB
TypeScript
209 lines
6.5 KiB
TypeScript
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
import { App, PluginSettingTab, Setting } from "obsidian";
|
|
import { GithubLinkPlugin, PluginSettings } from "./plugin";
|
|
|
|
import { AuthModal } from "./auth-modal";
|
|
import { Verification } from "@octokit/auth-oauth-device/dist-types/types";
|
|
import { auth } from "./github";
|
|
|
|
export interface GithubAccount {
|
|
id: string;
|
|
name: string;
|
|
orgs: string[];
|
|
token: string;
|
|
}
|
|
|
|
export interface GithubLinkPluginSettings {
|
|
accounts: GithubAccount[];
|
|
defaultAccount?: string;
|
|
}
|
|
|
|
export class GithubLinkPluginSettingsTab extends PluginSettingTab {
|
|
authModal: AuthModal | null = null;
|
|
newAccount: GithubAccount | null = null;
|
|
|
|
constructor(public app: App, private readonly plugin: GithubLinkPlugin) {
|
|
super(app, plugin);
|
|
}
|
|
|
|
display() {
|
|
const { containerEl } = this;
|
|
containerEl.empty();
|
|
containerEl.createEl("h2", { text: "GitHub authentication" });
|
|
|
|
containerEl.createEl("p", {
|
|
text: "No authentication is required to reference public repositories. Providing a token allows referencing private repos, but the token is stored in plain text. You can create multiple accounts for multiple tokens.",
|
|
});
|
|
|
|
new Setting(containerEl).setName("Add account").addButton((button) => {
|
|
button.setButtonText("");
|
|
button.setIcon("plus");
|
|
button.setTooltip("Add Account");
|
|
button.onClick(() => {
|
|
this.newAccount = { id: crypto.randomUUID(), name: "", orgs: [], token: "" };
|
|
this.display();
|
|
});
|
|
});
|
|
new Setting(containerEl)
|
|
.setName("Default account")
|
|
.setDesc("The account that will be used if no other users or organizations match.")
|
|
.addDropdown((dropdown) => {
|
|
const options = PluginSettings.accounts.reduce<Record<string, string>>((acc, account) => {
|
|
acc[account.id] = account.name;
|
|
return acc;
|
|
}, {});
|
|
dropdown.addOptions(options);
|
|
dropdown.setValue(PluginSettings.defaultAccount ?? "");
|
|
dropdown.onChange(async (value) => {
|
|
console.log(value);
|
|
const selectedAccount = PluginSettings.accounts.find((acc) => acc.id === value);
|
|
if (selectedAccount) {
|
|
PluginSettings.defaultAccount = selectedAccount.id;
|
|
await this.saveSettings();
|
|
}
|
|
});
|
|
});
|
|
|
|
// TODO: Combine the new account and existing account rendering to reduce duplication
|
|
if (this.newAccount !== null) {
|
|
const accountContainer = containerEl.createDiv();
|
|
const header = accountContainer.createEl("h3", { text: "New account" });
|
|
new Setting(accountContainer)
|
|
.setName("Account name")
|
|
.setDesc("Required.")
|
|
.addText((text) => {
|
|
text.setValue(this.newAccount!.name);
|
|
text.onChange((value) => {
|
|
this.newAccount!.name = value;
|
|
header.setText(value ?? "New account");
|
|
});
|
|
})
|
|
.addButton((button) => {
|
|
button.setIcon("trash");
|
|
button.setTooltip("Delete account");
|
|
button.onClick(() => {
|
|
this.newAccount = null;
|
|
this.display();
|
|
});
|
|
});
|
|
new Setting(accountContainer)
|
|
.setName("Orgs and users")
|
|
.setDesc(
|
|
"A comma separated list of the GitHub organizations and users this account should be used for. Optional."
|
|
)
|
|
.addTextArea((text) => {
|
|
text.setValue(this.newAccount!.orgs.join(", "));
|
|
text.onChange((value) => {
|
|
this.newAccount!.orgs = value.split(",");
|
|
});
|
|
});
|
|
new Setting(accountContainer)
|
|
.setName("Token")
|
|
.setDesc(
|
|
"A GitHub token, which can be generated automatically (recommended) or by creating a personal access token (not recommended unless org does not allow OAuth tokens). Required."
|
|
)
|
|
.addButton((button) => {
|
|
button.setButtonText("Generate Token");
|
|
button.onClick(async () => {
|
|
const authResult = await auth(this.tokenVerification.bind(this))({
|
|
type: "oauth",
|
|
});
|
|
this.authModal?.close();
|
|
this.authModal = null;
|
|
this.newAccount!.token = authResult.token;
|
|
this.display();
|
|
});
|
|
})
|
|
.addText((text) => {
|
|
text.setPlaceholder("Personal Access Token / OAuth Token");
|
|
text.setValue(this.newAccount!.token);
|
|
text.onChange((value) => {
|
|
this.newAccount!.token = value;
|
|
});
|
|
});
|
|
new Setting(accountContainer).addButton((button) => {
|
|
button.setTooltip("Save account");
|
|
button.setIcon("save");
|
|
button.onClick(async () => {
|
|
if (!this.newAccount || !this.newAccount.name || !this.newAccount.token) {
|
|
return;
|
|
}
|
|
PluginSettings.accounts.unshift(this.newAccount);
|
|
await this.saveSettings();
|
|
this.newAccount = null;
|
|
this.display();
|
|
});
|
|
});
|
|
}
|
|
|
|
for (const account of PluginSettings.accounts) {
|
|
const accountContainer = containerEl.createDiv();
|
|
accountContainer.createEl("h3", { text: account.name });
|
|
new Setting(accountContainer)
|
|
.setName("Account name")
|
|
.addText((text) => {
|
|
text.setValue(account.name);
|
|
text.onChange((value) => {
|
|
account.name = value;
|
|
this.saveSettings();
|
|
});
|
|
})
|
|
.addButton((button) => {
|
|
button.setIcon("trash");
|
|
button.setTooltip("Delete account");
|
|
button.onClick(async () => {
|
|
PluginSettings.accounts.remove(account);
|
|
await this.saveSettings();
|
|
this.display();
|
|
});
|
|
});
|
|
new Setting(accountContainer)
|
|
.setName("Orgs and users")
|
|
.setDesc(
|
|
"A comma separated list of the GitHub organizations and users this account should be used for."
|
|
)
|
|
.addTextArea((text) => {
|
|
text.setValue(account.orgs.join(", "));
|
|
text.onChange((value) => {
|
|
account.orgs = value.split(",").map((org) => org.trim());
|
|
this.saveSettings();
|
|
});
|
|
});
|
|
new Setting(accountContainer)
|
|
.setName("Token")
|
|
.setDesc(
|
|
"A GitHub token, which can be generated automatically (recommended) or by creating a personal access token (not recommended unless org does not allow OAuth tokens)."
|
|
)
|
|
.addButton((button) => {
|
|
button.setButtonText("Generate Token");
|
|
button.onClick(async () => {
|
|
const authResult = await auth(this.tokenVerification.bind(this))({
|
|
type: "oauth",
|
|
});
|
|
this.authModal?.close();
|
|
this.authModal = null;
|
|
account.token = authResult.token;
|
|
await this.saveSettings();
|
|
this.display();
|
|
});
|
|
})
|
|
.addText((text) => {
|
|
text.setPlaceholder("Personal Access Token / OAuth Token");
|
|
text.setValue(account.token);
|
|
text.onChange((value) => {
|
|
account.token = value;
|
|
this.saveSettings();
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
private saveSettings() {
|
|
return this.plugin.saveData(PluginSettings);
|
|
}
|
|
|
|
private tokenVerification(verification: Verification) {
|
|
this.authModal = new AuthModal(this.app, verification);
|
|
this.authModal.open();
|
|
}
|
|
}
|