File size: 7,762 Bytes
10e712d c1f0252 10e712d acfefde c1f0252 acfefde c1f0252 acfefde c1f0252 acfefde c1f0252 acfefde c1f0252 acfefde c1f0252 acfefde c1f0252 acfefde c1f0252 acfefde c1f0252 4e90688 acfefde c1f0252 4e90688 c1f0252 acfefde c1f0252 acfefde c1f0252 acfefde c1f0252 acfefde | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 | import { config } from "./config";
import { deleteSettings, getSetting, setSetting } from "./db";
import { addProvider, getProvider, removeProvider, tempConfigured, updateProvider } from "./temp-providers";
const AUTH_SETTING_KEYS = [
"claw.apiKey",
"claw.dashboardCookie",
"claw.userEmail",
"claw.workspaceId",
"claw.workspaceName",
"claw.parentMailboxId",
"claw.rootPrefix",
"claw.domain"
];
export function getClawApiKey(): string | undefined {
return getSetting("claw.apiKey") ?? config.CLAW_API_KEY;
}
export function requireClawApiKey(): string {
const value = getClawApiKey();
if (!value) {
throw new Error("CLAW_API_KEY is required for mail operations; connect Claw first");
}
return value;
}
export function getDashboardCookie(): string | undefined {
return getSetting("claw.dashboardCookie") ?? config.CLAW_DASHBOARD_COOKIE;
}
export function requireDashboardCookie(): string {
const value = getDashboardCookie();
if (!value) {
throw new Error("CLAW_DASHBOARD_COOKIE is required for mailbox management; connect Claw first");
}
return value;
}
export function getWorkspaceId(): string {
const value = getStoredWorkspaceId();
if (!value) {
throw new Error("Claw workspace is not configured; connect Claw first");
}
return value;
}
export function getParentMailboxId(): string {
const value = getStoredParentMailboxId();
if (!value) {
throw new Error("Claw parent mailbox is not configured; connect Claw first");
}
return value;
}
export function getRootPrefix(): string {
const value = getStoredRootPrefix();
if (!value) {
throw new Error("Claw root prefix is not configured; connect Claw first");
}
return value;
}
export function getDomain(): string {
return getStoredDomain();
}
export function hasClawMailConfig(): boolean {
return Boolean(getClawApiKey());
}
export function hasClawDashboardConfig(): boolean {
return Boolean(getDashboardCookie());
}
function getStoredWorkspaceId(): string | null {
return getSetting("claw.workspaceId") ?? config.CLAW_WORKSPACE_ID ?? null;
}
function getStoredParentMailboxId(): string | null {
return getSetting("claw.parentMailboxId") ?? config.CLAW_PARENT_MAILBOX_ID ?? null;
}
function getStoredRootPrefix(): string | null {
return getSetting("claw.rootPrefix") ?? config.CLAW_ROOT_PREFIX ?? null;
}
function getStoredDomain(): string {
return getSetting("claw.domain") ?? config.CLAW_DOMAIN;
}
export function getClawAuthStatus() {
const apiKey = getClawApiKey();
const cookie = getDashboardCookie();
const workspaceId = cookie ? getStoredWorkspaceId() : null;
const parentMailboxId = cookie ? getStoredParentMailboxId() : null;
const rootPrefix = cookie ? getStoredRootPrefix() : null;
const domain = cookie ? getStoredDomain() : null;
return {
connected: Boolean(apiKey && cookie && workspaceId && parentMailboxId && rootPrefix && domain),
hasApiKey: Boolean(apiKey),
hasDashboardCookie: Boolean(cookie),
userEmail: getSetting("claw.userEmail") ?? null,
workspaceId,
workspaceName: getSetting("claw.workspaceName") ?? null,
parentMailboxId,
rootPrefix,
domain,
apiKeyPrefix: apiKey ? apiKey.slice(0, 10) : null,
apiKeySuffix: apiKey ? apiKey.slice(-4) : null
};
}
export function saveClawAuthSettings(input: {
apiKey: string;
dashboardCookie: string;
userEmail?: string | null;
workspaceId: string;
workspaceName?: string | null;
parentMailboxId: string;
rootPrefix: string;
domain: string;
}): void {
setSetting("claw.apiKey", input.apiKey);
setSetting("claw.dashboardCookie", input.dashboardCookie);
setSetting("claw.workspaceId", input.workspaceId);
setSetting("claw.parentMailboxId", input.parentMailboxId);
setSetting("claw.rootPrefix", input.rootPrefix);
setSetting("claw.domain", input.domain);
if (input.userEmail) setSetting("claw.userEmail", input.userEmail);
if (input.workspaceName) setSetting("claw.workspaceName", input.workspaceName);
}
export function clearClawAuthSettings(): void {
deleteSettings(AUTH_SETTING_KEYS);
}
// ---------- 临时邮箱(多 provider;见 temp-providers.ts)----------
// 旧的「单配置」表单/接口仍可用,作用于「主 provider」(列表第一个),
// 向后兼容现有 edu;新增/管理多个源走 temp-providers 的 add/update/remove。
// 密码只写不回显。
export function cfConfigured(): boolean {
return tempConfigured();
}
export function getCfDomain(): string {
return getProvider()?.domain ?? "";
}
export function getCfConfigStatus() {
const primary = getProvider();
return {
configured: Boolean(primary),
endpoint: primary?.endpoint ?? "",
domain: primary?.domain ?? "",
hasPassword: Boolean(primary?.password),
source: primary ? (primary.id === "edu" ? "env" : "ui") : "none"
};
}
export function saveCfConfig(input: {
endpoint: string;
domain?: string | null;
password?: string | null;
}): void {
const primary = getProvider();
if (primary) {
updateProvider(primary.id, {
endpoint: input.endpoint,
domain: input.domain ?? undefined,
password: input.password ?? undefined
});
} else {
addProvider({
name: (input.domain ?? "").trim() || "temp",
type: "php",
endpoint: input.endpoint,
domain: input.domain ?? "",
password: input.password ?? ""
});
}
}
export function clearCfConfig(): void {
const primary = getProvider();
if (primary) removeProvider(primary.id);
}
// ---------- AI 助手(右下角气泡)配置 ----------
// OpenAI 兼容端点(base_url + key + model),provider 无关。UI 可配,存 app_settings
// (随 Supabase 持久化),env 兜底。api key 只写不回显。
const AI_SETTING_KEYS = ["ai.baseUrl", "ai.apiKey", "ai.model"];
const DEFAULT_AI_MODEL = "gpt-4o-mini";
export function getAiBaseUrl(): string | undefined {
const v = getSetting("ai.baseUrl") ?? config.AI_BASE_URL;
return v?.replace(/\/+$/, "");
}
export function getAiApiKey(): string | undefined {
return getSetting("ai.apiKey") ?? config.AI_API_KEY;
}
export function getAiModel(): string {
return getSetting("ai.model") ?? config.AI_MODEL ?? DEFAULT_AI_MODEL;
}
export function aiConfigured(): boolean {
return Boolean(getAiBaseUrl() && getAiApiKey());
}
export function getAiConfigStatus() {
const baseUrl = getAiBaseUrl();
const hasKey = Boolean(getAiApiKey());
const fromSettings = Boolean(getSetting("ai.baseUrl") || getSetting("ai.apiKey"));
// 只回显用户/env 真正设过的模型;没设就返回空,避免 UI 凭空冒出 gpt-4o-mini 默认值。
// (实际调用 getAiModel() 仍有 DEFAULT_AI_MODEL 兜底,不影响气泡可用。)
return {
configured: Boolean(baseUrl && hasKey),
baseUrl: baseUrl ?? "",
model: getSetting("ai.model") ?? config.AI_MODEL ?? "",
hasKey,
source: fromSettings ? "ui" : baseUrl || hasKey ? "env" : "none"
};
}
export function saveAiConfig(input: {
baseUrl: string;
model?: string | null;
apiKey?: string | null;
}): void {
setSetting("ai.baseUrl", input.baseUrl.trim().replace(/\/+$/, ""));
if (input.model && input.model.trim()) setSetting("ai.model", input.model.trim());
// 只在传入非空时覆盖 key,方便改 baseUrl/model 时不必重输密钥。
if (input.apiKey && input.apiKey.trim()) setSetting("ai.apiKey", input.apiKey.trim());
}
export function clearAiConfig(): void {
deleteSettings(AI_SETTING_KEYS);
}
|