Итерация 1: каркас Slim 4 приложения
- Slim 4 + php-di контейнер с маршрутизацией - Docker Compose: app (PHP 8.3-FPM) + web (nginx) + db (MariaDB) - Phinx миграция: таблица users (uuid, username, password_hash) - Auth: login/logout с сессиями - Setup: создание первого пользователя - Dashboard с layout (Bootstrap 5.3) - CLI: bin/console, bin/run-scan-worker.php - Smoke test: scripts/check.sh - README.md, PLAN.md
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
/* Domovoy custom styles */
|
||||
body {
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
|
||||
#sidebar-wrapper .list-group-item:hover {
|
||||
background-color: #343a40 !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
#sidebar-wrapper .list-group-item.active {
|
||||
background-color: #0d6efd !important;
|
||||
border-color: #0d6efd !important;
|
||||
}
|
||||
|
||||
.card {
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.12);
|
||||
}
|
||||
|
||||
.navbar-brand {
|
||||
font-weight: bold;
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
session_start();
|
||||
|
||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||
|
||||
use DI\ContainerBuilder;
|
||||
use Slim\Factory\AppFactory;
|
||||
|
||||
$dotenv = \Dotenv\Dotenv::createImmutable(dirname(__DIR__));
|
||||
$dotenv->safeLoad();
|
||||
|
||||
// Build container
|
||||
$containerBuilder = new ContainerBuilder();
|
||||
$containerBuilder->addDefinitions([
|
||||
'settings' => [
|
||||
'db' => [
|
||||
'host' => getenv('DB_HOST') ?: 'db',
|
||||
'port' => (int)(getenv('DB_PORT') ?: 3306),
|
||||
'database' => getenv('DB_DATABASE') ?: 'domovoy',
|
||||
'username' => getenv('DB_USERNAME') ?: 'domovoy',
|
||||
'password' => getenv('DB_PASSWORD') ?: 'domovoy',
|
||||
],
|
||||
'app' => [
|
||||
'env' => getenv('APP_ENV') ?: 'development',
|
||||
'secret' => getenv('APP_SECRET') ?: 'change-me',
|
||||
'encryption_key' => getenv('ENCRYPTION_KEY') ?: '',
|
||||
],
|
||||
'ssh' => [
|
||||
'connect_timeout' => (int)(getenv('SSH_CONNECT_TIMEOUT_SECONDS') ?: 5),
|
||||
'auth_timeout' => (int)(getenv('SSH_AUTH_TIMEOUT_SECONDS') ?: 10),
|
||||
'command_timeout' => (int)(getenv('SSH_COMMAND_TIMEOUT_SECONDS') ?: 8),
|
||||
'total_scan_timeout' => (int)(getenv('SSH_TOTAL_SCAN_TIMEOUT_SECONDS') ?: 60),
|
||||
'retry_count' => (int)(getenv('SSH_RETRY_COUNT') ?: 0),
|
||||
],
|
||||
],
|
||||
'logger' => function () {
|
||||
$logger = new \Monolog\Logger('domovoy');
|
||||
$logger->pushHandler(new \Monolog\Handler\StreamHandler(
|
||||
dirname(__DIR__) . '/storage/logs/app.log',
|
||||
\Monolog\Level::Debug
|
||||
));
|
||||
return $logger;
|
||||
},
|
||||
PDO::class => function ($c) {
|
||||
$db = $c->get('settings')['db'];
|
||||
$dsn = sprintf(
|
||||
'mysql:host=%s;port=%d;dbname=%s;charset=utf8mb4',
|
||||
$db['host'],
|
||||
$db['port'],
|
||||
$db['database']
|
||||
);
|
||||
return new PDO($dsn, $db['username'], $db['password'], [
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
PDO::ATTR_EMULATE_PREPARES => false,
|
||||
]);
|
||||
},
|
||||
\Domovoy\Repositories\UserRepository::class => function ($c) {
|
||||
return new \Domovoy\Repositories\UserRepository($c->get(PDO::class));
|
||||
},
|
||||
\Domovoy\Services\AuthService::class => function ($c) {
|
||||
return new \Domovoy\Services\AuthService($c->get(\Domovoy\Repositories\UserRepository::class));
|
||||
},
|
||||
\Domovoy\Controllers\AuthController::class => function ($c) {
|
||||
return new \Domovoy\Controllers\AuthController($c->get(\Domovoy\Services\AuthService::class));
|
||||
},
|
||||
\Domovoy\Controllers\SetupController::class => function ($c) {
|
||||
return new \Domovoy\Controllers\SetupController($c->get(\Domovoy\Services\AuthService::class));
|
||||
},
|
||||
\Domovoy\Controllers\DashboardController::class => function () {
|
||||
return new \Domovoy\Controllers\DashboardController();
|
||||
},
|
||||
]);
|
||||
$container = $containerBuilder->build();
|
||||
|
||||
// Build Slim app
|
||||
AppFactory::setContainer($container);
|
||||
$app = AppFactory::create();
|
||||
|
||||
$app->addRoutingMiddleware();
|
||||
$app->addBodyParsingMiddleware();
|
||||
$app->add(new \Domovoy\Middleware\AuthMiddleware());
|
||||
$app->addErrorMiddleware(true, true, true);
|
||||
|
||||
// Routes
|
||||
$app->get('/login', [\Domovoy\Controllers\AuthController::class, 'loginForm'])->setName('login');
|
||||
$app->post('/login', [\Domovoy\Controllers\AuthController::class, 'login'])->setName('login.post');
|
||||
$app->get('/setup', [\Domovoy\Controllers\SetupController::class, 'form'])->setName('setup');
|
||||
$app->post('/setup', [\Domovoy\Controllers\SetupController::class, 'create'])->setName('setup.post');
|
||||
|
||||
$app->group('', function (\Slim\Routing\RouteCollectorProxy $group) {
|
||||
$group->get('/dashboard', [\Domovoy\Controllers\DashboardController::class, 'index'])->setName('dashboard');
|
||||
$group->post('/logout', [\Domovoy\Controllers\AuthController::class, 'logout'])->setName('logout');
|
||||
});
|
||||
|
||||
$app->run();
|
||||
Reference in New Issue
Block a user