bugfix, profile picture WIP, profile frontend refactored
This commit is contained in:
@@ -18,11 +18,7 @@ namespace Core\API {
|
||||
}
|
||||
|
||||
protected function verifyAuthData(AuthenticationData $authData): bool {
|
||||
$settings = $this->context->getSettings();
|
||||
// $relyingParty = $settings->getSiteName();
|
||||
$domain = parse_url($settings->getBaseUrl(), PHP_URL_HOST);
|
||||
// $domain = "localhost";
|
||||
|
||||
$domain = getCurrentHostName();
|
||||
if (!$authData->verifyIntegrity($domain)) {
|
||||
return $this->createError("mismatched rpIDHash. expected: " . hash("sha256", $domain) . " got: " . bin2hex($authData->getHash()));
|
||||
} else if (!$authData->isUserPresent()) {
|
||||
@@ -264,7 +260,7 @@ namespace Core\API\TFA {
|
||||
$settings = $this->context->getSettings();
|
||||
$relyingParty = $settings->getSiteName();
|
||||
$sql = $this->context->getSQL();
|
||||
$domain = parse_url($settings->getBaseUrl(), PHP_URL_HOST);
|
||||
$domain = getCurrentHostName();
|
||||
|
||||
if (!$clientDataJSON || !$attestationObjectRaw) {
|
||||
$challenge = null;
|
||||
@@ -297,7 +293,6 @@ namespace Core\API\TFA {
|
||||
|
||||
$this->result["data"] = [
|
||||
"challenge" => $challenge,
|
||||
"id" => $currentUser->getId() . "@" . $domain, // <userId>@<domain>
|
||||
"relyingParty" => [
|
||||
"name" => $relyingParty,
|
||||
"id" => $domain
|
||||
|
||||
@@ -192,7 +192,7 @@ namespace Core\API\User {
|
||||
foreach ($requestedGroups as $groupId) {
|
||||
if (!isset($availableGroups[$groupId])) {
|
||||
return $this->createError("Group with id=$groupId does not exist.");
|
||||
} else if ($this->externalCall && $groupId === Group::ADMIN && !$currentUser->hasGroup(Group::ADMIN)) {
|
||||
} else if ($this->isExternalCall() && $groupId === Group::ADMIN && !$currentUser->hasGroup(Group::ADMIN)) {
|
||||
return $this->createError("You cannot create users with administrator groups.");
|
||||
} else {
|
||||
$groups[] = $groupId;
|
||||
@@ -1311,38 +1311,43 @@ namespace Core\API\User {
|
||||
return $this->createError("Error saving user token: " . $sql->getLastError());
|
||||
}
|
||||
|
||||
$name = htmlspecialchars($currentUser->getFullName());
|
||||
if (!$name) {
|
||||
$name = htmlspecialchars($currentUser->getUsername());
|
||||
}
|
||||
|
||||
$validHours = 1;
|
||||
$settings = $this->context->getSettings();
|
||||
$siteName = htmlspecialchars($settings->getSiteName());
|
||||
$baseUrl = htmlspecialchars($settings->getBaseUrl());
|
||||
$token = htmlspecialchars(urlencode($token));
|
||||
$url = "$baseUrl/confirmGPG?token=$token";
|
||||
$mailBody = "Hello $name,<br><br>" .
|
||||
"you imported a GPG public key for end-to-end encrypted mail communication. " .
|
||||
"To confirm the key and verify, you own the corresponding private key, please click on the following link. " .
|
||||
"The link is active for one hour.<br><br>" .
|
||||
"<a href='$url'>$url</a><br>Best Regards<br>$siteName Administration";
|
||||
$baseUrl = $settings->getBaseUrl();
|
||||
$siteName = $settings->getSiteName();
|
||||
$req = new Render($this->context);
|
||||
$this->success = $req->execute([
|
||||
"file" => "mail/gpg_import.twig",
|
||||
"parameters" => [
|
||||
"link" => "$baseUrl/resetPassword?token=$token",
|
||||
"site_name" => $siteName,
|
||||
"base_url" => $baseUrl,
|
||||
"username" => $currentUser->getDisplayName(),
|
||||
"valid_time" => $this->formatDuration($validHours, "hour")
|
||||
]
|
||||
]);
|
||||
|
||||
$sendMail = new \Core\API\Mail\Send($this->context);
|
||||
$this->success = $sendMail->execute(array(
|
||||
"to" => $currentUser->getEmail(),
|
||||
"subject" => "[$siteName] Confirm GPG-Key",
|
||||
"body" => $mailBody,
|
||||
"gpgFingerprint" => $gpgKey->getFingerprint()
|
||||
));
|
||||
|
||||
$this->lastError = $sendMail->getLastError();
|
||||
$this->lastError = $req->getLastError();
|
||||
|
||||
if ($this->success) {
|
||||
$currentUser->gpgKey = $gpgKey;
|
||||
if ($currentUser->save($sql, ["gpgKey"])) {
|
||||
$this->result["gpgKey"] = $gpgKey->jsonSerialize();
|
||||
} else {
|
||||
return $this->createError("Error updating user details: " . $sql->getLastError());
|
||||
$messageBody = $req->getResult()["html"];
|
||||
$sendMail = new \Core\API\Mail\Send($this->context);
|
||||
$this->success = $sendMail->execute(array(
|
||||
"to" => $currentUser->getEmail(),
|
||||
"subject" => "[$siteName] Confirm GPG-Key",
|
||||
"body" => $messageBody,
|
||||
"gpgFingerprint" => $gpgKey->getFingerprint()
|
||||
));
|
||||
|
||||
$this->lastError = $sendMail->getLastError();
|
||||
|
||||
if ($this->success) {
|
||||
$currentUser->gpgKey = $gpgKey;
|
||||
if ($currentUser->save($sql, ["gpgKey"])) {
|
||||
$this->result["gpgKey"] = $gpgKey->jsonSerialize();
|
||||
} else {
|
||||
return $this->createError("Error updating user details: " . $sql->getLastError());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1505,6 +1510,7 @@ namespace Core\API\User {
|
||||
|
||||
class UploadPicture extends UserAPI {
|
||||
public function __construct(Context $context, bool $externalCall = false) {
|
||||
// TODO: we should optimize the process here, we need an offset and size parameter to get a quadratic crop of the uploaded image
|
||||
parent::__construct($context, $externalCall, [
|
||||
"scale" => new Parameter("scale", Parameter::TYPE_FLOAT, true, NULL),
|
||||
]);
|
||||
@@ -1515,7 +1521,7 @@ namespace Core\API\User {
|
||||
/**
|
||||
* @throws ImagickException
|
||||
*/
|
||||
protected function onTransform(\Imagick $im, $uploadDir) {
|
||||
protected function onTransform(\Imagick $im, $uploadDir): bool|string {
|
||||
|
||||
$minSize = 75;
|
||||
$maxSize = 500;
|
||||
|
||||
@@ -52,22 +52,28 @@ class MySQL extends SQL {
|
||||
return true;
|
||||
}
|
||||
|
||||
$this->connection = @mysqli_connect(
|
||||
$this->connectionData->getHost(),
|
||||
$this->connectionData->getLogin(),
|
||||
$this->connectionData->getPassword(),
|
||||
$this->connectionData->getProperty('database'),
|
||||
$this->connectionData->getPort()
|
||||
);
|
||||
try {
|
||||
$this->connection = @mysqli_connect(
|
||||
$this->connectionData->getHost(),
|
||||
$this->connectionData->getLogin(),
|
||||
$this->connectionData->getPassword(),
|
||||
$this->connectionData->getProperty('database'),
|
||||
$this->connectionData->getPort()
|
||||
);
|
||||
|
||||
if (mysqli_connect_errno()) {
|
||||
if (mysqli_connect_errno()) {
|
||||
$this->lastError = $this->logger->severe("Failed to connect to MySQL: " . mysqli_connect_error());
|
||||
$this->connection = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
mysqli_set_charset($this->connection, $this->connectionData->getProperty('encoding', 'UTF8'));
|
||||
return true;
|
||||
} catch (\Exception $ex) {
|
||||
$this->lastError = $this->logger->severe("Failed to connect to MySQL: " . mysqli_connect_error());
|
||||
$this->connection = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
mysqli_set_charset($this->connection, $this->connectionData->getProperty('encoding', 'UTF8'));
|
||||
return true;
|
||||
}
|
||||
|
||||
public function disconnect() {
|
||||
|
||||
@@ -26,33 +26,18 @@ return [
|
||||
"username" => "Benutzername",
|
||||
"username_or_email" => "Benutzername oder E-Mail",
|
||||
"email" => "E-Mail Adresse",
|
||||
"password" => "Passwort",
|
||||
"password_confirm" => "Passwort bestätigen",
|
||||
"password_old" => "Altes Passwort",
|
||||
"password_new" => "Neues Passwort",
|
||||
"full_name" => "Voller Name",
|
||||
"remember_me" => "Eingeloggt bleiben",
|
||||
"signing_in" => "Einloggen",
|
||||
"sign_in" => "Einloggen",
|
||||
"confirmed" => "Bestätigt",
|
||||
"forgot_password" => "Passwort vergessen?",
|
||||
"change_password" => "Passwort ändern",
|
||||
"passwords_do_not_match" => "Die Passwörter stimmen nicht überein",
|
||||
"back_to_login" => "Zurück zum Login",
|
||||
"register_text" => "Noch keinen Account? Jetzt registrieren",
|
||||
"6_digit_code" => "6-stelliger Code",
|
||||
"2fa_title" => "Es werden weitere Informationen zum Einloggen benötigt",
|
||||
"2fa_text" => "Stecke dein 2FA-Gerät ein. Möglicherweise wird noch eine Interaktion benötigt, z.B. durch Eingabe einer PIN oder durch Berühren des Geräts",
|
||||
"confirming_email" => "Bestätige E-Mail Adresse",
|
||||
"proceed_to_login" => "Weiter zum Login",
|
||||
"invalid_link" => "Den Link den Sie besucht haben ist nicht länger gültig",
|
||||
"confirm_success" => "Ihre E-Mail Adresse wurde erfolgreich bestätigt, Sie können sich jetzt einloggen",
|
||||
"confirm_error" => "Fehler beim Bestätigen der E-Mail Adresse",
|
||||
"gpg_key" => "GPG-Schlüssel",
|
||||
"no_gpg_key_added" => "Kein GPG-Schlüssel hinzugefügt",
|
||||
"download_gpg_key" => "GPG-Schlüssel herunterladen",
|
||||
"2fa_token" => "Zwei-Faktor Authentifizierung (2FA)",
|
||||
"profile_picture_of" => "Profilbild von",
|
||||
"profile_of" => "Profil von",
|
||||
"language" => "Sprache",
|
||||
"profile" => "Benutzerprofil",
|
||||
@@ -71,6 +56,10 @@ return [
|
||||
"group" => "Gruppe",
|
||||
"no_members" => "Keine Mitglieder in dieser Gruppe",
|
||||
|
||||
# profile picture
|
||||
"change_picture" => "Profilbild ändern",
|
||||
"profile_picture_of" => "Profilbild von",
|
||||
|
||||
# dialogs
|
||||
"fetch_group_members_error" => "Fehler beim Holen der Gruppenmitglieder",
|
||||
"remove_group_member_error" => "Fehler beim Entfernen des Gruppenmitglieds",
|
||||
@@ -85,11 +74,18 @@ return [
|
||||
"remove_group_member_text" => "Möchten Sie wirklich den Benutzer '%s' von dieser Gruppe entfernen?",
|
||||
"add_group_member_title" => "Mitglied hinzufügen",
|
||||
"add_group_member_text" => "Einen Benutzer suchen um ihn der Gruppe hinzuzufügen",
|
||||
"edit_profile" => "Profil bearbeiten",
|
||||
|
||||
# GPG Key
|
||||
"gpg_key_placeholder_text" => "GPG-Key im ASCII format reinziehen oder einfügen...",
|
||||
"gpg_key" => "GPG-Schlüssel",
|
||||
"no_gpg_key_added" => "Kein GPG-Schlüssel hinzugefügt",
|
||||
"download_gpg_key" => "GPG-Schlüssel herunterladen",
|
||||
|
||||
# 2fa
|
||||
"2fa_title" => "Es werden weitere Informationen zum Einloggen benötigt",
|
||||
"2fa_text" => "Stecke dein 2FA-Gerät ein. Möglicherweise wird noch eine Interaktion benötigt, z.B. durch Eingabe einer PIN oder durch Berühren des Geräts",
|
||||
"2fa_token" => "Zwei-Faktor Authentifizierung (2FA)",
|
||||
"2fa_type_totp" => "Zeitbasiertes 2FA (TOTP)",
|
||||
"2fa_type_fido" => "Schlüsselbasiertes 2FA",
|
||||
"register_2fa_device" => "Ein 2FA-Gerät registrieren",
|
||||
@@ -98,4 +94,19 @@ return [
|
||||
"register_2fa_fido_text" => "Möglicherweise musst du mit dem Gerät interagieren, zum Beispiel durch Eingeben einer PIN oder durch Berühren des Geräts",
|
||||
"remove_2fa" => "2FA-Token entfernen",
|
||||
"remove_2fa_text" => "Gib dein aktuelles Passwort ein um das Entfernen des 2FA-Tokens zu bestätigen",
|
||||
"6_digit_code" => "6-stelliger Code",
|
||||
|
||||
# password
|
||||
"password" => "Passwort",
|
||||
"password_confirm" => "Passwort bestätigen",
|
||||
"password_old" => "Altes Passwort",
|
||||
"password_new" => "Neues Passwort",
|
||||
"forgot_password" => "Passwort vergessen?",
|
||||
"change_password" => "Passwort ändern",
|
||||
"passwords_do_not_match" => "Die Passwörter stimmen nicht überein",
|
||||
"password_very_strong" => "Sehr stark",
|
||||
"password_strong" => "Stark",
|
||||
"password_ok" => "OK",
|
||||
"password_weak" => "Schwach",
|
||||
"password_very_weak" => "Sehr schwach",
|
||||
];
|
||||
@@ -26,33 +26,19 @@ return [
|
||||
"username" => "Username",
|
||||
"username_or_email" => "Username or E-Mail",
|
||||
"email" => "E-Mail Address",
|
||||
"password" => "Password",
|
||||
"password_confirm" => "Confirm Password",
|
||||
"password_old" => "Old Password",
|
||||
"password_new" => "New Password",
|
||||
"full_name" => "Full Name",
|
||||
"remember_me" => "Remember Me",
|
||||
"signing_in" => "Signing in",
|
||||
"sign_in" => "Sign In",
|
||||
"confirmed" => "Confirmed",
|
||||
"forgot_password" => "Forgot password?",
|
||||
"change_password" => "Change password",
|
||||
"register_text" => "Don't have an account? Sign Up",
|
||||
"passwords_do_not_match" => "Your passwords did not match",
|
||||
"back_to_login" => "Back to Login",
|
||||
"6_digit_code" => "6-Digit Code",
|
||||
"2fa_title" => "Additional information is required for logging in",
|
||||
"2fa_text" => "Plugin your 2FA-Device. Interaction might be required, e.g. typing in a PIN or touching it.",
|
||||
"confirming_email" => "Confirming email",
|
||||
"proceed_to_login" => "Proceed to Login",
|
||||
"invalid_link" => "The link you visited is no longer valid",
|
||||
"confirm_success" => "Your e-mail address was successfully confirmed, you may now log in",
|
||||
"confirm_error" => "Error confirming e-mail address",
|
||||
"gpg_key" => "GPG Key",
|
||||
"no_gpg_key_added" => "No GPG key added",
|
||||
"download_gpg_key" => "Download GPG Key",
|
||||
"2fa_token" => "Two-Factor Authentication (2FA)",
|
||||
"profile_picture_of" => "Profile Picture of",
|
||||
"profile_of" => "Profile of",
|
||||
"language" => "Language",
|
||||
"profile" => "User Profile",
|
||||
@@ -70,6 +56,11 @@ return [
|
||||
"active" => "Active",
|
||||
"group" => "Group",
|
||||
"no_members" => "No members in this group",
|
||||
"edit_profile" => "Edit Profile",
|
||||
|
||||
# profile picture
|
||||
"change_picture" => "Change profile picture",
|
||||
"profile_picture_of" => "Profile Picture of",
|
||||
|
||||
# dialogs
|
||||
"fetch_group_members_error" => "Error fetching group members",
|
||||
@@ -87,9 +78,15 @@ return [
|
||||
"add_group_member_text" => "Search a user to add to the group",
|
||||
|
||||
# GPG Key
|
||||
"gpg_key" => "GPG Key",
|
||||
"no_gpg_key_added" => "No GPG key added",
|
||||
"download_gpg_key" => "Download GPG Key",
|
||||
"gpg_key_placeholder_text" => "Paste or drag'n'drop your GPG-Key in ASCII format...",
|
||||
|
||||
# 2fa
|
||||
"2fa_title" => "Additional information is required for logging in",
|
||||
"2fa_text" => "Plugin your 2FA-Device. Interaction might be required, e.g. typing in a PIN or touching it.",
|
||||
"2fa_token" => "Two-Factor Authentication (2FA)",
|
||||
"2fa_type_totp" => "Time-Based 2FA (TOTP)",
|
||||
"2fa_type_fido" => "Key-Based 2FA",
|
||||
"register_2fa_device" => "Register a 2FA-Device",
|
||||
@@ -98,4 +95,18 @@ return [
|
||||
"register_2fa_fido_text" => "You may need to interact with your Device, e.g. typing in your PIN or touching to confirm the registration.",
|
||||
"remove_2fa" => "Remove 2FA Token",
|
||||
"remove_2fa_text" => "Enter your current password to confirm the removal of your 2FA Token",
|
||||
"6_digit_code" => "6-Digit Code",
|
||||
|
||||
# password
|
||||
"password" => "Password",
|
||||
"password_confirm" => "Confirm Password",
|
||||
"password_old" => "Old Password",
|
||||
"password_new" => "New Password",
|
||||
"forgot_password" => "Forgot password?",
|
||||
"change_password" => "Change password",
|
||||
"password_very_strong" => "Very strong",
|
||||
"password_strong" => "Strong",
|
||||
"password_ok" => "OK",
|
||||
"password_weak" => "Weak",
|
||||
"password_very_weak" => "Very weak",
|
||||
];
|
||||
@@ -4,6 +4,7 @@ namespace Core\Objects;
|
||||
|
||||
use Core\Configuration\Configuration;
|
||||
use Core\Configuration\Settings;
|
||||
use Core\Driver\SQL\Column\Column;
|
||||
use Core\Driver\SQL\Condition\Compare;
|
||||
use Core\Driver\SQL\Condition\CondLike;
|
||||
use Core\Driver\SQL\Condition\CondOr;
|
||||
@@ -125,9 +126,9 @@ class Context {
|
||||
if ($this->sql) {
|
||||
$language = Language::findBy(Language::createBuilder($this->sql, true)
|
||||
->where(new CondOr(
|
||||
new CondLike("name", "%$lang%"), // english
|
||||
new CondLike(new Column("name"), "%$lang%"), // english
|
||||
new Compare("code", $lang), // de_DE
|
||||
new CondLike("code", "{$lang}_%") // de -> de_%
|
||||
new CondLike(new Column("code"), "{$lang}_%") // de -> de_%
|
||||
))
|
||||
);
|
||||
if ($language) {
|
||||
|
||||
@@ -38,8 +38,9 @@ class AuthenticationData extends ApiObject {
|
||||
$credentialIdLength = unpack("n", substr($buffer, $offset, 4))[1]; $offset += 2;
|
||||
$this->credentialID = substr($buffer, $offset, $credentialIdLength); $offset += $credentialIdLength;
|
||||
|
||||
if ($offset < $bufferLength) {
|
||||
if ($bufferLength > $offset) {
|
||||
$publicKeyData = $this->decode(substr($buffer, $offset));
|
||||
var_dump($publicKeyData);
|
||||
$this->publicKey = new PublicKey($publicKeyData);
|
||||
// TODO: we should add $publicKeyData->length to $offset, but it's not implemented yet?;
|
||||
}
|
||||
|
||||
9
Core/Templates/mail/gpg_import.twig
Normal file
9
Core/Templates/mail/gpg_import.twig
Normal file
@@ -0,0 +1,9 @@
|
||||
Hello {{ username }},<br>
|
||||
you imported a GPG public key for end-to-end encrypted mail communication on {{ site_name }}. <br>
|
||||
To confirm the key and verify, you own the corresponding private key, please click on the following link.
|
||||
The link is active for one hour:<br><br>
|
||||
|
||||
<a href="{{ link }}">{{ link }}</a><br><br>
|
||||
|
||||
Best Regards<br>
|
||||
{{ site_name }} Administration
|
||||
Reference in New Issue
Block a user