From dc335611f45f827b1fcb90bed8c36f0ab6d6bc45 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 20 Apr 2024 02:12:58 +0200 Subject: [PATCH] (Grav GitSync) Automatic Commit from dan --- .../item.en.md | 37 +++++++++++++++++++ plugins/login/CHANGELOG.md | 14 +++++++ plugins/login/README.md | 6 +++ plugins/login/blueprints.yaml | 8 +++- plugins/login/classes/Controller.php | 10 ++++- plugins/login/classes/Email.php | 31 ++++++++++------ plugins/login/classes/Login.php | 8 +++- plugins/login/languages/en.yaml | 5 ++- .../templates/emails/login/activate.html.twig | 1 + .../emails/login/reset-password.html.twig | 1 + plugins/taxonomylist/.gitignore | 1 + plugins/taxonomylist/CHANGELOG.md | 6 +++ plugins/taxonomylist/README.md | 7 ++++ plugins/taxonomylist/blueprints.yaml | 2 +- plugins/taxonomylist/classes/taxonomylist.php | 7 +++- plugins/taxonomylist/hebe.json | 15 ++++++++ .../templates/partials/taxonomylist.html.twig | 2 +- .../templates/de/partials/footer.html.twig | 4 +- .../templates/en/partials/footer.html.twig | 4 +- 19 files changed, 145 insertions(+), 24 deletions(-) create mode 100644 pages/01.blog/new-linux-mobile-operating-systems-section-and-pinephone-pro-as-a-daily-driver/item.en.md create mode 100644 plugins/taxonomylist/.gitignore create mode 100644 plugins/taxonomylist/hebe.json diff --git a/pages/01.blog/new-linux-mobile-operating-systems-section-and-pinephone-pro-as-a-daily-driver/item.en.md b/pages/01.blog/new-linux-mobile-operating-systems-section-and-pinephone-pro-as-a-daily-driver/item.en.md new file mode 100644 index 0000000..58c2a2a --- /dev/null +++ b/pages/01.blog/new-linux-mobile-operating-systems-section-and-pinephone-pro-as-a-daily-driver/item.en.md @@ -0,0 +1,37 @@ +--- +title: 'New Linux Mobile Operating Systems section and PinePhone (Pro) as a daily driver' +author: Dan +published: true +date: '20-04-2024 00:11' +taxonomy: + category: + - news + tag: + - 'Linux Mobile' + - postmarketos + - 'TECH SAVIOURS' + - 'Arch Linux ARM' + - wiki + - tutorials +aura: + author: dan +--- + +# Linux Mobile +A new section popped up in our wiki - [Linux Mobile](https://wiki.techsaviours.org/en/phone/operating_systems/linux_mobile)! +Based for now only on a PinePhone (Pro) specifically on a braveheart (original PP - latest motherboard) and explorer (PPP). +Arch Linux ARM and postmarketOS are the operating systems included in the wiki. It only contains the option to create the images on your Arch system. It covers [DanctNIXs Arch Linux ARM build script](https://github.com/dreemurrs-embedded/arch-pine64-build) and [postmarketOSs pmbootstrap](https://wiki.postmarketos.org/wiki/Pmbootstrap). + +# PinePhone as a daily driver? +Nope. +I wrote an article in 2021 or so about a daily driven PinePhone that I never published. I couldn't find it anymore, so here's just a bit about it in relation to the new wiki section basically. +I used the PinePhone Original for about 9 months with the Pine64s keyboard, but the brick in the pocket (don't run without a proper belt around your hip!) was really annoying, but without the keyboard the phone couldn't run for a day. The battery searched and found the number 0 (%) very quickly. +So the PP is not at all useful for me as a daily driver, I would like to use it without the keyboard. I use a phone mainly as a phone - calls, texting and browsing. And that brings me straight to the next main drawback, calls (back then, maybe fixed now?) had a few issues. The other side couldn't hear me, or I never got a call. That happened randomly. The PPP has even more issues, but it's much faster than the PP, so it's more interesting for me. +I hope that all the issues will "disappear" one day, because Linux Mobile is the future for me to finally get away from the crappy way that Android comes with. After about 15 years of rooting, flashing and so on, I want to finally get that out of my head and start enjoying the freedom that Linux Mobile already offers on the other side! +The few disadvantages it has, it also has a lot of potential! Backups for example, suuuper easy! No TWRP, no nand backups or other weird ways to have "backups" of the system, or apps blocking backups and so on, oh Android can be very annoying! +A proper firewall ... yes everything you can do with Linux ;) + +So Linux Mobile must be part of our wiki! Time to own your own phone! Especially the phone is a big part of our digital everyday life! + +Have a good weekend! +Dan \ No newline at end of file diff --git a/plugins/login/CHANGELOG.md b/plugins/login/CHANGELOG.md index 469f052..b027b92 100644 --- a/plugins/login/CHANGELOG.md +++ b/plugins/login/CHANGELOG.md @@ -1,3 +1,17 @@ +# v3.7.8.1 +## 04/19/2024 + +1. [](#bugfix) + * Fixed a typo in `Email::sendActivationEmail()` [#303](https://github.com/getgrav/grav-plugin-login/issues/303) + +# v3.7.8 +## 04/16/2024 + +1. [](#improved) + * Use `random_bytes()` for password reset and activation, only fallback to `mt_rand()` if there's a generation error - discovered by [Fortbridge](https://fortbridge.co.uk) + * Added a new `site_host` field in the "Security" section to use in password reset and activation links sent in email. This allows you to avoid any "Password Reset Poisoning" attacks. - discovered by [Fortbridge](https://fortbridge.co.uk) + * Added a new warning in reset and activation emails that shows the "site host" clearly in order to avoid any nefariously sent emails. + # v3.7.7 ## 01/05/2024 diff --git a/plugins/login/README.md b/plugins/login/README.md index 291b49e..b5c63bc 100644 --- a/plugins/login/README.md +++ b/plugins/login/README.md @@ -174,6 +174,8 @@ dynamic_page_visibility: false # Integrate access into page visibil 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 +site_host: # Optionally used in password reset and activation emails, to avoid "password poisoning attacks", this should be the URL of your site including the protocol. e.g. https://foo.com + rememberme: enabled: true # Enable 'remember me' functionality timeout: 604800 # Timeout in seconds. Defaults to 1 week @@ -427,6 +429,10 @@ user_registration: send_welcome_email: false # Send a welcome email to the user (probably should not be used with `send_activation_email` ``` +## Email Security Considerations + +For increased security and to deter users from being tricked into resetting their passwords or activating their accounts on 'fake' sites utilizing a [Password Poisoning Attack](https://portswigger.net/web-security/host-header/exploiting/password-reset-poisoning), you can now set the `site_host` property in the "Security" tab of the login properties, (e.g. `https://foo.com`) to ensure the users are sent to the original site only. + ## Sending an activation email By default the registration process adds a new user, and sets it as enabled. diff --git a/plugins/login/blueprints.yaml b/plugins/login/blueprints.yaml index e0dae9f..477d6b6 100644 --- a/plugins/login/blueprints.yaml +++ b/plugins/login/blueprints.yaml @@ -1,7 +1,7 @@ name: Login slug: login type: plugin -version: 3.7.7 +version: 3.7.8.1 testing: false description: Enables user authentication and login screen. icon: sign-in @@ -411,6 +411,12 @@ form: title: PLUGIN_LOGIN.SECURITY_TAB fields: + site_host: + type: text + size: medium + label: PLUGIN_LOGIN.SITE_HOST + help: PLUGIN_LOGIN.SITE_HOST_HELP + placeholder: "https://example.com" max_pw_resets_count: type: number size: x-small diff --git a/plugins/login/classes/Controller.php b/plugins/login/classes/Controller.php index ed006d7..76463e2 100644 --- a/plugins/login/classes/Controller.php +++ b/plugins/login/classes/Controller.php @@ -389,8 +389,14 @@ class Controller return true; } - $token = md5(uniqid((string)mt_rand(), true)); - $expire = time() + 604800; // next week + try { + $random_bytes = random_bytes(16); + } catch (\Exception $e) { + $random_bytes = mt_rand(); + } + + $token = md5(uniqid($random_bytes, true)); + $expire = time() + 86400; // 24 hours $user->reset = $token . '::' . $expire; $user->save(); diff --git a/plugins/login/classes/Email.php b/plugins/login/classes/Email.php index 74d0a98..dbf9cda 100644 --- a/plugins/login/classes/Email.php +++ b/plugins/login/classes/Email.php @@ -5,7 +5,6 @@ namespace Grav\Plugin\Login; use Grav\Common\Config\Config; use Grav\Common\Grav; use Grav\Common\Language\Language; -use Grav\Common\Page\Pages; use Grav\Common\User\Interfaces\UserInterface; use Grav\Common\Utils; use Grav\Plugin\Login\Invitations\Invitation; @@ -39,9 +38,12 @@ class Email throw new \RuntimeException('User activation route does not exist!'); } - /** @var Pages $pages */ - $pages = Grav::instance()['pages']; - $activationLink = $pages->url( + $site_host = $config->get('plugins.login.site_host'); + if (!empty($site_host)) { + $activationRoute = rtrim($site_host, '/') . '/' . ltrim($activationRoute, '/'); + } + + $activationLink = Utils::url( $activationRoute . '/token' . $param_sep . $token . '/username' . $param_sep . $user->username, null, true @@ -89,11 +91,14 @@ class Email throw new \RuntimeException('Password reset route does not exist!'); } - /** @var Pages $pages */ - $pages = Grav::instance()['pages']; - $resetLink = $pages->url( + $site_host = static::getConfig()->get('plugins.login.site_host'); + if (!empty($site_host)) { + $resetRoute = rtrim($site_host, '/') . '/' . ltrim($resetRoute, '/'); + } + + $resetLink = Utils::url( "{$resetRoute}/task{$param_sep}login.reset/token{$param_sep}{$token}/user{$param_sep}{$user->username}/nonce{$param_sep}" . Utils::getNonce('reset-form'), - null, + true, true ); @@ -190,9 +195,7 @@ class Email throw new \RuntimeException('User registration route does not exist!'); } - /** @var Pages $pages */ - $pages = Grav::instance()['pages']; - $invitationLink = $pages->url("{$inviteRoute}/{$param_sep}{$invitation->token}", null, true); + $invitationLink = Utils::url("{$inviteRoute}/{$param_sep}{$invitation->token}", true, true); $context = [ 'invitation_link' => $invitationLink, @@ -218,11 +221,17 @@ class Email $config = static::getConfig(); + $site_host = $config->get('plugins.login.site_host'); + if (empty($site_host)) { + $site_host = Grav::instance()['uri']->host(); + } + // Twig context. $context += [ 'actor' => $actor, 'user' => $user, 'site_name' => $config->get('site.title', 'Website'), + 'site_host' => $site_host, 'author' => $config->get('site.author.name', ''), ]; diff --git a/plugins/login/classes/Login.php b/plugins/login/classes/Login.php index 36b982b..f31eea4 100644 --- a/plugins/login/classes/Login.php +++ b/plugins/login/classes/Login.php @@ -491,7 +491,13 @@ class Login throw new \RuntimeException($this->language->translate('PLUGIN_LOGIN.USER_NEEDS_EMAIL_FIELD')); } - $token = md5(uniqid(mt_rand(), true)); + try { + $random_bytes = random_bytes(16); + } catch (\Exception $e) { + $random_bytes = mt_rand(); + } + + $token = md5(uniqid($random_bytes, true)); $expire = time() + 604800; // next week $user->activation_token = $token . '::' . $expire; $user->save(); diff --git a/plugins/login/languages/en.yaml b/plugins/login/languages/en.yaml index c3eb1f1..187cef5 100644 --- a/plugins/login/languages/en.yaml +++ b/plugins/login/languages/en.yaml @@ -156,4 +156,7 @@ PLUGIN_LOGIN: INVITATION_EMAIL_MESSAGE: "We welcome you to register an account to on site." INVALID_INVITE_EMAILS: "Error: An invalid list of emails was provided" INVALID_FORM: "Error: Invalid form" - FAILED_TO_SEND_EMAILS: "Failed to send emails to: %s" \ No newline at end of file + FAILED_TO_SEND_EMAILS: "Failed to send emails to: %s" + HOST_WARNING: '
NOTE: If you did not initiate this email or you don''t recognize the originating site: "%s" please ignore or delete this email.
' + SITE_HOST: "Site Host" + SITE_HOST_HELP: "For extra security, force this URL to be used in all password reset and activation emails. Leave empty to use the default site URL" \ No newline at end of file diff --git a/plugins/login/templates/emails/login/activate.html.twig b/plugins/login/templates/emails/login/activate.html.twig index fac447c..31c3193 100644 --- a/plugins/login/templates/emails/login/activate.html.twig +++ b/plugins/login/templates/emails/login/activate.html.twig @@ -7,6 +7,7 @@ {%- do email.message.setSubject(subject) %} {%- block content -%} + {{ 'PLUGIN_LOGIN.HOST_WARNING'|t(site_host)|raw }} {{ 'PLUGIN_LOGIN.ACTIVATION_EMAIL_BODY'|t(user.fullname, activation_link, site_name, author)|raw }} {%- endblock content -%} diff --git a/plugins/login/templates/emails/login/reset-password.html.twig b/plugins/login/templates/emails/login/reset-password.html.twig index fb9b566..c6fe499 100644 --- a/plugins/login/templates/emails/login/reset-password.html.twig +++ b/plugins/login/templates/emails/login/reset-password.html.twig @@ -7,6 +7,7 @@ {%- do email.message.setSubject(subject) %} {%- block content -%} + {{ 'PLUGIN_LOGIN.HOST_WARNING'|t(site_host)|raw }} {{ 'PLUGIN_LOGIN.FORGOT_EMAIL_BODY'|t(user.fullname ?? user.username, reset_link, author, site_name)|raw }} {%- endblock content -%} diff --git a/plugins/taxonomylist/.gitignore b/plugins/taxonomylist/.gitignore new file mode 100644 index 0000000..62c8935 --- /dev/null +++ b/plugins/taxonomylist/.gitignore @@ -0,0 +1 @@ +.idea/ \ No newline at end of file diff --git a/plugins/taxonomylist/CHANGELOG.md b/plugins/taxonomylist/CHANGELOG.md index b27d2fc..7246ef1 100644 --- a/plugins/taxonomylist/CHANGELOG.md +++ b/plugins/taxonomylist/CHANGELOG.md @@ -1,3 +1,9 @@ +# v1.3.6 +## 04/16/2024 + +1. [](#new) + * Specify the page from which to get the child tags [#39](https://github.com/getgrav/grav-plugin-taxonomylist/issues/39) + # v1.3.5 ## 12/02/2020 diff --git a/plugins/taxonomylist/README.md b/plugins/taxonomylist/README.md index 3b60f6f..d8ffd86 100644 --- a/plugins/taxonomylist/README.md +++ b/plugins/taxonomylist/README.md @@ -54,6 +54,13 @@ You can also include pass an optional parameter that will show taxonomy for chil {% include 'partials/taxonomylist.html.twig' with {base_url: my_url, taxonomy: 'tag', children_only: true} %} ``` +When using `children_only`, another optional parameter (`of_page`) may be used to specify the page to use: + +```twig +{% include 'partials/taxonomylist.html.twig' with {base_url: my_url, taxonomy: 'tag', children_only: true, of_page: page.parent} %} +``` + + > NOTE: If you want to see this plugin in action, have a look at our [Blog Site Skeleton](https://github.com/getgrav/grav-skeleton-blog-site/archive/master.zip) diff --git a/plugins/taxonomylist/blueprints.yaml b/plugins/taxonomylist/blueprints.yaml index 2e72841..b99c374 100644 --- a/plugins/taxonomylist/blueprints.yaml +++ b/plugins/taxonomylist/blueprints.yaml @@ -1,7 +1,7 @@ name: Taxonomy List type: plugin slug: taxonomylist -version: 1.3.5 +version: 1.3.6 description: "With the **TaxonomyList plugin** you can easily create list of **taxonomy** items such as **tags**, **categories**, etc." icon: tag author: diff --git a/plugins/taxonomylist/classes/taxonomylist.php b/plugins/taxonomylist/classes/taxonomylist.php index cc28b75..ddb129f 100644 --- a/plugins/taxonomylist/classes/taxonomylist.php +++ b/plugins/taxonomylist/classes/taxonomylist.php @@ -32,10 +32,13 @@ class Taxonomylist * * @return array */ - public function getChildPagesTags() + public function getChildPagesTags(PageInterface $current = null) { /** @var PageInterface $current */ - $current = Grav::instance()['page']; + if (null === $current) { + $current = Grav::instance()['page']; + } + $taxonomies = []; foreach ($current->children()->published() as $child) { if (!$child->isPage()) { diff --git a/plugins/taxonomylist/hebe.json b/plugins/taxonomylist/hebe.json new file mode 100644 index 0000000..83b7e70 --- /dev/null +++ b/plugins/taxonomylist/hebe.json @@ -0,0 +1,15 @@ +{ + "project":"grav-plugin-taxonomylist", + "platforms":{ + "grav":{ + "nodes":{ + "plugin":[ + { + "source":"/", + "destination":"/user/plugins/taxonomylist" + } + ] + } + } + } +} diff --git a/plugins/taxonomylist/templates/partials/taxonomylist.html.twig b/plugins/taxonomylist/templates/partials/taxonomylist.html.twig index 6641f6c..ae02376 100644 --- a/plugins/taxonomylist/templates/partials/taxonomylist.html.twig +++ b/plugins/taxonomylist/templates/partials/taxonomylist.html.twig @@ -1,4 +1,4 @@ -{% set taxlist = children_only is defined ? taxonomylist.getChildPagesTags() : taxonomylist.get() %} +{% set taxlist = children_only is defined ? taxonomylist.getChildPagesTags(of_page) : taxonomylist.get() %} {% if taxlist %} diff --git a/themes/mytheme/templates/de/partials/footer.html.twig b/themes/mytheme/templates/de/partials/footer.html.twig index 06b395f..fd7b153 100755 --- a/themes/mytheme/templates/de/partials/footer.html.twig +++ b/themes/mytheme/templates/de/partials/footer.html.twig @@ -26,9 +26,9 @@ - + diff --git a/themes/mytheme/templates/en/partials/footer.html.twig b/themes/mytheme/templates/en/partials/footer.html.twig index d117479..7fb2cca 100755 --- a/themes/mytheme/templates/en/partials/footer.html.twig +++ b/themes/mytheme/templates/en/partials/footer.html.twig @@ -26,10 +26,10 @@ - +