Mercurial
annotate react_games/backend/routes/todo.ts @ 71:75de5903355c
Giagantic changes that update Dowa library to be more align with stb style array and hashmap. Updated Seobeo to be caching on server side instead of file level caching. Deleted bunch of things I don't really use.
| author | June Park <parkjune1995@gmail.com> |
|---|---|
| date | Sun, 28 Dec 2025 20:34:22 -0800 |
| parents | fb9bcd3145cb |
| children |
| rev | line source |
|---|---|
|
37
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
1 import { Router } from 'express'; |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
2 import * as fs from 'node:fs/promises'; |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
3 import path from 'node:path'; |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
4 import crypto from 'node:crypto'; |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
5 |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
6 type Todo = { id: string; value: string; status: number }; |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
7 |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
8 /** Idk aynthing about encryption but this seemed fine to me so just going to use this... **/ |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
9 const ALGO = 'aes-256-gcm'; |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
10 const KEYLEN = 32; |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
11 const IVLEN = 12; |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
12 const SALTLEN = 16; |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
13 const PEPPER = process.env.TODO_PEPPER ?? ''; // optional server-side secret |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
14 |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
15 type EncryptedPayload = { |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
16 v: 1; |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
17 kdf: 'scrypt'; |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
18 salt: string; // base64 |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
19 iv: string; // base64 |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
20 tag: string; // base64 |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
21 ciphertext: string;// base64 |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
22 }; |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
23 |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
24 // ---- crypto helpers -------------------------------------------------------- |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
25 |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
26 function kdf(passphrase: string, salt: Buffer): Buffer { |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
27 // scryptSync is fine for small payloads; use async/promisified if you prefer. |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
28 return crypto.scryptSync(passphrase, salt, KEYLEN); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
29 } |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
30 |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
31 function encryptJSON(data: unknown, keyword: string): EncryptedPayload { |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
32 const salt = crypto.randomBytes(SALTLEN); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
33 const key = kdf(keyword + PEPPER, salt); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
34 const iv = crypto.randomBytes(IVLEN); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
35 |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
36 const cipher = crypto.createCipheriv(ALGO, key, iv); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
37 const plaintext = Buffer.from(JSON.stringify(data), 'utf8'); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
38 const ciphertext = Buffer.concat([cipher.update(plaintext), cipher.final()]); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
39 const tag = cipher.getAuthTag(); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
40 |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
41 return { |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
42 v: 1, |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
43 kdf: 'scrypt', |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
44 salt: salt.toString('base64'), |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
45 iv: iv.toString('base64'), |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
46 tag: tag.toString('base64'), |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
47 ciphertext: ciphertext.toString('base64'), |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
48 }; |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
49 } |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
50 |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
51 function decryptJSON(payload: EncryptedPayload, keyword: string): any { |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
52 const salt = Buffer.from(payload.salt, 'base64'); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
53 const iv = Buffer.from(payload.iv, 'base64'); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
54 const tag = Buffer.from(payload.tag, 'base64'); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
55 const ciphertext = Buffer.from(payload.ciphertext, 'base64'); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
56 |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
57 const key = kdf(keyword + PEPPER, salt); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
58 const decipher = crypto.createDecipheriv(ALGO, key, iv); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
59 decipher.setAuthTag(tag); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
60 |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
61 const plaintext = Buffer.concat([decipher.update(ciphertext), decipher.final()]); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
62 return JSON.parse(plaintext.toString('utf8')); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
63 } |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
64 |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
65 // ---- path helper: derive a file path from keyword -------------------------- |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
66 |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
67 function pathForKeyword(baseDir: string, keyword: string): string { |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
68 // Hash the keyword so you don’t leak it in the filename and to avoid FS-unsafe chars. |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
69 const h = crypto.createHash('sha256').update(keyword, 'utf8').digest('hex'); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
70 // Optional sharding to keep directories small: |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
71 return path.join(baseDir, h.slice(0, 2), `${h}.json`); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
72 } |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
73 |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
74 // ---- router ---------------------------------------------------------------- |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
75 const getInitialTodos = () => [ |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
76 { |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
77 id: crypto.randomUUID(), |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
78 value: "Hello from TODO", |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
79 status: 0, |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
80 } |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
81 ] |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
82 export function createTodoRouter(dataFileOrDir: string) { |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
83 const router = Router(); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
84 |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
85 // Support both a file path (old) or a directory (new). We’ll store under that directory. |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
86 const baseDir = path.extname(dataFileOrDir) |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
87 ? path.dirname(dataFileOrDir) |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
88 : dataFileOrDir; |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
89 |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
90 const requireKeyword = (req: any): string => { |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
91 const key = (typeof req.query.key === 'string' && req.query.key) || req.header('x-keyword'); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
92 if (typeof key !== 'string' || !key.trim()) { |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
93 throw Object.assign(new Error('Missing ?key= query or x-keyword header'), { status: 400 }); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
94 } |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
95 return key.trim(); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
96 }; |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
97 |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
98 const readTodos = async (userKeyword: string): Promise<Todo[]> => { |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
99 const filePath = pathForKeyword(baseDir, userKeyword); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
100 try { |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
101 const raw = await fs.readFile(filePath, 'utf8'); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
102 const parsed = JSON.parse(raw); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
103 |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
104 // If this looks like an encrypted payload, decrypt; else treat as plaintext array for backward compat. |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
105 if (parsed && parsed.ciphertext && parsed.iv && parsed.tag && parsed.salt) { |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
106 return decryptJSON(parsed as EncryptedPayload, userKeyword) as Todo[]; |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
107 } |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
108 // fallback (legacy plaintext) |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
109 return parsed as Todo[]; |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
110 } catch (e: any) { |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
111 if (e?.code === 'ENOENT') { |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
112 const initial = getInitialTodos(); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
113 await writeTodos(initial, userKeyword); // create the file immediately |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
114 return initial; |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
115 } |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
116 throw e; |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
117 } |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
118 }; |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
119 |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
120 const writeTodos = async (todos: Todo[], userKeyword: string) => { |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
121 const filePath = pathForKeyword(baseDir, userKeyword); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
122 await fs.mkdir(path.dirname(filePath), { recursive: true }); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
123 const payload = encryptJSON(todos, userKeyword); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
124 await fs.writeFile(filePath, JSON.stringify(payload, null, 2), { encoding: 'utf8', mode: 0o600 }); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
125 }; |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
126 |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
127 router.get('/', async (req, res) => { |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
128 try { |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
129 const keyword = requireKeyword(req); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
130 const todos = await readTodos(keyword); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
131 res.json({ todos }); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
132 } catch (err: any) { |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
133 res.status(err?.status || 500).json({ error: err?.message || 'Internal error' }); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
134 } |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
135 }); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
136 |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
137 router.post('/', async (req, res) => { |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
138 try { |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
139 const keyword = requireKeyword(req); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
140 |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
141 const body = req.body?.newTodo; |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
142 if (!body || typeof body.value !== 'string' || typeof body.status !== 'number') { |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
143 return res.status(400).json({ newTodo: null }); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
144 } |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
145 |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
146 const todos = await readTodos(keyword); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
147 const todo: Todo = { |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
148 id: body.id ?? crypto.randomUUID(), |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
149 value: body.value, |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
150 status: body.status, |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
151 }; |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
152 todos.push(todo); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
153 |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
154 // Optional chaos test: |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
155 // await new Promise(r => setTimeout(r, 1000)); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
156 // if (Math.random() > 0.5) return res.status(400).json({ newTodo: null }); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
157 |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
158 await writeTodos(todos, keyword); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
159 res.status(200).json({ newTodo: todo, todos }); // keep your shape if you prefer |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
160 } catch (err: any) { |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
161 res.status(err?.status || 500).json({ error: err?.message || 'Internal error' }); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
162 } |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
163 }); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
164 |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
165 router.patch('/', async (req, res) => { |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
166 try { |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
167 const keyword = requireKeyword(req); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
168 |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
169 const body = req.body; |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
170 if (!body || typeof body.todoId !== 'string' || typeof body.status !== 'number') { |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
171 return res.status(400).json({ newTodo: null }); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
172 } |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
173 |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
174 const todos = (await readTodos(keyword)).map( |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
175 (todo) => todo.id === body.todoId ? {...todo, status: body.status } : todo); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
176 |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
177 await writeTodos(todos, keyword); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
178 res.status(200).json({ todos }); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
179 } catch (err: any) { |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
180 res.status(err?.status || 500).json({ error: err?.message || 'Internal error' }); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
181 } |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
182 }); |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
183 |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
184 |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
185 return router; |
|
fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
186 } |