diff --git a/README.md b/README.md index b315457cc..efdb25f37 100644 --- a/README.md +++ b/README.md @@ -6,20 +6,6 @@ Application for VPN using Mysterium Network. ## Running manually -* [Install and run Tequilapi](https://github.com/MysteriumNetwork/node) on your PC -* Install dependencies - -```bash -yarn install -``` - -* Install React Native CLI: - -```bash -yarn global add react-native-cli -npm install -g react-native-cli -``` - ### Android * Setup crash reporting: * Ensure You have permission to the project here https://console.firebase.google.com @@ -47,7 +33,7 @@ export ANDROID_HOME=/Users//Library/Android/sdk/ Run app on default device (connected or emulator) ```bash -yarn android +Open Android Studio and click Run button :) ``` #### Android Releases @@ -87,7 +73,6 @@ vim fastlane/.env.local ``` - ##### Building release APK - Install Fastlane (if don't have it yet) @@ -115,81 +100,7 @@ source fastlane/.env.local && fastlane android beta ### iOS -* Setup crash reporting: - * Download firebase crashlytics config - `GoogleService-Info.plist` from https://console.firebase.google.com - * Place it in `ios/` - -* Install X Code using App Store - -* Set location for command line tools is X Code: - - * Open X Code - * Go to "X Code" -> "Preferences" -> "Locations" - * In "Command Line Tools", select single available option - -* Install Cocoa dependency manager - -```bash -brew bundle -``` - -```bash -cd ios -``` - -* Install Cocoa dependencies - -```bash -carthage bootstrap --plaftorm iOS --cache-builds -``` - -```bash -cd .. -``` - -* Run iOS - -```bash -yarn ios -``` - -* E2E tests - -Make sure these are installed: -```bash -brew tap wix/brew -brew install wix/brew/applesimutils -``` - -Run E2E tests: - -```bash -yarn test:e2e:ios -``` - -# Troubleshooting - -### iOS build & run error - -```bash -Command failed: /usr/libexec/PlistBuddy -c Print:CFBundleIdentifier build/Build/Products/Debug-iphonesimulator/MysteriumVPN.app/Info.plist -Print: Entry, ":CFBundleIdentifier", Does Not Exist -``` - -`Entry, ":CFBundleIdentifier", Does Not Exist` error is very generic, but doing the following steps fixed the issue. - -#### Xcode configuration -* Open project -* File -> Project settings -> Advanced -* Select "custom" -* Set the following: - - Products: build/Build/Products - - Intermediates: build/Build/Intermediates.noindex - - Index Datastore: Index/DataStore -* Product -> Build +iOS App is under development. ### Android build error ```bash @@ -218,7 +129,7 @@ brew install gnu-sed #### Bump mobile-node version - To Update `implementation "mysterium.network:mobile-node:0.5-rc"` line in `./android/app/build.gradle`, published versions can be found [here](https://bintray.com/mysterium/Node/mobile-node). -- Node usage can be found in `MainActivity.java`. +- Node usage can be found in `MainActivity.kt`. #### Native android logs diff --git a/babel.config.js b/babel.config.js deleted file mode 100644 index 884ea0135..000000000 --- a/babel.config.js +++ /dev/null @@ -1,11 +0,0 @@ -module.exports = { - presets: ['module:metro-react-native-babel-preset'], - plugins: [ - [ - require('@babel/plugin-proposal-decorators').default, - { - legacy: true - } - ], - ] -}; \ No newline at end of file diff --git a/index.js b/index.js deleted file mode 100644 index dc82ca1c6..000000000 --- a/index.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 2018 The "mysteriumnetwork/mysterium-vpn-mobile" Authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -/** - * @format - */ - -import { name as appName } from './app.json' -import { buildApp } from "./src/main"; - - -buildApp(appName) diff --git a/jest.config.js b/jest.config.js deleted file mode 100644 index e128b5cf7..000000000 --- a/jest.config.js +++ /dev/null @@ -1,29 +0,0 @@ -module.exports = { - preset: 'react-native', - setupFiles: [ - "/jest.setup.js" - ], - globals: { - __DEV__: true - }, - moduleFileExtensions: [ - "ts", - "tsx", - "js" - ], - transform: { - "^.+\\.(js)$": "/node_modules/react-native/jest/preprocessor.js", - "\\.(ts|tsx)$": "ts-jest" - }, - testRegex: "(/*\\.(test|spec))\\.(ts|tsx|js)$", - testPathIgnorePatterns: [ - "\\.snap$", - "/node_modules/", - "/lib/", - "/tests/e2e/" - ], - transformIgnorePatterns: [ - "node_modules/(?!react-native|native-base-shoutem-theme|native-base/node_modules)" - ], - cacheDirectory: ".jest/cache" -} diff --git a/jest.setup.js b/jest.setup.js deleted file mode 100644 index 8ed7757ac..000000000 --- a/jest.setup.js +++ /dev/null @@ -1,4 +0,0 @@ -const enzyme = require('enzyme') -const Adapter = require('enzyme-adapter-react-16') - -enzyme.configure({ adapter: new Adapter() }) diff --git a/metro.config.js b/metro.config.js deleted file mode 100644 index adb4bcf27..000000000 --- a/metro.config.js +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Metro configuration for React Native - * https://github.com/facebook/react-native - * - * @format - */ -module.exports = { - transformer: { - getTransformOptions: async () => ({ - transform: { - experimentalImportSupport: false, - inlineRequires: false, - }, - }), - }, -}; \ No newline at end of file diff --git a/package.json b/package.json deleted file mode 100644 index 3e0a62985..000000000 --- a/package.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "name": "MysteriumVPN", - "version": "0.10.0", - "license": "GPL-3.0", - "author": "Mysterium Network ", - "main": "./node_modules/react-native-scripts/build/bin/crna-entry.js", - "scripts": { - "android": "react-native run-android", - "log-android": "react-native log-android", - "ios": "react-native run-ios", - "start": "react-native start --reset-cache", - "test:unit": "jest", - "lint": "tsc --noEmit --skipLibCheck && tslint -p . 'src/**/*.{ts,tsx}' 'tests/**/*.{ts,tsx}'", - "ci": "yarn lint && yarn test:unit && util_scripts/check-headers.sh", - "bundle-android-js": "react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res" - }, - "devDependencies": { - "@babel/core": "^7.7.0", - "@babel/plugin-proposal-decorators": "^7.7.0", - "@babel/runtime": "^7.7.1", - "@babel/types": "^7.7.1", - "@types/enzyme": "^3.1.11", - "@types/jest": "^24.0.2", - "@types/react": "^16.9.11", - "@types/react-native": "^0.60.22", - "@types/react-native-htmlview": "^0.12.2", - "@types/react-native-push-notification": "^3.0.6", - "@types/react-test-renderer": "^16.9.1", - "enzyme": "^3.10.0", - "enzyme-adapter-react-16": "^1.15.1", - "enzyme-to-json": "^3.4.3", - "jest": "^24.9.0", - "jest-html-reporter": "2.7.0", - "metro-react-native-babel-preset": "^0.56.0", - "react-addons-test-utils": "^15.6.2", - "react-dom": "^16.4.1", - "react-native-mock": "^0.3.1", - "react-native-scripts": "1.14.0", - "react-native-typescript-transformer": "^1.2.3", - "react-test-renderer": "^16.3.0-alpha.1", - "ts-jest": "^23.10.5", - "tslint": "5.11.0", - "tslint-config-standard": "^8.0.1", - "tslint-react": "3.6.0", - "typescript": "^2.8.1" - }, - "dependencies": { - "axios": "0.19.0", - "computed-async-mobx": "^4.1.0", - "mobx": "^4.3.1", - "mobx-react": "^5.1.0", - "mobx-utils": "^5.0.2", - "mysterium-tequilapi": "^0.9.0", - "mysterium-vpn-js": "^0.0.2", - "native-base": "^2.8.1", - "react": "^16.11.0", - "react-native": "^0.61.4", - "react-native-dropdownalert": "^4.2.0", - "react-native-htmlview": "^0.13.0", - "react-native-push-notification": "^3.1.9", - "react-native-vector-icons": "^6.1.0" - }, - "jest": { - "snapshotSerializers": [ - "enzyme-to-json/serializer" - ] - } -} diff --git a/src/app/adapters/connection/connection-adapter.ts b/src/app/adapters/connection/connection-adapter.ts deleted file mode 100644 index 11c65a025..000000000 --- a/src/app/adapters/connection/connection-adapter.ts +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2019 The "mysteriumnetwork/mysterium-vpn-mobile" Authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -import { ConnectionStatusDTO } from 'mysterium-tequilapi/lib/dto/connection-status-dto' -import ConnectionStatistics from '../../models/connection-statistics' -import { Location } from '../../models/location' -import { ServiceType } from '../../models/service-type' - -// TODO: uncouple from mysterium-tequilapi by using domain models for response data -interface ConnectionAdapter { - connect (consumerId: string, providerId: string, serviceType: ServiceType): Promise - disconnect (): Promise - fetchStatus (): Promise - fetchStatistics (): Promise - fetchOriginalLocation (): Promise - fetchConnectionLocation (): Promise -} - -class ConnectionCanceled extends Error { - constructor () { - super('Connection canceled') - - // instanceof doesn't work out of the box for Errors - // https://github.com/Microsoft/TypeScript - // /wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work - Object.setPrototypeOf(this, ConnectionCanceled.prototype) - } -} - -export default ConnectionAdapter -export { ConnectionCanceled } diff --git a/src/app/adapters/connection/tequilapi-connection-adapter.ts b/src/app/adapters/connection/tequilapi-connection-adapter.ts deleted file mode 100644 index 6861a11a8..000000000 --- a/src/app/adapters/connection/tequilapi-connection-adapter.ts +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2019 The "mysteriumnetwork/mysterium-vpn-mobile" Authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -import { TequilapiClient } from 'mysterium-tequilapi/lib/client' -import { ConnectionStatusDTO } from 'mysterium-tequilapi/lib/dto/connection-status-dto' -import ConnectionStatistics from '../../models/connection-statistics' -import { Location } from '../../models/location' -import { ServiceType } from '../../models/service-type' -import ConnectionAdapter, { ConnectionCanceled } from './connection-adapter' - -class TequilapiConnectionAdapter implements ConnectionAdapter { - constructor (private tequilapiClient: TequilapiClient) { - } - - public async connect (consumerId: string, providerId: string, serviceType: ServiceType): Promise { - try { - const connection = await this.tequilapiClient.connectionCreate({ consumerId, providerId, serviceType }) - - console.log(`Connect returned status: ${JSON.stringify(connection)}`) - } catch (e) { - if (isConnectionCanceled(e)) { - console.log('Connect canceled') - - throw new ConnectionCanceled() - } - - console.log('Connect failed', e.message) - - throw e - } - } - - public async disconnect (): Promise { - await this.tequilapiClient.connectionCancel() - } - - public async fetchStatus (): Promise { - return this.tequilapiClient.connectionStatus() - } - - public async fetchStatistics (): Promise { - return this.tequilapiClient.connectionStatistics() - } - - public async fetchConnectionLocation (): Promise { - const dto = await this.tequilapiClient.connectionLocation() - - return { ip: dto.ip, countryCode: dto.country } - } - - public async fetchOriginalLocation (): Promise { - const location = await this.tequilapiClient.location() - - return location.country - } -} - -function isConnectionCanceled (e: Error): boolean { - const matches = e.message.match('code 499') - - return !!matches -} - -export default TequilapiConnectionAdapter -export { ConnectionCanceled } diff --git a/src/app/adapters/identity/identity-adapter.ts b/src/app/adapters/identity/identity-adapter.ts deleted file mode 100644 index 866ff9741..000000000 --- a/src/app/adapters/identity/identity-adapter.ts +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2019 The "mysteriumnetwork/mysterium-vpn-mobile" Authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -import { Identity } from '../../models/identity' - -interface IdentityAdapter { - list (): Promise - create (passphrase: string): Promise - unlock (identity: Identity, passphrase: string): Promise -} - -export { IdentityAdapter } diff --git a/src/app/adapters/identity/tequilapi-identity-adapter.ts b/src/app/adapters/identity/tequilapi-identity-adapter.ts deleted file mode 100644 index 7130a39c5..000000000 --- a/src/app/adapters/identity/tequilapi-identity-adapter.ts +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2019 The "mysteriumnetwork/mysterium-vpn-mobile" Authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -import { TequilapiClient } from 'mysterium-tequilapi/lib/client' -import { Identity } from '../../models/identity' -import { IdentityAdapter } from './identity-adapter' - -class TequilapiIdentityAdapter implements IdentityAdapter { - constructor (private tequilapiClient: TequilapiClient, private unlockTimeout: number) {} - - public async list (): Promise { - const dtos = await this.tequilapiClient.identitiesList() - return dtos.map(dto => dto.id) - } - - public async create (passphrase: string): Promise { - const dto = await this.tequilapiClient.identityCreate(passphrase) - return dto.id - } - - public async unlock (identity: Identity, passphrase: string): Promise { - await this.tequilapiClient.identityUnlock(identity, passphrase, this.unlockTimeout) - } -} - -export { TequilapiIdentityAdapter } diff --git a/src/app/adapters/notification/notification-adapter.ts b/src/app/adapters/notification/notification-adapter.ts deleted file mode 100644 index cc3a045b4..000000000 --- a/src/app/adapters/notification/notification-adapter.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2019 The "mysteriumnetwork/mysterium-vpn-mobile" Authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -interface NotificationAdapter { - show (title: string, message: string): void -} - -export default NotificationAdapter diff --git a/src/app/adapters/notification/react-native-notification-adapter.ts b/src/app/adapters/notification/react-native-notification-adapter.ts deleted file mode 100644 index 977d8295e..000000000 --- a/src/app/adapters/notification/react-native-notification-adapter.ts +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2019 The "mysteriumnetwork/mysterium-vpn-mobile" Authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -import PushNotification from 'react-native-push-notification' -import NotificationAdapter from './notification-adapter' - -class ReactNativeNotificationAdapter implements NotificationAdapter { - public show (title: string, message: string) { - PushNotification.localNotification({ title, message }) - } -} - -export default ReactNativeNotificationAdapter diff --git a/src/app/adapters/proposals/proposals-adapter.ts b/src/app/adapters/proposals/proposals-adapter.ts deleted file mode 100644 index 8ea20aa87..000000000 --- a/src/app/adapters/proposals/proposals-adapter.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2019 The "mysteriumnetwork/mysterium-vpn-mobile" Authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -import Proposal from '../../models/proposal' - -interface ProposalsAdapter { - findProposals (): Promise -} - -export { ProposalsAdapter } diff --git a/src/app/adapters/proposals/tequilapi-proposals-adapter.ts b/src/app/adapters/proposals/tequilapi-proposals-adapter.ts deleted file mode 100644 index 33ebfa34a..000000000 --- a/src/app/adapters/proposals/tequilapi-proposals-adapter.ts +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2019 The "mysteriumnetwork/mysterium-vpn-mobile" Authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -import axios from 'axios' -import { TequilapiClient } from 'mysterium-tequilapi/lib/client' -import { MetricsDTO } from 'mysterium-tequilapi/lib/dto/metrics-dto' -import { ProposalDTO } from 'mysterium-tequilapi/lib/dto/proposal' -import { ProposalQueryOptions } from 'mysterium-tequilapi/lib/dto/query/proposals-query-options' -import { Metrics } from 'mysterium-vpn-js' -import { Countries } from '../../../libraries/countries' -import Proposal from '../../models/proposal' -import { stringToServiceType } from '../../models/service-type' -import { ProposalsAdapter } from './proposals-adapter' - -class TequilapiProposalsAdapter implements ProposalsAdapter { - - // @ts-ignore - constructor (private tequilapiClient: TequilapiClient) {} - - public async findProposals (): Promise { - const options: ProposalQueryOptions = { - fetchConnectCounts: true - } - const proposalDtos = await axios.get('http://127.0.0.1:4050/proposals', { params: options }) - .then(res => res.data.proposals) - .then(proposals => proposals.filter((p: any) => { - const applicableServiceType = p.serviceType === 'openvpn' || p.serviceType === 'wireguard' - const withoutWhitelistPolicy = !p.accessPolicies - return applicableServiceType && withoutWhitelistPolicy - })) - return proposalDtosToModels(proposalDtos) - } -} - -function proposalDtosToModels (dtos: ProposalDTO[]): Proposal[] { - const proposals: Proposal[] = [] - dtos.forEach(dto => { - const proposal = proposalDtoToModel(dto) - if (proposal !== null) { - proposals.push(proposal) - } - }) - return proposals -} - -function proposalDtoToModel (dto: ProposalDTO): Proposal | null { - const serviceType = stringToServiceType(dto.serviceType) - if (serviceType === null) { - return null - } - const countryCode = getCountryCode(dto) - const countryName = getCountryName(countryCode) - const metrics = metricsDtoToModel(dto.metrics) - return new Proposal(dto.providerId, serviceType, countryCode, countryName, metrics) -} - -function getCountryCode (p: ProposalDTO): string | null { - if (p.serviceDefinition && p.serviceDefinition.locationOriginate && p.serviceDefinition.locationOriginate.country) { - return p.serviceDefinition.locationOriginate.country.toLocaleLowerCase() - } - return null -} - -function getCountryName (countryCode: string | null) { - if (countryCode === null) { - return null - } - return Countries[countryCode] -} - -function metricsDtoToModel (metrics?: MetricsDTO): Metrics { - const emptyMetrics: Metrics = { connectCount: { success: 0, fail: 0, timeout: 0 } } - if (metrics === undefined || metrics.connectCount === undefined) { - return emptyMetrics - } - - // FIXME quality oracle sometimes returns negative values, patching those to 0 - return { - connectCount: { - success: Math.max(0, metrics.connectCount.success), - fail: Math.max(0, metrics.connectCount.fail), - timeout: Math.max(0, metrics.connectCount.timeout) - } - } -} - -export default TequilapiProposalsAdapter diff --git a/src/app/adapters/statistics/statistics-adapter.ts b/src/app/adapters/statistics/statistics-adapter.ts deleted file mode 100644 index 3a70282e1..000000000 --- a/src/app/adapters/statistics/statistics-adapter.ts +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2019 The "mysteriumnetwork/mysterium-vpn-mobile" Authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -interface StatisticsAdapter { - startConnectionTracking ( - connectionDetails: ConnectionDetails, - countryDetails: CountryDetails - ): ConnectionEventAdapter -} - -interface ConnectionEventAdapter { - sendSuccessfulConnectionEvent (): void - sendFailedConnectionEvent (error: string): void - sendCanceledConnectionEvent (): void -} - -type ConnectionDetails = { - consumerId: string, - serviceType: string, - providerId: string -} - -type CountryDetails = { - originalCountry?: string, - providerCountry?: string -} - -export { StatisticsAdapter, ConnectionEventAdapter } diff --git a/src/app/adapters/storage/react-native-storage.ts b/src/app/adapters/storage/react-native-storage.ts deleted file mode 100644 index 02a5b54a9..000000000 --- a/src/app/adapters/storage/react-native-storage.ts +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2019 The "mysteriumnetwork/mysterium-vpn-mobile" Authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -import { AsyncStorage } from 'react-native' -import StorageAdapter from './storage-adapter' - -export class ReactNativeStorage implements StorageAdapter { - constructor (private key: string) {} - - public async save (data: any) { - await AsyncStorage.setItem(this.key, JSON.stringify(data)) - } - - public async load (): Promise { - const data = await this.getValue() - if (data === null) { - return null - } - return JSON.parse(data) - } - - // this method is needed, because AsyncStorage.getItem definition - // is incorrect - it returns null when key in not present - private async getValue (): Promise { - return AsyncStorage.getItem(this.key) - } -} - -export default ReactNativeStorage diff --git a/src/app/adapters/storage/storage-adapter.ts b/src/app/adapters/storage/storage-adapter.ts deleted file mode 100644 index 06e4e030b..000000000 --- a/src/app/adapters/storage/storage-adapter.ts +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) 2019 The "mysteriumnetwork/mysterium-vpn-mobile" Authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -type StorageAdapter = { - save (data: any): Promise - load (): Promise -} - -export default StorageAdapter diff --git a/src/app/app-loader.ts b/src/app/app-loader.ts deleted file mode 100644 index 5fbe5efca..000000000 --- a/src/app/app-loader.ts +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2019 The "mysteriumnetwork/mysterium-vpn-mobile" Authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -import { BugReporter } from '../bug-reporter/bug-reporter' -import { CONFIG } from '../config' -import TequilApiDriver from '../libraries/tequil-api/tequil-api-driver' -import Connection from './domain/connection' -import { IdentityManager } from './domain/identity-manager' -import ProposalsStore from './stores/proposals-store' - -function sleep (ms: number) { - return new Promise(resolve => setTimeout(resolve, ms)) -} - -/** - * Prepares app: refreshes connection state, ip and unlocks identity. - * Starts periodic state refreshing. - */ -class AppLoader { - constructor (private tequilAPIDriver: TequilApiDriver, - private identityManager: IdentityManager, - private connection: Connection, - private proposals: ProposalsStore, - private bugReporter: BugReporter) {} - - public async load () { - await this.waitForClient() - await sleep(2500) - this.proposals.startUpdating() - this.connection.startUpdating() - try { - await this.identityManager.unlock() - } catch (err) { - console.error('Unlocking identity failed', err) - this.bugReporter.sendException(err) - } - } - - private async waitForClient () { - console.info('Waiting for client to start up') - while (true) { - try { - await this.tequilAPIDriver.healthcheck() - return - } catch (err) { - console.info('Client still down', err) - await delay(CONFIG.HEALTHCHECK_DELAY) - } - } - } -} - -/** - * Resolves after given time in milliseconds. - */ -async function delay (ms: number) { - return new Promise(resolve => setTimeout(resolve, ms)) -} - -export default AppLoader diff --git a/src/app/app-styles.ts b/src/app/app-styles.ts deleted file mode 100644 index 0ad0a3ccb..000000000 --- a/src/app/app-styles.ts +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2018 The "mysteriumnetwork/mysterium-vpn-mobile" Authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -import { StyleSheet } from 'react-native' - -export default StyleSheet.create({ - app: { - backgroundColor: '#fff', - flex: 1 - }, - screen: { - alignItems: 'center', - flex: 1 - }, - imageBackground: { - width: '100%', - flex: 1 - }, - proposalPicker: { - width: '90%', - marginTop: 10, - marginBottom: 10 - } -}) diff --git a/src/app/app.tsx b/src/app/app.tsx deleted file mode 100644 index a45fc07aa..000000000 --- a/src/app/app.tsx +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (C) 2018 The "mysteriumnetwork/mysterium-vpn-mobile" Authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -import { observer } from 'mobx-react/native' -import React, { ReactNode } from 'react' -import { View } from 'react-native' -import FeedbackReporter from '../bug-reporter/feedback-reporter' -import TequilApiDriver from '../libraries/tequil-api/tequil-api-driver' -import AppLoader from './app-loader' -import styles from './app-styles' -import ErrorDropdown from './components/error-dropdown' -import Favorites from './domain/proposals/favorites' -import Terms from './domain/terms' -import MessageDisplayDelegate from './messages/message-display-delegate' -import FeedbackScreen from './screens/feedback-screen' -import LoadingScreen from './screens/loading-screen' -import TermsScreen from './screens/terms-screen' -import VpnScreen from './screens/vpn-screen' -import ConnectionStore from './stores/connection-store' -import ScreenStore from './stores/screen-store' -import VpnScreenStore from './stores/vpn-screen-store' - -type AppProps = { - tequilAPIDriver: TequilApiDriver, - connectionStore: ConnectionStore, - vpnScreenStore: VpnScreenStore, - screenStore: ScreenStore, - messageDisplayDelegate: MessageDisplayDelegate, - terms: Terms, - favorites: Favorites, - appLoader: AppLoader, - feedbackReporter: FeedbackReporter -} - -@observer -export default class App extends React.Component { - private readonly tequilAPIDriver: TequilApiDriver - private readonly connectionStore: ConnectionStore - private readonly messageDisplayDelegate: MessageDisplayDelegate - private readonly terms: Terms - private readonly vpnScreenStore: VpnScreenStore - private readonly screenStore: ScreenStore - private readonly favorites: Favorites - private readonly appLoader: AppLoader - private readonly feedbackReporter: FeedbackReporter - - constructor (props: AppProps) { - super(props) - this.tequilAPIDriver = props.tequilAPIDriver - this.connectionStore = props.connectionStore - this.messageDisplayDelegate = props.messageDisplayDelegate - this.terms = props.terms - this.vpnScreenStore = props.vpnScreenStore - this.screenStore = props.screenStore - this.favorites = props.favorites - this.appLoader = props.appLoader - this.feedbackReporter = props.feedbackReporter - } - - public render (): ReactNode { - return ( - - {this.renderCurrentScreen()} - this.messageDisplayDelegate.messageDisplay = ref}/> - - ) - } - - private renderCurrentScreen (): ReactNode { - if (this.screenStore.inTermsScreen) { - return this.screenStore.navigateToLoadingScreen()}/> - } - - if (this.screenStore.inLoadingScreen) { - return this.load()} /> - } - - if (this.screenStore.inFeedbackScreen) { - return ( - this.screenStore.navigateToVpnScreen()} - /> - ) - } - - return ( - - ) - } - - private async load () { - try { - await this.appLoader.load() - this.screenStore.navigateToVpnScreen() - } catch (err) { - console.log('App loading failed', err) - } - } -} diff --git a/src/app/components/button-connect.tsx b/src/app/components/button-connect.tsx deleted file mode 100644 index 3acde4353..000000000 --- a/src/app/components/button-connect.tsx +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (C) 2019 The "mysteriumnetwork/mysterium-vpn-mobile" Authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -import React, { Component } from 'react' -import { StyleSheet, Text, TouchableOpacity } from 'react-native' -import { CONFIG } from '../../config' -import { ConnectionStatusEnum } from '../../libraries/tequil-api/enums' -import { STYLES } from '../../styles' -import ConnectionStatus from '../models/connection-status' - -type ButtonConnectProps = { - connectionStatus: ConnectionStatus - connect: () => void, - disconnect: () => void -} - -export default class ButtonConnect extends Component { - public render () { - let buttonStylesDisabled: any - let textStylesDisabled: any - - if (!this.isButtonEnabled) { - buttonStylesDisabled = styles.disabledRoot - textStylesDisabled = styles.disabledButtonContent - } - - return ( - - - {this.buttonText} - - - ) - } - - private get isButtonEnabled (): boolean { - if (!this.props.connectionStatus) return false - const connectionStatus = this.props.connectionStatus - return (connectionStatus === ConnectionStatusEnum.NOT_CONNECTED - || connectionStatus === ConnectionStatusEnum.CONNECTED - || connectionStatus === ConnectionStatusEnum.CONNECTING - ) - } - - /*** - * Connects or disconnects to VPN server, depends on current connection state. - * Is connection state is unknown - does nothing - */ - private connectOrDisconnectOrCancel = async () => { - if (!this.props.connectionStatus) return - const status = this.props.connectionStatus - - if (status === ConnectionStatusEnum.CONNECTING - || status === ConnectionStatusEnum.CONNECTED) { - this.props.disconnect() - } - - if (status === ConnectionStatusEnum.NOT_CONNECTED) { - this.props.connect() - } - } - - private get buttonText (): string { - if (!this.props.connectionStatus) return CONFIG.TEXTS.UNKNOWN - - const connectionStatus = this.props.connectionStatus - switch (connectionStatus) { - case ConnectionStatusEnum.NOT_CONNECTED: - return CONFIG.TEXTS.CONNECT_BUTTON.CONNECT - case ConnectionStatusEnum.CONNECTED: - return CONFIG.TEXTS.CONNECT_BUTTON.DISCONNECT - case ConnectionStatusEnum.CONNECTING: - return CONFIG.TEXTS.CONNECT_BUTTON.CANCEL - case ConnectionStatusEnum.DISCONNECTING: - return CONFIG.TEXTS.CONNECT_BUTTON.DISCONNECTING - default: - return CONFIG.TEXTS.UNKNOWN - } - } -} - -const styles = StyleSheet.create({ - root: { - width: 220, - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'center', - padding: STYLES.PADDING, - borderRadius: 10, - shadowColor: '#000', - shadowOffset: { - width: 0, - height: 1 - }, - shadowOpacity: 0.35, - shadowRadius: 20, - borderColor: STYLES.COLOR_MAIN, - borderWidth: 1, - backgroundColor: STYLES.COLOR_BACKGROUND - }, - disabledRoot: { - borderColor: STYLES.COLOR_DISABLED - }, - buttonContent: { - fontSize: STYLES.FONT_NORMAL, - color: STYLES.COLOR_MAIN - }, - disabledButtonContent: { - color: STYLES.COLOR_DISABLED - } -}) diff --git a/src/app/components/connection-status.tsx b/src/app/components/connection-status.tsx deleted file mode 100644 index 2e214e24b..000000000 --- a/src/app/components/connection-status.tsx +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2019 The "mysteriumnetwork/mysterium-vpn-mobile" Authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -import React, { Component } from 'react' -import { StyleSheet, Text } from 'react-native' -import { CONFIG } from '../../config' -import { ConnectionStatusEnum } from '../../libraries/tequil-api/enums' -import { STYLES } from '../../styles' - -type ConnectionStatusProps = { - status?: string -} - -export default class ConnectionStatus extends Component { - private readonly connectionStatusTexts: { [key: string]: string | undefined } = { - [ConnectionStatusEnum.NOT_CONNECTED]: this.statusTexts.NOT_CONNECTED, - [ConnectionStatusEnum.CONNECTING]: this.statusTexts.CONNECTING, - [ConnectionStatusEnum.CONNECTED]: this.statusTexts.CONNECTED, - [ConnectionStatusEnum.DISCONNECTING]: this.statusTexts.DISCONNECTING - } - - public render () { - return ( - {this.connectionStatus} - ) - } - - private get connectionStatus (): string { - const status = this.props.status - - if (status === undefined) { - return this.statusTexts.UNKNOWN - } - - const text = this.connectionStatusTexts[status] - if (text === undefined) { - throw new Error(`Unknown connection status: ${status}`) - } - - return text - } - - private get statusTexts () { - return CONFIG.TEXTS.CONNECTION_STATUS - } -} - -const style = StyleSheet.create({ - root: { - marginTop: 45, - fontSize: STYLES.FONT_LARGE, - color: STYLES.COLOR_MAIN - } -}) diff --git a/src/app/components/error-dropdown.tsx b/src/app/components/error-dropdown.tsx deleted file mode 100644 index 4d436f7b2..000000000 --- a/src/app/components/error-dropdown.tsx +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2018 The "mysteriumnetwork/mysterium-vpn-mobile" Authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -import React, { ReactNode } from 'react' -// @ts-ignore -import DropdownAlert, { DropdownAlertType } from 'react-native-dropdownalert' -import MessageDisplay from '../messages/message-display' - -/** - * Allowing show error messages as a dropdowns. - */ -class ErrorDropdown extends React.Component implements MessageDisplay { - private dropdown?: DropdownAlert - - public render (): ReactNode { - return this.dropdown = ref}/> - } - - public showError (message: string) { - this.alert('error', 'Error', message) - } - - public showInfo (message: string) { - this.alert('info', 'Info', message) - } - - private alert (type: DropdownAlertType, title: string, message: string) { - if (this.dropdown === undefined) { - throw new Error('DropdownAlert not set yet') - } - this.dropdown.alertWithType(type, title, message) - } -} - -export default ErrorDropdown diff --git a/src/app/components/feedback-form.tsx b/src/app/components/feedback-form.tsx deleted file mode 100644 index 0c09fe416..000000000 --- a/src/app/components/feedback-form.tsx +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2018 The "mysteriumnetwork/mysterium-vpn-mobile" Authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -import { Button, Form, Grid, Picker, Row, Text, Textarea } from 'native-base' -import React, { ReactNode } from 'react' -import { StyleSheet } from 'react-native' -import { UserFeedback } from '../../bug-reporter/feedback-reporter' -import { STYLES } from '../../styles' -import colors from '../styles/colors' - -type FeedbackFormProps = { - onSubmit: (feedback: UserFeedback) => void, - - options: FeedbackTypeOption[] -} - -type FeedbackTypeOption = { - value: string, - label: string -} - -class FeedbackForm extends React.PureComponent - { - public state: UserFeedback = { - type: 'bug', - message: '' - } - - public render (): ReactNode { - return ( -
- - - Feedback type: - - - - {this.props.options.map((option: FeedbackTypeOption) => - )} - - - - Message: - - -