Passed
Push — teampass_3.0 ( b41394...43cd8c )
by Nils
03:23
created

fileFormatImage()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 15
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 5
eloc 11
c 2
b 0
f 0
nc 5
nop 1
dl 0
loc 15
rs 9.6111
1
<?php
2
/**
3
 * Teampass - a collaborative passwords manager.
4
 *
5
 * This library is distributed in the hope that it will be useful,
6
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
7
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
8
 *
9
 * @author    Nils Laumaillé <[email protected]>
10
 * @copyright 2009-2019 Teampass.net
11
 * @license   https://spdx.org/licenses/GPL-3.0-only.html#licenseText GPL-3.0
12
 *
13
 * @version   GIT: <git_id>
14
 *
15
 * @see      https://www.teampass.net
16
 */
17
require_once 'SecureHandler.php';
18
session_name('teampass_session');
19
session_start();
20
if (!isset($_SESSION['CPM']) || $_SESSION['CPM'] === false || !isset($_SESSION['key']) || empty($_SESSION['key'])) {
21
    die('Hacking attempt...');
22
}
23
24
// Load config
25
if (file_exists('../includes/config/tp.config.php')) {
26
    include_once '../includes/config/tp.config.php';
27
} elseif (file_exists('./includes/config/tp.config.php')) {
28
    include_once './includes/config/tp.config.php';
29
} else {
30
    throw new Exception("Error file '/includes/config/tp.config.php' not exists", 1);
31
}
32
33
// Do checks
34
require_once $SETTINGS['cpassman_dir'].'/includes/config/include.php';
35
require_once $SETTINGS['cpassman_dir'].'/sources/checks.php';
36
if (checkUser($_SESSION['user_id'], $_SESSION['key'], 'items', $SETTINGS) === false) {
37
    // Not allowed page
38
    $_SESSION['error']['code'] = ERR_NOT_ALLOWED;
39
    include $SETTINGS['cpassman_dir'].'/error.php';
40
    exit();
41
}
42
43
/*
44
 * Define Timezone
45
**/
46
if (isset($SETTINGS['timezone']) === true) {
47
    date_default_timezone_set($SETTINGS['timezone']);
48
} else {
49
    date_default_timezone_set('UTC');
50
}
51
52
require_once $SETTINGS['cpassman_dir'].'/includes/language/'.$_SESSION['user_language'].'.php';
53
require_once $SETTINGS['cpassman_dir'].'/includes/config/settings.php';
54
header('Content-type: text/html; charset=utf-8');
55
header('Cache-Control: no-cache, must-revalidate');
56
require_once 'main.functions.php';
57
58
// Ensure Complexity levels are translated
59
if (defined('TP_PW_COMPLEXITY') === false) {
60
    define(
61
        'TP_PW_COMPLEXITY',
62
        array(
63
            0 => array(0, langHdl('complex_level0'), 'fas fa-bolt text-danger'),
64
            25 => array(25, langHdl('complex_level1'), 'fas fa-thermometer-empty text-danger'),
65
            50 => array(50, langHdl('complex_level2'), 'fas fa-thermometer-quarter text-warning'),
66
            60 => array(60, langHdl('complex_level3'), 'fas fa-thermometer-half text-warning'),
67
            70 => array(70, langHdl('complex_level4'), 'fas fa-thermometer-three-quarters text-success'),
68
            80 => array(80, langHdl('complex_level5'), 'fas fa-thermometer-full text-success'),
69
            90 => array(90, langHdl('complex_level6'), 'far fa-gem text-success'),
70
        )
71
    );
72
}
73
74
// Connect to mysql server
75
require_once $SETTINGS['cpassman_dir'].'/includes/libraries/Database/Meekrodb/db.class.php';
76
if (defined('DB_PASSWD_CLEAR') === false) {
77
    define('DB_PASSWD_CLEAR', defuseReturnDecrypted(DB_PASSWD, $SETTINGS));
78
}
79
DB::$host = DB_HOST;
80
DB::$user = DB_USER;
81
DB::$password = DB_PASSWD_CLEAR;
82
DB::$dbName = DB_NAME;
83
DB::$port = DB_PORT;
84
DB::$encoding = DB_ENCODING;
85
//$link = mysqli_connect(DB_HOST, DB_USER, DB_PASSWD_CLEAR, DB_NAME, DB_PORT);
86
//$link->set_charset(DB_ENCODING);
87
88
// Class loader
89
require_once $SETTINGS['cpassman_dir'].'/sources/SplClassLoader.php';
90
91
//Load Tree
92
$tree = new SplClassLoader('Tree\NestedTree', '../includes/libraries');
93
$tree->register();
94
$tree = new Tree\NestedTree\NestedTree(prefixTable('nested_tree'), 'id', 'parent_id', 'title');
95
96
// Prepare POST variables
97
$post_page = filter_input(INPUT_POST, 'page', FILTER_SANITIZE_STRING);
98
$post_type = filter_input(INPUT_POST, 'type', FILTER_SANITIZE_STRING);
99
$post_data = filter_input(INPUT_POST, 'data', FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES);
100
$post_key = filter_input(INPUT_POST, 'key', FILTER_SANITIZE_STRING);
101
$post_label = filter_input(INPUT_POST, 'label', FILTER_SANITIZE_STRING);
102
$post_status = filter_input(INPUT_POST, 'status', FILTER_SANITIZE_STRING);
103
$post_cat = filter_input(INPUT_POST, 'cat', FILTER_SANITIZE_STRING);
104
$post_receipt = filter_input(INPUT_POST, 'receipt', FILTER_SANITIZE_STRING);
105
$post_item_id = filter_input(INPUT_POST, 'item_id', FILTER_SANITIZE_NUMBER_INT);
106
$post_id_tree = filter_input(INPUT_POST, 'id_tree', FILTER_SANITIZE_NUMBER_INT);
107
$post_folder_id = filter_input(INPUT_POST, 'folder_id', FILTER_SANITIZE_NUMBER_INT);
108
$post_id = filter_input(INPUT_POST, 'id', FILTER_SANITIZE_NUMBER_INT);
109
$post_destination = filter_input(INPUT_POST, 'destination', FILTER_SANITIZE_NUMBER_INT);
110
$post_source = filter_input(INPUT_POST, 'source', FILTER_SANITIZE_NUMBER_INT);
111
$post_user_id = filter_input(INPUT_POST, 'user_id', FILTER_SANITIZE_NUMBER_INT);
112
$post_iFolderId = filter_input(INPUT_POST, 'iFolderId', FILTER_SANITIZE_NUMBER_INT);
113
114
// Do asked action
115
if (null !== $post_type) {
116
    switch ($post_type) {
117
        /*
118
        * CASE
119
        * creating a new ITEM
120
        */
121
        case 'new_item':
122
            // Check KEY and rights
123
            if ($post_key !== $_SESSION['key']) {
124
                echo prepareExchangedData(
125
                    array(
126
                        'error' => true,
127
                        'message' => langHdl('key_is_not_correct'),
128
                    ),
129
                    'encode'
130
                );
131
                break;
132
            } elseif ($_SESSION['user_read_only'] === true) {
133
                echo prepareExchangedData(
134
                    array(
135
                        'error' => true,
136
                        'message' => langHdl('error_not_allowed_to'),
137
                    ),
138
                    'encode'
139
                );
140
                break;
141
            }
142
143
            // init
144
            $reloadPage = false;
145
            $returnValues = array();
146
            // decrypt and retreive data in JSON format
147
            $dataReceived = prepareExchangedData(
148
                $post_data,
149
                'decode'
150
            );
151
152
            if (count($dataReceived) > 0) {
0 ignored issues
show
Bug introduced by
$dataReceived of type string is incompatible with the type Countable|array expected by parameter $var of count(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

152
            if (count(/** @scrutinizer ignore-type */ $dataReceived) > 0) {
Loading history...
153
                // Prepare variables
154
                $post_anyone_can_modify = filter_var($dataReceived['anyone_can_modify'], FILTER_SANITIZE_NUMBER_INT);
155
                $post_complexity_level = filter_var($dataReceived['complexity_level'], FILTER_SANITIZE_NUMBER_INT);
156
                $post_description = ($dataReceived['description']);
157
                $post_diffusion_list = json_decode(
158
                    filter_var(
159
                        $dataReceived['diffusion_list'],
160
                        FILTER_SANITIZE_STRING
161
                    )
162
                );
163
                $post_email = filter_var(htmlspecialchars_decode($dataReceived['email']), FILTER_SANITIZE_EMAIL);
164
                $post_fields = json_decode(
165
                    filter_var(
166
                        $dataReceived['fields'],
167
                        FILTER_SANITIZE_STRING
168
                    )
169
                );
170
                $post_folder_id = filter_var($dataReceived['folder'], FILTER_SANITIZE_NUMBER_INT);
171
                $post_folder_is_personal = filter_var($dataReceived['folder_is_personal'], FILTER_SANITIZE_NUMBER_INT);
172
                $post_label = filter_var($dataReceived['label'], FILTER_SANITIZE_STRING);
173
                $post_login = filter_var($dataReceived['login'], FILTER_SANITIZE_STRING);
174
                $post_password = htmlspecialchars_decode($dataReceived['pw']);
175
                $post_restricted_to = json_decode(
176
                    filter_var(
177
                        $dataReceived['restricted_to'],
178
                        FILTER_SANITIZE_STRING
179
                    )
180
                );
181
                $post_restricted_to_roles = json_decode(
182
                    filter_var(
183
                        $dataReceived['restricted_to_roles'],
184
                        FILTER_SANITIZE_STRING
185
                    )
186
                );
187
                $post_salt_key_set = isset($_SESSION['user_settings']['session_psk']) === true
188
                    && empty($_SESSION['user_settings']['session_psk']) === false ? '1' : '0';
189
                $post_tags = htmlspecialchars_decode($dataReceived['tags']);
190
                $post_template_id = filter_var($dataReceived['template_id'], FILTER_SANITIZE_NUMBER_INT);
191
                $post_url = filter_var(htmlspecialchars_decode($dataReceived['url']), FILTER_SANITIZE_URL);
192
                $post_uploaded_file_id = filter_var($dataReceived['uploaded_file_id'], FILTER_SANITIZE_NUMBER_INT);
193
                $post_user_id = filter_var($dataReceived['user_id'], FILTER_SANITIZE_NUMBER_INT);
194
                $post_to_be_deleted_after_date = filter_var($dataReceived['to_be_deleted_after_date'], FILTER_SANITIZE_STRING);
195
                $post_to_be_deleted_after_x_views = filter_var($dataReceived['to_be_deleted_after_x_views'], FILTER_SANITIZE_NUMBER_INT);
196
197
                //-> DO A SET OF CHECKS
198
                // Perform a check in case of Read-Only user creating an item in his PF
199
                if ($_SESSION['user_read_only'] === true
200
                    && (in_array($post_folder_id, $_SESSION['personal_folders']) === false
201
                    || $post_folder_is_personal !== 1)
202
                ) {
203
                    echo prepareExchangedData(
204
                        array(
205
                            'error' => true,
206
                            'message' => langHdl('error_not_allowed_to_access_this_folder'),
207
                        ),
208
                        'encode'
209
                    );
210
                    break;
211
                }
212
213
                // Is author authorized to create in this folder
214
                if (count($_SESSION['list_folders_limited']) > 0) {
215
                    if (in_array($post_folder_id, array_keys($_SESSION['list_folders_limited'])) === false
216
                        && in_array($post_folder_id, $_SESSION['groupes_visibles']) === false
217
                        && in_array($post_folder_id, $_SESSION['personal_visible_groups_list']) === false
218
                    ) {
219
                        echo prepareExchangedData(
220
                            array(
221
                                'error' => true,
222
                                'message' => langHdl('error_not_allowed_to_access_this_folder'),
223
                            ),
224
                            'encode'
225
                        );
226
                        break;
227
                    }
228
                } else {
229
                    if (in_array($post_folder_id, $_SESSION['groupes_visibles']) === false) {
230
                        echo prepareExchangedData(
231
                            array(
232
                                'error' => true,
233
                                'message' => langHdl('error_not_allowed_to_access_this_folder'),
234
                            ),
235
                            'encode'
236
                        );
237
                        break;
238
                    }
239
                }
240
241
                // perform a check in case of Read-Only user creating an item in his PF
242
                if ($_SESSION['user_read_only'] === true
243
                    && in_array($post_folder_id, $_SESSION['personal_folders']) === false
244
                ) {
245
                    echo prepareExchangedData(
246
                        array(
247
                            'error' => true,
248
                            'message' => langHdl('error_not_allowed_to_access_this_folder'),
249
                        ),
250
                        'encode'
251
                    );
252
                    break;
253
                }
254
255
                // is pwd empty?
256
                if (empty($post_password)
257
                    && isset($_SESSION['user_settings']['create_item_without_password']) == true
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
258
                    && $_SESSION['user_settings']['create_item_without_password'] !== '1'
259
                ) {
260
                    echo prepareExchangedData(
261
                        array(
262
                            'error' => true,
263
                            'message' => langHdl('password_cannot_be_empty'),
264
                        ),
265
                        'encode'
266
                    );
267
                    break;
268
                }
269
270
                // Check length
271
                if (strlen($post_password) > $SETTINGS['pwd_maximum_length']) {
272
                    echo prepareExchangedData(
273
                        array(
274
                            'error' => true,
275
                            'message' => langHdl('password_too_long'),
276
                        ),
277
                        'encode'
278
                    );
279
                    break;
280
                }
281
282
                // Check PSK is set
283
                if ((int) $post_folder_is_personal === 1
284
                    && (isset($_SESSION['user_settings']['session_psk']) === false
285
                    || empty($post_password) === true)
286
                ) {
287
                    echo prepareExchangedData(
288
                        array(
289
                            'error' => true,
290
                            'message' => langHdl('provide_your_personal_saltkey'),
291
                        ),
292
                        'encode'
293
                    );
294
                    break;
295
                }
296
297
                // Need info in DB
298
                // About special settings
299
                $dataFolderSettings = DB::queryFirstRow(
300
                    'SELECT bloquer_creation, bloquer_modification, personal_folder
301
                    FROM '.prefixTable('nested_tree').' 
302
                    WHERE id = %i',
303
                    $post_folder_id
304
                );
305
                $itemInfos['personal_folder'] = $dataFolderSettings['personal_folder'];
306
                if ($itemInfos['personal_folder'] === '1') {
307
                    $itemInfos['no_complex_check_on_modification'] = 1;
308
                    $itemInfos['no_complex_check_on_creation'] = 1;
309
                } else {
310
                    $itemInfos['no_complex_check_on_modification'] = (int) $dataFolderSettings['bloquer_modification'];
311
                    $itemInfos['no_complex_check_on_creation'] = (int) $dataFolderSettings['bloquer_creation'];
312
                }
313
                // Get folder complexity
314
                $folderComplexity = DB::queryfirstrow(
315
                    'SELECT valeur
316
                    FROM '.prefixTable('misc').'
317
                    WHERE type = %s AND intitule = %i',
318
                    'complex',
319
                    $post_folder_id
320
                );
321
                $itemInfos['requested_folder_complexity'] = (int) $folderComplexity['valeur'];
322
323
                // Check COMPLEXITY
324
                if ($post_complexity_level < $itemInfos['requested_folder_complexity']) {
325
                    echo prepareExchangedData(
326
                        array(
327
                            'error' => true,
328
                            'message' => langHdl('error_security_level_not_reached'),
329
                        ),
330
                        'encode'
331
                    );
332
                    break;
333
                }
334
335
                // ./ END
336
337
                // check if element doesn't already exist
338
                $itemExists = 0;
339
                $newID = '';
340
                $data = DB::queryfirstrow(
341
                    'SELECT * FROM '.prefixTable('items').'
342
                    WHERE label = %s AND inactif = %i',
343
                    $post_label,
344
                    0
345
                );
346
                $counter = DB::count();
347
                if ($counter > 0) {
348
                    $itemExists = 1;
349
                } else {
350
                    $itemExists = 0;
351
                }
352
353
                // Manage case where item is personal.
354
                // In this case, duplication is allowed
355
                if (isset($SETTINGS['duplicate_item']) === true
356
                    && $SETTINGS['duplicate_item'] === '0'
357
                    && $post_salt_key_set === '1'
358
                    && isset($post_salt_key_set) === true
359
                    && $post_folder_is_personal === '1'
360
                    && isset($post_folder_is_personal) === true
361
                ) {
362
                    $itemExists = 0;
363
                }
364
365
                if ((isset($SETTINGS['duplicate_item']) === true
366
                    && $SETTINGS['duplicate_item'] === '0'
367
                    && (int) $itemExists === 0)
368
                    ||
369
                    (isset($SETTINGS['duplicate_item']) === true
370
                        && $SETTINGS['duplicate_item'] === '1')
371
                ) {
372
                    // Handle case where pw is empty
373
                    // if not allowed then warn user
374
                    if ((isset($_SESSION['user_settings']['create_item_without_password']) === true
375
                        && $_SESSION['user_settings']['create_item_without_password'] !== '1'
376
                        ) ||
377
                        empty($post_password) === false
378
                    ) {
379
                        // NEW ENCRYPTION
380
                        $cryptedStuff = doDataEncryption($post_password);
381
                    /*
382
                    // encrypt PW
383
                    if ($post_salt_key_set === '1'
384
                        && isset($post_salt_key_set) === true
385
                        && $post_folder_is_personal === '1'
386
                        && isset($post_folder_is_personal) === true
387
                    ) {
388
                        $passwd = cryption(
389
                            $post_password,
390
                            $_SESSION['user_settings']['session_psk'],
391
                            'encrypt',
392
                            $SETTINGS
393
                        );
394
                        $restictedTo = $_SESSION['user_id'];
395
                    } else {
396
                        $passwd = cryption(
397
                            $post_password,
398
                            '',
399
                            'encrypt',
400
                            $SETTINGS
401
                        );
402
                    }
403
                    */
404
                    } else {
405
                        $cryptedStuff['encrypted'] = '';
406
                    }
407
408
                    $post_password = $cryptedStuff['encrypted'];
409
410
                    // ADD item
411
                    DB::insert(
412
                        prefixTable('items'),
413
                        array(
414
                            'label' => $post_label,
415
                            'description' => $post_description,
416
                            'pw' => $post_password,
417
                            'pw_iv' => '',
418
                            'email' => $post_email,
419
                            'url' => $post_url,
420
                            'id_tree' => $post_folder_id,
421
                            'login' => $post_login,
422
                            'inactif' => 0,
423
                            'restricted_to' => empty($post_restricted_to) === true || count($post_restricted_to) === 0 ?
424
                                '' : implode(';', $post_restricted_to),
425
                            'perso' => (isset($post_folder_is_personal) === true && (int) $post_folder_is_personal === 1) ?
426
                                1 : 0,
427
                            'anyone_can_modify' => (isset($post_anyone_can_modify) === true
428
                                && $post_anyone_can_modify === 'on') ? 1 : 0,
429
                            'complexity_level' => $post_complexity_level,
430
                            'encryption_type' => 'teampass_aes',
431
                            )
432
                    );
433
                    $newID = DB::insertId();
434
435
                    // Create sharekeys for users
436
                    storeUsersShareKey(
437
                        prefixTable('sharekeys_items'),
438
                        $post_folder_is_personal,
439
                        $post_folder_id,
440
                        $newID,
441
                        $cryptedStuff['objectKey'],
442
                        $SETTINGS
443
                    );
444
445
                    /*
446
                    // Prepare shareKey for users
447
                    if ((int) $post_folder_is_personal === 1 && isset($post_folder_is_personal) === true) {
448
                        // If this is a personal object
449
                        DB::insert(
450
                            prefixTable('sharekeys_items'),
451
                            array(
452
                                'object_id' => $newID,
453
                                'user_id' => $_SESSION['user_id'],
454
                                'share_key' => encryptUserObjectKey($cryptedStuff['objectKey'], $_SESSION['user']['public_key']),
455
                            )
456
                        );
457
                    } else {
458
                        // This is a public object
459
                        $users = DB::query(
460
                            'SELECT id, public_key
461
                            FROM '.prefixTable('users').'
462
                            WHERE id NOT IN ("'.OTV_USER_ID.'","'.SSH_USER_ID.'","'.API_USER_ID.'")
463
                            AND public_key != ""'
464
                        );
465
                        foreach ($users as $user) {
466
                            // Insert in DB the new object key for this item by user
467
                            DB::insert(
468
                                prefixTable('sharekeys_items'),
469
                                array(
470
                                    'object_id' => $newID,
471
                                    'user_id' => $user['id'],
472
                                    'share_key' => encryptUserObjectKey($cryptedStuff['objectKey'], $user['public_key']),
473
                                )
474
                            );
475
                        }
476
                    }
477
                    */
478
479
                    // update fields
480
                    if (isset($SETTINGS['item_extra_fields']) === true
481
                        && (int) $SETTINGS['item_extra_fields'] === 1
482
                    ) {
483
                        foreach (explode('_|_', $post_fields) as $field) {
484
                            $field_data = explode('~~', $field);
485
                            if (count($field_data) > 1 && empty($field_data[1]) === false) {
486
                                // should we encrypt the data
487
                                $dataTmp = DB::queryFirstRow(
488
                                    'SELECT encrypted_data
489
                                    FROM '.prefixTable('categories').'
490
                                    WHERE id = %i',
491
                                    $field_data[0]
492
                                );
493
                                if ((int) $dataTmp['encrypted_data'] === 1) {
494
                                    $encrypt = cryption(
495
                                        $field_data[1],
496
                                        '',
497
                                        'encrypt',
498
                                        $SETTINGS
499
                                    );
500
                                    $enc_type = 'defuse';
501
                                } else {
502
                                    $encrypt['string'] = $field_data[1];
503
                                    $enc_type = 'not_set';
504
                                }
505
506
                                DB::insert(
507
                                    prefixTable('categories_items'),
508
                                    array(
509
                                        'item_id' => $newID,
510
                                        'field_id' => $field_data[0],
511
                                        'data' => $encrypt['string'],
512
                                        'data_iv' => '',
513
                                        'encryption_type' => $enc_type,
514
                                    )
515
                                );
516
                            }
517
                        }
518
                    }
519
520
                    // If template enable, is there a main one selected?
521
                    if (isset($SETTINGS['item_creation_templates']) === true
522
                        && (int) $SETTINGS['item_creation_templates'] === 1
523
                        && isset($post_template_id) === true
524
                        && empty($post_template_id) === false
525
                    ) {
526
                        DB::queryFirstRow(
527
                            'SELECT *
528
                            FROM '.prefixTable('templates').'
529
                            WHERE item_id = %i',
530
                            $newID
531
                        );
532
                        if (DB::count() === 0) {
533
                            // store field text
534
                            DB::insert(
535
                                prefixTable('templates'),
536
                                array(
537
                                    'item_id' => $newID,
538
                                    'category_id' => $post_template_id,
539
                                )
540
                            );
541
                        } else {
542
                            // Delete if empty
543
                            if (empty($post_template_id) === true) {
544
                                DB::delete(
545
                                    prefixTable('templates'),
546
                                    'item_id = %i',
547
                                    $newID
548
                                );
549
                            } else {
550
                                // Update value
551
                                DB::update(
552
                                    prefixTable('templates'),
553
                                    array(
554
                                        'category_id' => $post_template_id,
555
                                    ),
556
                                    'item_id = %i',
557
                                    $newID
558
                                );
559
                            }
560
                        }
561
                    }
562
563
                    // If automatic deletion asked
564
                    if (isset($SETTINGS['enable_delete_after_consultation']) === true
565
                        && (int) $SETTINGS['enable_delete_after_consultation'] === 1
566
                        && null !== $post_to_be_deleted_after_x_views
567
                        && null !== $post_to_be_deleted_after_date
568
                    ) {
569
                        if (empty($post_to_be_deleted_after_date) === false
570
                            || $post_to_be_deleted_after_x_views > 0
571
                        ) {
572
                            // Automatic deletion to be added
573
                            DB::insert(
574
                                prefixTable('automatic_del'),
575
                                array(
576
                                    'item_id' => $newID,
577
                                    'del_enabled' => 1,
578
                                    'del_type' => $post_to_be_deleted_after_x_views > 0 ? 1 : 2, //1 = numeric : 2 = date
579
                                    'del_value' => $post_to_be_deleted_after_x_views > 0 ? $post_to_be_deleted_after_x_views : dateToStamp($post_to_be_deleted_after_date, $SETTINGS),
580
                                    )
581
                            );
582
                        }
583
                    }
584
585
                    // Get readable list of restriction
586
                    $listOfRestricted = $oldRestrictionList = '';
587
                    if (is_array($post_restricted_to) === true
588
                        && count($post_restricted_to) > 0
589
                        && isset($SETTINGS['restricted_to']) === true
590
                        && (int) $SETTINGS['restricted_to'] === 1
591
                    ) {
592
                        foreach ($post_restricted_to as $userRest) {
593
                            if (empty($userRest) === false) {
594
                                $dataTmp = DB::queryfirstrow('SELECT login FROM '.prefixTable('users').' WHERE id= %i', $userRest);
595
                                if (empty($listOfRestricted)) {
596
                                    $listOfRestricted = $dataTmp['login'];
597
                                } else {
598
                                    $listOfRestricted .= ';'.$dataTmp['login'];
599
                                }
600
                            }
601
                        }
602
                    }
603
                    if ($data['restricted_to'] !== $post_restricted_to
604
                        && (int) $SETTINGS['restricted_to'] === 1
605
                    ) {
606
                        if (empty($data['restricted_to']) === false) {
607
                            foreach (explode(';', $data['restricted_to']) as $userRest) {
608
                                if (empty($userRest) === false) {
609
                                    $dataTmp = DB::queryfirstrow('SELECT login FROM '.prefixTable('users').' WHERE id= '.$userRest);
610
                                    if (empty($oldRestrictionList) === true) {
611
                                        $oldRestrictionList = $dataTmp['login'];
612
                                    } else {
613
                                        $oldRestrictionList .= ';'.$dataTmp['login'];
614
                                    }
615
                                }
616
                            }
617
                        }
618
                    }
619
                    // Manage retriction_to_roles
620
                    if (is_array($post_restricted_to_roles) === true
621
                        && count($post_restricted_to_roles) > 0
622
                        && isset($SETTINGS['restricted_to_roles']) === true
623
                        && (int) $SETTINGS['restricted_to_roles'] === 1
624
                    ) {
625
                        // add roles for item
626
                        if (is_array($post_restricted_to_roles) === true
627
                            && count($post_restricted_to_roles) > 0
628
                        ) {
629
                            foreach ($post_restricted_to_roles as $role) {
630
                                if (count($role) > 1) {
631
                                    $role = $role[1];
632
                                } else {
633
                                    $role = $role[0];
634
                                }
635
                                DB::insert(
636
                                    prefixTable('restriction_to_roles'),
637
                                    array(
638
                                        'role_id' => $role,
639
                                        'item_id' => $post_item_id,
640
                                        )
641
                                );
642
                            }
643
                        }
644
                    }
645
646
                    // log
647
                    logItems(
648
                        $SETTINGS,
649
                        $newID,
650
                        $post_label,
651
                        $_SESSION['user_id'],
652
                        'at_creation',
653
                        $_SESSION['login']
654
                    );
655
656
                    // Add tags
657
                    $tags = explode(' ', $post_tags);
658
                    foreach ($tags as $tag) {
659
                        if (empty($tag) === false) {
660
                            DB::insert(
661
                                prefixTable('tags'),
662
                                array(
663
                                    'item_id' => $newID,
664
                                    'tag' => strtolower($tag),
665
                                    )
666
                            );
667
                        }
668
                    }
669
670
                    // Check if any files have been added
671
                    if (empty($post_uploaded_file_id) === false) {
672
                        $rows = DB::query(
673
                            'SELECT id
674
                            FROM '.prefixTable('files').'
675
                            WHERE id_item = %s',
676
                            $post_uploaded_file_id
677
                        );
678
                        foreach ($rows as $record) {
679
                            // update item_id in files table
680
                            DB::update(
681
                                prefixTable('files'),
682
                                array(
683
                                    'id_item' => $newID,
684
                                    'confirmed' => 1,
685
                                    ),
686
                                'id=%i',
687
                                $record['id']
688
                            );
689
                        }
690
                    }
691
692
                    // Announce by email?
693
                    if (empty($post_diffusion_list) === false) {
694
                        // get links url
695
                        if (empty($SETTINGS['email_server_url'])) {
696
                            $SETTINGS['email_server_url'] = $SETTINGS['cpassman_url'];
697
                        }
698
699
                        // Get path
700
                        $path = geItemReadablePath(
701
                            $post_folder_id,
702
                            $label,
703
                            $SETTINGS
704
                        );
705
706
                        // send email
707
                        foreach (explode(';', $post_diffusion_list) as $emailAddress) {
708
                            if (empty($emailAddress) === false) {
709
                                // send it
710
                                sendEmail(
711
                                    langHdl('email_subject'),
712
                                    str_replace(
713
                                        array('#label', '#link'),
714
                                        array($path, $SETTINGS['email_server_url'].'/index.php?page=items&group='.$post_folder_id.'&id='.$newID.$txt['email_body3']),
715
                                        langHdl('new_item_email_body')
716
                                    ),
717
                                    $emailAddress,
718
                                    $SETTINGS,
719
                                    str_replace(
720
                                        array('#label', '#link'),
721
                                        array($path, $SETTINGS['email_server_url'].'/index.php?page=items&group='.$post_folder_id.'&id='.$newID.$txt['email_body3']),
722
                                        langHdl('new_item_email_body')
723
                                    )
724
                                );
725
                            }
726
                        }
727
                    }
728
                } elseif (isset($SETTINGS['duplicate_item']) === true
729
                    && (int) $SETTINGS['duplicate_item'] === 0
730
                    && (int) $itemExists === 1
731
                ) {
732
                    // Encrypt data to return
733
                    echo prepareExchangedData(
734
                        array(
735
                            'error' => true,
736
                            'message' => langHdl('error_item_exists'),
737
                        ),
738
                        'encode'
739
                    );
740
                    break;
741
                }
742
743
                // Add item to CACHE table if new item has been created
744
                if (isset($newID) === true) {
745
                    updateCacheTable(
746
                        'add_value',
747
                        $SETTINGS,
748
                        $newID
749
                    );
750
                }
751
752
                $arrData = array(
753
                    'error' => false,
754
                );
755
            } else {
756
                // an error appears on JSON format
757
                echo prepareExchangedData(
758
                    array(
759
                        'error' => true,
760
                        'message' => langHdl('json_error_format'),
761
                    ),
762
                    'encode'
763
                );
764
            }
765
766
            // Encrypt data to return
767
            echo prepareExchangedData($arrData, 'encode');
768
            break;
769
770
        /*
771
        * CASE
772
        * update an ITEM
773
        */
774
        case 'update_item':
775
            // Check KEY and rights
776
            if ($post_key !== $_SESSION['key']) {
777
                echo prepareExchangedData(
778
                    array(
779
                        'error' => true,
780
                        'message' => langHdl('key_is_not_correct'),
781
                    ),
782
                    'encode'
783
                );
784
                break;
785
            } elseif ($_SESSION['user_read_only'] === true) {
786
                echo prepareExchangedData(
787
                    array(
788
                        'error' => true,
789
                        'message' => langHdl('error_not_allowed_to'),
790
                    ),
791
                    'encode'
792
                );
793
                break;
794
            }
795
796
            // init
797
            $reloadPage = false;
798
            $returnValues = array();
799
            // decrypt and retreive data in JSON format
800
            $dataReceived = prepareExchangedData(
801
                $post_data,
802
                'decode'
803
            );
804
805
            if (count($dataReceived) > 0) {
806
                // Prepare variables
807
                $itemInfos = array();
808
                $post_label = filter_var(($dataReceived['label']), FILTER_SANITIZE_STRING);
809
                $post_url = filter_var(htmlspecialchars_decode($dataReceived['url']), FILTER_SANITIZE_URL);
810
                $post_password = $original_pw = htmlspecialchars_decode($dataReceived['pw']);
811
                $post_login = filter_var(htmlspecialchars_decode($dataReceived['login']), FILTER_SANITIZE_STRING);
812
                $post_tags = htmlspecialchars_decode($dataReceived['tags']);
813
                $post_email = filter_var(htmlspecialchars_decode($dataReceived['email']), FILTER_SANITIZE_EMAIL);
814
                $post_template_id = filter_var($dataReceived['template_id'], FILTER_SANITIZE_NUMBER_INT);
815
                $post_item_id = filter_var($dataReceived['id'], FILTER_SANITIZE_NUMBER_INT);
816
                $post_anyone_can_modify = filter_var($dataReceived['anyone_can_modify'], FILTER_SANITIZE_NUMBER_INT);
817
                $post_complexity_level = filter_var($dataReceived['complexity_level'], FILTER_SANITIZE_NUMBER_INT);
818
                $post_folder_id = filter_var($dataReceived['folder'], FILTER_SANITIZE_NUMBER_INT);
819
                $post_salt_key_set = isset($_SESSION['user_settings']['session_psk']) === true
820
                    && empty($_SESSION['user_settings']['session_psk']) === false ? '1' : '0';
821
                $post_folder_is_personal = filter_var($dataReceived['folder_is_personal'], FILTER_SANITIZE_NUMBER_INT);
822
                $post_restricted_to = filter_var_array(
823
                    $dataReceived['restricted_to'],
824
                    FILTER_SANITIZE_STRING
825
                );
826
                $post_restricted_to_roles = filter_var_array(
827
                    $dataReceived['restricted_to_roles'],
828
                    FILTER_SANITIZE_STRING
829
                );
830
                $post_diffusion_list = filter_var_array(
831
                    $dataReceived['diffusion_list'],
832
                    FILTER_SANITIZE_STRING
833
                );
834
                $post_to_be_deleted_after_x_views = filter_var(
835
                    $dataReceived['to_be_deleted_after_x_views'],
836
                    FILTER_SANITIZE_NUMBER_INT
837
                );
838
                $post_to_be_deleted_after_date = filter_var(
839
                    $dataReceived['to_be_deleted_after_date'],
840
                    FILTER_SANITIZE_STRING
841
                );
842
                $post_fields = (
843
                    filter_var_array(
844
                        $dataReceived['fields'],
845
                        FILTER_SANITIZE_STRING
846
                    )
847
                );
848
                $post_description = ($dataReceived['description']);
849
850
                //-> DO A SET OF CHECKS
851
                // Perform a check in case of Read-Only user creating an item in his PF
852
                if ($_SESSION['user_read_only'] === true
853
                    && (in_array($post_folder_id, $_SESSION['personal_folders']) === false
854
                    || $post_folder_is_personal !== 1)
855
                ) {
856
                    echo prepareExchangedData(
857
                        array(
858
                            'error' => true,
859
                            'message' => langHdl('error_not_allowed_to_access_this_folder'),
860
                        ),
861
                        'encode'
862
                    );
863
                    break;
864
                }
865
866
                // Check PWD EMPTY
867
                if (empty($pw) === true
868
                    && isset($_SESSION['user_settings']['create_item_without_password']) === true
869
                    && (int) $_SESSION['user_settings']['create_item_without_password'] !== 1
870
                ) {
871
                    echo prepareExchangedData(
872
                        array(
873
                            'error' => true,
874
                            'message' => langHdl('error_pw'),
875
                        ),
876
                        'encode'
877
                    );
878
                    break;
879
                }
880
881
                // Need info in DB
882
                // About special settings
883
                $dataFolderSettings = DB::queryFirstRow(
884
                    'SELECT bloquer_creation, bloquer_modification, personal_folder
885
                    FROM '.prefixTable('nested_tree').' 
886
                    WHERE id = %i',
887
                    $post_folder_id
888
                );
889
                $itemInfos['personal_folder'] = (int) $dataFolderSettings['personal_folder'];
890
                if ($itemInfos['personal_folder'] === '1') {
0 ignored issues
show
introduced by
The condition $itemInfos['personal_folder'] === '1' is always false.
Loading history...
891
                    $itemInfos['no_complex_check_on_modification'] = 1;
892
                    $itemInfos['no_complex_check_on_creation'] = 1;
893
                } else {
894
                    $itemInfos['no_complex_check_on_modification'] = (int) $dataFolderSettings['bloquer_modification'];
895
                    $itemInfos['no_complex_check_on_creation'] = (int) $dataFolderSettings['bloquer_creation'];
896
                }
897
                // Get folder complexity
898
                $folderComplexity = DB::queryfirstrow(
899
                    'SELECT valeur
900
                    FROM '.prefixTable('misc').'
901
                    WHERE type = %s AND intitule = %i',
902
                    'complex',
903
                    $post_folder_id
904
                );
905
                $itemInfos['requested_folder_complexity'] = (int) $folderComplexity['valeur'];
906
907
                // Check COMPLEXITY
908
                if ($post_complexity_level < $itemInfos['requested_folder_complexity']) {
909
                    echo prepareExchangedData(
910
                        array(
911
                            'error' => true,
912
                            'message' => langHdl('error_security_level_not_reached'),
913
                        ),
914
                        'encode'
915
                    );
916
                    break;
917
                }
918
919
                // Check length
920
                if (strlen($post_password) > $SETTINGS['pwd_maximum_length']) {
921
                    echo prepareExchangedData(
922
                        array(
923
                            'error' => true,
924
                            'message' => langHdl('error_pw_too_long'),
925
                        ),
926
                        'encode'
927
                    );
928
                    break;
929
                }
930
931
                // ./ END
932
933
                // Init
934
                $arrayOfChanges = array();
935
936
                // Get all informations for this item
937
                $dataItem = DB::queryfirstrow(
938
                    'SELECT *
939
                    FROM '.prefixTable('items').' as i
940
                    INNER JOIN '.prefixTable('log_items').' as l ON (l.id_item = i.id)
941
                    WHERE i.id=%i AND l.action = %s',
942
                    $post_item_id,
943
                    'at_creation'
944
                );
945
                // check that actual user can access this item
946
                $restrictionActive = true;
947
                $restrictedTo = array_filter(explode(';', $dataItem['restricted_to']));
948
                if (in_array($_SESSION['user_id'], $restrictedTo) === true) {
949
                    $restrictionActive = false;
950
                }
951
                if (empty($dataItem['restricted_to']) === true) {
952
                    $restrictionActive = false;
953
                }
954
955
                if ((in_array($dataItem['id_tree'], $_SESSION['groupes_visibles']) === true
956
                    && ((int) $dataItem['perso'] === 0
957
                    || ((int) $dataItem['perso'] === 1
958
                    && (int) $_SESSION['user_id'] === (int) $dataItem['id_user']))
959
                    && $restrictionActive === false
960
                    )
961
                    ||
962
                    (
963
                        isset($SETTINGS['anyone_can_modify']) === true
964
                        && (int) $SETTINGS['anyone_can_modify'] === 1
965
                        && (int) $dataItem['anyone_can_modify'] === 1
966
                        && (in_array($dataItem['id_tree'], $_SESSION['groupes_visibles']) === true
967
                        || (int) $_SESSION['is_admin'] === 1)
968
                        && $restrictionActive === false
969
                    )
970
                    ||
971
                    (null !== $post_folder_id
972
                    && isset($_SESSION['list_restricted_folders_for_items'][$post_folder_id]) === true
973
                    && in_array($post_id, $_SESSION['list_restricted_folders_for_items'][$post_folder_id]) === true
974
                    //&& $post_restricted === '1'
975
                    && $restrictionActive === false)
976
                ) {
977
                    // Get existing values
978
                    $data = DB::queryfirstrow(
979
                        'SELECT i.id as id, i.label as label, i.description as description, i.pw as pw, i.url as url, i.id_tree as id_tree, i.perso as perso, i.login as login, 
980
                        i.inactif as inactif, i.restricted_to as restricted_to, i.anyone_can_modify as anyone_can_modify, i.email as email, i.notification as notification,
981
                        u.login as user_login, u.email as user_email
982
                        FROM '.prefixTable('items').' as i
983
                        INNER JOIN '.prefixTable('log_items').' as l ON (i.id=l.id_item)
984
                        INNER JOIN '.prefixTable('users').' as u ON (u.id=l.id_user)
985
                        WHERE i.id=%i',
986
                        $post_item_id
987
                    );
988
989
                    // Should we log a password change?
990
                    $userKey = DB::queryFirstRow(
991
                        'SELECT share_key
992
                        FROM '.prefixTable('sharekeys_items').'
993
                        WHERE user_id = %i AND object_id = %i',
994
                        $_SESSION['user_id'],
995
                        $post_item_id
996
                    );
997
                    if (DB::count() === 0 || empty($data['pw']) === true) {
998
                        // No share key found
999
                        $pw = '';
1000
                    } else {
1001
                        $pw = base64_decode(doDataDecryption(
1002
                            $data['pw'],
1003
                            decryptUserObjectKey(
1004
                                $userKey['share_key'],
1005
                                $_SESSION['user']['private_key']
1006
                            )
1007
                        ));
1008
                    }
1009
1010
                    if ($post_password !== $pw) {
1011
                        logItems(
1012
                            $SETTINGS,
1013
                            $post_item_id,
1014
                            $post_label,
1015
                            $_SESSION['user_id'],
1016
                            'at_modification',
1017
                            $_SESSION['login'],
1018
                            'at_pw',
1019
                            'defuse'
1020
                        );
1021
                    }
1022
1023
                    // encrypt PW
1024
                    if ((isset($_SESSION['user_settings']['create_item_without_password']) === true
1025
                        && (int) $_SESSION['user_settings']['create_item_without_password'] !== 1)
1026
                        || empty($post_password) === false
1027
                    ) {
1028
                        //-----
1029
                        // NEW ENCRYPTION
1030
                        $cryptedStuff = doDataEncryption($post_password);
1031
1032
                        $encrypted_password = $cryptedStuff['encrypted'];
1033
1034
                        // Create sharekeys for users
1035
                        storeUsersShareKey(
1036
                            prefixTable('sharekeys_items'),
1037
                            $post_folder_is_personal,
1038
                            $post_folder_id,
1039
                            $post_item_id,
1040
                            $cryptedStuff['objectKey'],
1041
                            $SETTINGS
1042
                        );
1043
                    } else {
1044
                        $encrypted_password = '';
1045
                    }
1046
1047
                    // ---Manage tags
1048
                    // deleting existing tags for this item
1049
                    DB::delete(
1050
                        prefixTable('tags'),
1051
                        'item_id = %i',
1052
                        $post_item_id
1053
                    );
1054
1055
                    // Add new tags
1056
                    $return_tags = '';
1057
                    $post_tags = explode(' ', $post_tags);
1058
                    foreach ($post_tags as $tag) {
1059
                        if (empty($tag) === false) {
1060
                            // save in DB
1061
                            DB::insert(
1062
                                prefixTable('tags'),
1063
                                array(
1064
                                    'item_id' => $post_item_id,
1065
                                    'tag' => strtolower($tag),
1066
                                )
1067
                            );
1068
                        }
1069
                    }
1070
1071
                    // update item
1072
                    DB::update(
1073
                        prefixTable('items'),
1074
                        array(
1075
                            'label' => $post_label,
1076
                            'description' => $post_description,
1077
                            'pw' => $encrypted_password,
1078
                            'email' => $post_email,
1079
                            'login' => $post_login,
1080
                            'url' => $post_url,
1081
                            'id_tree' => $post_folder_id === 'undefined' ? $dataItem['id_tree'] : $post_folder_id,
1082
                            'restricted_to' => empty($post_restricted_to) === true || count($post_restricted_to) === 0 ? '' : implode(';', $post_restricted_to),
1083
                            'anyone_can_modify' => (int) $post_anyone_can_modify,
1084
                            'complexity_level' => (int) $post_complexity_level,
1085
                            'encryption_type' => 'defuse',
1086
                            'perso' => in_array($post_folder_id, $_SESSION['personal_folders']) === true ? 1 : 0,
1087
                            ),
1088
                        'id=%i',
1089
                        $post_item_id
1090
                    );
1091
1092
                    // update fields
1093
                    if (isset($SETTINGS['item_extra_fields']) === true
1094
                        && (int) $SETTINGS['item_extra_fields'] === 1
1095
                        && empty($post_fields) === false
1096
                    ) {
1097
                        foreach ($post_fields as $field) {
1098
                            if (empty($field['value']) === false) {
1099
                                $dataTmpCat = DB::queryFirstRow(
1100
                                    'SELECT c.id AS id, c.title AS title, i.data AS data, i.data_iv AS data_iv,
1101
                                    i.encryption_type AS encryption_type, c.encrypted_data AS encrypted_data,
1102
                                    c.masked AS masked, i.id AS field_item_id
1103
                                    FROM '.prefixTable('categories_items').' AS i
1104
                                    INNER JOIN '.prefixTable('categories').' AS c ON (i.field_id=c.id)
1105
                                    WHERE i.field_id = %i AND i.item_id = %i',
1106
                                    $field['id'],
1107
                                    $post_item_id
1108
                                );
1109
1110
                                // store Field text in DB
1111
                                if (DB::count() === 0) {
1112
                                    // The data for this foeld doesn't exist
1113
                                    // It has to be added
1114
1115
                                    // Perform new query
1116
                                    $dataTmpCat = DB::queryFirstRow(
1117
                                        'SELECT id, title, encrypted_data, masked
1118
                                        FROM '.prefixTable('categories').'
1119
                                        WHERE id = %i',
1120
                                        $field['id']
1121
                                    );
1122
1123
                                    // store field text
1124
                                    DB::insert(
1125
                                        prefixTable('categories_items'),
1126
                                        array(
1127
                                            'item_id' => $post_item_id,
1128
                                            'field_id' => $field['id'],
1129
                                            'data' => $field['value'],
1130
                                            'data_iv' => '',
1131
                                            'encryption_type' => 'not_set',
1132
                                        )
1133
                                    );
1134
1135
                                    $newId = DB::insertId();
1136
1137
                                    // Should we encrypt the data
1138
                                    if ((int) $dataTmpCat['encrypted_data'] === 1) {
1139
                                        $cryptedStuff = doDataEncryption($field['value']);
1140
1141
                                        // Create sharekeys for users
1142
                                        storeUsersShareKey(
1143
                                            prefixTable('sharekeys_fields'),
1144
                                            $post_folder_is_personal,
1145
                                            $post_folder_id,
1146
                                            $newId,
1147
                                            $cryptedStuff['objectKey'],
1148
                                            $SETTINGS
1149
                                        );
1150
1151
                                        // update value
1152
                                        DB::update(
1153
                                            prefixTable('categories_items'),
1154
                                            array(
1155
                                                'data' => $cryptedStuff['encrypted'],
1156
                                                'data_iv' => '',
1157
                                                'encryption_type' => TP_ENCRYPTION_NAME,
1158
                                            ),
1159
                                            'id = %i',
1160
                                            $newId
1161
                                        );
1162
                                    }
1163
1164
                                    // Store updates performed
1165
                                    array_push(
1166
                                        $arrayOfChanges,
1167
                                        $dataTmpCat['title']
1168
                                    );
1169
1170
                                    // update LOG
1171
                                    logItems(
1172
                                        $SETTINGS,
1173
                                        $post_item_id,
1174
                                        $post_label,
1175
                                        $_SESSION['user_id'],
1176
                                        'at_modification',
1177
                                        $_SESSION['login'],
1178
                                        'at_field : '.$dataTmpCat['title'].' : '.$field['value']
1179
                                    );
1180
                                } else {
1181
                                    // compare the old and new value
1182
                                    if ($dataTmpCat['encryption_type'] !== 'not_set') {
1183
                                        // Get user sharekey for this field
1184
                                        $userKey = DB::queryFirstRow(
1185
                                            'SELECT share_key
1186
                                            FROM '.prefixTable('sharekeys_fields').'
1187
                                            WHERE user_id = %i AND object_id = %i',
1188
                                            $_SESSION['user_id'],
1189
                                            $dataTmpCat['field_item_id']
1190
                                        );
1191
1192
                                        // Decrypt the current value
1193
                                        $oldVal = base64_decode(doDataDecryption(
1194
                                            $dataTmpCat['data'],
1195
                                            decryptUserObjectKey(
1196
                                                $userKey['share_key'],
1197
                                                $_SESSION['user']['private_key']
1198
                                            )
1199
                                        ));
1200
                                    } else {
1201
                                        $oldVal = $dataTmpCat['data'];
1202
                                    }
1203
1204
                                    // Compare both values to see if any change was done
1205
                                    if ($field['value'] !== $oldVal) {
1206
                                        // The strings are different
1207
1208
                                        // Should we encrypt the data
1209
                                        if ((int) $dataTmpCat['encrypted_data'] === 1) {
1210
                                            $cryptedStuff = doDataEncryption($field['value']);
1211
                                            $encrypt['string'] = $cryptedStuff['encrypted'];
1212
                                            $encrypt['type'] = TP_ENCRYPTION_NAME;
1213
1214
                                            // Create sharekeys for users
1215
                                            storeUsersShareKey(
1216
                                                prefixTable('sharekeys_fields'),
1217
                                                $post_folder_is_personal,
1218
                                                $post_folder_id,
1219
                                                $dataTmpCat['field_item_id'],
1220
                                                $cryptedStuff['objectKey'],
1221
                                                $SETTINGS
1222
                                            );
1223
                                        } else {
1224
                                            $encrypt['string'] = $field['value'];
1225
                                            $encrypt['type'] = 'not_set';
1226
                                        }
1227
1228
                                        // update value
1229
                                        DB::update(
1230
                                            prefixTable('categories_items'),
1231
                                            array(
1232
                                                'data' => $encrypt['string'],
1233
                                                'data_iv' => '',
1234
                                                'encryption_type' => $encrypt['type'],
1235
                                            ),
1236
                                            'item_id = %i AND field_id = %i',
1237
                                            $post_item_id,
1238
                                            $field['id']
1239
                                        );
1240
1241
                                        // Store updates performed
1242
                                        array_push(
1243
                                            $arrayOfChanges,
1244
                                            $dataTmpCat['title']
1245
                                        );
1246
1247
                                        // update LOG
1248
                                        logItems(
1249
                                            $SETTINGS,
1250
                                            $post_item_id,
1251
                                            $post_label,
1252
                                            $_SESSION['user_id'],
1253
                                            'at_modification',
1254
                                            $_SESSION['login'],
1255
                                            'at_field : '.$dataTmpCat['title'].' => '.$oldVal
1256
                                        );
1257
                                    }
1258
                                }
1259
                            } else {
1260
                                if (empty($field_data[1]) === true) {
1261
                                    DB::delete(
1262
                                        prefixTable('categories_items'),
1263
                                        'item_id = %i AND field_id = %s',
1264
                                        $post_item_id,
1265
                                        $field['id']
1266
                                    );
1267
                                }
1268
                            }
1269
                        }
1270
                    }
1271
1272
                    // If template enable, is there a main one selected?
1273
                    if (isset($SETTINGS['item_creation_templates']) === true
1274
                        && $SETTINGS['item_creation_templates'] === '1'
1275
                        && isset($post_template_id) === true
1276
                    ) {
1277
                        DB::queryFirstRow(
1278
                            'SELECT *
1279
                            FROM '.prefixTable('templates').'
1280
                            WHERE item_id = %i',
1281
                            $post_item_id
1282
                        );
1283
                        if (DB::count() === 0 && empty($post_template_id) === false) {
1284
                            // store field text
1285
                            DB::insert(
1286
                                prefixTable('templates'),
1287
                                array(
1288
                                    'item_id' => $post_item_id,
1289
                                    'category_id' => $post_template_id,
1290
                                )
1291
                            );
1292
                        } else {
1293
                            // Delete if empty
1294
                            if (empty($post_template_id) === true) {
1295
                                DB::delete(
1296
                                    prefixTable('templates'),
1297
                                    'item_id = %i',
1298
                                    $post_item_id
1299
                                );
1300
                            } else {
1301
                                // Update value
1302
                                DB::update(
1303
                                    prefixTable('templates'),
1304
                                    array(
1305
                                        'category_id' => $post_template_id,
1306
                                    ),
1307
                                    'item_id = %i',
1308
                                    $post_item_id
1309
                                );
1310
                            }
1311
                        }
1312
                    }
1313
1314
                    // Update automatic deletion - Only by the creator of the Item
1315
                    if (isset($SETTINGS['enable_delete_after_consultation']) === true
1316
                        && (int) $SETTINGS['enable_delete_after_consultation'] === 1
1317
                    ) {
1318
                        // check if elem exists in Table. If not add it or update it.
1319
                        DB::query(
1320
                            'SELECT *
1321
                            FROM '.prefixTable('automatic_del').'
1322
                            WHERE item_id = %i',
1323
                            $post_item_id
1324
                        );
1325
1326
                        if (DB::count() === 0) {
1327
                            // No automatic deletion for this item
1328
                            if (empty($post_to_be_deleted_after_date) === false
1329
                                || (int) $post_to_be_deleted_after_x_views > 0
1330
                            ) {
1331
                                // Automatic deletion to be added
1332
                                DB::insert(
1333
                                    prefixTable('automatic_del'),
1334
                                    array(
1335
                                        'item_id' => $post_item_id,
1336
                                        'del_enabled' => 1,
1337
                                        'del_type' => empty($post_to_be_deleted_after_x_views) === false ?
1338
                                            1 : 2, //1 = numeric : 2 = date
1339
                                        'del_value' => empty($post_to_be_deleted_after_x_views) === false ?
1340
                                            (int) $post_to_be_deleted_after_x_views :
1341
                                            dateToStamp($post_to_be_deleted_after_date, $SETTINGS),
1342
                                        )
1343
                                );
1344
1345
                                // Store updates performed
1346
                                array_push(
1347
                                    $arrayOfChanges,
1348
                                    langHdl('automatic_deletion_engaged').': '.langHdl('enabled')
1349
                                );
1350
1351
                                // update LOG
1352
                                logItems(
1353
                                    $SETTINGS,
1354
                                    $post_item_id,
1355
                                    $post_label,
1356
                                    $_SESSION['user_id'],
1357
                                    'at_modification',
1358
                                    $_SESSION['login'],
1359
                                    'at_automatic_del : enabled'
1360
                                );
1361
                            }
1362
                        } else {
1363
                            // Automatic deletion exists for this item
1364
                            if (empty($post_to_be_deleted_after_date) === false
1365
                                || (int) $post_to_be_deleted_after_x_views > 0
1366
                            ) {
1367
                                // Update automatic deletion
1368
                                DB::update(
1369
                                    prefixTable('automatic_del'),
1370
                                    array(
1371
                                        'del_type' => empty($post_to_be_deleted_after_x_views) === false ?
1372
                                            1 : 2, //1 = numeric : 2 = date
1373
                                        'del_value' => empty($post_to_be_deleted_after_x_views) === false ?
1374
                                            $post_to_be_deleted_after_x_views :
1375
                                            dateToStamp($post_to_be_deleted_after_date, $SETTINGS),
1376
                                        ),
1377
                                    'item_id = %i',
1378
                                    $post_item_id
1379
                                );
1380
                            } else {
1381
                                // delete automatic deleteion for this item
1382
                                DB::delete(
1383
                                    prefixTable('automatic_del'),
1384
                                    'item_id = %i',
1385
                                    $post_item_id
1386
                                );
1387
1388
                                // Store updates performed
1389
                                array_push(
1390
                                    $arrayOfChanges,
1391
                                    langHdl('automatic_deletion_engaged').': '.langHdl('disabled')
1392
                                );
1393
1394
                                // update LOG
1395
                                logItems(
1396
                                    $SETTINGS,
1397
                                    $post_item_id,
1398
                                    $post_label,
1399
                                    $_SESSION['user_id'],
1400
                                    'at_modification2',
1401
                                    $_SESSION['login'],
1402
                                    'at_automatic_del : disabled'
1403
                                );
1404
                            }
1405
                        }
1406
                    }
1407
1408
                    // get readable list of restriction
1409
                    $listOfRestricted = $oldRestrictionList = '';
1410
                    $arrayOfUsersRestriction = array();
1411
                    $arrayOfUsersIdRestriction = array();
1412
                    $diffUsersRestiction = array();
1413
                    $diffRolesRestiction = array();
1414
                    if (is_array($post_restricted_to) === true
1415
                        && count($post_restricted_to) > 0
1416
                        && isset($SETTINGS['restricted_to']) === true
1417
                        && $SETTINGS['restricted_to'] === '1'
1418
                    ) {
1419
                        foreach ($post_restricted_to as $userId) {
1420
                            if (empty($userId) === false) {
1421
                                $dataTmp = DB::queryfirstrow(
1422
                                    'SELECT id, name, lastname
1423
                                    FROM '.prefixTable('users').'
1424
                                    WHERE id= %i',
1425
                                    $userId
1426
                                );
1427
1428
                                // Add to array
1429
                                array_push(
1430
                                    $arrayOfUsersRestriction,
1431
                                    $dataTmp['name'].' '.$dataTmp['lastname']
1432
                                );
1433
                                array_push(
1434
                                    $arrayOfUsersIdRestriction,
1435
                                    $dataTmp['id']
1436
                                );
1437
                            }
1438
                        }
1439
                    }
1440
                    if ((int) $SETTINGS['restricted_to'] === 1) {
1441
                        $diffUsersRestiction = array_diff(
1442
                            empty($data['restricted_to']) === false ?
1443
                                explode(';', $data['restricted_to']) :
1444
                                array(),
1445
                            $arrayOfUsersIdRestriction
1446
                        );
1447
                    }
1448
1449
                    // Manage retriction_to_roles
1450
                    if (is_array($post_restricted_to_roles) === true
1451
                        && count($post_restricted_to_roles) > 0
1452
                        && isset($SETTINGS['restricted_to_roles']) === true
1453
                        && (int) $SETTINGS['restricted_to_roles'] === 1
1454
                    ) {
1455
                        // Init
1456
                        $arrayOfRestrictionRolesOld = array();
1457
                        $arrayOfRestrictionRoles = array();
1458
1459
                        // get values before deleting them
1460
                        $rows = DB::query(
1461
                            'SELECT t.title, t.id AS id
1462
                            FROM '.prefixTable('roles_title').' as t
1463
                            INNER JOIN '.prefixTable('restriction_to_roles').' as r ON (t.id=r.role_id)
1464
                            WHERE r.item_id = %i
1465
                            ORDER BY t.title ASC',
1466
                            $post_item_id
1467
                        );
1468
                        foreach ($rows as $record) {
1469
                            // Add to array
1470
                            array_push(
1471
                                $arrayOfRestrictionRolesOld,
1472
                                $record['title']
1473
                            );
1474
                        }
1475
                        // delete previous values
1476
                        DB::delete(
1477
                            prefixTable('restriction_to_roles'),
1478
                            'item_id = %i',
1479
                            $post_item_id
1480
                        );
1481
1482
                        // add roles for item
1483
                        if (is_array($post_restricted_to_roles) === true
1484
                            && count($post_restricted_to_roles) > 0
1485
                        ) {
1486
                            foreach ($post_restricted_to_roles as $role) {
1487
                                DB::insert(
1488
                                    prefixTable('restriction_to_roles'),
1489
                                    array(
1490
                                        'role_id' => $role,
1491
                                        'item_id' => $post_item_id,
1492
                                        )
1493
                                );
1494
                                $dataTmp = DB::queryfirstrow(
1495
                                    'SELECT title
1496
                                    FROM '.prefixTable('roles_title').'
1497
                                    WHERE id = %i',
1498
                                    $role
1499
                                );
1500
1501
                                // Add to array
1502
                                array_push(
1503
                                    $arrayOfRestrictionRoles,
1504
                                    $dataTmp['title']
1505
                                );
1506
                            }
1507
1508
                            if ((int) $SETTINGS['restricted_to'] === 1) {
1509
                                $diffRolesRestiction = array_diff(
1510
                                    $arrayOfRestrictionRoles,
1511
                                    $arrayOfRestrictionRolesOld
1512
                                );
1513
                            }
1514
                        }
1515
                    }
1516
                    // Update CACHE table
1517
                    updateCacheTable('update_value', $SETTINGS, $post_item_id);
1518
1519
                    //---- Log all modifications done ----
1520
1521
                    // RESTRICTIONS
1522
                    if (count($diffRolesRestiction) > 0 || count($diffUsersRestiction) > 0) {
1523
                        // Store updates performed
1524
                        array_push(
1525
                            $arrayOfChanges,
1526
                            langHdl('at_restriction')
1527
                        );
1528
1529
                        // Log
1530
                        logItems(
1531
                            $SETTINGS,
1532
                            $post_item_id,
1533
                            $post_label,
1534
                            $_SESSION['user_id'],
1535
                            'at_modification',
1536
                            $_SESSION['login'],
1537
                            'at_restriction : '.
1538
                                (count($diffUsersRestiction) > 0 ?
1539
                                    implode(', ', $arrayOfUsersRestriction).
1540
                                    (count($diffRolesRestiction) > 0 ? ', ' : '') :
1541
                                    ''
1542
                                ).(count($diffRolesRestiction) > 0 ? implode(', ', $arrayOfRestrictionRoles) : '')
1543
                        );
1544
                    }
1545
1546
                    // LABEL
1547
                    if ($data['label'] !== $post_label) {
1548
                        // Store updates performed
1549
                        array_push(
1550
                            $arrayOfChanges,
1551
                            langHdl('at_label')
1552
                        );
1553
1554
                        // Log
1555
                        logItems(
1556
                            $SETTINGS,
1557
                            $post_item_id,
1558
                            $post_label,
1559
                            $_SESSION['user_id'],
1560
                            'at_modification',
1561
                            $_SESSION['login'],
1562
                            'at_label : '.$data['label'].' => '.$post_label
1563
                        );
1564
                    }
1565
                    // LOGIN
1566
                    if ($data['login'] !== $post_login) {
1567
                        // Store updates performed
1568
                        array_push(
1569
                            $arrayOfChanges,
1570
                            langHdl('at_login')
1571
                        );
1572
1573
                        // Log
1574
                        logItems(
1575
                            $SETTINGS,
1576
                            $post_item_id,
1577
                            $post_label,
1578
                            $_SESSION['user_id'],
1579
                            'at_modification',
1580
                            $_SESSION['login'],
1581
                            'at_login : '.$data['login'].' => '.$post_login
1582
                        );
1583
                    }
1584
                    // EMAIL
1585
                    if (strcmp($data['email'], $post_email) !== 0) {
1586
                        // Store updates performed
1587
                        array_push(
1588
                            $arrayOfChanges,
1589
                            langHdl('at_email')
1590
                        );
1591
1592
                        // Log
1593
                        logItems(
1594
                            $SETTINGS,
1595
                            $post_item_id,
1596
                            $post_label,
1597
                            $_SESSION['user_id'],
1598
                            'at_modification',
1599
                            $_SESSION['login'],
1600
                            'at_email : '.$data['email'].' => '.$post_email
1601
                        );
1602
                    }
1603
                    // URL
1604
                    if ($data['url'] !== $post_url && $post_url !== 'http://') {
1605
                        // Store updates performed
1606
                        array_push(
1607
                            $arrayOfChanges,
1608
                            langHdl('at_url')
1609
                        );
1610
1611
                        // Log
1612
                        logItems(
1613
                            $SETTINGS,
1614
                            $post_item_id,
1615
                            $post_label,
1616
                            $_SESSION['user_id'],
1617
                            'at_modification',
1618
                            $_SESSION['login'],
1619
                            'at_url : '.$data['url'].' => '.$post_url
1620
                        );
1621
                    }
1622
                    // DESCRIPTION
1623
                    if (strcmp(md5($data['description']), md5($post_description)) !== 0) {
1624
                        // Store updates performed
1625
                        array_push(
1626
                            $arrayOfChanges,
1627
                            langHdl('at_description')
1628
                        );
1629
1630
                        // Log
1631
                        logItems(
1632
                            $SETTINGS,
1633
                            $post_item_id,
1634
                            $post_label,
1635
                            $_SESSION['user_id'],
1636
                            'at_modification',
1637
                            $_SESSION['login'],
1638
                            'at_description'
1639
                        );
1640
                    }
1641
                    // FOLDER
1642
                    if ($data['id_tree'] !== $post_folder_id) {
1643
                        // Get name of folders
1644
                        $dataTmp = DB::query('SELECT title FROM '.prefixTable('nested_tree').' WHERE id IN %li', array($data['id_tree'], $post_folder_id));
1645
1646
                        // Store updates performed
1647
                        array_push(
1648
                            $arrayOfChanges,
1649
                            langHdl('at_category')
1650
                        );
1651
1652
                        // Log
1653
                        logItems(
1654
                            $SETTINGS,
1655
                            $post_item_id,
1656
                            $post_label,
1657
                            $_SESSION['user_id'],
1658
                            'at_modification',
1659
                            $_SESSION['login'],
1660
                            'at_category : '.$dataTmp[0]['title'].' => '.$dataTmp[1]['title']
1661
                        );
1662
                        // ask for page reloading
1663
                        $reloadPage = true;
1664
                    }
1665
                    // ANYONE_CAN_MODIFY
1666
                    if ($post_anyone_can_modify !== $data['anyone_can_modify']) {
1667
                        // Store updates performed
1668
                        array_push(
1669
                            $arrayOfChanges,
1670
                            langHdl('at_anyoneconmodify').': '.
1671
                                    ((int) $post_anyone_can_modify === 0 ? langHdl('disabled') : langHdl('enabled'))
1672
                        );
1673
1674
                        // Log
1675
                        logItems(
1676
                            $SETTINGS,
1677
                            $post_item_id,
1678
                            $post_label,
1679
                            $_SESSION['user_id'],
1680
                            'at_modification',
1681
                            $_SESSION['login'],
1682
                            'at_anyoneconmodify : '.((int) $post_anyone_can_modify === 0 ? 'disabled' : 'enabled')
1683
                        );
1684
                    }
1685
1686
                    // Reload new values
1687
                    $dataItem = DB::queryfirstrow(
1688
                        'SELECT *
1689
                        FROM '.prefixTable('items').' as i
1690
                        INNER JOIN '.prefixTable('log_items').' as l ON (l.id_item = i.id)
1691
                        WHERE i.id = %i AND l.action = %s',
1692
                        $post_item_id,
1693
                        'at_creation'
1694
                    );
1695
                    // Reload History
1696
                    $history = '';
1697
                    $rows = DB::query(
1698
                        'SELECT l.date as date, l.action as action, l.raison as raison, u.login as login
1699
                        FROM '.prefixTable('log_items').' as l
1700
                        LEFT JOIN '.prefixTable('users').' as u ON (l.id_user=u.id)
1701
                        WHERE l.action <> %s AND id_item=%s',
1702
                        'at_shown',
1703
                        $post_item_id
1704
                    );
1705
                    foreach ($rows as $record) {
1706
                        $reason = explode(':', $record['raison']);
1707
                        if (count($reason) > 0) {
1708
                            $sentence = date($SETTINGS['date_format'].' '.$SETTINGS['time_format'], $record['date']).' - '
1709
                                .$record['login'].' - '.langHdl($record['action']).' - '
1710
                                .(empty($record['raison']) === false ?
1711
                                (count($reason) > 1 ? langHdl(trim($reason[0])).' : '.$reason[1]
1712
                                : langHdl(trim($reason[0]))) : '');
1713
                            if (empty($history)) {
1714
                                $history = $sentence;
1715
                            } else {
1716
                                $history .= '<br />'.$sentence;
1717
                            }
1718
                        }
1719
                    }
1720
1721
                    // TODO
1722
                    // decrypt PW
1723
                    if (empty($dataReceived['salt_key'])) {
1724
                        $encrypt = cryption(
1725
                            $dataItem['pw'],
1726
                            '',
1727
                            'encrypt',
1728
                            $SETTINGS
1729
                        );
1730
                    } else {
1731
                        $encrypt = cryption(
1732
                            $dataItem['pw'],
1733
                            $_SESSION['user_settings']['session_psk'],
1734
                            'encrypt',
1735
                            $SETTINGS
1736
                        );
1737
                    }
1738
1739
                    $pw = cleanString($encrypt['string']);
1740
                    // generate 2d key
1741
                    $_SESSION['key_tmp'] = bin2hex(GenerateCryptKey(16));
1742
1743
                    // Prepare files listing
1744
                    $files = $filesEdit = '';
1745
                    // launch query
1746
                    $rows = DB::query('SELECT id, name, file, extension FROM '.prefixTable('files').' WHERE id_item=%i', $post_item_id);
1747
                    foreach ($rows as $record) {
1748
                        // get icon image depending on file format
1749
                        $iconImage = fileFormatImage($record['extension']);
1750
1751
                        // If file is an image, then prepare lightbox. If not image, then prepare donwload
1752
                        if (in_array($record['extension'], TP_IMAGE_FILE_EXT)) {
1753
                            $files .= '<i class=\'fa fa-file-image-o\' /></i>&nbsp;<a class="image_dialog" href="#'.$record['id'].'" title="'.$record['name'].'">'.$record['name'].'</a><br />';
1754
                        } else {
1755
                            $files .= '<i class=\'fa fa-file-text-o\' /></i>&nbsp;<a href=\'sources/downloadFile.php?name='.urlencode($record['name']).'&type=sub&key='.$_SESSION['key'].'&key_tmp='.$_SESSION['key_tmp'].'&fileid='.$record['id'].'\' target=\'_blank\'>'.$record['name'].'</a><br />';
1756
                        }
1757
                        // Prepare list of files for edit dialogbox
1758
                        $filesEdit .= '<span id="span_edit_file_'.$record['id'].'"><span class="fa fa-'.$iconImage.'"></span>&nbsp;<span class="fa fa-eraser tip" style="cursor:pointer;"  onclick="delete_attached_file(\"'.$record['id'].'\")" title="'.langHdl('at_delete').'"></span>&nbsp;'.$record['name'].'</span><br />';
1759
                    }
1760
                    // Send email
1761
                    if (is_array($post_diffusion_list) === true && count($post_diffusion_list) > 0) {
1762
                        foreach (explode(';', $dataReceived['diffusion']) as $emailAddress) {
1763
                            if (empty($emailAddress) === false) {
1764
                                sendEmail(
1765
                                    langHdl('email_subject_item_updated'),
1766
                                    str_replace(
1767
                                        array('#item_label#', '#item_category#', '#item_id#', '#url#'),
1768
                                        array($post_label, $dataReceived['categorie'], $post_item_id, $SETTINGS['cpassman_url']),
1769
                                        langHdl('email_body_item_updated')
1770
                                    ),
1771
                                    $emailAddress,
1772
                                    $SETTINGS,
1773
                                    str_replace('#item_label#', $post_label, langHdl('email_bodyalt_item_updated'))
1774
                                );
1775
                            }
1776
                        }
1777
                    }
1778
1779
                    // Notifiy changes to the users
1780
                    notifyChangesToSubscribers($post_item_id, $post_label, $arrayOfChanges, $SETTINGS);
1781
1782
                    // Prepare some stuff to return
1783
                    $arrData = array(
1784
                        'error' => false,
1785
                        'message' => '',
1786
                        );
1787
                } else {
1788
                    echo prepareExchangedData(
1789
                        array(
1790
                            'error' => true,
1791
                            'message' => langHdl('error_not_allowed_to_edit_item'),
1792
                            'toto' => '1',
1793
                        ),
1794
                        'encode'
1795
                    );
1796
                    break;
1797
                }
1798
            } else {
1799
                // an error appears on JSON format
1800
                $arrData = array(
1801
                    'error' => true,
1802
                    'message' => 'ERR_JSON_FORMAT',
1803
                );
1804
            }
1805
            // return data
1806
            echo prepareExchangedData($arrData, 'encode');
1807
            break;
1808
1809
        /*
1810
          * CASE
1811
          * Copy an Item
1812
        */
1813
        case 'copy_item':
1814
            // Check KEY and rights
1815
            if ($post_key !== $_SESSION['key']) {
1816
                echo prepareExchangedData(
1817
                    array(
1818
                        'error' => true,
1819
                        'message' => langHdl('key_is_not_correct'),
1820
                    ),
1821
                    'encode'
1822
                );
1823
                break;
1824
            } elseif ($_SESSION['user_read_only'] === true) {
1825
                echo prepareExchangedData(
1826
                    array(
1827
                        'error' => true,
1828
                        'message' => langHdl('error_not_allowed_to'),
1829
                    ),
1830
                    'encode'
1831
                );
1832
                break;
1833
            }
1834
1835
            // decrypt and retreive data in JSON format
1836
            $dataReceived = prepareExchangedData(
1837
                $post_data,
1838
                'decode'
1839
            );
1840
1841
            // Prepare POST variables
1842
            $post_new_label = filter_var($dataReceived['new_label'], FILTER_SANITIZE_STRING);
1843
            $post_source_id = filter_var($dataReceived['source_id'], FILTER_SANITIZE_NUMBER_INT);
1844
            $post_dest_id = filter_var($dataReceived['dest_id'], FILTER_SANITIZE_NUMBER_INT);
1845
            $post_item_id = filter_var($dataReceived['item_id'], FILTER_SANITIZE_NUMBER_INT);
1846
1847
            // perform a check in case of Read-Only user creating an item in his PF
1848
            if ((int) $_SESSION['user_read_only'] === 1
1849
                && (in_array($post_source_id, $_SESSION['personal_folders']) === false
1850
                    || in_array($post_dest_id, $_SESSION['personal_folders']) === false)
1851
            ) {
1852
                echo prepareExchangedData(
1853
                    array(
1854
                        'error' => true,
1855
                        'message' => langHdl('error_not_allowed_to'),
1856
                    ),
1857
                    'encode'
1858
                );
1859
                break;
1860
            }
1861
1862
            // Init
1863
            $returnValues = '';
1864
            $pw = '';
1865
            $is_perso = 0;
1866
1867
            if (empty($post_item_id) === false
1868
                && empty($post_dest_id) === false
1869
            ) {
1870
                // load the original record into an array
1871
                $originalRecord = DB::queryfirstrow(
1872
                    'SELECT * FROM '.prefixTable('items').'
1873
                    WHERE id = %i',
1874
                    $post_item_id
1875
                );
1876
1877
                // Check if the folder where this item is accessible to the user
1878
                if (in_array($originalRecord['id_tree'], $_SESSION['groupes_visibles']) === false) {
1879
                    echo prepareExchangedData(
1880
                        array(
1881
                            'error' => true,
1882
                            'message' => langHdl('error_not_allowed_to'),
1883
                        ),
1884
                        'encode'
1885
                    );
1886
                    break;
1887
                }
1888
1889
                // Load the destination folder record into an array
1890
                $dataDestination = DB::queryfirstrow(
1891
                    'SELECT personal_folder FROM '.prefixTable('nested_tree').'
1892
                    WHERE id = %i',
1893
                    $post_dest_id
1894
                );
1895
1896
                // Get the ITEM object key for the user
1897
                $userKey = DB::queryFirstRow(
1898
                    'SELECT share_key
1899
                    FROM '.prefixTable('sharekeys_items').'
1900
                    WHERE user_id = %i AND object_id = %i',
1901
                    $_SESSION['user_id'],
1902
                    $post_item_id
1903
                );
1904
                if (DB::count() === 0) {
1905
                    // ERROR - No sharekey found for this item and user
1906
                    echo prepareExchangedData(
1907
                        array(
1908
                            'error' => true,
1909
                            'message' => langHdl('error_not_allowed_to'),
1910
                        ),
1911
                        'encode'
1912
                    );
1913
                    break;
1914
                }
1915
1916
                // Decrypt / Encrypt the password
1917
                $cryptedStuff = doDataEncryption(
1918
                    base64_decode(
1919
                        doDataDecryption(
1920
                            $originalRecord['pw'],
1921
                            decryptUserObjectKey(
1922
                                $userKey['share_key'],
1923
                                $_SESSION['user']['private_key']
1924
                            )
1925
                        )
1926
                    )
1927
                );
1928
                // reaffect pw
1929
                $originalRecord['pw'] = $cryptedStuff['encrypted'];
1930
1931
                // generate the query to update the new record with the previous values
1932
                $aSet = array();
1933
                foreach ($originalRecord as $key => $value) {
1934
                    if ($key === 'id_tree') {
1935
                        $aSet['id_tree'] = $post_dest_id;
1936
                    } elseif ($key === 'label') {
1937
                        $aSet[$key] = $post_new_label;
1938
                    } elseif ($key === 'viewed_no') {
1939
                        $aSet['viewed_no'] = '0';
1940
                    } elseif ($key === 'pw' && empty($pw) === false) {
1941
                        $aSet['pw'] = $originalRecord['pw'];
1942
                        $aSet['pw_iv'] = '';
1943
                    } elseif ($key === 'perso') {
1944
                        $aSet['perso'] = $is_perso;
1945
                    } elseif ($key != 'id' && $key != 'key') {
1946
                        $aSet[$key] = $value;
1947
                    }
1948
                }
1949
1950
                // insert the new record and get the new auto_increment id
1951
                DB::insert(
1952
                    prefixTable('items'),
1953
                    $aSet
1954
                );
1955
                $newItemId = DB::insertId();
1956
1957
                // Create sharekeys for users of this new ITEM
1958
                storeUsersShareKey(
1959
                    prefixTable('sharekeys_items'),
1960
                    $dataDestination['personal_folder'],
1961
                    $post_dest_id,
1962
                    $newItemId,
1963
                    $cryptedStuff['objectKey'],
1964
                    $SETTINGS
1965
                );
1966
1967
                // --------------------
1968
                // Manage Custom Fields
1969
                $rows = DB::query(
1970
                    'SELECT *
1971
                    FROM '.prefixTable('categories_items').'
1972
                    WHERE item_id = %i',
1973
                    $post_item_id
1974
                );
1975
                foreach ($rows as $field) {
1976
                    // Create the entry for the new item
1977
1978
                    // Is the data encrypted
1979
                    if ((int) $field['encryption_type'] === TP_ENCRYPTION_NAME) {
1980
                        $cryptedStuff = doDataEncryption($field['value']);
1981
                    }
1982
1983
                    // store field text
1984
                    DB::insert(
1985
                        prefixTable('categories_items'),
1986
                        array(
1987
                            'item_id' => $newItemId,
1988
                            'field_id' => $field['field_id'],
1989
                            'data' => (int) $field['encryption_type'] === TP_ENCRYPTION_NAME ?
1990
                                $cryptedStuff['encrypted'] :
1991
                                $field['value'],
1992
                            'data_iv' => '',
1993
                            'encryption_type' => (int) $field['encryption_type'] === TP_ENCRYPTION_NAME ?
1994
                                TP_ENCRYPTION_NAME :
1995
                                'not_set',
1996
                        )
1997
                    );
1998
                    $newFieldId = DB::insertId();
1999
2000
                    // Create sharekeys for users
2001
                    if ((int) $field['encryption_type'] === TP_ENCRYPTION_NAME) {
2002
                        storeUsersShareKey(
2003
                            prefixTable('sharekeys_fields'),
2004
                            $dataDestination['personal_folder'],
2005
                            $post_dest_id,
2006
                            $newFieldId,
2007
                            $cryptedStuff['objectKey'],
2008
                            $SETTINGS
2009
                        );
2010
                    }
2011
                }
2012
                // <---
2013
2014
                // ------------------
2015
                // Manage attachments
2016
2017
                // get file key
2018
                $rows = DB::query(
2019
                    'SELECT f.id AS id, f.file AS file, f.name AS name, f.status AS status, f.extension AS extension,
2020
                    f.size AS size, f.type AS type, s.share_key AS share_key
2021
                    FROM '.prefixTable('files').' AS f
2022
                    INNER JOIN '.prefixTable('sharekeys_files').' AS s ON (f.id = s.object_id)
2023
                    WHERE s.user_id = %i AND f.id_item = %i',
2024
                    $_SESSION['user_id'],
2025
                    $post_item_id
2026
                );
2027
                foreach ($rows as $record) {
2028
                    // Check if file still exists
2029
                    if (file_exists($SETTINGS['path_to_upload_folder'].DIRECTORY_SEPARATOR.TP_FILE_PREFIX.base64_decode($record['file'])) === true) {
2030
                        // Step1 - decrypt the file
2031
                        $fileContent = decryptFile(
2032
                            $record['file'],
2033
                            $SETTINGS['path_to_upload_folder'],
2034
                            decryptUserObjectKey($record['share_key'], $_SESSION['user']['private_key'])
2035
                        );
2036
2037
                        // Step2 - create file
2038
                        $newFileName = md5(time().'_'.$record['id']).'.'.$record['extension'];
2039
                        fwrite(
2040
                            fopen($SETTINGS['path_to_upload_folder'].DIRECTORY_SEPARATOR.$newFileName, 'ab'),
0 ignored issues
show
Bug introduced by
It seems like fopen($SETTINGS['path_to...R . $newFileName, 'ab') can also be of type false; however, parameter $handle of fwrite() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

2040
                            /** @scrutinizer ignore-type */ fopen($SETTINGS['path_to_upload_folder'].DIRECTORY_SEPARATOR.$newFileName, 'ab'),
Loading history...
2041
                            base64_decode($fileContent)
2042
                        );
2043
2044
                        // Step3 - encrypt the file
2045
                        $newFile = encryptFile($newFileName, $SETTINGS['path_to_upload_folder']);
2046
2047
                        // Step4 - store in database
2048
                        DB::insert(
2049
                            prefixTable('files'),
2050
                            array(
2051
                                'id_item' => $newItemId,
2052
                                'name' => $record['name'],
2053
                                'size' => $record['size'],
2054
                                'extension' => $record['extension'],
2055
                                'type' => $record['type'],
2056
                                'file' => $newFile['fileHash'],
2057
                                'status' => TP_ENCRYPTION_NAME,
2058
                                'confirmed' => 1,
2059
                            )
2060
                        );
2061
                        $newFileId = DB::insertId();
2062
2063
                        // Step5 - create sharekeys
2064
                        storeUsersShareKey(
2065
                            prefixTable('sharekeys_files'),
2066
                            $dataDestination['personal_folder'],
2067
                            $post_dest_id,
2068
                            $newFileId,
2069
                            $newFile['objectKey'],
2070
                            $SETTINGS
2071
                        );
2072
                    }
2073
                }
2074
                // <---
2075
2076
                // -------------------------
2077
                // Add specific restrictions
2078
                $rows = DB::query('SELECT * FROM '.prefixTable('restriction_to_roles').' WHERE item_id = %i', $post_item_id);
2079
                foreach ($rows as $record) {
2080
                    DB::insert(
2081
                        prefixTable('restriction_to_roles'),
2082
                        array(
2083
                            'item_id' => $newItemId,
2084
                            'role_id' => $record['role_id'],
2085
                            )
2086
                    );
2087
                }
2088
2089
                // Add Tags
2090
                $rows = DB::query('SELECT * FROM '.prefixTable('tags').' WHERE item_id = %i', $post_item_id);
2091
                foreach ($rows as $record) {
2092
                    DB::insert(
2093
                        prefixTable('tags'),
2094
                        array(
2095
                            'item_id' => $newItemId,
2096
                            'tag' => $record['tag'],
2097
                            )
2098
                    );
2099
                }
2100
2101
                // Add this duplicate in logs
2102
                logItems(
2103
                    $SETTINGS,
2104
                    $newItemId,
2105
                    $originalRecord['label'],
2106
                    $_SESSION['user_id'],
2107
                    'at_creation',
2108
                    $_SESSION['login']
2109
                );
2110
                // Add the fact that item has been copied in logs
2111
                logItems(
2112
                    $SETTINGS,
2113
                    $newItemId,
2114
                    $originalRecord['label'],
2115
                    $_SESSION['user_id'],
2116
                    'at_copy',
2117
                    $_SESSION['login']
2118
                );
2119
                // reload cache table
2120
                include_once $SETTINGS['cpassman_dir'].'/sources/main.functions.php';
2121
                updateCacheTable('reload', $SETTINGS, '');
2122
2123
                $returnValues = '[{"error" : ""} , {"status" : "ok"}, {"new_id" : "'.$newItemId.'"}]';
2124
            } else {
2125
                // no item
2126
                $returnValues = '[{"error" : "no_item"}, {"error_text" : "No item ID"}]';
2127
            }
2128
            // return data
2129
            echo $returnValues;
2130
            break;
2131
2132
        /*
2133
          * CASE
2134
          * Display informations of selected item
2135
        */
2136
        case 'show_details_item':
2137
            // Check KEY and rights
2138
            if ($post_key !== $_SESSION['key']) {
2139
                echo prepareExchangedData(
2140
                    array(
2141
                        'error' => true,
2142
                        'message' => langHdl('key_is_not_correct'),
2143
                    ),
2144
                    'encode'
2145
                );
2146
                break;
2147
            }
2148
2149
            // Step #1
2150
            $_SESSION['user_settings']['show_step2'] = false;
2151
2152
            // Decrypt and retreive data in JSON format
2153
            $dataReceived = prepareExchangedData($post_data, 'decode');
2154
2155
            // Init post variables
2156
            $post_id = filter_var(($dataReceived['id']), FILTER_SANITIZE_NUMBER_INT);
2157
            $post_folder_id = filter_var(($dataReceived['folder_id']), FILTER_SANITIZE_NUMBER_INT);
2158
            $post_salt_key_required = filter_var(($dataReceived['salt_key_required']), FILTER_SANITIZE_STRING);
2159
            $post_salt_key_set = isset($_SESSION['user_settings']['session_psk']) === true
2160
                && empty($_SESSION['user_settings']['session_psk']) === false ? '1' : '0';
2161
            $post_expired_item = filter_var(($dataReceived['expired_item']), FILTER_SANITIZE_NUMBER_INT);
2162
            $post_restricted = filter_var(($dataReceived['restricted']), FILTER_SANITIZE_STRING);
2163
            $post_page = filter_var(($dataReceived['page']), FILTER_SANITIZE_STRING);
2164
            $post_folder_access_level = isset($dataReceived['folder_access_level']) === true ?
2165
                filter_var(($dataReceived['folder_access_level']), FILTER_SANITIZE_STRING)
2166
                :
2167
                '';
2168
            $post_item_rights = filter_var(($dataReceived['rights']), FILTER_SANITIZE_NUMBER_INT);
2169
2170
            $arrData = array();
2171
            // return ID
2172
            $arrData['id'] = (int) $post_id;
2173
            $arrData['id_user'] = API_USER_ID;
2174
            $arrData['author'] = 'API';
2175
2176
            // Check if item is deleted
2177
            // taking into account that item can be restored.
2178
            // so if restoration timestamp is higher than the deletion one
2179
            // then we can show it
2180
            $item_deleted = DB::queryFirstRow(
2181
                'SELECT *
2182
                FROM '.prefixTable('log_items').'
2183
                WHERE id_item = %i AND action = %s
2184
                ORDER BY date DESC
2185
                LIMIT 0, 1',
2186
                $post_id,
2187
                'at_delete'
2188
            );
2189
            $dataDeleted = DB::count();
2190
2191
            $item_restored = DB::queryFirstRow(
2192
                'SELECT *
2193
                FROM '.prefixTable('log_items').'
2194
                WHERE id_item = %i AND action = %s
2195
                ORDER BY date DESC
2196
                LIMIT 0, 1',
2197
                $post_id,
2198
                'at_restored'
2199
            );
2200
2201
            if ($dataDeleted != 0 && intval($item_deleted['date']) > intval($item_restored['date'])) {
2202
                // This item is deleted => exit
2203
                echo prepareExchangedData(
2204
                    array(
2205
                        'error' => true,
2206
                        'message' => langHdl('not_allowed_to_see_pw'),
2207
                        'show_detail_option' => 2,
2208
                    ),
2209
                    'encode'
2210
                );
2211
                break;
2212
            }
2213
2214
            // Get all informations for this item
2215
            $dataItem = DB::queryfirstrow(
2216
                'SELECT *
2217
                FROM '.prefixTable('items').' as i
2218
                INNER JOIN '.prefixTable('log_items').' as l ON (l.id_item = i.id)
2219
                WHERE i.id = %i AND l.action = %s',
2220
                $post_id,
2221
                'at_creation'
2222
            );
2223
2224
            // Notification
2225
            DB::queryfirstrow(
2226
                'SELECT *
2227
                FROM '.prefixTable('notification').'
2228
                WHERE item_id = %i AND user_id = %i',
2229
                $post_id,
2230
                $_SESSION['user_id']
2231
            );
2232
            if (DB::count() > 0) {
2233
                $arrData['notification_status'] = true;
2234
            } else {
2235
                $arrData['notification_status'] = false;
2236
            }
2237
2238
            // Get all USERS infos
2239
            $listRest = array_filter(explode(';', $dataItem['restricted_to']));
2240
            $_SESSION['listNotificationEmails'] = '';
2241
            $listeRestriction = array();
2242
2243
            $user_in_restricted_list_of_item = false;
2244
            $rows = DB::query(
2245
                'SELECT id, login, email, admin, name, lastname
2246
                FROM '.prefixTable('users')
2247
            );
2248
            foreach ($rows as $user) {
2249
                // Get auhtor
2250
                if ($user['id'] === $dataItem['id_user']) {
2251
                    $arrData['author'] = $user['login'];
2252
                    $arrData['author_email'] = $user['email'];
2253
                    $arrData['id_user'] = (int) $dataItem['id_user'];
2254
                }
2255
2256
                // Get restriction list for users
2257
                if (in_array($user['id'], $listRest) === true) {
2258
                    array_push($listeRestriction, $user['id']);
2259
                    if ($_SESSION['user_id'] === $user['id']) {
2260
                        $user_in_restricted_list_of_item = true;
2261
                    }
2262
                }
2263
                // Get notification list for users
2264
                /*if (in_array($user['id'], $arrData['notification_list']) === true) {
2265
                    $_SESSION['listNotificationEmails'] .= $user['email'].',';
2266
                }*/
2267
2268
                // Add Admins to notification list if expected
2269
                if (isset($SETTINGS['enable_email_notification_on_item_shown']) === true
2270
                    && $SETTINGS['enable_email_notification_on_item_shown'] === '1'
2271
                    && $user['admin'] === '1'
2272
                ) {
2273
                    $_SESSION['listNotificationEmails'] .= $user['email'].',';
2274
                }
2275
            }
2276
2277
            // manage case of API user
2278
            if ($dataItem['id_user'] === API_USER_ID) {
2279
                $arrData['author'] = 'API ['.$dataItem['description'].']';
2280
                $arrData['id_user'] = API_USER_ID;
2281
                $arrData['author_email'] = '';
2282
                $arrData['notification_status'] = false;
2283
            }
2284
2285
            // Get all tags for this item
2286
            $tags = array();
2287
            $rows = DB::query(
2288
                'SELECT tag
2289
                FROM '.prefixTable('tags').'
2290
                WHERE item_id = %i',
2291
                $post_id
2292
            );
2293
            foreach ($rows as $record) {
2294
                array_push($tags, $record['tag']);
2295
            }
2296
2297
            // TODO -> improve this check
2298
            // check that actual user can access this item
2299
            $restrictionActive = true;
2300
            $restrictedTo = array_filter(explode(';', $dataItem['restricted_to']));
2301
            if (in_array($_SESSION['user_id'], $restrictedTo) === true
2302
                || ((int) $_SESSION['user_manager'] === 1 && (int) $SETTINGS['manager_edit'] === 1)) {
2303
                $restrictionActive = false;
2304
            }
2305
            if (empty($dataItem['restricted_to']) === true) {
2306
                $restrictionActive = false;
2307
            }
2308
2309
            // Check if user has a role that is accepted
2310
            $rows_tmp = DB::query(
2311
                'SELECT role_id
2312
                FROM '.prefixTable('restriction_to_roles').'
2313
                WHERE item_id=%i',
2314
                $post_id
2315
            );
2316
            foreach ($rows_tmp as $rec_tmp) {
2317
                if (in_array($rec_tmp['role_id'], explode(';', $_SESSION['fonction_id']))) {
2318
                    $restrictionActive = false;
2319
                }
2320
            }
2321
2322
            // Uncrypt PW
2323
            // Get the object key for the user
2324
            $userKey = DB::queryFirstRow(
2325
                'SELECT share_key
2326
                FROM '.prefixTable('sharekeys_items').'
2327
                WHERE user_id = %i AND object_id = %i',
2328
                $_SESSION['user_id'],
2329
                $post_id
2330
            );
2331
            if (DB::count() === 0 || empty($dataItem['pw']) === true) {
2332
                // No share key found
2333
                $pw = '';
2334
            } else {
2335
                $pw = doDataDecryption(
2336
                    $dataItem['pw'],
2337
                    decryptUserObjectKey($userKey['share_key'], $_SESSION['user']['private_key'])
2338
                );
2339
            }
2340
2341
           // echo $dataItem['id_tree']." ;; ";
2342
            //print_r($_SESSION['groupes_visibles']);
2343
2344
            // check user is admin
2345
            if ((int) $_SESSION['user_admin'] === 1
1 ignored issue
show
introduced by
Consider adding parentheses for clarity. Current Interpretation: ((int)$_SESSION['user_ad...=== TP_ADMIN_FULL_RIGHT, Probably Intended Meaning: (int)$_SESSION['user_adm...== TP_ADMIN_FULL_RIGHT)
Loading history...
2346
                && (int) $dataItem['perso'] !== 1
2347
                && (null !== TP_ADMIN_FULL_RIGHT && TP_ADMIN_FULL_RIGHT === true)
2348
                || null === TP_ADMIN_FULL_RIGHT
2349
            ) {
2350
                $arrData['show_details'] = 0;
2351
            // ---
2352
                // ---
2353
            } elseif ((
2354
                (in_array($dataItem['id_tree'], $_SESSION['groupes_visibles']) || $_SESSION['is_admin'] === '1') && ($dataItem['perso'] === '0' || ($dataItem['perso'] === '1' && in_array($dataItem['id_tree'], $_SESSION['personal_folders']) === true)) && $restrictionActive === false)
2355
                ||
2356
                (isset($SETTINGS['anyone_can_modify']) && $SETTINGS['anyone_can_modify'] === '1' && $dataItem['anyone_can_modify'] === '1' && (in_array($dataItem['id_tree'], $_SESSION['groupes_visibles']) || $_SESSION['is_admin'] === '1') && $restrictionActive === false)
2357
                ||
2358
                (null !== $post_folder_id
2359
                    && isset($_SESSION['list_restricted_folders_for_items'][$post_folder_id])
2360
                    && in_array($post_id, $_SESSION['list_restricted_folders_for_items'][$post_folder_id])
2361
                    && $post_restricted === '1'
2362
                    && $user_in_restricted_list_of_item === true)
2363
                ||
2364
                (isset($SETTINGS['restricted_to_roles']) && (int) $SETTINGS['restricted_to_roles'] === 1
2365
                    && $restrictionActive === false
2366
                )
2367
            ) {
2368
                // Check if actual USER can see this ITEM
2369
                // Allow show details
2370
                $arrData['show_details'] = 1;
2371
2372
                // Regarding user's roles, what type of modification is allowed?
2373
                /*$rows = DB::query(
2374
                    'SELECT r.type
2375
                    FROM '.prefixTable('roles_values').' AS r
2376
                    WHERE r.folder_id = %i AND r.role_id IN %ls',
2377
                    $dataItem['id_tree'],
2378
                    $_SESSION['groupes_visibles']
2379
                );
2380
                foreach ($rows as $record) {
2381
                    // TODO
2382
                }*/
2383
2384
                // Display menu icon for deleting if user is allowed
2385
                if ((int) $dataItem['id_user'] === (int) $_SESSION['user_id']
2386
                    || (int) $_SESSION['is_admin'] === 1
2387
                    || ((int) $_SESSION['user_manager'] === 1 && (int) $SETTINGS['manager_edit'] === 1)
2388
                    || (int) $dataItem['anyone_can_modify'] === 1
2389
                    || in_array($dataItem['id_tree'], $_SESSION['list_folders_editable_by_role']) === true
2390
                    || in_array($_SESSION['user_id'], $restrictedTo) === true
2391
                    //|| count($restrictedTo) === 0
2392
                    || (int) $post_folder_access_level === 3
2393
                    || (int) $post_item_rights >= 40
2394
                ) {
2395
                    $arrData['user_can_modify'] = 1;
2396
                    $user_is_allowed_to_modify = true;
2397
                } else {
2398
                    $arrData['user_can_modify'] = 0;
2399
                    $user_is_allowed_to_modify = false;
2400
                }
2401
2402
                // Get restriction list for roles
2403
                $listRestrictionRoles = array();
2404
                if (isset($SETTINGS['restricted_to_roles']) && $SETTINGS['restricted_to_roles'] === '1') {
2405
                    // Add restriction if item is restricted to roles
2406
                    $rows = DB::query(
2407
                        'SELECT t.title, t.id
2408
                        FROM '.prefixTable('roles_title').' AS t
2409
                        INNER JOIN '.prefixTable('restriction_to_roles').' AS r ON (t.id=r.role_id)
2410
                        WHERE r.item_id = %i
2411
                        ORDER BY t.title ASC',
2412
                        $post_id
2413
                    );
2414
                    foreach ($rows as $record) {
2415
                        if (!in_array($record['title'], $listRestrictionRoles)) {
2416
                            array_push($listRestrictionRoles, $record['id']);
2417
                        }
2418
                    }
2419
                }
2420
                // Check if any KB is linked to this item
2421
                if (isset($SETTINGS['enable_kb']) && $SETTINGS['enable_kb'] === '1') {
2422
                    $tmp = array();
2423
                    $rows = DB::query(
2424
                        'SELECT k.label, k.id
2425
                        FROM '.prefixTable('kb_items').' as i
2426
                        INNER JOIN '.prefixTable('kb').' as k ON (i.kb_id=k.id)
2427
                        WHERE i.item_id = %i
2428
                        ORDER BY k.label ASC',
2429
                        $post_id
2430
                    );
2431
                    foreach ($rows as $record) {
2432
                        array_push(
2433
                            $tmp,
2434
                            array(
2435
                                'id' => $record['id'],
2436
                                'label' => $record['label'],
2437
                            )
2438
                        );
2439
                    }
2440
                    $arrData['links_to_kbs'] = $tmp;
2441
                }
2442
                // Prepare DIalogBox data
2443
                if ((int) $post_expired_item === 0) {
2444
                    $arrData['show_detail_option'] = 0;
2445
                } elseif ($user_is_allowed_to_modify === true && (int) $post_expired_item === 1) {
2446
                    $arrData['show_detail_option'] = 1;
2447
                } else {
2448
                    $arrData['show_detail_option'] = 2;
2449
                }
2450
2451
                $arrData['label'] = htmlspecialchars_decode($dataItem['label'], ENT_QUOTES);
2452
                $arrData['pw'] = $pw;
2453
                $arrData['email'] = (empty($dataItem['email']) === true || $dataItem['email'] === null) ? '' : $dataItem['email'];
2454
                $arrData['url'] = empty($dataItem['url']) === true ? '' : $dataItem['url'];
2455
                $arrData['folder'] = $dataItem['id_tree'];
2456
2457
                $arrData['description'] = $dataItem['description'];
2458
                $arrData['login'] = htmlspecialchars_decode(str_replace(array('"'), array('&quot;'), $dataItem['login']), ENT_QUOTES);
2459
                $arrData['id_restricted_to'] = $listeRestriction;
2460
                $arrData['id_restricted_to_roles'] = $listRestrictionRoles;
2461
                $arrData['tags'] = $tags;
2462
                $arrData['folder'] = (int) $dataItem['id_tree'];
2463
2464
                if (isset($SETTINGS['enable_server_password_change'])
2465
                    && $SETTINGS['enable_server_password_change'] === '1') {
2466
                    $arrData['auto_update_pwd_frequency'] = $dataItem['auto_update_pwd_frequency'];
2467
                } else {
2468
                    $arrData['auto_update_pwd_frequency'] = '0';
2469
                }
2470
2471
                $arrData['anyone_can_modify'] = (int) $dataItem['anyone_can_modify'];
2472
2473
                // Add the fact that item has been viewed in logs
2474
                if (isset($SETTINGS['log_accessed']) && $SETTINGS['log_accessed'] === '1') {
2475
                    logItems(
2476
                        $SETTINGS,
2477
                        $post_id,
2478
                        $dataItem['label'],
2479
                        $_SESSION['user_id'],
2480
                        'at_shown',
2481
                        $_SESSION['login']
2482
                    );
2483
                }
2484
2485
                // statistics
2486
                DB::update(
2487
                    prefixTable('items'),
2488
                    array(
2489
                        'viewed_no' => $dataItem['viewed_no'] + 1,
2490
                    ),
2491
                    'id = %i',
2492
                    $post_id
2493
                );
2494
                $arrData['viewed_no'] = $dataItem['viewed_no'] + 1;
2495
2496
                // get fields
2497
                $fieldsTmp = array();
2498
                $arrCatList = $template_id = '';
2499
                if (isset($SETTINGS['item_extra_fields']) && (int) $SETTINGS['item_extra_fields'] === 1) {
2500
                    // get list of associated Categories
2501
                    $arrCatList = array();
2502
                    $rows_tmp = DB::query(
2503
                        'SELECT id_category
2504
                        FROM '.prefixTable('categories_folders').'
2505
                        WHERE id_folder=%i',
2506
                        $post_folder_id
2507
                    );
2508
                    if (DB::count() > 0) {
2509
                        foreach ($rows_tmp as $row) {
2510
                            array_push($arrCatList, (int) $row['id_category']);
2511
                        }
2512
2513
                        // get fields for this Item
2514
                        $rows_tmp = DB::query(
2515
                            'SELECT i.id AS id, i.field_id AS field_id, i.data AS data, i.item_id AS item_id,
2516
                            i.encryption_type AS encryption_type, c.encrypted_data, c.parent_id AS parent_id,
2517
                            c.type as field_type, c.masked AS field_masked, c.role_visibility AS role_visibility
2518
                            FROM '.prefixTable('categories_items').' AS i
2519
                            INNER JOIN '.prefixTable('categories').' AS c ON (i.field_id=c.id)
2520
                            WHERE i.item_id=%i AND c.parent_id IN %ls',
2521
                            $post_id,
2522
                            $arrCatList
2523
                        );
2524
                        foreach ($rows_tmp as $row) {
2525
                            // Uncrypt data
2526
                            // Get the object key for the user
2527
                            $userKey = DB::queryFirstRow(
2528
                                'SELECT share_key
2529
                                FROM '.prefixTable('sharekeys_fields').'
2530
                                WHERE user_id = %i AND object_id = %i',
2531
                                $_SESSION['user_id'],
2532
                                $row['id']
2533
                            );
2534
                            if (DB::count() === 0) {
2535
                                // Not encrypted
2536
                                $fieldText['string'] = $row['data'];
2537
                                $fieldText['encrypted'] = false;
2538
                            } else {
2539
                                $fieldText['string'] = doDataDecryption(
2540
                                    $row['data'],
2541
                                    decryptUserObjectKey(
2542
                                        $userKey['share_key'],
2543
                                        $_SESSION['user']['private_key']
2544
                                    )
2545
                                );
2546
                                $fieldText['encrypted'] = true;
2547
                            }
2548
2549
                            // Manage textarea string
2550
                            if ($row['field_type'] === 'textarea') {
2551
                                $fieldText = $fieldText;
2552
                            }
2553
2554
                            // build returned list of Fields text
2555
                            array_push(
2556
                                $fieldsTmp,
2557
                                array(
2558
                                    'id' => (int) $row['field_id'],
2559
                                    'value' => $fieldText['string'],
2560
                                    'encrypted' => (int) $fieldText['encrypted'],
2561
                                    'parent_id' => (int) $row['parent_id'],
2562
                                    'type' => $row['field_type'],
2563
                                    'masked' => (int) $row['field_masked'],
2564
                                )
2565
                            );
2566
                        }
2567
                    }
2568
                }
2569
2570
                // Now get the selected template (if exists)
2571
                if (isset($SETTINGS['item_creation_templates']) && $SETTINGS['item_creation_templates'] === '1') {
2572
                    $rows_tmp = DB::queryfirstrow(
2573
                        'SELECT category_id
2574
                        FROM '.prefixTable('templates').'
2575
                        WHERE item_id = %i',
2576
                        $post_id
2577
                    );
2578
                    if (DB::count() > 0) {
2579
                        $template_id = $rows_tmp['category_id'];
2580
                    }
2581
                }
2582
                //}
2583
                $arrData['fields'] = $fieldsTmp;
2584
                $arrData['categories'] = $arrCatList;
2585
                $arrData['template_id'] = (int) $template_id;
2586
                $arrData['to_be_deleted'] = '';
2587
2588
                // Manage user restriction
2589
                if (null !== $post_restricted) {
2590
                    $arrData['restricted'] = $post_restricted;
2591
                } else {
2592
                    $arrData['restricted'] = '';
2593
                }
2594
                // Decrement the number before being deleted
2595
                if (isset($SETTINGS['enable_delete_after_consultation']) && $SETTINGS['enable_delete_after_consultation'] === '1') {
2596
                    // Is the Item to be deleted?
2597
                    $dataDelete = DB::queryfirstrow(
2598
                        'SELECT * 
2599
                        FROM '.prefixTable('automatic_del').'
2600
                        WHERE item_id = %i',
2601
                        $post_id
2602
                    );
2603
                    if (DB::count() > 0) {
2604
                        $arrData['to_be_deleted'] = $dataDelete['del_value'];
2605
                    }
2606
                    $arrData['to_be_deleted_type'] = (int) $dataDelete['del_type'];
2607
2608
                    // Now delete if required
2609
                    if ((int) $dataDelete['del_enabled'] === 1 || intval($arrData['id_user']) !== intval($_SESSION['user_id'])) {
2610
                        if ((int) $dataDelete['del_type'] === 1 && $dataDelete['del_value'] >= 1) {
2611
                            // decrease counter
2612
                            DB::update(
2613
                                prefixTable('automatic_del'),
2614
                                array(
2615
                                    'del_value' => $dataDelete['del_value'] - 1,
2616
                                    ),
2617
                                'item_id = %i',
2618
                                $post_id
2619
                            );
2620
                            // store value
2621
                            $arrData['to_be_deleted'] = $dataDelete['del_value'] - 1;
2622
                        } elseif ((int) $dataDelete['del_type'] === 1
0 ignored issues
show
introduced by
Consider adding parentheses for clarity. Current Interpretation: ((int)$dataDelete['del_t...e['del_value'] < time(), Probably Intended Meaning: (int)$dataDelete['del_ty...['del_value'] < time())
Loading history...
2623
                            && $dataDelete['del_value'] <= 1
2624
                            || (int) $dataDelete['del_type'] === 2
2625
                            && $dataDelete['del_value'] < time()
2626
                        ) {
2627
                            $arrData['show_details'] = 0;
2628
                            // delete item
2629
                            DB::delete(prefixTable('automatic_del'), 'item_id = %i', $post_id);
2630
                            // make inactive object
2631
                            DB::update(
2632
                                prefixTable('items'),
2633
                                array(
2634
                                    'inactif' => 1,
2635
                                    ),
2636
                                'id = %i',
2637
                                $post_id
2638
                            );
2639
2640
                            // log
2641
                            logItems(
2642
                                $SETTINGS,
2643
                                $post_id,
2644
                                $dataItem['label'],
2645
                                $_SESSION['user_id'],
2646
                                'at_delete',
2647
                                $_SESSION['login'],
2648
                                'at_automatically_deleted'
2649
                            );
2650
2651
                            // Update cache table
2652
                            updateCacheTable(
2653
                                'delete_value',
2654
                                $SETTINGS,
2655
                                $post_id
2656
                            );
2657
2658
                            $arrData['show_detail_option'] = 1;
2659
                            $arrData['to_be_deleted'] = 0;
2660
                        } elseif ($dataDelete['del_type'] === '2') {
2661
                            $arrData['to_be_deleted'] = date($SETTINGS['date_format'], $dataDelete['del_value']);
2662
                        }
2663
                    } else {
2664
                        $arrData['to_be_deleted'] = '';
2665
                    }
2666
                } else {
2667
                    $arrData['to_be_deleted'] = 'not_enabled';
2668
                }
2669
                // ---
2670
                // ---
2671
            } else {
2672
                $arrData['show_details'] = 0;
2673
                // get readable list of restriction
2674
                $listOfRestricted = '';
2675
                if (empty($dataItem['restricted_to']) === false) {
2676
                    foreach (explode(';', $dataItem['restricted_to']) as $userRest) {
2677
                        if (empty($userRest) === false) {
2678
                            $dataTmp = DB::queryfirstrow('SELECT login FROM '.prefixTable('users').' WHERE id= '.$userRest);
2679
                            if (empty($listOfRestricted)) {
2680
                                $listOfRestricted = $dataTmp['login'];
2681
                            } else {
2682
                                $listOfRestricted .= ';'.$dataTmp['login'];
2683
                            }
2684
                        }
2685
                    }
2686
                }
2687
                $arrData['restricted_to'] = $listOfRestricted;
2688
                $arrData['notification_list'] = '';
2689
                $arrData['notification_status'] = '';
2690
            }
2691
2692
            // Set a timestamp
2693
            $arrData['timestamp'] = time();
2694
2695
            // Set temporary session variable to allow step2
2696
            $_SESSION['user_settings']['show_step2'] = true;
2697
2698
            // Error
2699
            $arrData['error'] = '';
2700
2701
            // Encrypt data to return
2702
            echo prepareExchangedData($arrData, 'encode');
2703
            break;
2704
2705
        /*
2706
           * CASE
2707
           * Display History of the selected Item
2708
        */
2709
        case 'showDetailsStep2':
2710
            // Is this query expected (must be run after a step1 and not standalone)
2711
            if ($_SESSION['user_settings']['show_step2'] !== true) {
2712
                // Check KEY and rights
2713
                if ($post_key !== $_SESSION['key']) {
2714
                    echo prepareExchangedData(
2715
                        array(
2716
                            'error' => true,
2717
                            'message' => langHdl('key_is_not_correct'),
2718
                        ),
2719
                        'encode'
2720
                    );
2721
                    break;
2722
                } elseif ($_SESSION['user_read_only'] === true) {
2723
                    echo prepareExchangedData(
2724
                        array(
2725
                            'error' => true,
2726
                            'message' => langHdl('error_not_allowed_to'),
2727
                        ),
2728
                        'encode'
2729
                    );
2730
                    break;
2731
                }
2732
            }
2733
            $returnArray = array();
2734
2735
            // Load item data
2736
            $dataItem = DB::queryFirstRow(
2737
                'SELECT i.*, n.title AS folder_title
2738
                FROM '.prefixTable('items').' AS i
2739
                INNER JOIN '.prefixTable('nested_tree').' AS n ON (i.id_tree = n.id)
2740
                WHERE i.id = %i',
2741
                $post_id
2742
            );
2743
2744
            // check that actual user can access this item
2745
            $restrictionActive = true;
2746
            $restrictedTo = array_filter(explode(';', $dataItem['restricted_to']));
2747
            if (in_array($_SESSION['user_id'], $restrictedTo)
2748
                || (((int) $_SESSION['user_manager'] === 1 || (int) $_SESSION['user_can_manage_all_users'] === 1)
2749
                && (int) $SETTINGS['manager_edit'] === 1)
2750
            ) {
2751
                $restrictionActive = false;
2752
            }
2753
            if (empty($dataItem['restricted_to'])) {
2754
                $restrictionActive = false;
2755
            }
2756
2757
            // Check if user has a role that is accepted
2758
            $rows_tmp = DB::query(
2759
                'SELECT role_id
2760
                FROM '.prefixTable('restriction_to_roles').'
2761
                WHERE item_id=%i',
2762
                $post_id
2763
            );
2764
            foreach ($rows_tmp as $rec_tmp) {
2765
                if (in_array($rec_tmp['role_id'], explode(';', $_SESSION['fonction_id']))) {
2766
                    $restrictionActive = false;
2767
                }
2768
            }
2769
2770
            // check user is admin
2771
            if ($_SESSION['user_admin'] === '1'
0 ignored issues
show
introduced by
Consider adding parentheses for clarity. Current Interpretation: ($_SESSION['user_admin']... == TP_ADMIN_FULL_RIGHT, Probably Intended Meaning: $_SESSION['user_admin'] ...== TP_ADMIN_FULL_RIGHT)
Loading history...
2772
                && $dataItem['perso'] !== 1
2773
                && (null !== TP_ADMIN_FULL_RIGHT && TP_ADMIN_FULL_RIGHT === true)
2774
                || null == TP_ADMIN_FULL_RIGHT
2775
            ) {
2776
                $returnArray['show_details'] = 0;
2777
            // Check if actual USER can see this ITEM
2778
            } elseif ((
2779
                (in_array($dataItem['id_tree'], $_SESSION['groupes_visibles']) || (int) $_SESSION['is_admin'] === 1) && ((int) $dataItem['perso'] === 0 || ((int) $dataItem['perso'] === 1 && in_array($dataItem['id_tree'], $_SESSION['personal_folders']) === true)) && $restrictionActive === false)
2780
                ||
2781
                (isset($SETTINGS['anyone_can_modify']) && $SETTINGS['anyone_can_modify'] === '1' && (int) $dataItem['anyone_can_modify'] === 1 && (in_array($dataItem['id_tree'], $_SESSION['groupes_visibles']) || (int) $_SESSION['is_admin'] === 1) && $restrictionActive === false)
2782
                ||
2783
                (null !== $post_folder_id
2784
                    && isset($_SESSION['list_restricted_folders_for_items'][$post_folder_id])
2785
                    && in_array($post_id, $_SESSION['list_restricted_folders_for_items'][$post_folder_id])
2786
                    && $post_restricted === '1'
2787
                    && $user_in_restricted_list_of_item === true)
2788
                ||
2789
                (isset($SETTINGS['restricted_to_roles']) && $SETTINGS['restricted_to_roles'] === '1'
2790
                    && $restrictionActive === false
2791
                )
2792
            ) {
2793
                /*
2794
                // GET Audit trail
2795
                $history = array();
2796
                $historyOfPws = array();
2797
                $rows = DB::query(
2798
                    'SELECT l.date as date, l.action as action, l.raison as raison, u.login as login, l.raison_iv AS raison_iv
2799
                    FROM '.prefixTable('log_items').' as l
2800
                    LEFT JOIN '.prefixTable('users').' as u ON (l.id_user=u.id)
2801
                    WHERE id_item=%i AND action <> %s
2802
                    ORDER BY date ASC',
2803
                    $post_id,
2804
                    'at_shown'
2805
                );
2806
                foreach ($rows as $record) {
2807
                    $reason = explode(':', $record['raison']);
2808
                    if ($record['action'] === 'at_modification' && $reason[0] === 'at_pw ') {
2809
                        // check if item is PF
2810
                        if ($dataItem['perso'] !== 1) {
2811
                            $pw = cryption(
2812
                                $reason[1],
2813
                                '',
2814
                                'decrypt',
2815
                                $SETTINGS
2816
                            );
2817
                        } else {
2818
                            if (isset($_SESSION['user_settings']['session_psk']) === true) {
2819
                                $pw = cryption(
2820
                                    $reason[1],
2821
                                    $_SESSION['user_settings']['session_psk'],
2822
                                    'decrypt',
2823
                                    $SETTINGS
2824
                                );
2825
                            } else {
2826
                                $pw['string'] = '';
2827
                            }
2828
                        }
2829
2830
                        $reason[1] = $pw['string'];
2831
                        // if not UTF8 then cleanup and inform that something is wrong with encrytion/decryption
2832
                        if (isUTF8($reason[1]) === false || is_array($reason[1]) === true) {
2833
                            $reason[1] = '';
2834
                        }
2835
                    }
2836
                    // imported via API
2837
                    if (empty($record['login'])) {
2838
                        $record['login'] = langHdl('imported_via_api');
2839
                    }
2840
2841
                    if (empty($reason[1]) === false && in_array($record['action'], array('at_copy', 'at_creation', 'at_manual', 'at_modification', 'at_delete', 'at_restored')) === true) {
2842
                        if (trim($reason[0]) === 'at_pw' && empty($reason[1]) === false) {
2843
                            array_push($historyOfPws, $reason[1]);
2844
                        }
2845
                    }
2846
                }
2847
                $returnArray['historyOfPassword'] = $historyOfPws;
2848
                */
2849
2850
                // generate 2d key
2851
                $_SESSION['key_tmp'] = bin2hex(GenerateCryptKey(16));
2852
2853
                // Prepare files listing
2854
                $attachments = array();
2855
                $files = $filesEdit = '';
2856
                // launch query
2857
                $rows = DB::query(
2858
                    'SELECT id, name, file, extension, size
2859
                    FROM '.prefixTable('files').'
2860
                    WHERE id_item = %i AND confirmed = 1',
2861
                    $post_id
2862
                );
2863
                foreach ($rows as $record) {
2864
                    array_push(
2865
                        $attachments,
2866
                        array(
2867
                            'icon' => fileFormatImage(strtolower($record['extension'])),
2868
                            'filename' => basename($record['name'], '.'.$record['extension']),
2869
                            'extension' => $record['extension'],
2870
                            'size' => formatSizeUnits($record['size']),
2871
                            'is_image' => in_array(strtolower($record['extension']), TP_IMAGE_FILE_EXT) === true ? 1 : 0,
2872
                            'id' => $record['id'],
2873
                            'key' => $_SESSION['key_tmp'],
2874
                        )
2875
                    );
2876
                }
2877
                $returnArray['attachments'] = $attachments;
2878
                // display lists
2879
                //$filesEdit = str_replace('"', '&quot;', $filesEdit);
2880
                //$files_id = $files;
2881
2882
                // disable add bookmark if alread bookmarked
2883
                $returnArray['favourite'] = in_array($post_id, $_SESSION['favourites']) === true ? 1 : 0;
2884
2885
                // Add this item to the latests list
2886
                if (isset($_SESSION['latest_items']) && isset($SETTINGS['max_latest_items']) && !in_array($dataItem['id'], $_SESSION['latest_items'])) {
2887
                    if (count($_SESSION['latest_items']) >= $SETTINGS['max_latest_items']) {
2888
                        array_pop($_SESSION['latest_items']); //delete last items
2889
                    }
2890
                    array_unshift($_SESSION['latest_items'], $dataItem['id']);
2891
                    // update DB
2892
                    DB::update(
2893
                        prefixTable('users'),
2894
                        array(
2895
                            'latest_items' => implode(';', $_SESSION['latest_items']),
2896
                            ),
2897
                        'id='.$_SESSION['user_id']
2898
                    );
2899
                }
2900
2901
                // get list of roles
2902
                $listOptionsForUsers = array();
2903
                $listOptionsForRoles = array();
2904
                $rows = DB::query(
2905
                    'SELECT r.role_id AS role_id, t.title AS title
2906
                    FROM '.prefixTable('roles_values').' AS r
2907
                    INNER JOIN '.prefixTable('roles_title').' AS t ON (r.role_id = t.id)
2908
                    WHERE r.folder_id = %i',
2909
                    $dataItem['id_tree']
2910
                );
2911
                foreach ($rows as $record) {
2912
                    array_push(
2913
                        $listOptionsForRoles,
2914
                        array(
2915
                            'id' => (int) $record['role_id'],
2916
                            'title' => $record['title'],
2917
                        )
2918
                    );
2919
                    $rows2 = DB::query(
2920
                        'SELECT id, login, fonction_id, email, name, lastname
2921
                        FROM '.prefixTable('users').'
2922
                        WHERE fonction_id LIKE %s',
2923
                        '%'.$record['role_id'].'%'
2924
                    );
2925
                    foreach ($rows2 as $record2) {
2926
                        foreach (explode(';', $record2['fonction_id']) as $role) {
2927
                            if (array_search($record2['id'], array_column($listOptionsForUsers, 'id')) === false
2928
                                && $role === $record['role_id']
2929
                            ) {
2930
                                array_push(
2931
                                    $listOptionsForUsers,
2932
                                    array(
2933
                                        'id' => (int) $record2['id'],
2934
                                        'login' => $record2['login'],
2935
                                        'name' => $record2['name'].' '.$record2['lastname'],
2936
                                        'email' => $record2['email'],
2937
                                    )
2938
                                );
2939
                            }
2940
                        }
2941
                    }
2942
                }
2943
2944
                $returnArray['users_list'] = $listOptionsForUsers;
2945
                $returnArray['roles_list'] = $listOptionsForRoles;
2946
2947
                // send notification if enabled
2948
                if (isset($SETTINGS['enable_email_notification_on_item_shown']) === true && $SETTINGS['enable_email_notification_on_item_shown'] === '1') {
2949
                    // Get path
2950
                    $arbo = $tree->getPath($dataItem['id_tree'], true);
2951
                    $path = '';
2952
                    foreach ($arbo as $elem) {
2953
                        if (empty($path) === true) {
2954
                            $path = htmlspecialchars(stripslashes(htmlspecialchars_decode($elem->title, ENT_QUOTES)), ENT_QUOTES).' ';
2955
                        } else {
2956
                            $path .= '&#8594; '.htmlspecialchars(stripslashes(htmlspecialchars_decode($elem->title, ENT_QUOTES)), ENT_QUOTES);
2957
                        }
2958
                    }
2959
                    // Build text to show user
2960
                    if (empty($path) === true) {
2961
                        $path = addslashes($dataItem['label']);
2962
                    } else {
2963
                        $path = addslashes($dataItem['label']).' ('.$path.')';
2964
                    }
2965
2966
                    // send back infos
2967
                    DB::insert(
2968
                        prefixTable('emails'),
2969
                        array(
2970
                            'timestamp' => time(),
2971
                            'subject' => langHdl('email_on_open_notification_subject'),
2972
                            'body' => str_replace(
2973
                                array('#tp_user#', '#tp_item#', '#tp_link#'),
2974
                                array(
2975
                                    addslashes($_SESSION['login']),
2976
                                    $path,
2977
                                    $SETTINGS['cpassman_url'].'/index.php?page=items&group='.$dataItem['id_tree'].'&id='.$dataItem['id'],
2978
                                ),
2979
                                langHdl('email_on_open_notification_mail')
2980
                            ),
2981
                            'receivers' => $_SESSION['listNotificationEmails'],
2982
                            'status' => '',
2983
                        )
2984
                    );
2985
                }
2986
2987
                // has this item a change proposal
2988
                DB::query('SELECT * FROM '.prefixTable('items_change').' WHERE item_id = %i', $post_id);
2989
                $returnArray['has_change_proposal'] = DB::count();
2990
2991
                // Setting
2992
                $returnArray['setting_restricted_to_roles'] = isset($SETTINGS['restricted_to_roles']) === true
2993
                    && $SETTINGS['restricted_to_roles'] === '1' ? 1 : 0;
2994
2995
                $_SESSION['user_settings']['show_step2'] = false;
2996
2997
                echo prepareExchangedData(
2998
                    $returnArray,
2999
                    'encode'
3000
                );
3001
            }
3002
            break;
3003
3004
        /*
3005
         * CASE
3006
         * Delete an item
3007
        */
3008
        case 'delete_item':
3009
            // Check KEY and rights
3010
            if ($post_key !== $_SESSION['key']) {
3011
                echo prepareExchangedData(
3012
                    array(
3013
                        'error' => true,
3014
                        'message' => langHdl('key_is_not_correct'),
3015
                    ),
3016
                    'encode'
3017
                );
3018
                break;
3019
            } elseif ($_SESSION['user_read_only'] === true) {
3020
                echo prepareExchangedData(
3021
                    array(
3022
                        'error' => true,
3023
                        'message' => langHdl('error_not_allowed_to'),
3024
                    ),
3025
                    'encode'
3026
                );
3027
                break;
3028
            }
3029
3030
            // decrypt and retreive data in JSON format
3031
            $dataReceived = prepareExchangedData(
3032
                $post_data,
3033
                'decode'
3034
            );
3035
3036
            // Prepare POST variables
3037
            $post_label = filter_var($dataReceived['label'], FILTER_SANITIZE_STRING);
3038
            $post_folder_id = filter_var($dataReceived['folder_id'], FILTER_SANITIZE_NUMBER_INT);
3039
            $post_item_id = filter_var($dataReceived['item_id'], FILTER_SANITIZE_NUMBER_INT);
3040
            $post_access_level = filter_var($dataReceived['access_level'], FILTER_SANITIZE_NUMBER_INT);
3041
3042
            // perform a check in case of Read-Only user creating an item in his PF
3043
            if ($_SESSION['user_read_only'] === true
0 ignored issues
show
introduced by
Consider adding parentheses for clarity. Current Interpretation: ($_SESSION['user_read_on...$post_access_level >= 2, Probably Intended Meaning: $_SESSION['user_read_onl...post_access_level >= 2)
Loading history...
3044
                && in_array($post_label, $_SESSION['personal_folders']) === false
3045
                || (int) $post_access_level >= 2
3046
            ) {
3047
                echo prepareExchangedData(
3048
                    array(
3049
                        'error' => true,
3050
                        'message' => langHdl('error_not_allowed_to'),
3051
                    ),
3052
                    'encode'
3053
                );
3054
                break;
3055
            }
3056
3057
            // Check that user can access this item
3058
            $granted = accessToItemIsGranted($post_item_id);
3059
            if ($granted !== true) {
3060
                echo prepareExchangedData(
3061
                    array(
3062
                        'error' => true,
3063
                        'message' => $granted,
3064
                    ),
3065
                    'encode'
3066
                );
3067
                break;
3068
            }
3069
3070
            // Load item data
3071
            $data = DB::queryFirstRow(
3072
                'SELECT id_tree
3073
                FROM '.prefixTable('items').'
3074
                WHERE id = %i',
3075
                $post_item_id
3076
            );
3077
3078
            // delete item consists in disabling it
3079
            DB::update(
3080
                prefixTable('items'),
3081
                array(
3082
                    'inactif' => '1',
3083
                    ),
3084
                'id = %i',
3085
                $post_item_id
3086
            );
3087
            // log
3088
            logItems(
3089
                $SETTINGS,
3090
                $post_item_id,
3091
                $post_label,
3092
                $_SESSION['user_id'],
3093
                'at_delete',
3094
                $_SESSION['login']
3095
            );
3096
            // Update CACHE table
3097
            updateCacheTable('delete_value', $SETTINGS, $post_item_id);
3098
3099
            echo prepareExchangedData(
3100
                array(
3101
                    'error' => false,
3102
                    'message' => '',
3103
                ),
3104
                'encode'
3105
            );
3106
            break;
3107
3108
        /*
3109
        * CASE
3110
        * Update a Group
3111
        */
3112
        case 'update_folder':
3113
            // Check KEY and rights
3114
            if ($post_key !== $_SESSION['key']) {
3115
                echo prepareExchangedData(
3116
                    array(
3117
                        'error' => true,
3118
                        'message' => langHdl('key_is_not_correct'),
3119
                    ),
3120
                    'encode'
3121
                );
3122
                break;
3123
            } elseif ($_SESSION['user_read_only'] === true) {
3124
                echo prepareExchangedData(
3125
                    array(
3126
                        'error' => true,
3127
                        'message' => langHdl('error_not_allowed_to'),
3128
                    ),
3129
                    'encode'
3130
                );
3131
                break;
3132
            }
3133
            // decrypt and retreive data in JSON format
3134
            $dataReceived = prepareExchangedData($post_data, 'decode');
3135
3136
            // Prepare variables
3137
            $title = filter_var(htmlspecialchars_decode($dataReceived['title'], ENT_QUOTES), FILTER_SANITIZE_STRING);
3138
            $post_folder_id = filter_var(htmlspecialchars_decode($dataReceived['folder']), FILTER_SANITIZE_NUMBER_INT);
3139
3140
            // Check if user is allowed to access this folder
3141
            if (!in_array($post_folder_id, $_SESSION['groupes_visibles'])) {
3142
                echo '[{"error" : "'.langHdl('error_not_allowed_to').'"}]';
3143
                break;
3144
            }
3145
3146
            // Check if title doesn't contains html codes
3147
            if (preg_match_all('|<[^>]+>(.*)</[^>]+>|U', $title, $out)) {
3148
                echo '[ { "error" : "'.langHdl('error_html_codes').'" } ]';
3149
                break;
3150
            }
3151
            // check that title is not numeric
3152
            if (is_numeric($title) === true) {
3153
                echo '[{"error" : "ERR_TITLE_ONLY_WITH_NUMBERS"}]';
3154
                break;
3155
            }
3156
3157
            // Check if duplicate folders name are allowed
3158
            $createNewFolder = true;
3159
            if (isset($SETTINGS['duplicate_folder']) && $SETTINGS['duplicate_folder'] === '0') {
3160
                $data = DB::queryFirstRow('SELECT id, title FROM '.prefixTable('nested_tree').' WHERE title = %s', $title);
3161
                if (empty($data['id']) === false && $dataReceived['folder'] != $data['id']) {
3162
                    echo '[ { "error" : "'.langHdl('error_group_exist').'" } ]';
3163
                    break;
3164
                }
3165
            }
3166
3167
            // query on folder
3168
            $data = DB::queryfirstrow(
3169
                'SELECT parent_id, personal_folder
3170
                FROM '.prefixTable('nested_tree').'
3171
                WHERE id = %i',
3172
                $post_folder_id
3173
            );
3174
3175
            // check if complexity level is good
3176
            // if manager or admin don't care
3177
            if ($_SESSION['is_admin'] != 1 && $_SESSION['user_manager'] != 1 && $data['personal_folder'] === '0') {
3178
                $data = DB::queryfirstrow(
3179
                    'SELECT valeur
3180
                    FROM '.prefixTable('misc').'
3181
                    WHERE intitule = %i AND type = %s',
3182
                    $data['parent_id'],
3183
                    'complex'
3184
                );
3185
                if (intval($dataReceived['complexity']) < intval($data['valeur'])) {
3186
                    echo '[ { "error" : "'.langHdl('error_folder_complexity_lower_than_top_folder').' [<b>'.TP_PW_COMPLEXITY[$data['valeur']][1].'</b>]"} ]';
3187
                    break;
3188
                }
3189
            }
3190
3191
            // update Folders table
3192
            $tmp = DB::queryFirstRow(
3193
                'SELECT title, parent_id, personal_folder FROM '.prefixTable('nested_tree').' WHERE id = %i',
3194
                $dataReceived['folder']
3195
            );
3196
            if ($tmp['parent_id'] != 0 || $tmp['title'] != $_SESSION['user_id'] || $tmp['personal_folder'] != 1) {
3197
                DB::update(
3198
                    prefixTable('nested_tree'),
3199
                    array(
3200
                        'title' => $title,
3201
                        ),
3202
                    'id=%s',
3203
                    $post_folder_id
3204
                );
3205
                // update complixity value
3206
                DB::update(
3207
                    prefixTable('misc'),
3208
                    array(
3209
                        'valeur' => $dataReceived['complexity'],
3210
                        ),
3211
                    'intitule = %s AND type = %s',
3212
                    $post_folder_id,
3213
                    'complex'
3214
                );
3215
                // rebuild fuild tree folder
3216
                $tree->rebuild();
3217
            }
3218
            // send data
3219
            echo '[{"error" : ""}]';
3220
            break;
3221
3222
        /*
3223
        * CASE
3224
        * Move a Group including sub-folders
3225
        */
3226
        case 'move_folder':
3227
            // Check KEY and rights
3228
            if ($post_key !== $_SESSION['key']) {
3229
                echo prepareExchangedData(
3230
                    array(
3231
                        'error' => true,
3232
                        'message' => langHdl('key_is_not_correct'),
3233
                    ),
3234
                    'encode'
3235
                );
3236
                break;
3237
            } elseif ($_SESSION['user_read_only'] === true) {
3238
                echo prepareExchangedData(
3239
                    array(
3240
                        'error' => true,
3241
                        'message' => langHdl('error_not_allowed_to'),
3242
                    ),
3243
                    'encode'
3244
                );
3245
                break;
3246
            }
3247
            // decrypt and retreive data in JSON format
3248
            $dataReceived = prepareExchangedData($post_data, 'decode');
3249
            $post_source_folder_id = filter_var(htmlspecialchars_decode($dataReceived['source_folder_id']), FILTER_SANITIZE_NUMBER_INT);
3250
            $post_target_folder_id = filter_var(htmlspecialchars_decode($dataReceived['target_folder_id']), FILTER_SANITIZE_NUMBER_INT);
3251
3252
            // Check that user can access this folder
3253
            if ((
3254
                    in_array($post_source_folder_id, $_SESSION['groupes_visibles']) === false ||
3255
                  in_array($post_target_folder_id, $_SESSION['groupes_visibles']) === false) &&
3256
                  (
3257
                        $post_target_folder_id === '0' &&
3258
                      isset($SETTINGS['can_create_root_folder']) === true && $SETTINGS['can_create_root_folder'] === '1'
3259
                    )
3260
            ) {
3261
                $returnValues = '[{"error" : "'.langHdl('error_not_allowed_to').'"}]';
3262
                echo $returnValues;
3263
                break;
3264
            }
3265
3266
            $tmp_source = DB::queryFirstRow(
3267
                'SELECT title, parent_id, personal_folder
3268
                FROM '.prefixTable('nested_tree').'
3269
                WHERE id = %i',
3270
                $post_source_folder_id
3271
            );
3272
3273
            $tmp_target = DB::queryFirstRow(
3274
                'SELECT title, parent_id, personal_folder
3275
                FROM '.prefixTable('nested_tree').'
3276
                WHERE id = %i',
3277
                $post_target_folder_id
3278
            );
3279
3280
            // check if target is not a child of source
3281
            if ($tree->isChildOf($post_target_folder_id, $post_source_folder_id) === true) {
3282
                $returnValues = '[{"error" : "'.langHdl('error_not_allowed_to').'"}]';
3283
                echo $returnValues;
3284
                break;
3285
            }
3286
3287
            // check if source or target folder is PF. If Yes, then cancel operation
3288
            if ($tmp_source['personal_folder'] === '1' || $tmp_target['personal_folder'] === '1') {
3289
                $returnValues = '[{"error" : "'.langHdl('error_not_allowed_to').'"}]';
3290
                echo $returnValues;
3291
                break;
3292
            }
3293
3294
            // check if source or target folder is PF. If Yes, then cancel operation
3295
            if ($tmp_source['title'] === $_SESSION['user_id'] || $tmp_target['title'] === $_SESSION['user_id']) {
3296
                $returnValues = '[{"error" : "'.langHdl('error_not_allowed_to').'"}]';
3297
                echo $returnValues;
3298
                break;
3299
            }
3300
3301
            // moving SOURCE folder
3302
            DB::update(
3303
                prefixTable('nested_tree'),
3304
                array(
3305
                    'parent_id' => $post_target_folder_id,
3306
                    ),
3307
                'id=%s',
3308
                $post_source_folder_id
3309
            );
3310
            $tree->rebuild();
3311
3312
            // send data
3313
            echo '[{"error" : ""}]';
3314
            break;
3315
3316
        /*
3317
        * CASE
3318
        * Store hierarchic position of Group
3319
        */
3320
        case 'save_position':
3321
            DB::update(
3322
                prefixTable('nested_tree'),
3323
                array(
3324
                    'parent_id' => $post_destination,
3325
                    ),
3326
                'id = %i',
3327
                $post_source
3328
            );
3329
            $tree = new Tree\NestedTree\NestedTree(prefixTable('nested_tree'), 'id', 'parent_id', 'title');
3330
            $tree->rebuild();
3331
            break;
3332
3333
        /*
3334
        * CASE
3335
        * List items of a group
3336
        */
3337
        case 'do_items_list_in_folder':
3338
            // Check KEY and rights
3339
            if ($post_key !== $_SESSION['key']) {
3340
                echo prepareExchangedData(
3341
                    array(
3342
                        'error' => true,
3343
                        'message' => langHdl('error_not_allowed_to'),
3344
                    ),
3345
                    'encode'
3346
                );
3347
                break;
3348
            }
3349
3350
            if (count($_SESSION['user_roles']) === 0) {
3351
                echo prepareExchangedData(
3352
                    array(
3353
                        'error' => true,
3354
                        'message' => langHdl('error_not_allowed_to'),
3355
                    ),
3356
                    'encode'
3357
                );
3358
                break;
3359
            }
3360
3361
            // decrypt and retreive data in JSON format
3362
            $dataReceived = prepareExchangedData(
3363
                $post_data,
3364
                'decode'
3365
            );
3366
3367
            // Prepare POST variables
3368
            $post_id = filter_var($dataReceived['id'], FILTER_SANITIZE_NUMBER_INT);
3369
            $post_restricted = filter_var($dataReceived['restricted'], FILTER_SANITIZE_NUMBER_INT);
3370
            $post_start = filter_var($dataReceived['start'], FILTER_SANITIZE_NUMBER_INT);
3371
            $post_nb_items_to_display_once = filter_var($dataReceived['nb_items_to_display_once'], FILTER_SANITIZE_NUMBER_INT);
3372
3373
            $arboHtml = $html = '';
3374
            $arr_arbo = [];
3375
            $folderIsPf = false;
3376
            $showError = 0;
3377
            $itemsIDList = $rights = $returnedData = $uniqueLoadData = $html_json = array();
3378
            // Build query limits
3379
            if (empty($post_start) === true) {
3380
                $start = 0;
3381
            } else {
3382
                $start = $post_start;
3383
            }
3384
3385
            // to do only on 1st iteration
3386
            if ((int) $start === 0) {
3387
                // Prepare tree
3388
                $arbo = $tree->getPath($post_id, true);
3389
                foreach ($arbo as $elem) {
3390
                    if ($elem->title == $_SESSION['user_id'] && $elem->nlevel === '1') {
3391
                        $elem->title = $_SESSION['login'];
3392
                        $folderIsPf = true;
3393
                    }
3394
                    // Store path elements
3395
                    array_push(
3396
                        $arr_arbo,
3397
                        array(
3398
                            'id' => $elem->id,
3399
                            'title' => htmlspecialchars(stripslashes(htmlspecialchars_decode($elem->title, ENT_QUOTES)), ENT_QUOTES),
3400
                            'visible' => in_array($elem->id, $_SESSION['groupes_visibles']) ? 1 : 0,
3401
                        )
3402
                    );
3403
                }
3404
                $uniqueLoadData['path'] = $arr_arbo;
3405
3406
                // store last folder accessed in cookie
3407
                setcookie(
3408
                    'jstree_select',
3409
                    $post_id,
3410
                    time() + TP_ONE_DAY_SECONDS * $SETTINGS['personal_saltkey_cookie_duration'],
3411
                    '/'
3412
                );
3413
3414
                // CHeck if roles have 'allow_pw_change' set to true
3415
                $forceItemEditPrivilege = false;
3416
                foreach ($_SESSION['user_roles'] as $role) {
3417
                    $roleQ = DB::queryfirstrow(
3418
                        'SELECT allow_pw_change
3419
                        FROM '.prefixTable('roles_title').'
3420
                        WHERE id = %i',
3421
                        $role
3422
                    );
3423
                    if ((int) $roleQ['allow_pw_change'] === 1) {
3424
                        $forceItemEditPrivilege = true;
3425
                        break;
3426
                    }
3427
                }
3428
3429
                // check role access on this folder (get the most restrictive) (2.1.23)
3430
                $accessLevel = 2;
3431
                $arrTmp = [];
3432
                foreach ($_SESSION['user_roles'] as $role) {
3433
                    $access = DB::queryFirstRow(
3434
                        'SELECT type FROM '.prefixTable('roles_values').' WHERE role_id = %i AND folder_id = %i',
3435
                        $role,
3436
                        $post_id
3437
                    );
3438
                    if ($access['type'] === 'R') {
3439
                        array_push($arrTmp, 1);
3440
                    } elseif ($access['type'] === 'W') {
3441
                        array_push($arrTmp, 3);
3442
                    } elseif ($access['type'] === 'ND'
3443
                        || ($forceItemEditPrivilege === true && $access['type'] === 'NDNE')
3444
                    ) {
3445
                        array_push($arrTmp, 2);
3446
                    } elseif ($access['type'] === 'NE') {
3447
                        array_push($arrTmp, 1);
3448
                    } elseif ($access['type'] === 'NDNE') {
3449
                        array_push($arrTmp, 1);
3450
                    } else {
3451
                        // Ensure to give access Right if allowed folder
3452
                        if (in_array($post_id, $_SESSION['groupes_visibles']) === true) {
3453
                            array_push($arrTmp, 3);
3454
                        } else {
3455
                            array_push($arrTmp, 0);
3456
                        }
3457
                    }
3458
                }
3459
                $accessLevel = count($arrTmp) > 0 ? min($arrTmp) : $accessLevel;
3460
                $uniqueLoadData['accessLevel'] = $accessLevel;
3461
3462
                /*
3463
                // check if this folder is a PF. If yes check if saltket is set
3464
                if ((!isset($_SESSION['user_settings']['encrypted_psk']) || empty($_SESSION['user_settings']['encrypted_psk'])) && $folderIsPf === true) {
3465
                    $showError = 'is_pf_but_no_saltkey';
3466
                }
3467
                */
3468
                $uniqueLoadData['showError'] = $showError;
3469
3470
                // check if items exist
3471
                $where = new WhereClause('and');
3472
                if (null !== $post_restricted && (int) $post_restricted === 1 && empty($_SESSION['list_folders_limited'][$post_id]) === false) {
3473
                    $counter = count($_SESSION['list_folders_limited'][$post_id]);
3474
                    $uniqueLoadData['counter'] = $counter;
3475
                // check if this folder is visible
3476
                } elseif (!in_array(
3477
                    $post_id,
3478
                    array_merge(
3479
                        $_SESSION['groupes_visibles'],
3480
                        @array_keys($_SESSION['list_restricted_folders_for_items']),
3481
                        @array_keys($_SESSION['list_folders_limited'])
3482
                    )
3483
                )) {
3484
                    echo prepareExchangedData(
3485
                        array(
3486
                            'error' => 'not_authorized',
3487
                            'arborescence' => $arr_arbo,
3488
                        ),
3489
                        'encode'
3490
                    );
3491
                    break;
3492
                } else {
3493
                    DB::query(
3494
                        'SELECT *
3495
                        FROM '.prefixTable('items').'
3496
                        WHERE inactif = %i',
3497
                        0
3498
                    );
3499
                    $counter = DB::count();
3500
                    $uniqueLoadData['counter'] = $counter;
3501
                }
3502
3503
                /*
3504
                // Identify if it is a personal folder
3505
                if (in_array($post_id, $_SESSION['personal_visible_groups'])) {
3506
                    $findPfGroup = 1;
3507
                } else {
3508
                    $findPfGroup = '';
3509
                }
3510
                $uniqueLoadData['findPfGroup'] = $findPfGroup;
3511
                */
3512
3513
                // Get folder complexity
3514
                $folderComplexity = DB::queryFirstRow(
3515
                    'SELECT valeur FROM '.prefixTable('misc').' WHERE type = %s AND intitule = %i',
3516
                    'complex',
3517
                    $post_id
3518
                );
3519
                $folderComplexity = $folderComplexity['valeur'];
3520
                $uniqueLoadData['folderComplexity'] = $folderComplexity;
3521
3522
                // Has this folder some categories to be displayed?
3523
                $categoriesStructure = array();
3524
                if (isset($SETTINGS['item_extra_fields']) && $SETTINGS['item_extra_fields'] === '1') {
3525
                    $folderRow = DB::query(
3526
                        'SELECT id_category
3527
                        FROM '.prefixTable('categories_folders').'
3528
                        WHERE id_folder = %i',
3529
                        $post_id
3530
                    );
3531
                    foreach ($folderRow as $category) {
3532
                        array_push(
3533
                            $categoriesStructure,
3534
                            $category['id_category']
3535
                        );
3536
                    }
3537
                }
3538
                $uniqueLoadData['categoriesStructure'] = $categoriesStructure;
3539
3540
                /*$categoriesStructure = array();
3541
                if (isset($SETTINGS['item_extra_fields']) && $SETTINGS['item_extra_fields'] === '1') {
3542
                    $folderRow = DB::query(
3543
                        'SELECT f.id_category, c.title AS title
3544
                        FROM '.prefixTable('categories_folders').' AS f
3545
                        INNER JOIN '.prefixTable('categories').' AS c ON (c.id = f.id_category)
3546
                        WHERE f.id_folder = %i',
3547
                        $post_id
3548
                    );
3549
                    foreach ($folderRow as $category) {
3550
                        $arrFields = array();
3551
                        // Get each category definition with fields
3552
                        $categoryRow = DB::query(
3553
                            "SELECT *
3554
                            FROM ".prefixTable("categories")."
3555
                            WHERE parent_id=%i
3556
                            ORDER BY `order` ASC",
3557
                            $category['id_category']
3558
                        );
3559
3560
                        if (DB::count() > 0) {
3561
                            foreach ($categoryRow as $field) {
3562
                                // Is this Field visibile by user?
3563
                                if ($field['role_visibility'] === 'all'
3564
                                    || count(
3565
                                        array_intersect(
3566
                                            explode(';', $_SESSION['fonction_id']),
3567
                                            explode(',', $field['role_visibility'])
3568
                                        )
3569
                                    ) > 0
3570
                                ) {
3571
                                    array_push(
3572
                                        $arrFields,
3573
                                        array(
3574
                                            $field['id'],
3575
                                            $field['title'],
3576
                                            $field['encrypted_data'],
3577
                                            $field['type'],
3578
                                            $field['masked'],
3579
                                            $field['is_mandatory']
3580
                                        )
3581
                                    );
3582
                                }
3583
                            }
3584
                        }
3585
3586
                        // store the categories
3587
                        array_push(
3588
                            $categoriesStructure,
3589
                            array(
3590
                                $category['id_category'],
3591
                                $category['title'],
3592
                                $arrFields
3593
                            )
3594
                        );
3595
                    }
3596
                }
3597
                $uniqueLoadData['categoriesStructure'] = $categoriesStructure;
3598
                */
3599
3600
                // is this folder a personal one
3601
                $folder_is_personal = in_array($post_id, $_SESSION['personal_folders']);
3602
                $uniqueLoadData['folder_is_personal'] = $folder_is_personal;
3603
3604
                $folder_is_in_personal = in_array($post_id, array_merge($_SESSION['personal_visible_groups'], $_SESSION['personal_folders']));
3605
                $uniqueLoadData['folder_is_in_personal'] = $folder_is_in_personal;
3606
3607
                if (isset($_SESSION['list_folders_editable_by_role'])) {
3608
                    $list_folders_editable_by_role = in_array($post_id, $_SESSION['list_folders_editable_by_role']);
3609
                } else {
3610
                    $list_folders_editable_by_role = '';
3611
                }
3612
                $uniqueLoadData['list_folders_editable_by_role'] = $list_folders_editable_by_role;
3613
            } else {
3614
                $uniqueLoadData = json_decode(
3615
                    filter_var($dataReceived['uniqueLoadData'], FILTER_UNSAFE_RAW),
3616
                    true
3617
                );
3618
3619
                // initialize main variables
3620
                $showError = $uniqueLoadData['showError'];
3621
                $accessLevel = $uniqueLoadData['accessLevel'];
3622
                $counter = $uniqueLoadData['counter'];
3623
                //$findPfGroup = $uniqueLoadData['findPfGroup'];
3624
                $counter_full = $uniqueLoadData['counter_full'];
3625
                $categoriesStructure = $uniqueLoadData['categoriesStructure'];
3626
                $folderComplexity = $uniqueLoadData['folderComplexity'];
3627
                //$arboHtml = $uniqueLoadData['arboHtml'];
3628
                $folder_is_personal = $uniqueLoadData['folder_is_personal'];
3629
                $folder_is_in_personal = $uniqueLoadData['folder_is_in_personal'];
3630
                $list_folders_editable_by_role = $uniqueLoadData['list_folders_editable_by_role'];
3631
            }
3632
3633
            // prepare query WHere conditions
3634
            $where = new WhereClause('and');
3635
            if (null !== $post_restricted && (int) $post_restricted === 1 && empty($_SESSION['list_folders_limited'][$post_id]) === false) {
3636
                $where->add('i.id IN %ls', $_SESSION['list_folders_limited'][$post_id]);
3637
            } else {
3638
                $where->add('i.id_tree=%i', $post_id);
3639
            }
3640
3641
            // build the HTML for this set of Items
3642
            if ($counter > 0 && empty($showError)) {
3643
                // init variables
3644
                $init_personal_folder = false;
3645
                $expired_item = false;
3646
                $limited_to_items = '';
3647
3648
                // List all ITEMS
3649
                if ($folderIsPf === false) {
3650
                    $where->add('i.inactif=%i', 0);
3651
                    $where->add('l.date=%l', '(SELECT date FROM '.prefixTable('log_items')." WHERE action IN ('at_creation', 'at_modification') AND id_item=i.id ORDER BY date DESC LIMIT 1)");
3652
                    if (empty($limited_to_items) === false) {
3653
                        $where->add('i.id IN %ls', explode(',', $limited_to_items));
3654
                    }
3655
3656
                    $query_limit = ' LIMIT '.
3657
                        $start.','.
3658
                        $post_nb_items_to_display_once;
3659
                    //db::debugmode(true);
3660
                    $rows = DB::query(
3661
                        'SELECT i.id AS id, MIN(i.restricted_to) AS restricted_to, MIN(i.perso) AS perso,
3662
                        MIN(i.label) AS label, MIN(i.description) AS description, MIN(i.pw) AS pw, MIN(i.login) AS login,
3663
                        MIN(i.anyone_can_modify) AS anyone_can_modify, l.date AS date, i.id_tree AS tree_id,
3664
                        MIN(n.renewal_period) AS renewal_period,
3665
                        MIN(l.action) AS log_action, l.id_user AS log_user
3666
                        FROM '.prefixTable('items').' AS i
3667
                        INNER JOIN '.prefixTable('nested_tree').' AS n ON (i.id_tree = n.id)
3668
                        INNER JOIN '.prefixTable('log_items').' AS l ON (i.id = l.id_item)
3669
                        WHERE %l
3670
                        GROUP BY i.id, l.date, l.id_user, l.action
3671
                        ORDER BY i.label ASC, l.date DESC'.$query_limit,
3672
                        $where
3673
                    );
3674
                //db::debugmode(false);
3675
                } else {
3676
                    $post_nb_items_to_display_once = 'max';
3677
                    $where->add('i.inactif=%i', 0);
3678
3679
                    $rows = DB::query(
3680
                        'SELECT i.id AS id, MIN(i.restricted_to) AS restricted_to, MIN(i.perso) AS perso,
3681
                        MIN(i.label) AS label, MIN(i.description) AS description, MIN(i.pw) AS pw, MIN(i.login) AS login,
3682
                        MIN(i.anyone_can_modify) AS anyone_can_modify,l.date AS date, i.id_tree AS tree_id,
3683
                        MIN(n.renewal_period) AS renewal_period,
3684
                        MIN(l.action) AS log_action, l.id_user AS log_user
3685
                        FROM '.prefixTable('items').' AS i
3686
                        INNER JOIN '.prefixTable('nested_tree').' AS n ON (i.id_tree = n.id)
3687
                        INNER JOIN '.prefixTable('log_items').' AS l ON (i.id = l.id_item)
3688
                        WHERE %l
3689
                        GROUP BY i.id, l.date, l.id_user, l.action
3690
                        ORDER BY i.label ASC, l.date DESC',
3691
                        $where
3692
                    );
3693
                }
3694
3695
                $idManaged = '';
3696
                $i = 0;
3697
                $arr_items_html = array();
3698
3699
                foreach ($rows as $record) {
3700
                    // exclude all results except the first one returned by query
3701
                    if (empty($idManaged) === true || $idManaged !== $record['id']) {
3702
                        // Fix a bug on Personal Item creation - field `perso` must be set to `1`
3703
                        if ((int) $record['perso'] !== 1 && (int) $folder_is_personal === 1) {
3704
                            DB::update(
3705
                                prefixTable('items'),
3706
                                array(
3707
                                    'perso' => 1,
3708
                                ),
3709
                                'id=%i',
3710
                                $record['id']
3711
                            );
3712
                            $record['perso'] = 1;
3713
                        }
3714
3715
                        // Does this item has restriction to groups of users?
3716
                        $item_is_restricted_to_role = false;
3717
                        DB::queryfirstrow(
3718
                            'SELECT role_id
3719
                            FROM '.prefixTable('restriction_to_roles').'
3720
                            WHERE item_id = %i',
3721
                            $record['id']
3722
                        );
3723
                        if (DB::count() > 0) {
3724
                            $item_is_restricted_to_role = true;
3725
                        }
3726
3727
                        // Has this item a restriction to Groups of Users
3728
                        $user_is_included_in_role = false;
3729
                        $roles = DB::query(
3730
                            'SELECT role_id
3731
                            FROM '.prefixTable('restriction_to_roles').'
3732
                            WHERE item_id = %i AND role_id IN %ls',
3733
                            $record['id'],
3734
                            $_SESSION['user_roles']
3735
                        );
3736
                        if (DB::count() > 0) {
3737
                            $user_is_included_in_role = true;
3738
                        }
3739
3740
                        // Is user in restricted list of users
3741
                        if (empty($record['restricted_to']) === false) {
3742
                            if (in_array($_SESSION['user_id'], explode(';', $record['restricted_to'])) === true
3743
                                || (((int) $_SESSION['user_manager'] === 1 || (int) $_SESSION['user_can_manage_all_users'] === 1)
3744
                                && (int) $SETTINGS['manager_edit'] === 1)
3745
                            ) {
3746
                                $user_is_in_restricted_list = true;
3747
                            } else {
3748
                                $user_is_in_restricted_list = false;
3749
                            }
3750
                        } else {
3751
                            $user_is_in_restricted_list = false;
3752
                        }
3753
3754
                        // Get Expiration date
3755
                        $expired_item = 0;
3756
                        if ((int) $SETTINGS['activate_expiration'] === 1
3757
                            && $record['renewal_period'] > 0
3758
                            && ($record['date'] + ($record['renewal_period'] * TP_ONE_MONTH_SECONDS)) < time()
3759
                        ) {
3760
                            $expired_item = 1;
3761
                        }
3762
                        // Init
3763
                        $html_json[$record['id']]['expired'] = (int) $expired_item;
3764
                        $html_json[$record['id']]['item_id'] = (int) $record['id'];
3765
                        $html_json[$record['id']]['tree_id'] = (int) $record['tree_id'];
3766
                        $html_json[$record['id']]['label'] = strip_tags($record['label']);
3767
                        if (isset($SETTINGS['show_description']) === true && $SETTINGS['show_description'] === '1') {
3768
                            $html_json[$record['id']]['desc'] = strip_tags((explode('<br>', $record['description'])[0]));
3769
                        } else {
3770
                            $html_json[$record['id']]['desc'] = '';
3771
                        }
3772
                        $html_json[$record['id']]['login'] = $record['login'];
3773
                        $html_json[$record['id']]['anyone_can_modify'] = (int) $record['anyone_can_modify'];
3774
                        $html_json[$record['id']]['is_result_of_search'] = 0;
3775
                        $html_json[$record['id']]['is_favourited'] = in_array($record['id'], $_SESSION['favourites']) === true ? 1 : 0;
3776
3777
                        /*************** */
3778
                        $showItem = 0;
3779
                        // Possible values:
3780
                        // 0 -> no access to item
3781
                        // 10 -> appears in list but no view
3782
                        // 20 -> can view without edit (no copy) or move
3783
                        // 30 -> can view without edit (no copy) but can move
3784
                        // 40 -> can edit but not move
3785
                        // 50 -> can edit and move
3786
                        $itemIsPersonal = false;
3787
3788
                        // Let's identify the rights belonging to this ITEM
3789
                        if ((int) $record['perso'] === 1
3790
                            && $record['log_action'] === 'at_creation'
3791
                            && $record['log_user'] === $_SESSION['user_id']
3792
                            && (int) $folder_is_in_personal === 1
3793
                            && (int) $folder_is_personal === 1
3794
                        ) {
3795
                            // Case 1 - Is this item personal and user its owner?
3796
                            // If yes then allow
3797
                            // If no then continue
3798
                            $itemIsPersonal = true;
3799
                            $right = 70;
3800
                        // ---
3801
                            // ----- END CASE 1 -----
3802
                        } elseif (((isset($_SESSION['user_manager']) === true && (int) $_SESSION['user_manager'] === 1)
3803
                            || (isset($_SESSION['user_can_manage_all_users']) === true && (int) $_SESSION['user_can_manage_all_users'] === 1))
3804
                            && (isset($SETTINGS['manager_edit']) === true && (int) $SETTINGS['manager_edit'] === 1)
3805
                            && (int) $record['perso'] !== 1
3806
                            && $user_is_in_restricted_list === true
3807
                        ) {
3808
                            // Case 2 - Is user manager and option "manager_edit" set to true?
3809
                            // Allow all rights
3810
                            $right = 70;
3811
                        // ---
3812
                            // ----- END CASE 2 -----
3813
                        } elseif ((int) $record['anyone_can_modify'] === 1
3814
                            && (int) $record['perso'] !== 1
3815
                            && (int) $_SESSION['user_read_only'] !== 1
3816
                        ) {
3817
                            // Case 3 - Has this item the setting "anyone can modify" set to true?
3818
                            // Allow all rights
3819
                            $right = 70;
3820
                        // ---
3821
                            // ----- END CASE 3 -----
3822
                        } elseif ($user_is_in_restricted_list === true
3823
                            && (int) $record['perso'] !== 1
3824
                            && (int) $_SESSION['user_read_only'] !== 1
3825
                        ) {
3826
                            // Case 4 - Is this item limited to Users? Is current user in this list?
3827
                            // Allow all rights
3828
                            $right = 70;
3829
                        // ---
3830
                            // ----- END CASE 4 -----
3831
                        } elseif ($user_is_included_in_role === true
3832
                            && (int) $record['perso'] !== 1
3833
                            && (int) $_SESSION['user_read_only'] !== 1
3834
                        ) {
3835
                            // Case 5 - Is this item limited to group of users? Is current user in one of those groups?
3836
                            // Allow all rights
3837
                            $right = 60;
3838
                        // ---
3839
                            // ----- END CASE 5 -----
3840
                        } elseif ((int) $record['perso'] !== 1
3841
                            && (int) $_SESSION['user_read_only'] === 1
3842
                        ) {
3843
                            // Case 6 - Is user readonly?
3844
                            // Allow limited rights
3845
                            $right = 10;
3846
                        // ---
3847
                            // ----- END CASE 6 -----
3848
                        } elseif ((int) $record['perso'] !== 1
3849
                            && (int) $_SESSION['user_read_only'] === 1
3850
                        ) {
3851
                            // Case 7 - Is user readonly?
3852
                            // Allow limited rights
3853
                            $right = 10;
3854
                        // ---
3855
                            // ----- END CASE 7 -----
3856
                        } elseif ((int) $record['perso'] !== 1
3857
                            && (int) $_SESSION['user_read_only'] === 1
3858
                        ) {
3859
                            // Case 8 - Is user allowed to access?
3860
                            // Allow rights
3861
                            $right = 10;
3862
                        // ---
3863
                            // ----- END CASE 8 -----
3864
                        } elseif (($user_is_included_in_role === false && $item_is_restricted_to_role === true)
3865
                            && (int) $record['perso'] !== 1
3866
                            && (int) $_SESSION['user_read_only'] !== 1
3867
                        ) {
3868
                            // Case 9 - Is this item limited to Users or Groups? Is current user in this list?
3869
                            // If no then Allow none
3870
                            $right = 10;
3871
                        // ---
3872
                            // ----- END CASE 9 -----
3873
                        } else {
3874
                            // Define the access based upon setting on folder
3875
                            // 0 -> no access to item
3876
                            // 10 -> appears in list but no view
3877
                            // 20 -> can view without edit (no copy) or move or delete
3878
                            // 30 -> can view without edit (no copy) or delete but can move
3879
                            // 40 -> can edit but not move and not delete
3880
                            // 50 -> can edit and delete but not move
3881
                            // 60 -> can edit and move but not delete
3882
                            // 70 -> can edit and move
3883
                            if ((int) $accessLevel === 0) {
3884
                                $right = 0;
3885
                            } elseif ((int) $accessLevel === 1) {
3886
                                $right = 20;
3887
                            } elseif ((int) $accessLevel === 2) {
3888
                                $right = 60;
3889
                            } elseif ((int) $accessLevel === 3) {
3890
                                $right = 70;
3891
                            } else {
3892
                                $right = 10;
3893
                            }
3894
                        }
3895
3896
                        // Now finalize the data to send back
3897
                        $html_json[$record['id']]['rights'] = $right;
3898
                        $html_json[$record['id']]['perso'] = 'fa-tag mi-red';
3899
                        $html_json[$record['id']]['sk'] = $itemIsPersonal === true ? 1 : 0;
3900
                        $html_json[$record['id']]['display'] = $right > 0 ? 1 : 0;
3901
                        $html_json[$record['id']]['open_edit'] = in_array($right, array(40, 50, 60, 70)) === true ? 1 : 0;
3902
                        $html_json[$record['id']]['canMove'] = in_array($right, array(30, 60, 70)) === true ? 1 : 0;
3903
3904
                        //*************** */
3905
3906
                        // Build array with items
3907
                        array_push(
3908
                            $itemsIDList,
3909
                            array(
3910
                                'id' => (int) $record['id'],
3911
                                //'display' => $displayItem,
3912
                                'edit' => $html_json[$record['id']]['open_edit'],
3913
                            )
3914
                        );
3915
3916
                        ++$i;
3917
                    }
3918
                    $idManaged = $record['id'];
3919
                }
3920
3921
                $rights = recupDroitCreationSansComplexite($post_id);
3922
            }
3923
3924
            // DELETE - 2.1.19 - AND (l.action = 'at_creation' OR (l.action = 'at_modification' AND l.raison LIKE 'at_pw :%'))
3925
            // count
3926
            if ((int) $start === 0) {
3927
                DB::query(
3928
                    'SELECT i.id
3929
                    FROM '.prefixTable('items').' as i
3930
                    INNER JOIN '.prefixTable('nested_tree').' as n ON (i.id_tree = n.id)
3931
                    INNER JOIN '.prefixTable('log_items').' as l ON (i.id = l.id_item)
3932
                    WHERE %l
3933
                    ORDER BY i.label ASC, l.date DESC',
3934
                    $where
3935
                );
3936
                $counter_full = DB::count();
3937
                $uniqueLoadData['counter_full'] = $counter_full;
3938
            }
3939
3940
            // Check list to be continued status
3941
            if ($post_nb_items_to_display_once !== 'max' && ($post_nb_items_to_display_once + $start) < $counter_full) {
3942
                $listToBeContinued = 'yes';
3943
            } else {
3944
                $listToBeContinued = 'end';
3945
            }
3946
3947
            // Prepare returned values
3948
            $returnValues = array(
3949
                'html_json' => $html_json,
3950
                //'folder_requests_psk' => $findPfGroup,
3951
                'arborescence' => $arr_arbo,
3952
                'array_items' => $itemsIDList,
3953
                'error' => $showError,
3954
                //'saltkey_is_required' => $folderIsPf === true ? 1 : 0,
3955
                'show_clipboard_small_icons' => isset($SETTINGS['copy_to_clipboard_small_icons']) && $SETTINGS['copy_to_clipboard_small_icons'] === '1' ? 1 : 0,
3956
                'next_start' => intval($post_nb_items_to_display_once) + intval($start),
3957
                'list_to_be_continued' => $listToBeContinued,
3958
                'items_count' => $counter,
3959
                'counter_full' => $counter_full,
3960
                'folder_complexity' => (int) $folderComplexity,
3961
                'categoriesStructure' => $categoriesStructure,
3962
                'access_level' => $accessLevel,
3963
                'IsPersonalFolder' => $folderIsPf === true ? 1 : 0,
3964
                'uniqueLoadData' => json_encode($uniqueLoadData),
3965
            );
3966
            // Check if $rights is not null
3967
            if (count($rights) > 0) {
3968
                $returnValues = array_merge($returnValues, $rights);
3969
            }
3970
3971
            // Encrypt data to return
3972
            echo prepareExchangedData($returnValues, 'encode');
3973
3974
            break;
3975
3976
        /*
3977
        *
3978
        *
3979
        */
3980
        case 'show_item_password':
3981
            // Check KEY
3982
            if ($post_key !== $_SESSION['key']) {
3983
                echo prepareExchangedData(
3984
                    array(
3985
                        'error' => true,
3986
                        'message' => langHdl('key_is_not_correct'),
3987
                    ),
3988
                    'encode'
3989
                );
3990
                break;
3991
            }
3992
3993
            // Prepare POST variables
3994
            $post_item_id = filter_input(INPUT_POST, 'item_id', FILTER_SANITIZE_NUMBER_INT);
3995
3996
            // Run query
3997
            $dataItem = DB::queryfirstrow(
3998
                'SELECT i.pw AS pw, s.share_key AS share_key
3999
                FROM '.prefixTable('items').' AS i
4000
                INNER JOIN '.prefixTable('sharekeys_items').' AS s ON (s.object_id = i.id)
4001
                WHERE user_id = %i AND i.id = %i',
4002
                $_SESSION['user_id'],
4003
                $post_item_id
4004
            );
4005
4006
            // Uncrypt PW
4007
            if (DB::count() === 0) {
4008
                // No share key found
4009
                $pw = '';
4010
            } else {
4011
                $pw = doDataDecryption(
4012
                    $dataItem['pw'],
4013
                    decryptUserObjectKey(
4014
                        $dataItem['share_key'],
4015
                        $_SESSION['user']['private_key']
4016
                    )
4017
                );
4018
            }
4019
4020
            $returnValues = array(
4021
                'error' => false,
4022
                'password' => $pw,
4023
                'password_error' => '',
4024
            );
4025
4026
            // Encrypt data to return
4027
            echo prepareExchangedData($returnValues, 'encode');
4028
            break;
4029
4030
        /*
4031
        * CASE
4032
        * Get complexity level of a group
4033
        */
4034
        case 'get_complixity_level':
4035
            // Prepare POST variables
4036
            $post_groupe = filter_input(INPUT_POST, 'groupe', FILTER_SANITIZE_STRING);
4037
            $post_context = filter_input(INPUT_POST, 'context', FILTER_SANITIZE_STRING);
4038
4039
            // get some info about ITEM
4040
            if (null !== $post_item_id && empty($post_item_id) === false) {
4041
                $dataItem = DB::queryfirstrow(
4042
                    'SELECT perso, anyone_can_modify
4043
                    FROM '.prefixTable('items').'
4044
                    WHERE id=%i',
4045
                    $post_item_id
4046
                );
4047
4048
                // is user allowed to access this folder - readonly
4049
                if (null !== $post_groupe && empty($post_groupe) === false) {
4050
                    if (in_array($post_groupe, $_SESSION['read_only_folders']) === true
4051
                        || in_array($post_groupe, $_SESSION['groupes_visibles']) === false
4052
                    ) {
4053
                        // check if this item can be modified by anyone
4054
                        if (isset($SETTINGS['anyone_can_modify']) && (int) $SETTINGS['anyone_can_modify'] === 1) {
4055
                            if ((int) $dataItem['anyone_can_modify'] !== 1) {
4056
                                // else return not authorized
4057
                                $returnValues = array(
4058
                                    'error' => true,
4059
                                    'message' => langHdl('error_not_allowed_to1'),
4060
                                );
4061
                                echo prepareExchangedData($returnValues, 'encode');
4062
                                break;
4063
                            }
4064
                        } else {
4065
                            // else return not authorized
4066
                            $returnValues = array(
4067
                                'error' => true,
4068
                                'message' => langHdl('error_not_allowed_to'),
4069
                            );
4070
                            echo prepareExchangedData($returnValues, 'encode');
4071
                            break;
4072
                        }
4073
                    }
4074
                }
4075
4076
                // Lock Item (if already locked), go back and warn
4077
                $dataTmp = DB::queryFirstRow('SELECT timestamp, user_id FROM '.prefixTable('items_edition').' WHERE item_id = %i', $post_item_id);
4078
4079
                // If token is taken for this Item and delay is passed then delete it.
4080
                if (isset($SETTINGS['delay_item_edition']) &&
4081
                    $SETTINGS['delay_item_edition'] > 0 && empty($dataTmp['timestamp']) === false &&
4082
                    round(abs(time() - $dataTmp['timestamp']) / 60, 2) > $SETTINGS['delay_item_edition']
4083
                ) {
4084
                    DB::delete(prefixTable('items_edition'), 'item_id = %i', $post_item_id);
4085
                    //reload the previous data
4086
                    $dataTmp = DB::queryFirstRow(
4087
                        'SELECT timestamp, user_id FROM '.prefixTable('items_edition').' WHERE item_id = %i',
4088
                        $post_item_id
4089
                    );
4090
                }
4091
4092
                // If edition by same user (and token not freed before for any reason, then update timestamp)
4093
                if (empty($dataTmp['timestamp']) === false && $dataTmp['user_id'] == $_SESSION['user_id']) {
4094
                    DB::update(
4095
                        prefixTable('items_edition'),
4096
                        array(
4097
                            'timestamp' => time(),
4098
                        ),
4099
                        'user_id = %i AND item_id = %i',
4100
                        $_SESSION['user_id'],
4101
                        $post_item_id
4102
                    );
4103
                // If no token for this Item, then initialize one
4104
                } elseif (empty($dataTmp[0])) {
4105
                    DB::insert(
4106
                        prefixTable('items_edition'),
4107
                        array(
4108
                            'timestamp' => time(),
4109
                            'item_id' => $post_item_id,
4110
                            'user_id' => $_SESSION['user_id'],
4111
                        )
4112
                    );
4113
                // Edition not possible
4114
                } else {
4115
                    $returnValues = array(
4116
                        'error' => true,
4117
                        'message' => langHdl('error_no_edition_possible_locked'),
4118
                    );
4119
                    echo prepareExchangedData($returnValues, 'encode');
4120
                    break;
4121
                }
4122
            }
4123
4124
            // do query on this folder
4125
            $data_this_folder = DB::queryFirstRow(
4126
                'SELECT id, personal_folder, title
4127
                FROM '.prefixTable('nested_tree').'
4128
                WHERE id = %s',
4129
                $post_groupe
4130
            );
4131
4132
            // check if user can perform this action
4133
            if (null !== $post_context
4134
                && empty($post_context) === false
4135
            ) {
4136
                if ($post_context === 'create_folder'
4137
                    || $post_context === 'edit_folder'
4138
                    || $post_context === 'delete_folder'
4139
                    || $post_context === 'copy_folder'
4140
                ) {
4141
                    if ((int) $_SESSION['is_admin'] !== 1
4142
                        && ((int) $_SESSION['user_manager'] !== 1)
4143
                        && (
4144
                            isset($SETTINGS['enable_user_can_create_folders'])
4145
                           && (int) $SETTINGS['enable_user_can_create_folders'] !== 1
4146
                        )
4147
                        && (
4148
                            (int) $data_this_folder['personal_folder'] !== 1 && $data_this_folder['title'] !== $_SESSION['user_id']
4149
                        )   // take into consideration if this is a personal folder
4150
                    ) {
4151
                        $returnValues = array(
4152
                            'error' => true,
4153
                            'message' => langHdl('error_not_allowed_to'),
4154
                        );
4155
                        echo prepareExchangedData($returnValues, 'encode');
4156
                        break;
4157
                    }
4158
                }
4159
            }
4160
4161
            // Get required Complexity for this Folder
4162
            $visibilite = '';
4163
            $data = DB::queryFirstRow(
4164
                'SELECT m.valeur, n.personal_folder
4165
                FROM '.prefixTable('misc').' AS m
4166
                INNER JOIN '.prefixTable('nested_tree').' AS n ON (m.intitule = n.id)
4167
                WHERE type=%s AND intitule = %s',
4168
                'complex',
4169
                $post_groupe
4170
            );
4171
4172
            if (isset($data['valeur']) === true && (empty($data['valeur']) === false || $data['valeur'] === '0')) {
4173
                $complexity = TP_PW_COMPLEXITY[$data['valeur']][1];
4174
                //$folder_is_personal = $data['personal_folder'];
4175
4176
                // Prepare Item actual visibility (what Users/Roles can see it)
4177
                $rows = DB::query(
4178
                    'SELECT t.title
4179
                    FROM '.prefixTable('roles_values').' as v
4180
                    INNER JOIN '.prefixTable('roles_title').' as t ON (v.role_id = t.id)
4181
                    WHERE v.folder_id = %i
4182
                    GROUP BY title',
4183
                    $post_groupe
4184
                );
4185
                foreach ($rows as $record) {
4186
                    if (empty($visibilite)) {
4187
                        $visibilite = $record['title'];
4188
                    } else {
4189
                        $visibilite .= ' - '.$record['title'];
4190
                    }
4191
                }
4192
            } else {
4193
                $complexity = langHdl('not_defined');
4194
4195
                // if not defined, then previous query failed and personal_folder is null
4196
                // do new query to know if current folder is pf
4197
                $data_pf = DB::queryFirstRow(
4198
                    'SELECT personal_folder
4199
                    FROM '.prefixTable('nested_tree').'
4200
                    WHERE id = %s',
4201
                    $post_groupe
4202
                );
4203
                //$folder_is_personal = $data_pf['personal_folder'];
4204
                $visibilite = $_SESSION['name'].' '.$_SESSION['lastname'].' ('.$_SESSION['login'].')';
4205
            }
4206
4207
            recupDroitCreationSansComplexite($post_groupe);
4208
4209
            // get list of roles
4210
            $listOptionsForUsers = array();
4211
            $listOptionsForRoles = array();
4212
            $rows = DB::query(
4213
                'SELECT r.role_id AS role_id, t.title AS title
4214
                FROM '.prefixTable('roles_values').' AS r
4215
                INNER JOIN '.prefixTable('roles_title').' AS t ON (r.role_id = t.id)
4216
                WHERE r.folder_id = %i',
4217
                $post_groupe
4218
            );
4219
            foreach ($rows as $record) {
4220
                array_push(
4221
                    $listOptionsForRoles,
4222
                    array(
4223
                        'id' => $record['role_id'],
4224
                        'title' => $record['title'],
4225
                    )
4226
                );
4227
                $rows2 = DB::query(
4228
                    'SELECT id, login, fonction_id, email, name, lastname
4229
                    FROM '.prefixTable('users').'
4230
                    WHERE admin = 0'
4231
                );
4232
                foreach ($rows2 as $record2) {
4233
                    foreach (explode(';', $record2['fonction_id']) as $role) {
4234
                        if (array_search($record2['id'], array_column($listOptionsForUsers, 'id')) === false
4235
                            && $role === $record['role_id']
4236
                        ) {
4237
                            array_push(
4238
                                $listOptionsForUsers,
4239
                                array(
4240
                                    'id' => $record2['id'],
4241
                                    'login' => $record2['login'],
4242
                                    'name' => $record2['name'].' '.$record2['lastname'],
4243
                                    'email' => $record2['email'],
4244
                                )
4245
                            );
4246
                        }
4247
                    }
4248
                }
4249
            }
4250
4251
            $returnValues = array(
4252
                'folderId' => (int) $post_groupe,
4253
                'error' => false,
4254
                'val' => (int) $data['valeur'],
4255
                'visibility' => $visibilite,
4256
                'complexity' => $complexity,
4257
                //'personal' => $folder_is_personal,
4258
                'usersList' => $listOptionsForUsers,
4259
                'rolesList' => $listOptionsForRoles,
4260
                'setting_restricted_to_roles' => isset($SETTINGS['restricted_to_roles']) === true
4261
                    && (int) $SETTINGS['restricted_to_roles'] === 1 ? 1 : 0,
4262
            );
4263
            echo prepareExchangedData($returnValues, 'encode');
4264
            break;
4265
4266
        /*
4267
        * CASE
4268
        * DELETE attached file from an item
4269
        */
4270
        case 'delete_attached_file':
4271
            // Check KEY
4272
            if ($post_key !== $_SESSION['key']) {
4273
                echo prepareExchangedData(
4274
                    array(
4275
                        'error' => true,
4276
                        'message' => langHdl('key_is_not_correct'),
4277
                    ),
4278
                    'encode'
4279
                );
4280
                break;
4281
            }
4282
4283
            // decrypt and retreive data in JSON format
4284
            $dataReceived = prepareExchangedData(
4285
                $post_data,
4286
                'decode'
4287
            );
4288
            $fileId = filter_var($dataReceived['file_id'], FILTER_SANITIZE_NUMBER_INT);
4289
4290
            // Get some info before deleting
4291
            $data = DB::queryFirstRow(
4292
                'SELECT name, id_item, file
4293
                FROM '.prefixTable('files').'
4294
                WHERE id = %i',
4295
                $fileId
4296
            );
4297
4298
            // Load item data
4299
            $data_item = DB::queryFirstRow(
4300
                'SELECT id_tree
4301
                FROM '.prefixTable('items').'
4302
                WHERE id = %i',
4303
                $data['id_item']
4304
            );
4305
4306
            // Check that user can access this folder
4307
            if (in_array($data_item['id_tree'], $_SESSION['groupes_visibles']) === false) {
4308
                echo prepareExchangedData(array('error' => 'ERR_FOLDER_NOT_ALLOWED'), 'encode');
4309
                break;
4310
            }
4311
4312
            if (empty($data['id_item']) === false) {
4313
                // Delete from FILES table
4314
                DB::delete(
4315
                    prefixTable('files'),
4316
                    'id = %i',
4317
                    $fileId
4318
                );
4319
4320
                // Update the log
4321
                logItems(
4322
                    $SETTINGS,
4323
                    $data['id_item'],
4324
                    $data['name'],
4325
                    $_SESSION['user_id'],
4326
                    'at_modification',
4327
                    $_SESSION['login'],
4328
                    'at_del_file : '.$data['name']
4329
                );
4330
4331
                // DElete sharekeys
4332
                DB::delete(
4333
                    prefixTable('sharekeys_files'),
4334
                    'object_id = %i',
4335
                    $fileId
4336
                );
4337
4338
                // Delete file from server
4339
                fileDelete($SETTINGS['path_to_upload_folder'].'/'.TP_FILE_PREFIX.base64_decode($data['file']), $SETTINGS);
4340
            }
4341
4342
            echo prepareExchangedData(
4343
                array(
4344
                    'error' => false,
4345
                    'message' => '',
4346
                ),
4347
                'encode'
4348
            );
4349
            break;
4350
4351
        /*
4352
        * CASE
4353
        * Clear HTML tags
4354
        */
4355
        case 'clear_html_tags':
4356
            // Get information for this item
4357
            $dataItem = DB::queryfirstrow(
4358
                'SELECT description FROM '.prefixTable('items').' WHERE id=%i',
4359
                filter_input(INPUT_POST, 'id_item', FILTER_SANITIZE_NUMBER_INT)
4360
            );
4361
            // Clean up the string
4362
            echo json_encode(array('description' => strip_tags($dataItem['description'])), JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP);
4363
            break;
4364
4365
        /*
4366
        * FUNCTION
4367
        * Launch an action when clicking on a quick icon
4368
        * $action = 0 => Make not favorite
4369
        * $action = 1 => Make favorite
4370
        */
4371
        case 'action_on_quick_icon':
4372
            // Check KEY and rights
4373
            if ($post_key !== $_SESSION['key']
4374
                || $_SESSION['user_read_only'] === true || !isset($SETTINGS['pwd_maximum_length'])
4375
            ) {
4376
                // error
4377
                exit();
4378
            }
4379
4380
            if ((int) filter_input(INPUT_POST, 'action', FILTER_SANITIZE_NUMBER_INT) === 0) {
4381
                // Add new favourite
4382
                array_push($_SESSION['favourites'], $post_item_id);
4383
                //print_r($_SESSION['favourites']);
4384
                DB::update(
4385
                    prefixTable('users'),
4386
                    array(
4387
                        'favourites' => implode(';', $_SESSION['favourites']),
4388
                        ),
4389
                    'id = %i',
4390
                    $_SESSION['user_id']
4391
                );
4392
                // Update SESSION with this new favourite
4393
                $data = DB::queryfirstrow(
4394
                    'SELECT label,id_tree
4395
                    FROM '.prefixTable('items').'
4396
                    WHERE id = '.mysqli_real_escape_string($link, $post_item_id)
4397
                );
4398
                $_SESSION['favourites_tab'][$post_item_id] = array(
4399
                    'label' => $data['label'],
4400
                    'url' => 'index.php?page=items&amp;group='.$data['id_tree'].'&amp;id='.$post_item_id,
4401
                    );
4402
            } elseif ((int) filter_input(INPUT_POST, 'action', FILTER_SANITIZE_NUMBER_INT) === 1) {
4403
                // delete from session
4404
                foreach ($_SESSION['favourites'] as $key => $value) {
4405
                    if ($_SESSION['favourites'][$key] === $post_item_id) {
4406
                        unset($_SESSION['favourites'][$key]);
4407
                        break;
4408
                    }
4409
                }
4410
                // delete from DB
4411
                DB::update(
4412
                    prefixTable('users'),
4413
                    array(
4414
                        'favourites' => implode(';', $_SESSION['favourites']),
4415
                    ),
4416
                    'id = %i',
4417
                    $_SESSION['user_id']
4418
                );
4419
                // refresh session fav list
4420
                if (isset($_SESSION['favourites_tab'])) {
4421
                    foreach ($_SESSION['favourites_tab'] as $key => $value) {
4422
                        if ($key == $post_id) {
4423
                            unset($_SESSION['favourites_tab'][$key]);
4424
                            break;
4425
                        }
4426
                    }
4427
                }
4428
            }
4429
            break;
4430
4431
        /*
4432
        * CASE
4433
        * Move an ITEM
4434
        */
4435
        case 'move_item':
4436
            // Check KEY and rights
4437
            if ($post_key !== $_SESSION['key']) {
4438
                echo prepareExchangedData(
4439
                    array(
4440
                        'error' => true,
4441
                        'message' => langHdl('key_is_not_correct'),
4442
                    ),
4443
                    'encode'
4444
                );
4445
                break;
4446
            } elseif ($_SESSION['user_read_only'] === true || isset($SETTINGS['pwd_maximum_length']) === false) {
4447
                echo prepareExchangedData(
4448
                    array(
4449
                        'error' => true,
4450
                        'message' => langHdl('error_not_allowed_to'),
4451
                    ),
4452
                    'encode'
4453
                );
4454
                break;
4455
            }
4456
4457
            // get data about item
4458
            $dataSource = DB::queryfirstrow(
4459
                'SELECT i.pw, f.personal_folder,i.id_tree, f.title,i.label
4460
                FROM '.prefixTable('items').' as i
4461
                INNER JOIN '.prefixTable('nested_tree').' as f ON (i.id_tree=f.id)
4462
                WHERE i.id=%i',
4463
                $post_item_id
4464
            );
4465
4466
            // get data about new folder
4467
            $dataDestination = DB::queryfirstrow(
4468
                'SELECT personal_folder, title
4469
                FROM '.prefixTable('nested_tree').'
4470
                WHERE id = %i',
4471
                $post_folder_id
4472
            );
4473
4474
            // Check that user can access this folder
4475
            if (in_array($dataSource['id_tree'], $_SESSION['groupes_visibles']) === false
4476
                || in_array($post_folder_id, $_SESSION['groupes_visibles']) === false
4477
            ) {
4478
                echo prepareExchangedData(
4479
                    array(
4480
                        'error' => true,
4481
                        'message' => langHdl('error_not_allowed_to'),
4482
                    ),
4483
                    'encode'
4484
                );
4485
                break;
4486
            }
4487
4488
            // Manage possible cases
4489
            if ($dataSource['personal_folder'] === '0' && $dataDestination['personal_folder'] === '0') {
4490
                // Previous is non personal folder and new too
4491
                // Just update is needed. Item key is the same
4492
                DB::update(
4493
                    prefixTable('items'),
4494
                    array(
4495
                        'id_tree' => $post_folder_id,
4496
                        ),
4497
                    'id=%i',
4498
                    $post_item_id
4499
                );
4500
            // ---
4501
                // ---
4502
            } elseif ($dataSource['personal_folder'] === '0' && $dataDestination['personal_folder'] === '1') {
4503
                // Source is public and destination is personal
4504
                // Decrypt and remove all sharekeys (items, fields, files)
4505
                // Encrypt only for the user
4506
4507
                // Remove all item sharekeys items
4508
                DB::delete(
4509
                    prefixTable('sharekeys_items'),
4510
                    'object_id = %i AND user_id != %i',
4511
                    $post_item_id,
4512
                    $_SESSION['user_id']
4513
                );
4514
4515
                // Remove all item sharekeys fields
4516
                // Get fields for this Item
4517
                $rows = DB::query(
4518
                    'SELECT id
4519
                    FROM '.prefixTable('categories_items').'
4520
                    WHERE item_id = %i',
4521
                    $post_item_id
4522
                );
4523
                foreach ($rows as $field) {
4524
                    DB::delete(
4525
                        prefixTable('sharekeys_fields'),
4526
                        'object_id = %i AND user_id != %i',
4527
                        $field['id'],
4528
                        $_SESSION['user_id']
4529
                    );
4530
                }
4531
4532
                // Remove all item sharekeys files
4533
                // Get FILES for this Item
4534
                $rows = DB::query(
4535
                    'SELECT id
4536
                    FROM '.prefixTable('files').'
4537
                    WHERE id_item = %i',
4538
                    $post_item_id
4539
                );
4540
                foreach ($rows as $attachment) {
4541
                    DB::delete(
4542
                        prefixTable('sharekeys_files'),
4543
                        'object_id = %i AND user_id != %i',
4544
                        $attachment['id'],
4545
                        $_SESSION['user_id']
4546
                    );
4547
                }
4548
4549
                // update pw
4550
                DB::update(
4551
                    prefixTable('items'),
4552
                    array(
4553
                        'id_tree' => $post_folder_id,
4554
                        'perso' => 1,
4555
                    ),
4556
                    'id=%i',
4557
                    $post_item_id
4558
                );
4559
            // ---
4560
                // ---
4561
            } elseif ($dataSource['personal_folder'] === '1' && $dataDestination['personal_folder'] === '1') {
4562
                // If previous is personal folder and new is personal folder too => no key exist on item
4563
                // just update is needed. Item key is the same
4564
                DB::update(
4565
                    prefixTable('items'),
4566
                    array(
4567
                        'id_tree' => $post_folder_id,
4568
                    ),
4569
                    'id=%i',
4570
                    $post_item_id
4571
                );
4572
            // ---
4573
                // ---
4574
            } elseif ($dataSource['personal_folder'] === '1' && $dataDestination['personal_folder'] === '0') {
4575
                // If previous is personal folder and new is not personal folder => no key exist on item => add new
4576
                // Create keys for all users
4577
4578
                // Get the ITEM object key for the user
4579
                $userKey = DB::queryFirstRow(
4580
                    'SELECT share_key
4581
                    FROM '.prefixTable('sharekeys_items').'
4582
                    WHERE user_id = %i AND object_id = %i',
4583
                    $_SESSION['user_id'],
4584
                    $post_item_id
4585
                );
4586
                if (DB::count() > 0) {
4587
                    $objectKey = decryptUserObjectKey($userKey['share_key'], $_SESSION['user']['private_key']);
4588
4589
                    // This is a public object
4590
                    $users = DB::query(
4591
                        'SELECT id, public_key
4592
                        FROM '.prefixTable('users').'
4593
                        WHERE id NOT IN ("'.OTV_USER_ID.'","'.SSH_USER_ID.'","'.API_USER_ID.'","'.$_SESSION['user_id'].'")
4594
                        AND public_key != ""'
4595
                    );
4596
                    foreach ($users as $user) {
4597
                        // Insert in DB the new object key for this item by user
4598
                        DB::insert(
4599
                            prefixTable('sharekeys_items'),
4600
                            array(
4601
                                'object_id' => $post_item_id,
4602
                                'user_id' => $user['id'],
4603
                                'share_key' => encryptUserObjectKey($objectKey, $user['public_key']),
4604
                            )
4605
                        );
4606
                    }
4607
                }
4608
4609
                // Get the FIELDS object key for the user
4610
                // Get fields for this Item
4611
                $rows = DB::query(
4612
                    'SELECT id
4613
                    FROM '.prefixTable('categories_items').'
4614
                    WHERE item_id = %i',
4615
                    $post_item_id
4616
                );
4617
                foreach ($rows as $field) {
4618
                    $userKey = DB::queryFirstRow(
4619
                        'SELECT share_key
4620
                        FROM '.prefixTable('sharekeys_fields').'
4621
                        WHERE user_id = %i AND object_id = %i',
4622
                        $_SESSION['user_id'],
4623
                        $field['id']
4624
                    );
4625
                    if (DB::count() > 0) {
4626
                        $objectKey = decryptUserObjectKey($userKey['share_key'], $_SESSION['user']['private_key']);
4627
4628
                        // This is a public object
4629
                        $users = DB::query(
4630
                            'SELECT id, public_key
4631
                            FROM '.prefixTable('users').'
4632
                            WHERE id NOT IN ("'.OTV_USER_ID.'","'.SSH_USER_ID.'","'.API_USER_ID.'","'.$_SESSION['user_id'].'")
4633
                            AND public_key != ""'
4634
                        );
4635
                        foreach ($users as $user) {
4636
                            // Insert in DB the new object key for this item by user
4637
                            DB::insert(
4638
                                prefixTable('sharekeys_fields'),
4639
                                array(
4640
                                    'object_id' => $field['id'],
4641
                                    'user_id' => $user['id'],
4642
                                    'share_key' => encryptUserObjectKey($objectKey, $user['public_key']),
4643
                                )
4644
                            );
4645
                        }
4646
                    }
4647
                }
4648
4649
                // Get the FILE object key for the user
4650
                // Get FILES for this Item
4651
                $rows = DB::query(
4652
                    'SELECT id
4653
                    FROM '.prefixTable('files').'
4654
                    WHERE id_item = %i',
4655
                    $post_item_id
4656
                );
4657
                foreach ($rows as $attachment) {
4658
                    $userKey = DB::queryFirstRow(
4659
                        'SELECT share_key
4660
                        FROM '.prefixTable('sharekeys_files').'
4661
                        WHERE user_id = %i AND object_id = %i',
4662
                        $_SESSION['user_id'],
4663
                        $attachment['id']
4664
                    );
4665
                    if (DB::count() > 0) {
4666
                        $objectKey = decryptUserObjectKey($userKey['share_key'], $_SESSION['user']['private_key']);
4667
4668
                        // This is a public object
4669
                        $users = DB::query(
4670
                            'SELECT id, public_key
4671
                            FROM '.prefixTable('users').'
4672
                            WHERE id NOT IN ("'.OTV_USER_ID.'","'.SSH_USER_ID.'","'.API_USER_ID.'","'.$_SESSION['user_id'].'")
4673
                            AND public_key != ""'
4674
                        );
4675
                        foreach ($users as $user) {
4676
                            // Insert in DB the new object key for this item by user
4677
                            DB::insert(
4678
                                prefixTable('sharekeys_files'),
4679
                                array(
4680
                                    'object_id' => $attachment['id'],
4681
                                    'user_id' => $user['id'],
4682
                                    'share_key' => encryptUserObjectKey($objectKey, $user['public_key']),
4683
                                )
4684
                            );
4685
                        }
4686
                    }
4687
                }
4688
4689
                // update item
4690
                DB::update(
4691
                    prefixTable('items'),
4692
                    array(
4693
                        'id_tree' => $post_folder_id,
4694
                        'perso' => 0,
4695
                    ),
4696
                    'id=%i',
4697
                    $post_item_id
4698
                );
4699
            }
4700
4701
            // Log item moved
4702
            logItems(
4703
                $SETTINGS,
4704
                $post_item_id,
4705
                $dataSource['label'],
4706
                $_SESSION['user_id'],
4707
                'at_modification',
4708
                $_SESSION['login'],
4709
                'at_moved : '.$dataSource['title'].' -> '.$dataDestination['title']
4710
            );
4711
4712
            $returnValues = array(
4713
                'error' => '',
4714
                'message' => '',
4715
                'from_folder' => $dataSource['id_tree'],
4716
                'to_folder' => $post_folder_id,
4717
            );
4718
            echo prepareExchangedData($returnValues, 'encode');
4719
            break;
4720
4721
        /*
4722
        * CASE
4723
        * MASSIVE Move an ITEM
4724
        */
4725
        case 'mass_move_items':
4726
            // Check KEY and rights
4727
            if ($post_key !== $_SESSION['key']) {
4728
                echo prepareExchangedData(
4729
                    array(
4730
                        'error' => true,
4731
                        'message' => langHdl('key_is_not_correct'),
4732
                    ),
4733
                    'encode'
4734
                );
4735
                break;
4736
            } elseif ($_SESSION['user_read_only'] === true || isset($SETTINGS['pwd_maximum_length']) === false) {
4737
                echo prepareExchangedData(
4738
                    array(
4739
                        'error' => true,
4740
                        'message' => langHdl('error_not_allowed_to'),
4741
                    ),
4742
                    'encode'
4743
                );
4744
                break;
4745
            }
4746
4747
            // decrypt and retreive data in JSON format
4748
            $dataReceived = prepareExchangedData(
4749
                $post_data,
4750
                'decode'
4751
            );
4752
            $post_folder_id = filter_var($dataReceived['folder_id'], FILTER_SANITIZE_NUMBER_INT);
4753
            $post_item_ids = filter_var($dataReceived['item_ids'], FILTER_SANITIZE_STRING);
4754
4755
            // loop on items to move
4756
            foreach (explode(';', $post_item_ids) as $item_id) {
4757
                if (empty($item_id) === false) {
4758
                    // get data about item
4759
                    $dataSource = DB::queryfirstrow(
4760
                        'SELECT i.pw, f.personal_folder,i.id_tree, f.title,i.label
4761
                        FROM '.prefixTable('items').' as i
4762
                        INNER JOIN '.prefixTable('nested_tree').' as f ON (i.id_tree=f.id)
4763
                        WHERE i.id=%i',
4764
                        $item_id
4765
                    );
4766
4767
                    // Check that user can access this folder
4768
                    if (in_array($dataSource['id_tree'], $_SESSION['groupes_visibles']) === false
4769
                        || in_array($post_folder_id, $_SESSION['groupes_visibles']) === false
4770
                    ) {
4771
                        echo prepareExchangedData(
4772
                            array(
4773
                                'error' => true,
4774
                                'message' => langHdl('error_not_allowed_to'),
4775
                            ),
4776
                            'encode'
4777
                        );
4778
                        exit();
4779
                    }
4780
4781
                    // get data about new folder
4782
                    $dataDestination = DB::queryfirstrow(
4783
                        'SELECT personal_folder, title FROM '.prefixTable('nested_tree').' WHERE id = %i',
4784
                        $post_folder_id
4785
                    );
4786
4787
                    // previous is non personal folder and new too
4788
                    if ((int) $dataSource['personal_folder'] === 0
4789
                        && (int) $dataDestination['personal_folder'] === 0
4790
                    ) {
4791
                        // just update is needed. Item key is the same
4792
                        DB::update(
4793
                            prefixTable('items'),
4794
                            array(
4795
                                'id_tree' => $post_folder_id,
4796
                                ),
4797
                            'id = %i',
4798
                            $item_id
4799
                        );
4800
                    // ---
4801
                        // ---
4802
                        // ---
4803
                    } elseif ((int) $dataSource['personal_folder'] === 0
4804
                        && (int) $dataDestination['personal_folder'] === 1
4805
                    ) {
4806
                        // Source is public and destination is personal
4807
                        // Decrypt and remove all sharekeys (items, fields, files)
4808
                        // Encrypt only for the user
4809
4810
                        // Remove all item sharekeys items
4811
                        DB::delete(
4812
                            prefixTable('sharekeys_items'),
4813
                            'object_id = %i AND user_id != %i',
4814
                            $item_id,
4815
                            $_SESSION['user_id']
4816
                        );
4817
4818
                        // Remove all item sharekeys fields
4819
                        // Get fields for this Item
4820
                        $rows = DB::query(
4821
                            'SELECT id
4822
                            FROM '.prefixTable('categories_items').'
4823
                            WHERE item_id = %i',
4824
                            $item_id
4825
                        );
4826
                        foreach ($rows as $field) {
4827
                            DB::delete(
4828
                                prefixTable('sharekeys_fields'),
4829
                                'object_id = %i AND user_id != %i',
4830
                                $field['id'],
4831
                                $_SESSION['user_id']
4832
                            );
4833
                        }
4834
4835
                        // Remove all item sharekeys files
4836
                        // Get FILES for this Item
4837
                        $rows = DB::query(
4838
                            'SELECT id
4839
                            FROM '.prefixTable('files').'
4840
                            WHERE id_item = %i',
4841
                            $item_id
4842
                        );
4843
                        foreach ($rows as $attachment) {
4844
                            DB::delete(
4845
                                prefixTable('sharekeys_files'),
4846
                                'object_id = %i AND user_id != %i',
4847
                                $attachment['id'],
4848
                                $_SESSION['user_id']
4849
                            );
4850
                        }
4851
4852
                        // update pw
4853
                        DB::update(
4854
                            prefixTable('items'),
4855
                            array(
4856
                                'id_tree' => $post_folder_id,
4857
                                'perso' => 1,
4858
                            ),
4859
                            'id = %i',
4860
                            $item_id
4861
                        );
4862
                    // ---
4863
                        // ---
4864
                        // ---
4865
                    } elseif ((int) $dataSource['personal_folder'] === 1
4866
                        && (int) $dataDestination['personal_folder'] === 1
4867
                    ) {
4868
                        // If previous is personal folder and new is personal folder too => no key exist on item
4869
                        // just update is needed. Item key is the same
4870
                        DB::update(
4871
                            prefixTable('items'),
4872
                            array(
4873
                                'id_tree' => $post_folder_id,
4874
                            ),
4875
                            'id = %i',
4876
                            $item_id
4877
                        );
4878
                    // ---
4879
                        // ---
4880
                        // ---
4881
                    } elseif ((int) $dataSource['personal_folder'] === 1
4882
                        && (int) $dataDestination['personal_folder'] === 0
4883
                    ) {
4884
                        // If previous is personal folder and new is not personal folder => no key exist on item => add new
4885
                        // Create keys for all users
4886
4887
                        // Get the ITEM object key for the user
4888
                        $userKey = DB::queryFirstRow(
4889
                            'SELECT share_key
4890
                            FROM '.prefixTable('sharekeys_items').'
4891
                            WHERE user_id = %i AND object_id = %i',
4892
                            $_SESSION['user_id'],
4893
                            $item_id
4894
                        );
4895
                        if (DB::count() > 0) {
4896
                            $objectKey = decryptUserObjectKey($userKey['share_key'], $_SESSION['user']['private_key']);
4897
4898
                            // This is a public object
4899
                            $users = DB::query(
4900
                                'SELECT id, public_key
4901
                                FROM '.prefixTable('users').'
4902
                                WHERE id NOT IN ("'.OTV_USER_ID.'","'.SSH_USER_ID.'","'.API_USER_ID.'","'.$_SESSION['user_id'].'")
4903
                                AND public_key != ""'
4904
                            );
4905
                            foreach ($users as $user) {
4906
                                // Insert in DB the new object key for this item by user
4907
                                DB::insert(
4908
                                    prefixTable('sharekeys_items'),
4909
                                    array(
4910
                                        'object_id' => $item_id,
4911
                                        'user_id' => $user['id'],
4912
                                        'share_key' => encryptUserObjectKey($objectKey, $user['public_key']),
4913
                                    )
4914
                                );
4915
                            }
4916
                        }
4917
4918
                        // Get the FIELDS object key for the user
4919
                        // Get fields for this Item
4920
                        $rows = DB::query(
4921
                            'SELECT id
4922
                            FROM '.prefixTable('categories_items').'
4923
                            WHERE item_id = %i',
4924
                            $item_id
4925
                        );
4926
                        foreach ($rows as $field) {
4927
                            $userKey = DB::queryFirstRow(
4928
                                'SELECT share_key
4929
                                FROM '.prefixTable('sharekeys_fields').'
4930
                                WHERE user_id = %i AND object_id = %i',
4931
                                $_SESSION['user_id'],
4932
                                $field['id']
4933
                            );
4934
                            if (DB::count() > 0) {
4935
                                $objectKey = decryptUserObjectKey($userKey['share_key'], $_SESSION['user']['private_key']);
4936
4937
                                // This is a public object
4938
                                $users = DB::query(
4939
                                    'SELECT id, public_key
4940
                                    FROM '.prefixTable('users').'
4941
                                    WHERE id NOT IN ("'.OTV_USER_ID.'","'.SSH_USER_ID.'","'.API_USER_ID.'","'.$_SESSION['user_id'].'")
4942
                                    AND public_key != ""'
4943
                                );
4944
                                foreach ($users as $user) {
4945
                                    // Insert in DB the new object key for this item by user
4946
                                    DB::insert(
4947
                                        prefixTable('sharekeys_fields'),
4948
                                        array(
4949
                                            'object_id' => $field['id'],
4950
                                            'user_id' => $user['id'],
4951
                                            'share_key' => encryptUserObjectKey($objectKey, $user['public_key']),
4952
                                        )
4953
                                    );
4954
                                }
4955
                            }
4956
                        }
4957
4958
                        // Get the FILE object key for the user
4959
                        // Get FILES for this Item
4960
                        $rows = DB::query(
4961
                            'SELECT id
4962
                            FROM '.prefixTable('files').'
4963
                            WHERE id_item = %i',
4964
                            $item_id
4965
                        );
4966
                        foreach ($rows as $attachment) {
4967
                            $userKey = DB::queryFirstRow(
4968
                                'SELECT share_key
4969
                                FROM '.prefixTable('sharekeys_files').'
4970
                                WHERE user_id = %i AND object_id = %i',
4971
                                $_SESSION['user_id'],
4972
                                $attachment['id']
4973
                            );
4974
                            if (DB::count() > 0) {
4975
                                $objectKey = decryptUserObjectKey($userKey['share_key'], $_SESSION['user']['private_key']);
4976
4977
                                // This is a public object
4978
                                $users = DB::query(
4979
                                    'SELECT id, public_key
4980
                                    FROM '.prefixTable('users').'
4981
                                    WHERE id NOT IN ("'.OTV_USER_ID.'","'.SSH_USER_ID.'","'.API_USER_ID.'","'.$_SESSION['user_id'].'")
4982
                                    AND public_key != ""'
4983
                                );
4984
                                foreach ($users as $user) {
4985
                                    // Insert in DB the new object key for this item by user
4986
                                    DB::insert(
4987
                                        prefixTable('sharekeys_files'),
4988
                                        array(
4989
                                            'object_id' => $attachment['id'],
4990
                                            'user_id' => $user['id'],
4991
                                            'share_key' => encryptUserObjectKey($objectKey, $user['public_key']),
4992
                                        )
4993
                                    );
4994
                                }
4995
                            }
4996
                        }
4997
4998
                        // update item
4999
                        DB::update(
5000
                            prefixTable('items'),
5001
                            array(
5002
                                'id_tree' => $post_folder_id,
5003
                                'perso' => 0,
5004
                            ),
5005
                            'id=%i',
5006
                            $item_id
5007
                        );
5008
5009
                        //----
5010
                        // If previous is personal folder and new is not personal folder => no key exist on item => add new
5011
                        $decrypt = cryption(
5012
                            $dataSource['pw'],
5013
                            stripslashes($_SESSION['user_settings']['session_psk']),
5014
                            'decrypt',
5015
                            $SETTINGS
5016
                        );
5017
                        $encrypt = cryption(
5018
                            $decrypt['string'],
5019
                            '',
5020
                            'encrypt',
5021
                            $SETTINGS
5022
                        );
5023
5024
                        // update item
5025
                        DB::update(
5026
                            prefixTable('items'),
5027
                            array(
5028
                                'id_tree' => $post_folder_id,
5029
                                'pw' => $encrypt['string'],
5030
                                'pw_iv' => '',
5031
                                'perso' => 0,
5032
                            ),
5033
                            'id=%i',
5034
                            $item_id
5035
                        );
5036
                    }
5037
                    // Log item moved
5038
                    logItems(
5039
                        $SETTINGS,
5040
                        $item_id,
0 ignored issues
show
Bug introduced by
$item_id of type string is incompatible with the type integer expected by parameter $item_id of logItems(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

5040
                        /** @scrutinizer ignore-type */ $item_id,
Loading history...
5041
                        $dataSource['label'],
5042
                        $_SESSION['user_id'],
5043
                        'at_modification',
5044
                        $_SESSION['login'],
5045
                        'at_moved : '.$dataSource['title'].' -> '.$dataDestination['title']
5046
                    );
5047
                }
5048
            }
5049
5050
            // reload cache table
5051
            require_once $SETTINGS['cpassman_dir'].'/sources/main.functions.php';
5052
            updateCacheTable('reload', $SETTINGS, '');
5053
5054
            echo prepareExchangedData(
5055
                array(
5056
                    'error' => false,
5057
                    'message' => '',
5058
                ),
5059
                'encode'
5060
            );
5061
            break;
5062
5063
        /*
5064
         * CASE
5065
         * MASSIVE Delete an item
5066
        */
5067
        case 'mass_delete_items':
5068
            // Check KEY and rights
5069
            if ($post_key !== $_SESSION['key']) {
5070
                echo prepareExchangedData(
5071
                    array(
5072
                        'error' => true,
5073
                        'message' => langHdl('key_is_not_correct'),
5074
                    ),
5075
                    'encode'
5076
                );
5077
                break;
5078
            } elseif ($_SESSION['user_read_only'] === true) {
5079
                echo prepareExchangedData(
5080
                    array(
5081
                        'error' => true,
5082
                        'message' => langHdl('error_not_allowed_to'),
5083
                    ),
5084
                    'encode'
5085
                );
5086
                break;
5087
            }
5088
5089
            // decrypt and retreive data in JSON format
5090
            $dataReceived = prepareExchangedData(
5091
                $post_data,
5092
                'decode'
5093
            );
5094
            $post_item_ids = filter_var($dataReceived['item_ids'], FILTER_SANITIZE_STRING);
5095
5096
            // perform a check in case of Read-Only user creating an item in his PF
5097
            if ($_SESSION['user_read_only'] === true) {
5098
                echo prepareExchangedData(
5099
                    array(
5100
                        'error' => true,
5101
                        'message' => langHdl('error_not_allowed_to'),
5102
                    ),
5103
                    'encode'
5104
                );
5105
                break;
5106
            }
5107
5108
            // loop on items to move
5109
            foreach (explode(';', $post_item_ids) as $item_id) {
5110
                if (empty($item_id) === false) {
5111
                    // get info
5112
                    $dataSource = DB::queryfirstrow(
5113
                        'SELECT label, id_tree
5114
                        FROM '.prefixTable('items').'
5115
                        WHERE id=%i',
5116
                        $item_id
5117
                    );
5118
5119
                    // Check that user can access this folder
5120
                    if (in_array($dataSource['id_tree'], $_SESSION['groupes_visibles']) === false
5121
                    ) {
5122
                        echo prepareExchangedData(
5123
                            array(
5124
                                'error' => true,
5125
                                'message' => langHdl('error_not_allowed_to'),
5126
                            ),
5127
                            'encode'
5128
                        );
5129
                        break;
5130
                    }
5131
5132
                    // delete item consists in disabling it
5133
                    DB::update(
5134
                        prefixTable('items'),
5135
                        array(
5136
                            'inactif' => '1',
5137
                            ),
5138
                        'id = %i',
5139
                        $item_id
5140
                    );
5141
5142
                    // log
5143
                    logItems(
5144
                        $SETTINGS,
5145
                        $item_id,
5146
                        $dataSource['label'],
5147
                        $_SESSION['user_id'],
5148
                        'at_delete',
5149
                        $_SESSION['login']
5150
                    );
5151
5152
                    // Update CACHE table
5153
                    updateCacheTable('delete_value', $SETTINGS, $item_id);
5154
                }
5155
            }
5156
5157
            echo prepareExchangedData(
5158
                array(
5159
                    'error' => false,
5160
                    'message' => '',
5161
                ),
5162
                'encode'
5163
            );
5164
            break;
5165
5166
            break;
5167
5168
            /*
5169
           * CASE
5170
           * Send email
5171
        */
5172
        case 'send_email':
5173
            // Check KEY
5174
            if ($post_key !== $_SESSION['key']) {
5175
                echo prepareExchangedData(
5176
                    array(
5177
                        'error' => true,
5178
                        'message' => langHdl('key_is_not_correct'),
5179
                    ),
5180
                    'encode'
5181
                );
5182
                break;
5183
            } elseif ($_SESSION['user_read_only'] === true) {
5184
                echo prepareExchangedData(
5185
                    array(
5186
                        'error' => true,
5187
                        'message' => langHdl('error_not_allowed_to'),
5188
                    ),
5189
                    'encode'
5190
                );
5191
                break;
5192
            }
5193
5194
            // decrypt and retrieve data in JSON format
5195
            $dataReceived = prepareExchangedData($post_data, 'decode');
5196
5197
            // Prepare variables
5198
            $post_id = filter_var($dataReceived['id'], FILTER_SANITIZE_NUMBER_INT);
5199
            $post_receipt = filter_var($dataReceived['receipt'], FILTER_SANITIZE_STRING);
5200
            $post_cat = filter_var($dataReceived['cat'], FILTER_SANITIZE_STRING);
5201
5202
            // get links url
5203
            if (empty($SETTINGS['email_server_url']) === true) {
5204
                $SETTINGS['email_server_url'] = $SETTINGS['cpassman_url'];
5205
            }
5206
            if ($post_cat === 'request_access_to_author') {
5207
                // Content
5208
                if (empty(filter_input(INPUT_POST, 'content', FILTER_SANITIZE_STRING)) === false) {
5209
                    $content = explode(',', filter_input(INPUT_POST, 'content', FILTER_SANITIZE_STRING));
5210
                }
5211
                // Variables
5212
                $dataAuthor = DB::queryfirstrow('SELECT email,login FROM '.prefixTable('users').' WHERE id= '.$content[1]);
5213
                $dataItem = DB::queryfirstrow('SELECT label, id_tree FROM '.prefixTable('items').' WHERE id= '.$content[0]);
5214
5215
                // Get path
5216
                $path = geItemReadablePath(
5217
                    $dataItem['id_tree'],
5218
                    $dataItem['label'],
5219
                    $SETTINGS
5220
                );
5221
5222
                $ret = json_decode(
5223
                    sendEmail(
5224
                        langHdl('email_request_access_subject'),
5225
                        str_replace(
5226
                            array('#tp_item_author#', '#tp_user#', '#tp_item#'),
5227
                            array(' '.addslashes($dataAuthor['login']), addslashes($_SESSION['login']), $path),
5228
                            langHdl('email_request_access_mail')
5229
                        ),
5230
                        $dataAuthor['email'],
5231
                        $SETTINGS
5232
                    ),
5233
                    true
5234
                );
5235
            } elseif ($post_cat === 'share_this_item') {
5236
                $dataItem = DB::queryfirstrow(
5237
                    'SELECT label,id_tree
5238
                    FROM '.prefixTable('items').'
5239
                    WHERE id= %i',
5240
                    $post_id
5241
                );
5242
5243
                // Get path
5244
                $path = geItemReadablePath(
5245
                    $dataItem['id_tree'],
5246
                    $dataItem['label'],
5247
                    $SETTINGS
5248
                );
5249
5250
                // send email
5251
                $ret = json_decode(
5252
                    sendEmail(
5253
                        langHdl('email_share_item_subject'),
5254
                        str_replace(
5255
                            array(
5256
                                '#tp_link#',
5257
                                '#tp_user#',
5258
                                '#tp_item#',
5259
                            ),
5260
                            array(
5261
                                empty($SETTINGS['email_server_url']) === false ?
5262
                                $SETTINGS['email_server_url'].'/index.php?page=items&group='.$dataItem['id_tree'].'&id='.$post_id :
5263
                                $SETTINGS['cpassman_url'].'/index.php?page=items&group='.$dataItem['id_tree'].'&id='.$post_id,
5264
                                addslashes($_SESSION['login']),
5265
                                addslashes($path),
5266
                            ),
5267
                            langHdl('email_share_item_mail')
5268
                        ),
5269
                        $post_receipt,
5270
                        $SETTINGS
5271
                    ),
5272
                    true
5273
                );
5274
            }
5275
5276
            echo prepareExchangedData(
5277
                array(
5278
                    'error' => empty($ret['error']) === true ? false : true,
5279
                    'message' => $ret['message'],
5280
                ),
5281
                'encode'
5282
            );
5283
5284
            break;
5285
5286
        /*
5287
           * CASE
5288
           * manage notification of an Item
5289
        */
5290
        case 'notify_a_user':
5291
            if ($post_key !== $_SESSION['key']) {
5292
                echo '[{"error" : "something_wrong"}]';
5293
                break;
5294
            } else {
5295
                if (filter_input(INPUT_POST, 'notify_type', FILTER_SANITIZE_STRING) === 'on_show') {
5296
                    // Check if values already exist
5297
                    $data = DB::queryfirstrow(
5298
                        'SELECT notification FROM '.prefixTable('items').' WHERE id = %i',
5299
                        $post_item_id
5300
                    );
5301
                    $notifiedUsers = explode(';', $data['notification']);
5302
                    // User is not in actual notification list
5303
                    if ($post_status === 'true' && !in_array($post_user_id, $notifiedUsers)) {
5304
                        // User is not in actual notification list and wants to be notified
5305
                        DB::update(
5306
                            prefixTable('items'),
5307
                            array(
5308
                                'notification' => empty($data['notification']) ?
5309
                                    filter_input(INPUT_POST, 'user_id', FILTER_SANITIZE_NUMBER_INT).';'
5310
                                    : $data['notification'].filter_input(INPUT_POST, 'user_id', FILTER_SANITIZE_NUMBER_INT),
5311
                                ),
5312
                            'id=%i',
5313
                            $post_item_id
5314
                        );
5315
                        echo '[{"error" : "", "new_status":"true"}]';
5316
                        break;
5317
                    } elseif ($post_status === false && in_array($post_user_id, $notifiedUsers)) {
5318
                        // TODO : delete user from array and store in DB
5319
                        // User is in actual notification list and doesn't want to be notified
5320
                        DB::update(
5321
                            prefixTable('items'),
5322
                            array(
5323
                                'notification' => empty($data['notification']) ?
5324
                                    filter_input(INPUT_POST, 'user_id', FILTER_SANITIZE_NUMBER_INT)
5325
                                    : $data['notification'].';'.filter_input(INPUT_POST, 'user_id', FILTER_SANITIZE_NUMBER_INT),
5326
                                ),
5327
                            'id=%i',
5328
                            $post_item_id
5329
                        );
5330
                    }
5331
                }
5332
            }
5333
            break;
5334
5335
        /*
5336
        * CASE
5337
        * Item History Log - add new entry
5338
        */
5339
        case 'history_entry_add':
5340
            if ($post_key !== $_SESSION['key']) {
5341
                $data = array('error' => 'key_is_wrong');
5342
                echo prepareExchangedData($data, 'encode');
5343
                break;
5344
            } else {
5345
                // decrypt and retreive data in JSON format
5346
                $dataReceived = prepareExchangedData($post_data, 'decode');
5347
                // Get all informations for this item
5348
                $dataItem = DB::queryfirstrow(
5349
                    'SELECT *
5350
                    FROM '.prefixTable('items').' as i
5351
                    INNER JOIN '.prefixTable('log_items').' as l ON (l.id_item = i.id)
5352
                    WHERE i.id=%i AND l.action = %s',
5353
                    $dataReceived['item_id'],
5354
                    'at_creation'
5355
                );
5356
                // check that actual user can access this item
5357
                $restrictionActive = true;
5358
                $restrictedTo = array_filter(explode(';', $dataItem['restricted_to']));
5359
                if (in_array($_SESSION['user_id'], $restrictedTo)) {
5360
                    $restrictionActive = false;
5361
                }
5362
                if (empty($dataItem['restricted_to'])) {
5363
                    $restrictionActive = false;
5364
                }
5365
5366
                if ((
5367
                        (in_array($dataItem['id_tree'], $_SESSION['groupes_visibles'])) && ($dataItem['perso'] === '0' || ($dataItem['perso'] === '1' && $dataItem['id_user'] == $_SESSION['user_id'])) && $restrictionActive === false
5368
                    )
5369
                    ||
5370
                    (
5371
                        isset($SETTINGS['anyone_can_modify']) && $SETTINGS['anyone_can_modify'] === '1' && $dataItem['anyone_can_modify'] === '1' && (in_array($dataItem['id_tree'], $_SESSION['groupes_visibles']) || $_SESSION['is_admin'] === '1') && $restrictionActive === false
5372
                    )
5373
                    ||
5374
                    (@in_array(
5375
                        $post_id,
5376
                        $_SESSION['list_folders_limited'][$post_folder_id]
5377
                    ))
5378
                ) {
5379
                    $error = '';
5380
                    // Query
5381
                    logItems(
5382
                        $SETTINGS,
5383
                        $dataReceived['item_id'],
5384
                        $dataItem['label'],
5385
                        $_SESSION['user_id'],
5386
                        'at_manual',
5387
                        $_SESSION['login'],
5388
                        htmlspecialchars_decode($dataReceived['label'], ENT_QUOTES)
5389
                    );
5390
                    // Prepare new line
5391
                    $data = DB::queryfirstrow(
5392
                        'SELECT * FROM '.prefixTable('log_items').' WHERE id_item = %i ORDER BY date DESC',
5393
                        $dataReceived['item_id']
5394
                    );
5395
                    $historic = date($SETTINGS['date_format'].' '.$SETTINGS['time_format'], $data['date']).' - '.$_SESSION['login'].' - '.langHdl($data['action']).' - '.$data['raison'];
5396
                    // send back
5397
                    $data = array(
5398
                        'error' => '',
5399
                        'new_line' => '<br>'.addslashes($historic),
5400
                    );
5401
                    echo prepareExchangedData($data, 'encode');
5402
                } else {
5403
                    $data = array('error' => 'something_wrong');
5404
                    echo prepareExchangedData($data, 'encode');
5405
                    break;
5406
                }
5407
            }
5408
            break;
5409
5410
        /*
5411
        * CASE
5412
        * Free Item for Edition
5413
        */
5414
        case 'free_item_for_edition':
5415
            // Check KEY
5416
            if ($post_key !== $_SESSION['key']) {
5417
                echo '[ { "error" : "key_not_conform" } ]';
5418
                break;
5419
            }
5420
            // Do
5421
            DB::delete(
5422
                prefixTable('items_edition'),
5423
                'item_id = %i',
5424
                $post_id
5425
            );
5426
            break;
5427
5428
        /*
5429
        * CASE
5430
        * Check if Item has been changed since loaded
5431
        */
5432
        case 'is_item_changed':
5433
            $data = DB::queryFirstRow(
5434
                'SELECT date FROM '.prefixTable('log_items').' WHERE action = %s AND id_item = %i ORDER BY date DESC',
5435
                'at_modification',
5436
                $post_item_id
5437
            );
5438
            // Check if it's in a personal folder. If yes, then force complexity overhead.
5439
            if ($data['date'] > filter_input(INPUT_POST, 'timestamp', FILTER_SANITIZE_STRING)) {
5440
                echo '{ "modified" : "1" }';
5441
            } else {
5442
                echo '{ "modified" : "0" }';
5443
            }
5444
            break;
5445
5446
        /*
5447
        * CASE
5448
        * Check if Item has been changed since loaded
5449
        */
5450
        case 'generate_OTV_url':
5451
            // Check KEY
5452
            if ($post_key !== $_SESSION['key']) {
5453
                echo '[ { "error" : "key_not_conform" } ]';
5454
                break;
5455
            }
5456
5457
            // delete all existing old otv codes
5458
            $rows = DB::query('SELECT id FROM '.prefixTable('otv').' WHERE timestamp < '.(time() - $SETTINGS['otv_expiration_period'] * 86400));
5459
            foreach ($rows as $record) {
5460
                DB::delete(prefixTable('otv'), 'id=%i', $record['id']);
5461
            }
5462
5463
            // generate session
5464
            $otv_code = GenerateCryptKey(32, false, true, true, false);
5465
            $otv_key = GenerateCryptKey(32, false, true, true, false);
5466
5467
            // Generate Defuse key
5468
            $otv_user_code_encrypted = defuse_generate_personal_key($otv_key);
5469
5470
            // check if psk is correct.
5471
            $otv_key_encoded = defuse_validate_personal_key(
5472
                $otv_key,
5473
                $otv_user_code_encrypted
5474
            );
5475
5476
            // Decrypt the pwd
5477
            // Should we log a password change?
5478
            $itemQ = DB::queryFirstRow(
5479
                'SELECT s.share_key, i.pw
5480
                FROM '.prefixTable('items').' AS i
5481
                INNER JOIN '.prefixTable('sharekeys_items').' AS s ON (i.id = s.object_id)
5482
                WHERE s.user_id = %i AND s.object_id = %i',
5483
                $_SESSION['user_id'],
5484
                $post_id
5485
            );
5486
            if (DB::count() === 0 || empty($itemQ['pw']) === true) {
5487
                // No share key found
5488
                $pw = '';
5489
            } else {
5490
                $pw = base64_decode(doDataDecryption(
5491
                    $itemQ['pw'],
5492
                    decryptUserObjectKey(
5493
                        $itemQ['share_key'],
5494
                        $_SESSION['user']['private_key']
5495
                    )
5496
                ));
5497
            }
5498
5499
            // Encrypt it with DEFUSE using the generated code as key
5500
            // This is required as the OTV is used by someone without any Teampass account
5501
            $passwd = cryption(
5502
                $pw,
5503
                $otv_key_encoded,
5504
                'encrypt',
5505
                $SETTINGS
5506
            );
5507
5508
            DB::insert(
5509
                prefixTable('otv'),
5510
                array(
5511
                    'id' => null,
5512
                    'item_id' => $post_id,
5513
                    'timestamp' => time(),
5514
                    'originator' => intval($_SESSION['user_id']),
5515
                    'code' => $otv_code,
5516
                    'encrypted' => $passwd['string'],
5517
                    )
5518
            );
5519
            $newID = DB::insertId();
5520
5521
            // Prepare URL content
5522
            $otv_session = array(
5523
                'code' => $otv_code,
5524
                'key' => $otv_key_encoded,
5525
                'stamp' => time(),
5526
            );
5527
5528
            if (isset($SETTINGS['otv_expiration_period']) === false) {
5529
                $SETTINGS['otv_expiration_period'] = 7;
5530
            }
5531
            $url = $SETTINGS['cpassman_url'].'/index.php?otv=true&'.http_build_query($otv_session);
5532
            $exp_date = date($SETTINGS['date_format'].' '.$SETTINGS['time_format'], time() + (intval($SETTINGS['otv_expiration_period']) * 86400));
5533
5534
            echo json_encode(
5535
                array(
5536
                    'error' => '',
5537
                    'url' => $url,
5538
                    /*'text' => str_replace(
5539
                        array('#URL#', '#DAY#'),
5540
                        array('<span id=\'otv_link\'>'.$url.'</span>&nbsp;<span class=\'fa-stack tip" title=\''.langHdl('copy').'\' style=\'cursor:pointer;\' id=\'button_copy_otv_link\'><span class=\'fa fa-square fa-stack-2x\'></span><span class=\'fa fa-clipboard fa-stack-1x fa-inverse\'></span></span>', $exp_date),
5541
                        langHdl('one_time_view_item_url_box')
5542
                    ),*/
5543
                )
5544
            );
5545
            break;
5546
5547
        /*
5548
        * CASE
5549
        * Free Item for Edition
5550
        */
5551
        case 'image_preview_preparation':
5552
            // Check KEY
5553
            if ($post_key !== $_SESSION['key']) {
5554
                echo prepareExchangedData(
5555
                    array(
5556
                        'error' => true,
5557
                        'message' => langHdl('key_is_not_correct'),
5558
                    ),
5559
                    'encode'
5560
                );
5561
                break;
5562
            }
5563
5564
            // get file info
5565
            $file_info = DB::queryfirstrow(
5566
                'SELECT f.id AS id, f.file AS file, f.name AS name, f.status AS status,
5567
                f.extension AS extension, f.type AS type,
5568
                s.share_key AS share_key
5569
                FROM '.prefixTable('files').' AS f
5570
                INNER JOIN '.prefixTable('sharekeys_files').' AS s ON (f.id = s.object_id)
5571
                WHERE s.user_id = %i AND s.object_id = %i',
5572
                $_SESSION['user_id'],
5573
                $post_id
5574
            );
5575
5576
            // Check if user has this sharekey
5577
            if (empty($file_info['share_key']) === true) {
5578
                echo prepareExchangedData(
5579
                    array(
5580
                        'error' => true,
5581
                        'message' => langHdl('no_sharekey_found'),
5582
                    ),
5583
                    'encode'
5584
                );
5585
                break;
5586
            }
5587
5588
            //$fileName = basename($file_info['name'], '.'.$file_info['extension']);
5589
5590
            // prepare image info
5591
            $post_title = basename($file_info['name'], '.'.$file_info['extension']);
5592
            $post_title = isBase64($post_title) === true ?
5593
                    base64_decode($post_title) :
5594
                    $post_title;
5595
            $image_code = $file_info['file'];
5596
            $extension = $file_info['extension'];
5597
5598
            // Get image content
5599
            $fileContent = decryptFile(
5600
                $image_code,
5601
                $SETTINGS['path_to_upload_folder'],
5602
                decryptUserObjectKey($file_info['share_key'], $_SESSION['user']['private_key'])
5603
            );
5604
5605
            // Encrypt data to return
5606
            echo prepareExchangedData(
5607
                array(
5608
                    'error' => false,
5609
                    'filename' => $post_title.'.'.$file_info['extension'],
5610
                    'file_type' => $file_info['type'],
5611
                    'file_content' => $fileContent,
5612
                ),
5613
                'encode'
5614
            );
5615
            break;
5616
5617
        /*
5618
        * CASE
5619
        * Free Item for Edition
5620
        */
5621
        case 'delete_file':
5622
            // Check KEY
5623
            if ($post_key !== $_SESSION['key']) {
5624
                echo '[ { "error" : "key_not_conform" } ]';
5625
                break;
5626
            }
5627
5628
            // get file info
5629
            $result = DB::queryfirstrow(
5630
                'SELECT file FROM '.prefixTable('files').' WHERE id=%i',
5631
                intval(substr(filter_input(INPUT_POST, 'uri', FILTER_SANITIZE_STRING), 1))
5632
            );
5633
5634
            fileDelete($SETTINGS['path_to_upload_folder'].'/'.$result['file'].filter_input(INPUT_POST, 'file_suffix', FILTER_SANITIZE_STRING), $SETTINGS);
5635
5636
            break;
5637
5638
        /*
5639
        * CASE
5640
        * Get list of users that have access to the folder
5641
        */
5642
        case 'check_for_title_duplicate':
5643
            // Check KEY
5644
            if ($post_key !== $_SESSION['key']) {
5645
                echo '[ { "error" : "key_not_conform" } ]';
5646
                break;
5647
            }
5648
            $error = '';
5649
            $duplicate = 0;
5650
5651
            // decrypt and retreive data in JSON format
5652
            $dataReceived = prepareExchangedData($post_data, 'decode');
5653
            // Prepare variables
5654
            $label = htmlspecialchars_decode($dataReceived['label']);
5655
            $idFolder = $dataReceived['idFolder'];
5656
5657
            // don't check if Personal Folder
5658
            $data = DB::queryFirstRow('SELECT title FROM '.prefixTable('nested_tree').' WHERE id = %i', $idFolder);
5659
            if ($data['title'] == $_SESSION['user_id']) {
5660
                // send data
5661
                echo '[{"duplicate" : "'.$duplicate.'" , error" : ""}]';
5662
            } else {
5663
                if (filter_input(INPUT_POST, 'option', FILTER_SANITIZE_STRING) === 'same_folder') {
5664
                    // case unique folder
5665
                    DB::query(
5666
                        'SELECT label
5667
                        FROM '.prefixTable('items').'
5668
                        WHERE id_tree = %i AND label = %s',
5669
                        $idFolder,
5670
                        $label
5671
                    );
5672
                } else {
5673
                    // case complete database
5674
5675
                    //get list of personal folders
5676
                    $arrayPf = array();
5677
                    $listPf = '';
5678
                    if (empty($row['id']) === false) {
5679
                        $rows = DB::query(
5680
                            'SELECT id FROM '.prefixTable('nested_tree').' WHERE personal_folder = %i',
5681
                            '1'
5682
                        );
5683
                        foreach ($rows as $record) {
5684
                            if (!in_array($record['id'], $arrayPf)) {
5685
                                array_push($arrayPf, $record['id']);
5686
                            }
5687
                        }
5688
                    }
5689
5690
                    // build WHERE condition
5691
                    $where = new WhereClause('and');
5692
                    $where->add('id_tree = %i', $idFolder);
5693
                    $where->add('label = %s', $label);
5694
                    if (empty($arrayPf) === false) {
5695
                        $where->add('id_tree NOT IN ('.implode(',', $arrayPf).')');
5696
                    }
5697
5698
                    DB::query(
5699
                        'SELECT label
5700
                        FROM '.prefixTable('items').'
5701
                        WHERE %l',
5702
                        $where
5703
                    );
5704
                }
5705
5706
                // count results
5707
                if (DB::count() > 0) {
5708
                    $duplicate = 1;
5709
                }
5710
5711
                // send data
5712
                echo '[{"duplicate" : "'.$duplicate.'" , "error" : ""}]';
5713
            }
5714
            break;
5715
5716
        /*
5717
        * CASE
5718
        * Get list of users that have access to the folder
5719
        */
5720
        case 'refresh_visible_folders':
5721
            // Check KEY
5722
            if ($post_key !== $_SESSION['key']) {
5723
                echo prepareExchangedData(
5724
                    array(
5725
                        'error' => true,
5726
                        'message' => langHdl('key_is_not_correct'),
5727
                    ),
5728
                    'encode'
5729
                );
5730
                break;
5731
            }
5732
5733
            // Init
5734
5735
            // Will we show the root folder?
5736
            $arr_data['can_create_root_folder'] = isset($SETTINGS['can_create_root_folder']) && $SETTINGS['can_create_root_folder'] === '1' ? 1 : 0;
5737
5738
            // Build list of visible folders
5739
            $selectVisibleFoldersOptions = $selectVisibleNonPersonalFoldersOptions = $selectVisibleActiveFoldersOptions = '';
5740
            if (isset($SETTINGS['can_create_root_folder']) && $SETTINGS['can_create_root_folder'] === '1') {
5741
                $selectVisibleFoldersOptions = '<option value="0">'.langHdl('root').'</option>';
5742
            }
5743
5744
            if ($_SESSION['user_admin'] === '1'
0 ignored issues
show
introduced by
Consider adding parentheses for clarity. Current Interpretation: ($_SESSION['user_admin']...=== TP_ADMIN_FULL_RIGHT, Probably Intended Meaning: $_SESSION['user_admin'] ...== TP_ADMIN_FULL_RIGHT)
Loading history...
5745
                && (null !== TP_ADMIN_FULL_RIGHT && TP_ADMIN_FULL_RIGHT === true)
5746
                || null === TP_ADMIN_FULL_RIGHT
5747
            ) {
5748
                $_SESSION['groupes_visibles'] = $_SESSION['personal_visible_groups'];
5749
                $_SESSION['groupes_visibles_list'] = implode(',', $_SESSION['groupes_visibles']);
5750
            }
5751
5752
            if (isset($_SESSION['list_folders_limited']) && count($_SESSION['list_folders_limited']) > 0) {
5753
                $listFoldersLimitedKeys = @array_keys($_SESSION['list_folders_limited']);
5754
            } else {
5755
                $listFoldersLimitedKeys = array();
5756
            }
5757
            // list of items accessible but not in an allowed folder
5758
            if (isset($_SESSION['list_restricted_folders_for_items'])
5759
                && count($_SESSION['list_restricted_folders_for_items']) > 0) {
5760
                $listRestrictedFoldersForItemsKeys = @array_keys($_SESSION['list_restricted_folders_for_items']);
5761
            } else {
5762
                $listRestrictedFoldersForItemsKeys = array();
5763
            }
5764
5765
            //Build tree
5766
            $tree = new SplClassLoader('Tree\NestedTree', $SETTINGS['cpassman_dir'].'/includes/libraries');
5767
            $tree->register();
5768
            $tree = new Tree\NestedTree\NestedTree(prefixTable('nested_tree'), 'id', 'parent_id', 'title');
5769
            $tree->rebuild();
5770
            $folders = $tree->getDescendants();
5771
            $inc = 0;
5772
5773
            foreach ($folders as $folder) {
5774
                // Be sure that user can only see folders he/she is allowed to
5775
                if (in_array($folder->id, $_SESSION['forbiden_pfs']) === false
5776
                    || in_array($folder->id, $_SESSION['groupes_visibles']) === true
5777
                    || in_array($folder->id, $listFoldersLimitedKeys) === true
5778
                    || in_array($folder->id, $listRestrictedFoldersForItemsKeys) === true
5779
                ) {
5780
                    // Init
5781
                    $displayThisNode = false;
5782
                    $hide_node = false;
5783
                    $nbChildrenItems = 0;
5784
5785
                    // Check if any allowed folder is part of the descendants of this node
5786
                    $nodeDescendants = $tree->getDescendants($folder->id, true, false, true);
5787
                    foreach ($nodeDescendants as $node) {
5788
                        // manage tree counters
5789
                        /*if (isset($SETTINGS['tree_counters']) && $SETTINGS['tree_counters'] === '1') {
5790
                            DB::query(
5791
                                "SELECT * FROM ".prefixTable("items")."
5792
                                WHERE inactif=%i AND id_tree = %i",
5793
                                0,
5794
                                $node
5795
                            );
5796
                            $nbChildrenItems += DB::count();
5797
                        }*/
5798
                        if (in_array($node, array_merge($_SESSION['groupes_visibles'], $_SESSION['list_restricted_folders_for_items'])) === true
5799
                            || @in_array($node, $listFoldersLimitedKeys)
5800
                            || @in_array($node, $listRestrictedFoldersForItemsKeys)
5801
                        ) {
5802
                            $displayThisNode = true;
5803
                            //break;
5804
                        }
5805
                    }
5806
5807
                    if ($displayThisNode === true) {
5808
                        // ALL FOLDERS
5809
                        // Is this folder disabled?
5810
                        $disabled = 0;
5811
                        if (in_array($folder->id, $_SESSION['groupes_visibles']) === false
5812
                            || in_array($folder->id, $_SESSION['read_only_folders']) === true
5813
                            //|| ((int) $_SESSION['user_read_only'] === 1 && in_array($folder->id, $_SESSION['personal_visible_groups']) === false)
5814
                        ) {
5815
                            $disabled = 1;
5816
                        }
5817
5818
                        // Build path
5819
                        $arbo = $tree->getPath($folder->id, false);
5820
                        $arr_data['folders'][$inc]['path'] = '';
5821
                        foreach ($arbo as $elem) {
5822
                            if (empty($arr_data['folders'][$inc]['path']) === true) {
5823
                                $arr_data['folders'][$inc]['path'] = htmlspecialchars(stripslashes(htmlspecialchars_decode($elem->title, ENT_QUOTES)), ENT_QUOTES);
5824
                            } else {
5825
                                $arr_data['folders'][$inc]['path'] .= ' / '.htmlspecialchars(stripslashes(htmlspecialchars_decode($elem->title, ENT_QUOTES)), ENT_QUOTES);
5826
                            }
5827
                        }
5828
5829
                        // Build array
5830
                        $arr_data['folders'][$inc]['id'] = intval($folder->id);
5831
                        $arr_data['folders'][$inc]['level'] = intval($folder->nlevel);
5832
                        $arr_data['folders'][$inc]['title'] = ($folder->title == $_SESSION['user_id'] && $folder->nlevel === '1') ? htmlspecialchars_decode($_SESSION['login']) : htmlspecialchars_decode($folder->title, ENT_QUOTES);
5833
                        $arr_data['folders'][$inc]['disabled'] = $disabled;
5834
                        $arr_data['folders'][$inc]['parent_id'] = intval($folder->parent_id);
5835
                        $arr_data['folders'][$inc]['perso'] = intval($folder->personal_folder);
5836
5837
                        // Is this folder an active folders? (where user can do something)
5838
                        $is_visible_active = 0;
5839
                        if (isset($_SESSION['read_only_folders']) === true
5840
                            && in_array($folder->id, $_SESSION['read_only_folders']) === true) {
5841
                            $is_visible_active = 1;
5842
                        }
5843
                        $arr_data['folders'][$inc]['is_visible_active'] = $is_visible_active;
5844
5845
                        ++$inc;
5846
                    }
5847
                }
5848
            }
5849
5850
            $data = array(
5851
                'error' => 'false',
5852
                'html_json' => $arr_data,
5853
            );
5854
            // send data
5855
            echo prepareExchangedData($data, 'encode');
5856
5857
            break;
5858
5859
        /*
5860
        * CASE
5861
        * Get list of users that have access to the folder
5862
        */
5863
        case 'refresh_folders_other_info':
5864
            // Check KEY
5865
            if ($post_key !== $_SESSION['key']) {
5866
                echo prepareExchangedData(
5867
                    array(
5868
                        'error' => true,
5869
                        'message' => langHdl('key_is_not_correct'),
5870
                    ),
5871
                    'encode'
5872
                );
5873
                break;
5874
            }
5875
5876
            $arr_data = array();
5877
5878
            foreach (json_decode($post_data) as $folder) {
5879
                // Do we have Categories
5880
                if (isset($SETTINGS['item_extra_fields']) && $SETTINGS['item_extra_fields'] === '1') {
5881
                    // get list of associated Categories
5882
                    $arrCatList = array();
5883
                    $rows_tmp = DB::query(
5884
                        'SELECT c.id, c.title, c.level, c.type, c.masked, c.order, c.encrypted_data, c.role_visibility, c.is_mandatory,
5885
                        f.id_category AS category_id
5886
                        FROM '.prefixTable('categories_folders').' AS f
5887
                        INNER JOIN '.prefixTable('categories').' AS c ON (f.id_category = c.parent_id)
5888
                        WHERE id_folder=%i',
5889
                        $folder
5890
                    );
5891
                    if (DB::count() > 0) {
5892
                        foreach ($rows_tmp as $row) {
5893
                            $arrCatList[$row['id']] = array(
5894
                                'id' => $row['id'],
5895
                                'title' => $row['title'],
5896
                                'level' => $row['level'],
5897
                                'type' => $row['type'],
5898
                                'masked' => $row['masked'],
5899
                                'order' => $row['order'],
5900
                                'encrypted_data' => $row['encrypted_data'],
5901
                                'role_visibility' => $row['role_visibility'],
5902
                                'is_mandatory' => $row['is_mandatory'],
5903
                                'category_id' => $row['category_id'],
5904
                            );
5905
                        }
5906
                    }
5907
                    $arr_data[$folder]['categories'] = $arrCatList;
5908
                }
5909
5910
                // Now get complexity
5911
                $valTemp = '';
5912
                $data = DB::queryFirstRow(
5913
                    'SELECT valeur
5914
                    FROM '.prefixTable('misc').'
5915
                    WHERE type = %s AND intitule=%i',
5916
                    'complex',
5917
                    $folder
5918
                );
5919
                if (DB::count() > 0 && empty($data['valeur']) === false) {
5920
                    $valTemp = array(
5921
                        'value' => $data['valeur'],
5922
                        'text' => TP_PW_COMPLEXITY[$data['valeur']][1],
5923
                    );
5924
                }
5925
                $arr_data[$folder]['complexity'] = $valTemp;
5926
5927
                // Now get Roles
5928
                $valTemp = '';
5929
                $rows_tmp = DB::query(
5930
                    'SELECT t.title
5931
                    FROM '.prefixTable('roles_values').' as v
5932
                    INNER JOIN '.prefixTable('roles_title').' as t ON (v.role_id = t.id)
5933
                    WHERE v.folder_id = %i
5934
                    GROUP BY title',
5935
                    $folder
5936
                );
5937
                foreach ($rows_tmp as $record) {
5938
                    if (empty($valTemp) === true) {
5939
                        $valTemp = $record['title'];
5940
                    } else {
5941
                        $valTemp .= ' - '.$record['title'];
5942
                    }
5943
                }
5944
                $arr_data[$folder]['visibilityRoles'] = $valTemp;
5945
            }
5946
5947
            $data = array(
5948
                'error' => '',
5949
                'result' => $arr_data,
5950
            );
5951
            // send data
5952
            echo prepareExchangedData($data, 'encode');
5953
5954
            break;
5955
5956
        /*
5957
        * CASE
5958
        * Load item history
5959
        */
5960
        case 'load_item_history':
5961
            // Check KEY
5962
            if ($post_key !== $_SESSION['key']) {
5963
                echo prepareExchangedData(array('error' => 'ERR_KEY_NOT_CORRECT'), 'encode');
5964
                break;
5965
            }
5966
5967
            // get item info
5968
            $dataItem = DB::queryFirstRow(
5969
                'SELECT *
5970
                FROM '.prefixTable('items').'
5971
                WHERE id=%i',
5972
                $post_item_id
5973
            );
5974
5975
            // get item history
5976
            $history = array();
5977
            $rows = DB::query(
5978
                'SELECT l.date as date, l.action as action, l.raison as raison, l.raison_iv AS raison_iv,
5979
                u.login as login, u.avatar_thumb as avatar_thumb, u.name as name, u.lastname as lastname
5980
                FROM '.prefixTable('log_items').' as l
5981
                LEFT JOIN '.prefixTable('users').' as u ON (l.id_user=u.id)
5982
                WHERE id_item=%i AND action <> %s
5983
                ORDER BY date DESC',
5984
                $post_item_id,
5985
                'at_shown'
5986
            );
5987
            foreach ($rows as $record) {
5988
                $reason = explode(' :', $record['raison']);
5989
                if ($reason[0] === 'at_pw') {
5990
                    // This is a password change.
5991
                    // Just indicate it was changed
5992
                }
5993
                // imported via API
5994
                if (empty($record['login'])) {
5995
                    $record['login'] = langHdl('imported_via_api').' ['.$record['raison'].']';
5996
                }
5997
5998
                if (in_array(
5999
                    $record['action'],
6000
                    array('at_password_copied', 'at_shown', 'at_password_shown')
6001
                ) === false
6002
                ) {
6003
                    // Prepare avatar
6004
                    if (isset($record['avatar_thumb']) && empty($record['avatar_thumb']) === false) {
6005
                        if (file_exists($SETTINGS['cpassman_dir'].'/includes/avatars/'.$record['avatar_thumb'])) {
6006
                            $avatar = $SETTINGS['cpassman_url'].'/includes/avatars/'.$record['avatar_thumb'];
6007
                        } else {
6008
                            $avatar = $SETTINGS['cpassman_url'].'/includes/images/photo.jpg';
6009
                        }
6010
                    } else {
6011
                        $avatar = $SETTINGS['cpassman_url'].'/includes/images/photo.jpg';
6012
                    }
6013
6014
                    // Prepare action
6015
                    $action = '';
6016
                    $detail = '';
6017
                    if ($reason[0] === 'at_pw') {
6018
                        $action = langHdl($reason[0]);
6019
                    } elseif ($reason[0] === 'at_description') {
6020
                        $action = langHdl('description_has_changed');
6021
                    } elseif (empty($record['raison']) === false && $reason[0] !== 'at_creation') {
6022
                        $action = langHdl($reason[0]);
6023
                        if ($reason[0] === 'at_moved') {
6024
                            $tmp = explode(' -> ', $reason[1]);
6025
                            $detail = langHdl('from').' <span class="font-weight-light">'.$tmp[0].'</span> '.langHdl('to').' <span class="font-weight-light">'.$tmp[1].' </span>';
6026
                        } elseif ($reason[0] === 'at_field') {
6027
                            $tmp = explode(' => ', $reason[1]);
6028
                            if (count($tmp) > 1) {
6029
                                $detail = '<b>'.trim($tmp[0]).'</b> | '.langHdl('previous_value').
6030
                                    ': <span class="font-weight-light">'.trim($tmp[1]).'</span>';
6031
                            } else {
6032
                                $detail = trim($reason[1]);
6033
                            }
6034
                        } elseif (in_array($reason[0], array('at_restriction', 'at_email', 'at_login', 'at_label', 'at_url')) === true) {
6035
                            $tmp = explode(' => ', $reason[1]);
6036
                            $detail = empty(trim($tmp[0])) === true ?
6037
                                langHdl('no_previous_value') :
6038
                                langHdl('previous_value').': <span class="font-weight-light">'.$tmp[0].' </span>';
6039
                        } elseif ($reason[0] === 'at_automatic_del') {
6040
                            $detail = langHdl($reason[1]);
6041
                        } elseif ($reason[0] === 'at_anyoneconmodify') {
6042
                            $detail = langHdl($reason[1]);
6043
                        } elseif ($reason[0] === 'at_add_file' || $reason[0] === 'at_del_file') {
6044
                            $tmp = explode(':', $reason[1]);
6045
                            $tmp = explode('.', $tmp[0]);
6046
                            $detail = isBase64($tmp[0]) === true ?
6047
                                base64_decode($tmp[0]).'.'.$tmp[1] :
6048
                                $tmp[0];
6049
                        } elseif ($reason[0] === 'at_import') {
6050
                            $detail = '';
6051
                        } elseif (in_array($reason[0], array('csv', 'pdf')) === true) {
6052
                            $detail = $reason[0];
6053
                            $action = langHdl('exported_to_file');
6054
                        } else {
6055
                            $detail = $reason[0];
6056
                        }
6057
                    } elseif ($record['action'] === 'at_manual') {
6058
                        $detail = langHdl($record['action']);
6059
                        $action = $reason[0];
6060
                    } else {
6061
                        $detail = langHdl($record['action']);
6062
                        $action = '';
6063
                    }
6064
6065
                    array_push(
6066
                        $history,
6067
                        array(
6068
                            'avatar' => $avatar,
6069
                            'login' => $record['login'],
6070
                            'name' => $record['name'].' '.$record['lastname'],
6071
                            'date' => date($SETTINGS['date_format'].' '.$SETTINGS['time_format'], $record['date']),
6072
                            'action' => $action,
6073
                            'detail' => $detail,
6074
                        )
6075
                    );
6076
                }
6077
            }
6078
6079
            $data = array(
6080
                'error' => '',
6081
                'history' => $history,
6082
            );
6083
6084
            // send data
6085
            echo prepareExchangedData($data, 'encode');
6086
6087
            break;
6088
6089
        case 'suggest_item_change':
6090
            // Check KEY
6091
            if ($post_key !== $_SESSION['key']) {
6092
                echo prepareExchangedData(
6093
                    array(
6094
                        'error' => 'key_not_conform',
6095
                        'message' => langHdl('key_is_not_correct'),
6096
                    ),
6097
                    'encode'
6098
                );
6099
                break;
6100
            }
6101
            // decrypt and retrieve data in JSON format
6102
            $data_received = prepareExchangedData($post_data, 'decode');
6103
6104
            // prepare variables
6105
            $label = htmlspecialchars_decode($data_received['label'], ENT_QUOTES);
6106
            $pwd = htmlspecialchars_decode($data_received['password']);
6107
            $login = htmlspecialchars_decode($data_received['login'], ENT_QUOTES);
6108
            $email = htmlspecialchars_decode($data_received['email']);
6109
            $url = htmlspecialchars_decode($data_received['url']);
6110
            $folder = htmlspecialchars_decode($data_received['folder_id']);
6111
            $comment = htmlspecialchars_decode($data_received['comment']);
6112
            $item_id = htmlspecialchars_decode($data_received['item_id']);
6113
6114
            if (empty($pwd)) {
6115
                $encrypt['string'] = '';
6116
            } else {
6117
                $encrypt = cryption($pwd, '', 'encrypt', $SETTINGS);
6118
            }
6119
6120
            // query
6121
            DB::insert(
6122
                prefixTable('items_change'),
6123
                array(
6124
                    'item_id' => $item_id,
6125
                    'label' => $label,
6126
                    'pw' => $encrypt['string'],
6127
                    'login' => $login,
6128
                    'email' => $email,
6129
                    'url' => $url,
6130
                    'description' => '',
6131
                    'comment' => $comment,
6132
                    'folder_id' => $folder,
6133
                    'user_id' => $_SESSION['user_id'],
6134
                    'timestamp' => time(),
6135
                )
6136
            );
6137
            $newID = DB::insertId();
6138
6139
            // get some info to add to the notification email
6140
            $resp_user = DB::queryfirstrow(
6141
                'SELECT login FROM '.prefixTable('users').' WHERE id = %i',
6142
                $_SESSION['user_id']
6143
            );
6144
            $resp_folder = DB::queryfirstrow(
6145
                'SELECT title FROM '.prefixTable('nested_tree').' WHERE id = %i',
6146
                $folder
6147
            );
6148
6149
            // notify Managers
6150
            $rows = DB::query(
6151
                'SELECT email
6152
                FROM '.prefixTable('users').'
6153
                WHERE `gestionnaire` = %i AND `email` IS NOT NULL',
6154
                1
6155
            );
6156
            foreach ($rows as $record) {
6157
                sendEmail(
6158
                    langHdl('suggestion_notify_subject'),
6159
                    str_replace(array('#tp_label#', '#tp_user#', '#tp_folder#'), array(addslashes($label), addslashes($resp_user['login']), addslashes($resp_folder['title'])), langHdl('suggestion_notify_body')),
6160
                    $record['email'],
6161
                    $SETTINGS
6162
                );
6163
            }
6164
6165
            echo prepareExchangedData(
6166
                array(
6167
                    'error' => '',
6168
                ),
6169
                'encode'
6170
            );
6171
            break;
6172
6173
        case 'build_list_of_users':
6174
            // Check KEY
6175
            if ($post_key !== $_SESSION['key']) {
6176
                echo '[ { "error" : "key_not_conform" } ]';
6177
                break;
6178
            }
6179
6180
            // Get list of users
6181
            $usersList = array();
6182
            $usersString = '';
6183
            $rows = DB::query('SELECT id,login,email FROM '.prefixTable('users').' ORDER BY login ASC');
6184
            foreach ($rows as $record) {
6185
                $usersList[$record['login']] = array(
6186
                    'id' => $record['id'],
6187
                    'login' => $record['login'],
6188
                    'email' => $record['email'],
6189
                    );
6190
                $usersString .= $record['id'].'#'.$record['login'].';';
6191
            }
6192
6193
            $data = array(
6194
                'error' => '',
6195
                'list' => $usersString,
6196
            );
6197
6198
            // send data
6199
            echo prepareExchangedData($data, 'encode');
6200
            break;
6201
6202
        case 'send_request_access':
6203
            // Check KEY
6204
            if ($post_key !== $_SESSION['key']) {
6205
                echo prepareExchangedData(
6206
                    array(
6207
                        'error' => 'key_not_conform',
6208
                        'message' => langHdl('key_is_not_correct'),
6209
                    ),
6210
                    'encode'
6211
                );
6212
                break;
6213
            }
6214
            // decrypt and retrieve data in JSON format
6215
            $dataReceived = prepareExchangedData($post_data, 'decode');
6216
6217
            // prepare variables
6218
            $post_email_body = filter_var($dataReceived['email'], FILTER_SANITIZE_STRING);
6219
            $post_item_id = filter_var($dataReceived['id'], FILTER_SANITIZE_NUMBER_INT);
6220
6221
            // Send email
6222
            $dataItem = DB::queryfirstrow(
6223
                'SELECT label, id_tree
6224
                FROM '.prefixTable('items').'
6225
                WHERE id = %i',
6226
                $post_item_id
6227
            );
6228
            $dataItemLog = DB::queryfirstrow(
6229
                'SELECT id_user
6230
                FROM '.prefixTable('log_items').'
6231
                WHERE id_item = %i AND action = %s',
6232
                $post_item_id,
6233
                'at_creation'
6234
            );
6235
            $dataAuthor = DB::queryfirstrow(
6236
                'SELECT email, login
6237
                FROM '.prefixTable('users').'
6238
                WHERE id = %i',
6239
                $dataItemLog['id_user']
6240
            );
6241
6242
            // Get path
6243
            $path = geItemReadablePath(
6244
                $dataItem['id_tree'],
6245
                $dataItem['label'],
6246
                $SETTINGS
6247
            );
6248
6249
            /*$ret = sendEmail(
6250
                langHdl('email_request_access_subject'),
6251
                str_replace(
6252
                    array(
6253
                        '#tp_item_author#',
6254
                        '#tp_user#',
6255
                        '#tp_item#',
6256
                        '#tp_reason#',
6257
                    ),
6258
                    array(
6259
                        ' '.addslashes($dataAuthor['login']),
6260
                        addslashes($_SESSION['login']),
6261
                        $path,
6262
                        nl2br(addslashes($post_email_body)),
6263
                    ),
6264
                    langHdl('email_request_access_mail')
6265
                ),
6266
                $dataAuthor['email'],
6267
                $SETTINGS
6268
            );*/
6269
6270
            // Do log
6271
            logItems(
6272
                $SETTINGS,
6273
                $post_item_id,
6274
                $dataItem['label'],
6275
                $_SESSION['user_id'],
6276
                'at_access',
6277
                $_SESSION['login']
6278
            );
6279
6280
            // Return
6281
            echo prepareExchangedData(
6282
                array(
6283
                    'error' => false,
6284
                    'message' => '',
6285
                ),
6286
                'encode'
6287
            );
6288
6289
            break;
6290
6291
        /*
6292
        * CASE
6293
        * GET CLIPBOARD DATA TO SHOW
6294
        */
6295
        case 'get_clipboard_data':
6296
            // Check KEY and rights
6297
            if ($post_key !== $_SESSION['key'] || $_SESSION['user_read_only'] === true || !isset($SETTINGS['pwd_maximum_length'])) {
6298
                // error
6299
                exit();
6300
            }
6301
6302
            // load the original record into an array
6303
            $dataItem = DB::queryfirstrow(
6304
                'SELECT label, pw, login, perso FROM '.prefixTable('items').'
6305
                WHERE id=%i',
6306
                $post_item_id
6307
            );
6308
6309
            if (filter_input(INPUT_POST, 'show_type', FILTER_SANITIZE_STRING) === 'password') {
6310
                // check if item is PF
6311
                if ($dataItem['perso'] !== 1) {
6312
                    $pw = cryption(
6313
                        $dataItem['pw'],
6314
                        '',
6315
                        'decrypt',
6316
                        $SETTINGS
6317
                    );
6318
                } else {
6319
                    if (isset($_SESSION['user_settings']['session_psk']) === true) {
6320
                        $pw = cryption(
6321
                            $dataItem['pw'],
6322
                            $_SESSION['user_settings']['session_psk'],
6323
                            'decrypt',
6324
                            $SETTINGS
6325
                        );
6326
                    } else {
6327
                        $pw = '';
6328
                    }
6329
                }
6330
6331
                // if not UTF8 then cleanup and inform that something is wrong with encrytion/decryption
6332
                if (isUTF8($pw['string']) === false) {
6333
                    $px = '';
6334
                }
6335
6336
                echo prepareExchangedData($pw['string'], 'encode');
6337
6338
                // Now log
6339
                logItems(
6340
                    $SETTINGS,
6341
                    $post_item_id,
6342
                    $dataItem['label'],
6343
                    $_SESSION['user_id'],
6344
                    'at_password_copied',
6345
                    $_SESSION['login']
6346
                );
6347
                break;
6348
            } else {
6349
                echo prepareExchangedData($dataItem['login'], 'encode');
6350
            }
6351
6352
            break;
6353
6354
        /*
6355
        * CASE
6356
        * save_notification_status
6357
        */
6358
        case 'save_notification_status':
6359
            // Check KEY
6360
            if ($post_key !== $_SESSION['key']) {
6361
                echo prepareExchangedData(
6362
                    array(
6363
                        'error' => 'key_not_conform',
6364
                        'message' => langHdl('key_is_not_correct'),
6365
                    ),
6366
                    'encode'
6367
                );
6368
                break;
6369
            }
6370
            // decrypt and retrieve data in JSON format
6371
            $dataReceived = prepareExchangedData($post_data, 'decode');
6372
6373
            // prepare variables
6374
            $post_notification_status = (int) filter_var($dataReceived['notification_status'], FILTER_SANITIZE_NUMBER_INT);
6375
            $post_item_id = (int) filter_var($dataReceived['item_id'], FILTER_SANITIZE_NUMBER_INT);
6376
6377
            DB::query(
6378
                'SELECT *
6379
                FROM '.prefixTable('notification').'
6380
                WHERE item_id = %i AND user_id = %i',
6381
                $post_item_id,
6382
                $_SESSION['user_id']
6383
            );
6384
            if (DB::count() > 0) {
6385
                // Notification is set for this user on this item
6386
                if ((int) $post_notification_status === 0) {
6387
                    // Remove the notification
6388
                    DB::delete(
6389
                        prefixTable('notification'),
6390
                        'item_id = %i AND user_id = %i',
6391
                        $post_item_id,
6392
                        $_SESSION['user_id']
6393
                    );
6394
                }
6395
            } else {
6396
                // Notification is not set on this item
6397
                if ((int) $post_notification_status === 1) {
6398
                    // Add the notification
6399
                    DB::insert(
6400
                        prefixTable('notification'),
6401
                        array(
6402
                            'item_id' => $post_item_id,
6403
                            'user_id' => $_SESSION['user_id'],
6404
                        )
6405
                    );
6406
                }
6407
            }
6408
6409
            $data = array(
6410
                'error' => false,
6411
                'message' => '',
6412
            );
6413
6414
            // send data
6415
            echo prepareExchangedData($data, 'encode');
6416
6417
            break;
6418
6419
        /*
6420
        * CASE
6421
        * delete_uploaded_files_but_not_saved
6422
        */
6423
        case 'delete_uploaded_files_but_not_saved':
6424
            // Check KEY
6425
            if ($post_key !== $_SESSION['key']) {
6426
                echo prepareExchangedData(
6427
                    array(
6428
                        'error' => 'key_not_conform',
6429
                        'message' => langHdl('key_is_not_correct'),
6430
                    ),
6431
                    'encode'
6432
                );
6433
                break;
6434
            }
6435
            // decrypt and retrieve data in JSON format
6436
            $dataReceived = prepareExchangedData($post_data, 'decode');
6437
6438
            // prepare variables
6439
            $post_item_id = (int) filter_var($dataReceived['item_id'], FILTER_SANITIZE_NUMBER_INT);
6440
6441
            // Delete non confirmed files for this item
6442
            // And related logs
6443
            $rows = DB::query(
6444
                'SELECT id, file AS filename
6445
                FROM '.prefixTable('files').'
6446
                WHERE id_item = %i AND confirmed = %i',
6447
                $post_item_id,
6448
                0
6449
            );
6450
            foreach ($rows as $file) {
6451
                // Delete file in DB
6452
                DB::delete(
6453
                    prefixTable('files'),
6454
                    'id = %i',
6455
                    $file['id']
6456
                );
6457
6458
                // Delete file on server
6459
                unlink($SETTINGS['path_to_upload_folder'].'/'.TP_FILE_PREFIX.base64_decode($file['filename']));
6460
6461
                // Delete related logs
6462
                $logFile = DB::query(
6463
                    'SELECT increment_id, raison
6464
                    FROM '.prefixTable('log_items').'
6465
                    WHERE id_item = %i AND id_user = %i AND action = %s AND raison LIKE "at_add_file :%"',
6466
                    $post_item_id,
6467
                    $_SESSION['user_id'],
6468
                    'at_modification'
6469
                );
6470
                foreach ($logFile as $log) {
6471
                    $tmp = explode(':', $log['raison']);
6472
                    if (count($tmp) === 3 && (int) $tmp[2] === (int) $file['id']) {
6473
                        DB::delete(
6474
                            prefixTable('log_items'),
6475
                            'increment_id = %i',
6476
                            $log['increment_id']
6477
                        );
6478
                    }
6479
                }
6480
            }
6481
6482
            $data = array(
6483
                'error' => false,
6484
                'message' => '',
6485
            );
6486
6487
            // send data
6488
            echo prepareExchangedData($data, 'encode');
6489
6490
            break;
6491
6492
        /*
6493
        * CASE
6494
        * confirm_attachments
6495
        */
6496
        case 'confirm_attachments':
6497
            // Check KEY
6498
            if ($post_key !== $_SESSION['key']) {
6499
                echo prepareExchangedData(
6500
                    array(
6501
                        'error' => 'key_not_conform',
6502
                        'message' => langHdl('key_is_not_correct'),
6503
                    ),
6504
                    'encode'
6505
                );
6506
                break;
6507
            }
6508
            // decrypt and retrieve data in JSON format
6509
            $dataReceived = prepareExchangedData($post_data, 'decode');
6510
6511
            // prepare variables
6512
            $post_item_id = (int) filter_var($dataReceived['item_id'], FILTER_SANITIZE_NUMBER_INT);
6513
6514
            // Confirm attachments
6515
            $rows = DB::query(
6516
                'SELECT id, file AS filename
6517
                FROM '.prefixTable('files').'
6518
                WHERE id_item = %i AND confirmed = %i',
6519
                $post_item_id,
6520
                0
6521
            );
6522
            foreach ($rows as $file) {
6523
                DB::update(
6524
                    prefixTable('files'),
6525
                    array(
6526
                        'confirmed' => 1,
6527
                    ),
6528
                    'id_item = %i',
6529
                    $post_item_id
6530
                );
6531
            }
6532
6533
            $data = array(
6534
                'error' => false,
6535
                'message' => '',
6536
            );
6537
6538
            // send data
6539
            echo prepareExchangedData($data, 'encode');
6540
6541
            break;
6542
    }
6543
}
6544
// Build the QUERY in case of GET
6545
if (isset($_GET['type'])) {
6546
    switch ($_GET['type']) {
6547
        /*
6548
        * CASE
6549
        * Autocomplet for TAGS
6550
        */
6551
        case 'autocomplete_tags':
6552
            // Get a list off all existing TAGS
6553
            $listOfTags = '';
6554
            $rows = DB::query('SELECT tag FROM '.prefixTable('tags').' WHERE tag LIKE %ss GROUP BY tag', $_GET['term']);
6555
            foreach ($rows as $record) {
6556
                if (empty($listOfTags)) {
6557
                    $listOfTags = '"'.$record['tag'].'"';
6558
                } else {
6559
                    $listOfTags .= ', "'.$record['tag'].'"';
6560
                }
6561
            }
6562
            echo '['.$listOfTags.']';
6563
            break;
6564
    }
6565
}
6566
6567
/*
6568
* FUNCTION
6569
* Identify if this group authorize creation of item without the complexit level reached
6570
*/
6571
function recupDroitCreationSansComplexite($groupe)
6572
{
6573
    $data = DB::queryFirstRow(
6574
        'SELECT bloquer_creation, bloquer_modification, personal_folder FROM '.prefixTable('nested_tree').' WHERE id = %i',
6575
        $groupe
6576
    );
6577
    // Check if it's in a personal folder. If yes, then force complexity overhead.
6578
    if ($data['personal_folder'] === '1') {
6579
        return array(
6580
            'bloquer_modification_complexite' => 1,
6581
            'bloquer_creation_complexite' => 1,
6582
        );
6583
    }
6584
6585
    return array(
6586
        'bloquer_modification_complexite' => (int) $data['bloquer_modification'],
6587
        'bloquer_creation_complexite' => (int) $data['bloquer_creation'],
6588
    );
6589
}
6590
6591
/**
6592
 * Permits to identify what icon to display depending on file extension.
6593
 *
6594
 * @param string $ext Extension
6595
 *
6596
 * @return string
6597
 */
6598
function fileFormatImage($ext)
6599
{
6600
    if (in_array($ext, TP_OFFICE_FILE_EXT)) {
6601
        $image = 'fas fa-file-word';
6602
    } elseif ($ext === 'pdf') {
6603
        $image = 'fas fa-file-pdf';
6604
    } elseif (in_array($ext, TP_IMAGE_FILE_EXT)) {
6605
        $image = 'fas fa-file-image';
6606
    } elseif ($ext === 'txt') {
6607
        $image = 'fas fa-file-alt';
6608
    } else {
6609
        $image = 'fas fa-file';
6610
    }
6611
6612
    return $image;
6613
}
6614
6615
/**
6616
 * Returns a cleaned up password.
6617
 *
6618
 * @param string $pwd String for pwd
6619
 *
6620
 * @return string
6621
 */
6622
function passwordReplacement($pwd)
6623
{
6624
    $pwPatterns = array('/ETCOMMERCIAL/', '/SIGNEPLUS/');
6625
    $pwRemplacements = array('&', '+');
6626
6627
    return preg_replace($pwPatterns, $pwRemplacements, $pwd);
6628
}
6629