Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions Notesnook.Inbox.API/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Notesnook Inbox API

## Running locally

### Requirements

- Bun (v1.0.0 or higher)

### Environment variables

- `PORT`
- `NOTESNOOK_API_SERVER_URL`

### Commands

- `bun install` - Install dependencies
- `bun run dev` - Start the development server
- `bun run build` - Build the project for production
- `bun run start` - Start the production server

## Self-hosting

...

Comment on lines +21 to +24
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not really sure how to write this section, @thecodrr could you guide?

## Writing from scratch

The inbox API server is pretty simple to write from scratch in any programming language and/or framework. There's only one endpoint that needs to be implemented, which does these three steps:

1. Fetch the user's public inbox API key from the Notesnook API.
2. Encrypt the payload (via libsodium).
3. Post the encrypted payload to the Notesnook API.

You can refer to the [source code](./src/index.ts) for implementation details.
19 changes: 18 additions & 1 deletion Notesnook.Inbox.API/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,20 @@ interface EncryptedInboxItem {
salt: string;
}

/**
* Encrypts raw data using a hybrid encryption scheme combining symmetric and asymmetric cryptography.
*
* The encryption process follows these steps:
* - Generate a random symmetric password using XChaCha20-Poly1305-IETF key generation
* - Generate a random salt for key derivation
* - Derive an encryption key from the password using Argon2i13
* - Generate a random nonce (IV) for the symmetric encryption
* - Encrypt the data using XChaCha20-Poly1305-IETF with the derived key
* - Encrypt the derived key using the recipient's public key (X25519 sealed box)
*
* @param {string} rawData - The plaintext data to encrypt
* @param {string} publicKey - The recipient's X25519 public key encoded in base64 URL-safe format without padding.
*/
function encrypt(rawData: string, publicKey: string): EncryptedInboxItem {
try {
const password = sodium.crypto_aead_xchacha20poly1305_ietf_keygen();
Expand Down Expand Up @@ -133,7 +147,10 @@ app.use(
limit: 60,
})
);
app.post("/inbox", async (req, res) => {
app.get("/health", (_, res) => {
return res.status(200).json({ status: "ok" });
});
app.post("/", async (req, res) => {
try {
const apiKey = req.headers["authorization"];
if (!apiKey) {
Expand Down