From 4248de1d7d9b8e5b192617ba5fda7ede00be19c7 Mon Sep 17 00:00:00 2001 From: Jeppe Bundgaard Date: Mon, 16 Feb 2026 14:55:01 +0100 Subject: [PATCH] Add password reset link generation and welcome email functionality - Introduce `generatePasswordResetLink` method in `users_o` for creating secure password reset links. - Add `sendWelcomeEmailToCustomer` method to `email` class with support for attachments. - Update `authRoute.php` to send welcome emails when creating new customers. - Extend `sendEmail` to handle optional attachments and references. - Disable PHP entrypoint in Dockerfile for improved flexibility. --- services/nginx/app/classes/email.php | 48 +++++++++++++++++++++++-- services/nginx/app/objects/users_o.php | 24 +++++++++++++ services/nginx/app/routes/authRoute.php | 4 ++- services/php/Dockerfile | 6 ++-- 4 files changed, 75 insertions(+), 7 deletions(-) diff --git a/services/nginx/app/classes/email.php b/services/nginx/app/classes/email.php index 45fea45e..5dba470f 100644 --- a/services/nginx/app/classes/email.php +++ b/services/nginx/app/classes/email.php @@ -11,6 +11,7 @@ require_once WD . '/modules/email/templates/email_template_booking_confirmation. require_once WD . '/modules/email/templates/email_template_booking_notification.php'; require_once WD . '/modules/email/templates/email_template_wash_certificate.php'; +use AllowDynamicProperties; use email\email_c; use email\templates\email_template_booking_confirmation; use email\templates\email_template_booking_notification; @@ -34,7 +35,7 @@ use objects\departments_o; use objects\users_o; use Psr\Http\Client\ClientExceptionInterface; -class email implements email_i +#[AllowDynamicProperties] class email implements email_i { /** * Configuration for the email service @@ -68,9 +69,11 @@ class email implements email_i * @param string $recipient_name Name of the recipient * @param string $subject Subject of the email * @param string $message Message of the email + * @param string|null $references Optional references header value + * @param array $attachments Array of attachments, where each attachment is an array with the first element being the file content and the second element being the filename * @throws Exception If an error occurs while sending the email */ - public function sendEmail(string $to, string $recipient_name, string $subject, string $message, string $references = null): void + public function sendEmail(string $to, string $recipient_name, string $subject, string $message, string $references = null, array $attachments = []): void { if ($this->config->mailersend_enabled->getVariableValue()) { try { @@ -80,7 +83,7 @@ class email implements email_i $html .= $message; // Add email footer $html .= self::generateHtmlFooter(); - $this->sendEmailMailerSend($to, $recipient_name, $subject, $message, $html, $references); + $this->sendEmailMailerSend($to, $recipient_name, $subject, $message, $html, $references, $attachments); } catch (JsonException|MailerSendException|ClientExceptionInterface $e) { throw new Exception('Error sending email: ' . $e->getMessage()); } @@ -445,5 +448,44 @@ class email implements email_i ); } + /** + * @throws Exception + */ + public function sendWelcomeEmailToCustomer(int $customer_number, string $email): void + { + $customer = (new users_o())->getUserByCustomerNumber($customer_number); + if (!$customer->exists()) { + throw new Exception('Customer not found with customer number: ' . $customer_number); + } + $password_reset_link = $customer->generatePasswordResetLink(); + /** + * Tillykke med din nye kredit konto! + * + * Du kan nu vaske i alle vores afdelinger. + * Vedhæftet finder du en liste over vores afdelinger, som kan viderebringes til dine chauffører. + * + * Opsæt din adgangskode her: $password_reset_link + * + * Vi har oprettet en kredit konto til dig, med følgende informationer: + * + * Virksomhed: AT Kloakservice ApS + * Tlf: 77302200 + * CVR: 40650717 + */ + $company_name = $customer->getCustomerName((int)$customer->customer_number->value()); + $phone = $customer->getCustomerEcocomicData()->economic_customer->mobilePhone; + $cvr = $customer->economic_customer->corporateIdentificationNumber; + // Craft the email message + $message = "Tillykke med din nye kredit konto!\n\nDu kan nu vaske i alle vores afdelinger.\nVedhæftet finder du en liste over vores afdelinger, som kan viderebringes til dine chauffører.\n\nOpsæt din adgangskode her: $password_reset_link\n\nVi har oprettet en kredit konto til dig, med følgende informationer:\n\nVirksomhed: $company_name\nTlf: $phone\nCVR: $cvr"; + // Send the email + $this->attachments = [ + [ + 'https://www.truckwash.dk/wp-content/uploads/2024/10/Truck-Wash_Flyer_A5.pdf', + 'Truck Wash Afdelinger.pdf' + ] + ]; + $this->sendEmail($email, $company_name, 'Velkommen til Truck Wash', nl2br($message), null, $this->attachments); + } + } \ No newline at end of file diff --git a/services/nginx/app/objects/users_o.php b/services/nginx/app/objects/users_o.php index 31ff1f89..ce9c5063 100644 --- a/services/nginx/app/objects/users_o.php +++ b/services/nginx/app/objects/users_o.php @@ -1478,4 +1478,28 @@ class users_o extends db } } + /** + * Generate password reset link for the user + * @return string The password reset link + * @throws Exception If the user is not selected + * @throws Exception If the user does not have an email address + */ + public function generatePasswordResetLink(): string + { + self::requireSelected(); + // Generate token + $token = customer_password_reset_keys_o::generateToken(); + + // Save token + $reset_key_o = new customer_password_reset_keys_o(); + $reset_key_o->add([ + 'customer_id' => (int)$this->customer_number->value(), + 'token' => (string)$token, + 'note' => 'Requested via API' + ]); + + // Generate reset link + return "https://truckwash.io/auth/password-reset/" . $token; + } + } \ No newline at end of file diff --git a/services/nginx/app/routes/authRoute.php b/services/nginx/app/routes/authRoute.php index 7ecd02b8..0ff521c7 100644 --- a/services/nginx/app/routes/authRoute.php +++ b/services/nginx/app/routes/authRoute.php @@ -265,9 +265,11 @@ class authRoute (int)$companyPhone, $name, (string)$cvr, - $invoiceEmail, + (string)$invoiceEmail, (string)$companyPhone, ); + $email = new email(); + $email->sendWelcomeEmailToCustomer((int)$companyPhone, (string)$invoiceEmail); /** * Return the result */ diff --git a/services/php/Dockerfile b/services/php/Dockerfile index ae0332d0..123e3f60 100644 --- a/services/php/Dockerfile +++ b/services/php/Dockerfile @@ -63,11 +63,11 @@ ENV COMPOSER_ALLOW_SUPERUSER=1 WORKDIR /var/www/html # Copy and enable entrypoint that installs Composer deps on first run -COPY services/php/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh -RUN chmod +x /usr/local/bin/docker-entrypoint.sh +#COPY services/php/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh +#RUN chmod +x /usr/local/bin/docker-entrypoint.sh # Expose port 9000 EXPOSE 9000 -ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"] +#ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"] CMD ["php-fpm"] \ No newline at end of file