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
JavaScript
"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