Files
MeBox/web/src/api/license.ts
T
ShukeBta 9be81222cc fix: 修复三个空白页面 + 许可证页面重构
- 修复发现页空白:后端 discover.go nil→[] Match,前端 discover.ts 加 ?? []
- 修复下载客户端页空白:后端 download_clients.go nil→[]model.DownloadClient,前端加 ?? []
- 修复通知渠道页空白:后端 notify_channels.go nil→[]struct{},前端加 ?? []
- 许可证页面重构:移除生成密钥功能,对接 LicenseServer 绑定/状态模式
- 所有变更通过 Go build + npm run build 零错误验证
2026-05-17 00:54:40 +08:00

60 lines
1.7 KiB
TypeScript

import { api } from './client'
// ── License Server types (generic, ready for MediaStationLicenseServer integration) ──
/** Response after binding/activating a license. */
export interface LicenseActivation {
id: string
key_id: string
/** The license key string (e.g. MS-XXXX-XXXX-XXXX) */
key?: string
device_id: string
device_name?: string
plan?: string
max_activations?: number
/** ISO8601 — null means perpetual */
expires_at?: string | null
valid: boolean
ip?: string
heartbeat_at?: string | null
created_at: string
}
/** Status of the currently bound license on this device. */
export interface LicenseStatus {
/** Whether a license is currently active */
active: boolean
activation?: LicenseActivation
/** Error or status message */
message?: string
}
/** Generate a short device fingerprint from browser/OS info. */
function deviceFingerprint(): string {
const nav = window.navigator
const parts = [nav.hardwareConcurrency, nav.language, screen.width, screen.height]
return btoa(parts.join('|')).slice(0, 32).replace(/[+/=]/g, '')
}
// ── API methods ──
export const licenseAPI = {
/** Bind / activate a license key for this device. */
bind: (key: string) =>
api
.post<LicenseActivation>('/license/activate', {
key: key.trim(),
device_id: deviceFingerprint(),
device_name: navigator.platform || 'Web Client',
})
.then((r) => r.data),
/** Get the status of the currently active license. */
status: () =>
api.get<LicenseStatus>('/license/status').then((r) => r.data),
/** Refresh the heartbeat for the active license. */
heartbeat: () =>
api.post('/license/heartbeat').then((r) => r.data),
}