Skip to content

Commit 8a53932

Browse files
committed
feat: align Lark workspace setup with app key credentials
1 parent bd42bed commit 8a53932

File tree

9 files changed

+66
-57
lines changed

9 files changed

+66
-57
lines changed

packages/config/dashboard-config.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ export type DashboardConfig = {
4747
slackAppToken?: string;
4848
slackBotToken?: string;
4949
discordBotToken?: string;
50+
larkAppKey?: string;
5051
larkAppId?: string;
5152
larkAppSecret?: string;
5253
channelDetails: {
@@ -183,7 +184,7 @@ const sanitizeWorkspace = (
183184
const slackAppToken = asString(workspace.slackAppToken, "");
184185
const slackBotToken = asString(workspace.slackBotToken, "");
185186
const discordBotToken = asString(workspace.discordBotToken, "");
186-
const larkAppId = asString(workspace.larkAppId, "");
187+
const larkAppKey = asString(workspace.larkAppKey, "") || asString(workspace.larkAppId, "");
187188
const larkAppSecret = asString(workspace.larkAppSecret, "");
188189
const type = workspace.type === "discord" ? "discord" : workspace.type === "lark" ? "lark" : "slack";
189190

@@ -199,7 +200,8 @@ const sanitizeWorkspace = (
199200
slackAppToken: slackAppToken || undefined,
200201
slackBotToken: slackBotToken || undefined,
201202
discordBotToken: discordBotToken || undefined,
202-
larkAppId: larkAppId || undefined,
203+
larkAppKey: larkAppKey || undefined,
204+
larkAppId: larkAppKey || undefined,
203205
larkAppSecret: larkAppSecret || undefined,
204206
channelDetails,
205207
};

packages/config/local/ode.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ const workspaceSchema = z.object({
108108
slackAppToken: z.string().optional().default(""),
109109
slackBotToken: z.string().optional().default(""),
110110
discordBotToken: z.string().optional().default(""),
111+
larkAppKey: z.string().optional().default(""),
111112
larkAppId: z.string().optional().default(""),
112113
larkAppSecret: z.string().optional().default(""),
113114
channelDetails: z.array(channelDetailSchema).optional().default([]),
@@ -503,7 +504,7 @@ export function getLarkAppCredentials(): Array<{
503504
const candidates = active.length > 0 ? active : getWorkspaces().filter((workspace) => workspace.type === "lark");
504505
return candidates
505506
.map((workspace) => ({
506-
appId: workspace.larkAppId?.trim() ?? "",
507+
appId: workspace.larkAppKey?.trim() || workspace.larkAppId?.trim() || "",
507508
appSecret: workspace.larkAppSecret?.trim() ?? "",
508509
workspaceId: workspace.id,
509510
workspaceName: workspace.name,

packages/core/onboarding.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ async function setupWorkspaces(rl: Interface, config: OdeConfig): Promise<OdeCon
306306
? await discoverDiscordWorkspace(await askRequired(rl, "Paste Discord bot token: "))
307307
: workspaceType === "lark"
308308
? await discoverLarkWorkspace(
309-
await askRequired(rl, "Paste Lark app id: "),
309+
await askRequired(rl, "Paste Lark app key: "),
310310
await askRequired(rl, "Paste Lark app secret: ")
311311
)
312312
: await discoverSlackWorkspace(
@@ -319,7 +319,8 @@ async function setupWorkspaces(rl: Interface, config: OdeConfig): Promise<OdeCon
319319
slackAppToken: discoveredWorkspace.slackAppToken ?? "",
320320
slackBotToken: discoveredWorkspace.slackBotToken ?? "",
321321
discordBotToken: discoveredWorkspace.discordBotToken ?? "",
322-
larkAppId: discoveredWorkspace.larkAppId ?? "",
322+
larkAppKey: discoveredWorkspace.larkAppKey ?? discoveredWorkspace.larkAppId ?? "",
323+
larkAppId: discoveredWorkspace.larkAppKey ?? discoveredWorkspace.larkAppId ?? "",
323324
larkAppSecret: discoveredWorkspace.larkAppSecret ?? "",
324325
channelDetails: discoveredWorkspace.channelDetails.map((channel) => ({
325326
...channel,

packages/core/web/local-settings.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -378,13 +378,13 @@ function buildLarkChannelDetails(
378378
}
379379

380380
export const discoverLarkWorkspace = async (
381-
larkAppId: string,
381+
larkAppKey: string,
382382
larkAppSecret: string
383383
): Promise<DashboardConfig["workspaces"][number]> => {
384-
const appId = larkAppId.trim();
384+
const appId = larkAppKey.trim();
385385
const appSecret = larkAppSecret.trim();
386386
if (!appId) {
387-
throw new Error("Missing Lark app id");
387+
throw new Error("Missing Lark app key");
388388
}
389389
if (!appSecret) {
390390
throw new Error("Missing Lark app secret");
@@ -420,6 +420,7 @@ export const discoverLarkWorkspace = async (
420420
channels: channelDetails.length,
421421
members: 0,
422422
lastSync: new Date().toISOString(),
423+
larkAppKey: appId,
423424
larkAppId: appId,
424425
larkAppSecret: appSecret,
425426
channelDetails,
@@ -438,7 +439,7 @@ export const syncLarkWorkspace = async (workspaceId: string): Promise<DashboardC
438439
throw new Error("Workspace is not Lark type");
439440
}
440441

441-
const appId = workspace.larkAppId?.trim() ?? "";
442+
const appId = workspace.larkAppKey?.trim() || workspace.larkAppId?.trim() || "";
442443
const appSecret = workspace.larkAppSecret?.trim() ?? "";
443444
if (!appId || !appSecret) {
444445
throw new Error("Missing Lark app credentials");

packages/core/web/server.ts

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ function getLarkWorkspaceCredentialsByChannel(channelId: string): { appId: strin
120120
if (!channelId) return undefined;
121121
for (const workspace of getWorkspaces()) {
122122
if (workspace.type !== "lark") continue;
123-
const appId = workspace.larkAppId?.trim();
123+
const appId = workspace.larkAppKey?.trim() || workspace.larkAppId?.trim();
124124
const appSecret = workspace.larkAppSecret?.trim();
125125
if (!appId || !appSecret) continue;
126126
if (workspace.channelDetails.some((channel) => channel.id === channelId)) {
@@ -134,7 +134,7 @@ function getLarkWorkspaceCredentialsByWorkspace(workspaceId: string): { appId: s
134134
if (!workspaceId) return undefined;
135135
for (const workspace of getWorkspaces()) {
136136
if (workspace.type !== "lark") continue;
137-
const appId = workspace.larkAppId?.trim();
137+
const appId = workspace.larkAppKey?.trim() || workspace.larkAppId?.trim();
138138
const appSecret = workspace.larkAppSecret?.trim();
139139
if (!appId || !appSecret) continue;
140140
if (workspace.id === workspaceId) {
@@ -307,7 +307,7 @@ function validateWorkspaceConfig(config: typeof defaultDashboardConfig): string
307307
const idCounts = new Map<string, number>();
308308
const slackBotTokenCounts = new Map<string, number>();
309309
const discordBotTokenCounts = new Map<string, number>();
310-
const larkAppIdCounts = new Map<string, number>();
310+
const larkAppKeyCounts = new Map<string, number>();
311311
for (const workspace of config.workspaces) {
312312
const workspaceId = workspace.id.trim();
313313
if (!workspaceId) {
@@ -325,13 +325,13 @@ function validateWorkspaceConfig(config: typeof defaultDashboardConfig): string
325325
}
326326

327327
if (workspace.type === "lark") {
328-
const appId = workspace.larkAppId?.trim() ?? "";
328+
const appId = workspace.larkAppKey?.trim() || workspace.larkAppId?.trim() || "";
329329
const appSecret = workspace.larkAppSecret?.trim() ?? "";
330330
if (!appId || !appSecret) {
331331
const label = workspace.name.trim() || workspace.id;
332-
return `Missing Lark app id/app secret for workspace: ${label}`;
332+
return `Missing Lark app key/app secret for workspace: ${label}`;
333333
}
334-
larkAppIdCounts.set(appId, (larkAppIdCounts.get(appId) ?? 0) + 1);
334+
larkAppKeyCounts.set(appId, (larkAppKeyCounts.get(appId) ?? 0) + 1);
335335
continue;
336336
}
337337

@@ -361,9 +361,9 @@ function validateWorkspaceConfig(config: typeof defaultDashboardConfig): string
361361
return "Duplicate Discord bot tokens found across workspaces";
362362
}
363363

364-
const duplicateLarkAppIdCount = Array.from(larkAppIdCounts.values()).filter((count) => count > 1).length;
365-
if (duplicateLarkAppIdCount > 0) {
366-
return "Duplicate Lark app ids found across workspaces";
364+
const duplicateLarkAppKeyCount = Array.from(larkAppKeyCounts.values()).filter((count) => count > 1).length;
365+
if (duplicateLarkAppKeyCount > 0) {
366+
return "Duplicate Lark app keys found across workspaces";
367367
}
368368

369369
return null;
@@ -659,9 +659,11 @@ async function handleRequest(request: Request): Promise<Response> {
659659
}
660660
try {
661661
const payload = (await request.json()) as Record<string, unknown>;
662-
const larkAppId = typeof payload.larkAppId === "string" ? payload.larkAppId : "";
662+
const larkAppKey = typeof payload.larkAppKey === "string"
663+
? payload.larkAppKey
664+
: (typeof payload.larkAppId === "string" ? payload.larkAppId : "");
663665
const larkAppSecret = typeof payload.larkAppSecret === "string" ? payload.larkAppSecret : "";
664-
const workspace = await discoverLarkWorkspace(larkAppId, larkAppSecret);
666+
const workspace = await discoverLarkWorkspace(larkAppKey, larkAppSecret);
665667
return jsonResponse(200, { ok: true, workspace });
666668
} catch (error) {
667669
const message = error instanceof Error ? error.message : "Lark workspace discovery failed";

packages/ims/lark/client.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ function getLarkCredentialsForChannel(channelId: string): LarkCredentials | null
4444
if (channel.length > 0) {
4545
for (const workspace of getWorkspaces()) {
4646
if (workspace.type !== "lark") continue;
47-
const appId = workspace.larkAppId?.trim() ?? "";
47+
const appId = workspace.larkAppKey?.trim() || workspace.larkAppId?.trim() || "";
4848
const appSecret = workspace.larkAppSecret?.trim() ?? "";
4949
if (!appId || !appSecret) continue;
5050
if (workspace.channelDetails.some((entry) => entry.id === channel)) {

packages/web-ui/src/lib/local-setting/store.ts

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ function validateWorkspaceConfig(config: DashboardConfig): string | null {
4747
const idCounts = new Map<string, number>();
4848
const slackBotTokenCounts = new Map<string, number>();
4949
const discordBotTokenCounts = new Map<string, number>();
50-
const larkAppIdCounts = new Map<string, number>();
50+
const larkAppKeyCounts = new Map<string, number>();
5151
for (const workspace of config.workspaces) {
5252
const workspaceId = workspace.id.trim();
5353
if (!workspaceId) {
@@ -61,9 +61,9 @@ function validateWorkspaceConfig(config: DashboardConfig): string | null {
6161
discordBotTokenCounts.set(botToken, (discordBotTokenCounts.get(botToken) ?? 0) + 1);
6262
}
6363
} else if (workspace.type === "lark") {
64-
const appId = workspace.larkAppId?.trim() ?? "";
65-
if (appId) {
66-
larkAppIdCounts.set(appId, (larkAppIdCounts.get(appId) ?? 0) + 1);
64+
const appKey = workspace.larkAppKey?.trim() || workspace.larkAppId?.trim() || "";
65+
if (appKey) {
66+
larkAppKeyCounts.set(appKey, (larkAppKeyCounts.get(appKey) ?? 0) + 1);
6767
}
6868
} else {
6969
const botToken = workspace.slackBotToken?.trim() ?? "";
@@ -94,19 +94,19 @@ function validateWorkspaceConfig(config: DashboardConfig): string | null {
9494
return `Duplicate Discord bot tokens found across workspaces.`;
9595
}
9696

97-
const duplicatedLarkAppIds = Array.from(larkAppIdCounts.entries())
97+
const duplicatedLarkAppKeys = Array.from(larkAppKeyCounts.entries())
9898
.filter(([, count]) => count > 1)
99-
.map(([appId]) => appId);
100-
if (duplicatedLarkAppIds.length > 0) {
101-
return `Duplicate Lark app ids found across workspaces.`;
99+
.map(([appKey]) => appKey);
100+
if (duplicatedLarkAppKeys.length > 0) {
101+
return `Duplicate Lark app keys found across workspaces.`;
102102
}
103103

104104
const missingTokenWorkspaces = config.workspaces.filter((workspace: DashboardConfig["workspaces"][number]) => {
105105
if (workspace.type === "discord") {
106106
return !(workspace.discordBotToken?.trim() ?? "");
107107
}
108108
if (workspace.type === "lark") {
109-
const appId = workspace.larkAppId?.trim() ?? "";
109+
const appId = workspace.larkAppKey?.trim() || workspace.larkAppId?.trim() || "";
110110
const appSecret = workspace.larkAppSecret?.trim() ?? "";
111111
return !appId || !appSecret;
112112
}
@@ -583,15 +583,15 @@ async function discoverDiscordWorkspace(
583583
}
584584

585585
async function discoverLarkWorkspace(
586-
larkAppId: string,
586+
larkAppKey: string,
587587
larkAppSecret: string
588588
): Promise<DashboardConfig["workspaces"][number] | null> {
589-
const appId = larkAppId.trim();
589+
const appId = larkAppKey.trim();
590590
const appSecret = larkAppSecret.trim();
591591
if (!appId || !appSecret) {
592592
store.update((state) => ({
593593
...state,
594-
message: "Validation failed: Lark app id and app secret are required.",
594+
message: "Validation failed: Lark app key and app secret are required.",
595595
}));
596596
return null;
597597
}
@@ -601,7 +601,7 @@ async function discoverLarkWorkspace(
601601
const response = await fetch("/api/lark-discover", {
602602
method: "POST",
603603
headers: { "content-type": "application/json" },
604-
body: JSON.stringify({ larkAppId: appId, larkAppSecret: appSecret }),
604+
body: JSON.stringify({ larkAppKey: appId, larkAppSecret: appSecret }),
605605
});
606606
const payload = (await response.json()) as {
607607
ok?: boolean;

packages/web-ui/src/routes/local-setting/+layout.svelte

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
let pendingSlackAppToken = "";
1414
let pendingSlackBotToken = "";
1515
let pendingDiscordBotToken = "";
16-
let pendingLarkAppId = "";
16+
let pendingLarkAppKey = "";
1717
let pendingLarkAppSecret = "";
1818
let isAddWorkspaceDialogOpen = false;
1919
@@ -32,7 +32,7 @@
3232
const workspace = pendingWorkspaceType === "discord"
3333
? await localSettingStore.discoverDiscordWorkspace(pendingDiscordBotToken)
3434
: pendingWorkspaceType === "lark"
35-
? await localSettingStore.discoverLarkWorkspace(pendingLarkAppId, pendingLarkAppSecret)
35+
? await localSettingStore.discoverLarkWorkspace(pendingLarkAppKey, pendingLarkAppSecret)
3636
: await localSettingStore.discoverSlackWorkspace(
3737
pendingSlackAppToken,
3838
pendingSlackBotToken
@@ -41,7 +41,7 @@
4141
pendingSlackAppToken = "";
4242
pendingSlackBotToken = "";
4343
pendingDiscordBotToken = "";
44-
pendingLarkAppId = "";
44+
pendingLarkAppKey = "";
4545
pendingLarkAppSecret = "";
4646
pendingWorkspaceType = "slack";
4747
isAddWorkspaceDialogOpen = false;
@@ -68,8 +68,8 @@
6868
pendingDiscordBotToken = (event.currentTarget as HTMLInputElement).value;
6969
}
7070
71-
function onPendingLarkAppIdInput(event: Event): void {
72-
pendingLarkAppId = (event.currentTarget as HTMLInputElement).value;
71+
function onPendingLarkAppKeyInput(event: Event): void {
72+
pendingLarkAppKey = (event.currentTarget as HTMLInputElement).value;
7373
}
7474
7575
function onPendingLarkAppSecretInput(event: Event): void {
@@ -228,12 +228,12 @@
228228
placeholder="Bot token"
229229
/>
230230
{:else}
231-
<label for="new-workspace-lark-app-id">Lark App ID</label>
231+
<label for="new-workspace-lark-app-key">Lark App Key</label>
232232
<input
233-
id="new-workspace-lark-app-id"
233+
id="new-workspace-lark-app-key"
234234
type="text"
235-
value={pendingLarkAppId}
236-
on:input={onPendingLarkAppIdInput}
235+
value={pendingLarkAppKey}
236+
on:input={onPendingLarkAppKeyInput}
237237
placeholder="cli_xxx"
238238
/>
239239

packages/web-ui/src/routes/local-setting/slack-bot/[workspaceName]/+page.svelte

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,13 @@
4141
$: duplicateWorkspaceIds = getDuplicateWorkspaceIds($localSettingStore.config.workspaces);
4242
$: duplicateSlackBotTokens = getDuplicateSlackBotTokens($localSettingStore.config.workspaces);
4343
$: duplicateDiscordBotTokens = getDuplicateDiscordBotTokens($localSettingStore.config.workspaces);
44-
$: duplicateLarkAppIds = getDuplicateLarkAppIds($localSettingStore.config.workspaces);
44+
$: duplicateLarkAppKeys = getDuplicateLarkAppKeys($localSettingStore.config.workspaces);
4545
$: selectedWorkspaceErrors = getWorkspaceErrors(
4646
selectedWorkspace,
4747
duplicateWorkspaceIds,
4848
duplicateSlackBotTokens,
4949
duplicateDiscordBotTokens,
50-
duplicateLarkAppIds
50+
duplicateLarkAppKeys
5151
);
5252
$: enabledProviders = agentProviders.filter((provider) => isProviderEnabled(provider));
5353
$: maybeCanonicalizeWorkspaceRoute();
@@ -93,18 +93,19 @@
9393
9494
function onWorkspaceFieldInput(
9595
workspaceId: string,
96-
field: "name" | "domain" | "slackAppToken" | "slackBotToken" | "discordBotToken" | "larkAppId" | "larkAppSecret",
96+
field: "name" | "domain" | "slackAppToken" | "slackBotToken" | "discordBotToken" | "larkAppKey" | "larkAppId" | "larkAppSecret",
9797
value: string
9898
): void {
9999
localSettingStore.updateWorkspace(workspaceId, (workspace) => ({
100100
...workspace,
101101
[field]: value,
102+
...(field === "larkAppKey" ? { larkAppId: value } : {}),
102103
}));
103104
}
104105
105106
function onWorkspaceTextInput(
106107
workspaceId: string,
107-
field: "name" | "domain" | "slackAppToken" | "slackBotToken" | "discordBotToken" | "larkAppId" | "larkAppSecret",
108+
field: "name" | "domain" | "slackAppToken" | "slackBotToken" | "discordBotToken" | "larkAppKey" | "larkAppId" | "larkAppSecret",
108109
event: Event
109110
): void {
110111
onWorkspaceFieldInput(workspaceId, field, (event.currentTarget as HTMLInputElement).value);
@@ -218,10 +219,11 @@
218219
return errors;
219220
}
220221
if (workspace.type === "lark") {
221-
if (!(workspace.larkAppId?.trim() ?? "")) {
222-
errors.push("Lark App ID is required.");
223-
} else if (duplicateLarkIds.has((workspace.larkAppId ?? "").trim())) {
224-
errors.push("Lark App ID must be unique across workspaces.");
222+
const appKey = workspace.larkAppKey?.trim() || workspace.larkAppId?.trim() || "";
223+
if (!appKey) {
224+
errors.push("Lark App Key is required.");
225+
} else if (duplicateLarkIds.has(appKey)) {
226+
errors.push("Lark App Key must be unique across workspaces.");
225227
}
226228
if (!(workspace.larkAppSecret?.trim() ?? "")) {
227229
errors.push("Lark App Secret is required.");
@@ -261,11 +263,11 @@
261263
return new Set(Array.from(counts.entries()).filter(([, count]) => count > 1).map(([token]) => token));
262264
}
263265
264-
function getDuplicateLarkAppIds(workspaces: DashboardConfig["workspaces"]): Set<string> {
266+
function getDuplicateLarkAppKeys(workspaces: DashboardConfig["workspaces"]): Set<string> {
265267
const counts = new Map<string, number>();
266268
for (const workspace of workspaces) {
267269
if (workspace.type !== "lark") continue;
268-
const appId = workspace.larkAppId?.trim() ?? "";
270+
const appId = workspace.larkAppKey?.trim() || workspace.larkAppId?.trim() || "";
269271
if (!appId) continue;
270272
counts.set(appId, (counts.get(appId) ?? 0) + 1);
271273
}
@@ -326,12 +328,12 @@
326328
on:input={(event) => onWorkspaceTextInput(selectedWorkspace.id, "discordBotToken", event)}
327329
/>
328330
{:else}
329-
<label for="workspace-lark-app-id">Lark App ID</label>
331+
<label for="workspace-lark-app-key">Lark App Key</label>
330332
<input
331-
id="workspace-lark-app-id"
333+
id="workspace-lark-app-key"
332334
type="text"
333-
value={selectedWorkspace.larkAppId ?? ""}
334-
on:input={(event) => onWorkspaceTextInput(selectedWorkspace.id, "larkAppId", event)}
335+
value={selectedWorkspace.larkAppKey ?? selectedWorkspace.larkAppId ?? ""}
336+
on:input={(event) => onWorkspaceTextInput(selectedWorkspace.id, "larkAppKey", event)}
335337
/>
336338

337339
<label for="workspace-lark-app-secret">Lark App Secret</label>

0 commit comments

Comments
 (0)