grabbit 13ce6ae442 feat: implement complete edge device registration system
- Add hardware fingerprinting with cross-platform support
- Implement secure device registration flow with X.509 certificates
- Add WebSocket real-time communication for device status
- Create comprehensive device management dashboard
- Establish zero-trust security architecture with multi-layer protection
- Add database migrations for device registration entities
- Implement Rust edge client with hardware identification
- Add certificate management and automated provisioning system

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-13 08:46:25 +08:00

129 lines
3.1 KiB
TypeScript

import {
Entity,
PrimaryGeneratedColumn,
Column,
ManyToOne,
JoinColumn,
CreateDateColumn,
UpdateDateColumn,
Index,
} from 'typeorm';
import { Device } from './device.entity';
export enum CertificateStatus {
ACTIVE = 'active',
REVOKED = 'revoked',
EXPIRED = 'expired',
PENDING = 'pending',
}
export enum CertificateType {
DEVICE = 'device',
USER = 'user',
INTERMEDIATE = 'intermediate',
ROOT = 'root',
}
@Entity('device_certificates')
@Index(['deviceId'])
@Index(['status'])
@Index(['expiresAt'])
@Index(['serialNumber'], { unique: true })
@Index(['fingerprint'], { unique: true })
export class DeviceCertificate {
@PrimaryGeneratedColumn('uuid')
id: string;
@Column({ name: 'device_id' })
deviceId: string;
@ManyToOne(() => Device, { onDelete: 'CASCADE' })
@JoinColumn({ name: 'device_id' })
device: Device;
@Column({ name: 'serial_number', type: 'varchar', length: 100, unique: true })
serialNumber: string;
@Column({ name: 'fingerprint', type: 'varchar', length: 128, unique: true })
fingerprint: string;
@Column({
name: 'certificate_type',
type: 'enum',
enum: CertificateType,
default: CertificateType.DEVICE,
})
certificateType: CertificateType;
@Column({
name: 'status',
type: 'enum',
enum: CertificateStatus,
default: CertificateStatus.ACTIVE,
})
status: CertificateStatus;
@Column({ name: 'subject_dn', type: 'text' })
subjectDn: string;
@Column({ name: 'issuer_dn', type: 'text' })
issuerDn: string;
@Column({ name: 'certificate_pem', type: 'text' })
certificatePem: string;
@Column({ name: 'private_key_pem', type: 'text', nullable: true })
privateKeyPem?: string;
@Column({ name: 'public_key_pem', type: 'text' })
publicKeyPem: string;
@Column({ name: 'key_algorithm', type: 'varchar', length: 50 })
keyAlgorithm: string;
@Column({ name: 'key_size', type: 'int' })
keySize: number;
@Column({ name: 'signature_algorithm', type: 'varchar', length: 50 })
signatureAlgorithm: string;
@Column({ name: 'issued_at', type: 'timestamptz' })
issuedAt: Date;
@Column({ name: 'expires_at', type: 'timestamptz' })
expiresAt: Date;
@Column({ name: 'revoked_at', type: 'timestamptz', nullable: true })
revokedAt?: Date;
@Column({ name: 'revocation_reason', type: 'varchar', length: 100, nullable: true })
revocationReason?: string;
@Column({ name: 'x509_extensions', type: 'jsonb', nullable: true })
x509Extensions?: {
key_usage: string[];
extended_key_usage: string[];
subject_alt_name?: string[];
basic_constraints?: {
ca: boolean;
path_len_constraint?: number;
};
authority_key_identifier?: string;
subject_key_identifier?: string;
};
@Column({ name: 'usage_count', type: 'bigint', default: 0 })
usageCount: number;
@Column({ name: 'last_used_at', type: 'timestamptz', nullable: true })
lastUsedAt?: Date;
@Column({ name: 'renewal_notified_at', type: 'timestamptz', nullable: true })
renewalNotifiedAt?: Date;
@CreateDateColumn({ name: 'created_at', type: 'timestamptz' })
createdAt: Date;
@UpdateDateColumn({ name: 'updated_at', type: 'timestamptz' })
updatedAt: Date;
}