diff --git a/.github/workflows/e2e-linux.yml b/.github/workflows/e2e-linux.yml index 6fcfe83493..1756069a6c 100644 --- a/.github/workflows/e2e-linux.yml +++ b/.github/workflows/e2e-linux.yml @@ -67,17 +67,17 @@ jobs: max_attempts: 3 command: cd packages/e2e-tests && npm run test invitationLink.test.ts - - name: Download App Image 1.2.0 - working-directory: ./packages/e2e-tests/Quiet - run: curl -LO https://github.com/TryQuiet/quiet/releases/download/quiet%401.2.0/Quiet-1.2.0.AppImage + # - name: Download App Image 1.2.0 + # working-directory: ./packages/e2e-tests/Quiet + # run: curl -LO https://github.com/TryQuiet/quiet/releases/download/quiet%401.2.0/Quiet-1.2.0.AppImage - - name: Chmod App Image 1.2.0 - working-directory: ./packages/e2e-tests/Quiet - run: chmod +x Quiet-1.2.0.AppImage + # - name: Chmod App Image 1.2.0 + # working-directory: ./packages/e2e-tests/Quiet + # run: chmod +x Quiet-1.2.0.AppImage - - name: Run Backwards Compatibility test - uses: nick-fields/retry@v2 - with: - timeout_minutes: 15 - max_attempts: 3 - command: cd packages/e2e-tests && npm run test backwardsCompatibility.test.ts \ No newline at end of file + # - name: Run Backwards Compatibility test + # uses: nick-fields/retry@v2 + # with: + # timeout_minutes: 15 + # max_attempts: 3 + # command: cd packages/e2e-tests && npm run test backwardsCompatibility.test.ts \ No newline at end of file diff --git a/.github/workflows/e2e-mac.yml b/.github/workflows/e2e-mac.yml index a835a24d28..8e1b0c5e17 100644 --- a/.github/workflows/e2e-mac.yml +++ b/.github/workflows/e2e-mac.yml @@ -47,27 +47,13 @@ jobs: - name: Add App file to applications run: cd ~ && cp -R "/Volumes/Quiet $VERSION/Quiet.app" /Applications - - name: Change name dir - run: cd ~ && mv /Applications/Quiet.app /Applications/Quiet-Latest.app - - # OLD ver - - name: Download DMG 1.2.0 - working-directory: ./packages/e2e-tests/Quiet - run: curl -LO https://github.com/TryQuiet/quiet/releases/download/quiet%401.2.0/Quiet-1.2.0.dmg - - - name: Chmod 1.2.0 - working-directory: ./packages/e2e-tests/Quiet - run: chmod +x Quiet-1.2.0.dmg - - - name: Mount installer file in volume on system 1.2.0 - working-directory: ./packages/e2e-tests/Quiet - run: hdiutil mount Quiet-1.2.0.dmg - - - name: Add App file to applications 1.2.0 - run: cd ~ && cp -R "/Volumes/Quiet 1.2.0/Quiet.app" /Applications - + - name: Run invitation link test - Includes 2 separate application clients + uses: nick-fields/retry@v2 + with: + timeout_minutes: 25 + max_attempts: 3 + command: cd packages/e2e-tests && npm run test invitationLink.test.ts - # OLD ver - name: Run one client test uses: nick-fields/retry@v2 with: @@ -75,13 +61,6 @@ jobs: max_attempts: 3 command: cd packages/e2e-tests && npm run test oneClient.test.ts - # - name: Run Backwards Compatibility test - # uses: nick-fields/retry@v2 - # with: - # timeout_minutes: 15 - # max_attempts: 3 - # command: cd packages/e2e-tests && npm run test backwardsCompatibility.test.ts - - name: Run two clients test uses: nick-fields/retry@v2 with: @@ -89,9 +68,4 @@ jobs: max_attempts: 3 command: cd packages/e2e-tests && npm run test twoClients.test.ts - - name: Run invitation link test - Includes 2 separate application clients - uses: nick-fields/retry@v2 - with: - timeout_minutes: 25 - max_attempts: 3 - command: cd packages/e2e-tests && npm run test invitationLink.test.ts + diff --git a/README.md b/README.md index ad7fa0c922..61769a5524 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Encrypted p2p team chat with no servers, just Tor.
- Downloads | + Downloads | How it Works | Features | Threat Model | @@ -52,7 +52,7 @@ See our [FAQ](https://github.com/TryQuiet/monorepo/wiki/Quiet-FAQ) for answers t ## Getting started -To try Quiet, download the [latest release](https://github.com/TryQuiet/quiet/releases/tag/quiet%401.4.0) for your platform (.dmg for macOS, .exe for Windows, etc.) and install it in the normal way. Then create a community and open the community's settings to invite members. +To try Quiet, download the [latest release](https://github.com/TryQuiet/quiet/releases/tag/quiet%401.8.0) for your platform (.dmg for macOS, .exe for Windows, etc.) and install it in the normal way. Then create a community and open the community's settings to invite members. If you'd like to help develop Quiet, see [Contributing to Quiet](#contributing-to-quiet). diff --git a/packages/backend-bundle/CHANGELOG.md b/packages/backend-bundle/CHANGELOG.md index 1c24d6ebc9..1ff8b2c0e0 100644 --- a/packages/backend-bundle/CHANGELOG.md +++ b/packages/backend-bundle/CHANGELOG.md @@ -3,6 +3,30 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.6.0](/compare/backend-bundle@1.6.0-alpha.0...backend-bundle@1.6.0) (2023-08-28) + +**Note:** Version bump only for package backend-bundle + + + + + +# [1.6.0-alpha.0](https://github.com/TryQuiet/quiet/compare/backend-bundle@1.5.0...backend-bundle@1.6.0-alpha.0) (2023-08-25) + +**Note:** Version bump only for package backend-bundle + + + + + +# [1.5.0](https://github.com/TryQuiet/quiet/compare/backend-bundle@1.4.0...backend-bundle@1.5.0) (2023-08-17) + +**Note:** Version bump only for package backend-bundle + + + + + # [1.4.0](https://github.com/ZbayApp/monorepo/compare/backend-bundle@1.4.0-alpha.1...backend-bundle@1.4.0) (2023-07-28) **Note:** Version bump only for package backend-bundle diff --git a/packages/backend-bundle/package-lock.json b/packages/backend-bundle/package-lock.json index bf24b88bc9..ae6447527c 100644 --- a/packages/backend-bundle/package-lock.json +++ b/packages/backend-bundle/package-lock.json @@ -1,12 +1,12 @@ { "name": "backend-bundle", - "version": "1.4.0", + "version": "1.6.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "backend-bundle", - "version": "1.4.0", + "version": "1.6.0", "license": "ISC" } } diff --git a/packages/backend-bundle/package.json b/packages/backend-bundle/package.json index 679f4e880a..46f3d0208f 100644 --- a/packages/backend-bundle/package.json +++ b/packages/backend-bundle/package.json @@ -1,6 +1,6 @@ { "name": "backend-bundle", - "version": "1.4.0", + "version": "1.6.0", "description": "", "main": "bundle.cjs", "scripts": {}, diff --git a/packages/backend/CHANGELOG.md b/packages/backend/CHANGELOG.md index 0e00c3c325..98138e28b3 100644 --- a/packages/backend/CHANGELOG.md +++ b/packages/backend/CHANGELOG.md @@ -3,6 +3,30 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.9.0](https://github.com/TryQuiet/backend/compare/@quiet/backend@1.9.0-alpha.0...@quiet/backend@1.9.0) (2023-08-28) + +**Note:** Version bump only for package @quiet/backend + + + + + +# [1.9.0-alpha.0](https://github.com/TryQuiet/backend/compare/@quiet/backend@1.8.0...@quiet/backend@1.9.0-alpha.0) (2023-08-25) + +**Note:** Version bump only for package @quiet/backend + + + + + +# [1.8.0](https://github.com/TryQuiet/backend/compare/@quiet/backend@1.7.1-alpha.3...@quiet/backend@1.8.0) (2023-08-17) + +**Note:** Version bump only for package @quiet/backend + + + + + ## [1.7.1-alpha.3](https://github.com/TryQuiet/backend/compare/@quiet/backend@1.7.1-alpha.2...@quiet/backend@1.7.1-alpha.3) (2023-08-11) **Note:** Version bump only for package @quiet/backend diff --git a/packages/backend/package-lock.json b/packages/backend/package-lock.json index 9f31e3eaec..90135f3d8a 100644 --- a/packages/backend/package-lock.json +++ b/packages/backend/package-lock.json @@ -1,12 +1,12 @@ { "name": "@quiet/backend", - "version": "1.7.1-alpha.3", + "version": "1.9.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@quiet/backend", - "version": "1.7.1-alpha.3", + "version": "1.9.0", "license": "MIT", "dependencies": { "@chainsafe/libp2p-gossipsub": "6.1.0", diff --git a/packages/backend/package.json b/packages/backend/package.json index a4ebd1cc60..73d5e57687 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -1,6 +1,6 @@ { "name": "@quiet/backend", - "version": "1.7.1-alpha.3", + "version": "1.9.0", "description": "tlg-manager", "types": "lib/index.d.ts", "type": "module", @@ -53,8 +53,8 @@ "@nestjs/cli": "^10.0.0", "@nestjs/schematics": "^10.0.0", "@nestjs/testing": "^10.0.0", - "@quiet/eslint-config": "^1.1.0", - "@quiet/state-manager": "^1.7.1-alpha.1", + "@quiet/eslint-config": "^1.3.0", + "@quiet/state-manager": "^1.9.0", "@types/crypto-js": "^4.0.2", "@types/express": "^4.17.9", "@types/jest": "28.1.8", @@ -89,10 +89,10 @@ "@nestjs/core": "^10.0.0", "@nestjs/platform-express": "^10.0.0", "@peculiar/webcrypto": "1.4.3", - "@quiet/common": "^1.6.0", - "@quiet/identity": "^1.6.0", - "@quiet/logger": "^1.4.0", - "@quiet/types": "^1.6.0", + "@quiet/common": "^1.8.0", + "@quiet/identity": "^1.8.0", + "@quiet/logger": "^1.6.0", + "@quiet/types": "^1.8.0", "abortable-iterator": "^3.0.0", "class-transformer": "^0.5.1", "class-validator": "^0.13.1", diff --git a/packages/backend/src/nest/common/utils.ts b/packages/backend/src/nest/common/utils.ts index d4b62b76c5..22e843a62c 100644 --- a/packages/backend/src/nest/common/utils.ts +++ b/packages/backend/src/nest/common/utils.ts @@ -144,11 +144,11 @@ export const torDirForPlatform = (basePath?: string): string => { } export const createLibp2pAddress = (address: string, peerId: string) => { - return `/dns4/${address}/tcp/443/wss/p2p/${peerId}` + return `/dns4/${address}/tcp/80/ws/p2p/${peerId}` } export const createLibp2pListenAddress = (address: string) => { - return `/dns4/${address}/tcp/443/wss` + return `/dns4/${address}/tcp/80/ws` } export const getUsersAddresses = async (users: User[]): Promise => { diff --git a/packages/backend/src/nest/connections-manager/connections-manager.service.ts b/packages/backend/src/nest/connections-manager/connections-manager.service.ts index 1f9b88290c..4f476ea334 100644 --- a/packages/backend/src/nest/connections-manager/connections-manager.service.ts +++ b/packages/backend/src/nest/connections-manager/connections-manager.service.ts @@ -209,6 +209,7 @@ export class ConnectionsManagerService extends EventEmitter implements OnModuleI } public async leaveCommunity() { + this.tor.resetHiddenServices() this.serverIoProvider.io.close() await this.localDbService.purge() await this.closeAllServices({ saveTor: true }) diff --git a/packages/backend/src/nest/libp2p/libp2p.service.spec.ts b/packages/backend/src/nest/libp2p/libp2p.service.spec.ts index 4c032fd705..2c6d1159b5 100644 --- a/packages/backend/src/nest/libp2p/libp2p.service.spec.ts +++ b/packages/backend/src/nest/libp2p/libp2p.service.spec.ts @@ -38,11 +38,13 @@ describe('Libp2pService', () => { it('creates libp2p address with proper ws type (%s)', async () => { const libp2pAddress = libp2pService.createLibp2pAddress(params.localAddress, params.peerId.toString()) - expect(libp2pAddress).toStrictEqual(`/dns4/${params.localAddress}/tcp/443/wss/p2p/${params.peerId.toString()}`) + expect(libp2pAddress).toStrictEqual( + `/dns4/${params.localAddress}.onion/tcp/80/wss/p2p/${params.peerId.toString()}` + ) }) it('creates libp2p listen address', async () => { - const libp2pListenAddress = libp2pService.createLibp2pListenAddress(params.listenAddresses[0]) - expect(libp2pListenAddress).toStrictEqual(`/dns4/${params.listenAddresses}/tcp/443/wss`) + const libp2pListenAddress = libp2pService.createLibp2pListenAddress('onionAddress') + expect(libp2pListenAddress).toStrictEqual(`/dns4/onionAddress.onion/tcp/80/wss`) }) }) diff --git a/packages/backend/src/nest/libp2p/libp2p.service.ts b/packages/backend/src/nest/libp2p/libp2p.service.ts index f35a3b6893..fa98820843 100644 --- a/packages/backend/src/nest/libp2p/libp2p.service.ts +++ b/packages/backend/src/nest/libp2p/libp2p.service.ts @@ -78,9 +78,6 @@ export class Libp2pService extends EventEmitter { filter: all, websocket: { agent: params.agent, - cert: params.cert, - key: params.key, - ca: params.ca, }, localAddress: params.localAddress, targetPort: params.targetPort, diff --git a/packages/backend/src/nest/libp2p/libp2p.utils.ts b/packages/backend/src/nest/libp2p/libp2p.utils.ts index 32f0379d7d..447ffa9267 100644 --- a/packages/backend/src/nest/libp2p/libp2p.utils.ts +++ b/packages/backend/src/nest/libp2p/libp2p.utils.ts @@ -1,7 +1,11 @@ +const ONION = '.onion' + export const createLibp2pAddress = (address: string, peerId: string) => { - return `/dns4/${address}/tcp/443/wss/p2p/${peerId}` + if (!address.endsWith(ONION)) address += ONION + return `/dns4/${address}/tcp/80/wss/p2p/${peerId}` } export const createLibp2pListenAddress = (address: string) => { - return `/dns4/${address}/tcp/443/wss` + if (!address.endsWith(ONION)) address += ONION + return `/dns4/${address}/tcp/80/wss` } diff --git a/packages/backend/src/nest/tor/tor-control.service.ts b/packages/backend/src/nest/tor/tor-control.service.ts index f8dcec17b2..1c2e6f509b 100644 --- a/packages/backend/src/nest/tor/tor-control.service.ts +++ b/packages/backend/src/nest/tor/tor-control.service.ts @@ -26,8 +26,6 @@ export class TorControl implements OnModuleInit { } private async connect(): Promise { - console.log('this.torControlParams', this.torControlParams) - console.log('configOptions.torControl', this.configOptions.torControlPort) return await new Promise((resolve, reject) => { if (this.connection) { reject(new Error('TOR: Connection already established')) @@ -82,8 +80,17 @@ export class TorControl implements OnModuleInit { } public async sendCommand(command: string): Promise<{ code: number; messages: string[] }> { + await this.waitForDisconnect() return await new Promise((resolve, reject) => { void this._sendCommand(command, resolve, reject) }) } + + private async waitForDisconnect() { + await new Promise(resolve => { + if (!this.connection) { + resolve() + } + }) + } } diff --git a/packages/backend/src/nest/tor/tor.service.tor.spec.ts b/packages/backend/src/nest/tor/tor.service.tor.spec.ts index 2f3a30fc65..59e188463b 100644 --- a/packages/backend/src/nest/tor/tor.service.tor.spec.ts +++ b/packages/backend/src/nest/tor/tor.service.tor.spec.ts @@ -10,6 +10,7 @@ import { jest } from '@jest/globals' import { TorControlAuthType } from './tor.types' import { TorControl } from './tor-control.service' import crypto from 'crypto' +import { sleep } from '../common/sleep' jest.setTimeout(200_000) describe('TorControl', () => { let module: TestingModule @@ -121,22 +122,15 @@ describe('TorControl', () => { expect(hiddenServiceOnionAddress).toBe('u2rg2direy34dj77375h2fbhsc2tvxj752h4tlso64mjnlevcv54oaad.onion') }) - // currently provider generate password - // it('generates hashed password', async () => { - // await torService.init() - // torService.generateHashedPassword() - // console.log(torService.torHashedPassword) - // console.log(torService.torPassword) - // expect(tor.torHashedPassword).toHaveLength(61) - // expect(tor.torPassword).toHaveLength(32) - // }) - - it('tor spawn repeating 3 times with 1 second timeout and repeating will stop after that', async () => { - await expect(torService.init({ repeat: 3, timeout: 1000 })).rejects.toThrow('Failed to spawn tor 4 times') + it('tor spawn repeats', async () => { + const spyOnInit = jest.spyOn(torService, 'init') + await torService.init(1000) + await sleep(4000) + expect(spyOnInit).toHaveBeenCalledTimes(2) }) it('tor is initializing correctly with 40 seconds timeout', async () => { - await torService.init({ repeat: 3, timeout: 40000 }) + await torService.init() }) it('creates and destroys hidden service', async () => { @@ -145,7 +139,6 @@ describe('TorControl', () => { const serviceId = hiddenService.onionAddress.split('.')[0] const status = await torService.destroyHiddenService(serviceId) expect(status).toBe(true) - // await torService.kill() }) it('attempt destroy nonexistent hidden service', async () => { diff --git a/packages/backend/src/nest/tor/tor.service.ts b/packages/backend/src/nest/tor/tor.service.ts index dd39ac4002..8fbbe162de 100644 --- a/packages/backend/src/nest/tor/tor.service.ts +++ b/packages/backend/src/nest/tor/tor.service.ts @@ -10,7 +10,7 @@ import { Inject, OnModuleInit } from '@nestjs/common' import { ConfigOptions, ServerIoProviderTypes } from '../types' import { CONFIG_OPTIONS, QUIET_DIR, SERVER_IO_PROVIDER, TOR_PARAMS_PROVIDER, TOR_PASSWORD_PROVIDER } from '../const' import { TorControl } from './tor-control.service' -import { GetInfoTorSignal, TorParams, TorParamsProvider, TorPasswordProvider } from './tor.types' +import { GetInfoTorSignal, HiddenServiceData, TorParams, TorParamsProvider, TorPasswordProvider } from './tor.types' import Logger from '../common/logger' @@ -21,8 +21,11 @@ export class Tor extends EventEmitter implements OnModuleInit { torPidPath: string extraTorProcessParams: TorParams controlPort: number | undefined + interval: any + timeout: any private readonly logger = Logger(Tor.name) - private hiddenServices: Map = new Map() + private hiddenServices: Map = new Map() + private initializedHiddenServices: Map = new Map() constructor( @Inject(CONFIG_OPTIONS) public configOptions: ConfigOptions, @Inject(QUIET_DIR) public readonly quietDir: string, @@ -56,23 +59,17 @@ export class Tor extends EventEmitter implements OnModuleInit { get torProcessParams(): string[] { return Array.from(Object.entries(this.extraTorProcessParams)).flat() } - public async init({ repeat = 6, timeout = 3600_000 } = {}): Promise { + + public async init(timeout = 120_000): Promise { + if (!this.socksPort) this.socksPort = await getPort() this.logger('Initializing tor...') - console.log('this.controlPort', this.controlPort) - console.log('this.torControl', this.torControl.torControlParams) - console.log('configOptions.torControl', this.configOptions.torControlPort) - this.socksPort = await getPort() - return await new Promise((resolve, reject) => { - if (this.process) { - throw new Error('Tor already initialized') - } + return await new Promise((resolve, reject) => { if (!fs.existsSync(this.quietDir)) { fs.mkdirSync(this.quietDir) } this.torDataDirectory = path.join.apply(null, [this.quietDir, 'TorDataDirectory']) - console.log('this.torDataDirectory', this.torDataDirectory) this.torPidPath = path.join.apply(null, [this.quietDir, 'torPid.json']) let oldTorPid: number | null = null if (fs.existsSync(this.torPidPath)) { @@ -80,15 +77,17 @@ export class Tor extends EventEmitter implements OnModuleInit { oldTorPid = Number(file.toString()) this.logger(`${this.torPidPath} exists. Old tor pid: ${oldTorPid}`) } - let counter = 0 - console.log(2) - const tryToSpawnTor = async () => { - this.logger(`Trying to spawn tor for the ${counter} time...`) - if (counter > repeat) { - reject(new Error(`Failed to spawn tor ${counter} times`)) - return + + this.timeout = setTimeout(async () => { + const log = await this.torControl.sendCommand('GETINFO status/bootstrap-phase') + if (log.messages[0] !== '250-status/bootstrap-phase=NOTICE BOOTSTRAP PROGRESS=100 TAG=done SUMMARY="Done"') { + this.initializedHiddenServices = new Map() + clearInterval(this.interval) + await this.init() } + }, timeout) + const tryToSpawnTor = async () => { this.clearOldTorProcess(oldTorPid) try { @@ -98,23 +97,39 @@ export class Tor extends EventEmitter implements OnModuleInit { } try { - await this.spawnTor(timeout) + await this.spawnTor() + + this.interval = setInterval(async () => { + const log = await this.torControl.sendCommand('GETINFO status/bootstrap-phase') + if ( + log.messages[0] === '250-status/bootstrap-phase=NOTICE BOOTSTRAP PROGRESS=100 TAG=done SUMMARY="Done"' + ) { + this.serverIoProvider.io.emit(SocketActionTypes.TOR_INITIALIZED) + + clearInterval(this.interval) + } + }, 2500) + resolve() } catch { this.logger('Killing tor') await this.process.kill() removeFilesFromDir(this.torDataDirectory) - counter++ // eslint-disable-next-line process.nextTick(tryToSpawnTor) } } - // eslint-disable-next-line + tryToSpawnTor() }) } + public resetHiddenServices() { + this.hiddenServices = new Map() + this.initializedHiddenServices = new Map() + } + private torProcessNameCommand(oldTorPid: string): string { const byPlatform = { android: `ps -p ${oldTorPid} -o comm=`, @@ -175,7 +190,7 @@ export class Tor extends EventEmitter implements OnModuleInit { ) } - protected async spawnTor(timeoutMs: number): Promise { + protected async spawnTor(): Promise { return await new Promise((resolve, reject) => { if (!this.configOptions.httpTunnelPort) { this.logger.error("Can't spawn tor - no httpTunnelPort") @@ -225,40 +240,45 @@ export class Tor extends EventEmitter implements OnModuleInit { this.torParamsProvider.options ) - const timeout = setTimeout(() => { - reject(new Error(`Timeout of ${timeoutMs / 1000} while waiting for tor to bootstrap`)) - }, timeoutMs) - - // this.socketService.on(SocketActionTypes.CONNECTION_PROCESS_INFO, (data) => { - // this.serverIoProvider.io.emit(SocketActionTypes.CONNECTION_PROCESS_INFO, data) - // }) - this.process.stdout.on('data', (data: any) => { this.logger(data.toString()) - this.serverIoProvider.io.emit(SocketActionTypes.TOR_BOOTSTRAP_PROCESS, data.toString()) - const regexp = /Bootstrapped 100%/ + const regexp = /Bootstrapped 0/ if (regexp.test(data.toString())) { - clearTimeout(timeout) + this.spawnHiddenServices() resolve() } }) }) } + public async spawnHiddenServices() { + for (const el of this.hiddenServices.values()) { + await this.spawnHiddenService(el) + } + } + public async spawnHiddenService({ targetPort, privKey, - virtPort = 443, + virtPort = 80, }: { targetPort: number privKey: string virtPort?: number }): Promise { + const initializedHiddenService = this.initializedHiddenServices.get(privKey) + if (initializedHiddenService) { + this.logger(`Hidden service already initialized for ${initializedHiddenService.onionAddress}`) + return initializedHiddenService.onionAddress + } const status = await this.torControl.sendCommand( `ADD_ONION ${privKey} Flags=Detach Port=${virtPort},127.0.0.1:${targetPort}` ) const onionAddress = status.messages[0].replace('250-ServiceID=', '') - this.hiddenServices.set(onionAddress, onionAddress) + + const hiddenService: HiddenServiceData = { targetPort, privKey, virtPort, onionAddress } + this.hiddenServices.set(privKey, hiddenService) + this.initializedHiddenServices.set(privKey, hiddenService) return `${onionAddress}.onion` } @@ -275,7 +295,7 @@ export class Tor extends EventEmitter implements OnModuleInit { public async createNewHiddenService({ targetPort, - virtPort = 443, + virtPort = 80, }: { targetPort: number virtPort?: number @@ -286,8 +306,9 @@ export class Tor extends EventEmitter implements OnModuleInit { const onionAddress = status.messages[0].replace('250-ServiceID=', '') const privateKey = status.messages[1].replace('250-PrivateKey=', '') + const hiddenService: HiddenServiceData = { targetPort, privKey: privateKey, virtPort, onionAddress } + this.hiddenServices.set(onionAddress, hiddenService) - this.hiddenServices.set(onionAddress, onionAddress) return { onionAddress: `${onionAddress}.onion`, privateKey, @@ -314,9 +335,6 @@ export class Tor extends EventEmitter implements OnModuleInit { } public async kill(): Promise { - // for (const hs of this.hiddenServices.keys()) { - // await this.destroyHiddenService(hs) - // } return await new Promise((resolve, reject) => { this.logger('Killing tor...') if (this.process === null) { @@ -324,6 +342,8 @@ export class Tor extends EventEmitter implements OnModuleInit { resolve() return } + if (this.timeout) clearTimeout(this.timeout) + if (this.interval) clearInterval(this.interval) this.process?.on('close', () => { this.process = null resolve() diff --git a/packages/backend/src/nest/tor/tor.types.ts b/packages/backend/src/nest/tor/tor.types.ts index 245cad89d4..843e5b0d48 100644 --- a/packages/backend/src/nest/tor/tor.types.ts +++ b/packages/backend/src/nest/tor/tor.types.ts @@ -53,3 +53,10 @@ export interface TorPasswordProvider { torPassword: string torHashedPassword: string } + +export interface HiddenServiceData { + targetPort: number + privKey: string + virtPort: number + onionAddress: string +} diff --git a/packages/backend/src/nest/websocketOverTor/index.ts b/packages/backend/src/nest/websocketOverTor/index.ts index 044700842e..929ac78cb2 100644 --- a/packages/backend/src/nest/websocketOverTor/index.ts +++ b/packages/backend/src/nest/websocketOverTor/index.ts @@ -1,22 +1,15 @@ import { socketToMaConn } from './socket-to-conn' import * as filters from './filters' - import { type MultiaddrFilter, type CreateListenerOptions, type DialOptions } from '@libp2p/interface-transport' import type { AbortOptions } from '@libp2p/interfaces' import type { Multiaddr } from '@multiformats/multiaddr' - import type { ClientOptions, ErrorEvent } from 'ws' - import os from 'os' import PeerId from 'peer-id' - import url from 'url' - import type { Server } from 'http' -import https from 'https' - +import * as http from 'http' import { EventEmitter } from 'events' - import pDefer from 'p-defer' import { multiaddrToUri as toUri } from '@multiformats/multiaddr-to-uri' import { AbortError } from '@libp2p/interfaces/errors' @@ -24,7 +17,6 @@ import { connect } from 'it-ws' import { type ServerOptions, type WebSocketServer as ItWsWebsocketServer } from 'it-ws/server' import { multiaddr } from '@multiformats/multiaddr' import { type MultiaddrConnection, type Connection } from '@libp2p/interface-connection' -import { dumpPEM } from './utils' import logger from '../common/logger' const log = logger('libp2p:websockets') @@ -88,7 +80,6 @@ export class WebSockets extends EventEmitter { socket = await this._connect(ma, { websocket: { ...this._websocketOpts, - ...this.certData, }, }) } catch (e) { @@ -113,24 +104,6 @@ export class WebSockets extends EventEmitter { } } - get certData() { - const { cert, key, ca } = this._websocketOpts - if (!cert || !key || !ca?.length || !ca[0]) { - throw new Error('No cert data in _websocketOpts') - } - let _ca: string | Buffer - if (Array.isArray(ca)) { - _ca = ca[0] - } else { - _ca = ca - } - return { - cert: dumpPEM('CERTIFICATE', cert.toString()), - key: dumpPEM('PRIVATE KEY', key.toString()), - ca: [dumpPEM('CERTIFICATE', _ca.toString())], - } - } - async _connect(ma: Multiaddr, options: any = {}) { if (options.signal?.aborted) { throw new AbortError() @@ -145,6 +118,7 @@ export class WebSockets extends EventEmitter { } const myUri = `${toUri(ma)}/?remoteAddress=${encodeURIComponent(this.localAddress)}` + const rawSocket = connect(myUri, Object.assign({ binary: true }, options)) if (rawSocket.socket.on) { @@ -203,14 +177,10 @@ export class WebSockets extends EventEmitter { server.__connections?.push(maConn) } - const serverHttps = https.createServer({ - ...this.certData, - requestCert: true, - enableTrace: false, - }) + const serverHttp = http.createServer() const optionsServ = { - server: serverHttps, + server: serverHttp, verifyClient: function (_info: any, done: (res: boolean) => void) { done(true) }, @@ -298,7 +268,7 @@ export class WebSockets extends EventEmitter { // we need to capture from the passed multiaddr if (listeningMultiaddr.toString().includes('ip4')) { let m = listeningMultiaddr.decapsulate('tcp') - m = m.encapsulate('/tcp/443/wss') + m = m.encapsulate('/tcp/80/ws') if (ipfsId) { m = m.encapsulate('/p2p/' + ipfsId) } diff --git a/packages/backend/src/nest/websocketOverTor/websocketOverTor.tor.spec.ts b/packages/backend/src/nest/websocketOverTor/websocketOverTor.tor.spec.ts index c68573947c..0ac6482471 100644 --- a/packages/backend/src/nest/websocketOverTor/websocketOverTor.tor.spec.ts +++ b/packages/backend/src/nest/websocketOverTor/websocketOverTor.tor.spec.ts @@ -216,7 +216,7 @@ describe('websocketOverTor', () => { expect((onConnection.mock.calls[0][0] as any).remoteAddr).toEqual(remoteAddress) }) - it('rejects connection if user cert is invalid', async () => { + it.skip('rejects connection if user cert is invalid', async () => { const pems = await createCertificatesTestHelper(`${service1.onionAddress}`, `${service2.onionAddress}`) const anotherPems = await createCertificatesTestHelper(`${service1.onionAddress}`, `${service2.onionAddress}`) @@ -284,7 +284,7 @@ describe('websocketOverTor', () => { ).rejects.toBeTruthy() }) - it('rejects connection if server cert is invalid', async () => { + it.skip('rejects connection if server cert is invalid', async () => { const pems = await createCertificatesTestHelper(`${service1.onionAddress}`, `${service2.onionAddress}`) const anotherPems = await createCertificatesTestHelper(`${service1.onionAddress}`, `${service2.onionAddress}`) diff --git a/packages/common/CHANGELOG.md b/packages/common/CHANGELOG.md index 7a3cb84072..d19e878265 100644 --- a/packages/common/CHANGELOG.md +++ b/packages/common/CHANGELOG.md @@ -3,6 +3,30 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.8.0](/compare/@quiet/common@1.8.0-alpha.0...@quiet/common@1.8.0) (2023-08-28) + +**Note:** Version bump only for package @quiet/common + + + + + +# [1.8.0-alpha.0](https://github.com/TryQuiet/quiet/compare/@quiet/common@1.7.0...@quiet/common@1.8.0-alpha.0) (2023-08-25) + +**Note:** Version bump only for package @quiet/common + + + + + +# [1.7.0](https://github.com/TryQuiet/quiet/compare/@quiet/common@1.6.0...@quiet/common@1.7.0) (2023-08-17) + +**Note:** Version bump only for package @quiet/common + + + + + # [1.6.0](https://github.com/ZbayApp/monorepo/compare/@quiet/common@1.5.1-alpha.0...@quiet/common@1.6.0) (2023-07-28) **Note:** Version bump only for package @quiet/common diff --git a/packages/common/package-lock.json b/packages/common/package-lock.json index c02a9138ae..63db7d500a 100644 --- a/packages/common/package-lock.json +++ b/packages/common/package-lock.json @@ -1,12 +1,12 @@ { "name": "@quiet/common", - "version": "1.6.0", + "version": "1.8.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@quiet/common", - "version": "1.6.0", + "version": "1.8.0", "license": "ISC", "dependencies": { "cross-env": "^5.2.0", diff --git a/packages/common/package.json b/packages/common/package.json index d320789a04..3072edc2ef 100644 --- a/packages/common/package.json +++ b/packages/common/package.json @@ -1,6 +1,6 @@ { "name": "@quiet/common", - "version": "1.6.0", + "version": "1.8.0", "description": "Common monorepo utils", "main": "lib/index.js", "types": "lib/index.d.ts", @@ -17,7 +17,7 @@ "rmDist": "rimraf lib/" }, "devDependencies": { - "@quiet/eslint-config": "^1.1.0", + "@quiet/eslint-config": "^1.3.0", "@types/jest": "^26.0.23", "@types/node": "^17.0.21", "jest": "^26.6.3", @@ -25,7 +25,7 @@ "typescript": "^4.9.3" }, "dependencies": { - "@quiet/types": "^1.6.0", + "@quiet/types": "^1.8.0", "cross-env": "^5.2.0", "debug": "^4.3.1" }, diff --git a/packages/desktop/CHANGELOG.md b/packages/desktop/CHANGELOG.md index aeda49a2f2..d4ef8a3c5c 100644 --- a/packages/desktop/CHANGELOG.md +++ b/packages/desktop/CHANGELOG.md @@ -3,6 +3,30 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.9.0](/compare/quiet@1.9.0-alpha.0...quiet@1.9.0) (2023-08-28) + +**Note:** Version bump only for package quiet + + + + + +# [1.9.0-alpha.0](https://github.com/TryQuiet/quiet/compare/quiet@1.8.0...quiet@1.9.0-alpha.0) (2023-08-25) + +**Note:** Version bump only for package quiet + + + + + +# [1.8.0](https://github.com/TryQuiet/quiet/compare/quiet@1.7.1-alpha.3...quiet@1.8.0) (2023-08-17) + +**Note:** Version bump only for package quiet + + + + + ## [1.7.1-alpha.3](https://github.com/TryQuiet/quiet/compare/quiet@1.7.1-alpha.2...quiet@1.7.1-alpha.3) (2023-08-11) **Note:** Version bump only for package quiet diff --git a/packages/desktop/package-lock.json b/packages/desktop/package-lock.json index da5d0701f6..8103421564 100644 --- a/packages/desktop/package-lock.json +++ b/packages/desktop/package-lock.json @@ -1,12 +1,12 @@ { "name": "quiet", - "version": "1.7.1-alpha.3", + "version": "1.9.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "quiet", - "version": "1.7.1-alpha.3", + "version": "1.9.0", "license": "ISC", "dependencies": { "@electron/remote": "^2.0.8", diff --git a/packages/desktop/package.json b/packages/desktop/package.json index b4799e5633..899199ca8b 100644 --- a/packages/desktop/package.json +++ b/packages/desktop/package.json @@ -80,7 +80,7 @@ }, "homepage": "https://github.com/TryQuiet", "@comment version": "To build new version for specific platform, just replace platform in version tag to one of following linux, mac, windows", - "version": "1.7.1-alpha.3", + "version": "1.9.0", "description": "Decentralized team chat", "main": "dist/main/main.js", "scripts": { @@ -125,11 +125,11 @@ "dependencies": { "@electron/remote": "^2.0.8", "@peculiar/webcrypto": "1.4.3", - "@quiet/common": "^1.6.0", - "@quiet/logger": "^1.4.0", - "@quiet/types": "^1.6.0", + "@quiet/common": "^1.8.0", + "@quiet/logger": "^1.6.0", + "@quiet/types": "^1.8.0", "@sentry/electron": "^2.5.4", - "backend-bundle": "^1.4.0", + "backend-bundle": "^1.6.0", "electron-debug": "^3.0.1", "electron-localshortcut": "^3.2.1", "electron-store": "^8.0.1", @@ -155,9 +155,9 @@ "@mui/icons-material": "^5.10.15", "@mui/lab": "^5.0.0-alpha.109", "@mui/material": "~5.10.15", - "@quiet/eslint-config": "^1.1.0", - "@quiet/identity": "^1.6.0", - "@quiet/state-manager": "^1.7.1-alpha.1", + "@quiet/eslint-config": "^1.3.0", + "@quiet/identity": "^1.8.0", + "@quiet/state-manager": "^1.9.0", "@redux-saga/types": "^1.1.0", "@reduxjs/toolkit": "^1.9.1", "@sentry/browser": "^6.19.7", diff --git a/packages/desktop/src/renderer/components/Channel/DeleteChannel/DeleteChannel.test.tsx b/packages/desktop/src/renderer/components/Channel/DeleteChannel/DeleteChannel.test.tsx index 140b83f70b..c724b4c1bd 100644 --- a/packages/desktop/src/renderer/components/Channel/DeleteChannel/DeleteChannel.test.tsx +++ b/packages/desktop/src/renderer/components/Channel/DeleteChannel/DeleteChannel.test.tsx @@ -21,8 +21,9 @@ describe('LeaveCommunity', () => { aria-hidden="true" />