This commit is contained in:
AtHeartEngineer
2025-07-22 01:33:29 -04:00
parent 25b4195c0b
commit a717b7a0b1
4 changed files with 39 additions and 11 deletions

View File

@@ -5,6 +5,13 @@ import bodyParser from 'body-parser';
import { WebSocketServer } from 'ws';
import { lobbiesRouter } from '../../api/lobbies';
import { readDB, writeDB } from '../../db/db';
import jwt from 'jsonwebtoken';
// JWT helper for tests
const JWT_SECRET = process.env.JWT_SECRET || 'supersecretkeylkj3lfgdklvadsvi2rsdfh';
const generateTestToken = (username: string, isSuper = false) => {
return jwt.sign({ username, isSuper }, JWT_SECRET);
};
// Mock WebSocket server
const mockWss = {
@@ -28,10 +35,13 @@ describe('Lobbies API', () => {
describe('POST /api/lobbies', () => {
it('should create a new lobby successfully', async () => {
const response = await request(app).post('/api/lobbies').send({
name: 'Test Lobby',
owner: 'testuser'
});
const token = generateTestToken('testuser');
const response = await request(app)
.post('/api/lobbies')
.set('Authorization', `Bearer ${token}`)
.send({
name: 'Test Lobby'
});
expect(response.status).toBe(201);
expect(response.body).toHaveProperty('id');

View File

@@ -25,7 +25,11 @@ describe('Users API', () => {
});
expect(response.status).toBe(201);
expect(response.body).toEqual({ username: 'testuser', isSuper: false });
expect(response.body).toEqual({
username: 'testuser',
isSuper: false,
token: expect.any(String)
});
// Verify user was saved to database
const db = await readDB();
@@ -93,7 +97,11 @@ describe('Users API', () => {
});
expect(response.status).toBe(200);
expect(response.body).toEqual({ username: 'testuser', isSuper: false });
expect(response.body).toEqual({
username: 'testuser',
isSuper: false,
token: expect.any(String)
});
});
it('should return 400 for invalid username', async () => {

View File

@@ -55,7 +55,10 @@ router.post('/register', async (req, res) => {
};
db.users.push(newUser);
await writeDB(db);
res.status(201).json({ username, isSuper: false });
// Generate and return JWT token for immediate login
const token = generateToken(newUser);
res.status(201).json({ username, isSuper: false, token });
});
router.post('/login', async (req, res) => {

View File

@@ -104,12 +104,15 @@ export const AuthProvider: React.FC<AuthProviderProps> = ({ children }) => {
}
}
// On mount: sync subscription if user and permission granted
// On mount: restore user and token, sync subscription if user and permission granted
useEffect(() => {
const savedUser = localStorage.getItem('user')
if (savedUser) {
const savedToken = localStorage.getItem('token')
if (savedUser && savedToken) {
const userData = JSON.parse(savedUser)
setUser(userData)
setToken(savedToken)
tokenRef.current = savedToken
if (Notification.permission === 'granted') {
setNotificationsEnabled(true)
syncPushSubscriptionWithBackend(userData)
@@ -180,10 +183,14 @@ export const AuthProvider: React.FC<AuthProviderProps> = ({ children }) => {
try {
setIsLoading(true)
const response = await axios.post('/api/users/register', { username, password })
// Registration does not return a token, so require login after
const userData = response.data
// Registration now returns a token for immediate login
const { username: uname, isSuper, token: jwt } = response.data
const userData = { username: uname, isSuper }
setUser(userData)
setToken(jwt)
tokenRef.current = jwt
localStorage.setItem('user', JSON.stringify(userData))
localStorage.setItem('token', jwt)
setTimeout(async () => {
if (Notification.permission === 'granted') {
setNotificationsEnabled(true)