Merge pull request 'fix for reports' (#5) from typing into main

Reviewed-on: nmemmert/Spelling#5
This commit is contained in:
nmemmert committed 2025-07-18 12:17:39 +00:00
commit 75eaf88d9d
7 files changed
+210 -4

No files matched your search

+4 -1
View File
@@ -5,5 +5,8 @@
"Accuracy Master",
"Practice Streak",
"Vocabulary Pro"
]
],
"admin1": [],
"student1": [],
"testuser": []
}
+3 -1
View File
@@ -67,5 +67,7 @@
],
"timestamp": "2025-07-15T14:36:13.273Z"
}
]
],
"admin1": [],
"testuser": []
}
+5
View File
@@ -13,5 +13,10 @@
"username": "student1",
"hash": "8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92",
"role": "student"
},
{
"username": "testuser",
"hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"role": "student"
}
]
+12
View File
@@ -17,5 +17,17 @@
"mouse",
"screen",
"printer"
],
"testuser": [
"hello",
"world",
"test",
"sample",
"basic",
"learn",
"spell",
"word",
"study",
"practice"
]
}
+87 -2
View File
@@ -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
+37
View File
@@ -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();
+62
View File
@@ -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();