fix: Proxy configuration improvements

This commit is contained in:
Davidson Gomes 2023-12-28 10:35:41 -03:00
parent dfc8330035
commit 7c2a8c0abb
10 changed files with 111 additions and 33 deletions

View File

@ -1,3 +1,10 @@
# 1.6.2 (develop)
### Fixed
* Proxy configuration improvements
* Correction in sending lists
# 1.6.1 (2023-12-22 11:43) # 1.6.1 (2023-12-22 11:43)
### Fixed ### Fixed

View File

@ -1086,7 +1086,18 @@ export const proxySchema: JSONSchema7 = {
type: 'object', type: 'object',
properties: { properties: {
enabled: { type: 'boolean', enum: [true, false] }, enabled: { type: 'boolean', enum: [true, false] },
proxy: { type: 'string' }, proxy: {
type: 'object',
properties: {
host: { type: 'string' },
port: { type: 'string' },
protocol: { type: 'string' },
username: { type: 'string' },
password: { type: 'string' },
},
required: ['host', 'port', 'protocol'],
...isNotEmpty('host', 'port', 'protocol'),
},
}, },
required: ['enabled', 'proxy'], required: ['enabled', 'proxy'],
...isNotEmpty('enabled', 'proxy'), ...isNotEmpty('enabled', 'proxy'),

View File

@ -12,7 +12,6 @@ import { RepositoryBroker } from '../repository/repository.manager';
import { AuthService, OldToken } from '../services/auth.service'; import { AuthService, OldToken } from '../services/auth.service';
import { ChatwootService } from '../services/chatwoot.service'; import { ChatwootService } from '../services/chatwoot.service';
import { WAMonitoringService } from '../services/monitor.service'; import { WAMonitoringService } from '../services/monitor.service';
import { ProxyService } from '../services/proxy.service';
import { RabbitmqService } from '../services/rabbitmq.service'; import { RabbitmqService } from '../services/rabbitmq.service';
import { SettingsService } from '../services/settings.service'; import { SettingsService } from '../services/settings.service';
import { SqsService } from '../services/sqs.service'; import { SqsService } from '../services/sqs.service';
@ -34,7 +33,6 @@ export class InstanceController {
private readonly settingsService: SettingsService, private readonly settingsService: SettingsService,
private readonly websocketService: WebsocketService, private readonly websocketService: WebsocketService,
private readonly rabbitmqService: RabbitmqService, private readonly rabbitmqService: RabbitmqService,
private readonly proxyService: ProxyService,
private readonly sqsService: SqsService, private readonly sqsService: SqsService,
private readonly typebotService: TypebotService, private readonly typebotService: TypebotService,
private readonly cache: RedisCache, private readonly cache: RedisCache,
@ -76,7 +74,6 @@ export class InstanceController {
typebot_delay_message, typebot_delay_message,
typebot_unknown_message, typebot_unknown_message,
typebot_listening_from_me, typebot_listening_from_me,
proxy,
}: InstanceDto) { }: InstanceDto) {
try { try {
this.logger.verbose('requested createInstance from ' + instanceName + ' instance'); this.logger.verbose('requested createInstance from ' + instanceName + ' instance');
@ -259,22 +256,6 @@ export class InstanceController {
} }
} }
if (proxy) {
this.logger.verbose('creating proxy');
try {
this.proxyService.create(
instance,
{
enabled: true,
proxy,
},
false,
);
} catch (error) {
this.logger.log(error);
}
}
let sqsEvents: string[]; let sqsEvents: string[];
if (sqs_enabled) { if (sqs_enabled) {
@ -406,7 +387,6 @@ export class InstanceController {
}, },
settings, settings,
qrcode: getQrcode, qrcode: getQrcode,
proxy,
}; };
this.logger.verbose('instance created'); this.logger.verbose('instance created');
@ -510,7 +490,6 @@ export class InstanceController {
name_inbox: instance.instanceName, name_inbox: instance.instanceName,
webhook_url: `${urlServer}/chatwoot/webhook/${encodeURIComponent(instance.instanceName)}`, webhook_url: `${urlServer}/chatwoot/webhook/${encodeURIComponent(instance.instanceName)}`,
}, },
proxy,
}; };
} catch (error) { } catch (error) {
this.logger.error(error.message[0]); this.logger.error(error.message[0]);

View File

@ -1,4 +1,7 @@
import axios from 'axios';
import { Logger } from '../../config/logger.config'; import { Logger } from '../../config/logger.config';
import { BadRequestException } from '../../exceptions';
import { InstanceDto } from '../dto/instance.dto'; import { InstanceDto } from '../dto/instance.dto';
import { ProxyDto } from '../dto/proxy.dto'; import { ProxyDto } from '../dto/proxy.dto';
import { ProxyService } from '../services/proxy.service'; import { ProxyService } from '../services/proxy.service';
@ -13,7 +16,16 @@ export class ProxyController {
if (!data.enabled) { if (!data.enabled) {
logger.verbose('proxy disabled'); logger.verbose('proxy disabled');
data.proxy = ''; data.proxy = null;
}
if (data.proxy) {
logger.verbose('proxy enabled');
const { host, port, protocol, username, password } = data.proxy;
const testProxy = await this.testProxy(host, port, protocol, username, password);
if (!testProxy) {
throw new BadRequestException('Invalid proxy');
}
} }
return this.proxyService.create(instance, data); return this.proxyService.create(instance, data);
@ -23,4 +35,36 @@ export class ProxyController {
logger.verbose('requested findProxy from ' + instance.instanceName + ' instance'); logger.verbose('requested findProxy from ' + instance.instanceName + ' instance');
return this.proxyService.find(instance); return this.proxyService.find(instance);
} }
private async testProxy(host: string, port: string, protocol: string, username?: string, password?: string) {
logger.verbose('requested testProxy');
try {
let proxyConfig: any = {
host: host,
port: parseInt(port),
protocol: protocol,
};
if (username && password) {
proxyConfig = {
...proxyConfig,
auth: {
username: username,
password: password,
},
};
}
const serverIp = await axios.get('http://meuip.com/api/meuip.php');
const response = await axios.get('http://meuip.com/api/meuip.php', {
proxy: proxyConfig,
});
logger.verbose('testProxy response: ' + response.data);
return response.data !== serverIp.data;
} catch (error) {
logger.error('testProxy error: ' + error);
return false;
}
}
} }

View File

@ -1,4 +1,12 @@
class Proxy {
host: string;
port: string;
protocol: string;
username?: string;
password?: string;
}
export class ProxyDto { export class ProxyDto {
enabled: boolean; enabled: boolean;
proxy: string; proxy: Proxy;
} }

View File

@ -2,16 +2,30 @@ import { Schema } from 'mongoose';
import { dbserver } from '../../libs/db.connect'; import { dbserver } from '../../libs/db.connect';
class Proxy {
host?: string;
port?: string;
protocol?: string;
username?: string;
password?: string;
}
export class ProxyRaw { export class ProxyRaw {
_id?: string; _id?: string;
enabled?: boolean; enabled?: boolean;
proxy?: string; proxy?: Proxy;
} }
const proxySchema = new Schema<ProxyRaw>({ const proxySchema = new Schema<ProxyRaw>({
_id: { type: String, _id: true }, _id: { type: String, _id: true },
enabled: { type: Boolean, required: true }, enabled: { type: Boolean, required: true },
proxy: { type: String, required: true }, proxy: {
host: { type: String, required: true },
port: { type: String, required: true },
protocol: { type: String, required: true },
username: { type: String, required: false },
password: { type: String, required: false },
},
}); });
export const ProxyModel = dbserver?.model(ProxyRaw.name, proxySchema, 'proxy'); export const ProxyModel = dbserver?.model(ProxyRaw.name, proxySchema, 'proxy');

View File

@ -27,7 +27,7 @@ export class ProxyService {
return result; return result;
} catch (error) { } catch (error) {
return { enabled: false, proxy: '' }; return { enabled: false, proxy: null };
} }
} }
} }

View File

@ -1369,8 +1369,8 @@ export class WAStartupService {
if (this.localProxy.enabled) { if (this.localProxy.enabled) {
this.logger.info('Proxy enabled: ' + this.localProxy.proxy); this.logger.info('Proxy enabled: ' + this.localProxy.proxy);
if (this.localProxy.proxy.includes('proxyscrape')) { if (this.localProxy.proxy.host.includes('proxyscrape')) {
const response = await axios.get(this.localProxy.proxy); const response = await axios.get(this.localProxy.proxy.host);
const text = response.data; const text = response.data;
const proxyUrls = text.split('\r\n'); const proxyUrls = text.split('\r\n');
const rand = Math.floor(Math.random() * Math.floor(proxyUrls.length)); const rand = Math.floor(Math.random() * Math.floor(proxyUrls.length));
@ -1379,8 +1379,15 @@ export class WAStartupService {
agent: new ProxyAgent(proxyUrl as any), agent: new ProxyAgent(proxyUrl as any),
}; };
} else { } else {
let proxyUri =
this.localProxy.proxy.protocol + '://' + this.localProxy.proxy.host + ':' + this.localProxy.proxy.port;
if (this.localProxy.proxy.username && this.localProxy.proxy.password) {
proxyUri = `${this.localProxy.proxy.username}:${this.localProxy.proxy.password}@${proxyUri}`;
}
options = { options = {
agent: new ProxyAgent(this.localProxy.proxy as any), agent: new ProxyAgent(proxyUri as any),
}; };
} }
} }
@ -1903,7 +1910,8 @@ export class WAStartupService {
this.logger.verbose('group ignored'); this.logger.verbose('group ignored');
return; return;
} }
if (key.remoteJid !== 'status@broadcast' && !key?.remoteJid?.match(/(:\d+)/)) { // if (key.remoteJid !== 'status@broadcast' && !key?.remoteJid?.match(/(:\d+)/)) {
if (key.remoteJid !== 'status@broadcast') {
this.logger.verbose('Message update is valid'); this.logger.verbose('Message update is valid');
let pollUpdates: any; let pollUpdates: any;

View File

@ -109,9 +109,17 @@ export declare namespace wa {
sessions?: Session[]; sessions?: Session[];
}; };
type Proxy = {
host?: string;
port?: string;
protocol?: string;
username?: string;
password?: string;
};
export type LocalProxy = { export type LocalProxy = {
enabled?: boolean; enabled?: boolean;
proxy?: string; proxy?: Proxy;
}; };
export type LocalChamaai = { export type LocalChamaai = {

View File

@ -148,7 +148,6 @@ export const instanceController = new InstanceController(
settingsService, settingsService,
websocketService, websocketService,
rabbitmqService, rabbitmqService,
proxyService,
sqsService, sqsService,
typebotService, typebotService,
cache, cache,