# License Manager

<div align="center">

![npm version](https://badge.fury.io/js/@flowerjunjie%2Flicense-manager.svg)
![npm downloads](https://img.shields.io/npm/dm/@flowerjunjie/license-manager)
![npm license](https://img.shields.io/npm/l/@flowerjunjie/license-manager)
![License Manager](https://img.shields.io/badge/License%20Manager-Enterprise%20Grade-blue)
![TypeScript](https://img.shields.io/badge/TypeScript-Ready-brightgreen)
![Node](https://img.shields.io/badge/Node.js-%3E=14.0-green)

🔐 专业软件授权和许可证管理系统 - 为您的应用提供企业级许可证管理方案

[功能特性](#-特性) • [快速开始](#-快速开始) • [文档](#-文档) • [示例](#-示例) • [API](#-api-文档)

[Installation](#-安装) • [Changelog](CHANGELOG.md) • [Publishing Guide](PUBLISH_GUIDE.md) • [NPM Package](https://www.npmjs.com/package/@flowerjunjie/license-manager)

</div>

---

## ✨ 特性

- ✅ **RSA签名** - 2048位RSA非对称加密，防篡改保证
- ✅ **功能授权** - 8种预定义功能 + 自定义功能，细粒度控制
- ✅ **使用限制** - 用户数、请求数、存储空间等多维度限制
- ✅ **绑定验证** - 支持域名（含通配符）、IP、机器码、MAC地址绑定
- ✅ **宽限期支持** - 过期后提供续费缓冲期，提升用户体验
- ✅ **批量生成** - 支持从数据库、CSV批量生成许可证
- ✅ **离线验证** - 无需网络连接，适合内网环境
- ✅ **CLI工具** - 命令行工具快速生成密钥和许可证
- ✅ **TypeScript** - 完整类型定义，开发体验友好
- ✅ **Express集成** - 开箱即用的中间件，快速集成到现有项目
- ✅ **多种许可证类型** - 试用版、标准版、专业版、企业版、自定义版
- ✅ **管理后台** - 完整的 Web 管理界面，支持许可证状态实时控制

## 📦 安装

从 npm 安装：

```bash
npm install @flowerjunjie/license-manager
```

## 🚀 快速开始

### 1. 生成密钥对

```bash
# 使用内置工具生成RSA密钥对
node -e "const { Crypto } = require('@flowerjunjie/license-manager'); const fs = require('fs'); const { publicKey, privateKey } = Crypto.generateKeyPair(); fs.writeFileSync('keys/private.key', privateKey); fs.writeFileSync('keys/public.key', publicKey); console.log('✅ 密钥对生成成功');"

# 密钥将保存到:
# - keys/private.key (私钥 - 用于生成许可证，请妥善保管)
# - keys/public.key (公钥 - 用于验证许可证，可嵌入应用)
```

### 2. 生成许可证

```typescript
// 本地安装
import { LicenseManager, LicenseType } from './license-manager/dist';

// 或 npm 安装后（待发布）
// import { LicenseManager, LicenseType } from '@flowerjunjie/license-manager';

import * as fs from 'fs';

// 读取私钥
const privateKey = fs.readFileSync('keys/private.key', 'utf8');

// 创建许可证管理器
const manager = new LicenseManager({ privateKey });

// 生成许可证
const license = manager.generate({
  licenseId: 'lic-001',
  clientId: 'customer-001',
  type: LicenseType.PROFESSIONAL,
  customerName: '示例客户',
  customerEmail: 'customer@example.com',

  // 功能授权
  features: {
    aiAssistant: true,
    advancedAnalytics: true,
    customReports: true,
    apiAccess: true,
    whiteLabel: false,
    multiTenant: false,
    customIntegration: false,
    premiumSupport: true,
  },

  // 使用限制
  limits: {
    maxUsers: 100,
    maxRequests: 1000000,
    maxStorage: 10240, // MB
  },

  // 绑定配置
  bindings: {
    domain: '*.example.com', // 支持通配符
  },

  duration: 365, // 有效期：365天
  gracePeriodDays: 30, // 宽限期：30天
});

// 导出许可证
const licenseKey = license.export('base64');
fs.writeFileSync('licenses/license.key', licenseKey);

console.log('✅ 许可证生成成功:', license.data.licenseId);
```

### 3. 验证许可证

```typescript
// 本地安装
import { LicenseValidator } from './license-manager/dist';

// 或 npm 安装后（待发布）
// import { LicenseValidator } from '@flowerjunjie/license-manager';

import * as fs from 'fs';

// 读取公钥
const publicKey = fs.readFileSync('keys/public.key', 'utf8');

// 创建验证器
const validator = new LicenseValidator(publicKey);

// 读取许可证
const licenseKey = fs.readFileSync('licenses/license.key', 'utf8');

try {
  // 验证许可证（允许宽限期）
  const license = validator.verify(licenseKey, {
    strict: true,           // 严格模式（检查过期）
    allowGracePeriod: true, // 允许宽限期
    checkBindings: {
      domain: 'app.example.com',
    },
  });

  console.log('✅ 许可证有效');
  console.log('客户:', license.data.customerName);
  console.log('类型:', license.data.type);

  // 检查宽限期状态
  if (license.isExpired()) {
    if (license.isInGracePeriod()) {
      const days = license.getGracePeriodDaysRemaining();
      console.log(`⚠️ 许可证已过期，但在宽限期内（剩余 ${days} 天）`);
    }
  }

  // 检查功能权限
  if (license.hasFeature('aiAssistant')) {
    console.log('✅ AI助手功能已启用');
  }

  // 检查使用限制
  if (license.isWithinLimit('maxUsers', currentUsers)) {
    console.log('✅ 用户数在限制范围内');
  }

} catch (error) {
  console.error('❌ 许可证验证失败:', error.message);
}
```

### 4. Express 集成

```typescript
import express from 'express';
import { requireLicense, requireFeature, checkLimit } from './middleware/license';

const app = express();

// 全局许可证验证
app.use('/api', requireLicense({
  strict: true,
  allowGracePeriod: true,
  checkDomain: true,
}));

// 功能权限检查
app.use('/api/ai', [
  requireLicense(),
  requireFeature('aiAssistant'), // 需要AI功能权限
]);

// 使用量限制检查
app.post('/api/users', [
  requireLicense(),
  checkLimit('maxUsers', async () => await User.countDocuments())
], createUserHandler);

// 许可证信息查询
app.get('/api/license/info', requireLicense(), (req, res) => {
  const license = req.license;
  res.json({
    customerName: license.data.customerName,
    type: license.data.type,
    features: license.data.features,
    expiresAt: license.data.expiresAt,
  });
});

app.listen(3000);
```

## 📚 文档

- 📖 [完整使用指南](./使用指南.md) - 详细的安装、配置和使用说明
- 🚀 [快速参考](./快速参考.md) - 常用代码片段和配置示例
- 📋 [部署检查清单](./部署检查清单.md) - 生产环境部署指南
- 📡 [API 文档](./API文档.md) - 完整的 API 参考文档
- ❓ [常见问题](./常见问题.md) - FAQ 和问题排查

## 🌟 核心功能详解

### 宽限期功能

允许许可证过期后继续使用一段时间，给客户续费缓冲期：

```typescript
// 生成带宽限期的许可证
const license = manager.generate({
  duration: 365,         // 1年有效期
  gracePeriodDays: 30,   // 30天宽限期
});

// 时间线：
// Day 0:    许可证生效
// Day 365:  许可证过期（但仍可使用）
// Day 395:  宽限期结束（完全不可用）

// 验证时允许宽限期
const verified = validator.verify(licenseKey, {
  strict: true,
  allowGracePeriod: true,  // 允许宽限期
});

// 检查宽限期状态
console.log('在宽限期内:', verified.isInGracePeriod());
console.log('剩余天数:', verified.getGracePeriodDaysRemaining());
```

### 批量生成许可证

从数据库或 CSV 批量生成许可证：

```typescript
// 从数据库批量生成
const customers = await Customer.find({});

customers.forEach(customer => {
  const license = manager.generate({
    clientId: customer.id,
    customerName: customer.company,
    type: customer.licenseType,
    duration: customer.duration,
  });

  fs.writeFileSync(`licenses/${customer.id}.key`, license.export('base64'));
});

// 从CSV批量生成
const csvData = fs.readFileSync('customers.csv', 'utf8');
const rows = csvData.split('\n');

rows.slice(1).forEach(row => {
  const [clientId, customerName, type, duration] = row.split(',');
  const license = manager.generate({
    clientId,
    customerName,
    type: type.toUpperCase(),
    duration: parseInt(duration),
  });
});
```

### 自定义过期日期

支持灵活的过期日期设置：

```typescript
// 方式1: 使用 duration（相对时间）
const license1 = manager.generate({
  duration: 365,  // 365天后过期
});

// 方式2: 使用 expiresAt（绝对时间）
const license2 = manager.generate({
  expiresAt: '2025-12-31T23:59:59.999Z',  // 指定具体日期
});

// 方式3: 计算特定日期
function getFiscalYearEnd() {
  const now = new Date();
  return new Date(now.getFullYear() + 1, 2, 31, 23, 59, 59).toISOString();
}

const license3 = manager.generate({
  expiresAt: getFiscalYearEnd(),  // 财年结束
});
```

## 📋 许可证类型

| 类型 | 说明 | 适用场景 |
|------|------|----------|
| `TRIAL` | 试用版 | 新用户试用，功能受限，短期授权 |
| `STANDARD` | 标准版 | 基础功能，适合小团队 |
| `PROFESSIONAL` | 专业版 | 完整功能，适合中型团队 |
| `ENTERPRISE` | 企业版 | 全功能+定制，大型企业 |
| `CUSTOM` | 自定义版 | 完全定制化配置 |

## 🔐 功能说明

### 预定义功能

- `aiAssistant` - AI助手功能
- `advancedAnalytics` - 高级分析
- `customReports` - 自定义报表
- `apiAccess` - API访问权限
- `whiteLabel` - 白标功能
- `multiTenant` - 多租户支持
- `customIntegration` - 自定义集成
- `premiumSupport` - 优先技术支持

### 使用限制

- `maxUsers` - 最大用户数
- `maxRequests` - 最大请求数（API调用）
- `maxStorage` - 最大存储空间（MB）
- `concurrentSessions` - 并发会话数
- `maxProjects` - 最大项目数
- `maxTeams` - 最大团队数

### 绑定选项

- `domain` - 域名绑定，支持通配符 `*.example.com`
- `ipAddress` - IP地址绑定
- `machineId` - 机器码绑定
- `macAddress` - MAC地址绑定

## 💡 使用场景示例

### 场景1: SaaS应用多套餐授权

```typescript
// 基础版
const basic = manager.generate({
  type: LicenseType.STANDARD,
  features: {
    customReports: true,
    apiAccess: false,
  },
  limits: {
    maxUsers: 50,
  },
});

// 专业版
const pro = manager.generate({
  type: LicenseType.PROFESSIONAL,
  features: {
    customReports: true,
    apiAccess: true,
    aiAssistant: true,
  },
  limits: {
    maxUsers: 200,
  },
});
```

### 场景2: 企业内网应用

```typescript
const license = manager.generate({
  clientId: 'enterprise-internal',
  type: LicenseType.ENTERPRISE,
  bindings: {
    domain: '*.internal.company.com',  // 内网域名
    ipAddress: '192.168.1.*',          // 内网IP段
  },
  duration: 365 * 3,  // 3年授权
});
```

### 场景3: 教育机构授权

```typescript
const schoolLicense = manager.generate({
  clientId: 'school-001',
  type: LicenseType.ENTERPRISE,
  customerName: '某某大学',
  limits: {
    maxUsers: 5000,  // 师生数量
    maxRequests: 500000,
  },
  duration: 365,  // 1学年
  gracePeriodDays: 90,  // 寒假宽限期
});
```

## 🛠️ 开发

### 构建

```bash
# 克隆仓库
git clone https://github.com/flowerjunjie/license-manager.git
cd license-manager

# 安装依赖
npm install

# 构建
npm run build

# 运行测试
npm test
```

### 项目结构

```
license-manager/
├── src/                    # 源代码
│   ├── core/              # 核心功能
│   │   ├── License.ts
│   │   ├── LicenseGenerator.ts
│   │   ├── LicenseValidator.ts
│   │   └── Crypto.ts
│   ├── types/             # 类型定义
│   └── index.ts           # 入口文件
├── dist/                  # 编译输出
├── examples/              # 示例代码
├── tests/                 # 测试文件
├── keys/                  # 密钥目录（不提交）
├── licenses/              # 许可证目录（不提交）
└── docs/                  # 文档
```

## 🔒 安全建议

1. **私钥保护**
   - ❌ 不要硬编码在代码中
   - ❌ 不要提交到 Git 仓库
   - ✅ 使用环境变量或密钥管理服务
   - ✅ 设置文件权限为 `600`

2. **公钥分发**
   - ✅ 可以安全地嵌入应用代码
   - ✅ 通过安全渠道分发给客户

3. **许可证存储**
   - ✅ 加密存储许可证密钥
   - ✅ 使用 HTTPS 传输

4. **生产环境**
   - ✅ 启用严格模式
   - ✅ 启用域名/IP绑定
   - ✅ 禁用开发绕过选项

## 📊 许可证数据结构

```typescript
interface LicenseData {
  // 基本信息
  licenseId: string;              // 许可证唯一ID
  clientId: string;               // 客户ID
  type: LicenseType;              // 许可证类型
  customerName: string;           // 客户名称
  customerEmail?: string;         // 客户邮箱

  // 功能授权
  features: LicenseFeatures;      // 功能配置

  // 使用限制
  limits: LicenseLimits;          // 限制配置

  // 绑定信息
  bindings: LicenseBindings;      // 绑定配置

  // 时间信息
  issuedAt: string;               // 发行日期（ISO 8601）
  expiresAt: string;              // 过期日期（ISO 8601）
  gracePeriodDays?: number;       // 宽限期天数

  // 元数据
  metadata?: Record<string, any>; // 自定义元数据
}
```

## 🤝 贡献

欢迎提交 Issue 和 Pull Request！

1. Fork 本仓库
2. 创建特性分支 (`git checkout -b feature/AmazingFeature`)
3. 提交更改 (`git commit -m 'Add some AmazingFeature'`)
4. 推送到分支 (`git push origin feature/AmazingFeature`)
5. 提交 Pull Request

## 📝 许可证

MIT License - 详见 [LICENSE](LICENSE) 文件

## 📧 联系方式

- 📧 Email: support@example.com
- 🐛 Issues: https://github.com/flowerjunjie/license-manager/issues
- 📚 文档: https://docs.example.com/license-manager

## ⭐ Star History

如果这个项目对您有帮助，请给我们一个 Star ⭐

---

<div align="center">

Made with ❤️ by License Manager Team

[⬆ 返回顶部](#license-manager)

</div>
