Documentation

Custom API Setup

If you want to use your own backend for storing passwords, you can set up a custom API. This guide explains the requirements for creating a compatible API server.

For Advanced Users Only

Setting up a custom API requires technical knowledge in server development and security best practices. Only proceed if you're confident in your ability to create a secure API.

API Requirements

Your custom API must implement the following endpoints to be compatible with Cryptica:

Required Endpoints

1. GET /items/:key

Retrieves all passwords for the authenticated user.

Response Format
{
  "key": "activity",
  "value": {
    "items": [
      {
        "date": "2023-01-01T00:00:00.000Z",
        "content": "encrypted-content-1"
      },
      {
        "date": "2023-01-02T00:00:00.000Z",
        "content": "encrypted-content-2"
      }
    ],
    "userId": "user-id-123"
  },
  "created_at": "2023-01-01T00:00:00.000Z",
  "updated_at": "2023-01-01T00:00:00.000Z"
}
2. PUT /items/:key

Updates an existing password entry.

Request Body
{
  "items": [
    {
      "date": "2023-01-01T00:00:00.000Z",
      "content": "encrypted-content-1" 
    }
  ],
  "userId": "user-id-123"
}
Response Format
{
  "key": "activity",
  "value": {
    "items": [
      {
        "date": "2023-01-01T00:00:00.000Z",
        "content": "encrypted-content-1"
      }
    ],
    "userId": "user-id-123"
  },
    "created_at": "2023-01-01T00:00:00.000Z",
    "updated_at": "2023-01-01T00:00:00.000Z"
  }
}
3. DELETE /items/:key

Deletes a password entry.

Response Format
{
  "status": "ok"
}
4. GET /test

Simple endpoint to test if the API is accessible.

Response Format
{
  "status": "ok"
}

Authentication

Your API must implement authentication to ensure users can only access their own data. Here are some common authentication methods:

Authentication Methods

Bearer Token

Use a JWT or other token type in the Authorization header.

Header Example
Authorization: Bearer your-token-here
API key

Use a custom header for API key authentication.

Header Example
X-API-Key: your-api-key-here

Configure Cryptica

To connect Cryptica to your custom API, follow these steps:

  1. Open Cryptica and go to Settings
  2. In the Database section, select Custom API as the provider
  3. Enter your API base URL and authentication details
  4. Click Test Connection to verify everything is working

Remember to enable CORS on your API server to allow requests from the Cryptica web app.

Example Implementation

Here's a simple example of a Node.js Express server that implements the required endpoints:

Node.js + Express
const express = require('express');
const cors = require('cors');
const jwt = require('jsonwebtoken');
const app = express();
const port = 3000;
const SECRET_KEY = 'your-secret-key';

// Middleware
app.use(cors());
app.use(express.json());

// In-memory database for demonstration
let items = {};

// Authentication middleware
const authenticate = (req, res, next) => {
  const authHeader = req.headers.authorization;
  
  if (!authHeader || !authHeader.startsWith('Bearer ')) {
    return res.status(401).json({ error: 'Missing or invalid token' });
  }
  
  const token = authHeader.split(' ')[1];
  
  try {
    const decoded = jwt.verify(token, SECRET_KEY);
    req.user = decoded;
    next();
  } catch (err) {
    return res.status(401).json({ error: 'Invalid token' });
  }
};

// Test endpoint
app.get('/test', (req, res) => {
  res.json({ status: 'ok' });
});

// Get an item by key
app.get('/items/:key', authenticate, (req, res) => {
  const { key } = req.params;
  const item = items[key];
  
  if (!item) {
    return res.status(404).json({ error: 'Item not found' });
  }
  
  // Verify the item belongs to this user
  if (item.value.userId !== req.user.id) {
    return res.status(403).json({ error: 'Access denied' });
  }
  
  res.json(item);
});

// Create or update an item
app.put('/items/:key', authenticate, (req, res) => {
  const { key } = req.params;
  const value = req.body;
  
  // Ensure userId is set to the authenticated user
  value.userId = req.user.id;
  
  const item = {
    key,
    value,
    created_at: items[key]?.created_at || new Date().toISOString(),
    updated_at: new Date().toISOString()
  };
  
  items[key] = item;
  res.status(200).json(item);
});

// Delete an item
app.delete('/items/:key', authenticate, (req, res) => {
  const { key } = req.params;
  
  if (!items[key]) {
    return res.status(404).json({ error: 'Item not found' });
  }
  
  // Verify the item belongs to this user
  if (items[key].value.userId !== req.user.id) {
    return res.status(403).json({ error: 'Access denied' });
  }
  
  delete items[key];
  res.status(200).json({ status: 'ok' });
});

app.listen(port, () => {
  console.log(`API server running on port ${port}`);
});
Documentation | Cryptica