Compare commits
No commits in common. "b24fe56c8ae6fc3e3f7a9b153fc4e5a6f3c7cb38" and "114a67dbe43ca65b3ca38e0be730436e0d310177" have entirely different histories.
b24fe56c8a
...
114a67dbe4
20
.env.develop
20
.env.develop
|
|
@ -1,23 +1,7 @@
|
|||
# .env.development: Environment variables for local development
|
||||
|
||||
# composer: Set cache directory
|
||||
# Set composer cache directory
|
||||
COMPOSER_CACHE_DIR=./.composer
|
||||
|
||||
# MariaDB container
|
||||
MYSQL_RANDOM_ROOT_PASSWORD=yes
|
||||
MYSQL_DATABASE=mailusers
|
||||
MYSQL_USER=mailaccountadmin
|
||||
MYSQL_PASSWORD=mailaccountadmin
|
||||
|
||||
# App settings
|
||||
APP_DEBUG=true
|
||||
|
||||
# - Disable Twig cache
|
||||
# Disable Twig cache
|
||||
TWIG_CACHE_DIR=
|
||||
TWIG_STRICT=true
|
||||
|
||||
# - Database credentials
|
||||
DB_HOST=db
|
||||
DB_DATABASE=mailusers
|
||||
DB_USER=mailaccountadmin
|
||||
DB_PASSWORD=mailaccountadmin
|
||||
|
|
|
|||
|
|
@ -12,21 +12,3 @@ services:
|
|||
volumes:
|
||||
- ./:/var/www/
|
||||
user: ${DOCKER_UID}
|
||||
|
||||
db:
|
||||
image: mariadb
|
||||
env_file:
|
||||
- .env.develop
|
||||
ports:
|
||||
- 13306:3306
|
||||
volumes:
|
||||
- db_data:/var/lib/mysql
|
||||
- ./sql/init_tables.sql:/docker-entrypoint-initdb.d/init_tables.sql:ro
|
||||
|
||||
adminer:
|
||||
image: adminer
|
||||
ports:
|
||||
- 8099:8080
|
||||
|
||||
volumes:
|
||||
db_data:
|
||||
|
|
|
|||
|
|
@ -9,13 +9,11 @@ use MailAccountAdmin\Routes;
|
|||
use MailAccountAdmin\Settings;
|
||||
use Slim\Factory\AppFactory;
|
||||
|
||||
session_start();
|
||||
|
||||
$settings = new Settings();
|
||||
$container = Dependencies::createContainer($settings);
|
||||
$app = AppFactory::createFromContainer($container);
|
||||
|
||||
Middlewares::setMiddlewares($app, $settings);
|
||||
Middlewares::setMiddlewares($app);
|
||||
Routes::setRoutes($app);
|
||||
|
||||
$app->run();
|
||||
|
|
|
|||
|
|
@ -1,50 +0,0 @@
|
|||
html, body {
|
||||
max-width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
/* --- Header --- */
|
||||
header {
|
||||
margin: 1em;
|
||||
}
|
||||
|
||||
header h1 {
|
||||
margin: 1em;
|
||||
}
|
||||
|
||||
/* --- Login page --- */
|
||||
main.login_page {
|
||||
margin: 2em;
|
||||
padding: 1em;
|
||||
border: 1px gray solid;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
main.login_page h2 {
|
||||
margin: 0 0 0.5em 0;
|
||||
}
|
||||
|
||||
main.login_page table td {
|
||||
padding: 0.2em;
|
||||
}
|
||||
|
||||
/* --- Text and other styling --- */
|
||||
.error {
|
||||
background: #ff4444;
|
||||
width: 30em;
|
||||
margin: 1em 0;
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 0.2em 1em;
|
||||
}
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
-- Create tables
|
||||
|
||||
SET NAMES utf8mb4;
|
||||
|
||||
-- TODO create on prod
|
||||
CREATE TABLE `admin_users`
|
||||
(
|
||||
`admin_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`username` varchar(255) NOT NULL,
|
||||
`password` varchar(255) NOT NULL,
|
||||
`is_active` tinyint(3) unsigned NOT NULL DEFAULT 1,
|
||||
`created_at` datetime NOT NULL DEFAULT NOW(),
|
||||
`modified_at` datetime NOT NULL DEFAULT NOW(),
|
||||
PRIMARY KEY (`admin_id`),
|
||||
UNIQUE KEY `username` (`username`)
|
||||
) DEFAULT CHARSET = utf8mb4;
|
||||
|
||||
-- Create initial admin user for development (password is 'admin')
|
||||
INSERT INTO `admin_users`
|
||||
(`username`, `password`, `is_active`, `created_at`, `modified_at`)
|
||||
VALUES ('admin', '$2y$10$zaNOBUk4PBlhDZD40h35CeyUxiqixi9LTrxlAxnrckXd95hcCctl6', '1', NOW(), NOW());
|
||||
|
||||
-- TODO rename on prod `users` -> `mail_users`
|
||||
CREATE TABLE `mail_users`
|
||||
(
|
||||
`user_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`username` varchar(255) NOT NULL,
|
||||
`password` varchar(255) NOT NULL,
|
||||
`is_active` tinyint(3) unsigned NOT NULL DEFAULT 1,
|
||||
`home_dir` varchar(255) NOT NULL,
|
||||
`memo` text DEFAULT NULL,
|
||||
`created_at` datetime NOT NULL DEFAULT NOW(),
|
||||
`modified_at` datetime NOT NULL DEFAULT NOW(),
|
||||
PRIMARY KEY (`user_id`),
|
||||
UNIQUE KEY `username` (`username`)
|
||||
) DEFAULT CHARSET = utf8mb4;
|
||||
|
||||
CREATE TABLE `mail_aliases`
|
||||
(
|
||||
`alias_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`user_id` int(10) unsigned NOT NULL,
|
||||
`mail_address` varchar(255) NOT NULL,
|
||||
`created_at` datetime NOT NULL DEFAULT NOW(),
|
||||
`modified_at` datetime NOT NULL DEFAULT NOW(),
|
||||
PRIMARY KEY (`alias_id`),
|
||||
UNIQUE KEY `mail_address` (`mail_address`),
|
||||
KEY `user_id` (`user_id`),
|
||||
-- TODO rename on prod `users` -> `mail_users`
|
||||
CONSTRAINT `mail_aliases_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `mail_users` (`user_id`)
|
||||
) DEFAULT CHARSET = utf8mb4;
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace MailAccountAdmin\Auth;
|
||||
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Server\MiddlewareInterface;
|
||||
use Psr\Http\Server\RequestHandlerInterface;
|
||||
use Slim\Psr7\Response;
|
||||
|
||||
class AuthMiddleware implements MiddlewareInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
|
||||
{
|
||||
$uri = $request->getUri();
|
||||
|
||||
// TODO: Lots of stuff. Session middleware, auth handler class, etc...
|
||||
if ($uri->getPath() !== '/login') {
|
||||
// Check authorization via session
|
||||
// TODO username or user ID?
|
||||
if (empty($_SESSION['username'])) {
|
||||
// Not logged in -> Redirect to /login
|
||||
$response = new Response();
|
||||
return $response
|
||||
->withHeader('Location', '/login')
|
||||
->withStatus(303);
|
||||
}
|
||||
}
|
||||
|
||||
return $handler->handle($request);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace MailAccountAdmin\Common;
|
||||
|
||||
use http\Exception\RuntimeException;
|
||||
use MailAccountAdmin\Models\AdminUser;
|
||||
use MailAccountAdmin\Repositories\AdminUserRepository;
|
||||
|
||||
class UserHelper
|
||||
{
|
||||
/** @var AdminUserRepository */
|
||||
private $adminUserRepository;
|
||||
|
||||
public function __construct(AdminUserRepository $adminUserRepository)
|
||||
{
|
||||
$this->adminUserRepository = $adminUserRepository;
|
||||
}
|
||||
|
||||
public function isLoggedIn(): bool
|
||||
{
|
||||
return !empty($_SESSION['username']);
|
||||
}
|
||||
|
||||
public function getCurrentUser(): AdminUser
|
||||
{
|
||||
$username = $_SESSION['username'] ?? null;
|
||||
if (empty($username)) {
|
||||
throw new RuntimeException('Not logged in!');
|
||||
}
|
||||
return $this->adminUserRepository->getUserByName($username);
|
||||
}
|
||||
}
|
||||
|
|
@ -4,20 +4,15 @@ declare(strict_types=1);
|
|||
namespace MailAccountAdmin;
|
||||
|
||||
use DI\Container;
|
||||
use MailAccountAdmin\Common\UserHelper;
|
||||
use MailAccountAdmin\Frontend\Login\LoginController;
|
||||
use MailAccountAdmin\Frontend\Dashboard\DashboardController;
|
||||
use MailAccountAdmin\Repositories\AdminUserRepository;
|
||||
use PDO;
|
||||
use MailAccountAdmin\Login\LoginController;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Slim\Views\Twig;
|
||||
|
||||
class Dependencies
|
||||
{
|
||||
public const SETTINGS = 'settings';
|
||||
public const TWIG = 'view';
|
||||
private const SETTINGS = 'settings';
|
||||
private const TWIG = 'view';
|
||||
private const TWIG_TEMPLATE_DIR = __DIR__ . '/../templates';
|
||||
public const DATABASE = 'database';
|
||||
|
||||
public static function createContainer(Settings $settings): Container
|
||||
{
|
||||
|
|
@ -34,50 +29,10 @@ class Dependencies
|
|||
return Twig::create(self::TWIG_TEMPLATE_DIR, $settings->getTwigSettings());
|
||||
});
|
||||
|
||||
// Database connection
|
||||
$container->set(self::DATABASE, function (ContainerInterface $c) {
|
||||
/** @var Settings $settings */
|
||||
$settings = $c->get(self::SETTINGS);
|
||||
$dbSettings = $settings->getDatabaseSettings();
|
||||
|
||||
return new PDO(
|
||||
"mysql:dbname={$dbSettings['dbname']};host={$dbSettings['host']};port={$dbSettings['port']}",
|
||||
$dbSettings['username'],
|
||||
$dbSettings['password'],
|
||||
[
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
],
|
||||
);
|
||||
});
|
||||
|
||||
// Repositories
|
||||
$container->set(AdminUserRepository::class, function (ContainerInterface $c) {
|
||||
return new AdminUserRepository(
|
||||
$c->get(self::DATABASE),
|
||||
);
|
||||
});
|
||||
|
||||
// Helper classes
|
||||
$container->set(UserHelper::class, function (ContainerInterface $c) {
|
||||
return new UserHelper(
|
||||
$c->get(AdminUserRepository::class),
|
||||
);
|
||||
});
|
||||
|
||||
// Login page
|
||||
// Login, registration, authentication
|
||||
$container->set(LoginController::class, function (ContainerInterface $c) {
|
||||
return new LoginController(
|
||||
$c->get(self::TWIG),
|
||||
$c->get(UserHelper::class),
|
||||
$c->get(AdminUserRepository::class),
|
||||
);
|
||||
});
|
||||
|
||||
// Dashboard
|
||||
$container->set(DashboardController::class, function (ContainerInterface $c) {
|
||||
return new DashboardController(
|
||||
$c->get(self::TWIG),
|
||||
$c->get(UserHelper::class),
|
||||
$c->get(self::TWIG)
|
||||
);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace MailAccountAdmin\Exceptions;
|
||||
|
||||
class AdminUserNotFoundException extends AppException
|
||||
{
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace MailAccountAdmin\Exceptions;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
class AppException extends RuntimeException
|
||||
{
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace MailAccountAdmin\Frontend;
|
||||
|
||||
use MailAccountAdmin\Common\UserHelper;
|
||||
use Slim\Views\Twig;
|
||||
|
||||
class BaseController
|
||||
{
|
||||
/** @var Twig */
|
||||
protected $view;
|
||||
/** @var UserHelper */
|
||||
protected $userHelper;
|
||||
|
||||
public function __construct(Twig $view, UserHelper $userHelper)
|
||||
{
|
||||
$this->view = $view;
|
||||
$this->userHelper = $userHelper;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace MailAccountAdmin\Frontend\Dashboard;
|
||||
|
||||
use MailAccountAdmin\Frontend\BaseController;
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
|
||||
class DashboardController extends BaseController
|
||||
{
|
||||
public function showDashboard(Request $request, Response $response): Response
|
||||
{
|
||||
$currentUser = $this->userHelper->getCurrentUser();
|
||||
|
||||
$renderData = [
|
||||
'username' => $currentUser->getUsername(),
|
||||
'user' => $currentUser,
|
||||
];
|
||||
|
||||
return $this->view->render($response, 'dashboard.html.twig', $renderData);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace MailAccountAdmin\Frontend\Login;
|
||||
|
||||
use MailAccountAdmin\Common\UserHelper;
|
||||
use MailAccountAdmin\Exceptions\AdminUserNotFoundException;
|
||||
use MailAccountAdmin\Frontend\BaseController;
|
||||
use MailAccountAdmin\Repositories\AdminUserRepository;
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
use Slim\Views\Twig;
|
||||
|
||||
class LoginController extends BaseController
|
||||
{
|
||||
/** @var AdminUserRepository */
|
||||
private $adminUserRepository;
|
||||
|
||||
public function __construct(Twig $view, UserHelper $userHelper, AdminUserRepository $adminUserRepository)
|
||||
{
|
||||
parent::__construct($view, $userHelper);
|
||||
$this->adminUserRepository = $adminUserRepository;
|
||||
}
|
||||
|
||||
private function renderLoginPage(Response $response, array $renderData = []): Response
|
||||
{
|
||||
return $this->view->render($response, 'login.html.twig', $renderData);
|
||||
}
|
||||
|
||||
public function showLoginPage(Request $request, Response $response): Response
|
||||
{
|
||||
if ($this->userHelper->isLoggedIn()) {
|
||||
// Already logged in, redirect to dashboard
|
||||
return $response
|
||||
->withHeader('Location', '/')
|
||||
->withStatus(303);
|
||||
}
|
||||
|
||||
return $this->renderLoginPage($response);
|
||||
}
|
||||
|
||||
public function authenticateUser(Request $request, Response $response): Response
|
||||
{
|
||||
$params = (array)$request->getParsedBody();
|
||||
|
||||
if (empty($params['username'])) {
|
||||
return $this->renderLoginPage($response, ['error' => 'Missing username!']);
|
||||
} elseif (empty($params['password'])) {
|
||||
return $this->renderLoginPage($response, ['error' => 'Missing password!']);
|
||||
}
|
||||
|
||||
$loginUsername = $params['username'];
|
||||
$loginPassword = $params['password'];
|
||||
|
||||
try {
|
||||
$user = $this->adminUserRepository->getUserByName($loginUsername);
|
||||
}
|
||||
catch (AdminUserNotFoundException $e) {
|
||||
$user = null;
|
||||
}
|
||||
|
||||
if ($user !== null && password_verify($loginPassword, $user->getPasswordHash())) {
|
||||
$_SESSION['username'] = $user->getUsername();
|
||||
return $response
|
||||
->withHeader('Location', '/')
|
||||
->withStatus(303);
|
||||
} else {
|
||||
return $this->renderLoginPage($response, ['error' => 'Wrong username or password!']);
|
||||
}
|
||||
}
|
||||
|
||||
public function logoutUser(Request $request, Response $response): Response
|
||||
{
|
||||
session_destroy();
|
||||
|
||||
return $response
|
||||
->withHeader('Location', '/login')
|
||||
->withStatus(303);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace MailAccountAdmin\Login;
|
||||
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
use Slim\Views\Twig;
|
||||
|
||||
class LoginController
|
||||
{
|
||||
/** @var Twig */
|
||||
private $view;
|
||||
|
||||
public function __construct(Twig $view)
|
||||
{
|
||||
$this->view = $view;
|
||||
}
|
||||
|
||||
public function showLoginPage(Request $request, Response $response): Response
|
||||
{
|
||||
$renderData = [
|
||||
];
|
||||
|
||||
return $this->view->render($response, 'login.html', $renderData);
|
||||
}
|
||||
}
|
||||
|
|
@ -3,18 +3,13 @@ declare(strict_types=1);
|
|||
|
||||
namespace MailAccountAdmin;
|
||||
|
||||
use MailAccountAdmin\Auth\AuthMiddleware;
|
||||
use Slim\App;
|
||||
use Slim\Views\TwigMiddleware;
|
||||
|
||||
class Middlewares
|
||||
{
|
||||
public static function setMiddlewares(App $app, Settings $settings): void
|
||||
public static function setMiddlewares(App $app): void
|
||||
{
|
||||
$displayErrorDetails = $settings->isDebugMode();
|
||||
|
||||
$app->addErrorMiddleware($displayErrorDetails, true, true);
|
||||
$app->add(new AuthMiddleware());
|
||||
$app->add(TwigMiddleware::createFromContainer($app));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,75 +0,0 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace MailAccountAdmin\Models;
|
||||
|
||||
use DateTimeImmutable;
|
||||
|
||||
class AdminUser
|
||||
{
|
||||
/** @var int */
|
||||
private $id;
|
||||
/** @var string */
|
||||
private $username;
|
||||
/** @var string */
|
||||
private $passwordHash;
|
||||
/** @var bool */
|
||||
private $active;
|
||||
/** @var DateTimeImmutable */
|
||||
private $createdAt;
|
||||
/** @var DateTimeImmutable */
|
||||
private $modifiedAt;
|
||||
|
||||
private function __construct(int $id, string $username, string $passwordHash, bool $isActive,
|
||||
DateTimeImmutable $createdAt, DateTimeImmutable $modifiedAt)
|
||||
{
|
||||
$this->id = $id;
|
||||
$this->username = $username;
|
||||
$this->passwordHash = $passwordHash;
|
||||
$this->active = $isActive;
|
||||
$this->createdAt = $createdAt;
|
||||
$this->modifiedAt = $modifiedAt;
|
||||
}
|
||||
|
||||
public static function createFromArray(array $data): self
|
||||
{
|
||||
return new self(
|
||||
(int)$data['admin_id'],
|
||||
$data['username'],
|
||||
$data['password'],
|
||||
$data['is_active'] === '1',
|
||||
new DateTimeImmutable($data['created_at']),
|
||||
new DateTimeImmutable($data['modified_at']),
|
||||
);
|
||||
}
|
||||
|
||||
public function getId(): int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getUsername(): string
|
||||
{
|
||||
return $this->username;
|
||||
}
|
||||
|
||||
public function getPasswordHash(): string
|
||||
{
|
||||
return $this->passwordHash;
|
||||
}
|
||||
|
||||
public function isActive(): bool
|
||||
{
|
||||
return $this->active;
|
||||
}
|
||||
|
||||
public function getCreatedAt(): DateTimeImmutable
|
||||
{
|
||||
return $this->createdAt;
|
||||
}
|
||||
|
||||
public function getModifiedAt(): DateTimeImmutable
|
||||
{
|
||||
return $this->modifiedAt;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace MailAccountAdmin\Repositories;
|
||||
|
||||
use MailAccountAdmin\Exceptions\AdminUserNotFoundException;
|
||||
use MailAccountAdmin\Models\AdminUser;
|
||||
use PDO;
|
||||
|
||||
class AdminUserRepository
|
||||
{
|
||||
/** @var PDO */
|
||||
private $pdo;
|
||||
|
||||
public function __construct(PDO $pdo)
|
||||
{
|
||||
$this->pdo = $pdo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws AdminUserNotFoundException
|
||||
*/
|
||||
public function getUserByName(string $username): AdminUser
|
||||
{
|
||||
$statement = $this->pdo->prepare('SELECT * FROM admin_users WHERE username = :username LIMIT 1');
|
||||
$statement->execute(['username' => $username]);
|
||||
|
||||
if ($statement->rowCount() < 1) {
|
||||
throw new AdminUserNotFoundException("Admin with username '$username' was not found.");
|
||||
}
|
||||
|
||||
$row = $statement->fetch(PDO::FETCH_ASSOC);
|
||||
return AdminUser::createFromArray($row);
|
||||
}
|
||||
}
|
||||
|
|
@ -3,20 +3,13 @@ declare(strict_types=1);
|
|||
|
||||
namespace MailAccountAdmin;
|
||||
|
||||
use MailAccountAdmin\Frontend\Dashboard\DashboardController;
|
||||
use MailAccountAdmin\Frontend\Login\LoginController;
|
||||
use MailAccountAdmin\Login\LoginController;
|
||||
use Slim\App;
|
||||
|
||||
class Routes
|
||||
{
|
||||
public static function setRoutes(App $app): void
|
||||
{
|
||||
// Login
|
||||
$app->get('/login', LoginController::class . ':showLoginPage');
|
||||
$app->post('/login', LoginController::class . ':authenticateUser');
|
||||
$app->get('/logout', LoginController::class . ':logoutUser');
|
||||
|
||||
// Dashboard
|
||||
$app->get('/', DashboardController::class . ':showDashboard');
|
||||
$app->get('/', LoginController::class . ':showLoginPage');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,27 +5,12 @@ namespace MailAccountAdmin;
|
|||
|
||||
class Settings
|
||||
{
|
||||
public function isDebugMode(): bool
|
||||
{
|
||||
return getenv('APP_DEBUG') === 'true';
|
||||
}
|
||||
|
||||
public function getTwigSettings(): array
|
||||
{
|
||||
return [
|
||||
'cache' => getenv('TWIG_CACHE_DIR') ?: false,
|
||||
'strict_variables' => getenv('TWIG_STRICT') === 'true',
|
||||
];
|
||||
}
|
||||
$cacheDir = getenv('TWIG_CACHE_DIR');
|
||||
|
||||
public function getDatabaseSettings(): array
|
||||
{
|
||||
return [
|
||||
'host' => getenv('DB_HOST') ?: 'localhost',
|
||||
'port' => getenv('DB_PORT') ?: 3306,
|
||||
'dbname' => getenv('DB_DATABASE') ?: '',
|
||||
'username' => getenv('DB_USER') ?: '',
|
||||
'password' => getenv('DB_PASSWORD') ?: '',
|
||||
'cache' => !empty($cacheDir) ? $cacheDir : false,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,23 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>{% block title %}Untitled page{% endblock %} - MailAccountAdmin</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="/static/style.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<header>
|
||||
<h1>MailAccountAdmin</h1>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
{% block content %}
|
||||
Nothing to see here...
|
||||
{% endblock %}
|
||||
</main>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
{% extends "base.html.twig" %}
|
||||
|
||||
{% block title %}Dashboard{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h2>Dashboard</h2>
|
||||
|
||||
<p>Hello, {{ username }}!</p>
|
||||
|
||||
<pre>
|
||||
ID: {{ user.getId() }}
|
||||
username: {{ user.getUsername() }}
|
||||
password: {{ user.getPasswordHash() }}
|
||||
is_active: {{ user.isActive() }}
|
||||
created_at: {{ user.getCreatedAt() | date() }}
|
||||
modified_at: {{ user.getModifiedAt() | date() }}
|
||||
</pre>
|
||||
|
||||
<a href="/logout">Logout.</a>
|
||||
{% endblock %}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>MailAccountAdmin</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<!-- <link rel="stylesheet" href=""> -->
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<h1>MailAccountAdmin - Login</h1>
|
||||
|
||||
<b>Hello.</b>
|
||||
|
||||
<!-- <script src="" async defer></script> -->
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Login - MailAccountAdmin</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="/static/style.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<header>
|
||||
<h1>MailAccountAdmin</h1>
|
||||
</header>
|
||||
|
||||
<main class="login_page">
|
||||
<h2>Login</h2>
|
||||
|
||||
<form action="/login" method="POST">
|
||||
{% if error is defined %}
|
||||
<div class="error">{{ error }}</div>
|
||||
{% endif %}
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td><label for="username">Username</label></td>
|
||||
<td><input type="text" id="username" name="username"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label for="password">Password</label></td>
|
||||
<td><input type="password" id="password" name="password"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td><button type="submit">Login</button></td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
</main>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Reference in New Issue