@bprotsyk/aso-core 2.0.11 → 2.0.13
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/lib/index.d.ts +1 -0
- package/lib/index.js +3 -1
- package/lib/utils/server-util.d.ts +12 -0
- package/lib/utils/server-util.js +116 -21
- package/package.json +5 -1
- package/src/index.ts +2 -1
- package/src/utils/server-util.ts +212 -83
package/lib/index.d.ts
CHANGED
|
@@ -23,3 +23,4 @@ export { IKeitaroStream } from "./keitaro/keitaro-stream";
|
|
|
23
23
|
export { ICloudflareDomainStatus, ICloudflareDomainType, ICloudflareDomain } from "./general/cloudflare-domain";
|
|
24
24
|
export { IDomain, IDomainSetupResult, DomainStatus, DomainTarget, CONST_CLOUFLARE_STATUS_READY, IDomainsBuyRequestResponse, getDomainTargetByIp } from "./general/domain";
|
|
25
25
|
export { INamecheapDomain, INamecheapBuyRequest, INamecheapContactInfo, NamecheapBuyRequestSchema, INamecheapGetDomainsResult, NamecheapBuyResult } from "./general/namecheap-domain";
|
|
26
|
+
export { ServerUtil } from './utils/server-util';
|
package/lib/index.js
CHANGED
|
@@ -23,7 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.NamecheapBuyRequestSchema = exports.getDomainTargetByIp = exports.CONST_CLOUFLARE_STATUS_READY = exports.DomainTarget = exports.DomainStatus = exports.ICloudflareDomainType = exports.ICloudflareDomainStatus = exports.KeitaroUtils = exports.KeitaroService = exports.ShapeDiv = exports.PanelUserSchema = exports.PanelUserAccessScope = exports.AlternativeOnActivityResult = exports.AlternativeOnBackPressed = exports.AlternativeNavigation = exports.AlternativeStorageType = exports.AlternativeNetworkTool = exports.AlternativeLogicType = exports.AlternativeSourceType = exports.AlternativeLayoutType = exports.AppType = exports.PlugType = exports.AppSchema = exports.IntegrationVersion = exports.SectionsListSchema = exports.DefaultSectionId = exports.OffersSectionSchema = exports.IOfferType = void 0;
|
|
26
|
+
exports.ServerUtil = exports.NamecheapBuyRequestSchema = exports.getDomainTargetByIp = exports.CONST_CLOUFLARE_STATUS_READY = exports.DomainTarget = exports.DomainStatus = exports.ICloudflareDomainType = exports.ICloudflareDomainStatus = exports.KeitaroUtils = exports.KeitaroService = exports.ShapeDiv = exports.PanelUserSchema = exports.PanelUserAccessScope = exports.AlternativeOnActivityResult = exports.AlternativeOnBackPressed = exports.AlternativeNavigation = exports.AlternativeStorageType = exports.AlternativeNetworkTool = exports.AlternativeLogicType = exports.AlternativeSourceType = exports.AlternativeLayoutType = exports.AppType = exports.PlugType = exports.AppSchema = exports.IntegrationVersion = exports.SectionsListSchema = exports.DefaultSectionId = exports.OffersSectionSchema = exports.IOfferType = void 0;
|
|
27
27
|
var offer_1 = require("./offers/offer");
|
|
28
28
|
Object.defineProperty(exports, "IOfferType", { enumerable: true, get: function () { return offer_1.IOfferType; } });
|
|
29
29
|
var section_1 = require("./offers/section");
|
|
@@ -64,3 +64,5 @@ Object.defineProperty(exports, "CONST_CLOUFLARE_STATUS_READY", { enumerable: tru
|
|
|
64
64
|
Object.defineProperty(exports, "getDomainTargetByIp", { enumerable: true, get: function () { return domain_1.getDomainTargetByIp; } });
|
|
65
65
|
var namecheap_domain_1 = require("./general/namecheap-domain");
|
|
66
66
|
Object.defineProperty(exports, "NamecheapBuyRequestSchema", { enumerable: true, get: function () { return namecheap_domain_1.NamecheapBuyRequestSchema; } });
|
|
67
|
+
var server_util_1 = require("./utils/server-util");
|
|
68
|
+
Object.defineProperty(exports, "ServerUtil", { enumerable: true, get: function () { return server_util_1.ServerUtil; } });
|
|
@@ -8,10 +8,22 @@ export declare class ServerUtil {
|
|
|
8
8
|
ssh?: NodeSSH;
|
|
9
9
|
constructor(ssh?: NodeSSH);
|
|
10
10
|
exec(command: string, options?: any): Promise<string>;
|
|
11
|
+
generateSSHKey(): Promise<string>;
|
|
12
|
+
createDirectories(): Promise<void>;
|
|
13
|
+
installGit(): Promise<void>;
|
|
14
|
+
addBitbucketToKnownHosts(): Promise<void>;
|
|
15
|
+
cloneRepository(repoName: string, targetPath: string): Promise<void>;
|
|
16
|
+
installNginx(): Promise<void>;
|
|
11
17
|
isNginxActive(): Promise<boolean>;
|
|
12
18
|
isMongoActive(): Promise<boolean>;
|
|
13
19
|
mongoInstallCommand: string;
|
|
14
20
|
domainNginxConfigExists(host: string): Promise<boolean>;
|
|
21
|
+
domainNginxCertsExist(host: string): Promise<boolean>;
|
|
15
22
|
isCerbotActive(): Promise<boolean>;
|
|
16
23
|
setupCertbot(): Promise<boolean>;
|
|
24
|
+
setupSSL(email: string, host: string): Promise<void>;
|
|
25
|
+
refresh(): Promise<boolean>;
|
|
26
|
+
deployLandingPage(host: string, username: string, password: string, remotePath: string, files: any): Promise<void>;
|
|
27
|
+
generateNginxConfig(domain: string, rootPath: string): Promise<string>;
|
|
28
|
+
serverConect(IP: string): Promise<string>;
|
|
17
29
|
}
|
package/lib/utils/server-util.js
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.ServerUtil = exports.PORT = exports.HOST = exports.PASSWORD = exports.IP = void 0;
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
+
const node_ssh_1 = require("node-ssh");
|
|
8
|
+
const child_process_1 = __importDefault(require("child_process"));
|
|
9
|
+
const ssh2_sftp_client_1 = __importDefault(require("ssh2-sftp-client"));
|
|
10
|
+
const fs_1 = __importDefault(require("fs"));
|
|
11
|
+
const mustache_1 = __importDefault(require("mustache"));
|
|
12
|
+
const { promisify } = require("util");
|
|
13
|
+
const execPromise = promisify(child_process_1.default.exec);
|
|
7
14
|
exports.IP = "185.123.53.227";
|
|
8
15
|
exports.PASSWORD = "xUA3oOX06Kfc9m12rZ";
|
|
9
16
|
exports.HOST = "cg-main-server.com";
|
|
@@ -27,10 +34,49 @@ class ServerUtil {
|
|
|
27
34
|
});
|
|
28
35
|
}
|
|
29
36
|
}
|
|
37
|
+
// SSH
|
|
38
|
+
async generateSSHKey() {
|
|
39
|
+
await this.exec(`ssh-keygen -t rsa -N '' -f ~/.ssh/id_rsa <<< n`);
|
|
40
|
+
let sshFingerprint = await this.exec(`cat ~/.ssh/id_rsa.pub`);
|
|
41
|
+
return sshFingerprint;
|
|
42
|
+
}
|
|
43
|
+
// create Directories in /Var
|
|
44
|
+
async createDirectories() {
|
|
45
|
+
await this.exec(`mkdir -p /var/www/ai`);
|
|
46
|
+
}
|
|
47
|
+
// install git
|
|
48
|
+
async installGit() {
|
|
49
|
+
await this.exec(`apt-get update; apt-get install -y git`);
|
|
50
|
+
}
|
|
51
|
+
// add ssh to bitbucket
|
|
52
|
+
async addBitbucketToKnownHosts() {
|
|
53
|
+
await this.exec(`ssh-keyscan bitbucket.org >> ~/.ssh/known_hosts`);
|
|
54
|
+
}
|
|
55
|
+
// clone bitbucket Repository
|
|
56
|
+
async cloneRepository(repoName, targetPath) {
|
|
57
|
+
let gitResponse = await this.exec(`git clone git@bitbucket.org:bprtsk/${repoName}.git`, { cwd: targetPath });
|
|
58
|
+
if (gitResponse.includes(`Please make sure you have the correct access rights`)) {
|
|
59
|
+
throw new Error(`No access to the remote repository!`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// не знаю чи треба але додав ?
|
|
63
|
+
// async checkoutBranch(branch: string, repoPath: string): Promise<void> {
|
|
64
|
+
// await this.exec(`git checkout -b ${branch}; git branch --set-upstream-to=origin/${branch} ${branch}; git reset --hard origin/${branch};`, { cwd: repoPath });
|
|
65
|
+
// }
|
|
66
|
+
// не знаю чи треба але додав ?
|
|
67
|
+
// async installJava(): Promise<void> {
|
|
68
|
+
// await this.exec(`apt-get update; apt-get install -y default-jre default-jdk`);
|
|
69
|
+
// }
|
|
70
|
+
// install Nginx
|
|
71
|
+
async installNginx() {
|
|
72
|
+
await this.exec(`apt-get update; apt-get install -y nginx`);
|
|
73
|
+
await this.exec(`systemctl enable nginx`);
|
|
74
|
+
await this.exec(`systemctl start nginx`);
|
|
75
|
+
}
|
|
30
76
|
// Nginx
|
|
31
77
|
async isNginxActive() {
|
|
32
78
|
try {
|
|
33
|
-
let result = await this.exec(
|
|
79
|
+
let result = await this.exec("systemctl status nginx");
|
|
34
80
|
if (result.includes("Active: active"))
|
|
35
81
|
return true;
|
|
36
82
|
}
|
|
@@ -42,7 +88,7 @@ class ServerUtil {
|
|
|
42
88
|
// Mongo
|
|
43
89
|
async isMongoActive() {
|
|
44
90
|
try {
|
|
45
|
-
let result = await this.exec(
|
|
91
|
+
let result = await this.exec("systemctl status mongod");
|
|
46
92
|
if (result.includes("Active: active"))
|
|
47
93
|
return true;
|
|
48
94
|
}
|
|
@@ -65,7 +111,7 @@ class ServerUtil {
|
|
|
65
111
|
systemctl enable mongod.service;
|
|
66
112
|
systemctl start mongod;
|
|
67
113
|
`;
|
|
68
|
-
//
|
|
114
|
+
// checking if nginx configuration exists
|
|
69
115
|
async domainNginxConfigExists(host) {
|
|
70
116
|
try {
|
|
71
117
|
let result = await this.exec(`ls ${this.DOMAIN_HOME}/${host}.nginx.ssl.conf`);
|
|
@@ -77,12 +123,22 @@ class ServerUtil {
|
|
|
77
123
|
}
|
|
78
124
|
return true;
|
|
79
125
|
}
|
|
80
|
-
//
|
|
81
|
-
|
|
126
|
+
// checking if the ssl certificate exists
|
|
127
|
+
async domainNginxCertsExist(host) {
|
|
128
|
+
try {
|
|
129
|
+
let result = await this.exec(`ls /etc/letsencrypt/live/${host}`);
|
|
130
|
+
if (result.includes("No such file or directory"))
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
catch (e) {
|
|
134
|
+
console.error(e);
|
|
135
|
+
}
|
|
136
|
+
return true;
|
|
137
|
+
}
|
|
82
138
|
// Certbot CRON
|
|
83
139
|
async isCerbotActive() {
|
|
84
140
|
try {
|
|
85
|
-
let result = await this.exec(
|
|
141
|
+
let result = await this.exec("which certbot");
|
|
86
142
|
if (result.includes("/usr/bin/certbot"))
|
|
87
143
|
return true;
|
|
88
144
|
}
|
|
@@ -91,21 +147,60 @@ class ServerUtil {
|
|
|
91
147
|
}
|
|
92
148
|
return false;
|
|
93
149
|
}
|
|
150
|
+
// install certbot
|
|
94
151
|
async setupCertbot() {
|
|
95
152
|
await this.exec(`apt-get install -y certbot python3-certbot-nginx;`);
|
|
96
153
|
return true;
|
|
97
154
|
}
|
|
155
|
+
// creating a SSL certificate
|
|
156
|
+
async setupSSL(email, host) {
|
|
157
|
+
let certbotResponse = await this.exec(`certbot --non-interactive --agree-tos --nginx -m "${email}" -d "${host}"`);
|
|
158
|
+
if (certbotResponse.includes(`Some challenges have failed.`)) {
|
|
159
|
+
throw new Error("Certbot encountered an error");
|
|
160
|
+
}
|
|
161
|
+
await this.exec(`echo "0 12 * * * /usr/bin/certbot renew --quiet" | crontab -`);
|
|
162
|
+
}
|
|
163
|
+
// Git
|
|
164
|
+
async refresh() {
|
|
165
|
+
await this.exec(`git stash; rm-rf built; git pull`);
|
|
166
|
+
return true;
|
|
167
|
+
}
|
|
168
|
+
async deployLandingPage(host, username, password, remotePath, files) {
|
|
169
|
+
let sftp = new ssh2_sftp_client_1.default();
|
|
170
|
+
try {
|
|
171
|
+
//connection to the server via sftp
|
|
172
|
+
await sftp.connect({ host, username, password });
|
|
173
|
+
// Завантажити файли на сервер
|
|
174
|
+
for (const file of files) {
|
|
175
|
+
await sftp.put(Buffer.from(file.content, "base64"), `${remotePath}/${file.name}`);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
finally {
|
|
179
|
+
sftp.end();
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
async generateNginxConfig(domain, rootPath) {
|
|
183
|
+
const template = fs_1.default.readFileSync("templates/nginx-template.conf", "utf8");
|
|
184
|
+
const config = mustache_1.default.render(template, { domain, rootPath });
|
|
185
|
+
return config;
|
|
186
|
+
}
|
|
187
|
+
async serverConect(IP) {
|
|
188
|
+
if (!this.ssh) {
|
|
189
|
+
this.ssh = new node_ssh_1.NodeSSH();
|
|
190
|
+
}
|
|
191
|
+
try {
|
|
192
|
+
await this.ssh.connect({
|
|
193
|
+
host: '46.246.98.201',
|
|
194
|
+
port: exports.PORT,
|
|
195
|
+
username: 'root',
|
|
196
|
+
password: 'A0a693E4CrK6tdvSlE',
|
|
197
|
+
});
|
|
198
|
+
return `Successfully connected to ${IP}`;
|
|
199
|
+
}
|
|
200
|
+
catch (error) {
|
|
201
|
+
console.error(`Failed to connect to ${IP}:`, error);
|
|
202
|
+
return `Failed to connect to ${IP}`;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
98
205
|
}
|
|
99
206
|
exports.ServerUtil = ServerUtil;
|
|
100
|
-
// (async () => {
|
|
101
|
-
// const ssh = new NodeSSH()
|
|
102
|
-
// await ssh.connect({
|
|
103
|
-
// host: IP,
|
|
104
|
-
// port: PORT,
|
|
105
|
-
// username: `root`,
|
|
106
|
-
// password: PASSWORD
|
|
107
|
-
// })
|
|
108
|
-
// let util = new ServerUtil(ssh)
|
|
109
|
-
// console.log(`Nginx is active: ${await util.isNginxActive()}`)
|
|
110
|
-
// process.exit(0)
|
|
111
|
-
// })()
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bprotsyk/aso-core",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.13",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"types": "lib/index.d.ts",
|
|
6
6
|
"scripts": {
|
|
@@ -30,17 +30,21 @@
|
|
|
30
30
|
"axios": "^1.4.0",
|
|
31
31
|
"module-alias": "^2.2.2",
|
|
32
32
|
"mongoose": "^6.8.3",
|
|
33
|
+
"mustache": "^4.2.0",
|
|
33
34
|
"node-ssh": "^13.2.0",
|
|
34
35
|
"react": "^18.3.1",
|
|
35
36
|
"react-dom": "^18.3.1",
|
|
36
37
|
"replace-in-file": "^7.0.1",
|
|
37
38
|
"sleep-promise": "^9.1.0",
|
|
39
|
+
"ssh2-sftp-client": "^11.0.0",
|
|
38
40
|
"styled-components": "^5.3.9"
|
|
39
41
|
},
|
|
40
42
|
"devDependencies": {
|
|
43
|
+
"@types/mustache": "^4.2.5",
|
|
41
44
|
"@types/node": "^20.14.12",
|
|
42
45
|
"@types/react": "^18.2.14",
|
|
43
46
|
"@types/react-dom": "^18.3.0",
|
|
47
|
+
"@types/ssh2-sftp-client": "^9.0.4",
|
|
44
48
|
"typedoc": "^0.23.28",
|
|
45
49
|
"typescript": "^4.9.5"
|
|
46
50
|
}
|
package/src/index.ts
CHANGED
|
@@ -29,4 +29,5 @@ export { IKeitaroStream } from "./keitaro/keitaro-stream"
|
|
|
29
29
|
|
|
30
30
|
export { ICloudflareDomainStatus, ICloudflareDomainType, ICloudflareDomain } from "./general/cloudflare-domain"
|
|
31
31
|
export { IDomain, IDomainSetupResult, DomainStatus, DomainTarget, CONST_CLOUFLARE_STATUS_READY, IDomainsBuyRequestResponse, getDomainTargetByIp } from "./general/domain"
|
|
32
|
-
export { INamecheapDomain, INamecheapBuyRequest, INamecheapContactInfo, NamecheapBuyRequestSchema, INamecheapGetDomainsResult, NamecheapBuyResult } from "./general/namecheap-domain"
|
|
32
|
+
export { INamecheapDomain, INamecheapBuyRequest, INamecheapContactInfo, NamecheapBuyRequestSchema, INamecheapGetDomainsResult, NamecheapBuyResult } from "./general/namecheap-domain"
|
|
33
|
+
export {ServerUtil} from './utils/server-util';
|
package/src/utils/server-util.ts
CHANGED
|
@@ -1,56 +1,120 @@
|
|
|
1
1
|
import { NodeSSH } from "node-ssh";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
export let
|
|
2
|
+
import ChildProcess from "child_process";
|
|
3
|
+
import Client from "ssh2-sftp-client";
|
|
4
|
+
import fs from "fs";
|
|
5
|
+
import mustache from "mustache";
|
|
6
|
+
const { promisify } = require("util");
|
|
7
|
+
const execPromise = promisify(ChildProcess.exec);
|
|
8
|
+
|
|
9
|
+
export let IP = "185.123.53.227";
|
|
10
|
+
export let PASSWORD = "xUA3oOX06Kfc9m12rZ";
|
|
11
|
+
export let HOST = "cg-main-server.com";
|
|
12
|
+
export let PORT = 56777;
|
|
10
13
|
|
|
11
14
|
export class ServerUtil {
|
|
12
|
-
|
|
15
|
+
DOMAIN_HOME = "/etc/nginx/sites-enabled";
|
|
16
|
+
|
|
17
|
+
ssh?: NodeSSH;
|
|
18
|
+
|
|
19
|
+
constructor(ssh?: NodeSSH) {
|
|
20
|
+
this.ssh = ssh;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Выконує команду або по SSH або локально, повертаючи текст незалежно від результату (помилка чи успіх)
|
|
24
|
+
async exec(command: string, options?: any): Promise<string> {
|
|
25
|
+
if (this.ssh) {
|
|
26
|
+
return (await this.ssh.execCommand(command, options)).stdout;
|
|
27
|
+
} else {
|
|
28
|
+
return await new Promise<string>((resolve) => {
|
|
29
|
+
execPromise(command, (err: string, stdout: string) => {
|
|
30
|
+
resolve(stdout);
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// SSH
|
|
37
|
+
async generateSSHKey(): Promise<string> {
|
|
38
|
+
await this.exec(`ssh-keygen -t rsa -N '' -f ~/.ssh/id_rsa <<< n`);
|
|
39
|
+
let sshFingerprint = await this.exec(`cat ~/.ssh/id_rsa.pub`);
|
|
40
|
+
return sshFingerprint;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// create Directories in /Var
|
|
44
|
+
async createDirectories(): Promise<void> {
|
|
45
|
+
await this.exec(`mkdir -p /var/www/ai`);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// install git
|
|
49
|
+
async installGit(): Promise<void> {
|
|
50
|
+
await this.exec(`apt-get update; apt-get install -y git`);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// add ssh to bitbucket
|
|
54
|
+
async addBitbucketToKnownHosts(): Promise<void> {
|
|
55
|
+
await this.exec(`ssh-keyscan bitbucket.org >> ~/.ssh/known_hosts`);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// clone bitbucket Repository
|
|
59
|
+
async cloneRepository(repoName: string, targetPath: string): Promise<void> {
|
|
60
|
+
let gitResponse = await this.exec(
|
|
61
|
+
`git clone git@bitbucket.org:bprtsk/${repoName}.git`,
|
|
62
|
+
{ cwd: targetPath }
|
|
63
|
+
);
|
|
64
|
+
if (
|
|
65
|
+
gitResponse.includes(
|
|
66
|
+
`Please make sure you have the correct access rights`
|
|
67
|
+
)
|
|
68
|
+
) {
|
|
69
|
+
throw new Error(`No access to the remote repository!`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
13
72
|
|
|
14
|
-
|
|
73
|
+
// не знаю чи треба але додав ?
|
|
15
74
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
75
|
+
// async checkoutBranch(branch: string, repoPath: string): Promise<void> {
|
|
76
|
+
// await this.exec(`git checkout -b ${branch}; git branch --set-upstream-to=origin/${branch} ${branch}; git reset --hard origin/${branch};`, { cwd: repoPath });
|
|
77
|
+
// }
|
|
19
78
|
|
|
20
|
-
|
|
21
|
-
async exec(command: string, options?: any): Promise<string> {
|
|
22
|
-
if (this.ssh) {
|
|
23
|
-
return (await this.ssh.execCommand(command, options)).stdout
|
|
24
|
-
} else {
|
|
25
|
-
return await new Promise<string>((resolve) => {
|
|
26
|
-
execPromise(command, (err: string, stdout: string) => {
|
|
27
|
-
resolve(stdout)
|
|
28
|
-
});
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
}
|
|
79
|
+
// не знаю чи треба але додав ?
|
|
32
80
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
let result = await this.exec('systemctl status nginx')
|
|
37
|
-
if (result.includes("Active: active")) return true
|
|
38
|
-
} catch (e) { console.error(e) }
|
|
81
|
+
// async installJava(): Promise<void> {
|
|
82
|
+
// await this.exec(`apt-get update; apt-get install -y default-jre default-jdk`);
|
|
83
|
+
// }
|
|
39
84
|
|
|
40
|
-
|
|
85
|
+
// install Nginx
|
|
86
|
+
|
|
87
|
+
async installNginx(): Promise<void> {
|
|
88
|
+
await this.exec(`apt-get update; apt-get install -y nginx`);
|
|
89
|
+
await this.exec(`systemctl enable nginx`);
|
|
90
|
+
await this.exec(`systemctl start nginx`);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Nginx
|
|
94
|
+
async isNginxActive(): Promise<boolean> {
|
|
95
|
+
try {
|
|
96
|
+
let result = await this.exec("systemctl status nginx");
|
|
97
|
+
if (result.includes("Active: active")) return true;
|
|
98
|
+
} catch (e) {
|
|
99
|
+
console.error(e);
|
|
41
100
|
}
|
|
42
101
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
try {
|
|
46
|
-
let result = await this.exec('systemctl status mongod')
|
|
47
|
-
if (result.includes("Active: active")) return true
|
|
48
|
-
} catch (e) { console.error(e) }
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
49
104
|
|
|
50
|
-
|
|
105
|
+
// Mongo
|
|
106
|
+
async isMongoActive(): Promise<boolean> {
|
|
107
|
+
try {
|
|
108
|
+
let result = await this.exec("systemctl status mongod");
|
|
109
|
+
if (result.includes("Active: active")) return true;
|
|
110
|
+
} catch (e) {
|
|
111
|
+
console.error(e);
|
|
51
112
|
}
|
|
52
113
|
|
|
53
|
-
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
mongoInstallCommand = `
|
|
54
118
|
echo "deb http://security.ubuntu.com/ubuntu focal-security main" | tee /etc/apt/sources.list.d/focal-security.list;
|
|
55
119
|
apt-get update;
|
|
56
120
|
apt-get install libssl1.1;
|
|
@@ -63,61 +127,126 @@ export class ServerUtil {
|
|
|
63
127
|
apt-get install -y mongodb-org;
|
|
64
128
|
systemctl enable mongod.service;
|
|
65
129
|
systemctl start mongod;
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
return true
|
|
130
|
+
`;
|
|
131
|
+
|
|
132
|
+
// checking if nginx configuration exists
|
|
133
|
+
async domainNginxConfigExists(host: string): Promise<boolean> {
|
|
134
|
+
try {
|
|
135
|
+
let result = await this.exec(
|
|
136
|
+
`ls ${this.DOMAIN_HOME}/${host}.nginx.ssl.conf`
|
|
137
|
+
);
|
|
138
|
+
if (result.includes("No such file or directory")) return false;
|
|
139
|
+
} catch (e) {
|
|
140
|
+
console.error(e);
|
|
79
141
|
}
|
|
80
142
|
|
|
81
|
-
|
|
143
|
+
return true;
|
|
144
|
+
}
|
|
82
145
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
146
|
+
// checking if the ssl certificate exists
|
|
147
|
+
async domainNginxCertsExist(host: string): Promise<boolean> {
|
|
148
|
+
try {
|
|
149
|
+
let result = await this.exec(`ls /etc/letsencrypt/live/${host}`);
|
|
150
|
+
if (result.includes("No such file or directory")) return false;
|
|
151
|
+
} catch (e) {
|
|
152
|
+
console.error(e);
|
|
153
|
+
}
|
|
154
|
+
return true;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Certbot CRON
|
|
158
|
+
async isCerbotActive(): Promise<boolean> {
|
|
159
|
+
try {
|
|
160
|
+
let result = await this.exec("which certbot");
|
|
161
|
+
if (result.includes("/usr/bin/certbot")) return true;
|
|
162
|
+
} catch (e) {
|
|
163
|
+
console.error(e);
|
|
164
|
+
}
|
|
91
165
|
|
|
92
|
-
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// install certbot
|
|
170
|
+
async setupCertbot(): Promise<boolean> {
|
|
171
|
+
await this.exec(`apt-get install -y certbot python3-certbot-nginx;`);
|
|
172
|
+
|
|
173
|
+
return true;
|
|
174
|
+
}
|
|
175
|
+
// creating a SSL certificate
|
|
176
|
+
async setupSSL(email: string, host: string): Promise<void> {
|
|
177
|
+
let certbotResponse = await this.exec(
|
|
178
|
+
`certbot --non-interactive --agree-tos --nginx -m "${email}" -d "${host}"`
|
|
179
|
+
);
|
|
180
|
+
if (certbotResponse.includes(`Some challenges have failed.`)) {
|
|
181
|
+
throw new Error("Certbot encountered an error");
|
|
182
|
+
}
|
|
183
|
+
await this.exec(
|
|
184
|
+
`echo "0 12 * * * /usr/bin/certbot renew --quiet" | crontab -`
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Git
|
|
189
|
+
async refresh(): Promise<boolean> {
|
|
190
|
+
await this.exec(`git stash; rm-rf built; git pull`);
|
|
191
|
+
|
|
192
|
+
return true;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
async deployLandingPage(
|
|
198
|
+
host: string,
|
|
199
|
+
username: string,
|
|
200
|
+
password: string,
|
|
201
|
+
remotePath: string,
|
|
202
|
+
files: any
|
|
203
|
+
): Promise<void> {
|
|
204
|
+
let sftp = new Client();
|
|
205
|
+
try {
|
|
206
|
+
//connection to the server via sftp
|
|
207
|
+
await sftp.connect({ host, username, password });
|
|
208
|
+
|
|
209
|
+
// Завантажити файли на сервер
|
|
210
|
+
for (const file of files) {
|
|
211
|
+
await sftp.put(
|
|
212
|
+
Buffer.from(file.content, "base64"),
|
|
213
|
+
`${remotePath}/${file.name}`
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
} finally {
|
|
217
|
+
sftp.end();
|
|
93
218
|
}
|
|
219
|
+
}
|
|
94
220
|
|
|
95
|
-
|
|
96
|
-
|
|
221
|
+
async generateNginxConfig(domain: string, rootPath: string): Promise<string> {
|
|
222
|
+
const template = fs.readFileSync("templates/nginx-template.conf", "utf8");
|
|
223
|
+
const config = mustache.render(template, { domain, rootPath });
|
|
224
|
+
return config;
|
|
225
|
+
}
|
|
97
226
|
|
|
98
|
-
|
|
227
|
+
async serverConect(IP: string): Promise<string> {
|
|
228
|
+
if (!this.ssh) {
|
|
229
|
+
this.ssh = new NodeSSH();
|
|
99
230
|
}
|
|
100
231
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
232
|
+
try {
|
|
233
|
+
await this.ssh.connect({
|
|
234
|
+
host: '46.246.98.201',
|
|
235
|
+
port: PORT,
|
|
236
|
+
username: 'root',
|
|
237
|
+
password: 'A0a693E4CrK6tdvSlE',
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
return `Successfully connected to ${IP}`;
|
|
241
|
+
} catch (error) {
|
|
242
|
+
console.error(`Failed to connect to ${IP}:`, error);
|
|
243
|
+
return `Failed to connect to ${IP}`;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
105
247
|
}
|
|
106
248
|
|
|
107
249
|
|
|
108
|
-
// (async () => {
|
|
109
|
-
// const ssh = new NodeSSH()
|
|
110
|
-
|
|
111
|
-
// await ssh.connect({
|
|
112
|
-
// host: IP,
|
|
113
|
-
// port: PORT,
|
|
114
|
-
// username: `root`,
|
|
115
|
-
// password: PASSWORD
|
|
116
|
-
// })
|
|
117
250
|
|
|
118
|
-
// let util = new ServerUtil(ssh)
|
|
119
251
|
|
|
120
|
-
// console.log(`Nginx is active: ${await util.isNginxActive()}`)
|
|
121
252
|
|
|
122
|
-
// process.exit(0)
|
|
123
|
-
// })()
|