AI Assistance Disclosure
AI tools were used to assist with wording and structure of this proposal. All technical content, architectural decisions, and implementation plans reflect my own understanding of the codebase gained through direct study of the relevant files.
About me
My name is Anurag, a Computer Science undergraduate from India. My primary stack is TypeScript, React, React Native, and Electron — Joplin's exact tech surface across desktop and mobile.
I've shipped production applications end-to-end including a Next.js financial calculator and a multi-agent AI travel planning app with a custom backend. I'm comfortable navigating large codebases and working independently under deadlines.
GitHub: Anurag-M1 (Anurag Singh) · GitHub
Contributions to Joplin so far:
laurent22/joplin#14845 — Fix "Leave notebook" disabled when notebook isn't currently open (all CI checks passing, awaiting review)
Problem
Joplin provides excellent E2EE during sync, but all notes are immediately accessible on the local device. A user who shares a device, stores medical records, private journals, or sensitive financial data has no way to lock individual notes behind a password. This is a well-documented gap in the forum and issue tracker.
Project goals
Implement per-note password-based local encryption independent from sync E2EE
Provide a clean UI on both desktop (Electron/React) and mobile (React Native)
Encrypt note body and attached resources using AES-256-GCM via Web Crypto API
Optionally extend to notebook-level encryption as a stretch goal
Write unit tests throughout the coding period, not at the end
Implementation
Encryption primitives:
AES-256-GCM via the Web Crypto API, already available in both Electron and React Native — no new native dependencies. Key derivation via PBKDF2 with 100,000 iterations and SHA-256. This mirrors the approach already used in crypto.ts which I've studied in depth.
Storage:
Add is_locally_encrypted boolean flag to the Note model. Store ciphertext in place of body. Salt and IV stored alongside the ciphertext. Resources (attachments) linked to the note encrypted separately using the same derived key.
Desktop UI (Electron + React):
"Encrypt note" context menu item
Password entry dialog with confirmation field
Locked note view with password prompt
Session-level key caching in memory so the user doesn't re-enter every time
Mobile UI (React Native):
Same flow adapted for mobile screen sizes
Biometric unlock as stretch goal via expo-local-authentication.
Sync compatibility:
Encrypted notes sync as ciphertext. Other devices can only decrypt with the correct password entered there too. Fully independent from sync E2EE — both can coexist without conflict.
Testing:
Unit tests will be written throughout each coding week, not deferred to the end. Tests will cover encrypt/decrypt round trips, wrong password rejection, tampered ciphertext detection, and session key caching behaviour.
Timeline
WeekDeliverable1–2Deep study of Note.ts, EncryptionService.ts, MasterKey.ts. Draft encryption schema. Post architecture for mentor review before writing code.3–4Core LocalEncryptionService.ts — encrypt/decrypt/key derivation using Web Crypto. Full unit test suite for this service.5–6Desktop UI: context menu item, password dialog, locked note view component. Integration with note open/save flow.7–8Mobile UI: React Native password prompt and locked note screen.9–10Resource (attachment) encryption. Session key caching. Edge case handling (empty notes, very large notes, concurrent edits).11Notebook-level encryption (stretch goal). Password change/rotation flow.12Documentation, polish, final test suite review, PR ready for merge.
Availability: I can commit 35–40 hours per week for the full GSoC period. I have no exams or travel conflicts during the coding phase. I will communicate with my mentor multiple times per week and post weekly progress updates on the forum.
Other commitments: None. GSoC will be my primary focus during this period.
About me
I am comfortable working independently with a remote mentor. English is my working language. I am submitting proposals to Joplin only.
Prior to GSoC, I have contributed to Joplin's codebase directly — studying crypto.ts, EncryptionService.ts, MasterKey.ts, and stateToWhenClauseContext.ts in depth and submitting a bug fix PR that passed all CI checks.
References available on request.
Open questions for mentors
Is AES-256-GCM via Web Crypto preferred, or does the team prefer libsodium?
Should the password be strictly per-note, or notebook-scoped?
Is session-level key caching in memory acceptable from a security standpoint?
This is a living draft. I will update it based on mentor feedback before March 31.