diff --git a/.gitignore b/.gitignore index 11abea6..2b7e4cf 100644 --- a/.gitignore +++ b/.gitignore @@ -125,3 +125,5 @@ nb-configuration.xml /phpunit*.xml /.phpunit.*.cache +.env +public/js/env.js diff --git a/app/Config/App.php b/app/Config/App.php index cd0e4dc..7f2cd47 100644 --- a/app/Config/App.php +++ b/app/Config/App.php @@ -3,7 +3,6 @@ namespace Config; use CodeIgniter\Config\BaseConfig; -use CodeIgniter\Session\Handlers\FileHandler; class App extends BaseConfig { @@ -21,10 +20,26 @@ class App extends BaseConfig * and path to your installation. However, you should always configure this * explicitly and never rely on auto-guessing, especially in production * environments. - * - * @var string */ - public $baseURL = 'https://finanzen.mawim.at/'; + public string $baseURL = 'https://finanzen.mawim.at'; + //public $nodeRedUrl = 'https://mqtt.mawim.at/api/'; + public string $nodeRedUrl = 'http://localhost:1880/api/'; + public string $speedTestUrl = 'http://mqtt.mawim.at:3000/d/qsjZJaYVz/ping-results?orgId=1&from=now-2d&to=now&var-client=nextcloud&kiosk'; + public string $spritPreisUrl = 'http://mqtt.mawim.at:3000/d/b1fce188-593b-4629-9a73-6bd11c2998bd/spritpreis?orgId=1&viewPanel=1&from=now-7d&to=now&kiosk'; + public bool $disableShield = false; + + /** + * Allowed Hostnames in the Site URL other than the hostname in the baseURL. + * If you want to accept multiple Hostnames, set this. + * + * E.g., + * When your site URL ($baseURL) is 'http://example.com/', and your site + * also accepts 'http://media.example.com/' and 'http://accounts.example.com/': + * ['media.example.com', 'accounts.example.com'] + * + * @var list + */ + public array $allowedHostnames = []; /** * -------------------------------------------------------------------------- @@ -34,10 +49,8 @@ class App extends BaseConfig * Typically this will be your index.php file, unless you've renamed it to * something else. If you are using mod_rewrite to remove the page set this * variable so that it is blank. - * - * @var string */ - public $indexPage = 'index.php'; + public string $indexPage = 'index.php'; /** * -------------------------------------------------------------------------- @@ -53,10 +66,32 @@ class App extends BaseConfig * 'PATH_INFO' Uses $_SERVER['PATH_INFO'] * * WARNING: If you set this to 'PATH_INFO', URIs will always be URL-decoded! - * - * @var string */ - public $uriProtocol = 'REQUEST_URI'; + public string $uriProtocol = 'REQUEST_URI'; + + /* + |-------------------------------------------------------------------------- + | Allowed URL Characters + |-------------------------------------------------------------------------- + | + | This lets you specify which characters are permitted within your URLs. + | When someone tries to submit a URL with disallowed characters they will + | get a warning message. + | + | As a security measure you are STRONGLY encouraged to restrict URLs to + | as few characters as possible. + | + | By default, only these are allowed: `a-z 0-9~%.:_-` + | + | Set an empty string to allow all characters -- but only if you are insane. + | + | The configured value is actually a regular expression character group + | and it will be used as: '/\A[]+\z/iu' + | + | DO NOT CHANGE THIS UNLESS YOU FULLY UNDERSTAND THE REPERCUSSIONS!! + | + */ + public string $permittedURIChars = 'a-z 0-9~%.:_\-'; /** * -------------------------------------------------------------------------- @@ -67,10 +102,8 @@ class App extends BaseConfig * is viewing the site from. It affects the language strings and other * strings (like currency markers, numbers, etc), that your program * should run under for this request. - * - * @var string */ - public $defaultLocale = 'de'; + public string $defaultLocale = 'de'; /** * -------------------------------------------------------------------------- @@ -81,10 +114,8 @@ class App extends BaseConfig * language to use based on the value of the Accept-Language header. * * If false, no automatic detection will be performed. - * - * @var bool */ - public $negotiateLocale = false; + public bool $negotiateLocale = false; /** * -------------------------------------------------------------------------- @@ -95,9 +126,9 @@ class App extends BaseConfig * by the application in descending order of priority. If no match is * found, the first locale will be used. * - * @var string[] + * @var list */ - public $supportedLocales = ['de']; + public array $supportedLocales = ['de']; /** * -------------------------------------------------------------------------- @@ -106,10 +137,8 @@ class App extends BaseConfig * * The default timezone that will be used in your application to display * dates with the date helper, and can be retrieved through app_timezone() - * - * @var string */ - public $appTimezone = 'Europe/Vienna'; + public string $appTimezone = 'Europe/Vienna'; /** * -------------------------------------------------------------------------- @@ -120,10 +149,8 @@ class App extends BaseConfig * that require a character set to be provided. * * @see http://php.net/htmlspecialchars for a list of supported charsets. - * - * @var string */ - public $charset = 'UTF-8'; + public string $charset = 'UTF-8'; /** * -------------------------------------------------------------------------- @@ -134,314 +161,31 @@ class App extends BaseConfig * made via a secure connection (HTTPS). If the incoming request is not * secure, the user will be redirected to a secure version of the page * and the HTTP Strict Transport Security header will be set. - * - * @var bool */ - public $forceGlobalSecureRequests = false; + public bool $forceGlobalSecureRequests = false; - /** - * -------------------------------------------------------------------------- - * Session Driver - * -------------------------------------------------------------------------- - * - * The session storage driver to use: - * - `CodeIgniter\Session\Handlers\FileHandler` - * - `CodeIgniter\Session\Handlers\DatabaseHandler` - * - `CodeIgniter\Session\Handlers\MemcachedHandler` - * - `CodeIgniter\Session\Handlers\RedisHandler` - * - * @var string - */ - public $sessionDriver = FileHandler::class; - - /** - * -------------------------------------------------------------------------- - * Session Cookie Name - * -------------------------------------------------------------------------- - * - * The session cookie name, must contain only [0-9a-z_-] characters - * - * @var string - */ - public $sessionCookieName = 'ci_session'; - - /** - * -------------------------------------------------------------------------- - * Session Expiration - * -------------------------------------------------------------------------- - * - * The number of SECONDS you want the session to last. - * Setting to 0 (zero) means expire when the browser is closed. - * - * @var int - */ - public $sessionExpiration = 7200; - - /** - * -------------------------------------------------------------------------- - * Session Save Path - * -------------------------------------------------------------------------- - * - * The location to save sessions to and is driver dependent. - * - * For the 'files' driver, it's a path to a writable directory. - * WARNING: Only absolute paths are supported! - * - * For the 'database' driver, it's a table name. - * Please read up the manual for the format with other session drivers. - * - * IMPORTANT: You are REQUIRED to set a valid save path! - * - * @var string - */ - public $sessionSavePath = WRITEPATH . 'session'; - - /** - * -------------------------------------------------------------------------- - * Session Match IP - * -------------------------------------------------------------------------- - * - * Whether to match the user's IP address when reading the session data. - * - * WARNING: If you're using the database driver, don't forget to update - * your session table's PRIMARY KEY when changing this setting. - * - * @var bool - */ - public $sessionMatchIP = false; - - /** - * -------------------------------------------------------------------------- - * Session Time to Update - * -------------------------------------------------------------------------- - * - * How many seconds between CI regenerating the session ID. - * - * @var int - */ - public $sessionTimeToUpdate = 300; - - /** - * -------------------------------------------------------------------------- - * Session Regenerate Destroy - * -------------------------------------------------------------------------- - * - * Whether to destroy session data associated with the old session ID - * when auto-regenerating the session ID. When set to FALSE, the data - * will be later deleted by the garbage collector. - * - * @var bool - */ - public $sessionRegenerateDestroy = false; - - /** - * -------------------------------------------------------------------------- - * Cookie Prefix - * -------------------------------------------------------------------------- - * - * Set a cookie name prefix if you need to avoid collisions. - * - * @var string - * - * @deprecated use Config\Cookie::$prefix property instead. - */ - public $cookiePrefix = ''; - - /** - * -------------------------------------------------------------------------- - * Cookie Domain - * -------------------------------------------------------------------------- - * - * Set to `.your-domain.com` for site-wide cookies. - * - * @var string - * - * @deprecated use Config\Cookie::$domain property instead. - */ - public $cookieDomain = ''; - - /** - * -------------------------------------------------------------------------- - * Cookie Path - * -------------------------------------------------------------------------- - * - * Typically will be a forward slash. - * - * @var string - * - * @deprecated use Config\Cookie::$path property instead. - */ - public $cookiePath = '/'; - - /** - * -------------------------------------------------------------------------- - * Cookie Secure - * -------------------------------------------------------------------------- - * - * Cookie will only be set if a secure HTTPS connection exists. - * - * @var bool - * - * @deprecated use Config\Cookie::$secure property instead. - */ - public $cookieSecure = false; - - /** - * -------------------------------------------------------------------------- - * Cookie HttpOnly - * -------------------------------------------------------------------------- - * - * Cookie will only be accessible via HTTP(S) (no JavaScript). - * - * @var bool - * - * @deprecated use Config\Cookie::$httponly property instead. - */ - public $cookieHTTPOnly = true; - - /** - * -------------------------------------------------------------------------- - * Cookie SameSite - * -------------------------------------------------------------------------- - * - * Configure cookie SameSite setting. Allowed values are: - * - None - * - Lax - * - Strict - * - '' - * - * Alternatively, you can use the constant names: - * - `Cookie::SAMESITE_NONE` - * - `Cookie::SAMESITE_LAX` - * - `Cookie::SAMESITE_STRICT` - * - * Defaults to `Lax` for compatibility with modern browsers. Setting `''` - * (empty string) means default SameSite attribute set by browsers (`Lax`) - * will be set on cookies. If set to `None`, `$cookieSecure` must also be set. - * - * @var string|null - * - * @deprecated use Config\Cookie::$samesite property instead. - */ - public $cookieSameSite = 'Lax'; - - /** + /** * -------------------------------------------------------------------------- * Reverse Proxy IPs * -------------------------------------------------------------------------- * * If your server is behind a reverse proxy, you must whitelist the proxy * IP addresses from which CodeIgniter should trust headers such as - * HTTP_X_FORWARDED_FOR and HTTP_CLIENT_IP in order to properly identify + * X-Forwarded-For or Client-IP in order to properly identify * the visitor's IP address. * - * You can use both an array or a comma-separated list of proxy addresses, - * as well as specifying whole subnets. Here are a few examples: + * You need to set a proxy IP address or IP address with subnets and + * the HTTP header for the client IP address. * - * Comma-separated: '10.0.1.200,192.168.5.0/24' - * Array: ['10.0.1.200', '192.168.5.0/24'] + * Here are some examples: + * [ + * '10.0.1.200' => 'X-Forwarded-For', + * '192.168.5.0/24' => 'X-Real-IP', + * ] * - * @var string|string[] + * @var array */ - public $proxyIPs = ''; - - /** - * -------------------------------------------------------------------------- - * CSRF Token Name - * -------------------------------------------------------------------------- - * - * The token name. - * - * @deprecated Use `Config\Security` $tokenName property instead of using this property. - * - * @var string - */ - public $CSRFTokenName = 'csrf_test_name'; - - /** - * -------------------------------------------------------------------------- - * CSRF Header Name - * -------------------------------------------------------------------------- - * - * The header name. - * - * @deprecated Use `Config\Security` $headerName property instead of using this property. - * - * @var string - */ - public $CSRFHeaderName = 'X-CSRF-TOKEN'; - - /** - * -------------------------------------------------------------------------- - * CSRF Cookie Name - * -------------------------------------------------------------------------- - * - * The cookie name. - * - * @deprecated Use `Config\Security` $cookieName property instead of using this property. - * - * @var string - */ - public $CSRFCookieName = 'csrf_cookie_name'; - - /** - * -------------------------------------------------------------------------- - * CSRF Expire - * -------------------------------------------------------------------------- - * - * The number in seconds the token should expire. - * - * @deprecated Use `Config\Security` $expire property instead of using this property. - * - * @var int - */ - public $CSRFExpire = 7200; - - /** - * -------------------------------------------------------------------------- - * CSRF Regenerate - * -------------------------------------------------------------------------- - * - * Regenerate token on every submission? - * - * @deprecated Use `Config\Security` $regenerate property instead of using this property. - * - * @var bool - */ - public $CSRFRegenerate = true; - - /** - * -------------------------------------------------------------------------- - * CSRF Redirect - * -------------------------------------------------------------------------- - * - * Redirect to previous page with error on failure? - * - * @deprecated Use `Config\Security` $redirect property instead of using this property. - * - * @var bool - */ - public $CSRFRedirect = true; - - /** - * -------------------------------------------------------------------------- - * CSRF SameSite - * -------------------------------------------------------------------------- - * - * Setting for CSRF SameSite cookie token. Allowed values are: - * - None - * - Lax - * - Strict - * - '' - * - * Defaults to `Lax` as recommended in this link: - * - * @see https://portswigger.net/web-security/csrf/samesite-cookies - * @deprecated `Config\Cookie` $samesite property is used. - * - * @var string - */ - public $CSRFSameSite = 'Lax'; + public array $proxyIPs = []; /** * -------------------------------------------------------------------------- @@ -458,8 +202,6 @@ class App extends BaseConfig * * @see http://www.html5rocks.com/en/tutorials/security/content-security-policy/ * @see http://www.w3.org/TR/CSP/ - * - * @var bool */ - public $CSPEnabled = false; -} + public bool $CSPEnabled = false; + } diff --git a/app/Config/Auth.php b/app/Config/Auth.php index 6c89e98..1d5274b 100644 --- a/app/Config/Auth.php +++ b/app/Config/Auth.php @@ -2,13 +2,28 @@ declare(strict_types=1); +/** + * This file is part of CodeIgniter Shield. + * + * (c) CodeIgniter Foundation + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + namespace Config; use CodeIgniter\Shield\Config\Auth as ShieldAuth; use CodeIgniter\Shield\Authentication\Actions\ActionInterface; use CodeIgniter\Shield\Authentication\AuthenticatorInterface; use CodeIgniter\Shield\Authentication\Authenticators\AccessTokens; +use CodeIgniter\Shield\Authentication\Authenticators\HmacSha256; +use CodeIgniter\Shield\Authentication\Authenticators\JWT; use CodeIgniter\Shield\Authentication\Authenticators\Session; +use CodeIgniter\Shield\Authentication\Passwords\CompositionValidator; +use CodeIgniter\Shield\Authentication\Passwords\DictionaryValidator; +use CodeIgniter\Shield\Authentication\Passwords\NothingPersonalValidator; +use CodeIgniter\Shield\Authentication\Passwords\PwnedValidator; use CodeIgniter\Shield\Authentication\Passwords\ValidatorInterface; use CodeIgniter\Shield\Models\UserModel; @@ -19,9 +34,20 @@ class Auth extends ShieldAuth * AUTHENTICATION * //////////////////////////////////////////////////////////////////// */ + + // Constants for Record Login Attempts. Do not change. + public const RECORD_LOGIN_ATTEMPT_NONE = 0; // Do not record at all + public const RECORD_LOGIN_ATTEMPT_FAILURE = 1; // Record only failures + public const RECORD_LOGIN_ATTEMPT_ALL = 2; // Record all login attempts + + /** + * -------------------------------------------------------------------- + * View files + * -------------------------------------------------------------------- + */ public array $views = [ - 'login' => '\CodeIgniter\Shield\Views\login', - 'register' => '\CodeIgniter\Shield\Views\register', + 'login' => 'auth/login', + 'register' => 'auth/register', 'layout' => '\CodeIgniter\Shield\Views\layout', 'action_email_2fa' => '\CodeIgniter\Shield\Views\email_2fa_show', 'action_email_2fa_verify' => '\CodeIgniter\Shield\Views\email_2fa_verify', @@ -35,16 +61,25 @@ class Auth extends ShieldAuth /** * -------------------------------------------------------------------- - * Redirect urLs + * Redirect URLs * -------------------------------------------------------------------- - * The default URL that a user will be redirected to after - * various auth actions. If you need more flexibility you can - * override the `getUrl()` method to apply any logic you may need. + * The default URL that a user will be redirected to after various auth + * actions. This can be either of the following: + * + * 1. An absolute URL. E.g. http://example.com OR https://example.com + * 2. A named route that can be accessed using `route_to()` or `url_to()` + * 3. A URI path within the application. e.g 'admin', 'login', 'expath' + * + * If you need more flexibility you can override the `getUrl()` method + * to apply any logic you may need. */ public array $redirects = [ - 'register' => '/', - 'login' => '/', - 'logout' => 'login', + 'register' => '/', + 'login' => '/', + 'logout' => 'login', + 'force_reset' => '/', + 'permission_denied' => '/', + 'group_denied' => '/', ]; /** @@ -57,13 +92,13 @@ class Auth extends ShieldAuth * You must register actions in the order of the actions to be performed. * * Available actions with Shield: - * - register: 'CodeIgniter\Shield\Authentication\Actions\EmailActivator' - * - login: 'CodeIgniter\Shield\Authentication\Actions\Email2FA' + * - register: \CodeIgniter\Shield\Authentication\Actions\EmailActivator::class + * - login: \CodeIgniter\Shield\Authentication\Actions\Email2FA::class * * @var array|null> */ public array $actions = [ - 'register' => null, + 'register' => \CodeIgniter\Shield\Authentication\Actions\EmailActivator::class, 'login' => null, ]; @@ -81,29 +116,10 @@ class Auth extends ShieldAuth public array $authenticators = [ 'tokens' => AccessTokens::class, 'session' => Session::class, + 'hmac' => HmacSha256::class, + // 'jwt' => JWT::class, ]; - /** - * -------------------------------------------------------------------- - * Name of Authenticator Header - * -------------------------------------------------------------------- - * The name of Header that the Authorization token should be found. - * According to the specs, this should be `Authorization`, but rare - * circumstances might need a different header. - */ - public array $authenticatorHeader = [ - 'tokens' => 'Authorization', - ]; - - /** - * -------------------------------------------------------------------- - * Unused Token Lifetime - * -------------------------------------------------------------------- - * Determines the amount of time, in seconds, that an unused - * access token can be used. - */ - public int $unusedTokenLifetime = YEAR; - /** * -------------------------------------------------------------------- * Default Authenticator @@ -121,12 +137,13 @@ class Auth extends ShieldAuth * when using the 'chain' filter. Each Authenticator listed will be checked. * If no match is found, then the next in the chain will be checked. * - * @var string[] - * @phpstan-var list + * @var list */ public array $authenticationChain = [ 'session', 'tokens', + 'hmac', + // 'jwt', ]; /** @@ -142,7 +159,10 @@ class Auth extends ShieldAuth * Record Last Active Date * -------------------------------------------------------------------- * If true, will always update the `last_active` datetime for the - * logged in user on every page request. + * logged-in user on every page request. + * This feature only works when session/tokens filter is active. + * + * @see https://codeigniter4.github.io/shield/quick_start_guide/using_session_auth/#protecting-pages for set filters. */ public bool $recordActiveDate = true; @@ -188,6 +208,43 @@ class Auth extends ShieldAuth 'rememberLength' => 30 * DAY, ]; + /** + * -------------------------------------------------------------------- + * The validation rules for username + * -------------------------------------------------------------------- + * + * Do not use string rules like `required|valid_email`. + * + * @var array|string> + */ + public array $usernameValidationRules = [ + 'label' => 'Auth.username', + 'rules' => [ + 'required', + 'max_length[30]', + 'min_length[3]', + 'regex_match[/\A[a-zA-Z0-9\.]+\z/]', + ], + ]; + + /** + * -------------------------------------------------------------------- + * The validation rules for email + * -------------------------------------------------------------------- + * + * Do not use string rules like `required|valid_email`. + * + * @var array|string> + */ + public array $emailValidationRules = [ + 'label' => 'Auth.email', + 'rules' => [ + 'required', + 'max_length[254]', + 'valid_email', + ], + ]; + /** * -------------------------------------------------------------------- * Minimum Password Length @@ -206,13 +263,13 @@ class Auth extends ShieldAuth * You can add custom classes as long as they adhere to the * CodeIgniter\Shield\Authentication\Passwords\ValidatorInterface. * - * @var class-string[] + * @var list> */ public array $passwordValidators = [ - 'CodeIgniter\Shield\Authentication\Passwords\CompositionValidator', - 'CodeIgniter\Shield\Authentication\Passwords\NothingPersonalValidator', - 'CodeIgniter\Shield\Authentication\Passwords\DictionaryValidator', - //'CodeIgniter\Shield\Authentication\Passwords\PwnedValidator', + CompositionValidator::class, + NothingPersonalValidator::class, + DictionaryValidator::class, + // PwnedValidator::class, ]; /** @@ -278,56 +335,87 @@ class Auth extends ShieldAuth /** * -------------------------------------------------------------------- - * Encryption Algorithm to use + * Hashing Algorithm to use * -------------------------------------------------------------------- * Valid values are * - PASSWORD_DEFAULT (default) * - PASSWORD_BCRYPT * - PASSWORD_ARGON2I - As of PHP 7.2 only if compiled with support for it * - PASSWORD_ARGON2ID - As of PHP 7.3 only if compiled with support for it - * - * If you choose to use any ARGON algorithm, then you might want to - * uncomment the "ARGON2i/D Algorithm" options to suit your needs */ public string $hashAlgorithm = PASSWORD_DEFAULT; /** * -------------------------------------------------------------------- - * ARGON2i/D Algorithm options + * ARGON2I/ARGON2ID Algorithm options * -------------------------------------------------------------------- - * The ARGON2I method of encryption allows you to define the "memory_cost", + * The ARGON2I method of hashing allows you to define the "memory_cost", * the "time_cost" and the number of "threads", whenever a password hash is * created. - * This defaults to a value of 10 which is an acceptable number. - * However, depending on the security needs of your application - * and the power of your hardware, you might want to increase the - * cost. This makes the hashing process takes longer. */ - public int $hashMemoryCost = 2048; // PASSWORD_ARGON2_DEFAULT_MEMORY_COST; + public int $hashMemoryCost = 65536; // PASSWORD_ARGON2_DEFAULT_MEMORY_COST; - public int $hashTimeCost = 4; // PASSWORD_ARGON2_DEFAULT_TIME_COST; - public int $hashThreads = 4; // PASSWORD_ARGON2_DEFAULT_THREADS; + public int $hashTimeCost = 4; // PASSWORD_ARGON2_DEFAULT_TIME_COST; + public int $hashThreads = 1; // PASSWORD_ARGON2_DEFAULT_THREADS; /** * -------------------------------------------------------------------- - * Password Hashing Cost + * BCRYPT Algorithm options * -------------------------------------------------------------------- - * The BCRYPT method of encryption allows you to define the "cost" + * The BCRYPT method of hashing allows you to define the "cost" * or number of iterations made, whenever a password hash is created. - * This defaults to a value of 10 which is an acceptable number. + * This defaults to a value of 12 which is an acceptable number. * However, depending on the security needs of your application * and the power of your hardware, you might want to increase the * cost. This makes the hashing process takes longer. * * Valid range is between 4 - 31. */ - public int $hashCost = 10; + public int $hashCost = 12; /** * //////////////////////////////////////////////////////////////////// * OTHER SETTINGS * //////////////////////////////////////////////////////////////////// */ + + /** + * -------------------------------------------------------------------- + * Customize the DB group used for each model + * -------------------------------------------------------------------- + */ + public ?string $DBGroup = null; + + /** + * -------------------------------------------------------------------- + * Customize Name of Shield Tables + * -------------------------------------------------------------------- + * Only change if you want to rename the default Shield table names + * + * It may be necessary to change the names of the tables for + * security reasons, to prevent the conflict of table names, + * the internal policy of the companies or any other reason. + * + * - users Auth Users Table, the users info is stored. + * - auth_identities Auth Identities Table, Used for storage of passwords, access tokens, social login identities, etc. + * - auth_logins Auth Login Attempts, Table records login attempts. + * - auth_token_logins Auth Token Login Attempts Table, Records Bearer Token type login attempts. + * - auth_remember_tokens Auth Remember Tokens (remember-me) Table. + * - auth_groups_users Groups Users Table. + * - auth_permissions_users Users Permissions Table. + * + * @var array + */ + public array $tables = [ + 'users' => 'users', + 'identities' => 'auth_identities', + 'logins' => 'auth_logins', + 'token_logins' => 'auth_token_logins', + 'remember_tokens' => 'auth_remember_tokens', + 'groups_users' => 'auth_groups_users', + 'permissions_users' => 'auth_permissions_users', + ]; + /** * -------------------------------------------------------------------- * User Provider @@ -340,7 +428,7 @@ class Auth extends ShieldAuth * * @var class-string */ - public string $userProvider = 'CodeIgniter\Shield\Models\UserModel'; + public string $userProvider = UserModel::class; /** * Returns the URL that a user should be redirected @@ -348,7 +436,8 @@ class Auth extends ShieldAuth */ public function loginRedirect(): string { - $url = setting('Auth.redirects')['login']; + $session = session(); + $url = $session->getTempdata('beforeLoginUrl') ?? setting('Auth.redirects')['login']; return $this->getUrl($url); } @@ -375,10 +464,65 @@ class Auth extends ShieldAuth return $this->getUrl($url); } + /** + * Returns the URL the user should be redirected to + * if force_reset identity is set to true. + */ + public function forcePasswordResetRedirect(): string + { + $url = setting('Auth.redirects')['force_reset']; + + return $this->getUrl($url); + } + + /** + * Returns the URL the user should be redirected to + * if permission denied. + */ + public function permissionDeniedRedirect(): string + { + $url = setting('Auth.redirects')['permission_denied']; + + return $this->getUrl($url); + } + + /** + * Returns the URL the user should be redirected to + * if group denied. + */ + public function groupDeniedRedirect(): string + { + $url = setting('Auth.redirects')['group_denied']; + + return $this->getUrl($url); + } + + /** + * Accepts a string which can be an absolute URL or + * a named route or just a URI path, and returns the + * full path. + * + * @param string $url an absolute URL or a named route or just URI path + */ protected function getUrl(string $url): string { - return strpos($url, 'http') === 0 - ? $url - : rtrim(site_url($url), '/ '); + // To accommodate all url patterns + $final_url = ''; + + switch (true) { + case strpos($url, 'http://') === 0 || strpos($url, 'https://') === 0: // URL begins with 'http' or 'https'. E.g. http://example.com + $final_url = $url; + break; + + case route_to($url) !== false: // URL is a named-route + $final_url = rtrim(url_to($url), '/ '); + break; + + default: // URL is a route (URI path) + $final_url = rtrim(site_url($url), '/ '); + break; + } + + return $final_url; } } diff --git a/app/Config/AuthGroups.php b/app/Config/AuthGroups.php index d13e244..fc02457 100644 --- a/app/Config/AuthGroups.php +++ b/app/Config/AuthGroups.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/** + * This file is part of CodeIgniter Shield. + * + * (c) CodeIgniter Foundation + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + namespace Config; use CodeIgniter\Shield\Config\AuthGroups as ShieldAuthGroups; @@ -20,10 +29,16 @@ class AuthGroups extends ShieldAuthGroups * -------------------------------------------------------------------- * Groups * -------------------------------------------------------------------- - * The available authentication systems, listed - * with alias and class name. These can be referenced - * by alias in the auth helper: - * auth('api')->attempt($credentials); + * An associative array of the available groups in the system, where the keys + * are the group names and the values are arrays of the group info. + * + * Whatever value you assign as the key will be used to refer to the group + * when using functions such as: + * $user->addGroup('superadmin'); + * + * @var array> + * + * @see https://codeigniter4.github.io/shield/quick_start_guide/using_authorization/#change-available-groups for more info */ public array $groups = [ 'superadmin' => [ @@ -34,17 +49,17 @@ class AuthGroups extends ShieldAuthGroups 'title' => 'Admin', 'description' => 'Day to day administrators of the site.', ], - 'developer' => [ - 'title' => 'Developer', - 'description' => 'Site programmers.', + 'finanzen' => [ + 'title' => 'Finanzmanger User', + 'description' => 'Buchhaltung.', ], 'user' => [ 'title' => 'User', 'description' => 'General users of the site. Often customers.', ], - 'beta' => [ - 'title' => 'Beta User', - 'description' => 'Has access to beta-level features.', + 'smarthome' => [ + 'title' => 'Smarthome User', + 'description' => 'Kann Smarthome eingeschränkt benutzen.', ], ]; @@ -52,8 +67,7 @@ class AuthGroups extends ShieldAuthGroups * -------------------------------------------------------------------- * Permissions * -------------------------------------------------------------------- - * The available permissions in the system. Each system is defined - * where the key is the + * The available permissions in the system. * * If a permission is not listed here it cannot be used. */ @@ -64,20 +78,28 @@ class AuthGroups extends ShieldAuthGroups 'users.create' => 'Can create new non-admin users', 'users.edit' => 'Can edit existing non-admin users', 'users.delete' => 'Can delete existing non-admin users', - 'beta.access' => 'Can access beta-level features', - ]; + 'finanzen.view' => 'Can view FinanzManager', + 'finanzen.change' => 'Can use FinanzManager', + 'smarthome.settings' => 'Can change settings in smarthome', + 'smarthome.action' => 'Can switch lights in smarthome', + 'smarthome.view' => 'Can view smarthome site', + ]; /** * -------------------------------------------------------------------- * Permissions Matrix * -------------------------------------------------------------------- * Maps permissions to groups. + * + * This defines group-level permissions. */ public array $matrix = [ 'superadmin' => [ 'admin.*', 'users.*', - 'beta.*', + 'smarthome.*', + 'finanzen.*', + ], 'admin' => [ 'admin.access', @@ -86,16 +108,15 @@ class AuthGroups extends ShieldAuthGroups 'users.delete', 'beta.access', ], - 'developer' => [ - 'admin.access', - 'admin.settings', - 'users.create', - 'users.edit', - 'beta.access', + 'finanzen' => [ + 'finanzen.view', + 'finanzen.change', ], - 'user' => [], - 'beta' => [ - 'beta.access', + 'user' => [ + 'smarthome.view', + ], + 'smarthome' => [ + 'smarthome.action', ], ]; } diff --git a/app/Config/AuthToken.php b/app/Config/AuthToken.php new file mode 100644 index 0000000..7ad404f --- /dev/null +++ b/app/Config/AuthToken.php @@ -0,0 +1,138 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +namespace Config; + +use CodeIgniter\Shield\Config\AuthToken as ShieldAuthToken; + +/** + * Configuration for Token Auth and HMAC Auth + */ +class AuthToken extends ShieldAuthToken +{ + /** + * -------------------------------------------------------------------- + * Record Login Attempts for Token Auth and HMAC Auth + * -------------------------------------------------------------------- + * Specify which login attempts are recorded in the database. + * + * Valid values are: + * - Auth::RECORD_LOGIN_ATTEMPT_NONE + * - Auth::RECORD_LOGIN_ATTEMPT_FAILURE + * - Auth::RECORD_LOGIN_ATTEMPT_ALL + */ + public int $recordLoginAttempt = Auth::RECORD_LOGIN_ATTEMPT_FAILURE; + + /** + * -------------------------------------------------------------------- + * Name of Authenticator Header + * -------------------------------------------------------------------- + * The name of Header that the Authorization token should be found. + * According to the specs, this should be `Authorization`, but rare + * circumstances might need a different header. + */ + public array $authenticatorHeader = [ + 'tokens' => 'Authorization', + 'hmac' => 'Authorization', + ]; + + /** + * -------------------------------------------------------------------- + * Unused Token Lifetime for Token Auth and HMAC Auth + * -------------------------------------------------------------------- + * Determines the amount of time, in seconds, that an unused token can + * be used. + */ + public int $unusedTokenLifetime = YEAR; + + /** + * -------------------------------------------------------------------- + * Secret2 storage character limit + * -------------------------------------------------------------------- + * Database size limit for the identities 'secret2' field. + */ + public int $secret2StorageLimit = 255; + + /** + * -------------------------------------------------------------------- + * HMAC secret key byte size + * -------------------------------------------------------------------- + * Specify in integer the desired byte size of the + * HMAC SHA256 byte size + */ + public int $hmacSecretKeyByteSize = 32; + + /** + * -------------------------------------------------------------------- + * HMAC encryption Keys + * -------------------------------------------------------------------- + * This sets the key to be used when encrypting a user's HMAC Secret Key. + * + * 'keys' is an array of keys which will facilitate key rotation. Valid + * keyTitles must include only [a-zA-Z0-9_] and should be kept to a + * max of 8 characters. + * + * Each keyTitle is an associative array containing the required 'key' + * value, and the optional 'driver' and 'digest' values. If the + * 'driver' and 'digest' values are not specified, the default 'driver' + * and 'digest' values will be used. + * + * Old keys will are used to decrypt existing Secret Keys. It is encouraged + * to run 'php spark shield:hmac reencrypt' to update existing Secret + * Key encryptions. + * + * @see https://codeigniter.com/user_guide/libraries/encryption.html + * + * @var array|string + * + * NOTE: The value becomes temporarily a string when setting value as JSON + * from environment variable. + * + * [key_name => ['key' => key_value]] + * or [key_name => ['key' => key_value, 'driver' => driver, 'digest' => digest]] + */ + public $hmacEncryptionKeys = [ + 'k1' => [ + 'key' => '', + ], + ]; + + /** + * -------------------------------------------------------------------- + * HMAC Current Encryption Key Selector + * -------------------------------------------------------------------- + * This specifies which of the encryption keys should be used. + */ + public string $hmacEncryptionCurrentKey = 'k1'; + + /** + * -------------------------------------------------------------------- + * HMAC Encryption Key Driver + * -------------------------------------------------------------------- + * This specifies which of the encryption drivers should be used. + * + * Available drivers: + * - OpenSSL + * - Sodium + */ + public string $hmacEncryptionDefaultDriver = 'OpenSSL'; + + /** + * -------------------------------------------------------------------- + * HMAC Encryption Key Driver + * -------------------------------------------------------------------- + * THis specifies the type of encryption to be used. + * e.g. 'SHA512' or 'SHA256'. + */ + public string $hmacEncryptionDefaultDigest = 'SHA512'; +} diff --git a/app/Config/Autoload.php b/app/Config/Autoload.php index ee27e3b..2464e8b 100644 --- a/app/Config/Autoload.php +++ b/app/Config/Autoload.php @@ -13,7 +13,12 @@ use CodeIgniter\Config\AutoloadConfig; * can find the files as needed. * * NOTE: If you use an identical key in $psr4 or $classmap, then - * the values in this file will overwrite the framework's values. + * the values in this file will overwrite the framework's values. + * + * NOTE: This class is required prior to Autoloader instantiation, + * and does not extend BaseConfig. + * + * @immutable */ class Autoload extends AutoloadConfig { @@ -25,24 +30,17 @@ class Autoload extends AutoloadConfig * their location on the file system. These are used by the autoloader * to locate files the first time they have been instantiated. * - * The '/app' and '/system' directories are already mapped for you. - * you may change the name of the 'App' namespace if you wish, + * The 'Config' (APPPATH . 'Config') and 'CodeIgniter' (SYSTEMPATH) are + * already mapped for you. + * + * You may change the name of the 'App' namespace if you wish, * but this should be done prior to creating any namespaced classes, * else you will need to modify all of those classes for this to work. * - * Prototype: - *``` - * $psr4 = [ - * 'CodeIgniter' => SYSTEMPATH, - * 'App' => APPPATH - * ]; - *``` - * - * @var array + * @var array|string> */ public $psr4 = [ - APP_NAMESPACE => APPPATH, // For custom app namespace - 'Config' => APPPATH . 'Config', + APP_NAMESPACE => APPPATH, ]; /** @@ -56,11 +54,9 @@ class Autoload extends AutoloadConfig * were being autoloaded through a namespace. * * Prototype: - *``` * $classmap = [ * 'MyClass' => '/path/to/class/file.php' * ]; - *``` * * @var array */ @@ -75,13 +71,24 @@ class Autoload extends AutoloadConfig * or for loading functions. * * Prototype: - * ``` - * $files = [ - * '/path/to/my/file.php', - * ]; - * ``` + * $files = [ + * '/path/to/my/file.php', + * ]; * - * @var array + * @var list */ public $files = []; -} + + /** + * ------------------------------------------------------------------- + * Helpers + * ------------------------------------------------------------------- + * Prototype: + * $helpers = [ + * 'form', + * ]; + * + * @var list + */ + public $helpers = ['auth', 'setting']; + } diff --git a/app/Config/Boot/development.php b/app/Config/Boot/development.php index 05a8612..a868447 100644 --- a/app/Config/Boot/development.php +++ b/app/Config/Boot/development.php @@ -7,8 +7,10 @@ | In development, we want to show as many errors as possible to help | make sure they don't make it to production. And save us hours of | painful debugging. + | + | If you set 'display_errors' to '1', CI4's detailed error report will show. */ -error_reporting(-1); +error_reporting(E_ALL); ini_set('display_errors', '1'); /* diff --git a/app/Config/Boot/production.php b/app/Config/Boot/production.php index 21d2580..1822cf5 100644 --- a/app/Config/Boot/production.php +++ b/app/Config/Boot/production.php @@ -6,9 +6,13 @@ |-------------------------------------------------------------------------- | Don't show ANY in production environments. Instead, let the system catch | it and display a generic error message. + | + | If you set 'display_errors' to '1', CI4's detailed error report will show. */ +error_reporting(E_ALL & ~E_DEPRECATED); +// If you want to suppress more types of errors. +// error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_STRICT & ~E_USER_NOTICE & ~E_USER_DEPRECATED); ini_set('display_errors', '0'); -error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_STRICT & ~E_USER_NOTICE & ~E_USER_DEPRECATED); /* |-------------------------------------------------------------------------- diff --git a/app/Config/Boot/testing.php b/app/Config/Boot/testing.php index e07a1d4..40b6ca8 100644 --- a/app/Config/Boot/testing.php +++ b/app/Config/Boot/testing.php @@ -1,5 +1,11 @@ */ - public $file = [ + public array $file = [ 'storePath' => WRITEPATH . 'cache/', 'mode' => 0640, ]; @@ -134,9 +105,9 @@ class Cache extends BaseConfig * * @see https://codeigniter.com/user_guide/libraries/caching.html#memcached * - * @var array + * @var array */ - public $memcached = [ + public array $memcached = [ 'host' => '127.0.0.1', 'port' => 11211, 'weight' => 1, @@ -152,7 +123,7 @@ class Cache extends BaseConfig * * @var array */ - public $redis = [ + public array $redis = [ 'host' => '127.0.0.1', 'password' => null, 'port' => 6379, @@ -168,9 +139,9 @@ class Cache extends BaseConfig * This is an array of cache engine alias' and class names. Only engines * that are listed here are allowed to be used. * - * @var array + * @var array> */ - public $validHandlers = [ + public array $validHandlers = [ 'dummy' => DummyHandler::class, 'file' => FileHandler::class, 'memcached' => MemcachedHandler::class, @@ -178,4 +149,23 @@ class Cache extends BaseConfig 'redis' => RedisHandler::class, 'wincache' => WincacheHandler::class, ]; + + /** + * -------------------------------------------------------------------------- + * Web Page Caching: Cache Include Query String + * -------------------------------------------------------------------------- + * + * Whether to take the URL query string into consideration when generating + * output cache files. Valid options are: + * + * false = Disabled + * true = Enabled, take all query parameters into account. + * Please be aware that this may result in numerous cache + * files generated for the same page over and over again. + * ['q'] = Enabled, but only take into account the specified list + * of query parameters. + * + * @var bool|list + */ + public $cacheQueryString = false; } diff --git a/app/Config/Cookie.php b/app/Config/Cookie.php index 8ee01c7..93446bc 100644 --- a/app/Config/Cookie.php +++ b/app/Config/Cookie.php @@ -13,10 +13,8 @@ class Cookie extends BaseConfig * -------------------------------------------------------------------------- * * Set a cookie name prefix if you need to avoid collisions. - * - * @var string */ - public $prefix = ''; + public string $prefix = ''; /** * -------------------------------------------------------------------------- @@ -37,10 +35,8 @@ class Cookie extends BaseConfig * -------------------------------------------------------------------------- * * Typically will be a forward slash. - * - * @var string */ - public $path = '/'; + public string $path = '/'; /** * -------------------------------------------------------------------------- @@ -48,10 +44,8 @@ class Cookie extends BaseConfig * -------------------------------------------------------------------------- * * Set to `.your-domain.com` for site-wide cookies. - * - * @var string - */ - public $domain = ''; + */ + public string $domain = ''; /** * -------------------------------------------------------------------------- @@ -59,10 +53,8 @@ class Cookie extends BaseConfig * -------------------------------------------------------------------------- * * Cookie will only be set if a secure HTTPS connection exists. - * - * @var bool */ - public $secure = false; + public bool $secure = false; /** * -------------------------------------------------------------------------- @@ -70,10 +62,8 @@ class Cookie extends BaseConfig * -------------------------------------------------------------------------- * * Cookie will only be accessible via HTTP(S) (no JavaScript). - * - * @var bool */ - public $httponly = true; + public bool $httponly = true; /** * -------------------------------------------------------------------------- @@ -94,10 +84,8 @@ class Cookie extends BaseConfig * Defaults to `Lax` for compatibility with modern browsers. Setting `''` * (empty string) means default SameSite attribute set by browsers (`Lax`) * will be set on cookies. If set to `None`, `$secure` must also be set. - * - * @var string */ - public $samesite = 'Lax'; + public string $samesite = 'Lax'; /** * -------------------------------------------------------------------------- @@ -110,10 +98,8 @@ class Cookie extends BaseConfig * If this is set to `true`, cookie names should be compliant of RFC 2616's * list of allowed characters. * - * @var bool - * * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#attributes * @see https://tools.ietf.org/html/rfc2616#section-2.2 */ - public $raw = false; + public bool $raw = false; } diff --git a/app/Config/Cors.php b/app/Config/Cors.php new file mode 100644 index 0000000..2b4edf6 --- /dev/null +++ b/app/Config/Cors.php @@ -0,0 +1,105 @@ +, + * allowedOriginsPatterns: list, + * supportsCredentials: bool, + * allowedHeaders: list, + * exposedHeaders: list, + * allowedMethods: list, + * maxAge: int, + * } + */ + public array $default = [ + /** + * Origins for the `Access-Control-Allow-Origin` header. + * + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin + * + * E.g.: + * - ['http://localhost:8080'] + * - ['https://www.example.com'] + */ + 'allowedOrigins' => [], + + /** + * Origin regex patterns for the `Access-Control-Allow-Origin` header. + * + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin + * + * NOTE: A pattern specified here is part of a regular expression. It will + * be actually `#\A\z#`. + * + * E.g.: + * - ['https://\w+\.example\.com'] + */ + 'allowedOriginsPatterns' => [], + + /** + * Weather to send the `Access-Control-Allow-Credentials` header. + * + * The Access-Control-Allow-Credentials response header tells browsers whether + * the server allows cross-origin HTTP requests to include credentials. + * + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials + */ + 'supportsCredentials' => false, + + /** + * Set headers to allow. + * + * The Access-Control-Allow-Headers response header is used in response to + * a preflight request which includes the Access-Control-Request-Headers to + * indicate which HTTP headers can be used during the actual request. + * + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers + */ + 'allowedHeaders' => [], + + /** + * Set headers to expose. + * + * The Access-Control-Expose-Headers response header allows a server to + * indicate which response headers should be made available to scripts running + * in the browser, in response to a cross-origin request. + * + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers + */ + 'exposedHeaders' => [], + + /** + * Set methods to allow. + * + * The Access-Control-Allow-Methods response header specifies one or more + * methods allowed when accessing a resource in response to a preflight + * request. + * + * E.g.: + * - ['GET', 'POST', 'PUT', 'DELETE'] + * + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Methods + */ + 'allowedMethods' => [], + + /** + * Set how many seconds the results of a preflight request can be cached. + * + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age + */ + 'maxAge' => 7200, + ]; +} diff --git a/app/Config/Database.php b/app/Config/Database.php index 6b43aa6..ed23d30 100644 --- a/app/Config/Database.php +++ b/app/Config/Database.php @@ -31,20 +31,16 @@ class Database extends Config * @var array */ public $default = [ - 'DSN' => 'host=192.168.16.14;dbname=mawim;user=finanzen;password=/mA!FZ22Wi', -// 'hostname' => 'localhost', +// 'DSN' => 'host=192.168.16.14;dbname=mawim;user=finanzen;password=/mA!FZ22Wi', + 'hostname' => '192.168.16.14', + 'database' => 'mawim', + 'username' => 'finanzen', + 'password' => '/mA!FZ22Wi', + 'port' => 5432, + 'charset' => 'utf8', 'DBDriver' => 'Postgre', + 'DBDebug' => false, 'schema' => 'finanzen,verwaltung', -// 'DBPrefix' => '', -// 'pConnect' => false, - 'DBDebug' => (ENVIRONMENT !== 'production'), -// 'charset' => 'utf8', -// 'DBCollat' => 'utf8_general_ci', -// 'swapPre' => '', -// 'encrypt' => false, -// 'compress' => false, -// 'strictOn' => false, -// 'failover' => [], ]; /** @@ -63,8 +59,8 @@ class Database extends Config 'DBPrefix' => 'db_', // Needed to ensure we're working correctly with prefixes live. DO NOT REMOVE FOR CI DEVS 'pConnect' => false, 'DBDebug' => (ENVIRONMENT !== 'production'), - 'charset' => 'utf8', - 'DBCollat' => 'utf8_general_ci', + 'charset' => 'utf8mb4', + 'DBCollat' => 'utf8mb4_general_ci', 'swapPre' => '', 'encrypt' => false, 'compress' => false, diff --git a/app/Config/DocTypes.php b/app/Config/DocTypes.php index 6f16693..7e8aaac 100755 --- a/app/Config/DocTypes.php +++ b/app/Config/DocTypes.php @@ -2,6 +2,9 @@ namespace Config; +/** + * @immutable + */ class DocTypes { /** @@ -9,7 +12,7 @@ class DocTypes * * @var array */ - public $list = [ + public array $list = [ 'xhtml11' => '', 'xhtml1-strict' => '', 'xhtml1-trans' => '', @@ -30,4 +33,14 @@ class DocTypes 'xhtml-rdfa-1' => '', 'xhtml-rdfa-2' => '', ]; + + /** + * Whether to remove the solidus (`/`) character for void HTML elements (e.g. ``) + * for HTML5 compatibility. + * + * Set to: + * `true` - to be HTML5 compatible + * `false` - to be XHTML compatible + */ + public bool $html5 = true; } diff --git a/app/Config/Email.php b/app/Config/Email.php index 3a42fbe..758e8ea 100644 --- a/app/Config/Email.php +++ b/app/Config/Email.php @@ -6,165 +6,114 @@ use CodeIgniter\Config\BaseConfig; class Email extends BaseConfig { - /** - * @var string - */ - public $fromEmail; + public string $fromEmail = "webmaster@mawim.at"; - /** - * @var string - */ - public $fromName; + public string $fromName = "Webmaster Smarthome"; - /** - * @var string - */ - public $recipients; + public string $recipients = ''; /** * The "user agent" - * - * @var string */ - public $userAgent = 'CodeIgniter'; + public string $userAgent = 'CodeIgniter'; /** * The mail sending protocol: mail, sendmail, smtp - * - * @var string */ - public $protocol = 'mail'; + public string $protocol = 'sendmail'; /** * The server path to Sendmail. - * - * @var string */ - public $mailPath = '/usr/sbin/sendmail'; + public string $mailPath = '/usr/sbin/sendmail'; /** * SMTP Server Address - * - * @var string */ - public $SMTPHost; + public string $SMTPHost ="web110.dogado.de"; /** * SMTP Username - * - * @var string */ - public $SMTPUser; + public string $SMTPUser = "markus@mawim.at"; /** * SMTP Password - * - * @var string */ - public $SMTPPass; + public string $SMTPPass ="3c2efe"; /** * SMTP Port - * - * @var int */ - public $SMTPPort = 25; + public int $SMTPPort = 465; /** * SMTP Timeout (in seconds) - * - * @var int */ - public $SMTPTimeout = 5; + public int $SMTPTimeout = 5; /** * Enable persistent SMTP connections - * - * @var bool */ - public $SMTPKeepAlive = false; + public bool $SMTPKeepAlive = false; /** * SMTP Encryption. Either tls or ssl - * - * @var string */ - public $SMTPCrypto = 'tls'; + public string $SMTPCrypto = ''; /** * Enable word-wrap - * - * @var bool */ - public $wordWrap = true; + public bool $wordWrap = true; /** * Character count to wrap at - * - * @var int */ - public $wrapChars = 76; + public int $wrapChars = 76; /** * Type of mail, either 'text' or 'html' - * - * @var string */ - public $mailType = 'text'; + public string $mailType = 'html'; /** * Character set (utf-8, iso-8859-1, etc.) - * - * @var string */ - public $charset = 'UTF-8'; + public string $charset = 'UTF-8'; /** * Whether to validate the email address - * - * @var bool */ - public $validate = false; + public bool $validate = false; /** * Email Priority. 1 = highest. 5 = lowest. 3 = normal - * - * @var int */ - public $priority = 3; + public int $priority = 3; /** * Newline character. (Use “\r\n” to comply with RFC 822) - * - * @var string */ - public $CRLF = "\r\n"; + public string $CRLF = "\r\n"; /** * Newline character. (Use “\r\n” to comply with RFC 822) - * - * @var string */ - public $newline = "\r\n"; + public string $newline = "\r\n"; /** * Enable BCC Batch Mode. - * - * @var bool */ - public $BCCBatchMode = false; + public bool $BCCBatchMode = false; /** * Number of emails in each BCC batch - * - * @var int */ - public $BCCBatchSize = 200; + public int $BCCBatchSize = 200; /** * Enable notify message from server - * - * @var bool */ - public $DSN = false; + public bool $DSN = false; } diff --git a/app/Config/Encryption.php b/app/Config/Encryption.php index 07b45a0..2834413 100644 --- a/app/Config/Encryption.php +++ b/app/Config/Encryption.php @@ -20,10 +20,8 @@ class Encryption extends BaseConfig * If you use the Encryption class you must set an encryption key (seed). * You need to ensure it is long enough for the cipher and mode you plan to use. * See the user guide for more info. - * - * @var string */ - public $key = ''; + public string $key = ''; /** * -------------------------------------------------------------------------- @@ -35,10 +33,8 @@ class Encryption extends BaseConfig * Available drivers: * - OpenSSL * - Sodium - * - * @var string */ - public $driver = 'OpenSSL'; + public string $driver = 'OpenSSL'; /** * -------------------------------------------------------------------------- @@ -49,10 +45,8 @@ class Encryption extends BaseConfig * before it is encrypted. This value should be greater than zero. * * See the user guide for more information on padding. - * - * @var int */ - public $blockSize = 16; + public int $blockSize = 16; /** * -------------------------------------------------------------------------- @@ -60,8 +54,39 @@ class Encryption extends BaseConfig * -------------------------------------------------------------------------- * * HMAC digest to use, e.g. 'SHA512' or 'SHA256'. Default value is 'SHA512'. - * - * @var string */ - public $digest = 'SHA512'; + public string $digest = 'SHA512'; + + /** + * Whether the cipher-text should be raw. If set to false, then it will be base64 encoded. + * This setting is only used by OpenSSLHandler. + * + * Set to false for CI3 Encryption compatibility. + */ + public bool $rawData = true; + + /** + * Encryption key info. + * This setting is only used by OpenSSLHandler. + * + * Set to 'encryption' for CI3 Encryption compatibility. + */ + public string $encryptKeyInfo = ''; + + /** + * Authentication key info. + * This setting is only used by OpenSSLHandler. + * + * Set to 'authentication' for CI3 Encryption compatibility. + */ + public string $authKeyInfo = ''; + + /** + * Cipher to use. + * This setting is only used by OpenSSLHandler. + * + * Set to 'AES-128-CBC' to decrypt encrypted data that encrypted + * by CI3 Encryption default configuration. + */ + public string $cipher = 'AES-256-CTR'; } diff --git a/app/Config/Events.php b/app/Config/Events.php index 5219f4a..62a7b86 100644 --- a/app/Config/Events.php +++ b/app/Config/Events.php @@ -4,6 +4,7 @@ namespace Config; use CodeIgniter\Events\Events; use CodeIgniter\Exceptions\FrameworkException; +use CodeIgniter\HotReloader\HotReloader; /* * -------------------------------------------------------------------- @@ -22,7 +23,7 @@ use CodeIgniter\Exceptions\FrameworkException; * Events::on('create', [$myInstance, 'myMethod']); */ -Events::on('pre_system', static function () { +Events::on('pre_system', static function (): void { if (ENVIRONMENT !== 'testing') { if (ini_get('zlib.output_compression')) { throw FrameworkException::forEnabledZlibOutputCompression(); @@ -44,5 +45,11 @@ Events::on('pre_system', static function () { if (CI_DEBUG && ! is_cli()) { Events::on('DBQuery', 'CodeIgniter\Debug\Toolbar\Collectors\Database::collect'); Services::toolbar()->respond(); + // Hot Reload route - for framework use on the hot reloader. + if (ENVIRONMENT === 'development') { + Services::routes()->get('__hot-reload', static function (): void { + (new HotReloader())->run(); + }); + } } }); diff --git a/app/Config/Exceptions.php b/app/Config/Exceptions.php index 7cbc78a..4e33963 100644 --- a/app/Config/Exceptions.php +++ b/app/Config/Exceptions.php @@ -3,6 +3,10 @@ namespace Config; use CodeIgniter\Config\BaseConfig; +use CodeIgniter\Debug\ExceptionHandler; +use CodeIgniter\Debug\ExceptionHandlerInterface; +use Psr\Log\LogLevel; +use Throwable; /** * Setup how the exception handler works. @@ -17,10 +21,8 @@ class Exceptions extends BaseConfig * through Services::Log. * * Default: true - * - * @var bool */ - public $log = true; + public bool $log = true; /** * -------------------------------------------------------------------------- @@ -29,9 +31,9 @@ class Exceptions extends BaseConfig * Any status codes here will NOT be logged if logging is turned on. * By default, only 404 (Page Not Found) exceptions are ignored. * - * @var array + * @var list */ - public $ignoreCodes = [404]; + public array $ignoreCodes = [404]; /** * -------------------------------------------------------------------------- @@ -41,10 +43,8 @@ class Exceptions extends BaseConfig * directories that hold the views used to generate errors. * * Default: APPPATH.'Views/errors' - * - * @var string */ - public $errorViewPath = APPPATH . 'Views/errors'; + public string $errorViewPath = APPPATH . 'Views/errors'; /** * -------------------------------------------------------------------------- @@ -54,7 +54,53 @@ class Exceptions extends BaseConfig * In order to specify 2 levels, use "/" to separate. * ex. ['server', 'setup/password', 'secret_token'] * - * @var array + * @var list */ - public $sensitiveDataInTrace = []; + public array $sensitiveDataInTrace = []; + + /** + * -------------------------------------------------------------------------- + * WHETHER TO THROW AN EXCEPTION ON DEPRECATED ERRORS + * -------------------------------------------------------------------------- + * If set to `true`, DEPRECATED errors are only logged and no exceptions are + * thrown. This option also works for user deprecations. + */ + public bool $logDeprecations = true; + + /** + * -------------------------------------------------------------------------- + * LOG LEVEL THRESHOLD FOR DEPRECATIONS + * -------------------------------------------------------------------------- + * If `$logDeprecations` is set to `true`, this sets the log level + * to which the deprecation will be logged. This should be one of the log + * levels recognized by PSR-3. + * + * The related `Config\Logger::$threshold` should be adjusted, if needed, + * to capture logging the deprecations. + */ + public string $deprecationLogLevel = LogLevel::WARNING; + + /* + * DEFINE THE HANDLERS USED + * -------------------------------------------------------------------------- + * Given the HTTP status code, returns exception handler that + * should be used to deal with this error. By default, it will run CodeIgniter's + * default handler and display the error information in the expected format + * for CLI, HTTP, or AJAX requests, as determined by is_cli() and the expected + * response format. + * + * Custom handlers can be returned if you want to handle one or more specific + * error codes yourself like: + * + * if (in_array($statusCode, [400, 404, 500])) { + * return new \App\Libraries\MyExceptionHandler(); + * } + * if ($exception instanceOf PageNotFoundException) { + * return new \App\Libraries\MyExceptionHandler(); + * } + */ + public function handler(int $statusCode, Throwable $exception): ExceptionHandlerInterface + { + return new ExceptionHandler($this); + } } diff --git a/app/Config/Feature.php b/app/Config/Feature.php index 4c5ec90..efd4a0b 100644 --- a/app/Config/Feature.php +++ b/app/Config/Feature.php @@ -9,24 +9,21 @@ use CodeIgniter\Config\BaseConfig; */ class Feature extends BaseConfig { - /** - * Enable multiple filters for a route or not. - * - * If you enable this: - * - CodeIgniter\CodeIgniter::handleRequest() uses: - * - CodeIgniter\Filters\Filters::enableFilters(), instead of enableFilter() - * - CodeIgniter\CodeIgniter::tryToRouteIt() uses: - * - CodeIgniter\Router\Router::getFilters(), instead of getFilter() - * - CodeIgniter\Router\Router::handle() uses: - * - property $filtersInfo, instead of $filterInfo - * - CodeIgniter\Router\RouteCollection::getFiltersForRoute(), instead of getFilterForRoute() - * - * @var bool - */ - public $multipleFilters = false; - /** * Use improved new auto routing instead of the default legacy version. */ public bool $autoRoutesImproved = false; + + /** + * Use filter execution order in 4.4 or before. + */ + public bool $oldFilterOrder = false; + + /** + * The behavior of `limit(0)` in Query Builder. + * + * If true, `limit(0)` returns all records. (the behavior of 4.4.x or before in version 4.x.) + * If false, `limit(0)` returns no records. (the behavior of 3.1.9 or later in version 3.x.) + */ + public bool $limitZeroAsAll = true; } diff --git a/app/Config/Filters.php b/app/Config/Filters.php index d0a9723..75ee0a7 100644 --- a/app/Config/Filters.php +++ b/app/Config/Filters.php @@ -2,43 +2,80 @@ namespace Config; -use CodeIgniter\Config\BaseConfig; +use CodeIgniter\Config\Filters as BaseFilters; +use CodeIgniter\Filters\Cors; use CodeIgniter\Filters\CSRF; use CodeIgniter\Filters\DebugToolbar; +use CodeIgniter\Filters\ForceHTTPS; use CodeIgniter\Filters\Honeypot; use CodeIgniter\Filters\InvalidChars; +use CodeIgniter\Filters\PageCache; +use CodeIgniter\Filters\PerformanceMetrics; use CodeIgniter\Filters\SecureHeaders; -class Filters extends BaseConfig +class Filters extends BaseFilters { /** * Configures aliases for Filter classes to * make reading things nicer and simpler. * - * @var array + * @var array> + * + * [filter_name => classname] + * or [filter_name => [classname1, classname2, ...]] */ - public $aliases = [ + public array $aliases = [ 'csrf' => CSRF::class, 'toolbar' => DebugToolbar::class, 'honeypot' => Honeypot::class, 'invalidchars' => InvalidChars::class, 'secureheaders' => SecureHeaders::class, + 'cors' => Cors::class, + 'forcehttps' => ForceHTTPS::class, + 'pagecache' => PageCache::class, + 'performance' => PerformanceMetrics::class, + ]; + + /** + * List of special required filters. + * + * The filters listed here are special. They are applied before and after + * other kinds of filters, and always applied even if a route does not exist. + * + * Filters set by default provide framework functionality. If removed, + * those functions will no longer work. + * + * @see https://codeigniter.com/user_guide/incoming/filters.html#provided-filters + * + * @var array{before: list, after: list} + */ + public array $required = [ + 'before' => [ + 'forcehttps', // Force Global Secure Requests + 'pagecache', // Web Page Caching + ], + 'after' => [ + 'pagecache', // Web Page Caching + 'performance', // Performance Metrics + 'toolbar', // Debug Toolbar + ], ]; /** * List of filter aliases that are always * applied before and after every request. * - * @var array + * @var array>>|array> */ - public $globals = [ + public array $globals = [ 'before' => [ // 'honeypot', // 'csrf', // 'invalidchars', + 'session' => ['except' => ['login*', 'register', 'auth/a/*', 'logout']], + 'permission' =>['isAuthorized'=>[]], ], 'after' => [ - 'toolbar', // 'honeypot', // 'secureheaders', ], @@ -49,15 +86,15 @@ class Filters extends BaseConfig * particular HTTP method (GET, POST, etc.). * * Example: - * 'post' => ['foo', 'bar'] + * 'POST' => ['foo', 'bar'] * * If you use this, you should disable auto-routing because auto-routing * permits any HTTP method to access a controller. Accessing the controller - * with a method you don’t expect could bypass the filter. + * with a method you don't expect could bypass the filter. * - * @var array + * @var array> */ - public $methods = []; + public array $methods = []; /** * List of filter aliases that should run on any @@ -66,7 +103,7 @@ class Filters extends BaseConfig * Example: * 'isLoggedIn' => ['before' => ['account/*', 'profiles/*']] * - * @var array + * @var array>> */ - public $filters = []; + public array $filters = []; } diff --git a/app/Config/ForeignCharacters.php b/app/Config/ForeignCharacters.php index 174ddb1..f1a9572 100644 --- a/app/Config/ForeignCharacters.php +++ b/app/Config/ForeignCharacters.php @@ -4,6 +4,9 @@ namespace Config; use CodeIgniter\Config\ForeignCharacters as BaseForeignCharacters; +/** + * @immutable + */ class ForeignCharacters extends BaseForeignCharacters { } diff --git a/app/Config/Generators.php b/app/Config/Generators.php index 11214fd..cc92c7a 100644 --- a/app/Config/Generators.php +++ b/app/Config/Generators.php @@ -23,9 +23,13 @@ class Generators extends BaseConfig * * YOU HAVE BEEN WARNED! * - * @var array + * @var array|string> */ - public $views = [ + public array $views = [ + 'make:cell' => [ + 'class' => 'CodeIgniter\Commands\Generators\Views\cell.tpl.php', + 'view' => 'CodeIgniter\Commands\Generators\Views\cell_view.tpl.php', + ], 'make:command' => 'CodeIgniter\Commands\Generators\Views\command.tpl.php', 'make:config' => 'CodeIgniter\Commands\Generators\Views\config.tpl.php', 'make:controller' => 'CodeIgniter\Commands\Generators\Views\controller.tpl.php', diff --git a/app/Config/Honeypot.php b/app/Config/Honeypot.php index 42b5a0d..67ebcb0 100644 --- a/app/Config/Honeypot.php +++ b/app/Config/Honeypot.php @@ -8,36 +8,35 @@ class Honeypot extends BaseConfig { /** * Makes Honeypot visible or not to human - * - * @var bool */ - public $hidden = true; + public bool $hidden = true; /** * Honeypot Label Content - * - * @var string */ - public $label = 'Fill This Field'; + public string $label = 'Fill This Field'; /** * Honeypot Field Name - * - * @var string */ - public $name = 'honeypot'; + public string $name = 'honeypot'; /** * Honeypot HTML Template - * - * @var string */ - public $template = ''; + public string $template = ''; /** * Honeypot container * - * @var string + * If you enabled CSP, you can remove `style="display:none"`. */ - public $container = '
{template}
'; + public string $container = '
{template}
'; + + /** + * The id attribute for Honeypot container tag + * + * Used when CSP is enabled. + */ + public string $containerId = 'hpc'; } diff --git a/app/Config/Kint.php b/app/Config/Kint.php index b1016ed..d070782 100644 --- a/app/Config/Kint.php +++ b/app/Config/Kint.php @@ -2,8 +2,10 @@ namespace Config; -use CodeIgniter\Config\BaseConfig; -use Kint\Renderer\Renderer; +use Kint\Parser\ConstructablePluginInterface; +use Kint\Renderer\AbstractRenderer; +use Kint\Renderer\Rich\TabPluginInterface; +use Kint\Renderer\Rich\ValuePluginInterface; /** * -------------------------------------------------------------------------- @@ -15,7 +17,7 @@ use Kint\Renderer\Renderer; * * @see https://kint-php.github.io/kint/ for details on these settings. */ -class Kint extends BaseConfig +class Kint { /* |-------------------------------------------------------------------------- @@ -23,20 +25,32 @@ class Kint extends BaseConfig |-------------------------------------------------------------------------- */ + /** + * @var list|ConstructablePluginInterface>|null + */ public $plugins; - public $maxDepth = 6; - public $displayCalledFrom = true; - public $expanded = false; + + public int $maxDepth = 6; + public bool $displayCalledFrom = true; + public bool $expanded = false; /* |-------------------------------------------------------------------------- | RichRenderer Settings |-------------------------------------------------------------------------- */ - public $richTheme = 'aante-light.css'; - public $richFolder = false; - public $richSort = Renderer::SORT_FULL; + public string $richTheme = 'aante-light.css'; + public bool $richFolder = false; + public int $richSort = AbstractRenderer::SORT_FULL; + + /** + * @var array>|null + */ public $richObjectPlugins; + + /** + * @var array>|null + */ public $richTabPlugins; /* @@ -44,8 +58,8 @@ class Kint extends BaseConfig | CLI Settings |-------------------------------------------------------------------------- */ - public $cliColors = true; - public $cliForceUTF8 = false; - public $cliDetectWidth = true; - public $cliMinWidth = 40; + public bool $cliColors = true; + public bool $cliForceUTF8 = false; + public bool $cliDetectWidth = true; + public int $cliMinWidth = 40; } diff --git a/app/Config/Logger.php b/app/Config/Logger.php index fe389d8..5abce4e 100644 --- a/app/Config/Logger.php +++ b/app/Config/Logger.php @@ -2,8 +2,8 @@ namespace Config; -use CodeIgniter\Log\Handlers\FileHandler; use CodeIgniter\Config\BaseConfig; +use CodeIgniter\Log\Handlers\FileHandler; class Logger extends BaseConfig { @@ -36,9 +36,9 @@ class Logger extends BaseConfig * For a live site you'll usually enable Critical or higher (3) to be logged otherwise * your log files will fill up very fast. * - * @var array|int + * @var int|list */ - public $threshold = 4; + public $threshold = (ENVIRONMENT === 'production') ? 4 : 9; /** * -------------------------------------------------------------------------- @@ -47,10 +47,8 @@ class Logger extends BaseConfig * * Each item that is logged has an associated date. You can use PHP date * codes to set your own date formatting - * - * @var string */ - public $dateFormat = 'Y-m-d H:i:s'; + public string $dateFormat = 'Y-m-d H:i:s'; /** * -------------------------------------------------------------------------- @@ -60,7 +58,7 @@ class Logger extends BaseConfig * The logging system supports multiple actions to be taken when something * is logged. This is done by allowing for multiple Handlers, special classes * designed to write the log to their chosen destinations, whether that is - * a file on the server, a cloud-based service, or even taking actions such + * a file on the getServer, a cloud-based service, or even taking actions such * as emailing the dev team. * * Each handler is defined by the class name used for that handler, and it @@ -75,10 +73,9 @@ class Logger extends BaseConfig * Handlers are executed in the order defined in this array, starting with * the handler on top and continuing down. * - * @var array + * @var array|string>> */ - public $handlers = [ - + public array $handlers = [ /* * -------------------------------------------------------------------- * File Handler @@ -103,7 +100,7 @@ class Logger extends BaseConfig * An extension of 'php' allows for protecting the log files via basic * scripting, when they are to be stored under a publicly accessible directory. * - * Note: Leaving it blank will default to 'log'. + * NOTE: Leaving it blank will default to 'log'. */ 'fileExtension' => '', @@ -141,14 +138,14 @@ class Logger extends BaseConfig * Uncomment this block to use it. */ // 'CodeIgniter\Log\Handlers\ErrorlogHandler' => [ - // /* The log levels this handler can handle. */ - // 'handles' => ['critical', 'alert', 'emergency', 'debug', 'error', 'info', 'notice', 'warning'], + // /* The log levels this handler can handle. */ + // 'handles' => ['critical', 'alert', 'emergency', 'debug', 'error', 'info', 'notice', 'warning'], // - // /* - // * The message type where the error should go. Can be 0 or 4, or use the - // * class constants: `ErrorlogHandler::TYPE_OS` (0) or `ErrorlogHandler::TYPE_SAPI` (4) - // */ - // 'messageType' => 0, + // /* + // * The message type where the error should go. Can be 0 or 4, or use the + // * class constants: `ErrorlogHandler::TYPE_OS` (0) or `ErrorlogHandler::TYPE_SAPI` (4) + // */ + // 'messageType' => 0, // ], ]; } diff --git a/app/Config/Migrations.php b/app/Config/Migrations.php index 91e80b4..1dec8b9 100644 --- a/app/Config/Migrations.php +++ b/app/Config/Migrations.php @@ -15,10 +15,8 @@ class Migrations extends BaseConfig * * You should enable migrations whenever you intend to do a schema migration * and disable it back when you're done. - * - * @var bool */ - public $enabled = true; + public bool $enabled = true; /** * -------------------------------------------------------------------------- @@ -27,13 +25,9 @@ class Migrations extends BaseConfig * * This is the name of the table that will store the current migrations state. * When migrations runs it will store in a database table which migration - * level the system is at. It then compares the migration level in this - * table to the $config['migration_version'] if they are not the same it - * will migrate up. This must be set. - * - * @var string + * files have already been run. */ - public $table = 'migrations'; + public string $table = 'migrations'; /** * -------------------------------------------------------------------------- @@ -42,14 +36,15 @@ class Migrations extends BaseConfig * * This is the format that will be used when creating new migrations * using the CLI command: - * > php spark migrate:create + * > php spark make:migration * - * Typical formats: + * NOTE: if you set an unsupported format, migration runner will not find + * your migration files. + * + * Supported formats: * - YmdHis_ * - Y-m-d-His_ * - Y_m_d_His_ - * - * @var string */ - public $timestampFormat = 'Y-m-d-His_'; + public string $timestampFormat = 'Y-m-d-His_'; } diff --git a/app/Config/Mimes.php b/app/Config/Mimes.php index 884e76b..7722444 100644 --- a/app/Config/Mimes.php +++ b/app/Config/Mimes.php @@ -15,15 +15,17 @@ namespace Config; * * When working with mime types, please make sure you have the ´fileinfo´ * extension enabled to reliably detect the media types. + * + * @immutable */ class Mimes { /** * Map of extensions to mime types. * - * @var array + * @var array|string> */ - public static $mimes = [ + public static array $mimes = [ 'hqx' => [ 'application/mac-binhex40', 'application/mac-binhex', @@ -55,6 +57,8 @@ class Mimes 'lzh' => 'application/octet-stream', 'exe' => [ 'application/octet-stream', + 'application/vnd.microsoft.portable-executable', + 'application/x-dosexec', 'application/x-msdownload', ], 'class' => 'application/octet-stream', diff --git a/app/Config/Modules.php b/app/Config/Modules.php index bde4079..8d4bf56 100644 --- a/app/Config/Modules.php +++ b/app/Config/Modules.php @@ -4,6 +4,14 @@ namespace Config; use CodeIgniter\Modules\Modules as BaseModules; +/** + * Modules Configuration. + * + * NOTE: This class is required prior to Autoloader instantiation, + * and does not extend BaseConfig. + * + * @immutable + */ class Modules extends BaseModules { /** @@ -31,6 +39,29 @@ class Modules extends BaseModules */ public $discoverInComposer = true; + /** + * The Composer package list for Auto-Discovery + * This setting is optional. + * + * E.g.: + * [ + * 'only' => [ + * // List up all packages to auto-discover + * 'codeigniter4/shield', + * ], + * ] + * or + * [ + * 'exclude' => [ + * // List up packages to exclude. + * 'pestphp/pest', + * ], + * ] + * + * @var array{only?: list, exclude?: list} + */ + public $composerPackages = []; + /** * -------------------------------------------------------------------------- * Auto-Discovery Rules @@ -41,7 +72,7 @@ class Modules extends BaseModules * * If it is not listed, only the base application elements will be used. * - * @var string[] + * @var list */ public $aliases = [ 'events', diff --git a/app/Config/Optimize.php b/app/Config/Optimize.php new file mode 100644 index 0000000..6fb441f --- /dev/null +++ b/app/Config/Optimize.php @@ -0,0 +1,32 @@ + + * @var array */ public $restrictions = [ ROOTPATH => '*', diff --git a/app/Config/Routes.php b/app/Config/Routes.php index 1f7d68d..ee71b28 100644 --- a/app/Config/Routes.php +++ b/app/Config/Routes.php @@ -1,37 +1,13 @@ setDefaultNamespace('App\Controllers'); -$routes->setDefaultController('Home'); -$routes->setDefaultMethod('index'); -$routes->setTranslateURIDashes(false); -$routes->set404Override(); -// The Auto Routing (Legacy) is very dangerous. It is easy to create vulnerable apps -// where controller filters or CSRF protection are bypassed. -// If you don't want to define all routes, please use the Auto Routing (Improved). -// Set `$autoRoutesImproved` to true in `app/Config/Feature.php` and set the following to true. -$routes->setAutoRoute(false); -/* - * -------------------------------------------------------------------- - * Route Definitions - * -------------------------------------------------------------------- - */ + + // We get a performance increase by specifying the default // route since we don't have to scan directories. @@ -56,20 +32,3 @@ $routes->get('viewScheduled', 'Home::viewScheduled'); service('auth')->routes($routes); - -/* - * -------------------------------------------------------------------- - * Additional Routing - * -------------------------------------------------------------------- - * - * There will often be times that you need additional routing and you - * need it to be able to override any defaults in this file. Environment - * based routes is one such time. require() additional route files here - * to make that happen. - * - * You will have access to the $routes object within that file without - * needing to reload it. - */ -if (is_file(APPPATH . 'Config/' . ENVIRONMENT . '/Routes.php')) { - require APPPATH . 'Config/' . ENVIRONMENT . '/Routes.php'; -} diff --git a/app/Config/Routing.php b/app/Config/Routing.php new file mode 100644 index 0000000..7abadc7 --- /dev/null +++ b/app/Config/Routing.php @@ -0,0 +1,140 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +namespace Config; + +use CodeIgniter\Config\Routing as BaseRouting; + +/** + * Routing configuration + */ +class Routing extends BaseRouting +{ + /** + * For Defined Routes. + * An array of files that contain route definitions. + * Route files are read in order, with the first match + * found taking precedence. + * + * Default: APPPATH . 'Config/Routes.php' + * + * @var list + */ + public array $routeFiles = [ + APPPATH . 'Config/Routes.php', + ]; + + /** + * For Defined Routes and Auto Routing. + * The default namespace to use for Controllers when no other + * namespace has been specified. + * + * Default: 'App\Controllers' + */ + public string $defaultNamespace = 'App\Controllers'; + + /** + * For Auto Routing. + * The default controller to use when no other controller has been + * specified. + * + * Default: 'Home' + */ + public string $defaultController = 'Home'; + + /** + * For Defined Routes and Auto Routing. + * The default method to call on the controller when no other + * method has been set in the route. + * + * Default: 'index' + */ + public string $defaultMethod = 'index'; + + /** + * For Auto Routing. + * Whether to translate dashes in URIs for controller/method to underscores. + * Primarily useful when using the auto-routing. + * + * Default: false + */ + public bool $translateURIDashes = false; + + /** + * Sets the class/method that should be called if routing doesn't + * find a match. It can be the controller/method name like: Users::index + * + * This setting is passed to the Router class and handled there. + * + * If you want to use a closure, you will have to set it in the + * routes file by calling: + * + * $routes->set404Override(function() { + * // Do something here + * }); + * + * Example: + * public $override404 = 'App\Errors::show404'; + */ + public ?string $override404 = null; + + /** + * If TRUE, the system will attempt to match the URI against + * Controllers by matching each segment against folders/files + * in APPPATH/Controllers, when a match wasn't found against + * defined routes. + * + * If FALSE, will stop searching and do NO automatic routing. + */ + public bool $autoRoute = false; + + /** + * For Defined Routes. + * If TRUE, will enable the use of the 'prioritize' option + * when defining routes. + * + * Default: false + */ + public bool $prioritize = false; + + /** + * For Defined Routes. + * If TRUE, matched multiple URI segments will be passed as one parameter. + * + * Default: false + */ + public bool $multipleSegmentsOneParam = false; + + /** + * For Auto Routing (Improved). + * Map of URI segments and namespaces. + * + * The key is the first URI segment. The value is the controller namespace. + * E.g., + * [ + * 'blog' => 'Acme\Blog\Controllers', + * ] + * + * @var array + */ + public array $moduleRoutes = []; + + /** + * For Auto Routing (Improved). + * Whether to translate dashes in URIs for controller/method to CamelCase. + * E.g., blog-controller -> BlogController + * + * If you enable this, $translateURIDashes is ignored. + * + * Default: false + */ + public bool $translateUriToCamelCase = false; +} diff --git a/app/Config/Security.php b/app/Config/Security.php index c4ac174..c077d37 100644 --- a/app/Config/Security.php +++ b/app/Config/Security.php @@ -15,7 +15,7 @@ class Security extends BaseConfig * * @var string 'cookie' or 'session' */ - public $csrfProtection = 'session'; + public string $csrfProtection = 'session'; /** * -------------------------------------------------------------------------- @@ -23,10 +23,8 @@ class Security extends BaseConfig * -------------------------------------------------------------------------- * * Randomize the CSRF Token for added security. - * - * @var bool */ - public $tokenRandomize = false; + public bool $tokenRandomize = false; /** * -------------------------------------------------------------------------- @@ -34,10 +32,8 @@ class Security extends BaseConfig * -------------------------------------------------------------------------- * * Token name for Cross Site Request Forgery protection. - * - * @var string */ - public $tokenName = 'csrf_test_name'; + public string $tokenName = 'csrf_test_name'; /** * -------------------------------------------------------------------------- @@ -45,10 +41,8 @@ class Security extends BaseConfig * -------------------------------------------------------------------------- * * Header name for Cross Site Request Forgery protection. - * - * @var string */ - public $headerName = 'X-CSRF-TOKEN'; + public string $headerName = 'X-CSRF-TOKEN'; /** * -------------------------------------------------------------------------- @@ -56,10 +50,8 @@ class Security extends BaseConfig * -------------------------------------------------------------------------- * * Cookie name for Cross Site Request Forgery protection. - * - * @var string */ - public $cookieName = 'csrf_cookie_name'; + public string $cookieName = 'csrf_cookie_name'; /** * -------------------------------------------------------------------------- @@ -69,10 +61,8 @@ class Security extends BaseConfig * Expiration time for Cross Site Request Forgery protection cookie. * * Defaults to two hours (in seconds). - * - * @var int */ - public $expires = 7200; + public int $expires = 7200; /** * -------------------------------------------------------------------------- @@ -80,10 +70,8 @@ class Security extends BaseConfig * -------------------------------------------------------------------------- * * Regenerate CSRF Token on every submission. - * - * @var bool */ - public $regenerate = true; + public bool $regenerate = true; /** * -------------------------------------------------------------------------- @@ -92,9 +80,9 @@ class Security extends BaseConfig * * Redirect to previous page with error on failure. * - * @var bool + * @see https://codeigniter4.github.io/userguide/libraries/security.html#redirection-on-failure */ - public $redirect = true; + public bool $redirect = (ENVIRONMENT === 'production'); /** * -------------------------------------------------------------------------- @@ -109,9 +97,7 @@ class Security extends BaseConfig * * @see https://portswigger.net/web-security/csrf/samesite-cookies * - * @var string - * * @deprecated `Config\Cookie` $samesite property is used. */ - public $samesite = 'Lax'; + public string $samesite = 'Lax'; } diff --git a/app/Config/Session.php b/app/Config/Session.php new file mode 100644 index 0000000..6944710 --- /dev/null +++ b/app/Config/Session.php @@ -0,0 +1,127 @@ + + */ + public string $driver = FileHandler::class; + + /** + * -------------------------------------------------------------------------- + * Session Cookie Name + * -------------------------------------------------------------------------- + * + * The session cookie name, must contain only [0-9a-z_-] characters + */ + public string $cookieName = 'ci_session'; + + /** + * -------------------------------------------------------------------------- + * Session Expiration + * -------------------------------------------------------------------------- + * + * The number of SECONDS you want the session to last. + * Setting to 0 (zero) means expire when the browser is closed. + */ + public int $expiration = 7200; + + /** + * -------------------------------------------------------------------------- + * Session Save Path + * -------------------------------------------------------------------------- + * + * The location to save sessions to and is driver dependent. + * + * For the 'files' driver, it's a path to a writable directory. + * WARNING: Only absolute paths are supported! + * + * For the 'database' driver, it's a table name. + * Please read up the manual for the format with other session drivers. + * + * IMPORTANT: You are REQUIRED to set a valid save path! + */ + public string $savePath = WRITEPATH . 'session'; + + /** + * -------------------------------------------------------------------------- + * Session Match IP + * -------------------------------------------------------------------------- + * + * Whether to match the user's IP address when reading the session data. + * + * WARNING: If you're using the database driver, don't forget to update + * your session table's PRIMARY KEY when changing this setting. + */ + public bool $matchIP = false; + + /** + * -------------------------------------------------------------------------- + * Session Time to Update + * -------------------------------------------------------------------------- + * + * How many seconds between CI regenerating the session ID. + */ + public int $timeToUpdate = 300; + + /** + * -------------------------------------------------------------------------- + * Session Regenerate Destroy + * -------------------------------------------------------------------------- + * + * Whether to destroy session data associated with the old session ID + * when auto-regenerating the session ID. When set to FALSE, the data + * will be later deleted by the garbage collector. + */ + public bool $regenerateDestroy = false; + + /** + * -------------------------------------------------------------------------- + * Session Database Group + * -------------------------------------------------------------------------- + * + * DB Group for the database session. + */ + public ?string $DBGroup = null; + + /** + * -------------------------------------------------------------------------- + * Lock Retry Interval (microseconds) + * -------------------------------------------------------------------------- + * + * This is used for RedisHandler. + * + * Time (microseconds) to wait if lock cannot be acquired. + * The default is 100,000 microseconds (= 0.1 seconds). + */ + public int $lockRetryInterval = 100_000; + + /** + * -------------------------------------------------------------------------- + * Lock Max Retries + * -------------------------------------------------------------------------- + * + * This is used for RedisHandler. + * + * Maximum number of lock acquisition attempts. + * The default is 300 times. That is lock timeout is about 30 (0.1 * 300) + * seconds. + */ + public int $lockMaxRetries = 300; +} diff --git a/app/Config/Toolbar.php b/app/Config/Toolbar.php index 7183e13..4df9508 100644 --- a/app/Config/Toolbar.php +++ b/app/Config/Toolbar.php @@ -31,9 +31,9 @@ class Toolbar extends BaseConfig * List of toolbar collectors that will be called when Debug Toolbar * fires up and collects data from. * - * @var string[] + * @var list */ - public $collectors = [ + public array $collectors = [ Timers::class, Database::class, Logs::class, @@ -49,12 +49,10 @@ class Toolbar extends BaseConfig * Collect Var Data * -------------------------------------------------------------------------- * - * If set to false var data from the views will not be colleted. Usefull to + * If set to false var data from the views will not be collected. Useful to * avoid high memory usage when there are lots of data passed to the view. - * - * @var bool */ - public $collectVarData = true; + public bool $collectVarData = true; /** * -------------------------------------------------------------------------- @@ -64,10 +62,8 @@ class Toolbar extends BaseConfig * `$maxHistory` sets a limit on the number of past requests that are stored, * helping to conserve file space used to store them. You can set it to * 0 (zero) to not have any history stored, or -1 for unlimited history. - * - * @var int */ - public $maxHistory = 20; + public int $maxHistory = 20; /** * -------------------------------------------------------------------------- @@ -76,10 +72,8 @@ class Toolbar extends BaseConfig * * The full path to the the views that are used by the toolbar. * This MUST have a trailing slash. - * - * @var string */ - public $viewsPath = SYSTEMPATH . 'Debug/Toolbar/Views/'; + public string $viewsPath = SYSTEMPATH . 'Debug/Toolbar/Views/'; /** * -------------------------------------------------------------------------- @@ -92,8 +86,37 @@ class Toolbar extends BaseConfig * with hundreds of queries. * * `$maxQueries` defines the maximum amount of queries that will be stored. + */ + public int $maxQueries = 100; + + /** + * -------------------------------------------------------------------------- + * Watched Directories + * -------------------------------------------------------------------------- * - * @var int + * Contains an array of directories that will be watched for changes and + * used to determine if the hot-reload feature should reload the page or not. + * We restrict the values to keep performance as high as possible. + * + * NOTE: The ROOTPATH will be prepended to all values. + * + * @var list */ - public $maxQueries = 100; + public array $watchedDirectories = [ + 'app', + ]; + + /** + * -------------------------------------------------------------------------- + * Watched File Extensions + * -------------------------------------------------------------------------- + * + * Contains an array of file extensions that will be watched for changes and + * used to determine if the hot-reload feature should reload the page or not. + * + * @var list + */ + public array $watchedExtensions = [ + 'php', 'css', 'js', 'html', 'svg', 'json', 'env', + ]; } diff --git a/app/Config/Validation.php b/app/Config/Validation.php index a254c18..497b940 100644 --- a/app/Config/Validation.php +++ b/app/Config/Validation.php @@ -18,9 +18,9 @@ class Validation extends BaseConfig * Stores the classes that contain the * rules that are available. * - * @var string[] + * @var list */ - public $ruleSets = [ + public array $ruleSets = [ Rules::class, FormatRules::class, FileRules::class, @@ -33,7 +33,7 @@ class Validation extends BaseConfig * * @var array */ - public $templates = [ + public array $templates = [ 'list' => 'CodeIgniter\Validation\Views\list', 'single' => 'CodeIgniter\Validation\Views\single', ]; diff --git a/app/Config/View.php b/app/Config/View.php index 78cd547..cf8dd06 100644 --- a/app/Config/View.php +++ b/app/Config/View.php @@ -5,6 +5,10 @@ namespace Config; use CodeIgniter\Config\View as BaseView; use CodeIgniter\View\ViewDecoratorInterface; +/** + * @phpstan-type parser_callable (callable(mixed): mixed) + * @phpstan-type parser_callable_string (callable(mixed): mixed)&string + */ class View extends BaseView { /** @@ -30,7 +34,8 @@ class View extends BaseView * { title|esc(js) } * { created_on|date(Y-m-d)|esc(attr) } * - * @var array + * @var array + * @phpstan-var array */ public $filters = []; @@ -39,7 +44,8 @@ class View extends BaseView * by the core Parser by creating aliases that will be replaced with * any callable. Can be single or tag pair. * - * @var array + * @var array|string> + * @phpstan-var array|parser_callable_string|parser_callable> */ public $plugins = []; @@ -50,7 +56,7 @@ class View extends BaseView * * All classes must implement CodeIgniter\View\ViewDecoratorInterface * - * @var class-string[] + * @var list> */ public array $decorators = []; } diff --git a/app/Controllers/BaseController.php b/app/Controllers/BaseController.php index 7f42a70..122db5f 100644 --- a/app/Controllers/BaseController.php +++ b/app/Controllers/BaseController.php @@ -42,8 +42,6 @@ abstract class BaseController extends Controller */ public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger) { - $this->helpers = array_merge($this->helpers, ['setting']); - // Do Not Edit This Line parent::initController($request, $response, $logger); diff --git a/app/Controllers/Home.php b/app/Controllers/Home.php index 4eed9e4..17b242c 100644 --- a/app/Controllers/Home.php +++ b/app/Controllers/Home.php @@ -222,28 +222,33 @@ class Home extends BaseController } public function syncScheduled(){ + if (!$this->request->isAJAX()) return; $scheduled = model('App\Models\mScheduled'); $schedules = $scheduled->findAll(); + $result = array(); + $line = ""; foreach ( $schedules as $schedule ) { $cur_date = $schedule['next_date']; while ( strtotime( $cur_date ) <= strtotime( "now" ) ) { - echo "$cur_date - "; + $line .= " $cur_date - "; $bill = array_merge($this->loadFormDefaults(),(array)json_decode($schedule['data'])); //echo "Hugo:".$schedule['id']; $bill['id']=0; // to generate a new booking $bill['datum'] = $cur_date; $bill['type'] = $bill['transfer']?'transfer':'multiple'; - echo $bill['receiver']; + $line .= $bill['receiver']; $bills = model('App\Models\mBills'); $bills->saveBill($bill); $cur_date = $scheduled->calcNextDate( $cur_date, $bill['scheduledNum'], $bill['scheduledType']); - echo " - $cur_date
"; + $line .= " - $cur_date
"; //log_message('debug','BudgetScheduled:process data: '.logArray($booking->getData())); $scheduled->update($schedule['id'], ['next_date'=>$cur_date ]); + } } + return $line; //$this->showTableBookings(); } diff --git a/app/Views/auth/change_password.php b/app/Views/auth/change_password.php new file mode 100644 index 0000000..1549f10 --- /dev/null +++ b/app/Views/auth/change_password.php @@ -0,0 +1,64 @@ +extend('layouts/smarthome'); ?> +section('menu'); ?> + include('menu/dashboard_menu') ?> +endSection(); ?> +section('content'); ?> +
+
+
+ +
+
+
Hallo user()->username ?>, Passwort ändern
+ + + + + + + + + + + +
+ + + +
+ +
+ + +
+ +
+ + +
+ +
+ +
+ +
+ +
+ +
+
+
+
+
+ + +endSection(); ?> \ No newline at end of file diff --git a/app/Views/auth/email_invition.php b/app/Views/auth/email_invition.php new file mode 100644 index 0000000..b193804 --- /dev/null +++ b/app/Views/auth/email_invition.php @@ -0,0 +1,27 @@ + + + + + + + + Einladung zur Registrierung bei Smarthome + + + + Hi, + um Smarthome Dashboard zu benutzen, musst du dich registrieren. + Benutze hierfür den Link: + + + + + + +
+ +
+

+ + + diff --git a/app/Views/auth/email_register_notify.php b/app/Views/auth/email_register_notify.php new file mode 100644 index 0000000..57e9ad8 --- /dev/null +++ b/app/Views/auth/email_register_notify.php @@ -0,0 +1,24 @@ + + + + + + + + Neue Registrierung bei der Verwaltung der Wörgler Flughunden ist erfolgt + + + + + Der Benutzer mit der Emailadresse hat sich neu registriert.
+ Die Gruppenzugehörigkeit gehört eingestellt. + + + + + +
+ Check +
+ + diff --git a/app/Views/auth/login.php b/app/Views/auth/login.php new file mode 100644 index 0000000..0fa098a --- /dev/null +++ b/app/Views/auth/login.php @@ -0,0 +1,73 @@ +extend('layout'); ?> + +section('menu'); ?> +include('sidebar') ?> +endSection(); ?> +section('content'); ?> +
+
+
+ +
+
+
+
+
+ + + + + + + + + + + +
+ + + +
+ +
+ + +
+ +
+ + + +
+ +
+ + +
+ +
+ + +

+ + +
+
+
+
+ + +endSection(); ?> \ No newline at end of file diff --git a/app/Views/auth/register.php b/app/Views/auth/register.php new file mode 100644 index 0000000..ef0d17e --- /dev/null +++ b/app/Views/auth/register.php @@ -0,0 +1,65 @@ +extend('layouts/smarthome'); ?> +section('menu'); ?> + include('menu/dashboard_menu') ?> +endSection(); ?> +section('content'); ?> +
+
+
+
+
+
+ + + + + + +
+ + + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ +
+ +
+ +

+ +
+
+
+
+ +endSection() ?> diff --git a/app/Views/auth/table_users.php b/app/Views/auth/table_users.php new file mode 100644 index 0000000..db67918 --- /dev/null +++ b/app/Views/auth/table_users.php @@ -0,0 +1,92 @@ +extend('layouts/smarthome'); ?> +section('css'); ?> + +endSection(); ?> +section('menu'); ?> + include('menu/dashboard_menu') ?> +endSection(); ?> + +section('content'); ?> + + +
+ +
+
+endSection(); ?> +section('scripts'); ?> + + +endSection(); ?> \ No newline at end of file diff --git a/app/Views/errors/cli/error_exception.php b/app/Views/errors/cli/error_exception.php index f24e98f..9f47d25 100644 --- a/app/Views/errors/cli/error_exception.php +++ b/app/Views/errors/cli/error_exception.php @@ -3,17 +3,26 @@ use CodeIgniter\CLI\CLI; // The main Exception -CLI::newLine(); -CLI::write('[' . get_class($exception) . ']', 'light_gray', 'red'); -CLI::newLine(); +CLI::write('[' . $exception::class . ']', 'light_gray', 'red'); CLI::write($message); -CLI::newLine(); CLI::write('at ' . CLI::color(clean_path($exception->getFile()) . ':' . $exception->getLine(), 'green')); CLI::newLine(); +$last = $exception; + +while ($prevException = $last->getPrevious()) { + $last = $prevException; + + CLI::write(' Caused by:'); + CLI::write(' [' . $prevException::class . ']', 'red'); + CLI::write(' ' . $prevException->getMessage()); + CLI::write(' at ' . CLI::color(clean_path($prevException->getFile()) . ':' . $prevException->getLine(), 'green')); + CLI::newLine(); +} + // The backtrace if (defined('SHOW_DEBUG_BACKTRACE') && SHOW_DEBUG_BACKTRACE) { - $backtraces = $exception->getTrace(); + $backtraces = $last->getTrace(); if ($backtraces) { CLI::write('Backtrace:', 'green'); @@ -41,20 +50,11 @@ if (defined('SHOW_DEBUG_BACKTRACE') && SHOW_DEBUG_BACKTRACE) { $function .= $padClass . $error['function']; } - $args = implode(', ', array_map(static function ($value) { - switch (true) { - case is_object($value): - return 'Object(' . get_class($value) . ')'; - - case is_array($value): - return count($value) ? '[...]' : '[]'; - - case $value === null: - return 'null'; // return the lowercased version - - default: - return var_export($value, true); - } + $args = implode(', ', array_map(static fn ($value) => match (true) { + is_object($value) => 'Object(' . $value::class . ')', + is_array($value) => count($value) ? '[...]' : '[]', + $value === null => 'null', // return the lowercased version + default => var_export($value, true), }, array_values($error['args'] ?? []))); $function .= '(' . $args . ')'; diff --git a/app/Views/errors/html/debug.css b/app/Views/errors/html/debug.css index 98f54db..6a050c8 100644 --- a/app/Views/errors/html/debug.css +++ b/app/Views/errors/html/debug.css @@ -19,7 +19,6 @@ body { } h1 { font-weight: lighter; - letter-spacing: 0.8; font-size: 3rem; color: var(--dark-text-color); margin: 0; @@ -44,7 +43,7 @@ p.lead { color: var(--dark-text-color); } .header .container { - padding: 1rem 1.75rem 1.75rem 1.75rem; + padding: 1rem; } .header h1 { font-size: 2.5rem; @@ -65,14 +64,11 @@ p.lead { display: inline; } -.footer { +.environment { background: var(--dark-bg-color); color: var(--light-text-color); -} -.footer .container { - border-top: 1px solid #e7e7e7; - margin-top: 1rem; text-align: center; + padding: 0.2rem; } .source { @@ -112,7 +108,7 @@ p.lead { } .tabs a:link, .tabs a:visited { - padding: 0rem 1rem; + padding: 0 1rem; line-height: 2.7; text-decoration: none; color: var(--dark-text-color); @@ -152,9 +148,6 @@ p.lead { border-radius: 5px; color: #31708f; } -ul, ol { - line-height: 1.8; -} table { width: 100%; diff --git a/app/Views/errors/html/error_404.php b/app/Views/errors/html/error_404.php index 5ba9f8a..e506f08 100644 --- a/app/Views/errors/html/error_404.php +++ b/app/Views/errors/html/error_404.php @@ -2,7 +2,7 @@ - 404 Page Not Found + <?= lang('Errors.pageNotFound') ?> - @@ -18,6 +24,12 @@
+
+ Displayed at — + PHP: — + CodeIgniter: -- + Environment: +

getCode() ? ' #' . $exception->getCode() : '') ?>

@@ -39,6 +51,30 @@

+
+ getPrevious()) { + $last = $prevException; + ?> + +
+    Caused by:
+    getCode() ? ' #' . $prevException->getCode() : '') ?>
+
+    getMessage())) ?>
+    getMessage())) ?>"
+       rel="noreferrer" target="_blank">search →
+    getFile()) . ':' . $prevException->getLine()) ?>
+    
+ + +
+ +
    @@ -61,7 +97,7 @@
  • - +   —   - - ( arguments ) -

    + + ( arguments ) +
    getParameters(); } @@ -189,7 +225,7 @@
    - +
    @@ -199,7 +235,7 @@ - + @@ -270,60 +306,11 @@ - getHeaders(); ?> + headers(); ?>

    Headers

    -
    HTTP MethodgetMethod())) ?>getMethod()) ?>
    IP Address
    - - - - - - - - - - - - - - - - - -
    HeaderValue
    getName(), 'html') ?>getValueLine(), 'html') ?>
    - - -
    - - - setStatusCode(http_response_code()); - ?> -
    - - - - - -
    Response StatusgetStatusCode() . ' - ' . $response->getReasonPhrase()) ?>
    - - getHeaders(); ?> - - - -

    Headers

    - @@ -335,7 +322,64 @@ $value) : ?> - + + + + +
    getHeaderLine($name), 'html') ?> + getValueLine(), 'html'); + } else { + foreach ($value as $i => $header) { + echo ' ('. $i+1 . ') ' . esc($header->getValueLine(), 'html'); + } + } + ?> +
    + + +
    + + + setStatusCode(http_response_code()); + ?> +
    + + + + + +
    Response StatusgetStatusCode() . ' - ' . $response->getReasonPhrase()) ?>
    + + headers(); ?> + +

    Headers

    + + + + + + + + + + $value) : ?> + + + @@ -380,18 +424,7 @@ - - + diff --git a/app/Views/layout.php b/app/Views/layout.php index d98d6e3..d24762d 100644 --- a/app/Views/layout.php +++ b/app/Views/layout.php @@ -48,6 +48,22 @@ + @@ -46,12 +52,12 @@ + + + + + + + --> diff --git a/preload.php b/preload.php index ae935b0..755df5e 100644 --- a/preload.php +++ b/preload.php @@ -16,7 +16,8 @@ * See https://www.php.net/manual/en/opcache.preloading.php * * How to Use: - * 1. Set preload::$paths. + * 0. Copy this file to your project root folder. + * 1. Set the $paths property of the preload class below. * 2. Set opcache.preload in php.ini. * php.ini: * opcache.preload=/path/to/preload.php @@ -28,19 +29,6 @@ require __DIR__ . '/app/Config/Paths.php'; // Path to the front controller define('FCPATH', __DIR__ . DIRECTORY_SEPARATOR . 'public' . DIRECTORY_SEPARATOR); -/** - * See https://www.php.net/manual/en/function.str-contains.php#126277 - */ -if (! function_exists('str_contains')) { - /** - * Polyfill of str_contains() - */ - function str_contains(string $haystack, string $needle): bool - { - return empty($needle) || strpos($haystack, $needle) !== false; - } -} - class preload { /** @@ -48,23 +36,27 @@ class preload */ private array $paths = [ [ - 'include' => __DIR__ . '/vendor/codeigniter4/framework/system', + 'include' => __DIR__ . '/vendor/codeigniter4/framework/system', // Change this path if using manual installation 'exclude' => [ // Not needed if you don't use them. '/system/Database/OCI8/', '/system/Database/Postgre/', + '/system/Database/SQLite3/', '/system/Database/SQLSRV/', - // Not needed. + // Not needed for web apps. '/system/Database/Seeder.php', '/system/Test/', - '/system/Language/', '/system/CLI/', '/system/Commands/', '/system/Publisher/', '/system/ComposerScripts.php', + // Not Class/Function files. + '/system/Config/Routes.php', + '/system/Language/', + '/system/bootstrap.php', + '/system/rewrite.php', '/Views/', // Errors occur. - '/system/Config/Routes.php', '/system/ThirdParty/', ], ], @@ -75,16 +67,18 @@ class preload $this->loadAutoloader(); } - private function loadAutoloader() + private function loadAutoloader(): void { $paths = new Config\Paths(); - require rtrim($paths->systemDirectory, '\\/ ') . DIRECTORY_SEPARATOR . 'bootstrap.php'; + require rtrim($paths->systemDirectory, '\\/ ') . DIRECTORY_SEPARATOR . 'Boot.php'; + + CodeIgniter\Boot::preload($paths); } /** * Load PHP files. */ - public function load() + public function load(): void { foreach ($this->paths as $path) { $directory = new RecursiveDirectoryIterator($path['include']); diff --git a/public/.htaccess b/public/.htaccess index a5d6c2a..dbed322 100644 --- a/public/.htaccess +++ b/public/.htaccess @@ -1,5 +1,5 @@ # Disable directory browsing -Options All -Indexes +Options -Indexes # ---------------------------------------------------------------------- # Rewrite engine diff --git a/public/index.php b/public/index.php index 96e7f45..5ec58a7 100644 --- a/public/index.php +++ b/public/index.php @@ -1,7 +1,12 @@ systemDirectory, '\\/ ') . DIRECTORY_SEPARATOR . 'bootstrap.php'; +// LOAD THE FRAMEWORK BOOTSTRAP FILE +require $paths->systemDirectory . '/Boot.php'; -// Load environment settings from .env files into $_SERVER and $_ENV -require_once SYSTEMPATH . 'Config/DotEnv.php'; -(new CodeIgniter\Config\DotEnv(ROOTPATH))->load(); - -/* - * --------------------------------------------------------------- - * GRAB OUR CODEIGNITER INSTANCE - * --------------------------------------------------------------- - * - * The CodeIgniter class contains the core functionality to make - * the application run, and does all of the dirty work to get - * the pieces all working together. - */ - -$app = Config\Services::codeigniter(); -$app->initialize(); -$context = is_cli() ? 'php-cli' : 'web'; -$app->setContext($context); - -/* - *--------------------------------------------------------------- - * LAUNCH THE APPLICATION - *--------------------------------------------------------------- - * Now that everything is setup, it's time to actually fire - * up the engines and make this app do its thang. - */ - -$app->run(); +exit(CodeIgniter\Boot::bootWeb($paths)); diff --git a/public/js/scheduled.js b/public/js/scheduled.js index 14a80b3..5bad190 100644 --- a/public/js/scheduled.js +++ b/public/js/scheduled.js @@ -10,11 +10,22 @@ $(document).ready(function(){ info:false, order: [[ 1, 'asc' ]], ajax: {url: '/Ajax/getScheduledData',dataSrc:''}, - dom: '<"toolbar">frt', + layout: { + topStart: { + buttons: [ + {text:'Neue Rechnung',className:'btn-sm',action: function ( e, dt, node, config ) { + location.href = '/newScheduled'; + }}, + {text:'Neuer Transfer',className:'btn-sm mx-2',action: function ( e, dt, node, config ) { + location.href = '/newScheduledTransfer'; + }}, + ] + }, + topEnd: 'search' + }, columns: columnspez }); - $("div.toolbar").html('Neue RechnungNeuer Transfer'); - + $('#scheduled tbody').on('click', 'td.dt-receiver', function () {collapseDetails($(this), datatable);} ); $('#scheduled tbody').on('click', 'td.dt-datum', function () {location.href = '/editScheduled/'+getId($(this),datatable);}); $('#scheduled tbody').on('click', 'table.tabdet', function () {location.href = '/editScheduled/'+$(this).attr('data-bs-id');}); diff --git a/public/js/tabs_overview.js b/public/js/tabs_overview.js index 9686fc1..2e12144 100644 --- a/public/js/tabs_overview.js +++ b/public/js/tabs_overview.js @@ -1,6 +1,33 @@ var datatable; var todos; +function syncScheduled(){ + $('#mySnycModal').modal('show'); + $('#mySnycModal').find('.modal-title').html("Synchronisierte Einträge!"); + $.ajax({ + type: "GET", + url: "/syncScheduled/", + data: {}, // serializes the form's elements. + success: function(data){ + const myModale = document.querySelector('#mySnycModal'); + var modalText = myModale.querySelector('.modal-body'); + var modalFenster = myModale.querySelector('.modal-dialog'); + modalText.innerHTML = data; + $('#todos').DataTable().ajax.reload(); + }, + error: function(data){ + const myModale = document.querySelector('#mySnycModal'); + var modalText = myModale.querySelector('.modal-body'); + var modalFenster = myModale.querySelector('.modal-dialog'); + modalFenster.classList.add("alert"); + modalFenster.classList.add("alert-danger"); + modalText.textContent = 'Fehler bei der Ausführung!'; + $('#todos').DataTable().ajax.reload(); + } + }); + // location.href = '/syncScheduled/'; +} + $(document).ready(function(){ datatable = $('#bookings').DataTable({ paging: false, @@ -38,9 +65,7 @@ $(document).ready(function(){ layout: { topStart: { buttons: [ - {text:'Sync',className:'btn-sm',action: function ( e, dt, node, config ) { - location.href = '/syncScheduled/'; - }}, + {text:'Sync',className:'btn-sm',action: syncScheduled}, ] }, topEnd: 'search' diff --git a/spark b/spark index 49a00aa..a730e0b 100755 --- a/spark +++ b/spark @@ -12,22 +12,30 @@ /* * -------------------------------------------------------------------- - * CodeIgniter command-line tools + * CODEIGNITER COMMAND-LINE TOOLS * -------------------------------------------------------------------- * The main entry point into the CLI system and allows you to run * commands and perform maintenance on your application. - * - * Because CodeIgniter can handle CLI requests as just another web request - * this class mainly acts as a passthru to the framework itself. + */ + +/* + *--------------------------------------------------------------- + * CHECK SERVER API + *--------------------------------------------------------------- */ // Refuse to run when called from php-cgi -if (strpos(PHP_SAPI, 'cgi') === 0) { +if (str_starts_with(PHP_SAPI, 'cgi')) { exit("The cli tool is not supported when running php-cgi. It needs php-cli to function!\n\n"); } -// Check PHP version. -$minPhpVersion = '7.4'; // If you update this, don't forget to update `public/index.php`. +/* + *--------------------------------------------------------------- + * CHECK PHP VERSION + *--------------------------------------------------------------- + */ + +$minPhpVersion = '8.1'; // If you update this, don't forget to update `public/index.php`. if (version_compare(PHP_VERSION, $minPhpVersion, '<')) { $message = sprintf( 'Your PHP version must be %s or higher to run CodeIgniter. Current version: %s', @@ -39,15 +47,14 @@ if (version_compare(PHP_VERSION, $minPhpVersion, '<')) { } // We want errors to be shown when using it from the CLI. -error_reporting(-1); +error_reporting(E_ALL); ini_set('display_errors', '1'); -/** - * @var bool - * - * @deprecated No longer in use. `CodeIgniter` has `$context` property. +/* + *--------------------------------------------------------------- + * SET THE CURRENT DIRECTORY + *--------------------------------------------------------------- */ -define('SPARKED', true); // Path to the front controller define('FCPATH', __DIR__ . DIRECTORY_SEPARATOR . 'public' . DIRECTORY_SEPARATOR); @@ -64,39 +71,14 @@ chdir(FCPATH); * and fires up an environment-specific bootstrapping. */ -// Load our paths config file +// LOAD OUR PATHS CONFIG FILE // This is the line that might need to be changed, depending on your folder structure. -require FCPATH . '../app/Config/Paths.php'; +require FCPATH . '../smarthome/app/Config/Paths.php'; // ^^^ Change this line if you move your application folder $paths = new Config\Paths(); -// Location of the framework bootstrap file. -require rtrim($paths->systemDirectory, '\\/ ') . DIRECTORY_SEPARATOR . 'bootstrap.php'; +// LOAD THE FRAMEWORK BOOTSTRAP FILE +require $paths->systemDirectory . '/Boot.php'; -// Load environment settings from .env files into $_SERVER and $_ENV -require_once SYSTEMPATH . 'Config/DotEnv.php'; -(new CodeIgniter\Config\DotEnv(ROOTPATH))->load(); - -// Grab our CodeIgniter -$app = Config\Services::codeigniter(); -$app->initialize(); -$app->setContext('spark'); - -// Grab our Console -$console = new CodeIgniter\CLI\Console($app); - -// Show basic information before we do anything else. -if (is_int($suppress = array_search('--no-header', $_SERVER['argv'], true))) { - unset($_SERVER['argv'][$suppress]); // @codeCoverageIgnore - $suppress = true; -} - -$console->showHeader($suppress); - -// fire off the command in the main framework. -$response = $console->run(); - -if ($response->getStatusCode() >= 300) { - exit($response->getStatusCode()); -} +exit(CodeIgniter\Boot::bootSpark($paths));
    HeaderValue
    + getHeaderLine($name), 'html'); + } else { + foreach ($value as $i => $header) { + echo ' ('. $i+1 . ') ' . esc($header->getValueLine(), 'html'); + } + } + ?> +