/** * 更新发布工具 - 认证与服务器连接模块 * * Copyright © 2025 imengyu.top imengyu-update-server */ import { readFile, writeFile } from 'node:fs/promises'; import path from 'node:path'; import { dirname } from 'node:path'; import { fileURLToPath } from 'node:url'; import axios from 'axios'; import md5 from 'md5'; import { password } from '@inquirer/prompts'; import { config } from './postConfig.mjs'; // 基础配置 // ======================================== const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); export const constant = { ServerUrl: config.server, TokenSave: path.resolve(__dirname, './_token.json'), }; let currentData = { token: '', identifier: '', }; function initIdentifier() { if (!currentData.identifier) currentData.identifier = `commandClient${Math.floor(Math.random() * 1000)}`; } function getErrorMessage(e) { return e instanceof Error ? e.message : (typeof e === 'object' ? e : '' + e); } // Axios 实例 // ======================================== export const axiosInstance = axios.create({ baseURL: constant.ServerUrl, timeoutErrorMessage: '请求超时,请检查网络连接', responseType: 'json', withCredentials: false, validateStatus: () => true, }); axiosInstance.interceptors.request.use((value) => { value.headers['authorization'] = JSON.stringify({ auth: currentData?.token?.authName, validity: currentData?.token?.authKey, nonce: 'aaaaaaaaaa', identifier: currentData.identifier, key: 'abc123', }); value.url = value.url + (value.url.includes('?') ? '&' : '?') + `identifier=${currentData.identifier}`; return value; }); axiosInstance.interceptors.response.use((value) => { if (value.data.success) return value.data; else return Promise.reject(value.data); }); // 认证初始化 // ======================================== /** * 初始化认证模块,从本地加载 token * @returns {Promise} */ export async function initAuth() { try { const res = await readFile(constant.TokenSave); const parsed = JSON.parse(res); if (parsed && typeof parsed === 'object') { currentData = { ...currentData, ...parsed }; } } catch { // 无 token 文件时使用默认值 } initIdentifier(); } /** * 获取当前认证数据(只读) */ export function getCurrentData() { return { ...currentData }; } // 登录相关 // ======================================== /** * 检查登录状态 */ export async function checkLogged() { try { await axiosInstance.get('/auth'); console.log('已登录'); } catch (e) { console.error('获取状态失败:', getErrorMessage(e)); } } /** * 登录 * @param {string} user 用户名 */ export async function login(user) { try { const pass = await password({ message: '输入密码' }); const res = await axiosInstance.post('/auth?rember=true', { method: 'key', key: `${user}@${md5(pass)}`, }); currentData.token = { authName: res.data.authName, authKey: res.data.authKey, }; await writeFile(constant.TokenSave, JSON.stringify(currentData)); console.log('登录成功'); } catch (e) { console.error('登录失败', getErrorMessage(e)); } } /** * 退出登录 */ export async function logout() { currentData.token = ''; await writeFile(constant.TokenSave, JSON.stringify(currentData)); try { await axiosInstance.delete('/auth'); console.log('退出登录成功'); } catch (e) { console.error('退出登录失败', getErrorMessage(e)); } }