{"id":51837362,"url":"https://github.com/yunusey/obsidian-proton-integration","last_synced_at":"2026-07-23T00:03:28.398Z","repository":{"id":366040889,"uuid":"1272539414","full_name":"yunusey/obsidian-proton-integration","owner":"yunusey","description":"The bridge between Obsidian and Proton Drive.","archived":false,"fork":false,"pushed_at":"2026-06-20T01:20:05.000Z","size":103,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-20T03:13:56.179Z","etag":null,"topics":["obsidian","obsidian-plugin","protondrive"],"latest_commit_sha":null,"homepage":"https://community.obsidian.md/plugins/proton-integration","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yunusey.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-17T17:53:41.000Z","updated_at":"2026-06-20T01:39:07.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/yunusey/obsidian-proton-integration","commit_stats":null,"previous_names":["yunusey/obsidian-proton-integration"],"tags_count":1,"template":false,"template_full_name":"obsidianmd/obsidian-sample-plugin","purl":"pkg:github/yunusey/obsidian-proton-integration","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yunusey%2Fobsidian-proton-integration","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yunusey%2Fobsidian-proton-integration/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yunusey%2Fobsidian-proton-integration/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yunusey%2Fobsidian-proton-integration/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yunusey","download_url":"https://codeload.github.com/yunusey/obsidian-proton-integration/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yunusey%2Fobsidian-proton-integration/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35782275,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-07-20T02:08:10.276Z","status":"online","status_checked_at":"2026-07-22T02:00:06.236Z","response_time":124,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["obsidian","obsidian-plugin","protondrive"],"created_at":"2026-07-23T00:03:25.947Z","updated_at":"2026-07-23T00:03:28.394Z","avatar_url":"https://github.com/yunusey.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Proton Drive Integration\n\nBridge between [Obsidian](https://obsidian.md) and [Proton Drive](https://proton.me/drive), built on the official [`@protontech/drive-sdk`](https://www.npmjs.com/package/@protontech/drive-sdk). This is an independent project and is **not affiliated with, endorsed by, or sponsored by Proton AG** or any of its products.\n\n## Status\n\nEarly foundation: browser sign-in, optional session persistence, and Proton drive link embeds in reading view.\n\n\u003e [!CAUTION]\n\u003e The Proton Drive SDK is still evolving and does not yet ship standalone auth. This plugin implements the same auth/API wiring pattern used by the [official Drive CLI](https://github.com/ProtonDriveApps/sdk/tree/main/js/cli).\n\n## Requirements\n\n- Obsidian desktop or mobile\n- A Proton account\n\n## Development\n\n```bash\nnpm install\nnpm run dev\nnpm run build\nnpm run typecheck\n```\n\nCopy `main.js`, `manifest.json`, and `styles.css` into your vault's `.obsidian/plugins/obsidian-proton-integration/` folder (or symlink the repo).\n\n## Usage\n\n1. Open **Settings → Obsidian Proton Integration** and click **Sign in**, or run **Sign in to proton drive** from the command palette.\n2. Complete sign-in in your browser when prompted.\n3. Embed Proton files in reading view (see below).\n\nSupported embed types: **images**, **videos**, and **documents** (PDF inline preview, plain text, and markdown).\n\n### Node UID links (recommended)\n\nThe plugin supports **`proton-drive:///` links** -- a stable embed format based on Proton’s canonical node UID (`volumeId~nodeId`), not the share ID in a browser URL.\n\n**Why prefer these over `drive.proton.me` links?**\n\n- **Stable:** the UID identifies the file in storage; it does not depend on share context (`shareId`) from the web app.\n- **Works for Photos:** library items often have no copyable web URL; UID links are the supported way to embed them.\n- **Aligned with the SDK:** Proton’s web URLs (`.../shareId/file/nodeId`) are legacy; resolving them uses deprecated SDK APIs (`getNodeUid`) that exist only for backward compatibility with the old web app.\n\n**How to add one**\n\n1. Run **Insert proton drive embed from node uid** from the command palette, paste a UID (`volumeId~nodeId`), and insert the embed; or\n2. Paste a link directly in a note:\n\n```markdown\n![](proton-drive:///volumeId~nodeId)\n```\n\nThe plugin URL-encodes the UID in the path (for example, `~` becomes `%7E`).\n\nWorks for files in **My files** and the **Photos** library (your own volumes).\n\n### Web share links (legacy)\n\nYou can still embed My files items copied from the browser:\n\n```markdown\n![](https://drive.proton.me/.../shareId/file/nodeId)\n```\n\nThese rely on deprecated share-ID resolution in the SDK and may break as Proton moves to volume-based navigation. They do **not** work for Photos library items. Prefer **`proton-drive:///`** links when you can.\n\n### Privacy and local storage\n\n- **Keep credentials in memory only:** sign-in data is not written to Obsidian plugin storage; you sign in again after each Obsidian restart. Because Proton is known for its stance \"Privacy by default\", this is the default behavior.\n\n    If you would like your session to persist across Obsidian sessions, you can disable this option. However, please keep in mind that doing so will write your credentials to `.obsidian/plugins/obsidian-proton-integration/data.json`, unencrypted. **Do not share this file, and do not add it to version control.**\n\n- **Client UID:** the plugin also stores a random `protonClientUid` in `data.json`. This is required by the Proton Drive SDK to identify this Obsidian installation (for upload/sync state on Proton's side). It is not a credential, is not tied to your Proton identity, and is always persisted, even when \"Keep credentials in memory only\" is enabled. If you are not using session persistence, `data.json` contains only this UID. You can safely share it or add it to version control. Deleting it will cause a new one to be generated on next launch.\n\n## Architecture\n\n```\nsrc/\n  main.ts                 Plugin entry, sign-in, embed registration\n  embed/                  Proton drive link embeds (reading view)\n  settings.ts             Settings tab\n  plugin-storage.ts       Credential + client UID persistence\n  proton/\n    drive-service.ts      ProtonDriveClient lifecycle\n    crypto.ts             @protontech/crypto initialization\n    credentials.ts        Session state\n    api/                  Auth + HTTP layer (SDK prerequisites)\n```\n\nThe SDK handles encrypted drive operations once `ProtonDriveClient` is constructed with:\n\n- `httpClient` — authenticated requests to `drive-api.proton.me`\n- `account` — user keys/addresses for decryption\n- `openPGPCryptoModule` — crypto via `@protontech/crypto`\n- `srpModule` — SRP auth helpers\n- `entitiesCache` / `cryptoCache` — in-memory caches (SQLite later)\n\n## Proton SDK guidelines\n\nThis plugin identifies itself to Proton APIs as:\n\n`external-drive-obsidian_integration@0.1.0-stable`\n\nPer [Proton's SDK usage guidelines](https://github.com/ProtonDriveApps/sdk#usage-guidelines-for-personal-projects), third-party apps must not use Proton branding and must disclose that credentials are entered into an unofficial application.\n\n## AI disclosure\n\nThis project has used AI tools during development, and this section explains how.\n\nDuring the early foundation stage, [Cursor](https://cursor.com) (Pro) was used to move quickly and explore implementations. Each change was reviewed manually to the best of my ability before landing. Going forward, the focus shifts toward slower, smaller changes; I expect the project's own stability to improve as a result.\n\nThat said, stability also depends on upstream: the Proton Drive SDK is still evolving and can change without much notice. This plugin cannot promise a stable or backwards-compatible experience anytime soon, regardless of how carefully changes are reviewed here.\n\nFor pull requests, I review every change myself first. After that, I also run [GitHub Copilot](https://github.com/features/copilot) code review on the PR. Those review comments are public on GitHub. I rely on this extra pass mainly because I am the sole maintainer of the project for now.\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyunusey%2Fobsidian-proton-integration","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyunusey%2Fobsidian-proton-integration","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyunusey%2Fobsidian-proton-integration/lists"}