settings send test mail frontend
This commit is contained in:
parent
98fcd2822c
commit
964b98c22a
@ -185,6 +185,7 @@ namespace Core\API\Mail {
|
|||||||
$mail->addStringAttachment("Version: 1", null, PHPMailer::ENCODING_BASE64, "application/pgp-encrypted", "");
|
$mail->addStringAttachment("Version: 1", null, PHPMailer::ENCODING_BASE64, "application/pgp-encrypted", "");
|
||||||
$mail->addStringAttachment($encryptedBody, "encrypted.asc", PHPMailer::ENCODING_7BIT, "application/octet-stream", "");
|
$mail->addStringAttachment($encryptedBody, "encrypted.asc", PHPMailer::ENCODING_7BIT, "application/octet-stream", "");
|
||||||
} else {
|
} else {
|
||||||
|
$this->logger->error("Error encrypting with gpg: " . $res["error"]);
|
||||||
return $this->createError($res["error"]);
|
return $this->createError($res["error"]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -237,6 +238,7 @@ namespace Core\API\Mail {
|
|||||||
if ($this->success && is_array($mailQueueItems)) {
|
if ($this->success && is_array($mailQueueItems)) {
|
||||||
if ($debug) {
|
if ($debug) {
|
||||||
echo "Found " . count($mailQueueItems) . " mails to send" . PHP_EOL;
|
echo "Found " . count($mailQueueItems) . " mails to send" . PHP_EOL;
|
||||||
|
$this->logger->debug("Found " . count($mailQueueItems) . " mails to send");
|
||||||
}
|
}
|
||||||
|
|
||||||
$successfulMails = 0;
|
$successfulMails = 0;
|
||||||
@ -249,6 +251,7 @@ namespace Core\API\Mail {
|
|||||||
|
|
||||||
if ($debug) {
|
if ($debug) {
|
||||||
echo "Sending subject=$mailQueueItem->subject to=$mailQueueItem->to" . PHP_EOL;
|
echo "Sending subject=$mailQueueItem->subject to=$mailQueueItem->to" . PHP_EOL;
|
||||||
|
$this->logger->debug("Sending subject=$mailQueueItem->subject to=$mailQueueItem->to");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($mailQueueItem->send($this->context)) {
|
if ($mailQueueItem->send($this->context)) {
|
||||||
@ -257,6 +260,9 @@ namespace Core\API\Mail {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->success = $successfulMails === count($mailQueueItems);
|
$this->success = $successfulMails === count($mailQueueItems);
|
||||||
|
if ($successfulMails > 0) {
|
||||||
|
$this->logger->debug("Sent $successfulMails emails successfully");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->success;
|
return $this->success;
|
||||||
|
@ -117,6 +117,10 @@ namespace Core\API\Settings {
|
|||||||
|
|
||||||
$this->success = ($query->execute() !== FALSE);
|
$this->success = ($query->execute() !== FALSE);
|
||||||
$this->lastError = $sql->getLastError();
|
$this->lastError = $sql->getLastError();
|
||||||
|
|
||||||
|
if ($this->success) {
|
||||||
|
$this->logger->info("The site settings were changed");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->success;
|
return $this->success;
|
||||||
|
@ -183,6 +183,8 @@ namespace Core\API\User {
|
|||||||
|
|
||||||
$groups = [];
|
$groups = [];
|
||||||
$sql = $this->context->getSQL();
|
$sql = $this->context->getSQL();
|
||||||
|
$currentUser = $this->context->getUser();
|
||||||
|
$currentUserId = $currentUser->getId();
|
||||||
|
|
||||||
$requestedGroups = array_unique($this->getParam("groups"));
|
$requestedGroups = array_unique($this->getParam("groups"));
|
||||||
if (!empty($requestedGroups)) {
|
if (!empty($requestedGroups)) {
|
||||||
@ -190,7 +192,7 @@ namespace Core\API\User {
|
|||||||
foreach ($requestedGroups as $groupId) {
|
foreach ($requestedGroups as $groupId) {
|
||||||
if (!isset($availableGroups[$groupId])) {
|
if (!isset($availableGroups[$groupId])) {
|
||||||
return $this->createError("Group with id=$groupId does not exist.");
|
return $this->createError("Group with id=$groupId does not exist.");
|
||||||
} else if ($groupId === Group::ADMIN && !$this->context->getUser()->hasGroup(Group::ADMIN)) {
|
} else if ($groupId === Group::ADMIN && !$currentUser->hasGroup(Group::ADMIN)) {
|
||||||
return $this->createError("You cannot create users with administrator groups.");
|
return $this->createError("You cannot create users with administrator groups.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -202,6 +204,7 @@ namespace Core\API\User {
|
|||||||
if ($user !== false) {
|
if ($user !== false) {
|
||||||
$this->user = $user;
|
$this->user = $user;
|
||||||
$this->result["userId"] = $user->getId();
|
$this->result["userId"] = $user->getId();
|
||||||
|
$this->logger->info("A new user with username='$username' and email='$email' was created by userId='$currentUserId'");
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->success;
|
return $this->success;
|
||||||
@ -423,6 +426,9 @@ namespace Core\API\User {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$currentUserId = $this->context->getUser()->getId();
|
||||||
|
$this->logger->info("A new user with username='$username' and email='$email' was invited by userId='$currentUserId'");
|
||||||
|
|
||||||
// Create Token
|
// Create Token
|
||||||
$token = generateRandomString(36);
|
$token = generateRandomString(36);
|
||||||
$validDays = 7;
|
$validDays = 7;
|
||||||
@ -724,6 +730,8 @@ namespace Core\API\User {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->logger->info("A new user with username='$username' and email='$email' was created");
|
||||||
|
|
||||||
$validHours = 48;
|
$validHours = 48;
|
||||||
$token = generateRandomString(36);
|
$token = generateRandomString(36);
|
||||||
$userToken = new UserToken($user, $token, UserToken::TYPE_EMAIL_CONFIRM, $validHours);
|
$userToken = new UserToken($user, $token, UserToken::TYPE_EMAIL_CONFIRM, $validHours);
|
||||||
@ -756,12 +764,12 @@ namespace Core\API\User {
|
|||||||
$this->lastError = $request->getLastError();
|
$this->lastError = $request->getLastError();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$this->lastError = "Could create user token: " . $sql->getLastError();
|
$this->lastError = "Could not create user token: " . $sql->getLastError();
|
||||||
$this->success = false;
|
$this->success = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$this->success) {
|
if (!$this->success) {
|
||||||
$this->logger->error("Could not deliver email to=$email type=register reason=" . $this->lastError);
|
$this->logger->error("Could not deliver email to='$email' type='register' reason='" . $this->lastError . "'");
|
||||||
$this->lastError = "Your account was registered but the confirmation email could not be sent. " .
|
$this->lastError = "Your account was registered but the confirmation email could not be sent. " .
|
||||||
"Please contact the server administration. This issue has been automatically logged. Reason: " . $this->lastError;
|
"Please contact the server administration. This issue has been automatically logged. Reason: " . $this->lastError;
|
||||||
}
|
}
|
||||||
@ -1007,7 +1015,7 @@ namespace Core\API\User {
|
|||||||
"gpgFingerprint" => $gpgFingerprint
|
"gpgFingerprint" => $gpgFingerprint
|
||||||
));
|
));
|
||||||
$this->lastError = $request->getLastError();
|
$this->lastError = $request->getLastError();
|
||||||
$this->logger->info("Requested password reset for user id=" . $user->getId() . " by ip_address=" . $_SERVER["REMOTE_ADDR"]);
|
$this->logger->info("Requested password reset for user id='" . $user->getId() . "' by ip_address='" . $_SERVER["REMOTE_ADDR"] . "'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -159,7 +159,8 @@ class Settings {
|
|||||||
->addRow("mail_password", "", true, false)
|
->addRow("mail_password", "", true, false)
|
||||||
->addRow("mail_from", "", false, false)
|
->addRow("mail_from", "", false, false)
|
||||||
->addRow("mail_last_sync", "", false, false)
|
->addRow("mail_last_sync", "", false, false)
|
||||||
->addRow("mail_footer", "", false, false);
|
->addRow("mail_footer", "", false, false)
|
||||||
|
->addRow("mail_async", false, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSiteName(): string {
|
public function getSiteName(): string {
|
||||||
|
@ -50,6 +50,8 @@ return [
|
|||||||
"info" => "Info",
|
"info" => "Info",
|
||||||
"reload" => "Aktualisieren",
|
"reload" => "Aktualisieren",
|
||||||
"success" => "Erfolg",
|
"success" => "Erfolg",
|
||||||
|
"send" => "Senden",
|
||||||
|
"sending" => "Sende ab",
|
||||||
|
|
||||||
# file
|
# file
|
||||||
"choose_file" => "Datei auswählen",
|
"choose_file" => "Datei auswählen",
|
||||||
|
@ -47,6 +47,9 @@ return [
|
|||||||
"mail_username" => "Mail-Server Benutzername",
|
"mail_username" => "Mail-Server Benutzername",
|
||||||
"mail_password" => "Mail-Server Passwort",
|
"mail_password" => "Mail-Server Passwort",
|
||||||
"mail_footer" => "Pfad zum E-Mail-Footer",
|
"mail_footer" => "Pfad zum E-Mail-Footer",
|
||||||
|
"mail_async" => "E-Mails asynchron senden (erfordert einen Cron-Job)",
|
||||||
|
"mail_address" => "E-Mail Adresse",
|
||||||
|
"send_test_email" => "Test E-Mail senden",
|
||||||
|
|
||||||
# recaptcha
|
# recaptcha
|
||||||
"recaptcha_enabled" => "Aktiviere Google reCaptcha",
|
"recaptcha_enabled" => "Aktiviere Google reCaptcha",
|
||||||
@ -57,4 +60,6 @@ return [
|
|||||||
"fetch_settings_error" => "Fehler beim Holen der Einstellungen",
|
"fetch_settings_error" => "Fehler beim Holen der Einstellungen",
|
||||||
"save_settings_success" => "Einstellungen erfolgreich gespeichert",
|
"save_settings_success" => "Einstellungen erfolgreich gespeichert",
|
||||||
"save_settings_error" => "Fehler beim Speichern der Einstellungen",
|
"save_settings_error" => "Fehler beim Speichern der Einstellungen",
|
||||||
|
"send_test_email_error" => "Fehler beim Senden der Test E-Mail",
|
||||||
|
"send_test_email_success" => "Test E-Mail erfolgreich versendet, überprüfen Sie Ihren Posteingang!",
|
||||||
];
|
];
|
@ -48,6 +48,8 @@ return [
|
|||||||
"info" => "Info",
|
"info" => "Info",
|
||||||
"reload" => "Reload",
|
"reload" => "Reload",
|
||||||
"success" => "Success",
|
"success" => "Success",
|
||||||
|
"send" => "Send",
|
||||||
|
"sending" => "Sending",
|
||||||
|
|
||||||
# file
|
# file
|
||||||
"choose_file" => "Choose File",
|
"choose_file" => "Choose File",
|
||||||
|
@ -47,6 +47,9 @@ return [
|
|||||||
"mail_username" => "Mail server username",
|
"mail_username" => "Mail server username",
|
||||||
"mail_password" => "Mail server password",
|
"mail_password" => "Mail server password",
|
||||||
"mail_footer" => "Path to e-mail footer",
|
"mail_footer" => "Path to e-mail footer",
|
||||||
|
"mail_async" => "Send e-mails asynchronously (requires a cron-job)",
|
||||||
|
"mail_address" => "Mail address",
|
||||||
|
"send_test_email" => "Send test e-mail",
|
||||||
|
|
||||||
# recaptcha
|
# recaptcha
|
||||||
"recaptcha_enabled" => "Enable Google reCaptcha",
|
"recaptcha_enabled" => "Enable Google reCaptcha",
|
||||||
@ -57,4 +60,6 @@ return [
|
|||||||
"fetch_settings_error" => "Error fetching settings",
|
"fetch_settings_error" => "Error fetching settings",
|
||||||
"save_settings_success" => "Settings saved successfully",
|
"save_settings_success" => "Settings saved successfully",
|
||||||
"save_settings_error" => "Error saving settings",
|
"save_settings_error" => "Error saving settings",
|
||||||
|
"send_test_email_error" => "Error sending test email",
|
||||||
|
"send_test_email_success" => "Test email successfully sent. Please check your inbox!",
|
||||||
];
|
];
|
@ -3,7 +3,7 @@ import {LocaleContext} from "shared/locale";
|
|||||||
import {
|
import {
|
||||||
Box, Button, Checkbox,
|
Box, Button, Checkbox,
|
||||||
CircularProgress, FormControl, FormControlLabel,
|
CircularProgress, FormControl, FormControlLabel,
|
||||||
FormGroup, FormLabel, IconButton,
|
FormGroup, FormLabel, Grid, IconButton,
|
||||||
Paper, Select, styled,
|
Paper, Select, styled,
|
||||||
Tab,
|
Tab,
|
||||||
Table,
|
Table,
|
||||||
@ -14,7 +14,17 @@ import {
|
|||||||
Tabs, TextField
|
Tabs, TextField
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import {Link} from "react-router-dom";
|
import {Link} from "react-router-dom";
|
||||||
import {Add, Delete, Google, LibraryBooks, Mail, RestartAlt, Save, SettingsApplications} from "@mui/icons-material";
|
import {
|
||||||
|
Add,
|
||||||
|
Delete,
|
||||||
|
Google,
|
||||||
|
LibraryBooks,
|
||||||
|
Mail,
|
||||||
|
RestartAlt,
|
||||||
|
Save,
|
||||||
|
Send,
|
||||||
|
SettingsApplications
|
||||||
|
} from "@mui/icons-material";
|
||||||
import {TableContainer} from "@material-ui/core";
|
import {TableContainer} from "@material-ui/core";
|
||||||
import TIME_ZONES from "shared/time-zones";
|
import TIME_ZONES from "shared/time-zones";
|
||||||
|
|
||||||
@ -50,6 +60,7 @@ export default function SettingsView(props) {
|
|||||||
"mail_port",
|
"mail_port",
|
||||||
"mail_username",
|
"mail_username",
|
||||||
"mail_password",
|
"mail_password",
|
||||||
|
"mail_async",
|
||||||
],
|
],
|
||||||
"recaptcha": [
|
"recaptcha": [
|
||||||
"recaptcha_enabled",
|
"recaptcha_enabled",
|
||||||
@ -69,6 +80,8 @@ export default function SettingsView(props) {
|
|||||||
const [hasChanged, setChanged] = useState(false);
|
const [hasChanged, setChanged] = useState(false);
|
||||||
const [isSaving, setSaving] = useState(false);
|
const [isSaving, setSaving] = useState(false);
|
||||||
const [newKey, setNewKey] = useState("");
|
const [newKey, setNewKey] = useState("");
|
||||||
|
const [testMailAddress, setTestMailAddress] = useState("");
|
||||||
|
const [isSending, setSending] = useState(false);
|
||||||
|
|
||||||
const isUncategorized = (key) => {
|
const isUncategorized = (key) => {
|
||||||
return !(Object.values(KNOWN_SETTING_KEYS).reduce((acc, arr) => {
|
return !(Object.values(KNOWN_SETTING_KEYS).reduce((acc, arr) => {
|
||||||
@ -161,11 +174,26 @@ export default function SettingsView(props) {
|
|||||||
}
|
}
|
||||||
}, [settings]);
|
}, [settings]);
|
||||||
|
|
||||||
|
const onSendTestMail = useCallback(() => {
|
||||||
|
if (!isSending) {
|
||||||
|
setSending(true);
|
||||||
|
api.sendTestMail(testMailAddress).then(data => {
|
||||||
|
setSending(false);
|
||||||
|
if (!data.success) {
|
||||||
|
showDialog(data.msg, L("settings.send_test_email_error"));
|
||||||
|
} else {
|
||||||
|
showDialog(L("settings.send_test_email_success"), L("general.success"));
|
||||||
|
setTestMailAddress("");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [api, showDialog, testMailAddress, isSending]);
|
||||||
|
|
||||||
if (settings === null) {
|
if (settings === null) {
|
||||||
return <CircularProgress />
|
return <CircularProgress />
|
||||||
}
|
}
|
||||||
|
|
||||||
const parseBool = (v) => v === true || v === 1 || ["true", "1", "yes"].includes(v.toString().toLowerCase());
|
const parseBool = (v) => v !== undefined && (v === true || v === 1 || ["true", "1", "yes"].includes(v.toString().toLowerCase()));
|
||||||
|
|
||||||
const renderTextInput = (key_name, disabled=false, props={}) => {
|
const renderTextInput = (key_name, disabled=false, props={}) => {
|
||||||
return <SettingsFormGroup key={"form-" + key_name} {...props}>
|
return <SettingsFormGroup key={"form-" + key_name} {...props}>
|
||||||
@ -254,6 +282,30 @@ export default function SettingsView(props) {
|
|||||||
renderTextInput("mail_username", !parseBool(settings.mail_enabled)),
|
renderTextInput("mail_username", !parseBool(settings.mail_enabled)),
|
||||||
renderPasswordInput("mail_password", !parseBool(settings.mail_enabled)),
|
renderPasswordInput("mail_password", !parseBool(settings.mail_enabled)),
|
||||||
renderTextInput("mail_footer", !parseBool(settings.mail_enabled)),
|
renderTextInput("mail_footer", !parseBool(settings.mail_enabled)),
|
||||||
|
renderCheckBox("mail_async", !parseBool(settings.mail_enabled)),
|
||||||
|
<FormGroup key={"mail-test"}>
|
||||||
|
<FormLabel>{L("settings.send_test_email")}</FormLabel>
|
||||||
|
<FormControl disabled={!parseBool(settings.mail_enabled)}>
|
||||||
|
<Grid container spacing={1}>
|
||||||
|
<Grid item xs={1}>
|
||||||
|
<Button startIcon={isSending ? <CircularProgress size={14} /> : <Send />}
|
||||||
|
variant={"outlined"} onClick={onSendTestMail}
|
||||||
|
fullWidth={true}
|
||||||
|
disabled={!parseBool(settings.mail_enabled) || isSending || !api.hasPermission("mail/test")}>
|
||||||
|
{isSending ? L("general.sending") + "…" : L("general.send")}
|
||||||
|
</Button>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={11}>
|
||||||
|
<TextField disabled={!parseBool(settings.mail_enabled)}
|
||||||
|
fullWidth={true}
|
||||||
|
variant={"outlined"} value={testMailAddress}
|
||||||
|
onChange={e => setTestMailAddress(e.target.value)}
|
||||||
|
size={"small"} type={"email"}
|
||||||
|
placeholder={L("settings.mail_address")} />
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</FormControl>
|
||||||
|
</FormGroup>
|
||||||
];
|
];
|
||||||
} else if (selectedTab === "recaptcha") {
|
} else if (selectedTab === "recaptcha") {
|
||||||
return [
|
return [
|
||||||
@ -348,7 +400,7 @@ export default function SettingsView(props) {
|
|||||||
<ButtonBar>
|
<ButtonBar>
|
||||||
<Button color={"primary"}
|
<Button color={"primary"}
|
||||||
onClick={onSaveSettings}
|
onClick={onSaveSettings}
|
||||||
disabled={isSaving}
|
disabled={isSaving || !api.hasPermission("settings/set")}
|
||||||
startIcon={isSaving ? <CircularProgress size={14} /> : <Save />}
|
startIcon={isSaving ? <CircularProgress size={14} /> : <Save />}
|
||||||
variant={"outlined"} title={L(hasChanged ? "general.unsaved_changes" : "general.save")}>
|
variant={"outlined"} title={L(hasChanged ? "general.unsaved_changes" : "general.save")}>
|
||||||
{isSaving ? L("general.saving") + "…" : (L("general.save") + (hasChanged ? " *" : ""))}
|
{isSaving ? L("general.saving") + "…" : (L("general.save") + (hasChanged ? " *" : ""))}
|
||||||
|
Loading…
Reference in New Issue
Block a user