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

feat: Resend Code Verification Time #1147

Draft
wants to merge 28 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
75d3b2c
add class property $resendCodeVerification
warcooft Jul 17, 2024
4e031c9
update: sending email verification every 60 seconds
warcooft Jul 17, 2024
79eff58
add remaining time info
warcooft Jul 17, 2024
58d2f2d
add translation for remainingTime
warcooft Jul 17, 2024
de2ce69
add lang[en] for remainingTime
warcooft Jul 17, 2024
e417839
fix: some errors occurred
warcooft Jul 18, 2024
987b78a
fix: respect coding standards
warcooft Jul 18, 2024
af64d1e
lang: add temp lang [remainingTime]
warcooft Jul 18, 2024
5ae1e55
lang: add temp lang [remainingTime]
warcooft Jul 18, 2024
1ff731e
lang: add temp lang [remainingTime]
warcooft Jul 18, 2024
44b12ae
lang: add temp lang [remainingTime]
warcooft Jul 18, 2024
e39f7c8
lang: add temp lang [remainingTime]
warcooft Jul 18, 2024
3d69d09
lang: add temp lang [remainingTime]
warcooft Jul 18, 2024
ee8b3e6
lang: add temp lang [remainingTime]
warcooft Jul 18, 2024
b893f13
lang: add temp lang [remainingTime]
warcooft Jul 18, 2024
d5e7ba8
lang: add temp lang [remainingTime]
warcooft Jul 18, 2024
c863986
lang: add temp lang [remainingTime]
warcooft Jul 18, 2024
cfeaf55
lang: add temp lang [remainingTime]
warcooft Jul 18, 2024
71f81f6
lang: add temp lang [remainingTime]
warcooft Jul 18, 2024
d673f90
lang: add temp lang [remainingTime]
warcooft Jul 18, 2024
b0eaddc
lang: add temp lang [remainingTime]
warcooft Jul 18, 2024
1d45530
lang: add temp lang [remainingTime]
warcooft Jul 18, 2024
8051e86
lang: add temp lang [remainingTime]
warcooft Jul 18, 2024
cf77b82
lang: add temp lang [remainingTime]
warcooft Jul 18, 2024
8c86bca
lang: add temp lang [remainingTime]
warcooft Jul 18, 2024
5499476
lang: add temp lang [remainingTime]
warcooft Jul 18, 2024
8aeca80
lang: add temp lang [remainingTime]
warcooft Jul 18, 2024
4a49a82
update the model
warcooft Jul 18, 2024
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
74 changes: 47 additions & 27 deletions src/Authentication/Actions/EmailActivator.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,36 +54,56 @@
);
}

$code = $this->createIdentity($user);

/** @var IncomingRequest $request */
$request = service('request');

$ipAddress = $request->getIPAddress();
$userAgent = (string) $request->getUserAgent();
$date = Time::now()->toDateTimeString();

// Send the email
helper('email');
$email = emailer(['mailType' => 'html'])
->setFrom(setting('Email.fromEmail'), setting('Email.fromName') ?? '');
$email->setTo($userEmail);
$email->setSubject(lang('Auth.emailActivateSubject'));
$email->setMessage($this->view(
setting('Auth.views')['action_email_activate_email'],
['code' => $code, 'user' => $user, 'ipAddress' => $ipAddress, 'userAgent' => $userAgent, 'date' => $date],
['debug' => false]
));

if ($email->send(false) === false) {
throw new RuntimeException('Cannot send email for user: ' . $user->email . "\n" . $email->printDebugger(['headers']));
}
$userIdentities = $user->identities;
$userIdentity = array_pop($userIdentities);

$now = new Time('now');
$identityCreated = Time::parse($userIdentity->created_at);

$timDiff = $identityCreated->difference($now);

$configRCV = setting('Auth.resendCodeVerification');

$resendCodeVerificationTime = ((int) $configRCV - $timDiff->getSeconds());

if ($timDiff->getSeconds() >= (int) $configRCV || $userIdentity->secret2 === null) {
$code = $this->createIdentity($user);

// Clear the email
$email->clear();
/** @var IncomingRequest $request */
$request = service('request');

$ipAddress = $request->getIPAddress();
$userAgent = (string) $request->getUserAgent();
$date = Time::now()->toDateTimeString();

// Send the email
helper('email');
$email = emailer(['mailType' => 'html'])
->setFrom(setting('Email.fromEmail'), setting('Email.fromName') ?? '');
$email->setTo($userEmail);
$email->setSubject(lang('Auth.emailActivateSubject'));
$email->setMessage($this->view(
setting('Auth.views')['action_email_activate_email'],
['code' => $code, 'user' => $user, 'ipAddress' => $ipAddress, 'userAgent' => $userAgent, 'date' => $date],
['debug' => false]
));

if ($email->send(false) === false) {
throw new RuntimeException('Cannot send email for user: ' . $user->email . "\n" . $email->printDebugger(['headers']));
}

/** @var UserIdentityModel $identityModel */
model(UserIdentityModel::class)

Check failure on line 96 in src/Authentication/Actions/EmailActivator.php

View workflow job for this annotation

GitHub Actions / phpstan / PHP 7.4 Static Analysis

Ignored error pattern #^Call to function model with CodeIgniter\\Shield\\Models\\UserIdentityModel\:\:class is discouraged\.$# in path /home/runner/work/shield/shield/src/Authentication/Actions/EmailActivator.php is expected to occur 2 times, but occurred 3 times.

Check failure on line 96 in src/Authentication/Actions/EmailActivator.php

View workflow job for this annotation

GitHub Actions / phpstan / PHP 7.4 Static Analysis

Variable $identityModel in PHPDoc tag @var does not exist.

Check failure on line 96 in src/Authentication/Actions/EmailActivator.php

View workflow job for this annotation

GitHub Actions / phpstan / PHP 8.1 Static Analysis

Ignored error pattern #^Call to function model with CodeIgniter\\Shield\\Models\\UserIdentityModel\:\:class is discouraged\.$# in path /home/runner/work/shield/shield/src/Authentication/Actions/EmailActivator.php is expected to occur 2 times, but occurred 3 times.

Check failure on line 96 in src/Authentication/Actions/EmailActivator.php

View workflow job for this annotation

GitHub Actions / phpstan / PHP 8.1 Static Analysis

Variable $identityModel in PHPDoc tag @var does not exist.

Check failure on line 96 in src/Authentication/Actions/EmailActivator.php

View workflow job for this annotation

GitHub Actions / phpstan / PHP 8.0 Static Analysis

Ignored error pattern #^Call to function model with CodeIgniter\\Shield\\Models\\UserIdentityModel\:\:class is discouraged\.$# in path /home/runner/work/shield/shield/src/Authentication/Actions/EmailActivator.php is expected to occur 2 times, but occurred 3 times.

Check failure on line 96 in src/Authentication/Actions/EmailActivator.php

View workflow job for this annotation

GitHub Actions / phpstan / PHP 8.0 Static Analysis

Variable $identityModel in PHPDoc tag @var does not exist.

Check failure on line 96 in src/Authentication/Actions/EmailActivator.php

View workflow job for this annotation

GitHub Actions / phpstan / PHP 8.2 Static Analysis

Ignored error pattern #^Call to function model with CodeIgniter\\Shield\\Models\\UserIdentityModel\:\:class is discouraged\.$# in path /home/runner/work/shield/shield/src/Authentication/Actions/EmailActivator.php is expected to occur 2 times, but occurred 3 times.

Check failure on line 96 in src/Authentication/Actions/EmailActivator.php

View workflow job for this annotation

GitHub Actions / phpstan / PHP 8.2 Static Analysis

Variable $identityModel in PHPDoc tag @var does not exist.

Check failure on line 96 in src/Authentication/Actions/EmailActivator.php

View workflow job for this annotation

GitHub Actions / phpstan / PHP 8.3 Static Analysis

Ignored error pattern #^Call to function model with CodeIgniter\\Shield\\Models\\UserIdentityModel\:\:class is discouraged\.$# in path /home/runner/work/shield/shield/src/Authentication/Actions/EmailActivator.php is expected to occur 2 times, but occurred 3 times.

Check failure on line 96 in src/Authentication/Actions/EmailActivator.php

View workflow job for this annotation

GitHub Actions / phpstan / PHP 8.3 Static Analysis

Variable $identityModel in PHPDoc tag @var does not exist.
->where('secret', $code)
->set(['secret2' => 'SEND'])
->update();

// Clear the email
$email->clear();
}

// Display the info page
return $this->view(setting('Auth.views')['action_email_activate_show'], ['user' => $user]);
return $this->view(setting('Auth.views')['action_email_activate_show'], ['user' => $user, 'remainingTime' => $resendCodeVerificationTime]);
}

/**
Expand Down Expand Up @@ -165,7 +185,7 @@
private function getIdentity(User $user): ?UserIdentity
{
/** @var UserIdentityModel $identityModel */
$identityModel = model(UserIdentityModel::class);

Check failure on line 188 in src/Authentication/Actions/EmailActivator.php

View workflow job for this annotation

GitHub Actions / phpstan / PHP 7.4 Static Analysis

Call to function model with CodeIgniter\Shield\Models\UserIdentityModel::class is discouraged.

Check failure on line 188 in src/Authentication/Actions/EmailActivator.php

View workflow job for this annotation

GitHub Actions / phpstan / PHP 8.1 Static Analysis

Call to function model with CodeIgniter\Shield\Models\UserIdentityModel::class is discouraged.

Check failure on line 188 in src/Authentication/Actions/EmailActivator.php

View workflow job for this annotation

GitHub Actions / phpstan / PHP 8.0 Static Analysis

Call to function model with CodeIgniter\Shield\Models\UserIdentityModel::class is discouraged.

Check failure on line 188 in src/Authentication/Actions/EmailActivator.php

View workflow job for this annotation

GitHub Actions / phpstan / PHP 8.2 Static Analysis

Call to function model with CodeIgniter\Shield\Models\UserIdentityModel::class is discouraged.

Check failure on line 188 in src/Authentication/Actions/EmailActivator.php

View workflow job for this annotation

GitHub Actions / phpstan / PHP 8.3 Static Analysis

Call to function model with CodeIgniter\Shield\Models\UserIdentityModel::class is discouraged.

return $identityModel->getIdentityByType(
$user,
Expand Down
9 changes: 9 additions & 0 deletions src/Config/Auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,15 @@ class Auth extends BaseConfig
*/
public int $magicLinkLifetime = HOUR;

/**
* --------------------------------------------------------------------
* Resend Code Verification Time for re-new the code and send it again
* --------------------------------------------------------------------
* Specify in integer how many seconds of delay time you want to
* re-new the code and send it from email. The default is 60 seconds.
*/
public int $resendCodeVerification = 60;

/**
* --------------------------------------------------------------------
* Session Authenticator Configuration
Expand Down
1 change: 1 addition & 0 deletions src/Language/ar/Auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
'invalidActivateToken' => 'الرمز غير صحيح',
'needActivate' => 'يجب عليك إكمال تسجيل حسابك عن طريق تأكيد الرمز المرسل إلى عنوان بريدك الإلكتروني.',
'activationBlocked' => 'يجب عليك تفعيل حسابك قبل تسجيل الدخول.',
'remainingTime' => '(To be translated) You can receive a new code in {0, number} seconds.',

// Groups
'unknownGroup' => '{0} ليست مجموعة صالحة.',
Expand Down
1 change: 1 addition & 0 deletions src/Language/bg/Auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
'invalidActivateToken' => 'Кода е невалиден.',
'needActivate' => 'Трябва да завършите регистрацията си, като потвърдите кода, изпратен на вашия имейл адрес.',
'activationBlocked' => 'Трябва да активирате акаунта си, преди да влезете.',
'remainingTime' => '(To be translated) You can receive a new code in {0, number} seconds.',

// Групи
'unknownGroup' => '{0} не е валидна група.',
Expand Down
1 change: 1 addition & 0 deletions src/Language/cs/Auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
'invalidActivateToken' => 'Kód byl nesprávný',
'needActivate' => 'Registraci musíte dokončit potvrzením kódu zaslaného na vaši e-mailovou adresu.',
'activationBlocked' => 'Před přihlášením musíte svůj účet aktivovat.',
'remainingTime' => '(To be translated) You can receive a new code in {0, number} seconds.',

// Groups
'unknownGroup' => '{0} není platná skupina.',
Expand Down
1 change: 1 addition & 0 deletions src/Language/de/Auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
'invalidActivateToken' => 'Der Code war falsch.',
'needActivate' => 'Sie müssen Ihre Anmeldung abschließen, indem Sie den an Ihre E-Mail-Adresse gesendeten Code bestätigen.',
'activationBlocked' => 'Bevor Sie sich anmelden können muss das Konto aktiviert werden.',
'remainingTime' => '(To be translated) You can receive a new code in {0, number} seconds.',

// Groups
'unknownGroup' => '{0} ist eine ungültige Gruppe.',
Expand Down
1 change: 1 addition & 0 deletions src/Language/en/Auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
'invalidActivateToken' => 'The code was incorrect.',
'needActivate' => 'You must complete your registration by confirming the code sent to your email address.',
'activationBlocked' => 'You must activate your account before logging in.',
'remainingTime' => 'You can receive a new code in {0, number} seconds.',

// Groups
'unknownGroup' => '{0} is not a valid group.',
Expand Down
1 change: 1 addition & 0 deletions src/Language/es/Auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
'invalidActivateToken' => 'El código era incorrecto.',
'needActivate' => 'Debes completar tu registro confirmando el código enviado a tu dirección de correo electrónico.',
'activationBlocked' => 'Debes activar tu cuenta antes de iniciar sesión.',
'remainingTime' => '(To be translated) You can receive a new code in {0, number} seconds.',

// Grupos
'unknownGroup' => '{0} no es un grupo válido.',
Expand Down
1 change: 1 addition & 0 deletions src/Language/fa/Auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
'invalidActivateToken' => 'کد صحیح نمی باشد.',
'needActivate' => 'شما باید با ارائه کد ارسال شده به ایمیلتان، ثبت نام را تکمیل کنید.',
'activationBlocked' => 'قبل از تلاش برای ورود، باید اکانت خود را فعال کنید.',
'remainingTime' => '(To be translated) You can receive a new code in {0, number} seconds.',

// Groups
'unknownGroup' => '{0} گروهی معتبر نیست.',
Expand Down
1 change: 1 addition & 0 deletions src/Language/fr/Auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
'invalidActivateToken' => 'Le code était incorrect.',
'needActivate' => 'Complétez votre inscription en confirmant le code envoyé à votre email.',
'activationBlocked' => 'Vous devez activer votre compte avant de vous connecter.',
'remainingTime' => '(To be translated) You can receive a new code in {0, number} seconds.',

// Groups
'unknownGroup' => '{0} n\'est pas un groupe valide.',
Expand Down
1 change: 1 addition & 0 deletions src/Language/id/Auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
'invalidActivateToken' => 'Kode tidak sesuai.',
'needActivate' => 'Anda harus menyelesaikan registrasi Anda dengan mengonfirmasi kode yang dikirim ke alamat email Anda.',
'activationBlocked' => 'Anda harus mengaktifkan akun Anda sebelum masuk.',
'remainingTime' => 'Anda dapat menerima kode baru dalam {0, number} detik lagi.',

// Groups
'unknownGroup' => '{0} bukan grup yang sah.',
Expand Down
1 change: 1 addition & 0 deletions src/Language/it/Auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
'invalidActivateToken' => 'Il codice era sbagliato.',
'needActivate' => 'Devi completare la registrazione confermando il codice inviato al tuo indrizzo email.',
'activationBlocked' => '(to be translated) You must activate your account before logging in.',
'remainingTime' => '(To be translated) You can receive a new code in {0, number} seconds.',

// Groups
'unknownGroup' => '{0} non è un gruppo valido.',
Expand Down
1 change: 1 addition & 0 deletions src/Language/ja/Auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
'invalidActivateToken' => 'コードが間違っています。', // 'The code was incorrect.'
'needActivate' => 'メールアドレスに送信されたコードを確認し、登録を完了する必要があります。', // 'You must complete your registration by confirming the code sent to your email address.'
'activationBlocked' => 'ログインする前にアカウントを有効化する必要があります。', // 'You must activate your account before logging in.'
'remainingTime' => '(To be translated) You can receive a new code in {0, number} seconds.',

// Groups
'unknownGroup' => '{0} は有効なグループではありません。', // '{0} is not a valid group.'
Expand Down
1 change: 1 addition & 0 deletions src/Language/lt/Auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
'invalidActivateToken' => 'Kodas buvo neteisingas.',
'needActivate' => 'Turite baigti registraciją panaudodami kodą, išsiųstą Jums el. pašto adresu.',
'activationBlocked' => 'Prieš prisijungdami turite aktyvuoti paskyrą.',
'remainingTime' => '(To be translated) You can receive a new code in {0, number} seconds.',

// Groups
'unknownGroup' => '{0} nėra egzistuojanti grupė.',
Expand Down
1 change: 1 addition & 0 deletions src/Language/nl/Auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
'invalidActivateToken' => 'De code was niet correct.',
'needActivate' => 'Je moet je registratie voltooien door de code te bevestigen die naar je e-mailadres is gestuurd.',
'activationBlocked' => 'Je moet je account activeren voordat je kunt inloggen.',
'remainingTime' => '(To be translated) You can receive a new code in {0, number} seconds.',

// Groups
'unknownGroup' => '{0} is geen geldige groep.',
Expand Down
1 change: 1 addition & 0 deletions src/Language/pl/Auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
'invalidActivateToken' => 'Kod był nieprawidłowy.',
'needActivate' => 'Musisz zakończyć rejestrację, potwierdzając kod wysłany na adres e-mail.',
'activationBlocked' => 'Musisz aktywować swoje konto przed zalogowaniem się.',
'remainingTime' => '(To be translated) You can receive a new code in {0, number} seconds.',

// Groups
'unknownGroup' => '{0} nie jest ważną grupą.',
Expand Down
1 change: 1 addition & 0 deletions src/Language/pt-BR/Auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
'invalidActivateToken' => 'O código estava incorreto.',
'needActivate' => 'Você deve concluir seu registro confirmando o código enviado para seu endereço de e-mail.',
'activationBlocked' => 'Você deve ativar sua conta antes de fazer o login.',
'remainingTime' => '(To be translated) You can receive a new code in {0, number} seconds.',

// Grupos
'unknownGroup' => '{0} não é um grupo válido.',
Expand Down
1 change: 1 addition & 0 deletions src/Language/pt/Auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
'invalidActivateToken' => 'O código estava incorreto.',
'needActivate' => 'Deve concluir seu registro confirmando o código enviado para seu endereço de e-mail.',
'activationBlocked' => 'Deve ativar sua conta antes de fazer o login.',
'remainingTime' => '(To be translated) You can receive a new code in {0, number} seconds.',

// Grupos
'unknownGroup' => '{0} não é um grupo válido.',
Expand Down
1 change: 1 addition & 0 deletions src/Language/ru/Auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
'invalidActivateToken' => 'Код неверный.',
'needActivate' => 'Вы должны завершить регистрацию, подтвердив код, отправленный на ваш адрес электронной почты.',
'activationBlocked' => 'Вы должны активировать свою учетную запись перед входом в систему.',
'remainingTime' => '(To be translated) You can receive a new code in {0, number} seconds.',

// Groups
'unknownGroup' => '{0} не является действительной группой.',
Expand Down
1 change: 1 addition & 0 deletions src/Language/sk/Auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
'invalidActivateToken' => 'Kód bol nesprávny',
'needActivate' => 'Registráciu musíte dokončiť potvrdením kódu zaslaného na vašu e-mailovú adresu.',
'activationBlocked' => 'Pred prihlásením si musíte aktivovať svoj účet.',
'remainingTime' => '(To be translated) You can receive a new code in {0, number} seconds.',

// Groups
'unknownGroup' => '{0} nie je platná skupina.',
Expand Down
1 change: 1 addition & 0 deletions src/Language/sr/Auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
'invalidActivateToken' => 'Kod nije ispravan.',
'needActivate' => 'Morate dovršiti registraciju potvrdom koda poslatog na vašu email adresu.',
'activationBlocked' => 'Morate aktivirati vaš nalog pre pristupanja sistemu.',
'remainingTime' => '(To be translated) You can receive a new code in {0, number} seconds.',

// Groups
'unknownGroup' => '{0} neispravna grupa.',
Expand Down
1 change: 1 addition & 0 deletions src/Language/sv-SE/Auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
'invalidActivateToken' => 'Koden var fel.',
'needActivate' => 'Du måste slutföra registreringen genom att ange aktiveringskoden som skickats till din epostadress.',
'activationBlocked' => 'Du måste aktivera ditt konto innan du kan logga in.',
'remainingTime' => '(To be translated) You can receive a new code in {0, number} seconds.',

// Groups
'unknownGroup' => '{0} är inte en giltig grupp.',
Expand Down
1 change: 1 addition & 0 deletions src/Language/tr/Auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
'invalidActivateToken' => 'Kod yanlıştı.',
'needActivate' => 'E-posta adresinize gönderilen kodu onaylayarak kaydınızı tamamlamanız gerekmektedir.',
'activationBlocked' => 'Giriş yapmadan önce hesabınızı etkinleştirmeniz gerekmektedir.',
'remainingTime' => '(To be translated) You can receive a new code in {0, number} seconds.',

// Groups
'unknownGroup' => '{0} geçerli bir grup değil.',
Expand Down
1 change: 1 addition & 0 deletions src/Language/uk/Auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
'invalidActivateToken' => 'Код був невірний.',
'needActivate' => 'Ви повинні завершити реєстрацію, підтвердивши код, надісланий на вашу електронну адресу.',
'activationBlocked' => 'Ви повинні активувати свій обліковий запис перед входом.',
'remainingTime' => '(To be translated) You can receive a new code in {0, number} seconds.',

// Groups
'unknownGroup' => '{0} недійсна група.',
Expand Down
2 changes: 2 additions & 0 deletions src/Views/email_activate_show.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
<button type="submit" class="btn btn-primary btn-block"><?= lang('Auth.send') ?></button>
</div>

<p><?= lang('Auth.remainingTime', [$remainingTime]) ?></p>

</form>
</div>
</div>
Expand Down
Loading