(Grav GitSync) Automatic Commit from dan
This commit is contained in:
parent
90cd548737
commit
dc335611f4
19 changed files with 145 additions and 24 deletions
|
@ -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
|
|
@ -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
|
# v3.7.7
|
||||||
## 01/05/2024
|
## 01/05/2024
|
||||||
|
|
||||||
|
|
|
@ -174,6 +174,8 @@ dynamic_page_visibility: false # Integrate access into page visibil
|
||||||
parent_acl: false # Look to parent `access` rules for access requirements
|
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
|
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:
|
rememberme:
|
||||||
enabled: true # Enable 'remember me' functionality
|
enabled: true # Enable 'remember me' functionality
|
||||||
timeout: 604800 # Timeout in seconds. Defaults to 1 week
|
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`
|
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
|
## Sending an activation email
|
||||||
|
|
||||||
By default the registration process adds a new user, and sets it as enabled.
|
By default the registration process adds a new user, and sets it as enabled.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
name: Login
|
name: Login
|
||||||
slug: login
|
slug: login
|
||||||
type: plugin
|
type: plugin
|
||||||
version: 3.7.7
|
version: 3.7.8.1
|
||||||
testing: false
|
testing: false
|
||||||
description: Enables user authentication and login screen.
|
description: Enables user authentication and login screen.
|
||||||
icon: sign-in
|
icon: sign-in
|
||||||
|
@ -411,6 +411,12 @@ form:
|
||||||
title: PLUGIN_LOGIN.SECURITY_TAB
|
title: PLUGIN_LOGIN.SECURITY_TAB
|
||||||
|
|
||||||
fields:
|
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:
|
max_pw_resets_count:
|
||||||
type: number
|
type: number
|
||||||
size: x-small
|
size: x-small
|
||||||
|
|
|
@ -389,8 +389,14 @@ class Controller
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
$token = md5(uniqid((string)mt_rand(), true));
|
try {
|
||||||
$expire = time() + 604800; // next week
|
$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->reset = $token . '::' . $expire;
|
||||||
$user->save();
|
$user->save();
|
||||||
|
|
|
@ -5,7 +5,6 @@ namespace Grav\Plugin\Login;
|
||||||
use Grav\Common\Config\Config;
|
use Grav\Common\Config\Config;
|
||||||
use Grav\Common\Grav;
|
use Grav\Common\Grav;
|
||||||
use Grav\Common\Language\Language;
|
use Grav\Common\Language\Language;
|
||||||
use Grav\Common\Page\Pages;
|
|
||||||
use Grav\Common\User\Interfaces\UserInterface;
|
use Grav\Common\User\Interfaces\UserInterface;
|
||||||
use Grav\Common\Utils;
|
use Grav\Common\Utils;
|
||||||
use Grav\Plugin\Login\Invitations\Invitation;
|
use Grav\Plugin\Login\Invitations\Invitation;
|
||||||
|
@ -39,9 +38,12 @@ class Email
|
||||||
throw new \RuntimeException('User activation route does not exist!');
|
throw new \RuntimeException('User activation route does not exist!');
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @var Pages $pages */
|
$site_host = $config->get('plugins.login.site_host');
|
||||||
$pages = Grav::instance()['pages'];
|
if (!empty($site_host)) {
|
||||||
$activationLink = $pages->url(
|
$activationRoute = rtrim($site_host, '/') . '/' . ltrim($activationRoute, '/');
|
||||||
|
}
|
||||||
|
|
||||||
|
$activationLink = Utils::url(
|
||||||
$activationRoute . '/token' . $param_sep . $token . '/username' . $param_sep . $user->username,
|
$activationRoute . '/token' . $param_sep . $token . '/username' . $param_sep . $user->username,
|
||||||
null,
|
null,
|
||||||
true
|
true
|
||||||
|
@ -89,11 +91,14 @@ class Email
|
||||||
throw new \RuntimeException('Password reset route does not exist!');
|
throw new \RuntimeException('Password reset route does not exist!');
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @var Pages $pages */
|
$site_host = static::getConfig()->get('plugins.login.site_host');
|
||||||
$pages = Grav::instance()['pages'];
|
if (!empty($site_host)) {
|
||||||
$resetLink = $pages->url(
|
$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'),
|
"{$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
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -190,9 +195,7 @@ class Email
|
||||||
throw new \RuntimeException('User registration route does not exist!');
|
throw new \RuntimeException('User registration route does not exist!');
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @var Pages $pages */
|
$invitationLink = Utils::url("{$inviteRoute}/{$param_sep}{$invitation->token}", true, true);
|
||||||
$pages = Grav::instance()['pages'];
|
|
||||||
$invitationLink = $pages->url("{$inviteRoute}/{$param_sep}{$invitation->token}", null, true);
|
|
||||||
|
|
||||||
$context = [
|
$context = [
|
||||||
'invitation_link' => $invitationLink,
|
'invitation_link' => $invitationLink,
|
||||||
|
@ -218,11 +221,17 @@ class Email
|
||||||
|
|
||||||
$config = static::getConfig();
|
$config = static::getConfig();
|
||||||
|
|
||||||
|
$site_host = $config->get('plugins.login.site_host');
|
||||||
|
if (empty($site_host)) {
|
||||||
|
$site_host = Grav::instance()['uri']->host();
|
||||||
|
}
|
||||||
|
|
||||||
// Twig context.
|
// Twig context.
|
||||||
$context += [
|
$context += [
|
||||||
'actor' => $actor,
|
'actor' => $actor,
|
||||||
'user' => $user,
|
'user' => $user,
|
||||||
'site_name' => $config->get('site.title', 'Website'),
|
'site_name' => $config->get('site.title', 'Website'),
|
||||||
|
'site_host' => $site_host,
|
||||||
'author' => $config->get('site.author.name', ''),
|
'author' => $config->get('site.author.name', ''),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -491,7 +491,13 @@ class Login
|
||||||
throw new \RuntimeException($this->language->translate('PLUGIN_LOGIN.USER_NEEDS_EMAIL_FIELD'));
|
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
|
$expire = time() + 604800; // next week
|
||||||
$user->activation_token = $token . '::' . $expire;
|
$user->activation_token = $token . '::' . $expire;
|
||||||
$user->save();
|
$user->save();
|
||||||
|
|
|
@ -157,3 +157,6 @@ PLUGIN_LOGIN:
|
||||||
INVALID_INVITE_EMAILS: "<strong>Error:</strong> An invalid list of emails was provided"
|
INVALID_INVITE_EMAILS: "<strong>Error:</strong> An invalid list of emails was provided"
|
||||||
INVALID_FORM: "<strong>Error:</strong> Invalid form"
|
INVALID_FORM: "<strong>Error:</strong> Invalid form"
|
||||||
FAILED_TO_SEND_EMAILS: "Failed to send emails to: %s"
|
FAILED_TO_SEND_EMAILS: "Failed to send emails to: %s"
|
||||||
|
HOST_WARNING: '<div style="background-color: #FFEDAD; color: #725F1C; border: 1px solid #FFD74E; padding: 10px; margin: 10px 0; border-radius: 5px;">NOTE: If you did not initiate this email or you don''t recognize the originating site: <strong>"%s"</strong> please ignore or delete this email.</div>'
|
||||||
|
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"
|
|
@ -7,6 +7,7 @@
|
||||||
{%- do email.message.setSubject(subject) %}
|
{%- do email.message.setSubject(subject) %}
|
||||||
|
|
||||||
{%- block content -%}
|
{%- block content -%}
|
||||||
|
{{ 'PLUGIN_LOGIN.HOST_WARNING'|t(site_host)|raw }}
|
||||||
{{ 'PLUGIN_LOGIN.ACTIVATION_EMAIL_BODY'|t(user.fullname, activation_link, site_name, author)|raw }}
|
{{ 'PLUGIN_LOGIN.ACTIVATION_EMAIL_BODY'|t(user.fullname, activation_link, site_name, author)|raw }}
|
||||||
{%- endblock content -%}
|
{%- endblock content -%}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
{%- do email.message.setSubject(subject) %}
|
{%- do email.message.setSubject(subject) %}
|
||||||
|
|
||||||
{%- block content -%}
|
{%- 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 }}
|
{{ 'PLUGIN_LOGIN.FORGOT_EMAIL_BODY'|t(user.fullname ?? user.username, reset_link, author, site_name)|raw }}
|
||||||
{%- endblock content -%}
|
{%- endblock content -%}
|
||||||
|
|
||||||
|
|
1
plugins/taxonomylist/.gitignore
vendored
Normal file
1
plugins/taxonomylist/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
.idea/
|
|
@ -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
|
# v1.3.5
|
||||||
## 12/02/2020
|
## 12/02/2020
|
||||||
|
|
||||||
|
|
|
@ -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} %}
|
{% 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)
|
> 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)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
name: Taxonomy List
|
name: Taxonomy List
|
||||||
type: plugin
|
type: plugin
|
||||||
slug: taxonomylist
|
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."
|
description: "With the **TaxonomyList plugin** you can easily create list of **taxonomy** items such as **tags**, **categories**, etc."
|
||||||
icon: tag
|
icon: tag
|
||||||
author:
|
author:
|
||||||
|
|
|
@ -32,10 +32,13 @@ class Taxonomylist
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function getChildPagesTags()
|
public function getChildPagesTags(PageInterface $current = null)
|
||||||
{
|
{
|
||||||
/** @var PageInterface $current */
|
/** @var PageInterface $current */
|
||||||
$current = Grav::instance()['page'];
|
if (null === $current) {
|
||||||
|
$current = Grav::instance()['page'];
|
||||||
|
}
|
||||||
|
|
||||||
$taxonomies = [];
|
$taxonomies = [];
|
||||||
foreach ($current->children()->published() as $child) {
|
foreach ($current->children()->published() as $child) {
|
||||||
if (!$child->isPage()) {
|
if (!$child->isPage()) {
|
||||||
|
|
15
plugins/taxonomylist/hebe.json
Normal file
15
plugins/taxonomylist/hebe.json
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
"project":"grav-plugin-taxonomylist",
|
||||||
|
"platforms":{
|
||||||
|
"grav":{
|
||||||
|
"nodes":{
|
||||||
|
"plugin":[
|
||||||
|
{
|
||||||
|
"source":"/",
|
||||||
|
"destination":"/user/plugins/taxonomylist"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 %}
|
{% if taxlist %}
|
||||||
<span class="tags">
|
<span class="tags">
|
||||||
|
|
|
@ -26,9 +26,9 @@
|
||||||
<a class="btn2 btn2-dark btn2-social mx-2" href="https://git.techsaviours.org/">
|
<a class="btn2 btn2-dark btn2-social mx-2" href="https://git.techsaviours.org/">
|
||||||
<i class="fa fa-code-fork"></i>
|
<i class="fa fa-code-fork"></i>
|
||||||
</a>
|
</a>
|
||||||
<a class="btn2 btn2-dark btn2-social mx-2" href="https://github.com/TECH-SAVIOURS-ORG">
|
<!-- <a class="btn2 btn2-dark btn2-social mx-2" href="https://github.com/TECH-SAVIOURS-ORG">
|
||||||
<i class="fa fa-github"></i>
|
<i class="fa fa-github"></i>
|
||||||
</a>
|
</a>-->
|
||||||
<!-- <a class="btn2 btn2-dark btn2-social mx-2" href="https://www.reddit.com/r/TECHSAVIOURS_ORG/">
|
<!-- <a class="btn2 btn2-dark btn2-social mx-2" href="https://www.reddit.com/r/TECHSAVIOURS_ORG/">
|
||||||
<i class="fa fa-reddit"></i>
|
<i class="fa fa-reddit"></i>
|
||||||
</a> -->
|
</a> -->
|
||||||
|
|
|
@ -26,10 +26,10 @@
|
||||||
<a class="btn2 btn2-dark btn2-social mx-2" href="https://git.techsaviours.org/">
|
<a class="btn2 btn2-dark btn2-social mx-2" href="https://git.techsaviours.org/">
|
||||||
<i class="fa fa-code-fork"></i>
|
<i class="fa fa-code-fork"></i>
|
||||||
</a>
|
</a>
|
||||||
<a class="btn2 btn2-dark btn2-social mx-2" href="https://github.com/TECH-SAVIOURS-ORG">
|
<!-- <a class="btn2 btn2-dark btn2-social mx-2" href="https://github.com/TECH-SAVIOURS-ORG">
|
||||||
<i class="fa fa-github"></i>
|
<i class="fa fa-github"></i>
|
||||||
</a>
|
</a>
|
||||||
<!-- <a class="btn2 btn2-dark btn2-social mx-2" href="https://www.reddit.com/r/TECHSAVIOURS_ORG/">
|
--> <!-- <a class="btn2 btn2-dark btn2-social mx-2" href="https://www.reddit.com/r/TECHSAVIOURS_ORG/">
|
||||||
<i class="fa fa-reddit"></i>
|
<i class="fa fa-reddit"></i>
|
||||||
</a> -->
|
</a> -->
|
||||||
<!-- <a class="btn2 btn2-dark btn2-social mx-2" href="https://twitter.com/techsavioursorg">
|
<!-- <a class="btn2 btn2-dark btn2-social mx-2" href="https://twitter.com/techsavioursorg">
|
||||||
|
|
Loading…
Reference in a new issue