🎉 init: 小龙的工作空间
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "@network-tool/shared-crypto",
|
||||
"version": "0.1.0",
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"dev": "tsc --watch"
|
||||
},
|
||||
"dependencies": {
|
||||
"bcryptjs": "^2.4.3",
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
"uuid": "^9.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bcryptjs": "^2.4.6",
|
||||
"@types/jsonwebtoken": "^9.0.5",
|
||||
"@types/uuid": "^9.0.7",
|
||||
"typescript": "^5.4.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
import bcrypt from 'bcryptjs';
|
||||
import jwt from 'jsonwebtoken';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import crypto from 'crypto';
|
||||
|
||||
// ============================================================
|
||||
// 密码哈希
|
||||
// ============================================================
|
||||
|
||||
const SALT_ROUNDS = 10;
|
||||
|
||||
export function hashPassword(password: string): Promise<string> {
|
||||
return bcrypt.hash(password, SALT_ROUNDS);
|
||||
}
|
||||
|
||||
export function verifyPassword(password: string, hash: string): Promise<boolean> {
|
||||
return bcrypt.compare(password, hash);
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// JWT
|
||||
// ============================================================
|
||||
|
||||
export interface JwtPayload {
|
||||
user_id: number;
|
||||
email: string;
|
||||
role: string;
|
||||
}
|
||||
|
||||
export function generateToken(payload: JwtPayload, secret: string, expiresIn: string | number = '24h'): string {
|
||||
return jwt.sign(payload, secret, { expiresIn: expiresIn as any });
|
||||
}
|
||||
|
||||
export function verifyToken(token: string, secret: string): JwtPayload | null {
|
||||
try {
|
||||
return jwt.verify(token, secret) as JwtPayload;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// 连接 Token(用于客户端-节点验证)
|
||||
// ============================================================
|
||||
|
||||
export interface ConnectionTokenPayload {
|
||||
user_id: number;
|
||||
device_id: number;
|
||||
node_id: number;
|
||||
nonce: string;
|
||||
}
|
||||
|
||||
export function generateConnectionToken(
|
||||
payload: ConnectionTokenPayload,
|
||||
secret: string,
|
||||
expiresIn: string | number = '5m'
|
||||
): string {
|
||||
return jwt.sign(payload, secret, { expiresIn: expiresIn as any });
|
||||
}
|
||||
|
||||
export function verifyConnectionToken(
|
||||
token: string,
|
||||
secret: string
|
||||
): ConnectionTokenPayload | null {
|
||||
try {
|
||||
return jwt.verify(token, secret) as ConnectionTokenPayload;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// 哈希 & ID 生成
|
||||
// ============================================================
|
||||
|
||||
export function sha256(data: string): string {
|
||||
return crypto.createHash('sha256').update(data).digest('hex');
|
||||
}
|
||||
|
||||
export function generateDeviceFingerprint(seed?: string): string {
|
||||
return sha256(seed || uuidv4());
|
||||
}
|
||||
|
||||
export function generateMessageId(): string {
|
||||
return uuidv4();
|
||||
}
|
||||
|
||||
export function generateNonce(): string {
|
||||
return crypto.randomBytes(16).toString('hex');
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"module": "commonjs",
|
||||
"declaration": true,
|
||||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
Reference in New Issue
Block a user