Some checks failed
CI/CD Pipeline / Solidity Contracts (push) Failing after 1m18s
CI/CD Pipeline / Security Scanning (push) Successful in 2m34s
CI/CD Pipeline / Lint and Format (push) Failing after 54s
CI/CD Pipeline / Terraform Validation (push) Failing after 27s
CI/CD Pipeline / Kubernetes Validation (push) Successful in 28s
Deploy ChainID 138 / Deploy ChainID 138 (push) Failing after 39s
HYBX OMNL TypeScript & anchor / token-aggregation build + reconcile artifact (push) Failing after 31s
Validation / validate-genesis (push) Successful in 28s
Validation / validate-terraform (push) Failing after 31s
Validation / validate-kubernetes (push) Failing after 11s
Validation / validate-smart-contracts (push) Failing after 11s
Validation / validate-security (push) Failing after 1m27s
Validation / validate-documentation (push) Failing after 21s
Verify Deployment / Verify Deployment (push) Has been cancelled
Co-authored-by: Cursor <cursoragent@cursor.com>
129 lines
4.9 KiB
JavaScript
129 lines
4.9 KiB
JavaScript
"use strict";
|
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.loadSuperAdminRegistry = loadSuperAdminRegistry;
|
|
exports.extractApiKey = extractApiKey;
|
|
exports.loadCustomerSecurityPolicy = loadCustomerSecurityPolicy;
|
|
exports.resolveOmnlPrincipal = resolveOmnlPrincipal;
|
|
exports.principalHasScope = principalHasScope;
|
|
exports.isProductionSecurityMode = isProductionSecurityMode;
|
|
const fs_1 = __importDefault(require("fs"));
|
|
const path_1 = __importDefault(require("path"));
|
|
let superAdminCache = null;
|
|
function repoRoot() {
|
|
return process.env.OMNL_BANK_ROOT || process.env.REPO_ROOT || process.cwd();
|
|
}
|
|
function loadSuperAdminRegistry() {
|
|
if (superAdminCache)
|
|
return superAdminCache;
|
|
const configPath = process.env.OMNL_SUPER_ADMINS_CONFIG ||
|
|
path_1.default.join(repoRoot(), 'config/omnl-super-admins.v1.json');
|
|
try {
|
|
const raw = JSON.parse(fs_1.default.readFileSync(configPath, 'utf8'));
|
|
superAdminCache = raw.superAdmins ?? [];
|
|
}
|
|
catch {
|
|
superAdminCache = [];
|
|
}
|
|
return superAdminCache;
|
|
}
|
|
function extractApiKey(req) {
|
|
const auth = String(req.headers.authorization || '');
|
|
const bearer = auth.startsWith('Bearer ') ? auth.slice(7).trim() : '';
|
|
const headerKey = String(req.headers['x-api-key'] ?? '').trim();
|
|
const q = String(req.query?.access_token ?? '').trim();
|
|
return bearer || headerKey || q || undefined;
|
|
}
|
|
function customerKeys() {
|
|
const map = new Map();
|
|
const policy = loadCustomerSecurityPolicy();
|
|
const scopes = policy.customerAllowedScopes;
|
|
const raw = process.env.OMNL_CUSTOMER_API_KEYS?.trim();
|
|
if (raw) {
|
|
for (const part of raw.split(',').map((s) => s.trim()).filter(Boolean)) {
|
|
const [key, scopeList] = part.split(':');
|
|
if (!key)
|
|
continue;
|
|
map.set(key.trim(), scopeList ? scopeList.split('|').map((s) => s.trim()).filter(Boolean) : scopes);
|
|
}
|
|
}
|
|
for (const envKey of ['OMNL_CUSTOMER_API_KEY_1', 'OMNL_CUSTOMER_API_KEY_2', 'OMNL_CUSTOMER_API_KEY_3']) {
|
|
const val = process.env[envKey]?.trim();
|
|
if (val)
|
|
map.set(val, scopes);
|
|
}
|
|
return map;
|
|
}
|
|
function loadCustomerSecurityPolicy() {
|
|
const configPath = process.env.OMNL_CUSTOMER_SECURITY_CONFIG ||
|
|
path_1.default.join(repoRoot(), 'config/omnl-customer-security.production.v1.json');
|
|
try {
|
|
return JSON.parse(fs_1.default.readFileSync(configPath, 'utf8'));
|
|
}
|
|
catch {
|
|
return {
|
|
version: '1.0.0',
|
|
production: true,
|
|
neverExposeOperatorKeyInBrowser: true,
|
|
portalInjectAuthViaNginx: true,
|
|
requireApiKeyAllExchangeRoutes: true,
|
|
customerAllowedScopes: ['read', 'trade'],
|
|
superAdminOnlyScopes: ['settle', 'token_load', 'transfer', 'admin'],
|
|
rateLimits: { customerPerMinute: 30, superAdminPerMinute: 120, anonymousPerMinute: 0 },
|
|
corsOrigins: [],
|
|
};
|
|
}
|
|
}
|
|
function portalInternalOk(req) {
|
|
const secret = process.env.OMNL_PORTAL_INTERNAL_SECRET?.trim();
|
|
if (!secret)
|
|
return false;
|
|
const header = String(req.headers['x-omnl-portal-auth'] ?? '').trim();
|
|
return header === secret;
|
|
}
|
|
function resolveOmnlPrincipal(req, key) {
|
|
if (portalInternalOk(req)) {
|
|
return { role: 'portal_internal', scopes: ['read', 'trade', 'settle', 'token_load', 'transfer', 'admin'] };
|
|
}
|
|
const apiKey = key ?? extractApiKey(req);
|
|
if (!apiKey)
|
|
return null;
|
|
const legacy = process.env.OMNL_API_KEY?.trim();
|
|
if (legacy && apiKey === legacy) {
|
|
return { role: 'legacy_operator', scopes: ['read', 'trade', 'settle', 'token_load', 'transfer', 'admin'] };
|
|
}
|
|
for (const admin of loadSuperAdminRegistry()) {
|
|
const adminKey = process.env[admin.envKey]?.trim();
|
|
if (adminKey && apiKey === adminKey) {
|
|
return {
|
|
role: 'super_admin',
|
|
adminId: admin.id,
|
|
portalCtid: admin.portalCtid,
|
|
scopes: ['read', 'trade', 'settle', 'token_load', 'transfer', 'admin'],
|
|
};
|
|
}
|
|
}
|
|
const customers = customerKeys();
|
|
const customerScopes = customers.get(apiKey);
|
|
if (customerScopes) {
|
|
return { role: 'customer', scopes: customerScopes };
|
|
}
|
|
return null;
|
|
}
|
|
function principalHasScope(principal, scope) {
|
|
if (!principal)
|
|
return false;
|
|
if (principal.role === 'super_admin' || principal.role === 'legacy_operator' || principal.role === 'portal_internal') {
|
|
return true;
|
|
}
|
|
return (principal.scopes ?? []).includes(scope);
|
|
}
|
|
function isProductionSecurityMode() {
|
|
const policy = loadCustomerSecurityPolicy();
|
|
return (policy.production ||
|
|
process.env.OMNL_CUSTOMER_SECURITY_PRODUCTION === '1' ||
|
|
(process.env.NODE_ENV || '').toLowerCase() === 'production');
|
|
}
|