Scrollreveal+cat+datenews

This commit is contained in:
2019-01-07 11:43:39 +01:00
parent e4cac3d01e
commit 762a1ad170
3158 changed files with 140699 additions and 73915 deletions
+2
View File
@@ -0,0 +1,2 @@
.idea
.DS_Store
+29
View File
@@ -1,3 +1,32 @@
# v2.8.2
## 12/14/2018
1. [](#new)
* Fire `onUserLoginRegisteredUser()` event to allow manipulation of User object after registration
# v2.8.1
## 12/13/2018
1. [](#bugfix)
* Fix various redirects to use `lang-safe` variety for better multi-language support [#186]((https://github.com/getgrav/grav-plugin-login/issues/186))
* Ensure only defined `user_registration.fields` are allowed in registration and profile forms
# v2.8.0
## 11/12/2018
1. [](#new)
* Store remember me triplets into `user://data/rememberme` instead of storing them into the cache
* Ability to register + authorize but require accounts to be manually enabled [#180](https://github.com/getgrav/grav-plugin-login/issues/180)
1. [](#improved)
* If login on registration or activation has been turned on, use login redirect if override is not set
* Dont set default templates for `register` and `unauthorized`, use overridable templates [#179](https://github.com/getgrav/grav-plugin-login/issues/179)
* Updated `de.yaml` [#175](https://github.com/getgrav/grav-plugin-login/pull/175)
* Updated `ru.yaml` [#176](https://github.com/getgrav/grav-plugin-login/pull/176)
1. [](#bugfix)
* Fixed broken remember me functionality
* Fixed client side validation in login forms
* Fix uppercase and Unicode username handling [#177](https://github.com/getgrav/grav-plugin-login/pull/177)
# v2.7.3
## 06/20/2018
+66 -21
View File
@@ -139,31 +139,61 @@ access:
# Default Configuration
```yaml
enabled: true # Enable the plugin
built_in_css: true # Use built-in CSS
route: # Specific route for Login page (default is '/login')
redirect_to_login: true # If you try to access a page you don't have access to, should you redirect to login route
redirect_after_login: # Path to redirect to after a successful login (eg '/user_profile')
route_activate: '/activate_user' # Route for the user activation process
route_forgot: '/forgot_password' # Route for the forgot password process
route_reset: '/reset_password' # Route for the reset password process
route_profile: '/user_profile' # Route for the user profile page
route_register: '/user_register' # Route for the user registration page
route_unauthorized: '/user_unauthorized' # Route for a page to display if user is unauthorized
enabled: true # Enable the plugin
built_in_css: true # Use built-in CSS
route: # Specific route for Login page (default is '/login')
redirect_to_login: true # If you try to access a page you don't have access to, should you redirect to login route
redirect_after_login: # Path to redirect to after a successful login (eg '/user_profile')
redirect_after_logout: '/' # Path to redirect to after a successful logout (eg '/')
route_activate: '/activate_user' # Route for the user activation process
route_forgot: '/forgot_password' # Route for the forgot password process
route_reset: '/reset_password' # Route for the reset password process
route_profile: '/user_profile' # Route for the user profile page
route_register: '/user_register' # Route for the user registration page
route_unauthorized: '/user_unauthorized' # Route for a page to display if user is unauthorized
dynamic_page_visibility: false # Integrate access into page visibility so things can be shown or hidden in the menu
parent_acl: false # Look to parent `access` rules for access requirements
protect_protected_page_media: false # Take `access` rules into account when directly accessing a page's media
dynamic_page_visibility: false # Integrate access into page visibility so things can be shown or hidden in the menu
parent_acl: false # Look to parent `access` rules for access requirements
protect_protected_page_media: false # Take `access` rules into account when directly accessing a page's media
rememberme:
enabled: true # Enable 'remember me' functionality
timeout: 604800 # Timeout in seconds. Defaults to 1 week
name: grav-rememberme # Name prefix of the session cookie
enabled: true # Enable 'remember me' functionality
timeout: 604800 # Timeout in seconds. Defaults to 1 week
name: grav-rememberme # Name prefix of the session cookie
max_pw_resets_count: 0 # Number of password resets in a specific time frame (0 = unlimited)
max_pw_resets_interval: 60 # Time in minutes to track password resets
max_login_count: 0 # Number of failed login attempts in a specific time frame (0 = unlimited)
max_login_interval: 2 # Time in minutes to track login attempts
max_pw_resets_count: 0 # Number of password resets in a specific time frame (0 = unlimited)
max_pw_resets_interval: 60 # Time in minutes to track password resets
max_login_count: 0 # Number of failed login attempts in a specific time frame (0 = unlimited)
max_login_interval: 2 # Time in minutes to track login attempts
user_registration:
enabled: false # Enable User Registration Process
fields: # List of fields to validate and store during user registration
- 'username' # This should match up with your registration form definition
- 'password'
- 'email'
- 'fullname'
- 'title'
- 'level'
default_values: # Any default values for fields you would like to set
level: Newbie # Here the 'level' field will be pre-populated with 'Newbie' text
access: # Default access to set for users created during registration
site:
login: 'true'
redirect_after_registration: '' # Route to redirect to after registration
options:
validate_password1_and_password2: true # Ensure that password1 and password2 match during registration (allows you to have just 1 pw field or 2)
set_user_disabled: false # Set this `true` if you want a user to activate their account via email
login_after_registration: false # Automatically login after registration
send_activation_email: false # Send an email that requires a special link to be clicked in order to activate the account
manually_enable: false # When using activation email, don't enable until an admin does it manually
send_notification_email: false # Send an email to the site administrator to indicate a user has registered
send_welcome_email: false # Send a welcome email to the user (probably should not be used with `send_activation_email`
```
# Usage
@@ -483,7 +513,22 @@ You can set the "Redirect after registration" option in the Login plugin, or as
display: /welcome
```
## Dynamic Page Visibility
You can control whether or not a page is visible to a user by first enabling the option in the `login` configuration:
```
dyanamic_page_visilbity: true
```
With this activated you can put the following option into the header of each page:
```
login:
visibility_requires_access: true
```
This will ensure the `access:` options on the page are satisfied in order for this page to be `visible` and therefore displayed in the menu structure.
# Known issues
+18 -5
View File
@@ -1,5 +1,5 @@
name: Login
version: 2.7.3
version: 2.8.2
description: Enables user authentication and login screen.
icon: sign-in
author:
@@ -290,7 +290,7 @@ form:
type: toggle
label: PLUGIN_LOGIN.SET_USER_DISABLED
help: PLUGIN_LOGIN.SET_USER_DISABLED_HELP
highlight: 1
highlight: 0
options:
1: PLUGIN_ADMIN.YES
0: PLUGIN_ADMIN.NO
@@ -312,18 +312,29 @@ form:
type: toggle
label: PLUGIN_LOGIN.SEND_ACTIVATION_EMAIL
help: PLUGIN_LOGIN.SEND_ACTIVATION_EMAIL_HELP
highlight: 1
highlight: 0
options:
1: PLUGIN_ADMIN.YES
0: PLUGIN_ADMIN.NO
validate:
type: bool
user_registration.options.manually_enable:
type: toggle
label: PLUGIN_LOGIN.MANUALLY_ENABLE
help: PLUGIN_LOGIN.MANUALLY_ENABLE_HELP
highlight: 0
options:
1: PLUGIN_ADMIN.YES
0: PLUGIN_ADMIN.NO
validate:
type: bool
user_registration.options.send_notification_email:
type: toggle
label: PLUGIN_LOGIN.SEND_NOTIFICATION_EMAIL
help: PLUGIN_LOGIN.SEND_NOTIFICATION_EMAIL_HELP
highlight: 1
highlight: 0
options:
1: PLUGIN_ADMIN.YES
0: PLUGIN_ADMIN.NO
@@ -334,10 +345,12 @@ form:
type: toggle
label: PLUGIN_LOGIN.SEND_WELCOME_EMAIL
help: PLUGIN_LOGIN.SEND_WELCOME_EMAIL_HELP
highlight: 1
highlight: 0
options:
1: PLUGIN_ADMIN.YES
0: PLUGIN_ADMIN.NO
validate:
type: bool
Security:
type: tab
+10 -4
View File
@@ -335,7 +335,13 @@ class Controller
$author = $this->grav['config']->get('site.author.name', '');
$fullname = $user->fullname ?: $user->username;
$reset_link = $this->grav['base_url_absolute'] . $this->grav['config']->get('plugins.login.route_reset') . '/task:login.reset/token' . $param_sep . $token . '/user' . $param_sep . $user->username . '/nonce' . $param_sep . Utils::getNonce('reset-form');
if ($this->grav['language']->getDefault() != $this->grav['language']->getLanguage()) {
$lang = '/'.$this->grav['language']->getLanguage();
} else {
$lang = '';
}
$reset_link = $this->grav['base_url_absolute'] . $lang . $this->grav['config']->get('plugins.login.route_reset') . '/task:login.reset/token' . $param_sep . $token . '/user' . $param_sep . $user->username . '/nonce' . $param_sep . Utils::getNonce('reset-form');
$sitename = $this->grav['config']->get('site.title', 'Website');
@@ -381,7 +387,7 @@ class Controller
if ($good_token === $token) {
if (time() > $expire) {
$messages->add($language->translate('PLUGIN_LOGIN.RESET_LINK_EXPIRED'), 'error');
$this->grav->redirect($this->grav['config']->get('plugins.login.route_forgot', '/'));
$this->grav->redirectLangSafe($this->grav['config']->get('plugins.login.route_forgot', '/'));
return true;
}
@@ -401,7 +407,7 @@ class Controller
}
$messages->add($language->translate('PLUGIN_LOGIN.RESET_INVALID_LINK'), 'error');
$this->grav->redirect($this->grav['config']->get('plugins.login.route_forgot'));
$this->grav->redirectLangSafe($this->grav['config']->get('plugins.login.route_forgot'));
return true;
@@ -412,7 +418,7 @@ class Controller
if (!$user || !$token) {
$messages->add($language->translate('PLUGIN_LOGIN.RESET_INVALID_LINK'), 'error');
$this->grav->redirect($this->grav['config']->get('plugins.login.route_forgot'));
$this->grav->redirectLangSafe($this->grav['config']->get('plugins.login.route_forgot'));
return true;
}
+7 -8
View File
@@ -196,7 +196,7 @@ class Login
}
if ($redirect) {
$this->grav->redirect($redirect, $event->getRedirectCode());
$this->grav->redirectLangSafe($redirect, $event->getRedirectCode());
}
return $user->authenticated && $user->authorized;
@@ -230,7 +230,7 @@ class Login
$username = $this->validateField('username', $data['username']);
$file = CompiledYamlFile::instance($this->grav['locator']->findResource('account://' . $username . YAML_EXT,
$file = CompiledYamlFile::instance($this->grav['locator']->findResource('account://' . mb_strtolower($username) . YAML_EXT,
true, true));
// Create user object and save it
@@ -423,9 +423,6 @@ class Login
$author
]);
$to = $user->email;
$sent = EmailUtils::sendEmail($subject, $content, $to);
if ($sent < 1) {
@@ -452,12 +449,14 @@ class Login
if (!$this->rememberMe) {
/** @var Config $config */
$config = $this->grav['config'];
$cookieName = $config->get('plugins.login.rememberme.name');
$timeout = $config->get('plugins.login.rememberme.timeout');
// Setup storage for RememberMe cookies
$storage = new TokenStorage;
$storage = new TokenStorage('user://data/rememberme', $timeout);
$this->rememberMe = new RememberMe($storage);
$this->rememberMe->setCookieName($config->get('plugins.login.rememberme.name'));
$this->rememberMe->setExpireTime($config->get('plugins.login.rememberme.timeout'));
$this->rememberMe->setCookieName($cookieName);
$this->rememberMe->setExpireTime($timeout);
// Hardening cookies with user-agent and random salt or
// fallback to use system based cache key
@@ -2,35 +2,28 @@
/**
* @package Grav\Plugin\Login
*
* @copyright Copyright (C) 2014 - 2017 RocketTheme, LLC. All rights reserved.
* @copyright Copyright (C) 2014 - 2018 RocketTheme, LLC. All rights reserved.
* @license MIT License; see LICENSE file for details.
*/
namespace Grav\Plugin\Login\RememberMe;
use Grav\Common\Cache;
use Grav\Common\File\CompiledYamlFile;
use Grav\Common\Filesystem\Folder;
use Grav\Common\Grav;
use Doctrine\Common\Cache\CacheProvider;
use Doctrine\Common\Cache\FilesystemCache;
use Birke\Rememberme\Storage\StorageInterface;
/**
* Storage wrapper for Doctrine cache
* Token Storage wrapper
*
* Used for storing the credential/token/persistentToken triplets.
*
* @author Sommerregen <sommerregen@benjamin-regler.de>
*/
class TokenStorage implements StorageInterface
{
/**
* @var CacheProvider
*/
protected $driver;
/** @var string */
protected $path;
/**
* @var string
*/
protected $cache_dir;
/** @var int */
protected $timeout;
/**
* Constructor
@@ -38,28 +31,16 @@ class TokenStorage implements StorageInterface
* @param string $path Path to storage directory
* @throws \InvalidArgumentException
*/
public function __construct($path = 'cache://rememberme')
public function __construct($path = 'user://data/rememberme', $timeout = 604800)
{
/** @var Cache $cache */
$cache = Grav::instance()['cache'];
$this->cache_dir = Grav::instance()['locator']->findResource($path, true, true);
// Setup cache
$this->driver = $cache->getCacheDriver();
if ($this->driver instanceof FilesystemCache) {
$this->driver = new FilesystemCache($this->cache_dir);
}
// Set the cache namespace to our unique key
$this->driver->setNamespace($cache->getKey());
$this->path = Grav::instance()['locator']->findResource($path, true, true);
$this->timeout = $timeout;
}
/**
* Return Tri-state value constant
*
* @param mixed $credential Unique credential (user id,
* email address, user name)
* @param mixed $credential Unique credential (user id, email address, user name)
* @param string $token One-Time Token
* @param string $persistentToken Persistent Token
*
@@ -67,64 +48,47 @@ class TokenStorage implements StorageInterface
*/
public function findTriplet($credential, $token, $persistentToken)
{
// Hash the tokens, because they can contain a salt and can be accessed in the file system
$persistentToken = sha1($persistentToken);
$token = sha1($token);
// Hash the tokens, because they can contain a salt and can be
// accessed in the file system
$persistentToken = sha1(trim($persistentToken));
$token = sha1(trim($token));
$file = $this->getFile($credential);
$tokens = (array)$file->content();
$id = $this->getId($credential);
if (!$this->driver->contains($id)) {
if (!isset($tokens[$persistentToken]) || $tokens[$persistentToken] < time() + $this->timeout) {
return self::TRIPLET_NOT_FOUND;
}
list($expire, $tokens) = $this->driver->fetch($id);
if (isset($tokens[$persistentToken]) && $tokens[$persistentToken] === $token) {
return self::TRIPLET_FOUND;
$stored = key($tokens[$persistentToken]);
if ($stored !== $token) {
return self::TRIPLET_INVALID;
}
return self::TRIPLET_INVALID;
return self::TRIPLET_FOUND;
}
/**
* Store the new token for the credential and the persistent token.
* Create a new storage entry, if the combination of credential and
* persistent token does not exist.
* Store the new token for the credential and the persistent token. Create a new storage entry, if the combination
* of credential and persistent token does not exist.
*
* @param mixed $credential
* @param string $token
* @param string $persistentToken
* @param int $expire Timestamp when this triplet
* will expire (0 = no expiry)
* @param int $expire Timestamp when this triplet will expire (0 = no expiry)
*/
public function storeTriplet($credential, $token, $persistentToken, $expire = null)
{
// Hash the tokens, because they can contain a salt and can be
// accessed in the file system
$persistentToken = sha1(trim($persistentToken));
$token = sha1(trim($token));
// Hash the tokens, because they can contain a salt and can be accessed in the file system
$persistentToken = sha1($persistentToken);
$token = sha1($token);
$e = null;
$tokens = [];
$id = $this->getId($credential);
if ($this->driver->contains($id)) {
list($e, $tokens) = $this->driver->fetch($id);
}
$file = $this->getFile($credential);
$tokens = (array)$file->content();
// Get cache lifetime for tokens
if ($expire === null && $e === null) {
/** @var Cache $cache */
$cache = Grav::instance()['cache'];
$expire = $cache->getLifetime();
} elseif ($expire === null) {
$expire = $e;
}
// Update token
$tokens[$persistentToken] = [$token => time()];
// Update tokens
$tokens[$persistentToken] = $token;
$this->driver->save($id, [$expire, $tokens], $expire);
return $this;
$file->save($tokens);
}
/**
@@ -137,7 +101,6 @@ class TokenStorage implements StorageInterface
*/
public function replaceTriplet($credential, $token, $persistentToken, $expire = null)
{
$this->cleanTriplet($credential, $persistentToken);
$this->storeTriplet($credential, $token, $persistentToken, $expire);
}
@@ -149,16 +112,25 @@ class TokenStorage implements StorageInterface
*/
public function cleanTriplet($credential, $persistentToken)
{
// Hash the tokens, because they can contain a salt and can be
// accessed in the file system
$persistentToken = sha1(trim($persistentToken));
// Hash the tokens, because they can contain a salt and can be accessed in the file system
$persistentToken = sha1($persistentToken);
// Delete token from storage
$id = $this->getId($credential);
if ($this->driver->contains($id)) {
list($expire, $tokens) = $this->driver->fetch($id);
$file = $this->getFile($credential);
if (!$file->exists()) {
return;
}
$tokens = (array)$file->content();
if (isset($tokens[$persistentToken])) {
// Delete token from storage
unset($tokens[$persistentToken]);
$this->driver->save($id, [$expire, $tokens], $expire);
if ($tokens) {
$file->save($tokens);
} else {
$file->delete();
}
}
}
@@ -170,8 +142,10 @@ class TokenStorage implements StorageInterface
*/
public function cleanAllTriplets($credential)
{
$id = $this->getId($credential);
$this->driver->delete($id);
$file = $this->getFile($credential);
if ($file->exists()) {
$file->delete();
}
}
/**
@@ -179,20 +153,17 @@ class TokenStorage implements StorageInterface
*/
public function clearCache()
{
$this->driver->flushAll();
if (is_dir($this->path)) {
Folder::delete($this->path, false);
}
}
/**
* Get the cache id
*
* @param string $key A key to compute the cache id for
* @return string The cache id
* @param string $credential
* @return CompiledYamlFile
*/
protected function getId($key)
protected function getFile($credential)
{
/** @var Cache $cache */
$cache = Grav::instance()['cache'];
return 'login' . md5(trim($key) . $cache->getKey());
return CompiledYamlFile::instance($this->path . '/' . sha1($credential) . '.yaml');
}
}
@@ -118,7 +118,7 @@ class ChangePasswordCommand extends ConsoleCommand
}
// Lowercase the username for the filename
$username = strtolower($username);
$username = mb_strtolower($username);
/** @var UniformResourceLocator $locator */
$locator = Grav::instance()['locator'];
@@ -116,7 +116,7 @@ class ChangeUserStateCommand extends ConsoleCommand
}
// Lowercase the username for the filename
$username = strtolower($username);
$username = mb_strtolower($username);
/** @var UniformResourceLocator $locator */
$locator = Grav::instance()['locator'];
+4 -4
View File
@@ -131,9 +131,9 @@ class NewUserCommand extends ConsoleCommand
return $value;
});
$username = $helper->ask($this->input, $this->output, $question);
$data['username'] = $helper->ask($this->input, $this->output, $question);
} else {
$username = $this->options['user'];
$data['username'] = $this->options['user'];
}
@@ -227,7 +227,7 @@ class NewUserCommand extends ConsoleCommand
}
// Lowercase the username for the filename
$username = strtolower($username);
$username = mb_strtolower($data['username']);
/** @var UniformResourceLocator $locator */
$locator = Grav::instance()['locator'];
@@ -281,4 +281,4 @@ class NewUserCommand extends ConsoleCommand
$question->setHiddenFallback(true);
return $helper->ask($this->input, $this->output, $question);
}
}
}
+15
View File
@@ -0,0 +1,15 @@
{
"project":"grav-plugin-login",
"platforms":{
"grav":{
"nodes":{
"plugin":[
{
"source":"/",
"destination":"/user/plugins/login"
}
]
}
}
}
}
+110 -29
View File
@@ -1,47 +1,128 @@
PLUGIN_LOGIN:
USERNAME: "Benutzername"
EMAIL: "Email"
USERNAME_EMAIL: "Benutzername/Email"
EMAIL: "E-Mail"
USERNAME_EMAIL: "Benutzername/E-Mail"
PASSWORD: "Passwort"
ACCESS_DENIED: "Zugang verweigert"
LOGIN_FAILED: "Login fehlgeschlagen..."
LOGIN_SUCCESSFUL: "Du wurdest erfolgreich eingeloggt."
ACCESS_DENIED: "Zugang verweigert"
LOGIN_FAILED: "Login fehlgeschlagen"
LOGIN_SUCCESSFUL: "Sie wurden erfolgreich angemeldet."
BTN_LOGIN: "Anmelden"
BTN_LOGOUT: "Abmelden"
BTN_FORGOT: "Vergessen"
BTN_REGISTER: "Registrieren"
BTN_RESET: "Passwort zurücksetzen"
BTN_SEND_INSTRUCTIONS: "Sende Anweisungen zum Zurücksetzen"
RESET_LINK_EXPIRED: "Der Link zum Zurücksetzen ist abgelaufen. Bitte erneut versuchen."
RESET_PASSWORD_RESET: "Das Passwort wurde zurückgesetzt"
RESET_INVALID_LINK: "Es wurde ein ungültiger Link zum Zurücksetzen verwendet. Bitte erneut versuchen."
FORGOT_INSTRUCTIONS_SENT_VIA_EMAIL: "Die Anweisungen zum Zurücksetzen Ihres Passworts wurden per E-Mail gesendet."
FORGOT_FAILED_TO_EMAIL: "Das Versenden der Anweisung per E-Mail ist fehlgeschlagen. Bitte später erneut versuchen."
FORGOT_CANNOT_RESET_EMAIL_NO_EMAIL: "Das Passwort für %s kann nicht zurückgesetzt werden. Es ist keine E-Mail-Adresse hinterlegt."
FORGOT_CANNOT_RESET_EMAIL_NO_PASSWORD: "Das Passwort für %s kann nicht zurückgesetzt werden. Diese E-Mail ist mit einem Remote-Account verknüpft."
FORGOT_USERNAME_DOES_NOT_EXIST: "Der Benutzer mit dem Benutzername <b>%s</ b> existiert nicht."
FORGOT_EMAIL_NOT_CONFIGURED: "Das Passwort kann nicht zurückgesetzt werden, da die Website ist nicht zum Versenden von E-Mails konfiguriert."
FORGOT_EMAIL_SUBJECT: "Passwort zurückzusetzen für %s"
FORGOT_EMAIL_BODY: "<h1>Passwort Zurücksetzen</h1><p>Hallo %1$s,</p><p>Es wurde ein Anfrage auf <b>%4$s</b> gestellt, um Ihr Passwort zu ändern.</p><p><br /><a href=\"%2$s\" class=\"btn-primary\">Klicken Sie hier, um Ihr Passwort zurückzusetzen</a><br /><br /></p><p>Alternativ kopieren Sie die folgende URL in die Adresszeile Ihres Browsers:</p> <p class=\"word-break\"><a href=\"%2$s\">%2$s</a></p> <p><br />Mit freundlichen Grüßen,<br /><br />%3$s</p>"
REMEMBER_ME: "Angemeldet bleiben"
REMEMBER_ME_HELP: "Speichert einen Cookie im Browser, welcher eine fortwährende Anmeldung sicherstellt."
BUILTIN_CSS: "Nutze das integrierte CSS"
REMEMBER_ME_STOLEN_COOKIE: "Jemand anderes hat Ihre Zugangsdaten verwendet, um auf diese Seite zuzugreifen! Alle Sitzungen wurden ausgeloggt. Bitte melden Sie sich mit Ihren Zugangsdaten an und überprüfen Sie Ihre Daten."
BUILTIN_CSS: "Nutze das integrierte Plugin CSS"
BUILTIN_CSS_HELP: "Nutze das CSS, welches vom Admin Plugin bereitgestellt werden"
ROUTE: "Anmeldepfad"
ROUTE_HELP: "Route zu einer benutzerdefinierten Anmeldeseite, die von Ihrem Theme bereitgestellt wird."
ROUTE_REGISTER: "Registrierungspfad"
USERNAME_NOT_AVAILABLE: "Der Nutzername %s existiert bereits, bitte wähle einen Anderen"
USER_NEEDS_EMAIL_FIELD: "Der Nutzer benötigt ein E-Mail Feld"
EMAIL_SENDING_FAILURE: "Ein Fehler ist beim senden der E-Mail aufgetreten"
ACTIVATION_EMAIL_SUBJECT: "Aktiviere dein Account auf %s"
ACTIVATION_EMAIL_BODY: "Hi %s, click %s to activate your account on %s"
WELCOME_EMAIL_SUBJECT: "Willkommen zu %s"
WELCOME_EMAIL_BODY: "Hi %s, willkommen zu %s!"
NOTIFICATION_EMAIL_SUBJECT: "Neuer Nutzer auf %s"
NOTIFICATION_EMAIL_BODY: "Hi, ein neuer Nutzer hat sich auf %s registriert. Nutzername: %s, E-Mail: %s"
ROUTE_REGISTER_HELP: "Pfad zur Registrierungsseite. Stellen Sie dies ein, wenn Sie die eingebaute Registrierungsseite verwenden möchten. Lassen Sie das Feld leer, wenn Sie ein eigenes Anmeldeformular haben."
USERNAME_NOT_VALID: "Der Benutzername sollte zwischen 3 und 16 Zeichen enthalten, einschließlich Kleinbuchstaben, Zahlen, Unterstrichen und Bindestrichen. Großbuchstaben, Leerzeichen und Sonderzeichen sind nicht zulässig"
USERNAME_NOT_AVAILABLE: "Der Benutzername %s existiert bereits. Bitte wählen Sie einen anderen Benutzernamen."
EMAIL_NOT_AVAILABLE: "Die E-Mail-Adresse %s ist bereits vorhanden. Bitte wählen Sie eine andere E-Mail-Adresse aus."
PASSWORD_NOT_VALID: "Das Passwort muss mindestens eine Zahl und einen Groß- und Kleinbuchstaben sowie mindestens 8 oder mehr Zeichen enthalten."
PASSWORDS_DO_NOT_MATCH: "Die Passwörter stimmen nicht überein. Überprüfen Sie, ob Sie das gleiche Passwort zweimal eingegeben haben."
USER_NEEDS_EMAIL_FIELD: "Der Benutzer benötigt ein E-Mail Feld."
EMAIL_SENDING_FAILURE: "Beim Senden der E-Mail ist ein Fehler aufgetreten."
ACTIVATION_EMAIL_SUBJECT: "Aktivieren Sie Ihren Account bei %s"
ACTIVATION_EMAIL_BODY: "<h1>Account Aktivierung</h1><p>Hallo %1$s, </p><p>Ihr Konto bei <b>%3$s</b> wurde erfolgreich erstellt, aber Sie können sich erst anmelden, wenn es aktiviert ist.</p><p><br/><a href=\"%2$s\" class=\"btn-primary\">Account jetzt aktivieren</a><br/><br/></p><p>Alternativ kopieren Sie die folgende URL in die Adresszeile Ihres Browsers:</p><p class=\"word-break\"><a href=\"%2$s\">%2$s</a></p><p><br/>Mit freundlichen Grüßen,<br/><br/>%4$s</p>"
ACTIVATION_NOTICE_MSG: "Hallo %s, Ihr Konto wurde erstellt. Bitte überprüfen Sie Ihre E-Mail, um es vollständig zu aktivieren"
WELCOME_EMAIL_SUBJECT: "Willkommen bei %s"
WELCOME_EMAIL_BODY: "<h1>Account erstellt</h1><p>Hallo %1$s, </p><p>Ihr Konto bei <b>%3$s</b> wurde erfolgreich erstellt.</p><p><br/><a href=\"%2$s\" class=\"btn-primary\">Jetzt anmelden</a><br/><br/></p><p>Alternativ kopieren Sie die folgende URL in die Adresszeile Ihres Browsers:</p><p class=\"word-break\"><a href=\"%2$s\">%2$s</a></p><p><br/>Mit freundlichen Grüßen,<br/><br/>%4$s</p>"
WELCOME_NOTICE_MSG: "Hallo %s, Ihr Account wurde erfolgreich erstellt"
NOTIFICATION_EMAIL_SUBJECT: "Neuer Benutzer bei %s"
NOTIFICATION_EMAIL_BODY: "<h1>Neuer Benutzer</h1><p>Hallo, ein neuer Benutzer hat sich bei %1$s registriert.</p><p><ul><li>Benutzername: <b>%2$s</b></li><li>E-Mail: <b>%3$s</b></ul><p><p><br/><a href=\"%4$s\" class=\"btn-primary\">%1$s aufrufen</a><br/><br/></p>"
EMAIL_FOOTER: "GetGrav.org"
ACTIVATION_LINK_EXPIRED: "Aktivierungslink ist abgelaufen"
USER_ACTIVATED_SUCCESSFULLY: "Nutzer erfolgreich aktiviert"
INVALID_REQUEST: "Ungültige Anfrage"
USER_REGISTRATION: "Nutzer Registrierung"
USER_REGISTRATION_ENABLED_HELP: "Aktiviere die Nutzer Registrierung"
VALIDATE_PASSWORD1_AND_PASSWORD2: "Überprüfe das doppelt eingegebene Passwort"
SEND_ACTIVATION_EMAIL: "Aktivierungs E-Mail senden"
SEND_NOTIFICATION_EMAIL: "Benachtichtigungs E-Mail senden"
SEND_WELCOME_EMAIL: "Sende eine Willkommens E-Mail"
DEFAULT_VALUES: "Standard Werte"
ACTIVATION_LINK_EXPIRED: "Der Aktivierungslink ist abgelaufen."
USER_ACTIVATED_SUCCESSFULLY: "Benutzer wurde erfolgreich aktiviert."
INVALID_REQUEST: "Ungültige Anfrage."
USER_REGISTRATION: "Benutzerregistrierung."
USER_REGISTRATION_ENABLED_HELP: "Benutzerregistrierung aktivieren."
VALIDATE_PASSWORD1_AND_PASSWORD2: "Doppelt eingegebenes Passwort bestätigen."
VALIDATE_PASSWORD1_AND_PASSWORD2_HELP: "Validieren und vergleichen Sie zwei verschiedene Felder für die Passwörter mit den Namen `password1` und` password2`. Aktivieren Sie diese Option, wenn Sie im Anmeldeformular zwei Passwortfelder haben."
SET_USER_DISABLED: "Benutzer als deaktiviert festlegen"
SET_USER_DISABLED_HELP: "Am besten zusammen mit der E-Mail 'Aktivierungs-E-Mail senden' verwenden. Fügt den Benutzer zu Grav hinzu, setzt ihn jedoch als deaktiviert"
LOGIN_AFTER_REGISTRATION: "Benutzer nach Registrierung anmelden."
LOGIN_AFTER_REGISTRATION_HELP: "Meldet den Benutzer direkt nach der Registrierung an. Wenn eine E-Mail-Aktivierung erforderlich ist, wird der Benutzer sofort nach der Aktivierung des Kontos angemeldet."
SEND_ACTIVATION_EMAIL: "Aktivierungs-E-Mail senden"
SEND_ACTIVATION_EMAIL_HELP: "Sendet eine E-Mail an den Benutzer, um seinen Account zu aktivieren. Aktivieren Sie die Option 'Benutzer als deaktiviert festlegen', wenn Sie diese Funktion verwenden, sodass der Benutzer als deaktiviert festgelegt wird und eine E-Mail gesendet wird, um das Konto zu aktivieren"
SEND_NOTIFICATION_EMAIL: "Benachrichtigungs-E-Mail senden"
SEND_NOTIFICATION_EMAIL_HELP: "Benachrichtigt den Seiten-Administrator, dass sich ein neuer Benutzer registriert hat. Die E-Mail wird in der E-Mail-Plugin-Konfiguration an das Feld 'to' gesendet"
SEND_WELCOME_EMAIL: "Sende Willkommens-E-Mail"
SEND_WELCOME_EMAIL_HELP: "Sendet eine E-Mail an den neu registrierten Benutzer"
DEFAULT_VALUES: "Standardwerte"
DEFAULT_VALUES_HELP: "Liste der Feldnamen und der zugehörigen Werte, die standardmäßig dem Benutzerprofil (Yaml-Datei) hinzugefügt werden, ohne vom Benutzer konfiguriert zu werden. Trennen Sie mehrere Werte durch ein Komma ohne Leerzeichen zwischen den Werten."
ADDITIONAL_PARAM_KEY: "Parameter"
ADDITIONAL_PARAM_VALUE: "Wert"
REGISTRATION_FIELDS: "Registrierungsfelder"
REGISTRATION_FIELDS_HELP: "Fügen Sie die Felder hinzu, die der Yaml-Datei des Benutzers hinzugefügt werden. Felder, die hier nicht aufgeführt sind, werden nicht hinzugefügt, auch wenn sie im Anmeldeformular vorhanden sind."
REGISTRATION_FIELD_KEY: "Feldname"
REDIRECT_AFTER_LOGIN: "Umleitung nach Login"
REDIRECT_AFTER_REGISTRATION: "Umleitung nach Registrierung"
REDIRECT_AFTER_LOGIN: "Weiterleitung nach Login."
REDIRECT_AFTER_LOGIN_HELP: "Benutzerdefinierte Seite zu der, nach erfolgreichem Login, weitergeleitet wird."
REDIRECT_AFTER_LOGOUT: "Weiterleitung nach Abmelden."
REDIRECT_AFTER_LOGOUT_HELP: "Benutzerdefinierte Seite zu der, nach dem Abmelden des Benutzers, weitergeleitet wird."
REDIRECT_AFTER_REGISTRATION: "Weiterleitung nach Registrierung."
REDIRECT_AFTER_REGISTRATION_HELP: "Benutzerdefinierte Seite zu der, nach Abschluss der Registrierung, weitergeleitet wird."
OPTIONS: "Optionen"
EMAIL_VALIDATION_MESSAGE: "Muss eine gültige E-Mail Adresse sein"
WELCOME: "Willkommen"
EMAIL_VALIDATION_MESSAGE: "Muss eine gültige E-Mail-Adresse sein."
PASSWORD_VALIDATION_MESSAGE: "Das Passwort muss mindestens eine Zahl und einen Groß- und Kleinbuchstaben sowie mindestens 8 oder mehr Zeichen enthalten."
TIMEOUT_HELP: "Legt das Sitzungszeitlimit in Sekunden fest, wenn 'Angemeldet bleiben' vom Benutzer aktiviert und überprüft wird. Das Minimum ist 604800, was einer Woche entspricht."
GROUPS_HELP: "Liste der Gruppen, denen neu registrierte Benutzer zugewiesen werden, falls vorhanden."
SITE_ACCESS_HELP: "Liste der Seiten, auf die neu registrierte Benutzer Zugriff haben. Beispiel: `login` -> `true`"
WELCOME: "Willkommen"
REDIRECT_AFTER_ACTIVATION: "Weiterleitung nach Benutzeraktivierung"
REDIRECT_AFTER_ACTIVATION_HELP: "Wird verwendet, wenn der Benutzer das Konto per E-Mail aktivieren muss. Einmal aktiviert, wird diese Seite angezeigt"
REGISTRATION_DISABLED: "Registrierung deaktiviert"
USE_PARENT_ACL_LABEL: "Übergeordnete Zugriffsregeln verwenden"
USE_PARENT_ACL_HELP: "Verwende übergeordneten Zugriffsregeln, wenn keine Regeln definiert sind."
PROTECT_PROTECTED_PAGE_MEDIA_LABEL: Schütze auch die Medien, von Login-geschützten Seiten."
PROTECT_PROTECTED_PAGE_MEDIA_HELP: "Wenn diese Option aktiviert ist, ist das Medium einer, durch einen Login geschützten, Seite ebenfalls Login-geschützt und kann nur angezeigt werden, wenn Sie angemeldet sind."
SECURITY_TAB: "Sicherheit"
MAX_RESETS_COUNT: "Max. Anzahl an Versuchen, um das Passwort zurücksetzen."
MAX_RESETS_COUNT_HELP: "'Flood protection' Einstellung, um das Passwort zurücksetzen (0 - nicht begrenzt)"
MAX_RESETS_INTERVAL: "Max. Intervall an Versuchen, um das Passwort zurücksetzen."
MAX_RESETS_INTERVAL_HELP: "Zeitintervall für die max. Anzahl an Versuchen das Passwort zurückzusetzen."
FORGOT_CANNOT_RESET_IT_IS_BLOCKED: "Kann das Passwort für %s nicht zurücksetzen, die Funktion zum Zurücksetzen des Passworts wurde vorübergehend blockiert. Bitte versuchen Sie es später erneut (maximal %s Minuten)"
MAX_LOGINS_COUNT: "Max. Anzahl an Anmeldeversuche"
MAX_LOGINS_COUNT_HELP: "'Flood protection' Einstellung (0 - nicht begrenzt)"
MAX_LOGINS_INTERVAL: "Max. Login Intervall"
MAX_LOGINS_INTERVAL_HELP: "Das max. Zeitintervall für Anmeldeversuche."
TOO_MANY_LOGIN_ATTEMPTS: "Zu viele fehlgeschlagene Anmeldeversuche in der konfigurierten Zeit (%s Minuten)"
SECONDS: "Sekunden"
RESETS: "Resets"
ATTEMPTS: "Versuche"
ROUTES: "Pfade"
ROUTE_FORGOT: "Pfad für 'Passwort vergessen'"
ROUTE_RESET: "Pfad für 'Passwort zurücksetzen'"
ROUTE_PROFILE: "Benutzerprofil Pfad"
ROUTE_ACTIVATE: "Benutzeraktivierung Pfad"
LOGGED_OUT: "Sie wurden erfolgreich abgemeldet…"
PAGE_RESTRICTED: "Der Zugang ist eingeschränkt, bitte melden Sie sich an…"
DYNAMIC_VISIBILITY: "Dynamische Seitensichtbarkeit"
DYNAMIC_VISIBILITY_HELP: "Ermöglicht die dynamische Verarbeitung der Seitensichtbarkeit basierend auf Zugriffsregeln, wenn 'login.visibility_requires_access' auf einer Seite auf 'true' gesetzt ist."
USER_IS_REMOTE_ONLY: "Dieser Benutzer wurde mit einem Remotedienst authentifiziert, sodass sein Profil nicht gespeichert werden kann."
2FA_TITLE: "2-Faktor-Authentifizierung"
2FA_INSTRUCTIONS: "##### 2-Faktor-Authentifizierung\n Sie haben **2FA** für dieses Konto aktiviert. Bitte verwenden Sie Ihre **2FA** App, um den aktuellen **6-stelligen Code ** einzugeben, damit der Anmeldevorgang abgeschlossen werden kann."
2FA_REGEN_HINT: "Wenn Sie das Secret neu generieren, müssen Sie Ihre Authentifikator-App aktualisieren."
2FA_FAILED: "Ungültiger 2-Faktor-Authentifizierungscode, bitte versuchen Sie es erneut…"
2FA_ENABLED: "2FA aktiviert"
2FA_CODE_INPUT: "000000"
2FA_SECRET: "2FA Secret"
2FA_SECRET_HELP: "Scannen Sie diesen QR-Code in Ihre [Authenticator App](https://learn.getgrav.org/admin-panel/2fa#apps). Es ist sinnvoll, das Secret an einem sicheren Ort zu sichern, falls Sie Ihre App neu installieren müssen. In der [Grav Doku](https://learn.getgrav.org/admin-panel/2fa) finden Sie weitere Informationen."
2FA_REGENERATE: "Neu generieren"
BTN_CANCEL: "Abbrechen"
+5 -2
View File
@@ -50,7 +50,8 @@ PLUGIN_LOGIN:
NOTIFICATION_EMAIL_BODY: "<h1>New User</h1><p>Hi, a new user registered on %1$s.</p><p><ul><li>Username: <b>%2$s</b></li><li>Email: <b>%3$s</b></ul><p><p><br/><a href=\"%4$s\" class=\"btn-primary\">Visit %1$s</a><br/><br/></p>"
EMAIL_FOOTER: "GetGrav.org"
ACTIVATION_LINK_EXPIRED: "Activation link expired"
USER_ACTIVATED_SUCCESSFULLY: "User activated successfully"
USER_ACTIVATED_SUCCESSFULLY: "User account activated successfully"
USER_ACTIVATED_SUCCESSFULLY_NOT_ENABLED: "User account activated but account is being reviewed"
INVALID_REQUEST: "Invalid request"
USER_REGISTRATION: "User Registration"
USER_REGISTRATION_ENABLED_HELP: "Enable the user registration"
@@ -126,4 +127,6 @@ PLUGIN_LOGIN:
2FA_SECRET: "2FA Secret"
2FA_SECRET_HELP: "Scan this QR code into your [Authenticator App](https://learn.getgrav.org/admin-panel/2fa#apps). Also it's a good idea to backup the secret in a safe location, in case you need to reinstall your app. Check the [Grav docs](https://learn.getgrav.org/admin-panel/2fa) for more information "
2FA_REGENERATE: "Regenerate"
BTN_CANCEL: "Cancel"
BTN_CANCEL: "Cancel"
MANUALLY_ENABLE: "Manually Enable"
MANUALLY_ENABLE_HELP: "When using 'activation email' and 'notification email', you can ensure the user can self activate, but requires manually enabling the user to login"
+24 -3
View File
@@ -18,6 +18,7 @@ PLUGIN_LOGIN:
FORGOT_INSTRUCTIONS_SENT_VIA_EMAIL: "Инструкции по сбросу пароля были отправлены по электронной почте"
FORGOT_FAILED_TO_EMAIL: "Не удалось отправить инструкции по электронной почте, повторите попытку позже"
FORGOT_CANNOT_RESET_EMAIL_NO_EMAIL: "Не удается сбросить пароль для %s, адресс электронной почты не установлен"
FORGOT_CANNOT_RESET_EMAIL_NO_PASSWORD: "Невозможно сбросить пароль для %s, этот email связан с удаленной учетной записью"
FORGOT_USERNAME_DOES_NOT_EXIST: "Пользователь с именем <b>%s</b> не существует"
FORGOT_EMAIL_NOT_CONFIGURED: "Невозможно сбросить пароль. Этот сайт не настроен для отправки писем"
FORGOT_EMAIL_SUBJECT: "%s Запрос на сброс пароля"
@@ -34,14 +35,17 @@ PLUGIN_LOGIN:
ROUTE_REGISTER_HELP: "Путь к пользовательской странице регистрации. Заполните, если вы хотите использовать встроенную страницу регистрации. Оставьте его пустым, если у вас есть собственная регистрационная форма"
USERNAME_NOT_VALID: "Имя пользователя должно быть от 3 до 16 символов, включая строчные буквы, цифры, символы подчеркивания и дефисы. Прописные буквы, пробелы и специальные символы не допускаются"
USERNAME_NOT_AVAILABLE: "Имя пользователя %s уже существует, выберите другое имя пользователя"
EMAIL_NOT_AVAILABLE: "Адрес электронной почты %s уже существует, выберите другой адрес электронной почты"
PASSWORD_NOT_VALID: "Пароль должен содержать как минимум одно число, одну прописную и строчную букву, и быть не менее 8 символов"
PASSWORDS_DO_NOT_MATCH: "Пароли не совпадают. Дважды проверьте, что вы дважды ввели тот же пароль"
USER_NEEDS_EMAIL_FIELD: "Пользователю требуется поле электронной почты"
EMAIL_SENDING_FAILURE: "Произошла ошибка при отправке письма"
ACTIVATION_EMAIL_SUBJECT: "Активируйте свою учетную запись %s"
ACTIVATION_EMAIL_BODY: "Привет %s, перейдите <a href=\"%s\">сюда</a> для активации вашей учетной записи %s"
ACTIVATION_NOTICE_MSG: "Привет %s, ваша учетная запись создана, пожалуйста проверьте электронную почту, чтобы полностью ее активировать"
WELCOME_EMAIL_SUBJECT: "Добро пожаловать в %s"
WELCOME_EMAIL_BODY: "Привет %s, добро пожаловать в %s!"
WELCOME_NOTICE_MSG: "Привет %s, ваша учетная запись была успешно создана"
NOTIFICATION_EMAIL_SUBJECT: "Новый пользователь %s"
NOTIFICATION_EMAIL_BODY: "Привет, новый пользователь, зарегистрированный на %s. Имя пользователя: %s, email: %s"
EMAIL_FOOTER: "GetGrav.org"
@@ -54,8 +58,8 @@ PLUGIN_LOGIN:
VALIDATE_PASSWORD1_AND_PASSWORD2_HELP: "Подтвердить и сравнить два разных поля для паролей с именами `password1` и` password2`. Включите это, если у вас есть два поля пароля в регистрационной форме"
SET_USER_DISABLED: "Установить пользователя как отключенный"
SET_USER_DISABLED_HELP: "Лучше всего использовать электронную почту «Отправить электронную почту активации». Добавляет пользователя в Grav, но устанавливает его как отключенный"
LOGIN_AFTER_REGISTRATION: "Воход в систему после регистрации"
LOGIN_AFTER_REGISTRATION_HELP: "Автоматический воход в систему после регистрации. Если требуется активация электронной почты, пользователь будет входить в систему сразу после активации учетной записи"
LOGIN_AFTER_REGISTRATION: "Вход в систему после регистрации"
LOGIN_AFTER_REGISTRATION_HELP: "Автоматический вход в систему после регистрации. Если требуется активация электронной почты, пользователь будет входить в систему сразу после активации учетной записи"
SEND_ACTIVATION_EMAIL: "Отправить письмо активации"
SEND_ACTIVATION_EMAIL_HELP: "Отправляет электронное письмо пользователю для активации своей учетной записи. Включите параметр «Установить пользователя как отключенный» при использовании этой функции, чтобы пользователь был отключен, и для активации учетной записи будет отправлено электронное письмо"
SEND_NOTIFICATION_EMAIL: "Отправить уведомление по электронной почте"
@@ -71,6 +75,8 @@ PLUGIN_LOGIN:
REGISTRATION_FIELD_KEY: "Имя поля"
REDIRECT_AFTER_LOGIN: "Перенаправление после входа в систему"
REDIRECT_AFTER_LOGIN_HELP: "Пользовательский маршрут для перенаправления после входа в систему"
REDIRECT_AFTER_LOGOUT: "Перенаправление после выхода из системы"
REDIRECT_AFTER_LOGOUT_HELP: "Пользовательский маршрут для перенаправления после выхода из системы"
REDIRECT_AFTER_REGISTRATION: "Перенаправление после регистрации"
REDIRECT_AFTER_REGISTRATION_HELP: "Пользовательский маршрут для перенаправления после регистрации"
OPTIONS: "Опции"
@@ -105,4 +111,19 @@ PLUGIN_LOGIN:
ROUTE_FORGOT: "Забыли пароль"
ROUTE_RESET: "Сброса пароля"
ROUTE_PROFILE: "Профиля пользователя"
ROUTE_ACTIVATE: "Активации пользователя"
ROUTE_ACTIVATE: "Активации пользователя"
LOGGED_OUT: "Вы успешно вышли из системы..."
PAGE_RESTRICTED: "Доступ ограничен, войдите в систему..."
DYNAMIC_VISIBILITY: "Динамическая видимость страницы"
DYNAMIC_VISIBILITY_HELP: "Позволяет динамически обрабатывать видимость страницы на основе правил доступа, если для параметра login.visibility_requires_access установлено значение true на странице"
USER_IS_REMOTE_ONLY: "Этот пользователь аутентифицирован с помощью удаленного сервиса, поэтому профиль не может быть сохранен"
2FA_TITLE: "2-факторная аутентификация"
2FA_INSTRUCTIONS: "##### 2-факторная аутентификация\nВ вашем аккаунте включена **2FA**. Пожалуйста, используйте свое **2FA** приложение для ввода текущего **6-значного кода** для завершения процесса входа в систему."
2FA_REGEN_HINT: "Чтобы восстановить секрет, вам потребуется обновить приложение для аутентификации"
2FA_FAILED: "Недопустимый код проверки подлинности 2-факторной аутентификации, повторите попытку...."
2FA_ENABLED: "2FA Включена"
2FA_CODE_INPUT: "000000"
2FA_SECRET: "2FA Секрет"
2FA_SECRET_HELP: "Сканируйте этот QR-код в свое [Приложение аутентификации](https://learn.getgrav.org/admin-panel/2fa#apps). Также рекомендуется сохранить секрет в безопасном месте, если вам прийдется переустановить приложение. Проверьте [Grav docs](https://learn.getgrav.org/admin-panel/2fa) для дополнительной информации "
2FA_REGENERATE: "Сгенерировать повторно"
BTN_CANCEL: "Отмена"
Executable → Regular
+98 -26
View File
@@ -7,6 +7,8 @@
*/
namespace Grav\Plugin;
use Grav\Common\Data\Data;
use Grav\Common\Debugger;
use Grav\Common\Grav;
use Grav\Common\Language\Language;
use Grav\Common\Page\Page;
@@ -330,7 +332,6 @@ class LoginPlugin extends Plugin
if (!$page) {
$page = new Page;
$page->init(new \SplFileInfo(__DIR__ . '/pages/register.md'));
$page->template('form');
$page->slug(basename($route));
$pages->addPage($page, $route);
@@ -354,6 +355,9 @@ class LoginPlugin extends Plugin
$token = $uri->param('token');
$user = User::load($username);
$redirect_route = $this->config->get('plugins.login.user_registration.redirect_after_activation');
$redirect_code = null;
if (empty($user->activation_token)) {
$message = $this->grav['language']->translate('PLUGIN_LOGIN.INVALID_REQUEST');
$messages->add($message, 'error');
@@ -365,13 +369,17 @@ class LoginPlugin extends Plugin
$message = $this->grav['language']->translate('PLUGIN_LOGIN.ACTIVATION_LINK_EXPIRED');
$messages->add($message, 'error');
} else {
$user['state'] = 'enabled';
if ($this->config->get('plugins.login.user_registration.options.manually_enable', false)) {
$message = $this->grav['language']->translate('PLUGIN_LOGIN.USER_ACTIVATED_SUCCESSFULLY_NOT_ENABLED');
} else {
$user['state'] = 'enabled';
$message = $this->grav['language']->translate('PLUGIN_LOGIN.USER_ACTIVATED_SUCCESSFULLY');
}
$messages->add($message, 'info');
unset($user['activation_token']);
$user->save();
$message = $this->grav['language']->translate('PLUGIN_LOGIN.USER_ACTIVATED_SUCCESSFULLY');
$messages->add($message, 'info');
if ($this->config->get('plugins.login.user_registration.options.send_welcome_email', false)) {
$this->login->sendWelcomeEmail($user);
}
@@ -380,7 +388,18 @@ class LoginPlugin extends Plugin
}
if ($this->config->get('plugins.login.user_registration.options.login_after_registration', false)) {
$this->login->login(['username' => $username], ['after_registration' => true]);
$loginEvent = $this->login->login(['username' => $username], ['after_registration' => true, 'return_event' => true]);
// If there's no activation redirect, get one from login.
if (!$redirect_route) {
$message = $loginEvent->getMessage();
if ($message) {
$messages->add($message, $loginEvent->getMessageType());
}
$redirect_route = $loginEvent->getRedirect();
$redirect_code = $loginEvent->getRedirectCode();
}
}
}
} else {
@@ -389,8 +408,7 @@ class LoginPlugin extends Plugin
}
}
$redirect_route = $this->config->get('plugins.login.user_registration.redirect_after_activation', '/');
$this->grav->redirect($redirect_route);
$this->grav->redirectLangSafe($redirect_route ?: '/', $redirect_code);
}
/**
@@ -430,7 +448,6 @@ class LoginPlugin extends Plugin
if (!$page) {
$page = new Page;
$page->init(new \SplFileInfo(__DIR__ . '/pages/unauthorized.md'));
$page->template('default');
$page->slug(basename($route));
$pages->addPage($page, $route);
@@ -521,7 +538,7 @@ class LoginPlugin extends Plugin
// User is not logged in; redirect to login page.
if ($this->redirect_to_login && $this->route && !$authorized) {
$this->grav->redirect($this->route, 302);
$this->grav->redirectLangSafe($this->route, 302);
}
/** @var Twig $twig */
@@ -637,8 +654,14 @@ class LoginPlugin extends Plugin
throw new \RuntimeException($language->translate('PLUGIN_LOGIN.USER_REGISTRATION_DISABLED'));
}
$form->validate();
$form->filter();
/** @var Data $form_data */
$form_data = $form->getData();
// Check for existing username
$username = $form->value('username');
$username = $form_data->get('username');
$existing_username = User::find($username,['username']);
if ($existing_username->exists()) {
$this->grav->fireEvent('onFormValidationError', new Event([
@@ -653,7 +676,7 @@ class LoginPlugin extends Plugin
}
// Check for existing email
$email = $form->value('email');
$email = $form_data->get('email');
$existing_email = User::find($email,['email']);
if ($existing_email->exists()) {
$this->grav->fireEvent('onFormValidationError', new Event([
@@ -675,7 +698,7 @@ class LoginPlugin extends Plugin
if ($this->config->get('plugins.login.user_registration.options.validate_password1_and_password2',
false)
) {
if ($form->value('password1') !== $form->value('password2')) {
if ($form_data->get('password1') !== $form_data->get('password2')) {
$this->grav->fireEvent('onFormValidationError', new Event([
'form' => $form,
'message' => $language->translate('PLUGIN_LOGIN.PASSWORDS_DO_NOT_MATCH')
@@ -684,7 +707,7 @@ class LoginPlugin extends Plugin
return;
}
$data['password'] = $form->value('password1');
$data['password'] = $form_data->get('password1');
}
$fields = (array)$this->config->get('plugins.login.user_registration.fields', []);
@@ -706,8 +729,8 @@ class LoginPlugin extends Plugin
}
}
if (!isset($data[$field]) && $form->value($field)) {
$data[$field] = $form->value($field);
if (!isset($data[$field]) && $form_data->get($field)) {
$data[$field] = $form_data->get($field);
}
}
@@ -719,6 +742,7 @@ class LoginPlugin extends Plugin
$this->grav->fireEvent('onUserLoginRegisterData', new Event(['data' => &$data]));
$user = $this->login->register($data);
$this->grav->fireEvent('onUserLoginRegisteredUser', new Event(['user' => &$user]));
$fullname = $user->fullname ?: $user->username;
@@ -739,13 +763,26 @@ class LoginPlugin extends Plugin
$this->grav->fireEvent('onUserLoginRegistered', new Event(['user' => $user]));
$redirect = $this->config->get('plugins.login.user_registration.redirect_after_registration');
$redirect_code = null;
if (isset($data['state']) && $data['state'] === 'enabled' && $this->config->get('plugins.login.user_registration.options.login_after_registration', false)) {
$this->login->login(['username' => $username], ['after_registration' => true], ['user' => $user]);
$loginEvent = $this->login->login(['username' => $username], ['after_registration' => true], ['user' => $user, 'return_event' => true]);
// If there's no registration redirect, get one from login.
if (!$redirect) {
$message = $loginEvent->getMessage();
if ($message) {
$messages->add($message, $loginEvent->getMessageType());
}
$redirect = $loginEvent->getRedirect();
$redirect_code = $loginEvent->getRedirectCode();
}
}
$redirect = $this->config->get('plugins.login.user_registration.redirect_after_registration', false);
if ($redirect) {
$this->grav->redirect($redirect);
$this->grav->redirectLangSafe($redirect, $redirect_code);
}
}
@@ -762,6 +799,12 @@ class LoginPlugin extends Plugin
$user = $this->grav['user'];
$language = $this->grav['language'];
$form->validate();
$form->filter();
/** @var Data $form_data */
$form_data = $form->getData();
// Don't save if user doesn't exist
if (!$user->exists()) {
$this->grav->fireEvent('onFormValidationError', new Event([
@@ -773,7 +816,7 @@ class LoginPlugin extends Plugin
}
// Stop overloading of username
$username = $form->value('username');
$username = $form->data('username');
if (isset($username)) {
$this->grav->fireEvent('onFormValidationError', new Event([
'form' => $form,
@@ -787,7 +830,7 @@ class LoginPlugin extends Plugin
}
// Check for existing email
$email = $form->value('email');
$email = $form->data('email');
$existing_email = User::find($email,['email']);
if ($user->username != $existing_email->username && $existing_email->exists()) {
$this->grav->fireEvent('onFormValidationError', new Event([
@@ -801,7 +844,15 @@ class LoginPlugin extends Plugin
return;
}
$user->merge($form->getData()->toArray());
$fields = (array)$this->config->get('plugins.login.user_registration.fields', []);
$data = [];
foreach ($fields as $field) {
if (!isset($data[$field]) && $form_data->get($field)) {
$data[$field] = $form_data->get($field);
}
}
$user->merge($data);
try {
$user->save();
@@ -865,17 +916,24 @@ class LoginPlugin extends Plugin
// Only use remember me if user isn't set and feature is enabled.
if ($this->grav['config']->get('plugins.login.rememberme.enabled') && !$event->getUser()->exists()) {
/** @var Debugger $debugger */
$debugger = $this->grav['debugger'];
/** @var RememberMe $rememberMe */
$rememberMe = $this->grav['login']->rememberMe();
$username = $rememberMe->login();
if ($rememberMe->loginTokenWasInvalid()) {
// Token was invalid. We will display error page as this was likely an attack.
$debugger->addMessage('Remember Me: Stolen token!');
throw new \RuntimeException($this->grav['language']->translate('PLUGIN_LOGIN.REMEMBER_ME_STOLEN_COOKIE'), 403);
}
if ($username === false) {
// User has not been remembered, there is no point of continuing.
$debugger->addMessage('Remember Me: No token matched.');
$event->setStatus($event::AUTHENTICATION_FAILURE);
$event->stopPropagation();
@@ -883,8 +941,25 @@ class LoginPlugin extends Plugin
}
// Allow remember me to work with different login methods.
$user = User::load($username, false);
$event->setCredential('username', $username);
$event->setUser(User::load($username, false));
$event->setUser($user);
if (!$user->exists()) {
$debugger->addMessage('Remember Me: User does not exist');
$event->setStatus($event::AUTHENTICATION_FAILURE);
$event->stopPropagation();
return;
}
$debugger->addMessage('Remember Me: Authenticated!');
$event->setStatus($event::AUTHENTICATION_SUCCESS);
$event->stopPropagation();
return;
}
}
@@ -967,9 +1042,6 @@ class LoginPlugin extends Plugin
$username = $event->getUser()->get('username');
if ($event->getCredential('rememberme')) {
$login->rememberMe()->createCookie($username);
} else {
$login->rememberMe()->getStorage()->cleanAllTriplets($username);
$login->rememberMe()->clearCookie();
}
}
}
+1
View File
@@ -50,5 +50,6 @@ user_registration:
set_user_disabled: false # Set this `true` if you want a user to activate their account via email
login_after_registration: false # Automatically login after registration
send_activation_email: false # Send an email that requires a special link to be clicked in order to activate the account
manually_enable: false # When using activation email, don't enable until an admin does it manually
send_notification_email: false # Send an email to the site administrator to indicate a user has registered
send_welcome_email: false # Send a welcome email to the user (probably should not be used with `send_activation_email`
@@ -1,3 +1,6 @@
{% set client_side_validation = form.client_side_validation is not null ? form.client_side_validation : config.plugins.form.client_side_validation|default(true) %}
{% set inline_errors = form.inline_errors is not null ? form.inline_errors : config.plugins.form.inline_errors(false) %}
<section id="grav-login">
{{ content|raw }}
+5 -2
View File
@@ -1,3 +1,6 @@
{% set client_side_validation = form.client_side_validation is not null ? form.client_side_validation : config.plugins.form.client_side_validation|default(true) %}
{% set inline_errors = form.inline_errors is not null ? form.inline_errors : config.plugins.form.inline_errors(false) %}
<section id="grav-login">
{% if page.template == 'login' or show_login_form %}
@@ -18,7 +21,7 @@
{% include template %}
{% endfor %}
<form method="post" action="{{ (base_url_relative ~ uri.path)|e }}" class="{{ form_outer_classes }}">
<form method="post" action="{{ (base_url_relative ~ uri.path)|e }}" class="{{ form_outer_classes }}">
{# OLD WAY OF INCLUDING 3RD PARTY LOGIN OPTIONS #}
{% if grav.twig.plugins_hooked_loginPage %}
@@ -58,4 +61,4 @@
{% endif %}
</section>
</section>
View File
@@ -1,4 +1,6 @@
{% set form = forms('login-twofa') %}
{% set client_side_validation = form.client_side_validation is not null ? form.client_side_validation : config.plugins.form.client_side_validation|default(true) %}
{% set inline_errors = form.inline_errors is not null ? form.inline_errors : config.plugins.form.inline_errors(false) %}
<form method="post" action="{{ (base_url_relative ~ uri.path)|e }}" class="{{ form_outer_classes }}">
{% for field in form.fields %}
@@ -1,4 +1,7 @@
{% if uri.param('token') and uri.param('task') %}
{% set client_side_validation = form.client_side_validation is not null ? form.client_side_validation : config.plugins.form.client_side_validation|default(true) %}
{% set inline_errors = form.inline_errors is not null ? form.inline_errors : config.plugins.form.inline_errors(false) %}
<section id="grav-login">
{{ content|raw }}
@@ -0,0 +1 @@
{% extends 'form.html.twig' %}
@@ -0,0 +1 @@
{% extends 'default.html.twig' %}
@@ -0,0 +1,9 @@
composer.lock
vendor
nbproject
.idea
.buildpath
.project
.DS_Store
.*.sw*
.*.un~
@@ -0,0 +1,14 @@
language: php
php:
- 5.4
- 5.5
- 5.6
- 7.0
- 7.1
- hhvm
install:
- travis_retry composer install --no-interaction
- composer info -i
script: vendor/bin/phpunit --bootstrap tests/bootstrap.php --configuration tests/phpunit.xml tests
@@ -0,0 +1,4 @@
.idea
nbproject
example/tokens
/vendor/
View File
View File
View File
View File
View File
View File
View File
View File
@@ -0,0 +1,3 @@
/composer.lock
/phpunit.xml
/vendor/
+41
View File
@@ -0,0 +1,41 @@
sudo: false
language: php
cache:
directories:
- $HOME/.composer/cache
- $HOME/.local
- vendor
matrix:
fast_finish: true
include:
- php: 7.1
env:
- EXECUTE_CS_CHECK=true
- EXECUTE_TEST_COVERALLS=true
- PATH="$HOME/.local/bin:$PATH"
- php: nightly
allow_failures:
- php: nightly
before_install:
- if [[ $EXECUTE_TEST_COVERALLS != 'true' ]]; then phpenv config-rm xdebug.ini || return 0 ; fi
- composer self-update
- if [[ $EXECUTE_TEST_COVERALLS == 'true' ]]; then composer require --dev --no-update satooshi/php-coveralls:dev-master ; fi
install:
- travis_retry composer install --no-interaction
- composer info -i
script:
- if [[ $EXECUTE_TEST_COVERALLS == 'true' ]]; then vendor/bin/phpunit --coverage-clover clover.xml ; fi
- if [[ $EXECUTE_TEST_COVERALLS != 'true' ]]; then vendor/bin/phpunit ; fi
- if [[ $EXECUTE_CS_CHECK == 'true' ]]; then vendor/bin/phpcs ; fi
after_script:
- if [[ $EXECUTE_TEST_COVERALLS == 'true' ]]; then vendor/bin/coveralls ; fi
notifications:
email: true
@@ -0,0 +1,189 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
build/
bld/
[Bb]in/
[Oo]bj/
# Roslyn cache directories
*.ide/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
#NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding addin-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
_NCrunch_*
.*crunch*.local.xml
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# If using the old MSBuild-Integrated Package Restore, uncomment this:
#!**/packages/repositories.config
# Windows Azure Build Output
csx/
*.build.csdef
# Windows Store app package directory
AppPackages/
# Others
sql/
*.Cache
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.pfx
*.publishsettings
node_modules/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# Composer
/vendor
# .vs
.vs/
@@ -0,0 +1,18 @@
language: php
dist: trusty
matrix:
include:
- php: 5.3
dist: precise
php:
- 5.4
- 5.5
- 5.6
- 7.0
- 7.1
- hhvm
script:
- if [[ "$TRAVIS_PHP_VERSION" == '5.6' ]]; then phpunit --coverage-text tests ; fi