Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Review: recover-email-changes #1516

Merged
merged 1 commit into from
Aug 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
/node_modules
/public/hot
/public/storage
/public/css
/public/js
/storage/*.key
/vendor
.env
Expand Down
5 changes: 5 additions & 0 deletions app/Http/Controllers/Auth/ResetPasswordController.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\IATI\Models\User\User;
use App\Providers\RouteServiceProvider;
use Illuminate\Auth\Events\PasswordReset;
use Illuminate\Foundation\Auth\ResetsPasswords;
Expand Down Expand Up @@ -136,6 +137,10 @@ protected function resetPassword($user, $password)

$user->save();

if (!$user->email_verified_at) {
User::resendEmail($user);
}

event(new PasswordReset($user));
}
}
3 changes: 2 additions & 1 deletion app/IATI/Repositories/User/UserRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,8 @@ public function filterUsers($query, $queryParams): Builder
if (array_key_exists('q', $queryParams)) {
$query = $query->where(function ($query) use ($queryParams) {
$query->where('username', 'ilike', '%' . Arr::get($queryParams, 'q') . '%')
->orWhere('full_name', 'ilike', '%' . Arr::get($queryParams, 'q') . '%');
->orWhere('full_name', 'ilike', '%' . Arr::get($queryParams, 'q') . '%')
->orWhere('email', 'ilike', '%' . Arr::get($queryParams, 'q') . '%');
});
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

declare(strict_types=1);

use App\Constants\DBTables;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;

/*
* Change source: https://github.com/younginnovations/iatipublisher/issues/1491
*/
return new class extends Migration {
/**
* Making email field case-insensitive by:
* 1. Creating citext extension. Citext datatype makes string values case-insensitive on db level.
* 2. Change email field type to citext.
* 3. Refresh unique constraint in email field.
*
* @return void
*/
public function up(): void
{
DB::statement('CREATE EXTENSION IF NOT EXISTS citext;');

DB::statement('ALTER TABLE ' . DBTables::USERS . ' ALTER COLUMN email TYPE citext USING email::citext;');

$uniqueConstraintExists = DB::select(
"
SELECT constraint_name
FROM information_schema.table_constraints
WHERE table_name = '" . DBTables::USERS . "'
AND constraint_type = 'UNIQUE'
AND constraint_name = 'users_email_unique'"
);

if (empty($uniqueConstraintExists)) {
Schema::table(DBTables::USERS, function (Blueprint $table) {
$table->unique('email');
});
}
}

/**
* Reverse the migration.
* Basically
* 1. Drop unique constraint.
* 2. Change email field type to varchar.
* 3. Add unique constraint again.
*
* @return void
*/
public function down(): void
{
Schema::table(DBTables::USERS, function (Blueprint $table) {
$table->dropUnique('users_email_unique');
});

DB::statement('ALTER TABLE ' . DBTables::USERS . ' ALTER COLUMN email TYPE varchar USING email::varchar;');

Schema::table(DBTables::USERS, function (Blueprint $table) {
$table->unique('email');
});
}
};
15 changes: 15 additions & 0 deletions tests/Feature/AuthenticationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,19 @@ public function test_successful_login_with_email_and_password(): void

$response->assertRedirect('/activities');
}

public function test_successful_login_with_different_email_case(): void
{
$role = Role::factory()->create();
$org = Organization::factory()->has(User::factory(['role_id' => $role->id]))->create();

$uppercasedEmail = strtoupper($org->user->email);

$response = $this->post('/login', [
'emailOrUsername' => $uppercasedEmail,
'password' => encryptString('password'),
]);

$response->assertRedirect('/activities');
}
}