Implement Blake3 hashing in CDokumente; update related metadata and localization files
This commit is contained in:
@@ -35,22 +35,24 @@ class CDokumente extends \Espo\Core\Hooks\Base
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Berechne neue Hashes
|
// Berechne Blake3 Hash
|
||||||
$newMd5 = hash_file('md5', $filePath);
|
$fileContent = file_get_contents($filePath);
|
||||||
$newSha256 = hash_file('sha256', $filePath);
|
if ($fileContent === false) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Setze Hashes
|
$newBlake3 = bin2hex(blake3($fileContent));
|
||||||
$entity->set('md5sum', $newMd5);
|
|
||||||
$entity->set('sha256', $newSha256);
|
// Setze Hash
|
||||||
|
$entity->set('blake3hash', $newBlake3);
|
||||||
|
|
||||||
// Bestimme Status
|
// Bestimme Status
|
||||||
if ($entity->isNew()) {
|
if ($entity->isNew()) {
|
||||||
$entity->set('fileStatus', 'new');
|
$entity->set('fileStatus', 'new');
|
||||||
} else {
|
} else {
|
||||||
$oldMd5 = $entity->getFetched('md5sum');
|
$oldBlake3 = $entity->getFetched('blake3hash');
|
||||||
$oldSha256 = $entity->getFetched('sha256');
|
|
||||||
|
|
||||||
if ($oldMd5 !== $newMd5 || $oldSha256 !== $newSha256) {
|
if ($oldBlake3 !== $newBlake3) {
|
||||||
$entity->set('fileStatus', 'changed');
|
$entity->set('fileStatus', 'changed');
|
||||||
} else {
|
} else {
|
||||||
$entity->set('fileStatus', 'synced');
|
$entity->set('fileStatus', 'synced');
|
||||||
|
|||||||
@@ -3,8 +3,7 @@
|
|||||||
"dokument": "Download",
|
"dokument": "Download",
|
||||||
"preview": "Vorschau",
|
"preview": "Vorschau",
|
||||||
"ydocumentuuid": "Y-Document-UUID",
|
"ydocumentuuid": "Y-Document-UUID",
|
||||||
"md5sum": "MD5-Prüfsumme",
|
"blake3hash": "Blake3-Hash",
|
||||||
"sha256": "SHA256-Prüfsumme",
|
|
||||||
"fileStatus": "Datei-Status",
|
"fileStatus": "Datei-Status",
|
||||||
"contactsvmhdokumente": "Freigegebene Nutzer",
|
"contactsvmhdokumente": "Freigegebene Nutzer",
|
||||||
"vmhMietverhltnisesDokumente": "Mietverhältnisse",
|
"vmhMietverhltnisesDokumente": "Mietverhältnisse",
|
||||||
@@ -41,6 +40,7 @@
|
|||||||
"Create CDokumente": "Dokument erstellen"
|
"Create CDokumente": "Dokument erstellen"
|
||||||
},
|
},
|
||||||
"tooltips": {
|
"tooltips": {
|
||||||
|
"blake3hash": "Kryptografischer Blake3-Hash der Datei (schneller und sicherer als MD5/SHA256)",
|
||||||
"fileStatus": "Status der Datei: new = neu hochgeladen, changed = geändert, synced = synchronisiert"
|
"fileStatus": "Status der Datei: new = neu hochgeladen, changed = geändert, synced = synchronisiert"
|
||||||
},
|
},
|
||||||
"options": {
|
"options": {
|
||||||
|
|||||||
@@ -8,8 +8,7 @@
|
|||||||
"vmhErstgespraechsdokumente": "Initial Consultations",
|
"vmhErstgespraechsdokumente": "Initial Consultations",
|
||||||
"vmhRumungsklagesdokumente": "Eviction Lawsuits",
|
"vmhRumungsklagesdokumente": "Eviction Lawsuits",
|
||||||
"kuendigungDokumente": "Terminations",
|
"kuendigungDokumente": "Terminations",
|
||||||
"md5sum": "MD5 Checksum",
|
"blake3hash": "Blake3 Hash",
|
||||||
"sha256": "SHA256 Checksum",
|
|
||||||
"beteiligte2dokumente": "Parties",
|
"beteiligte2dokumente": "Parties",
|
||||||
"mietobjekt2dokumente": "Properties",
|
"mietobjekt2dokumente": "Properties",
|
||||||
"mietinkassosdokumente": "Rent Collection",
|
"mietinkassosdokumente": "Rent Collection",
|
||||||
@@ -47,6 +46,7 @@
|
|||||||
"listForAIKnowledge": "List for AI Knowledge"
|
"listForAIKnowledge": "List for AI Knowledge"
|
||||||
},
|
},
|
||||||
"tooltips": {
|
"tooltips": {
|
||||||
|
"blake3hash": "Cryptographic Blake3 hash of the file (faster and more secure than MD5/SHA256)",
|
||||||
"fileStatus": "File status: new = newly uploaded, changed = modified, synced = synchronized"
|
"fileStatus": "File status: new = newly uploaded, changed = modified, synced = synchronized"
|
||||||
},
|
},
|
||||||
"options": {
|
"options": {
|
||||||
|
|||||||
@@ -61,13 +61,9 @@
|
|||||||
"name": "fileStatus"
|
"name": "fileStatus"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "md5sum"
|
"name": "blake3hash"
|
||||||
}
|
},
|
||||||
],
|
{}
|
||||||
[
|
|
||||||
{
|
|
||||||
"name": "sha256"
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
"dynamicLogicVisible": null,
|
"dynamicLogicVisible": null,
|
||||||
|
|||||||
@@ -59,21 +59,14 @@
|
|||||||
"readOnlyAfterCreate": false,
|
"readOnlyAfterCreate": false,
|
||||||
"isCustom": true
|
"isCustom": true
|
||||||
},
|
},
|
||||||
"md5sum": {
|
"blake3hash": {
|
||||||
"type": "varchar",
|
"type": "varchar",
|
||||||
"maxLength": 32,
|
"maxLength": 64,
|
||||||
"copyToClipboard": true,
|
"copyToClipboard": true,
|
||||||
"readOnlyAfterCreate": true,
|
"readOnlyAfterCreate": true,
|
||||||
"options": [],
|
"options": [],
|
||||||
"isCustom": true
|
|
||||||
},
|
|
||||||
"sha256": {
|
|
||||||
"type": "varchar",
|
|
||||||
"maxLength": 64,
|
|
||||||
"readOnlyAfterCreate": true,
|
|
||||||
"options": [],
|
|
||||||
"isCustom": true,
|
"isCustom": true,
|
||||||
"copyToClipboard": true
|
"tooltip": true
|
||||||
},
|
},
|
||||||
"puls": {
|
"puls": {
|
||||||
"type": "link",
|
"type": "link",
|
||||||
@@ -298,14 +291,9 @@
|
|||||||
"id"
|
"id"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"md5sum": {
|
"blake3hash": {
|
||||||
"columns": [
|
"columns": [
|
||||||
"md5sum"
|
"blake3hash"
|
||||||
]
|
|
||||||
},
|
|
||||||
"sha256": {
|
|
||||||
"columns": [
|
|
||||||
"sha256"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"beforeSaveScript": "// Automatische x.AI Sync-Status Verwaltung\n\n// Fall 1: xaiId wurde gelöscht (war vorher vorhanden, jetzt leer)\nif (\n attribute\\fetched('xaiId') != null &&\n xaiId == null\n) {\n xaiSyncStatus = 'no_sync';\n}\n// Fall 2: xaiId wird neu gesetzt (war vorher leer, jetzt gefüllt)\nelse if (\n attribute\\fetched('xaiId') == null &&\n xaiId != null\n) {\n xaiSyncStatus = 'pending_sync';\n}\n// Fall 3: Dokument hat xaiId und relevante Felder haben sich geändert\nelse if (\n xaiId != null &&\n xaiSyncStatus != 'no_sync' &&\n (\n attribute\\isChanged('name') ||\n attribute\\isChanged('description') ||\n attribute\\isChanged('dokumentId') ||\n attribute\\isChanged('md5sum') ||\n attribute\\isChanged('sha256')\n )\n) {\n xaiSyncStatus = 'unclean';\n}\n// Fall 4: Bei neuem Dokument MIT xaiId → pending_sync\nelse if (\n entity\\isNew() &&\n xaiId != null\n) {\n xaiSyncStatus = 'pending_sync';\n}\n// Fall 5: Bei neuem Dokument OHNE xaiId → no_sync\nelse if (\n entity\\isNew() &&\n xaiId == null\n) {\n xaiSyncStatus = 'no_sync';\n}\n\n// Automatische Advoware Sync-Status Verwaltung\n\n// Fall 1: aktennr wurde gelöscht (war vorher vorhanden, jetzt leer)\nif (\n attribute\\fetched('aktennr') != null &&\n aktennr == null\n) {\n syncStatus = 'no_sync';\n}\n// Fall 2: aktennr wird neu gesetzt (war vorher leer, jetzt gefüllt)\nelse if (\n attribute\\fetched('aktennr') == null &&\n aktennr != null\n) {\n syncStatus = 'pending_sync';\n}\n// Fall 3: Dokument hat aktennr und relevante Felder haben sich geändert\nelse if (\n aktennr != null &&\n syncStatus != 'no_sync' &&\n (\n attribute\\isChanged('name') ||\n attribute\\isChanged('description') ||\n attribute\\isChanged('dokumentId') ||\n attribute\\isChanged('md5sum') ||\n attribute\\isChanged('sha256')\n )\n) {\n syncStatus = 'unclean';\n}\n// Fall 4: Bei neuem Dokument MIT aktennr → pending_sync\nelse if (\n entity\\isNew() &&\n aktennr != null\n) {\n syncStatus = 'pending_sync';\n}\n// Fall 5: Bei neuem Dokument OHNE aktennr → no_sync\nelse if (\n entity\\isNew() &&\n aktennr == null\n) {\n syncStatus = 'no_sync';\n}"
|
"beforeSaveScript": "// Automatische x.AI Sync-Status Verwaltung\n\n// Fall 1: xaiId wurde gelöscht (war vorher vorhanden, jetzt leer)\nif (\n attribute\\fetched('xaiId') != null &&\n xaiId == null\n) {\n xaiSyncStatus = 'no_sync';\n}\n// Fall 2: xaiId wird neu gesetzt (war vorher leer, jetzt gefüllt)\nelse if (\n attribute\\fetched('xaiId') == null &&\n xaiId != null\n) {\n xaiSyncStatus = 'pending_sync';\n}\n// Fall 3: Dokument hat xaiId und relevante Felder haben sich geändert\nelse if (\n xaiId != null &&\n xaiSyncStatus != 'no_sync' &&\n (\n attribute\\isChanged('name') ||\n attribute\\isChanged('description') ||\n attribute\\isChanged('dokumentId') ||\n attribute\\isChanged('blake3hash')\n )\n) {\n xaiSyncStatus = 'unclean';\n}\n// Fall 4: Bei neuem Dokument MIT xaiId → pending_sync\nelse if (\n entity\\isNew() &&\n xaiId != null\n) {\n xaiSyncStatus = 'pending_sync';\n}\n// Fall 5: Bei neuem Dokument OHNE xaiId → no_sync\nelse if (\n entity\\isNew() &&\n xaiId == null\n) {\n xaiSyncStatus = 'no_sync';\n}\n\n// Automatische Advoware Sync-Status Verwaltung\n\n// Fall 1: aktennr wurde gelöscht (war vorher vorhanden, jetzt leer)\nif (\n attribute\\fetched('aktennr') != null &&\n aktennr == null\n) {\n syncStatus = 'no_sync';\n}\n// Fall 2: aktennr wird neu gesetzt (war vorher leer, jetzt gefüllt)\nelse if (\n attribute\\fetched('aktennr') == null &&\n aktennr != null\n) {\n syncStatus = 'pending_sync';\n}\n// Fall 3: Dokument hat aktennr und relevante Felder haben sich geändert\nelse if (\n aktennr != null &&\n syncStatus != 'no_sync' &&\n (\n attribute\\isChanged('name') ||\n attribute\\isChanged('description') ||\n attribute\\isChanged('dokumentId') ||\n attribute\\isChanged('blake3hash')\n )\n) {\n syncStatus = 'unclean';\n}\n// Fall 4: Bei neuem Dokument MIT aktennr → pending_sync\nelse if (\n entity\\isNew() &&\n aktennr != null\n) {\n syncStatus = 'pending_sync';\n}\n// Fall 5: Bei neuem Dokument OHNE aktennr → no_sync\nelse if (\n entity\\isNew() &&\n aktennr == null\n) {\n syncStatus = 'no_sync';\n}"
|
||||||
}
|
}
|
||||||
|
|||||||
87
custom/scripts/install_blake3.sh
Executable file
87
custom/scripts/install_blake3.sh
Executable file
@@ -0,0 +1,87 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Blake3 PHP Extension Installation Script
|
||||||
|
# Für EspoCRM Docker Container
|
||||||
|
|
||||||
|
set -e # Beende bei Fehler
|
||||||
|
|
||||||
|
echo "========================================="
|
||||||
|
echo "Blake3 PHP Extension Installation"
|
||||||
|
echo "========================================="
|
||||||
|
|
||||||
|
# Schritt 1: Build-Tools installieren
|
||||||
|
echo ""
|
||||||
|
echo "Schritt 1: Installiere Build-Tools..."
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y \
|
||||||
|
git \
|
||||||
|
build-essential \
|
||||||
|
autoconf \
|
||||||
|
automake \
|
||||||
|
libtool \
|
||||||
|
pkg-config \
|
||||||
|
curl \
|
||||||
|
libcurl4-openssl-dev
|
||||||
|
|
||||||
|
# PHP-Dev ist bereits im Image vorhanden
|
||||||
|
echo "PHP Development headers: $(php-config --version)"
|
||||||
|
|
||||||
|
# Schritt 2: Blake3 C-Bibliothek klonen
|
||||||
|
echo ""
|
||||||
|
echo "Schritt 2: Lade Blake3 C-Bibliothek..."
|
||||||
|
cd /tmp
|
||||||
|
rm -rf BLAKE3 php-blake3
|
||||||
|
git clone https://github.com/BLAKE3-team/BLAKE3.git
|
||||||
|
cd BLAKE3/c
|
||||||
|
gcc -shared -O3 -o libblake3.so blake3.c blake3_dispatch.c blake3_portable.c blake3_sse2_x86-64_unix.S blake3_sse41_x86-64_unix.S blake3_avx2_x86-64_unix.S blake3_avx512_x86-64_unix.S -fPIC
|
||||||
|
cp libblake3.so /usr/local/lib/
|
||||||
|
ldconfig
|
||||||
|
|
||||||
|
# Schritt 3: PHP Blake3 Extension klonen und kompilieren
|
||||||
|
echo ""
|
||||||
|
echo "Schritt 3: Kompiliere PHP Blake3 Extension..."
|
||||||
|
cd /tmp
|
||||||
|
git clone https://github.com/cypherbits/php-blake3.git
|
||||||
|
cd php-blake3
|
||||||
|
|
||||||
|
phpize
|
||||||
|
./configure
|
||||||
|
make
|
||||||
|
make install
|
||||||
|
|
||||||
|
# Schritt 4: Extension aktivieren
|
||||||
|
echo ""
|
||||||
|
echo "Schritt 4: Aktiviere Blake3 Extension..."
|
||||||
|
PHP_INI_DIR=$(php -i | grep "Scan this dir for additional .ini files" | cut -d'>' -f2 | xargs)
|
||||||
|
if [ -z "$PHP_INI_DIR" ]; then
|
||||||
|
PHP_INI_DIR="/usr/local/etc/php/conf.d"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "extension=blake3.so" > ${PHP_INI_DIR}/99-blake3.ini
|
||||||
|
|
||||||
|
# Schritt 5: Verifizierung
|
||||||
|
echo ""
|
||||||
|
echo "Schritt 5: Verifiziere Installation..."
|
||||||
|
php -m | grep -i blake3
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo "✅ Blake3 Extension erfolgreich installiert!"
|
||||||
|
php -r "echo 'Test Hash: ' . hash('blake3', 'test') . PHP_EOL;"
|
||||||
|
else
|
||||||
|
echo "❌ Blake3 Extension nicht geladen!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Cleanup
|
||||||
|
echo ""
|
||||||
|
echo "Schritt 6: Aufräumen..."
|
||||||
|
cd /
|
||||||
|
rm -rf /tmp/BLAKE3 /tmp/php-blake3
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "========================================="
|
||||||
|
echo "✅ Installation abgeschlossen!"
|
||||||
|
echo "========================================="
|
||||||
|
echo ""
|
||||||
|
echo "Nächste Schritte:"
|
||||||
|
echo "1. Starte PHP-FPM neu: service php8.4-fpm restart || pkill -USR2 php-fpm"
|
||||||
|
echo "2. Überprüfe: php -m | grep blake3"
|
||||||
|
echo "3. Teste: php -r \"echo hash('blake3', 'test');\""
|
||||||
@@ -360,7 +360,7 @@ return [
|
|||||||
0 => 'youtube.com',
|
0 => 'youtube.com',
|
||||||
1 => 'google.com'
|
1 => 'google.com'
|
||||||
],
|
],
|
||||||
'microtime' => 1773262547.930204,
|
'microtime' => 1773264000.882682,
|
||||||
'siteUrl' => 'https://crm.bitbylaw.com',
|
'siteUrl' => 'https://crm.bitbylaw.com',
|
||||||
'fullTextSearchMinLength' => 4,
|
'fullTextSearchMinLength' => 4,
|
||||||
'webSocketUrl' => 'ws://api.bitbylaw.com:5000/espocrm/ws',
|
'webSocketUrl' => 'ws://api.bitbylaw.com:5000/espocrm/ws',
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
return [
|
return [
|
||||||
'cacheTimestamp' => 1773262548,
|
'cacheTimestamp' => 1773264001,
|
||||||
'microtimeState' => 1773262548.062426,
|
'microtimeState' => 1773264001.003279,
|
||||||
'currencyRates' => [
|
'currencyRates' => [
|
||||||
'EUR' => 1.0
|
'EUR' => 1.0
|
||||||
],
|
],
|
||||||
|
|||||||
Reference in New Issue
Block a user