Files
wpywmail-client/server/account.js
T

93 lines
3.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use strict';
/**
* 账户配置的读取与保存。
*
* 位置优先级:
* 1. 环境变量 WPYWMAIL_ACCOUNT_FILE 指定的文件(自测/多账户时用)
* 2. %LOCALAPPDATA%\WpywMailClient\account.json(默认,跟着用户走)
*
* 安全说明(不粉饰):密码以明文存在这个文件里。这是自研客户端的常见做法
* (Thunderbird 之类会用系统凭据库/主密码,那需要额外依赖)。本文件只放在
* 当前用户自己的 profile 目录下,不做任何网络传输;若在意,可把
* account.savePassword 设为 false,每次启动时手动输入密码。
*/
const fs = require('node:fs');
const os = require('node:os');
const path = require('node:path');
const DEFAULTS = {
host: 'mail.example.com',
imapPort: 993,
smtpPort: 587,
implicitTls: true, // 993 隐式 TLS
startTls: true, // 587 先 STARTTLS 再 AUTH
user: '',
password: '',
displayName: '',
domain: 'wpy.email',
savePassword: true,
// 服务器「账号接口」入口(注册 / 找回密码 / 会话与资料)。
// 只放账号类接口,邮件读写仍然走 IMAP/SMTP —— 这里看不到任何邮件数据。
apiBase: 'https://mail.example.com:9443',
// 界面默认值
pageSize: 50,
folders: { inbox: 'INBOX', sent: 'Sent', drafts: 'Drafts', archive: 'Archive', trash: 'Trash', junk: 'Junk' },
};
function defaultDir() {
if (process.env.WPYWMAIL_CONFIG_DIR) return process.env.WPYWMAIL_CONFIG_DIR;
const base = process.env.LOCALAPPDATA || path.join(os.homedir(), 'AppData', 'Local');
return path.join(base, 'WpywMailClient');
}
function accountFile() {
if (process.env.WPYWMAIL_ACCOUNT_FILE) return process.env.WPYWMAIL_ACCOUNT_FILE;
return path.join(defaultDir(), 'account.json');
}
function loadAccount() {
const file = accountFile();
let data = {};
try {
if (fs.existsSync(file)) data = JSON.parse(fs.readFileSync(file, 'utf8'));
} catch (err) {
throw new Error(`账户配置读取失败(${file}):${err.message}`);
}
return Object.assign({}, DEFAULTS, data, { _file: file });
}
function saveAccount(account) {
const file = accountFile();
const clean = Object.assign({}, account);
delete clean._file;
fs.mkdirSync(path.dirname(file), { recursive: true });
fs.writeFileSync(file, JSON.stringify(clean, null, 2), { encoding: 'utf8', mode: 0o600 });
return file;
}
/** 供 UI 与自测复用:把配置变成两个客户端 */
function connectionOptions(account) {
return {
imap: {
host: account.host,
port: account.imapPort,
user: account.user,
password: account.password,
implicitTls: !!account.implicitTls,
startTls: !!account.startTls,
},
smtp: {
host: account.host,
port: account.smtpPort,
user: account.user,
password: account.password,
startTls: !!account.startTls,
heloName: account.heloName || undefined,
},
};
}
module.exports = { DEFAULTS, accountFile, defaultDir, loadAccount, saveAccount, connectionOptions };