Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
86.36% covered (success)
86.36%
38 / 44
n/a
0 / 0
CRAP
n/a
0 / 0
1<?php
2
3/**
4 * @file
5 * Login action: change password (requires valid session).
6 */
7
8    declare(strict_types=1);
9
10    /**
11     * Action callable: change password (GET device, session, old, new).
12     *
13     * Validates session, verifies old password, updates USER password in a transaction.
14     *
15     * @param string $body Request body (unused).
16     * @param array<string, mixed> $query Query params: device, session, old, new.
17     * @param \ConxHelper $conx Connection helper (from LoginService; uses ->global for central DB).
18     * @param \Psr\Log\LoggerInterface $logger Logger (from LoggerFactory).
19     * @param \UppServices\SessionService $sessionService Session service for check.
20     * @return array{output: string, contentType: string} JSON output and content type.
21     */
22    return function (string $body, array $query, \ConxHelper $conx, \Psr\Log\LoggerInterface $logger, \UppServices\SessionService $sessionService): array {
23        $retval = ApplicationError::Success;
24        $userid = null;
25        $userinfo = null;
26
27        $device = $query['device'] ?? null;
28        if (!$device) {
29            $logger->error("No device provided on URL. Operation cancelled.");
30            $retval = ApplicationError::Parameters;
31        }
32
33        if (success($retval)) {
34            $session = $query['session'] ?? null;
35            if (!$session) {
36                $logger->error("No session provided on URL. Operation cancelled.");
37                $retval = ApplicationError::Parameters;
38            } 
39            else {
40                $retval = $sessionService->checkSession($conx, $session, $device, $userid);
41            }
42        }
43
44        if (success($retval)) {
45            $oldpassword = $query['old'] ?? null;
46            if (!$oldpassword) {
47                $logger->error("Mandatory parameter 'old' not provided on URL. Operation cancelled.");
48                $retval = ApplicationError::Parameters;
49            }
50        }
51
52        if (success($retval)) {
53            $newpassword = $query['new'] ?? null;
54            if (!$newpassword) {
55                $logger->error("Mandatory parameter 'new' not provided on URL. Operation cancelled.");
56                $retval = ApplicationError::Parameters;
57            }
58        }
59
60        if (success($retval)) {
61            $results = [];
62            
63            $res = $conx->global->query('USER', ['objid' => $userid, 'password' => $oldpassword, 'status' => ['PA', 'AC']], $results);
64            if ($res && count($results) > 0) {
65                $userinfo = $results[0];
66            } 
67            else {
68                if (!$res) {
69                    $retval = ApplicationError::Parameters;
70                } 
71                else {
72                    $logger->warning("No user found with id '".$userid."' and password (crc32) '".$oldpassword."'.");
73                    $retval = ApplicationError::NotFound;
74                }
75            }
76        }
77
78        if (success($retval)) {
79            $ok = $conx->global->transactional(function (\transaction $transaction) use (&$userinfo, $newpassword) {
80                $userinfo['password'] = $newpassword;
81                return (bool) $transaction->update('USER', $userinfo);
82            });
83            
84            if (!$ok) {
85                // Previously begin() failure returned Parameters; DB write/commit failure is Database.
86                $retval = ApplicationError::Database;
87            }
88        }
89
90        $result = ["errorcode" => $retval];
91        $output = json_encode($result);
92        
93        return ['output' => $output, 'contentType' => 'application/json; charset=utf-8'];
94    };