Files
LingChair/server/api/FileTokenManager.ts
2025-09-23 23:29:20 +08:00

56 lines
1.7 KiB
TypeScript

import { Buffer } from "node:buffer"
import config from "../config.ts"
import User from "../data/User.ts"
import crypto from 'node:crypto'
import Token from "./Token.ts"
function normalizeKey(key: string, keyLength = 32) {
const hash = crypto.createHash('sha256')
hash.update(key)
const keyBuffer = hash.digest()
return keyLength ? keyBuffer.slice(0, keyLength) : keyBuffer
}
export default class FileTokenManager {
static makeAuth(user: User) {
return crypto.createHash("sha256").update(user.bean.id + user.getPassword() + config.salt + '_file').digest().toString('hex')
}
static encode(token: Token) {
return crypto.createCipheriv("aes-256-gcm", normalizeKey(config.aes_key + '_file'), '01234567890123456').update(
JSON.stringify(token)
).toString('hex')
}
static decode(token: string) {
if (token == null) throw new Error('令牌為空!')
return JSON.parse(crypto.createDecipheriv("aes-256-gcm", normalizeKey(config.aes_key + '_file'), '01234567890123456').update(
Buffer.from(token, 'hex')
).toString()) as Token
}
/**
* 簽發文件令牌
*/
static make(user: User, device_id: string) {
const time = Date.now()
return this.encode({
author: user.bean.id,
auth: this.makeAuth(user),
made_time: time,
// 過期時間: 2分鐘
expired_time: time + (1 * 1000 * 60 * 2),
device_id: device_id
})
}
/**
* 校驗文件令牌
*/
static check(user: User, token: string) {
const tk = this.decode(token)
return (
this.makeAuth(user) == tk.auth
&& tk.expired_time < Date.now()
)
}
}