mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-06-21 14:21:46 +00:00
fix(auth): trim username and email on all write paths
Self-registration stored values verbatim, so trailing whitespace could produce rows that lookup code (which trims input) silently misses. Trim username and email before validation and INSERT in registerUser, adminService.updateUser, and oidcService.findOrCreateUser. updateSettings and adminService.createUser already trimmed correctly. Adds a one-shot backfill migration (trimUserWhitespace) that trims existing dirty rows; collisions are resolved by appending __migrated_<id> to the value with a loud console.warn so operators can review affected accounts. 18 new tests covering registration trim, duplicate detection, admin update trim, trip-member lookup regression, and all migration branches.
This commit is contained in:
@@ -218,6 +218,54 @@ describe('Registration', () => {
|
||||
});
|
||||
});
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// Registration — whitespace normalization
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
describe('Registration — whitespace normalization', () => {
|
||||
it('AUTH-REG-TRIM-1 — username with surrounding whitespace is trimmed before storage', async () => {
|
||||
const res = await request(app).post('/api/auth/register').send({
|
||||
username: ' trimmeduser ',
|
||||
email: 'trimmed@example.com',
|
||||
password: 'Str0ng!Pass',
|
||||
});
|
||||
expect(res.status).toBe(201);
|
||||
const row = testDb.prepare('SELECT username FROM users WHERE email = ?').get('trimmed@example.com') as { username: string };
|
||||
expect(row.username).toBe('trimmeduser');
|
||||
});
|
||||
|
||||
it('AUTH-REG-TRIM-2 — email with surrounding whitespace is trimmed before storage', async () => {
|
||||
const res = await request(app).post('/api/auth/register').send({
|
||||
username: 'emailtrimuser',
|
||||
email: ' emailtrim@example.com ',
|
||||
password: 'Str0ng!Pass',
|
||||
});
|
||||
expect(res.status).toBe(201);
|
||||
const row = testDb.prepare('SELECT email FROM users WHERE username = ?').get('emailtrimuser') as { email: string };
|
||||
expect(row.email).toBe('emailtrim@example.com');
|
||||
});
|
||||
|
||||
it('AUTH-REG-TRIM-3 — whitespace-padded username that trims to existing username returns 409', async () => {
|
||||
createUser(testDb, { username: 'alice', email: 'alice@example.com' });
|
||||
const res = await request(app).post('/api/auth/register').send({
|
||||
username: ' alice ',
|
||||
email: 'alice2@example.com',
|
||||
password: 'Str0ng!Pass',
|
||||
});
|
||||
expect(res.status).toBe(409);
|
||||
});
|
||||
|
||||
it('AUTH-REG-TRIM-4 — whitespace-padded email that trims to existing email returns 409', async () => {
|
||||
createUser(testDb, { username: 'bob', email: 'bob@example.com' });
|
||||
const res = await request(app).post('/api/auth/register').send({
|
||||
username: 'bob2',
|
||||
email: ' bob@example.com ',
|
||||
password: 'Str0ng!Pass',
|
||||
});
|
||||
expect(res.status).toBe(409);
|
||||
});
|
||||
});
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// Session / Me
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user