Add password reset request endpoint to authentication routes; update OpenAPI spec and improve user email handling in users_o

This commit is contained in:
Jeppe Bundgaard
2026-01-19 11:17:35 +01:00
parent 09b5c618ed
commit da9ee98fb5
3 changed files with 88 additions and 0 deletions
+34
View File
@@ -296,6 +296,40 @@ paths:
'400':
$ref: '#/components/responses/BadRequest'
/auth/password-reset/request:
post:
tags:
- Authentication
summary: Request a customer password reset email
description: Send an email with a password reset token to the customer's email address
operationId: requestPasswordReset
security: []
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- customer_number
properties:
customer_number:
type: integer
description: The customer number
example: 123456
responses:
'200':
description: Request processed
content:
application/json:
schema:
type: object
properties:
message:
type: string
'400':
$ref: '#/components/responses/BadRequest'
/auth/password-reset/validate:
get:
tags:
+8
View File
@@ -157,6 +157,14 @@ class users_o extends db
$this->add($customer_number, '', 0);
// Nullify the password
$this->password->nullify();
// If the customer has an email address, save it
if (isset($customer_data->email)) {
$this->email->set($customer_data->email);
}
// If the customer has a name, save it as the display name
if (isset($customer_data->name)) {
$this->display_name->set($customer_data->name);
}
}
}
// Else return false
+46
View File
@@ -4,8 +4,10 @@ namespace routes;
use classes\authentication;
use classes\economic;
use classes\email;
use classes\recaptcha;
use classes\virkdata;
use Exception;
use objects\customer_password_reset_keys_o;
use objects\logs_o;
use objects\tokens_o;
@@ -268,6 +270,50 @@ class authRoute
}
});
$this->post('/auth/password-reset/request', function () {
global $response;
$this->requireRecaptcha();
self::requireParameters(['customer_number']);
$customer_number = (int)self::getParameter('customer_number');
$user = (new users_o())->getUserByCustomerNumber($customer_number);
if (!$user->id) {
// For security reasons, don't reveal if the user exists
$response->success(['message' => 'If the customer exists, a password reset email has been sent.']);
}
$email_address = $user->email->value();
if (empty($email_address)) {
// If no email is set, we can't send the reset email
$response->error('No email address associated with this account. Please contact support.', 400);
}
// 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' => $customer_number,
'token' => $token,
'note' => 'Requested via API'
]);
// Send email
$email = new email();
$reset_link = "https://truckwash.io/auth/password-reset/" . $token;
$subject = 'Adgangskode nulstilling';
$message = "Du har anmodet om at nulstille din adgangskode. Klik på linket herunder for at fortsætte:<br><br><a href='$reset_link'>$reset_link</a><br><br>Linket er gyldigt i 1 time.";
try {
$email->sendEmail($email_address, $user->display_name->value() ?? 'Kunde', $subject, $message, null);
$response->success(['message' => 'If the customer exists, a password reset email has been sent.']);
} catch (Exception $e) {
$response->error('Failed to send email: ' . $e->getMessage(), 500);
}
});
$this->get('/auth/password-reset/validate', function () {
global $response;
self::requireParameters(['token']);