diff --git a/coderd/database/databasefake/databasefake.go b/coderd/database/databasefake/databasefake.go index f0cdee99f2..839633f7f8 100644 --- a/coderd/database/databasefake/databasefake.go +++ b/coderd/database/databasefake/databasefake.go @@ -311,7 +311,7 @@ func (q *fakeQuerier) GetUserByEmailOrUsername(_ context.Context, arg database.G defer q.mutex.RUnlock() for _, user := range q.users { - if (user.Email == arg.Email || user.Username == arg.Username) && user.Deleted == arg.Deleted { + if (strings.EqualFold(user.Email, arg.Email) || strings.EqualFold(user.Username, arg.Username)) && user.Deleted == arg.Deleted { return user, nil } } diff --git a/coderd/database/dump.sql b/coderd/database/dump.sql index 6bf0961b37..9413e0822d 100644 --- a/coderd/database/dump.sql +++ b/coderd/database/dump.sql @@ -532,6 +532,8 @@ CREATE UNIQUE INDEX idx_users_username ON users USING btree (username) WHERE (de CREATE UNIQUE INDEX templates_organization_id_name_idx ON templates USING btree (organization_id, lower((name)::text)) WHERE (deleted = false); +CREATE UNIQUE INDEX users_email_lower_idx ON users USING btree (lower(email)) WHERE (deleted = false); + CREATE UNIQUE INDEX users_username_lower_idx ON users USING btree (lower(username)) WHERE (deleted = false); CREATE UNIQUE INDEX workspaces_owner_id_lower_idx ON workspaces USING btree (owner_id, lower((name)::text)) WHERE (deleted = false); diff --git a/coderd/database/migrations/000054_email_case.down.sql b/coderd/database/migrations/000054_email_case.down.sql new file mode 100644 index 0000000000..e69de29bb2 diff --git a/coderd/database/migrations/000054_email_case.up.sql b/coderd/database/migrations/000054_email_case.up.sql new file mode 100644 index 0000000000..90a80e550a --- /dev/null +++ b/coderd/database/migrations/000054_email_case.up.sql @@ -0,0 +1 @@ +CREATE UNIQUE INDEX IF NOT EXISTS users_email_lower_idx ON users USING btree (lower(email)) WHERE (deleted = false); diff --git a/coderd/database/queries.sql.go b/coderd/database/queries.sql.go index ae7b420a05..669a9d2e07 100644 --- a/coderd/database/queries.sql.go +++ b/coderd/database/queries.sql.go @@ -3071,7 +3071,7 @@ SELECT FROM users WHERE - (LOWER(username) = LOWER($1) OR email = $2) + (LOWER(username) = LOWER($1) OR LOWER(email) = LOWER($2)) AND deleted = $3 LIMIT 1 diff --git a/coderd/database/queries/users.sql b/coderd/database/queries/users.sql index fd47afa1a1..8f29e8a8d2 100644 --- a/coderd/database/queries/users.sql +++ b/coderd/database/queries/users.sql @@ -17,7 +17,7 @@ SELECT FROM users WHERE - (LOWER(username) = LOWER(@username) OR email = @email) + (LOWER(username) = LOWER(@username) OR LOWER(email) = LOWER(@email)) AND deleted = @deleted LIMIT 1; diff --git a/coderd/database/unique_constraint.go b/coderd/database/unique_constraint.go index d3b38a8161..e0f8dfb9cd 100644 --- a/coderd/database/unique_constraint.go +++ b/coderd/database/unique_constraint.go @@ -20,6 +20,7 @@ const ( UniqueIndexUsersEmail UniqueConstraint = "idx_users_email" // CREATE UNIQUE INDEX idx_users_email ON users USING btree (email) WHERE (deleted = false); UniqueIndexUsersUsername UniqueConstraint = "idx_users_username" // CREATE UNIQUE INDEX idx_users_username ON users USING btree (username) WHERE (deleted = false); UniqueTemplatesOrganizationIDNameIndex UniqueConstraint = "templates_organization_id_name_idx" // CREATE UNIQUE INDEX templates_organization_id_name_idx ON templates USING btree (organization_id, lower((name)::text)) WHERE (deleted = false); + UniqueUsersEmailLowerIndex UniqueConstraint = "users_email_lower_idx" // CREATE UNIQUE INDEX users_email_lower_idx ON users USING btree (lower(email)) WHERE (deleted = false); UniqueUsersUsernameLowerIndex UniqueConstraint = "users_username_lower_idx" // CREATE UNIQUE INDEX users_username_lower_idx ON users USING btree (lower(username)) WHERE (deleted = false); UniqueWorkspacesOwnerIDLowerIndex UniqueConstraint = "workspaces_owner_id_lower_idx" // CREATE UNIQUE INDEX workspaces_owner_id_lower_idx ON workspaces USING btree (owner_id, lower((name)::text)) WHERE (deleted = false); ) diff --git a/coderd/users_test.go b/coderd/users_test.go index 6477b69113..e6c8d5da26 100644 --- a/coderd/users_test.go +++ b/coderd/users_test.go @@ -256,11 +256,19 @@ func TestPostLogin(t *testing.T) { } _, err := client.CreateFirstUser(ctx, req) require.NoError(t, err) + _, err = client.LoginWithPassword(ctx, codersdk.LoginWithPasswordRequest{ Email: req.Email, Password: req.Password, }) require.NoError(t, err) + + // Login should be case insensitive + _, err = client.LoginWithPassword(ctx, codersdk.LoginWithPasswordRequest{ + Email: strings.ToUpper(req.Email), + Password: req.Password, + }) + require.NoError(t, err) }) t.Run("Lifetime&Expire", func(t *testing.T) {