homebridge-savanthost
Version:
156 lines • 5.78 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getDeviceId = getDeviceId;
exports.generateAddressCode = generateAddressCode;
exports.validateAuthCode = validateAuthCode;
exports.getAuthData = getAuthData;
exports.saveAuthData = saveAuthData;
exports.activatePlugin = activatePlugin;
exports.isPluginActivated = isPluginActivated;
exports.getAddressCode = getAddressCode;
const fs_1 = require("fs");
const path = __importStar(require("path"));
const os = __importStar(require("os"));
const crypto = __importStar(require("crypto"));
// 授权状态存储路径
const AUTH_FILE_PATH = path.join(os.homedir(), '.homebridge', 'savanthost-auth.json');
// 获取设备MAC地址
async function getDeviceId() {
const networkInterfaces = os.networkInterfaces();
// 尝试获取第一个非内部的网络接口的MAC地址
for (const key of Object.keys(networkInterfaces)) {
const interfaces = networkInterfaces[key];
if (interfaces) {
for (const intrfc of interfaces) {
// 跳过内部接口和没有MAC地址的接口
if (!intrfc.internal && intrfc.mac && intrfc.mac !== '00:00:00:00:00:00') {
// 移除MAC地址中的冒号,转为大写
return intrfc.mac.replace(/:/g, '').toUpperCase();
}
}
}
}
// 如果无法获取MAC地址,生成一个基于主机名的唯一ID
const fallbackId = crypto.createHash('md5').update(os.hostname()).digest('hex').toUpperCase().slice(0, 16);
return fallbackId;
}
// 生成地址码
async function generateAddressCode(deviceId) {
// 对设备ID进行混淆处理,生成16位地址码
const hash = crypto.createHash('sha256').update(deviceId + 'SavantHost').digest('hex');
return hash.substring(0, 16).toUpperCase();
}
// 验证授权码
function validateAuthCode(addressCode, authCode) {
// 实现验证逻辑:对地址码进行特定算法处理后生成授权码
// 这里简单实现为对地址码进行反转后再进行SHA256哈希取前16位
const expectedAuthCode = crypto.createHash('sha256')
.update(addressCode.split('').reverse().join('') + 'SavantHostAuth')
.digest('hex')
.substring(0, 16)
.toUpperCase();
return authCode.toUpperCase() === expectedAuthCode;
}
// 读取授权信息
async function getAuthData(log) {
try {
const data = await fs_1.promises.readFile(AUTH_FILE_PATH, 'utf-8');
return JSON.parse(data);
}
catch (error) {
log.debug('未找到授权文件或文件读取错误');
// 获取设备ID并生成新的授权数据
const deviceId = await getDeviceId();
const newAuthData = {
deviceId,
activated: false,
};
// 保存新的授权数据
await saveAuthData(newAuthData, log);
return newAuthData;
}
}
// 保存授权信息
async function saveAuthData(authData, log) {
try {
await fs_1.promises.mkdir(path.dirname(AUTH_FILE_PATH), { recursive: true });
await fs_1.promises.writeFile(AUTH_FILE_PATH, JSON.stringify(authData, null, 2));
}
catch (error) {
log.error('保存授权数据失败:', error);
throw error;
}
}
// 激活插件
async function activatePlugin(authCode, log) {
try {
const authData = await getAuthData(log);
if (authData.activated) {
log.info('插件已激活');
return true;
}
const addressCode = await generateAddressCode(authData.deviceId);
log.debug(`设备ID: ${authData.deviceId}, 地址码: ${addressCode}`);
if (validateAuthCode(addressCode, authCode)) {
authData.activated = true;
authData.authCode = authCode;
await saveAuthData(authData, log);
log.info('插件已成功激活');
return true;
}
else {
log.error('授权码无效');
return false;
}
}
catch (error) {
log.error('激活过程中出错:', error);
return false;
}
}
// 检查插件是否已激活
async function isPluginActivated(log) {
try {
const authData = await getAuthData(log);
return authData.activated;
}
catch (error) {
log.error('检查授权状态失败:', error);
return false;
}
}
// 获取地址码
async function getAddressCode(log) {
try {
const authData = await getAuthData(log);
return await generateAddressCode(authData.deviceId);
}
catch (error) {
log.error('获取地址码失败:', error);
throw error;
}
}
//# sourceMappingURL=auth.js.map