diff --git a/client/tools/build/setup_linux_android.sh b/.github/scripts/android_setup_ci.sh old mode 100755 new mode 100644 similarity index 97% rename from client/tools/build/setup_linux_android.sh rename to .github/scripts/android_setup_ci.sh index aba6ff1f17..725a0d6db3 --- a/client/tools/build/setup_linux_android.sh +++ b/.github/scripts/android_setup_ci.sh @@ -45,4 +45,4 @@ rm android-commandline-tools.zip PATH="${PATH}:${ANDROID_HOME}/platform-tools:${ANDROID_HOME}/cmdline-tools/tools/bin" -yes | sdkmanager "build-tools;${OUTLINE_ANDROID_BUILD_TOOLS_VERSION}" "ndk;${OUTLINE_ANDROID_NDK_VERSION}" +yes | sdkmanager "build-tools;${OUTLINE_ANDROID_BUILD_TOOLS_VERSION}" "ndk;${OUTLINE_ANDROID_NDK_VERSION}" \ No newline at end of file diff --git a/client/tools/build/android_tools_versions.sh b/.github/scripts/android_tools_versions.sh similarity index 100% rename from client/tools/build/android_tools_versions.sh rename to .github/scripts/android_tools_versions.sh diff --git a/.github/workflows/build_and_test_debug_client.yml b/.github/workflows/build_and_test_debug_client.yml index 9fbcf9e817..254a2c8f9f 100644 --- a/.github/workflows/build_and_test_debug_client.yml +++ b/.github/workflows/build_and_test_debug_client.yml @@ -69,7 +69,7 @@ jobs: go-version-file: '${{ github.workspace }}/go.mod' - name: Build Linux Client - run: npm run action src/electron/build linux + run: npm run action client/electron/build linux windows_debug_build: name: Windows Debug Build @@ -99,7 +99,7 @@ jobs: go-version-file: '${{ github.workspace }}/go.mod' - name: Build Windows Client - run: npm run action src/electron/build windows + run: npm run action client/electron/build windows macos_debug_build: name: MacOS Debug Build @@ -257,7 +257,7 @@ jobs: java-version: 11 - name: Setup Android - run: bash ./client/tools/build/setup_linux_android.sh + run: bash ./.github/scripts/android_setup_ci.sh - name: Build Android Client run: npm run action client/src/cordova/build android -- --verbose diff --git a/README.md b/README.md index b90509307e..fe0798c6d8 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,20 @@ -# Outline Apps +# Outline Manager Logo  Outline Apps  Outline Client Logo -[![Mattermost](https://badgen.net/badge/Mattermost/Outline%20Community/blue)](https://community.internetfreedomfestival.org/community/channels/outline-community) [![Reddit](https://badgen.net/badge/Reddit/r%2Foutlinevpn/orange)](https://www.reddit.com/r/outlinevpn/) -[![codecov](https://codecov.io/gh/Jigsaw-Code/outline-app/branch/master/graph/badge.svg?token=gasD8v5tjn)](https://codecov.io/gh/Jigsaw-Code/outline-app) +[![Reddit](https://badgen.net/badge/Reddit/r%2Foutlinevpn/orange)](https://www.reddit.com/r/outlinevpn/) [![Mattermost](https://badgen.net/badge/Mattermost/Outline%20Community/blue)](https://community.internetfreedomfestival.org/community/channels/outline-community) [![codecov](https://codecov.io/gh/Jigsaw-Code/outline-apps/branch/master/graph/badge.svg?token=gasD8v5tjn)](https://codecov.io/gh/Jigsaw-Code/outline-apps) -## Access to the free and open internet! +> [!WARNING] +> Codecov currently only tracks the `/client` Apple libraries and core web view code. -Outline makes it easy to create a VPN server, giving anyone access to the free and open internet. +Outline makes it easy for anyone to create a VPN server, allowing you to share access to the free and open internet with those in need. **We have two core applications:** -We have two core apps +    Outline Manager Logo  **Outline Manager** ([`/server_manager`](server_manager)): A graphical user interface for managing Outline servers. It is available for Windows, macOS, and Linux. [You can install the manager here](https://getoutline.org/get-started/#step-1). -- Outline Manager Logo **Outline Manager** ([`/server_manager`](server_manager)): A graphical user interface for managing Outline servers. It is available for Windows, macOS, and Linux. +    Outline Client Logo  **Outline Client** ([`/client`](client)): A cross-platform proxy client for Windows, macOS, iOS, Android, and Linux. The Outline Client is designed for use with the server deployed with the Outline Manager, but it is also fully compatible with any [Shadowsocks](https://shadowsocks.org/) server. [You can install the client here](https://getoutline.org/get-started/#step-3). -- Outline Client Logo **Outline Client** ([`/client`](client)): A cross-platform proxy client for Windows, macOS, iOS, Android, and Linux. The Outline Client is designed for use with the server deployed with the Outline Manager, but it is also fully compatible with any [Shadowsocks](https://shadowsocks.org/) server. +## Community and Support -Go to https://getoutline.org for ready-to-use versions of both. +Interested in **contributing to Outline?** See our [Contributing Guide](CONTRIBUTING.md) for more information. -**Join the Outline Community** by signing up for the [IFF Mattermost](https://wiki.digitalrights.community/index.php?title=IFF_Mattermost)! +You can also **join the Outline Community** by signing up for the [IFF Mattermost](https://wiki.digitalrights.community/index.php?title=IFF_Mattermost)! -## Support - -For support and to contact us, see: https://support.getoutline.org. +For customer support and to **contact us directly**, go to https://support.getoutline.org. diff --git a/client/README.md b/client/README.md index 3f9a344ad6..73c9b6c1c8 100644 --- a/client/README.md +++ b/client/README.md @@ -1,11 +1,8 @@ -# Outline Client +# Outline Client Logo  Outline Client -![Build and Test](https://github.com/Jigsaw-Code/outline-apps/actions/workflows/build_and_test_debug_client.yml/badge.svg?branch=master) [![codecov](https://codecov.io/gh/Jigsaw-Code/outline-apps/graph/badge.svg?token=gasD8v5tjn)](https://codecov.io/gh/Jigsaw-Code/outline-apps) +![Build and Test](https://github.com/Jigsaw-Code/outline-apps/actions/workflows/build_and_test_debug_client.yml/badge.svg?branch=master) -> [!NOTE] -> Test coverage currently only tracks the Apple Libraries and core web view code. - -The Outline Client is a cross-platform VPN or proxy client for Windows, macOS, iOS, Android, and ChromeOS. The Outline Client is designed for use with the [Outline Server](https://github.com/Jigsaw-Code/outline-server) software, but it is fully compatible with any [Shadowsocks](https://shadowsocks.org/) server. +The Outline Client is a cross-platform VPN or proxy client for Windows, macOS, iOS, Android, and Debian-based Linux. The Outline Client is designed for use with the [Outline Server](https://github.com/Jigsaw-Code/outline-server) software, but it is fully compatible with any [Shadowsocks](https://shadowsocks.org/) server. The client's user interface is implemented in [Polymer](https://www.polymer-project.org/) 2.0. Platform support is provided by [Cordova](https://cordova.apache.org/) and [Electron](https://electronjs.org/), with additional native components in this repository. @@ -72,7 +69,7 @@ Each platform is handled differently: 1. [Developing for Apple **(MacOS and iOS)**](src/cordova/apple) 2. [Developing for **Android**](src/cordova/android) -3. [Developing for Electron **(Windows and Linux)**](src/electron) +3. [Developing for Electron **(Windows and Linux)**](electron) ## Error reporting diff --git a/src/electron/README.md b/client/electron/README.md similarity index 87% rename from src/electron/README.md rename to client/electron/README.md index d737bdfb95..32467be80b 100644 --- a/src/electron/README.md +++ b/client/electron/README.md @@ -2,16 +2,16 @@ Unlike the Android and Apple clients, the Windows and Linux clients use the Electron framework, rather than Cordova. -To build the Electron clients, run (it will also package an installer executable into `build/dist`): +To build the Electron clients, run (it will also package an installer executable into `output/client/electron/build`): ```sh -npm run action electron/build [windows|linux] +npm run action client/electron/build [windows|linux] ``` To run the Electron clients, run: ```sh -npm run action electron/start [windows|linux] +npm run action client/electron/start [windows|linux] ``` ## Cross-Compiling diff --git a/src/electron/add_tap_device.bat b/client/electron/add_tap_device.bat similarity index 100% rename from src/electron/add_tap_device.bat rename to client/electron/add_tap_device.bat diff --git a/src/electron/build.action.mjs b/client/electron/build.action.mjs similarity index 81% rename from src/electron/build.action.mjs rename to client/electron/build.action.mjs index e8e7fb8953..885b05c70e 100644 --- a/src/electron/build.action.mjs +++ b/client/electron/build.action.mjs @@ -16,18 +16,14 @@ import fs from 'fs/promises'; import path from 'path'; import url from 'url'; -import copydir from 'copy-dir'; import electron, {Platform} from 'electron-builder'; import minimist from 'minimist'; -import {getBuildParameters} from '../../client/src/build/get_build_parameters.mjs'; -import {getRootDir} from '../build/get_root_dir.mjs'; -import {runAction} from '../build/run_action.mjs'; +import {getRootDir} from '../../src/build/get_root_dir.mjs'; +import {runAction} from '../../src/build/run_action.mjs'; +import {getBuildParameters} from '../src/build/get_build_parameters.mjs'; - - - -const ELECTRON_BUILD_DIR = 'build'; +const ELECTRON_BUILD_DIR = 'output'; const ELECTRON_PLATFORMS = ['linux', 'windows']; export async function main(...parameters) { @@ -55,15 +51,12 @@ export async function main(...parameters) { await runAction('client/src/www/build', ...parameters); await runAction('client/src/tun2socks/build', ...parameters); - await runAction('src/electron/build_main', ...parameters); + await runAction('client/electron/build_main', ...parameters); - await copydir.sync( - path.join(getRootDir(), 'src', 'electron', 'icons'), - path.join(getRootDir(), ELECTRON_BUILD_DIR, 'icons') - ); + await fs.mkdir(path.join(getRootDir(), ELECTRON_BUILD_DIR, 'client', 'electron'), {recursive: true}); const electronConfig = JSON.parse( - await fs.readFile(path.resolve(getRootDir(), 'src', 'electron', 'electron-builder.json')) + await fs.readFile(path.resolve(getRootDir(), 'client', 'electron', 'electron-builder.json')) ); // build electron binary diff --git a/src/electron/build_main.action.mjs b/client/electron/build_main.action.mjs similarity index 83% rename from src/electron/build_main.action.mjs rename to client/electron/build_main.action.mjs index c1c9455b72..49285f8e57 100644 --- a/src/electron/build_main.action.mjs +++ b/client/electron/build_main.action.mjs @@ -17,13 +17,13 @@ import path from 'path'; import url from 'url'; import electronMainWebpackConfigs from './webpack_electron_main.mjs'; -import {getBuildParameters} from '../../client/src/build/get_build_parameters.mjs'; -import {getWebpackBuildMode} from '../../client/src/build/get_webpack_build_mode.mjs'; -import {runWebpack} from '../../client/src/build/run_webpack.mjs'; -import {getRootDir} from '../build/get_root_dir.mjs'; -import {runAction} from '../build/run_action.mjs'; +import {getRootDir} from '../../src/build/get_root_dir.mjs'; +import {runAction} from '../../src/build/run_action.mjs'; +import {getBuildParameters} from '../src/build/get_build_parameters.mjs'; +import {getWebpackBuildMode} from '../src/build/get_webpack_build_mode.mjs'; +import {runWebpack} from '../src/build/run_webpack.mjs'; -const ELECTRON_BUILD_DIR = 'build'; +const ELECTRON_BUILD_DIR = 'output'; const ELECTRON_PLATFORMS = ['linux', 'windows']; export async function main(...parameters) { @@ -58,7 +58,7 @@ export async function main(...parameters) { windowsEnvironment += `\n!define SENTRY_URL ""`; } - await fs.writeFile(path.resolve(getRootDir(), ELECTRON_BUILD_DIR, 'env.nsh'), windowsEnvironment); + await fs.writeFile(path.resolve(getRootDir(), ELECTRON_BUILD_DIR, 'client', 'electron', 'env.nsh'), windowsEnvironment); } } diff --git a/src/electron/connectivity.ts b/client/electron/connectivity.ts similarity index 95% rename from src/electron/connectivity.ts rename to client/electron/connectivity.ts index d3a242d372..80a8d59657 100644 --- a/src/electron/connectivity.ts +++ b/client/electron/connectivity.ts @@ -15,7 +15,8 @@ import * as dns from 'dns'; import {timeoutPromise} from '@outline/infrastructure/timeout_promise'; -import * as errors from '../../client/src/www/model/errors'; + +import * as errors from '../src/www/model/errors'; const DNS_LOOKUP_TIMEOUT_MS = 10000; diff --git a/src/electron/custom_install_steps.nsh b/client/electron/custom_install_steps.nsh similarity index 92% rename from src/electron/custom_install_steps.nsh rename to client/electron/custom_install_steps.nsh index 4ca378065d..65b8eb8183 100755 --- a/src/electron/custom_install_steps.nsh +++ b/client/electron/custom_install_steps.nsh @@ -1,170 +1,170 @@ -; Copyright 2018 The Outline Authors -; -; Licensed under the Apache License, Version 2.0 (the "License"); -; you may not use this file except in compliance with the License. -; You may obtain a copy of the License at -; -; http://www.apache.org/licenses/LICENSE-2.0 -; -; Unless required by applicable law or agreed to in writing, software -; distributed under the License is distributed on an "AS IS" BASIS, -; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -; See the License for the specific language governing permissions and -; limitations under the License. - -!include StrFunc.nsh -!include WinVer.nsh -!include x64.nsh - -!include env.nsh - -; StrFunc weirdness; this fix suggested here: -; https://github.com/electron-userland/electron-builder/issues/888 -!ifndef BUILD_UNINSTALLER -${StrLoc} -${StrNSISToIO} -${StrRep} -!endif - -!macro customInstall - ; Normally, because we mark the installer binary as requiring administrator permissions, the - ; installer will be running with administrator permissions at this point. The exception is when - ; the system is running with the *lowest* (least safe) UAC setting in which case the installer - ; can progress to this point without administrator permissions. - ; - ; If that's the case, exit now so we don't waste time to trying to install the TAP device, etc. - ; Additionally, the client can detect their absence and prompt the user to reinstall. - ; - ; The returned value does *not* seem to be based on the user's current diaplay language. - UserInfo::GetAccountType - Pop $0 - StrCmp $0 "Admin" isadmin - MessageBox MB_OK "Sorry, Outline requires administrator permissions." - Quit - - isadmin: - - ; TAP device files. - SetOutPath "$INSTDIR\tap-windows6" - ${If} ${RunningX64} - File /r "${PROJECT_DIR}\third_party\tap-windows6\bin\amd64\*" - ${Else} - File /r "${PROJECT_DIR}\third_party\tap-windows6\bin\i386\*" - ${EndIf} - SetOutPath - - File "${PROJECT_DIR}\src\electron\add_tap_device.bat" - File "${PROJECT_DIR}\src\electron\find_tap_device_name.bat" - - ; OutlineService files, stopping the service first in case it's still running. - nsExec::Exec "$SYSDIR\net stop OutlineService" - File "${PROJECT_DIR}\tools\OutlineService\OutlineService\bin\OutlineService.exe" - File "${PROJECT_DIR}\tools\smartdnsblock\bin\smartdnsblock.exe" - File "${PROJECT_DIR}\third_party\newtonsoft\Newtonsoft.Json.dll" - File "${PROJECT_DIR}\src\electron\install_windows_service.bat" - - ; ExecToStack captures both stdout and stderr from the script, in the order output. - ; Set a (long) timeout in case the device never becomes visible to netsh. - ReadEnvStr $0 COMSPEC - nsExec::ExecToStack /timeout=180000 '$0 /c add_tap_device.bat' - - Pop $0 - Pop $1 - StrCmp $0 0 installservice - - ; The TAP device may have failed to install because the user did not want to - ; install the device driver. If so: - ; - tell the user that they need to install the driver - ; - skip the Sentry report - ; - quit - ; - ; When this happens, tapinstall.exe prints an error message like this: - ; UpdateDriverForPlugAndPlayDevices failed, GetLastError=-536870333 - ; - ; We can use the presence of that magic number to detect this case. - Var /GLOBAL DRIVER_FAILURE_MAGIC_NUMBER_INDEX - ${StrLoc} $DRIVER_FAILURE_MAGIC_NUMBER_INDEX $1 "536870333" ">" - - StrCmp $DRIVER_FAILURE_MAGIC_NUMBER_INDEX "" submitsentryreport - ; The term "device software" is the same as that used by the prompt, at least on Windows 7. - MessageBox MB_OK "Sorry, you must install the device software in order to use Outline. Please try \ - running the installer again." - Quit - - submitsentryreport: - MessageBox MB_OK "Sorry, we could not configure your system to connect to Outline. Please try \ - running the installer again. If you still cannot install Outline, please get in \ - touch with us and let us know that the TAP device failed to install with error code $0." - - ; Submit a Sentry error event. - ; - ; This will get bundled into an issue named "could not install TAP device" with the following - ; attributes: - ; - a single breadcrumb containing the output of add_tap_device.bat - ; - Windows version, as a tag named "os" with a value identical in most cases to what the - ; JavaScript Sentry client produces, e.g. "Windows 10.0.17134" - ; - client version - ; - ; Note: - ; - Sentry won't accept a breadcrumbs without a timestamp; fortunately, it accepts obviously - ; bogus values so we don't have to fetch the real time. - ; - Because nsExec::ExecToStack yields "NSIS strings" strings suitable for inclusion in, for - ; example, a MessageBox, e.g. "device not found$\ncommand failed", we must convert it to a - ; string that Sentry will like *and* can fit on one line, e.g. - ; "device not found\ncommand failed"; fortunately, StrFunc.nsh's StrNSISToIO does precisely - ; this. - ; - RELEASE and SENTRY_URL are defined in env.nsh which is generated at build time by - ; {package,release}_action.sh. - - ; TODO: Remove this once we figure out why/if breadcrumbs are being truncated. - Var /GLOBAL FAILURE_MESSAGE_LENGTH - StrLen $FAILURE_MESSAGE_LENGTH $1 - - ; http://nsis.sourceforge.net/Docs/StrFunc/StrFunc.txt - Var /GLOBAL FAILURE_MESSAGE - ${StrNSISToIO} $FAILURE_MESSAGE $1 - ${StrRep} $FAILURE_MESSAGE $FAILURE_MESSAGE '"' '\"' - - ${WinVerGetMajor} $R0 - ${WinVerGetMinor} $R1 - ${WinVerGetBuild} $R2 - - ; http://nsis.sourceforge.net/Inetc_plug-in#post - inetc::post '{\ - "message":"could not install TAP device ($0)",\ - "release":"${RELEASE}",\ - "tags":[\ - ["os", "Windows $R0.$R1.$R2"],\ - ["error_message_length", "$FAILURE_MESSAGE_LENGTH"]\ - ],\ - "breadcrumbs":[\ - {"timestamp":1, "message":"$FAILURE_MESSAGE"}\ - ]\ - }' /TOSTACK ${SENTRY_URL} /END - - Quit - - installservice: - - nsExec::Exec install_windows_service.bat - - nsExec::Exec "$SYSDIR\sc query OutlineService" - Pop $0 - StrCmp $0 0 success - ; TODO: Trigger a Sentry report for service installation failure, too, and revisit - ; the restart stuff in the TypeScript code. - MessageBox MB_OK "Sorry, we could not configure your system to connect to Outline. Please try \ - running the installer again. If you still cannot install Outline, please get in touch with us \ - and let us know that OutlineService failed to install." - Quit - - success: - -!macroend - -; TODO: Remove the TAP device on uninstall. This is impossible to implement safely -; with the bundled tapinstall.exe because it can only remove *all* devices -; having hwid tap0901 and these may include non-Outline devices. -!macro customUnInstall - nsExec::Exec "$SYSDIR\net stop OutlineService" - nsExec::Exec "$SYSDIR\sc delete OutlineService" -!macroend +; Copyright 2018 The Outline Authors +; +; Licensed under the Apache License, Version 2.0 (the "License"); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions and +; limitations under the License. + +!include StrFunc.nsh +!include WinVer.nsh +!include x64.nsh + +!include env.nsh + +; StrFunc weirdness; this fix suggested here: +; https://github.com/electron-userland/electron-builder/issues/888 +!ifndef BUILD_UNINSTALLER +${StrLoc} +${StrNSISToIO} +${StrRep} +!endif + +!macro customInstall + ; Normally, because we mark the installer binary as requiring administrator permissions, the + ; installer will be running with administrator permissions at this point. The exception is when + ; the system is running with the *lowest* (least safe) UAC setting in which case the installer + ; can progress to this point without administrator permissions. + ; + ; If that's the case, exit now so we don't waste time to trying to install the TAP device, etc. + ; Additionally, the client can detect their absence and prompt the user to reinstall. + ; + ; The returned value does *not* seem to be based on the user's current diaplay language. + UserInfo::GetAccountType + Pop $0 + StrCmp $0 "Admin" isadmin + MessageBox MB_OK "Sorry, Outline requires administrator permissions." + Quit + + isadmin: + + ; TAP device files. + SetOutPath "$INSTDIR\tap-windows6" + ${If} ${RunningX64} + File /r "${PROJECT_DIR}\third_party\tap-windows6\bin\amd64\*" + ${Else} + File /r "${PROJECT_DIR}\third_party\tap-windows6\bin\i386\*" + ${EndIf} + SetOutPath - + File "${PROJECT_DIR}\client\electron\add_tap_device.bat" + File "${PROJECT_DIR}\client\electron\find_tap_device_name.bat" + + ; OutlineService files, stopping the service first in case it's still running. + nsExec::Exec "$SYSDIR\net stop OutlineService" + File "${PROJECT_DIR}\client\electron\windows\OutlineService\OutlineService\bin\OutlineService.exe" + File "${PROJECT_DIR}\client\electron\windows\smartdnsblock\bin\smartdnsblock.exe" + File "${PROJECT_DIR}\third_party\newtonsoft\Newtonsoft.Json.dll" + File "${PROJECT_DIR}\client\electron\install_windows_service.bat" + + ; ExecToStack captures both stdout and stderr from the script, in the order output. + ; Set a (long) timeout in case the device never becomes visible to netsh. + ReadEnvStr $0 COMSPEC + nsExec::ExecToStack /timeout=180000 '$0 /c add_tap_device.bat' + + Pop $0 + Pop $1 + StrCmp $0 0 installservice + + ; The TAP device may have failed to install because the user did not want to + ; install the device driver. If so: + ; - tell the user that they need to install the driver + ; - skip the Sentry report + ; - quit + ; + ; When this happens, tapinstall.exe prints an error message like this: + ; UpdateDriverForPlugAndPlayDevices failed, GetLastError=-536870333 + ; + ; We can use the presence of that magic number to detect this case. + Var /GLOBAL DRIVER_FAILURE_MAGIC_NUMBER_INDEX + ${StrLoc} $DRIVER_FAILURE_MAGIC_NUMBER_INDEX $1 "536870333" ">" + + StrCmp $DRIVER_FAILURE_MAGIC_NUMBER_INDEX "" submitsentryreport + ; The term "device software" is the same as that used by the prompt, at least on Windows 7. + MessageBox MB_OK "Sorry, you must install the device software in order to use Outline. Please try \ + running the installer again." + Quit + + submitsentryreport: + MessageBox MB_OK "Sorry, we could not configure your system to connect to Outline. Please try \ + running the installer again. If you still cannot install Outline, please get in \ + touch with us and let us know that the TAP device failed to install with error code $0." + + ; Submit a Sentry error event. + ; + ; This will get bundled into an issue named "could not install TAP device" with the following + ; attributes: + ; - a single breadcrumb containing the output of add_tap_device.bat + ; - Windows version, as a tag named "os" with a value identical in most cases to what the + ; JavaScript Sentry client produces, e.g. "Windows 10.0.17134" + ; - client version + ; + ; Note: + ; - Sentry won't accept a breadcrumbs without a timestamp; fortunately, it accepts obviously + ; bogus values so we don't have to fetch the real time. + ; - Because nsExec::ExecToStack yields "NSIS strings" strings suitable for inclusion in, for + ; example, a MessageBox, e.g. "device not found$\ncommand failed", we must convert it to a + ; string that Sentry will like *and* can fit on one line, e.g. + ; "device not found\ncommand failed"; fortunately, StrFunc.nsh's StrNSISToIO does precisely + ; this. + ; - RELEASE and SENTRY_URL are defined in env.nsh which is generated at build time by + ; {package,release}_action.sh. + + ; TODO: Remove this once we figure out why/if breadcrumbs are being truncated. + Var /GLOBAL FAILURE_MESSAGE_LENGTH + StrLen $FAILURE_MESSAGE_LENGTH $1 + + ; http://nsis.sourceforge.net/Docs/StrFunc/StrFunc.txt + Var /GLOBAL FAILURE_MESSAGE + ${StrNSISToIO} $FAILURE_MESSAGE $1 + ${StrRep} $FAILURE_MESSAGE $FAILURE_MESSAGE '"' '\"' + + ${WinVerGetMajor} $R0 + ${WinVerGetMinor} $R1 + ${WinVerGetBuild} $R2 + + ; http://nsis.sourceforge.net/Inetc_plug-in#post + inetc::post '{\ + "message":"could not install TAP device ($0)",\ + "release":"${RELEASE}",\ + "tags":[\ + ["os", "Windows $R0.$R1.$R2"],\ + ["error_message_length", "$FAILURE_MESSAGE_LENGTH"]\ + ],\ + "breadcrumbs":[\ + {"timestamp":1, "message":"$FAILURE_MESSAGE"}\ + ]\ + }' /TOSTACK ${SENTRY_URL} /END + + Quit + + installservice: + + nsExec::Exec install_windows_service.bat + + nsExec::Exec "$SYSDIR\sc query OutlineService" + Pop $0 + StrCmp $0 0 success + ; TODO: Trigger a Sentry report for service installation failure, too, and revisit + ; the restart stuff in the TypeScript code. + MessageBox MB_OK "Sorry, we could not configure your system to connect to Outline. Please try \ + running the installer again. If you still cannot install Outline, please get in touch with us \ + and let us know that OutlineService failed to install." + Quit + + success: + +!macroend + +; TODO: Remove the TAP device on uninstall. This is impossible to implement safely +; with the bundled tapinstall.exe because it can only remove *all* devices +; having hwid tap0901 and these may include non-Outline devices. +!macro customUnInstall + nsExec::Exec "$SYSDIR\net stop OutlineService" + nsExec::Exec "$SYSDIR\sc delete OutlineService" +!macroend diff --git a/client/electron/electron-builder.json b/client/electron/electron-builder.json new file mode 100644 index 0000000000..bc0c7575e4 --- /dev/null +++ b/client/electron/electron-builder.json @@ -0,0 +1,52 @@ +{ + "artifactName": "Outline-Client.${ext}", + "asarUnpack": [ "client" ], + "directories": { + "buildResources": "output/client/electron", + "output": "output/client/electron/build" + }, + "extraMetadata": { + "main": "output/client/electron/index.js" + }, + "files": [ + "client/www", + "client/resources/tray", + "output/client/electron", + "!output/client/electron/build" + ], + "linux": { + "category": "Network", + "files": [ + "client/electron/linux_proxy_controller/dist", + "client/electron/icons/png", + "client/output/build/linux" + ], + "icon": "client/electron/icons/png", + "target": { + "arch": [ + "x64" + ], + "target": "AppImage" + } + }, + "nsis": { + "include": "client/electron/custom_install_steps.nsh", + "perMachine": true + }, + "win": { + "files": [ + "client/output/build/windows" + ], + "icon": "client/electron/icons/win/icon.ico", + "sign": "client/electron/windows/electron_builder_signing_plugin.cjs", + "signingHashAlgorithms": [ + "sha256" + ], + "target": [ + { + "arch": "ia32", + "target": "nsis" + } + ] + } +} diff --git a/src/electron/find_tap_device_name.bat b/client/electron/find_tap_device_name.bat similarity index 100% rename from src/electron/find_tap_device_name.bat rename to client/electron/find_tap_device_name.bat diff --git a/src/electron/go_vpn_tunnel.ts b/client/electron/go_vpn_tunnel.ts similarity index 97% rename from src/electron/go_vpn_tunnel.ts rename to client/electron/go_vpn_tunnel.ts index 1b9171eac9..e225222287 100755 --- a/src/electron/go_vpn_tunnel.ts +++ b/client/electron/go_vpn_tunnel.ts @@ -19,11 +19,9 @@ import {powerMonitor} from 'electron'; import {ChildProcessHelper, ProcessTerminatedExitCodeError, ProcessTerminatedSignalError} from './process'; import {RoutingDaemon} from './routing_service'; import {VpnTunnel} from './vpn_tunnel'; -import {pathToEmbeddedTun2socksBinary} from '../../client/infrastructure/electron/app_paths'; -import {ShadowsocksSessionConfig} from '../../client/src/www/app/tunnel'; -import {TunnelStatus} from '../../client/src/www/app/tunnel'; -import {ErrorCode, fromErrorCode, UnexpectedPluginError} from '../../client/src/www/model/errors'; - +import {pathToEmbeddedTun2socksBinary} from '../infrastructure/electron/app_paths'; +import {ShadowsocksSessionConfig, TunnelStatus} from '../src/www/app/tunnel'; +import {ErrorCode, fromErrorCode, UnexpectedPluginError} from '../src/www/model/errors'; const isLinux = platform() === 'linux'; const isWindows = platform() === 'win32'; diff --git a/src/electron/icons/mac/icon.icns b/client/electron/icons/mac/icon.icns similarity index 100% rename from src/electron/icons/mac/icon.icns rename to client/electron/icons/mac/icon.icns diff --git a/src/electron/icons/png/1024x1024.png b/client/electron/icons/png/1024x1024.png similarity index 100% rename from src/electron/icons/png/1024x1024.png rename to client/electron/icons/png/1024x1024.png diff --git a/src/electron/icons/png/128x128.png b/client/electron/icons/png/128x128.png similarity index 100% rename from src/electron/icons/png/128x128.png rename to client/electron/icons/png/128x128.png diff --git a/src/electron/icons/png/16x16.png b/client/electron/icons/png/16x16.png similarity index 100% rename from src/electron/icons/png/16x16.png rename to client/electron/icons/png/16x16.png diff --git a/src/electron/icons/png/24x24.png b/client/electron/icons/png/24x24.png similarity index 100% rename from src/electron/icons/png/24x24.png rename to client/electron/icons/png/24x24.png diff --git a/src/electron/icons/png/256x256.png b/client/electron/icons/png/256x256.png similarity index 100% rename from src/electron/icons/png/256x256.png rename to client/electron/icons/png/256x256.png diff --git a/src/electron/icons/png/32x32.png b/client/electron/icons/png/32x32.png similarity index 100% rename from src/electron/icons/png/32x32.png rename to client/electron/icons/png/32x32.png diff --git a/src/electron/icons/png/48x48.png b/client/electron/icons/png/48x48.png similarity index 100% rename from src/electron/icons/png/48x48.png rename to client/electron/icons/png/48x48.png diff --git a/src/electron/icons/png/512x512.png b/client/electron/icons/png/512x512.png similarity index 100% rename from src/electron/icons/png/512x512.png rename to client/electron/icons/png/512x512.png diff --git a/src/electron/icons/png/64x64.png b/client/electron/icons/png/64x64.png similarity index 100% rename from src/electron/icons/png/64x64.png rename to client/electron/icons/png/64x64.png diff --git a/src/electron/icons/win/icon.ico b/client/electron/icons/win/icon.ico similarity index 100% rename from src/electron/icons/win/icon.ico rename to client/electron/icons/win/icon.ico diff --git a/src/electron/index.ts b/client/electron/index.ts similarity index 98% rename from src/electron/index.ts rename to client/electron/index.ts index dfd3a5d957..bc9498babc 100644 --- a/src/electron/index.ts +++ b/client/electron/index.ts @@ -24,15 +24,14 @@ import autoLaunch = require('auto-launch'); // tslint:disable-line import {app, BrowserWindow, ipcMain, Menu, MenuItemConstructorOptions, nativeImage, shell, Tray} from 'electron'; import {autoUpdater} from 'electron-updater'; - -import {lookupIp} from './connectivity'; +import {lookupIp} from "./connectivity"; import {GoVpnTunnel} from './go_vpn_tunnel'; import {installRoutingServices, RoutingDaemon} from './routing_service'; import {TunnelStore, SerializableTunnel} from './tunnel_store'; import {VpnTunnel} from './vpn_tunnel'; -import {TunnelStatus} from '../../client/src/www/app/tunnel'; -import {ShadowsocksSessionConfig} from '../../client/src/www/app/tunnel'; -import * as errors from '../../client/src/www/model/errors'; +import {ShadowsocksSessionConfig} from '../src/www/app/tunnel'; +import {TunnelStatus} from '../src/www/app/tunnel'; +import * as errors from '../src/www/model/errors'; // TODO: can we define these macros in other .d.ts files with default values? // Build-time macros injected by webpack's DefinePlugin: @@ -143,7 +142,7 @@ function setupWindow(): void { // The ideal solution would be: either electron-builder supports the app icon; or we add // dpi-aware features to this app. if (isLinux) { - mainWindow.setIcon(path.join(app.getAppPath(), 'build', 'icons', 'png', '64x64.png')); + mainWindow.setIcon(path.join(app.getAppPath(), 'output', 'client', 'electron', 'icons', 'png', '64x64.png')); } const pathToIndexHtml = path.join(app.getAppPath(), 'client', 'www', 'index_electron.html'); diff --git a/src/electron/install_windows_service.bat b/client/electron/install_windows_service.bat similarity index 100% rename from src/electron/install_windows_service.bat rename to client/electron/install_windows_service.bat diff --git a/client/tools/outline_proxy_controller/.gitignore b/client/electron/linux_proxy_controller/.gitignore similarity index 100% rename from client/tools/outline_proxy_controller/.gitignore rename to client/electron/linux_proxy_controller/.gitignore diff --git a/client/tools/outline_proxy_controller/CMakeLists.txt b/client/electron/linux_proxy_controller/CMakeLists.txt similarity index 100% rename from client/tools/outline_proxy_controller/CMakeLists.txt rename to client/electron/linux_proxy_controller/CMakeLists.txt diff --git a/client/tools/outline_proxy_controller/Dockerfile b/client/electron/linux_proxy_controller/Dockerfile similarity index 100% rename from client/tools/outline_proxy_controller/Dockerfile rename to client/electron/linux_proxy_controller/Dockerfile diff --git a/client/tools/outline_proxy_controller/OutlineProxyControllerConfig.h.in b/client/electron/linux_proxy_controller/OutlineProxyControllerConfig.h.in similarity index 100% rename from client/tools/outline_proxy_controller/OutlineProxyControllerConfig.h.in rename to client/electron/linux_proxy_controller/OutlineProxyControllerConfig.h.in diff --git a/client/tools/outline_proxy_controller/README.md b/client/electron/linux_proxy_controller/README.md similarity index 100% rename from client/tools/outline_proxy_controller/README.md rename to client/electron/linux_proxy_controller/README.md diff --git a/client/tools/outline_proxy_controller/build.action.sh b/client/electron/linux_proxy_controller/build.action.sh similarity index 100% rename from client/tools/outline_proxy_controller/build.action.sh rename to client/electron/linux_proxy_controller/build.action.sh diff --git a/client/tools/outline_proxy_controller/dist/OutlineProxyController b/client/electron/linux_proxy_controller/dist/OutlineProxyController similarity index 100% rename from client/tools/outline_proxy_controller/dist/OutlineProxyController rename to client/electron/linux_proxy_controller/dist/OutlineProxyController diff --git a/client/tools/outline_proxy_controller/dist/install_linux_service.sh b/client/electron/linux_proxy_controller/dist/install_linux_service.sh similarity index 100% rename from client/tools/outline_proxy_controller/dist/install_linux_service.sh rename to client/electron/linux_proxy_controller/dist/install_linux_service.sh diff --git a/client/tools/outline_proxy_controller/dist/outline_proxy_controller.service b/client/electron/linux_proxy_controller/dist/outline_proxy_controller.service similarity index 100% rename from client/tools/outline_proxy_controller/dist/outline_proxy_controller.service rename to client/electron/linux_proxy_controller/dist/outline_proxy_controller.service diff --git a/client/tools/outline_proxy_controller/logger.cpp b/client/electron/linux_proxy_controller/logger.cpp similarity index 100% rename from client/tools/outline_proxy_controller/logger.cpp rename to client/electron/linux_proxy_controller/logger.cpp diff --git a/client/tools/outline_proxy_controller/logger.h b/client/electron/linux_proxy_controller/logger.h similarity index 100% rename from client/tools/outline_proxy_controller/logger.h rename to client/electron/linux_proxy_controller/logger.h diff --git a/client/tools/outline_proxy_controller/network_monitor.cpp b/client/electron/linux_proxy_controller/network_monitor.cpp similarity index 100% rename from client/tools/outline_proxy_controller/network_monitor.cpp rename to client/electron/linux_proxy_controller/network_monitor.cpp diff --git a/client/tools/outline_proxy_controller/network_monitor.h b/client/electron/linux_proxy_controller/network_monitor.h similarity index 100% rename from client/tools/outline_proxy_controller/network_monitor.h rename to client/electron/linux_proxy_controller/network_monitor.h diff --git a/client/tools/outline_proxy_controller/outline_controller_server.cpp b/client/electron/linux_proxy_controller/outline_controller_server.cpp similarity index 100% rename from client/tools/outline_proxy_controller/outline_controller_server.cpp rename to client/electron/linux_proxy_controller/outline_controller_server.cpp diff --git a/client/tools/outline_proxy_controller/outline_controller_server.h b/client/electron/linux_proxy_controller/outline_controller_server.h similarity index 100% rename from client/tools/outline_proxy_controller/outline_controller_server.h rename to client/electron/linux_proxy_controller/outline_controller_server.h diff --git a/client/tools/outline_proxy_controller/outline_daemon.cpp b/client/electron/linux_proxy_controller/outline_daemon.cpp similarity index 100% rename from client/tools/outline_proxy_controller/outline_daemon.cpp rename to client/electron/linux_proxy_controller/outline_daemon.cpp diff --git a/client/tools/outline_proxy_controller/outline_error.cpp b/client/electron/linux_proxy_controller/outline_error.cpp similarity index 100% rename from client/tools/outline_proxy_controller/outline_error.cpp rename to client/electron/linux_proxy_controller/outline_error.cpp diff --git a/client/tools/outline_proxy_controller/outline_error.h b/client/electron/linux_proxy_controller/outline_error.h similarity index 100% rename from client/tools/outline_proxy_controller/outline_error.h rename to client/electron/linux_proxy_controller/outline_error.h diff --git a/client/tools/outline_proxy_controller/outline_proxy_controller.cpp b/client/electron/linux_proxy_controller/outline_proxy_controller.cpp similarity index 100% rename from client/tools/outline_proxy_controller/outline_proxy_controller.cpp rename to client/electron/linux_proxy_controller/outline_proxy_controller.cpp diff --git a/client/tools/outline_proxy_controller/outline_proxy_controller.h b/client/electron/linux_proxy_controller/outline_proxy_controller.h similarity index 100% rename from client/tools/outline_proxy_controller/outline_proxy_controller.h rename to client/electron/linux_proxy_controller/outline_proxy_controller.h diff --git a/src/electron/preload.d.ts b/client/electron/preload.d.ts similarity index 100% rename from src/electron/preload.d.ts rename to client/electron/preload.d.ts diff --git a/src/electron/preload.ts b/client/electron/preload.ts similarity index 100% rename from src/electron/preload.ts rename to client/electron/preload.ts diff --git a/src/electron/process.ts b/client/electron/process.ts similarity index 100% rename from src/electron/process.ts rename to client/electron/process.ts diff --git a/src/electron/routing_service.ts b/client/electron/routing_service.ts similarity index 98% rename from src/electron/routing_service.ts rename to client/electron/routing_service.ts index ed1718f102..3ae942954b 100755 --- a/src/electron/routing_service.ts +++ b/client/electron/routing_service.ts @@ -20,9 +20,9 @@ import * as path from 'path'; import * as fsextra from 'fs-extra'; import * as sudo from 'sudo-prompt'; -import {pathToEmbeddedOutlineService} from '../../client/infrastructure/electron/app_paths'; -import {TunnelStatus} from '../../client/src/www/app/tunnel'; -import {ErrorCode, SystemConfigurationException} from '../../client/src/www/model/errors'; +import {pathToEmbeddedOutlineService} from '../infrastructure/electron/app_paths'; +import {TunnelStatus} from '../src/www/app/tunnel'; +import {ErrorCode, SystemConfigurationException} from '../src/www/model/errors'; const isLinux = platform() === 'linux'; const isWindows = platform() === 'win32'; diff --git a/src/electron/start.action.mjs b/client/electron/start.action.mjs similarity index 63% rename from src/electron/start.action.mjs rename to client/electron/start.action.mjs index 4343a5f05f..589ac27d1b 100644 --- a/src/electron/start.action.mjs +++ b/client/electron/start.action.mjs @@ -12,14 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. +import path from 'path'; import url from 'url'; import electron from 'electron'; -import {getBuildParameters} from '../../client/src/build/get_build_parameters.mjs'; -import {getRootDir} from '../../client/src/build/get_root_dir.mjs'; -import {runAction} from '../../client/src/build/run_action.mjs'; -import {spawnStream} from '../../client/src/build/spawn_stream.mjs'; +import {getRootDir} from '../../src/build/get_root_dir.mjs'; +import {runAction} from '../../src/build/run_action.mjs'; +import {spawnStream} from '../../src/build/spawn_stream.mjs'; +import {getBuildParameters} from '../src/build/get_build_parameters.mjs'; /** * @description Builds and starts the electron application. @@ -29,13 +30,13 @@ import {spawnStream} from '../../client/src/build/spawn_stream.mjs'; export async function main(...parameters) { const {platform, buildMode} = getBuildParameters(parameters); - await runAction('www/build', platform, `--buildMode=${buildMode}`); - await runAction('electron/build_main', ...parameters); - await runAction('electron/build', platform, `--buildMode=${buildMode}`); + await runAction('client/src/www/build', platform, `--buildMode=${buildMode}`); + await runAction('client/electron/build_main', ...parameters); + await runAction('client/electron/build', platform, `--buildMode=${buildMode}`); process.env.OUTLINE_DEBUG = buildMode === 'debug'; - await spawnStream(electron, getRootDir()); + await spawnStream(electron, path.join(getRootDir(), 'output', 'client', 'electron')); } if (import.meta.url === url.pathToFileURL(process.argv[1]).href) { diff --git a/client/electron/tsconfig.json b/client/electron/tsconfig.json new file mode 100644 index 0000000000..1ee59c8ae3 --- /dev/null +++ b/client/electron/tsconfig.json @@ -0,0 +1,6 @@ +{ + "extends": "../src/www/tsconfig.json", + "compilerOptions": { + "outDir": "../../output/electron" + } +} diff --git a/src/electron/tunnel_store.ts b/client/electron/tunnel_store.ts similarity index 97% rename from src/electron/tunnel_store.ts rename to client/electron/tunnel_store.ts index 44743c6efc..720c1b48cc 100755 --- a/src/electron/tunnel_store.ts +++ b/client/electron/tunnel_store.ts @@ -15,7 +15,7 @@ import * as fs from 'fs'; import * as path from 'path'; -import {ShadowsocksSessionConfig} from '../../client/src/www/app/tunnel'; +import {ShadowsocksSessionConfig} from '../src/www/app/tunnel'; // Format to store a tunnel configuration. export interface SerializableTunnel { diff --git a/src/electron/types/socks/index.d.ts b/client/electron/types/socks/index.d.ts similarity index 100% rename from src/electron/types/socks/index.d.ts rename to client/electron/types/socks/index.d.ts diff --git a/src/electron/vpn_tunnel.ts b/client/electron/vpn_tunnel.ts similarity index 96% rename from src/electron/vpn_tunnel.ts rename to client/electron/vpn_tunnel.ts index 12cca0981d..707d12dd36 100755 --- a/src/electron/vpn_tunnel.ts +++ b/client/electron/vpn_tunnel.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -import {TunnelStatus} from '../../client/src/www/app/tunnel'; +import {TunnelStatus} from '../src/www/app/tunnel'; // Represents a VPN tunnel to a proxy server. export interface VpnTunnel { diff --git a/src/electron/webpack_electron_main.mjs b/client/electron/webpack_electron_main.mjs similarity index 87% rename from src/electron/webpack_electron_main.mjs rename to client/electron/webpack_electron_main.mjs index 58ee3d4264..5eacdd83c1 100755 --- a/src/electron/webpack_electron_main.mjs +++ b/client/electron/webpack_electron_main.mjs @@ -23,7 +23,7 @@ const __dirname = path.dirname(__filename); export default ({sentryDsn, appVersion}) => [ { - entry: './src/electron/index.ts', + entry: './client/electron/index.ts', target: 'electron-main', node: { __dirname: false, @@ -50,11 +50,11 @@ export default ({sentryDsn, appVersion}) => [ ], output: { filename: 'index.js', - path: path.resolve(__dirname, '..', '..', 'build', 'electron', 'electron'), + path: path.resolve(__dirname, '..', '..', 'output', 'client', 'electron'), }, }, { - entry: './src/electron/preload.ts', + entry: './client/electron/preload.ts', target: 'electron-preload', devtool: 'inline-source-map', module: { @@ -71,7 +71,7 @@ export default ({sentryDsn, appVersion}) => [ }, output: { filename: 'preload.js', - path: path.resolve(__dirname, '..', '..', 'build', 'electron', 'electron'), + path: path.resolve(__dirname, '..', '..', 'output', 'client', 'electron'), }, }, ]; diff --git a/tools/OutlineService/OutlineService.sln b/client/electron/windows/OutlineService/OutlineService.sln similarity index 100% rename from tools/OutlineService/OutlineService.sln rename to client/electron/windows/OutlineService/OutlineService.sln diff --git a/tools/OutlineService/OutlineService/App.config b/client/electron/windows/OutlineService/OutlineService/App.config similarity index 100% rename from tools/OutlineService/OutlineService/App.config rename to client/electron/windows/OutlineService/OutlineService/App.config diff --git a/tools/OutlineService/OutlineService/OutlineService.Designer.cs b/client/electron/windows/OutlineService/OutlineService/OutlineService.Designer.cs similarity index 100% rename from tools/OutlineService/OutlineService/OutlineService.Designer.cs rename to client/electron/windows/OutlineService/OutlineService/OutlineService.Designer.cs diff --git a/tools/OutlineService/OutlineService/OutlineService.cs b/client/electron/windows/OutlineService/OutlineService/OutlineService.cs similarity index 100% rename from tools/OutlineService/OutlineService/OutlineService.cs rename to client/electron/windows/OutlineService/OutlineService/OutlineService.cs diff --git a/tools/OutlineService/OutlineService/OutlineService.csproj b/client/electron/windows/OutlineService/OutlineService/OutlineService.csproj similarity index 100% rename from tools/OutlineService/OutlineService/OutlineService.csproj rename to client/electron/windows/OutlineService/OutlineService/OutlineService.csproj diff --git a/tools/OutlineService/OutlineService/OutlineService.resx b/client/electron/windows/OutlineService/OutlineService/OutlineService.resx similarity index 100% rename from tools/OutlineService/OutlineService/OutlineService.resx rename to client/electron/windows/OutlineService/OutlineService/OutlineService.resx diff --git a/tools/OutlineService/OutlineService/Program.cs b/client/electron/windows/OutlineService/OutlineService/Program.cs similarity index 100% rename from tools/OutlineService/OutlineService/Program.cs rename to client/electron/windows/OutlineService/OutlineService/Program.cs diff --git a/tools/OutlineService/OutlineService/Properties/AssemblyInfo.cs b/client/electron/windows/OutlineService/OutlineService/Properties/AssemblyInfo.cs similarity index 100% rename from tools/OutlineService/OutlineService/Properties/AssemblyInfo.cs rename to client/electron/windows/OutlineService/OutlineService/Properties/AssemblyInfo.cs diff --git a/tools/OutlineService/OutlineService/bin/OutlineService.exe b/client/electron/windows/OutlineService/OutlineService/bin/OutlineService.exe similarity index 100% rename from tools/OutlineService/OutlineService/bin/OutlineService.exe rename to client/electron/windows/OutlineService/OutlineService/bin/OutlineService.exe diff --git a/tools/OutlineService/OutlineService/bin/Release/OutlineService.exe.config b/client/electron/windows/OutlineService/OutlineService/bin/Release/OutlineService.exe.config similarity index 100% rename from tools/OutlineService/OutlineService/bin/Release/OutlineService.exe.config rename to client/electron/windows/OutlineService/OutlineService/bin/Release/OutlineService.exe.config diff --git a/tools/OutlineService/OutlineService/packages.config b/client/electron/windows/OutlineService/OutlineService/packages.config similarity index 100% rename from tools/OutlineService/OutlineService/packages.config rename to client/electron/windows/OutlineService/OutlineService/packages.config diff --git a/src/electron/windows/digicert-usb-config/eToken-macos.cfg b/client/electron/windows/digicert-usb-config/eToken-macos.cfg similarity index 100% rename from src/electron/windows/digicert-usb-config/eToken-macos.cfg rename to client/electron/windows/digicert-usb-config/eToken-macos.cfg diff --git a/src/electron/windows/digicert-usb-config/eToken-windows.cfg b/client/electron/windows/digicert-usb-config/eToken-windows.cfg similarity index 100% rename from src/electron/windows/digicert-usb-config/eToken-windows.cfg rename to client/electron/windows/digicert-usb-config/eToken-windows.cfg diff --git a/src/electron/windows/electron_builder_signing_plugin.cjs b/client/electron/windows/electron_builder_signing_plugin.cjs similarity index 92% rename from src/electron/windows/electron_builder_signing_plugin.cjs rename to client/electron/windows/electron_builder_signing_plugin.cjs index cc66e17f3e..8613f811e3 100644 --- a/src/electron/windows/electron_builder_signing_plugin.cjs +++ b/client/electron/windows/electron_builder_signing_plugin.cjs @@ -29,8 +29,8 @@ * @param {Object} configuration.options a duplication of electron-builder.json */ async function electronBuilderEntryPoint(configuration) { - const {runAction} = await import('../../build/run_action.mjs'); - await runAction('src/electron/windows/sign_windows_executable', + const {runAction} = await import('../../../src/build/run_action.mjs'); + await runAction('client/electron/windows/sign_windows_executable', '--target', configuration.path, '--algorithm', configuration.hash); } diff --git a/src/electron/windows/sign_windows_executable.action.mjs b/client/electron/windows/sign_windows_executable.action.mjs similarity index 99% rename from src/electron/windows/sign_windows_executable.action.mjs rename to client/electron/windows/sign_windows_executable.action.mjs index 72e30a83f5..bc71d95492 100644 --- a/src/electron/windows/sign_windows_executable.action.mjs +++ b/client/electron/windows/sign_windows_executable.action.mjs @@ -179,7 +179,7 @@ async function main() { } // Call this script through CLI to sign a Windows executable: -// npm run action src/electron/windows/sign_windows_executable -- +// npm run action client/electron/windows/sign_windows_executable -- // --target // --algorithm // --certtype diff --git a/tools/smartdnsblock/README.md b/client/electron/windows/smartdnsblock/README.md similarity index 100% rename from tools/smartdnsblock/README.md rename to client/electron/windows/smartdnsblock/README.md diff --git a/tools/smartdnsblock/bin/smartdnsblock.exe b/client/electron/windows/smartdnsblock/bin/smartdnsblock.exe similarity index 100% rename from tools/smartdnsblock/bin/smartdnsblock.exe rename to client/electron/windows/smartdnsblock/bin/smartdnsblock.exe diff --git a/tools/smartdnsblock/smartdnsblock.sln b/client/electron/windows/smartdnsblock/smartdnsblock.sln similarity index 100% rename from tools/smartdnsblock/smartdnsblock.sln rename to client/electron/windows/smartdnsblock/smartdnsblock.sln diff --git a/tools/smartdnsblock/smartdnsblock/smartdnsblock.cpp b/client/electron/windows/smartdnsblock/smartdnsblock/smartdnsblock.cpp similarity index 100% rename from tools/smartdnsblock/smartdnsblock/smartdnsblock.cpp rename to client/electron/windows/smartdnsblock/smartdnsblock/smartdnsblock.cpp diff --git a/tools/smartdnsblock/smartdnsblock/smartdnsblock.filters b/client/electron/windows/smartdnsblock/smartdnsblock/smartdnsblock.filters similarity index 100% rename from tools/smartdnsblock/smartdnsblock/smartdnsblock.filters rename to client/electron/windows/smartdnsblock/smartdnsblock/smartdnsblock.filters diff --git a/tools/smartdnsblock/smartdnsblock/smartdnsblock.user b/client/electron/windows/smartdnsblock/smartdnsblock/smartdnsblock.user similarity index 100% rename from tools/smartdnsblock/smartdnsblock/smartdnsblock.user rename to client/electron/windows/smartdnsblock/smartdnsblock/smartdnsblock.user diff --git a/tools/smartdnsblock/smartdnsblock/smartdnsblock.vcxproj b/client/electron/windows/smartdnsblock/smartdnsblock/smartdnsblock.vcxproj similarity index 100% rename from tools/smartdnsblock/smartdnsblock/smartdnsblock.vcxproj rename to client/electron/windows/smartdnsblock/smartdnsblock/smartdnsblock.vcxproj diff --git a/client/package.json b/client/package.json index c4c6cb9e99..0bed1ef01f 100644 --- a/client/package.json +++ b/client/package.json @@ -143,6 +143,6 @@ ] }, "scripts": { - "clean": "rm -rf build output node_modules www platforms plugins" + "clean": "rm -rf output node_modules www platforms plugins" } } diff --git a/client/src/cordova/apple/xcode/ios/Outline.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/client/src/cordova/apple/xcode/ios/Outline.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 0000000000..23be32741b --- /dev/null +++ b/client/src/cordova/apple/xcode/ios/Outline.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,32 @@ +{ + "pins" : [ + { + "identity" : "cocoalumberjack", + "kind" : "remoteSourceControl", + "location" : "https://github.com/CocoaLumberjack/CocoaLumberjack", + "state" : { + "revision" : "4b8714a7fb84d42393314ce897127b3939885ec3", + "version" : "3.8.5" + } + }, + { + "identity" : "sentry-cocoa", + "kind" : "remoteSourceControl", + "location" : "https://github.com/getsentry/sentry-cocoa", + "state" : { + "revision" : "cf43eac1aa12017868c257ad3854ad87a5de0758", + "version" : "7.31.5" + } + }, + { + "identity" : "swift-log", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-log", + "state" : { + "revision" : "e97a6fcb1ab07462881ac165fdbb37f067e205d5", + "version" : "1.5.4" + } + } + ], + "version" : 2 +} diff --git a/client/src/www/app/electron_main.ts b/client/src/www/app/electron_main.ts index 0a2ef70673..a63619b5f2 100644 --- a/client/src/www/app/electron_main.ts +++ b/client/src/www/app/electron_main.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -/// +/// import 'web-animations-js/web-animations-next-lite.min.js'; import '@webcomponents/webcomponentsjs/webcomponents-bundle.js'; diff --git a/client/src/www/tsconfig.json b/client/src/www/tsconfig.json index 93c6c6f982..d8684f8427 100644 --- a/client/src/www/tsconfig.json +++ b/client/src/www/tsconfig.json @@ -2,6 +2,10 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": "../../www", - "lib": ["es2022", "dom", "dom.iterable"] + "lib": ["es2022", "dom", "dom.iterable"], + "paths": { + // without this, import 'electron' resolves to ./client/electron/index.ts + "electron": ["./node_modules/electron/index.js"] + } } } diff --git a/client/tools/build/Dockerfile b/client/tools/build/Dockerfile deleted file mode 100644 index a2df4e22eb..0000000000 --- a/client/tools/build/Dockerfile +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright 2019 The Outline Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Though we normally prefer Alpine, many of the Android build tools require glibc. -FROM debian:9 - -# Notes on dependencies: -# - Bower requires git -# - gnupg is needed by the Node.js installer to add an Apt repository. -# - Several of Outline's build scripts require rsync. -RUN apt update && apt dist-upgrade -y && apt install -y wget unzip openjdk-8-jdk-headless gradle git gnupg rsync && apt clean - -# Node.js and NPM. -RUN wget -qO- https://deb.nodesource.com/setup_10.x | bash - -RUN apt update && apt install -y nodejs && apt clean - -# https://stackoverflow.com/questions/25672924/run-bower-from-root-user-its-possible-how -RUN echo '{"allow_root": true}' > /root/.bowerrc - -# https://cordova.apache.org/docs/en/latest/reference/cordova-cli/#cordova-telemetry-command -ENV CI=true - -COPY ./setup_linux_android.sh ./setup_linux_android.sh - -RUN bash ./setup_linux_android.sh diff --git a/client/tools/build/README.md b/client/tools/build/README.md deleted file mode 100644 index f8efea8c4a..0000000000 --- a/client/tools/build/README.md +++ /dev/null @@ -1,47 +0,0 @@ -Build the Outline Android app with Docker. No other tools are needed. - -This approach is based on [microcontainers](https://www.iron.io/microcontainers-tiny-portable-containers/), using [mhart's Node.js images](https://github.com/mhart/alpine-node). - -# Usage - -First, install Docker: -https://docs.docker.com/engine/installation/ - -Then, prefix your commands with: `./tools/build/build.sh` - -So, to install dependencies and build: -```bash -./tools/build/build.sh npm ci -./tools/build/build.sh npm run build -``` - -What does this script do?: - - 1. Starts a new Docker container, fetching the `outline/build-android` Docker image from Docker Hub if necessary. - 1. Runs the specified command in the container. - 1. Makes you the owner of all files in the repository (because commands in the container run as `root`, any new files created in the previous step will be owned by `root`). - 1. Deletes the container. - -# Updating the Image - -## Build - -```bash -npm run action tools/build/build -``` - -## Tag - -```bash -docker tag quay.io/outline/build-android:latest quay.io/outline/build-android:$(date +%F) -``` - -## Upload - -```bash -docker push quay.io/outline/build-android:$(date +%F) -``` - -## Fix script - -Update `IMAGE_NAME` in `build.sh` (`docker images --digests` to find the new image's digest) and prepare a pull request. diff --git a/client/tools/build/build.action.sh b/client/tools/build/build.action.sh deleted file mode 100755 index 17adee4477..0000000000 --- a/client/tools/build/build.action.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -# -# Copyright 2018 The Outline Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -set -eux - -docker build -t quay.io/outline/build-android tools/build diff --git a/client/tools/build/build.sh b/client/tools/build/build.sh deleted file mode 100755 index 0a99627d33..0000000000 --- a/client/tools/build/build.sh +++ /dev/null @@ -1,60 +0,0 @@ -#!/bin/bash -# -# Copyright 2018 The Outline Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -set -eu - -readonly IMAGE_NAME="quay.io/outline/build-android:2020-09-14@sha256:432b3ad1d7bfb247e8bda82e2943cbe06f7d07b6585e3f3d22df5706fc6b9ba1" - -BUILD=false -PUBLISH=false - -function error() { - echo "$@" >&2 -} - -function usage() { - cat <<-EOM -Usage: $0 commands - -Examples: - $0 npm run clean - $0 npm ci - $0 build -EOM -exit 1 -} - -while getopts h? opt; do - case $opt in - *) usage ;; - esac -done -shift $((OPTIND-1)) - -if ! which docker > /dev/null; then - error "You must install docker first. See https://docs.docker.com/engine/installation/" - exit 1 -fi - -if (( $# > 0 )); then - readonly GIT_ROOT=$(git rev-parse --show-toplevel) - # Rather than a working directory of something like "/worker", mirror - # the path on the host so that symlink tricks work as expected. - docker run --rm -ti -v "$GIT_ROOT":"$GIT_ROOT" -w "$GIT_ROOT" -e SENTRY_DSN=${SENTRY_DSN:-} $IMAGE_NAME "$@" - # GNU stat uses -c for format, which BSD stat does not accept; it uses -f instead - stat -c 2>&1 | grep -q illegal && STATFLAG="f" || STATFLAG="c" - # TODO: Don't spin up a second container just to chown. - docker run --rm -ti -v "$GIT_ROOT":/worker -w /worker $IMAGE_NAME chown -R $(stat -$STATFLAG "%u:%g" .git) /worker -fi diff --git a/client/tools/build/setup_macos_android.sh b/client/tools/build/setup_macos_android.sh deleted file mode 100755 index d40ffe75d1..0000000000 --- a/client/tools/build/setup_macos_android.sh +++ /dev/null @@ -1,98 +0,0 @@ -#!/bin/bash -# -# Copyright 2022 The Outline Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set -eu - -source "$(dirname "$0")/android_tools_versions.sh" || exit - -function install_jdk() { - # Cordova Android 10 has to use JDK 11. - if [[ -d "${HOME}/Library/Java/JavaVirtualMachines/jdk-11.0.2.jdk" ]]; then - echo 'JDK already installed, but not configured properly. Make sure to set JAVA_HOME.' - return - fi - - mkdir -p "${HOME}/Library/Java/JavaVirtualMachines/" - - echo 'Downloading JDK' - curl https://download.java.net/java/GA/jdk11/9/GPL/openjdk-11.0.2_osx-x64_bin.tar.gz | tar -xzk -C "${HOME}/Library/Java/JavaVirtualMachines/" -} - -function install_android_tools() { - declare -r android_home=${1?Need to pass Android SDK home} - declare -r cmdline_tools_root="${android_home}/cmdline-tools" - declare -r cmdline_tools_dir="${cmdline_tools_root}/8.0" - if [[ -d "${cmdline_tools_dir}" ]]; then - echo "Android command line tools already installed at ${cmdline_tools_dir}" - else - # From https://developer.android.com/studio#command-line-tools-only - echo "Installing Android command-line tools to ${cmdline_tools_dir}" - declare -r tmp_zip_dir="$(mktemp -d)" - - # android commandlinetools download location found on this webpage: https://developer.android.com/studio#command-line-tools-only - curl "https://dl.google.com/android/repository/commandlinetools-mac-9123335_latest.zip" --create-dirs --output "${tmp_zip_dir}/tools.zip" - unzip -q "${tmp_zip_dir}/tools.zip" -d "${tmp_zip_dir}" - mkdir -p "${cmdline_tools_root}" - mv "${tmp_zip_dir}/cmdline-tools" "${cmdline_tools_dir}" - rm -r "${tmp_zip_dir}" - fi - - echo 'Installing build-tools and ndk' - "${cmdline_tools_dir}/bin/sdkmanager" "build-tools;${OUTLINE_ANDROID_BUILD_TOOLS_VERSION}" "ndk;${OUTLINE_ANDROID_NDK_VERSION}" -} - -function install_gradle() { - declare -r gradle_home=${1?Need to pass Gradle home} - if which -s gradle; then - echo 'Gradle already installed' - return - fi - - declare -r tmp_zip_dir="$(mktemp -d)" - mkdir -p "${gradle_home}" - curl "https://downloads.gradle-dn.com/distributions/gradle-7.6-bin.zip" --create-dirs --output "${tmp_zip_dir}/gradle.zip" - unzip -d "${gradle_home}" "${tmp_zip_dir}/gradle.zip" - rm -r "${tmp_zip_dir}" -} - -function main() { - # See https://cordova.apache.org/docs/en/11.x/guide/platforms/android/index.html - # For Cordova Android requirements. - - if [[ "$(uname -s)" != 'Darwin' ]]; then - echo 'Must run from a macOS machine' > 2 - exit 1 - fi - - install_jdk - java -version - echo - - declare -r android_home="${ANDROID_HOME:-$HOME/Library/Android/sdk}" - install_android_tools "${android_home}" - echo - - declare -r gradle_home="$HOME/Library/gradle" - install_gradle "${gradle_home}" - "${gradle_home}/gradle-7.6/bin/gradle" --version - - echo 'Setup done. Make these environment variables are defined:' - echo 'export JAVA_HOME=$HOME/Library/Java/JavaVirtualMachines/jdk-11.0.2.jdk/Contents/Home' - echo "export ANDROID_HOME=${android_home}" - echo 'export PATH="$PATH:${ANDROID_HOME}/platform-tools:${ANDROID_HOME}/cmdline-tools/8.0/bin:${ANDROID_HOME}/emulator:'"${gradle_home}"'/gradle-7.6/bin"' -} - -main diff --git a/package.json b/package.json index 25c22f8733..b8e583da9e 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,5 @@ "electron-builder": "^24.13.3", "eslint-plugin-import": "^2.29.1", "node-fetch": "^2.6.7" - }, - "main": "build/electron/electron/index.js" + } } diff --git a/server_manager/README.md b/server_manager/README.md index a5015c4e50..da361a95cf 100644 --- a/server_manager/README.md +++ b/server_manager/README.md @@ -1,4 +1,4 @@ -# Outline Manager +# Outline Manager Logo  Outline Manager ![Build and Test](https://github.com/Jigsaw-Code/outline-apps/actions/workflows/build_and_test_debug_manager.yml/badge.svg?branch=master) diff --git a/src/electron/electron-builder.json b/src/electron/electron-builder.json deleted file mode 100644 index a547380483..0000000000 --- a/src/electron/electron-builder.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "files": ["build/electron", "client/www", "client/resources/tray", "!node_modules/electron"], - "asarUnpack": ["client"], - "artifactName": "Outline-Client.${ext}", - "directories": { - "output": "output/build/dist" - }, - "linux": { - "target": { - "target": "AppImage", - "arch": ["x64"] - }, - "files": ["build/icons/png", "client/output/build/linux", "client/tools/outline_proxy_controller/dist"], - "icon": "build/icons/png", - "category": "Network" - }, - "win": { - "target": [ - { - "target": "nsis", - "arch": "ia32" - } - ], - "files": ["client/output/build/windows"], - "icon": "build/icons/win/icon.ico", - "sign": "src/electron/windows/electron_builder_signing_plugin.cjs", - "signingHashAlgorithms": ["sha256"] - }, - "nsis": { - "perMachine": true, - "include": "src/electron/custom_install_steps.nsh" - } -} diff --git a/src/electron/tsconfig.json b/src/electron/tsconfig.json deleted file mode 100644 index 89375e09b8..0000000000 --- a/src/electron/tsconfig.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "extends": "../../client/src/www/tsconfig.json", - "compilerOptions": { - "outDir": "../../build/electron" - } -}