mirror of
https://github.com/zulip/zulip-desktop.git
synced 2025-11-03 13:33:18 +00:00
191 lines
4.7 KiB
TypeScript
191 lines
4.7 KiB
TypeScript
import fs from "fs";
|
|
import path from "path";
|
|
|
|
import {app, dialog} from "@electron/remote";
|
|
import {JsonDB} from "node-json-db";
|
|
import {DataError} from "node-json-db/dist/lib/Errors";
|
|
import * as z from "zod";
|
|
|
|
import * as EnterpriseUtil from "../../../common/enterprise-util";
|
|
import Logger from "../../../common/logger-util";
|
|
import * as Messages from "../../../common/messages";
|
|
import type {ServerConf} from "../../../common/types";
|
|
import {ipcRenderer} from "../typed-ipc-renderer";
|
|
|
|
const logger = new Logger({
|
|
file: "domain-util.log",
|
|
});
|
|
|
|
const defaultIconUrl = "../renderer/img/icon.png";
|
|
|
|
const serverConfSchema = z.object({
|
|
url: z.string(),
|
|
alias: z.string(),
|
|
icon: z.string(),
|
|
});
|
|
|
|
let db!: JsonDB;
|
|
|
|
reloadDB();
|
|
|
|
// Migrate from old schema
|
|
try {
|
|
const oldDomain = db.getObject<unknown>("/domain");
|
|
if (typeof oldDomain === "string") {
|
|
(async () => {
|
|
await addDomain({
|
|
alias: "Zulip",
|
|
url: oldDomain,
|
|
});
|
|
db.delete("/domain");
|
|
})();
|
|
}
|
|
} catch (error: unknown) {
|
|
if (!(error instanceof DataError)) throw error;
|
|
}
|
|
|
|
export function getDomains(): ServerConf[] {
|
|
reloadDB();
|
|
try {
|
|
return serverConfSchema.array().parse(db.getObject<unknown>("/domains"));
|
|
} catch (error: unknown) {
|
|
if (!(error instanceof DataError)) throw error;
|
|
return [];
|
|
}
|
|
}
|
|
|
|
export function getDomain(index: number): ServerConf {
|
|
reloadDB();
|
|
return serverConfSchema.parse(db.getObject<unknown>(`/domains[${index}]`));
|
|
}
|
|
|
|
export function updateDomain(index: number, server: ServerConf): void {
|
|
reloadDB();
|
|
serverConfSchema.parse(server);
|
|
db.push(`/domains[${index}]`, server, true);
|
|
}
|
|
|
|
export async function addDomain(server: {
|
|
url: string;
|
|
alias: string;
|
|
icon?: string;
|
|
}): Promise<void> {
|
|
if (server.icon) {
|
|
const localIconUrl = await saveServerIcon(server.icon);
|
|
server.icon = localIconUrl;
|
|
serverConfSchema.parse(server);
|
|
db.push("/domains[]", server, true);
|
|
reloadDB();
|
|
} else {
|
|
server.icon = defaultIconUrl;
|
|
serverConfSchema.parse(server);
|
|
db.push("/domains[]", server, true);
|
|
reloadDB();
|
|
}
|
|
}
|
|
|
|
export function removeDomains(): void {
|
|
db.delete("/domains");
|
|
reloadDB();
|
|
}
|
|
|
|
export function removeDomain(index: number): boolean {
|
|
if (EnterpriseUtil.isPresetOrg(getDomain(index).url)) {
|
|
return false;
|
|
}
|
|
|
|
db.delete(`/domains[${index}]`);
|
|
reloadDB();
|
|
return true;
|
|
}
|
|
|
|
// Check if domain is already added
|
|
export function duplicateDomain(domain: string): boolean {
|
|
domain = formatUrl(domain);
|
|
return getDomains().some((server) => server.url === domain);
|
|
}
|
|
|
|
export async function checkDomain(
|
|
domain: string,
|
|
silent = false,
|
|
): Promise<ServerConf> {
|
|
if (!silent && duplicateDomain(domain)) {
|
|
// Do not check duplicate in silent mode
|
|
throw new Error("This server has been added.");
|
|
}
|
|
|
|
domain = formatUrl(domain);
|
|
|
|
try {
|
|
return await getServerSettings(domain);
|
|
} catch {
|
|
throw new Error(Messages.invalidZulipServerError(domain));
|
|
}
|
|
}
|
|
|
|
async function getServerSettings(domain: string): Promise<ServerConf> {
|
|
return ipcRenderer.invoke("get-server-settings", domain);
|
|
}
|
|
|
|
export async function saveServerIcon(iconURL: string): Promise<string> {
|
|
return ipcRenderer.invoke("save-server-icon", iconURL);
|
|
}
|
|
|
|
export async function updateSavedServer(
|
|
url: string,
|
|
index: number,
|
|
): Promise<void> {
|
|
// Does not promise successful update
|
|
const oldIcon = getDomain(index).icon;
|
|
try {
|
|
const newServerConf = await checkDomain(url, true);
|
|
const localIconUrl = await saveServerIcon(newServerConf.icon);
|
|
if (!oldIcon || localIconUrl !== "../renderer/img/icon.png") {
|
|
newServerConf.icon = localIconUrl;
|
|
updateDomain(index, newServerConf);
|
|
reloadDB();
|
|
}
|
|
} catch (error: unknown) {
|
|
logger.log("Could not update server icon.");
|
|
logger.log(error);
|
|
logger.reportSentry(error);
|
|
}
|
|
}
|
|
|
|
function reloadDB(): void {
|
|
const domainJsonPath = path.join(
|
|
app.getPath("userData"),
|
|
"config/domain.json",
|
|
);
|
|
try {
|
|
const file = fs.readFileSync(domainJsonPath, "utf8");
|
|
JSON.parse(file);
|
|
} catch (error: unknown) {
|
|
if (fs.existsSync(domainJsonPath)) {
|
|
fs.unlinkSync(domainJsonPath);
|
|
dialog.showErrorBox(
|
|
"Error saving new organization",
|
|
"There seems to be error while saving new organization, " +
|
|
"you may have to re-add your previous organizations back.",
|
|
);
|
|
logger.error("Error while JSON parsing domain.json: ");
|
|
logger.error(error);
|
|
logger.reportSentry(error);
|
|
}
|
|
}
|
|
|
|
db = new JsonDB(domainJsonPath, true, true);
|
|
}
|
|
|
|
export function formatUrl(domain: string): string {
|
|
if (domain.startsWith("http://") || domain.startsWith("https://")) {
|
|
return domain;
|
|
}
|
|
|
|
if (domain.startsWith("localhost:")) {
|
|
return `http://${domain}`;
|
|
}
|
|
|
|
return `https://${domain}`;
|
|
}
|