QUIQQER issueshttps://dev.quiqqer.com/quiqqer/quiqqer/-/issues2024-03-12T13:43:39Zhttps://dev.quiqqer.com/quiqqer/quiqqer/-/issues/1202User::hasPermission und ::getPermission verhalten sich falsch/komisch2024-03-12T13:43:39ZJan WennrichUser::hasPermission und ::getPermission verhalten sich falsch/komisch**tl;dr:**
- `hasPermission` und `getPermission` in der `User`-Klasse prüfen nicht die Permissions der Gruppen des Benutzers.
- `checkPermission` prüft die Permission der Gruppen des Benutzers
- Das Verhalten ist inkonsistent und verwir...**tl;dr:**
- `hasPermission` und `getPermission` in der `User`-Klasse prüfen nicht die Permissions der Gruppen des Benutzers.
- `checkPermission` prüft die Permission der Gruppen des Benutzers
- Das Verhalten ist inkonsistent und verwirrend
**Ausführliche Informationen:**
Folgende Ausgangssituation:
1. `quiqqer/quiqqer` ist in der neuesten `dev-dev` Version installiert
1. Es gibt eine Boolean Permission `meine.permission`
1. Es gibt eine Gruppe `Händler`
1. Die Gruppe `Händler` hat die Permission `meine.permission` auf `true`
1. Die Standard-Gruppe `Everyone` hat die Permission `meine.permission` auf `false`
1. Es gibt einen Benutzer `Jan`
1. Der Benutzer `Jan` hat die Permission `meine.permission` auf `false`
1. Benutzer `Jan` ist Mitglied der Gruppen `Händler` und `Everyone`
Ich wollte nun herausfinden ob der Benutzer `Jan` die Permission `meine.permission` hat.
Dazu habe ich die folgenden Permission Methoden des Benutzers mit den dahinter stehenden Ergebnissen genutzt:
- `checkPermission('meine.permission')` -> `NULL`
- `hasPermission('meine.permission')` -> `false`
- `getPermission('meine.permission')` -> `false`
Dass `checkPermission` den Wert `NULL` zurückgibt, kann ich noch einigermaßen verstehen, da eine Exception geworfen wird, wenn er die Permission nicht hat.
Dass `hasPermission()` und `getPermission()` beide `false` zurückgeben finde ich allerdings seltsam.
Über die Gruppe `Händler` sollte der Benutzer `Jan` die Permission haben.
Wenn ich dem Benutzer die Permission direkt gebe, dann geben die beiden Methoden richtigerweise `true` zurück.
Die beiden Methoden `hasPermission` und `getPermission` prüfen also nur ob der Benutzer direkt die Permission hat und nicht ob er die Permission über eine Gruppe hat.
Man könnte argumentieren, dass die Methoden auf dem Benutzer Objekt aufgerufen werden und daher auch nur den Benutzer überprüfen sollen.
Dann sollte sich aber auch `checkPermission` konsistent verhalten und eine Permission-Exception werfen, wenn der Benutzer selbst die Permission nicht hat.
Am intuitivsten fände ich es, wenn alle drei Methoden auch die Permissions der Gruppen des Benutzers überprüfen würden.
Was meint ihr dazu, @henbug @peat @mor ?Jan WennrichJan Wennrich2024-01-15https://dev.quiqqer.com/quiqqer/quiqqer/-/issues/1340Integration von PHPStan2024-03-04T07:04:33ZJan WennrichIntegration von PHPStanEs soll diskutiert werden, ob PHPStan in die CI aufgenommen wird, um die Codebase stabiler zu machen.
## Was ist PHPStan?
> PHPStan finds bugs in your code without writing tests.
> PHPStan scans your whole codebase and looks for both ...Es soll diskutiert werden, ob PHPStan in die CI aufgenommen wird, um die Codebase stabiler zu machen.
## Was ist PHPStan?
> PHPStan finds bugs in your code without writing tests.
> PHPStan scans your whole codebase and looks for both obvious & tricky bugs. Even in those rarely executed if statements that certainly aren't covered by tests.
> Thanks to rule levels you don't get overwhelmed with thousands of errors on the first run.
> You can increase PHPStan's capabilities on your code at your own pace. It makes work feel like a game.
> Enjoy new language features before they come to PHP. Do you dream of generics? Array shapes? Checked exceptions? With PHPStan you can use these today by leveraging the power of PHPDocs.
## Was sind Level?
>>>
1. basic checks, unknown classes, unknown functions, unknown methods called on $this, wrong number of arguments passed to those methods and functions, always undefined variables
1. possibly undefined variables, unknown magic methods and properties on classes with __call and __get
1. unknown methods checked on all expressions (not just $this), validating PHPDocs
1. return types, types assigned to properties
1. basic dead code checking - always false instanceof and other type checks, dead else branches, unreachable code after return; etc.
1. checking types of arguments passed to methods and functions
1. report missing typehints
1. report partially wrong union types - if you call a method that only exists on some types in a union type, level 7 starts to report that; other possibly incorrect situations
1. report calling methods and accessing properties on nullable types
1. be strict about the mixed type - the only allowed operation you can do with it is to pass it to another mixed
>>>
Laut diversen Meinungen sollte Level 5 von jedem Projekt erreicht werden (können), um eine grundlegende Stabilität zu bieten.
Jedes Level enthält alle vorherigen Level (also enthält Level 5 auch die Level 0-4)
_Weitere Informationen: https://phpstan.org/user-guide/rule-levels_
## Wie wird PHPStan integriert? (Nutzung der Baseline)
tl;dr: Mit der Baseline werden die Fehler der aktuellen Codebase ignoriert und nur neue Fehler gemeldet
>>>
The usual workflow when introducing PHPStan to the CI pipeline is to get the number of errors reported on level 0 to zero and merge that into the main branch. When the developers feel like it, they can try raising the level by one, go through the list of errors, fix all of them, and enjoy increased strictness from that point on.
>>>
Beim Erhöhen des Level gibt es dann voraussichtlich eine Vielzahl an Fehlern, die nicht auf einmal behoben werden können. Um dieses Problem zu vermeiden, wird die "Baseline" genutzt:
>>>
PHPStan allows you to declare the currently reported list of errors as “the baseline” and cause it not being reported in subsequent runs. It allows you to be interested in violations only in new and changed code.
>>>
## Was ist zu diskutieren?
In den Kommentaren unten zeige ich beispielhaft die Fehler, die von PHPStan in `quiqqer/quiqqer:dev-dev` bei den diversen Levels gemeldet werden.
Auf dieser Basis kann geklärt werden, ob die Integration von PHPStan sinnvoll ist.Jan WennrichJan Wennrichhttps://dev.quiqqer.com/quiqqer/quiqqer/-/issues/1330require_once der `/bootstrap.php` entfernen2024-01-30T14:40:42ZJan Wennrichrequire_once der `/bootstrap.php` entfernenDie `packages/quiqqer/quiqqer/quiqqer.php` Datei required die `/bootstrap.php` Datei: https://dev.quiqqer.com/quiqqer/quiqqer/-/blob/master/quiqqer.php#L87.
Also die Datei, die im Webroot liegt.
Die Datei scheint "nur" `ETC_DIR` zu de...Die `packages/quiqqer/quiqqer/quiqqer.php` Datei required die `/bootstrap.php` Datei: https://dev.quiqqer.com/quiqqer/quiqqer/-/blob/master/quiqqer.php#L87.
Also die Datei, die im Webroot liegt.
Die Datei scheint "nur" `ETC_DIR` zu definieren und dann eine weitere Bootstrap Datei von `quiqqer/quiqqer` zu laden.
Das Problem hierbei ist, dass das `require_once` nicht funktioniert, wenn `quiqqer/quiqqer` nicht an dem "normalen" Ort installiert ist (bspw. per Symlink oder ganz ohne QUIQQER-System). Das Problem tritt aktuell bei mir in der CI-Pipeline zum Testen auf.
Kann der Inhalt der `bootstrap.php` Datei mit in die `quiqqer.php` aufgenommen und das Requirement damit entfernt werden?
Im Optimalfall sollte `quiqqer/quiqqer` komplett eigenständig funktionieren können, ohne Abhängigkeiten nach außen kennen zu müssen.Jan WennrichJan Wennrichhttps://dev.quiqqer.com/quiqqer/quiqqer/-/issues/1291PHP Foundation durch Spenden unterstützen2023-08-29T22:01:35ZJan WennrichPHP Foundation durch Spenden unterstützen>>>
The PHP Foundation is a collective of people and organizations relying on the PHP language. Its mission is to ensure the long-term prosperity of the PHP language.
The PHP Foundation focuses on providing financial support and guidanc...>>>
The PHP Foundation is a collective of people and organizations relying on the PHP language. Its mission is to ensure the long-term prosperity of the PHP language.
The PHP Foundation focuses on providing financial support and guidance to PHP language developers to support its goals of improving the language for its users, providing high-quality maintenance, and improving the PHP language project to retain current contributors and to integrate new contributors.
>>>
Die PHP Foundation wurde vor kurzem gegründet. Sie stellt sicher, dass es immer genug Entwickler gibt, die am PHP Core arbeiten. Dies wird erreicht, indem den Entwicklern marktübliche Gehälter gezahlt werden. Auf diese Weise wird die Wahrscheinlichkeit gering gehalten, dass das PHP Projekt dadurch scheitert, dass wichtige Personen Ausfallen/Weggehen (sog. "Bus-Faktor"). Ein Beispiel für eine solche wichtige Person ist bspw. Nikita Popov, der sehr viel zu den neuesten PHP Versionen beigetragen hat, aber bald nicht mehr (so viel) am PHP Core arbeiten wird.
Die PHP Foundation wird durch Spenden finanziert.
Um das Fortbestehen und Wachstum von PHP zu sichern, sollte die Foundation durch eine (kleine) Spende unterstützt werden.
Weitere Informationen:
- https://thephp.foundation/
- https://blog.jetbrains.com/de/phpstorm/2022/01/the-php-foundation/
/cc @mor
/cc @henbugMoritz ScholzMoritz Scholzhttps://dev.quiqqer.com/quiqqer/quiqqer/-/issues/1257Einführung von Dependency Injection2023-07-31T21:58:56ZJan WennrichEinführung von Dependency InjectionIch habe mich in der letzten Zeit mit Dependency Injection (in PHP) befasst und darin viele Vorteile gefunden.
_Aus der Feder von ChatGPT (von mir validiert):_
>>>
Dependency Injection (DI) ist ein weit verbreitetes Design-Muster, das ...Ich habe mich in der letzten Zeit mit Dependency Injection (in PHP) befasst und darin viele Vorteile gefunden.
_Aus der Feder von ChatGPT (von mir validiert):_
>>>
Dependency Injection (DI) ist ein weit verbreitetes Design-Muster, das das Prinzip der Inversion of Control (IoC) implementiert. Es bietet eine Reihe von Vorteilen gegenüber harten Abhängigkeiten, insbesondere in der PHP-Entwicklung:
1. Testbarkeit: Mit Dependency Injection kann man Abhängigkeiten durch "Mock"-Objekte ersetzen, was das Schreiben von Unit-Tests erheblich erleichtert. Bei harten Abhängigkeiten ist es oft schwierig, Teile des Codes zu isolieren, was das Schreiben von Tests erschwert.
1. Entkopplung von Komponenten: DI fördert eine lose Kopplung zwischen Klassen und Modulen. Statt dass eine Klasse eine andere instanziiert, werden die benötigten Abhängigkeiten als Parameter übergeben. Dies macht den Code flexibler und erlaubt es, Komponenten einfacher zu tauschen oder zu aktualisieren.
1. Vereinfachtes Refactoring: Da der Code weniger stark gekoppelt ist, ist es einfacher, Änderungen an einzelnen Komponenten vorzunehmen, ohne andere Teile des Codes beeinflussen zu müssen.
1. Bessere Lesbarkeit und Wartbarkeit: Da Abhängigkeiten explizit deklariert werden, ist es einfacher, den Code zu verstehen und zu warten. Man kann schnell sehen, welche Abhängigkeiten eine Klasse hat, ohne dass man den Code der Klasse durchsuchen muss.
1. Wiederverwendbarkeit: Da Komponenten weniger stark miteinander verknüpft sind, ist es leichter, sie in verschiedenen Kontexten wiederzuverwenden.
1. Konfigurierbarkeit: Es ist einfacher, die Konfiguration einer Anwendung zu ändern, indem man einfach verschiedene Implementierungen von Abhängigkeiten injiziert, anstatt Code zu ändern.
Insgesamt kann man sagen, dass Dependency Injection dazu beiträgt, den Code sauberer, modularer und testbarer zu machen, was zu einer besseren Softwarequalität führt. Es sollte jedoch mit Bedacht eingesetzt werden, da es auch zu Komplexität führen kann, wenn es nicht richtig gehandhabt wird.
>>>
Vor allem die bessere Testbarkeit (siehe dazu auch #1256) sowie die Inversion of Control (und die daraus resultierende Entkopplung) sehe ich als große Vorteile.
Außerdem lassen sich so fremde Frameworks und Libraries vermutlich leichter/schöner nutzen, ohne dass man dafür immer eigene Wrapper und/oder Factory-Methoden bauen muss.
Bei meinen eigenen Tests habe ich das [`PHP-DI`-Framework](https://php-di.org/) für Dependency Injection verwendet.
Es unterstützt [Autowiring](https://php-di.org/doc/autowiring.html) und hält sich an den [PSR-11 Standard für Container](https://www.php-fig.org/psr/psr-11/).
Das Framework findet und instanziiert die angeforderten Abhängigkeiten also selbst.
Mein Beispiel Projekt ist das hier: https://github.com/JanWennrich/PHP-Sorting-Algorithms/tree/main
Hier ist ein vergleichendes Beispiele für die Verwendung von Dependency Injection von ChatGPT (von mir validiert):
>>>
1. Harter Dependency-Code:
In diesem Fall erstellt die UserManager-Klasse eine Instanz der UserRepository-Klasse direkt in der Methode createUser.
```php
class UserRepository
{
public function save($data)
{
// Logic to save user data to the database
}
}
```
```php
class UserManager
{
public function createUser($data)
{
$repository = new UserRepository();
$repository->save($data);
}
}
```
Die Probleme hier sind:
- Die UserManager-Klasse ist stark an die UserRepository-Klasse gekoppelt.
- Es ist schwierig, die UserManager-Klasse zu testen, da Sie nicht einfach eine gemockte UserRepository-Instanz injizieren können.
- Wenn Sie die UserRepository-Klasse ändern möchten (z.B. die Art und Weise, wie Sie die Daten speichern), müssen Sie die UserManager-Klasse ebenfalls ändern.
2. Code mit Dependency Injection:
Hier wird die UserRepository-Instanz als Konstruktorparameter zur UserManager-Klasse hinzugefügt. Das bedeutet, dass Sie die Abhängigkeit "injizieren".
```php
class UserRepository
{
public function save($data)
{
// Logic to save user data to the database
}
}
```
```php
class UserManager
{
protected $repository;
public function __construct(UserRepository $repository)
{
$this->repository = $repository;
}
public function createUser($data)
{
$this->repository->save($data);
}
}
```
Die Vorteile sind:
- Die UserManager-Klasse ist nun weniger stark an die UserRepository-Klasse gekoppelt.
- Sie können eine andere Implementierung von UserRepository injizieren, solange diese das gleiche Interface verwendet.
- Es ist einfacher, die UserManager-Klasse zu testen, da Sie nun einfach eine gemockte UserRepository-Instanz injizieren können.
- Wenn Sie die UserRepository-Klasse ändern möchten, müssen Sie die UserManager-Klasse nicht mehr ändern.
Insgesamt erlaubt Ihnen die Dependency Injection, Ihren Code modularer und testbarer zu gestalten. Es reduziert die Kopplung zwischen Ihren Klassen und macht sie wiederverwendbarer und leichter zu warten.
>>>
Sehr ihr irgendwelche Probleme und/oder Nachteile an der Verwendung von Dependency Injection oder habt ihr schon damit Erfahrungen gemacht?
/cc @peat
/cc @henbug
/cc @morJan WennrichJan Wennrichhttps://dev.quiqqer.com/quiqqer/quiqqer/-/issues/1248PSR-kompatible Caching Library verwenden2024-01-25T07:37:14ZJan WennrichPSR-kompatible Caching Library verwendenAktuell verwendet QUIQQER [`tedivm/stash`](https://github.com/tedious/Stash) als Library für das Caching.
Die Library gibt vor mit ["PSR-6: Caching Interface"](https://www.php-fig.org/psr/psr-6/) kompatibel zu sein.
Mit ["PSR-16: Commo...Aktuell verwendet QUIQQER [`tedivm/stash`](https://github.com/tedious/Stash) als Library für das Caching.
Die Library gibt vor mit ["PSR-6: Caching Interface"](https://www.php-fig.org/psr/psr-6/) kompatibel zu sein.
Mit ["PSR-16: Common Interface for Caching Libraries"](https://www.php-fig.org/psr/psr-16/#definitions) ist sie offiziell nicht kompatibel.
Allerdings wird die PSR-6 Kompatibilität nicht strikt umgesetzt, sodass man auch PSR-6 inkompatibles Caching durchführen kann: https://github.com/tedious/Stash/issues/349
Das erschwert den Austausch der Caching-Library in Zukunft.
Des Weiteren wurde die Library seit einem Jahr nicht weiterentwickelt und es existiert noch keine stabile Version (`v0.17.6` vs `1.*`).
Es sollte überlegt werden, ob wir auf eine stabilere sowie PSR-6 und PSR-16 kompatible Caching Library umsteigen wollen.
Das würde das Erweitern und/oder Austauschen der Caching Library in Zukunft vereinfachen.
Mögliche PSR-6 und PSR-16 kompatible Alternativen wären:
- https://github.com/symfony/cache
- https://www.php-cache.com/en/latest/ (empfiehlt selbst Symfony Cache zu verwenden)
/cc @peat @henbug @mor1.11 (K* K*)Jan WennrichJan Wennrichhttps://dev.quiqqer.com/quiqqer/quiqqer/-/issues/1246Ausführung von CRONs parallelisieren2023-06-09T08:13:28ZJan WennrichAusführung von CRONs parallelisierenCRONs werden sequentiell ausgeführt - also ein registrierter CRON nach dem nächsten.
Aktuell kommt es wohl teilweise vor, dass manche CRONs so viel Zeit benötigen, dass die übrigen CRONs nicht rechtzeitig oder gar nicht ausgeführt wer...CRONs werden sequentiell ausgeführt - also ein registrierter CRON nach dem nächsten.
Aktuell kommt es wohl teilweise vor, dass manche CRONs so viel Zeit benötigen, dass die übrigen CRONs nicht rechtzeitig oder gar nicht ausgeführt werden.
Da jeder CRON für sich eine eigene "Einheit" ist, die unabhängig vom Rest ist, könnten alle CRONs theoretisch auch parallel ausgeführt werden.
Mit PHP 8.1 wurden [Fibers](https://www.php.net/manual/de/language.fibers.php) eingeführt, mit denen Code "non-blocking" im Hintergrund ausgeführt werden kann.
Mit den Fibers selbst, oder einem vereinfachenden Framework wie bspw. [`amphp/parallel`](https://github.com/amphp/parallel), könnten die CRONs so parallel (im Hintergrund) ausgeführt werden.
Mit diesem Ticket kann diskutiert werden, ob es sinnvoll ist dies zu implementieren.
/cc @mor @henbug @peatJan WennrichJan Wennrichhttps://dev.quiqqer.com/quiqqer/quiqqer/-/issues/1242"minimum-stability" standardmäßig auf "stable" setzen2024-01-25T07:43:28ZJan Wennrich"minimum-stability" standardmäßig auf "stable" setzen_(Basiert auf der Diskussion aus quiqqer/quiqqer#1214)_
Installiert man QUIQQER in einer stabilen Version (bspw. `1.*`), könnten auch Pakete in instabilen Versionen installiert werden.
Die `composer.json` sagt nur, dass stabile Versio..._(Basiert auf der Diskussion aus quiqqer/quiqqer#1214)_
Installiert man QUIQQER in einer stabilen Version (bspw. `1.*`), könnten auch Pakete in instabilen Versionen installiert werden.
Die `composer.json` sagt nur, dass stabile Versionen bevorzugt werden sollen (`prefer-stable: true`). Wenn es aber keine (passende) stabile Version gibt, wird eine instabile Version installiert.
Aus meiner Sicht darf/sollte es in einer stabilen QUIQQER Installation keine instabilen Abhängigkeiten geben. Bei einem Update besteht sonst immer die Gefahr, dass instabile Änderungen das gesamte System lahmlegen. In der `composer.json` des Systems sollte daher die `minimum-stability` auf `stable` gesetzt werden.
Aktuell (QUIQQER Version 1.7) lässt sich das nicht umsetzen, da einige Pakete in instabilen Versionen required werden. Außerdem ist es bei der Installation möglich per Freitext ein bestimmtes Template und dessen Version zu wählen. Die Installation würde abbrechen, wenn man ein Template wählt, dass instabile Abhängigkeiten hat.
Ich könnte mir stattdessen folgenden Ablauf vorstellen, der die Installation vermutlich auch stark vereinfachen würde:
1. QUIQQER wird mit einem Standard-Template installiert. Man kann das Template also nicht mehr frei wählen.
2. Standardmäßig ist `minimum-stability: stable` gesetzt, sodass nur stabile Abhängigkeiten installiert werden können
3. Möchte man nun ein anderes Template nutzen, kann man es über die Administration oder die Konsole nachträglich installieren.
4. Nutzt das Template instabile Abhängigkeiten, kann es (richtigerweise) nicht installiert werden, da das System sonst instabil wird.
5. Wenn man das Risiko bewusst eingehen möchte, kann man die `minimum-stability` manuell anpassen (ggf. Setting in der Administration hinzufügen).
Dieses Ticket soll dazu dienen dieses Thema zu diskutieren.Jan WennrichJan Wennrichhttps://dev.quiqqer.com/quiqqer/quiqqer/-/issues/1230XML Dateien validieren2023-07-31T21:56:29ZJan WennrichXML Dateien validierenUm XML Dateien zu validieren, können [`Document Type Definitions` (`DTD`)](https://wiki.selfhtml.org/wiki/XML/DTD) genutzt werden.
In einer `DTD`-Datei kann angegeben werden, welche Elemente es an welcher Stelle in der XML-Datei geben ...Um XML Dateien zu validieren, können [`Document Type Definitions` (`DTD`)](https://wiki.selfhtml.org/wiki/XML/DTD) genutzt werden.
In einer `DTD`-Datei kann angegeben werden, welche Elemente es an welcher Stelle in der XML-Datei geben darf.
Damit könnte beim Erstellen einer Version und bei der Installation geprüft werden, ob die Datei nicht nur "wohlgeformt" (gültiges XML) sondern auch gültig (der Spezifikation entsprechend) ist. Fehlerhafte XML Dateien können dann frühzeitig abgelehnt werden.
Das DTD für jede Art von XML Datei müsste an einer zentralen Stelle verfügbar sein (bspw. `https://www.quiqqer.de/xml/dtd/locale.dtd`) und wird dann wie folgt im Kopf der XML-Datei referenziert:
```xml
<!DOCTYPE locales SYSTEM "https://www.quiqqer.de/xml/dtd/locale.dtd">
```
Nach dem Laden der Datei kann dann in PHP auf dem [`DOMDocument` die `validate()`-Methode](https://www.php.net/manual/en/domdocument.validate.php) aufgerufen werden.
Diese gibt `true` zurück, wenn alles okay ist, oder wirft bei Fehlern eine Exception.
-------
Alternativ (oder besser) kann man auch [XML-Schema `1.0`](https://www.wilfried-grupe.de/XSD3_.html) verwenden.
Hierbei muss das Schema **NICHT** in jeder XML Datei referenziert werden und auch **NICHT** an einer zentralen online erreichbaren Stelle liegen.
Die verschiedenen Schemas für jede XML-Datei könnte man bspw. im `quiqqer/quiqqer` oder einem eigenen Repository ablegen.
Die Prüfung der per PHP in ein `DOMDocument` geladenen XML-Datei erfolgt dann per [`DOMDocument::schemaValidate($schemaPath)`](https://www.php.net/manual/en/domdocument.schemavalidate.php).Jan WennrichJan Wennrichhttps://dev.quiqqer.com/quiqqer/quiqqer/-/issues/1152Add security.txt file2024-01-25T07:37:20ZJan WennrichAdd security.txt fileThe IETF released a draft for a standardized file (`security.txt`) that contains information on how to disclose security related issues:
> “When security risks in web services are discovered by independent security researchers who under...The IETF released a draft for a standardized file (`security.txt`) that contains information on how to disclose security related issues:
> “When security risks in web services are discovered by independent security researchers who understand the severity of the risk, they often lack the channels to disclose them properly. As a result, security issues may be left unreported. security.txt defines a standard to help organizations define the process for security researchers to disclose security vulnerabilities securely.”
>
> security.txt files have been implemented by Google, Facebook, GitHub, the UK government, and many other organisations. In addition, the UK’s Ministry of Justice, the Cybersecurity and Infrastructure Security Agency (US), the French government, the Italian government, and the Australian Cyber Security Centre endorse the use of security.txt files.
As there is currently no clear indication on QUIQQER websites that we (PCSG) are developing QUIQQER or how to contact us, a `security.txt` file should be added.
What do you think about that, @mor & @henbug?
Further information:
1. https://securitytxt.org/
1. https://datatracker.ietf.org/doc/html/draft-foudil-securitytxt-121.11 (K* K*)Henning LeutzHenning Leutzhttps://dev.quiqqer.com/quiqqer/quiqqer/-/issues/1138Angemeldet bleiben Funktion inplementieren2023-11-28T14:33:20ZMoritz ScholzAngemeldet bleiben Funktion inplementierenFür eine optimale Arbeitserfahrung und verbesserte Sicherheit ist es empfehlenswert, dass ein Nutzer auf einem System, auf dem er sicher arbeiten kann, dauerhaft angemeldet bleibt. Dies ermöglicht eine erhöhte Systemintegrität und Nutzer...Für eine optimale Arbeitserfahrung und verbesserte Sicherheit ist es empfehlenswert, dass ein Nutzer auf einem System, auf dem er sicher arbeiten kann, dauerhaft angemeldet bleibt. Dies ermöglicht eine erhöhte Systemintegrität und Nutzersicherheit.
Es sollte eine optionale Funktion bereitgestellt werden, die es dem Nutzer ermöglicht, dauerhaft auf dem jeweiligen System angemeldet zu bleiben. Das bedeutet, dass die Session auf dem aktuellen System - eine Kombination aus Betriebssystem und Browser - automatisch erneuert wird, sofern diese Option aktiviert ist.
Um dies zu ermöglichen, müssten auf dem Client Informationen sowie ein zusätzlicher verschlüsselter Identifikator, beispielsweise durch ein Cookie oder Storage, hinterlegt werden. Ein denkbarer Ansatz hierfür könnte die Web Authentication API (WebAuthn) sein, wie unter https://www.w3.org/TR/webauthn-2/#sctn-user-handle-privacy beschrieben.
Zudem könnte hier eine Browseridentifikation integriert werden, die den aufrufenden Browser erkennt und die Nutzerinformationen des zuletzt angemeldeten Nutzers speichert. Dies könnte sowohl auf Backend- als auch auf Frontenduser-Ebene umgesetzt werden.
Auf diese Weise könnte der Nutzer, selbst wenn er abgemeldet ist, zum Beispiel durch ein Session Timeout, noch persönlich begrüßt werden, wie es von anderen Diensten bereits bekannt ist. In diesem Fall wäre es für den Nutzer lediglich notwendig, sein Passwort einzugeben, nicht aber seinen Nutzernamen oder seine E-Mail-Adresse. Dies stellt eine zusätzliche Vereinfachung des Anmeldeprozesses dar und erhöht den Komfort für den Nutzer.1.12 (L* L*)Henning LeutzHenning Leutzhttps://dev.quiqqer.com/quiqqer/quiqqer/-/issues/1023Überschriften-Ebene für Listeneinträge einstellbar machen2020-06-18T13:17:48ZMark LeibleinÜberschriften-Ebene für Listeneinträge einstellbar machenGerade mit Hen kurz besprochen. Aktuell kann man in Quiqqer noch keine Überschriften-Ebenen für Listeneinträge definieren.
**Beispiel NameRobot:**
https://www.namerobot.de/namensfindung-blog
Hier sind alle Listeneinträge H1:
![image]...Gerade mit Hen kurz besprochen. Aktuell kann man in Quiqqer noch keine Überschriften-Ebenen für Listeneinträge definieren.
**Beispiel NameRobot:**
https://www.namerobot.de/namensfindung-blog
Hier sind alle Listeneinträge H1:
![image](/uploads/2cb9bf1bd12c7c22a37d5b4f748f09e2/image.png)
**Beispiel Namestorm:**
![image](/uploads/2712b6fd06e8d19715597de18d3b8074/image.png)
Hier sind neben der eigentlichen H1 "Unsere Leistungen..." auch alle Listeneinträge als H1 definiert.
@mor fyihttps://dev.quiqqer.com/quiqqer/quiqqer/-/issues/998Adressen -> Feld für Staat/Bundesland2023-10-31T08:27:02ZPatrick MüllerAdressen -> Feld für Staat/BundeslandIn vielen Ländern werden Orte noch durch das Bundesland/Bundesstaat spezifiziert (z.B. USA wo es Städtename zu Hauf doppelt gibt).
Es müsste in Kunden (und wahrscheinlich auch generell in QUIQQER) möglich sein, das in der Adresse zu hin...In vielen Ländern werden Orte noch durch das Bundesland/Bundesstaat spezifiziert (z.B. USA wo es Städtename zu Hauf doppelt gibt).
Es müsste in Kunden (und wahrscheinlich auch generell in QUIQQER) möglich sein, das in der Adresse zu hinterlegen. Einige Zahlungsanbieter (z.B. PayPal) verlangen auch die Angabe des Bundesstaats bei Lieferadressen in bestimmte Länder (USA).
Wie wollen wir das am besten handhaben?Henning LeutzHenning Leutzhttps://dev.quiqqer.com/quiqqer/quiqqer/-/issues/983Debug Levels2023-10-31T08:23:01ZHenning LeutzDebug Levelsdebug level must be introduced / implemented / established.
At the moment, every debug message has the same priority.
This floats the debug log and debugging becomes a paindebug level must be introduced / implemented / established.
At the moment, every debug message has the same priority.
This floats the debug log and debugging becomes a painhttps://dev.quiqqer.com/quiqqer/quiqqer/-/issues/880ReAuth Function2023-10-31T08:24:06ZMoritz ScholzReAuth FunctionIt would be nice if whenever the user session has expired an authentication window would be displayed automatically. Currently this is only the case if the user sends a request that requires authentication.
This could be done e.g. by a ...It would be nice if whenever the user session has expired an authentication window would be displayed automatically. Currently this is only the case if the user sends a request that requires authentication.
This could be done e.g. by a regular request when a user is logged in. However, this request must pass urgently after the session renewal because otherwise the session would always be extended.Henning LeutzHenning Leutzhttps://dev.quiqqer.com/quiqqer/quiqqer/-/issues/792Get User by attribute2018-11-19T11:52:57ZJan WennrichGet User by attributeI added some additional user attributes via the `user.xml` file.
As far as I know it is not possible to get a User by one of these custom properties, right?
So I can do:
```
Users\Manager->get()
Users\Manager->getUserByMail()
User...I added some additional user attributes via the `user.xml` file.
As far as I know it is not possible to get a User by one of these custom properties, right?
So I can do:
```
Users\Manager->get()
Users\Manager->getUserByMail()
Users\Manager->getUserByName()
```
But it's not possible to do something like:
```
Users\Manager->getByAttribute('my.custom.attribute', 123)
```
to get the user having the attribute `my.custom.attribute` with a value of `123`.
----------
I know these attributes are stored as JSON in a single database field so it's not easy/possible to query them.
But recently I found out about MySQL supporting JSON and having some handy JSON functions (such as `JSON_EXTRACT`). These functions would make it possible to query JSON data as well.
For example:
If have the following data in my table:
| id | data |
|----|-----------------------------------------------------------|
| 1 | {"my.attribute": false, "some.other.attribute": "blargh"} |
| 2 | {"my-attribute": false, "some.other.attribute": "blargh"} |
| 3 | {"my-attribute": true, "some.other.attribute": "blargh"} |
Using this query
```mysql
SELECT * FROM my_table WHERE JSON_EXTRACT(data, '$."my.attribute"') = true;
```
Returns:
| id | data |
|----|-----------------------------------------------------------|
| 3 | {"my.attribute": true, "some.other.attribute": "blargh"} |
----------------
**Conclusion:**
This means querying by attributes would be possible.
I didn't check the performance yet, but I read about MySQL being able to cache and optimize queries if you define keys (for/inside the JSON?).
I guess the performance would be even better if the type of the attribute column would be `JSON`.
Only caveat is that the JSON functionality became part of MySQL in version 5.7 and I'm not sure which MySQL versions QUIQQER tries to support.
What do you think of integrating this into QUIQQER, @henbug (and maybe @mor)https://dev.quiqqer.com/quiqqer/quiqqer/-/issues/790Video Ideas2018-11-18T14:34:11ZJan WennrichVideo IdeasTo anyone who wants to help us, we are always looking for active support. Even if you are not a professional developer, anyone can support us!
Tutorials for example are a good start. We want to make it as easy as possible for everyone t...To anyone who wants to help us, we are always looking for active support. Even if you are not a professional developer, anyone can support us!
Tutorials for example are a good start. We want to make it as easy as possible for everyone to use QUIQQER. If you have no idea which kind of tutorials you could create, here is a list of videos that would help anyone
* [ ] How to install QUIQQER?
* [ ] How to create my first package?
* [ ] ow to start a blog with QUIQQER?
* [ ] My first SaaS
* [ ] CRON
* [ ] REST
* [ ] Queues
* [ ] How to create an app from my homepage?
* [ ] Google XML sitemap
* [ ] How to speed up my QUIQQER page?https://dev.quiqqer.com/quiqqer/quiqqer/-/issues/763Google AMP und/oder Facebook Instant Articles Seiten(Typen)2018-10-04T04:28:40ZJan WennrichGoogle AMP und/oder Facebook Instant Articles Seiten(Typen)Für schnelle Seitenaufrufe fände ich es interessant, wenn man seine Seiten auch als Google Accelerated Media Pages oder Facebook Instant Articles anbieten könnte.
Siehe dazu:
https://www.ampproject.org/docs/fundamentals/converting ...Für schnelle Seitenaufrufe fände ich es interessant, wenn man seine Seiten auch als Google Accelerated Media Pages oder Facebook Instant Articles anbieten könnte.
Siehe dazu:
https://www.ampproject.org/docs/fundamentals/converting
https://developers.facebook.com/docs/instant-articles/guides/importing
Was haltet ihr davon, @mor und @henbug?https://dev.quiqqer.com/quiqqer/quiqqer/-/issues/647QUIQQER auf einem RPI und 32Bit testen2018-09-25T14:26:28ZHenning LeutzQUIQQER auf einem RPI und 32Bit testenDurch die integration von UUID kann es sein das dies nicht mehr kompatibel ist.Durch die integration von UUID kann es sein das dies nicht mehr kompatibel ist.https://dev.quiqqer.com/quiqqer/quiqqer/-/issues/598Stresstest bei QUIQQER durchführen2017-12-04T15:12:30ZHenning LeutzStresstest bei QUIQQER durchführen- Cache etc testen
- Mehr Benutzer im System testen
- Bottlenecks finden- Cache etc testen
- Mehr Benutzer im System testen
- Bottlenecks findenMoritz ScholzMoritz Scholz