mirror of
https://github.com/sudosylabs/vnidrop.git
synced 2026-08-05 02:29:55 +02:00
Merge pull request #16 from vnidrop/feat/project-community-docs
docs: establish project documentation and licensing
This commit is contained in:
161
CODE_OF_CONDUCT.md
Normal file
161
CODE_OF_CONDUCT.md
Normal file
@@ -0,0 +1,161 @@
|
||||
# VniDrop Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
We pledge to make our community welcoming, safe, and equitable for all.
|
||||
|
||||
We are committed to fostering an environment that respects and promotes the
|
||||
dignity, rights, and contributions of all individuals, regardless of
|
||||
characteristics including race, ethnicity, caste, color, age, physical
|
||||
characteristics, neurodiversity, disability, sex or gender, gender identity or
|
||||
expression, sexual orientation, language, philosophy or religion, national or
|
||||
social origin, socio-economic position, level of education, or other status.
|
||||
The same privileges of participation are extended to everyone who participates
|
||||
in good faith and in accordance with this Code of Conduct.
|
||||
|
||||
## Encouraged Behaviors
|
||||
|
||||
While acknowledging differences in social norms, we all strive to meet our
|
||||
community's expectations for positive behavior. We also understand that our
|
||||
words and actions may be interpreted differently than we intend based on
|
||||
culture, background, or native language.
|
||||
|
||||
With these considerations in mind, we agree to behave mindfully toward each
|
||||
other and act in ways that center our shared values, including:
|
||||
|
||||
1. Respecting the purpose of our community, our activities, and our ways of
|
||||
gathering.
|
||||
2. Engaging kindly and honestly with others.
|
||||
3. Respecting different viewpoints and experiences.
|
||||
4. Taking responsibility for our actions and contributions.
|
||||
5. Gracefully giving and accepting constructive feedback.
|
||||
6. Committing to repairing harm when it occurs.
|
||||
7. Behaving in other ways that promote and sustain the well-being of our
|
||||
community.
|
||||
|
||||
## Restricted Behaviors
|
||||
|
||||
We agree to restrict the following behaviors in our community. Instances,
|
||||
threats, and promotion of these behaviors are violations of this Code of
|
||||
Conduct.
|
||||
|
||||
1. **Harassment.** Violating explicitly expressed boundaries or engaging in
|
||||
unnecessary personal attention after any clear request to stop.
|
||||
2. **Character attacks.** Making insulting, demeaning, or pejorative comments
|
||||
directed at a community member or group of people.
|
||||
3. **Stereotyping or discrimination.** Characterizing anyone's personality or
|
||||
behavior on the basis of immutable identities or traits.
|
||||
4. **Sexualization.** Behaving in a way that would generally be considered
|
||||
inappropriately intimate in the context or purpose of the community.
|
||||
5. **Violating confidentiality.** Sharing or acting on someone's personal or
|
||||
private information without their permission.
|
||||
6. **Endangerment.** Causing, encouraging, or threatening violence or other
|
||||
harm toward any person or group.
|
||||
7. **Behaving in other ways that threaten the well-being of our community.**
|
||||
|
||||
### Other Restrictions
|
||||
|
||||
1. **Misleading identity.** Impersonating someone else for any reason, or
|
||||
pretending to be someone else to evade enforcement actions.
|
||||
2. **Failing to credit sources.** Not properly crediting the sources of content
|
||||
you contribute.
|
||||
3. **Promotional materials.** Sharing marketing or other commercial content in
|
||||
a way that is outside the norms of the community.
|
||||
4. **Irresponsible communication.** Failing to responsibly present content
|
||||
which includes, links, or describes any other restricted behaviors.
|
||||
|
||||
## Reporting an Issue
|
||||
|
||||
Tensions can occur between community members even when they are trying their
|
||||
best to collaborate. Not every conflict represents a Code of Conduct violation,
|
||||
and this Code of Conduct reinforces encouraged behaviors and norms that can help
|
||||
avoid conflicts and minimize harm.
|
||||
|
||||
To report a possible violation, contact a VniDrop maintainer privately using the
|
||||
contact information on their GitHub profile. Do not disclose sensitive details
|
||||
in a public issue. If a report concerns a maintainer, contact a different
|
||||
maintainer who is not involved in the incident.
|
||||
|
||||
Include the relevant links, dates, context, and any supporting material you are
|
||||
comfortable sharing. Community Moderators will take reports seriously and make
|
||||
every effort to respond promptly. They will investigate reports by reviewing
|
||||
available messages, logs, and other evidence, or by interviewing witnesses and
|
||||
participants. They will keep investigation and enforcement actions as
|
||||
transparent as possible while prioritizing safety and confidentiality.
|
||||
|
||||
Enforcement actions are carried out privately with the involved parties, but
|
||||
communicating to the whole community may be part of a mutually agreed-upon
|
||||
resolution.
|
||||
|
||||
## Addressing and Repairing Harm
|
||||
|
||||
If an investigation finds that this Code of Conduct has been violated, the
|
||||
following enforcement ladder may be used to determine how best to repair harm,
|
||||
based on the incident's impact on the individuals involved and the community as
|
||||
a whole. Depending on the severity of a violation, lower rungs on the ladder may
|
||||
be skipped.
|
||||
|
||||
### 1. Warning
|
||||
|
||||
- **Event:** A violation involving a single incident or series of incidents.
|
||||
- **Consequence:** A private, written warning from the Community Moderators.
|
||||
- **Repair:** Examples include a private written apology, acknowledgement of
|
||||
responsibility, and seeking clarification on expectations.
|
||||
|
||||
### 2. Temporarily Limited Activities
|
||||
|
||||
- **Event:** A repeated incidence of a violation that previously resulted in a
|
||||
warning, or the first incidence of a more serious violation.
|
||||
- **Consequence:** A private, written warning with a time-limited cooldown
|
||||
period designed to underscore the seriousness of the situation and give the
|
||||
community members involved time to process the incident. The cooldown period
|
||||
may be limited to particular communication channels or interactions with
|
||||
particular community members.
|
||||
- **Repair:** Examples include making an apology, using the cooldown period to
|
||||
reflect on actions and impact, and being thoughtful about re-entering
|
||||
community spaces after the period is over.
|
||||
|
||||
### 3. Temporary Suspension
|
||||
|
||||
- **Event:** A pattern of repeated violations which the Community Moderators
|
||||
have tried to address with warnings, or a single serious violation.
|
||||
- **Consequence:** A private written warning with conditions for return from
|
||||
suspension. In general, temporary suspensions give the person being suspended
|
||||
time to reflect upon their behavior and possible corrective actions.
|
||||
- **Repair:** Examples include respecting the spirit of the suspension, meeting
|
||||
the specified conditions for return, and being thoughtful about how to
|
||||
reintegrate with the community when the suspension is lifted.
|
||||
|
||||
### 4. Permanent Ban
|
||||
|
||||
- **Event:** A pattern of repeated Code of Conduct violations that other steps
|
||||
on the ladder have failed to resolve, or a violation so serious that the
|
||||
Community Moderators determine there is no way to keep the community safe
|
||||
with this person as a member.
|
||||
- **Consequence:** Access to all community spaces, tools, and communication
|
||||
channels is removed. Permanent bans should be rarely used, have strong
|
||||
reasoning behind them, and only be used if other remedies have failed to
|
||||
change the behavior.
|
||||
- **Repair:** There is no possible repair in cases of this severity.
|
||||
|
||||
This enforcement ladder is a guideline. It does not limit the ability of
|
||||
Community Moderators to use their discretion and judgment in the best interests
|
||||
of the VniDrop community.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all VniDrop community spaces and also when
|
||||
an individual is officially representing VniDrop in public or other spaces.
|
||||
Examples of representation include using an official email address, posting via
|
||||
an official social media account, or acting as an appointed representative at
|
||||
an online or offline event.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant, version
|
||||
3.0](https://www.contributor-covenant.org/version/3/0/).
|
||||
|
||||
Contributor Covenant is stewarded by the Organization for Ethical Source. This
|
||||
adapted Code of Conduct is licensed under [CC BY-SA
|
||||
4.0](https://creativecommons.org/licenses/by-sa/4.0/). The enforcement ladder
|
||||
was inspired by the work of Mozilla's code of conduct team.
|
||||
167
CONTRIBUTING.md
Normal file
167
CONTRIBUTING.md
Normal file
@@ -0,0 +1,167 @@
|
||||
# Contributing to VniDrop
|
||||
|
||||
Thank you for helping improve VniDrop. Contributions may include bug reports,
|
||||
feature proposals, documentation, tests, design feedback, and code.
|
||||
|
||||
By participating, you agree to follow the project
|
||||
[Code of Conduct](CODE_OF_CONDUCT.md).
|
||||
|
||||
## Before You Start
|
||||
|
||||
- Search existing issues and pull requests before opening a duplicate.
|
||||
- For a substantial feature or architecture change, open an issue first so the
|
||||
approach and platform impact can be discussed.
|
||||
- Keep each change focused. Avoid unrelated refactors, dependency upgrades, or
|
||||
repository-wide formatting.
|
||||
- Report suspected vulnerabilities through the private process in
|
||||
[`SECURITY.md`](SECURITY.md), never in a public issue with technical details.
|
||||
- Never include secrets, private tickets, file contents, key material, or
|
||||
passphrases in an issue, log, test fixture, commit, or pull request.
|
||||
|
||||
## Development Setup
|
||||
|
||||
Clone the repository and create a branch from an up-to-date `master`:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/vnidrop/vnidrop.git
|
||||
cd vnidrop
|
||||
git switch master
|
||||
git pull --ff-only
|
||||
git switch -c feat/short-description
|
||||
```
|
||||
|
||||
Use a branch name that describes the outcome, such as
|
||||
`feat/folder-share`, `fix/cancel-export-hang`, or `docs/contributing`.
|
||||
|
||||
Install the tools needed for the area you plan to change:
|
||||
|
||||
- JDK 17 or newer for Gradle and application builds
|
||||
- Rust stable with `rustfmt` and Clippy for the transfer core
|
||||
- Android SDK and NDK for Android builds
|
||||
- Xcode on macOS for iOS builds and simulator tests
|
||||
- Node.js 22.12 or newer for the optional diagnostics service
|
||||
|
||||
The first Rust and Gradle builds may take several minutes while dependencies are
|
||||
downloaded and native components are compiled.
|
||||
|
||||
## Repository Structure
|
||||
|
||||
| Path | Purpose |
|
||||
|------|---------|
|
||||
| `crates/vnidrop/` | Rust transfer core, persistence, approval, and streaming |
|
||||
| `shared/` | Shared Kotlin Multiplatform UI and platform bridges |
|
||||
| `androidApp/` | Android application shell |
|
||||
| `iosApp/` | iOS application shell |
|
||||
| `desktopApp/` | Desktop JVM application shell |
|
||||
| `services/diagnostics-api/` | Optional Cloudflare diagnostics service |
|
||||
|
||||
Read the nearest contributor guidance before editing:
|
||||
|
||||
- [`AGENTS.md`](AGENTS.md) contains repository-wide engineering rules.
|
||||
- [`crates/vnidrop/AGENTS.md`](crates/vnidrop/AGENTS.md) covers the Rust core.
|
||||
- [`shared/AGENTS.md`](shared/AGENTS.md) covers Compose and Kotlin
|
||||
Multiplatform work.
|
||||
|
||||
## Engineering Expectations
|
||||
|
||||
VniDrop follows a few important design constraints:
|
||||
|
||||
- File transfer payloads are streamed by Rust and should not be routed through
|
||||
the Kotlin heap as the primary design.
|
||||
- Android directory sharing expands SAF trees into individual file descriptors;
|
||||
directory file descriptors are not passed to Rust.
|
||||
- Approval and access checks must not be weakened for convenience.
|
||||
- Receive publishing must preserve the existing no-overwrite behavior.
|
||||
- Locks and synchronous guards must not be held across Rust `.await` points.
|
||||
- Bug fixes require a regression test at the lowest layer that demonstrates the
|
||||
failure.
|
||||
|
||||
Match the style of nearby code. Comments should explain non-obvious invariants,
|
||||
platform constraints, concurrency behavior, or design decisions instead of
|
||||
restating the code.
|
||||
|
||||
## Testing
|
||||
|
||||
Run checks from the repository root. Choose the suite for the files you changed.
|
||||
|
||||
### Rust Core
|
||||
|
||||
```bash
|
||||
cargo fmt --all
|
||||
cargo clippy --workspace --all-targets -- -D warnings
|
||||
cargo test -p vnidrop
|
||||
```
|
||||
|
||||
For cancel, export, or output-sink changes, also run:
|
||||
|
||||
```bash
|
||||
cargo test -p vnidrop --test output_sink
|
||||
```
|
||||
|
||||
For broader core changes, run the complete workspace suite:
|
||||
|
||||
```bash
|
||||
cargo test --workspace --all-targets
|
||||
```
|
||||
|
||||
### Shared Kotlin and Compose
|
||||
|
||||
```bash
|
||||
./gradlew :shared:jvmTest
|
||||
```
|
||||
|
||||
Platform-specific checks may also be appropriate:
|
||||
|
||||
```bash
|
||||
./gradlew :shared:testAndroidHostTest
|
||||
./gradlew :shared:iosSimulatorArm64Test
|
||||
./gradlew :androidApp:assembleDebug
|
||||
```
|
||||
|
||||
### Diagnostics Service
|
||||
|
||||
```bash
|
||||
cd services/diagnostics-api
|
||||
npm ci
|
||||
npm run check
|
||||
```
|
||||
|
||||
If a required check cannot run on your machine, explain why in the pull request
|
||||
and list the checks you did run.
|
||||
|
||||
## Commits
|
||||
|
||||
Use concise commit messages that describe the outcome. The repository commonly
|
||||
uses Conventional Commit-style subjects:
|
||||
|
||||
```text
|
||||
feat(core): add folder transfer metadata
|
||||
fix(ui): preserve receive progress after rotation
|
||||
docs: clarify desktop setup
|
||||
```
|
||||
|
||||
Create signed commits when your repository configuration requires signing. Do
|
||||
not bypass a signing requirement with an unsigned commit.
|
||||
|
||||
## Pull Requests
|
||||
|
||||
Open pull requests against `master`. A good pull request should:
|
||||
|
||||
1. Explain what changed and why.
|
||||
2. Stay limited to one coherent outcome.
|
||||
3. Link the relevant issue, when one exists.
|
||||
4. Describe platform or compatibility implications.
|
||||
5. Include regression coverage for bug fixes and behavior changes.
|
||||
6. Provide an executable test plan with the exact commands or concrete manual
|
||||
scenarios used for verification.
|
||||
7. Avoid generated files, unrelated formatting, and dependency changes unless
|
||||
they are required by the contribution.
|
||||
|
||||
Review feedback is part of the collaboration process. Keep follow-up commits
|
||||
focused, and resolve review threads only after the concern has been addressed.
|
||||
|
||||
## Licensing
|
||||
|
||||
VniDrop is distributed under the [Apache License 2.0](LICENSE). Unless explicitly
|
||||
stated otherwise, contributions accepted into this repository are distributed
|
||||
under the same license.
|
||||
202
LICENSE
Normal file
202
LICENSE
Normal file
@@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
159
README.md
159
README.md
@@ -1,36 +1,143 @@
|
||||
This is a Kotlin Multiplatform project targeting Android, iOS, Desktop (JVM).
|
||||
<p align="center">
|
||||
<img src="assets/1024x1024.png" alt="VniDrop app icon" width="128" />
|
||||
</p>
|
||||
|
||||
* [/iosApp](./iosApp/iosApp) contains an iOS application. Even if you’re sharing your UI with Compose Multiplatform,
|
||||
you need this entry point for your iOS app. This is also where you should add SwiftUI code for your project.
|
||||
<h1 align="center">VniDrop</h1>
|
||||
|
||||
* [/shared](./shared/src) is for code that will be shared across your Compose Multiplatform applications.
|
||||
It contains several subfolders:
|
||||
- [commonMain](./shared/src/commonMain/kotlin) is for code that’s common for all targets.
|
||||
- Other folders are for Kotlin code that will be compiled for only the platform indicated in the folder name.
|
||||
For example, if you want to use Apple’s CoreCrypto for the iOS part of your Kotlin app,
|
||||
the [iosMain](./shared/src/iosMain/kotlin) folder would be the right place for such calls.
|
||||
Similarly, if you want to edit the Desktop (JVM) specific part, the [jvmMain](./shared/src/jvmMain/kotlin)
|
||||
folder is the appropriate location.
|
||||
<p align="center">
|
||||
<strong>Send files directly. Stay in control of who receives them.</strong>
|
||||
</p>
|
||||
|
||||
### Running the apps
|
||||
<p align="center">
|
||||
Cross-platform file transfer for Android, iOS, macOS, Windows, and Linux.
|
||||
</p>
|
||||
|
||||
Use the run configurations provided by the run widget in your IDE's toolbar. You can also use these commands and
|
||||
options:
|
||||
<p align="center">
|
||||
<a href="https://github.com/vnidrop/vnidrop/actions/workflows/rust-core.yml"><img src="https://github.com/vnidrop/vnidrop/actions/workflows/rust-core.yml/badge.svg" alt="Rust core status" /></a>
|
||||
<a href="https://github.com/vnidrop/vnidrop/actions/workflows/shared-kmp.yml"><img src="https://github.com/vnidrop/vnidrop/actions/workflows/shared-kmp.yml/badge.svg" alt="Shared KMP status" /></a>
|
||||
<img src="https://img.shields.io/badge/status-early%20development-F59E0B" alt="Early development" />
|
||||
<a href="LICENSE"><img src="https://img.shields.io/badge/license-Apache%202.0-6D28D9" alt="Apache 2.0 license" /></a>
|
||||
</p>
|
||||
|
||||
- Android app: `./gradlew :androidApp:assembleDebug`
|
||||
- Desktop app:
|
||||
- Hot reload: `./gradlew :desktopApp:hotRun --auto`
|
||||
- Standard run: `./gradlew :desktopApp:run`
|
||||
- iOS app: open the [/iosApp](./iosApp) directory in Xcode and run it from there.
|
||||
VniDrop moves files and folders from one device to another without first
|
||||
uploading them to a file-hosting service. Choose what to send, decide who may
|
||||
receive it, and share a small invitation. The receiving device uses that
|
||||
invitation to find the sender and request the files.
|
||||
|
||||
### Running tests
|
||||
There is no account to create and no cloud copy of the transfer waiting after
|
||||
you are done. The sender remains in control and can stop sharing at any time.
|
||||
|
||||
Use the run button in your IDE's editor gutter, or run tests using Gradle tasks:
|
||||
## How a transfer works
|
||||
|
||||
- Android tests: `./gradlew :shared:testAndroidHostTest`
|
||||
- Desktop tests: `./gradlew :shared:jvmTest`
|
||||
- iOS tests: `./gradlew :shared:iosSimulatorArm64Test`
|
||||
1. **Choose files or a folder.** VniDrop prepares the selection on the sender's
|
||||
device and keeps the original folder structure.
|
||||
2. **Create an invitation.** The app produces a small VniDrop invitation that
|
||||
describes the transfer and how to reach the sender. Share it as a QR code, an
|
||||
NFC tag, or a `.vnd` file.
|
||||
3. **Connect to the sender.** The receiver opens the invitation. Iroh helps the
|
||||
devices find each other and establishes an authenticated, end-to-end
|
||||
encrypted connection.
|
||||
4. **Request access.** By default, the sender sees who wants the transfer and
|
||||
chooses whether to approve or refuse the request.
|
||||
5. **Stream and verify.** After access is granted, `iroh-blobs` streams the files
|
||||
and verifies their content while it arrives. VniDrop saves each file directly
|
||||
to the chosen destination without replacing an existing file.
|
||||
6. **Stay in control.** The sender can follow each receiver's progress, cancel a
|
||||
transfer, or stop sharing so the invitation can no longer be used.
|
||||
|
||||
---
|
||||
Iroh tries to connect the devices directly, including across home routers and
|
||||
mobile networks. If a direct path cannot be established, it can forward the
|
||||
same end-to-end encrypted connection through a relay. The relay forwards
|
||||
encrypted packets; it is not a VniDrop file store.
|
||||
|
||||
Learn more about [Kotlin Multiplatform](https://www.jetbrains.com/help/kotlin-multiplatform-dev/get-started.html)…
|
||||
## Why Iroh and `iroh-blobs`?
|
||||
|
||||
VniDrop combines a networking layer with its own sharing rules:
|
||||
|
||||
| Layer | What it does |
|
||||
|-------|--------------|
|
||||
| [Iroh](https://docs.iroh.computer/) | Gives each device a secure identity, helps devices find one another, creates encrypted connections, and falls back to relays when a direct path is unavailable. |
|
||||
| [`iroh-blobs`](https://docs.rs/iroh-blobs/0.103.0/iroh_blobs/) | Turns files into content-addressed, verified streams, so corrupted or unexpected data is detected while receiving. Multiple files are grouped into one collection. |
|
||||
| **VniDrop** | Adds human-friendly invitations, receiver approval, per-transfer access rules, progress, history, cancellation, and safe saving on each operating system. |
|
||||
|
||||
Content addressing is useful here because the invitation identifies exactly
|
||||
what was shared. The receiver does not simply trust a filename or claimed size:
|
||||
the incoming content must match its expected hash.
|
||||
|
||||
## Approval is part of the transfer
|
||||
|
||||
A VniDrop invitation helps two devices meet, but the default invitation is not
|
||||
automatic permission to download.
|
||||
|
||||
| Access mode | Behavior |
|
||||
|-------------|----------|
|
||||
| **Ask before each download** | The default. Every new receiver asks first, and the sender can approve or refuse the request. Approval gives that device temporary access to this transfer. |
|
||||
| **Anyone with this transfer** | No interactive approval is required. Anyone holding the invitation may receive the files until the sender stops sharing. This mode is intended only for non-sensitive items. |
|
||||
|
||||
VniDrop starts from a deny-by-default position: it serves only the content in an
|
||||
active share, and only when that receiver's access mode allows it. Unknown
|
||||
content requests are rejected.
|
||||
|
||||
Treat an invitation like a private access link. Share it only with the intended
|
||||
people, especially when using **Anyone with this transfer**.
|
||||
|
||||
## What VniDrop supports
|
||||
|
||||
- Individual files, multiple files, and complete folders
|
||||
- QR codes, NFC tags, and portable `.vnd` invitation files
|
||||
- Per-receiver requests, approvals, progress, and delivery status
|
||||
- Cancel, stop sharing, and local transfer history
|
||||
- Safe receive destinations that do not silently overwrite existing files
|
||||
- Android, iOS, and desktop apps built from a shared Compose Multiplatform UI
|
||||
- Opt-in diagnostics with transfer contents, invitations, and file paths
|
||||
excluded
|
||||
|
||||
## Privacy by design
|
||||
|
||||
- **No hosted transfer copy.** VniDrop does not upload file contents to its
|
||||
diagnostics service or a VniDrop storage bucket.
|
||||
- **Encrypted in transit.** Iroh connections are authenticated and encrypted
|
||||
end to end, including when a relay is needed.
|
||||
- **Local control.** Transfer history and sharing state stay on the device.
|
||||
- **Sensitive invitations.** An invitation can grant access, so it is
|
||||
deliberately excluded from product logs and diagnostics.
|
||||
- **Explicit access.** Approval is required by default, and stopping a share
|
||||
removes access immediately.
|
||||
|
||||
Please report suspected vulnerabilities through the private process in
|
||||
[`SECURITY.md`](SECURITY.md), not through a public issue.
|
||||
|
||||
## Project status
|
||||
|
||||
VniDrop is in early development. The transfer engine, application experience,
|
||||
and stored history format may change before a stable release. Build from source
|
||||
if you want to try the current version.
|
||||
|
||||
```bash
|
||||
git clone https://github.com/vnidrop/vnidrop.git
|
||||
cd vnidrop
|
||||
|
||||
# Desktop
|
||||
./gradlew :desktopApp:run
|
||||
|
||||
# Android debug build
|
||||
./gradlew :androidApp:assembleDebug
|
||||
|
||||
# iOS
|
||||
open iosApp/iosApp.xcodeproj
|
||||
```
|
||||
|
||||
See [`CONTRIBUTING.md`](CONTRIBUTING.md) for prerequisites, development setup,
|
||||
testing, and pull request guidance.
|
||||
|
||||
## Learn more
|
||||
|
||||
- [`crates/vnidrop/CORE_FLOW.md`](crates/vnidrop/CORE_FLOW.md) — protocol,
|
||||
approval, durability, and file-handling details
|
||||
- [`CONTRIBUTING.md`](CONTRIBUTING.md) — development and contribution guide
|
||||
- [`SECURITY.md`](SECURITY.md) — security policy and private reporting
|
||||
- [`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md) — community standards
|
||||
|
||||
## License
|
||||
|
||||
VniDrop is available under the [Apache License 2.0](LICENSE).
|
||||
|
||||
102
SECURITY.md
Normal file
102
SECURITY.md
Normal file
@@ -0,0 +1,102 @@
|
||||
# VniDrop Security Policy
|
||||
|
||||
VniDrop transfers files directly between devices and treats invitations as
|
||||
capabilities. Security reports are taken seriously, especially when they affect
|
||||
transfer authorization, file integrity, peer privacy, or the handling of local
|
||||
files.
|
||||
|
||||
## Supported Versions
|
||||
|
||||
VniDrop is currently pre-release software and does not yet have tagged stable
|
||||
releases. Security fixes are developed for the latest commit on `master`.
|
||||
|
||||
| Version | Supported |
|
||||
|---------|-----------|
|
||||
| Latest `master` | Yes |
|
||||
| Older commits and unofficial builds | No |
|
||||
|
||||
Before reporting an issue, check whether it is reproducible on the latest
|
||||
`master` when it is safe to do so. This table will be updated when versioned
|
||||
releases are published.
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
Do not disclose a suspected vulnerability, proof of concept, invitation ticket,
|
||||
private file, or sensitive log in a public issue or discussion.
|
||||
|
||||
To make a private report:
|
||||
|
||||
1. Contact a VniDrop maintainer privately using the contact information on their
|
||||
GitHub profile.
|
||||
2. If no private contact method is available, open a public issue titled
|
||||
**Security contact request**. Include no vulnerability details. A maintainer
|
||||
will arrange a private channel for the report.
|
||||
|
||||
Code of Conduct incidents should instead follow the private reporting process in
|
||||
[`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md).
|
||||
|
||||
### What to Include
|
||||
|
||||
Provide as much of the following information as you safely can:
|
||||
|
||||
- A concise description of the vulnerability and its potential impact
|
||||
- The affected commit, platform, and application version
|
||||
- Reproduction steps or a minimal proof of concept using test data
|
||||
- Required access, permissions, or user interaction
|
||||
- Relevant logs or screenshots with tickets, paths, endpoint identifiers,
|
||||
credentials, and personal data redacted
|
||||
- Any suggested mitigation or fix
|
||||
- Whether the issue has been disclosed to anyone else
|
||||
|
||||
Do not attach real user files or reusable invitation tickets. Generate isolated
|
||||
test fixtures where possible.
|
||||
|
||||
## Security-Sensitive Areas
|
||||
|
||||
Reports are especially useful when they involve:
|
||||
|
||||
- Bypassing transfer approval, access policy, or provider authorization
|
||||
- Forging, leaking, replaying, or incorrectly accepting invitation tickets
|
||||
- Serving blobs that are not registered for an active share
|
||||
- Path traversal, symlink attacks, file overwrite, or unsafe temporary-file
|
||||
publication
|
||||
- Unsafe handling of Android file descriptors, SAF permissions, or iOS
|
||||
security-scoped resources
|
||||
- Remote code execution, memory-safety failures, or denial of service caused by
|
||||
untrusted peer input
|
||||
- Exposure of file contents, local paths, tickets, endpoint identifiers,
|
||||
credentials, or other sensitive values through diagnostics or logs
|
||||
- Authentication, authorization, or data-isolation failures in the diagnostics
|
||||
service
|
||||
|
||||
The transfer protocol and file-publication invariants are documented in
|
||||
[`crates/vnidrop/CORE_FLOW.md`](crates/vnidrop/CORE_FLOW.md).
|
||||
|
||||
## Coordinated Disclosure
|
||||
|
||||
After receiving a report, maintainers will aim to:
|
||||
|
||||
1. Confirm receipt and establish a private communication channel.
|
||||
2. Reproduce and assess the issue, including affected platforms and versions.
|
||||
3. Develop and verify a fix without weakening existing security boundaries.
|
||||
4. Coordinate the release and public disclosure with the reporter.
|
||||
5. Credit the reporter if they want public acknowledgement.
|
||||
|
||||
Response and remediation times depend on severity and complexity. Please allow
|
||||
maintainers a reasonable opportunity to investigate and release a fix before
|
||||
publishing technical details.
|
||||
|
||||
## Research Guidelines
|
||||
|
||||
When investigating VniDrop:
|
||||
|
||||
- Use devices, accounts, files, and peers that you own or have permission to
|
||||
test.
|
||||
- Minimize access to personal data and stop testing if you encounter data that
|
||||
does not belong to you.
|
||||
- Avoid privacy violations, service disruption, data destruction, and testing
|
||||
that affects other users.
|
||||
- Keep vulnerability details confidential until disclosure is coordinated.
|
||||
- Follow applicable laws and the project [Code of Conduct](CODE_OF_CONDUCT.md).
|
||||
|
||||
Thank you for helping keep VniDrop and its users safe.
|
||||
@@ -2,6 +2,7 @@
|
||||
name = "vnidrop"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
license = "Apache-2.0"
|
||||
|
||||
[lib]
|
||||
name = "vnidrop"
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
"name": "vnidrop-diagnostics-api",
|
||||
"private": true,
|
||||
"version": "0.1.0",
|
||||
"license": "Apache-2.0",
|
||||
"type": "module",
|
||||
"engines": {
|
||||
"node": ">=22.12"
|
||||
|
||||
Reference in New Issue
Block a user