Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
73.86% covered (warning)
73.86%
65 / 88
0.00% covered (danger)
0.00%
0 / 2
CRAP
n/a
0 / 0
register_user_data
81.48% covered (success)
81.48%
22 / 27
0.00% covered (danger)
0.00%
0 / 1
8.41
delete_user_data
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 1
20
1<?php
2
3/**
4 * @file
5 * Login action: register new user and send validation email.
6 * Logic inlined from legacy/login/register.php; no longer requires that file.
7 */
8
9declare(strict_types=1);
10
11require_once __DIR__.'/../legacy/login/validate.php';
12
13/**
14 * Registers a new user (activation pending). Returns ApplicationError code.
15 *
16 * Uses central DB (USER table); connection resolved inside.
17 *
18 * @param \ConxHelper $conx Connection helper.
19 * @param array<string, mixed> $userinfo Input: username, password. Output: objid, email, etc.
20 * @param \Psr\Log\LoggerInterface $logger Logger for debug output.
21 * @return int ApplicationError code.
22 */
23function register_user_data(\ConxHelper $conx, array &$userinfo, \Psr\Log\LoggerInterface $logger): int {
24    if (!check_free_email($conx, $userinfo['username'])) {
25        return ApplicationError::Exists;
26    }
27
28    $retval = ApplicationError::Success;
29    if ($conx->global === null) {
30        addlog(__FILE__, LogLevel::Error, "Connection to central database failed.");
31        return ApplicationError::Database;
32    }
33
34    $iteminfo = [
35        'email' => $userinfo['username'],
36        'password' => $userinfo['password'],
37        'license' => 1
38    ];
39
40    $transaction = $conx->global->begin();
41    if (!$transaction) {
42        return ApplicationError::Database;
43    }
44
45    $userinfo['objid'] = '';
46    $res = $transaction->insert('USER', $iteminfo, $userinfo['objid']);
47    $logger->debug('NEW USER:'.PHP_EOL.print_r($userinfo, true).PHP_EOL);
48    if (!$res) {
49        $retval = ApplicationError::Database;
50    }
51    $transaction->flush($res);
52
53    if (success($retval)) {
54        $results = [];
55        $res = $conx->global->query('USER', $iteminfo, $results);
56        if ($res && count($results) > 0) {
57            $userinfo = $results[0];
58        } else {
59            $retval = ApplicationError::Database;
60        }
61    }
62
63    return $retval;
64}
65
66/**
67 * Soft-deletes a user (sets status DE).
68 *
69 * Uses central DB (USER table); connection resolved inside.
70 *
71 * @param \ConxHelper $conx Connection helper.
72 * @param array<string, mixed> $userinfo Must contain objid.
73 * @param \Psr\Log\LoggerInterface $logger Logger for debug output.
74 * @return int ApplicationError code.
75 */
76function delete_user_data(\ConxHelper $conx, array &$userinfo, \Psr\Log\LoggerInterface $logger): int {
77    $retval = ApplicationError::Success;
78
79    if ($conx->global === null) {
80        addlog(__FILE__, LogLevel::Error, "Connection to central database failed.");
81        return ApplicationError::Database;
82    }
83
84    $transaction = $conx->global->begin();
85    if (!$transaction) {
86        return ApplicationError::Database;
87    }
88
89    $iteminfo = [
90        'objid' => $userinfo['objid'],
91        'status' => 'DE'
92    ];
93    $res = $transaction->update('USER', $iteminfo);
94    $logger->debug('DELETED USER:'.PHP_EOL.print_r($userinfo, true).PHP_EOL);
95    if (!$res) {
96        $retval = ApplicationError::Database;
97    }
98    $transaction->flush($res);
99
100    return $retval;
101}
102
103/**
104 * Action callable: register new user (POST body username/password + GET device, lang).
105 *
106 * Registers user (activation pending), grants session, sends validation mail.
107 * On error after creating user, deletes the created user.
108 *
109 * @param string $body JSON body with username, password.
110 * @param array<string, mixed> $query Query params: device, lang.
111 * @param \ConxHelper $conx Connection helper (from LoginService; uses ->global for central DB).
112 * @param \Psr\Log\LoggerInterface $logger Logger (from LoggerFactory).
113 * @param \UppServices\SessionService $sessionService Session service for grant.
114 * @return array{output: string, contentType: string} JSON output and content type.
115 */
116return function (string $body, array $query, \ConxHelper $conx, \Psr\Log\LoggerInterface $logger, \UppServices\SessionService $sessionService): array {
117    $retval = ApplicationError::Success;
118    $userinfo = [];
119    $user_created = false;
120
121    if ($body === '') {
122        $output = json_encode(['errorcode' => ApplicationError::Parameters]);
123        return ['output' => $output, 'contentType' => 'application/json; charset=utf-8'];
124    }
125
126    $data = json_decode($body, true);
127    $logger->debug("DUMP OF POST DATA:".PHP_EOL.print_r($data, true).PHP_EOL);
128    if (json_last_error() !== \JSON_ERROR_NONE) {
129        $logger->error("Invalid JSON format in post request data");
130        $retval = ApplicationError::Generic;
131    }
132
133    $deviceid = $query['device'] ?? null;
134    if (success($retval) && !$deviceid) {
135        $logger->error("Missing 'device' parameter in url request");
136        $retval = ApplicationError::Parameters;
137    }
138
139    $username = $data['username'] ?? null;
140    if (success($retval) && !$username) {
141        $logger->error("Mandatory argument 'username' not provided in post data.");
142        $retval = ApplicationError::Parameters;
143    }
144
145    $password = $data['password'] ?? null;
146    if (success($retval) && !$password) {
147        $logger->error("Mandatory argument 'password' not provided in post data.");
148        $retval = ApplicationError::Parameters;
149    }
150
151    if (success($retval)) {
152        $userinfo = ['username' => $username, 'password' => $password];
153        $retval = register_user_data($conx, $userinfo, $logger);
154        if (success($retval)) {
155            $user_created = true;
156        }
157    }
158
159    $userinfo['session'] = null;
160    if (success($retval)) {
161        $retval = $sessionService->grantSession($conx, $deviceid, $userinfo['objid'], $userinfo['session']);
162    }
163
164    if ($user_created && !success($retval)) {
165        delete_user_data($conx, $userinfo, $logger);
166    }
167
168    if (!success($retval)) {
169        $result = ['errorcode' => $retval];
170    } 
171    else {
172        $result = ['errorcode' => $retval, 'session' => $userinfo['session']];
173    }
174
175    if (success($retval)) {
176        $lang = $query['lang'] ?? 'EN';
177        send_validation_mail($conx, $lang, $userinfo['email']);
178    }
179
180    $output = json_encode($result);
181    return ['output' => $output, 'contentType' => 'application/json; charset=utf-8'];
182};