diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..55c0122 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -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. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..58aaf30 --- /dev/null +++ b/CONTRIBUTING.md @@ -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. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/LICENSE @@ -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. diff --git a/README.md b/README.md index 49b0343..454ee63 100644 --- a/README.md +++ b/README.md @@ -1,36 +1,143 @@ -This is a Kotlin Multiplatform project targeting Android, iOS, Desktop (JVM). +

+ VniDrop app icon +

-* [/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. +

VniDrop

-* [/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. +

+ Send files directly. Stay in control of who receives them. +

-### Running the apps +

+ Cross-platform file transfer for Android, iOS, macOS, Windows, and Linux. +

-Use the run configurations provided by the run widget in your IDE's toolbar. You can also use these commands and -options: +

+ Rust core status + Shared KMP status + Early development + Apache 2.0 license +

-- 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). diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..61f77eb --- /dev/null +++ b/SECURITY.md @@ -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. diff --git a/crates/vnidrop/Cargo.toml b/crates/vnidrop/Cargo.toml index 7c1e77c..9df0499 100644 --- a/crates/vnidrop/Cargo.toml +++ b/crates/vnidrop/Cargo.toml @@ -2,6 +2,7 @@ name = "vnidrop" version = "0.1.0" edition = "2021" +license = "Apache-2.0" [lib] name = "vnidrop" diff --git a/services/diagnostics-api/package.json b/services/diagnostics-api/package.json index 91a7635..d08a7d5 100644 --- a/services/diagnostics-api/package.json +++ b/services/diagnostics-api/package.json @@ -2,6 +2,7 @@ "name": "vnidrop-diagnostics-api", "private": true, "version": "0.1.0", + "license": "Apache-2.0", "type": "module", "engines": { "node": ">=22.12"