Merge pull request 'fix for reports' (#5) from typing into main
Reviewed-on: nmemmert/Spelling#5
This commit is contained in:
commit
75eaf88d9d
7 files changed
+210
-4
No files matched your search
+4
-1
@@ -5,5 +5,8 @@
|
||||
"Accuracy Master",
|
||||
"Practice Streak",
|
||||
"Vocabulary Pro"
|
||||
]
|
||||
],
|
||||
"admin1": [],
|
||||
"student1": [],
|
||||
"testuser": []
|
||||
}
|
||||
+3
-1
@@ -67,5 +67,7 @@
|
||||
],
|
||||
"timestamp": "2025-07-15T14:36:13.273Z"
|
||||
}
|
||||
]
|
||||
],
|
||||
"admin1": [],
|
||||
"testuser": []
|
||||
}
|
||||
@@ -13,5 +13,10 @@
|
||||
"username": "student1",
|
||||
"hash": "8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92",
|
||||
"role": "student"
|
||||
},
|
||||
{
|
||||
"username": "testuser",
|
||||
"hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||||
"role": "student"
|
||||
}
|
||||
]
|
||||
@@ -17,5 +17,17 @@
|
||||
"mouse",
|
||||
"screen",
|
||||
"printer"
|
||||
],
|
||||
"testuser": [
|
||||
"hello",
|
||||
"world",
|
||||
"test",
|
||||
"sample",
|
||||
"basic",
|
||||
"learn",
|
||||
"spell",
|
||||
"word",
|
||||
"study",
|
||||
"practice"
|
||||
]
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
@@ -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();
|
||||
Reference in new issue
Block a user