* * 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; 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' => '\App\Views\login', 'register' => '\App\Views\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', 'action_email_2fa_email' => '\CodeIgniter\Shield\Views\Email\email_2fa_email', 'action_email_activate_show' => '\CodeIgniter\Shield\Views\email_activate_show', 'action_email_activate_email' => '\CodeIgniter\Shield\Views\Email\email_activate_email', 'magic-link-login' => '\CodeIgniter\Shield\Views\magic_link_form', 'magic-link-message' => '\CodeIgniter\Shield\Views\magic_link_message', 'magic-link-email' => '\CodeIgniter\Shield\Views\Email\magic_link_email', ]; /** * -------------------------------------------------------------------- * Redirect URLs * -------------------------------------------------------------------- * 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' => '/hi', 'login' => '/hi', 'logout' => '/login', 'force_reset' => '/', 'permission_denied' => '/', 'group_denied' => '/', ]; /** * -------------------------------------------------------------------- * Authentication Actions * -------------------------------------------------------------------- * Specifies the class that represents an action to take after * the user logs in or registers a new account at the site. * * You must register actions in the order of the actions to be performed. * * Available actions with Shield: * - register: \CodeIgniter\Shield\Authentication\Actions\EmailActivator::class * - login: \CodeIgniter\Shield\Authentication\Actions\Email2FA::class * * @var array|null> */ public array $actions = [ 'register' => null, 'login' => null, ]; /** * -------------------------------------------------------------------- * Authenticators * -------------------------------------------------------------------- * The available authentication systems, listed * with alias and class name. These can be referenced * by alias in the auth helper: * auth('tokens')->attempt($credentials); * * @var array> */ public array $authenticators = [ 'tokens' => AccessTokens::class, 'session' => Session::class, 'hmac' => HmacSha256::class, // 'jwt' => JWT::class, ]; /** * -------------------------------------------------------------------- * Default Authenticator * -------------------------------------------------------------------- * The Authenticator to use when none is specified. * Uses the $key from the $authenticators array above. */ public string $defaultAuthenticator = 'session'; /** * -------------------------------------------------------------------- * Authentication Chain * -------------------------------------------------------------------- * The Authenticators to test logged in status against * 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 list */ public array $authenticationChain = [ 'session', 'tokens', 'hmac', // 'jwt', ]; /** * -------------------------------------------------------------------- * Allow Registration * -------------------------------------------------------------------- * Determines whether users can register for the site. */ public bool $allowRegistration = true; /** * -------------------------------------------------------------------- * Record Last Active Date * -------------------------------------------------------------------- * If true, will always update the `last_active` datetime for the * 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; /** * -------------------------------------------------------------------- * Allow Magic Link Logins * -------------------------------------------------------------------- * If true, will allow the use of "magic links" sent via the email * as a way to log a user in without the need for a password. * By default, this is used in place of a password reset flow, but * could be modified as the only method of login once an account * has been set up. */ public bool $allowMagicLinkLogins = true; /** * -------------------------------------------------------------------- * Magic Link Lifetime * -------------------------------------------------------------------- * Specifies the amount of time, in seconds, that a magic link is valid. * You can use Time Constants or any desired number. */ public int $magicLinkLifetime = HOUR; /** * -------------------------------------------------------------------- * Session Authenticator Configuration * -------------------------------------------------------------------- * These settings only apply if you are using the Session Authenticator * for authentication. * * - field The name of the key the current user info is stored in session * - allowRemembering Does the system allow use of "remember-me" * - rememberCookieName The name of the cookie to use for "remember-me" * - rememberLength The length of time, in seconds, to remember a user. * * @var array */ public array $sessionConfig = [ 'field' => 'user', 'allowRemembering' => true, 'rememberCookieName' => 'remember', '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', ], ]; /** * -------------------------------------------------------------------- * The validation rules for Company ID * -------------------------------------------------------------------- * * Do not use string rules like `required|valid_email`. * * @var array|string> */ public array $companyIDValidationRules = [ 'label' => 'Auth.company_id', 'rules' => [ 'required' ], ]; /** * -------------------------------------------------------------------- * The validation rules for Employee ID * -------------------------------------------------------------------- * * Do not use string rules like `required|valid_email`. * * @var array|string> */ public array $employeeIDValidationRules = [ 'label' => 'Auth.employee_id', 'rules' => [ 'required' ], ]; /** * -------------------------------------------------------------------- * The validation rules for Display Name * -------------------------------------------------------------------- * * Do not use string rules like `required|valid_email`. * * @var array|string> */ public array $displayNameValidationRules = [ 'label' => 'Auth.display_name', 'rules' => [ 'required' ], ]; /** * -------------------------------------------------------------------- * Minimum Password Length * -------------------------------------------------------------------- * The minimum length that a password must be to be accepted. * Recommended minimum value by NIST = 8 characters. */ public int $minimumPasswordLength = 8; /** * -------------------------------------------------------------------- * Password Check Helpers * -------------------------------------------------------------------- * The PasswordValidator class runs the password through all of these * classes, each getting the opportunity to pass/fail the password. * You can add custom classes as long as they adhere to the * CodeIgniter\Shield\Authentication\Passwords\ValidatorInterface. * * @var list> */ public array $passwordValidators = [ CompositionValidator::class, NothingPersonalValidator::class, DictionaryValidator::class, // PwnedValidator::class, ]; /** * -------------------------------------------------------------------- * Valid login fields * -------------------------------------------------------------------- * Fields that are available to be used as credentials for login. */ public array $validFields = [ //'email', 'username', ]; /** * -------------------------------------------------------------------- * Additional Fields for "Nothing Personal" * -------------------------------------------------------------------- * The NothingPersonalValidator prevents personal information from * being used in passwords. The email and username fields are always * considered by the validator. Do not enter those field names here. * * An extended User Entity might include other personal info such as * first and/or last names. $personalFields is where you can add * fields to be considered as "personal" by the NothingPersonalValidator. * For example: * $personalFields = ['firstname', 'lastname']; */ public array $personalFields = []; /** * -------------------------------------------------------------------- * Password / Username Similarity * -------------------------------------------------------------------- * Among other things, the NothingPersonalValidator checks the * amount of sameness between the password and username. * Passwords that are too much like the username are invalid. * * The value set for $maxSimilarity represents the maximum percentage * of similarity at which the password will be accepted. In other words, any * calculated similarity equal to, or greater than $maxSimilarity * is rejected. * * The accepted range is 0-100, with 0 (zero) meaning don't check similarity. * Using values at either extreme of the *working range* (1-100) is * not advised. The low end is too restrictive and the high end is too permissive. * The suggested value for $maxSimilarity is 50. * * You may be thinking that a value of 100 should have the effect of accepting * everything like a value of 0 does. That's logical and probably true, * but is unproven and untested. Besides, 0 skips the work involved * making the calculation unlike when using 100. * * The (admittedly limited) testing that's been done suggests a useful working range * of 50 to 60. You can set it lower than 50, but site users will probably start * to complain about the large number of proposed passwords getting rejected. * At around 60 or more it starts to see pairs like 'captain joe' and 'joe*captain' as * perfectly acceptable which clearly they are not. * * To disable similarity checking set the value to 0. * public $maxSimilarity = 0; */ public int $maxSimilarity = 50; /** * -------------------------------------------------------------------- * 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 */ public string $hashAlgorithm = PASSWORD_DEFAULT; /** * -------------------------------------------------------------------- * ARGON2I/ARGON2ID Algorithm options * -------------------------------------------------------------------- * 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. */ public int $hashMemoryCost = 65536; // PASSWORD_ARGON2_DEFAULT_MEMORY_COST; public int $hashTimeCost = 4; // PASSWORD_ARGON2_DEFAULT_TIME_COST; public int $hashThreads = 1; // PASSWORD_ARGON2_DEFAULT_THREADS; /** * -------------------------------------------------------------------- * BCRYPT Algorithm options * -------------------------------------------------------------------- * 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 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 = 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 * -------------------------------------------------------------------- * The name of the class that handles user persistence. * By default, this is the included UserModel, which * works with any of the database engines supported by CodeIgniter. * You can change it as long as they adhere to the * CodeIgniter\Shield\Models\UserModel. * * @var class-string */ public string $userProvider = UserModel::class; /** * Returns the URL that a user should be redirected * to after a successful login. */ public function loginRedirect(): string { $session = session(); $url = $session->getTempdata('beforeLoginUrl') ?? setting('Auth.redirects')['login']; return $this->getUrl($url); } /** * Returns the URL that a user should be redirected * to after they are logged out. */ public function logoutRedirect(): string { $url = setting('Auth.redirects')['logout']; return $this->getUrl($url); } /** * Returns the URL the user should be redirected to * after a successful registration. */ public function registerRedirect(): string { $url = setting('Auth.redirects')['register']; 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 { // 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; } }