Plugin Directory

source: backuply/trunk/main/ajax.php

Last change on this file was 3267947, checked in by softaculous, 13 days ago

New version 1.4.4

File size: 34.0 KB
Line 
1<?php
2/*
3* BACKUPLY
4* https://backuply.com
5* (c) Backuply Team
6*/
7
8// Are we being accessed directly ?
9if(!defined('BACKUPLY_VERSION')) {
10        exit('Hacking Attempt !');
11}
12
13set_time_limit(60);
14ignore_user_abort(true);
15
16// Is the nonce there ?
17if(empty($_REQUEST['security'])){
18        return;
19}
20
21// AJAX Actions
22add_action('wp_ajax_backuply_create_backup', 'backuply_create_backup');
23add_action('wp_ajax_backuply_stop_backup', 'backuply_stop_backup');
24add_action('wp_ajax_backuply_download_backup', 'backuply_download_backup');
25add_action('wp_ajax_backuply_multi_backup_delete', 'backuply_multi_backup_delete');
26add_action('wp_ajax_backuply_check_status', 'backuply_check_status');
27add_action('wp_ajax_backuply_check_backup_status', 'backuply_backup_progress_status');
28add_action('wp_ajax_backuply_checkrestorestatus_action', 'backuply_checkrestorestatus_action');
29add_action('wp_ajax_backuply_restore_curl_query', 'backuply_restore_curl_query');
30add_action('wp_ajax_backuply_retry_htaccess', 'backuply_retry_htaccess');
31add_action('wp_ajax_backuply_kill_proccess', 'backuply_force_stop');
32add_action('wp_ajax_backuply_get_loc_details', 'backuply_get_loc_details');
33add_action('wp_ajax_backuply_sync_backups', 'backuply_sync_backups');
34add_action('wp_ajax_nopriv_backuply_restore_response', 'backuply_restore_response');
35add_action('wp_ajax_nopriv_backuply_update_serialization', 'backuply_update_serialization_ajax');
36add_action('wp_ajax_backuply_creating_session', 'backuply_creating_session');
37add_action('wp_ajax_nopriv_backuply_creating_session', 'backuply_creating_session');
38add_action('wp_ajax_backuply_last_logs', 'backuply_get_last_logs');
39add_action('wp_ajax_backuply_save_excludes', 'backuply_save_excludes');
40add_action('wp_ajax_backuply_exclude_rule_delete', 'backuply_exclude_rule_delete');
41add_action('wp_ajax_backuply_get_jstree', 'backuply_get_jstree');
42add_action('wp_ajax_backuply_hide_backup_nag', 'backuply_hide_backup_nag');
43add_action('wp_ajax_backuply_get_restore_key', 'backuply_get_restore_key');
44add_action('wp_ajax_backuply_handle_backup', 'backuply_handle_backup_request');
45add_action('wp_ajax_backuply_download_bcloud', 'backuply_download_bcloud');
46add_action('wp_ajax_backuply_update_quota', 'backuply_update_quota');
47add_action('wp_ajax_backuply_backup_upload', 'backuply_backup_upload');
48add_action('wp_ajax_nopriv_backuply_restore_status_log', 'backuply_restore_status_log');
49add_action('wp_ajax_backuply_restore_status_log', 'backuply_restore_status_log');
50
51// Backuply CLoud
52add_action('wp_ajax_bcloud_trial', 'backuply_bcloud_trial');
53add_action('wp_ajax_backuply_verify_trial', 'backuply_verify_trial');
54add_action('wp_ajax_backuply_trial_settings', 'backuply_trial_settings');
55
56function backuply_ajax_nonce_verify($key = 'security'){
57       
58        if(!wp_verify_nonce($_REQUEST[$key], 'backuply_nonce')) {
59                wp_send_json(array('success' => false, 'message' => 'Security Check Failed.'));
60        }
61       
62        // Check capability
63        if(!current_user_can( 'activate_plugins' )){
64                wp_send_json(array('success' => false, 'message' => 'You cannot create backups as per your capabilities !'));
65        }
66       
67        return true;
68}
69
70// AJAX handle to download backup
71// TODO:: Delete this after pushing out the direct download version.
72function backuply_download_backup() {
73       
74        backuply_ajax_nonce_verify();
75       
76        if(empty($_GET['backup_name'])) {
77                wp_send_json(array('success' => false, 'message' => 'Wrong File name provided.'));
78        }
79       
80        $filename = backuply_optget('backup_name');
81        $filename = backuply_sanitize_filename($filename);
82        $backups_dir = backuply_glob('backups');
83       
84        $file = $backups_dir . '/'. $filename;
85       
86        if(!file_exists($file)) {
87                wp_send_json(array('success' => false, 'message' => 'File not found.'));
88        }
89       
90        ob_start();
91        header('Content-Type: application/octet-stream');
92        header('Content-Disposition: attachment; filename="' . basename($filename) . '"');
93        header('Content-Transfer-Encoding: binary');
94        header('Content-Length: ' . filesize($file));
95        header('Content-Range: 0-' . (filesize($file) - 1) . '/' . filesize($file));
96        wp_ob_end_flush_all();
97
98        readfile($file);
99        wp_die();
100}
101
102// AJAX handle to delete Multiple backups
103function backuply_multi_backup_delete() {
104        global $error;
105       
106        backuply_ajax_nonce_verify();
107       
108        if(empty($_POST['backup_name'])) {
109                wp_send_json(array('success' => false, 'message' => 'No Backup selected for deletion.'));
110        }
111       
112        $backup = backuply_optpost('backup_name');
113       
114        if(empty($backup)) {
115                wp_send_json(array('success' => false, 'message' => 'No File was provided to be deleted'));
116        }
117       
118        if(!backuply_delete_backup($backup)) {
119                $error_string = __('Below are the errors faced', 'backuply');
120               
121                foreach($error as $e) {
122                        $error_string .= $e . "\n";
123                }
124               
125                wp_send_json(array('success' => false, 'message' => $error_string));
126        }
127       
128        wp_send_json(array('success' => true));
129}
130
131// AJAX handle to create backup
132function backuply_create_backup() {
133       
134        backuply_ajax_nonce_verify();
135       
136        $bak_options = json_decode(sanitize_text_field(wp_unslash($_POST['values'])), true);
137
138        backuply_create_log_file();
139       
140        update_option('backuply_backup_stopped', false);
141        update_option('backuply_status', $bak_options);
142        backuply_status_log('Initializing...', 'info', 13);
143        backuply_status_log('Creating a job to start Backup', 'info', 17);
144
145        if(backuply_backup_request()) {
146                wp_schedule_single_event(time() + BACKUPLY_TIMEOUT_TIME, 'backuply_timeout_check', array('is_restore' => false));
147                wp_send_json(array('success' => true));
148        }
149       
150        // Failed !
151        wp_send_json(array('success' => false, 'message' => 'Unable to start a backup at this moment, Please try again later'));
152}
153
154function backuply_backup_request(){
155
156        $url = admin_url('admin-ajax.php') . '?action=backuply_handle_backup&security=' . wp_create_nonce('backuply_create_backup');
157
158        $res = wp_remote_get($url, array(
159                'timeout' => 0.01,
160                'blocking' => false,
161                'cookies' => array(LOGGED_IN_COOKIE => $_COOKIE[LOGGED_IN_COOKIE]),
162                'sslverify' => false,
163                'user-agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36',
164        ));
165
166        if(empty($res) || is_wp_error($res)){
167                return false;
168        }
169       
170        $res_code = wp_remote_retrieve_response_code($res);     
171
172        if(!empty($res_code) && $res_code != 200){
173                return false;
174        }
175       
176        if(isset($res[0]) && $res[0] == false){
177                return false;
178        }
179
180        return true;
181       
182}
183
184function backuply_handle_backup_request(){
185
186        if(!wp_verify_nonce($_REQUEST['security'], 'backuply_create_backup')) {
187                backuply_status_log('Security Failed', 'error', 100);
188
189                return false;
190        }
191
192        // Check capability
193        if(!current_user_can( 'activate_plugins' )){
194                backuply_status_log('You cannot create backups as per your capabilities !', 'error', 100);
195                return false;
196        }
197
198        backuply_backup_execute();
199        return true;
200}
201
202// Returns status for backup and restore
203function backuply_backup_progress_status() {
204        // Security Check
205        backuply_ajax_nonce_verify();
206       
207        $last_status = !empty($_POST['last_status']) ? backuply_optpost('last_status') : 0;
208       
209        // negative progress means backup is being stopped
210        wp_send_json(array(
211                'success' => true,
212                'is_stoppable' => true,
213                'progress_log' => backuply_get_status($last_status)
214                )
215        );
216}
217
218function backuply_stop_backup() {
219       
220        backuply_ajax_nonce_verify();
221       
222        backuply_status_log('Stopping the Backup', 'info', -1);
223        update_option('backuply_backup_stopped', true, false);
224        wp_send_json(array('success' => true));
225}
226
227// Retries creating htaccess
228function backuply_retry_htaccess() {
229       
230        backuply_ajax_nonce_verify();
231
232        $res = backuply_add_htaccess();
233       
234        if($res) {
235                wp_send_json(array('success' => true));
236        }
237       
238        wp_send_json(array('success' => false, 'message' => 'We are not able to create the htaccess file, So please use the manual way.'));
239}
240
241// AJAX handle to restore backupp
242function backuply_restore_curl_query(){
243
244        backuply_ajax_nonce_verify();
245
246        if(!empty($_POST['fname'])) {
247                $info = map_deep($_POST, 'sanitize_text_field');
248
249                backuply_init_restore($info);
250                exit();
251        }
252}
253
254// Kills process
255function backuply_force_stop() {
256        backuply_ajax_nonce_verify();
257       
258        delete_option('backuply_status');
259        update_option('backuply_backup_stopped', true, false);
260       
261        if(file_exists(BACKUPLY_BACKUP_DIR . 'restoration/restoration.php')){
262                @unlink(BACKUPLY_BACKUP_DIR . 'restoration/restoration.php');
263        }
264       
265        wp_send_json(['success' => true]);
266}
267
268// Fetches details of a specific location
269function backuply_get_loc_details() {
270       
271        //Security check
272        backuply_ajax_nonce_verify();
273       
274        $loc_id = backuply_optpost('loc_id');
275       
276        if(empty($loc_id)){
277                wp_send_json(array('success' => false, 'message' => __('No location id specified', 'backuply')));
278        }
279       
280        // The filters are the fields which we dont want to show in edit as these are keys.
281        $filter = ['ftp_pass', 'aws_secretKey', 'aws_accessKey'];
282        $loc_info = backuply_get_loc_by_id($loc_id, $filter);
283       
284        if(empty($loc_info)) {
285                wp_send_json(array('success' => false, 'message' => __('The specified location not found', 'backuply')));
286        }
287       
288        wp_send_json(array('success' => true, 'data' => $loc_info));
289}
290
291// Syncs the backups in the remote location with us
292function backuply_sync_backups(){
293        //Security check
294        backuply_ajax_nonce_verify();
295       
296        $loc_id = backuply_optget('id');
297       
298        if(empty($loc_id)){
299                wp_send_json(array('success' => false, 'message' => __('No location id specified', 'backuply')));
300        }
301       
302        $sync = backuply_sync_remote_backup_infos($loc_id);
303       
304        wp_send_json(array('success' => true));
305}
306
307// Deletes all remote info files on Restore Success
308function backuply_delete_rinfo_on_restore() {
309        $backup_info_f = backuply_glob('backups_info') . '/';
310        $backup_info = backuply_get_backups_info();
311
312        foreach($backup_info as $info){
313                if(!isset($info->backup_location)){
314                        continue;
315                }
316               
317                @unlink($backup_info_f . $info->name . '.php');
318        }
319}
320
321
322// Handles WP related functionality after restore has happened Restore
323function backuply_restore_response($is_last = false) {
324       
325        $keepalive = (int) time() + 25;
326
327        if(!backuply_verify_self(backuply_optreq('security'), true)){
328                backuply_status_log('Security Check Failed', 'error');
329                die();
330        }
331
332        if(!$is_last && !empty($_REQUEST['restore_db']) && !empty($_REQUEST['is_migrating'])){
333                $session_data = array('time' => time(), 'key' => backuply_optreq('sess_key'), 'user_id' => backuply_optreq('user_id'));
334       
335                update_option('backuply_restore_session_key', $session_data, false);
336                backuply_status_log('Repairing database serialization', 'info', 78);
337
338                // NOTE:: If you add any table here make sure to update the same in the backuply_wp_clone_sql function as well.
339                $clones = ['options' => 'option', 'postmeta' => 'meta', 'commentmeta' => 'meta'];
340                backuply_update_serialization($keepalive, $clones);
341        }
342
343        // Clears WP Cron for timeout
344        if($timestamp = wp_next_scheduled('backuply_timeout_check', array('is_restore' => true))) {
345                wp_unschedule_event($timestamp, 'backuply_timeout_check', array('is_restore' => true));
346        }
347       
348        // Delete the config file.
349        if(file_exists(BACKUPLY_BACKUP_DIR . 'backuply_config.php')){
350                backuply_keys_to_db(); // After restore we need push the keys back to db.
351        }
352       
353        $email = get_option('backuply_notify_email_address');
354        $site_url = get_site_url();
355        $dir_path = backuply_cleanpath(ABSPATH);
356        $backuply_backup_dir = backuply_cleanpath(BACKUPLY_BACKUP_DIR);
357       
358        // Was there an error ?
359        if(backuply_optget('error')){
360       
361                $error_string = urldecode(backuply_optget('error_string'));
362                // Send mail
363                $mail = array();
364                $mail['to'] = $email;   
365                $mail['subject'] = 'Restore of your WordPress installation failed - Backuply';
366                $mail['headers'] = "Content-Type: text/html; charset=UTF-8\r\n";
367                $mail['message'] = 'Hi, <br><br>
368
369The most recent restore attempt for your WordPress site has failed. <br>
370Installation URL : '.$site_url.' <br>
371'.$error_string.' <br><br>
372
373
374Regards,<br>
375Backuply';
376
377                if(!empty($mail['to'])){
378                        wp_mail($mail['to'], $mail['subject'], $mail['message'], $mail['headers']);
379                }
380                backuply_report_error(backuply_optget('error_string'));
381               
382                backuply_status_log('Restore Failed!.','error');
383                backuply_copy_log_file(true);
384                backuply_clean_restoration_file();
385
386                exit(1);
387        }
388
389        backuply_status_log('Sending an Email notification.','working', 84);
390       
391        // Send mail
392        $mail = array();
393        $mail['to'] = $email;   
394        $mail['subject'] = 'Restore of your WordPress - Backuply';
395        $mail['headers'] = "Content-Type: text/html; charset=UTF-8\r\n";
396        $mail['message'] = 'Hi, <br><br>
397
398The restore of your WordPress backup was completed successfully. <br>
399The details are as follows : <br><br>
400
401Installation Path : '.$dir_path.'<br>
402Installation URL : '.$site_url.'<br>
403Regards,<br>
404Backuply';
405
406        if(!empty($mail['to'])){
407                wp_mail($mail['to'], $mail['subject'], $mail['message'], $mail['headers']);
408        }
409       
410        if(!empty($_GET['not_writable'])){
411                backuply_status_log(__('Please check the logs, there were some files, which Backuply was unable to replace as those files were not writable', 'backuply') . ' <a href="https://backuply.com/docs/common-issues/files-not-writable/" target="_blank">Read More</a>', 'info');
412        }
413
414        backuply_status_log('Restore performed successfully.', 'success', 100);
415        update_option('backuply_last_restore', time(), false);
416        backuply_delete_rinfo_on_restore();
417        backuply_copy_log_file(true);
418        backuply_clean_restoration_file();
419
420        die();
421}
422
423// Loops(based on timeout) through the fixing serialized
424function backuply_update_serialization($keepalive, $options = array(), $i = null) {
425       
426        if(!function_exists('backuply_wp_clone_sql')){
427                include_once BACKUPLY_DIR . '/functions.php';
428        }
429
430        $keys = array_keys($options);
431        $repair_log = get_option('backuply_sql_repair_log');
432       
433        if(empty($repair_log)) {
434                $repair_log = array('table' => $keys[0], 'try' => 0);
435                update_option('backuply_sql_repair_log', $repair_log);
436        }
437
438        $res = backuply_wp_clone_sql($keys[0], $options[$keys[0]], $keepalive, $i);
439
440        if(!is_numeric($res)) {
441                delete_option('backuply_sql_repair_log');
442                if(isset($options[$keys[0]])){
443                        unset($options[$keys[0]]);
444                }
445        }
446
447        if($res === false){
448                backuply_status_log('Something went wrong while repairing database', 'error');
449                die();
450        }
451       
452        if(empty($options)){
453                backuply_status_log('Successfully repaired the database', 'info', 81);
454                backuply_restore_response(true);
455                die();
456        }
457       
458        $config = backuply_get_config();
459        if(empty($config['RESTORE_KEY'])){
460                backuply_status_log('Restore key not found!', 'error');
461                die();
462        }
463       
464        $body = array('options' => $options);
465       
466        if(is_numeric($res)){
467               
468                if($keys[0] == $repair_log['table'] && $repair_log['try'] > 1){
469                        backuply_status_log('Repairing of the database serialization failed, Restoration has completed but some plugins may work weirdly', 'error', 100);
470                }
471               
472                if(!empty($restore_log['i']) && $repair_log['i'] == $res && $keys[0] == $repair_log['table']){
473                        $repair_log['try'] += 1;
474                }
475               
476                $repair_log['i'] = $res;
477               
478                update_option('backuply_sql_repair_log', $repair_log);
479               
480                $body['i'] = $res;
481        }
482       
483        $url = admin_url('admin-ajax.php'). '?action=backuply_update_serialization&security='. $config['RESTORE_KEY'];
484       
485        wp_remote_post($url, array(
486                'body' => $body,
487                'timeout' => 2,
488                'sslverify' => false,
489                'user-agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36',
490        ));
491       
492        die();
493}
494
495// Ajax to handle the loop of fixing serialized
496function backuply_update_serialization_ajax() {
497
498        //Security Check
499        if(!backuply_verify_self(backuply_optreq('security'), true)){
500                backuply_status_log('Security Check Failed', 'error');
501                die();
502        }
503       
504        @touch(BACKUPLY_BACKUP_DIR.'/restoration/restoration.php'); // Updating restore time
505        @touch(BACKUPLY_BACKUP_DIR.'/status.lock'); // Updating Status Lock mtime
506       
507        $keepalive = time() + 25;
508
509        $i = !empty(backuply_optpost('i')) ? (int) backuply_optpost('i') : null;
510        $options = map_deep(wp_unslash($_POST['options']), 'sanitize_text_field');
511       
512        backuply_update_serialization($keepalive, $options, $i);
513}
514
515function backuply_get_restore_key(){
516       
517        backuply_ajax_nonce_verify();
518        backuply_update_restore_key();
519
520        $config_set = backuply_set_config_file(); // Add the config keys to the file.
521       
522        if(empty($config_set)){
523                backuply_status_log('Unable to set Config file', 'error', 100);
524                unlink($backuply_backup_dir.'/restoration/restoration.php');
525                wp_send_json(array('success' => false, 'message' => 'Unable to create the config file!'));
526        }
527
528        @touch(BACKUPLY_BACKUP_DIR. '/status.lock');
529       
530        $config = backuply_get_config();
531       
532        if(empty($config) || empty($config['RESTORE_KEY'])){
533                wp_send_json(array('success' => false, 'message' => 'Config is empty, please try again'));
534        }
535       
536        wp_send_json(array('success' => true, 'restore_key' => $config['RESTORE_KEY'], 'backuply_key' => $config['BACKUPLY_KEY']));
537}
538
539
540// Creates a WP session if user is not logged in
541function backuply_creating_session(){
542       
543        // Security Check
544        if(!backuply_verify_self(backuply_optreq('security'), true)){
545                backuply_status_log('Security Check Failed', 'error');
546                die();
547        }
548       
549        $key = get_option('backuply_restore_session_key');
550       
551        // Search for the user ID
552        if(empty($key)){
553                wp_send_json(array('success' => false, 'error' => true, 'message' => 'Session Key has not been updated yet!'));
554        }
555       
556        if((time() - $key['time']) > 600 || (isset($_REQUEST['sess_key']) && $_REQUEST['sess_key'] != $key['key'])){
557                //backuply_status_log('Session key verification failed', 'error');
558                die();
559        }
560       
561        if(is_user_logged_in()){
562                wp_send_json(array('success' => false, 'message' => 'Already logged in'));
563        }
564       
565        // Setting Session
566        if(!empty($key['user_id'])){
567                $user = get_user_by('id', $key['user_id']);
568        }else{
569                $user = get_userdata(1);
570               
571                // Try to find an admin if we do not have any admin with ID => 1
572                if(empty($user) || empty($user->user_login)){
573                        $admin_id = get_users(array('role__in' => array('administrator'), 'number' => 1, 'fields' => array('ID')));
574                        $user = get_userdata($admin_id[0]->ID);
575                }
576               
577                $username = $user->user_login;
578                $user = get_user_by('login', $username);
579        }
580
581        if(isset($user) && is_object($user) && property_exists($user, 'ID')){
582                clean_user_cache(get_current_user_id());
583                clean_user_cache($user->ID);
584                wp_clear_auth_cookie();
585                wp_set_current_user($user->ID, $user->user_login);
586                wp_set_auth_cookie($user->ID, 1, is_ssl());
587                do_action('wp_login', $user->user_login, $user);
588                update_user_caches($user);
589
590                wp_send_json(array('success' => true));
591        }
592}
593
594// Returns logs of last backup/restore
595function backuply_get_last_logs(){
596       
597        backuply_ajax_nonce_verify();
598       
599        $is_restore = backuply_optget('is_restore');
600        $backup_log_name = !empty($_GET['file_name']) ? backuply_optget('file_name') : 'backuply_backup_log.php';
601        $location_id = !empty($_GET['proto_id']) ? backuply_optget('proto_id') : '';   
602        $backup_log_name = backuply_sanitize_filename($backup_log_name);
603       
604        $log_fname = !empty($is_restore) ? 'backuply_restore_log.php' : $backup_log_name;
605        $log_file = BACKUPLY_BACKUP_DIR . $log_fname;
606        $logs = array();
607       
608        if(!file_exists($log_file)){
609                if(!backuply_sync_remote_backup_logs($location_id, $log_fname)){
610                        wp_send_json(array('success' => false, 'progress_log' => 'No log found!|writing\n'));
611                }
612        }
613       
614        $fh = fopen($log_file, 'r');
615
616        @fseek($fh, 16);
617       
618        $lines = fread($fh, fstat($fh)['size']);
619        fclose($fh);
620        $fh = null;
621       
622        wp_send_json(array('success' => true, 'progress_log' => $lines));
623}
624
625function backuply_save_excludes() {
626       
627        global $backuply;
628       
629        backuply_ajax_nonce_verify();
630       
631        $type = backuply_optpost('type');
632        $pattern = backuply_optpost('pattern'); // Pattern is also used as path when the type is specific
633       
634        // Clean the pattern in case its a full path
635        if('exact' == $type){
636                $pattern = str_replace(['..', './'], '', $pattern);
637                $pattern = backuply_cleanpath($pattern);
638        }
639       
640        if(!empty($_POST['key'])) {
641                $key = backuply_optpost('key');
642        }
643       
644        // Remove dot in case the user adds it
645        if($type == 'extension'){
646                $pattern = trim($pattern, '.');
647        }
648       
649        if(empty($backuply['excludes'][$type])){
650                $backuply['excludes'][$type] = array();
651        }
652       
653        $this_type = &$backuply['excludes'][$type];
654
655        if(in_array($pattern, $this_type)){
656                wp_send_json(array('success' => false, 'message' => 'Exclude rule is already present'));
657        }
658
659        if(empty($key)){
660                do{
661                        $key = wp_generate_password(6, false);
662                } while(array_key_exists($key, $this_type));
663        }
664        $this_type[$key] = $pattern;
665
666        update_option('backuply_excludes', $backuply['excludes'], false);
667       
668        wp_send_json(array('success' => true, 'key' => $key));
669       
670}
671
672function backuply_exclude_rule_delete() {
673       
674        global $backuply;
675       
676        backuply_ajax_nonce_verify();
677       
678        $type = backuply_optget('type');
679        $key = backuply_optget('key');
680       
681        if(empty($type) || empty($key)){
682                wp_send_json(array('success' => false, 'message' => 'Unable to delete this Exclude rule'));
683        }
684       
685        $this_type = &$backuply['excludes'][$type];
686
687        // Deleting the rule
688        if(empty($this_type)){
689                wp_send_json(array('success' => false, 'message' => 'Rule not found'));
690        }
691       
692        unset($this_type[$key]);
693        update_option('backuply_excludes', $backuply['excludes'], false);
694       
695        wp_send_json(array('success' => true));
696}
697
698
699function backuply_get_jstree() {
700       
701        backuply_ajax_nonce_verify();
702       
703        $node = map_deep($_POST['nodeid'], 'sanitize_text_field');
704        $scan_path = $node['id'];
705
706        if('#' == $node['id']){
707                $scan_path = WP_CONTENT_DIR;
708        }
709       
710        // Cleaning the path to prevent directory traversal
711        $scan_path = str_replace('..', '', $scan_path);
712        $scan_path = backuply_cleanpath($scan_path);
713
714        $nodes = array();
715
716        if(empty($scan_path)){
717                wp_send_json(array('success' => true, 'nodes' => $nodes));
718        }
719       
720        // Making sure we only show files inside WP Content Dir.
721        if(strpos($scan_path, backuply_cleanpath(WP_CONTENT_DIR)) !== 0){
722                wp_send_json(array('success' => true, 'nodes' => $nodes));
723        }
724
725        $contents = @scandir($scan_path);
726       
727        if(empty($contents)){
728                wp_send_json(array('success' => true, 'nodes' => $nodes));
729        }
730       
731        foreach($contents as $con){
732                if(in_array($con, array('.', '..'))){
733                        continue;
734                }
735               
736                if(is_dir($scan_path . DIRECTORY_SEPARATOR . $con)){
737                        $nodes[] = array(
738                                'text' => $con,
739                                'children' => true,
740                                'id' => backuply_cleanpath($scan_path . DIRECTORY_SEPARATOR . $con),
741                                'type' => 'folder',
742                                'icon' => 'jstree-folder'
743                        );
744                } else {
745                        $ext = pathinfo($con, PATHINFO_EXTENSION);
746                       
747                        $icon = 'jstree-file';
748                       
749                        if('php' == $ext){
750                                $icon = BACKUPLY_URL . '/assets/images/php-logo32.svg';
751                        }
752                       
753                        $nodes[] = array(
754                                'text' => $con,
755                                'children' => false,
756                                'id' => backuply_cleanpath($scan_path . DIRECTORY_SEPARATOR . $con),
757                                'type' => 'file',
758                                'icon' => $icon
759                        );
760                }
761        }
762
763        wp_send_json(array('success' => true, 'nodes' => $nodes));
764       
765}
766
767// Updates the backuply_backup_nag to current timestamp
768function backuply_hide_backup_nag(){
769
770        backuply_ajax_nonce_verify();
771       
772        update_option('backuply_backup_nag', time());
773       
774        wp_send_json(true);
775}
776
777function backuply_bcloud_trial(){
778        global $backuply;
779
780        if(!wp_verify_nonce($_POST['security'], 'backuply_trial_nonce')){
781                wp_send_json_error(null, 401);
782        }
783       
784        $remote_locs = get_option('backuply_remote_backup_locs', []);
785
786        // Getting the bcloud ID
787        foreach($remote_locs as $loc){
788                if($loc['protocol'] === 'bcloud'){
789                        wp_send_json_error(__('Backuply Cloud is already added as a Location', 'backuply'));
790                }
791        }
792
793        $url = BACKUPLY_API . '/cloud/token.php';
794        $args = array(
795                'body' => array(
796                        'url' => site_url(),
797                ),
798                'sslverify' => false,
799                'timeout' => 30
800        );
801
802        if(empty($_POST['value'])){
803                wp_send_json_error(__('Please enter a license to Proceed', 'backuply'), 422);
804        }
805       
806        $args['body']['license'] = sanitize_text_field($_POST['value']);
807        $license['license'] = sanitize_text_field($_POST['value']);
808
809        // Checking if License is inactive.
810        if(!empty($backuply['license']) && !empty($backuply['license']['license']) && empty($backuply['license']['active'])){
811                wp_send_json_error(__('Your license is not activated, please go to License page and activate it', 'backuply'));
812        }
813
814        // Sending Request
815        $res = wp_remote_post($url, $args);
816       
817        if(empty($res) || is_wp_error($res)){
818                wp_send_json_error(__('Something went wrong while sending request to Backuply API', 'backuply'), 500);
819        }
820
821        // Reading Body
822        $body = wp_remote_retrieve_body($res);
823       
824        if(empty($body)){
825                wp_send_json_error(__('Did not get any response from Backuply API', 'backuply'));
826        }
827       
828        $body = json_decode($body, 1);
829       
830        // Updating the license if we create a trial account else the request will not return license as an array.
831        if(!empty($body['license']) && is_array($body['license'])){
832                $license = map_deep($body['license'], 'sanitize_text_field');
833                update_option('backuply_license', $body['license']);
834        }
835       
836        if(empty($body['success'])){
837                wp_send_json_error($body['message']);
838        } 
839       
840        if(empty($body['data']) || empty($body['data']['bcloud_key'])){
841                wp_send_json_error(__('Did not got the Backuply Cloud key, contact support!', 'backuply'));
842        }
843       
844        // Adding bacloud as a location
845        $bcloud_keys = map_deep($body['data'], 'sanitize_text_field');
846        $location_id = (empty($remote_locs) ? 1 : max(array_keys($remote_locs)) + 1);
847       
848        // Basic info for remote location
849        $remote_locs[$location_id]['id'] = $location_id;
850        $remote_locs[$location_id]['name'] = 'Backuply Cloud';
851        $remote_locs[$location_id]['protocol'] = 'bcloud';
852        $remote_locs[$location_id]['backup_loc'] = '';
853        $remote_locs[$location_id]['bcloud_key'] = !empty($bcloud_keys['bcloud_key']) ? sanitize_key($bcloud_keys['bcloud_key']) : '';
854       
855        // Building full path, it will contain access key and other details to use.
856        $remote_locs[$location_id]['full_backup_loc'] = !empty($bcloud_keys) ? 'bcloud://'.$bcloud_keys['access_key'].':'.$bcloud_keys['secret_key'].'@'.$license['license'].'/'.$bcloud_keys['region'].'/us-east-1/'.$bcloud_keys['bcloud_key'] : '';
857
858        // Adding the bcloud key
859        update_option('bcloud_key', $bcloud_keys['bcloud_key']);
860        update_option('backuply_remote_backup_locs', $remote_locs);
861        $backuply['bcloud_key'] = $bcloud_keys['bcloud_key'];
862
863        /* We are updating Cron and default backup location if the Cron is not set yet,
864                we are doing so to make sure we do not break users cron if its already set.*/
865        if(empty($backuply['cron'])){
866                $backuply['settings']['backup_location'] = $location_id;
867                update_option('backuply_settings', $backuply['settings']);
868               
869                $backuply['cron']['backuply_cron_schedule'] = 'backuply_daily';
870                $backuply['cron']['backup_dir'] = 1;
871                $backuply['cron']['backup_db'] = 1;
872                $backuply['cron']['backup_rotation'] = 4;
873                $backuply['cron']['backup_location'] = $location_id;
874               
875                update_option('backuply_cron_settings', $backuply['cron']);
876               
877                if(!function_exists('backuply_add_auto_backup_schedule')){
878                        include_once BACKUPLY_DIR . '/main/bcloud-cron.php';
879                }
880               
881                backuply_add_auto_backup_schedule($backuply['cron']['backuply_cron_schedule']); // Will create a WP Cron event
882        }
883       
884        if(!defined('BACKUPLY_PRO')){
885                update_option('bcloud_trial_time', time() + 2592000, false);
886        }
887
888        wp_send_json_success(__('Backuply Cloud has been integrated Successfully, It\'s ready to use now', 'backuply'));
889}
890
891// Verify if the user has verified the email for the trial account by checking if the license is active.
892function backuply_verify_trial(){
893        global $backuply;
894       
895        // Security Check
896        if(!wp_verify_nonce($_POST['security'], 'backuply_trial_nonce')){
897                wp_send_json_error(null, 401);
898        }
899       
900        if(empty($backuply['license']) || empty($backuply['license']['license'])){
901                wp_send_json_error(__('You could not find a license key to verify the confirmation', 'backuply'));
902        }
903
904        $resp = wp_remote_get(BACKUPLY_API.'/license.php?license='.$backuply['license']['license'].'&url='.rawurlencode(site_url()), array('timeout' => 30));
905       
906        $json = json_decode($resp['body'], true);
907
908        if(empty($json['license'])){
909                wp_send_json_error(__('There was issue fetching License details', 'backuply'));
910        }
911       
912        $is_active = false;
913       
914        if(!empty($json['active'])){
915                $is_active = true;
916        }
917
918        update_option('backuply_license', $json);
919        $backuply['license'] = $json;
920
921        if(!empty($is_active)){
922                wp_send_json_success(array('message' => __('Verification Completed!','backuply'), 'license' => $json['license']), 200);
923        }
924
925        wp_send_json_error(__('The license is still inactive, please check if you have checked the Confirmation email sent to your email', 'backuply'));
926       
927}
928
929// Updates the settings When the user is PRO
930function backuply_trial_settings(){
931        global $backuply;
932       
933        // Security Check
934        if(!wp_verify_nonce($_POST['security'], 'backuply_trial_nonce')){
935                wp_send_json_error(null, 401);
936        }
937
938        $remote_locs = get_option('backuply_remote_backup_locs', []);
939       
940        if(empty($remote_locs)){
941                wp_send_json_success();
942        }
943       
944        // Getting the bcloud ID
945        foreach($remote_locs as $loc){
946                if(empty($loc['protocol']) || $loc['protocol'] != 'bcloud'){
947                        continue;
948                }
949               
950                $bcloud_id = $loc['id'];
951        }
952       
953        if(empty($bcloud_id)){
954                wp_send_json_success();
955        }
956       
957        // Updating Backup Location
958        $backuply['settings']['backup_location'] = $bcloud_id;
959        update_option('backuply_settings', $backuply['settings']);
960
961        // Updating the Cron settings
962        $backuply['cron']['backuply_cron_schedule'] = 'backuply_daily';
963        $backuply['cron']['backup_dir'] = 1;
964        $backuply['cron']['backup_db'] = 1;
965        $backuply['cron']['backup_rotation'] = 4;
966        $backuply['cron']['backup_location'] = $bcloud_id; 
967       
968        update_option('backuply_cron_settings', $backuply['cron']);
969       
970        if(!function_exists('backuply_add_auto_backup_schedule')){
971                include_once BACKUPLY_DIR . '/main/bcloud-cron.php';
972        }
973
974        backuply_add_auto_backup_schedule($backuply['cron']['backuply_cron_schedule']); // Will create a WP Cron event
975
976        wp_send_json_success();
977       
978}
979
980// Download Backuply Cloud Files
981function backuply_download_bcloud(){
982
983        // Security Check
984        if(!wp_verify_nonce($_POST['security'], 'backuply_nonce')){
985                wp_send_json_error('Security Check failed!');
986        }
987       
988        if(empty($_POST['filename'])){
989                wp_send_json_error(esc_html__('File name was not given, so download can not proceed.', 'backuply'));
990        }
991       
992        $filename = backuply_sanitize_filename($_POST['filename']);
993        $bcloud = backuply_load_remote_backup('bcloud');
994       
995        if(empty($bcloud)){
996                wp_send_json_error(esc_html__('Backuply Cloud Not found', 'backuply'));
997        }
998
999        $bcloud_info = backuply_load_remote_backup_info('bcloud');
1000
1001        if(empty($bcloud_info['full_backup_loc'])){
1002                wp_send_json_error(esc_html__('Backuply Cloud has not been added yet as a Backup location, if you have already added it then remove it and add it again.', 'backuply'));
1003        }
1004       
1005        $download_path = $bcloud_info['full_backup_loc'] . '/' . $filename;
1006        $download_link = $bcloud->download_direct($download_path);
1007       
1008        if(empty($download_link)){
1009                wp_send_json_error(esc_html__('Unable to download the file', 'backuply'));
1010        }
1011       
1012        wp_send_json_success(array('url' => $download_link, 'filename' => $filename));
1013}
1014
1015// Fetches the usage on the given storage location.
1016function backuply_update_quota(){
1017       
1018        // Security Check
1019        if(!wp_verify_nonce($_POST['security'], 'backuply_nonce')){
1020                wp_send_json_error('Security Check failed!');
1021        }
1022
1023        $storage_loc = sanitize_text_field($_POST['location']);
1024       
1025        if(empty($storage_loc)){
1026                wp_send_json_error(__('No Storage location provided', 'backuply'));
1027        }
1028
1029        $quota = backuply_get_quota($storage_loc);
1030       
1031        if(empty($quota)){
1032                wp_send_json_error();
1033        }
1034       
1035        $info = get_option('backuply_remote_backup_locs', []);
1036       
1037        if(!empty($info)){
1038                foreach($info as $key => $locs){
1039                        if($locs['protocol'] === $storage_loc){
1040                                $info[$key]['backup_quota'] = (int) $quota['used'];
1041                                $info[$key]['allocated_storage'] = (int) $quota['total'];
1042                        }
1043                }
1044               
1045                update_option('backuply_remote_backup_locs', $info);
1046        }
1047
1048        wp_send_json_success();
1049       
1050}
1051
1052function backuply_backup_upload(){
1053       
1054        if(!wp_verify_nonce($_POST['security'], 'backuply_nonce')){
1055                wp_send_json_error('Security Check failed!');
1056        }
1057       
1058        if(!current_user_can('manage_options')){
1059                wp_send_json_error('You don\'t have privilege to upload the backup!');
1060        }
1061
1062        $file_name = backuply_optpost('file_name');
1063        $file_name = backuply_cleanpath($file_name); // Makes sure the file name is safe
1064        $file_name = backuply_sanitize_filename($file_name);
1065        $backup_dir = backuply_glob('backups');
1066       
1067        if(!preg_match('/\.tar\.gz$/i', $file_name)){
1068                wp_send_json_error(__('You are not uploading a Backup file, please choose the correct backup file', 'backuply'));
1069        }
1070       
1071        // Attempting to abort the process
1072        if(!empty($_POST['abort'])){
1073                if(file_exists($backup_dir . '/.' . $file_name)){
1074                        if(unlink($backup_dir . '/.' . $file_name)){
1075                                wp_send_json_success(__('Abort successful', 'backuply'));
1076                        }
1077                       
1078                        wp_send_json_error(__('Unable to clean the already uploaded data.', 'backuply'));
1079                }
1080               
1081                wp_send_json_error(__('Unable to clean the already uploaded data.', 'backuply'));
1082        }
1083       
1084        // Sanitizing the parameters.
1085        $chunk_number = (int) sanitize_text_field($_POST['chunk_number']);
1086        $total_chunks = (int) sanitize_text_field($_POST['total_chunks']);
1087        $chunk_data = file_get_contents($_FILES['file']['tmp_name']);
1088
1089        $chunk_size = 2 * 1024 * 1024; // 2MB
1090        $chunk_data_size = strlen($chunk_data);
1091       
1092        if(file_exists($backup_dir . '/' . $file_name)){
1093                wp_send_json_error(__('File with same name already exists', 'backuply'));
1094        }
1095       
1096        if($chunk_data_size < $chunk_size && $total_chunks !== $chunk_number){
1097                wp_send_json_error(__('The data recieved is malformed, the size of data is less then the data sent!', 'backuply'));
1098        }
1099       
1100        if($chunk_data_size > $chunk_size){
1101                wp_send_json_error(__('The data recieved is malformed, the size of data is more then the data sent!', 'backuply'));
1102        }
1103
1104        $file_loc = $backup_dir . '/.' . $file_name;
1105
1106        $fh = fopen($file_loc, 'ab');
1107        if($chunk_number > 1){
1108                fseek($fh, (($chunk_number - 1) * $chunk_size));
1109        }
1110
1111        fwrite($fh, $chunk_data);
1112        fclose($fh);
1113       
1114        if($chunk_number === $total_chunks){
1115                if(function_exists('mime_content_type')){
1116                        $mime = mime_content_type($file_loc);
1117               
1118                        $possible_mime = ['application/gzip', 'application/x-gzip'];
1119                        if(!in_array($mime, $possible_mime)){
1120                                wp_send_json_error(__('Upload failed, file type is different than the expected', 'backuply'));
1121                        }
1122                }
1123               
1124                rename($file_loc, $backup_dir . '/' . $file_name);
1125        }
1126       
1127        wp_send_json_success($chunk_number * $chunk_size);
1128
1129}
1130
1131function backuply_restore_status_log(){
1132       
1133        // Checking the Status key.
1134        if(!backuply_verify_status_log()){
1135                wp_send_json(array('success' => false, 'progress_log' => 'Ajax Security Check Failed!|error'));
1136                die();
1137        }
1138       
1139        $log_file = BACKUPLY_BACKUP_DIR. '/backuply_log.php';
1140        $logs = [];
1141        $last_log = (int) sanitize_text_field(wp_unslash($_REQUEST['last_status']));
1142
1143        if(!file_exists($log_file)){
1144                $logs[] = 'Something went wrong!|error';
1145                wp_send_json(array('success' => false, 'progress_log' => $logs));
1146                die();
1147        }
1148       
1149        $fh = fopen($log_file, 'r');
1150       
1151        $seek_to = $last_log + 16; // 16 for php exit
1152       
1153        @fseek($fh, $seek_to);
1154       
1155        $lines = fread($fh, fstat($fh)['size']);
1156        fclose($fh);
1157        $fh = null;
1158       
1159        wp_send_json(array('success' => true, 'progress_log' => $lines));
1160}
Note: See TracBrowser for help on using the repository browser.