diff --git a/crates/storage-pg/.sqlx/query-48213d718a256a12540c0aec595ca3e436be423f2d0c868700c6397745ed0455.json b/crates/storage-pg/.sqlx/query-d2a4f5c01603463b78198529d295f7f121769ea5730d01c20c0ddbcdc79a5716.json similarity index 88% rename from crates/storage-pg/.sqlx/query-48213d718a256a12540c0aec595ca3e436be423f2d0c868700c6397745ed0455.json rename to crates/storage-pg/.sqlx/query-d2a4f5c01603463b78198529d295f7f121769ea5730d01c20c0ddbcdc79a5716.json index 52c7ab0bc..171a83623 100644 --- a/crates/storage-pg/.sqlx/query-48213d718a256a12540c0aec595ca3e436be423f2d0c868700c6397745ed0455.json +++ b/crates/storage-pg/.sqlx/query-d2a4f5c01603463b78198529d295f7f121769ea5730d01c20c0ddbcdc79a5716.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n SELECT user_id\n , username\n , created_at\n , locked_at\n , deactivated_at\n , can_request_admin\n FROM users\n WHERE username = $1\n ", + "query": "\n SELECT user_id\n , username\n , created_at\n , locked_at\n , deactivated_at\n , can_request_admin\n FROM users\n WHERE LOWER(username) = LOWER($1)\n ", "describe": { "columns": [ { @@ -48,5 +48,5 @@ false ] }, - "hash": "48213d718a256a12540c0aec595ca3e436be423f2d0c868700c6397745ed0455" + "hash": "d2a4f5c01603463b78198529d295f7f121769ea5730d01c20c0ddbcdc79a5716" } diff --git a/crates/storage-pg/migrations/20250410121612_users_lower_username_idx.sql b/crates/storage-pg/migrations/20250410121612_users_lower_username_idx.sql new file mode 100644 index 000000000..625e07e1b --- /dev/null +++ b/crates/storage-pg/migrations/20250410121612_users_lower_username_idx.sql @@ -0,0 +1,10 @@ +-- no-transaction +-- Copyright 2025 New Vector Ltd. +-- +-- SPDX-License-Identifier: AGPL-3.0-only +-- Please see LICENSE in the repository root for full details. + +-- Create an index on the username column, lower-cased, so that we can lookup +-- usernames in a case-insensitive manner. +CREATE INDEX CONCURRENTLY users_lower_username_idx + ON users (LOWER(username)); diff --git a/crates/storage-pg/src/user/mod.rs b/crates/storage-pg/src/user/mod.rs index 2f5036134..abcd21ef0 100644 --- a/crates/storage-pg/src/user/mod.rs +++ b/crates/storage-pg/src/user/mod.rs @@ -175,7 +175,7 @@ impl UserRepository for PgUserRepository<'_> { , deactivated_at , can_request_admin FROM users - WHERE username = $1 + WHERE LOWER(username) = LOWER($1) "#, username, ) diff --git a/crates/storage/src/user/mod.rs b/crates/storage/src/user/mod.rs index 01feebbc4..395c6e615 100644 --- a/crates/storage/src/user/mod.rs +++ b/crates/storage/src/user/mod.rs @@ -155,7 +155,7 @@ pub trait UserRepository: Send + Sync { /// Returns [`Self::Error`] if the underlying repository fails async fn lookup(&mut self, id: Ulid) -> Result, Self::Error>; - /// Find a [`User`] by its username + /// Find a [`User`] by its username, in a case-insensitive manner /// /// Returns `None` if no [`User`] was found ///