Skip to content

Commit

Permalink
srp ok
Browse files Browse the repository at this point in the history
  • Loading branch information
asika32764 committed Nov 17, 2023
1 parent 75b60e9 commit 796def1
Show file tree
Hide file tree
Showing 8 changed files with 152 additions and 63 deletions.
52 changes: 33 additions & 19 deletions assets/dist/srp.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion assets/dist/srp.js.map

Large diffs are not rendered by default.

60 changes: 39 additions & 21 deletions assets/src/js/srp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class SRPRegistration {
verifierInput: HTMLInputElement;

public submitting = false;
public disabledInputs = [];

constructor(public el: HTMLFormElement, public options: Partial<SRPOptions> = {}) {
this.options = Object.assign({}, defaultOptions, this.options);
Expand Down Expand Up @@ -51,25 +52,34 @@ class SRPRegistration {
});

this.el.addEventListener('invalid', () => {
this.submitting = false;
this.release();
}, true);
}

disablePasswords() {
if (this.passwordInput.value) {
this.passwordInput.disabled = true;
release() {
this.submitting = false;

setTimeout(() => {
this.passwordInput.disabled = false;
}, 1000);
for (const disabledInput of this.disabledInputs) {
disabledInput.disabled = false;
}
}

const inputs = this.el.querySelectorAll<HTMLInputElement>('[data-srp-override]');
getPasswordInputs() {
return [
this.passwordInput,
...this.el.querySelectorAll<HTMLInputElement>('[data-srp-override]')
];
}

disablePasswords() {
this.disabledInputs = [];

for (const input of inputs) {
if (input.value) {
for (const input of this.getPasswordInputs()) {
if (input.value && !input.disabled) {
input.disabled = true;

this.disabledInputs.push(input);

setTimeout(() => {
input.disabled = false;
}, 1000);
Expand Down Expand Up @@ -132,6 +142,8 @@ class SRPLogin {
public submitting = false;
public submitter: HTMLButtonElement;

public disabledInputs = [];

constructor(public el: HTMLFormElement, public options: Partial<SRPOptions> = {}) {
this.options = Object.assign({}, defaultOptions, this.options);

Expand Down Expand Up @@ -184,6 +196,11 @@ class SRPLogin {

this.submitting = false;
this.fallback = false;
this.getHiddenInput('srp[M2]').value = '';

for (const disabledInput of this.disabledInputs) {
disabledInput.disabled = false;
}
}

async auth() {
Expand Down Expand Up @@ -261,21 +278,22 @@ class SRPLogin {
this.getHiddenInput('srp[M2]').value = M2.toString(16);
}

disablePasswords() {
if (this.passwordInput.value) {
this.passwordInput.disabled = true;

setTimeout(() => {
this.passwordInput.disabled = false;
}, 1000);
}
getPasswordInputs() {
return [
this.passwordInput,
...this.el.querySelectorAll<HTMLInputElement>('[data-srp-override]')
];
}

const inputs = this.el.querySelectorAll<HTMLInputElement>('[data-srp-override]');
disablePasswords() {
this.disabledInputs = [];

for (const input of inputs) {
if (input.value) {
for (const input of this.getPasswordInputs()) {
if (input.value && !input.disabled) {
input.disabled = true;

this.disabledInputs.push(input);

setTimeout(() => {
input.disabled = false;
}, 1000);
Expand Down
9 changes: 7 additions & 2 deletions src/Auth/SRP/SRPService.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Lyrasoft\Luna\Auth\SRP;

use Brick\Math\BigInteger;
use Lyrasoft\Luna\Entity\User;
use Lyrasoft\Luna\Script\SRPScript;
use Windwalker\Core\Application\AppContext;
use Windwalker\Core\Application\ApplicationInterface;
Expand Down Expand Up @@ -79,7 +80,7 @@ public function loginDirective(array $options = []): string
return HTMLElement::buildAttributes(['uni-srp-login' => json_encode($options)]);
}

public function handleRegister(AppContext $app, array $user): array
public function handleRegister(AppContext $app, array|User $user): array|User
{
if (!$this->isEnabled()) {
return $user;
Expand All @@ -89,7 +90,11 @@ public function handleRegister(AppContext $app, array $user): array

$password = static::encodePasswordVerifier($srp['salt'], $srp['verifier']);

$user['password'] = $password;
if ($user instanceof User) {
$user->setPassword($password);
} else {
$user['password'] = $password;
}

return $user;
}
Expand Down
31 changes: 24 additions & 7 deletions src/Module/Front/Auth/ForgetController.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use Lyrasoft\Luna\Auth\SRP\SRPService;
use Lyrasoft\Luna\Entity\User;
use Lyrasoft\Luna\User\UserService;
use Windwalker\Core\Application\AppContext;
Expand All @@ -16,6 +17,7 @@
use Windwalker\Core\Renderer\RendererService;
use Windwalker\Core\Router\Navigator;
use Windwalker\Core\Router\RouteUri;
use Windwalker\Crypt\Hasher\PasswordHasherInterface;
use Windwalker\ORM\ORM;

/**
Expand Down Expand Up @@ -114,10 +116,12 @@ public function confirm(AppContext $app, UserService $userService, Navigator $na
return $nav->to('forget_reset');
}

public function reset(AppContext $app, UserService $userService, ORM $orm, Navigator $nav): RouteUri
{
$password = $app->input('password');
$password2 = $app->input('password2');
public function reset(
AppContext $app,
UserService $userService,
ORM $orm,
Navigator $nav
): RouteUri {
$token = $app->input('token');

if (!$token) {
Expand All @@ -142,14 +146,27 @@ public function reset(AppContext $app, UserService $userService, ORM $orm, Navig
throw new ValidateFailException($this->trans('luna.forget.request.message.invalid.token'));
}

if ($password !== $password2) {
throw new ValidateFailException($this->trans('luna.forget.reset.message.password.not.match'));
$srpService = $app->retrieve(SRPService::class);

if ($srpService->isEnabled()) {
$user = $srpService->handleRegister($app, $user);
} else {
$password = $app->input('password');
$password2 = $app->input('password2');

$hasher = $app->retrieve(PasswordHasherInterface::class);

if ($password !== $password2) {
throw new ValidateFailException($this->trans('luna.forget.reset.message.password.not.match'));
}

$user->setPassword($hasher->hash($password));
}

$user->setPassword(password_hash($password, PASSWORD_DEFAULT));
$user->setResetToken('');
$user->setLastReset('now');


$orm->updateOne(
User::class,
$user
Expand Down
31 changes: 29 additions & 2 deletions src/Module/Front/Auth/ForgetResetView.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,20 @@

namespace Lyrasoft\Luna\Module\Front\Auth;

use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use Lyrasoft\Luna\Auth\SRP\SRPService;
use Lyrasoft\Luna\Entity\User;
use Lyrasoft\Luna\LunaPackage;
use Lyrasoft\Luna\User\UserService;
use Windwalker\Core\Application\AppContext;
use Windwalker\Core\Attributes\ViewModel;
use Windwalker\Core\Language\TranslatorTrait;
use Windwalker\Core\Router\Navigator;
use Windwalker\Core\View\View;
use Windwalker\Core\View\ViewModelInterface;
use Windwalker\Data\Collection;
use Windwalker\ORM\ORM;

/**
* The ForgetResetView class.
Expand All @@ -28,7 +36,7 @@ class ForgetResetView implements ViewModelInterface
/**
* Constructor.
*/
public function __construct(protected Navigator $nav)
public function __construct(protected Navigator $nav, protected SRPService $srp)
{
//
}
Expand All @@ -51,6 +59,25 @@ public function prepare(AppContext $app, View $view): mixed

$view->setTitle($this->trans('luna.reset.form.title'));

return compact('token');
$identity = '';

if ($this->srp->isEnabled()) {
$payload = JWT::decode(
$token,
new Key($app->getSecret(), 'HS256'),
);

$email = $payload->email ?? null;

/** @var User $user */
$user = $app->retrieve(ORM::class)
->findOne(User::class, ['email' => (string) $email], Collection::class);

$loginName = $app->service(LunaPackage::class)->getLoginName();

$identity = $user->$loginName;
}

return compact('token', 'identity');
}
}
Loading

0 comments on commit 796def1

Please sign in to comment.