50c 1.5.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +49 -235
- package/bin/50c.js +210 -258
- package/lib/config.js +185 -0
- package/lib/core/tools.js +107 -0
- package/lib/index.js +166 -0
- package/lib/packs/beacon.js +224 -0
- package/lib/packs/cf.js +156 -0
- package/lib/packs/labs.js +188 -0
- package/lib/packs/labs_plus.js +246 -0
- package/lib/packs/ux.js +76 -0
- package/lib/packs/whm.js +228 -0
- package/lib/packs/wp.js +82 -0
- package/lib/packs.js +406 -0
- package/lib/vault.js +354 -0
- package/package.json +25 -11
- package/LICENSE +0 -31
package/lib/packs/whm.js
ADDED
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 50c WHM Pack - WHM/cPanel/SSH Automation
|
|
3
|
+
* 39 tools for complete hosting control
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const https = require('https');
|
|
7
|
+
const { spawn } = require('child_process');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
const os = require('os');
|
|
10
|
+
const vault = require('../vault');
|
|
11
|
+
|
|
12
|
+
// Get credentials from vault or env
|
|
13
|
+
async function getWHMCreds() {
|
|
14
|
+
// Try vault first
|
|
15
|
+
try {
|
|
16
|
+
if (await vault.isUnlocked()) {
|
|
17
|
+
const creds = await vault.get('whm/default');
|
|
18
|
+
if (creds) {
|
|
19
|
+
const [user, token] = creds.split(':');
|
|
20
|
+
return { host: process.env.WHM_HOST, user, token };
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
} catch {}
|
|
24
|
+
|
|
25
|
+
// Fall back to env
|
|
26
|
+
return {
|
|
27
|
+
host: process.env.WHM_HOST || '',
|
|
28
|
+
user: process.env.WHM_USER || 'root',
|
|
29
|
+
token: process.env.WHM_TOKEN || ''
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// WHM API Request
|
|
34
|
+
async function whmRequest(func, params = {}) {
|
|
35
|
+
const creds = await getWHMCreds();
|
|
36
|
+
if (!creds.host || !creds.token) {
|
|
37
|
+
return { error: 'WHM not configured. Add credentials: vault_add whm/default "root:YOUR_TOKEN" and set WHM_HOST env var' };
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return new Promise((resolve) => {
|
|
41
|
+
const queryParams = new URLSearchParams({ 'api.version': '1', ...params });
|
|
42
|
+
const reqPath = `/json-api/${func}?${queryParams.toString()}`;
|
|
43
|
+
|
|
44
|
+
const options = {
|
|
45
|
+
hostname: creds.host,
|
|
46
|
+
port: 2087,
|
|
47
|
+
path: reqPath,
|
|
48
|
+
method: 'GET',
|
|
49
|
+
headers: { 'Authorization': `whm ${creds.user}:${creds.token}` },
|
|
50
|
+
rejectUnauthorized: false
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const req = https.request(options, (res) => {
|
|
54
|
+
let data = '';
|
|
55
|
+
res.on('data', chunk => data += chunk);
|
|
56
|
+
res.on('end', () => {
|
|
57
|
+
try {
|
|
58
|
+
const json = JSON.parse(data);
|
|
59
|
+
resolve(json.result || json.data || json);
|
|
60
|
+
} catch { resolve({ raw: data }); }
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
req.on('error', (e) => resolve({ error: e.message }));
|
|
65
|
+
req.end();
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// cPanel UAPI Request
|
|
70
|
+
async function cpanelRequest(user, module, func, params = {}) {
|
|
71
|
+
const creds = await getWHMCreds();
|
|
72
|
+
if (!creds.host || !creds.token) {
|
|
73
|
+
return { error: 'WHM not configured' };
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return new Promise((resolve) => {
|
|
77
|
+
const queryParams = new URLSearchParams({
|
|
78
|
+
'api.version': '1',
|
|
79
|
+
'cpanel_jsonapi_user': user,
|
|
80
|
+
'cpanel_jsonapi_apiversion': '3',
|
|
81
|
+
'cpanel_jsonapi_module': module,
|
|
82
|
+
'cpanel_jsonapi_func': func,
|
|
83
|
+
...params
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
const options = {
|
|
87
|
+
hostname: creds.host,
|
|
88
|
+
port: 2087,
|
|
89
|
+
path: `/json-api/cpanel?${queryParams.toString()}`,
|
|
90
|
+
method: 'GET',
|
|
91
|
+
headers: { 'Authorization': `whm ${creds.user}:${creds.token}` },
|
|
92
|
+
rejectUnauthorized: false
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const req = https.request(options, (res) => {
|
|
96
|
+
let data = '';
|
|
97
|
+
res.on('data', chunk => data += chunk);
|
|
98
|
+
res.on('end', () => {
|
|
99
|
+
try {
|
|
100
|
+
const json = JSON.parse(data);
|
|
101
|
+
resolve(json.result?.data || json);
|
|
102
|
+
} catch { resolve({ raw: data }); }
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
req.on('error', (e) => resolve({ error: e.message }));
|
|
107
|
+
req.end();
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// SSH Execution
|
|
112
|
+
async function sshExec(command, host = null) {
|
|
113
|
+
const creds = await getWHMCreds();
|
|
114
|
+
const targetHost = host || creds.host;
|
|
115
|
+
|
|
116
|
+
if (!targetHost) {
|
|
117
|
+
return { error: 'No host configured' };
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const sshKeyPath = process.env.SSH_KEY_PATH || path.join(os.homedir(), '.ssh', 'id_rsa');
|
|
121
|
+
const sshUser = process.env.SSH_USER || creds.user || 'root';
|
|
122
|
+
|
|
123
|
+
return new Promise((resolve) => {
|
|
124
|
+
const ssh = spawn('ssh', [
|
|
125
|
+
'-i', sshKeyPath,
|
|
126
|
+
'-o', 'StrictHostKeyChecking=no',
|
|
127
|
+
'-o', 'BatchMode=yes',
|
|
128
|
+
`${sshUser}@${targetHost}`,
|
|
129
|
+
command
|
|
130
|
+
]);
|
|
131
|
+
|
|
132
|
+
let stdout = '', stderr = '';
|
|
133
|
+
ssh.stdout.on('data', d => stdout += d);
|
|
134
|
+
ssh.stderr.on('data', d => stderr += d);
|
|
135
|
+
|
|
136
|
+
ssh.on('close', (code) => {
|
|
137
|
+
resolve({ exit_code: code, stdout: stdout.trim(), stderr: stderr.trim(), success: code === 0 });
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
ssh.on('error', (err) => resolve({ error: err.message }));
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Tool definitions
|
|
145
|
+
const WHM_TOOLS = [
|
|
146
|
+
// Account Management
|
|
147
|
+
{ name: 'whm_list_accounts', description: 'List cPanel accounts. FREE.', inputSchema: { type: 'object', properties: { search: { type: 'string' } } } },
|
|
148
|
+
{ name: 'whm_account_summary', description: 'Get account details. FREE.', inputSchema: { type: 'object', properties: { user: { type: 'string' } }, required: ['user'] } },
|
|
149
|
+
{ name: 'whm_create_account', description: 'Create cPanel account. 5 credits.', inputSchema: { type: 'object', properties: { username: { type: 'string' }, domain: { type: 'string' }, password: { type: 'string' }, plan: { type: 'string' } }, required: ['username', 'domain'] } },
|
|
150
|
+
{ name: 'whm_suspend_account', description: 'Suspend account. 2 credits.', inputSchema: { type: 'object', properties: { user: { type: 'string' }, reason: { type: 'string' } }, required: ['user'] } },
|
|
151
|
+
{ name: 'whm_unsuspend_account', description: 'Unsuspend account. 2 credits.', inputSchema: { type: 'object', properties: { user: { type: 'string' } }, required: ['user'] } },
|
|
152
|
+
{ name: 'whm_terminate_account', description: 'Delete account. 5 credits.', inputSchema: { type: 'object', properties: { user: { type: 'string' } }, required: ['user'] } },
|
|
153
|
+
{ name: 'whm_list_packages', description: 'List hosting packages. FREE.', inputSchema: { type: 'object', properties: {} } },
|
|
154
|
+
{ name: 'whm_server_info', description: 'Get server info. FREE.', inputSchema: { type: 'object', properties: {} } },
|
|
155
|
+
|
|
156
|
+
// DNS
|
|
157
|
+
{ name: 'whm_list_zones', description: 'List DNS zones. FREE.', inputSchema: { type: 'object', properties: {} } },
|
|
158
|
+
{ name: 'whm_get_zone', description: 'Get zone records. FREE.', inputSchema: { type: 'object', properties: { domain: { type: 'string' } }, required: ['domain'] } },
|
|
159
|
+
{ name: 'whm_add_zone_record', description: 'Add DNS record. 2 credits.', inputSchema: { type: 'object', properties: { domain: { type: 'string' }, name: { type: 'string' }, type: { type: 'string' }, value: { type: 'string' } }, required: ['domain', 'name', 'type', 'value'] } },
|
|
160
|
+
|
|
161
|
+
// SSL
|
|
162
|
+
{ name: 'whm_autossl_check', description: 'Check AutoSSL status. FREE.', inputSchema: { type: 'object', properties: { user: { type: 'string' } }, required: ['user'] } },
|
|
163
|
+
{ name: 'whm_autossl_run', description: 'Run AutoSSL. 3 credits.', inputSchema: { type: 'object', properties: { user: { type: 'string' } }, required: ['user'] } },
|
|
164
|
+
|
|
165
|
+
// Services
|
|
166
|
+
{ name: 'whm_service_status', description: 'Check services. FREE.', inputSchema: { type: 'object', properties: {} } },
|
|
167
|
+
{ name: 'whm_restart_service', description: 'Restart service. 3 credits.', inputSchema: { type: 'object', properties: { service: { type: 'string' } }, required: ['service'] } },
|
|
168
|
+
{ name: 'whm_server_load', description: 'Get server load. FREE.', inputSchema: { type: 'object', properties: {} } },
|
|
169
|
+
|
|
170
|
+
// cPanel UAPI
|
|
171
|
+
{ name: 'cp_list_domains', description: 'List domains. FREE.', inputSchema: { type: 'object', properties: { user: { type: 'string' } }, required: ['user'] } },
|
|
172
|
+
{ name: 'cp_list_email', description: 'List email accounts. FREE.', inputSchema: { type: 'object', properties: { user: { type: 'string' } }, required: ['user'] } },
|
|
173
|
+
{ name: 'cp_create_email', description: 'Create email. 2 credits.', inputSchema: { type: 'object', properties: { user: { type: 'string' }, email: { type: 'string' }, password: { type: 'string' } }, required: ['user', 'email', 'password'] } },
|
|
174
|
+
{ name: 'cp_list_databases', description: 'List databases. FREE.', inputSchema: { type: 'object', properties: { user: { type: 'string' } }, required: ['user'] } },
|
|
175
|
+
{ name: 'cp_create_database', description: 'Create database. 2 credits.', inputSchema: { type: 'object', properties: { user: { type: 'string' }, dbname: { type: 'string' } }, required: ['user', 'dbname'] } },
|
|
176
|
+
|
|
177
|
+
// SSH
|
|
178
|
+
{ name: 'ssh_exec', description: 'Execute SSH command. 3 credits.', inputSchema: { type: 'object', properties: { command: { type: 'string' }, host: { type: 'string' } }, required: ['command'] } }
|
|
179
|
+
];
|
|
180
|
+
|
|
181
|
+
// Handle WHM tool calls
|
|
182
|
+
async function handleTool(name, args) {
|
|
183
|
+
try {
|
|
184
|
+
// Account Management
|
|
185
|
+
if (name === 'whm_list_accounts') {
|
|
186
|
+
const result = await whmRequest('listaccts', args.search ? { search: args.search, searchtype: 'domain' } : {});
|
|
187
|
+
if (result.acct) return result.acct.map(a => ({ user: a.user, domain: a.domain, plan: a.plan, suspended: a.suspended }));
|
|
188
|
+
return result;
|
|
189
|
+
}
|
|
190
|
+
if (name === 'whm_account_summary') return whmRequest('accountsummary', { user: args.user });
|
|
191
|
+
if (name === 'whm_create_account') return whmRequest('createacct', args);
|
|
192
|
+
if (name === 'whm_suspend_account') return whmRequest('suspendacct', { user: args.user, reason: args.reason || '' });
|
|
193
|
+
if (name === 'whm_unsuspend_account') return whmRequest('unsuspendacct', { user: args.user });
|
|
194
|
+
if (name === 'whm_terminate_account') return whmRequest('removeacct', { user: args.user });
|
|
195
|
+
if (name === 'whm_list_packages') return whmRequest('listpkgs');
|
|
196
|
+
if (name === 'whm_server_info') return whmRequest('version');
|
|
197
|
+
|
|
198
|
+
// DNS
|
|
199
|
+
if (name === 'whm_list_zones') return whmRequest('listzones');
|
|
200
|
+
if (name === 'whm_get_zone') return whmRequest('dumpzone', { domain: args.domain });
|
|
201
|
+
if (name === 'whm_add_zone_record') return whmRequest('addzonerecord', { domain: args.domain, name: args.name, type: args.type, address: args.value });
|
|
202
|
+
|
|
203
|
+
// SSL
|
|
204
|
+
if (name === 'whm_autossl_check') return whmRequest('get_autossl_check_for_cpanel_users', { username: args.user });
|
|
205
|
+
if (name === 'whm_autossl_run') return whmRequest('start_autossl_check_for_one_user', { username: args.user });
|
|
206
|
+
|
|
207
|
+
// Services
|
|
208
|
+
if (name === 'whm_service_status') return whmRequest('servicestatus');
|
|
209
|
+
if (name === 'whm_restart_service') return whmRequest('restartservice', { service: args.service });
|
|
210
|
+
if (name === 'whm_server_load') return whmRequest('loadavg');
|
|
211
|
+
|
|
212
|
+
// cPanel
|
|
213
|
+
if (name === 'cp_list_domains') return cpanelRequest(args.user, 'DomainInfo', 'list_domains');
|
|
214
|
+
if (name === 'cp_list_email') return cpanelRequest(args.user, 'Email', 'list_pops');
|
|
215
|
+
if (name === 'cp_create_email') return cpanelRequest(args.user, 'Email', 'add_pop', { email: args.email, password: args.password });
|
|
216
|
+
if (name === 'cp_list_databases') return cpanelRequest(args.user, 'Mysql', 'list_databases');
|
|
217
|
+
if (name === 'cp_create_database') return cpanelRequest(args.user, 'Mysql', 'create_database', { name: args.dbname });
|
|
218
|
+
|
|
219
|
+
// SSH
|
|
220
|
+
if (name === 'ssh_exec') return sshExec(args.command, args.host);
|
|
221
|
+
|
|
222
|
+
return { error: `Unknown WHM tool: ${name}` };
|
|
223
|
+
} catch (e) {
|
|
224
|
+
return { error: e.message };
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
module.exports = { WHM_TOOLS, handleTool };
|
package/lib/packs/wp.js
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 50c WP Pack - WordPress Management
|
|
3
|
+
* 14 tools for full site control
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const https = require('https');
|
|
7
|
+
const vault = require('../vault');
|
|
8
|
+
|
|
9
|
+
async function getWPCreds() {
|
|
10
|
+
try {
|
|
11
|
+
if (await vault.isUnlocked()) {
|
|
12
|
+
const creds = await vault.get('wp/default');
|
|
13
|
+
if (creds) {
|
|
14
|
+
const [user, pass] = creds.split(':');
|
|
15
|
+
return { url: process.env.WP_URL, user, pass };
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
} catch {}
|
|
19
|
+
return { url: process.env.WP_URL, user: process.env.WP_USER, pass: process.env.WP_APP_PASSWORD };
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async function wpRequest(method, endpoint, body = null) {
|
|
23
|
+
const creds = await getWPCreds();
|
|
24
|
+
if (!creds.url || !creds.user || !creds.pass) {
|
|
25
|
+
return { error: 'WordPress not configured. Set WP_URL env and: vault_add wp/default "user:app_password"' };
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return new Promise((resolve) => {
|
|
29
|
+
const url = new URL(`/wp-json/wp/v2${endpoint}`, creds.url);
|
|
30
|
+
const auth = Buffer.from(`${creds.user}:${creds.pass}`).toString('base64');
|
|
31
|
+
|
|
32
|
+
const options = {
|
|
33
|
+
hostname: url.hostname,
|
|
34
|
+
port: url.port || 443,
|
|
35
|
+
path: url.pathname + url.search,
|
|
36
|
+
method,
|
|
37
|
+
headers: { 'Authorization': `Basic ${auth}`, 'Content-Type': 'application/json' },
|
|
38
|
+
rejectUnauthorized: true
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const req = https.request(options, (res) => {
|
|
42
|
+
let data = '';
|
|
43
|
+
res.on('data', chunk => data += chunk);
|
|
44
|
+
res.on('end', () => { try { resolve(JSON.parse(data)); } catch { resolve({ raw: data }); } });
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
req.on('error', (e) => resolve({ error: e.message }));
|
|
48
|
+
if (body) req.write(JSON.stringify(body));
|
|
49
|
+
req.end();
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const WP_TOOLS = [
|
|
54
|
+
{ name: 'wp_list_pages', description: 'List pages. FREE.', inputSchema: { type: 'object', properties: { status: { type: 'string' } } } },
|
|
55
|
+
{ name: 'wp_get_page', description: 'Get page. FREE.', inputSchema: { type: 'object', properties: { id: { type: 'number' } }, required: ['id'] } },
|
|
56
|
+
{ name: 'wp_create_page', description: 'Create page. 2 credits.', inputSchema: { type: 'object', properties: { title: { type: 'string' }, content: { type: 'string' }, status: { type: 'string' } }, required: ['title', 'content'] } },
|
|
57
|
+
{ name: 'wp_update_page', description: 'Update page. 2 credits.', inputSchema: { type: 'object', properties: { id: { type: 'number' }, title: { type: 'string' }, content: { type: 'string' } }, required: ['id'] } },
|
|
58
|
+
{ name: 'wp_delete_page', description: 'Delete page. 2 credits.', inputSchema: { type: 'object', properties: { id: { type: 'number' } }, required: ['id'] } },
|
|
59
|
+
{ name: 'wp_list_posts', description: 'List posts. FREE.', inputSchema: { type: 'object', properties: {} } },
|
|
60
|
+
{ name: 'wp_create_post', description: 'Create post. 2 credits.', inputSchema: { type: 'object', properties: { title: { type: 'string' }, content: { type: 'string' } }, required: ['title', 'content'] } },
|
|
61
|
+
{ name: 'wp_list_plugins', description: 'List plugins. FREE.', inputSchema: { type: 'object', properties: {} } },
|
|
62
|
+
{ name: 'wp_list_themes', description: 'List themes. FREE.', inputSchema: { type: 'object', properties: {} } },
|
|
63
|
+
{ name: 'wp_get_site', description: 'Get site info. FREE.', inputSchema: { type: 'object', properties: {} } }
|
|
64
|
+
];
|
|
65
|
+
|
|
66
|
+
async function handleTool(name, args) {
|
|
67
|
+
try {
|
|
68
|
+
if (name === 'wp_list_pages') return wpRequest('GET', `/pages?status=${args.status || 'publish'}`);
|
|
69
|
+
if (name === 'wp_get_page') return wpRequest('GET', `/pages/${args.id}`);
|
|
70
|
+
if (name === 'wp_create_page') return wpRequest('POST', '/pages', { title: args.title, content: args.content, status: args.status || 'draft' });
|
|
71
|
+
if (name === 'wp_update_page') return wpRequest('POST', `/pages/${args.id}`, { title: args.title, content: args.content });
|
|
72
|
+
if (name === 'wp_delete_page') return wpRequest('DELETE', `/pages/${args.id}?force=true`);
|
|
73
|
+
if (name === 'wp_list_posts') return wpRequest('GET', '/posts');
|
|
74
|
+
if (name === 'wp_create_post') return wpRequest('POST', '/posts', { title: args.title, content: args.content, status: 'draft' });
|
|
75
|
+
if (name === 'wp_list_plugins') return wpRequest('GET', '/plugins');
|
|
76
|
+
if (name === 'wp_list_themes') return wpRequest('GET', '/themes');
|
|
77
|
+
if (name === 'wp_get_site') return wpRequest('GET', '/settings');
|
|
78
|
+
return { error: `Unknown WP tool: ${name}` };
|
|
79
|
+
} catch (e) { return { error: e.message }; }
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
module.exports = { WP_TOOLS, handleTool };
|