Initial version

This commit is contained in:
2025-06-15 18:40:30 -06:00
parent 78eb6e64df
commit 2f08b94c89
7 changed files with 1682 additions and 0 deletions

122
server.js Normal file
View File

@ -0,0 +1,122 @@
import express from "express";
import { EncryptedTodoService } from "./todo-service.js";
const app = express();
const todoService = new EncryptedTodoService();
app.use(express.json());
app.use(express.static("public"));
// Create user
app.post("/api/users", async (req, res) => {
try {
const { userId } = req.body;
if (!userId) {
return res.status(400).json({ error: "userId is required" });
}
const user = await todoService.createUser(userId);
res.json(user);
} catch (error) {
res.status(400).json({ error: error.message });
}
});
// Get all users (for sharing)
app.get("/api/users", async (req, res) => {
try {
const users = Array.from(todoService.users.keys());
res.json(users);
} catch (error) {
res.status(400).json({ error: error.message });
}
});
// Add todo
app.post("/api/users/:userId/todos", async (req, res) => {
try {
const { userId } = req.params;
const { text } = req.body;
if (!text) {
return res.status(400).json({ error: "Todo text is required" });
}
const todoId = await todoService.addTodo(userId, text);
res.json({ todoId });
} catch (error) {
res.status(400).json({ error: error.message });
}
});
// Get todos (decrypted)
app.get("/api/users/:userId/todos", async (req, res) => {
try {
const { userId } = req.params;
const todos = await todoService.getTodos(userId);
res.json(todos);
} catch (error) {
res.status(400).json({ error: error.message });
}
});
// Get encrypted todos
app.get("/api/users/:userId/todos/encrypted", async (req, res) => {
try {
const { userId } = req.params;
// Get the user's todo IDs
const todoIds = todoService.userTodos.get(userId) || new Set();
// Get the encrypted todos
const encryptedTodos = Array.from(todoIds)
.map((todoId) => {
const todo = todoService.todos.get(todoId);
if (!todo) return null;
return {
id: todoId,
encrypted: todo.encrypted,
createdAt: todo.createdAt,
};
})
.filter((todo) => todo !== null);
res.json(encryptedTodos);
} catch (error) {
res.status(400).json({ error: error.message });
}
});
// Delete todo
app.delete("/api/users/:userId/todos/:todoId", async (req, res) => {
try {
const { userId, todoId } = req.params;
await todoService.deleteTodo(userId, todoId);
res.json({ success: true });
} catch (error) {
res.status(400).json({ error: error.message });
}
});
// Share todo with another user
app.post("/api/users/:userId/todos/:todoId/share", async (req, res) => {
try {
const { userId, todoId } = req.params;
const { recipientId } = req.body;
if (!recipientId) {
return res.status(400).json({ error: "Recipient ID is required" });
}
await todoService.shareTodo(userId, todoId, recipientId);
res.json({ success: true });
} catch (error) {
res.status(400).json({ error: error.message });
}
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Encrypted Todo server running on port ${PORT}`);
});