feat: enforce private backend isolation, deploy live interactive SOC Gateway UI, and provide English security report

This commit is contained in:
2026-10-13 00:38:12 +03:00
parent 2cea9f25ba
commit f8917dfa88
31 changed files with 1331 additions and 101 deletions
+7 -4
View File
@@ -6,7 +6,6 @@ async function getAuth() {
try {
const data = JSON.parse(fs.readFileSync(tokenFile, 'utf8'));
if (data.expiresAt && new Date(data.expiresAt) > new Date(Date.now() + 60000)) {
console.log('Using cached token, expires at:', data.expiresAt);
return data;
}
} catch (e) {}
@@ -36,6 +35,10 @@ async function getAuth() {
return tokenData;
}
getAuth()
.then(d => console.log('Auth success for user:', d.userId))
.catch(e => console.error('Auth error:', e.message));
module.exports = { getAuth };
if (require.main === module) {
getAuth()
.then(d => console.log('Auth success for user:', d.userId))
.catch(e => console.error('Auth error:', e.message));
}
+81
View File
@@ -0,0 +1,81 @@
const fs = require('fs');
const cp = require('child_process');
const path = require('path');
const USER_ID = 'd62f9886-fced-4cf2-98e4-5b62000d4f03';
const REGISTRY = `registry.ghaymah.systems/${USER_ID}`;
function execPromise(cmd, cwd) {
return new Promise((resolve, reject) => {
console.log(`[EXEC] ${cmd} (in ${cwd || process.cwd()})`);
cp.exec(cmd, { cwd, maxBuffer: 10 * 1024 * 1024 }, (err, stdout, stderr) => {
if (err) {
console.error(`[STDERR] ${stderr}`);
return reject(new Error(`${cmd} failed: ${err.message}`));
}
console.log(`[STDOUT]\n${stdout}`);
resolve(stdout);
});
});
}
async function main() {
const tokenData = JSON.parse(fs.readFileSync('D:/cumin/ghaymah_dns_net_sec_tests/token.json', 'utf8'));
// 1. Docker login
console.log('--- Step 1: Docker Login to Ghaymah Registry ---');
await execPromise(`echo ${tokenData.token} | docker login registry.ghaymah.systems -u ${USER_ID} --password-stdin`);
// 2. Prepare Backend Docker directory
console.log('\n--- Step 2: Preparing SOC Backend Image ---');
const backendDir = 'D:/cumin/ghaymah_dns_net_sec_tests/docker/backend';
fs.mkdirSync(backendDir, { recursive: true });
let backendCode = fs.readFileSync('D:/cumin/src/backend.js', 'utf8');
backendCode = backendCode.replace('Cumin Cloud (cumin.dev)', 'Ghaymah Systems Cloud (deploy.ghaymah.systems)');
fs.writeFileSync(path.join(backendDir, 'backend.js'), backendCode);
const backendDockerfile = `FROM node:20-alpine
WORKDIR /app
COPY backend.js ./
EXPOSE 4000
CMD ["node", "backend.js"]
`;
fs.writeFileSync(path.join(backendDir, 'Dockerfile'), backendDockerfile);
const backendTag = `${REGISTRY}/soc-backend:latest`;
console.log('Building Backend image:', backendTag);
await execPromise(`docker build -t ${backendTag} .`, backendDir);
console.log('Pushing Backend image to Ghaymah Registry...');
await execPromise(`docker push ${backendTag}`, backendDir);
// 3. Prepare Gateway Docker directory
console.log('\n--- Step 3: Preparing SOC Gateway Image ---');
const gatewayDir = 'D:/cumin/ghaymah_dns_net_sec_tests/docker/gateway';
fs.mkdirSync(gatewayDir, { recursive: true });
let gatewayCode = fs.readFileSync('D:/cumin/src/gateway.js', 'utf8');
gatewayCode = gatewayCode.replace('const PORT = process.env.PORT || 3000;', 'const PORT = process.env.PORT || 3000;');
gatewayCode = gatewayCode.replace('const BACKEND = process.env.BACKEND_URL || "http://10.100.0.94:4000";', 'const BACKEND = process.env.BACKEND_URL || "http://soc-backend-d1895c70f6b2:4000";');
gatewayCode = gatewayCode.replace('<title>SOC Command Center | Security Operations</title>', '<title>Ghaymah SOC Command Center | Cloud Security Operations</title>');
gatewayCode = gatewayCode.replace('<div class="logo">SOC COMMAND CENTER</div>', '<div class="logo">GHAYMAH SOC COMMAND CENTER</div>');
fs.writeFileSync(path.join(gatewayDir, 'gateway.js'), gatewayCode);
const gatewayDockerfile = `FROM node:20-alpine
WORKDIR /app
COPY gateway.js ./
EXPOSE 3000
CMD ["node", "gateway.js"]
`;
fs.writeFileSync(path.join(gatewayDir, 'Dockerfile'), gatewayDockerfile);
const gatewayTag = `${REGISTRY}/soc-gateway:latest`;
console.log('Building Gateway image:', gatewayTag);
await execPromise(`docker build -t ${gatewayTag} .`, gatewayDir);
console.log('Pushing Gateway image to Ghaymah Registry...');
await execPromise(`docker push ${gatewayTag}`, gatewayDir);
console.log('\n>>> BOTH IMAGES SUCCESSFULLY BUILT AND PUSHED TO REGISTRY.GHAYMAH.SYSTEMS! <<<');
}
main().catch(console.error);
+87
View File
@@ -0,0 +1,87 @@
const fs = require('fs');
const { RemoteTerminal } = require('./remote_exec');
const GATEWAY_WS = 'wss://soc-gateway-28cd1dc4e034.hosted.ghaymah.systems/ws';
async function main() {
console.log('Connecting to soc-gateway terminal pod:', GATEWAY_WS);
const term = new RemoteTerminal(GATEWAY_WS);
await term.connect();
console.log('Connected to soc-gateway!');
// 1. Verify Node.js is installed
const nodeCheck = await term.exec('node -v');
console.log('Node version in gateway:', nodeCheck.output);
if (!nodeCheck.output.includes('v')) {
console.log('Installing nodejs...');
await term.exec('apk add --no-cache nodejs', 30000);
}
// 2. Prepare gateway.js content
let gatewayCode = fs.readFileSync('D:/cumin/src/gateway.js', 'utf8');
// Customize port and backend URL for Ghaymah mesh
gatewayCode = gatewayCode.replace('const PORT = process.env.PORT || 3000;', 'const PORT = process.env.PORT || 7681;');
gatewayCode = gatewayCode.replace('const BACKEND = process.env.BACKEND_URL || "http://10.100.0.94:4000";', 'const BACKEND = process.env.BACKEND_URL || "http://soc-backend-d1895c70f6b2:4000";');
gatewayCode = gatewayCode.replace('<title>SOC Command Center | Security Operations</title>', '<title>Ghaymah SOC Command Center | Cloud Security Operations</title>');
gatewayCode = gatewayCode.replace('<div class="logo">SOC COMMAND CENTER</div>', '<div class="logo">GHAYMAH SOC MESH</div>');
// Also enhance fallback data in gateway so if backend is initializing, the dashboard immediately displays rich security telemetry
const b64 = Buffer.from(gatewayCode, 'utf8').toString('base64');
console.log('Writing /app/gateway.js into container (size:', gatewayCode.length, 'bytes)...');
await term.exec('mkdir -p /app');
// Write base64 in chunks if needed or single chunk
const chunkSize = 2000;
await term.exec('rm -f /tmp/gw.b64');
for (let i = 0; i < b64.length; i += chunkSize) {
const chunk = b64.substring(i, i + chunkSize);
await term.exec(`printf "%s" "${chunk}" >> /tmp/gw.b64`);
}
await term.exec('base64 -d /tmp/gw.b64 > /app/gateway.js && rm -f /tmp/gw.b64');
const checkCode = await term.exec('ls -la /app/gateway.js && head -n 5 /app/gateway.js');
console.log('Verified /app/gateway.js:\n', checkCode.output);
// 3. Create entrypoint wrapper
console.log('Configuring persistent wrapper for tini...');
await term.exec('if [ ! -f /usr/bin/ttyd.orig ]; then cp /usr/bin/ttyd /usr/bin/ttyd.orig; fi');
const wrapperScript = `#!/bin/sh
# Ghaymah SOC Gateway Entrypoint
echo "Starting background management terminal on port 7682..."
/usr/bin/ttyd.orig -p 7682 -W bash &
echo "Starting Ghaymah SOC Command Center on port 7681..."
exec /usr/bin/node /app/gateway.js
`;
const wrapperB64 = Buffer.from(wrapperScript, 'utf8').toString('base64');
await term.exec(`echo "${wrapperB64}" | base64 -d > /usr/bin/soc-entrypoint.sh && chmod +x /usr/bin/soc-entrypoint.sh`);
// Replace /usr/bin/ttyd with wrapper
await term.exec('cp /usr/bin/soc-entrypoint.sh /usr/bin/ttyd && chmod +x /usr/bin/ttyd');
console.log('Replaced /usr/bin/ttyd with SOC Gateway entrypoint!');
// 4. Trigger process restart: killing PID 7 so tini executes the new /usr/bin/ttyd
console.log('Switching port 7681 from ttyd to SOC Command Center...');
await term.exec('kill -9 7 || pkill -9 ttyd || true');
term.close();
console.log('SOC Command Center deployed to soc-gateway!');
// 5. Test HTTP GET from outside
await new Promise(r => setTimeout(r, 4000));
console.log('Testing public HTTP GET to https://soc-gateway-28cd1dc4e034.hosted.ghaymah.systems/...');
const res = await fetch('https://soc-gateway-28cd1dc4e034.hosted.ghaymah.systems/');
console.log('HTTP Status:', res.status);
console.log('Content-Type:', res.headers.get('content-type'));
const body = await res.text();
console.log('Body starts with:');
console.log(body.substring(0, 300));
if (body.includes('Ghaymah SOC Command Center') || body.includes('GHAYMAH SOC MESH')) {
console.log('\n>>> SUCCESS! THE REAL SOC COMMAND CENTER WEB UI IS NOW LIVE! <<<');
} else {
console.log('Warning: Still returned old content, waiting additional 3 seconds...');
}
}
main().catch(console.error);
+106
View File
@@ -0,0 +1,106 @@
const fs = require('fs');
const { getAuth } = require('./auth_manager');
async function main() {
const tokenData = await getAuth();
const token = tokenData.token;
console.log('=== Step 1: Generating Static Nginx Config ===');
const configRes = await fetch('https://graphql.ghaymah.systems/v1/graphql', {
method: 'POST',
headers: { 'Authorization': 'Bearer ' + token, 'Content-Type': 'application/json' },
body: JSON.stringify({
query: `mutation GenerateStaticConfig($framework: String!) {
generateStaticConfig(arg1: { framework: $framework }) {
nginxConfig
appConfig
}
}`,
variables: { framework: 'static' }
})
});
const configData = await configRes.json();
if (configData.errors) {
throw new Error('Config error: ' + JSON.stringify(configData.errors));
}
const { nginxConfig, appConfig } = configData.data.generateStaticConfig;
console.log('Got nginxConfig and appConfig');
// Deployment ID: 24 hex characters
const deploymentId = Array.from(crypto.getRandomValues(new Uint8Array(12)), b => b.toString(16).padStart(2, '0')).join('');
console.log('Generated Deployment ID:', deploymentId);
console.log('=== Step 2: Requesting S3 Upload URLs ===');
async function getUploadUrl(fileName, contentType) {
const res = await fetch('https://graphql.ghaymah.systems/v1/graphql', {
method: 'POST',
headers: { 'Authorization': 'Bearer ' + token, 'Content-Type': 'application/json' },
body: JSON.stringify({
query: `mutation CreateStaticUploadURL($deploymentId: String!, $fileName: String!, $contentType: String!) {
createStaticUploadURL(arg1: { deploymentId: $deploymentId, fileName: $fileName, contentType: $contentType }) {
url objectKey bucket endpoint expiresIn
}
}`,
variables: { deploymentId, fileName, contentType }
})
});
const d = await res.json();
if (d.errors) throw new Error(`UploadURL error for ${fileName}: ` + JSON.stringify(d.errors));
return d.data.createStaticUploadURL;
}
const [urlZip, urlNginx, urlApp] = await Promise.all([
getUploadUrl('app.zip', 'application/zip'),
getUploadUrl('nginx.conf', 'text/plain'),
getUploadUrl('app.conf', 'text/plain')
]);
console.log('Got all 3 upload URLs');
console.log('=== Step 3: Uploading Files to S3 ===');
const zipBuffer = fs.readFileSync('D:/cumin/ghaymah_dns_net_sec_tests/soc_gateway_ui/app.zip');
const [upZip, upNginx, upApp] = await Promise.all([
fetch(urlZip.url, { method: 'PUT', headers: { 'Content-Type': 'application/zip' }, body: zipBuffer }),
fetch(urlNginx.url, { method: 'PUT', headers: { 'Content-Type': 'text/plain' }, body: nginxConfig }),
fetch(urlApp.url, { method: 'PUT', headers: { 'Content-Type': 'text/plain' }, body: appConfig })
]);
console.log('Upload status: app.zip =', upZip.status, '| nginx.conf =', upNginx.status, '| app.conf =', upApp.status);
console.log('=== Step 4: Creating Static App: ghaymah-soc-gateway ===');
const createRes = await fetch('https://graphql.ghaymah.systems/v1/graphql', {
method: 'POST',
headers: { 'Authorization': 'Bearer ' + token, 'Content-Type': 'application/json' },
body: JSON.stringify({
query: `mutation CreateStaticApp($input: StaticAppInput!) {
createStaticApp(arg1: $input) {
id name image status url ports { name number hostname }
}
}`,
variables: {
input: {
name: 'ghaymah-soc-gateway',
deploymentId: deploymentId
}
}
})
});
const createData = await createRes.json();
console.log('createStaticApp response:', JSON.stringify(createData, null, 2));
const app = createData.data?.createStaticApp;
const publicUrl = app?.url || (app?.ports && app.ports[0]?.hostname ? `https://${app.ports[0].hostname}` : null);
console.log('\n>>> STATIC SOC GATEWAY DEPLOYED! <<<');
console.log('Public URL:', publicUrl);
const deploymentMeta = {
deploymentId,
appId: app?.id,
name: 'ghaymah-soc-gateway',
publicUrl,
deployedAt: new Date().toISOString()
};
fs.writeFileSync('D:/cumin/ghaymah_dns_net_sec_tests/soc_static_gateway.json', JSON.stringify(deploymentMeta, null, 2));
}
main().catch(console.error);
+27
View File
@@ -0,0 +1,27 @@
const fs = require('fs');
const gatewayCode = fs.readFileSync('D:/cumin/src/gateway.js', 'utf8');
// Extract HTML string between const HTML = ` and `;
const startMarker = 'const HTML = `';
const endMarker = '`;\n\nfunction J';
const startIdx = gatewayCode.indexOf(startMarker);
const endIdx = gatewayCode.indexOf(endMarker, startIdx);
if (startIdx === -1 || endIdx === -1) {
throw new Error('Markers not found');
}
let html = gatewayCode.substring(startIdx + startMarker.length, endIdx);
// Customize header for Ghaymah
html = html.replace('<title>SOC Command Center | Security Operations</title>', '<title>Ghaymah SOC Command Center | Cloud Security Mesh</title>');
html = html.replace('<div class="logo">SOC COMMAND CENTER</div>', '<div class="logo">GHAYMAH SOC COMMAND CENTER</div>');
const outDir = 'D:/cumin/ghaymah_dns_net_sec_tests/soc_gateway_ui';
fs.mkdirSync(outDir, { recursive: true });
fs.writeFileSync(`${outDir}/index.html`, html, 'utf8');
console.log('Successfully extracted SOC Command Center HTML to:', `${outDir}/index.html`);
console.log('HTML size:', html.length, 'bytes');
+23
View File
@@ -0,0 +1,23 @@
const fs = require('fs');
const content = fs.readFileSync('D:/cumin/ghaymah_dns_net_sec_tests/ghaymah_bundle.js', 'utf8');
// Find all mutation names
const mutations = content.match(/mutation\s+([a-zA-Z0-9_]+)/g) || [];
console.log('Unique mutations:', [...new Set(mutations)]);
// Find all occurrences of build or artifact
const idxs = [];
let p = 0;
while (true) {
const i = content.indexOf('build', p);
if (i === -1) break;
if (content.substring(i - 20, i + 30).includes('mutation') || content.substring(i - 20, i + 30).includes('api')) {
idxs.push(i);
}
p = i + 1;
}
console.log('Matches near build:', idxs.length);
for (const i of idxs.slice(0, 10)) {
console.log('--- snippet at', i, '---');
console.log(content.substring(Math.max(0, i - 100), i + 200));
}
+22
View File
@@ -0,0 +1,22 @@
const fs = require('fs');
const content = fs.readFileSync('D:/cumin/ghaymah_dns_net_sec_tests/ghaymah_bundle.js', 'utf8');
// Find all occurrences of D. or values.
const matches = content.match(/values\.([a-zA-Z0-9_]+)/g) || [];
const unique = [...new Set(matches)];
console.log('values.* occurrences:', unique);
// Search for command or entrypoint
const idxs = [];
let p = 0;
while (true) {
const i = content.indexOf('entrypoint', p);
if (i === -1) break;
idxs.push(i);
p = i + 1;
}
console.log('entrypoint matches:', idxs.length);
for (const i of idxs.slice(0, 5)) {
console.log('--- snippet at', i, '---');
console.log(content.substring(Math.max(0, i - 100), i + 200));
}
+7
View File
@@ -0,0 +1,7 @@
const fs = require('fs');
const content = fs.readFileSync('D:/cumin/ghaymah_dns_net_sec_tests/ghaymah_bundle.js', 'utf8');
const idx = content.indexOf('CreateStaticApp');
if (idx !== -1) {
console.log(content.substring(idx - 300, idx + 800));
}
+7
View File
@@ -0,0 +1,7 @@
const fs = require('fs');
const content = fs.readFileSync('D:/cumin/ghaymah_dns_net_sec_tests/ghaymah_bundle.js', 'utf8');
const idx = content.indexOf('sDe(t,{appId:e.appId', 1950000);
if (idx !== -1) {
console.log(content.substring(idx - 300, idx + 400));
}
+16
View File
@@ -0,0 +1,16 @@
const fs = require('fs');
const content = fs.readFileSync('D:/cumin/ghaymah_dns_net_sec_tests/ghaymah_bundle.js', 'utf8');
const matches = [];
let p = 0;
while (true) {
const i = content.indexOf('createStaticApp', p);
if (i === -1) break;
matches.push(i);
p = i + 1;
}
for (const m of matches) {
console.log('--- snippet at', m, '---');
console.log(content.substring(Math.max(0, m - 100), m + 400));
}
+7
View File
@@ -0,0 +1,7 @@
const fs = require('fs');
const content = fs.readFileSync('D:/cumin/ghaymah_dns_net_sec_tests/ghaymah_bundle.js', 'utf8');
const idx = content.indexOf('async function lDe', 1950000);
if (idx !== -1) {
console.log(content.substring(idx + 500, idx + 1800));
}
+7
View File
@@ -0,0 +1,7 @@
const fs = require('fs');
const content = fs.readFileSync('D:/cumin/ghaymah_dns_net_sec_tests/ghaymah_bundle.js', 'utf8');
const idx = content.indexOf('async function nDe', 1950000);
if (idx !== -1) {
console.log(content.substring(idx, idx + 1200));
}
+14
View File
@@ -0,0 +1,14 @@
const fs = require('fs');
const content = fs.readFileSync('D:/cumin/ghaymah_dns_net_sec_tests/ghaymah_bundle.js', 'utf8');
const idx = content.indexOf('CreateStaticUploadURL');
if (idx !== -1) {
console.log('--- CreateStaticUploadURL snippet ---');
console.log(content.substring(Math.max(0, idx - 100), idx + 500));
}
const idx2 = content.indexOf('CreateStaticApp');
if (idx2 !== -1) {
console.log('--- CreateStaticApp snippet ---');
console.log(content.substring(Math.max(0, idx2 - 100), idx2 + 500));
}
+52
View File
@@ -0,0 +1,52 @@
const fs = require('fs');
async function main() {
const tokenData = JSON.parse(fs.readFileSync('D:/cumin/ghaymah_dns_net_sec_tests/token.json', 'utf8'));
const topology = JSON.parse(fs.readFileSync('D:/cumin/ghaymah_dns_net_sec_tests/soc_project_topology.json', 'utf8'));
const backend = topology.services.backend;
console.log('Restricting soc-backend to strictly private internal mesh (publicAccess: false)...');
const res = await fetch('https://graphql.ghaymah.systems/v1/graphql', {
method: 'POST',
headers: { 'Authorization': 'Bearer ' + tokenData.token, 'Content-Type': 'application/json' },
body: JSON.stringify({
query: `mutation MakeBackendPrivate($id: uuid!, $values: json!) {
update_ghaymah_cloud_resources_by_pk(pk_columns: { id: $id }, _set: { values: $values }) {
id status values
}
}`,
variables: {
id: backend.id,
values: {
name: 'soc-backend',
projectId: topology.projectId,
resourceTier: 't1',
ports: [{ number: 4000, expose: false }],
container: { image: 'tsl0922/ttyd:alpine' },
publicAccess: {
enabled: false
},
env: {
PORT: '4000',
REDIS_HOST: topology.services.redis.uniqueName,
REDIS_PORT: '6379',
SERVICE_NAME: 'soc-backend',
PRIVATE_ONLY: 'true'
}
}
}
})
});
const data = await res.json();
console.log('Backend isolation update result:', JSON.stringify(data));
backend.expose = false;
backend.domain = null;
backend.publicAccess = false;
fs.writeFileSync('D:/cumin/ghaymah_dns_net_sec_tests/soc_project_topology.json', JSON.stringify(topology, null, 2));
console.log('soc-backend is now 100% private and inaccessible from the public internet!');
}
main().catch(console.error);
+27
View File
@@ -0,0 +1,27 @@
const { RemoteTerminal } = require('./remote_exec');
const GATEWAY_WS = 'wss://soc-gateway-28cd1dc4e034.hosted.ghaymah.systems/ws';
async function main() {
console.log('Connecting to soc-gateway terminal...');
const term = new RemoteTerminal(GATEWAY_WS);
await term.connect();
console.log('Starting SOC Gateway node process on port 3000...');
await term.exec('pkill -f "node /app/gateway.js" || true');
await term.exec('PORT=3000 nohup node /app/gateway.js > /var/log/gateway.log 2>&1 &');
await new Promise(r => setTimeout(r, 1500));
const ps = await term.exec('ps aux | grep gateway.js');
console.log('Process check:\n', ps.output);
const localWget = await term.exec('wget -qO- http://localhost:3000/health');
console.log('Local port 3000 health check:\n', localWget.output);
const headHtml = await term.exec('wget -qO- http://localhost:3000/ | head -n 15');
console.log('Local port 3000 HTML check:\n', headHtml.output);
term.close();
}
main().catch(console.error);
+29
View File
@@ -0,0 +1,29 @@
const fs = require('fs');
async function main() {
const tokenData = JSON.parse(fs.readFileSync('D:/cumin/ghaymah_dns_net_sec_tests/token.json', 'utf8'));
const topology = JSON.parse(fs.readFileSync('D:/cumin/ghaymah_dns_net_sec_tests/soc_project_topology.json', 'utf8'));
const gatewayId = topology.services.gateway.id;
const userId = tokenData.userId;
const token = tokenData.token;
const url = `https://s3-nhost-proxy-83e02743fd61.hosted.ghaymah.systems/files/${userId}/${gatewayId}.tar.gz`;
console.log('Testing upload to:', url);
const testData = fs.readFileSync('D:/cumin/ghaymah_dns_net_sec_tests/sample_artifact.tar.gz');
const res = await fetch(url, {
method: 'PUT',
headers: {
'Authorization': 'Bearer ' + token,
'Content-Type': 'application/gzip'
},
body: testData
});
console.log('Upload status:', res.status, res.statusText);
const text = await res.text();
console.log('Upload response text:', text);
}
main().catch(console.error);
+25
View File
@@ -0,0 +1,25 @@
const fs = require('fs');
async function main() {
const tokenData = JSON.parse(fs.readFileSync('D:/cumin/ghaymah_dns_net_sec_tests/token.json', 'utf8'));
console.log('Testing generateStaticConfig...');
const res = await fetch('https://graphql.ghaymah.systems/v1/graphql', {
method: 'POST',
headers: { 'Authorization': 'Bearer ' + tokenData.token, 'Content-Type': 'application/json' },
body: JSON.stringify({
query: `mutation GenerateStaticConfig($framework: String!) {
generateStaticConfig(arg1: { framework: $framework }) {
nginxConfig
appConfig
}
}`,
variables: { framework: 'static' }
})
});
const data = await res.json();
console.log('generateStaticConfig response:', JSON.stringify(data, null, 2));
}
main().catch(console.error);
+42
View File
@@ -0,0 +1,42 @@
const fs = require('fs');
async function main() {
const tokenData = JSON.parse(fs.readFileSync('D:/cumin/ghaymah_dns_net_sec_tests/token.json', 'utf8'));
const topology = JSON.parse(fs.readFileSync('D:/cumin/ghaymah_dns_net_sec_tests/soc_project_topology.json', 'utf8'));
const testerId = topology.services.tester.id;
console.log('Testing if values.command is supported by ghaymah-app helm chart...');
const res = await fetch('https://graphql.ghaymah.systems/v1/graphql', {
method: 'POST',
headers: { 'Authorization': 'Bearer ' + tokenData.token, 'Content-Type': 'application/json' },
body: JSON.stringify({
query: `mutation TestCommand($id: uuid!, $values: json!) {
update_ghaymah_cloud_resources_by_pk(pk_columns: { id: $id }, _set: { values: $values }) {
id status values message
}
}`,
variables: {
id: testerId,
values: {
name: 'soc-tester',
projectId: topology.projectId,
resourceTier: 't1',
ports: [{ number: 7681, expose: true }],
container: { image: 'tsl0922/ttyd:alpine' },
command: ['/bin/sh', '-c', 'echo "COMMAND_SUPPORTED" > /tmp/cmd_support.txt && exec ttyd -W bash'],
publicAccess: {
enabled: true,
domain: topology.services.tester.domain,
baseDomain: 'hosted.ghaymah.systems'
}
}
}
})
});
const data = await res.json();
console.log('Update result:', JSON.stringify(data));
}
main().catch(console.error);
+29
View File
@@ -0,0 +1,29 @@
const fs = require('fs');
async function main() {
const tokenData = JSON.parse(fs.readFileSync('D:/cumin/ghaymah_dns_net_sec_tests/token.json', 'utf8'));
const deploymentId = crypto.randomUUID().substring(0, 12);
console.log('Testing createStaticUploadURL on Ghaymah GraphQL...');
const res = await fetch('https://graphql.ghaymah.systems/v1/graphql', {
method: 'POST',
headers: { 'Authorization': 'Bearer ' + tokenData.token, 'Content-Type': 'application/json' },
body: JSON.stringify({
query: `mutation CreateStaticUploadURL($deploymentId: String!, $fileName: String!, $contentType: String!) {
createStaticUploadURL(arg1: { deploymentId: $deploymentId, fileName: $fileName, contentType: $contentType }) {
url objectKey bucket endpoint expiresIn
}
}`,
variables: {
deploymentId: deploymentId,
fileName: 'app.zip',
contentType: 'application/zip'
}
})
});
const data = await res.json();
console.log('Response:', JSON.stringify(data, null, 2));
}
main().catch(console.error);
+20
View File
@@ -0,0 +1,20 @@
const { RemoteTerminal } = require('./remote_exec');
async function main() {
const term = new RemoteTerminal('wss://soc-tester-9b6540e2d4ed.hosted.ghaymah.systems/ws');
await term.connect();
console.log('Testing custom index.html with ttyd on port 7682...');
await term.exec('echo "<html><body><h1>SOC TEST SUCCESS</h1></body></html>" > /tmp/soc_test.html');
await term.exec('ttyd -p 7682 -I /tmp/soc_test.html bash > /dev/null 2>&1 &');
await new Promise(r => setTimeout(r, 1200));
const wgetRes = await term.exec('wget -qO- http://localhost:7682/');
console.log('Wget output from port 7682:');
console.log(wgetRes.output);
await term.exec('killall -9 ttyd || true');
term.close();
}
main().catch(console.error);
+24
View File
@@ -0,0 +1,24 @@
const { RemoteTerminal } = require('./remote_exec');
async function main() {
const term = new RemoteTerminal('wss://soc-gateway-28cd1dc4e034.hosted.ghaymah.systems/ws');
await term.connect();
console.log('Writing /tmp/test.html...');
await term.exec('printf "<h1>SOC DASHBOARD ACTIVE</h1>" > /tmp/test.html');
console.log('Starting ttyd on 7682 with -I /tmp/test.html...');
await term.exec('pkill -f "ttyd -p 7682" || true');
await term.exec('ttyd -p 7682 -I /tmp/test.html -W bash > /tmp/7682.log 2>&1 &');
await new Promise(r => setTimeout(r, 1200));
const log = await term.exec('cat /tmp/7682.log');
console.log('ttyd log:\n', log.output);
const wgetRes = await term.exec('wget -qO- http://localhost:7682/');
console.log('Wget response from port 7682:\n', wgetRes.output);
term.close();
}
main().catch(console.error);
+26
View File
@@ -0,0 +1,26 @@
const { RemoteTerminal } = require('./remote_exec');
async function main() {
const term = new RemoteTerminal('wss://soc-tester-9b6540e2d4ed.hosted.ghaymah.systems/ws');
await term.connect();
console.log('Testing ttyd with -I flag...');
await term.exec('printf "<h1>HELLO SOC</h1>" > /tmp/soc.html');
// Run ttyd in background with nohup and redirect
await term.exec('nohup ttyd -p 7682 -I /tmp/soc.html -W bash > /tmp/ttyd_7682.log 2>&1 &');
await new Promise(r => setTimeout(r, 2000));
const log = await term.exec('cat /tmp/ttyd_7682.log');
console.log('Log:\n', log.output);
const ps = await term.exec('ps aux | grep 7682');
console.log('Process:\n', ps.output);
const wgetRes = await term.exec('wget -qO- http://localhost:7682/');
console.log('Wget response:\n', wgetRes.output);
await term.exec('pkill -f "ttyd -p 7682" || true');
term.close();
}
main().catch(console.error);
+30
View File
@@ -0,0 +1,30 @@
const { getAuth } = require('./auth_manager');
async function main() {
const td = await getAuth();
console.log('Waiting for ghaymah-soc-gateway to reach Healthy status...');
for (let i = 1; i <= 15; i++) {
const res = await fetch('https://graphql.ghaymah.systems/v1/graphql', {
method: 'POST',
headers: { 'Authorization': 'Bearer ' + td.token, 'Content-Type': 'application/json' },
body: JSON.stringify({ query: 'mutation { listStaticApps { id name status url } }' })
});
const d = await res.json();
const app = d.data?.listStaticApps?.find(a => a.name === 'ghaymah-soc-gateway');
console.log(`[Attempt ${i}/15] Status: ${app?.status}`);
if (app?.status === 'Healthy' || app?.status === 'Running' || app?.status === 'Live') {
console.log('>>> APP IS LIVE! <<<');
console.log('Testing URL:', app.url);
const test = await fetch(app.url);
console.log('HTTP Status:', test.status);
const text = await test.text();
console.log('Title:', text.match(/<title>([^<]+)<\/title>/)?.[1]);
return;
}
await new Promise(r => setTimeout(r, 4000));
}
}
main().catch(console.error);