├── .github
├── CODEOWNERS
└── workflows
│ ├── ci.yml
│ └── jekyll-gh-pages.yml
├── .gitignore
├── 404.html
├── CNAME
├── CONTRIBUTING.md
├── Cargo.lock
├── Cargo.toml
├── Gemfile
├── LICENSE
├── README.md
├── _config.yml
├── _layouts
└── default.html
├── about.markdown
├── favicon.png
├── file-change-consumer
├── Cargo.toml
└── src
│ └── main.rs
├── file-change-router
├── Cargo.toml
└── src
│ └── main.rs
├── file-tree-merge
├── Cargo.toml
├── src
│ ├── apply_change.rs
│ ├── change_tree.rs
│ ├── change_tree_merge.rs
│ ├── lib.rs
│ ├── main.rs
│ ├── path_walker.rs
│ └── tree_creator.rs
└── tests
│ └── scripts
│ ├── cleanup.sh
│ ├── common.sh
│ ├── setup.sh
│ ├── tests.sh
│ └── tests
│ ├── add.sh
│ ├── add_modify_delete.sh
│ ├── add_modify_delete_multiple_paths.sh
│ ├── add_more.sh
│ ├── delete.sh
│ ├── delete_many.sh
│ ├── dry-run.sh
│ ├── large
│ └── add_modify_delete.sh
│ ├── modify.sh
│ ├── modify_many.sh
│ └── no-crc.sh
├── file-watcher
├── Cargo.toml
└── src
│ └── main.rs
├── p2p-transfer
├── .cargo
│ └── config.toml
├── .gitignore
├── .typos.toml
├── Cargo.lock
├── Cargo.toml
├── LICENSE-APACHE
├── LICENSE-MIT
├── README.md
├── Trunk.toml
├── assets
│ ├── favicon.ico
│ ├── icon-1024.png
│ ├── icon-256.png
│ ├── icon_ios_touch_192.png
│ ├── manifest.json
│ ├── maskable_icon_x512.png
│ └── sw.js
├── check.sh
├── fill_template.ps1
├── fill_template.sh
├── flake.nix
├── index.html
├── rust-toolchain
└── src
│ ├── app.rs
│ ├── lib.rs
│ ├── main.rs
│ └── node.rs
└── website
├── pages
├── compare.md
├── features.md
├── features
│ ├── analytics.md
│ ├── antivirus.md
│ ├── automation.md
│ ├── backup.md
│ ├── browser-app.md
│ ├── cleanup.md
│ ├── clients.md
│ ├── emails.md
│ ├── encrypt.md
│ ├── global-view.md
│ ├── integrations.md
│ ├── large-files.md
│ ├── links.md
│ ├── local-app.md
│ ├── local-view.md
│ ├── photos.md
│ ├── receive.md
│ ├── search.md
│ ├── share-external.md
│ ├── share-local.md
│ ├── share-providers.md
│ ├── status.md
│ ├── supported-providers.md
│ ├── sync-local.md
│ ├── sync-providers.md
│ └── versioning.md
├── how-it-works.md
├── name.md
├── poc-demo.md
├── stack.md
└── use-cases.md
└── resources
├── app.png
├── automation.png
├── backup-emails-locally.png
├── backup-emails-with-service.png
├── backup-local-files.png
├── backup-provider.png
├── clients.png
├── diagram-encrypt-share.png
├── diagram-receive.png
├── diagram-share-external.png
├── diagram-share-local.png
├── diagram-share-provider.png
├── diagram-sync-local.png
├── diagram-sync-providers.png
├── frame-analytics.png
├── frame-local-view.png
├── frame-receive.png
├── mvp.png
├── poc.png
├── receive-file-with-provider.png
├── receive-local-file.png
├── services.png
├── share-encrypte-with-external-user.png
├── share-encryptyed-with-service-user.png
├── share-local.png
├── share-providers.png
├── sync-emails.png
├── sync-encrypted.png
├── sync-local.png
├── sync-providers.png
└── syncoxiders-icon-20p.png
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # This is a comment.
2 | # Each line is a file pattern followed by one or more owners.
3 |
4 | # These owners will be the default owners for everything in
5 | # the repo. Unless a later match takes precedence,
6 | # @global-owner1 and @global-owner2 will be requested for
7 | # review when someone opens a pull request.
8 | * @radumarias
9 |
10 | # Order is important; the last matching pattern takes the most
11 | # precedence. When someone opens a pull request that only
12 | # modifies JS files, only @js-owner and not the global
13 | # owner(s) will be requested for a review.
14 | # *.js @js-owner #This is an inline comment.
15 |
16 | # You can also use email addresses if you prefer. They'll be
17 | # used to look up users just like we do for commit author
18 | # emails.
19 | # *.go docs@example.com
20 |
21 | # Teams can be specified as code owners as well. Teams should
22 | # be identified in the format @org/team-name. Teams must have
23 | # explicit write access to the repository. In this example,
24 | # the octocats team in the octo-org organization owns all .txt files.
25 | # *.txt @octo-org/octocats
26 |
27 | # In this example, @doctocat owns any files in the build/logs
28 | # directory at the root of the repository and any of its
29 | # subdirectories.
30 | # /build/logs/ @doctocat
31 |
32 | # The `docs/*` pattern will match files like
33 | # `docs/getting-started.md` but not further nested files like
34 | # `docs/build-app/troubleshooting.md`.
35 | # docs/* docs@example.com
36 |
37 | # In this example, @octocat owns any file in an apps directory
38 | # anywhere in your repository.
39 | # apps/ @octocat
40 |
41 | # In this example, @doctocat owns any file in the `/docs`
42 | # directory in the root of your repository and any of its
43 | # subdirectories.
44 | # /docs/ @doctocat
45 |
46 | # In this example, any change inside the `/scripts` directory
47 | # will require approval from @doctocat or @octocat.
48 | # /scripts/ @doctocat @octocat
49 |
50 | # In this example, @octocat owns any file in a `/logs` directory such as
51 | # `/build/logs`, `/scripts/logs`, and `/deeply/nested/logs`. Any changes
52 | # in a `/logs` directory will require approval from @octocat.
53 | # **/logs @octocat
54 |
55 | # In this example, @octocat owns any file in the `/apps`
56 | # directory in the root of your repository except for the `/apps/github`
57 | # subdirectory, as its owners are left empty.
58 | # /apps/ @octocat
59 | # /apps/github
60 |
61 | # In this example, @octocat owns any file in the `/apps`
62 | # directory in the root of your repository except for the `/apps/github`
63 | # subdirectory, as this subdirectory has its own owner @doctocat
64 | # /apps/ @octocat
65 | # /apps/github @doctocat
66 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: ci
2 | on:
3 | push:
4 | branches: [ main, release ]
5 | pull_request:
6 | branches: [ main, release ]
7 | concurrency:
8 | group: ${{ github.workflow }}-${{ github.ref }}
9 | cancel-in-progress: true
10 |
11 | env:
12 | CARGO_TERM_COLOR: always
13 | CARGO_INCREMENTAL: 0 # TODO: remove this when we cache the builds
14 |
15 | jobs:
16 | ci:
17 | runs-on: ${{ matrix.runner }}
18 | strategy:
19 | matrix:
20 | runner: [ubuntu-latest, macos-latest, windows-latest]
21 | steps:
22 | - uses: actions/checkout@v4
23 |
24 | - name: Setup Rust
25 | run: rustup update
26 |
27 | - name: build
28 | run: cargo build --all --release
29 |
30 | - name: test
31 | run: |
32 | cargo test --release --all-targets
33 |
34 | #cd file-tree-merge/tests/scripts
35 | #sh tests.sh
36 | shell: bash
37 |
38 | - name: upload binary
39 | if: ${{ !startsWith(matrix.runner, 'windows') }}
40 | uses: actions/upload-artifact@v4
41 | with:
42 | name: syncoxiders_${{ matrix.runner }}
43 | path: target/release/syncoxiders
44 |
45 | - name: upload binary
46 | if: startsWith(matrix.runner, 'windows')
47 | uses: actions/upload-artifact@v4
48 | with:
49 | name: syncoxiders_${{ matrix.runner }}
50 | path: target/release/syncoxiders.exe
--------------------------------------------------------------------------------
/.github/workflows/jekyll-gh-pages.yml:
--------------------------------------------------------------------------------
1 | # Sample workflow for building and deploying a Jekyll site to GitHub Pages
2 | name: Deploy Jekyll with GitHub Pages dependencies preinstalled
3 |
4 | on:
5 | # Runs on pushes targeting the default branch
6 | push:
7 | branches: ["main"]
8 |
9 | # Allows you to run this workflow manually from the Actions tab
10 | workflow_dispatch:
11 |
12 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
13 | permissions:
14 | contents: read
15 | pages: write
16 | id-token: write
17 |
18 | # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
19 | # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
20 | concurrency:
21 | group: "pages"
22 | cancel-in-progress: true
23 |
24 | jobs:
25 | # Build job
26 | build:
27 | runs-on: ubuntu-latest
28 | steps:
29 | - name: Checkout
30 | uses: actions/checkout@v4
31 | - name: Setup Pages
32 | uses: actions/configure-pages@v5
33 | - name: Build with Jekyll
34 | uses: actions/jekyll-build-pages@v1
35 | with:
36 | source: ./
37 | destination: ./_site
38 | - name: Upload artifact
39 | uses: actions/upload-pages-artifact@v3
40 |
41 | # Deployment job
42 | deploy:
43 | environment:
44 | name: github-pages
45 | url: ${{ steps.deployment.outputs.page_url }}
46 | runs-on: ubuntu-latest
47 | needs: build
48 | steps:
49 | - name: Deploy to GitHub Pages
50 | id: deployment
51 | uses: actions/deploy-pages@v4
52 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 | Gemfile.lock
3 | .idea/
4 |
--------------------------------------------------------------------------------
/404.html:
--------------------------------------------------------------------------------
1 | ---
2 | permalink: /404.html
3 | layout: default
4 | ---
5 |
6 |
19 |
20 |
21 |
404
22 |
23 |
Page not found :(
24 |
The requested page could not be found.
25 |
26 |
--------------------------------------------------------------------------------
/CNAME:
--------------------------------------------------------------------------------
1 | syncoxide.rs
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | ## How to contribute
2 |
3 | You can use this [CONTRIBUTING](https://github.com/radumarias/rencfs/blob/main/CONTRIBUTING.md) guide as a reference, skipping the steps that don't apply.
4 |
--------------------------------------------------------------------------------
/Cargo.toml:
--------------------------------------------------------------------------------
1 | [workspace]
2 | members = ["file-change-consumer", "file-change-router", "file-tree-merge", "file-watcher", "p2p-transfer"]
3 |
4 | resolver = "2"
5 |
6 | [workspace.package]
7 | description = "Cloud files Sync, Sharing, Backup and Encryption solution written in Rust."
8 | version = "0.1.0"
9 | edition = "2021"
10 | license = "MIT OR Apache-2.0"
11 | authors = ["Radu Marias "]
12 | homepage = "https://github.com/radumarias/syncoxiders"
13 | repository = "https://github.com/radumarias/syncoxiders"
14 | readme = "README.md"
15 | keywords = ["sync", "share", "cloud", "filesystem", "encryption"]
16 | categories = ["cryptography", "filesystem"]
17 | documentation = "https://docs.rs/syncoxiders"
18 | exclude = [".github/"]
19 |
20 | [profile.release]
21 | panic = "abort"
22 |
23 | [workspace.dependencies]
24 | colored = "2.1.0"
25 | rayon = "^1.10.0"
26 | anyhow = "1.0.80"
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source "https://rubygems.org"
2 | # Hello! This is where you manage which Jekyll version is used to run.
3 | # When you want to use a different version, change it below, save the
4 | # file and run `bundle install`. Run Jekyll with `bundle exec`, like so:
5 | #
6 | # bundle exec jekyll serve
7 | #
8 | # This will help ensure the proper Jekyll version is running.
9 | # Happy Jekylling!
10 | # gem "jekyll", "~> 4.3.3"
11 |
12 | gem "github-pages", "~> 3.9.5", group: :jekyll_plugins
13 |
14 | # This is the default theme for new Jekyll sites. You may change this to anything you like.
15 | gem "minima", "~> 2.5"
16 | # If you want to use GitHub Pages, remove the "gem "jekyll"" above and
17 | # uncomment the line below. To upgrade, run `bundle update github-pages`.
18 | # gem "github-pages", group: :jekyll_plugins
19 | # If you have any plugins, put them here!
20 | group :jekyll_plugins do
21 | gem "jekyll-feed", "~> 0.12"
22 | end
23 |
24 | # Windows and JRuby does not include zoneinfo files, so bundle the tzinfo-data gem
25 | # and associated library.
26 | platforms :mingw, :x64_mingw, :mswin, :jruby do
27 | gem "tzinfo", ">= 1", "< 3"
28 | gem "tzinfo-data"
29 | end
30 |
31 | # Performance-booster for watching directories on Windows
32 | gem "wdm", "~> 0.1.1", :platforms => [:mingw, :x64_mingw, :mswin]
33 |
34 | # Lock `http_parser.rb` gem to `v0.6.x` on JRuby builds since newer versions of the gem
35 | # do not have a Java counterpart.
36 | gem "http_parser.rb", "~> 0.6.0", :platforms => [:jruby]
37 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | #  SyncOxiders
2 |
3 | Cloud file and email Sync, file Sharing, inter-cloud Encryption and Backup solution written in Rust and modern technologies.
4 |
5 | The purpose of this project is to offer an easy and reliable way to sync files and emails between multiple providers and share files between multiple storage providers (like Google Drive, Dropbox, S3, SFTP servers, ...) and local files. Also simple way for backup of your files and emails and encryption.
6 | It offers real time sync (from simple Copy One-way to Two-way Sync) all handled in the cloud, without the explicit need of local clients.
7 |
8 | > [!WARNING]
9 | > For now it's in PoC phase, it has some or the core components, like encryption, basic Google Drive client and a basic [CLI app](website/pages/poc-demo.md#using-cli).
10 |
11 | It's using [rencfs](https://github.com/radumarias/rencfs) for encryption and [gdrive-rs](https://github.com/radumarias/gdrive-rs) for accesing Google Drive.
12 |
13 | > [!IMPORTANT]
14 | > It you could take this [**SURVEY**](https://forms.gle/qgnWBJhzCpzPLSmv5) to express your opinion about the current solution and offer your opinion on what features you would want from a service like this it would help a lot.
15 |
16 | You can see rhe [results](https://docs.google.com/forms/d/1d4V8BZB7TGp08NhY6_L0kUgcGe0glRFOjp4rjrt7_bs/viewanalytics?chromeless=1) of the survey.
17 |
18 | > [!NOTE]
19 | In many cases we'll use present tense for several functionality, even though they are not yet implemented, it's used to give an idea of what the system could be.
20 |
21 | [What's with the name](website/pages/name.md)
22 |
23 | # PoC
24 |
25 | You can see more [details](website/pages/poc-demo.md) on what's working now, play with the [CLI app](website/pages/poc-demo.md#using-cli) and see a short [demo](https://www.youtube.com/watch?v=JHQC1XpCzQw).
26 |
27 | Working on having these in up to 2 months:
28 | - in `Docker` ability to sync 2 folders in the filesystem
29 | - run `rclone` in `Docker` and mount `Google Drive` and `Dropbox` or `MS OneDrive` in 2 folders
30 | - from CLI trigger a sync which will make a Two-Way sync between the folders, first sync will do a union between the 2, no delete or rename will be performed
31 | - do some changes in both local folders and trigger a sync, from now on it will propagate deletes and renames also
32 | - do some changes on the remotes, trigger a sync and make sure changes are propagated in both local folders and on remotes
33 | - save files encrypted using `rencfs`
34 | - this will save encrypted data on the mount points of `rclone` and expose them with `FUSE`
35 |
36 |
37 |
38 | # MVP
39 |
40 | It would be possible to have something in about 6 months with this functionality:
41 | - integration with `Google Drive` and `Dropbox` or `MS OneDrive`
42 | - Sync between the two
43 | - Share files from providers with another user
44 | - browser app with basic functionality like:
45 | - adding providers
46 | - setup sync rules
47 | - share between providers
48 | - some basic functionality of sharing local files, no sync between them
49 | - encryption
50 |
51 | For this phase we will still be using `rclone` to access providers, this is to simplify the access. But for future plan is to:
52 | - implement our own clients that will directly communicate with the providers API
53 | - receive changes in close to real-time
54 | - store the changes in `Kafka` and window them (group them) with `Flink`
55 | - feed them as changes tree to the `files tree merge` algorithm which will do the merge, resolve conflicts and applying changes to the other providers or local files
56 |
57 |
58 |
59 | # The big picture
60 |
61 | This is what it's planned to have in the end.
62 |
63 |
64 |
65 | [Use cases](website/pages/use-cases.md)
66 |
67 | [Features](website/pages/features.md)
68 |
69 | [What separates it from other products](website/pages/compare.md)
70 |
71 | [How it works](website/pages/how-it-works.md)
72 |
73 | [Tech stack](website/pages/stack.md)
74 |
75 | # Contribute
76 |
77 | Feel free to fork it, change and use it in any way that you want. If you build something interesting and feel like sharing pull requests are always appreciated.
78 |
79 | ## How to contribute
80 |
81 | ### Browser
82 |
83 | If you want to give it a quick try and not setup anything locally you can
84 | [](https://gitpod.io/#https://github.com/radumarias/syncoxiders)
85 |
86 | [](https://github.com/codespaces/new/?repo=radumarias%2Fsyncoxiders&ref=main)
87 |
88 | You can compile it, run it, and give it a quick try in browser. After you start it from above
89 |
90 | ```bash
91 | sudo apt-get update && sudo apt-get install fuse3
92 | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
93 | mkdir sync && mkdir sync/repo sync/a sync/b
94 | ```
95 |
96 | Add some files in `sync/a` and then run th sync
97 |
98 | ```bash
99 | cargo run --release --bin syncoxiders -- --repo sync/repo sync/a sync/b
100 | ```
101 |
102 | Now check `sync/b` it should have same content as `file/a`.
103 |
104 | For now this **is working**
105 | - sync files: create, delete, update, move
106 | - sync one to many, you can put several paths, it will sync from path1 to all others
107 |
108 | It **DOESN'T** work
109 | - folders sync: create, delete, rename, will be fixed soon
110 |
111 | ### Locally
112 |
113 | #### Getting the sources
114 |
115 | ```bash
116 | git clone git@github.com:radumarias/syncoxiders.git && cd syncoxiders
117 | ````
118 |
119 | #### Dependencies
120 |
121 | ##### Rust
122 |
123 | To build from source, you need to have Rust installed, you can see more details on how to install
124 | it [here](https://www.rust-lang.org/tools/install).
125 |
126 | ```bash
127 | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
128 | ````
129 |
130 | Accordingly, it is customary for Rust developers to include this directory in their `PATH` environment variable.
131 | During installation `rustup` will attempt to configure the `PATH`. Because of differences between platforms, command
132 | shells,
133 | and bugs in `rustup`, the modifications to `PATH` may not take effect until the console is restarted, or the user is
134 | logged out, or it may not succeed at all.
135 |
136 | If, after installation, running `rustc --version` in the console fails, this is the most likely reason.
137 | In that case please add it to the `PATH` manually.
138 |
139 | Project is setup to use `nightly` toolchain in `rust-toolchain.toml`, on first build you will see it fetch the nightly.
140 |
141 | Make sure to add this you your `$PATH` too
142 |
143 | ```bash
144 | export PATH="$PATH::$HOME/.cargo/bin"
145 | ```
146 |
147 | ##### Other dependencies
148 |
149 | Also, these deps are required (or based on your distribution):
150 |
151 | ###### Arch
152 |
153 | ```bash
154 | sudo pacman -Syu && sudo pacman -S base-devel act
155 | ```
156 |
157 | ###### Ubuntu
158 |
159 | ```bash
160 | sudo apt-get update && sudo apt-get install build-essential act
161 | ```
162 |
163 | ###### Fedora
164 |
165 | ```bash
166 | sudo dnf update && sudo dnf install && dnf install @development-tools act
167 | ```
168 |
169 | #### Build for debug
170 |
171 | ```bash
172 | cargo build
173 | ```
174 |
175 | #### Build release
176 |
177 | ```bash
178 | cargo build --release
179 | ```
180 |
181 | ### Run
182 |
183 | ```bash
184 | cargo run --release --bin syncoxiders -- --repo REPO A B
185 | ```
186 |
187 | ### Developing inside a Container
188 |
189 | See here how to configure for [RustRover](https://www.jetbrains.com/help/rust/connect-to-devcontainer.html) and for [VsCode](https://code.visualstudio.com/docs/devcontainers/containers).
190 |
191 | You can use the `.devcontainer` directory from the project to start a container with all the necessary tools to build
192 | and run the app.
193 |
194 | Please see [CONTRIBUTING.md](https://github.com/radumarias/rencfs/blob/main/CONTRIBUTING.md).
195 |
196 | # Minimum Supported Rust Version (MSRV)
197 |
198 | The minimum supported version is `1.75`.
199 |
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | title: SyncOxiders homepage
2 | remote_theme: pages-themes/hacker@v0.2.0
3 | plugins:
4 | - jekyll-remote-theme
5 | - jekyll-seo-tag
6 |
--------------------------------------------------------------------------------
/_layouts/default.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | {% seo %}
9 |
10 |
11 |
12 |
13 |
14 |
15 | {% include head-custom.html %}
16 |
17 |
18 |
19 |
The app has crashed. See the developer console for details.
",
68 | );
69 | panic!("Failed to start eframe: {e:?}");
70 | }
71 | }
72 | }
73 | });
74 | }
75 |
--------------------------------------------------------------------------------
/p2p-transfer/src/node.rs:
--------------------------------------------------------------------------------
1 | use iroh::endpoint::{Accept, Connection};
2 | use iroh::{Endpoint, NodeId};
3 | use iroh::protocol::{ProtocolHandler, Router};
4 | use tokio::sync::broadcast;
5 | use anyhow::Result;
6 | use async_channel::Sender;
7 | use log::info;
8 | use n0_future::boxed::BoxFuture;
9 | use n0_future::future::Boxed;
10 | use n0_future::{task, Stream};
11 | use serde::{Deserialize, Serialize};
12 |
13 | pub struct EchoNode{
14 | router: Router,
15 | accept_events: broadcast::Sender,
16 | }
17 |
18 | impl EchoNode {
19 | pub async fn spawn() -> Result {
20 |
21 | let endpoint = Endpoint::builder().discovery_n0().alpns(vec![Echo::ALPN.to_vec()]).bind().await?;
22 | let (event_sender, _event_receiver) = broadcast::channel(128);
23 | let echo = Echo::new(event_sender.clone());
24 | let router = Router::builder(endpoint)
25 | .accept(Echo::ALPN, echo)
26 | .spawn();
27 | Ok(Self { router, accept_events: event_sender })
28 |
29 |
30 | }
31 |
32 | pub fn endpoint(&self) -> &Endpoint {
33 | self.router.endpoint()
34 | }
35 |
36 | pub fn connect(
37 | &self,
38 | node_id: NodeId,
39 | payload: String
40 | ) -> impl Stream + Unpin {
41 |
42 | let (event_sender, event_receiver) = async_channel::bounded(16);
43 | let endpoint = self.router.endpoint().clone();
44 | task::spawn(async move {
45 | let res = connect(&endpoint, node_id, payload, event_sender.clone()).await;
46 | let error = res.as_ref().err().map(|e| e.to_string());
47 | event_sender.send(ConnectEvent::Closed {error}).await.ok();
48 | });
49 | Box::pin(event_receiver)
50 | }
51 | }
52 |
53 | #[derive(Debug, Clone , Serialize, Deserialize)]
54 | #[serde(tag="type", rename_all = "camelCase")]
55 | pub enum ConnectEvent {
56 | Connected,
57 | Sent {bytes_sent: u64},
58 | Received {bytes_received: u64},
59 | Closed {error: Option}
60 | }
61 |
62 | #[derive(Debug, Clone, Serialize, Deserialize)]
63 | #[serde(tag="type", rename_all = "camelCase")]
64 | pub enum AcceptEvent {
65 |
66 | Accepted {
67 | node_id: NodeId,
68 | },
69 | Echoed {
70 | node_id: NodeId,
71 | bytes_sent: u64
72 | },
73 | Closed {
74 | node_id: NodeId,
75 | error: Option
76 | }
77 | }
78 |
79 | #[derive(Debug, Clone)]
80 | pub struct Echo{
81 | event_sender: broadcast::Sender
82 | }
83 |
84 | impl Echo{
85 | pub const ALPN: &[u8] = b"iroh/example-browser-echo/0";
86 | pub fn new(event_sender: broadcast::Sender) -> Self {
87 |
88 | Self { event_sender }
89 |
90 | }
91 | }
92 |
93 | impl Echo {
94 | async fn handle_connection(self, connection: Connection) -> Result<()> {
95 |
96 | let node_id = connection.remote_node_id()?;
97 | self.event_sender.send(AcceptEvent::Accepted {node_id }).ok();
98 | let res = self.handle_connection_0(&connection).await;
99 | let error = res.as_ref().err().map(|err| err.to_string());
100 | self.event_sender.send(AcceptEvent::Closed {node_id, error}).ok();
101 | res
102 |
103 |
104 | }
105 |
106 | async fn handle_connection_0(&self, connection: &Connection) -> Result<()> {
107 |
108 | let node_id = connection.remote_node_id()?;
109 | info!("Accepted connection from {}", node_id);
110 |
111 | let (mut send, mut recv) = connection.accept_bi().await?;
112 |
113 | //Echo any bytes received
114 | let bytes_sent = tokio::io::copy(&mut recv, &mut send).await?;
115 |
116 | info!("Copied over {bytes_sent} byte(s)");
117 |
118 | self.event_sender.send(AcceptEvent::Echoed {node_id, bytes_sent}).ok();
119 |
120 | send.finish()?;
121 | connection.closed().await;
122 | Ok(())
123 |
124 |
125 | }
126 | }
127 |
128 | impl ProtocolHandler for Echo{
129 | fn accept(&self, connection: Connection) -> BoxFuture> {
130 | Box::pin(self.clone().handle_connection(connection))
131 | }
132 | }
133 |
134 | async fn connect(
135 | endpoint: &Endpoint,
136 | node_id: NodeId,
137 | payload: String,
138 | event_sender: Sender
139 | ) -> Result<()>{
140 |
141 | let connection = endpoint.connect(node_id, Echo::ALPN).await?;
142 | event_sender.send(ConnectEvent::Connected).await?;
143 | let (mut send_stream , mut recv_stream) = connection.open_bi().await?;
144 | let event_sender_clone = event_sender.clone();
145 | let send_task = task::spawn(async move {
146 | let event_sender = event_sender_clone.clone();
147 | async move {
148 | let bytes_sent = payload.len();
149 | send_stream.write_all(payload.as_bytes()).await?;
150 | event_sender.send(ConnectEvent::Sent {
151 | bytes_sent: bytes_sent as u64,
152 | })
153 | .await?;
154 | anyhow::Ok(())
155 | }
156 | });
157 | let n = tokio::io::copy(&mut recv_stream, &mut tokio::io::sink()).await?;
158 | connection.close(1u8.into(), b"done");
159 | event_sender.send(ConnectEvent::Received {
160 | bytes_received: n as u64,
161 | }).await?;
162 | send_task.await?.await?;
163 | Ok(())
164 |
165 | }
--------------------------------------------------------------------------------
/website/pages/compare.md:
--------------------------------------------------------------------------------
1 | [⟵ Back](../../README.md#what-separates-it-from-other-products)
2 |
3 | # What separates it from others
4 |
5 | ## What other solutions are there
6 |
7 | MultCloud, S3 Drive, rclone, odrive, Resilio Sync.
8 | Some of them are hard to use especially for non-technical users and also they lack multiple features.
9 |
10 | - `MultCloud` seems to be very similar for Sync and Backup but lacks sync with local files. Share is only read only, the files are not kept in sync. Also it’s very buggy, login with Google doesn’t work when you access the shared link, reset pass doesn’t work well, their Google Drive app is still under review and for some reason their Android app is not in store but distributed as APK on their site. Also it lacks encryption
11 | - `S3 Drive` is a bit harder to setup as it requires some manual config in some cases providing access tokens manually. Also lacks many features like Share, Backup, Encryption. The sync is also quite slow
12 | - `rclone` is great but it’s mostly for geeks, you need to do some manual config and start it, mostly from the console. For Google Drive they have a problem, it is not quite real time Sync from remote to local. It has delay for auto-sync (even if you are listing the content of a folder it doesn’t immediately pickup changes) and does sync on some specific operations
13 | - `odrive` doesn’t have sync between providers but just offers a unified view between all your providers. For sharing it offers the other person just a view of the shared files in odrive apps, they cannot add the files to their provider for accessing in there and keeping them in sync, or save them locally and keep them in sync
14 | - `Resilio Sync` is also great but is not of the scale I'm proposing, it only handles your local files sync, not between storage providers and also doesn't have such an easy sharing
15 |
16 | **What all are missing is:**
17 | - **An easy way to send a file to someone with just the browser**
18 | - **Share between storage providers**
19 |
20 | ## What we offer better or additionally
21 |
22 | **Main ones are:**
23 | - **True real-time `bi-directional Sync` and especially `Share` between storage providers (but also for local files)**
24 | - **Simple and quick way to `Share` files with someone using minimal tools, ideally only a browser**
25 | - **Simple and secure inter-cloud Encryption**
26 |
27 | Additionally:
28 | - Receiving files, like S3 presigned URLs but it creates a dest folder where others can upload more files and even folders
29 | - Can combine both local files for Sync and Share and files on storage providers
30 | - Encryption for stored files
31 | - Backup solution with borgbackup and repo
32 | - Performant, efficient, and secure (implemented in RUST and other modern technologies)
33 | - Search and analytics
34 | - WAL (Write-Ahead Logging) to ensure file integrity
35 | - Handles very large files efficiently with concurrent and resumable transfers
36 | - Unified browser, desktop and mobile apps
37 | - Extensive cilents and access, libs, CLI app, REST API and gRPC service
38 |
--------------------------------------------------------------------------------
/website/pages/features.md:
--------------------------------------------------------------------------------
1 | [⟵ Back](../../README.md#features)
2 |
3 | # Features
4 |
5 | All sync operations and changes are applied with WAL (Write-Ahead Logging) to ensure file integrity on crash or power loss. That is, any changes are first written to WAL and then applied to the file. On crash or power loss, the next time the process starts it will apply remaining changes, this repeats until all changes are successfully applied.
6 |
7 | MD5, SHA1 hashes are checked at all times for file integrity. After we transfer the files we will compare local hash with remote hash to ensure data integrity.
8 |
9 | All transfers are multi-threaded and resumable. I can handles very large files efficiently with parallel and resumable downloads.
10 |
11 | - [Sync between providers, Copy, Sync, Move, Two-way sync](features/sync-providers.md#sync-between-providers)
12 | - [Conflict resolution](features/sync-providers.md#conflict-resolution)
13 | - [Sync local files between multiple authenticated devices](features/sync-local.md)
14 | - [MD5, SHA1 hashes are checked at all times for file integrity](features.md#features)
15 | - Multi-threaded transfers
16 | - [Make sync (and changes) with WAL (Write-Ahead Logging) to ensure file integrity](features.md#features)
17 | - [Share between multiple providers like Google Drive, Dropbox, S3, ...](features/share-providers.md)
18 | - [Share local files](features/share-local.md)
19 | - [Easy way to share files with external users, via a link or notification](features/share-external.md)
20 | - [Receiving files, like S3 presigned URLs but create a dest folder where others can upload more files and even folders](features/receive.md)
21 | - deadline, late uploads, password
22 | - [Encrypted files and folders, with files saved in provider or with local files](features/encrypt.md)
23 | - also encrypted sharing with PGP
24 | - [Browser app built in WebAssembly compatible with all major browsers](features/browser-app.md)
25 | - [Local app for desktop and mobile, access files via FUSE on Linux and macOS, WinFSP (or others) on Windows and file picker on mobile](features/local-app.md)
26 | - encrypted cache, full copy kept in sync, notifications
27 | - [Handles very large files efficiently with concurrent and resumable transfers](features/large-files.md)
28 | - [Local views: My Drive, Computers, Shared, Shared with me, Recents, Starred, Trash](features/local-view.md)
29 | - [Global view from all providers and local files, My Drive, Computers, Shared, Shared with me, Recents, Starred, Trash](features/global-view.md)
30 | - [Internal links to other files](features/links.md)
31 | - [Search capabilities](features/search.md)
32 | - [Analytics](features/analytics.md)
33 | - [File history and versioning](features/versioning.md)
34 | - [Cleanup storage](features/cleanup.md)
35 | - [Sync, share status, storage overview](features/status.md)
36 | - [Backups with Borg, encrypted, deduplicated and compressed](features/backup.md)
37 | - [Keep emails in sync between multiple providers](features/emails.md)
38 | - [Backup your emails locally or on our Borg repo](features/emails.md)
39 | - [Anti-Virus scanning](features/antivirus.md)
40 | - [Automation, convert to PDF, convert image, unzip, convert audio/video, watermark files](features/automation.md)
41 | - [Photo manager](features/photos.md)
42 | - [REST API, gRPC, CLI clients and client libs in multiple languages](features/clients.md)
43 | - [Many supported providers](features/supported-providers.md)
44 | - [Integration with other systems](features/integrations.md)
45 |
--------------------------------------------------------------------------------
/website/pages/features/analytics.md:
--------------------------------------------------------------------------------
1 | [⟵ Back](../features.md#features)
2 |
3 | # Analytics
4 |
5 | We offer various analytics like:
6 | - stats on types of files, images, videos, ...
7 | - metrics on files metadata, files size, changed date, changed by, ...
8 | - stats per provider, space used, free, transferred MB per month, in total, ...
9 | - metrics on files activity, how often a file is changed, who did the most/recent change, most changed/used files, unused files ...
10 | - duplicate files between providers
11 |
12 | 
13 |
--------------------------------------------------------------------------------
/website/pages/features/antivirus.md:
--------------------------------------------------------------------------------
1 | # Anti-Virus scanning
2 |
3 | When you upload a file it will be automatically scanned for viruses with [ClamAV](https://www.clamav.net) and reported to you. Files with viruses will not be accepted or will be kept in a quarantine folder that you can act upon.
4 |
--------------------------------------------------------------------------------
/website/pages/features/automation.md:
--------------------------------------------------------------------------------
1 | [⟵ Back](../features.md#features)
2 |
3 | # Automation
4 |
5 | You will be able to define some automation actions for folders. When files are added or changed in them the following actions could be performed:
6 | - rename files
7 | - convert to PDF
8 | - convert image
9 | - convert audio/video
10 | - unzip
11 | - watermark files
12 |
13 | 
14 |
--------------------------------------------------------------------------------
/website/pages/features/backup.md:
--------------------------------------------------------------------------------
1 | [⟵ Back](../features.md#features)
2 |
3 | # Backups with BorgBackup, encrypted, deduplicated and compressed
4 |
5 | We’re using [BorgBackup](https://www.borgbackup.org) which handles encryption, deduplication and compression. We offer BorgBackup repos that can be used to backup data. Subscription is separate from the Sync and Share services.
6 |
7 | There are 2 scopes of backups:
8 | - **local data**: using the local app or browser app you can setup backup schedule for local files, this will be done with cron jobs, scheduled tasks on Windows, termux-job-scheduler on Android and ibimobiledevice in iOS
9 | - **provider files**: from browser app or local app you can schedule backups from provider files. The service will need to read all files and changes from the provider and will backup on our repo. All the process is handled by the service, you don’t need the local app running for this.
10 |
11 | When you want to restore some data you can use the local app or browser app, you’ll select the archive to restore from, you can then access files in the app and copy them locally or to a provider. In the local app you can also mount it in the OS from where you can copy the files. You can also use BorgBackup CLI or `Vorta` for GUI if you want, setup will be provided for you in the local app, browser app and on our website.
12 |
--------------------------------------------------------------------------------
/website/pages/features/browser-app.md:
--------------------------------------------------------------------------------
1 | [⟵ Back](../features.md#features)
2 |
3 | # Browser app built in WebAssembly
4 |
5 | We have a browser app as a file manager built in WebAssembly that is compatible with all major browsers. You can perform all operations from it and it handles the traffic also. Concurrent and resumable transfers.
6 |
7 | It supports notifications that you receive for several events and changes, like when someone is sharing a file with you, someone accepted your share, someone changed a shared file and others.
8 |
9 | 
10 | Image is copyrighted to `SpaceDrive`.
11 |
--------------------------------------------------------------------------------
/website/pages/features/cleanup.md:
--------------------------------------------------------------------------------
1 | [⟵ Back](../features.md#features)
2 |
3 | # Cleanup storage
4 |
5 | Based on the analytics overview you can choose what files to delete when you need to make more space on provider or locally.
6 |
--------------------------------------------------------------------------------
/website/pages/features/clients.md:
--------------------------------------------------------------------------------
1 | [⟵ Back](../features.md#features)
2 |
3 | # REST API, gRPC, CLI clients and client libs in multiple languages
4 |
5 | We will expose a `REST API` and `gRPC` service and will have client libs in multiple languages that users can use to build their own apps.
6 | Also we will have a CLI that can be used for example to automate various flows.
7 |
8 | 
9 |
--------------------------------------------------------------------------------
/website/pages/features/emails.md:
--------------------------------------------------------------------------------
1 | [⟵ Back](../features.md#features)
2 |
3 | # Keep emails in sync between multiple providers
4 |
5 | You can define sync rules between multiple email addresses. This extends mail forwarding as it’s `Two-way` sync and you can define specific filters like from what emails, what words, specific actions like where to sync it, which provider has priority, if we should mark it as read or archive it.
6 |
7 | 
8 |
9 | # Backup your emails locally or on our BorgBackup repo
10 |
11 | From the browser app or local app you can define backup rules and schedule and app will run on those intervals and backup your emails locally.
12 |
13 | 
14 |
15 | 
16 |
--------------------------------------------------------------------------------
/website/pages/features/encrypt.md:
--------------------------------------------------------------------------------
1 | [⟵ Back](../features.md#features)
2 |
3 | # Encrypt
4 |
5 | In transit data (between our apps, service, provider, browser, torrent clients) is always encrypted using TLS 1.3 when possible. But you may decide to keep your files encrypted (at rest), for privacy reasons. Your provider will not have access to the content of your files, nor metadata. You will need the local app or browser app to access the files. Works with local files too.
6 |
7 | You can choose to encrypt the whole provider content or just selected folders.
8 |
9 | 
10 |
11 | ## Encrypted share
12 |
13 | It uses `PGP` to handle encryption. There are 2 options:
14 | - **share with users in our service**: a session key will be generated then encrypted with destination’s user public key. The encrypted key will be sent along when sharing. If user is adding the share to providers or local app the decryption and encryption will be handled automatically. The file will be decryted in memory on demand using the session key (decrypting only the chunks that are read). On the disk or in provider it will be kept encrypted all the time
15 | - **share with external users**: if the other user is not using our service or they download the file with browser or torrent, before they can download they will need to upload their public key. After that the file is downloaded as encrypted along with the encrypted session key. Users can then decrypt the session key with their private key and then decrypt the file, this can be handled with any PGP client like GPG
16 |
17 | 
18 |
19 | 
20 |
21 | 
22 |
--------------------------------------------------------------------------------
/website/pages/features/global-view.md:
--------------------------------------------------------------------------------
1 | [⟵ Back](../features.md#features)
2 |
3 | # Global view from all providers and local files, My Drive, Computers, Shared, Shared with me, Recents, Starred, Trash
4 |
5 | Like local views but gives you an overview of files from all providers and local folders accessed based on some basic categories. Corresponds to All folder from the Local view frame. You can perform all operations on them, create new files, copy between them, share, search, ...
6 |
7 | There is one more special folder, Shared with me at the root level, where you can keep files that are shared with you which you don’t want to add to a provider or save locally. This is accessible only from our apps and when you go there you see latest version of those files and any changes you and others make will be synced between all of you.
8 |
--------------------------------------------------------------------------------
/website/pages/features/integrations.md:
--------------------------------------------------------------------------------
1 | [⟵ Back](../features.md#features)
2 |
3 | # Integration with other systems
4 |
5 | We consider providing integration with:
6 | - Google Workspace
7 | - Microsoft
8 | - Slack
9 | - AWS
10 | - HubSpot
11 | - Autodesk
12 | - Canva
13 | - Figma
14 | - Miro
15 |
--------------------------------------------------------------------------------
/website/pages/features/large-files.md:
--------------------------------------------------------------------------------
1 | [⟵ Back](../features.md#features)
2 |
3 | # Handles very large files efficiently with concurrent and resumable transfers for the browser app, local app and shared files
4 |
5 | All transfers are made concurrently and are resumable. This is true for browser app, local app (if they crash or closed while transferring the next time they star the transfer will continue) and for shared files (browser transfers and with torrent clients).
6 |
7 | When possible we use `BitTorrent` with `QUIC` or `Apache Arrow` format to sync files, this is true between local files for ex, but for provider files we use the supported provider protocols.
8 |
--------------------------------------------------------------------------------
/website/pages/features/links.md:
--------------------------------------------------------------------------------
1 | [⟵ Back](../features.md#features)
2 |
3 | # Internal links to other files
4 |
5 | Links to files inside same provider or local files. This is normally dependent on the underlying remote support, but in cases it’s not supported we do our best to implement inks which then you can only manage and access with our apps.
6 |
--------------------------------------------------------------------------------
/website/pages/features/local-app.md:
--------------------------------------------------------------------------------
1 | [⟵ Back](../features.md#features)
2 |
3 | # Local app for desktop and mobile
4 |
5 | We have local apps for all major desktop OSs and on mobile for Android and iOS.
6 |
7 | The desktop app is very similar to browser app, in fact they share the same code. The same, will handle all operations and transfers with the service and with other P2P apps. Will expose files with FUSE on Linux and macOS, WinFSP (or others) on Windows and file picker on mobile. Concurrent and resumable transfers.
8 |
9 | It operates in 2 modes:
10 | - **encrypted cache (default)**: it downloads the files on demand in real-time and keep them in a local encrypted cache with a maximum size
11 | - **full copy kept in sync**: it will download all files for each provider and keeps them in `Two-way` sync
12 |
13 | It supports notifications that you receive for several events and changes, like when someone is sharing a file with you, someone accepted your share, someone changed a shared file and others.
14 |
15 | 
16 | Image is copyrighted to `SpaceDrive`.
17 |
--------------------------------------------------------------------------------
/website/pages/features/local-view.md:
--------------------------------------------------------------------------------
1 | [⟵ Back](../features.md#features)
2 |
3 | # Local views: My Drive, Computers, Shared, Shared with me, Recents, Starred, Trash
4 |
5 | You will have a dedicated entry point folder for each provider and also for local folders. Inside each folder you there will be some basic categories. You can perform all operations on them, create new files, copy between provider or local folders, share, search, ...
6 |
7 | 
8 |
--------------------------------------------------------------------------------
/website/pages/features/photos.md:
--------------------------------------------------------------------------------
1 | [⟵ Back](../features.md#features)
2 |
3 | # Photo manager
4 |
5 | We will offer a basic browser based and local app photo manager. It can manage photos from all providers, or local photos, offers basic edit operations, share photos, albums, stats,
6 |
--------------------------------------------------------------------------------
/website/pages/features/receive.md:
--------------------------------------------------------------------------------
1 | [⟵ Back](../features.md#features)
2 |
3 | # Receiving files
4 |
5 | Someone might want to send you a file. For that you first setup a Request Files link, send it to them, and we’ll handle how the file gets back to you.
6 |
7 | This is similar to [S3 presigned URLs](https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-presigned-url.html) but create a dest folder where others can upload more files and even folders.
8 | Useful for `One-way` one time transfers. After upload the files will not be kept in sync.
9 |
10 | You can create such an URL from a provider folder or local folder. For local folders the browser app or local app need to be running when the user upload the files.
11 |
12 | We’ll notify the user with the link, or you can send it to them. You will be notified when they uploaded new files.
13 |
14 | 
15 |
16 | You can define these:
17 | - title and description
18 | - destination folder: in your provider or locally
19 | - deadline: until the link is valid
20 | - late uploads: if users are allowed to upload after this date
21 | - password: a password user need to use to upload files
22 |
23 | When user opens the link it will be presented with:
24 | - **upload with browser**: will use the browser to upload multiple files and folders
25 | - **upload with torrent**: based on a link the user’s torrent client will be started and they can upload by adding files or folders to their local folder linked to the torrent
26 | - **upload with browser app**: will start the browser file manager app (they can create an account if they want) from where they can choose to upload files from a provider (if they have an account on our service), `Shared with me` folder or local files
27 | - **upload with local app**: they can install and/or use the local app from where they can choose to upload a files from a provider (if they have an account on our service), `Shared with me` folder or local files
28 | - a QR code will also be presented if they want to use the mobile apps
29 |
30 | 
31 |
32 | 
33 |
34 | 
35 |
--------------------------------------------------------------------------------
/website/pages/features/search.md:
--------------------------------------------------------------------------------
1 | [⟵ Back](../features.md#features)
2 |
3 | # Search capabilities
4 |
5 | - **metadata fields**: like name, size, modified date
6 | - **advanced search*: like shared with, last modified by
7 | - **file content**: search inside file content, this is dependent on the underlying remote support. You might opt-in for us analyzing the files and offer content search capabilities but this would require us to read all files
8 |
--------------------------------------------------------------------------------
/website/pages/features/share-external.md:
--------------------------------------------------------------------------------
1 | [⟵ Back](../features.md#features)
2 |
3 | # Share with external users
4 |
5 | You can share a file from your providers with someone not using our service or any other storage providers. We’ll generate a link, we’ll email to them, or you can send them, and they can get it from browser, with a torrent client or sync it with local our client.
6 |
7 | You can initiated the share in 2 ways:
8 | - **from browser app**: using our file manager app in browser you will pick-up a file from a provider
9 | - **from local app**: you will initiate the share from local app
10 |
11 | Sync mode (`Copy`, `Move`, `One-way`, `Two-way`), `compare-mode` and `conflict resolution` are handled as per above.
12 |
13 | You can define these options when sharing:
14 | - password
15 | - expiry date
16 |
17 | You always have the option to stop sharing.
18 |
19 | You will be notified when they accepted or change something and they will be notified when you make changes.
20 |
21 | When they access the link will have these options:
22 | - **download with browser**: download will be handled by their browser, it’s a `One-way` one time transfer
23 | - **download with torrent**: they will use a torrent client to get the file. We will handle the torrent tracker. This is a `One-way` transfer
24 | - **use browser app**: will start the file manager browser app (they can create an account if they want) from where they can add the files to a provider (if they have an account on our service), save it as link in `Shared with me` folder or save them locally. Files will be kept in sync between the two of you
25 | - **use local app**: they can install and/or use the local app from where they can add the files to a provider (if they have an account on our service), save it as link in `Shared with me` folder or sync them locally. Files will be kept in sync between the two of you
26 | - a QR code will also be presented if they want to use the mobile apps
27 | - **preview**: for some types we offer preview, like for images, videos, audios, text files, PDFs, ...
28 | -
29 | Sync mode (`Copy`, `Move`, `One-way`, `Two-way`), `compare-mode` and `conflict resolution` are handled as per above.
30 |
31 | 
32 |
--------------------------------------------------------------------------------
/website/pages/features/share-local.md:
--------------------------------------------------------------------------------
1 | [⟵ Back](../features.md#features)
2 |
3 | # Share Local files
4 |
5 | You can quickly share a file directly with someone via a link, they can get it from browser, with a torrent client or sync it with our apps.
6 |
7 | If both of you are using any of our apps you can share it directly from the app and files will be kept in sync.
8 |
9 | The file transfer can be handled in 2 ways:
10 | - **P2P**: in a `peer-to-peer` manner, your can use our file manager app in browser (uses `WebRTC`) or local app (uses `HTTP`, `QUIC` and `BitTorrent`). In both cases the apps need to be running for the user to download the files
11 | - **Upload to our service**: with the browser app or local app you can first upload the local files to us and user will download them directly from us. The browser app or local app doesn't need to be running for download to happen
12 |
13 | Sync mode (`Copy`, `Move`, `One-way`, `Two-way`), `compare-mode` and `conflict resolution` are handled as per above.
14 |
15 | You can define these options when sharing:
16 | - password
17 | - expiry date
18 |
19 | You always have the option to stop sharing.
20 |
21 | You will be notified when they accepted or change something and they will be notified when you make changes.
22 |
23 | When they access the link they have the same options as above for sharing between other service users or with external users.
24 |
25 | 
26 |
27 | 
28 |
--------------------------------------------------------------------------------
/website/pages/features/share-providers.md:
--------------------------------------------------------------------------------
1 | [⟵ Back](../features.md#features)
2 |
3 | # Share between service users
4 |
5 | You may share a file from your provider with another person, using our service. After they accept it it will be accessible in their provider, both of you can change the file and the changes are kept in sync.
6 |
7 | The service will notify the other user and he will select where to save the files, what provider and folder. You will be notified back when they accepted and also when they changed something.
8 |
9 | The user may decide to not add the shared files to their providers but keep it as a link (reference), in that case the shared files will be visible to him in a Shared with me folder in the browser or local app. Any changes he makes in there will synced.
10 |
11 | On sharing on the same provider if it supports sharing it will use its build-in sharing functionality when possible.
12 |
13 | In other cases, it will copy the file to destination provider and then keep it in sync between the two of you. Both of you need to use our service with the providers setup in our service for this to work. Sync mode (Copy, Move, One-way, Two-way), compare-mode and conflict resolution are handled as per above.
14 |
15 | The service will notify the user. You will be notified back when they accepted and when they changed something, they will be notified when you changed something.
16 |
17 | When they access the link will have these options:
18 | - **download with browser**: download will be handled by their browser, it’s a `One-way` one time transfer
19 | - **download with torrent**: they will use a torrent client to get the file. We will act as the torrent tracker. This is a One-way transfer
20 | - **use browser app**: will start the file manager browser app from where they can add the files to a provider, save it as link in `Shared with me` folder or save them locally. Files will be kept in sync between the two of you
21 | - **use local app**: they can install and/or use the local app from where they can add the files to a provider, save it as link in `Shared with me` folder or save them locally. Files will be kept in sync between the two of you
22 | - a QR code will also be presented if they want to use the mobile apps
23 | - **preview**: for some types we offer preview, like for images, videos, audios, text files, PDFs, ...
24 |
25 | 
26 |
27 | 
28 |
--------------------------------------------------------------------------------
/website/pages/features/status.md:
--------------------------------------------------------------------------------
1 | [⟵ Back](../features.md#features)
2 |
3 | # Sync, share status, storage overview
4 |
5 | We offer some health overview for you like:
6 | - **connection status**: between your local apps, our service and providers
7 | - **sync status**: when was the last sync, if was successful or it failed, pending changes to be synced locally, pending local changes to be synced to providers, ...
8 | - **share**: pending shared files to be accepted, pending Request Files, ...
9 | - **storage stats**: basic stats like used/free space per provider, type of files, ...
10 |
--------------------------------------------------------------------------------
/website/pages/features/supported-providers.md:
--------------------------------------------------------------------------------
1 | [⟵ Back](../features.md#features)
2 |
3 | # Many supported providers
4 |
5 | Initially we will use [rclone](https://rclone.org#providers) on the service side and we will support all their supported providers.
6 |
7 | In the future we plan to implement our own clients for several providers which might offer more granular and efficient sync. It helps us for example to catch remote changes almost in real-time (as soon as we are notified by the remote), and propagate the changes to other destinations, without needing to use file watchers or rely on the sync logic of rclone provider implementation.
8 |
--------------------------------------------------------------------------------
/website/pages/features/sync-local.md:
--------------------------------------------------------------------------------
1 | [⟵ Back](../features.md#features)
2 |
3 | # Sync local files
4 |
5 | Useful to sync local files between multiple devices with no remote providers involved. It will do it in a `P2P` manner using `QUIC` (will fallback to `TCP/IP` if firewalls blocks `UDP`). Your local apps need to be running for the sync to happen. This is similar to `Resilio Sync`.
6 |
7 | All devices are authenticated using web of trust to make sure are trusted by you. When you setup a sync an invite link or QR code is be generated. When you open the other app based on these it will send a handshake for the device to join the sync group and you need to confirm it from any of the other devices in the group. This will give him a cryptographic key synced between all devices and only then other devices will accept sync operations with it.
8 |
9 | Sync mode (`Copy`, `Move`, `One-way`, `Two-way`), `compare-mode` and `conflict resolution` are handled as per above.
10 |
11 | 
12 |
13 | 
14 |
--------------------------------------------------------------------------------
/website/pages/features/sync-providers.md:
--------------------------------------------------------------------------------
1 | [⟵ Back](../features.md#features)
2 |
3 | # Sync between providers
4 |
5 | After you setup the providers and Sync rules the sync process is automatically handled in the cloud. All your files will stay in sync in real-time and you can access them directly on providers solutions (local client or in browser) or on our local app or browser app.
6 |
7 | We also offer a cloud storage solution based on S3 for now, you can setup our service as a provider and use the local app to sync the files. Then you can take full advantage of syncing those files between providers.
8 |
9 | This is useful when you want to keep files in sync between multiple and/or different providers.
10 |
11 | ## Sync modes
12 |
13 | There are 4 modes to sync the files:
14 | 1. `Copy`: it will copy new and changes files from source to destination. No deletes or renames will occur on dst. In case the file is changed on destination also (see how this is determined based on **compare-mode** below) it will resolve the conflict using `keep-mode: path1` (see below)
15 | 2. `Move`: like `Copy` but will move files from source to destination, deleting them from source after transferred
16 | 3. `One-way`: like Copy but will also delete and rename files on destination. Conflicts are handled based on conflict resolution
17 | 4. `Two-way`: will propagate changes in both directions. In case of changes on both sides conflicts are handled based on conflict resolution
18 |
19 | ## compare-mode
20 |
21 | Takes a comma-separated list, with the currently supported values being `size`, `modtime`, and `hash`. For example, you could compare `size` and `modtime` but not the `hash`.
22 |
23 | ## Conflict resolution
24 |
25 | If configured first it will try to `auto-merge` (see below). This is disabled by default as it needs to download the remote file to perform the merge. if it doesn’t succeed it will keep the content based on `keep-mode` and will copy the other file to a new file with suffix in name like `conflict--date` indicating the other identifier and the date when the change was made.
26 |
27 | ## auto-merge
28 |
29 | - `text files`: it will try to merge the changes similar to Git. If there are changes on different lines the files will be merged, if the changes are on the same line it’s a conflict and will not merge anything. This is disabled by default as it needs to download the remote file
30 | - `binary files`: it will not do any auto-merge
31 |
32 | ## keep-mode
33 | - `newer (default)`: the newer file (by modtime) is considered the winner, regardless of which side it came from. This may result in having a mix of some winners from `Path1`, and some winners from `Path2`
34 | - `older`: same as newer, except the older file is considered the winner
35 | - `bigger`: the bigger file (by `size`) is considered the winner (regardless of `modtime`, if any). This can be a useful option for remotes without `modtime` support, or with the kinds of files (such as logs) that tend to grow but not shrink, over time
36 | - `smaller`: the smaller file (by `size`) is considered the winner (regardless of `modtime`, if any)
37 | - `path1`: the version from `Path1` is unconditionally considered the winner (regardless of `modtime` and `size`, if any). This can be useful if one side is more trusted or up-to-date than the other
38 | - `path2`: same as `path1`, except the `path2` version is considered the winner
39 |
40 | If either of the underlying remotes lacks support for the chosen method, it will be ignored and will fall back to the default of `newer`. If `modtime` is not supported either by the remote it will fallback to `path1`.
41 |
42 | 
43 |
44 | 
45 |
--------------------------------------------------------------------------------
/website/pages/features/versioning.md:
--------------------------------------------------------------------------------
1 | [⟵ Back](../features.md#features)
2 |
3 | # File history and versioning
4 |
5 | ## History
6 |
7 | Many providers offer a history of changes and operations for each file. Where supported we will use that, where not we will try to implement and make it available in apps and clients. The same will offer this for local files.
8 |
9 | This mostly refers to name change and activity history, not convent history, see versioning for that.
10 |
11 | ## Versioning
12 |
13 | Many providers support having multiple versions of the same file, as you copy a new file with same name or change it, it will be a new version. When supported by providers we will use it, when not we will try to implement it our own and make it available in apps and clients. Works also for local files.
14 |
15 | Implementation note: this could be a good use case of git repos with LFS. Git objects are compressed and deduplicated inside same object.
16 |
--------------------------------------------------------------------------------
/website/pages/how-it-works.md:
--------------------------------------------------------------------------------
1 | [⟵ Back](../../README.md#how-it-works)
2 |
3 | # How it works
4 | There are several ways to interact with our service:
5 | - **browser app**: we expose an app built for WebAssembly than can manage all operations and transfers
6 | - **local app**: we also have a local app which is very similar to the browser app, in fact they share the same code. The same, will handle all operations and transfers with the service and with other P2P apps. Will expose files with FUSE or other technologies
7 | - **mobile app**: similar to local app but for Android and iOS
8 | - **clients**:
9 | - **CLI app**: a command line interface to interact with our service. It can also expose files with FUSE or other technologies
10 | - **libs**: we have libs in several languages. They can also expose files with FUSE or other technologies
11 | - **API**: we expose a REST API and gRPC service that you can use to manage all operations and transfers. It uses WebSockets to notify you about changes
12 |
13 | 
14 |
15 | ## Sync
16 |
17 | ### Files
18 |
19 | #### Between providers
20 |
21 | - You setup your providers on our site, you login and grant access to all providers that you need
22 | - Define sync rules, like just Copy from one provider to another or Two-way sync between them
23 | - From this point on we’ll handle syncing all changes between providers (no local app needed for this, it’s all happening in the cloud)
24 | - We also offer a cloud storage solution, you can setup our service as a provider and use a local app to sync the files. Then you can take full advantage of syncing those files between providers
25 |
26 | 
27 |
28 | #### Local files
29 |
30 | - In case you have some local files you want to keep in sync between multiple devices, without any file storage providers, you can use our local app on each device which will handle sync in P2P manner using QUIC. Apps need to be running for this. This is similar to Resilio Sync
31 | - All devices are authenticated using web of trust to make sure are trusted by you
32 |
33 | 
34 |
35 | #### Emails
36 |
37 | You can define sync rules between multiple email addresses. This extends mail forwarding as it’s Two-Way sync and you can define specific filters like from what emails, what words, specific actions like where to sync it, which provider has priority, if we should mark it as read or archive it.
38 |
39 | 
40 |
41 | ## Share files
42 |
43 | ### Between service users
44 |
45 | - You may share a file from your provider with another person, using our service. After they accept it it will be accessible in their provider, both of you can change the file and the changes are kept in sync
46 | - The service will notify the other user and he will select where to save the files, what provider and folder. You will be notified back when they accepted and also when they changed something
47 | - The user may decide to not add the shared files to their providers but keep it as a link (reference), in that case the shared files will be visible to him in a Shared with me folder in the browser or local app. Any changes he makes in there will synced
48 | - On sharing on the same provider if it supports sharing it will use their build-in sharing functionality. On other cases it will copy the file to destination provider and then keep it in sync between the two of you
49 |
50 | 
51 |
52 | ### With external users
53 |
54 | - You can share a file from your providers with someone not using our service or any other storage providers. We’ll generate a link, we’ll email to them, or you can send them, and they can get it from browser, with a torrent client or sync it with our local client
55 | - If they are using our browser or local app you will be notified when they changed something and they will be notified when you make changes
56 |
57 | ### Local files
58 |
59 | - You can quickly share a file directly with someone via a link, they can get it from browser, with a torrent client or sync it with our browser or local app
60 | - If both of you are using the local app you can share directly from the app and files will be kept in sync
61 | - The share can be made in 2 ways:
62 | - **P2P**: in a peer-to-peer manner, your can use our file manager app in browser (uses WebRTC) or local app (uses HTTP, QUIC and BitTorrent), in both cases they need to be running for the user to download the files
63 | - **Upload to our service**: with the browser app or local app you can first upload the local file to us and user will download it directly from us. The browser app or local app don’t need to be running for the download to happen
64 |
65 | 
66 |
67 | ### Receiving files into provider
68 |
69 | Someone might want to send you a file, you setup a Request Files link, send it to them, and we’ll handle how the files gets back to you.
70 |
71 | 
72 |
73 | ### Receiving files locally
74 |
75 | User might upload the file to our service and we’ll save it to your provider, or it can send it directly to you via P2P.
76 |
77 | You can mix between these, for example you can share a local file and the other person who save it on their provider, both files will be kept in sync.
78 | Or you can create a Request Files link based on a provider folder (or local folder) and others can send you files from their provider or local files using their browser, torrent client or local app.
79 |
80 | 
81 |
82 | ## Encrypt
83 |
84 | You may want to keep your files encrypted for privacy. Your provider will not have access to the content of your files, nor metadata. You will need the local app or browser app to access the files. It works with local files too.
85 |
86 | Encrypted share: it uses PGP to handle encryption. There are 2 options:
87 | - **share with users on our service**: a session key will be generated then encrypted with destination’s user’s public key. The encrypted key will be sent along with the file when sharing. If user is adding the shared file to provider or local app the file will be decryted on demand using the session key. On the disk or on provider it will be kept encrypted all the time
88 | - **share with external user**: if user is not using our service or downloads the file with browser or torrent, before downloading the file they will need to upload their public key. After that the file is downloaded as encrypted along with the encrypted session key. User can then decrypt the session key with his private key and then decrypt the file, this can be handled with any PGP client like GPG (instructions will be provided on the download page)
89 |
90 | ### Sync encrypted between providers
91 |
92 | 
93 |
94 | ### Share encrypted with users on our service
95 |
96 | 
97 |
98 | ### Share encrypted with external user
99 |
100 | 
101 |
102 | ## Backup
103 |
104 | We’re using BorgBackup which handles encryption, deduplication and compression. We offer BorgBackup repos that can be used to backup data. Subscription is separate from the Sync and Share services.
105 |
106 | ### Files
107 |
108 | There are 2 sources of backups:
109 | - **files from provider**: from browser app or local app you can schedule backups from provider files. The service will need to read all files and changes from the provider and will backup on our repo. Everything is handled by the service, you don’t need the local app running for this
110 | - **local files**: using the local app you can setup backups schedule for local files and the local app will handle the backup process
111 |
112 | When you want to restore some data you can use the local app, you’ll select the archive to restore from and it will be mounted in OS from where you can copy the files. You can also use BorgBackup CLI or Vorta for GUI if you want, setup will be provided for you in the local app, browser app and on our website
113 |
114 | ### Backup files from provider
115 |
116 | 
117 |
118 | #### Backup local files
119 |
120 | 
121 |
122 | When you want to restore some data you can use the local app, you’ll select the archive to restore from and it will be mounted in OS from where you can copy the files. You can also use borg CLI or Vorta for GUI if you want, setup will be provided for you in the local app, browser app and on our website.
123 |
124 | ### Emails
125 |
126 | From the browser app or local app you can define backup rules and schedule. There are 2 modes:
127 | - **backup by our service**: running backup in scheduled time will be handled by our service, all emails will be read by us from your email provider and saved to our BorgBackup repo
128 | - **backup locally**: local app will run on defined intervals, read the mails directly from your email provider and backup to our BorgBackup repo
129 |
130 | #### Backup by our service
131 |
132 | 
133 |
134 | #### Backup locally
135 |
136 | 
137 |
--------------------------------------------------------------------------------
/website/pages/name.md:
--------------------------------------------------------------------------------
1 | [⟵ Back](../../README.md#whats-with-the-name)
2 |
3 | # What's with the name
4 |
5 | `SyncOxiders` :) Well:
6 | - in Rust community the term `oxide` or `oxidize` it's often used, as it relates to `rust` as a substance
7 | - `rs` it's short for `rust` and it's the Rust files extension
8 | - many Rust related domains tend to be `.rs`
9 |
10 | So the name is `Sync` obvious, `Oxide` as mentioned before and `rs` for the domain. So we have the website [syncoxide.rs](https://syncoxide.rs/)
11 |
--------------------------------------------------------------------------------
/website/pages/poc-demo.md:
--------------------------------------------------------------------------------
1 | [< Back](../../README.md#poc)
2 |
3 | # How it works for now
4 |
5 | `One-way` `One-to-Many` sync for `Add`, `Modify`, `Delete`, `Rename` operations. You can see here a short video demo:
6 | [](https://www.youtube.com/watch?v=JHQC1XpCzQw)
7 |
8 | We'll exemplify for 2 paths, from `path1` to `path2` but it works with multiple paths, it will Sync from `path1` to
9 | others.
10 |
11 | **`One-way` sync:**
12 |
13 | - have 2 mounted folders with rclone (`path1`, `path2`)
14 | - build changes tree for `path1`
15 | - apply changes from `path1` to `path2` for these operations:
16 | - `Add`, `Modify`, `Delete`, `Rename`
17 |
18 | We use `git` to catch the changes, how it works:
19 |
20 | - we have a special directory `repo` shared for both endpoints. This will be used to create a git repo for each path and
21 | tracks changes. It should persist between runs
22 | - inside the `repo` for each path we create a `tree` directory and create the tree structure from `path` in there
23 | - in the files content we keep `size` and `mtime` or `MD5 hash` if enabled
24 | - we do `git add .`, then `git status -s` shows what's changed, we use `git2` crate to interact with git
25 | - after we have the changes tree we apply them to `path2`
26 | - on `Add` and `Modify` we check if the file is already present in `path2` and if it's the same as in `path1` we
27 | skip it
28 | - comparison between the files is made using `size`, `mtime` or `MD5 hash`, if enabled
29 | - on `Rename` if the `old` file is not present in the `path2` to move it, we copy it from `path1`
30 | - changes are applied wth WAL logic, we use git changes as WAL
31 | - after we build the changes tree we unstage all changes
32 | - after we applied a change for a file we stage that file in git
33 | - after each `64MB` we write we are checkpointing (we do `git commit`)
34 | - after applying all changes we commit remainig staged ones
35 | - then we delete the history and keep just an index of all files so e can catch new changes
36 | - like this if the process is suddenly interrupted the next time it runs it will see there are changes and will
37 | apply them
38 | - this hapens until all pending changes are applied
39 |
40 | # Using CLI
41 |
42 | **For now you need to have the `git` client installed locally.**
43 |
44 | You can find the binaries [here](https://github.com/radumarias/syncoxiders/actions/workflows/ci.yml).
45 | Select the last successful run and at the bottom you should have binaries for multiple OSs.
46 |
47 | For other targets you could clone the repo and build it, see below how.
48 |
49 | You can run `syncoxiders -h` to see all args. The basic usage is like this:
50 |
51 | ```bash
52 | syncoxiders --repo
53 | ```
54 |
55 | - `inputs` (``): a lists of paths that will be synced
56 | - ``: a directory that should persist between runs, we create a `git` repo with metadata of files from all paths.
57 | **MUST NOT BE IN ANY OF THE PATHS**. If it doesn't persist, next time it runs it will see all files as `Add`ed, but
58 | will skip copying them if already the same as on the other side
59 |
60 | For now, it does `One-way` sync propagating the changes from `path1` to other paths:
61 |
62 | - `Add`, `Modify`, `Delete`, `Rename`
63 | - on `Add` and `Modify` we check if the file is already present in `path2` and if it's the same as in `path1` we skip it
64 | - comparison between the files is made using `size` and `mtime` or `MD5 hash` (if enabled, see `--checksum` param below)
65 | - on `Rename` if the `old` file is not present in the `path2` to move it, we copy it from `path1`
66 |
67 | By default it detects changes in files based on `size` and `mtime`. After copying to `path2` it will set `atime`
68 | and `mtime` for the files.
69 |
70 | Other args:
71 |
72 | - `--checksum`: (disabled by default): if specified it will calculate `MD5 hash` for files when detecting changes and
73 | when comparing file in `path1` with the file in `path2` when applying `Add` and `Modify` operations.
74 | **This is especially useful if any pf the paths is accessed over the network and doesn't support `mtime` or
75 | even `size` or if the clocks are out of sync**
76 | **It will be considerably slower when enabled**
77 | - `--no-crc`: (disabled by default): if specified it will skip `CRC` check after file was transferred. Without this it
78 | compares the `CRC` of the file in `path1` with the `CRC` of the file in `path2` after transferred. This ensures the
79 | file integrity after transfered.
80 | **Checking `CRC` is highly recommend if any of the paths is accessed over the network.**
81 | - `--dry-run`: this simulates the sync. Will not apply any changes to the paths, will just print the operations that
82 | would have normally be applied to paths
83 | - `--log-all-changes`: by default it doesn't log each change that is applied, but every 100th change so it won't clutter
84 | the logs. Setting this will log all changes
85 |
86 | ## Limitations
87 |
88 | - conflicts are not handled yet. If the file is changed in both `path1` and `path2` the winner is the one from `path1`.
89 | It's like `master-slave` sync where `path1` is the master
90 | - it doesn't sync any of `Add`, `Delete`, or `Rename` operations on empty folders. This is actually a limitation
91 | of `git` as it works only on files. The directory tree will be recreated based on the file parent, but folders with no
92 | files in them will not be synced
93 |
94 | ## Troubleshooting
95 |
96 | In case you experience any inconsistencies in the way the files are synced, or not synced, you can delete the `repo`
97 | directory and run it again. It will see all files as new but will not copy them to the oher sides if already present and
98 | the same, it will just copy the new or changed ones.
99 |
100 | ## Compile it from source code
101 |
102 | ### Clone the repo
103 |
104 | ```bash
105 | git clone git@github.com:radumarias/syncoxiders.git
106 | cd syncoxiders
107 | ```
108 |
109 | ### gcc
110 |
111 | You need to have `gcc` installed locally.
112 |
113 | ### Install rust
114 |
115 | [Install Rust](https://www.rust-lang.org/tools/install)
116 |
117 | ```bash
118 | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
119 | ```
120 |
121 | #### Configuring the PATH environment variable
122 |
123 | In the Rust development environment, all tools are installed to the `~/.cargo/bin` directory, and this is where you will
124 | find the Rust toolchain, including rustc, cargo, and rustup.
125 |
126 | Accordingly, it is customary for Rust developers to include this directory in their `PATH` environment variable. During
127 | installation rustup will attempt to configure the `PATH`. Because of differences between platforms, command shells, and
128 | bugs in rustup, the modifications to PATH may not take effect until the console is restarted, or the user is logged out,
129 | or it may not succeed at all.
130 |
131 | If, after installation, running `rustc --version` in the console fails, this is the most likely reason.
132 |
133 | You can try this also:
134 |
135 | ```bash
136 | $HOME/.cargo/env
137 | ```
138 |
139 | ### Compile the code
140 |
141 | ```bash
142 | cargo build --release
143 | ```
144 |
145 | ### Run it
146 |
147 | ```bash
148 | target/release/syncoxiders --repo
149 | ```
150 |
151 | # Work in progress
152 |
153 | - resolve conflicts
154 | - `One-to-Many` sync optimization (read one time from `path1` when applying changes to multiple paths)
155 | - apply changes by chunks in parallel
156 | - apply changes to both `path1` and `path2`, `Two-Way` sync
157 | - apply changes between multiple paths, `N-Way` sync
158 |
--------------------------------------------------------------------------------
/website/pages/stack.md:
--------------------------------------------------------------------------------
1 | [⟵ Back](../../README.md#stack)
2 |
3 | We’ll build it mostly in Rust with a bit of Java (Spark and Flink) and Python (Airflow) and deployed on AWS and Kubernetes.
4 |
5 | | Scope | Solution |
6 | | ----- | -------- |
7 | | REST API, gRPC | axum, tonic |
8 | | Websocket | tokio-tungstenite |
9 | | DB | RDS, ScyllaDB, Google Cloud Spanner, Neo4j |
10 | | Local app DB | SurrealDB |
11 | | Browser app | egui, wasi, wasm-bindgen, rencfs, pgp |
12 | | Local app desktop | egui, mainline, transmission_rs, cratetorrent/rqbit, quinn, rencfs, pgp, fuse3 |
13 | | Local app mobile | Kotlin Multiplatform |
14 | | Sync daemon | tokio, rencfs, gdrive-rs, git2, rclone, Flink |
15 | | Use Kafka | rdkafka |
16 | | Keycloak | axum-keycloak-auth (in app token verificaton) or Keycloak Gatekeeper (reverse proxy in front of the services) |
17 | | Event Bus | Kafka / Amazon SQS / RabbitMQ |
18 | | Streaming processor | Flink |
19 | | File storage | S3 |
20 | | Search and Analytics | ELK, Apache Spark, Apache Flink, Apache Airflow |
21 | | Identity Provider | Keycloak |
22 | | Cache | Redis |
23 | | Deploy | AWS Lambda and Amazon EKS |
24 | | Metrics | Prometheus and Grafana Mimir |
25 | | Tracing | Prometheus and Grafana Tempo |
26 | | Logs | Grafana Loki |
27 |
--------------------------------------------------------------------------------
/website/pages/use-cases.md:
--------------------------------------------------------------------------------
1 | [⟵ Back](../../README.md#use-cases)
2 |
3 | # Use cases
4 |
5 | - You have various storage cloud providers, and you need to keep files in sync between them
6 | - You're using a primary storage cloud provider, and you want to have backups to other providers
7 | - You want to quickly share a local file with someone with minimal tools involved
8 | - You want to share a Dropbox file with someone who doesn’t have a Dropbox account but wants to keep that file in sync with them
9 | - Someone wants to send you a file but doesn’t have any storage cloud provider accounts
10 | - Keep local files in sync between multiple devices, without any other storage providers, directly with P2P
11 | - You want a global view of files among all providers, My Drive, shared, starred, recent, and trash folders
12 | - You want to access your remote storage provider files locally in the filesystem
13 | - Encrypt local files or files stored on remote providers
14 | - Inter-storage cloud provider encryption
15 | - Search and analytics, what files you most often access, what types of files you have, etc.
16 | - Quick and secure backups
17 | - Keep emails in sync between multiple providers
18 | - Backup your emails
19 | - Photo manager
20 |
--------------------------------------------------------------------------------
/website/resources/app.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radumarias/syncoxiders/15eefe592bcd40cd8ee2338ab0a464c7516eb41b/website/resources/app.png
--------------------------------------------------------------------------------
/website/resources/automation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radumarias/syncoxiders/15eefe592bcd40cd8ee2338ab0a464c7516eb41b/website/resources/automation.png
--------------------------------------------------------------------------------
/website/resources/backup-emails-locally.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radumarias/syncoxiders/15eefe592bcd40cd8ee2338ab0a464c7516eb41b/website/resources/backup-emails-locally.png
--------------------------------------------------------------------------------
/website/resources/backup-emails-with-service.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radumarias/syncoxiders/15eefe592bcd40cd8ee2338ab0a464c7516eb41b/website/resources/backup-emails-with-service.png
--------------------------------------------------------------------------------
/website/resources/backup-local-files.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radumarias/syncoxiders/15eefe592bcd40cd8ee2338ab0a464c7516eb41b/website/resources/backup-local-files.png
--------------------------------------------------------------------------------
/website/resources/backup-provider.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radumarias/syncoxiders/15eefe592bcd40cd8ee2338ab0a464c7516eb41b/website/resources/backup-provider.png
--------------------------------------------------------------------------------
/website/resources/clients.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radumarias/syncoxiders/15eefe592bcd40cd8ee2338ab0a464c7516eb41b/website/resources/clients.png
--------------------------------------------------------------------------------
/website/resources/diagram-encrypt-share.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radumarias/syncoxiders/15eefe592bcd40cd8ee2338ab0a464c7516eb41b/website/resources/diagram-encrypt-share.png
--------------------------------------------------------------------------------
/website/resources/diagram-receive.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radumarias/syncoxiders/15eefe592bcd40cd8ee2338ab0a464c7516eb41b/website/resources/diagram-receive.png
--------------------------------------------------------------------------------
/website/resources/diagram-share-external.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radumarias/syncoxiders/15eefe592bcd40cd8ee2338ab0a464c7516eb41b/website/resources/diagram-share-external.png
--------------------------------------------------------------------------------
/website/resources/diagram-share-local.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radumarias/syncoxiders/15eefe592bcd40cd8ee2338ab0a464c7516eb41b/website/resources/diagram-share-local.png
--------------------------------------------------------------------------------
/website/resources/diagram-share-provider.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radumarias/syncoxiders/15eefe592bcd40cd8ee2338ab0a464c7516eb41b/website/resources/diagram-share-provider.png
--------------------------------------------------------------------------------
/website/resources/diagram-sync-local.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radumarias/syncoxiders/15eefe592bcd40cd8ee2338ab0a464c7516eb41b/website/resources/diagram-sync-local.png
--------------------------------------------------------------------------------
/website/resources/diagram-sync-providers.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radumarias/syncoxiders/15eefe592bcd40cd8ee2338ab0a464c7516eb41b/website/resources/diagram-sync-providers.png
--------------------------------------------------------------------------------
/website/resources/frame-analytics.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radumarias/syncoxiders/15eefe592bcd40cd8ee2338ab0a464c7516eb41b/website/resources/frame-analytics.png
--------------------------------------------------------------------------------
/website/resources/frame-local-view.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radumarias/syncoxiders/15eefe592bcd40cd8ee2338ab0a464c7516eb41b/website/resources/frame-local-view.png
--------------------------------------------------------------------------------
/website/resources/frame-receive.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radumarias/syncoxiders/15eefe592bcd40cd8ee2338ab0a464c7516eb41b/website/resources/frame-receive.png
--------------------------------------------------------------------------------
/website/resources/mvp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radumarias/syncoxiders/15eefe592bcd40cd8ee2338ab0a464c7516eb41b/website/resources/mvp.png
--------------------------------------------------------------------------------
/website/resources/poc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radumarias/syncoxiders/15eefe592bcd40cd8ee2338ab0a464c7516eb41b/website/resources/poc.png
--------------------------------------------------------------------------------
/website/resources/receive-file-with-provider.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radumarias/syncoxiders/15eefe592bcd40cd8ee2338ab0a464c7516eb41b/website/resources/receive-file-with-provider.png
--------------------------------------------------------------------------------
/website/resources/receive-local-file.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radumarias/syncoxiders/15eefe592bcd40cd8ee2338ab0a464c7516eb41b/website/resources/receive-local-file.png
--------------------------------------------------------------------------------
/website/resources/services.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radumarias/syncoxiders/15eefe592bcd40cd8ee2338ab0a464c7516eb41b/website/resources/services.png
--------------------------------------------------------------------------------
/website/resources/share-encrypte-with-external-user.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radumarias/syncoxiders/15eefe592bcd40cd8ee2338ab0a464c7516eb41b/website/resources/share-encrypte-with-external-user.png
--------------------------------------------------------------------------------
/website/resources/share-encryptyed-with-service-user.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radumarias/syncoxiders/15eefe592bcd40cd8ee2338ab0a464c7516eb41b/website/resources/share-encryptyed-with-service-user.png
--------------------------------------------------------------------------------
/website/resources/share-local.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radumarias/syncoxiders/15eefe592bcd40cd8ee2338ab0a464c7516eb41b/website/resources/share-local.png
--------------------------------------------------------------------------------
/website/resources/share-providers.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radumarias/syncoxiders/15eefe592bcd40cd8ee2338ab0a464c7516eb41b/website/resources/share-providers.png
--------------------------------------------------------------------------------
/website/resources/sync-emails.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radumarias/syncoxiders/15eefe592bcd40cd8ee2338ab0a464c7516eb41b/website/resources/sync-emails.png
--------------------------------------------------------------------------------
/website/resources/sync-encrypted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radumarias/syncoxiders/15eefe592bcd40cd8ee2338ab0a464c7516eb41b/website/resources/sync-encrypted.png
--------------------------------------------------------------------------------
/website/resources/sync-local.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radumarias/syncoxiders/15eefe592bcd40cd8ee2338ab0a464c7516eb41b/website/resources/sync-local.png
--------------------------------------------------------------------------------
/website/resources/sync-providers.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radumarias/syncoxiders/15eefe592bcd40cd8ee2338ab0a464c7516eb41b/website/resources/sync-providers.png
--------------------------------------------------------------------------------
/website/resources/syncoxiders-icon-20p.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radumarias/syncoxiders/15eefe592bcd40cd8ee2338ab0a464c7516eb41b/website/resources/syncoxiders-icon-20p.png
--------------------------------------------------------------------------------