mirror of
https://github.com/sudosylabs/vnidrop.git
synced 2026-08-05 10:29:58 +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,
|
<h1 align="center">VniDrop</h1>
|
||||||
you need this entry point for your iOS app. This is also where you should add SwiftUI code for your project.
|
|
||||||
|
|
||||||
* [/shared](./shared/src) is for code that will be shared across your Compose Multiplatform applications.
|
<p align="center">
|
||||||
It contains several subfolders:
|
<strong>Send files directly. Stay in control of who receives them.</strong>
|
||||||
- [commonMain](./shared/src/commonMain/kotlin) is for code that’s common for all targets.
|
</p>
|
||||||
- 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.
|
|
||||||
|
|
||||||
### 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
|
<p align="center">
|
||||||
options:
|
<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`
|
VniDrop moves files and folders from one device to another without first
|
||||||
- Desktop app:
|
uploading them to a file-hosting service. Choose what to send, decide who may
|
||||||
- Hot reload: `./gradlew :desktopApp:hotRun --auto`
|
receive it, and share a small invitation. The receiving device uses that
|
||||||
- Standard run: `./gradlew :desktopApp:run`
|
invitation to find the sender and request the files.
|
||||||
- iOS app: open the [/iosApp](./iosApp) directory in Xcode and run it from there.
|
|
||||||
|
|
||||||
### 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`
|
1. **Choose files or a folder.** VniDrop prepares the selection on the sender's
|
||||||
- Desktop tests: `./gradlew :shared:jvmTest`
|
device and keeps the original folder structure.
|
||||||
- iOS tests: `./gradlew :shared:iosSimulatorArm64Test`
|
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"
|
name = "vnidrop"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
license = "Apache-2.0"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
name = "vnidrop"
|
name = "vnidrop"
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
"name": "vnidrop-diagnostics-api",
|
"name": "vnidrop-diagnostics-api",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
|
"license": "Apache-2.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=22.12"
|
"node": ">=22.12"
|
||||||
|
|||||||
Reference in New Issue
Block a user