Passed
Push — teampass_3.0 ( 8b1532...1c3073 )
by Nils
03:38
created

fileFormatImage()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 15
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 11
c 1
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) {
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
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 = prepareEmaiItemPath(
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') {
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
                // Get all informations for this item
934
                $dataItem = DB::queryfirstrow(
935
                    'SELECT *
936
                    FROM '.prefixTable('items').' as i
937
                    INNER JOIN '.prefixTable('log_items').' as l ON (l.id_item = i.id)
938
                    WHERE i.id=%i AND l.action = %s',
939
                    $post_item_id,
940
                    'at_creation'
941
                );
942
                // check that actual user can access this item
943
                $restrictionActive = true;
944
                $restrictedTo = array_filter(explode(';', $dataItem['restricted_to']));
945
                if (in_array($_SESSION['user_id'], $restrictedTo) === true) {
946
                    $restrictionActive = false;
947
                }
948
                if (empty($dataItem['restricted_to']) === true) {
949
                    $restrictionActive = false;
950
                }
951
952
                if ((in_array($dataItem['id_tree'], $_SESSION['groupes_visibles']) === true
953
                    && ((int) $dataItem['perso'] === 0
954
                    || ((int) $dataItem['perso'] === 1
955
                    && (int) $_SESSION['user_id'] === (int) $dataItem['id_user']))
956
                    && $restrictionActive === false
957
                    )
958
                    ||
959
                    (
960
                        isset($SETTINGS['anyone_can_modify']) === true
961
                        && (int) $SETTINGS['anyone_can_modify'] === 1
962
                        && (int) $dataItem['anyone_can_modify'] === 1
963
                        && (in_array($dataItem['id_tree'], $_SESSION['groupes_visibles']) === true
964
                        || (int) $_SESSION['is_admin'] === 1)
965
                        && $restrictionActive === false
966
                    )
967
                    ||
968
                    (null !== $post_folder_id
969
                    && isset($_SESSION['list_restricted_folders_for_items'][$post_folder_id]) === true
970
                    && in_array($post_id, $_SESSION['list_restricted_folders_for_items'][$post_folder_id]) === true
971
                    //&& $post_restricted === '1'
972
                    && $restrictionActive === false)
973
                ) {
974
                    // Get existing values
975
                    $data = DB::queryfirstrow(
976
                        '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, 
977
                        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,
978
                        u.login as user_login, u.email as user_email
979
                        FROM '.prefixTable('items').' as i
980
                        INNER JOIN '.prefixTable('log_items').' as l ON (i.id=l.id_item)
981
                        INNER JOIN '.prefixTable('users').' as u ON (u.id=l.id_user)
982
                        WHERE i.id=%i',
983
                        $post_item_id
984
                    );
985
986
                    // Should we log a password change?
987
                    $userKey = DB::queryFirstRow(
988
                        'SELECT share_key
989
                        FROM '.prefixTable('sharekeys_items').'
990
                        WHERE user_id = %i AND object_id = %i',
991
                        $_SESSION['user_id'],
992
                        $post_item_id
993
                    );
994
                    if (DB::count() === 0 || empty($data['pw']) === true) {
995
                        // No share key found
996
                        $pw = '';
997
                    } else {
998
                        $pw = base64_decode(doDataDecryption(
999
                            $data['pw'],
1000
                            decryptUserObjectKey(
1001
                                $userKey['share_key'],
1002
                                $_SESSION['user']['private_key']
1003
                            )
1004
                        ));
1005
                    }
1006
1007
                    if ($post_password !== $pw) {
1008
                        logItems(
1009
                            $SETTINGS,
1010
                            $post_item_id,
1011
                            $post_label,
1012
                            $_SESSION['user_id'],
1013
                            'at_modification',
1014
                            $_SESSION['login'],
1015
                            'at_pw',
1016
                            'defuse'
1017
                        );
1018
                    }
1019
1020
                    // encrypt PW
1021
                    if ((isset($_SESSION['user_settings']['create_item_without_password']) === true
1022
                        && (int) $_SESSION['user_settings']['create_item_without_password'] !== 1)
1023
                        || empty($post_password) === false
1024
                    ) {
1025
                        //-----
1026
                        // NEW ENCRYPTION
1027
                        $cryptedStuff = doDataEncryption($post_password);
1028
1029
                        $encrypted_password = $cryptedStuff['encrypted'];
1030
1031
                        // Create sharekeys for users
1032
                        storeUsersShareKey(
1033
                            prefixTable('sharekeys_items'),
1034
                            $post_folder_is_personal,
1035
                            $post_folder_id,
1036
                            $post_item_id,
1037
                            $cryptedStuff['objectKey'],
1038
                            $SETTINGS
1039
                        );
1040
                    } else {
1041
                        $encrypted_password = '';
1042
                    }
1043
1044
                    // ---Manage tags
1045
                    // deleting existing tags for this item
1046
                    DB::delete(
1047
                        prefixTable('tags'),
1048
                        'item_id = %i',
1049
                        $post_item_id
1050
                    );
1051
1052
                    // Add new tags
1053
                    $return_tags = '';
1054
                    $post_tags = explode(' ', $post_tags);
1055
                    foreach ($post_tags as $tag) {
1056
                        if (empty($tag) === false) {
1057
                            // save in DB
1058
                            DB::insert(
1059
                                prefixTable('tags'),
1060
                                array(
1061
                                    'item_id' => $post_item_id,
1062
                                    'tag' => strtolower($tag),
1063
                                )
1064
                            );
1065
                        }
1066
                    }
1067
1068
                    // update item
1069
                    DB::update(
1070
                        prefixTable('items'),
1071
                        array(
1072
                            'label' => $post_label,
1073
                            'description' => $post_description,
1074
                            'pw' => $encrypted_password,
1075
                            'email' => $post_email,
1076
                            'login' => $post_login,
1077
                            'url' => $post_url,
1078
                            'id_tree' => $post_folder_id === 'undefined' ? $dataItem['id_tree'] : $post_folder_id,
1079
                            'restricted_to' => empty($post_restricted_to) === true || count($post_restricted_to) === 0 ? '' : implode(';', $post_restricted_to),
1080
                            'anyone_can_modify' => (int) $post_anyone_can_modify,
1081
                            'complexity_level' => (int) $post_complexity_level,
1082
                            'encryption_type' => 'defuse',
1083
                            'perso' => in_array($post_folder_id, $_SESSION['personal_folders']) === true ? 1 : 0,
1084
                            ),
1085
                        'id=%i',
1086
                        $post_item_id
1087
                    );
1088
1089
                    // update fields
1090
                    if (isset($SETTINGS['item_extra_fields']) === true
1091
                        && (int) $SETTINGS['item_extra_fields'] === 1
1092
                        && empty($post_fields) === false
1093
                    ) {
1094
                        foreach ($post_fields as $field) {
1095
                            if (empty($field['value']) === false) {
1096
                                $dataTmpCat = DB::queryFirstRow(
1097
                                    'SELECT c.id AS id, c.title AS title, i.data AS data, i.data_iv AS data_iv,
1098
                                    i.encryption_type AS encryption_type, c.encrypted_data AS encrypted_data,
1099
                                    c.masked AS masked, i.id AS field_item_id
1100
                                    FROM '.prefixTable('categories_items').' AS i
1101
                                    INNER JOIN '.prefixTable('categories').' AS c ON (i.field_id=c.id)
1102
                                    WHERE i.field_id = %i AND i.item_id = %i',
1103
                                    $field['id'],
1104
                                    $post_item_id
1105
                                );
1106
1107
                                // store Field text in DB
1108
                                if (DB::count() === 0) {
1109
                                    // The data for this foeld doesn't exist
1110
                                    // It has to be added
1111
1112
                                    // Perform new query
1113
                                    $dataTmpCat = DB::queryFirstRow(
1114
                                        'SELECT id, title, encrypted_data, masked
1115
                                        FROM '.prefixTable('categories').'
1116
                                        WHERE id = %i',
1117
                                        $field['id']
1118
                                    );
1119
1120
                                    // store field text
1121
                                    DB::insert(
1122
                                        prefixTable('categories_items'),
1123
                                        array(
1124
                                            'item_id' => $post_item_id,
1125
                                            'field_id' => $field['id'],
1126
                                            'data' => $field['value'],
1127
                                            'data_iv' => '',
1128
                                            'encryption_type' => 'not_set',
1129
                                        )
1130
                                    );
1131
1132
                                    $newId = DB::insertId();
1133
1134
                                    // Should we encrypt the data
1135
                                    if ((int) $dataTmpCat['encrypted_data'] === 1) {
1136
                                        $cryptedStuff = doDataEncryption($field['value']);
1137
1138
                                        // Create sharekeys for users
1139
                                        storeUsersShareKey(
1140
                                            prefixTable('sharekeys_fields'),
1141
                                            $post_folder_is_personal,
1142
                                            $post_folder_id,
1143
                                            $newId,
1144
                                            $cryptedStuff['objectKey'],
1145
                                            $SETTINGS
1146
                                        );
1147
1148
                                        // update value
1149
                                        DB::update(
1150
                                            prefixTable('categories_items'),
1151
                                            array(
1152
                                                'data' => $cryptedStuff['encrypted'],
1153
                                                'data_iv' => '',
1154
                                                'encryption_type' => TP_ENCRYPTION_NAME,
1155
                                            ),
1156
                                            'id = %i',
1157
                                            $newId
1158
                                        );
1159
                                    }
1160
1161
                                    // update LOG
1162
                                    logItems(
1163
                                        $SETTINGS,
1164
                                        $post_item_id,
1165
                                        $post_label,
1166
                                        $_SESSION['user_id'],
1167
                                        'at_modification',
1168
                                        $_SESSION['login'],
1169
                                        'at_field : '.$dataTmpCat['title'].' : '.$field['value']
1170
                                    );
1171
                                } else {
1172
                                    // compare the old and new value
1173
                                    if ($dataTmpCat['encryption_type'] !== 'not_set') {
1174
                                        // Get user sharekey for this field
1175
                                        $userKey = DB::queryFirstRow(
1176
                                            'SELECT share_key
1177
                                            FROM '.prefixTable('sharekeys_fields').'
1178
                                            WHERE user_id = %i AND object_id = %i',
1179
                                            $_SESSION['user_id'],
1180
                                            $dataTmpCat['field_item_id']
1181
                                        );
1182
1183
                                        // Decrypt the current value
1184
                                        $oldVal = base64_decode(doDataDecryption(
1185
                                            $dataTmpCat['data'],
1186
                                            decryptUserObjectKey(
1187
                                                $userKey['share_key'],
1188
                                                $_SESSION['user']['private_key']
1189
                                            )
1190
                                        ));
1191
                                    } else {
1192
                                        $oldVal = $dataTmpCat['data'];
1193
                                    }
1194
1195
                                    // Compare both values to see if any change was done
1196
                                    if ($field['value'] !== $oldVal) {
1197
                                        // The strings are different
1198
1199
                                        // Should we encrypt the data
1200
                                        if ((int) $dataTmpCat['encrypted_data'] === 1) {
1201
                                            $cryptedStuff = doDataEncryption($field['value']);
1202
                                            $encrypt['string'] = $cryptedStuff['encrypted'];
1203
                                            $encrypt['type'] = TP_ENCRYPTION_NAME;
1204
1205
                                            // Create sharekeys for users
1206
                                            storeUsersShareKey(
1207
                                                prefixTable('sharekeys_fields'),
1208
                                                $post_folder_is_personal,
1209
                                                $post_folder_id,
1210
                                                $dataTmpCat['field_item_id'],
1211
                                                $cryptedStuff['objectKey'],
1212
                                                $SETTINGS
1213
                                            );
1214
                                        } else {
1215
                                            $encrypt['string'] = $field['value'];
1216
                                            $encrypt['type'] = 'not_set';
1217
                                        }
1218
1219
                                        // update value
1220
                                        DB::update(
1221
                                            prefixTable('categories_items'),
1222
                                            array(
1223
                                                'data' => $encrypt['string'],
1224
                                                'data_iv' => '',
1225
                                                'encryption_type' => $encrypt['type'],
1226
                                            ),
1227
                                            'item_id = %i AND field_id = %i',
1228
                                            $post_item_id,
1229
                                            $field['id']
1230
                                        );
1231
1232
                                        // update LOG
1233
                                        logItems(
1234
                                            $SETTINGS,
1235
                                            $post_item_id,
1236
                                            $post_label,
1237
                                            $_SESSION['user_id'],
1238
                                            'at_modification',
1239
                                            $_SESSION['login'],
1240
                                            'at_field : '.$dataTmpCat['title'].' => '.$oldVal
1241
                                        );
1242
                                    }
1243
                                }
1244
                            } else {
1245
                                if (empty($field_data[1]) === true) {
1246
                                    DB::delete(
1247
                                        prefixTable('categories_items'),
1248
                                        'item_id = %i AND field_id = %s',
1249
                                        $post_item_id,
1250
                                        $field['id']
1251
                                    );
1252
                                }
1253
                            }
1254
                        }
1255
                    }
1256
1257
                    // If template enable, is there a main one selected?
1258
                    if (isset($SETTINGS['item_creation_templates']) === true
1259
                        && $SETTINGS['item_creation_templates'] === '1'
1260
                        && isset($post_template_id) === true
1261
                    ) {
1262
                        DB::queryFirstRow(
1263
                            'SELECT *
1264
                            FROM '.prefixTable('templates').'
1265
                            WHERE item_id = %i',
1266
                            $post_item_id
1267
                        );
1268
                        if (DB::count() === 0 && empty($post_template_id) === false) {
1269
                            // store field text
1270
                            DB::insert(
1271
                                prefixTable('templates'),
1272
                                array(
1273
                                    'item_id' => $post_item_id,
1274
                                    'category_id' => $post_template_id,
1275
                                )
1276
                            );
1277
                        } else {
1278
                            // Delete if empty
1279
                            if (empty($post_template_id) === true) {
1280
                                DB::delete(
1281
                                    prefixTable('templates'),
1282
                                    'item_id = %i',
1283
                                    $post_item_id
1284
                                );
1285
                            } else {
1286
                                // Update value
1287
                                DB::update(
1288
                                    prefixTable('templates'),
1289
                                    array(
1290
                                        'category_id' => $post_template_id,
1291
                                    ),
1292
                                    'item_id = %i',
1293
                                    $post_item_id
1294
                                );
1295
                            }
1296
                        }
1297
                    }
1298
1299
                    // Update automatic deletion - Only by the creator of the Item
1300
                    if (isset($SETTINGS['enable_delete_after_consultation']) === true
1301
                        && (int) $SETTINGS['enable_delete_after_consultation'] === 1
1302
                    ) {
1303
                        // check if elem exists in Table. If not add it or update it.
1304
                        DB::query(
1305
                            'SELECT *
1306
                            FROM '.prefixTable('automatic_del').'
1307
                            WHERE item_id = %i',
1308
                            $post_item_id
1309
                        );
1310
1311
                        if (DB::count() === 0) {
1312
                            // No automatic deletion for this item
1313
                            if (empty($post_to_be_deleted_after_date) === false
1314
                                || (int) $post_to_be_deleted_after_x_views > 0
1315
                            ) {
1316
                                // Automatic deletion to be added
1317
                                DB::insert(
1318
                                    prefixTable('automatic_del'),
1319
                                    array(
1320
                                        'item_id' => $post_item_id,
1321
                                        'del_enabled' => 1,
1322
                                        'del_type' => empty($post_to_be_deleted_after_x_views) === false ?
1323
                                            1 : 2, //1 = numeric : 2 = date
1324
                                        'del_value' => empty($post_to_be_deleted_after_x_views) === false ?
1325
                                            (int) $post_to_be_deleted_after_x_views :
1326
                                            dateToStamp($post_to_be_deleted_after_date, $SETTINGS),
1327
                                        )
1328
                                );
1329
                                // update LOG
1330
                                logItems(
1331
                                    $SETTINGS,
1332
                                    $post_item_id,
1333
                                    $post_label,
1334
                                    $_SESSION['user_id'],
1335
                                    'at_modification',
1336
                                    $_SESSION['login'],
1337
                                    'at_automatic_del : enabled'
1338
                                );
1339
                            }
1340
                        } else {
1341
                            // Automatic deletion exists for this item
1342
                            if (empty($post_to_be_deleted_after_date) === false
1343
                                || (int) $post_to_be_deleted_after_x_views > 0
1344
                            ) {
1345
                                // Update automatic deletion
1346
                                DB::update(
1347
                                    prefixTable('automatic_del'),
1348
                                    array(
1349
                                        'del_type' => empty($post_to_be_deleted_after_x_views) === false ?
1350
                                            1 : 2, //1 = numeric : 2 = date
1351
                                        'del_value' => empty($post_to_be_deleted_after_x_views) === false ?
1352
                                            $post_to_be_deleted_after_x_views :
1353
                                            dateToStamp($post_to_be_deleted_after_date, $SETTINGS),
1354
                                        ),
1355
                                    'item_id = %i',
1356
                                    $post_item_id
1357
                                );
1358
                            } else {
1359
                                // delete automatic deleteion for this item
1360
                                DB::delete(
1361
                                    prefixTable('automatic_del'),
1362
                                    'item_id = %i',
1363
                                    $post_item_id
1364
                                );
1365
1366
                                // update LOG
1367
                                logItems(
1368
                                    $SETTINGS,
1369
                                    $post_item_id,
1370
                                    $post_label,
1371
                                    $_SESSION['user_id'],
1372
                                    'at_modification2',
1373
                                    $_SESSION['login'],
1374
                                    'at_automatic_del : disabled'
1375
                                );
1376
                            }
1377
                        }
1378
                    }
1379
1380
                    // get readable list of restriction
1381
                    $listOfRestricted = $oldRestrictionList = '';
1382
                    $arrayOfUsersRestriction = array();
1383
                    $arrayOfUsersIdRestriction = array();
1384
                    $diffUsersRestiction = array();
1385
                    $diffRolesRestiction = array();
1386
                    if (is_array($post_restricted_to) === true
1387
                        && count($post_restricted_to) > 0
1388
                        && isset($SETTINGS['restricted_to']) === true
1389
                        && $SETTINGS['restricted_to'] === '1'
1390
                    ) {
1391
                        foreach ($post_restricted_to as $userId) {
1392
                            if (empty($userId) === false) {
1393
                                $dataTmp = DB::queryfirstrow(
1394
                                    'SELECT id, name, lastname
1395
                                    FROM '.prefixTable('users').'
1396
                                    WHERE id= %i',
1397
                                    $userId
1398
                                );
1399
1400
                                // Add to array
1401
                                array_push(
1402
                                    $arrayOfUsersRestriction,
1403
                                    $dataTmp['name'].' '.$dataTmp['lastname']
1404
                                );
1405
                                array_push(
1406
                                    $arrayOfUsersIdRestriction,
1407
                                    $dataTmp['id']
1408
                                );
1409
                            }
1410
                        }
1411
                    }
1412
                    if ((int) $SETTINGS['restricted_to'] === 1) {
1413
                        $diffUsersRestiction = array_diff(
1414
                            empty($data['restricted_to']) === false ?
1415
                                explode(';', $data['restricted_to']) :
1416
                                array(),
1417
                            $arrayOfUsersIdRestriction
1418
                        );
1419
                    }
1420
1421
                    // Manage retriction_to_roles
1422
                    if (is_array($post_restricted_to_roles) === true
1423
                        && count($post_restricted_to_roles) > 0
1424
                        && isset($SETTINGS['restricted_to_roles']) === true
1425
                        && (int) $SETTINGS['restricted_to_roles'] === 1
1426
                    ) {
1427
                        // Init
1428
                        $arrayOfRestrictionRolesOld = array();
1429
                        $arrayOfRestrictionRoles = array();
1430
1431
                        // get values before deleting them
1432
                        $rows = DB::query(
1433
                            'SELECT t.title, t.id AS id
1434
                            FROM '.prefixTable('roles_title').' as t
1435
                            INNER JOIN '.prefixTable('restriction_to_roles').' as r ON (t.id=r.role_id)
1436
                            WHERE r.item_id = %i
1437
                            ORDER BY t.title ASC',
1438
                            $post_item_id
1439
                        );
1440
                        foreach ($rows as $record) {
1441
                            // Add to array
1442
                            array_push(
1443
                                $arrayOfRestrictionRolesOld,
1444
                                $record['title']
1445
                            );
1446
                        }
1447
                        // delete previous values
1448
                        DB::delete(
1449
                            prefixTable('restriction_to_roles'),
1450
                            'item_id = %i',
1451
                            $post_item_id
1452
                        );
1453
1454
                        // add roles for item
1455
                        if (is_array($post_restricted_to_roles) === true
1456
                            && count($post_restricted_to_roles) > 0
1457
                        ) {
1458
                            foreach ($post_restricted_to_roles as $role) {
1459
                                DB::insert(
1460
                                    prefixTable('restriction_to_roles'),
1461
                                    array(
1462
                                        'role_id' => $role,
1463
                                        'item_id' => $post_item_id,
1464
                                        )
1465
                                );
1466
                                $dataTmp = DB::queryfirstrow(
1467
                                    'SELECT title
1468
                                    FROM '.prefixTable('roles_title').'
1469
                                    WHERE id = %i',
1470
                                    $role
1471
                                );
1472
1473
                                // Add to array
1474
                                array_push(
1475
                                    $arrayOfRestrictionRoles,
1476
                                    $dataTmp['title']
1477
                                );
1478
                            }
1479
1480
                            if ((int) $SETTINGS['restricted_to'] === 1) {
1481
                                $diffRolesRestiction = array_diff(
1482
                                    $arrayOfRestrictionRoles,
1483
                                    $arrayOfRestrictionRolesOld
1484
                                );
1485
                            }
1486
                        }
1487
                    }
1488
                    // Update CACHE table
1489
                    updateCacheTable('update_value', $SETTINGS, $post_item_id);
1490
1491
                    //---- Log all modifications done ----
1492
1493
                    // RESTRICTIONS
1494
                    if (count($diffRolesRestiction) > 0 || count($diffUsersRestiction) > 0) {
1495
                        logItems(
1496
                            $SETTINGS,
1497
                            $post_item_id,
1498
                            $post_label,
1499
                            $_SESSION['user_id'],
1500
                            'at_modification',
1501
                            $_SESSION['login'],
1502
                            'at_restriction : '.
1503
                                (count($diffUsersRestiction) > 0 ?
1504
                                    implode(', ', $arrayOfUsersRestriction).
1505
                                    (count($diffRolesRestiction) > 0 ? ', ' : '') :
1506
                                    ''
1507
                                ).(count($diffRolesRestiction) > 0 ? implode(', ', $arrayOfRestrictionRoles) : '')
1508
                        );
1509
                    }
1510
1511
                    // LABEL
1512
                    if ($data['label'] !== $post_label) {
1513
                        logItems(
1514
                            $SETTINGS,
1515
                            $post_item_id,
1516
                            $post_label,
1517
                            $_SESSION['user_id'],
1518
                            'at_modification',
1519
                            $_SESSION['login'],
1520
                            'at_label : '.$data['label'].' => '.$post_label
1521
                        );
1522
                    }
1523
                    // LOGIN
1524
                    if ($data['login'] !== $post_login) {
1525
                        logItems(
1526
                            $SETTINGS,
1527
                            $post_item_id,
1528
                            $post_label,
1529
                            $_SESSION['user_id'],
1530
                            'at_modification',
1531
                            $_SESSION['login'],
1532
                            'at_login : '.$data['login'].' => '.$post_login
1533
                        );
1534
                    }
1535
                    // EMAIL
1536
                    if (strcmp($data['email'], $post_email) !== 0) {
1537
                        logItems(
1538
                            $SETTINGS,
1539
                            $post_item_id,
1540
                            $post_label,
1541
                            $_SESSION['user_id'],
1542
                            'at_modification',
1543
                            $_SESSION['login'],
1544
                            'at_email : '.$data['email'].' => '.$post_email
1545
                        );
1546
                    }
1547
                    // URL
1548
                    if ($data['url'] !== $post_url && $post_url !== 'http://') {
1549
                        logItems(
1550
                            $SETTINGS,
1551
                            $post_item_id,
1552
                            $post_label,
1553
                            $_SESSION['user_id'],
1554
                            'at_modification',
1555
                            $_SESSION['login'],
1556
                            'at_url : '.$data['url'].' => '.$post_url
1557
                        );
1558
                    }
1559
                    // DESCRIPTION
1560
                    if (strcmp(md5($data['description']), md5($post_description)) !== 0) {
1561
                        logItems(
1562
                            $SETTINGS,
1563
                            $post_item_id,
1564
                            $post_label,
1565
                            $_SESSION['user_id'],
1566
                            'at_modification',
1567
                            $_SESSION['login'],
1568
                            'at_description'
1569
                        );
1570
                    }
1571
                    // FOLDER
1572
                    if ($data['id_tree'] !== $post_folder_id) {
1573
                        // Get name of folders
1574
                        $dataTmp = DB::query('SELECT title FROM '.prefixTable('nested_tree').' WHERE id IN %li', array($data['id_tree'], $post_folder_id));
1575
1576
                        logItems(
1577
                            $SETTINGS,
1578
                            $post_item_id,
1579
                            $post_label,
1580
                            $_SESSION['user_id'],
1581
                            'at_modification',
1582
                            $_SESSION['login'],
1583
                            'at_category : '.$dataTmp[0]['title'].' => '.$dataTmp[1]['title']
1584
                        );
1585
                        // ask for page reloading
1586
                        $reloadPage = true;
1587
                    }
1588
                    // ANYONE_CAN_MODIFY
1589
                    if ($post_anyone_can_modify !== $data['anyone_can_modify']) {
1590
                        logItems(
1591
                            $SETTINGS,
1592
                            $post_item_id,
1593
                            $post_label,
1594
                            $_SESSION['user_id'],
1595
                            'at_modification',
1596
                            $_SESSION['login'],
1597
                            'at_anyoneconmodify : '.((int) $post_anyone_can_modify === 0 ? 'disabled' : 'enabled')
1598
                        );
1599
                    }
1600
1601
                    // Reload new values
1602
                    $dataItem = DB::queryfirstrow(
1603
                        'SELECT *
1604
                        FROM '.prefixTable('items').' as i
1605
                        INNER JOIN '.prefixTable('log_items').' as l ON (l.id_item = i.id)
1606
                        WHERE i.id = %i AND l.action = %s',
1607
                        $post_item_id,
1608
                        'at_creation'
1609
                    );
1610
                    // Reload History
1611
                    $history = '';
1612
                    $rows = DB::query(
1613
                        'SELECT l.date as date, l.action as action, l.raison as raison, u.login as login
1614
                        FROM '.prefixTable('log_items').' as l
1615
                        LEFT JOIN '.prefixTable('users').' as u ON (l.id_user=u.id)
1616
                        WHERE l.action <> %s AND id_item=%s',
1617
                        'at_shown',
1618
                        $post_item_id
1619
                    );
1620
                    foreach ($rows as $record) {
1621
                        $reason = explode(':', $record['raison']);
1622
                        if (count($reason) > 0) {
1623
                            $sentence = date($SETTINGS['date_format'].' '.$SETTINGS['time_format'], $record['date']).' - '
1624
                                .$record['login'].' - '.langHdl($record['action']).' - '
1625
                                .(empty($record['raison']) === false ?
1626
                                (count($reason) > 1 ? langHdl(trim($reason[0])).' : '.$reason[1]
1627
                                : langHdl(trim($reason[0]))) : '');
1628
                            if (empty($history)) {
1629
                                $history = $sentence;
1630
                            } else {
1631
                                $history .= '<br />'.$sentence;
1632
                            }
1633
                        }
1634
                    }
1635
1636
                    // TODO
1637
                    // decrypt PW
1638
                    if (empty($dataReceived['salt_key'])) {
1639
                        $encrypt = cryption(
1640
                            $dataItem['pw'],
1641
                            '',
1642
                            'encrypt',
1643
                            $SETTINGS
1644
                        );
1645
                    } else {
1646
                        $encrypt = cryption(
1647
                            $dataItem['pw'],
1648
                            $_SESSION['user_settings']['session_psk'],
1649
                            'encrypt',
1650
                            $SETTINGS
1651
                        );
1652
                    }
1653
1654
                    $pw = cleanString($encrypt['string']);
1655
                    // generate 2d key
1656
                    $_SESSION['key_tmp'] = bin2hex(GenerateCryptKey(16));
1657
1658
                    // Prepare files listing
1659
                    $files = $filesEdit = '';
1660
                    // launch query
1661
                    $rows = DB::query('SELECT id, name, file, extension FROM '.prefixTable('files').' WHERE id_item=%i', $post_item_id);
1662
                    foreach ($rows as $record) {
1663
                        // get icon image depending on file format
1664
                        $iconImage = fileFormatImage($record['extension']);
1665
1666
                        // If file is an image, then prepare lightbox. If not image, then prepare donwload
1667
                        if (in_array($record['extension'], TP_IMAGE_FILE_EXT)) {
1668
                            $files .= '<i class=\'fa fa-file-image-o\' /></i>&nbsp;<a class="image_dialog" href="#'.$record['id'].'" title="'.$record['name'].'">'.$record['name'].'</a><br />';
1669
                        } else {
1670
                            $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 />';
1671
                        }
1672
                        // Prepare list of files for edit dialogbox
1673
                        $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 />';
1674
                    }
1675
                    // Send email
1676
                    if (is_array($post_diffusion_list) === true && count($post_diffusion_list) > 0) {
1677
                        foreach (explode(';', $dataReceived['diffusion']) as $emailAddress) {
1678
                            if (empty($emailAddress) === false) {
1679
                                sendEmail(
1680
                                    langHdl('email_subject_item_updated'),
1681
                                    str_replace(
1682
                                        array('#item_label#', '#item_category#', '#item_id#', '#url#'),
1683
                                        array($post_label, $dataReceived['categorie'], $post_item_id, $SETTINGS['cpassman_url']),
1684
                                        langHdl('email_body_item_updated')
1685
                                    ),
1686
                                    $emailAddress,
1687
                                    $SETTINGS,
1688
                                    str_replace('#item_label#', $post_label, langHdl('email_bodyalt_item_updated'))
1689
                                );
1690
                            }
1691
                        }
1692
                    }
1693
1694
                    // send email to user that what to be notified
1695
                    $notification = DB::queryOneColumn(
1696
                        'email',
1697
                        'SELECT *
1698
                        FROM '.prefixTable('notification').' AS n
1699
                        INNER JOIN '.prefixTable('users').' AS u ON (n.user_id = u.id)
1700
                        WHERE n.item_id = %i AND n.user_id != %i',
1701
                        $post_item_id,
1702
                        $_SESSION['user_id']
1703
                    );
1704
1705
                    if (DB::count() > 0) {
1706
                        // Get name of folders
1707
                        $dataTmp = DB::queryFirstRow(
1708
                            'SELECT title 
1709
                            FROM '.prefixTable('nested_tree').' 
1710
                            WHERE id = %i',
1711
                            $post_folder_id
1712
                        );
1713
1714
                        // send email
1715
                        DB::insert(
1716
                            prefixTable('emails'),
1717
                            array(
1718
                                'timestamp' => time(),
1719
                                'subject' => langHdl('email_subject_item_updated'),
1720
                                'body' => str_replace(
1721
                                    array('#item_label#', '#folder_name#', '#item_id#', '#url#', '#name#', '#lastname#'),
1722
                                    array($post_label, $dataTmp['title'], $post_item_id, $SETTINGS['cpassman_url'], $_SESSION['name'], $_SESSION['lastname']),
1723
                                    langHdl('email_body_item_updated')
1724
                                ),
1725
                                'receivers' => implode(',', $notification),
1726
                                'status' => '',
1727
                            )
1728
                        );
1729
                    }
1730
1731
                    // Prepare some stuff to return
1732
                    $arrData = array(
1733
                        'error' => false,
1734
                        'message' => '',
1735
                        );
1736
                } else {
1737
                    echo prepareExchangedData(
1738
                        array(
1739
                            'error' => true,
1740
                            'message' => langHdl('error_not_allowed_to_edit_item'),
1741
                            'toto' => '1',
1742
                        ),
1743
                        'encode'
1744
                    );
1745
                    break;
1746
                }
1747
            } else {
1748
                // an error appears on JSON format
1749
                $arrData = array(
1750
                    'error' => true,
1751
                    'message' => 'ERR_JSON_FORMAT',
1752
                );
1753
            }
1754
            // return data
1755
            echo prepareExchangedData($arrData, 'encode');
1756
            break;
1757
1758
        /*
1759
          * CASE
1760
          * Copy an Item
1761
        */
1762
        case 'copy_item':
1763
            // Check KEY and rights
1764
            if ($post_key !== $_SESSION['key']) {
1765
                echo prepareExchangedData(
1766
                    array(
1767
                        'error' => true,
1768
                        'message' => langHdl('key_is_not_correct'),
1769
                    ),
1770
                    'encode'
1771
                );
1772
                break;
1773
            } elseif ($_SESSION['user_read_only'] === true) {
1774
                echo prepareExchangedData(
1775
                    array(
1776
                        'error' => true,
1777
                        'message' => langHdl('error_not_allowed_to'),
1778
                    ),
1779
                    'encode'
1780
                );
1781
                break;
1782
            }
1783
1784
            // decrypt and retreive data in JSON format
1785
            $dataReceived = prepareExchangedData(
1786
                $post_data,
1787
                'decode'
1788
            );
1789
1790
            // Prepare POST variables
1791
            $post_new_label = filter_var($dataReceived['new_label'], FILTER_SANITIZE_STRING);
1792
            $post_source_id = filter_var($dataReceived['source_id'], FILTER_SANITIZE_NUMBER_INT);
1793
            $post_dest_id = filter_var($dataReceived['dest_id'], FILTER_SANITIZE_NUMBER_INT);
1794
            $post_item_id = filter_var($dataReceived['item_id'], FILTER_SANITIZE_NUMBER_INT);
1795
1796
            // perform a check in case of Read-Only user creating an item in his PF
1797
            if ((int) $_SESSION['user_read_only'] === 1
1798
                && (in_array($post_source_id, $_SESSION['personal_folders']) === false
1799
                    || in_array($post_dest_id, $_SESSION['personal_folders']) === false)
1800
            ) {
1801
                echo prepareExchangedData(
1802
                    array(
1803
                        'error' => true,
1804
                        'message' => langHdl('error_not_allowed_to'),
1805
                    ),
1806
                    'encode'
1807
                );
1808
                break;
1809
            }
1810
1811
            // Init
1812
            $returnValues = '';
1813
            $pw = '';
1814
            $is_perso = 0;
1815
1816
            if (empty($post_item_id) === false
1817
                && empty($post_dest_id) === false
1818
            ) {
1819
                // load the original record into an array
1820
                $originalRecord = DB::queryfirstrow(
1821
                    'SELECT * FROM '.prefixTable('items').'
1822
                    WHERE id = %i',
1823
                    $post_item_id
1824
                );
1825
1826
                // Check if the folder where this item is accessible to the user
1827
                if (in_array($originalRecord['id_tree'], $_SESSION['groupes_visibles']) === false) {
1828
                    echo prepareExchangedData(
1829
                        array(
1830
                            'error' => true,
1831
                            'message' => langHdl('error_not_allowed_to'),
1832
                        ),
1833
                        'encode'
1834
                    );
1835
                    break;
1836
                }
1837
1838
                // Load the destination folder record into an array
1839
                $dataDestination = DB::queryfirstrow(
1840
                    'SELECT personal_folder FROM '.prefixTable('nested_tree').'
1841
                    WHERE id = %i',
1842
                    $post_dest_id
1843
                );
1844
1845
                // Get the ITEM object key for the user
1846
                $userKey = DB::queryFirstRow(
1847
                    'SELECT share_key
1848
                    FROM '.prefixTable('sharekeys_items').'
1849
                    WHERE user_id = %i AND object_id = %i',
1850
                    $_SESSION['user_id'],
1851
                    $post_item_id
1852
                );
1853
                if (DB::count() === 0) {
1854
                    // ERROR - No sharekey found for this item and user
1855
                    echo prepareExchangedData(
1856
                        array(
1857
                            'error' => true,
1858
                            'message' => langHdl('error_not_allowed_to'),
1859
                        ),
1860
                        'encode'
1861
                    );
1862
                    break;
1863
                }
1864
1865
                // Decrypt / Encrypt the password
1866
                $cryptedStuff = doDataEncryption(
1867
                    base64_decode(
1868
                        doDataDecryption(
1869
                            $originalRecord['pw'],
1870
                            decryptUserObjectKey(
1871
                                $userKey['share_key'],
1872
                                $_SESSION['user']['private_key']
1873
                            )
1874
                        )
1875
                    )
1876
                );
1877
                // reaffect pw
1878
                $originalRecord['pw'] = $cryptedStuff['encrypted'];
1879
1880
                // generate the query to update the new record with the previous values
1881
                $aSet = array();
1882
                foreach ($originalRecord as $key => $value) {
1883
                    if ($key === 'id_tree') {
1884
                        $aSet['id_tree'] = $post_dest_id;
1885
                    } elseif ($key === 'label') {
1886
                        $aSet[$key] = $post_new_label;
1887
                    } elseif ($key === 'viewed_no') {
1888
                        $aSet['viewed_no'] = '0';
1889
                    } elseif ($key === 'pw' && empty($pw) === false) {
1890
                        $aSet['pw'] = $originalRecord['pw'];
1891
                        $aSet['pw_iv'] = '';
1892
                    } elseif ($key === 'perso') {
1893
                        $aSet['perso'] = $is_perso;
1894
                    } elseif ($key != 'id' && $key != 'key') {
1895
                        $aSet[$key] = $value;
1896
                    }
1897
                }
1898
1899
                // insert the new record and get the new auto_increment id
1900
                DB::insert(
1901
                    prefixTable('items'),
1902
                    $aSet
1903
                );
1904
                $newItemId = DB::insertId();
1905
1906
                // Create sharekeys for users of this new ITEM
1907
                storeUsersShareKey(
1908
                    prefixTable('sharekeys_items'),
1909
                    $dataDestination['personal_folder'],
1910
                    $post_dest_id,
1911
                    $newItemId,
1912
                    $cryptedStuff['objectKey'],
1913
                    $SETTINGS
1914
                );
1915
1916
                // --------------------
1917
                // Manage Custom Fields
1918
                $rows = DB::query(
1919
                    'SELECT *
1920
                    FROM '.prefixTable('categories_items').'
1921
                    WHERE item_id = %i',
1922
                    $post_item_id
1923
                );
1924
                foreach ($rows as $field) {
1925
                    // Create the entry for the new item
1926
1927
                    // Is the data encrypted
1928
                    if ((int) $field['encryption_type'] === TP_ENCRYPTION_NAME) {
1929
                        $cryptedStuff = doDataEncryption($field['value']);
1930
                    }
1931
1932
                    // store field text
1933
                    DB::insert(
1934
                        prefixTable('categories_items'),
1935
                        array(
1936
                            'item_id' => $newItemId,
1937
                            'field_id' => $field['field_id'],
1938
                            'data' => (int) $field['encryption_type'] === TP_ENCRYPTION_NAME ?
1939
                                $cryptedStuff['encrypted'] :
1940
                                $field['value'],
1941
                            'data_iv' => '',
1942
                            'encryption_type' => (int) $field['encryption_type'] === TP_ENCRYPTION_NAME ?
1943
                                TP_ENCRYPTION_NAME :
1944
                                'not_set',
1945
                        )
1946
                    );
1947
                    $newFieldId = DB::insertId();
1948
1949
                    // Create sharekeys for users
1950
                    if ((int) $field['encryption_type'] === TP_ENCRYPTION_NAME) {
1951
                        storeUsersShareKey(
1952
                            prefixTable('sharekeys_fields'),
1953
                            $dataDestination['personal_folder'],
1954
                            $post_dest_id,
1955
                            $newFieldId,
1956
                            $cryptedStuff['objectKey'],
1957
                            $SETTINGS
1958
                        );
1959
                    }
1960
                }
1961
                // <---
1962
1963
                // ------------------
1964
                // Manage attachments
1965
1966
                // get file key
1967
                $rows = DB::query(
1968
                    'SELECT f.id AS id, f.file AS file, f.name AS name, f.status AS status, f.extension AS extension,
1969
                    f.size AS size, f.type AS type, s.share_key AS share_key
1970
                    FROM '.prefixTable('files').' AS f
1971
                    INNER JOIN '.prefixTable('sharekeys_files').' AS s ON (f.id = s.object_id)
1972
                    WHERE s.user_id = %i AND f.id_item = %i',
1973
                    $_SESSION['user_id'],
1974
                    $post_item_id
1975
                );
1976
                foreach ($rows as $record) {
1977
                    // Check if file still exists
1978
                    if (file_exists($SETTINGS['path_to_upload_folder'].DIRECTORY_SEPARATOR.TP_FILE_PREFIX.base64_decode($record['file'])) === true) {
1979
                        // Step1 - decrypt the file
1980
                        $fileContent = decryptFile(
1981
                            $record['file'],
1982
                            $SETTINGS['path_to_upload_folder'],
1983
                            decryptUserObjectKey($record['share_key'], $_SESSION['user']['private_key'])
1984
                        );
1985
1986
                        // Step2 - create file
1987
                        $newFileName = md5(time().'_'.$record['id']).'.'.$record['extension'];
1988
                        fwrite(
1989
                            fopen($SETTINGS['path_to_upload_folder'].DIRECTORY_SEPARATOR.$newFileName, 'ab'),
1990
                            base64_decode($fileContent)
1991
                        );
1992
1993
                        // Step3 - encrypt the file
1994
                        $newFile = encryptFile($newFileName, $SETTINGS['path_to_upload_folder']);
1995
1996
                        // Step4 - store in database
1997
                        DB::insert(
1998
                            prefixTable('files'),
1999
                            array(
2000
                                'id_item' => $newItemId,
2001
                                'name' => $record['name'],
2002
                                'size' => $record['size'],
2003
                                'extension' => $record['extension'],
2004
                                'type' => $record['type'],
2005
                                'file' => $newFile['fileHash'],
2006
                                'status' => TP_ENCRYPTION_NAME,
2007
                                'confirmed' => 1,
2008
                            )
2009
                        );
2010
                        $newFileId = DB::insertId();
2011
2012
                        // Step5 - create sharekeys
2013
                        storeUsersShareKey(
2014
                            prefixTable('sharekeys_files'),
2015
                            $dataDestination['personal_folder'],
2016
                            $post_dest_id,
2017
                            $newFileId,
2018
                            $newFile['objectKey'],
2019
                            $SETTINGS
2020
                        );
2021
                    }
2022
                }
2023
                // <---
2024
2025
                // -------------------------
2026
                // Add specific restrictions
2027
                $rows = DB::query('SELECT * FROM '.prefixTable('restriction_to_roles').' WHERE item_id = %i', $post_item_id);
2028
                foreach ($rows as $record) {
2029
                    DB::insert(
2030
                        prefixTable('restriction_to_roles'),
2031
                        array(
2032
                            'item_id' => $newItemId,
2033
                            'role_id' => $record['role_id'],
2034
                            )
2035
                    );
2036
                }
2037
2038
                // Add Tags
2039
                $rows = DB::query('SELECT * FROM '.prefixTable('tags').' WHERE item_id = %i', $post_item_id);
2040
                foreach ($rows as $record) {
2041
                    DB::insert(
2042
                        prefixTable('tags'),
2043
                        array(
2044
                            'item_id' => $newItemId,
2045
                            'tag' => $record['tag'],
2046
                            )
2047
                    );
2048
                }
2049
2050
                // Add this duplicate in logs
2051
                logItems(
2052
                    $SETTINGS,
2053
                    $newItemId,
2054
                    $originalRecord['label'],
2055
                    $_SESSION['user_id'],
2056
                    'at_creation',
2057
                    $_SESSION['login']
2058
                );
2059
                // Add the fact that item has been copied in logs
2060
                logItems(
2061
                    $SETTINGS,
2062
                    $newItemId,
2063
                    $originalRecord['label'],
2064
                    $_SESSION['user_id'],
2065
                    'at_copy',
2066
                    $_SESSION['login']
2067
                );
2068
                // reload cache table
2069
                include_once $SETTINGS['cpassman_dir'].'/sources/main.functions.php';
2070
                updateCacheTable('reload', $SETTINGS, '');
2071
2072
                $returnValues = '[{"error" : ""} , {"status" : "ok"}, {"new_id" : "'.$newItemId.'"}]';
2073
            } else {
2074
                // no item
2075
                $returnValues = '[{"error" : "no_item"}, {"error_text" : "No item ID"}]';
2076
            }
2077
            // return data
2078
            echo $returnValues;
2079
            break;
2080
2081
        /*
2082
          * CASE
2083
          * Display informations of selected item
2084
        */
2085
        case 'show_details_item':
2086
            // Check KEY and rights
2087
            if ($post_key !== $_SESSION['key']) {
2088
                echo prepareExchangedData(
2089
                    array(
2090
                        'error' => true,
2091
                        'message' => langHdl('key_is_not_correct'),
2092
                    ),
2093
                    'encode'
2094
                );
2095
                break;
2096
            }
2097
2098
            // Step #1
2099
            $_SESSION['user_settings']['show_step2'] = false;
2100
2101
            // Decrypt and retreive data in JSON format
2102
            $dataReceived = prepareExchangedData($post_data, 'decode');
2103
2104
            // Init post variables
2105
            $post_id = filter_var(($dataReceived['id']), FILTER_SANITIZE_NUMBER_INT);
2106
            $post_folder_id = filter_var(($dataReceived['folder_id']), FILTER_SANITIZE_NUMBER_INT);
2107
            $post_salt_key_required = filter_var(($dataReceived['salt_key_required']), FILTER_SANITIZE_STRING);
2108
            $post_salt_key_set = isset($_SESSION['user_settings']['session_psk']) === true
2109
                && empty($_SESSION['user_settings']['session_psk']) === false ? '1' : '0';
2110
            $post_expired_item = filter_var(($dataReceived['expired_item']), FILTER_SANITIZE_STRING);
2111
            $post_restricted = filter_var(($dataReceived['restricted']), FILTER_SANITIZE_STRING);
2112
            $post_page = filter_var(($dataReceived['page']), FILTER_SANITIZE_STRING);
2113
            $post_folder_access_level = isset($dataReceived['folder_access_level']) === true ?
2114
                filter_var(($dataReceived['folder_access_level']), FILTER_SANITIZE_STRING)
2115
                :
2116
                '';
2117
2118
            $arrData = array();
2119
            // return ID
2120
            $arrData['id'] = (int) $post_id;
2121
            $arrData['id_user'] = API_USER_ID;
2122
            $arrData['author'] = 'API';
2123
2124
            // Check if item is deleted
2125
            // taking into account that item can be restored.
2126
            // so if restoration timestamp is higher than the deletion one
2127
            // then we can show it
2128
            $item_deleted = DB::queryFirstRow(
2129
                'SELECT *
2130
                FROM '.prefixTable('log_items').'
2131
                WHERE id_item = %i AND action = %s
2132
                ORDER BY date DESC
2133
                LIMIT 0, 1',
2134
                $post_id,
2135
                'at_delete'
2136
            );
2137
            $dataDeleted = DB::count();
2138
2139
            $item_restored = DB::queryFirstRow(
2140
                'SELECT *
2141
                FROM '.prefixTable('log_items').'
2142
                WHERE id_item = %i AND action = %s
2143
                ORDER BY date DESC
2144
                LIMIT 0, 1',
2145
                $post_id,
2146
                'at_restored'
2147
            );
2148
2149
            if ($dataDeleted != 0 && intval($item_deleted['date']) > intval($item_restored['date'])) {
2150
                // This item is deleted => exit
2151
                echo prepareExchangedData(
2152
                    array(
2153
                        'error' => true,
2154
                        'message' => langHdl('not_allowed_to_see_pw'),
2155
                        'show_detail_option' => 2,
2156
                    ),
2157
                    'encode'
2158
                );
2159
                break;
2160
            }
2161
2162
            // Get all informations for this item
2163
            $dataItem = DB::queryfirstrow(
2164
                'SELECT *
2165
                FROM '.prefixTable('items').' as i
2166
                INNER JOIN '.prefixTable('log_items').' as l ON (l.id_item = i.id)
2167
                WHERE i.id = %i AND l.action = %s',
2168
                $post_id,
2169
                'at_creation'
2170
            );
2171
2172
            // Notification
2173
            DB::queryfirstrow(
2174
                'SELECT *
2175
                FROM '.prefixTable('notification').'
2176
                WHERE item_id = %i AND user_id = %i',
2177
                $post_id,
2178
                $_SESSION['user_id']
2179
            );
2180
            if (DB::count() > 0) {
2181
                $arrData['notification_status'] = true;
2182
            } else {
2183
                $arrData['notification_status'] = false;
2184
            }
2185
2186
            // Get all USERS infos
2187
            $listRest = array_filter(explode(';', $dataItem['restricted_to']));
2188
            $_SESSION['listNotificationEmails'] = '';
2189
            $listeRestriction = array();
2190
2191
            $user_in_restricted_list_of_item = false;
2192
            $rows = DB::query(
2193
                'SELECT id, login, email, admin, name, lastname
2194
                FROM '.prefixTable('users')
2195
            );
2196
            foreach ($rows as $user) {
2197
                // Get auhtor
2198
                if ($user['id'] === $dataItem['id_user']) {
2199
                    $arrData['author'] = $user['login'];
2200
                    $arrData['author_email'] = $user['email'];
2201
                    $arrData['id_user'] = (int) $dataItem['id_user'];
2202
                }
2203
2204
                // Get restriction list for users
2205
                if (in_array($user['id'], $listRest) === true) {
2206
                    array_push($listeRestriction, $user['id']);
2207
                    if ($_SESSION['user_id'] === $user['id']) {
2208
                        $user_in_restricted_list_of_item = true;
2209
                    }
2210
                }
2211
                // Get notification list for users
2212
                /*if (in_array($user['id'], $arrData['notification_list']) === true) {
2213
                    $_SESSION['listNotificationEmails'] .= $user['email'].',';
2214
                }*/
2215
2216
                // Add Admins to notification list if expected
2217
                if (isset($SETTINGS['enable_email_notification_on_item_shown']) === true
2218
                    && $SETTINGS['enable_email_notification_on_item_shown'] === '1'
2219
                    && $user['admin'] === '1'
2220
                ) {
2221
                    $_SESSION['listNotificationEmails'] .= $user['email'].',';
2222
                }
2223
            }
2224
2225
            // manage case of API user
2226
            if ($dataItem['id_user'] === API_USER_ID) {
2227
                $arrData['author'] = 'API ['.$dataItem['description'].']';
2228
                $arrData['id_user'] = API_USER_ID;
2229
                $arrData['author_email'] = '';
2230
                $arrData['notification_status'] = false;
2231
            }
2232
2233
            // Get all tags for this item
2234
            $tags = array();
2235
            $rows = DB::query(
2236
                'SELECT tag
2237
                FROM '.prefixTable('tags').'
2238
                WHERE item_id = %i',
2239
                $post_id
2240
            );
2241
            foreach ($rows as $record) {
2242
                array_push($tags, $record['tag']);
2243
            }
2244
2245
            // TODO -> improve this check
2246
            // check that actual user can access this item
2247
            $restrictionActive = true;
2248
            $restrictedTo = array_filter(explode(';', $dataItem['restricted_to']));
2249
            if (in_array($_SESSION['user_id'], $restrictedTo) === true) {
2250
                $restrictionActive = false;
2251
            }
2252
            if (empty($dataItem['restricted_to'])) {
2253
                $restrictionActive = false;
2254
            }
2255
2256
            // Check if user has a role that is accepted
2257
            $rows_tmp = DB::query(
2258
                'SELECT role_id
2259
                FROM '.prefixTable('restriction_to_roles').'
2260
                WHERE item_id=%i',
2261
                $post_id
2262
            );
2263
            foreach ($rows_tmp as $rec_tmp) {
2264
                if (in_array($rec_tmp['role_id'], explode(';', $_SESSION['fonction_id']))) {
2265
                    $restrictionActive = false;
2266
                }
2267
            }
2268
2269
            // Uncrypt PW
2270
            // Get the object key for the user
2271
            $userKey = DB::queryFirstRow(
2272
                'SELECT share_key
2273
                FROM '.prefixTable('sharekeys_items').'
2274
                WHERE user_id = %i AND object_id = %i',
2275
                $_SESSION['user_id'],
2276
                $post_id
2277
            );
2278
            if (DB::count() === 0 || empty($dataItem['pw']) === true) {
2279
                // No share key found
2280
                $pw = '';
2281
            } else {
2282
                $pw = doDataDecryption(
2283
                    $dataItem['pw'],
2284
                    decryptUserObjectKey($userKey['share_key'], $_SESSION['user']['private_key'])
2285
                );
2286
            }
2287
2288
            // check if item is expired
2289
            if (null !== $post_expired_item
2290
                && $post_expired_item === '1'
2291
            ) {
2292
                $item_is_expired = true;
2293
            } else {
2294
                $item_is_expired = false;
2295
            }
2296
2297
           // echo $dataItem['id_tree']." ;; ";
2298
            //print_r($_SESSION['groupes_visibles']);
2299
2300
            // check user is admin
2301
            if ($_SESSION['user_admin'] === '1'
2302
                && $dataItem['perso'] != 1
2303
                && (null !== TP_ADMIN_FULL_RIGHT && TP_ADMIN_FULL_RIGHT === true)
2304
                || null === TP_ADMIN_FULL_RIGHT
2305
            ) {
2306
                $arrData['show_details'] = 0;
2307
            // Check if actual USER can see this ITEM
2308
            } elseif ((
2309
                (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)
2310
                ||
2311
                (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)
2312
                ||
2313
                (null !== $post_folder_id
2314
                    && isset($_SESSION['list_restricted_folders_for_items'][$post_folder_id])
2315
                    && in_array($post_id, $_SESSION['list_restricted_folders_for_items'][$post_folder_id])
2316
                    && $post_restricted === '1'
2317
                    && $user_in_restricted_list_of_item === true)
2318
                ||
2319
                (isset($SETTINGS['restricted_to_roles']) && $SETTINGS['restricted_to_roles'] === '1'
2320
                    && $restrictionActive === false
2321
                )
2322
            ) {
2323
                // Allow show details
2324
                $arrData['show_details'] = 1;
2325
2326
                // Regarding user's roles, what type of modification is allowed?
2327
                /*$rows = DB::query(
2328
                    'SELECT r.type
2329
                    FROM '.prefixTable('roles_values').' AS r
2330
                    WHERE r.folder_id = %i AND r.role_id IN %ls',
2331
                    $dataItem['id_tree'],
2332
                    $_SESSION['groupes_visibles']
2333
                );
2334
                foreach ($rows as $record) {
2335
                    // TODO
2336
                }*/
2337
2338
                // Display menu icon for deleting if user is allowed
2339
                if ($dataItem['id_user'] == $_SESSION['user_id']
2340
                    || (int) $_SESSION['is_admin'] === 1
2341
                    || ((int) $_SESSION['user_manager'] === 1 && (int) $SETTINGS['manager_edit'] === 1)
2342
                    || (int) $dataItem['anyone_can_modify'] === 1
2343
                    || in_array($dataItem['id_tree'], $_SESSION['list_folders_editable_by_role']) === true
2344
                    || in_array($_SESSION['user_id'], $restrictedTo) === true
2345
                    //|| count($restrictedTo) === 0
2346
                    || (int) $post_folder_access_level === 0
2347
                ) {
2348
                    $arrData['user_can_modify'] = 1;
2349
                    $user_is_allowed_to_modify = true;
2350
                } else {
2351
                    $arrData['user_can_modify'] = 0;
2352
                    $user_is_allowed_to_modify = false;
2353
                }
2354
2355
                // Get restriction list for roles
2356
                $listRestrictionRoles = array();
2357
                if (isset($SETTINGS['restricted_to_roles']) && $SETTINGS['restricted_to_roles'] === '1') {
2358
                    // Add restriction if item is restricted to roles
2359
                    $rows = DB::query(
2360
                        'SELECT t.title, t.id
2361
                        FROM '.prefixTable('roles_title').' AS t
2362
                        INNER JOIN '.prefixTable('restriction_to_roles').' AS r ON (t.id=r.role_id)
2363
                        WHERE r.item_id = %i
2364
                        ORDER BY t.title ASC',
2365
                        $post_id
2366
                    );
2367
                    foreach ($rows as $record) {
2368
                        if (!in_array($record['title'], $listRestrictionRoles)) {
2369
                            array_push($listRestrictionRoles, $record['id']);
2370
                        }
2371
                    }
2372
                }
2373
                // Check if any KB is linked to this item
2374
                if (isset($SETTINGS['enable_kb']) && $SETTINGS['enable_kb'] === '1') {
2375
                    $tmp = array();
2376
                    $rows = DB::query(
2377
                        'SELECT k.label, k.id
2378
                        FROM '.prefixTable('kb_items').' as i
2379
                        INNER JOIN '.prefixTable('kb').' as k ON (i.kb_id=k.id)
2380
                        WHERE i.item_id = %i
2381
                        ORDER BY k.label ASC',
2382
                        $post_id
2383
                    );
2384
                    foreach ($rows as $record) {
2385
                        array_push(
2386
                            $tmp,
2387
                            array(
2388
                                'id' => $record['id'],
2389
                                'label' => $record['label'],
2390
                            )
2391
                        );
2392
                    }
2393
                    $arrData['links_to_kbs'] = $tmp;
2394
                }
2395
                // Prepare DIalogBox data
2396
                if ($item_is_expired === false) {
2397
                    $arrData['show_detail_option'] = 0;
2398
                } elseif ($user_is_allowed_to_modify === true && $item_is_expired === true) {
2399
                    $arrData['show_detail_option'] = 1;
2400
                } else {
2401
                    $arrData['show_detail_option'] = 2;
2402
                }
2403
2404
                $arrData['label'] = htmlspecialchars_decode($dataItem['label'], ENT_QUOTES);
2405
                $arrData['pw'] = $pw;
2406
                $arrData['email'] = (empty($dataItem['email']) === true || $dataItem['email'] === null) ? '' : $dataItem['email'];
2407
                $arrData['url'] = empty($dataItem['url']) === true ? '' : $dataItem['url'];
2408
                $arrData['folder'] = $dataItem['id_tree'];
2409
2410
                $arrData['description'] = $dataItem['description'];
2411
                $arrData['login'] = htmlspecialchars_decode(str_replace(array('"'), array('&quot;'), $dataItem['login']), ENT_QUOTES);
2412
                $arrData['id_restricted_to'] = $listeRestriction;
2413
                $arrData['id_restricted_to_roles'] = $listRestrictionRoles;
2414
                $arrData['tags'] = $tags;
2415
                $arrData['folder'] = (int) $dataItem['id_tree'];
2416
2417
                if (isset($SETTINGS['enable_server_password_change'])
2418
                    && $SETTINGS['enable_server_password_change'] === '1') {
2419
                    $arrData['auto_update_pwd_frequency'] = $dataItem['auto_update_pwd_frequency'];
2420
                } else {
2421
                    $arrData['auto_update_pwd_frequency'] = '0';
2422
                }
2423
2424
                $arrData['anyone_can_modify'] = (int) $dataItem['anyone_can_modify'];
2425
2426
                // Add the fact that item has been viewed in logs
2427
                if (isset($SETTINGS['log_accessed']) && $SETTINGS['log_accessed'] === '1') {
2428
                    logItems(
2429
                        $SETTINGS,
2430
                        $post_id,
2431
                        $dataItem['label'],
2432
                        $_SESSION['user_id'],
2433
                        'at_shown',
2434
                        $_SESSION['login']
2435
                    );
2436
                }
2437
2438
                // statistics
2439
                DB::update(
2440
                    prefixTable('items'),
2441
                    array(
2442
                        'viewed_no' => $dataItem['viewed_no'] + 1,
2443
                    ),
2444
                    'id = %i',
2445
                    $post_id
2446
                );
2447
                $arrData['viewed_no'] = $dataItem['viewed_no'] + 1;
2448
2449
                // get fields
2450
                $fieldsTmp = array();
2451
                $arrCatList = $template_id = '';
2452
                if (isset($SETTINGS['item_extra_fields']) && (int) $SETTINGS['item_extra_fields'] === 1) {
2453
                    // get list of associated Categories
2454
                    $arrCatList = array();
2455
                    $rows_tmp = DB::query(
2456
                        'SELECT id_category
2457
                        FROM '.prefixTable('categories_folders').'
2458
                        WHERE id_folder=%i',
2459
                        $post_folder_id
2460
                    );
2461
                    if (DB::count() > 0) {
2462
                        foreach ($rows_tmp as $row) {
2463
                            array_push($arrCatList, (int) $row['id_category']);
2464
                        }
2465
2466
                        // get fields for this Item
2467
                        $rows_tmp = DB::query(
2468
                            'SELECT i.id AS id, i.field_id AS field_id, i.data AS data, i.item_id AS item_id,
2469
                            i.encryption_type AS encryption_type, c.encrypted_data, c.parent_id AS parent_id,
2470
                            c.type as field_type, c.masked AS field_masked, c.role_visibility AS role_visibility
2471
                            FROM '.prefixTable('categories_items').' AS i
2472
                            INNER JOIN '.prefixTable('categories').' AS c ON (i.field_id=c.id)
2473
                            WHERE i.item_id=%i AND c.parent_id IN %ls',
2474
                            $post_id,
2475
                            $arrCatList
2476
                        );
2477
                        foreach ($rows_tmp as $row) {
2478
                            // Uncrypt data
2479
                            // Get the object key for the user
2480
                            $userKey = DB::queryFirstRow(
2481
                                'SELECT share_key
2482
                                FROM '.prefixTable('sharekeys_fields').'
2483
                                WHERE user_id = %i AND object_id = %i',
2484
                                $_SESSION['user_id'],
2485
                                $row['id']
2486
                            );
2487
                            if (DB::count() === 0) {
2488
                                // Not encrypted
2489
                                $fieldText['string'] = $row['data'];
2490
                                $fieldText['encrypted'] = false;
2491
                            } else {
2492
                                $fieldText['string'] = doDataDecryption(
2493
                                    $row['data'],
2494
                                    decryptUserObjectKey(
2495
                                        $userKey['share_key'],
2496
                                        $_SESSION['user']['private_key']
2497
                                    )
2498
                                );
2499
                                $fieldText['encrypted'] = true;
2500
                            }
2501
2502
                            // Manage textarea string
2503
                            if ($row['field_type'] === 'textarea') {
2504
                                $fieldText = $fieldText;
2505
                            }
2506
2507
                            // build returned list of Fields text
2508
                            array_push(
2509
                                $fieldsTmp,
2510
                                array(
2511
                                    'id' => (int) $row['field_id'],
2512
                                    'value' => $fieldText['string'],
2513
                                    'encrypted' => (int) $fieldText['encrypted'],
2514
                                    'parent_id' => (int) $row['parent_id'],
2515
                                    'type' => $row['field_type'],
2516
                                    'masked' => (int) $row['field_masked'],
2517
                                )
2518
                            );
2519
                        }
2520
                    }
2521
                }
2522
2523
                // Now get the selected template (if exists)
2524
                if (isset($SETTINGS['item_creation_templates']) && $SETTINGS['item_creation_templates'] === '1') {
2525
                    $rows_tmp = DB::queryfirstrow(
2526
                        'SELECT category_id
2527
                        FROM '.prefixTable('templates').'
2528
                        WHERE item_id = %i',
2529
                        $post_id
2530
                    );
2531
                    if (DB::count() > 0) {
2532
                        $template_id = $rows_tmp['category_id'];
2533
                    }
2534
                }
2535
                //}
2536
                $arrData['fields'] = $fieldsTmp;
2537
                $arrData['categories'] = $arrCatList;
2538
                $arrData['template_id'] = (int) $template_id;
2539
                $arrData['to_be_deleted'] = '';
2540
2541
                // Manage user restriction
2542
                if (null !== $post_restricted) {
2543
                    $arrData['restricted'] = $post_restricted;
2544
                } else {
2545
                    $arrData['restricted'] = '';
2546
                }
2547
                // Decrement the number before being deleted
2548
                if (isset($SETTINGS['enable_delete_after_consultation']) && $SETTINGS['enable_delete_after_consultation'] === '1') {
2549
                    // Is the Item to be deleted?
2550
                    $dataDelete = DB::queryfirstrow(
2551
                        'SELECT * 
2552
                        FROM '.prefixTable('automatic_del').'
2553
                        WHERE item_id = %i',
2554
                        $post_id
2555
                    );
2556
                    if (DB::count() > 0) {
2557
                        $arrData['to_be_deleted'] = $dataDelete['del_value'];
2558
                    }
2559
                    $arrData['to_be_deleted_type'] = (int) $dataDelete['del_type'];
2560
2561
                    // Now delete if required
2562
                    if ((int) $dataDelete['del_enabled'] === 1 || intval($arrData['id_user']) !== intval($_SESSION['user_id'])) {
2563
                        if ((int) $dataDelete['del_type'] === 1 && $dataDelete['del_value'] >= 1) {
2564
                            // decrease counter
2565
                            DB::update(
2566
                                prefixTable('automatic_del'),
2567
                                array(
2568
                                    'del_value' => $dataDelete['del_value'] - 1,
2569
                                    ),
2570
                                'item_id = %i',
2571
                                $post_id
2572
                            );
2573
                            // store value
2574
                            $arrData['to_be_deleted'] = $dataDelete['del_value'] - 1;
2575
                        } elseif ((int) $dataDelete['del_type'] === 1
2576
                            && $dataDelete['del_value'] <= 1
2577
                            || (int) $dataDelete['del_type'] === 2
2578
                            && $dataDelete['del_value'] < time()
2579
                        ) {
2580
                            $arrData['show_details'] = 0;
2581
                            // delete item
2582
                            DB::delete(prefixTable('automatic_del'), 'item_id = %i', $post_id);
2583
                            // make inactive object
2584
                            DB::update(
2585
                                prefixTable('items'),
2586
                                array(
2587
                                    'inactif' => 1,
2588
                                    ),
2589
                                'id = %i',
2590
                                $post_id
2591
                            );
2592
2593
                            // log
2594
                            logItems(
2595
                                $SETTINGS,
2596
                                $post_id,
2597
                                $dataItem['label'],
2598
                                $_SESSION['user_id'],
2599
                                'at_delete',
2600
                                $_SESSION['login'],
2601
                                'at_automatically_deleted'
2602
                            );
2603
2604
                            // Update cache table
2605
                            updateCacheTable(
2606
                                'delete_value',
2607
                                $SETTINGS,
2608
                                $post_id
2609
                            );
2610
2611
                            $arrData['show_detail_option'] = 1;
2612
                            $arrData['to_be_deleted'] = 0;
2613
                        } elseif ($dataDelete['del_type'] === '2') {
2614
                            $arrData['to_be_deleted'] = date($SETTINGS['date_format'], $dataDelete['del_value']);
2615
                        }
2616
                    } else {
2617
                        $arrData['to_be_deleted'] = '';
2618
                    }
2619
                } else {
2620
                    $arrData['to_be_deleted'] = 'not_enabled';
2621
                }
2622
            } else {
2623
                $arrData['show_details'] = 0;
2624
                // get readable list of restriction
2625
                $listOfRestricted = '';
2626
                if (empty($dataItem['restricted_to']) === false) {
2627
                    foreach (explode(';', $dataItem['restricted_to']) as $userRest) {
2628
                        if (empty($userRest) === false) {
2629
                            $dataTmp = DB::queryfirstrow('SELECT login FROM '.prefixTable('users').' WHERE id= '.$userRest);
2630
                            if (empty($listOfRestricted)) {
2631
                                $listOfRestricted = $dataTmp['login'];
2632
                            } else {
2633
                                $listOfRestricted .= ';'.$dataTmp['login'];
2634
                            }
2635
                        }
2636
                    }
2637
                }
2638
                $arrData['restricted_to'] = $listOfRestricted;
2639
                $arrData['notification_list'] = '';
2640
                $arrData['notification_status'] = '';
2641
            }
2642
2643
            // Set a timestamp
2644
            $arrData['timestamp'] = time();
2645
2646
            // Set temporary session variable to allow step2
2647
            $_SESSION['user_settings']['show_step2'] = true;
2648
2649
            // Error
2650
            $arrData['error'] = '';
2651
2652
            // Encrypt data to return
2653
            echo prepareExchangedData($arrData, 'encode');
2654
            break;
2655
2656
        /*
2657
           * CASE
2658
           * Display History of the selected Item
2659
        */
2660
        case 'showDetailsStep2':
2661
            // Is this query expected (must be run after a step1 and not standalone)
2662
            if ($_SESSION['user_settings']['show_step2'] !== true) {
2663
                $returnValues = '[{"error" : "not_allowed"}, {"error_text" : "'.langHdl('error_not_allowed_to').'"}]';
2664
                echo prepareExchangedData($returnValues, 'encode');
2665
                break;
2666
            }
2667
            $returnArray = array();
2668
2669
            // Load item data
2670
            $dataItem = DB::queryFirstRow(
2671
                'SELECT i.*, n.title AS folder_title
2672
                FROM '.prefixTable('items').' AS i
2673
                INNER JOIN '.prefixTable('nested_tree').' AS n ON (i.id_tree = n.id)
2674
                WHERE i.id = %i',
2675
                $post_id
2676
            );
2677
2678
            // check that actual user can access this item
2679
            $restrictionActive = true;
2680
            $restrictedTo = array_filter(explode(';', $dataItem['restricted_to']));
2681
            if (in_array($_SESSION['user_id'], $restrictedTo)) {
2682
                $restrictionActive = false;
2683
            }
2684
            if (empty($dataItem['restricted_to'])) {
2685
                $restrictionActive = false;
2686
            }
2687
2688
            // Check if user has a role that is accepted
2689
            $rows_tmp = DB::query(
2690
                'SELECT role_id
2691
                FROM '.prefixTable('restriction_to_roles').'
2692
                WHERE item_id=%i',
2693
                $post_id
2694
            );
2695
            foreach ($rows_tmp as $rec_tmp) {
2696
                if (in_array($rec_tmp['role_id'], explode(';', $_SESSION['fonction_id']))) {
2697
                    $restrictionActive = false;
2698
                }
2699
            }
2700
2701
            // check user is admin
2702
            if ($_SESSION['user_admin'] === '1'
2703
                && $dataItem['perso'] !== 1
2704
                && (null !== TP_ADMIN_FULL_RIGHT && TP_ADMIN_FULL_RIGHT === true)
2705
                || null == TP_ADMIN_FULL_RIGHT
2706
            ) {
2707
                $returnArray['show_details'] = 0;
2708
            // Check if actual USER can see this ITEM
2709
            } elseif ((
2710
                (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)
2711
                ||
2712
                (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)
2713
                ||
2714
                (null !== $post_folder_id
2715
                    && isset($_SESSION['list_restricted_folders_for_items'][$post_folder_id])
2716
                    && in_array($post_id, $_SESSION['list_restricted_folders_for_items'][$post_folder_id])
2717
                    && $post_restricted === '1'
2718
                    && $user_in_restricted_list_of_item === true)
2719
                ||
2720
                (isset($SETTINGS['restricted_to_roles']) && $SETTINGS['restricted_to_roles'] === '1'
2721
                    && $restrictionActive === false
2722
                )
2723
            ) {
2724
                /*
2725
                // GET Audit trail
2726
                $history = array();
2727
                $historyOfPws = array();
2728
                $rows = DB::query(
2729
                    'SELECT l.date as date, l.action as action, l.raison as raison, u.login as login, l.raison_iv AS raison_iv
2730
                    FROM '.prefixTable('log_items').' as l
2731
                    LEFT JOIN '.prefixTable('users').' as u ON (l.id_user=u.id)
2732
                    WHERE id_item=%i AND action <> %s
2733
                    ORDER BY date ASC',
2734
                    $post_id,
2735
                    'at_shown'
2736
                );
2737
                foreach ($rows as $record) {
2738
                    $reason = explode(':', $record['raison']);
2739
                    if ($record['action'] === 'at_modification' && $reason[0] === 'at_pw ') {
2740
                        // check if item is PF
2741
                        if ($dataItem['perso'] !== 1) {
2742
                            $pw = cryption(
2743
                                $reason[1],
2744
                                '',
2745
                                'decrypt',
2746
                                $SETTINGS
2747
                            );
2748
                        } else {
2749
                            if (isset($_SESSION['user_settings']['session_psk']) === true) {
2750
                                $pw = cryption(
2751
                                    $reason[1],
2752
                                    $_SESSION['user_settings']['session_psk'],
2753
                                    'decrypt',
2754
                                    $SETTINGS
2755
                                );
2756
                            } else {
2757
                                $pw['string'] = '';
2758
                            }
2759
                        }
2760
2761
                        $reason[1] = $pw['string'];
2762
                        // if not UTF8 then cleanup and inform that something is wrong with encrytion/decryption
2763
                        if (isUTF8($reason[1]) === false || is_array($reason[1]) === true) {
2764
                            $reason[1] = '';
2765
                        }
2766
                    }
2767
                    // imported via API
2768
                    if (empty($record['login'])) {
2769
                        $record['login'] = langHdl('imported_via_api');
2770
                    }
2771
2772
                    if (empty($reason[1]) === false && in_array($record['action'], array('at_copy', 'at_creation', 'at_manual', 'at_modification', 'at_delete', 'at_restored')) === true) {
2773
                        if (trim($reason[0]) === 'at_pw' && empty($reason[1]) === false) {
2774
                            array_push($historyOfPws, $reason[1]);
2775
                        }
2776
                    }
2777
                }
2778
                $returnArray['historyOfPassword'] = $historyOfPws;
2779
                */
2780
2781
                // generate 2d key
2782
                $_SESSION['key_tmp'] = bin2hex(GenerateCryptKey(16));
2783
2784
                // Prepare files listing
2785
                $attachments = array();
2786
                $files = $filesEdit = '';
2787
                // launch query
2788
                $rows = DB::query(
2789
                    'SELECT id, name, file, extension, size
2790
                    FROM '.prefixTable('files').'
2791
                    WHERE id_item = %i AND confirmed = 1',
2792
                    $post_id
2793
                );
2794
                foreach ($rows as $record) {
2795
                    array_push(
2796
                        $attachments,
2797
                        array(
2798
                            'icon' => fileFormatImage(strtolower($record['extension'])),
2799
                            'filename' => basename($record['name'], '.'.$record['extension']),
2800
                            'extension' => $record['extension'],
2801
                            'size' => formatSizeUnits($record['size']),
2802
                            'is_image' => in_array(strtolower($record['extension']), TP_IMAGE_FILE_EXT) === true ? 1 : 0,
2803
                            'id' => $record['id'],
2804
                            'key' => $_SESSION['key_tmp'],
2805
                        )
2806
                    );
2807
                }
2808
                $returnArray['attachments'] = $attachments;
2809
                // display lists
2810
                //$filesEdit = str_replace('"', '&quot;', $filesEdit);
2811
                //$files_id = $files;
2812
2813
                // disable add bookmark if alread bookmarked
2814
                $returnArray['favourite'] = in_array($post_id, $_SESSION['favourites']) === true ? 1 : 0;
2815
2816
                // Add this item to the latests list
2817
                if (isset($_SESSION['latest_items']) && isset($SETTINGS['max_latest_items']) && !in_array($dataItem['id'], $_SESSION['latest_items'])) {
2818
                    if (count($_SESSION['latest_items']) >= $SETTINGS['max_latest_items']) {
2819
                        array_pop($_SESSION['latest_items']); //delete last items
2820
                    }
2821
                    array_unshift($_SESSION['latest_items'], $dataItem['id']);
2822
                    // update DB
2823
                    DB::update(
2824
                        prefixTable('users'),
2825
                        array(
2826
                            'latest_items' => implode(';', $_SESSION['latest_items']),
2827
                            ),
2828
                        'id='.$_SESSION['user_id']
2829
                    );
2830
                }
2831
2832
                // get list of roles
2833
                $listOptionsForUsers = array();
2834
                $listOptionsForRoles = array();
2835
                $rows = DB::query(
2836
                    'SELECT r.role_id AS role_id, t.title AS title
2837
                    FROM '.prefixTable('roles_values').' AS r
2838
                    INNER JOIN '.prefixTable('roles_title').' AS t ON (r.role_id = t.id)
2839
                    WHERE r.folder_id = %i',
2840
                    $dataItem['id_tree']
2841
                );
2842
                foreach ($rows as $record) {
2843
                    array_push(
2844
                        $listOptionsForRoles,
2845
                        array(
2846
                            'id' => (int) $record['role_id'],
2847
                            'title' => $record['title'],
2848
                        )
2849
                    );
2850
                    $rows2 = DB::query(
2851
                        'SELECT id, login, fonction_id, email, name, lastname
2852
                        FROM '.prefixTable('users').'
2853
                        WHERE fonction_id LIKE %s',
2854
                        '%'.$record['role_id'].'%'
2855
                    );
2856
                    foreach ($rows2 as $record2) {
2857
                        foreach (explode(';', $record2['fonction_id']) as $role) {
2858
                            if (array_search($record2['id'], array_column($listOptionsForUsers, 'id')) === false
2859
                                && $role === $record['role_id']
2860
                            ) {
2861
                                array_push(
2862
                                    $listOptionsForUsers,
2863
                                    array(
2864
                                        'id' => (int) $record2['id'],
2865
                                        'login' => $record2['login'],
2866
                                        'name' => $record2['name'].' '.$record2['lastname'],
2867
                                        'email' => $record2['email'],
2868
                                    )
2869
                                );
2870
                            }
2871
                        }
2872
                    }
2873
                }
2874
2875
                $returnArray['users_list'] = $listOptionsForUsers;
2876
                $returnArray['roles_list'] = $listOptionsForRoles;
2877
2878
                // send notification if enabled
2879
                if (isset($SETTINGS['enable_email_notification_on_item_shown']) === true && $SETTINGS['enable_email_notification_on_item_shown'] === '1') {
2880
                    // Get path
2881
                    $arbo = $tree->getPath($dataItem['id_tree'], true);
2882
                    $path = '';
2883
                    foreach ($arbo as $elem) {
2884
                        if (empty($path) === true) {
2885
                            $path = htmlspecialchars(stripslashes(htmlspecialchars_decode($elem->title, ENT_QUOTES)), ENT_QUOTES).' ';
2886
                        } else {
2887
                            $path .= '&#8594; '.htmlspecialchars(stripslashes(htmlspecialchars_decode($elem->title, ENT_QUOTES)), ENT_QUOTES);
2888
                        }
2889
                    }
2890
                    // Build text to show user
2891
                    if (empty($path) === true) {
2892
                        $path = addslashes($dataItem['label']);
2893
                    } else {
2894
                        $path = addslashes($dataItem['label']).' ('.$path.')';
2895
                    }
2896
2897
                    // send back infos
2898
                    DB::insert(
2899
                        prefixTable('emails'),
2900
                        array(
2901
                            'timestamp' => time(),
2902
                            'subject' => langHdl('email_on_open_notification_subject'),
2903
                            'body' => str_replace(
2904
                                array('#tp_user#', '#tp_item#', '#tp_link#'),
2905
                                array(
2906
                                    addslashes($_SESSION['login']),
2907
                                    $path,
2908
                                    $SETTINGS['cpassman_url'].'/index.php?page=items&group='.$dataItem['id_tree'].'&id='.$dataItem['id'],
2909
                                ),
2910
                                langHdl('email_on_open_notification_mail')
2911
                            ),
2912
                            'receivers' => $_SESSION['listNotificationEmails'],
2913
                            'status' => '',
2914
                        )
2915
                    );
2916
                }
2917
2918
                // has this item a change proposal
2919
                DB::query('SELECT * FROM '.prefixTable('items_change').' WHERE item_id = %i', $post_id);
2920
                $returnArray['has_change_proposal'] = DB::count();
2921
2922
                // Setting
2923
                $returnArray['setting_restricted_to_roles'] = isset($SETTINGS['restricted_to_roles']) === true
2924
                    && $SETTINGS['restricted_to_roles'] === '1' ? 1 : 0;
2925
2926
                $_SESSION['user_settings']['show_step2'] = false;
2927
2928
                echo prepareExchangedData(
2929
                    $returnArray,
2930
                    'encode'
2931
                );
2932
            }
2933
            break;
2934
2935
        /*
2936
         * CASE
2937
         * Delete an item
2938
        */
2939
        case 'delete_item':
2940
            // Check KEY and rights
2941
            if ($post_key !== $_SESSION['key']) {
2942
                echo prepareExchangedData(
2943
                    array(
2944
                        'error' => true,
2945
                        'message' => langHdl('key_is_not_correct'),
2946
                    ),
2947
                    'encode'
2948
                );
2949
                break;
2950
            } elseif ($_SESSION['user_read_only'] === true) {
2951
                echo prepareExchangedData(
2952
                    array(
2953
                        'error' => true,
2954
                        'message' => langHdl('error_not_allowed_to'),
2955
                    ),
2956
                    'encode'
2957
                );
2958
                break;
2959
            }
2960
2961
            // decrypt and retreive data in JSON format
2962
            $dataReceived = prepareExchangedData(
2963
                $post_data,
2964
                'decode'
2965
            );
2966
2967
            // Prepare POST variables
2968
            $post_label = filter_var($dataReceived['label'], FILTER_SANITIZE_STRING);
2969
            $post_folder_id = filter_var($dataReceived['folder_id'], FILTER_SANITIZE_NUMBER_INT);
2970
            $post_item_id = filter_var($dataReceived['item_id'], FILTER_SANITIZE_NUMBER_INT);
2971
2972
            // perform a check in case of Read-Only user creating an item in his PF
2973
            if ($_SESSION['user_read_only'] === true
2974
                && in_array($post_label, $_SESSION['personal_folders']) === false
2975
            ) {
2976
                echo prepareExchangedData(
2977
                    array(
2978
                        'error' => true,
2979
                        'message' => langHdl('error_not_allowed_to'),
2980
                    ),
2981
                    'encode'
2982
                );
2983
                break;
2984
            }
2985
2986
            // Check that user can access this item
2987
            $granted = accessToItemIsGranted($post_item_id);
2988
            if ($granted !== true) {
2989
                echo prepareExchangedData(
2990
                    array(
2991
                        'error' => true,
2992
                        'message' => $granted,
2993
                    ),
2994
                    'encode'
2995
                );
2996
                break;
2997
            }
2998
2999
            // Load item data
3000
            $data = DB::queryFirstRow(
3001
                'SELECT id_tree
3002
                FROM '.prefixTable('items').'
3003
                WHERE id = %i',
3004
                $post_item_id
3005
            );
3006
3007
            // delete item consists in disabling it
3008
            DB::update(
3009
                prefixTable('items'),
3010
                array(
3011
                    'inactif' => '1',
3012
                    ),
3013
                'id = %i',
3014
                $post_item_id
3015
            );
3016
            // log
3017
            logItems(
3018
                $SETTINGS,
3019
                $post_item_id,
3020
                $post_label,
3021
                $_SESSION['user_id'],
3022
                'at_delete',
3023
                $_SESSION['login']
3024
            );
3025
            // Update CACHE table
3026
            updateCacheTable('delete_value', $SETTINGS, $post_item_id);
3027
3028
            echo prepareExchangedData(
3029
                array(
3030
                    'error' => false,
3031
                    'message' => '',
3032
                ),
3033
                'encode'
3034
            );
3035
            break;
3036
3037
        /*
3038
        * CASE
3039
        * Update a Group
3040
        */
3041
        case 'update_folder':
3042
            // Check KEY and rights
3043
            if ($post_key !== $_SESSION['key']) {
3044
                echo prepareExchangedData(
3045
                    array(
3046
                        'error' => true,
3047
                        'message' => langHdl('key_is_not_correct'),
3048
                    ),
3049
                    'encode'
3050
                );
3051
                break;
3052
            } elseif ($_SESSION['user_read_only'] === true) {
3053
                echo prepareExchangedData(
3054
                    array(
3055
                        'error' => true,
3056
                        'message' => langHdl('error_not_allowed_to'),
3057
                    ),
3058
                    'encode'
3059
                );
3060
                break;
3061
            }
3062
            // decrypt and retreive data in JSON format
3063
            $dataReceived = prepareExchangedData($post_data, 'decode');
3064
3065
            // Prepare variables
3066
            $title = filter_var(htmlspecialchars_decode($dataReceived['title'], ENT_QUOTES), FILTER_SANITIZE_STRING);
3067
            $post_folder_id = filter_var(htmlspecialchars_decode($dataReceived['folder']), FILTER_SANITIZE_NUMBER_INT);
3068
3069
            // Check if user is allowed to access this folder
3070
            if (!in_array($post_folder_id, $_SESSION['groupes_visibles'])) {
3071
                echo '[{"error" : "'.langHdl('error_not_allowed_to').'"}]';
3072
                break;
3073
            }
3074
3075
            // Check if title doesn't contains html codes
3076
            if (preg_match_all('|<[^>]+>(.*)</[^>]+>|U', $title, $out)) {
3077
                echo '[ { "error" : "'.langHdl('error_html_codes').'" } ]';
3078
                break;
3079
            }
3080
            // check that title is not numeric
3081
            if (is_numeric($title) === true) {
3082
                echo '[{"error" : "ERR_TITLE_ONLY_WITH_NUMBERS"}]';
3083
                break;
3084
            }
3085
3086
            // Check if duplicate folders name are allowed
3087
            $createNewFolder = true;
3088
            if (isset($SETTINGS['duplicate_folder']) && $SETTINGS['duplicate_folder'] === '0') {
3089
                $data = DB::queryFirstRow('SELECT id, title FROM '.prefixTable('nested_tree').' WHERE title = %s', $title);
3090
                if (empty($data['id']) === false && $dataReceived['folder'] != $data['id']) {
3091
                    echo '[ { "error" : "'.langHdl('error_group_exist').'" } ]';
3092
                    break;
3093
                }
3094
            }
3095
3096
            // query on folder
3097
            $data = DB::queryfirstrow(
3098
                'SELECT parent_id, personal_folder
3099
                FROM '.prefixTable('nested_tree').'
3100
                WHERE id = %i',
3101
                $post_folder_id
3102
            );
3103
3104
            // check if complexity level is good
3105
            // if manager or admin don't care
3106
            if ($_SESSION['is_admin'] != 1 && $_SESSION['user_manager'] != 1 && $data['personal_folder'] === '0') {
3107
                $data = DB::queryfirstrow(
3108
                    'SELECT valeur
3109
                    FROM '.prefixTable('misc').'
3110
                    WHERE intitule = %i AND type = %s',
3111
                    $data['parent_id'],
3112
                    'complex'
3113
                );
3114
                if (intval($dataReceived['complexity']) < intval($data['valeur'])) {
3115
                    echo '[ { "error" : "'.langHdl('error_folder_complexity_lower_than_top_folder').' [<b>'.TP_PW_COMPLEXITY[$data['valeur']][1].'</b>]"} ]';
3116
                    break;
3117
                }
3118
            }
3119
3120
            // update Folders table
3121
            $tmp = DB::queryFirstRow(
3122
                'SELECT title, parent_id, personal_folder FROM '.prefixTable('nested_tree').' WHERE id = %i',
3123
                $dataReceived['folder']
3124
            );
3125
            if ($tmp['parent_id'] != 0 || $tmp['title'] != $_SESSION['user_id'] || $tmp['personal_folder'] != 1) {
3126
                DB::update(
3127
                    prefixTable('nested_tree'),
3128
                    array(
3129
                        'title' => $title,
3130
                        ),
3131
                    'id=%s',
3132
                    $post_folder_id
3133
                );
3134
                // update complixity value
3135
                DB::update(
3136
                    prefixTable('misc'),
3137
                    array(
3138
                        'valeur' => $dataReceived['complexity'],
3139
                        ),
3140
                    'intitule = %s AND type = %s',
3141
                    $post_folder_id,
3142
                    'complex'
3143
                );
3144
                // rebuild fuild tree folder
3145
                $tree->rebuild();
3146
            }
3147
            // send data
3148
            echo '[{"error" : ""}]';
3149
            break;
3150
3151
        /*
3152
        * CASE
3153
        * Move a Group including sub-folders
3154
        */
3155
        case 'move_folder':
3156
            // Check KEY and rights
3157
            if ($post_key !== $_SESSION['key']) {
3158
                echo prepareExchangedData(
3159
                    array(
3160
                        'error' => true,
3161
                        'message' => langHdl('key_is_not_correct'),
3162
                    ),
3163
                    'encode'
3164
                );
3165
                break;
3166
            } elseif ($_SESSION['user_read_only'] === true) {
3167
                echo prepareExchangedData(
3168
                    array(
3169
                        'error' => true,
3170
                        'message' => langHdl('error_not_allowed_to'),
3171
                    ),
3172
                    'encode'
3173
                );
3174
                break;
3175
            }
3176
            // decrypt and retreive data in JSON format
3177
            $dataReceived = prepareExchangedData($post_data, 'decode');
3178
            $post_source_folder_id = filter_var(htmlspecialchars_decode($dataReceived['source_folder_id']), FILTER_SANITIZE_NUMBER_INT);
3179
            $post_target_folder_id = filter_var(htmlspecialchars_decode($dataReceived['target_folder_id']), FILTER_SANITIZE_NUMBER_INT);
3180
3181
            // Check that user can access this folder
3182
            if ((
3183
                    in_array($post_source_folder_id, $_SESSION['groupes_visibles']) === false ||
3184
                  in_array($post_target_folder_id, $_SESSION['groupes_visibles']) === false) &&
3185
                  (
3186
                        $post_target_folder_id === '0' &&
3187
                      isset($SETTINGS['can_create_root_folder']) === true && $SETTINGS['can_create_root_folder'] === '1'
3188
                    )
3189
            ) {
3190
                $returnValues = '[{"error" : "'.langHdl('error_not_allowed_to').'"}]';
3191
                echo $returnValues;
3192
                break;
3193
            }
3194
3195
            $tmp_source = DB::queryFirstRow(
3196
                'SELECT title, parent_id, personal_folder
3197
                FROM '.prefixTable('nested_tree').'
3198
                WHERE id = %i',
3199
                $post_source_folder_id
3200
            );
3201
3202
            $tmp_target = DB::queryFirstRow(
3203
                'SELECT title, parent_id, personal_folder
3204
                FROM '.prefixTable('nested_tree').'
3205
                WHERE id = %i',
3206
                $post_target_folder_id
3207
            );
3208
3209
            // check if target is not a child of source
3210
            if ($tree->isChildOf($post_target_folder_id, $post_source_folder_id) === true) {
3211
                $returnValues = '[{"error" : "'.langHdl('error_not_allowed_to').'"}]';
3212
                echo $returnValues;
3213
                break;
3214
            }
3215
3216
            // check if source or target folder is PF. If Yes, then cancel operation
3217
            if ($tmp_source['personal_folder'] === '1' || $tmp_target['personal_folder'] === '1') {
3218
                $returnValues = '[{"error" : "'.langHdl('error_not_allowed_to').'"}]';
3219
                echo $returnValues;
3220
                break;
3221
            }
3222
3223
            // check if source or target folder is PF. If Yes, then cancel operation
3224
            if ($tmp_source['title'] === $_SESSION['user_id'] || $tmp_target['title'] === $_SESSION['user_id']) {
3225
                $returnValues = '[{"error" : "'.langHdl('error_not_allowed_to').'"}]';
3226
                echo $returnValues;
3227
                break;
3228
            }
3229
3230
            // moving SOURCE folder
3231
            DB::update(
3232
                prefixTable('nested_tree'),
3233
                array(
3234
                    'parent_id' => $post_target_folder_id,
3235
                    ),
3236
                'id=%s',
3237
                $post_source_folder_id
3238
            );
3239
            $tree->rebuild();
3240
3241
            // send data
3242
            echo '[{"error" : ""}]';
3243
            break;
3244
3245
        /*
3246
        * CASE
3247
        * Store hierarchic position of Group
3248
        */
3249
        case 'save_position':
3250
            DB::update(
3251
                prefixTable('nested_tree'),
3252
                array(
3253
                    'parent_id' => $post_destination,
3254
                    ),
3255
                'id = %i',
3256
                $post_source
3257
            );
3258
            $tree = new Tree\NestedTree\NestedTree(prefixTable('nested_tree'), 'id', 'parent_id', 'title');
3259
            $tree->rebuild();
3260
            break;
3261
3262
        /*
3263
        * CASE
3264
        * List items of a group
3265
        */
3266
        case 'do_items_list_in_folder':
3267
            // Check KEY and rights
3268
            if ($post_key !== $_SESSION['key']) {
3269
                $returnValues = '[{"error" : "not_allowed"}, {"error_text" : "'.str_replace('"', '\"', langHdl('error_not_allowed_to')).'"}]';
3270
                echo prepareExchangedData($returnValues, 'encode');
3271
                break;
3272
            }
3273
3274
            // Prepare POST variables
3275
            $post_restricted = filter_input(INPUT_POST, 'restricted', FILTER_SANITIZE_NUMBER_INT);
3276
            $post_start = filter_input(INPUT_POST, 'start', FILTER_SANITIZE_NUMBER_INT);
3277
            $post_nb_items_to_display_once = filter_input(INPUT_POST, 'nb_items_to_display_once', FILTER_SANITIZE_NUMBER_INT);
3278
3279
            $arboHtml = $html = '';
3280
            $arr_arbo = [];
3281
            $folderIsPf = false;
3282
            $showError = 0;
3283
            $itemsIDList = $rights = $returnedData = $uniqueLoadData = $html_json = array();
3284
            // Build query limits
3285
            if (empty($post_start) === true) {
3286
                $start = 0;
3287
            } else {
3288
                $start = $post_start;
3289
            }
3290
3291
            // to do only on 1st iteration
3292
            if ((int) $start === 0) {
3293
                // Prepare tree
3294
                $arbo = $tree->getPath($post_id, true);
3295
                foreach ($arbo as $elem) {
3296
                    if ($elem->title == $_SESSION['user_id'] && $elem->nlevel === '1') {
3297
                        $elem->title = $_SESSION['login'];
3298
                        $folderIsPf = true;
3299
                    }
3300
                    // Store path elements
3301
                    array_push(
3302
                        $arr_arbo,
3303
                        array(
3304
                            'id' => $elem->id,
3305
                            'title' => htmlspecialchars(stripslashes(htmlspecialchars_decode($elem->title, ENT_QUOTES)), ENT_QUOTES),
3306
                            'visible' => in_array($elem->id, $_SESSION['groupes_visibles']) ? 1 : 0,
3307
                        )
3308
                    );
3309
                }
3310
                $uniqueLoadData['path'] = $arr_arbo;
3311
3312
                // store last folder accessed in cookie
3313
                setcookie(
3314
                    'jstree_select',
3315
                    $post_id,
3316
                    time() + TP_ONE_DAY_SECONDS * $SETTINGS['personal_saltkey_cookie_duration'],
3317
                    '/'
3318
                );
3319
3320
                // CHeck if roles have 'allow_pw_change' set to true
3321
                $forceItemEditPrivilege = false;
3322
                foreach ($_SESSION['user_roles'] as $role) {
3323
                    $roleQ = DB::queryfirstrow(
3324
                        'SELECT allow_pw_change
3325
                        FROM '.prefixTable('roles_title').'
3326
                        WHERE id = %i',
3327
                        $role
3328
                    );
3329
                    if ((int) $roleQ['allow_pw_change'] === 1) {
3330
                        $forceItemEditPrivilege = true;
3331
                        break;
3332
                    }
3333
                }
3334
3335
                // check role access on this folder (get the most restrictive) (2.1.23)
3336
                $accessLevel = 2;
3337
                $arrTmp = [];
3338
                foreach ($_SESSION['user_roles'] as $role) {
3339
                    $access = DB::queryFirstRow(
3340
                        'SELECT type FROM '.prefixTable('roles_values').' WHERE role_id = %i AND folder_id = %i',
3341
                        $role,
3342
                        $post_id
3343
                    );
3344
                    if ($access['type'] === 'R') {
3345
                        array_push($arrTmp, 1);
3346
                    } elseif ($access['type'] === 'W') {
3347
                        array_push($arrTmp, 0);
3348
                    } elseif ($access['type'] === 'ND'
3349
                        || ($forceItemEditPrivilege === true && $access['type'] === 'NDNE')
3350
                    ) {
3351
                        array_push($arrTmp, 2);
3352
                    } elseif ($access['type'] === 'NE') {
3353
                        array_push($arrTmp, 1);
3354
                    } elseif ($access['type'] === 'NDNE') {
3355
                        array_push($arrTmp, 1);
3356
                    } else {
3357
                        // Ensure to give access Right if allowed folder
3358
                        if (in_array($post_id, $_SESSION['groupes_visibles']) === true) {
3359
                            array_push($arrTmp, 0);
3360
                        } else {
3361
                            array_push($arrTmp, 3);
3362
                        }
3363
                    }
3364
                }
3365
                $accessLevel = min($arrTmp);
3366
                $uniqueLoadData['accessLevel'] = $accessLevel;
3367
3368
                /*
3369
                // check if this folder is a PF. If yes check if saltket is set
3370
                if ((!isset($_SESSION['user_settings']['encrypted_psk']) || empty($_SESSION['user_settings']['encrypted_psk'])) && $folderIsPf === true) {
3371
                    $showError = 'is_pf_but_no_saltkey';
3372
                }
3373
                */
3374
                $uniqueLoadData['showError'] = $showError;
3375
3376
                // check if items exist
3377
                $where = new WhereClause('and');
3378
                if (null !== $post_restricted && (int) $post_restricted === 1 && empty($_SESSION['list_folders_limited'][$post_id]) === false) {
3379
                    $counter = count($_SESSION['list_folders_limited'][$post_id]);
3380
                    $uniqueLoadData['counter'] = $counter;
3381
                // check if this folder is visible
3382
                } elseif (!in_array(
3383
                    $post_id,
3384
                    array_merge(
3385
                        $_SESSION['groupes_visibles'],
3386
                        @array_keys($_SESSION['list_restricted_folders_for_items']),
3387
                        @array_keys($_SESSION['list_folders_limited'])
3388
                    )
3389
                )) {
3390
                    echo prepareExchangedData(
3391
                        array(
3392
                            'error' => 'not_authorized',
3393
                            'arborescence' => $arr_arbo,
3394
                        ),
3395
                        'encode'
3396
                    );
3397
                    break;
3398
                } else {
3399
                    DB::query(
3400
                        'SELECT *
3401
                        FROM '.prefixTable('items').'
3402
                        WHERE inactif = %i',
3403
                        0
3404
                    );
3405
                    $counter = DB::count();
3406
                    $uniqueLoadData['counter'] = $counter;
3407
                }
3408
3409
                /*
3410
                // Identify if it is a personal folder
3411
                if (in_array($post_id, $_SESSION['personal_visible_groups'])) {
3412
                    $findPfGroup = 1;
3413
                } else {
3414
                    $findPfGroup = '';
3415
                }
3416
                $uniqueLoadData['findPfGroup'] = $findPfGroup;
3417
                */
3418
3419
                // Get folder complexity
3420
                $folderComplexity = DB::queryFirstRow(
3421
                    'SELECT valeur FROM '.prefixTable('misc').' WHERE type = %s AND intitule = %i',
3422
                    'complex',
3423
                    $post_id
3424
                );
3425
                $folderComplexity = $folderComplexity['valeur'];
3426
                $uniqueLoadData['folderComplexity'] = $folderComplexity;
3427
3428
                // Has this folder some categories to be displayed?
3429
                $categoriesStructure = array();
3430
                if (isset($SETTINGS['item_extra_fields']) && $SETTINGS['item_extra_fields'] === '1') {
3431
                    $folderRow = DB::query(
3432
                        'SELECT id_category
3433
                        FROM '.prefixTable('categories_folders').'
3434
                        WHERE id_folder = %i',
3435
                        $post_id
3436
                    );
3437
                    foreach ($folderRow as $category) {
3438
                        array_push(
3439
                            $categoriesStructure,
3440
                            $category['id_category']
3441
                        );
3442
                    }
3443
                }
3444
                $uniqueLoadData['categoriesStructure'] = $categoriesStructure;
3445
3446
                /*$categoriesStructure = array();
3447
                if (isset($SETTINGS['item_extra_fields']) && $SETTINGS['item_extra_fields'] === '1') {
3448
                    $folderRow = DB::query(
3449
                        'SELECT f.id_category, c.title AS title
3450
                        FROM '.prefixTable('categories_folders').' AS f
3451
                        INNER JOIN '.prefixTable('categories').' AS c ON (c.id = f.id_category)
3452
                        WHERE f.id_folder = %i',
3453
                        $post_id
3454
                    );
3455
                    foreach ($folderRow as $category) {
3456
                        $arrFields = array();
3457
                        // Get each category definition with fields
3458
                        $categoryRow = DB::query(
3459
                            "SELECT *
3460
                            FROM ".prefixTable("categories")."
3461
                            WHERE parent_id=%i
3462
                            ORDER BY `order` ASC",
3463
                            $category['id_category']
3464
                        );
3465
3466
                        if (DB::count() > 0) {
3467
                            foreach ($categoryRow as $field) {
3468
                                // Is this Field visibile by user?
3469
                                if ($field['role_visibility'] === 'all'
3470
                                    || count(
3471
                                        array_intersect(
3472
                                            explode(';', $_SESSION['fonction_id']),
3473
                                            explode(',', $field['role_visibility'])
3474
                                        )
3475
                                    ) > 0
3476
                                ) {
3477
                                    array_push(
3478
                                        $arrFields,
3479
                                        array(
3480
                                            $field['id'],
3481
                                            $field['title'],
3482
                                            $field['encrypted_data'],
3483
                                            $field['type'],
3484
                                            $field['masked'],
3485
                                            $field['is_mandatory']
3486
                                        )
3487
                                    );
3488
                                }
3489
                            }
3490
                        }
3491
3492
                        // store the categories
3493
                        array_push(
3494
                            $categoriesStructure,
3495
                            array(
3496
                                $category['id_category'],
3497
                                $category['title'],
3498
                                $arrFields
3499
                            )
3500
                        );
3501
                    }
3502
                }
3503
                $uniqueLoadData['categoriesStructure'] = $categoriesStructure;
3504
                */
3505
3506
                // is this folder a personal one
3507
                $folder_is_personal = in_array($post_id, $_SESSION['personal_folders']);
3508
                $uniqueLoadData['folder_is_personal'] = $folder_is_personal;
3509
3510
                $folder_is_in_personal = in_array($post_id, array_merge($_SESSION['personal_visible_groups'], $_SESSION['personal_folders']));
3511
                $uniqueLoadData['folder_is_in_personal'] = $folder_is_in_personal;
3512
3513
                if (isset($_SESSION['list_folders_editable_by_role'])) {
3514
                    $list_folders_editable_by_role = in_array($post_id, $_SESSION['list_folders_editable_by_role']);
3515
                } else {
3516
                    $list_folders_editable_by_role = '';
3517
                }
3518
                $uniqueLoadData['list_folders_editable_by_role'] = $list_folders_editable_by_role;
3519
            } else {
3520
                // get preloaded data
3521
                $uniqueLoadData = json_decode(
3522
                    filter_input(INPUT_POST, 'uniqueLoadData', FILTER_UNSAFE_RAW),
3523
                    true
3524
                );
3525
3526
                // initialize main variables
3527
                $showError = $uniqueLoadData['showError'];
3528
                $accessLevel = $uniqueLoadData['accessLevel'];
3529
                $counter = $uniqueLoadData['counter'];
3530
                //$findPfGroup = $uniqueLoadData['findPfGroup'];
3531
                $counter_full = $uniqueLoadData['counter_full'];
3532
                $categoriesStructure = $uniqueLoadData['categoriesStructure'];
3533
                $folderComplexity = $uniqueLoadData['folderComplexity'];
3534
                //$arboHtml = $uniqueLoadData['arboHtml'];
3535
                $folder_is_personal = $uniqueLoadData['folder_is_personal'];
3536
                $folder_is_in_personal = $uniqueLoadData['folder_is_in_personal'];
3537
                $list_folders_editable_by_role = $uniqueLoadData['list_folders_editable_by_role'];
3538
            }
3539
3540
            // prepare query WHere conditions
3541
            $where = new WhereClause('and');
3542
            if (null !== $post_restricted && (int) $post_restricted === 1 && empty($_SESSION['list_folders_limited'][$post_id]) === false) {
3543
                $where->add('i.id IN %ls', $_SESSION['list_folders_limited'][$post_id]);
3544
            } else {
3545
                $where->add('i.id_tree=%i', $post_id);
3546
            }
3547
3548
            // build the HTML for this set of Items
3549
            if ($counter > 0 && empty($showError)) {
3550
                // init variables
3551
                $init_personal_folder = false;
3552
                $expired_item = false;
3553
                $limited_to_items = '';
3554
3555
                // List all ITEMS
3556
                if ($folderIsPf === false) {
3557
                    $where->add('i.inactif=%i', 0);
3558
                    $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)");
3559
                    if (empty($limited_to_items) === false) {
3560
                        $where->add('i.id IN %ls', explode(',', $limited_to_items));
3561
                    }
3562
3563
                    $query_limit = ' LIMIT '.
3564
                        $start.','.
3565
                        $post_nb_items_to_display_once;
3566
3567
                    $rows = DB::query(
3568
                        'SELECT i.id AS id, MIN(i.restricted_to) AS restricted_to, MIN(i.perso) AS perso,
3569
                        MIN(i.label) AS label, MIN(i.description) AS description, MIN(i.pw) AS pw, MIN(i.login) AS login,
3570
                        MIN(i.anyone_can_modify) AS anyone_can_modify, l.date AS date, i.id_tree AS tree_id,
3571
                        MIN(n.renewal_period) AS renewal_period,
3572
                        MIN(l.action) AS log_action, l.id_user AS log_user
3573
                        FROM '.prefixTable('items').' AS i
3574
                        INNER JOIN '.prefixTable('nested_tree').' AS n ON (i.id_tree = n.id)
3575
                        INNER JOIN '.prefixTable('log_items').' AS l ON (i.id = l.id_item)
3576
                        WHERE %l
3577
                        GROUP BY i.id, l.date, l.id_user, l.action
3578
                        ORDER BY i.label ASC, l.date DESC'.$query_limit,
3579
                        $where
3580
                    );
3581
                } else {
3582
                    $post_nb_items_to_display_once = 'max';
3583
                    $where->add('i.inactif=%i', 0);
3584
3585
                    $rows = DB::query(
3586
                        'SELECT i.id AS id, MIN(i.restricted_to) AS restricted_to, MIN(i.perso) AS perso,
3587
                        MIN(i.label) AS label, MIN(i.description) AS description, MIN(i.pw) AS pw, MIN(i.login) AS login,
3588
                        MIN(i.anyone_can_modify) AS anyone_can_modify,l.date AS date, i.id_tree AS tree_id,
3589
                        MIN(n.renewal_period) AS renewal_period,
3590
                        MIN(l.action) AS log_action, l.id_user AS log_user
3591
                        FROM '.prefixTable('items').' AS i
3592
                        INNER JOIN '.prefixTable('nested_tree').' AS n ON (i.id_tree = n.id)
3593
                        INNER JOIN '.prefixTable('log_items').' AS l ON (i.id = l.id_item)
3594
                        WHERE %l
3595
                        GROUP BY i.id, l.date, l.id_user, l.action
3596
                        ORDER BY i.label ASC, l.date DESC',
3597
                        $where
3598
                    );
3599
                }
3600
3601
                $idManaged = '';
3602
                $i = 0;
3603
                $arr_items_html = array();
3604
3605
                foreach ($rows as $record) {
3606
                    // exclude all results except the first one returned by query
3607
                    if (empty($idManaged) === true || $idManaged !== $record['id']) {
3608
                        // Fix a bug on Personal Item creation - field `perso` must be set to `1`
3609
                        if ((int) $record['perso'] !== 1 && (int) $folder_is_personal === 1) {
3610
                            DB::update(
3611
                                prefixTable('items'),
3612
                                array(
3613
                                    'perso' => 1,
3614
                                ),
3615
                                'id=%i',
3616
                                $record['id']
3617
                            );
3618
                            $record['perso'] = 1;
3619
                        }
3620
3621
                        // Does this item has restriction to groups of users?
3622
                        $item_is_restricted_to_role = false;
3623
                        DB::queryfirstrow(
3624
                            'SELECT role_id
3625
                            FROM '.prefixTable('restriction_to_roles').'
3626
                            WHERE item_id = %i',
3627
                            $record['id']
3628
                        );
3629
                        if (DB::count() > 0) {
3630
                            $item_is_restricted_to_role = true;
3631
                        }
3632
3633
                        // Has this item a restriction to Groups of Users
3634
                        $user_is_included_in_role = false;
3635
                        $roles = DB::query(
3636
                            'SELECT role_id
3637
                            FROM '.prefixTable('restriction_to_roles').'
3638
                            WHERE item_id = %i AND role_id IN %ls',
3639
                            $record['id'],
3640
                            $_SESSION['user_roles']
3641
                        );
3642
                        if (DB::count() > 0) {
3643
                            $user_is_included_in_role = true;
3644
                        }
3645
3646
                        // Get Expiration date
3647
                        $expired_item = 0;
3648
                        if ($SETTINGS['activate_expiration'] === '1'
3649
                            && $record['renewal_period'] > 0
3650
                            && ($record['date'] + ($record['renewal_period'] * TP_ONE_MONTH_SECONDS)) < time()
3651
                        ) {
3652
                            $expired_item = 1;
3653
                        }
3654
                        // Init
3655
                        $html_json[$record['id']]['expired'] = (int) $expired_item;
3656
                        $html_json[$record['id']]['item_id'] = (int) $record['id'];
3657
                        $html_json[$record['id']]['tree_id'] = (int) $record['tree_id'];
3658
                        $html_json[$record['id']]['label'] = strip_tags($record['label']);
3659
                        if (isset($SETTINGS['show_description']) === true && $SETTINGS['show_description'] === '1') {
3660
                            $html_json[$record['id']]['desc'] = strip_tags((explode('<br>', $record['description'])[0]));
3661
                        } else {
3662
                            $html_json[$record['id']]['desc'] = '';
3663
                        }
3664
                        $html_json[$record['id']]['login'] = $record['login'];
3665
                        $html_json[$record['id']]['anyone_can_modify'] = (int) $record['anyone_can_modify'];
3666
                        $html_json[$record['id']]['is_result_of_search'] = 0;
3667
                        $html_json[$record['id']]['is_favourited'] = in_array($record['id'], $_SESSION['favourites']) === true ? 1 : 0;
3668
3669
                        /*************** */
3670
                        $showItem = 0;
3671
                        // Possible values:
3672
                        // 0 -> no access to item
3673
                        // 10 -> appears in list but no view
3674
                        // 20 -> can view without edit (no copy) or move
3675
                        // 30 -> can view without edit (no copy) but can move
3676
                        // 40 -> can edit but not move
3677
                        // 50 -> can edit and move
3678
                        $itemIsPersonal = false;
3679
3680
                        // Let's identify the rights belonging to this ITEM
3681
                        if ((int) $record['perso'] === 1
3682
                            && $record['log_action'] === 'at_creation'
3683
                            && $record['log_user'] === $_SESSION['user_id']
3684
                            && (int) $folder_is_in_personal === 1
3685
                            && (int) $folder_is_personal === 1
3686
                        ) {
3687
                            // Case 1 - Is this item personal and user its owner?
3688
                            // If yes then allow
3689
                            // If no then continue
3690
                            $itemIsPersonal = true;
3691
                            $right = 70;
3692
3693
                        // ----- END CASE 1 -----
3694
                        } elseif (((isset($_SESSION['user_manager']) === true && (int) $_SESSION['user_manager'] === 1)
3695
                            || (isset($_SESSION['user_can_manage_all_users']) === true && (int) $_SESSION['user_can_manage_all_users'] === 1))
3696
                            && (isset($SETTINGS['manager_edit']) === true && (int) $SETTINGS['manager_edit'] === 1)
3697
                            && $record['perso'] !== 1
3698
                        ) {
3699
                            // Case 2 - Is user manager and option "manager_edit" set to true?
3700
                            // Allow all rights
3701
                            $right = 70;
3702
3703
                        // ----- END CASE 2 -----
3704
                        } elseif ((int) $record['anyone_can_modify'] === 1
3705
                            && $record['perso'] !== 1
3706
                            && (int) $_SESSION['user_read_only'] !== 1
3707
                        ) {
3708
                            // Case 3 - Has this item the setting "anyone can modify" set to true?
3709
                            // Allow all rights
3710
                            $right = 70;
3711
3712
                        // ----- END CASE 3 -----
3713
                        } elseif (empty($record['restricted_to']) === false
3714
                            && in_array($_SESSION['user_id'], explode(';', $record['restricted_to'])) === true
3715
                            && $record['perso'] !== 1
3716
                            && (int) $_SESSION['user_read_only'] !== 1
3717
                        ) {
3718
                            // Case 4 - Is this item limited to Users? Is current user in this list?
3719
                            // Allow all rights
3720
                            $right = 70;
3721
3722
                        // ----- END CASE 4 -----
3723
                        } elseif ($user_is_included_in_role === true
3724
                            && $record['perso'] !== 1
3725
                            && (int) $_SESSION['user_read_only'] !== 1
3726
                        ) {
3727
                            // Case 5 - Is this item limited to group of users? Is current user in one of those groups?
3728
                            // Allow all rights
3729
                            $right = 60;
3730
3731
                        // ----- END CASE 5 -----
3732
                        } elseif ($record['perso'] !== 1
3733
                            && (int) $_SESSION['user_read_only'] === 1
3734
                        ) {
3735
                            // Case 6 - Is user readonly?
3736
                            // Allow limited rights
3737
                            $right = 10;
3738
3739
                        // ----- END CASE 6 -----
3740
                        } elseif ($record['perso'] !== 1
3741
                            && (int) $_SESSION['user_read_only'] === 1
3742
                        ) {
3743
                            // Case 7 - Is user readonly?
3744
                            // Allow limited rights
3745
                            $right = 10;
3746
3747
                        // ----- END CASE 7 -----
3748
                        } elseif ($record['perso'] !== 1
3749
                            && (int) $_SESSION['user_read_only'] === 1
3750
                        ) {
3751
                            // Case 8 - Is user allowed to access?
3752
                            // Allow rights
3753
                            $right = 10;
3754
3755
                        // ----- END CASE 8 -----
3756
                        } elseif (((empty($record['restricted_to']) === false
3757
                            && in_array($_SESSION['user_id'], explode(';', $record['restricted_to'])) === false)
3758
                            || ($user_is_included_in_role === false && $item_is_restricted_to_role === true))
3759
                            && $record['perso'] !== 1
3760
                            && (int) $_SESSION['user_read_only'] !== 1
3761
                        ) {
3762
                            // Case 9 - Is this item limited to Users or Groups? Is current user in this list?
3763
                            // If no then Allow none
3764
                            $right = 10;
3765
3766
                        // ----- END CASE 9 -----
3767
                        } else {
3768
                            // Define the access based upon setting on folder
3769
                            // 0 -> no access to item
3770
                            // 10 -> appears in list but no view
3771
                            // 20 -> can view without edit (no copy) or move or delete
3772
                            // 30 -> can view without edit (no copy) or delete but can move
3773
                            // 40 -> can edit but not move and not delete
3774
                            // 50 -> can edit and delete but not move
3775
                            // 60 -> can edit and move but not delete
3776
                            // 70 -> can edit and move
3777
                            if ((int) $accessLevel === 0) {
3778
                                $right = 70;
3779
                            } elseif ((int) $accessLevel === 1) {
3780
                                $right = 20;
3781
                            } elseif ((int) $accessLevel === 2) {
3782
                                $right = 60;
3783
                            } elseif ((int) $accessLevel === 3) {
3784
                                $right = 70;
3785
                            } else {
3786
                                $right = 10;
3787
                            }
3788
                        }
3789
3790
                        // Now finalize the data to send back
3791
                        $html_json[$record['id']]['rights'] = $right;
3792
                        $html_json[$record['id']]['perso'] = 'fa-tag mi-red';
3793
                        $html_json[$record['id']]['sk'] = $itemIsPersonal === true ? 1 : 0;
3794
                        $html_json[$record['id']]['display'] = $right > 0 ? 1 : 0;
3795
                        $html_json[$record['id']]['open_edit'] = in_array($right, array(40, 50, 60, 70)) === true ? 1 : 0;
3796
                        $html_json[$record['id']]['canMove'] = in_array($right, array(30, 60, 70)) === true ? 1 : 0;
3797
3798
                        //*************** */
3799
3800
                        // Build array with items
3801
                        array_push(
3802
                            $itemsIDList,
3803
                            array(
3804
                                'id' => (int) $record['id'],
3805
                                //'display' => $displayItem,
3806
                                'edit' => $html_json[$record['id']]['open_edit'],
3807
                            )
3808
                        );
3809
3810
                        ++$i;
3811
                    }
3812
                    $idManaged = $record['id'];
3813
                }
3814
3815
                $rights = recupDroitCreationSansComplexite($post_id);
3816
            }
3817
3818
            // DELETE - 2.1.19 - AND (l.action = 'at_creation' OR (l.action = 'at_modification' AND l.raison LIKE 'at_pw :%'))
3819
            // count
3820
            if ((int) $start === 0) {
3821
                DB::query(
3822
                    'SELECT i.id
3823
                    FROM '.prefixTable('items').' as i
3824
                    INNER JOIN '.prefixTable('nested_tree').' as n ON (i.id_tree = n.id)
3825
                    INNER JOIN '.prefixTable('log_items').' as l ON (i.id = l.id_item)
3826
                    WHERE %l
3827
                    ORDER BY i.label ASC, l.date DESC',
3828
                    $where
3829
                );
3830
                $counter_full = DB::count();
3831
                $uniqueLoadData['counter_full'] = $counter_full;
3832
            }
3833
3834
            // Check list to be continued status
3835
            if ($post_nb_items_to_display_once !== 'max' && ($post_nb_items_to_display_once + $start) < $counter_full) {
3836
                $listToBeContinued = 'yes';
3837
            } else {
3838
                $listToBeContinued = 'end';
3839
            }
3840
3841
            // Prepare returned values
3842
            $returnValues = array(
3843
                'html_json' => $html_json,
3844
                //'folder_requests_psk' => $findPfGroup,
3845
                'arborescence' => $arr_arbo,
3846
                'array_items' => $itemsIDList,
3847
                'error' => $showError,
3848
                //'saltkey_is_required' => $folderIsPf === true ? 1 : 0,
3849
                'show_clipboard_small_icons' => isset($SETTINGS['copy_to_clipboard_small_icons']) && $SETTINGS['copy_to_clipboard_small_icons'] === '1' ? 1 : 0,
3850
                'next_start' => intval($post_nb_items_to_display_once) + intval($start),
3851
                'list_to_be_continued' => $listToBeContinued,
3852
                'items_count' => $counter,
3853
                'counter_full' => $counter_full,
3854
                'folder_complexity' => (int) $folderComplexity,
3855
                'categoriesStructure' => $categoriesStructure,
3856
                'access_level' => $accessLevel,
3857
                'IsPersonalFolder' => $folderIsPf === true ? 1 : 0,
3858
                'uniqueLoadData' => json_encode($uniqueLoadData),
3859
            );
3860
            // Check if $rights is not null
3861
            if (count($rights) > 0) {
3862
                $returnValues = array_merge($returnValues, $rights);
3863
            }
3864
3865
            // Encrypt data to return
3866
            echo prepareExchangedData($returnValues, 'encode');
3867
3868
            break;
3869
3870
        /*
3871
        *
3872
        *
3873
        */
3874
        case 'show_item_password':
3875
            // Check KEY
3876
            if ($post_key !== $_SESSION['key']) {
3877
                echo prepareExchangedData(
3878
                    array(
3879
                        'error' => true,
3880
                        'message' => langHdl('key_is_not_correct'),
3881
                    ),
3882
                    'encode'
3883
                );
3884
                break;
3885
            }
3886
3887
            // Prepare POST variables
3888
            $post_item_id = filter_input(INPUT_POST, 'item_id', FILTER_SANITIZE_NUMBER_INT);
3889
3890
            // Run query
3891
            $dataItem = DB::queryfirstrow(
3892
                'SELECT i.pw AS pw, s.share_key AS share_key
3893
                FROM '.prefixTable('items').' AS i
3894
                INNER JOIN '.prefixTable('sharekeys_items').' AS s ON (s.object_id = i.id)
3895
                WHERE user_id = %i AND i.id = %i',
3896
                $_SESSION['user_id'],
3897
                $post_item_id
3898
            );
3899
3900
            // Uncrypt PW
3901
            if (DB::count() === 0) {
3902
                // No share key found
3903
                $pw = '';
3904
            } else {
3905
                $pw = doDataDecryption(
3906
                    $dataItem['pw'],
3907
                    decryptUserObjectKey(
3908
                        $dataItem['share_key'],
3909
                        $_SESSION['user']['private_key']
3910
                    )
3911
                );
3912
            }
3913
3914
            $returnValues = array(
3915
                'error' => false,
3916
                'password' => $pw,
3917
                'password_error' => '',
3918
            );
3919
3920
            // Encrypt data to return
3921
            echo prepareExchangedData($returnValues, 'encode');
3922
            break;
3923
3924
        /*
3925
        * CASE
3926
        * Get complexity level of a group
3927
        */
3928
        case 'get_complixity_level':
3929
            // Prepare POST variables
3930
            $post_groupe = filter_input(INPUT_POST, 'groupe', FILTER_SANITIZE_STRING);
3931
            $post_context = filter_input(INPUT_POST, 'context', FILTER_SANITIZE_STRING);
3932
3933
            // get some info about ITEM
3934
            if (null !== $post_item_id && empty($post_item_id) === false) {
3935
                $dataItem = DB::queryfirstrow(
3936
                    'SELECT perso, anyone_can_modify
3937
                    FROM '.prefixTable('items').'
3938
                    WHERE id=%i',
3939
                    $post_item_id
3940
                );
3941
3942
                // is user allowed to access this folder - readonly
3943
                if (null !== $post_groupe && empty($post_groupe) === false) {
3944
                    if (in_array($post_groupe, $_SESSION['read_only_folders']) === true
3945
                        || in_array($post_groupe, $_SESSION['groupes_visibles']) === false
3946
                    ) {
3947
                        // check if this item can be modified by anyone
3948
                        if (isset($SETTINGS['anyone_can_modify']) && (int) $SETTINGS['anyone_can_modify'] === 1) {
3949
                            if ((int) $dataItem['anyone_can_modify'] !== 1) {
3950
                                // else return not authorized
3951
                                $returnValues = array(
3952
                                    'error' => true,
3953
                                    'message' => langHdl('error_not_allowed_to1'),
3954
                                );
3955
                                echo prepareExchangedData($returnValues, 'encode');
3956
                                break;
3957
                            }
3958
                        } else {
3959
                            // else return not authorized
3960
                            $returnValues = array(
3961
                                'error' => true,
3962
                                'message' => langHdl('error_not_allowed_to'),
3963
                            );
3964
                            echo prepareExchangedData($returnValues, 'encode');
3965
                            break;
3966
                        }
3967
                    }
3968
                }
3969
3970
                // Lock Item (if already locked), go back and warn
3971
                $dataTmp = DB::queryFirstRow('SELECT timestamp, user_id FROM '.prefixTable('items_edition').' WHERE item_id = %i', $post_item_id);
3972
3973
                // If token is taken for this Item and delay is passed then delete it.
3974
                if (isset($SETTINGS['delay_item_edition']) &&
3975
                    $SETTINGS['delay_item_edition'] > 0 && empty($dataTmp['timestamp']) === false &&
3976
                    round(abs(time() - $dataTmp['timestamp']) / 60, 2) > $SETTINGS['delay_item_edition']
3977
                ) {
3978
                    DB::delete(prefixTable('items_edition'), 'item_id = %i', $post_item_id);
3979
                    //reload the previous data
3980
                    $dataTmp = DB::queryFirstRow(
3981
                        'SELECT timestamp, user_id FROM '.prefixTable('items_edition').' WHERE item_id = %i',
3982
                        $post_item_id
3983
                    );
3984
                }
3985
3986
                // If edition by same user (and token not freed before for any reason, then update timestamp)
3987
                if (empty($dataTmp['timestamp']) === false && $dataTmp['user_id'] == $_SESSION['user_id']) {
3988
                    DB::update(
3989
                        prefixTable('items_edition'),
3990
                        array(
3991
                            'timestamp' => time(),
3992
                        ),
3993
                        'user_id = %i AND item_id = %i',
3994
                        $_SESSION['user_id'],
3995
                        $post_item_id
3996
                    );
3997
                // If no token for this Item, then initialize one
3998
                } elseif (empty($dataTmp[0])) {
3999
                    DB::insert(
4000
                        prefixTable('items_edition'),
4001
                        array(
4002
                            'timestamp' => time(),
4003
                            'item_id' => $post_item_id,
4004
                            'user_id' => $_SESSION['user_id'],
4005
                        )
4006
                    );
4007
                // Edition not possible
4008
                } else {
4009
                    $returnValues = array(
4010
                        'error' => true,
4011
                        'message' => langHdl('error_no_edition_possible_locked'),
4012
                    );
4013
                    echo prepareExchangedData($returnValues, 'encode');
4014
                    break;
4015
                }
4016
            }
4017
4018
            // do query on this folder
4019
            $data_this_folder = DB::queryFirstRow(
4020
                'SELECT id, personal_folder, title
4021
                FROM '.prefixTable('nested_tree').'
4022
                WHERE id = %s',
4023
                $post_groupe
4024
            );
4025
4026
            // check if user can perform this action
4027
            if (null !== $post_context
4028
                && empty($post_context) === false
4029
            ) {
4030
                if ($post_context === 'create_folder'
4031
                    || $post_context === 'edit_folder'
4032
                    || $post_context === 'delete_folder'
4033
                    || $post_context === 'copy_folder'
4034
                ) {
4035
                    if ((int) $_SESSION['is_admin'] !== 1
4036
                        && ((int) $_SESSION['user_manager'] !== 1)
4037
                        && (
4038
                            isset($SETTINGS['enable_user_can_create_folders'])
4039
                           && (int) $SETTINGS['enable_user_can_create_folders'] !== 1
4040
                        )
4041
                        && (
4042
                            (int) $data_this_folder['personal_folder'] !== 1 && $data_this_folder['title'] !== $_SESSION['user_id']
4043
                        )   // take into consideration if this is a personal folder
4044
                    ) {
4045
                        $returnValues = array(
4046
                            'error' => true,
4047
                            'message' => langHdl('error_not_allowed_to'),
4048
                        );
4049
                        echo prepareExchangedData($returnValues, 'encode');
4050
                        break;
4051
                    }
4052
                }
4053
            }
4054
4055
            // Get required Complexity for this Folder
4056
            $visibilite = '';
4057
            $data = DB::queryFirstRow(
4058
                'SELECT m.valeur, n.personal_folder
4059
                FROM '.prefixTable('misc').' AS m
4060
                INNER JOIN '.prefixTable('nested_tree').' AS n ON (m.intitule = n.id)
4061
                WHERE type=%s AND intitule = %s',
4062
                'complex',
4063
                $post_groupe
4064
            );
4065
4066
            if (isset($data['valeur']) === true && (empty($data['valeur']) === false || $data['valeur'] === '0')) {
4067
                $complexity = TP_PW_COMPLEXITY[$data['valeur']][1];
4068
                //$folder_is_personal = $data['personal_folder'];
4069
4070
                // Prepare Item actual visibility (what Users/Roles can see it)
4071
                $rows = DB::query(
4072
                    'SELECT t.title
4073
                    FROM '.prefixTable('roles_values').' as v
4074
                    INNER JOIN '.prefixTable('roles_title').' as t ON (v.role_id = t.id)
4075
                    WHERE v.folder_id = %i
4076
                    GROUP BY title',
4077
                    $post_groupe
4078
                );
4079
                foreach ($rows as $record) {
4080
                    if (empty($visibilite)) {
4081
                        $visibilite = $record['title'];
4082
                    } else {
4083
                        $visibilite .= ' - '.$record['title'];
4084
                    }
4085
                }
4086
            } else {
4087
                $complexity = langHdl('not_defined');
4088
4089
                // if not defined, then previous query failed and personal_folder is null
4090
                // do new query to know if current folder is pf
4091
                $data_pf = DB::queryFirstRow(
4092
                    'SELECT personal_folder
4093
                    FROM '.prefixTable('nested_tree').'
4094
                    WHERE id = %s',
4095
                    $post_groupe
4096
                );
4097
                //$folder_is_personal = $data_pf['personal_folder'];
4098
                $visibilite = $_SESSION['name'].' '.$_SESSION['lastname'].' ('.$_SESSION['login'].')';
4099
            }
4100
4101
            recupDroitCreationSansComplexite($post_groupe);
4102
4103
            // get list of roles
4104
            $listOptionsForUsers = array();
4105
            $listOptionsForRoles = array();
4106
            $rows = DB::query(
4107
                'SELECT r.role_id AS role_id, t.title AS title
4108
                FROM '.prefixTable('roles_values').' AS r
4109
                INNER JOIN '.prefixTable('roles_title').' AS t ON (r.role_id = t.id)
4110
                WHERE r.folder_id = %i',
4111
                $post_groupe
4112
            );
4113
            foreach ($rows as $record) {
4114
                array_push(
4115
                    $listOptionsForRoles,
4116
                    array(
4117
                        'id' => $record['role_id'],
4118
                        'title' => $record['title'],
4119
                    )
4120
                );
4121
                $rows2 = DB::query(
4122
                    'SELECT id, login, fonction_id, email, name, lastname
4123
                    FROM '.prefixTable('users').'
4124
                    WHERE admin = 0'
4125
                );
4126
                foreach ($rows2 as $record2) {
4127
                    foreach (explode(';', $record2['fonction_id']) as $role) {
4128
                        if (array_search($record2['id'], array_column($listOptionsForUsers, 'id')) === false
4129
                            && $role === $record['role_id']
4130
                        ) {
4131
                            array_push(
4132
                                $listOptionsForUsers,
4133
                                array(
4134
                                    'id' => $record2['id'],
4135
                                    'login' => $record2['login'],
4136
                                    'name' => $record2['name'].' '.$record2['lastname'],
4137
                                    'email' => $record2['email'],
4138
                                )
4139
                            );
4140
                        }
4141
                    }
4142
                }
4143
            }
4144
4145
            $returnValues = array(
4146
                'folderId' => (int) $post_groupe,
4147
                'error' => false,
4148
                'val' => (int) $data['valeur'],
4149
                'visibility' => $visibilite,
4150
                'complexity' => $complexity,
4151
                //'personal' => $folder_is_personal,
4152
                'usersList' => $listOptionsForUsers,
4153
                'rolesList' => $listOptionsForRoles,
4154
                'setting_restricted_to_roles' => isset($SETTINGS['restricted_to_roles']) === true
4155
                    && (int) $SETTINGS['restricted_to_roles'] === 1 ? 1 : 0,
4156
            );
4157
            echo prepareExchangedData($returnValues, 'encode');
4158
            break;
4159
4160
        /*
4161
        * CASE
4162
        * DELETE attached file from an item
4163
        */
4164
        case 'delete_attached_file':
4165
            // Check KEY
4166
            if ($post_key !== $_SESSION['key']) {
4167
                echo prepareExchangedData(
4168
                    array(
4169
                        'error' => true,
4170
                        'message' => langHdl('key_is_not_correct'),
4171
                    ),
4172
                    'encode'
4173
                );
4174
                break;
4175
            }
4176
4177
            // decrypt and retreive data in JSON format
4178
            $dataReceived = prepareExchangedData(
4179
                $post_data,
4180
                'decode'
4181
            );
4182
            $fileId = filter_var($dataReceived['file_id'], FILTER_SANITIZE_NUMBER_INT);
4183
4184
            // Get some info before deleting
4185
            $data = DB::queryFirstRow(
4186
                'SELECT name, id_item, file
4187
                FROM '.prefixTable('files').'
4188
                WHERE id = %i',
4189
                $fileId
4190
            );
4191
4192
            // Load item data
4193
            $data_item = DB::queryFirstRow(
4194
                'SELECT id_tree
4195
                FROM '.prefixTable('items').'
4196
                WHERE id = %i',
4197
                $data['id_item']
4198
            );
4199
4200
            // Check that user can access this folder
4201
            if (in_array($data_item['id_tree'], $_SESSION['groupes_visibles']) === false) {
4202
                echo prepareExchangedData(array('error' => 'ERR_FOLDER_NOT_ALLOWED'), 'encode');
4203
                break;
4204
            }
4205
4206
            if (empty($data['id_item']) === false) {
4207
                // Delete from FILES table
4208
                DB::delete(
4209
                    prefixTable('files'),
4210
                    'id = %i',
4211
                    $fileId
4212
                );
4213
4214
                // Update the log
4215
                logItems(
4216
                    $SETTINGS,
4217
                    $data['id_item'],
4218
                    $data['name'],
4219
                    $_SESSION['user_id'],
4220
                    'at_modification',
4221
                    $_SESSION['login'],
4222
                    'at_del_file : '.$data['name']
4223
                );
4224
4225
                // DElete sharekeys
4226
                DB::delete(
4227
                    prefixTable('sharekeys_files'),
4228
                    'object_id = %i',
4229
                    $fileId
4230
                );
4231
4232
                // Delete file from server
4233
                fileDelete($SETTINGS['path_to_upload_folder'].'/'.TP_FILE_PREFIX.base64_decode($data['file']), $SETTINGS);
4234
            }
4235
4236
            echo prepareExchangedData(
4237
                array(
4238
                    'error' => false,
4239
                    'message' => '',
4240
                ),
4241
                'encode'
4242
            );
4243
            break;
4244
4245
        /*
4246
        * CASE
4247
        * Clear HTML tags
4248
        */
4249
        case 'clear_html_tags':
4250
            // Get information for this item
4251
            $dataItem = DB::queryfirstrow(
4252
                'SELECT description FROM '.prefixTable('items').' WHERE id=%i',
4253
                filter_input(INPUT_POST, 'id_item', FILTER_SANITIZE_NUMBER_INT)
4254
            );
4255
            // Clean up the string
4256
            echo json_encode(array('description' => strip_tags($dataItem['description'])), JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP);
4257
            break;
4258
4259
        /*
4260
        * FUNCTION
4261
        * Launch an action when clicking on a quick icon
4262
        * $action = 0 => Make not favorite
4263
        * $action = 1 => Make favorite
4264
        */
4265
        case 'action_on_quick_icon':
4266
            // Check KEY and rights
4267
            if ($post_key !== $_SESSION['key']
4268
                || $_SESSION['user_read_only'] === true || !isset($SETTINGS['pwd_maximum_length'])
4269
            ) {
4270
                // error
4271
                exit();
4272
            }
4273
4274
            if ((int) filter_input(INPUT_POST, 'action', FILTER_SANITIZE_NUMBER_INT) === 0) {
4275
                // Add new favourite
4276
                array_push($_SESSION['favourites'], $post_item_id);
4277
                //print_r($_SESSION['favourites']);
4278
                DB::update(
4279
                    prefixTable('users'),
4280
                    array(
4281
                        'favourites' => implode(';', $_SESSION['favourites']),
4282
                        ),
4283
                    'id = %i',
4284
                    $_SESSION['user_id']
4285
                );
4286
                // Update SESSION with this new favourite
4287
                $data = DB::queryfirstrow(
4288
                    'SELECT label,id_tree
4289
                    FROM '.prefixTable('items').'
4290
                    WHERE id = '.mysqli_real_escape_string($link, $post_item_id)
4291
                );
4292
                $_SESSION['favourites_tab'][$post_item_id] = array(
4293
                    'label' => $data['label'],
4294
                    'url' => 'index.php?page=items&amp;group='.$data['id_tree'].'&amp;id='.$post_item_id,
4295
                    );
4296
            } elseif ((int) filter_input(INPUT_POST, 'action', FILTER_SANITIZE_NUMBER_INT) === 1) {
4297
                // delete from session
4298
                foreach ($_SESSION['favourites'] as $key => $value) {
4299
                    if ($_SESSION['favourites'][$key] === $post_item_id) {
4300
                        unset($_SESSION['favourites'][$key]);
4301
                        break;
4302
                    }
4303
                }
4304
                // delete from DB
4305
                DB::update(
4306
                    prefixTable('users'),
4307
                    array(
4308
                        'favourites' => implode(';', $_SESSION['favourites']),
4309
                    ),
4310
                    'id = %i',
4311
                    $_SESSION['user_id']
4312
                );
4313
                // refresh session fav list
4314
                if (isset($_SESSION['favourites_tab'])) {
4315
                    foreach ($_SESSION['favourites_tab'] as $key => $value) {
4316
                        if ($key == $post_id) {
4317
                            unset($_SESSION['favourites_tab'][$key]);
4318
                            break;
4319
                        }
4320
                    }
4321
                }
4322
            }
4323
            break;
4324
4325
        /*
4326
        * CASE
4327
        * Move an ITEM
4328
        */
4329
        case 'move_item':
4330
            // Check KEY and rights
4331
            if ($post_key !== $_SESSION['key']) {
4332
                echo prepareExchangedData(
4333
                    array(
4334
                        'error' => true,
4335
                        'message' => langHdl('key_is_not_correct'),
4336
                    ),
4337
                    'encode'
4338
                );
4339
                break;
4340
            } elseif ($_SESSION['user_read_only'] === true || isset($SETTINGS['pwd_maximum_length']) === false) {
4341
                echo prepareExchangedData(
4342
                    array(
4343
                        'error' => true,
4344
                        'message' => langHdl('error_not_allowed_to'),
4345
                    ),
4346
                    'encode'
4347
                );
4348
                break;
4349
            }
4350
4351
            // get data about item
4352
            $dataSource = DB::queryfirstrow(
4353
                'SELECT i.pw, f.personal_folder,i.id_tree, f.title,i.label
4354
                FROM '.prefixTable('items').' as i
4355
                INNER JOIN '.prefixTable('nested_tree').' as f ON (i.id_tree=f.id)
4356
                WHERE i.id=%i',
4357
                $post_item_id
4358
            );
4359
4360
            // get data about new folder
4361
            $dataDestination = DB::queryfirstrow(
4362
                'SELECT personal_folder, title
4363
                FROM '.prefixTable('nested_tree').'
4364
                WHERE id = %i',
4365
                $post_folder_id
4366
            );
4367
4368
            // Check that user can access this folder
4369
            if (in_array($dataSource['id_tree'], $_SESSION['groupes_visibles']) === false
4370
                || in_array($post_folder_id, $_SESSION['groupes_visibles']) === false
4371
            ) {
4372
                echo prepareExchangedData(
4373
                    array(
4374
                        'error' => true,
4375
                        'message' => langHdl('error_not_allowed_to'),
4376
                    ),
4377
                    'encode'
4378
                );
4379
                break;
4380
            }
4381
4382
            // Manage possible cases
4383
            if ($dataSource['personal_folder'] === '0' && $dataDestination['personal_folder'] === '0') {
4384
                // Previous is non personal folder and new too
4385
                // Just update is needed. Item key is the same
4386
                DB::update(
4387
                    prefixTable('items'),
4388
                    array(
4389
                        'id_tree' => $post_folder_id,
4390
                        ),
4391
                    'id=%i',
4392
                    $post_item_id
4393
                );
4394
            // ---
4395
                // ---
4396
            } elseif ($dataSource['personal_folder'] === '0' && $dataDestination['personal_folder'] === '1') {
4397
                // Source is public and destination is personal
4398
                // Decrypt and remove all sharekeys (items, fields, files)
4399
                // Encrypt only for the user
4400
4401
                // Remove all item sharekeys items
4402
                DB::delete(
4403
                    prefixTable('sharekeys_items'),
4404
                    'object_id = %i AND user_id != %i',
4405
                    $post_item_id,
4406
                    $_SESSION['user_id']
4407
                );
4408
4409
                // Remove all item sharekeys fields
4410
                // Get fields for this Item
4411
                $rows = DB::query(
4412
                    'SELECT id
4413
                    FROM '.prefixTable('categories_items').'
4414
                    WHERE item_id = %i',
4415
                    $post_item_id
4416
                );
4417
                foreach ($rows as $field) {
4418
                    DB::delete(
4419
                        prefixTable('sharekeys_fields'),
4420
                        'object_id = %i AND user_id != %i',
4421
                        $field['id'],
4422
                        $_SESSION['user_id']
4423
                    );
4424
                }
4425
4426
                // Remove all item sharekeys files
4427
                // Get FILES for this Item
4428
                $rows = DB::query(
4429
                    'SELECT id
4430
                    FROM '.prefixTable('files').'
4431
                    WHERE id_item = %i',
4432
                    $post_item_id
4433
                );
4434
                foreach ($rows as $attachment) {
4435
                    DB::delete(
4436
                        prefixTable('sharekeys_files'),
4437
                        'object_id = %i AND user_id != %i',
4438
                        $attachment['id'],
4439
                        $_SESSION['user_id']
4440
                    );
4441
                }
4442
4443
                // update pw
4444
                DB::update(
4445
                    prefixTable('items'),
4446
                    array(
4447
                        'id_tree' => $post_folder_id,
4448
                        'perso' => 1,
4449
                    ),
4450
                    'id=%i',
4451
                    $post_item_id
4452
                );
4453
            // ---
4454
                // ---
4455
            } elseif ($dataSource['personal_folder'] === '1' && $dataDestination['personal_folder'] === '1') {
4456
                // If previous is personal folder and new is personal folder too => no key exist on item
4457
                // just update is needed. Item key is the same
4458
                DB::update(
4459
                    prefixTable('items'),
4460
                    array(
4461
                        'id_tree' => $post_folder_id,
4462
                    ),
4463
                    'id=%i',
4464
                    $post_item_id
4465
                );
4466
            // ---
4467
                // ---
4468
            } elseif ($dataSource['personal_folder'] === '1' && $dataDestination['personal_folder'] === '0') {
4469
                // If previous is personal folder and new is not personal folder => no key exist on item => add new
4470
                // Create keys for all users
4471
4472
                // Get the ITEM object key for the user
4473
                $userKey = DB::queryFirstRow(
4474
                    'SELECT share_key
4475
                    FROM '.prefixTable('sharekeys_items').'
4476
                    WHERE user_id = %i AND object_id = %i',
4477
                    $_SESSION['user_id'],
4478
                    $post_item_id
4479
                );
4480
                if (DB::count() > 0) {
4481
                    $objectKey = decryptUserObjectKey($userKey['share_key'], $_SESSION['user']['private_key']);
4482
4483
                    // This is a public object
4484
                    $users = DB::query(
4485
                        'SELECT id, public_key
4486
                        FROM '.prefixTable('users').'
4487
                        WHERE id NOT IN ("'.OTV_USER_ID.'","'.SSH_USER_ID.'","'.API_USER_ID.'","'.$_SESSION['user_id'].'")
4488
                        AND public_key != ""'
4489
                    );
4490
                    foreach ($users as $user) {
4491
                        // Insert in DB the new object key for this item by user
4492
                        DB::insert(
4493
                            prefixTable('sharekeys_items'),
4494
                            array(
4495
                                'object_id' => $post_item_id,
4496
                                'user_id' => $user['id'],
4497
                                'share_key' => encryptUserObjectKey($objectKey, $user['public_key']),
4498
                            )
4499
                        );
4500
                    }
4501
                }
4502
4503
                // Get the FIELDS object key for the user
4504
                // Get fields for this Item
4505
                $rows = DB::query(
4506
                    'SELECT id
4507
                    FROM '.prefixTable('categories_items').'
4508
                    WHERE item_id = %i',
4509
                    $post_item_id
4510
                );
4511
                foreach ($rows as $field) {
4512
                    $userKey = DB::queryFirstRow(
4513
                        'SELECT share_key
4514
                        FROM '.prefixTable('sharekeys_fields').'
4515
                        WHERE user_id = %i AND object_id = %i',
4516
                        $_SESSION['user_id'],
4517
                        $field['id']
4518
                    );
4519
                    if (DB::count() > 0) {
4520
                        $objectKey = decryptUserObjectKey($userKey['share_key'], $_SESSION['user']['private_key']);
4521
4522
                        // This is a public object
4523
                        $users = DB::query(
4524
                            'SELECT id, public_key
4525
                            FROM '.prefixTable('users').'
4526
                            WHERE id NOT IN ("'.OTV_USER_ID.'","'.SSH_USER_ID.'","'.API_USER_ID.'","'.$_SESSION['user_id'].'")
4527
                            AND public_key != ""'
4528
                        );
4529
                        foreach ($users as $user) {
4530
                            // Insert in DB the new object key for this item by user
4531
                            DB::insert(
4532
                                prefixTable('sharekeys_fields'),
4533
                                array(
4534
                                    'object_id' => $field['id'],
4535
                                    'user_id' => $user['id'],
4536
                                    'share_key' => encryptUserObjectKey($objectKey, $user['public_key']),
4537
                                )
4538
                            );
4539
                        }
4540
                    }
4541
                }
4542
4543
                // Get the FILE object key for the user
4544
                // Get FILES for this Item
4545
                $rows = DB::query(
4546
                    'SELECT id
4547
                    FROM '.prefixTable('files').'
4548
                    WHERE id_item = %i',
4549
                    $post_item_id
4550
                );
4551
                foreach ($rows as $attachment) {
4552
                    $userKey = DB::queryFirstRow(
4553
                        'SELECT share_key
4554
                        FROM '.prefixTable('sharekeys_files').'
4555
                        WHERE user_id = %i AND object_id = %i',
4556
                        $_SESSION['user_id'],
4557
                        $attachment['id']
4558
                    );
4559
                    if (DB::count() > 0) {
4560
                        $objectKey = decryptUserObjectKey($userKey['share_key'], $_SESSION['user']['private_key']);
4561
4562
                        // This is a public object
4563
                        $users = DB::query(
4564
                            'SELECT id, public_key
4565
                            FROM '.prefixTable('users').'
4566
                            WHERE id NOT IN ("'.OTV_USER_ID.'","'.SSH_USER_ID.'","'.API_USER_ID.'","'.$_SESSION['user_id'].'")
4567
                            AND public_key != ""'
4568
                        );
4569
                        foreach ($users as $user) {
4570
                            // Insert in DB the new object key for this item by user
4571
                            DB::insert(
4572
                                prefixTable('sharekeys_files'),
4573
                                array(
4574
                                    'object_id' => $attachment['id'],
4575
                                    'user_id' => $user['id'],
4576
                                    'share_key' => encryptUserObjectKey($objectKey, $user['public_key']),
4577
                                )
4578
                            );
4579
                        }
4580
                    }
4581
                }
4582
4583
                // update item
4584
                DB::update(
4585
                    prefixTable('items'),
4586
                    array(
4587
                        'id_tree' => $post_folder_id,
4588
                        'perso' => 0,
4589
                    ),
4590
                    'id=%i',
4591
                    $post_item_id
4592
                );
4593
            }
4594
4595
            // Log item moved
4596
            logItems(
4597
                $SETTINGS,
4598
                $post_item_id,
4599
                $dataSource['label'],
4600
                $_SESSION['user_id'],
4601
                'at_modification',
4602
                $_SESSION['login'],
4603
                'at_moved : '.$dataSource['title'].' -> '.$dataDestination['title']
4604
            );
4605
4606
            $returnValues = array(
4607
                'error' => '',
4608
                'message' => '',
4609
                'from_folder' => $dataSource['id_tree'],
4610
                'to_folder' => $post_folder_id,
4611
            );
4612
            echo prepareExchangedData($returnValues, 'encode');
4613
            break;
4614
4615
        /*
4616
        * CASE
4617
        * MASSIVE Move an ITEM
4618
        */
4619
        case 'mass_move_items':
4620
            // Check KEY and rights
4621
            if ($post_key !== $_SESSION['key']) {
4622
                echo prepareExchangedData(
4623
                    array(
4624
                        'error' => true,
4625
                        'message' => langHdl('key_is_not_correct'),
4626
                    ),
4627
                    'encode'
4628
                );
4629
                break;
4630
            } elseif ($_SESSION['user_read_only'] === true || isset($SETTINGS['pwd_maximum_length']) === false) {
4631
                echo prepareExchangedData(
4632
                    array(
4633
                        'error' => true,
4634
                        'message' => langHdl('error_not_allowed_to'),
4635
                    ),
4636
                    'encode'
4637
                );
4638
                break;
4639
            }
4640
4641
            // decrypt and retreive data in JSON format
4642
            $dataReceived = prepareExchangedData(
4643
                $post_data,
4644
                'decode'
4645
            );
4646
            $post_folder_id = filter_var($dataReceived['folder_id'], FILTER_SANITIZE_NUMBER_INT);
4647
            $post_item_ids = filter_var($dataReceived['item_ids'], FILTER_SANITIZE_STRING);
4648
4649
            // loop on items to move
4650
            foreach (explode(';', $post_item_ids) as $item_id) {
4651
                if (empty($item_id) === false) {
4652
                    // get data about item
4653
                    $dataSource = DB::queryfirstrow(
4654
                        'SELECT i.pw, f.personal_folder,i.id_tree, f.title,i.label
4655
                        FROM '.prefixTable('items').' as i
4656
                        INNER JOIN '.prefixTable('nested_tree').' as f ON (i.id_tree=f.id)
4657
                        WHERE i.id=%i',
4658
                        $item_id
4659
                    );
4660
4661
                    // Check that user can access this folder
4662
                    if (in_array($dataSource['id_tree'], $_SESSION['groupes_visibles']) === false
4663
                        || in_array($post_folder_id, $_SESSION['groupes_visibles']) === false
4664
                    ) {
4665
                        echo prepareExchangedData(
4666
                            array(
4667
                                'error' => true,
4668
                                'message' => langHdl('error_not_allowed_to'),
4669
                            ),
4670
                            'encode'
4671
                        );
4672
                        exit();
4673
                    }
4674
4675
                    // get data about new folder
4676
                    $dataDestination = DB::queryfirstrow(
4677
                        'SELECT personal_folder, title FROM '.prefixTable('nested_tree').' WHERE id = %i',
4678
                        $post_folder_id
4679
                    );
4680
4681
                    // previous is non personal folder and new too
4682
                    if ((int) $dataSource['personal_folder'] === 0
4683
                        && (int) $dataDestination['personal_folder'] === 0
4684
                    ) {
4685
                        // just update is needed. Item key is the same
4686
                        DB::update(
4687
                            prefixTable('items'),
4688
                            array(
4689
                                'id_tree' => $post_folder_id,
4690
                                ),
4691
                            'id = %i',
4692
                            $item_id
4693
                        );
4694
                    // ---
4695
                        // ---
4696
                        // ---
4697
                    } elseif ((int) $dataSource['personal_folder'] === 0
4698
                        && (int) $dataDestination['personal_folder'] === 1
4699
                    ) {
4700
                        // Source is public and destination is personal
4701
                        // Decrypt and remove all sharekeys (items, fields, files)
4702
                        // Encrypt only for the user
4703
4704
                        // Remove all item sharekeys items
4705
                        DB::delete(
4706
                            prefixTable('sharekeys_items'),
4707
                            'object_id = %i AND user_id != %i',
4708
                            $item_id,
4709
                            $_SESSION['user_id']
4710
                        );
4711
4712
                        // Remove all item sharekeys fields
4713
                        // Get fields for this Item
4714
                        $rows = DB::query(
4715
                            'SELECT id
4716
                            FROM '.prefixTable('categories_items').'
4717
                            WHERE item_id = %i',
4718
                            $item_id
4719
                        );
4720
                        foreach ($rows as $field) {
4721
                            DB::delete(
4722
                                prefixTable('sharekeys_fields'),
4723
                                'object_id = %i AND user_id != %i',
4724
                                $field['id'],
4725
                                $_SESSION['user_id']
4726
                            );
4727
                        }
4728
4729
                        // Remove all item sharekeys files
4730
                        // Get FILES for this Item
4731
                        $rows = DB::query(
4732
                            'SELECT id
4733
                            FROM '.prefixTable('files').'
4734
                            WHERE id_item = %i',
4735
                            $item_id
4736
                        );
4737
                        foreach ($rows as $attachment) {
4738
                            DB::delete(
4739
                                prefixTable('sharekeys_files'),
4740
                                'object_id = %i AND user_id != %i',
4741
                                $attachment['id'],
4742
                                $_SESSION['user_id']
4743
                            );
4744
                        }
4745
4746
                        // update pw
4747
                        DB::update(
4748
                            prefixTable('items'),
4749
                            array(
4750
                                'id_tree' => $post_folder_id,
4751
                                'perso' => 1,
4752
                            ),
4753
                            'id = %i',
4754
                            $item_id
4755
                        );
4756
                    // ---
4757
                        // ---
4758
                        // ---
4759
                    } elseif ((int) $dataSource['personal_folder'] === 1
4760
                        && (int) $dataDestination['personal_folder'] === 1
4761
                    ) {
4762
                        // If previous is personal folder and new is personal folder too => no key exist on item
4763
                        // just update is needed. Item key is the same
4764
                        DB::update(
4765
                            prefixTable('items'),
4766
                            array(
4767
                                'id_tree' => $post_folder_id,
4768
                            ),
4769
                            'id = %i',
4770
                            $item_id
4771
                        );
4772
                    // ---
4773
                        // ---
4774
                        // ---
4775
                    } elseif ((int) $dataSource['personal_folder'] === 1
4776
                        && (int) $dataDestination['personal_folder'] === 0
4777
                    ) {
4778
                        // If previous is personal folder and new is not personal folder => no key exist on item => add new
4779
                        // Create keys for all users
4780
4781
                        // Get the ITEM object key for the user
4782
                        $userKey = DB::queryFirstRow(
4783
                            'SELECT share_key
4784
                            FROM '.prefixTable('sharekeys_items').'
4785
                            WHERE user_id = %i AND object_id = %i',
4786
                            $_SESSION['user_id'],
4787
                            $item_id
4788
                        );
4789
                        if (DB::count() > 0) {
4790
                            $objectKey = decryptUserObjectKey($userKey['share_key'], $_SESSION['user']['private_key']);
4791
4792
                            // This is a public object
4793
                            $users = DB::query(
4794
                                'SELECT id, public_key
4795
                                FROM '.prefixTable('users').'
4796
                                WHERE id NOT IN ("'.OTV_USER_ID.'","'.SSH_USER_ID.'","'.API_USER_ID.'","'.$_SESSION['user_id'].'")
4797
                                AND public_key != ""'
4798
                            );
4799
                            foreach ($users as $user) {
4800
                                // Insert in DB the new object key for this item by user
4801
                                DB::insert(
4802
                                    prefixTable('sharekeys_items'),
4803
                                    array(
4804
                                        'object_id' => $item_id,
4805
                                        'user_id' => $user['id'],
4806
                                        'share_key' => encryptUserObjectKey($objectKey, $user['public_key']),
4807
                                    )
4808
                                );
4809
                            }
4810
                        }
4811
4812
                        // Get the FIELDS object key for the user
4813
                        // Get fields for this Item
4814
                        $rows = DB::query(
4815
                            'SELECT id
4816
                            FROM '.prefixTable('categories_items').'
4817
                            WHERE item_id = %i',
4818
                            $item_id
4819
                        );
4820
                        foreach ($rows as $field) {
4821
                            $userKey = DB::queryFirstRow(
4822
                                'SELECT share_key
4823
                                FROM '.prefixTable('sharekeys_fields').'
4824
                                WHERE user_id = %i AND object_id = %i',
4825
                                $_SESSION['user_id'],
4826
                                $field['id']
4827
                            );
4828
                            if (DB::count() > 0) {
4829
                                $objectKey = decryptUserObjectKey($userKey['share_key'], $_SESSION['user']['private_key']);
4830
4831
                                // This is a public object
4832
                                $users = DB::query(
4833
                                    'SELECT id, public_key
4834
                                    FROM '.prefixTable('users').'
4835
                                    WHERE id NOT IN ("'.OTV_USER_ID.'","'.SSH_USER_ID.'","'.API_USER_ID.'","'.$_SESSION['user_id'].'")
4836
                                    AND public_key != ""'
4837
                                );
4838
                                foreach ($users as $user) {
4839
                                    // Insert in DB the new object key for this item by user
4840
                                    DB::insert(
4841
                                        prefixTable('sharekeys_fields'),
4842
                                        array(
4843
                                            'object_id' => $field['id'],
4844
                                            'user_id' => $user['id'],
4845
                                            'share_key' => encryptUserObjectKey($objectKey, $user['public_key']),
4846
                                        )
4847
                                    );
4848
                                }
4849
                            }
4850
                        }
4851
4852
                        // Get the FILE object key for the user
4853
                        // Get FILES for this Item
4854
                        $rows = DB::query(
4855
                            'SELECT id
4856
                            FROM '.prefixTable('files').'
4857
                            WHERE id_item = %i',
4858
                            $item_id
4859
                        );
4860
                        foreach ($rows as $attachment) {
4861
                            $userKey = DB::queryFirstRow(
4862
                                'SELECT share_key
4863
                                FROM '.prefixTable('sharekeys_files').'
4864
                                WHERE user_id = %i AND object_id = %i',
4865
                                $_SESSION['user_id'],
4866
                                $attachment['id']
4867
                            );
4868
                            if (DB::count() > 0) {
4869
                                $objectKey = decryptUserObjectKey($userKey['share_key'], $_SESSION['user']['private_key']);
4870
4871
                                // This is a public object
4872
                                $users = DB::query(
4873
                                    'SELECT id, public_key
4874
                                    FROM '.prefixTable('users').'
4875
                                    WHERE id NOT IN ("'.OTV_USER_ID.'","'.SSH_USER_ID.'","'.API_USER_ID.'","'.$_SESSION['user_id'].'")
4876
                                    AND public_key != ""'
4877
                                );
4878
                                foreach ($users as $user) {
4879
                                    // Insert in DB the new object key for this item by user
4880
                                    DB::insert(
4881
                                        prefixTable('sharekeys_files'),
4882
                                        array(
4883
                                            'object_id' => $attachment['id'],
4884
                                            'user_id' => $user['id'],
4885
                                            'share_key' => encryptUserObjectKey($objectKey, $user['public_key']),
4886
                                        )
4887
                                    );
4888
                                }
4889
                            }
4890
                        }
4891
4892
                        // update item
4893
                        DB::update(
4894
                            prefixTable('items'),
4895
                            array(
4896
                                'id_tree' => $post_folder_id,
4897
                                'perso' => 0,
4898
                            ),
4899
                            'id=%i',
4900
                            $item_id
4901
                        );
4902
4903
                        //----
4904
                        // If previous is personal folder and new is not personal folder => no key exist on item => add new
4905
                        $decrypt = cryption(
4906
                            $dataSource['pw'],
4907
                            stripslashes($_SESSION['user_settings']['session_psk']),
4908
                            'decrypt',
4909
                            $SETTINGS
4910
                        );
4911
                        $encrypt = cryption(
4912
                            $decrypt['string'],
4913
                            '',
4914
                            'encrypt',
4915
                            $SETTINGS
4916
                        );
4917
4918
                        // update item
4919
                        DB::update(
4920
                            prefixTable('items'),
4921
                            array(
4922
                                'id_tree' => $post_folder_id,
4923
                                'pw' => $encrypt['string'],
4924
                                'pw_iv' => '',
4925
                                'perso' => 0,
4926
                            ),
4927
                            'id=%i',
4928
                            $item_id
4929
                        );
4930
                    }
4931
                    // Log item moved
4932
                    logItems(
4933
                        $SETTINGS,
4934
                        $item_id,
4935
                        $dataSource['label'],
4936
                        $_SESSION['user_id'],
4937
                        'at_modification',
4938
                        $_SESSION['login'],
4939
                        'at_moved : '.$dataSource['title'].' -> '.$dataDestination['title']
4940
                    );
4941
                }
4942
            }
4943
4944
            // reload cache table
4945
            require_once $SETTINGS['cpassman_dir'].'/sources/main.functions.php';
4946
            updateCacheTable('reload', $SETTINGS, '');
4947
4948
            echo prepareExchangedData(
4949
                array(
4950
                    'error' => false,
4951
                    'message' => '',
4952
                ),
4953
                'encode'
4954
            );
4955
            break;
4956
4957
        /*
4958
         * CASE
4959
         * MASSIVE Delete an item
4960
        */
4961
        case 'mass_delete_items':
4962
            // Check KEY and rights
4963
            if ($post_key !== $_SESSION['key']) {
4964
                echo prepareExchangedData(
4965
                    array(
4966
                        'error' => true,
4967
                        'message' => langHdl('key_is_not_correct'),
4968
                    ),
4969
                    'encode'
4970
                );
4971
                break;
4972
            } elseif ($_SESSION['user_read_only'] === true) {
4973
                echo prepareExchangedData(
4974
                    array(
4975
                        'error' => true,
4976
                        'message' => langHdl('error_not_allowed_to'),
4977
                    ),
4978
                    'encode'
4979
                );
4980
                break;
4981
            }
4982
4983
            // decrypt and retreive data in JSON format
4984
            $dataReceived = prepareExchangedData(
4985
                $post_data,
4986
                'decode'
4987
            );
4988
            $post_item_ids = filter_var($dataReceived['item_ids'], FILTER_SANITIZE_STRING);
4989
4990
            // perform a check in case of Read-Only user creating an item in his PF
4991
            if ($_SESSION['user_read_only'] === true) {
4992
                echo prepareExchangedData(
4993
                    array(
4994
                        'error' => true,
4995
                        'message' => langHdl('error_not_allowed_to'),
4996
                    ),
4997
                    'encode'
4998
                );
4999
                break;
5000
            }
5001
5002
            // loop on items to move
5003
            foreach (explode(';', $post_item_ids) as $item_id) {
5004
                if (empty($item_id) === false) {
5005
                    // get info
5006
                    $dataSource = DB::queryfirstrow(
5007
                        'SELECT label, id_tree
5008
                        FROM '.prefixTable('items').'
5009
                        WHERE id=%i',
5010
                        $item_id
5011
                    );
5012
5013
                    // Check that user can access this folder
5014
                    if (in_array($dataSource['id_tree'], $_SESSION['groupes_visibles']) === false
5015
                    ) {
5016
                        echo prepareExchangedData(
5017
                            array(
5018
                                'error' => true,
5019
                                'message' => langHdl('error_not_allowed_to'),
5020
                            ),
5021
                            'encode'
5022
                        );
5023
                        break;
5024
                    }
5025
5026
                    // delete item consists in disabling it
5027
                    DB::update(
5028
                        prefixTable('items'),
5029
                        array(
5030
                            'inactif' => '1',
5031
                            ),
5032
                        'id = %i',
5033
                        $item_id
5034
                    );
5035
5036
                    // log
5037
                    logItems(
5038
                        $SETTINGS,
5039
                        $item_id,
5040
                        $dataSource['label'],
5041
                        $_SESSION['user_id'],
5042
                        'at_delete',
5043
                        $_SESSION['login']
5044
                    );
5045
5046
                    // Update CACHE table
5047
                    updateCacheTable('delete_value', $SETTINGS, $item_id);
5048
                }
5049
            }
5050
5051
            echo prepareExchangedData(
5052
                array(
5053
                    'error' => false,
5054
                    'message' => '',
5055
                ),
5056
                'encode'
5057
            );
5058
            break;
5059
5060
            break;
5061
5062
            /*
5063
           * CASE
5064
           * Send email
5065
        */
5066
        case 'send_email':
5067
            // Check KEY
5068
            if ($post_key !== $_SESSION['key']) {
5069
                echo prepareExchangedData(
5070
                    array(
5071
                        'error' => true,
5072
                        'message' => langHdl('key_is_not_correct'),
5073
                    ),
5074
                    'encode'
5075
                );
5076
                break;
5077
            } elseif ($_SESSION['user_read_only'] === true) {
5078
                echo prepareExchangedData(
5079
                    array(
5080
                        'error' => true,
5081
                        'message' => langHdl('error_not_allowed_to'),
5082
                    ),
5083
                    'encode'
5084
                );
5085
                break;
5086
            }
5087
5088
             // decrypt and retrieve data in JSON format
5089
             $dataReceived = prepareExchangedData($post_data, 'decode');
5090
5091
            // Prepare variables
5092
            $post_id = filter_var($dataReceived['id'], FILTER_SANITIZE_NUMBER_INT);
5093
            $post_receipt = filter_var($dataReceived['receipt'], FILTER_SANITIZE_STRING);
5094
            $post_cat = filter_var($dataReceived['cat'], FILTER_SANITIZE_STRING);
5095
5096
            // get links url
5097
            if (empty($SETTINGS['email_server_url']) === true) {
5098
                $SETTINGS['email_server_url'] = $SETTINGS['cpassman_url'];
5099
            }
5100
            if ($post_cat === 'request_access_to_author') {
5101
                // Content
5102
                if (empty(filter_input(INPUT_POST, 'content', FILTER_SANITIZE_STRING)) === false) {
5103
                    $content = explode(',', filter_input(INPUT_POST, 'content', FILTER_SANITIZE_STRING));
5104
                }
5105
                // Variables
5106
                $dataAuthor = DB::queryfirstrow('SELECT email,login FROM '.prefixTable('users').' WHERE id= '.$content[1]);
5107
                $dataItem = DB::queryfirstrow('SELECT label, id_tree FROM '.prefixTable('items').' WHERE id= '.$content[0]);
5108
5109
                // Get path
5110
                $path = prepareEmaiItemPath(
5111
                    $dataItem['id_tree'],
5112
                    $dataItem['label'],
5113
                    $SETTINGS
5114
                );
5115
5116
                $ret = json_decode(
5117
                    sendEmail(
5118
                        langHdl('email_request_access_subject'),
5119
                        str_replace(
5120
                            array('#tp_item_author#', '#tp_user#', '#tp_item#'),
5121
                            array(' '.addslashes($dataAuthor['login']), addslashes($_SESSION['login']), $path),
5122
                            langHdl('email_request_access_mail')
5123
                        ),
5124
                        $dataAuthor['email'],
5125
                        $SETTINGS
5126
                    ),
5127
                    true
5128
                );
5129
            } elseif ($post_cat === 'share_this_item') {
5130
                $dataItem = DB::queryfirstrow(
5131
                    'SELECT label,id_tree
5132
                    FROM '.prefixTable('items').'
5133
                    WHERE id= %i',
5134
                    $post_id
5135
                );
5136
5137
                // Get path
5138
                $path = prepareEmaiItemPath(
5139
                    $dataItem['id_tree'],
5140
                    $dataItem['label'],
5141
                    $SETTINGS
5142
                );
5143
5144
                // send email
5145
                $ret = json_decode(
5146
                    sendEmail(
5147
                        langHdl('email_share_item_subject'),
5148
                        str_replace(
5149
                            array(
5150
                                '#tp_link#',
5151
                                '#tp_user#',
5152
                                '#tp_item#',
5153
                            ),
5154
                            array(
5155
                                empty($SETTINGS['email_server_url']) === false ?
5156
                                $SETTINGS['email_server_url'].'/index.php?page=items&group='.$dataItem['id_tree'].'&id='.$post_id :
5157
                                $SETTINGS['cpassman_url'].'/index.php?page=items&group='.$dataItem['id_tree'].'&id='.$post_id,
5158
                                addslashes($_SESSION['login']),
5159
                                addslashes($path),
5160
                            ),
5161
                            langHdl('email_share_item_mail')
5162
                        ),
5163
                        $post_receipt,
5164
                        $SETTINGS
5165
                    ),
5166
                    true
5167
                );
5168
            }
5169
5170
            echo prepareExchangedData(
5171
                array(
5172
                    'error' => empty($ret['error']) === true ? false : true,
5173
                    'message' => $ret['message'],
5174
                ),
5175
                'encode'
5176
            );
5177
5178
            break;
5179
5180
        /*
5181
           * CASE
5182
           * manage notification of an Item
5183
        */
5184
        case 'notify_a_user':
5185
            if ($post_key !== $_SESSION['key']) {
5186
                echo '[{"error" : "something_wrong"}]';
5187
                break;
5188
            } else {
5189
                if (filter_input(INPUT_POST, 'notify_type', FILTER_SANITIZE_STRING) === 'on_show') {
5190
                    // Check if values already exist
5191
                    $data = DB::queryfirstrow(
5192
                        'SELECT notification FROM '.prefixTable('items').' WHERE id = %i',
5193
                        $post_item_id
5194
                    );
5195
                    $notifiedUsers = explode(';', $data['notification']);
5196
                    // User is not in actual notification list
5197
                    if ($post_status === 'true' && !in_array($post_user_id, $notifiedUsers)) {
5198
                        // User is not in actual notification list and wants to be notified
5199
                        DB::update(
5200
                            prefixTable('items'),
5201
                            array(
5202
                                'notification' => empty($data['notification']) ?
5203
                                    filter_input(INPUT_POST, 'user_id', FILTER_SANITIZE_NUMBER_INT).';'
5204
                                    : $data['notification'].filter_input(INPUT_POST, 'user_id', FILTER_SANITIZE_NUMBER_INT),
5205
                                ),
5206
                            'id=%i',
5207
                            $post_item_id
5208
                        );
5209
                        echo '[{"error" : "", "new_status":"true"}]';
5210
                        break;
5211
                    } elseif ($post_status === false && in_array($post_user_id, $notifiedUsers)) {
5212
                        // TODO : delete user from array and store in DB
5213
                        // User is in actual notification list and doesn't want to be notified
5214
                        DB::update(
5215
                            prefixTable('items'),
5216
                            array(
5217
                                'notification' => empty($data['notification']) ?
5218
                                    filter_input(INPUT_POST, 'user_id', FILTER_SANITIZE_NUMBER_INT)
5219
                                    : $data['notification'].';'.filter_input(INPUT_POST, 'user_id', FILTER_SANITIZE_NUMBER_INT),
5220
                                ),
5221
                            'id=%i',
5222
                            $post_item_id
5223
                        );
5224
                    }
5225
                }
5226
            }
5227
            break;
5228
5229
        /*
5230
        * CASE
5231
        * Item History Log - add new entry
5232
        */
5233
        case 'history_entry_add':
5234
            if ($post_key !== $_SESSION['key']) {
5235
                $data = array('error' => 'key_is_wrong');
5236
                echo prepareExchangedData($data, 'encode');
5237
                break;
5238
            } else {
5239
                // decrypt and retreive data in JSON format
5240
                $dataReceived = prepareExchangedData($post_data, 'decode');
5241
                // Get all informations for this item
5242
                $dataItem = DB::queryfirstrow(
5243
                    'SELECT *
5244
                    FROM '.prefixTable('items').' as i
5245
                    INNER JOIN '.prefixTable('log_items').' as l ON (l.id_item = i.id)
5246
                    WHERE i.id=%i AND l.action = %s',
5247
                    $dataReceived['item_id'],
5248
                    'at_creation'
5249
                );
5250
                // check that actual user can access this item
5251
                $restrictionActive = true;
5252
                $restrictedTo = array_filter(explode(';', $dataItem['restricted_to']));
5253
                if (in_array($_SESSION['user_id'], $restrictedTo)) {
5254
                    $restrictionActive = false;
5255
                }
5256
                if (empty($dataItem['restricted_to'])) {
5257
                    $restrictionActive = false;
5258
                }
5259
5260
                if ((
5261
                        (in_array($dataItem['id_tree'], $_SESSION['groupes_visibles'])) && ($dataItem['perso'] === '0' || ($dataItem['perso'] === '1' && $dataItem['id_user'] == $_SESSION['user_id'])) && $restrictionActive === false
5262
                    )
5263
                    ||
5264
                    (
5265
                        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
5266
                    )
5267
                    ||
5268
                    (@in_array(
5269
                        $post_id,
5270
                        $_SESSION['list_folders_limited'][$post_folder_id]
5271
                    ))
5272
                ) {
5273
                    $error = '';
5274
                    // Query
5275
                    logItems(
5276
                        $SETTINGS,
5277
                        $dataReceived['item_id'],
5278
                        $dataItem['label'],
5279
                        $_SESSION['user_id'],
5280
                        'at_manual',
5281
                        $_SESSION['login'],
5282
                        htmlspecialchars_decode($dataReceived['label'], ENT_QUOTES)
5283
                    );
5284
                    // Prepare new line
5285
                    $data = DB::queryfirstrow(
5286
                        'SELECT * FROM '.prefixTable('log_items').' WHERE id_item = %i ORDER BY date DESC',
5287
                        $dataReceived['item_id']
5288
                    );
5289
                    $historic = date($SETTINGS['date_format'].' '.$SETTINGS['time_format'], $data['date']).' - '.$_SESSION['login'].' - '.langHdl($data['action']).' - '.$data['raison'];
5290
                    // send back
5291
                    $data = array(
5292
                        'error' => '',
5293
                        'new_line' => '<br>'.addslashes($historic),
5294
                    );
5295
                    echo prepareExchangedData($data, 'encode');
5296
                } else {
5297
                    $data = array('error' => 'something_wrong');
5298
                    echo prepareExchangedData($data, 'encode');
5299
                    break;
5300
                }
5301
            }
5302
            break;
5303
5304
        /*
5305
        * CASE
5306
        * Free Item for Edition
5307
        */
5308
        case 'free_item_for_edition':
5309
            // Check KEY
5310
            if ($post_key !== $_SESSION['key']) {
5311
                echo '[ { "error" : "key_not_conform" } ]';
5312
                break;
5313
            }
5314
            // Do
5315
            DB::delete(
5316
                prefixTable('items_edition'),
5317
                'item_id = %i',
5318
                $post_id
5319
            );
5320
            break;
5321
5322
        /*
5323
        * CASE
5324
        * Check if Item has been changed since loaded
5325
        */
5326
        case 'is_item_changed':
5327
            $data = DB::queryFirstRow(
5328
                'SELECT date FROM '.prefixTable('log_items').' WHERE action = %s AND id_item = %i ORDER BY date DESC',
5329
                'at_modification',
5330
                $post_item_id
5331
            );
5332
            // Check if it's in a personal folder. If yes, then force complexity overhead.
5333
            if ($data['date'] > filter_input(INPUT_POST, 'timestamp', FILTER_SANITIZE_STRING)) {
5334
                echo '{ "modified" : "1" }';
5335
            } else {
5336
                echo '{ "modified" : "0" }';
5337
            }
5338
            break;
5339
5340
        /*
5341
        * CASE
5342
        * Check if Item has been changed since loaded
5343
        */
5344
        case 'generate_OTV_url':
5345
            // Check KEY
5346
            if ($post_key !== $_SESSION['key']) {
5347
                echo '[ { "error" : "key_not_conform" } ]';
5348
                break;
5349
            }
5350
5351
            // delete all existing old otv codes
5352
            $rows = DB::query('SELECT id FROM '.prefixTable('otv').' WHERE timestamp < '.(time() - $SETTINGS['otv_expiration_period'] * 86400));
5353
            foreach ($rows as $record) {
5354
                DB::delete(prefixTable('otv'), 'id=%i', $record['id']);
5355
            }
5356
5357
            // generate session
5358
            $otv_code = GenerateCryptKey(32, false, true, true, false);
5359
            $otv_user_code = GenerateCryptKey(32, false, true, true, false);
5360
<<<<<<< HEAD
0 ignored issues
show
Bug introduced by
A parse error occurred: Syntax error, unexpected T_SL on line 5360 at column 0
Loading history...
5361
=======
5362
5363
            // Generate Defuse key
5364
            $otv_user_code_encrypted = defuse_generate_personal_key($otv_user_code);
5365
5366
            // check if psk is correct.
5367
            $otv_key_encoded = defuse_validate_personal_key(
5368
                $otv_user_code,
5369
                $otv_user_code_encrypted
5370
            );
5371
5372
            // Decrypt the pwd
5373
            // Should we log a password change?
5374
            $itemQ = DB::queryFirstRow(
5375
                'SELECT s.share_key, i.pw
5376
                FROM '.prefixTable('items').' AS i
5377
                INNER JOIN '.prefixTable('sharekeys_items').' AS s ON (i.id = s.object_id)
5378
                WHERE s.user_id = %i AND s.object_id = %i',
5379
                $_SESSION['user_id'],
5380
                $post_id
5381
            );
5382
            if (DB::count() === 0 || empty($itemQ['pw']) === true) {
5383
                // No share key found
5384
                $pw = '';
5385
            } else {
5386
                $pw = base64_decode(doDataDecryption(
5387
                    $itemQ['pw'],
5388
                    decryptUserObjectKey(
5389
                        $itemQ['share_key'],
5390
                        $_SESSION['user']['private_key']
5391
                    )
5392
                ));
5393
            }
5394
5395
            // Encrypt it with DEFUSE using the generated code as key
5396
            // This is required as the OTV is used by someone without any Teampass account
5397
            $passwd = cryption(
5398
                $pw,
5399
                $otv_key_encoded,
5400
                'encrypt',
5401
                $SETTINGS
5402
            );
5403
>>>>>>> 7a37a6c5... 3.0.0
5404
5405
            DB::insert(
5406
                prefixTable('otv'),
5407
                array(
5408
                    'id' => null,
5409
                    'item_id' => $post_id,
5410
                    'timestamp' => time(),
5411
                    'originator' => intval($_SESSION['user_id']),
5412
                    'code' => $otv_code,
5413
                    'encrypted' => $passwd['string'],
5414
                    )
5415
            );
5416
            $newID = DB::insertId();
5417
5418
            // Prepare URL content
5419
            $otv_session = array(
5420
                'code' => $otv_code,
5421
                'key' => $otv_user_code,
5422
                'stamp' => time(),
5423
            );
5424
5425
            if (isset($SETTINGS['otv_expiration_period']) === false) {
5426
                $SETTINGS['otv_expiration_period'] = 7;
5427
            }
5428
            $url = $SETTINGS['cpassman_url'].'/index.php?otv=true&'.http_build_query($otv_session);
5429
            $exp_date = date($SETTINGS['date_format'].' '.$SETTINGS['time_format'], time() + (intval($SETTINGS['otv_expiration_period']) * 86400));
5430
5431
            echo json_encode(
5432
                array(
5433
                    'error' => '',
5434
                    'url' => $url,
5435
                    /*'text' => str_replace(
5436
                        array('#URL#', '#DAY#'),
5437
                        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),
5438
                        langHdl('one_time_view_item_url_box')
5439
                    ),*/
5440
                )
5441
            );
5442
            break;
5443
5444
        /*
5445
        * CASE
5446
        * Free Item for Edition
5447
        */
5448
        case 'image_preview_preparation':
5449
            // Check KEY
5450
            if ($post_key !== $_SESSION['key']) {
5451
                echo prepareExchangedData(
5452
                    array(
5453
                        'error' => true,
5454
                        'message' => langHdl('key_is_not_correct'),
5455
                    ),
5456
                    'encode'
5457
                );
5458
                break;
5459
            }
5460
5461
            // get file info
5462
            $file_info = DB::queryfirstrow(
5463
                'SELECT f.id AS id, f.file AS file, f.name AS name, f.status AS status,
5464
                f.extension AS extension, f.type AS type,
5465
                s.share_key AS share_key
5466
                FROM '.prefixTable('files').' AS f
5467
                INNER JOIN '.prefixTable('sharekeys_files').' AS s ON (f.id = s.object_id)
5468
                WHERE s.user_id = %i AND s.object_id = %i',
5469
                $_SESSION['user_id'],
5470
                $post_id
5471
            );
5472
5473
            //$fileName = basename($file_info['name'], '.'.$file_info['extension']);
5474
5475
            // prepare image info
5476
            $post_title = basename($file_info['name'], '.'.$file_info['extension']);
5477
            $post_title = isBase64($post_title) === true ?
5478
                    base64_decode($post_title) :
5479
                    $post_title;
5480
            $image_code = $file_info['file'];
5481
            $extension = $file_info['extension'];
5482
            $file_to_display = $SETTINGS['url_to_upload_folder'].'/'.$image_code;
5483
5484
            // Get image content
5485
            $fileContent = decryptFile(
5486
                $image_code,
5487
                $SETTINGS['path_to_upload_folder'],
5488
                decryptUserObjectKey($file_info['share_key'], $_SESSION['user']['private_key'])
5489
            );
5490
5491
            // Encrypt data to return
5492
            echo json_encode(array(
5493
                'error' => false,
5494
                'filename' => $post_title.'.'.$file_info['extension'],
5495
                'file_type' => $file_info['type'],
5496
                'file_content' => $fileContent,
5497
            ));
5498
            break;
5499
5500
        /*
5501
        * CASE
5502
        * Free Item for Edition
5503
        */
5504
        case 'delete_file':
5505
            // Check KEY
5506
            if ($post_key !== $_SESSION['key']) {
5507
                echo '[ { "error" : "key_not_conform" } ]';
5508
                break;
5509
            }
5510
5511
            // get file info
5512
            $result = DB::queryfirstrow(
5513
                'SELECT file FROM '.prefixTable('files').' WHERE id=%i',
5514
                intval(substr(filter_input(INPUT_POST, 'uri', FILTER_SANITIZE_STRING), 1))
5515
            );
5516
5517
            fileDelete($SETTINGS['path_to_upload_folder'].'/'.$result['file'].filter_input(INPUT_POST, 'file_suffix', FILTER_SANITIZE_STRING), $SETTINGS);
5518
5519
            break;
5520
5521
        /*
5522
        * CASE
5523
        * Get list of users that have access to the folder
5524
        */
5525
        case 'check_for_title_duplicate':
5526
            // Check KEY
5527
            if ($post_key !== $_SESSION['key']) {
5528
                echo '[ { "error" : "key_not_conform" } ]';
5529
                break;
5530
            }
5531
            $error = '';
5532
            $duplicate = 0;
5533
5534
            // decrypt and retreive data in JSON format
5535
            $dataReceived = prepareExchangedData($post_data, 'decode');
5536
            // Prepare variables
5537
            $label = htmlspecialchars_decode($dataReceived['label']);
5538
            $idFolder = $dataReceived['idFolder'];
5539
5540
            // don't check if Personal Folder
5541
            $data = DB::queryFirstRow('SELECT title FROM '.prefixTable('nested_tree').' WHERE id = %i', $idFolder);
5542
            if ($data['title'] == $_SESSION['user_id']) {
5543
                // send data
5544
                echo '[{"duplicate" : "'.$duplicate.'" , error" : ""}]';
5545
            } else {
5546
                if (filter_input(INPUT_POST, 'option', FILTER_SANITIZE_STRING) === 'same_folder') {
5547
                    // case unique folder
5548
                    DB::query(
5549
                        'SELECT label
5550
                        FROM '.prefixTable('items').'
5551
                        WHERE id_tree = %i AND label = %s',
5552
                        $idFolder,
5553
                        $label
5554
                    );
5555
                } else {
5556
                    // case complete database
5557
5558
                    //get list of personal folders
5559
                    $arrayPf = array();
5560
                    $listPf = '';
5561
                    if (empty($row['id']) === false) {
5562
                        $rows = DB::query(
5563
                            'SELECT id FROM '.prefixTable('nested_tree').' WHERE personal_folder = %i',
5564
                            '1'
5565
                        );
5566
                        foreach ($rows as $record) {
5567
                            if (!in_array($record['id'], $arrayPf)) {
5568
                                array_push($arrayPf, $record['id']);
5569
                            }
5570
                        }
5571
                    }
5572
5573
                    // build WHERE condition
5574
                    $where = new WhereClause('and');
5575
                    $where->add('id_tree = %i', $idFolder);
5576
                    $where->add('label = %s', $label);
5577
                    if (empty($arrayPf) === false) {
5578
                        $where->add('id_tree NOT IN ('.implode(',', $arrayPf).')');
5579
                    }
5580
5581
                    DB::query(
5582
                        'SELECT label
5583
                        FROM '.prefixTable('items').'
5584
                        WHERE %l',
5585
                        $where
5586
                    );
5587
                }
5588
5589
                // count results
5590
                if (DB::count() > 0) {
5591
                    $duplicate = 1;
5592
                }
5593
5594
                // send data
5595
                echo '[{"duplicate" : "'.$duplicate.'" , "error" : ""}]';
5596
            }
5597
            break;
5598
5599
        /*
5600
        * CASE
5601
        * Get list of users that have access to the folder
5602
        */
5603
        case 'refresh_visible_folders':
5604
            // Check KEY
5605
            if ($post_key !== $_SESSION['key']) {
5606
                echo prepareExchangedData(
5607
                    array(
5608
                        'error' => true,
5609
                        'message' => langHdl('key_is_not_correct'),
5610
                    ),
5611
                    'encode'
5612
                );
5613
                break;
5614
            }
5615
5616
            // Init
5617
5618
            // Will we show the root folder?
5619
            $arr_data['can_create_root_folder'] = isset($SETTINGS['can_create_root_folder']) && $SETTINGS['can_create_root_folder'] === '1' ? 1 : 0;
5620
5621
            // Build list of visible folders
5622
            $selectVisibleFoldersOptions = $selectVisibleNonPersonalFoldersOptions = $selectVisibleActiveFoldersOptions = '';
5623
            if (isset($SETTINGS['can_create_root_folder']) && $SETTINGS['can_create_root_folder'] === '1') {
5624
                $selectVisibleFoldersOptions = '<option value="0">'.langHdl('root').'</option>';
5625
            }
5626
5627
            if ($_SESSION['user_admin'] === '1'
5628
                && (null !== TP_ADMIN_FULL_RIGHT && TP_ADMIN_FULL_RIGHT === true)
5629
                || null === TP_ADMIN_FULL_RIGHT
5630
            ) {
5631
                $_SESSION['groupes_visibles'] = $_SESSION['personal_visible_groups'];
5632
                $_SESSION['groupes_visibles_list'] = implode(',', $_SESSION['groupes_visibles']);
5633
            }
5634
5635
            if (isset($_SESSION['list_folders_limited']) && count($_SESSION['list_folders_limited']) > 0) {
5636
                $listFoldersLimitedKeys = @array_keys($_SESSION['list_folders_limited']);
5637
            } else {
5638
                $listFoldersLimitedKeys = array();
5639
            }
5640
            // list of items accessible but not in an allowed folder
5641
            if (isset($_SESSION['list_restricted_folders_for_items'])
5642
                && count($_SESSION['list_restricted_folders_for_items']) > 0) {
5643
                $listRestrictedFoldersForItemsKeys = @array_keys($_SESSION['list_restricted_folders_for_items']);
5644
            } else {
5645
                $listRestrictedFoldersForItemsKeys = array();
5646
            }
5647
5648
            //Build tree
5649
            $tree = new SplClassLoader('Tree\NestedTree', $SETTINGS['cpassman_dir'].'/includes/libraries');
5650
            $tree->register();
5651
            $tree = new Tree\NestedTree\NestedTree(prefixTable('nested_tree'), 'id', 'parent_id', 'title');
5652
            $tree->rebuild();
5653
            $folders = $tree->getDescendants();
5654
            $inc = 0;
5655
5656
            foreach ($folders as $folder) {
5657
                // Be sure that user can only see folders he/she is allowed to
5658
                if (in_array($folder->id, $_SESSION['forbiden_pfs']) === false
5659
                    || in_array($folder->id, $_SESSION['groupes_visibles']) === true
5660
                    || in_array($folder->id, $listFoldersLimitedKeys) === true
5661
                    || in_array($folder->id, $listRestrictedFoldersForItemsKeys) === true
5662
                ) {
5663
                    // Init
5664
                    $displayThisNode = false;
5665
                    $hide_node = false;
5666
                    $nbChildrenItems = 0;
5667
5668
                    // Check if any allowed folder is part of the descendants of this node
5669
                    $nodeDescendants = $tree->getDescendants($folder->id, true, false, true);
5670
                    foreach ($nodeDescendants as $node) {
5671
                        // manage tree counters
5672
                        /*if (isset($SETTINGS['tree_counters']) && $SETTINGS['tree_counters'] === '1') {
5673
                            DB::query(
5674
                                "SELECT * FROM ".prefixTable("items")."
5675
                                WHERE inactif=%i AND id_tree = %i",
5676
                                0,
5677
                                $node
5678
                            );
5679
                            $nbChildrenItems += DB::count();
5680
                        }*/
5681
                        if (in_array($node, array_merge($_SESSION['groupes_visibles'], $_SESSION['list_restricted_folders_for_items'])) === true
5682
                            || @in_array($node, $listFoldersLimitedKeys)
5683
                            || @in_array($node, $listRestrictedFoldersForItemsKeys)
5684
                        ) {
5685
                            $displayThisNode = true;
5686
                            //break;
5687
                        }
5688
                    }
5689
5690
                    if ($displayThisNode === true) {
5691
                        // ALL FOLDERS
5692
                        // Is this folder disabled?
5693
                        $disabled = 0;
5694
                        if (in_array($folder->id, $_SESSION['groupes_visibles']) === false
5695
                            || in_array($folder->id, $_SESSION['read_only_folders']) === true
5696
                            //|| ((int) $_SESSION['user_read_only'] === 1 && in_array($folder->id, $_SESSION['personal_visible_groups']) === false)
5697
                        ) {
5698
                            $disabled = 1;
5699
                        }
5700
5701
                        // Build path
5702
                        $arbo = $tree->getPath($folder->id, false);
5703
                        $arr_data['folders'][$inc]['path'] = '';
5704
                        foreach ($arbo as $elem) {
5705
                            if (empty($arr_data['folders'][$inc]['path']) === true) {
5706
                                $arr_data['folders'][$inc]['path'] = htmlspecialchars(stripslashes(htmlspecialchars_decode($elem->title, ENT_QUOTES)), ENT_QUOTES);
5707
                            } else {
5708
                                $arr_data['folders'][$inc]['path'] .= ' / '.htmlspecialchars(stripslashes(htmlspecialchars_decode($elem->title, ENT_QUOTES)), ENT_QUOTES);
5709
                            }
5710
                        }
5711
5712
                        // Build array
5713
                        $arr_data['folders'][$inc]['id'] = intval($folder->id);
5714
                        $arr_data['folders'][$inc]['level'] = intval($folder->nlevel);
5715
                        $arr_data['folders'][$inc]['title'] = ($folder->title == $_SESSION['user_id'] && $folder->nlevel === '1') ? htmlspecialchars_decode($_SESSION['login']) : htmlspecialchars_decode($folder->title, ENT_QUOTES);
5716
                        $arr_data['folders'][$inc]['disabled'] = $disabled;
5717
                        $arr_data['folders'][$inc]['parent_id'] = intval($folder->parent_id);
5718
                        $arr_data['folders'][$inc]['perso'] = intval($folder->personal_folder);
5719
5720
                        // Is this folder an active folders? (where user can do something)
5721
                        $is_visible_active = 0;
5722
                        if (isset($_SESSION['read_only_folders']) === true
5723
                            && in_array($folder->id, $_SESSION['read_only_folders']) === true) {
5724
                            $is_visible_active = 1;
5725
                        }
5726
                        $arr_data['folders'][$inc]['is_visible_active'] = $is_visible_active;
5727
5728
                        ++$inc;
5729
                    }
5730
                }
5731
            }
5732
5733
            $data = array(
5734
                'error' => 'false',
5735
                'html_json' => $arr_data,
5736
            );
5737
            // send data
5738
            echo prepareExchangedData($data, 'encode');
5739
5740
            break;
5741
5742
        /*
5743
        * CASE
5744
        * Get list of users that have access to the folder
5745
        */
5746
        case 'refresh_folders_other_info':
5747
            // Check KEY
5748
            if ($post_key !== $_SESSION['key']) {
5749
                echo prepareExchangedData(
5750
                    array(
5751
                        'error' => true,
5752
                        'message' => langHdl('key_is_not_correct'),
5753
                    ),
5754
                    'encode'
5755
                );
5756
                break;
5757
            }
5758
5759
            $arr_data = array();
5760
5761
            foreach (json_decode($post_data) as $folder) {
5762
                // Do we have Categories
5763
                if (isset($SETTINGS['item_extra_fields']) && $SETTINGS['item_extra_fields'] === '1') {
5764
                    // get list of associated Categories
5765
                    $arrCatList = array();
5766
                    $rows_tmp = DB::query(
5767
                        'SELECT c.id, c.title, c.level, c.type, c.masked, c.order, c.encrypted_data, c.role_visibility, c.is_mandatory,
5768
                        f.id_category AS category_id
5769
                        FROM '.prefixTable('categories_folders').' AS f
5770
                        INNER JOIN '.prefixTable('categories').' AS c ON (f.id_category = c.parent_id)
5771
                        WHERE id_folder=%i',
5772
                        $folder
5773
                    );
5774
                    if (DB::count() > 0) {
5775
                        foreach ($rows_tmp as $row) {
5776
                            $arrCatList[$row['id']] = array(
5777
                                'id' => $row['id'],
5778
                                'title' => $row['title'],
5779
                                'level' => $row['level'],
5780
                                'type' => $row['type'],
5781
                                'masked' => $row['masked'],
5782
                                'order' => $row['order'],
5783
                                'encrypted_data' => $row['encrypted_data'],
5784
                                'role_visibility' => $row['role_visibility'],
5785
                                'is_mandatory' => $row['is_mandatory'],
5786
                                'category_id' => $row['category_id'],
5787
                            );
5788
                        }
5789
                    }
5790
                    $arr_data[$folder]['categories'] = $arrCatList;
5791
                }
5792
5793
                // Now get complexity
5794
                $valTemp = '';
5795
                $data = DB::queryFirstRow(
5796
                    'SELECT valeur
5797
                    FROM '.prefixTable('misc').'
5798
                    WHERE type = %s AND intitule=%i',
5799
                    'complex',
5800
                    $folder
5801
                );
5802
                if (DB::count() > 0 && empty($data['valeur']) === false) {
5803
                    $valTemp = array(
5804
                        'value' => $data['valeur'],
5805
                        'text' => TP_PW_COMPLEXITY[$data['valeur']][1],
5806
                    );
5807
                }
5808
                $arr_data[$folder]['complexity'] = $valTemp;
5809
5810
                // Now get Roles
5811
                $valTemp = '';
5812
                $rows_tmp = DB::query(
5813
                    'SELECT t.title
5814
                    FROM '.prefixTable('roles_values').' as v
5815
                    INNER JOIN '.prefixTable('roles_title').' as t ON (v.role_id = t.id)
5816
                    WHERE v.folder_id = %i
5817
                    GROUP BY title',
5818
                    $folder
5819
                );
5820
                foreach ($rows_tmp as $record) {
5821
                    if (empty($valTemp) === true) {
5822
                        $valTemp = $record['title'];
5823
                    } else {
5824
                        $valTemp .= ' - '.$record['title'];
5825
                    }
5826
                }
5827
                $arr_data[$folder]['visibilityRoles'] = $valTemp;
5828
            }
5829
5830
            $data = array(
5831
                'error' => '',
5832
                'result' => $arr_data,
5833
            );
5834
            // send data
5835
            echo prepareExchangedData($data, 'encode');
5836
5837
            break;
5838
5839
        /*
5840
        * CASE
5841
        * Load item history
5842
        */
5843
        case 'load_item_history':
5844
            // Check KEY
5845
            if ($post_key !== $_SESSION['key']) {
5846
                echo prepareExchangedData(array('error' => 'ERR_KEY_NOT_CORRECT'), 'encode');
5847
                break;
5848
            }
5849
5850
            // get item info
5851
            $dataItem = DB::queryFirstRow(
5852
                'SELECT *
5853
                FROM '.prefixTable('items').'
5854
                WHERE id=%i',
5855
                $post_item_id
5856
            );
5857
5858
            // get item history
5859
            $history = array();
5860
            $rows = DB::query(
5861
                'SELECT l.date as date, l.action as action, l.raison as raison, l.raison_iv AS raison_iv,
5862
                u.login as login, u.avatar_thumb as avatar_thumb, u.name as name, u.lastname as lastname
5863
                FROM '.prefixTable('log_items').' as l
5864
                LEFT JOIN '.prefixTable('users').' as u ON (l.id_user=u.id)
5865
                WHERE id_item=%i AND action <> %s
5866
                ORDER BY date DESC',
5867
                $post_item_id,
5868
                'at_shown'
5869
            );
5870
            foreach ($rows as $record) {
5871
                $reason = explode(' :', $record['raison']);
5872
                if ($reason[0] === 'at_pw') {
5873
                    // This is a password change.
5874
                    // Just indicate it was changed
5875
                }
5876
                // imported via API
5877
                if (empty($record['login'])) {
5878
                    $record['login'] = langHdl('imported_via_api').' ['.$record['raison'].']';
5879
                }
5880
5881
                if (in_array(
5882
                    $record['action'],
5883
                    array('at_password_copied', 'at_shown', 'at_password_shown')
5884
                ) === false
5885
                ) {
5886
                    // Prepare avatar
5887
                    if (isset($record['avatar_thumb']) && empty($record['avatar_thumb']) === false) {
5888
                        if (file_exists($SETTINGS['cpassman_dir'].'/includes/avatars/'.$record['avatar_thumb'])) {
5889
                            $avatar = $SETTINGS['cpassman_url'].'/includes/avatars/'.$record['avatar_thumb'];
5890
                        } else {
5891
                            $avatar = $SETTINGS['cpassman_url'].'/includes/images/photo.jpg';
5892
                        }
5893
                    } else {
5894
                        $avatar = $SETTINGS['cpassman_url'].'/includes/images/photo.jpg';
5895
                    }
5896
5897
                    // Prepare action
5898
                    $action = '';
5899
                    $detail = '';
5900
                    if ($reason[0] === 'at_pw') {
5901
                        $action = langHdl($reason[0]);
5902
                    } elseif ($reason[0] === 'at_description') {
5903
                        $action = langHdl('description_has_changed');
5904
                    } elseif (empty($record['raison']) === false && $reason[0] !== 'at_creation') {
5905
                        if ($reason[0] === 'at_moved') {
5906
                            $tmp = explode(' -> ', $reason[1]);
5907
                            $detail = langHdl('from').' <span class="font-weight-light">'.$tmp[0].'</span> '.langHdl('to').' <span class="font-weight-light">'.$tmp[1].' </span>';
5908
                        } elseif ($reason[0] === 'at_field') {
5909
                            $tmp = explode(' => ', $reason[1]);
5910
                            if (count($tmp) > 1) {
5911
                                $detail = '<b>'.trim($tmp[0]).'</b> | '.langHdl('previous_value').
5912
                                    ': <span class="font-weight-light">'.trim($tmp[1]).'</span>';
5913
                            } else {
5914
                                $detail = trim($reason[1]);
5915
                            }
5916
                        } elseif (in_array($reason[0], array('at_restriction', 'at_email', 'at_login', 'at_label', 'at_url')) === true) {
5917
                            $tmp = explode(' => ', $reason[1]);
5918
                            $detail = empty(trim($tmp[0])) === true ?
5919
                                langHdl('no_previous_value') :
5920
                                langHdl('previous_value').': <span class="font-weight-light">'.$tmp[0].' </span>';
5921
                        } elseif ($reason[0] === 'at_automatic_del') {
5922
                            $detail = langHdl($reason[1]);
5923
                        } elseif ($reason[0] === 'at_anyoneconmodify') {
5924
                            $detail = langHdl($reason[1]);
5925
                        } elseif ($reason[0] === 'at_add_file' || $reason[0] === 'at_del_file') {
5926
                            $tmp = explode(':', $reason[1]);
5927
                            $tmp = explode('.', $tmp[0]);
5928
                            $detail = isBase64($tmp[0]) === true ?
5929
                                base64_decode($tmp[0]).'.'.$tmp[1] :
5930
                                $tmp[0];
5931
                        } elseif ($reason[0] === 'at_import') {
5932
                            $detail = '';
5933
                        } else {
5934
                            $detail = $reason[0];
5935
                        }
5936
                        $action = langHdl($reason[0]);
5937
                    } elseif ($record['action'] === 'at_manual') {
5938
                        $detail = langHdl($record['action']);
5939
                        $action = $reason[0];
5940
                    } else {
5941
                        $detail = langHdl($record['action']);
5942
                        $action = '';
5943
                    }
5944
5945
                    array_push(
5946
                        $history,
5947
                        array(
5948
                            'avatar' => $avatar,
5949
                            'login' => $record['login'],
5950
                            'name' => $record['name'].' '.$record['lastname'],
5951
                            'date' => date($SETTINGS['date_format'].' '.$SETTINGS['time_format'], $record['date']),
5952
                            'action' => $action,
5953
                            'detail' => $detail,
5954
                        )
5955
                    );
5956
                }
5957
            }
5958
5959
            $data = array(
5960
                'error' => '',
5961
                'history' => $history,
5962
            );
5963
5964
            // send data
5965
            echo prepareExchangedData($data, 'encode');
5966
5967
            break;
5968
5969
        case 'suggest_item_change':
5970
            // Check KEY
5971
            if ($post_key !== $_SESSION['key']) {
5972
                echo prepareExchangedData(
5973
                    array(
5974
                        'error' => 'key_not_conform',
5975
                        'message' => langHdl('key_is_not_correct'),
5976
                    ),
5977
                    'encode'
5978
                );
5979
                break;
5980
            }
5981
            // decrypt and retrieve data in JSON format
5982
            $data_received = prepareExchangedData($post_data, 'decode');
5983
5984
            // prepare variables
5985
            $label = htmlspecialchars_decode($data_received['label'], ENT_QUOTES);
5986
            $pwd = htmlspecialchars_decode($data_received['password']);
5987
            $login = htmlspecialchars_decode($data_received['login'], ENT_QUOTES);
5988
            $email = htmlspecialchars_decode($data_received['email']);
5989
            $url = htmlspecialchars_decode($data_received['url']);
5990
            $folder = htmlspecialchars_decode($data_received['folder_id']);
5991
            $comment = htmlspecialchars_decode($data_received['comment']);
5992
            $item_id = htmlspecialchars_decode($data_received['item_id']);
5993
5994
            if (empty($pwd)) {
5995
                $encrypt['string'] = '';
5996
            } else {
5997
                $encrypt = cryption($pwd, '', 'encrypt', $SETTINGS);
5998
            }
5999
6000
            // query
6001
            DB::insert(
6002
                prefixTable('items_change'),
6003
                array(
6004
                    'item_id' => $item_id,
6005
                    'label' => $label,
6006
                    'pw' => $encrypt['string'],
6007
                    'login' => $login,
6008
                    'email' => $email,
6009
                    'url' => $url,
6010
                    'description' => '',
6011
                    'comment' => $comment,
6012
                    'folder_id' => $folder,
6013
                    'user_id' => $_SESSION['user_id'],
6014
                    'timestamp' => time(),
6015
                )
6016
            );
6017
            $newID = DB::insertId();
6018
6019
            // get some info to add to the notification email
6020
            $resp_user = DB::queryfirstrow(
6021
                'SELECT login FROM '.prefixTable('users').' WHERE id = %i',
6022
                $_SESSION['user_id']
6023
            );
6024
            $resp_folder = DB::queryfirstrow(
6025
                'SELECT title FROM '.prefixTable('nested_tree').' WHERE id = %i',
6026
                $folder
6027
            );
6028
6029
            // notify Managers
6030
            $rows = DB::query(
6031
                'SELECT email
6032
                FROM '.prefixTable('users').'
6033
                WHERE `gestionnaire` = %i AND `email` IS NOT NULL',
6034
                1
6035
            );
6036
            foreach ($rows as $record) {
6037
                sendEmail(
6038
                    langHdl('suggestion_notify_subject'),
6039
                    str_replace(array('#tp_label#', '#tp_user#', '#tp_folder#'), array(addslashes($label), addslashes($resp_user['login']), addslashes($resp_folder['title'])), langHdl('suggestion_notify_body')),
6040
                    $record['email'],
6041
                    $SETTINGS
6042
                );
6043
            }
6044
6045
            echo prepareExchangedData(
6046
                array(
6047
                    'error' => '',
6048
                ),
6049
                'encode'
6050
            );
6051
            break;
6052
6053
        case 'build_list_of_users':
6054
            // Check KEY
6055
            if ($post_key !== $_SESSION['key']) {
6056
                echo '[ { "error" : "key_not_conform" } ]';
6057
                break;
6058
            }
6059
6060
            // Get list of users
6061
            $usersList = array();
6062
            $usersString = '';
6063
            $rows = DB::query('SELECT id,login,email FROM '.prefixTable('users').' ORDER BY login ASC');
6064
            foreach ($rows as $record) {
6065
                $usersList[$record['login']] = array(
6066
                    'id' => $record['id'],
6067
                    'login' => $record['login'],
6068
                    'email' => $record['email'],
6069
                    );
6070
                $usersString .= $record['id'].'#'.$record['login'].';';
6071
            }
6072
6073
            $data = array(
6074
                'error' => '',
6075
                'list' => $usersString,
6076
            );
6077
6078
            // send data
6079
            echo prepareExchangedData($data, 'encode');
6080
            break;
6081
6082
        case 'send_request_access':
6083
            // Check KEY
6084
            if ($post_key !== $_SESSION['key']) {
6085
                echo prepareExchangedData(
6086
                    array(
6087
                        'error' => 'key_not_conform',
6088
                        'message' => langHdl('key_is_not_correct'),
6089
                    ),
6090
                    'encode'
6091
                );
6092
                break;
6093
            }
6094
            // decrypt and retrieve data in JSON format
6095
            $dataReceived = prepareExchangedData($post_data, 'decode');
6096
6097
            // prepare variables
6098
            $post_email_body = filter_var($dataReceived['email'], FILTER_SANITIZE_STRING);
6099
            $post_item_id = filter_var($dataReceived['id'], FILTER_SANITIZE_NUMBER_INT);
6100
6101
            // Send email
6102
            $dataItem = DB::queryfirstrow(
6103
                'SELECT label, id_tree
6104
                FROM '.prefixTable('items').'
6105
                WHERE id = %i',
6106
                $post_item_id
6107
            );
6108
            $dataItemLog = DB::queryfirstrow(
6109
                'SELECT id_user
6110
                FROM '.prefixTable('log_items').'
6111
                WHERE id_item = %i AND action = %s',
6112
                $post_item_id,
6113
                'at_creation'
6114
            );
6115
            $dataAuthor = DB::queryfirstrow(
6116
                'SELECT email, login
6117
                FROM '.prefixTable('users').'
6118
                WHERE id = %i',
6119
                $dataItemLog['id_user']
6120
            );
6121
6122
            // Get path
6123
            $path = prepareEmaiItemPath(
6124
                $dataItem['id_tree'],
6125
                $dataItem['label'],
6126
                $SETTINGS
6127
            );
6128
6129
            /*$ret = sendEmail(
6130
                langHdl('email_request_access_subject'),
6131
                str_replace(
6132
                    array(
6133
                        '#tp_item_author#',
6134
                        '#tp_user#',
6135
                        '#tp_item#',
6136
                        '#tp_reason#',
6137
                    ),
6138
                    array(
6139
                        ' '.addslashes($dataAuthor['login']),
6140
                        addslashes($_SESSION['login']),
6141
                        $path,
6142
                        nl2br(addslashes($post_email_body)),
6143
                    ),
6144
                    langHdl('email_request_access_mail')
6145
                ),
6146
                $dataAuthor['email'],
6147
                $SETTINGS
6148
            );*/
6149
6150
            // Do log
6151
            logItems(
6152
                $SETTINGS,
6153
                $post_item_id,
6154
                $dataItem['label'],
6155
                $_SESSION['user_id'],
6156
                'at_access',
6157
                $_SESSION['login']
6158
            );
6159
6160
            // Return
6161
            echo prepareExchangedData(
6162
                array(
6163
                    'error' => false,
6164
                    'message' => '',
6165
                ),
6166
                'encode'
6167
            );
6168
6169
            break;
6170
6171
        /*
6172
        * CASE
6173
        * GET CLIPBOARD DATA TO SHOW
6174
        */
6175
        case 'get_clipboard_data':
6176
            // Check KEY and rights
6177
            if ($post_key !== $_SESSION['key'] || $_SESSION['user_read_only'] === true || !isset($SETTINGS['pwd_maximum_length'])) {
6178
                // error
6179
                exit();
6180
            }
6181
6182
            // load the original record into an array
6183
            $dataItem = DB::queryfirstrow(
6184
                'SELECT label, pw, login, perso FROM '.prefixTable('items').'
6185
                WHERE id=%i',
6186
                $post_item_id
6187
            );
6188
6189
            if (filter_input(INPUT_POST, 'show_type', FILTER_SANITIZE_STRING) === 'password') {
6190
                // check if item is PF
6191
                if ($dataItem['perso'] !== 1) {
6192
                    $pw = cryption(
6193
                        $dataItem['pw'],
6194
                        '',
6195
                        'decrypt',
6196
                        $SETTINGS
6197
                    );
6198
                } else {
6199
                    if (isset($_SESSION['user_settings']['session_psk']) === true) {
6200
                        $pw = cryption(
6201
                            $dataItem['pw'],
6202
                            $_SESSION['user_settings']['session_psk'],
6203
                            'decrypt',
6204
                            $SETTINGS
6205
                        );
6206
                    } else {
6207
                        $pw = '';
6208
                    }
6209
                }
6210
6211
                // if not UTF8 then cleanup and inform that something is wrong with encrytion/decryption
6212
                if (isUTF8($pw['string']) === false) {
6213
                    $px = '';
6214
                }
6215
6216
                echo prepareExchangedData($pw['string'], 'encode');
6217
6218
                // Now log
6219
                logItems(
6220
                    $SETTINGS,
6221
                    $post_item_id,
6222
                    $dataItem['label'],
6223
                    $_SESSION['user_id'],
6224
                    'at_password_copied',
6225
                    $_SESSION['login']
6226
                );
6227
                break;
6228
            } else {
6229
                echo prepareExchangedData($dataItem['login'], 'encode');
6230
            }
6231
6232
            break;
6233
6234
        /*
6235
        * CASE
6236
        * save_notification_status
6237
        */
6238
        case 'save_notification_status':
6239
            // Check KEY
6240
            if ($post_key !== $_SESSION['key']) {
6241
                echo prepareExchangedData(
6242
                    array(
6243
                        'error' => 'key_not_conform',
6244
                        'message' => langHdl('key_is_not_correct'),
6245
                    ),
6246
                    'encode'
6247
                );
6248
                break;
6249
            }
6250
            // decrypt and retrieve data in JSON format
6251
            $dataReceived = prepareExchangedData($post_data, 'decode');
6252
6253
            // prepare variables
6254
            $post_notification_status = (int) filter_var($dataReceived['notification_status'], FILTER_SANITIZE_NUMBER_INT);
6255
            $post_item_id = (int) filter_var($dataReceived['item_id'], FILTER_SANITIZE_NUMBER_INT);
6256
6257
            DB::query(
6258
                'SELECT *
6259
                FROM '.prefixTable('notification').'
6260
                WHERE item_id = %i AND user_id = %i',
6261
                $post_item_id,
6262
                $_SESSION['user_id']
6263
            );
6264
            if (DB::count() > 0) {
6265
                // Notification is set for this user on this item
6266
                if ((int) $post_notification_status === 0) {
6267
                    // Remove the notification
6268
                    DB::delete(
6269
                        prefixTable('notification'),
6270
                        'item_id = %i AND user_id = %i',
6271
                        $post_item_id,
6272
                        $_SESSION['user_id']
6273
                    );
6274
                }
6275
            } else {
6276
                // Notification is not set on this item
6277
                if ((int) $post_notification_status === 1) {
6278
                    // Add the notification
6279
                    DB::insert(
6280
                        prefixTable('notification'),
6281
                        array(
6282
                            'item_id' => $post_item_id,
6283
                            'user_id' => $_SESSION['user_id'],
6284
                        )
6285
                    );
6286
                }
6287
            }
6288
6289
            $data = array(
6290
                'error' => false,
6291
                'message' => '',
6292
            );
6293
6294
            // send data
6295
            echo prepareExchangedData($data, 'encode');
6296
6297
            break;
6298
6299
        /*
6300
        * CASE
6301
        * delete_uploaded_files_but_not_saved
6302
        */
6303
        case 'delete_uploaded_files_but_not_saved':
6304
            // Check KEY
6305
            if ($post_key !== $_SESSION['key']) {
6306
                echo prepareExchangedData(
6307
                    array(
6308
                        'error' => 'key_not_conform',
6309
                        'message' => langHdl('key_is_not_correct'),
6310
                    ),
6311
                    'encode'
6312
                );
6313
                break;
6314
            }
6315
            // decrypt and retrieve data in JSON format
6316
            $dataReceived = prepareExchangedData($post_data, 'decode');
6317
6318
            // prepare variables
6319
            $post_item_id = (int) filter_var($dataReceived['item_id'], FILTER_SANITIZE_NUMBER_INT);
6320
6321
            // Delete non confirmed files for this item
6322
            // And related logs
6323
            $rows = DB::query(
6324
                'SELECT id, file AS filename
6325
                FROM '.prefixTable('files').'
6326
                WHERE id_item = %i AND confirmed = %i',
6327
                $post_item_id,
6328
                0
6329
            );
6330
            foreach ($rows as $file) {
6331
                // Delete file in DB
6332
                DB::delete(
6333
                    prefixTable('files'),
6334
                    'id = %i',
6335
                    $file['id']
6336
                );
6337
6338
                // Delete file on server
6339
                unlink($SETTINGS['path_to_upload_folder'].'/'.TP_FILE_PREFIX.base64_decode($file['filename']));
6340
6341
                // Delete related logs
6342
                $logFile = DB::query(
6343
                    'SELECT increment_id, raison
6344
                    FROM '.prefixTable('log_items').'
6345
                    WHERE id_item = %i AND id_user = %i AND action = %s AND raison LIKE "at_add_file :%"',
6346
                    $post_item_id,
6347
                    $_SESSION['user_id'],
6348
                    'at_modification'
6349
                );
6350
                foreach ($logFile as $log) {
6351
                    $tmp = explode(':', $log['raison']);
6352
                    if (count($tmp) === 3 && (int) $tmp[2] === (int) $file['id']) {
6353
                        DB::delete(
6354
                            prefixTable('log_items'),
6355
                            'increment_id = %i',
6356
                            $log['increment_id']
6357
                        );
6358
                    }
6359
                }
6360
            }
6361
6362
            $data = array(
6363
                'error' => false,
6364
                'message' => '',
6365
            );
6366
6367
            // send data
6368
            echo prepareExchangedData($data, 'encode');
6369
6370
            break;
6371
6372
        /*
6373
        * CASE
6374
        * confirm_attachments
6375
        */
6376
        case 'confirm_attachments':
6377
            // Check KEY
6378
            if ($post_key !== $_SESSION['key']) {
6379
                echo prepareExchangedData(
6380
                    array(
6381
                        'error' => 'key_not_conform',
6382
                        'message' => langHdl('key_is_not_correct'),
6383
                    ),
6384
                    'encode'
6385
                );
6386
                break;
6387
            }
6388
            // decrypt and retrieve data in JSON format
6389
            $dataReceived = prepareExchangedData($post_data, 'decode');
6390
6391
            // prepare variables
6392
            $post_item_id = (int) filter_var($dataReceived['item_id'], FILTER_SANITIZE_NUMBER_INT);
6393
6394
            // Confirm attachments
6395
            $rows = DB::query(
6396
                'SELECT id, file AS filename
6397
                FROM '.prefixTable('files').'
6398
                WHERE id_item = %i AND confirmed = %i',
6399
                $post_item_id,
6400
                0
6401
            );
6402
            foreach ($rows as $file) {
6403
                DB::update(
6404
                    prefixTable('files'),
6405
                    array(
6406
                        'confirmed' => 1,
6407
                    ),
6408
                    'id_item = %i',
6409
                    $post_item_id
6410
                );
6411
            }
6412
6413
            $data = array(
6414
                'error' => false,
6415
                'message' => '',
6416
            );
6417
6418
            // send data
6419
            echo prepareExchangedData($data, 'encode');
6420
6421
            break;
6422
    }
6423
}
6424
// Build the QUERY in case of GET
6425
if (isset($_GET['type'])) {
6426
    switch ($_GET['type']) {
6427
        /*
6428
        * CASE
6429
        * Autocomplet for TAGS
6430
        */
6431
        case 'autocomplete_tags':
6432
            // Get a list off all existing TAGS
6433
            $listOfTags = '';
6434
            $rows = DB::query('SELECT tag FROM '.prefixTable('tags').' WHERE tag LIKE %ss GROUP BY tag', $_GET['term']);
6435
            foreach ($rows as $record) {
6436
                if (empty($listOfTags)) {
6437
                    $listOfTags = '"'.$record['tag'].'"';
6438
                } else {
6439
                    $listOfTags .= ', "'.$record['tag'].'"';
6440
                }
6441
            }
6442
            echo '['.$listOfTags.']';
6443
            break;
6444
    }
6445
}
6446
6447
/*
6448
* FUNCTION
6449
* Identify if this group authorize creation of item without the complexit level reached
6450
*/
6451
function recupDroitCreationSansComplexite($groupe)
6452
{
6453
    $data = DB::queryFirstRow(
6454
        'SELECT bloquer_creation, bloquer_modification, personal_folder FROM '.prefixTable('nested_tree').' WHERE id = %i',
6455
        $groupe
6456
    );
6457
    // Check if it's in a personal folder. If yes, then force complexity overhead.
6458
    if ($data['personal_folder'] === '1') {
6459
        return array(
6460
            'bloquer_modification_complexite' => 1,
6461
            'bloquer_creation_complexite' => 1,
6462
        );
6463
    }
6464
6465
    return array(
6466
        'bloquer_modification_complexite' => (int) $data['bloquer_modification'],
6467
        'bloquer_creation_complexite' => (int) $data['bloquer_creation'],
6468
    );
6469
}
6470
6471
/**
6472
 * Permits to identify what icon to display depending on file extension.
6473
 *
6474
 * @param string $ext Extension
6475
 *
6476
 * @return string
6477
 */
6478
function fileFormatImage($ext)
6479
{
6480
    if (in_array($ext, TP_OFFICE_FILE_EXT)) {
6481
        $image = 'fas fa-file-word';
6482
    } elseif ($ext === 'pdf') {
6483
        $image = 'fas fa-file-pdf';
6484
    } elseif (in_array($ext, TP_IMAGE_FILE_EXT)) {
6485
        $image = 'fas fa-file-image';
6486
    } elseif ($ext === 'txt') {
6487
        $image = 'fas fa-file-alt';
6488
    } else {
6489
        $image = 'fas fa-file';
6490
    }
6491
6492
    return $image;
6493
}
6494
6495
/**
6496
 * Returns a cleaned up password.
6497
 *
6498
 * @param string $pwd String for pwd
6499
 *
6500
 * @return string
6501
 */
6502
function passwordReplacement($pwd)
6503
{
6504
    $pwPatterns = array('/ETCOMMERCIAL/', '/SIGNEPLUS/');
6505
    $pwRemplacements = array('&', '+');
6506
6507
    return preg_replace($pwPatterns, $pwRemplacements, $pwd);
6508
}
6509
6510
/**
6511
 * Returns the Item + path.
6512
 *
6513
 * @param int    $id_tree
6514
 * @param string $label
6515
 * @param array  $SETTINGS
6516
 *
6517
 * @return string
6518
 */
6519
function prepareEmaiItemPath($id_tree, $label, $SETTINGS)
6520
{
6521
    // Class loader
6522
    require_once $SETTINGS['cpassman_dir'].'/sources/SplClassLoader.php';
6523
6524
    //Load Tree
6525
    $tree = new SplClassLoader('Tree\NestedTree', '../includes/libraries');
6526
    $tree->register();
6527
    $tree = new Tree\NestedTree\NestedTree(prefixTable('nested_tree'), 'id', 'parent_id', 'title');
6528
6529
    $arbo = $tree->getPath($id_tree, true);
6530
    $path = '';
6531
    foreach ($arbo as $elem) {
6532
        if (empty($path) === true) {
6533
            $path = htmlspecialchars(stripslashes(htmlspecialchars_decode($elem->title, ENT_QUOTES)), ENT_QUOTES).' ';
6534
        } else {
6535
            $path .= '&#8594; '.htmlspecialchars(stripslashes(htmlspecialchars_decode($elem->title, ENT_QUOTES)), ENT_QUOTES);
6536
        }
6537
    }
6538
    // Build text to show user
6539
    if (empty($path) === true) {
6540
        $path = addslashes($label);
6541
    } else {
6542
        $path = addslashes($label).' ('.$path.')';
6543
    }
6544
6545
    return $path;
6546
}
6547