Kategorien
Angular JavaScript

Identifizieren von ungenutzten NPM Packeten mit depcheck in Angular

Das npm Packet depcheck kann ungenutzten NPM Packete finden. Diese Information ist wichtig, weil fremde Packete ein Sicherheitsrisiko darstellen.

Das Risiko geht von fremden npm Packeten

Es gibt verschiedene potenzielle Angriffe oder Sicherheitsrisiken, die mit npm-Paketen verbunden sein können. Hier sind einige Beispiele:

  1. Maliziöse Pakete: Angreifer können böswillige oder schädliche Pakete veröffentlichen, die als nützliche oder beliebte Bibliotheken getarnt sind. Diese Pakete können schädlichen Code enthalten, der dein System oder deine Anwendung beeinträchtigen kann.
  2. Abhängigkeitskette: Wenn du npm-Pakete in deinem Projekt verwendest, können diese wiederum von anderen Paketen abhängen. Angreifer könnten eine Schwachstelle in einer Abhängigkeit ausnutzen, um Zugriff auf dein System zu erlangen oder deine Anwendung zu kompromittieren.
  3. Verwaiste Pakete: Verwaiste Pakete sind solche, deren ursprüngliche Entwickler die Wartung eingestellt haben. Diese Pakete erhalten möglicherweise keine Sicherheitsupdates mehr und könnten anfällig für Angriffe sein. Verwenden deiner Anwendung veraltete und unsichere Pakete erhöht das Risiko von Sicherheitslücken.
  4. Manipulation von Paketregistrierungen: Ein Angreifer könnte versuchen, die Infrastruktur der Paketregistrierung zu kompromittieren und schädliche Pakete in den offiziellen Paketkanälen bereitzustellen. Dies könnte dazu führen, dass du unwissentlich gefährliche Pakete installierst.
  5. Code-Injektion: Wenn du npm-Pakete verwendest, ist es wichtig, darauf zu achten, dass der Code sicher ist. Ein fehlerhaftes oder unsicher implementiertes Paket kann Angreifern die Möglichkeit bieten, schädlichen Code in deine Anwendung einzuschleusen.

Die Funktionsweise von Depcheck

Depcheck analysiert den Quellcode deines Projekts, um festzustellen, welche Pakete tatsächlich verwendet werden. Dabei untersucht es verschiedene Aspekte des Codes, um die Verwendung von Paketen zu ermitteln:

  1. Importanweisungen: Depcheck überprüft die Importanweisungen in den JavaScript-/TypeScript-Dateien. Es sucht nach importierten Modulen, Klassen, Funktionen oder Variablen und ermittelt so, welche Pakete im Code verwendet werden.
  2. Referenzen und Verwendungen: Depcheck analysiert den Code, um festzustellen, ob die importierten Module, Klassen, Funktionen oder Variablen tatsächlich verwendet werden. Es überprüft, ob Funktionen aufgerufen, Methoden aufgerufen, Eigenschaften gelesen oder Variablen referenziert werden. Wenn ein importiertes Element nicht verwendet wird, markiert depcheck das zugehörige Paket als potenziell unbenutzt.
  3. Berücksichtigung verschiedener Dateitypen: Depcheck kann auch andere relevante Dateitypen analysieren, wie z.B. HTML-Dateien oder Konfigurationsdateien, um die Verwendung von Paketen zu ermitteln. Beispielsweise können in HTML-Dateien verwendete Direktiven oder Komponenten auf Pakete hinweisen, die im Code selbst möglicherweise nicht explizit importiert werden.

Einbinden von depcheck in Angular

Die Installation erfolgt über

npm install -g depcheck typescript

Beispiel Ausgabe bei einem Angular Projekt:

Unused dependencies
* @types/quill
* @types/vis
* bootstrap
* ngx-quill
* tslib
Unused devDependencies
* @angular-devkit/build-angular
* @angular/cli
* @angular/compiler-cli
* @types/jasmine
* jasmine-core
* karma
* karma-chrome-launcher
* karma-coverage
* karma-jasmine
* karma-jasmine-html-reporter
* typescript

In der package.json befanden sich 11 dev Dependencies und 19 normale Dependencies. Es wurden alle dev Dependencies falsch positiv erkannt. Von den potenziel gefährlicheren normalen Packete, die nicht nur im dev Modus existieren, wurden korrekt 13 Packete als verwendet erkannt. Die 5 Packete kann man einfach per Namen oder Regex (@types/*) entfernen.

Es wird tatsächlich erkannt, das ngx-quill in dem Beispiel als einziges Packet nicht verwendet wird.

Es muss also eine Menge von Hand ausgechlossen werden, wofür ein spezielle depcheck Angular Erweiterung nützlich wäre, aber leider noch nicht existiert im Gegensatz zu React JSX und Vue.js.

Fazit

Depcheck ist nützlich um unbenutzte Packete zu identifizieren, um die Sicherheit von Angular Anwendungen zu gewährleisten.

Außerdem sollten alle Packete fortwährend auf Sicherheitslücken gescannt werden. Wenn ein Packet nicht mehr weiter entwickelt wird oder Sicherheitslücken nicht schließt, sollte es ausgetauscht werden gegen eine aktuelle Variante.

Kategorien
Projekte

Berlin Tipps Webseite veröffentlicht

Als kleines neben Projekt, habe ich die Webseite fnfn.de veröffentlicht, indem ich die besten Restaurants, Bars, Sehenswürdigkeiten und Clubs von Berlin vorstelle.

Kategorien
Symfony

Sonata 4 Admin Variablen im Template

In Sonata 4 stehen verschiedene Sonata-spezifische Variablen in den Templates zur Verfügung. Hier sind einige der häufig verwendeten Variablen:

  1. admin: Diese Variable repräsentiert das aktuelle Admin-Objekt und ermöglicht den Zugriff auf verschiedene Admin-spezifische Informationen und Methoden. Sie kann verwendet werden, um beispielsweise den Admin-Titel oder die Routen zu erhalten.
  2. object: Diese Variable repräsentiert das aktuelle Objekt oder die aktuelle Entität, mit der das Template arbeitet. Sie ermöglicht den Zugriff auf Eigenschaften und Methoden des Objekts, um dynamische Inhalte im Template zu generieren.
  3. id: Diese Variable enthält die ID des aktuellen Objekts. Sie ist besonders nützlich in Templates, die auf einzelne Objekte angewendet werden, um spezifische Daten abzurufen oder Aktionen durchzuführen.
  4. form: Wenn das Template ein Formular darstellt, steht die form Variable zur Verfügung. Diese Variable ermöglicht den Zugriff auf das Formularobjekt und dessen Felder, um beispielsweise Validierungen durchzuführen oder Daten zu verarbeiten.
  5. base_template: Diese Variable definiert das Basis-Template, das von einem spezifischen Sonata Template erweitert wird. Sie ermöglicht es Entwicklern, das Standardverhalten von Sonata anzupassen, indem sie ein benutzerdefiniertes Basis-Template festlegen.
  6. admin_pool: Diese Variable stellt den Admin-Pool dar und bietet Zugriff auf den gesamten verfügbaren Admin-Bereich. Sie ermöglicht den Zugriff auf Informationen über alle registrierten Admin-Klassen und kann zum Beispiel verwendet werden, um eine Liste der verfügbaren Admin-Objekte anzuzeigen.

In Sonata 4 stehen neben den zuvor genannten Variablen auch die value-Variable zur Verfügung. Diese Variable repräsentiert den aktuellen Wert eines bestimmten Feldes oder einer Eigenschaft des Objekts.

Hier ist ein Beispiel, wie die value-Variable im Template array.html.twig verwendet werden kann:

{% extends '@SonataAdmin/CRUD/base_show_field.html.twig' %}

{% block field %}
    {% if value is not empty %}
        {{ value | join(', ') }}
    {% endif %}
{% endblock %}
protected function configureShowFields(ShowMapper $show): void
{
	$show->add('my_attrbute', null, [
		'label' => 'Array Attribute Example',
		'template' => 'array.html.twig',
		]
	)
}
Kategorien
PHP Symfony

SQL vs. Doctrine Migrations

In Symfony und Doctrine stehen Ihnen zwei Optionen zur Verfügung, um Datenbankmigrationen zu verwalten: SQL und Doctrine-Objekte.

  1. SQL-Migrationen: Mit SQL-Migrationen schreiben Sie die Datenbankänderungen als SQL-Skripte. Dies gibt Ihnen die volle Kontrolle über den genauen SQL-Code, der ausgeführt wird. Sie können spezifische Datenbankfunktionen und -funktionen nutzen, die möglicherweise nicht direkt von Doctrine unterstützt werden. SQL-Migrationen können auch einfacher sein, wenn Sie bereits über umfangreiche SQL-Kenntnisse verfügen.

Einige Vorteile der SQL-Migrationen sind:

  • Direkte Kontrolle über den SQL-Code.
  • Nutzung spezifischer Datenbankfunktionen.
  • Einfacher für Entwickler mit umfangreichen SQL-Kenntnissen.

Einige Nachteile der SQL-Migrationen sind:

  • Möglicherweise weniger portabel, da der SQL-Code an eine bestimmte Datenbank-Engine gebunden sein kann.
  • Weniger objektorientiert und weniger Integration mit dem Doctrine ORM.
  1. Doctrine-Objekt-Migrationen: Mit Doctrine-Objekt-Migrationen verwenden Sie Doctrine-Migrationsklassen, um Ihre Datenbankänderungen zu definieren. Dies ermöglicht eine objektorientierte Herangehensweise an die Migrationen und eine bessere Integration mit dem Doctrine ORM. Sie können auf die Funktionen von Doctrine zugreifen und beispielsweise Änderungen an Ihren Datenbanktabellen über die Objektmodelle vornehmen.

Einige Vorteile der Doctrine-Objekt-Migrationen sind:

  • Objektorientierte Herangehensweise an Migrationen.
  • Bessere Integration mit dem Doctrine ORM.
  • Portabler, da Doctrine den generierten SQL-Code an die spezifische Datenbank-Engine anpasst.

Der entscheidende Nachteil von Doctrine-Objekt-Migrationen

Ein wichtiger Nachteil bei der Verwendung von Doctrine-Objekt-Migrationen besteht darin, dass bei der Erstellung der Entitäten ein Fehler auftritt, wenn ein Attribut in der Datenbank nicht vorhanden ist. Dies kann insbesondere dann zum Problem werden, wenn Sie vorhandene Datenbanktabellen haben und Änderungen an den Entitäten vornehmen, die zu Spalten hinzufügen oder entfernen.

Wenn Sie beispielsweise eine Entität mit einem bestimmten Attribut definieren und versuchen, die Datenbanktabellen basierend auf dieser Entität zu erstellen, wird Doctrine einen Fehler werfen, wenn das entsprechende Attribut in der Datenbanktabelle nicht vorhanden ist. Dies liegt daran, dass Doctrine die Entitäten und die Datenbanktabellen synchron halten möchte.

Aufgrund meiner Erfahrungen mit Migrationen würde ich immer empfehlen SQL-Migrationen zu verwenden, weil beim hinzufügen von Attributen ansonsten immer Fehler geworfen werden.

Kategorien
Webdeveloper Tools

PHPStorm Klassenhierachie anzeigen

Mit der Tastenkombination STRG + ALT + U kann man sich zu einer beliebigen Klassse ein Diagramm über die Vererbungen und Interfaces aufrufen lassen in der IDE.

Beispiel:

Klassendiagramm der Klasse User in PHP
Klassendiagramm der Klasse User in TypeScript
Kategorien
Symfony

GuzzleHttp loggen aller Requests nach Monolog

Um alle Requests und Responses zu loggen, die mittels Guzzle in einer Symfony Applikation getätigt werden, kann man Guzzle folger Maßen konfigurieren:

    guzzle.handler_stack_log:
      class: 'GuzzleHttp\HandlerStack'
      factory: [ GuzzleHttp\HandlerStack, create ]
      calls:
        - [ push, [ '@guzzle.middleware_log', 'log_default' ] ]

    guzzle.middleware_log:
      class: callback
      factory: [ GuzzleHttp\Middleware, log ]
      arguments:
        - '@monolog.logger.my_guzzle_log'
        - '@GuzzleHttp\MessageFormatter'

    GuzzleHttp\MessageFormatter:
      - "Request:\n{request}\nDuration: {req_time}\nResponse:\n{response}\nError:\n{error}"

Damit werden alle Logs nach zum Monolog Service monolog.logger.my_guzzle_log weitergeleitet.

Der MessageFormatter unterstützt verschiedene Formatzeichenfolgen, die Sie in Ihren Protokollen verwenden können. Hier sind fünf nützliche GuzzleHttp\MessageFormatter-Formate:

  1. Log-Eintrag, der die URL, Methode, und Status-Code umfasst: Format: "Request: {method} {uri}, Response: {code}"

Beispiel Output: "Request: GET http://example.com, Response: 200"

  1. Log-Eintrag, der die Anforderungsdauer und den Antwortstatus beinhaltet: Format: "Duration: {req_time}, Response: {code}"

Beispiel Output: "Duration: 1.123, Response: 200"

  1. Log-Eintrag, der die Anfrage, Antwort und etwaige Fehler anzeigt: Format: "Request:\n{request}\nResponse:\n{response}\nError:\n{error}"

Beispiel Output:

Request:
GET / HTTP/1.1
Host: example.com

Response:
HTTP/1.1 200 OK
Content-Length: 348
Content-Type: text/html

Error:
None

Der GuzzleHttp\MessageFormatter unterstützt eine Vielzahl von Platzhaltern, die in den Formatstrings verwendet werden können. Hier ist eine Liste einiger der verfügbaren Platzhalter:

ParameterBeschreibungBeispiel Output
{request}Vollständige HTTP-Anforderungsnachricht„GET / HTTP/1.1\r\nHost: example.com\r\nAccept: */*\r\n“
{response}Vollständige HTTP-Antwortnachricht„HTTP/1.1 200 OK\r\nContent-Length: 348\r\nContent-Type: text/html\r\n“
{ts}Timestamp„1519211809.123456“
{date_iso_8601}Aktuelles Datum im ISO 8601 Format„2023-06-03T14:30:00Z“
{date_common_log}Aktuelles Datum im Common Log Format„03/Jun/2023:14:30:00 +0000“
{host}Der Host der Anforderung„example.com“
{method}HTTP-Methode der Anforderung„GET“
{uri}URI der Anforderung„http://example.com“
{version}HTTP-Version„1.1“
{target}Anforderungsziel (Pfad + Abfragestring der URI)„/path?query=example“
{hostname}Der Hostname des lokalen Rechners„localhost“
{code}Statuscode der Antwort„200“
{phrase}Statusphrase der Antwort„OK“
{error}Error message„Error: Connection refused“
{req_header_User-Agent}Einzelner Request-Header„GuzzleHttp/6.3.3 curl/7.54.0 PHP/7.2.7“
{res_header_Content-Type}Einzelner Response-Header„text/html“
{req_headers}Kopfzeilen der Anforderung„Host: example.com\r\nUser-Agent: GuzzleHttp/6.3.3 curl/7.54.0 PHP/7.2.7\r\n“
{res_headers}Kopfzeilen der Antwort„Content-Type: text/html\r\nContent-Length: 348\r\n“
{req_body}Anforderungskörper„name=John+Doe“
{res_body}Antwortkörper„Hello, John Doe!“
{req_body_size}Größe des Anforderungskörpers„13“
{res_body_size}Größe des Antwortkörpers„15“
{curl_err}Fehlermeldung von cURL (falls vorhanden)„Couldn’t resolve host name“
{curl_info}Information von cURL (falls vorhanden)„Array ( [url] => http://example.com [content_type] => text/html [http_code] => 200 [header_size] => 228 [request_size] => 78…)“
{curl_version}cURL-Version (falls verwendet)„7.54.0“
{handler_stats}Handler spezifische Statistiken (falls verfügbar)„Array ( [total_time] => 0.152404 [namelookup_time] => 0.02914 [connect_time] => 0.049718 )“

Kategorien
Symfony

Symfony monolog Logs auf der Konsole anzeigen

Um die Monolog-Logs in der Symfony-Konsole anzuzeigen, können Sie Folgendes tun:

  1. Sie müssen zuerst sicherstellen, dass Monolog so konfiguriert ist, dass es auf der Konsole loggt. Dazu müssen Sie die config/packages/dev/monolog.yaml-Datei bearbeiten und sicherstellen, dass eine Stream-Handler-Konfiguration für die Konsole vorhanden ist.
monolog:
    handlers:
        console:
            type:   stream
            path:   "php://stdout"
            level:  debug
            channels: ["!event"]
  1. Es empfiehlt ich auch beim ausführen der Tests den Consolen Logger zu aktivieren in config/packages/test/monolog.yaml. Damit erhält man wertvolle Loginformationen beim Ausführen seiner Tests.
  1. In Ihrem Konsolenbefehl können Sie dann das Logger-Interface injizieren und verwenden, um Meldungen zu loggen. Hier ist ein einfacher Konsolenbefehl, der dies demonstriert:
namespace App\Command;

use Psr\Log\LoggerInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class YourCommand extends Command
{
    private $logger;

    public function __construct(LoggerInterface $logger)
    {
        $this->logger = $logger;

        parent::__construct();
    }

    protected function configure()
    {
        $this
            ->setName('app:your-command')
            ->setDescription('Description of your command.');
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $this->logger->info('This is an info log entry.');

        // ...

        return Command::SUCCESS;
    }
}
  1. Starten Sie dann Ihren Befehl von der Konsole aus, und Sie sollten die Protokolle auf der Konsole sehen:
$ php bin/console app:your-command
[2023-06-02T12:34:56.789Z] info: This is an info log entry.

Bitte beachten Sie, dass die obige Konfiguration die Logs auf allen Kanälen außer „event“ auf „php://stdout“ ausgibt. Sie können die Kanäle an Ihre Bedürfnisse anpassen.

Ebenfalls beachten Sie bitte, dass die Protokolle nur ausgegeben werden, wenn der Log-Level Ihrer Meldung dem in der Monolog-Konfiguration festgelegten Level entspricht oder darüber liegt. Im obigen Beispiel wird alles auf „debug“-Level und darüber protokolliert.

Kategorien
Angular

Angular Relogin User on Wake Up

In einer Angular-App gibt es eine Möglichkeit, ein Ereignis auszulösen, wenn ein Benutzer den Browser-Tab wieder öffnet. Dies kann mithilfe des Page Visibility API erreicht werden, das vom Browser bereitgestellt wird.

Um auf das Ereignis zu reagieren, wenn der Benutzer den Tab wieder öffnet, kannst du das visibilitychange-Ereignis an das document-Objekt binden. Hier ist ein Beispiel, wie du dies in Angular umsetzen kannst:

import {Component, HostListener} from '@angular/core';
import {AuthService} from './shared/auth/auth.service';
import {Router} from '@angular/router';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  constructor(
    private authService: AuthService,
    private router: Router,
  ) {}

  // when user is reopening app, we check if the API session is expired and user nees to login again
  @HostListener('document:visibilitychange', ['$event'])
  visibilitychange() {
    console.log('visibilitychange event');
    if (!document.hidden) {
      console.log('check if user is logged in');
      if (!this.authService.checkTokenValidity()) {
        console.log('user token validity has expired. make logout');
        this.router.navigate(['/logout']);
      }
    }
  }
}

Zusammenfassend wird dieser Code verwendet, um zu überprüfen, ob die API-Sitzung des Benutzers abgelaufen ist, wenn der Benutzer die App erneut öffnet. Wenn das Benutzertoken abgelaufen ist, wird der Benutzer automatisch zur Logout-Seite weitergeleitet. Dadurch wird eine erneute Authentifizierung ermöglicht und der Benutzer aufgefordert, sich erneut anzumelden, um auf geschützte Funktionen der App zugreifen zu können.

Kategorien
JavaScript

NVM für Windows

Der Node Version Manager, auch bekannt als NVM, ist ein Open-Source-Tool, das es Entwicklern ermöglicht, mehrere Versionen von Node.js auf ihrem System zu installieren und zwischen ihnen zu wechseln. Mit NVM können Sie problemlos zwischen verschiedenen Node.js-Versionen wechseln, ohne manuelle Installationen oder Deinstallationen vornehmen zu müssen. Das bedeutet, dass Sie für jedes Projekt die optimale Node.js-Version auswählen können, abhängig von den Anforderungen und Kompatibilitätsfaktoren.

Die wichtigsten Befehler sind:

#install a version of Node
nvm install <node-version>

#see the versions of Node you have installed on your machine
nvm list

# list all available versions including not installed versions
nvm list available

#use a specific version of Node
nvm use <node-version>

#create alias fpr nvm version
nvm alias <name> <version>

Kategorien
PHP

OpenAI ChatGPT-3 PHP Client

Mit dem folgenden Code kann man per PHP auf GPT-3 via API zugreifen. Vorraussetzung ist ein valider API Key.

<?php


// Setzen Sie Ihren OpenAI API-Zugriffsschlüssel
$api_key = '';

// API-Anfrage senden
$response = send_api_request("Wer war Pablo Picasso?", $api_key);

print_r($response);

// Funktion zum Senden einer API-Anfrage
function send_api_request($prompt, $api_key)
{
    $data = array(
        'messages' => [
            [
                "role" => 'user',
                "content" => $prompt,
            ],
        ],
        'max_tokens' => 100,
        'temperature' => 0.7,
        'model' => 'gpt-3.5-turbo'
    );

    $headers = array(
        'Content-Type: application/json',
        'Authorization: Bearer ' . $api_key
    );

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, 'https://api.openai.com/v1/chat/completions');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

    $response = curl_exec($ch);
    curl_close($ch);

    return $response;
}