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.
{
"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.
{
"items": [
{
"date": "2023-01-01T00:00:00.000Z",
"content": "encrypted-content-1"
}
],
"userId": "user-id-123"
}
{
"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.
{
"status": "ok"
}
4. GET /test
Simple endpoint to test if the API is accessible.
{
"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.
Authorization: Bearer your-token-here
API key
Use a custom header for API key authentication.
X-API-Key: your-api-key-here
Configure Cryptica
To connect Cryptica to your custom API, follow these steps:
- Open Cryptica and go to Settings
- In the Database section, select Custom API as the provider
- Enter your API base URL and authentication details
- 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:
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}`);
});