Skip to content

Commit 9207147

Browse files
committed
domain: Add id, change commit message later.
1 parent 33690b2 commit 9207147

File tree

4 files changed

+64
-12
lines changed

4 files changed

+64
-12
lines changed

app/common/typed-ipc.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type {DndSettings} from "./dnd-util.ts";
2-
import type {MenuProperties, ServerConfig} from "./types.ts";
2+
import type {MenuProperties, ServerSettings} from "./types.ts";
33

44
export type MainMessage = {
55
"clear-app-settings": () => void;
@@ -26,7 +26,7 @@ export type MainMessage = {
2626
};
2727

2828
export type MainCall = {
29-
"get-server-settings": (domain: string) => ServerConfig;
29+
"get-server-settings": (domain: string) => ServerSettings;
3030
"is-online": (url: string) => boolean;
3131
"poll-clipboard": (key: Uint8Array, sig: Uint8Array) => string | undefined;
3232
"save-server-icon": (iconURL: string) => string | null;

app/common/types.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,16 @@ export type NavigationItem =
1212
| "Shortcuts";
1313

1414
export type ServerConfig = {
15+
id: string;
1516
url: string;
1617
alias: string;
1718
icon: string;
1819
zulipVersion: string;
1920
zulipFeatureLevel: number;
2021
};
2122

23+
export type ServerSettings = Omit<ServerConfig, "id">;
24+
2225
export type TabRole = "server" | "function";
2326
export type TabPage = "Settings" | "About";
2427

app/main/request.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {z} from "zod";
1010

1111
import Logger from "../common/logger-util.ts";
1212
import * as Messages from "../common/messages.ts";
13-
import type {ServerConfig} from "../common/types.ts";
13+
import type {ServerSettings} from "../common/types.ts";
1414

1515
/* Request: domain-util */
1616

@@ -42,7 +42,7 @@ const generateFilePath = (url: string): string => {
4242
export const _getServerSettings = async (
4343
domain: string,
4444
session: Session,
45-
): Promise<ServerConfig> => {
45+
): Promise<ServerSettings> => {
4646
const response = await session.fetch(domain + "/api/v1/server_settings");
4747
if (!response.ok) {
4848
throw new Error(Messages.invalidZulipServerError(domain));

app/renderer/js/utils/domain-util.ts

Lines changed: 57 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import assert from "node:assert";
2+
import {randomBytes} from "node:crypto";
13
import fs from "node:fs";
24
import path from "node:path";
35

@@ -11,26 +13,43 @@ import * as EnterpriseUtil from "../../../common/enterprise-util.ts";
1113
import Logger from "../../../common/logger-util.ts";
1214
import * as Messages from "../../../common/messages.ts";
1315
import * as t from "../../../common/translation-util.ts";
14-
import type {ServerConfig} from "../../../common/types.ts";
16+
import type {ServerConfig, ServerSettings} from "../../../common/types.ts";
1517
import defaultIcon from "../../img/icon.png";
1618
import {ipcRenderer} from "../typed-ipc-renderer.ts";
1719

1820
const logger = new Logger({
1921
file: "domain-util.log",
2022
});
2123

24+
export function generateDomainId(): string {
25+
return randomBytes(5).toString("hex");
26+
}
27+
2228
// For historical reasons, we store this string in domain.json to denote a
2329
// missing icon; it does not change with the actual icon location.
2430
export const defaultIconSentinel = "../renderer/img/icon.png";
2531

26-
const serverConfigSchema = z.object({
32+
const storedServerSchema = z.object({
33+
id: z.string().optional(),
2734
url: z.url(),
2835
alias: z.string(),
2936
icon: z.string(),
3037
zulipVersion: z.string().default("unknown"),
3138
zulipFeatureLevel: z.number().default(0),
3239
});
3340

41+
const serverConfigSchema = storedServerSchema.extend({
42+
id: z.string(),
43+
});
44+
45+
function addServerId(server: z.infer<typeof storedServerSchema>): ServerConfig {
46+
assert.ok(server.id === undefined);
47+
return serverConfigSchema.parse({
48+
...server,
49+
id: generateDomainId(),
50+
});
51+
}
52+
3453
let database!: JsonDB;
3554

3655
reloadDatabase();
@@ -88,8 +107,8 @@ export async function addDomain(server: {
88107
server.icon = defaultIconSentinel;
89108
}
90109

91-
serverConfigSchema.parse(server);
92-
database.push("/domains[]", server, true);
110+
const serverWithId = addServerId(storedServerSchema.parse(server));
111+
database.push("/domains[]", serverWithId, true);
93112
reloadDatabase();
94113
}
95114

@@ -117,7 +136,7 @@ export function duplicateDomain(domain: string): boolean {
117136
export async function checkDomain(
118137
domain: string,
119138
silent = false,
120-
): Promise<ServerConfig> {
139+
): Promise<ServerSettings> {
121140
if (!silent && duplicateDomain(domain)) {
122141
// Do not check duplicate in silent mode
123142
throw new Error("This server has been added.");
@@ -126,13 +145,13 @@ export async function checkDomain(
126145
domain = formatUrl(domain);
127146

128147
try {
129-
return await getServerSettings(domain);
148+
return storedServerSchema.parse(await getServerSettings(domain));
130149
} catch {
131150
throw new Error(Messages.invalidZulipServerError(domain));
132151
}
133152
}
134153

135-
async function getServerSettings(domain: string): Promise<ServerConfig> {
154+
async function getServerSettings(domain: string): Promise<ServerSettings> {
136155
return ipcRenderer.invoke("get-server-settings", domain);
137156
}
138157

@@ -151,7 +170,11 @@ export async function updateSavedServer(
151170
const serverConfig = getDomain(index);
152171
const oldIcon = serverConfig.icon;
153172
try {
154-
const newServerConfig = await checkDomain(url, true);
173+
const newServerSetting = await checkDomain(url, true);
174+
const newServerConfig: ServerConfig = {
175+
...newServerSetting,
176+
id: serverConfig.id,
177+
};
155178
const localIconUrl = await saveServerIcon(newServerConfig.icon);
156179
if (!oldIcon || localIconUrl !== defaultIconSentinel) {
157180
newServerConfig.icon = localIconUrl;
@@ -168,6 +191,31 @@ export async function updateSavedServer(
168191
}
169192
}
170193

194+
function ensureDomainIds(): void {
195+
try {
196+
const domains = storedServerSchema
197+
.array()
198+
.parse(database.getObject<unknown>("/domains"));
199+
200+
let changed = false;
201+
202+
const updatedDomains = domains.map((server) => {
203+
if (server.id === undefined) {
204+
changed = true;
205+
server = addServerId(server);
206+
}
207+
208+
return server;
209+
});
210+
211+
if (changed) {
212+
database.push("/domains", updatedDomains, true);
213+
}
214+
} catch (error: unknown) {
215+
if (!(error instanceof DataError)) throw error;
216+
}
217+
}
218+
171219
function reloadDatabase(): void {
172220
const domainJsonPath = path.join(
173221
app.getPath("userData"),
@@ -192,6 +240,7 @@ function reloadDatabase(): void {
192240
}
193241

194242
database = new JsonDB(domainJsonPath, true, true);
243+
ensureDomainIds();
195244
}
196245

197246
export function formatUrl(domain: string): string {

0 commit comments

Comments
 (0)