fix: handle usernames case-insensitively in auth and oidc (#197)

This commit is contained in:
Daniel Volz
2026-02-14 18:43:30 +01:00
committed by GitHub
parent bb693243c1
commit 684abd7fb6
3 changed files with 43 additions and 5 deletions
+3 -3
View File
@@ -1,6 +1,6 @@
import { randomBytes } from "node:crypto";
import argon2 from "argon2";
import { eq } from "drizzle-orm";
import { eq, sql } from "drizzle-orm";
import type { FastifyInstance } from "fastify";
import { z } from "zod";
import { db } from "../db/client.js";
@@ -129,7 +129,7 @@ export async function authRoutes(app: FastifyInstance) {
const { username, password } = parsed.data;
// Check if username already exists
const [existingUser] = await db.select().from(users).where(eq(users.username, username));
const [existingUser] = await db.select().from(users).where(sql`lower(${users.username}) = lower(${username})`);
if (existingUser) {
return reply.status(409).send({ error: "Username already taken", code: "USERNAME_EXISTS" });
}
@@ -190,7 +190,7 @@ export async function authRoutes(app: FastifyInstance) {
const { username, password, rememberMe } = parsed.data;
// Find user by username
const [user] = await db.select().from(users).where(eq(users.username, username));
const [user] = await db.select().from(users).where(sql`lower(${users.username}) = lower(${username})`);
// Generic error to prevent user enumeration
const invalidCredentialsError = () =>
+2 -2
View File
@@ -1,5 +1,5 @@
import { createHash, randomBytes } from "node:crypto";
import { eq } from "drizzle-orm";
import { eq, sql } from "drizzle-orm";
import type { FastifyInstance, FastifyReply } from "fastify";
import * as client from "openid-client";
import { db } from "../db/client.js";
@@ -234,7 +234,7 @@ async function findOrCreateOIDCUser(
}
// Check if username already exists (potential collision)
const [existingByUsername] = await db.select().from(users).where(eq(users.username, username));
const [existingByUsername] = await db.select().from(users).where(sql`lower(${users.username}) = lower(${username})`);
if (existingByUsername) {
// Username collision! Check if it's a local user without OIDC linked