From 6bbf0afbabc08790557cc7eab76aa4b2cc98f860 Mon Sep 17 00:00:00 2001 From: "nate@necloud.us" Date: Fri, 18 Jul 2025 08:16:30 -0400 Subject: [PATCH] fix for reports --- data/badges.json | 5 ++- data/results.json | 4 +- data/users.json | 5 +++ data/wordlists.json | 12 ++++++ server.js | 89 ++++++++++++++++++++++++++++++++++++++++++- test_add_user.js | 37 ++++++++++++++++++ test_new_user_init.js | 62 ++++++++++++++++++++++++++++++ 7 files changed, 210 insertions(+), 4 deletions(-) create mode 100644 test_add_user.js create mode 100644 test_new_user_init.js diff --git a/data/badges.json b/data/badges.json index 7ede664..3cd8b9f 100644 --- a/data/badges.json +++ b/data/badges.json @@ -5,5 +5,8 @@ "Accuracy Master", "Practice Streak", "Vocabulary Pro" - ] + ], + "admin1": [], + "student1": [], + "testuser": [] } \ No newline at end of file diff --git a/data/results.json b/data/results.json index 5a1f230..9d68fe3 100644 --- a/data/results.json +++ b/data/results.json @@ -67,5 +67,7 @@ ], "timestamp": "2025-07-15T14:36:13.273Z" } - ] + ], + "admin1": [], + "testuser": [] } \ No newline at end of file diff --git a/data/users.json b/data/users.json index ff8b016..6016be7 100644 --- a/data/users.json +++ b/data/users.json @@ -13,5 +13,10 @@ "username": "student1", "hash": "8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92", "role": "student" + }, + { + "username": "testuser", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "role": "student" } ] \ No newline at end of file diff --git a/data/wordlists.json b/data/wordlists.json index fa05c1a..78d247e 100644 --- a/data/wordlists.json +++ b/data/wordlists.json @@ -17,5 +17,17 @@ "mouse", "screen", "printer" + ], + "testuser": [ + "hello", + "world", + "test", + "sample", + "basic", + "learn", + "spell", + "word", + "study", + "practice" ] } \ No newline at end of file diff --git a/server.js b/server.js index dc109f8..2ca5886 100644 --- a/server.js +++ b/server.js @@ -89,6 +89,30 @@ for (const [key, file] of Object.entries(files)) { ensureFileWithSeed(file, defaultData); } +// 🔄 Initialize existing users in all data files +function initializeAllExistingUsers() { + console.log('🔄 Checking all users are initialized...'); + const users = readJsonSafe(path.join(DATA_DIR, files.users), []); + + users.forEach(user => { + // Check if user exists in all data files + const wordlists = readJsonSafe(path.join(DATA_DIR, files.wordlists), {}); + const results = readJsonSafe(path.join(DATA_DIR, files.results), {}); + const badges = readJsonSafe(path.join(DATA_DIR, files.badges), {}); + + const needsInit = !wordlists[user.username] || !results[user.username] || !badges[user.username]; + + if (needsInit) { + console.log(`🔧 User "${user.username}" needs initialization`); + initializeUserInAllFiles(user.username); + } + }); + console.log('✅ All users initialized'); +} + +// Initialize all existing users +initializeAllExistingUsers(); + // 🔐 JSON utility function readJsonSafe(filePath, fallback = {}) { try { @@ -98,6 +122,41 @@ function readJsonSafe(filePath, fallback = {}) { } } +// 🔧 Initialize user across all data files +function initializeUserInAllFiles(username) { + console.log(`🔧 Initializing user "${username}" across all data files`); + + // Initialize in wordlists.json + const wordlistsPath = path.join(DATA_DIR, files.wordlists); + const wordlists = readJsonSafe(wordlistsPath, {}); + if (!wordlists[username]) { + wordlists[username] = [ + "hello", "world", "test", "sample", "basic", + "learn", "spell", "word", "study", "practice" + ]; + fs.writeFileSync(wordlistsPath, JSON.stringify(wordlists, null, 2)); + console.log(`📝 Added default word list for "${username}"`); + } + + // Initialize in results.json + const resultsPath = path.join(DATA_DIR, files.results); + const results = readJsonSafe(resultsPath, {}); + if (!results[username]) { + results[username] = []; + fs.writeFileSync(resultsPath, JSON.stringify(results, null, 2)); + console.log(`📊 Added results tracking for "${username}"`); + } + + // Initialize in badges.json + const badgesPath = path.join(DATA_DIR, files.badges); + const badges = readJsonSafe(badgesPath, {}); + if (!badges[username]) { + badges[username] = []; + fs.writeFileSync(badgesPath, JSON.stringify(badges, null, 2)); + console.log(`🏆 Added badge tracking for "${username}"`); + } +} + // 🔐 Verify login app.post('/verifyUser', (req, res) => { const { username, hash } = req.body; @@ -136,9 +195,15 @@ app.post('/addUser', (req, res) => { if (users.find(u => u.username === username)) { return res.status(409).send("User already exists"); } + + // Add user to users.json users.push({ username: username.trim(), hash, role: role.trim() }); fs.writeFileSync(path.join(DATA_DIR, files.users), JSON.stringify(users, null, 2)); - res.send(`✅ User "${username}" added`); + + // Initialize user in all other data files + initializeUserInAllFiles(username.trim()); + + res.send(`✅ User "${username}" added and initialized`); }); // ❌ Delete user @@ -153,8 +218,28 @@ app.post('/deleteUser', (req, res) => { if (users.length === updated.length) { return res.status(404).send("User not found"); } + + // Remove from users.json fs.writeFileSync(usersPath, JSON.stringify(updated, null, 2)); - res.send(`✅ User "${username}" deleted`); + + // Clean up from other data files + const wordlistsPath = path.join(DATA_DIR, files.wordlists); + const wordlists = readJsonSafe(wordlistsPath, {}); + delete wordlists[username]; + fs.writeFileSync(wordlistsPath, JSON.stringify(wordlists, null, 2)); + + const resultsPath = path.join(DATA_DIR, files.results); + const results = readJsonSafe(resultsPath, {}); + delete results[username]; + fs.writeFileSync(resultsPath, JSON.stringify(results, null, 2)); + + const badgesPath = path.join(DATA_DIR, files.badges); + const badges = readJsonSafe(badgesPath, {}); + delete badges[username]; + fs.writeFileSync(badgesPath, JSON.stringify(badges, null, 2)); + + console.log(`🗑️ Cleaned up all data for user "${username}"`); + res.send(`✅ User "${username}" deleted and cleaned up`); }); // 🔐 Change user password diff --git a/test_add_user.js b/test_add_user.js new file mode 100644 index 0000000..b60d3c1 --- /dev/null +++ b/test_add_user.js @@ -0,0 +1,37 @@ +const http = require('http'); + +const postData = JSON.stringify({ + username: 'testuser', + hash: 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', // empty string hash + role: 'student' +}); + +const options = { + hostname: 'localhost', + port: 3000, + path: '/addUser', + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Content-Length': Buffer.byteLength(postData) + } +}; + +const req = http.request(options, (res) => { + console.log(`Status: ${res.statusCode}`); + console.log(`Headers: ${JSON.stringify(res.headers)}`); + res.setEncoding('utf8'); + res.on('data', (chunk) => { + console.log(`Body: ${chunk}`); + }); + res.on('end', () => { + console.log('No more data in response.'); + }); +}); + +req.on('error', (e) => { + console.error(`Problem with request: ${e.message}`); +}); + +req.write(postData); +req.end(); diff --git a/test_new_user_init.js b/test_new_user_init.js new file mode 100644 index 0000000..2f12791 --- /dev/null +++ b/test_new_user_init.js @@ -0,0 +1,62 @@ +const http = require('http'); + +// Test adding a new user +const postData = JSON.stringify({ + username: 'teststudent', + hash: 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', // empty string hash + role: 'student' +}); + +const options = { + hostname: 'localhost', + port: 3000, + path: '/addUser', + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Content-Length': Buffer.byteLength(postData) + } +}; + +console.log('Testing new user addition and initialization...'); + +const req = http.request(options, (res) => { + console.log(`✅ Add User Status: ${res.statusCode}`); + res.setEncoding('utf8'); + res.on('data', (chunk) => { + console.log(`📝 Response: ${chunk}`); + }); + res.on('end', () => { + console.log('🔄 Now testing if user data is properly initialized...'); + + // Test getting word list for new user + const wordListReq = http.request({ + hostname: 'localhost', + port: 3000, + path: '/getWordList?username=teststudent', + method: 'GET' + }, (res) => { + console.log(`📚 Word List Status: ${res.statusCode}`); + res.setEncoding('utf8'); + res.on('data', (chunk) => { + console.log(`📝 Word List Data: ${chunk}`); + }); + res.on('end', () => { + console.log('✅ Test completed - New user properly initialized!'); + }); + }); + + wordListReq.on('error', (e) => { + console.error(`❌ Word List Error: ${e.message}`); + }); + + wordListReq.end(); + }); +}); + +req.on('error', (e) => { + console.error(`❌ Add User Error: ${e.message}`); +}); + +req.write(postData); +req.end();