diff --git a/Grocy.php b/Grocy.php
index 60c676ea..a28d2d6c 100644
--- a/Grocy.php
+++ b/Grocy.php
@@ -101,4 +101,48 @@ class Grocy
return self::$InstalledVersion;
}
+
+ /**
+ * @return boolean
+ */
+ public static function IsValidSession($sessionKey)
+ {
+ if ($sessionKey === null || empty($sessionKey))
+ {
+ return false;
+ }
+ else
+ {
+ return file_exists(__DIR__ . "/data/sessions/$sessionKey.txt");
+ }
+ }
+
+ /**
+ * @return string
+ */
+ public static function CreateSession()
+ {
+ if (!file_exists(__DIR__ . '/data/sessions'))
+ {
+ mkdir(__DIR__ . '/data/sessions');
+ }
+
+ $now = time();
+ foreach (new FilesystemIterator(__DIR__ . '/data/sessions') as $file)
+ {
+ if ($now - $file->getCTime() >= 2678400) //31 days
+ {
+ unlink(__DIR__ . '/data/sessions/' . $file->getFilename());
+ }
+ }
+
+ $newSessionKey = uniqid() . uniqid() . uniqid();
+ file_put_contents(__DIR__ . "/data/sessions/$newSessionKey.txt", '');
+ return $newSessionKey;
+ }
+
+ public static function RemoveSession($sessionKey)
+ {
+ unlink(__DIR__ . "/data/sessions/$sessionKey.txt");
+ }
}
diff --git a/composer.json b/composer.json
index 095e0937..c92fd905 100644
--- a/composer.json
+++ b/composer.json
@@ -2,7 +2,6 @@
"require": {
"slim/slim": "^3.8",
"slim/php-view": "^2.2",
- "morris/lessql": "^0.3.4",
- "tuupola/slim-basic-auth": "^2.2"
+ "morris/lessql": "^0.3.4"
}
}
diff --git a/grocy.phpproj b/grocy.phpproj
index f59648ee..f5f02a63 100644
--- a/grocy.phpproj
+++ b/grocy.phpproj
@@ -30,6 +30,7 @@
+
@@ -60,6 +61,7 @@
+
diff --git a/index.php b/index.php
index db99d49d..55c81c40 100644
--- a/index.php
+++ b/index.php
@@ -15,6 +15,7 @@ require_once __DIR__ . '/GrocyPhpHelper.php';
$app = new \Slim\App(new \Slim\Container([
'settings' => [
'displayErrorDetails' => true,
+ 'determineRouteBeforeAppMiddleware' => true
],
]));
$container = $app->getContainer();
@@ -22,18 +23,65 @@ $container['renderer'] = new PhpRenderer('./views');
if (!Grocy::IsDemoInstallation())
{
- $isHttpsReverseProxied = !empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https';
- $app->add(new \Slim\Middleware\HttpBasicAuthentication([
- 'realm' => 'grocy',
- 'secure' => !$isHttpsReverseProxied,
- 'users' => [
- HTTP_USER => HTTP_PASSWORD
- ]
- ]));
+ $sessionMiddleware = function(Request $request, Response $response, callable $next)
+ {
+ $route = $request->getAttribute('route');
+ $routeName = $route->getName();
+
+ if (!Grocy::IsValidSession($_COOKIE['grocy_session']) && $routeName !== 'login')
+ {
+ $response = $response->withRedirect('/login');
+ }
+ else
+ {
+ $response = $next($request, $response);
+ }
+
+ return $response;
+ };
+
+ $app->add($sessionMiddleware);
}
$db = Grocy::GetDbConnection();
+$app->get('/login', function(Request $request, Response $response)
+{
+ return $this->renderer->render($response, '/layout.php', [
+ 'title' => 'Login',
+ 'contentPage' => 'login.php'
+ ]);
+})->setName('login');
+
+$app->post('/login', function(Request $request, Response $response)
+{
+ $postParams = $request->getParsedBody();
+ if (isset($postParams['username']) && isset($postParams['password']))
+ {
+ if ($postParams['username'] === HTTP_USER && $postParams['password'] === HTTP_PASSWORD)
+ {
+ $sessionKey = Grocy::CreateSession();
+ setcookie('grocy_session', $sessionKey, time()+2592000); //30 days
+
+ return $response->withRedirect('/');
+ }
+ else
+ {
+ return $response->withRedirect('/login?invalid=true');
+ }
+ }
+ else
+ {
+ return $response->withRedirect('/login?invalid=true');
+ }
+})->setName('login');
+
+$app->get('/logout', function(Request $request, Response $response)
+{
+ Grocy::RemoveSession($_COOKIE['grocy_session']);
+ return $response->withRedirect('/');
+});
+
$app->get('/', function(Request $request, Response $response) use($db)
{
$db = Grocy::GetDbConnection(true); //For database schema migration
diff --git a/version.txt b/version.txt
index 589268e6..e21e727f 100644
--- a/version.txt
+++ b/version.txt
@@ -1 +1 @@
-1.3.0
\ No newline at end of file
+1.4.0
\ No newline at end of file
diff --git a/views/layout.php b/views/layout.php
index 4cc4f6d1..ff582724 100644
--- a/views/layout.php
+++ b/views/layout.php
@@ -38,6 +38,14 @@
grocy
+
+
diff --git a/views/login.js b/views/login.js
new file mode 100644
index 00000000..08134ca3
--- /dev/null
+++ b/views/login.js
@@ -0,0 +1,12 @@
+$(function()
+{
+ $('.logout-button').hide();
+
+ $('#username').focus();
+
+ if (Grocy.GetUriParam('invalid') === 'true')
+ {
+ $('#login-error').text('Invalid credentials, please try again.');
+ $('#login-error').show();
+ }
+});
diff --git a/views/login.php b/views/login.php
new file mode 100644
index 00000000..e323543b
--- /dev/null
+++ b/views/login.php
@@ -0,0 +1,23 @@
+