mirror of
https://github.com/grocy/grocy.git
synced 2026-04-01 02:29:26 +02:00
Handle passwords in-transit Base64 encoded to allow arbitrary characters / escape sequences (fixes #2892)
This commit is contained in:
parent
763676c936
commit
d4bf5d075a
2
app.php
2
app.php
|
|
@ -117,7 +117,9 @@ else
|
|||
|
||||
$authMiddlewareClass = GROCY_AUTH_CLASS;
|
||||
$app->add(new $authMiddlewareClass($container, $app->getResponseFactory()));
|
||||
|
||||
// Add default middleware
|
||||
$app->addBodyParsingMiddleware();
|
||||
$app->addRoutingMiddleware();
|
||||
$errorMiddleware = $app->addErrorMiddleware(true, false, false);
|
||||
$errorMiddleware->setDefaultErrorHandler(
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@
|
|||
|
||||
### General
|
||||
|
||||
- xxx
|
||||
- Fixed that it wasn't possible to log in using passwords containing special escape sequences (e.g. `<<`)
|
||||
|
||||
### API
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,15 @@ class LoginController extends BaseController
|
|||
public function ProcessLogin(Request $request, Response $response, array $args)
|
||||
{
|
||||
$authMiddlewareClass = GROCY_AUTH_CLASS;
|
||||
if ($authMiddlewareClass::ProcessLogin($request->getParsedBody()))
|
||||
|
||||
$postParams = $request->getParsedBody();
|
||||
if (isset($postParams['password_base64']))
|
||||
{
|
||||
$postParams['password'] = base64_decode($postParams['password_base64']);
|
||||
}
|
||||
unset($postParams['password_base64']);
|
||||
|
||||
if ($authMiddlewareClass::ProcessLogin($postParams))
|
||||
{
|
||||
return $response->withRedirect($this->AppContainer->get('UrlManager')->ConstructUrl('/'));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,6 +43,12 @@ class UsersApiController extends BaseApiController
|
|||
throw new \Exception('Request body could not be parsed (probably invalid JSON format or missing/wrong Content-Type header)');
|
||||
}
|
||||
|
||||
if (isset($requestBody['password_base64']))
|
||||
{
|
||||
$requestBody['password'] = base64_decode($requestBody['password_base64']);
|
||||
}
|
||||
unset($requestBody['password_base64']);
|
||||
|
||||
$this->getUsersService()->CreateUser($requestBody['username'], $requestBody['first_name'], $requestBody['last_name'], $requestBody['password'], $requestBody['picture_file_name']);
|
||||
return $this->EmptyApiResponse($response);
|
||||
}
|
||||
|
|
@ -81,6 +87,12 @@ class UsersApiController extends BaseApiController
|
|||
|
||||
try
|
||||
{
|
||||
if (isset($requestBody['password_base64']))
|
||||
{
|
||||
$requestBody['password'] = base64_decode($requestBody['password_base64']);
|
||||
}
|
||||
unset($requestBody['password_base64']);
|
||||
|
||||
$this->getUsersService()->EditUser($args['userId'], $requestBody['username'], $requestBody['first_name'], $requestBody['last_name'], $requestBody['password'], $requestBody['picture_file_name']);
|
||||
return $this->EmptyApiResponse($response);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
setTimeout(function()
|
||||
setTimeout(function ()
|
||||
{
|
||||
$('#username').focus();
|
||||
}, Grocy.FormFocusDelay);
|
||||
|
|
@ -8,3 +8,11 @@ if (GetUriParam('invalid') === 'true')
|
|||
$('#login-error').text(__t('Invalid credentials, please try again'));
|
||||
$('#login-error').removeClass('d-none');
|
||||
}
|
||||
|
||||
$("#login-button").on("click", function (e)
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
$("#password_base64").val(btoa($("#password_input").val()));
|
||||
$("#login-form").trigger("submit");
|
||||
});
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
});
|
||||
}
|
||||
|
||||
$('#save-user-button').on('click', function(e)
|
||||
$('#save-user-button').on('click', function (e)
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
|
|
@ -46,11 +46,16 @@ $('#save-user-button').on('click', function(e)
|
|||
jsonData.picture_file_name = RandomString() + CleanFileName($("#user-picture")[0].files[0].name);
|
||||
}
|
||||
|
||||
jsonData.password_base64 = btoa(jsonData.password);
|
||||
delete jsonData.password;
|
||||
delete jsonData.password_confirm;
|
||||
delete jsonData.change_password;
|
||||
|
||||
if (Grocy.EditMode === 'create')
|
||||
{
|
||||
Grocy.Api.Post('users', jsonData,
|
||||
(result) => SaveUserPicture(result, jsonData),
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
Grocy.FrontendHelpers.EndUiBusy("user-form");
|
||||
console.error(xhr);
|
||||
|
|
@ -64,11 +69,11 @@ $('#save-user-button').on('click', function(e)
|
|||
jsonData.picture_file_name = null;
|
||||
|
||||
Grocy.Api.DeleteFile(Grocy.UserPictureFileName, 'userpictures',
|
||||
function(result)
|
||||
function (result)
|
||||
{
|
||||
// Nothing to do
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
Grocy.FrontendHelpers.EndUiBusy("user-form");
|
||||
Grocy.FrontendHelpers.ShowGenericError('Error while saving, probably this item already exists', xhr.response);
|
||||
|
|
@ -78,7 +83,7 @@ $('#save-user-button').on('click', function(e)
|
|||
|
||||
Grocy.Api.Put('users/' + Grocy.EditObjectId, jsonData,
|
||||
(result) => SaveUserPicture(result, jsonData),
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
Grocy.FrontendHelpers.EndUiBusy("user-form");
|
||||
console.error(xhr);
|
||||
|
|
@ -87,7 +92,7 @@ $('#save-user-button').on('click', function(e)
|
|||
}
|
||||
});
|
||||
|
||||
$('#user-form input').keyup(function(event)
|
||||
$('#user-form input').keyup(function (event)
|
||||
{
|
||||
var element = document.getElementById("password_confirm");
|
||||
if ($("#password").val() !== $("#password_confirm").val())
|
||||
|
|
@ -102,7 +107,7 @@ $('#user-form input').keyup(function(event)
|
|||
Grocy.FrontendHelpers.ValidateForm('user-form');
|
||||
});
|
||||
|
||||
$('#user-form input').keydown(function(event)
|
||||
$('#user-form input').keydown(function (event)
|
||||
{
|
||||
if (event.keyCode === 13) // Enter
|
||||
{
|
||||
|
|
@ -119,7 +124,7 @@ $('#user-form input').keydown(function(event)
|
|||
}
|
||||
});
|
||||
|
||||
$("#user-picture").on("change", function(e)
|
||||
$("#user-picture").on("change", function (e)
|
||||
{
|
||||
$("#user-picture-label").removeClass("d-none");
|
||||
$("#user-picture-label-none").addClass("d-none");
|
||||
|
|
@ -129,7 +134,7 @@ $("#user-picture").on("change", function(e)
|
|||
});
|
||||
|
||||
Grocy.DeleteUserPictureOnSave = false;
|
||||
$("#delete-current-user-picture-button").on("click", function(e)
|
||||
$("#delete-current-user-picture-button").on("click", function (e)
|
||||
{
|
||||
Grocy.DeleteUserPictureOnSave = true;
|
||||
$("#current-user-picture").addClass("d-none");
|
||||
|
|
@ -138,12 +143,12 @@ $("#delete-current-user-picture-button").on("click", function(e)
|
|||
$("#user-picture-label-none").removeClass("d-none");
|
||||
});
|
||||
|
||||
$("#change_password").click(function()
|
||||
$("#change_password").click(function ()
|
||||
{
|
||||
$("#password").attr("disabled", !this.checked);
|
||||
$("#password_confirm").attr("disabled", !this.checked);
|
||||
|
||||
setTimeout(function()
|
||||
setTimeout(function ()
|
||||
{
|
||||
$("#password").focus();
|
||||
}, Grocy.FormFocusDelay);
|
||||
|
|
@ -155,7 +160,7 @@ if (GetUriParam("changepw") === "true")
|
|||
}
|
||||
else
|
||||
{
|
||||
setTimeout(function()
|
||||
setTimeout(function ()
|
||||
{
|
||||
$('#username').focus();
|
||||
}, Grocy.FormFocusDelay);
|
||||
|
|
|
|||
|
|
@ -23,13 +23,16 @@
|
|||
name="username">
|
||||
</div>
|
||||
|
||||
|
||||
<input type="hidden"
|
||||
id="password_base64"
|
||||
name="password_base64">
|
||||
<div class="form-group">
|
||||
<label for="password">{{ $__t('Password') }}</label>
|
||||
<label for="password_input">{{ $__t('Password') }}</label>
|
||||
<input type="password"
|
||||
class="form-control"
|
||||
required
|
||||
id="password"
|
||||
name="password">
|
||||
id="password_input">
|
||||
<div id="login-error"
|
||||
class="form-text text-danger d-none"></div>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user