Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
87.72% covered (success)
87.72%
50 / 57
50.00% covered (danger)
50.00%
1 / 2
CRAP
n/a
0 / 0
activate_user_impl
76.19% covered (warning)
76.19%
16 / 21
0.00% covered (danger)
0.00%
0 / 1
5.34
build_activate_output_html
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3/**
4 * @file
5 * Login action: activate user from email link (authorization + usermail).
6 */
7
8    declare(strict_types=1);
9
10    require_once __DIR__.'/../../Legacy/common/authorize.php';
11    require_once __DIR__.'/../../Legacy/common/awake.php';
12
13    /**
14     * Activate user in DB (status PA -> AC).
15     *
16     * Finds USER by email with status PA, updates status to AC in a transaction.
17     * Uses central DB (USER table).
18     *
19     * @param \ConxHelper $conx Connection helper.
20     * @param string $usermail User email to activate.
21     * @param array|null $user Output: filled with user row on success.
22     * @param \Psr\Log\LoggerInterface $logger Logger for errors.
23     * @return int ApplicationError::Success, ::NotFound, or ::Database.
24     */
25    function activate_user_impl(\ConxHelper $conx, string $usermail, &$user, \Psr\Log\LoggerInterface $logger): int
26    {
27        if ($conx->global === null) {
28            return ApplicationError::Database;
29        }
30
31        $retval = ApplicationError::Success;
32        $result = [];
33        
34        $res = $conx->global->query('USER', ['email' => $usermail, 'status' => 'PA'], $result);
35        if ($res) {
36            if (count($result) === 0) {
37                $logger->error("No user entry found with email address '".$usermail."'");
38                return ApplicationError::NotFound;
39            }
40            
41            $user = $result[0];
42            
43            $ok = $conx->global->transactional(function (\transaction $transaction) use ($user) {
44                $iteminfo = [
45                    'objid' => $user['objid'],
46                    'status' => 'AC',
47                ];
48                
49                return (bool) $transaction->update('USER', $iteminfo);
50            });
51            
52            if (!$ok) {
53                $retval = ApplicationError::Database;
54            }
55        } 
56        else {
57            $retval = ApplicationError::Database;
58        }
59        
60        return $retval;
61    }
62
63    /**
64     * Build redirect HTML for activate result (IonUrl on-activate).
65     *
66     * @param string $language Language code for the redirect URL.
67     * @param int $errorcode ApplicationError::Success or other (maps to SUCCESS/FAILURE).
68     * @return string HTML page with meta refresh to IonUrl on-activate.
69     */
70    function build_activate_output_html(string $language, int $errorcode): string
71    {
72        $result = ($errorcode === ApplicationError::Success) ? 'SUCCESS' : 'FAILURE';
73        $dsturl = AppConstants::IonUrl().'on-activate?lang='.$language.'&result='.$result;
74        
75        $html = '<!DOCTYPE html>';
76        $html .= '<html>';
77        $html .= '<head><meta http-equiv=\'refresh\' content=\'0; URL='.$dsturl.'\'></head>';
78        $html .= '<body><p>You are being redirected. If not, please follow <a href=\''.$dsturl.'\'>this link</a>.</p></body>';
79        $html .= '</html>';
80        
81        return $html;
82    }
83
84    /**
85     * Action callable: activate user from email link (GET authorization, usermail, lang).
86     *
87     * Validates authorization, activates user (PA -> AC), notifies via awake_on_update,
88     * returns HTML redirect to IonUrl on-activate.
89     *
90     * @param string $body Request body (unused).
91     * @param array<string, mixed> $query Query params: authorization, usermail, lang.
92     * @param \ConxHelper $conx Connection helper (from LoginService; uses ->global for central DB).
93     * @param \Psr\Log\LoggerInterface $logger Logger (from LoggerFactory).
94     * @param \UppServices\SessionService $sessionService Session service (unused).
95     * @return array{output: string, contentType: string} HTML output and content type.
96     */
97    return function (string $body, array $query, \ConxHelper $conx, \Psr\Log\LoggerInterface $logger, \UppServices\SessionService $sessionService): array {
98        $retval = ApplicationError::Success;
99        $userinfo = null;
100
101        $logger->info("Checking authorization key for user activation..");
102        $auth = $query['authorization'] ?? null;
103        if (!$auth) {
104            $logger->error("No authorization key provided on URL. Operation cancelled.");
105            $retval = ApplicationError::Parameters;
106        }
107
108        if (success($retval)) {
109            $item = use_authorization($conx, $auth);
110            if (!$item) {
111                $logger->error("Authorization key '".$auth."' not found or invalid.");
112                $retval = ApplicationError::Unauthorized;
113            } 
114            else {
115                $logger->info("Authorization check test sucessfull.");
116            }
117        }
118
119        if (success($retval)) {
120            $usermail = $query['usermail'] ?? null;
121            if (!$usermail) {
122                $logger->error("No usermail provided on URL. Operation cancelled.");
123                $retval = ApplicationError::Parameters;
124            } 
125            else {
126                $retval = activate_user_impl($conx, $usermail, $userinfo, $logger);
127            }
128        }
129        
130        if (success($retval)) {
131            $retval = awake_on_update($conx, 'USER', [$userinfo], true);
132        }
133
134        $lang = $query['lang'] ?? 'EN';
135        $output = build_activate_output_html($lang, $retval);
136        
137        return ['output' => $output, 'contentType' => 'text/html; charset=utf-8'];
138    };