diff --git a/.cspell/words.txt b/.cspell/words.txt
index 105d1a80..1da8f974 100644
--- a/.cspell/words.txt
+++ b/.cspell/words.txt
@@ -3,6 +3,7 @@ _mkgmtime
_sh_denyno
_sh_denyrd
_sh_denyrw
+_spawnv
aarch64
advapi32
armv8
@@ -114,6 +115,7 @@ googletest
gpath
gtest_version
has_setxattr
+hkey
httpapi
httplib
icudata
@@ -121,6 +123,7 @@ icui18n
icuuc
iostreams
iphlpapi
+ipstream
jthread
libbitcoin
libbitcoinsystem
@@ -142,6 +145,7 @@ libuuid_include_dirs
libvlc
linkflags
localappdata
+lpbyte
lptr
lpwstr
markdownlint
@@ -154,8 +158,10 @@ mtune
musl-libc
nana
ncrypt
+nlohmann
nlohmann_json
nmakeprg
+nohup
nominmax
ntstatus
nullptr
@@ -163,6 +169,7 @@ nuspell_version
oleaut32
openal_version
openssldir
+pistream
pkgconfig
plarge_integer
plex
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 00000000..d3af6d38
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,4 @@
+*.tgz filter=lfs diff=lfs merge=lfs -text
+*.tar.gz filter=lfs diff=lfs merge=lfs -text
+*.tar.xz filter=lfs diff=lfs merge=lfs -text
+*.zip filter=lfs diff=lfs merge=lfs -text
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 331271ad..19db631f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,11 +1,28 @@
# Changelog
+## v2.0.5-rc
+
+### Issues
+
+* \#39 Create management portal in Flutter
+
+### Changes from v2.0.4-rc
+
+* Continue documentation updates
+* Fixed `-status` command erasing active mount information
+* Fixed overlapping HTTP REST API port's
+* Refactored/fixed instance locking
+* Removed passwords and secret key values from API calls
+* Renamed setting `ApiAuth` to `ApiPassword`
+* Require `--name,-na` option for encryption provider
+
## v2.0.4-rc
### BREAKING CHANGES
* `renterd` v2.0.0+ is now required. Prior versions will fail to mount.
+
### Issues
* \#35 [bug] Low frequency check is set to '0' instead of 1 hour by default
diff --git a/README.md b/README.md
index b78006c3..fafe53d7 100644
--- a/README.md
+++ b/README.md
@@ -3,11 +3,42 @@
Repertory allows you to mount S3 and Sia via FUSE on Linux or via WinFSP
on Windows.
+## Contents
+
+1. [Details and Features](#details-and-features)
+2. [Minimum Requirements](#minimum-requirements)
+ 1. [Supported Operating Systems](#supported-operating-systems)
+3. [GUI](#gui)
+4. [Usage](#usage)
+ 1. [Important Options](#important-options)
+ 2. [Sia](#sia)
+ * [Sia Initial Configuration](#sia-initial-configuration)
+ * [Sia Mounting](#sia-mounting)
+ * [Sia Configuration File](#sia-configuration-file)
+ 3. [S3](#s3)
+ * [S3 Initial Configuration](#s3-initial-configuration)
+ * [S3 Mounting](#s3-mounting)
+ * [S3 Configuration File](#s3-configuration-file)
+5. [Data Directories](#data-directories)
+ 1. [Linux Directories](#linux-directories)
+ 2. [Windows Directories](#windows-directories)
+6. [Remote Mounting](#remote-mounting)
+ 1. [Server Setup](#server-setup)
+ * [Remote Mount Configuration File Section](#remote-mount-configuration-file-section)
+ 2. [Client Setup](#client-setup)
+ * [Client Remote Mounting](#client-remote-mounting)
+ * [Remote Mount Configuration File](#remote-mount-configuration-file)
+7. [Compiling](#compiling)
+ 1. [Linux Compilation](#linux-compilation)
+ 2. [Windows Setup](#windows-compilation)
+8. [Credits](#credits)
+9. [Developer Public Key](#developer-public-key)
+10. [Consult the Wiki for additional information](https://git.fifthgrid.com/BlockStorage/repertory/wiki)
+
## Details and Features
* Optimized for [Plex Media Server](https://www.plex.tv/)
-* Single application to mount S3 and/or Sia
-* Remote mounting of Repertory instances on Linux and Windows
+* Remote mounting of `repertory` instances on Linux and Windows
* Securely share your mounts over TCP/IP via `XChaCha20-Poly1305` with other systems on your network or over the internet.
* Cross-platform support (Linux 64-bit, Linux arm64/aarch64, Windows 64-bit)
* Optionally encrypt file names and file data via `XChaCha20-Poly1305` in S3 mounts
@@ -15,137 +46,388 @@ on Windows.
## Minimum Requirements
* [Sia renterd](https://github.com/SiaFoundation/renterd/releases) v2.0.0+ for Sia support
-* Only 64-bit operating systems are supported
- * By default, Linux requires `fusermount3`; otherwise, `repertory` must be manually compiled with `libfuse2` support
- * Windows requires the following dependencies to be installed:
- * [WinFSP 2023](https://github.com/winfsp/winfsp/releases/download/v2.0/winfsp-2.0.23075.msi)
+* Linux requires `fusermount3`; otherwise, `repertory` must be manually compiled with `libfuse2` support
+* Windows requires the following dependencies to be installed:
+ * [WinFSP 2023](https://github.com/winfsp/winfsp/releases/download/v2.0/winfsp-2.0.23075.msi)
-## Supported Operating Systems
+### Supported Operating Systems
+
+Only 64-bit operating systems are supported
* Linux `arm64/aarch64`
* Linux `amd64`
* Windows 64-bit 10, 11
+## GUI
+
+As of `v2.0.5-rc`, mounts can be managed using the `Repertory Management Portal`.
+To launch the portal, execute the following command:
+
+* `repertory -ui`
+ * The default username is `repertory`
+ * The default password is `repertory`
+
+After first launch, `ui.json` will be created in the appropriate data directory.
+See [Data Directories](#data-directories).
+You should modify this file directly or use the portal to change the default
+username and password.
+
+### Screenshot
+
+
+
## Usage
-### Sia
-
-* Initial Configuration
- * Sia steps:
- * Set the appropriate bucket name and `renterd` API password in `repertory` configuration:
- * To use `default` as the bucket name and configuration name:
- * `repertory -set HostConfig.ApiPassword ''`
- * To use a different bucket name with `default` as the configuration name:
- * `repertory -set HostConfig.ApiPassword ''`
- * `repertory -set SiaConfig.Bucket ''`
- * For all other configurations:
- * `repertory --name '' -set HostConfig.ApiPassword ''`
- * `repertory --name '' -set SiaConfig.Bucket ''`
- * To verify/view all configuration options:
- * `repertory -dc`
- * `repertory --name '' -dc`
- * Example:
- * `repertory --name default -dc`
-* Mounting on Linux:
- * `repertory /mnt/location`
- * `repertory --name '' /mnt/location`
- * Example:
- * `repertory --name default /mnt/location`
-* Mounting on Windows:
- * `repertory t:`
- * `repertory --name '' t:`
- * Example:
- * `repertory --name default t:`
-
-### S3
-
-* Initial Configuration
- * S3 steps:
- * Set the appropriate base URL:
- * `repertory -s3 --name '' -set S3Config.URL ''`
- * Example:
- * `repertory -s3 --name minio -set S3Config.URL 'http://localhost:9000'`
- * Set the appropriate bucket name:
- * `repertory -s3 --name '' -set S3Config.Bucket ''`
- * Set the appropriate access key:
- * `repertory -s3 --name '' -set S3Config.AccessKey ''`
- * Set the appropriate secret key:
- * `repertory -s3 --name '' -set S3Config.SecretKey ''`
- * For Sia and most local S3 gateway instances, enable path style URL's:
- * `repertory -s3 --name '' -set S3Config.UsePathStyle true`
- * Optional steps:
- * Set an appropriate region. Default is set to `any`:
- * `repertory -s3 --name '' -set S3Config.Region ''`
- * Enable encrypted file names and file data. Set a strong, random encryption token and be sure to store it in a secure backup location:
- * `repertory -s3 --name '' -set S3Config.EncryptionToken ''`
- * To verify/view all configuration options:
- * `repertory -s3 --name '' -dc`
- * Example:
- * `repertory -s3 --name minio -dc`
-* Mounting on Linux:
- * `repertory -s3 --name '' /mnt/location`
- * Example:
- * `repertory -s3 --name minio /mnt/location`
-* Mounting on Windows:
- * `repertory -s3 --name '' t:`
- * Example:
- * `repertory -s3 --name minio t:`
-
-### Notable Options
+### Important Options
* `--help`
* Display all mount utility options
+
+* `-f`
+ * Keep process in foreground on Linux.
+
* `--name, -na [name]`
+ * Identifies a unique configuration name to support multiple mounts.
* The `--name` option can be set to any valid value allowed as a file name for your filesystem.
* For Sia, the bucket name will be set to the same value if it is empty in the configuration file.
* If the `--name` option is not specified, `default` will be used.
* For S3, the `--name` option is required and does not affect the bucket name.
+
* `-dc`
* Display mount configuration
* For Sia, `--name` is optional
* For S3, the `-s3` option is required along with `--name`
+### Sia
+
+#### Sia Initial Configuration
+
+* Required steps:
+ * Set the appropriate bucket name and `renterd` API password in `repertory` configuration:
+ * To use `default` as the bucket name and configuration name, you only need to set the `renterd` API password:
+ * `repertory -set HostConfig.ApiPassword ''`
+ * To specify a different bucket name while using `default` as the configuration name:
+ * `repertory -set HostConfig.ApiPassword ''`
+ * `repertory -set SiaConfig.Bucket ''`
+ * For all other configurations:
+ * `repertory --name '' -set HostConfig.ApiPassword ''`
+ * `repertory --name '' -set SiaConfig.Bucket ''`
+
+* Optional steps:
+ * Set a user name used during `renterd` basic authentication:
+ * `repertory -set HostConfig.ApiUser ''`
+ * `repertory --name '' -set HostConfig.ApiUser ''`
+ * Set a custom agent string (default `Sia-Agent`):
+ * `repertory -set HostConfig.AgentString ''`
+ * `repertory --name '' -set HostConfig.AgentString ''`
+ * Set the host name or IP of the `renterd` instance (default `localhost`):
+ * `repertory -set HostConfig.HostNameOrIp ''`
+ * `repertory --name '' -set HostConfig.HostNameOrIp ''`
+ * Set the `renterd` API port (default `9980`):
+ * `repertory -set HostConfig.ApiPort 9981`
+ * `repertory --name '' -set HostConfig.ApiPort 9981`
+
+* To verify/view all configuration options:
+ * `repertory -dc`
+ * `repertory --name '' -dc`
+ * Example:
+ * `repertory --name default -dc`
+
+#### Sia Mounting
+
+* Linux:
+ * `repertory /mnt/location`
+ * `repertory --name '' /mnt/location`
+ * Example:
+ * `repertory --name default /mnt/location`
+
+* Windows:
+ * `repertory t:`
+ * `repertory --name '' t:`
+ * Example:
+ * `repertory --name default t:`
+
+#### Sia Configuration File
+
+```json
+{
+ "ApiPassword": "",
+ "ApiPort": 10000,
+ "ApiUser": "repertory",
+ "DatabaseType": "rocksdb",
+ "DownloadTimeoutSeconds": 30,
+ "EnableDownloadTimeout": true,
+ "EnableDriveEvents": false,
+ "EventLevel": "info",
+ "EvictionDelayMinutes": 1,
+ "EvictionUseAccessedTime": false,
+ "HighFreqIntervalSeconds": 30,
+ "HostConfig": {
+ "AgentString": "Sia-Agent",
+ "ApiPassword": "",
+ "ApiPort": 9980,
+ "ApiUser": "",
+ "HostNameOrIp": "localhost",
+ "Path": "",
+ "Protocol": "http",
+ "TimeoutMs": 60000
+ },
+ "LowFreqIntervalSeconds": 3600,
+ "MaxCacheSizeBytes": 21474836480,
+ "MaxUploadCount": 5,
+ "MedFreqIntervalSeconds": 120,
+ "OnlineCheckRetrySeconds": 60,
+ "PreferredDownloadType": "default",
+ "RemoteMount": {
+ "ApiPort": 20000,
+ "ClientPoolSize": 20,
+ "Enable": false,
+ "EncryptionToken": ""
+ },
+ "RetryReadCount": 6,
+ "RingBufferFileSize": 512,
+ "SiaConfig": {
+ "Bucket": "default"
+ },
+ "TaskWaitMs": 100,
+ "Version": 1
+}
+```
+
+### S3
+
+#### S3 Initial Configuration
+
+* Required steps:
+ * Set the appropriate base URL:
+ * `repertory -s3 --name '' -set S3Config.URL ''`
+ * Example:
+ * `repertory -s3 --name minio -set S3Config.URL 'http://localhost:9000'`
+ * Set the appropriate bucket name:
+ * `repertory -s3 --name '' -set S3Config.Bucket ''`
+ * Set the appropriate access key:
+ * `repertory -s3 --name '' -set S3Config.AccessKey ''`
+ * Set the appropriate secret key:
+ * `repertory -s3 --name '' -set S3Config.SecretKey ''`
+ * For Sia and most local S3 gateway instances, enable path style URL's:
+ * `repertory -s3 --name '' -set S3Config.UsePathStyle true`
+
+* Optional steps:
+ * Set an appropriate region. Default is set to `any`:
+ * `repertory -s3 --name '' -set S3Config.Region ''`
+ * Enable encrypted file names and file data. Set a strong, random encryption token and be sure to store it in a secure backup location:
+ * `repertory -s3 --name '' -set S3Config.EncryptionToken ''`
+
+* To verify/view all configuration options:
+ * `repertory -s3 --name '' -dc`
+ * Example:
+ * `repertory -s3 --name minio -dc`
+
+#### S3 Mounting
+
+* Linux:
+ * `repertory -s3 --name '' /mnt/location`
+ * Example:
+ * `repertory -s3 --name minio /mnt/location`
+
+* Windows:
+ * `repertory -s3 --name '' t:`
+ * Example:
+ * `repertory -s3 --name minio t:`
+
+#### S3 Configuration File
+
+```json
+{
+ "ApiPassword": "",
+ "ApiPort": 10100,
+ "ApiUser": "repertory",
+ "DatabaseType": "rocksdb",
+ "DownloadTimeoutSeconds": 30,
+ "EnableDownloadTimeout": true,
+ "EnableDriveEvents": false,
+ "EventLevel": "info",
+ "EvictionDelayMinutes": 1,
+ "EvictionUseAccessedTime": false,
+ "HighFreqIntervalSeconds": 30,
+ "LowFreqIntervalSeconds": 3600,
+ "MaxCacheSizeBytes": 21474836480,
+ "MaxUploadCount": 5,
+ "MedFreqIntervalSeconds": 120,
+ "OnlineCheckRetrySeconds": 60,
+ "PreferredDownloadType": "default",
+ "RemoteMount": {
+ "ApiPort": 20100,
+ "ClientPoolSize": 20,
+ "Enable": false,
+ "EncryptionToken": ""
+ },
+ "RetryReadCount": 6,
+ "RingBufferFileSize": 512,
+ "S3Config": {
+ "AccessKey": "",
+ "Bucket": "",
+ "EncryptionToken": "",
+ "Region": "any",
+ "SecretKey": "",
+ "TimeoutMs": 60000,
+ "URL": "http://localhost:9000",
+ "UsePathStyle": true,
+ "UseRegionInURL": false
+ },
+ "TaskWaitMs": 100,
+ "Version": 1
+}
+```
+
### Data Directories
-* Linux
- * `~/.local/repertory2`
-* Windows
- * `%LOCALAPPDATA%\repertory2`
- * Example:
- * `C:\Users\Tom\AppData\Local\repertory2`
- * IMPORTANT:
- * It is highly recommended to exclude this folder from any anti-virus/anti-malware applications as severe performance issues may arise.
- * Excluding the mounted drive letter is also highly recommended.
+#### Linux Directories
+
+* `~/.local/repertory2/s3`
+* `~/.local/repertory2/sia`
+
+#### Windows Directories
+
+* `%LOCALAPPDATA%\repertory2\s3`
+* `%LOCALAPPDATA%\repertory2\sia`
+ * Examples:
+ * `C:\Users\Tom\AppData\Local\repertory2\s3`
+ * `C:\Users\Tom\AppData\Local\repertory2\sia`
+* IMPORTANT:
+ * It is highly recommended to exclude this folder from any anti-virus/anti-malware applications as severe performance issues may arise.
+ * Excluding the mounted drive letter is also highly recommended.
## Remote Mounting
-`Repertory` allows local mounts to be shared with other computers on your network.
-This option is referred to as remote mounting. Instructions TBD.
+`repertory` allows local mounts to be shared with other computers on your network
+or over the internet. This option is referred to as remote mounting.
+
+### Server Setup
+
+The following steps must be performed on the mount you wish to share with
+other systems. Changes to configuration will not take affect while a mount is
+active, so it is recommended to unmount beforehand.
+
+* Required steps:
+ * Enable remote mount:
+ * Sia
+ * `repertory -set RemoteMount.Enable true`
+ * `repertory --name '' -set RemoteMount.Enable true`
+ * S3:
+ * `repertory -s3 --name '' -set RemoteMount.Enable true`
+ * Set a secure encryption token:
+ * Sia:
+ * `repertory -set RemoteMount.EncryptionToken ''`
+ * `repertory --name '' -set RemoteMount.EncryptionToken ''`
+ * S3:
+ * `repertory -s3 --name '' -set RemoteMount.EncryptionToken ''`
+
+* Optional steps:
+ * Change the port clients will use to connect to your mount:
+ * Sia:
+ * `repertory -set RemoteMount.ApiPort 20000`
+ * `repertory --name '' -set RemoteMount.ApiPort 20000`
+ * S3:
+ * `repertory -s3 --name '' -set RemoteMount.ApiPort 20000`
+
+* IMPORTANT:
+ * Be sure to configure your firewall to allow incoming TCP connections on the port configured in `RemoteMount.ApiPort`.
+
+#### Remote Mount Configuration File Section
+
+```json
+{
+ ...
+ "RemoteMount": {
+ "ApiPort": 20000,
+ "ClientPoolSize": 20,
+ "Enable": true,
+ "EncryptionToken": ""
+ },
+ ...
+}
+```
+
+### Client Setup
+
+Client configuration is provider agnostic, so there's no need to specify `-s3`
+for S3 providers.
+
+* Required steps:
+ * Set the encryption token to the same value configured during server setup:
+ * `repertory -rm : -set RemoteConfig.EncryptionToken ''`
+ * Replace `` with the host name or IP of the server
+ * Replace `` with the value of `RemoteMount.ApiPort` used in the server configuration
+ * Example:
+ * `repertory -rm 192.168.1.10:20000 -set RemoteConfig.EncryptionToken ''`
+ * `repertory -rm my.host.com:20000 -set RemoteConfig.EncryptionToken ''`
+
+#### Client Remote Mounting
+
+* Linux:
+ * `repertory -rm : /mnt/location`
+ * Example:
+ * `repertory -rm 192.168.1.10:20000 /mnt/location`
+
+* Windows:
+ * `repertory -rm : t:`
+ * Example:
+ * `repertory -rm 192.168.1.10:20000 t:`
+
+#### Remote Mount Configuration File
+
+```json
+{
+ "ApiPassword": "",
+ "ApiPort": 10010,
+ "ApiUser": "repertory",
+ "EnableDriveEvents": false,
+ "EventLevel": "info",
+ "RemoteConfig": {
+ "ApiPort": 20000,
+ "EncryptionToken": "",
+ "HostNameOrIp": "192.168.1.10",
+ "MaxConnections": 20,
+ "ReceiveTimeoutMs": 120000,
+ "SendTimeoutMs": 30000
+ },
+ "TaskWaitMs": 100,
+ "Version": 1
+}
+```
## Compiling
-* Successful compilation will result in all required files being placed in the `dist/` directory
-* Linux
+Successful compilation will result in all files required for execution to be placed
+in the `dist/` directory
+
+### Linux Compilation
+
+* Ensure `docker` is installed
+ * For x86_64:
+ * RelWithDebInfo: `scripts/make_unix.sh`
+ * Release: `scripts/make_unix.sh x86_64 Release`
+ * Debug: `scripts/make_unix.sh x86_64 Debug`
+
+ * For aarch64:
+ * RelWithDebInfo: `scripts/make_unix.sh aarch64`
+ * Release: `scripts/make_unix.sh aarch64 Release`
+ * Debug: `scripts/make_unix.sh aarch64 Debug`
+
+### Windows Compilation
+
+* OFFICIAL: Cross-compiling on Linux
* Ensure `docker` is installed
- * For x86_64:
- * RelWithDebInfo: `scripts/make_unix.sh`
- * Release: `scripts/make_unix.sh x86_64 Release`
- * Debug: `scripts/make_unix.sh x86_64 Debug`
- * For aarch64:
- * RelWithDebInfo: `scripts/make_unix.sh aarch64`
- * Release: `scripts/make_unix.sh aarch64 Release`
- * Debug: `scripts/make_unix.sh aarch64 Debug`
-* Windows
- * OFFICIAL: Cross-compiling on Linux
- * Ensure `docker` is installed
- * RelWithDebInfo: `scripts/make_win32.sh`
- * Release: `scripts/make_win32.sh x86_64 Release`
- * Debug: `scripts/make_win32.sh x86_64 Debug`
- * UNOFFICIAL: Compiling on Windows
- * Ensure latest [MSYS2](https://www.msys2.org/) is installed
- * RelWithDebInfo: `scripts\make_win32.cmd`
- * Release: `scripts\make_win32.cmd x86_64 Release`
- * Debug: `scripts\make_win32.cmd x86_64 Debug`
+ * RelWithDebInfo: `scripts/make_win32.sh`
+ * Release: `scripts/make_win32.sh x86_64 Release`
+ * Debug: `scripts/make_win32.sh x86_64 Debug`
+
+* UNOFFICIAL: Compiling on Windows
+ * Ensure latest [MSYS2](https://www.msys2.org/) is installed
+ * RelWithDebInfo: `scripts\make_win32.cmd`
+ * Release: `scripts\make_win32.cmd x86_64 Release`
+ * Debug: `scripts\make_win32.cmd x86_64 Debug`
## Credits
diff --git a/cmake/hashes.cmake b/cmake/hashes.cmake
index 9fbd0b43..942952c9 100644
--- a/cmake/hashes.cmake
+++ b/cmake/hashes.cmake
@@ -1,20 +1,20 @@
set(BINUTILS_HASH b53606f443ac8f01d1d5fc9c39497f2af322d99e14cea5c0b4b124d630379365)
set(BOOST2_HASH 7bd7ddceec1a1dfdcbdb3e609b60d01739c38390a5f956385a12f3122049f0ca)
set(BOOST_HASH f55c340aa49763b1925ccf02b2e83f35fdcf634c9d5164a2acb87540173c741d)
-set(CPP_HTTPLIB_HASH 405abd8170f2a446fc8612ac635d0db5947c0d2e156e32603403a4496255ff00)
-set(CURL_HASH 5a231145114589491fc52da118f9c7ef8abee885d1cb1ced99c7290e9a352f07)
+set(CPP_HTTPLIB_HASH c9b9e0524666e1cd088f0874c57c1ce7c0eaa8552f9f4e15c755d5201fc8c608)
+set(CURL_HASH 6edc063d1ebaf9cf3b3b46e9fef2f3cd8932694989ecd43d005d6e828426d09f)
set(EXPAT_HASH 372b18f6527d162fa9658f1c74d22a37429b82d822f5a1e1fc7e00f6045a06a2)
set(GCC_HASH 7d376d445f93126dc545e2c0086d0f647c3094aae081cdb78f42ce2bc25e7293)
-set(GTEST_HASH 7b42b4d6ed48810c5362c265a17faebe90dc2373c885e5216439d37927f02926)
+set(GTEST_HASH 78c676fc63881529bf97bf9d45948d905a66833fbfa5318ea2cd7478cb98f399)
set(ICU_HASH a2c443404f00098e9e90acf29dc318e049d2dc78d9ae5f46efb261934a730ce2)
set(JSON_HASH 0d8ef5af7f9794e3263480193c491549b2ba6cc74bb018906202ada498a79406)
set(LIBSODIUM_HASH 8e5aeca07a723a27bbecc3beef14b0068d37e7fc0e97f51b3f1c82d2a58005c1)
-set(MINGW_HASH 30e5aad2c48dd318150f79cff47661232c4175876d6b4d6b270961cf2b49a48b)
-set(OPENSSL_HASH e15dda82fe2fe8139dc2ac21a36d4ca01d5313c75f99f46c4e8a27709b7294bf)
+set(MINGW_HASH cc41898aac4b6e8dd5cffd7331b9d9515b912df4420a3a612b5ea2955bbeed2f)
+set(OPENSSL_HASH 002a2d6b30b58bf4bea46c43bdd96365aaf8daa6c428782aa4feee06da197df3)
set(PKG_CONFIG_HASH 6fc69c01688c9458a57eb9a1664c9aba372ccda420a02bf4429fe610e7e7d591)
-set(PUGIXML_HASH 2f10e276870c64b1db6809050a75e11a897a8d7456c4be5c6b2e35a11168a015)
-set(ROCKSDB_HASH 9b810c81731835fda0d4bbdb51d3199d901fa4395733ab63752d297da84c5a47)
-set(SPDLOG_HASH 9962648c9b4f1a7bbc76fd8d9172555bad1871fdb14ff4f842ef87949682caa5)
-set(SQLITE_HASH 77823cb110929c2bcb0f5d48e4833b5c59a8a6e40cdea3936b99e199dbbe5784)
+set(PUGIXML_HASH 655ade57fa703fb421c2eb9a0113b5064bddb145d415dd1f88c79353d90d511a)
+set(ROCKSDB_HASH fdccab16133c9d927a183c2648bcea8d956fb41eb1df2aacaa73eb0b95e43724)
+set(SPDLOG_HASH 25c843860f039a1600f232c6eb9e01e6627f7d030a2ae5e232bdd3c9205d26cc)
+set(SQLITE_HASH 6cebd1d8403fc58c30e93939b246f3e6e58d0765a5cd50546f16c00fd805d2c3)
set(STDUUID_HASH b1176597e789531c38481acbbed2a6894ad419aab0979c10410d59eb0ebf40d3)
set(ZLIB_HASH 17e88863f3600672ab49182f217281b6fc4d3c762bde361935e436a95214d05c)
diff --git a/cmake/libraries/boost.cmake b/cmake/libraries/boost.cmake
index a345372c..99825e4b 100644
--- a/cmake/libraries/boost.cmake
+++ b/cmake/libraries/boost.cmake
@@ -120,11 +120,11 @@ if(PROJECT_ENABLE_BOOST)
--with-libraries=atomic,chrono,date_time,filesystem,iostreams,locale,log,program_options,random,regex,serialization,system,test,thread
BUILD_COMMAND
./b2
- -j1
+ -j$ENV{CMAKE_BUILD_PARALLEL_LEVEL}
${BOOST_BUILD_ARGS}
INSTALL_COMMAND
./b2
- -j1
+ -j$ENV{CMAKE_BUILD_PARALLEL_LEVEL}
${BOOST_BUILD_ARGS}
install
)
diff --git a/cmake/libraries/cpp_httplib.cmake b/cmake/libraries/cpp_httplib.cmake
index 014fc9a2..019075b1 100644
--- a/cmake/libraries/cpp_httplib.cmake
+++ b/cmake/libraries/cpp_httplib.cmake
@@ -15,10 +15,13 @@ if(PROJECT_ENABLE_CPP_HTTPLIB)
CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
-DBUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS}
-DBUILD_STATIC_LIBS=ON
- -DHTTPLIB_REQUIRE_OPENSSL=${PROJECT_ENABLE_OPENSSL}
- -DHTTPLIB_REQUIRE_ZLIB=ON
-DHTTPLIB_REQUIRE_BROTLI=OFF
+ -DHTTPLIB_REQUIRE_OPENSSL=ON
+ -DHTTPLIB_REQUIRE_ZLIB=ON
-DHTTPLIB_TEST=OFF
+ -DHTTPLIB_USE_BROTLI_IF_AVAILABLE=OFF
+ -DHTTPLIB_USE_OPENSSL_IF_AVAILABLE=ON
+ -DHTTPLIB_USE_ZLIB_IF_AVAILABLE=ON
-DOPENSSL_USE_STATIC_LIBS=${OPENSSL_USE_STATIC_LIBS}
)
diff --git a/cmake/libraries/curl.cmake b/cmake/libraries/curl.cmake
index 17be921e..ae0cee71 100644
--- a/cmake/libraries/curl.cmake
+++ b/cmake/libraries/curl.cmake
@@ -18,8 +18,9 @@ if(PROJECT_ENABLE_CURL)
URL ${PROJECT_3RD_PARTY_DIR}/curl-${CURL_VERSION}.tar.gz
URL_HASH SHA256=${CURL_HASH}
LIST_SEPARATOR |
- CMAKE_ARGS
- ${PROJECT_EXTERNAL_CMAKE_FLAGS}
+ BUILD_COMMAND
+ ${CMAKE_COMMAND} --build . -- -j$ENV{CMAKE_BUILD_PARALLEL_LEVEL}
+ CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
-DBUILD_CURL_EXE=OFF
-DBUILD_LIBCURL_DOCS=OFF
-DBUILD_MISC_DOCS=OFF
@@ -28,6 +29,7 @@ if(PROJECT_ENABLE_CURL)
-DBUILD_STATIC_LIBS=ON
-DBUILD_STATIC_LIBS=ON
-DBUILD_TESTING=OFF
+ -DCURL_BROTLI=OFF
-DCURL_CA_BUNDLE=./cacert.pem
-DCURL_CA_FALLBACK=ON
-DCURL_DISABLE_LDAP=ON
diff --git a/cmake/libraries/rocksdb.cmake b/cmake/libraries/rocksdb.cmake
index 92b2396e..123748af 100644
--- a/cmake/libraries/rocksdb.cmake
+++ b/cmake/libraries/rocksdb.cmake
@@ -9,6 +9,8 @@ if(PROJECT_ENABLE_ROCKSDB)
URL ${PROJECT_3RD_PARTY_DIR}/rocksdb-${ROCKSDB_VERSION}.tar.gz
URL_HASH SHA256=${ROCKSDB_HASH}
LIST_SEPARATOR |
+ BUILD_COMMAND
+ ${CMAKE_COMMAND} --build . -- -j$ENV{CMAKE_BUILD_PARALLEL_LEVEL}
CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
-DBUILD_SHARED_LIBS=OFF
-DBUILD_STATIC_LIBS=ON
@@ -31,4 +33,4 @@ if(PROJECT_ENABLE_ROCKSDB)
list(APPEND PROJECT_DEPENDENCIES rocksdb_project)
endif()
-endif()
\ No newline at end of file
+endif()
diff --git a/cmake/libraries/sqlite.cmake b/cmake/libraries/sqlite.cmake
index 49b87217..b37e8958 100644
--- a/cmake/libraries/sqlite.cmake
+++ b/cmake/libraries/sqlite.cmake
@@ -2,7 +2,7 @@ if(PROJECT_ENABLE_SQLITE)
if(PROJECT_BUILD)
add_definitions(-DPROJECT_ENABLE_SQLITE)
if (PROJECT_IS_MINGW AND NOT PROJECT_IS_MINGW_UNIX)
- pkg_check_modules(SQLITE3 REQUIRED sqlite3>=${SQLITE2_VERSION})
+ pkg_check_modules(SQLITE3 REQUIRED sqlite3)
include_directories(SYSTEM BEFORE ${SQLITE3_INCLUDE_DIRS})
link_libraries(${SQLITE3_LIBRARIES})
else()
diff --git a/cmake/versions.cmake b/cmake/versions.cmake
index 2a121d97..147a990d 100644
--- a/cmake/versions.cmake
+++ b/cmake/versions.cmake
@@ -5,24 +5,24 @@ set(BOOST2_PATCH_VERSION 0)
set(BOOST_MAJOR_VERSION 1)
set(BOOST_MINOR_VERSION 87)
set(BOOST_PATCH_VERSION 0)
-set(CPP_HTTPLIB_VERSION 0.18.1)
-set(CURL2_VERSION 8_11_0)
-set(CURL_VERSION 8.11.0)
+set(CPP_HTTPLIB_VERSION 0.19.0)
+set(CURL2_VERSION 8_12_1)
+set(CURL_VERSION 8.12.1)
set(EXPAT2_VERSION 2_6_4)
set(EXPAT_VERSION 2.6.4)
set(GCC_VERSION 14.2.0)
-set(GTEST_VERSION 1.15.2)
+set(GTEST_VERSION 1.16.0)
set(ICU_VERSION 76-1)
set(JSON_VERSION 3.11.3)
set(LIBSODIUM_VERSION 1.0.20)
set(MESA_VERSION 23.3.3)
set(MINGW_VERSION 12.0.0)
-set(OPENSSL_VERSION 3.4.0)
+set(OPENSSL_VERSION 3.4.1)
set(PKG_CONFIG_VERSION 0.29.2)
-set(PUGIXML_VERSION 1.14)
-set(ROCKSDB_VERSION 9.7.4)
-set(SPDLOG_VERSION 1.15.0)
-set(SQLITE2_VERSION 3.46.1)
-set(SQLITE_VERSION 3460100)
+set(PUGIXML_VERSION 1.15)
+set(ROCKSDB_VERSION 9.10.0)
+set(SPDLOG_VERSION 1.15.1)
+set(SQLITE2_VERSION 3.49.1)
+set(SQLITE_VERSION 3490100)
set(STDUUID_VERSION 1.2.3)
set(ZLIB_VERSION 1.3.1)
diff --git a/config.sh b/config.sh
index 9b2999ec..7e647523 100755
--- a/config.sh
+++ b/config.sh
@@ -10,7 +10,7 @@ PROJECT_DESC="Mount utility for Sia and S3"
PROJECT_MAJOR_VERSION=2
PROJECT_MINOR_VERSION=0
-PROJECT_REVISION_VERSION=4
+PROJECT_REVISION_VERSION=5
PROJECT_RELEASE_NUM=0
PROJECT_RELEASE_ITER=rc
@@ -19,6 +19,8 @@ PROJECT_APP_LIST=(${PROJECT_NAME})
PROJECT_PRIVATE_KEY=${DEVELOPER_PRIVATE_KEY}
PROJECT_PUBLIC_KEY=${DEVELOPER_PUBLIC_KEY}
+PROJECT_FLUTTER_BASE_HREF="/ui/"
+
PROJECT_ENABLE_WIN32_LONG_PATH_NAMES=OFF
PROJECT_ENABLE_BACKWARD_CPP=OFF
diff --git a/docker/aarch64/alpine b/docker/aarch64/alpine
index 6b580f00..b6f62e92 100644
--- a/docker/aarch64/alpine
+++ b/docker/aarch64/alpine
@@ -31,6 +31,7 @@ RUN apk add \
gflags \
gflags-dev \
git \
+ git-lfs \
icu-dev \
icu-libs \
icu-static \
diff --git a/docker/x86_64/alpine b/docker/x86_64/alpine
index 3346e7be..ad24210e 100644
--- a/docker/x86_64/alpine
+++ b/docker/x86_64/alpine
@@ -31,6 +31,7 @@ RUN apk add \
gflags \
gflags-dev \
git \
+ git-lfs \
icu-dev \
icu-libs \
icu-static \
diff --git a/docker/x86_64/flutter b/docker/x86_64/flutter
new file mode 100644
index 00000000..20e14228
--- /dev/null
+++ b/docker/x86_64/flutter
@@ -0,0 +1,48 @@
+FROM debian:latest
+
+ARG UID=0
+ARG GID=0
+
+RUN apt-get update
+RUN apt-get install -y \
+ bash \
+ curl \
+ fonts-droid-fallback \
+ gdb \
+ git \
+ lib32stdc++6 \
+ libgconf-2-4 \
+ libglu1-mesa \
+ libstdc++6 \
+ python3 \
+ unzip \
+ wget
+RUN apt-get clean
+
+RUN git clone https://github.com/flutter/flutter.git /flutter
+RUN git config --system --add safe.directory /flutter
+
+ENV PATH="/flutter/bin:/flutter/bin/cache/dart-sdk/bin:${PATH}"
+
+RUN flutter doctor -v
+RUN flutter channel master
+RUN flutter upgrade
+RUN flutter --disable-analytics
+
+RUN flutter config --no-analytics
+RUN flutter config --enable-web
+RUN flutter config --no-cli-animations
+
+RUN mkdir /nonexistent
+RUN chown -R $UID:$GID /nonexistent
+
+RUN mkdir /.config
+RUN chown -R $UID:$GID /.config
+
+RUN mkdir /.dart-tool
+RUN chown -R $UID:$GID /.dart-tool
+
+RUN mkdir /.pub-cache
+RUN chown -R $UID:$GID /.pub-cache
+
+RUN chown -R $UID:$GID /flutter
diff --git a/docker/x86_64/mingw64 b/docker/x86_64/mingw64
index b790cc0b..8bbe85ec 100644
--- a/docker/x86_64/mingw64
+++ b/docker/x86_64/mingw64
@@ -18,6 +18,7 @@ RUN apk add \
gcc \
gettext \
git \
+ git-lfs \
gmp \
gmp-dev \
gperf \
@@ -679,6 +680,7 @@ RUN if [ -f "/3rd_party/curl-${MY_CURL_VERSION}.tar.gz" ]; then \
-DCMAKE_CXX_STANDARD=${MY_CXX_STANDARD} \
-DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
-DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \
+ -DCURL_BROTLI=OFF \
-DCURL_CA_BUNDLE=./cacert.pem \
-DCURL_CA_FALLBACK=ON \
-DCURL_DISABLE_LDAP=ON \
@@ -714,6 +716,9 @@ RUN if [ -f "/3rd_party/cpp-httplib-${MY_CPP_HTTPLIB_VERSION}.tar.gz" ]; then \
-DHTTPLIB_REQUIRE_OPENSSL=ON \
-DHTTPLIB_REQUIRE_ZLIB=ON \
-DHTTPLIB_TEST=OFF \
+ -DHTTPLIB_USE_BROTLI_IF_AVAILABLE=OFF \
+ -DHTTPLIB_USE_OPENSSL_IF_AVAILABLE=YES \
+ -DHTTPLIB_USE_ZLIB_IF_AVAILABLE=ON \
&& make -j${MY_NUM_JOBS} \
&& make install \
&& cd ${MY_WORKDIR} \
diff --git a/repertory/librepertory/include/app_config.hpp b/repertory/librepertory/include/app_config.hpp
index 572a135e..db4be5f0 100644
--- a/repertory/librepertory/include/app_config.hpp
+++ b/repertory/librepertory/include/app_config.hpp
@@ -43,8 +43,7 @@ public:
[[nodiscard]] static auto default_remote_api_port(const provider_type &prov)
-> std::uint16_t;
- [[nodiscard]] static auto default_rpc_port(const provider_type &prov)
- -> std::uint16_t;
+ [[nodiscard]] static auto default_rpc_port() -> std::uint16_t;
[[nodiscard]] static auto get_provider_display_name(const provider_type &prov)
-> std::string;
@@ -52,6 +51,8 @@ public:
[[nodiscard]] static auto get_provider_name(const provider_type &prov)
-> std::string;
+ [[nodiscard]] static auto get_root_data_directory() -> std::string;
+
public:
[[nodiscard]] static auto get_stop_requested() -> bool;
@@ -71,7 +72,7 @@ public:
private:
provider_type prov_;
- atomic api_auth_;
+ atomic api_password_;
std::atomic api_port_;
atomic api_user_;
std::atomic config_changed_;
@@ -121,7 +122,7 @@ private:
auto set_value(dest &dst, const source &src) -> bool;
public:
- [[nodiscard]] auto get_api_auth() const -> std::string;
+ [[nodiscard]] auto get_api_password() const -> std::string;
[[nodiscard]] auto get_api_port() const -> std::uint16_t;
@@ -199,7 +200,7 @@ public:
void save();
- void set_api_auth(const std::string &value);
+ void set_api_password(const std::string &value);
void set_api_port(std::uint16_t value);
diff --git a/repertory/librepertory/include/common.hpp b/repertory/librepertory/include/common.hpp
index 2c5d6e40..7c92b326 100644
--- a/repertory/librepertory/include/common.hpp
+++ b/repertory/librepertory/include/common.hpp
@@ -57,7 +57,7 @@ using json = nlohmann::json;
inline constexpr const std::string_view REPERTORY = "repertory";
inline constexpr const std::wstring_view REPERTORY_W = L"repertory";
-inline constexpr const std::uint64_t REPERTORY_CONFIG_VERSION = 1ULL;
+inline constexpr const std::uint64_t REPERTORY_CONFIG_VERSION = 2ULL;
inline constexpr const std::string_view REPERTORY_DATA_NAME = "repertory2";
inline constexpr const std::string_view REPERTORY_MIN_REMOTE_VERSION = "2.0.0";
diff --git a/repertory/librepertory/include/platform/platform.hpp b/repertory/librepertory/include/platform/platform.hpp
index 743a3587..99ff62cf 100644
--- a/repertory/librepertory/include/platform/platform.hpp
+++ b/repertory/librepertory/include/platform/platform.hpp
@@ -22,6 +22,13 @@
#ifndef REPERTORY_INCLUDE_PLATFORM_PLATFORM_HPP_
#define REPERTORY_INCLUDE_PLATFORM_PLATFORM_HPP_
+#include "types/repertory.hpp"
+
+namespace repertory {
+[[nodiscard]] auto create_lock_id(provider_type prov,
+ std::string_view unique_id)->std::string;
+}
+
#if defined(_WIN32)
#include "platform/win32_platform.hpp"
#include "utils/windows.hpp"
diff --git a/repertory/librepertory/include/platform/unix_platform.hpp b/repertory/librepertory/include/platform/unix_platform.hpp
index 158be5ad..fbb9ceab 100644
--- a/repertory/librepertory/include/platform/unix_platform.hpp
+++ b/repertory/librepertory/include/platform/unix_platform.hpp
@@ -30,38 +30,45 @@ class i_provider;
class lock_data final {
public:
- explicit lock_data(const provider_type &pt, std::string unique_id /*= ""*/);
+ lock_data(provider_type prov, std::string_view unique_id);
- lock_data();
+ lock_data(const lock_data &) = delete;
+ lock_data(lock_data &&) = delete;
+
+ auto operator=(const lock_data &) -> lock_data & = delete;
+ auto operator=(lock_data &&) -> lock_data & = delete;
~lock_data();
private:
- const provider_type pt_;
- const std::string unique_id_;
- const std::string mutex_id_;
- int lock_fd_;
- int lock_status_ = EWOULDBLOCK;
+ std::string mutex_id_;
+
+private:
+ int handle_{};
+ int lock_status_{EWOULDBLOCK};
private:
[[nodiscard]] static auto get_state_directory() -> std::string;
- [[nodiscard]] static auto get_lock_data_file() -> std::string;
+ [[nodiscard]] auto get_lock_data_file() const -> std::string;
- [[nodiscard]] auto get_lock_file() -> std::string;
+ [[nodiscard]] auto get_lock_file() const -> std::string;
private:
- [[nodiscard]] static auto
- wait_for_lock(int fd, std::uint8_t retry_count = 30u) -> int;
+ [[nodiscard]] static auto wait_for_lock(int handle,
+ std::uint8_t retry_count = 30U)
+ -> int;
public:
[[nodiscard]] auto get_mount_state(json &mount_state) -> bool;
- [[nodiscard]] auto grab_lock(std::uint8_t retry_count = 30u) -> lock_result;
+ [[nodiscard]] auto grab_lock(std::uint8_t retry_count = 30U) -> lock_result;
+
+ void release();
[[nodiscard]] auto set_mount_state(bool active,
- const std::string &mount_location,
- int pid) -> bool;
+ std::string_view mount_location, int pid)
+ -> bool;
};
[[nodiscard]] auto create_meta_attributes(
@@ -76,5 +83,5 @@ public:
const api_file &file) -> api_error;
} // namespace repertory
-#endif // _WIN32
+#endif // !defined(_WIN32)
#endif // REPERTORY_INCLUDE_PLATFORM_UNIXPLATFORM_HPP_
diff --git a/repertory/librepertory/include/platform/win32_platform.hpp b/repertory/librepertory/include/platform/win32_platform.hpp
index e4cf5136..628a0d06 100644
--- a/repertory/librepertory/include/platform/win32_platform.hpp
+++ b/repertory/librepertory/include/platform/win32_platform.hpp
@@ -23,7 +23,6 @@
#define REPERTORY_INCLUDE_PLATFORM_WINPLATFORM_HPP_
#if defined(_WIN32)
-#include "app_config.hpp"
#include "types/repertory.hpp"
namespace repertory {
@@ -31,43 +30,32 @@ class i_provider;
class lock_data final {
public:
- explicit lock_data(const provider_type &pt, std::string unique_id /*= ""*/)
- : pt_(pt),
- unique_id_(std::move(unique_id)),
- mutex_id_("repertory_" + app_config::get_provider_name(pt) + "_" +
- unique_id_),
- mutex_handle_(::CreateMutex(nullptr, FALSE, &mutex_id_[0u])) {}
+ explicit lock_data(provider_type prov, std::string unique_id);
+ lock_data(const lock_data &) = delete;
+ lock_data(lock_data &&) = delete;
- lock_data()
- : pt_(provider_type::sia),
- unique_id_(""),
- mutex_id_(""),
- mutex_handle_(INVALID_HANDLE_VALUE) {}
+ ~lock_data();
- ~lock_data() { release(); }
+ auto operator=(const lock_data &) -> lock_data & = delete;
+ auto operator=(lock_data &&) -> lock_data & = delete;
private:
- const provider_type pt_;
- const std::string unique_id_;
- const std::string mutex_id_;
- HANDLE mutex_handle_;
- DWORD mutex_state_ = WAIT_FAILED;
+ std::string mutex_id_;
+ HANDLE mutex_handle_{INVALID_HANDLE_VALUE};
+ DWORD mutex_state_{WAIT_FAILED};
+
+ [[nodiscard]] auto get_current_mount_state(json &mount_state) -> bool;
public:
- [[nodiscard]] auto get_mount_state(const provider_type &pt,
- json &mount_state) -> bool;
-
[[nodiscard]] auto get_mount_state(json &mount_state) -> bool;
- [[nodiscard]] auto get_unique_id() const -> std::string { return unique_id_; }
-
- [[nodiscard]] auto grab_lock(std::uint8_t retry_count = 30) -> lock_result;
+ [[nodiscard]] auto grab_lock(std::uint8_t retry_count = 30U) -> lock_result;
void release();
[[nodiscard]] auto set_mount_state(bool active,
- const std::string &mount_location,
- const std::int64_t &pid) -> bool;
+ std::string_view mount_location,
+ std::int64_t pid) -> bool;
};
[[nodiscard]] auto create_meta_attributes(
diff --git a/repertory/librepertory/include/rpc/client/client.hpp b/repertory/librepertory/include/rpc/client/client.hpp
index b9b27c12..0e9f64de 100644
--- a/repertory/librepertory/include/rpc/client/client.hpp
+++ b/repertory/librepertory/include/rpc/client/client.hpp
@@ -48,9 +48,9 @@ public:
[[nodiscard]] auto get_pinned_files() -> rpc_response;
- [[nodiscard]] auto pin_file(const std::string &api_file) -> rpc_response;
+ [[nodiscard]] auto pin_file(const std::string &api_path) -> rpc_response;
- [[nodiscard]] auto pinned_status(const std::string &api_file) -> rpc_response;
+ [[nodiscard]] auto pinned_status(const std::string &api_path) -> rpc_response;
[[nodiscard]] auto set_config_value_by_name(const std::string &name,
const std::string &value)
@@ -58,7 +58,7 @@ public:
[[nodiscard]] auto unmount() -> rpc_response;
- [[nodiscard]] auto unpin_file(const std::string &api_file) -> rpc_response;
+ [[nodiscard]] auto unpin_file(const std::string &api_path) -> rpc_response;
};
} // namespace repertory
diff --git a/repertory/librepertory/include/rpc/common.hpp b/repertory/librepertory/include/rpc/common.hpp
new file mode 100644
index 00000000..fb2827a4
--- /dev/null
+++ b/repertory/librepertory/include/rpc/common.hpp
@@ -0,0 +1,82 @@
+/*
+ Copyright <2018-2025>
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+*/
+#ifndef REPERTORY_INCLUDE_RPC_COMMON_HPP_
+#define REPERTORY_INCLUDE_RPC_COMMON_HPP_
+
+#include "utils/base64.hpp"
+#include "utils/error_utils.hpp"
+#include "utils/string.hpp"
+
+namespace repertory::rpc {
+[[nodiscard]] auto check_authorization(const auto &cfg,
+ const httplib::Request &req) -> bool {
+ REPERTORY_USES_FUNCTION_NAME();
+
+ if (cfg.get_api_password().empty() || cfg.get_api_user().empty()) {
+ utils::error::raise_error(function_name,
+ "authorization user or password is not set");
+ return false;
+ }
+
+ auto authorization = req.get_header_value("Authorization");
+ if (authorization.empty()) {
+ utils::error::raise_error(function_name,
+ "'Authorization' header is not set");
+ return false;
+ }
+
+ auto auth_parts = utils::string::split(authorization, ' ', true);
+ if (auth_parts.empty()) {
+ utils::error::raise_error(function_name, "'Authorization' header is empty");
+ return false;
+ }
+
+ auto auth_type = auth_parts[0U];
+ if (auth_type != "Basic") {
+ utils::error::raise_error(function_name,
+ "authorization type is not 'Basic'");
+ return false;
+ }
+
+ auto data = macaron::Base64::Decode(authorization.substr(6U));
+ auto auth_str = std::string(data.begin(), data.end());
+
+ auto auth = utils::string::split(auth_str, ':', false);
+ if (auth.size() < 2U) {
+ utils::error::raise_error(function_name, "authorization data is not valid");
+ return false;
+ }
+
+ auto user = auth.at(0U);
+ auth.erase(auth.begin());
+
+ auto pwd = utils::string::join(auth, ':');
+ if ((user != cfg.get_api_user()) || (pwd != cfg.get_api_password())) {
+ utils::error::raise_error(function_name, "authorization failed");
+ return false;
+ }
+
+ return true;
+}
+} // namespace repertory::rpc
+
+#endif // REPERTORY_INCLUDE_RPC_COMMON_HPP_
diff --git a/repertory/librepertory/include/rpc/server/server.hpp b/repertory/librepertory/include/rpc/server/server.hpp
index 48735e10..5892d732 100644
--- a/repertory/librepertory/include/rpc/server/server.hpp
+++ b/repertory/librepertory/include/rpc/server/server.hpp
@@ -40,8 +40,6 @@ private:
std::mutex start_stop_mutex_;
private:
- [[nodiscard]] auto check_authorization(const httplib::Request &req) -> bool;
-
void handle_get_config(const httplib::Request &req, httplib::Response &res);
void handle_get_config_value_by_name(const httplib::Request &req,
diff --git a/repertory/librepertory/include/types/repertory.hpp b/repertory/librepertory/include/types/repertory.hpp
index fce1cbc2..434fc6f0 100644
--- a/repertory/librepertory/include/types/repertory.hpp
+++ b/repertory/librepertory/include/types/repertory.hpp
@@ -23,7 +23,7 @@
#define REPERTORY_INCLUDE_TYPES_REPERTORY_HPP_
namespace repertory {
-constexpr const auto default_api_auth_size{48U};
+constexpr const auto default_api_password_size{48U};
constexpr const auto default_download_timeout_secs{30U};
constexpr const auto default_eviction_delay_mins{1U};
constexpr const auto default_high_freq_interval_secs{std::uint16_t{30U}};
@@ -38,6 +38,7 @@ constexpr const auto default_retry_read_count{6U};
constexpr const auto default_ring_buffer_file_size{512U};
constexpr const auto default_task_wait_ms{100U};
constexpr const auto default_timeout_ms{60000U};
+constexpr const auto default_ui_mgmt_port{std::uint16_t{30000U}};
constexpr const auto max_ring_buffer_file_size{std::uint16_t(1024U)};
constexpr const auto max_s3_object_name_length{1024U};
constexpr const auto min_cache_size_bytes{
@@ -280,6 +281,8 @@ enum class exit_code : std::int32_t {
pin_failed = -16,
unpin_failed = -17,
init_failed = -18,
+ ui_mount_failed = -19,
+ exception = -20,
};
enum http_error_codes : std::int32_t {
@@ -304,6 +307,18 @@ enum class provider_type : std::size_t {
unknown,
};
+[[nodiscard]] auto
+provider_type_from_string(std::string_view type,
+ provider_type default_type = provider_type::unknown)
+ -> provider_type;
+
+[[nodiscard]] auto provider_type_to_string(provider_type type) -> std::string;
+
+void clean_json_config(provider_type prov, nlohmann::json &data);
+
+[[nodiscard]] auto clean_json_value(std::string_view name,
+ std::string_view data) -> std::string;
+
#if defined(_WIN32)
struct open_file_data final {
PVOID directory_buffer{nullptr};
@@ -452,7 +467,6 @@ using meta_provider_callback = std::function;
inline constexpr const auto JSON_ACCESS_KEY{"AccessKey"};
inline constexpr const auto JSON_AGENT_STRING{"AgentString"};
-inline constexpr const auto JSON_API_AUTH{"ApiAuth"};
inline constexpr const auto JSON_API_PARENT{"ApiParent"};
inline constexpr const auto JSON_API_PASSWORD{"ApiPassword"};
inline constexpr const auto JSON_API_PATH{"ApiPath"};
@@ -487,6 +501,7 @@ inline constexpr const auto JSON_MAX_UPLOAD_COUNT{"MaxUploadCount"};
inline constexpr const auto JSON_MED_FREQ_INTERVAL_SECS{
"MedFreqIntervalSeconds"};
inline constexpr const auto JSON_META{"Meta"};
+inline constexpr const auto JSON_MOUNT_LOCATIONS{"MountLocations"};
inline constexpr const auto JSON_ONLINE_CHECK_RETRY_SECS{
"OnlineCheckRetrySeconds"};
inline constexpr const auto JSON_PATH{"Path"};
diff --git a/repertory/librepertory/include/utils/cli_utils.hpp b/repertory/librepertory/include/utils/cli_utils.hpp
index 06ce1f41..c0f9ed01 100644
--- a/repertory/librepertory/include/utils/cli_utils.hpp
+++ b/repertory/librepertory/include/utils/cli_utils.hpp
@@ -49,6 +49,8 @@ static const option password_option = {"-pw", "--password"};
static const option remote_mount_option = {"-rm", "--remote_mount"};
static const option set_option = {"-set", "--set"};
static const option status_option = {"-status", "--status"};
+static const option ui_option = {"-ui", "--ui"};
+static const option ui_port_option = {"-up", "--ui_port"};
static const option unmount_option = {"-unmount", "--unmount"};
static const option unpin_file_option = {"-uf", "--unpin_file"};
static const option user_option = {"-us", "--user"};
@@ -75,6 +77,8 @@ static const std::vector