UNPKG

recoder-code

Version:

Complete AI-powered development platform with ML model training, plugin registry, real-time collaboration, monitoring, infrastructure automation, and enterprise deployment capabilities

260 lines 9.64 kB
"use strict"; /** * ApiKey Entity * Manages API keys for authentication and access control */ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ApiKey = exports.ApiKeyStatus = exports.ApiKeyScope = void 0; const typeorm_1 = require("typeorm"); const User_1 = require("./User"); var ApiKeyScope; (function (ApiKeyScope) { ApiKeyScope["READ"] = "read"; ApiKeyScope["WRITE"] = "write"; ApiKeyScope["ADMIN"] = "admin"; ApiKeyScope["PUBLISH"] = "publish"; ApiKeyScope["UNPUBLISH"] = "unpublish"; ApiKeyScope["DEPRECATE"] = "deprecate"; })(ApiKeyScope = exports.ApiKeyScope || (exports.ApiKeyScope = {})); var ApiKeyStatus; (function (ApiKeyStatus) { ApiKeyStatus["ACTIVE"] = "active"; ApiKeyStatus["REVOKED"] = "revoked"; ApiKeyStatus["EXPIRED"] = "expired"; ApiKeyStatus["SUSPENDED"] = "suspended"; })(ApiKeyStatus = exports.ApiKeyStatus || (exports.ApiKeyStatus = {})); let ApiKey = class ApiKey { // Methods static generateKey() { const crypto = require('crypto'); // Generate a secure random key const key = 'rck_' + crypto.randomBytes(32).toString('hex'); // Hash the key for storage const hash = crypto.createHash('sha256').update(key).digest('hex'); // Get prefix for display const prefix = key.substring(0, 12) + '...'; return { key, hash, prefix }; } static hashKey(key) { const crypto = require('crypto'); return crypto.createHash('sha256').update(key).digest('hex'); } hasScope(scope) { return this.scopes.includes(scope) || this.scopes.includes(ApiKeyScope.ADMIN); } hasScopes(scopes) { if (this.scopes.includes(ApiKeyScope.ADMIN)) return true; return scopes.every(scope => this.scopes.includes(scope)); } isExpired() { if (!this.expires_at) return false; return new Date() > this.expires_at; } isActive() { return this.status === ApiKeyStatus.ACTIVE && !this.isExpired(); } canAccessPackage(packageName) { if (!this.restrictions?.package_patterns) return true; return this.restrictions.package_patterns.some(pattern => { // Simple glob pattern matching const regex = new RegExp(pattern.replace(/\*/g, '.*')); return regex.test(packageName); }); } isIpAllowed(ip) { if (!this.restrictions?.ip_whitelist) return true; return this.restrictions.ip_whitelist.includes(ip); } recordUsage(ip) { this.last_used = new Date(); this.usage_count += 1; if (ip) { this.last_used_ip = ip; } // Update daily usage stats const today = new Date().toISOString().split('T')[0]; if (!this.usage_stats) { this.usage_stats = { daily_usage: {}, weekly_usage: {}, monthly_usage: {} }; } this.usage_stats.daily_usage[today] = (this.usage_stats.daily_usage[today] || 0) + 1; } revoke(reason) { this.status = ApiKeyStatus.REVOKED; this.revoked_at = new Date(); this.revocation_reason = reason; } suspend() { this.status = ApiKeyStatus.SUSPENDED; } activate() { this.status = ApiKeyStatus.ACTIVE; this.revoked_at = undefined; this.revocation_reason = undefined; } extend(newExpiryDate) { this.expires_at = newExpiryDate; } addScope(scope) { if (!this.scopes.includes(scope)) { this.scopes.push(scope); } } removeScope(scope) { this.scopes = this.scopes.filter(s => s !== scope); } setRestrictions(restrictions) { this.restrictions = restrictions; } getDailyUsage(days = 30) { if (!this.usage_stats?.daily_usage) return {}; const result = {}; const today = new Date(); for (let i = 0; i < days; i++) { const date = new Date(today); date.setDate(date.getDate() - i); const dateStr = date.toISOString().split('T')[0]; result[dateStr] = this.usage_stats.daily_usage[dateStr] || 0; } return result; } isRateLimited() { if (!this.restrictions?.rate_limit) return false; const { requests, window } = this.restrictions.rate_limit; const windowStart = new Date(Date.now() - window * 1000); // In a real implementation, this would check against a rate limiting store // For now, we'll use a simple time-based check const recentUsage = this.getDailyUsage(1); const todayUsage = Object.values(recentUsage)[0] || 0; return todayUsage >= requests; } toSafeFormat() { return { id: this.id, name: this.name, key_prefix: this.key_prefix, scopes: this.scopes, status: this.status, description: this.description, restrictions: this.restrictions, expires_at: this.expires_at, last_used: this.last_used, usage_count: this.usage_count, created_at: this.created_at, is_expired: this.isExpired(), is_active: this.isActive() }; } toDetailedFormat() { return { ...this.toSafeFormat(), last_used_ip: this.last_used_ip, usage_stats: this.usage_stats, revoked_at: this.revoked_at, revocation_reason: this.revocation_reason }; } }; __decorate([ (0, typeorm_1.PrimaryGeneratedColumn)('uuid'), __metadata("design:type", String) ], ApiKey.prototype, "id", void 0); __decorate([ (0, typeorm_1.Column)({ type: 'varchar', length: 255 }), __metadata("design:type", String) ], ApiKey.prototype, "name", void 0); __decorate([ (0, typeorm_1.Column)({ type: 'varchar', length: 255, unique: true }), __metadata("design:type", String) ], ApiKey.prototype, "key_hash", void 0); __decorate([ (0, typeorm_1.Column)({ type: 'varchar', length: 100 }), __metadata("design:type", String) ], ApiKey.prototype, "key_prefix", void 0); __decorate([ (0, typeorm_1.Column)({ type: 'json' }), __metadata("design:type", Array) ], ApiKey.prototype, "scopes", void 0); __decorate([ (0, typeorm_1.Column)({ type: 'enum', enum: ApiKeyStatus, default: ApiKeyStatus.ACTIVE }), __metadata("design:type", String) ], ApiKey.prototype, "status", void 0); __decorate([ (0, typeorm_1.Column)({ type: 'text', nullable: true }), __metadata("design:type", String) ], ApiKey.prototype, "description", void 0); __decorate([ (0, typeorm_1.Column)({ type: 'json', nullable: true }), __metadata("design:type", Object) ], ApiKey.prototype, "restrictions", void 0); __decorate([ (0, typeorm_1.Column)({ type: 'timestamp', nullable: true }), __metadata("design:type", Date) ], ApiKey.prototype, "expires_at", void 0); __decorate([ (0, typeorm_1.Column)({ type: 'timestamp', nullable: true }), __metadata("design:type", Date) ], ApiKey.prototype, "last_used", void 0); __decorate([ (0, typeorm_1.Column)({ type: 'varchar', length: 45, nullable: true }), __metadata("design:type", String) ], ApiKey.prototype, "last_used_ip", void 0); __decorate([ (0, typeorm_1.Column)({ type: 'int', default: 0 }), __metadata("design:type", Number) ], ApiKey.prototype, "usage_count", void 0); __decorate([ (0, typeorm_1.Column)({ type: 'json', nullable: true }), __metadata("design:type", Object) ], ApiKey.prototype, "usage_stats", void 0); __decorate([ (0, typeorm_1.CreateDateColumn)(), __metadata("design:type", Date) ], ApiKey.prototype, "created_at", void 0); __decorate([ (0, typeorm_1.UpdateDateColumn)(), __metadata("design:type", Date) ], ApiKey.prototype, "updated_at", void 0); __decorate([ (0, typeorm_1.Column)({ type: 'timestamp', nullable: true }), __metadata("design:type", Date) ], ApiKey.prototype, "revoked_at", void 0); __decorate([ (0, typeorm_1.Column)({ type: 'text', nullable: true }), __metadata("design:type", String) ], ApiKey.prototype, "revocation_reason", void 0); __decorate([ (0, typeorm_1.ManyToOne)(() => User_1.User, user => user.api_keys, { onDelete: 'CASCADE' }), __metadata("design:type", User_1.User) ], ApiKey.prototype, "user", void 0); __decorate([ (0, typeorm_1.Column)({ type: 'uuid' }), __metadata("design:type", String) ], ApiKey.prototype, "user_id", void 0); ApiKey = __decorate([ (0, typeorm_1.Entity)('api_keys'), (0, typeorm_1.Index)(['key_hash'], { unique: true }), (0, typeorm_1.Index)(['user_id']), (0, typeorm_1.Index)(['status']), (0, typeorm_1.Index)(['expires_at']) ], ApiKey); exports.ApiKey = ApiKey; //# sourceMappingURL=ApiKey.js.map