Add imapsync tool
This commit is contained in:
		
							parent
							
								
									c403933017
								
							
						
					
					
						commit
						96ae33ee6a
					
				| @ -1,6 +1,6 @@ | |||||||
| <?php | <?php | ||||||
| require_once("inc/prerequisites.inc.php"); | require_once("inc/prerequisites.inc.php"); | ||||||
| $AuthUsers = array("admin", "domainadmin"); | $AuthUsers = array("admin", "domainadmin", "user"); | ||||||
| if (!isset($_SESSION['mailcow_cc_role']) OR !in_array($_SESSION['mailcow_cc_role'], $AuthUsers)) { | if (!isset($_SESSION['mailcow_cc_role']) OR !in_array($_SESSION['mailcow_cc_role'], $AuthUsers)) { | ||||||
| 	header('Location: /'); | 	header('Location: /'); | ||||||
| 	exit(); | 	exit(); | ||||||
| @ -259,6 +259,82 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm | |||||||
| 	<?php | 	<?php | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "user")) { | ||||||
|  |   if (isset($_GET['syncjob'])) { | ||||||
|  | ?>
 | ||||||
|  | 				<h4><?=$lang['add']['syncjob'];?></h4>
 | ||||||
|  | 				<p><?=$lang['add']['syncjob_hint'];?></p>
 | ||||||
|  | 				<form class="form-horizontal" role="form" method="post" action="<?=($FORM_ACTION == "previous") ? $_SESSION['return_to'] : null;?>"> | ||||||
|  | 					<div class="form-group"> | ||||||
|  | 						<label class="control-label col-sm-2" for="host1"><?=$lang['add']['hostname'];?></label>
 | ||||||
|  | 						<div class="col-sm-10"> | ||||||
|  | 						<input type="text" class="form-control" name="host1" id="host1" required> | ||||||
|  | 						</div> | ||||||
|  | 					</div> | ||||||
|  | 					<div class="form-group"> | ||||||
|  | 						<label class="control-label col-sm-2" for="port1">Port</label> | ||||||
|  | 						<div class="col-sm-10"> | ||||||
|  | 						<input type="number" class="form-control" name="port1" id="port1" min="1" max="65535" value="143" required> | ||||||
|  | 						</div> | ||||||
|  | 					</div> | ||||||
|  | 					<div class="form-group"> | ||||||
|  | 						<label class="control-label col-sm-2" for="user1"><?=$lang['add']['username'];?></label>
 | ||||||
|  | 						<div class="col-sm-10"> | ||||||
|  | 						<input type="text" class="form-control" name="user1" id="user1" required> | ||||||
|  | 						</div> | ||||||
|  | 					</div> | ||||||
|  | 					<div class="form-group"> | ||||||
|  | 						<label class="control-label col-sm-2" for="password1"><?=$lang['add']['password'];?></label>
 | ||||||
|  | 						<div class="col-sm-10"> | ||||||
|  | 						<input type="text" class="form-control" name="password1" id="password1" required> | ||||||
|  | 						</div> | ||||||
|  | 					</div> | ||||||
|  | 					<div class="form-group"> | ||||||
|  | 						<label class="control-label col-sm-2" for="enc1"><?=$lang['add']['enc_method'];?></label>
 | ||||||
|  | 						<div class="col-sm-10"> | ||||||
|  | 							<select name="enc1" id="enc1" title="<?=$lang['add']['select'];?>" required> | ||||||
|  |                 <option selected>TLS</option> | ||||||
|  |                 <option>SSL</option> | ||||||
|  |                 <option>PLAIN</option> | ||||||
|  | 							</select> | ||||||
|  | 						</div> | ||||||
|  | 					</div> | ||||||
|  | 					<div class="form-group"> | ||||||
|  | 						<label class="control-label col-sm-2" for="mins_interval"><?=$lang['add']['mins_interval'];?></label>
 | ||||||
|  | 						<div class="col-sm-10"> | ||||||
|  |               <input type="number" class="form-control" name="mins_interval" min="10" max="3600" value="20" required> | ||||||
|  | 						</div> | ||||||
|  | 					</div> | ||||||
|  | 					<div class="form-group"> | ||||||
|  | 						<label class="control-label col-sm-2" for="exclude"><?=$lang['add']['exclude'];?></label>
 | ||||||
|  | 						<div class="col-sm-10"> | ||||||
|  | 						<input type="text" class="form-control" name="exclude" id="exclude" value="(?i)spam|(?i)junk"> | ||||||
|  | 						</div> | ||||||
|  | 					</div> | ||||||
|  | 					<div class="form-group"> | ||||||
|  | 						<div class="col-sm-offset-2 col-sm-10"> | ||||||
|  | 							<div class="checkbox"> | ||||||
|  | 							<label><input type="checkbox" name="delete2duplicates" checked> <?=$lang['add']['delete2duplicates'];?></label>
 | ||||||
|  | 							</div> | ||||||
|  | 						</div> | ||||||
|  | 					</div> | ||||||
|  | 					<div class="form-group"> | ||||||
|  | 						<div class="col-sm-offset-2 col-sm-10"> | ||||||
|  | 							<div class="checkbox"> | ||||||
|  | 							<label><input type="checkbox" name="active" checked> <?=$lang['add']['active'];?></label>
 | ||||||
|  | 							</div> | ||||||
|  | 						</div> | ||||||
|  | 					</div> | ||||||
|  | 					<div class="form-group"> | ||||||
|  | 						<div class="col-sm-offset-2 col-sm-10"> | ||||||
|  | 							<button type="submit" name="trigger_add_syncjob" value="1" class="btn btn-success "><?=$lang['add']['save'];?></button>
 | ||||||
|  | 						</div> | ||||||
|  | 					</div> | ||||||
|  | 				</form> | ||||||
|  | 	<?php | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| else { | else { | ||||||
| ?>
 | ?>
 | ||||||
| 				<div class="alert alert-danger" role="alert"><?=$lang['danger']['access_denied'];?></div>
 | 				<div class="alert alert-danger" role="alert"><?=$lang['danger']['access_denied'];?></div>
 | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| <?php | <?php | ||||||
| require_once("inc/prerequisites.inc.php"); | require_once("inc/prerequisites.inc.php"); | ||||||
| $AuthUsers = array("admin", "domainadmin"); | $AuthUsers = array("admin", "domainadmin", "user"); | ||||||
| if (!isset($_SESSION['mailcow_cc_role']) OR !in_array($_SESSION['mailcow_cc_role'], $AuthUsers)) { | if (!isset($_SESSION['mailcow_cc_role']) OR !in_array($_SESSION['mailcow_cc_role'], $AuthUsers)) { | ||||||
| 	header('Location: /'); | 	header('Location: /'); | ||||||
| 	exit(); | 	exit(); | ||||||
| @ -148,6 +148,50 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm | |||||||
| 		<?php | 		<?php | ||||||
| 		} | 		} | ||||||
| } | } | ||||||
|  | elseif (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "user")) { | ||||||
|  | 		// DELETE SYNCJOB
 | ||||||
|  | 		if (isset($_GET["syncjob"]) && | ||||||
|  | 			is_numeric($_GET["syncjob"]) && | ||||||
|  |       filter_var($_SESSION['mailcow_cc_username'], FILTER_VALIDATE_EMAIL)) { | ||||||
|  |         try { | ||||||
|  |           $stmt = $pdo->prepare("SELECT `user2` FROM `imapsync`
 | ||||||
|  |               WHERE `id` = :id AND user2 = :user2");
 | ||||||
|  |           $stmt->execute(array(':id' => $_GET["syncjob"], ':user2' => $_SESSION['mailcow_cc_username'])); | ||||||
|  |           $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC)); | ||||||
|  |         } | ||||||
|  |         catch(PDOException $e) { | ||||||
|  |           $_SESSION['return'] = array( | ||||||
|  |             'type' => 'danger', | ||||||
|  |             'msg' => 'MySQL: '.$e | ||||||
|  |           ); | ||||||
|  |         } | ||||||
|  | 				if ($num_results != 0 && !empty($num_results)) { | ||||||
|  | 				?>
 | ||||||
|  | 					<div class="alert alert-warning" role="alert"><?=sprintf($lang['delete']['remove_syncjob_warning'], htmlspecialchars($_SESSION['mailcow_cc_username']));?></div>
 | ||||||
|  | 					<p><?=$lang['delete']['remove_syncjob_details'];?></p>
 | ||||||
|  | 					<form class="form-horizontal" role="form" method="post" action="/user.php"> | ||||||
|  | 					<input type="hidden" name="username" value="<?=htmlspecialchars($mailbox);?>"> | ||||||
|  | 						<div class="form-group"> | ||||||
|  | 							<div class="col-sm-offset-1 col-sm-10"> | ||||||
|  | 								<input type="hidden" name="id" value="<?=$_GET["syncjob"];?>"> | ||||||
|  | 								<button type="submit" name="trigger_delete_syncjob" value="1" class="btn btn-default btn-sm"><?=$lang['delete']['remove_button'];?></button>
 | ||||||
|  | 							</div> | ||||||
|  | 						</div> | ||||||
|  | 					</form> | ||||||
|  | 				<?php | ||||||
|  | 				} | ||||||
|  | 				else { | ||||||
|  | 				?>
 | ||||||
|  | 					<div class="alert alert-info" role="alert"><?=$lang['info']['no_action'];?></div>
 | ||||||
|  | 				<?php | ||||||
|  | 				} | ||||||
|  | 		} | ||||||
|  | 		else { | ||||||
|  | 		?>
 | ||||||
|  | 			<div class="alert alert-info" role="alert"><?=$lang['info']['no_action'];?></div>
 | ||||||
|  | 		<?php | ||||||
|  | 		} | ||||||
|  | } | ||||||
| else { | else { | ||||||
| ?>
 | ?>
 | ||||||
| 	<div class="alert alert-danger" role="alert"><?=$lang['danger']['access_denied'];?></div>
 | 	<div class="alert alert-danger" role="alert"><?=$lang['danger']['access_denied'];?></div>
 | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| <?php | <?php | ||||||
| require_once("inc/prerequisites.inc.php"); | require_once("inc/prerequisites.inc.php"); | ||||||
| $AuthUsers = array("admin", "domainadmin"); | $AuthUsers = array("admin", "domainadmin", "user"); | ||||||
| if (!isset($_SESSION['mailcow_cc_role']) OR !in_array($_SESSION['mailcow_cc_role'], $AuthUsers)) { | if (!isset($_SESSION['mailcow_cc_role']) OR !in_array($_SESSION['mailcow_cc_role'], $AuthUsers)) { | ||||||
| 	header('Location: /'); | 	header('Location: /'); | ||||||
| 	exit(); | 	exit(); | ||||||
| @ -517,6 +517,104 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm | |||||||
| 	<?php | 	<?php | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "user")) { | ||||||
|  | 	if (isset($_GET['syncjob']) && | ||||||
|  |     is_numeric($_GET["syncjob"]) && | ||||||
|  |     filter_var($_SESSION['mailcow_cc_username'], FILTER_VALIDATE_EMAIL)) { | ||||||
|  | 			$id = $_GET["syncjob"]; | ||||||
|  |       $username = $_SESSION['mailcow_cc_username']; | ||||||
|  | 			try { | ||||||
|  | 				$stmt = $pdo->prepare("SELECT * FROM `imapsync` WHERE `user2` = :username AND id = :id"); | ||||||
|  | 				$stmt->execute(array( | ||||||
|  | 					':username' => $username, | ||||||
|  | 					':id' => $id | ||||||
|  | 				)); | ||||||
|  | 				$result = $stmt->fetch(PDO::FETCH_ASSOC); | ||||||
|  | 			} | ||||||
|  | 			catch(PDOException $e) { | ||||||
|  | 				$_SESSION['return'] = array( | ||||||
|  | 					'type' => 'danger', | ||||||
|  | 					'msg' => 'MySQL: '.$e | ||||||
|  | 				); | ||||||
|  |       } | ||||||
|  |       if ($result && !empty($result)) { | ||||||
|  | 			?>
 | ||||||
|  | 				<h4><?=$lang['edit']['syncjob'];?></h4>
 | ||||||
|  | 				<form class="form-horizontal" role="form" method="post" action="<?=($FORM_ACTION == "previous") ? $_SESSION['return_to'] : null;?>"> | ||||||
|  | 				<input type="hidden" name="id" value="<?=htmlspecialchars($result['id']);?>"> | ||||||
|  | 					<div class="form-group"> | ||||||
|  | 						<label class="control-label col-sm-2" for="host1"><?=$lang['edit']['hostname'];?></label>
 | ||||||
|  | 						<div class="col-sm-10"> | ||||||
|  | 						<input type="text" class="form-control" name="host1" id="host1" value="<?=htmlspecialchars($result['host1'], ENT_QUOTES, 'UTF-8');?>"> | ||||||
|  | 						</div> | ||||||
|  | 					</div> | ||||||
|  | 					<div class="form-group"> | ||||||
|  | 						<label class="control-label col-sm-2" for="port1">Port</label> | ||||||
|  | 						<div class="col-sm-10"> | ||||||
|  | 						<input type="number" class="form-control" name="port1" id="port1" min="1" max="65535" value="<?=htmlspecialchars($result['port1'], ENT_QUOTES, 'UTF-8');?>"> | ||||||
|  | 						</div> | ||||||
|  | 					</div> | ||||||
|  | 					<div class="form-group"> | ||||||
|  | 						<label class="control-label col-sm-2" for="user1"><?=$lang['edit']['username'];?></label>
 | ||||||
|  | 						<div class="col-sm-10"> | ||||||
|  | 						<input type="text" class="form-control" name="user1" id="user1" value="<?=htmlspecialchars($result['user1'], ENT_QUOTES, 'UTF-8');?>"> | ||||||
|  | 						</div> | ||||||
|  | 					</div> | ||||||
|  | 					<div class="form-group"> | ||||||
|  | 						<label class="control-label col-sm-2" for="password1"><?=$lang['edit']['password'];?></label>
 | ||||||
|  | 						<div class="col-sm-10"> | ||||||
|  | 						<input type="text" class="form-control" name="password1" id="password1" value="<?=htmlspecialchars($result['password1'], ENT_QUOTES, 'UTF-8');?>"> | ||||||
|  | 						</div> | ||||||
|  | 					</div> | ||||||
|  | 					<div class="form-group"> | ||||||
|  | 						<label class="control-label col-sm-2" for="enc1"><?=$lang['edit']['encryption'];?>:</label>
 | ||||||
|  | 						<div class="col-sm-10"> | ||||||
|  | 							<select id="enc1" name="enc1"> | ||||||
|  | 								<option <?=($result['enc1'] == "TLS") ? "selected" : null;?>>TLS</option>
 | ||||||
|  | 								<option <?=($result['enc1'] == "SSL") ? "selected" : null;?>>SSL</option>
 | ||||||
|  | 								<option <?=($result['enc1'] == "PLAIN") ? "selected" : null;?>>PLAIN</option>
 | ||||||
|  | 							</select> | ||||||
|  | 						</div> | ||||||
|  | 					</div> | ||||||
|  | 					<div class="form-group"> | ||||||
|  | 						<label class="control-label col-sm-2" for="mins_interval"><?=$lang['edit']['mins_interval'];?></label>
 | ||||||
|  | 						<div class="col-sm-10"> | ||||||
|  |               <input type="number" class="form-control" name="mins_interval" min="10" max="3600" value="<?=htmlspecialchars($result['mins_interval'], ENT_QUOTES, 'UTF-8');?>" required> | ||||||
|  | 						</div> | ||||||
|  | 					</div> | ||||||
|  | 					<div class="form-group"> | ||||||
|  | 						<label class="control-label col-sm-2" for="exclude"><?=$lang['edit']['exclude'];?></label>
 | ||||||
|  | 						<div class="col-sm-10"> | ||||||
|  | 						<input type="text" class="form-control" name="exclude" id="exclude" value="<?=htmlspecialchars($result['exclude'], ENT_QUOTES, 'UTF-8');?>"> | ||||||
|  | 						</div> | ||||||
|  | 					</div> | ||||||
|  | 					<div class="form-group"> | ||||||
|  | 						<div class="col-sm-offset-2 col-sm-10"> | ||||||
|  | 							<div class="checkbox"> | ||||||
|  | 							<label><input type="checkbox" name="active" <?=($result['active']=="1") ? "checked" : "";?>> <?=$lang['edit']['active'];?></label>
 | ||||||
|  | 							</div> | ||||||
|  | 						</div> | ||||||
|  | 					</div> | ||||||
|  | 					<div class="form-group"> | ||||||
|  | 						<div class="col-sm-offset-2 col-sm-10"> | ||||||
|  | 							<button type="submit" name="trigger_edit_syncjob" value="1" class="btn btn-success btn-sm"><?=$lang['edit']['save'];?></button>
 | ||||||
|  | 						</div> | ||||||
|  | 					</div> | ||||||
|  | 				</form> | ||||||
|  | 			<?php | ||||||
|  | 			} | ||||||
|  | 			else { | ||||||
|  | 			?>
 | ||||||
|  | 				<div class="alert alert-info" role="alert"><?=$lang['info']['no_action'];?></div>
 | ||||||
|  | 			<?php | ||||||
|  | 			} | ||||||
|  | 	} | ||||||
|  | 	else { | ||||||
|  | 	?>
 | ||||||
|  | 		<div class="alert alert-info" role="alert"><?=$lang['info']['no_action'];?></div>
 | ||||||
|  | 	<?php | ||||||
|  | 	} | ||||||
|  | } | ||||||
| else { | else { | ||||||
| ?>
 | ?>
 | ||||||
| 	<div class="alert alert-danger" role="alert"><?=$lang['danger']['access_denied'];?></div>
 | 	<div class="alert alert-danger" role="alert"><?=$lang['danger']['access_denied'];?></div>
 | ||||||
|  | |||||||
| @ -84,6 +84,30 @@ function init_db_schema() { | |||||||
|   if ($num_results == 0) { |   if ($num_results == 0) { | ||||||
|     $pdo->query("ALTER TABLE `mailbox` ADD `wants_tagged_subject` tinyint(1) NOT NULL DEFAULT '0'"); |     $pdo->query("ALTER TABLE `mailbox` ADD `wants_tagged_subject` tinyint(1) NOT NULL DEFAULT '0'"); | ||||||
|   } |   } | ||||||
|  |   $stmt = $pdo->query("SELECT * FROM information_schema.TABLES WHERE TABLE_NAME = 'imapsync'"); | ||||||
|  |   $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC)); | ||||||
|  | 
 | ||||||
|  |   if ($num_results == 0) { | ||||||
|  |     $pdo->query("CREATE TABLE IF NOT EXISTS `imapsync` (
 | ||||||
|  |       `id` int NOT NULL AUTO_INCREMENT, | ||||||
|  |       `user2` VARCHAR(255) NOT NULL, | ||||||
|  |       `host1` VARCHAR(255) NOT NULL, | ||||||
|  |       `authmech1` ENUM('PLAIN','LOGIN','CRAM-MD5') DEFAULT 'PLAIN', | ||||||
|  |       `user1` VARCHAR(255) NOT NULL, | ||||||
|  |       `exclude` VARCHAR(500) NOT NULL DEFAULT '', | ||||||
|  |       `password1` VARCHAR(255) NOT NULL, | ||||||
|  |       `mins_interval` VARCHAR(50) NOT NULL, | ||||||
|  |       `port1` SMALLINT NOT NULL, | ||||||
|  |       `enc1` ENUM('TLS','SSL','PLAIN') DEFAULT 'TLS', | ||||||
|  |       `delete2duplicates` TINYINT(1) NOT NULL DEFAULT '1', | ||||||
|  |       `returned_text` TEXT, | ||||||
|  |       `last_run` TIMESTAMP NULL DEFAULT NULL, | ||||||
|  |       `created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, | ||||||
|  |       `modified` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, | ||||||
|  |       `active` TINYINT(1) NOT NULL DEFAULT '0', | ||||||
|  |       PRIMARY KEY (`id`) | ||||||
|  |     ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;");
 | ||||||
|  |   } | ||||||
| } | } | ||||||
| function verify_ssha256($hash, $password) { | function verify_ssha256($hash, $password) { | ||||||
| 	// Remove tag if any
 | 	// Remove tag if any
 | ||||||
| @ -2466,6 +2490,247 @@ function set_tls_policy($postarray) { | |||||||
| 		'msg' => sprintf($lang['success']['mailbox_modified'], $username) | 		'msg' => sprintf($lang['success']['mailbox_modified'], $username) | ||||||
| 	); | 	); | ||||||
| } | } | ||||||
|  | function set_syncjob($postarray, $action) { | ||||||
|  | 	global $lang; | ||||||
|  | 	global $pdo; | ||||||
|  |   $username = $_SESSION['mailcow_cc_username']; | ||||||
|  |   if (!filter_var($username, FILTER_VALIDATE_EMAIL)) { | ||||||
|  |     $_SESSION['return'] = array( | ||||||
|  |       'type' => 'danger', | ||||||
|  |       'msg' => sprintf($lang['danger']['access_denied']) | ||||||
|  |     ); | ||||||
|  |     return false; | ||||||
|  |   } | ||||||
|  |   if ($_SESSION['mailcow_cc_role'] != "user") { | ||||||
|  |     $_SESSION['return'] = array( | ||||||
|  |       'type' => 'danger', | ||||||
|  |       'msg' => sprintf($lang['danger']['access_denied']) | ||||||
|  |     ); | ||||||
|  |     return false; | ||||||
|  |   } | ||||||
|  |   // DELETE
 | ||||||
|  |   if ($action == "delete") { | ||||||
|  |     $id = $postarray['id']; | ||||||
|  |     if (!is_numeric($id)) { | ||||||
|  |       $_SESSION['return'] = array( | ||||||
|  |         'type' => 'danger', | ||||||
|  |         'msg' => sprintf($lang['danger']['access_denied']) | ||||||
|  |       ); | ||||||
|  |       return false; | ||||||
|  |     } | ||||||
|  |     try { | ||||||
|  |       $stmt = $pdo->prepare("DELETE FROM `imapsync` WHERE `user2` = :username AND `id`= :id"); | ||||||
|  |       $stmt->execute(array( | ||||||
|  |         ':username' => $username, | ||||||
|  |         ':id' => $id, | ||||||
|  |       )); | ||||||
|  |     } | ||||||
|  |     catch (PDOException $e) { | ||||||
|  |       $_SESSION['return'] = array( | ||||||
|  |         'type' => 'danger', | ||||||
|  |         'msg' => 'MySQL: '.$e | ||||||
|  |       ); | ||||||
|  |       return false; | ||||||
|  |     } | ||||||
|  |     $_SESSION['return'] = array( | ||||||
|  |       'type' => 'success', | ||||||
|  |       'msg' => sprintf($lang['success']['mailbox_modified'], htmlspecialchars($username)) | ||||||
|  |     ); | ||||||
|  |     return true; | ||||||
|  |   } | ||||||
|  |   elseif ($action == "add") { | ||||||
|  |     isset($postarray['active']) ? $active = '1' : $active = '0'; | ||||||
|  |     isset($postarray['delete2duplicates']) ? $delete2duplicates = '1' : $delete2duplicates = '0'; | ||||||
|  |     $port1            = $postarray['port1']; | ||||||
|  |     $host1            = $postarray['host1']; | ||||||
|  |     $password1        = $postarray['password1']; | ||||||
|  |     $exclude          = $postarray['exclude']; | ||||||
|  |     $user1            = $postarray['user1']; | ||||||
|  |     $mins_interval    = $postarray['mins_interval']; | ||||||
|  |     $enc1             = $postarray['enc1']; | ||||||
|  | 
 | ||||||
|  |     if (!filter_var($port1, FILTER_VALIDATE_INT, array('options' => array('min_range' => 1, 'max_range' => 65535)))) { | ||||||
|  |       $_SESSION['return'] = array( | ||||||
|  |         'type' => 'danger', | ||||||
|  |         'msg' => sprintf($lang['danger']['access_denied']) | ||||||
|  |       ); | ||||||
|  |       return false; | ||||||
|  |     } | ||||||
|  |     if (!filter_var($mins_interval, FILTER_VALIDATE_INT, array('options' => array('min_range' => 10, 'max_range' => 3600)))) { | ||||||
|  |       $_SESSION['return'] = array( | ||||||
|  |         'type' => 'danger', | ||||||
|  |         'msg' => sprintf($lang['danger']['access_denied']) | ||||||
|  |       ); | ||||||
|  |       return false; | ||||||
|  |     } | ||||||
|  |     if (!is_valid_domain_name($host1)) { | ||||||
|  |       $_SESSION['return'] = array( | ||||||
|  |         'type' => 'danger', | ||||||
|  |         'msg' => sprintf($lang['danger']['access_denied']) | ||||||
|  |       ); | ||||||
|  |       return false; | ||||||
|  |     } | ||||||
|  |     if ($enc1 != "TLS" && $enc1 != "SSL" && $enc1 != "PLAIN") { | ||||||
|  |       $_SESSION['return'] = array( | ||||||
|  |         'type' => 'danger', | ||||||
|  |         'msg' => sprintf($lang['danger']['access_denied']) | ||||||
|  |       ); | ||||||
|  |       return false; | ||||||
|  |     } | ||||||
|  |     if (@preg_match("/" . $exclude . "/", null) === false) { | ||||||
|  |       $_SESSION['return'] = array( | ||||||
|  |         'type' => 'danger', | ||||||
|  |         'msg' => sprintf($lang['danger']['access_denied']) | ||||||
|  |       ); | ||||||
|  |       return false; | ||||||
|  |     } | ||||||
|  |     try { | ||||||
|  |       $stmt = $pdo->prepare("SELECT `user2`, `user1` FROM `imapsync`
 | ||||||
|  |         WHERE `user2` = :user2 AND `user1` = :user1");
 | ||||||
|  |       $stmt->execute(array(':user1' => $user1, ':user2' => $username)); | ||||||
|  |       $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC)); | ||||||
|  |     } | ||||||
|  |     catch(PDOException $e) { | ||||||
|  |       $_SESSION['return'] = array( | ||||||
|  |         'type' => 'danger', | ||||||
|  |         'msg' => 'MySQL: '.$e | ||||||
|  |       ); | ||||||
|  |       return false; | ||||||
|  |     } | ||||||
|  |     if ($num_results != 0) { | ||||||
|  |       $_SESSION['return'] = array( | ||||||
|  |         'type' => 'danger', | ||||||
|  |         'msg' => sprintf($lang['danger']['object_exists'], htmlspecialchars($host1 . ' / ' . $user1)) | ||||||
|  |       ); | ||||||
|  |       return false; | ||||||
|  |     } | ||||||
|  |     try { | ||||||
|  |       $stmt = $pdo->prepare("INSERT INTO `imapsync` (`user2`, `exclude`, `host1`, `authmech1`, `user1`, `password1`, `mins_interval`, `port1`, `enc1`, `delete2duplicates`, `active`)
 | ||||||
|  |         VALUES (:user2, :exclude, :host1, :authmech1, :user1, :password1, :mins_interval, :port1, :enc1, :delete2duplicates, :active)");
 | ||||||
|  |       $stmt->execute(array( | ||||||
|  |         ':user2' => $username, | ||||||
|  |         ':exclude' => $exclude, | ||||||
|  |         ':host1' => $host1, | ||||||
|  |         ':authmech1' => 'PLAIN', | ||||||
|  |         ':user1' => $user1, | ||||||
|  |         ':password1' => $password1, | ||||||
|  |         ':mins_interval' => $mins_interval, | ||||||
|  |         ':port1' => $port1, | ||||||
|  |         ':enc1' => $enc1, | ||||||
|  |         ':delete2duplicates' => $delete2duplicates, | ||||||
|  |         ':active' => $active, | ||||||
|  |       )); | ||||||
|  |     } | ||||||
|  |     catch(PDOException $e) { | ||||||
|  |       $_SESSION['return'] = array( | ||||||
|  |         'type' => 'danger', | ||||||
|  |         'msg' => 'MySQL: '.$e | ||||||
|  |       ); | ||||||
|  |       return false; | ||||||
|  |     } | ||||||
|  |     $_SESSION['return'] = array( | ||||||
|  |       'type' => 'success', | ||||||
|  |       'msg' => sprintf($lang['success']['mailbox_modified'], $username) | ||||||
|  |     ); | ||||||
|  |     return true; | ||||||
|  |   } | ||||||
|  |   elseif ($action == "edit") { | ||||||
|  |     isset($postarray['active']) ? $active = '1' : $active = '0'; | ||||||
|  |     isset($postarray['delete2duplicates']) ? $delete2duplicates = '1' : $delete2duplicates = '0'; | ||||||
|  |     $id               = $postarray['id']; | ||||||
|  |     $port1            = $postarray['port1']; | ||||||
|  |     $host1            = $postarray['host1']; | ||||||
|  |     $password1        = $postarray['password1']; | ||||||
|  |     $exclude          = $postarray['exclude']; | ||||||
|  |     $user1            = $postarray['user1']; | ||||||
|  |     $mins_interval    = $postarray['mins_interval']; | ||||||
|  |     $enc1             = $postarray['enc1']; | ||||||
|  |     if (!filter_var($port1, FILTER_VALIDATE_INT, array('options' => array('min_range' => 1, 'max_range' => 65535)))) { | ||||||
|  |       $_SESSION['return'] = array( | ||||||
|  |         'type' => 'danger', | ||||||
|  |         'msg' => sprintf($lang['danger']['access_denied']) | ||||||
|  |       ); | ||||||
|  |       return false; | ||||||
|  |     } | ||||||
|  |     if (!filter_var($mins_interval, FILTER_VALIDATE_INT, array('options' => array('min_range' => 10, 'max_range' => 3600)))) { | ||||||
|  |       $_SESSION['return'] = array( | ||||||
|  |         'type' => 'danger', | ||||||
|  |         'msg' => sprintf($lang['danger']['access_denied']) | ||||||
|  |       ); | ||||||
|  |       return false; | ||||||
|  |     } | ||||||
|  |     if (!is_valid_domain_name($host1)) { | ||||||
|  |       $_SESSION['return'] = array( | ||||||
|  |         'type' => 'danger', | ||||||
|  |         'msg' => sprintf($lang['danger']['access_denied']) | ||||||
|  |       ); | ||||||
|  |       return false; | ||||||
|  |     } | ||||||
|  |     if ($enc1 != "TLS" && $enc1 != "SSL" && $enc1 != "PLAIN") { | ||||||
|  |       $_SESSION['return'] = array( | ||||||
|  |         'type' => 'danger', | ||||||
|  |         'msg' => sprintf($lang['danger']['access_denied']) | ||||||
|  |       ); | ||||||
|  |       return false; | ||||||
|  |     } | ||||||
|  |     if (@preg_match("/" . $exclude . "/", null) === false) { | ||||||
|  |       $_SESSION['return'] = array( | ||||||
|  |         'type' => 'danger', | ||||||
|  |         'msg' => sprintf($lang['danger']['access_denied']) | ||||||
|  |       ); | ||||||
|  |       return false; | ||||||
|  |     } | ||||||
|  |     try { | ||||||
|  |       $stmt = $pdo->prepare("SELECT `user2` FROM `imapsync`
 | ||||||
|  |         WHERE `user2` = :user2 AND `id` = :id");
 | ||||||
|  |       $stmt->execute(array(':user2' => $username, ':id' => $id)); | ||||||
|  |       $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC)); | ||||||
|  |     } | ||||||
|  |     catch(PDOException $e) { | ||||||
|  |       $_SESSION['return'] = array( | ||||||
|  |         'type' => 'danger', | ||||||
|  |         'msg' => 'MySQL: '.$e | ||||||
|  |       ); | ||||||
|  |       return false; | ||||||
|  |     } | ||||||
|  |     if (empty($num_results)) { | ||||||
|  |       $_SESSION['return'] = array( | ||||||
|  |         'type' => 'danger', | ||||||
|  |         'msg' => sprintf($lang['danger']['access_denied']) | ||||||
|  |       ); | ||||||
|  |       return false; | ||||||
|  |     } | ||||||
|  |     try { | ||||||
|  |       $stmt = $pdo->prepare("UPDATE `imapsync` set `exclude` = :exclude, `host1` = :host1, `user1` = :user1, `password1` = :password1, `mins_interval` = :mins_interval, `port1` = :port1, `enc1` = :enc1, `delete2duplicates` = :delete2duplicates, `active` = :active
 | ||||||
|  |         WHERE `user2` = :user2 AND `id` = :id");
 | ||||||
|  |       $stmt->execute(array( | ||||||
|  |         ':user2' => $username, | ||||||
|  |         ':id' => $id, | ||||||
|  |         ':exclude' => $exclude, | ||||||
|  |         ':host1' => $host1, | ||||||
|  |         ':user1' => $user1, | ||||||
|  |         ':password1' => $password1, | ||||||
|  |         ':mins_interval' => $mins_interval, | ||||||
|  |         ':port1' => $port1, | ||||||
|  |         ':enc1' => $enc1, | ||||||
|  |         ':delete2duplicates' => $delete2duplicates, | ||||||
|  |         ':active' => $active, | ||||||
|  |       )); | ||||||
|  |     } | ||||||
|  |     catch(PDOException $e) { | ||||||
|  |       $_SESSION['return'] = array( | ||||||
|  |         'type' => 'danger', | ||||||
|  |         'msg' => 'MySQL: '.$e | ||||||
|  |       ); | ||||||
|  |       return false; | ||||||
|  |     } | ||||||
|  |     $_SESSION['return'] = array( | ||||||
|  |       'type' => 'success', | ||||||
|  |       'msg' => sprintf($lang['success']['mailbox_modified'], $username) | ||||||
|  |     ); | ||||||
|  |     return true; | ||||||
|  |   } | ||||||
|  | } | ||||||
| function get_tls_policy($username) { | function get_tls_policy($username) { | ||||||
| 	global $lang; | 	global $lang; | ||||||
| 	global $pdo; | 	global $pdo; | ||||||
|  | |||||||
| @ -102,6 +102,26 @@ CREATE TABLE IF NOT EXISTS `filterconf` ( | |||||||
| 	KEY `object` (`object`) | 	KEY `object` (`object`) | ||||||
| ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; | ||||||
| 
 | 
 | ||||||
|  | CREATE TABLE IF NOT EXISTS `imapsync` ( | ||||||
|  |   `id` int NOT NULL AUTO_INCREMENT, | ||||||
|  |   `user2` varchar(255) NOT NULL, | ||||||
|  |   `host1` varchar(255) NOT NULL, | ||||||
|  |   `authmech1` ENUM('PLAIN','LOGIN','CRAM-MD5') DEFAULT 'PLAIN', | ||||||
|  |   `user1` varchar(255) NOT NULL, | ||||||
|  |   `password1` varchar(255) NOT NULL, | ||||||
|  |   `exclude` VARCHAR(500) NOT NULL DEFAULT '', | ||||||
|  |   `mins_interval` VARCHAR(50) NOT NULL, | ||||||
|  |   `port1` SMALLINT NOT NULL, | ||||||
|  |   `enc1` ENUM('TLS','SSL','PLAIN') DEFAULT 'TLS', | ||||||
|  |   `delete2duplicates` TINYINT(1) NOT NULL DEFAULT '1', | ||||||
|  |   `returned_text` TEXT, | ||||||
|  |   `last_run` TIMESTAMP NULL DEFAULT NULL, | ||||||
|  |   `created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, | ||||||
|  |   `modified` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, | ||||||
|  |   `active` TINYINT(1) NOT NULL DEFAULT '0', | ||||||
|  |   PRIMARY KEY (`id`) | ||||||
|  | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; | ||||||
|  | 
 | ||||||
| DROP VIEW IF EXISTS grouped_mail_aliases; | DROP VIEW IF EXISTS grouped_mail_aliases; | ||||||
| DROP VIEW IF EXISTS grouped_sender_acl; | DROP VIEW IF EXISTS grouped_sender_acl; | ||||||
| DROP VIEW IF EXISTS grouped_domain_alias_address; | DROP VIEW IF EXISTS grouped_domain_alias_address; | ||||||
|  | |||||||
| @ -60,6 +60,15 @@ if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == "user | |||||||
| 	if (isset($_POST["trigger_set_tls_policy"])) { | 	if (isset($_POST["trigger_set_tls_policy"])) { | ||||||
| 		set_tls_policy($_POST); | 		set_tls_policy($_POST); | ||||||
| 	} | 	} | ||||||
|  | 	if (isset($_POST["trigger_add_syncjob"])) { | ||||||
|  | 		set_syncjob($_POST, "add"); | ||||||
|  | 	} | ||||||
|  | 	if (isset($_POST["trigger_edit_syncjob"])) { | ||||||
|  | 		set_syncjob($_POST, "edit"); | ||||||
|  | 	} | ||||||
|  | 	if (isset($_POST["trigger_delete_syncjob"])) { | ||||||
|  | 		set_syncjob($_POST, "delete"); | ||||||
|  | 	} | ||||||
| 	if (isset($_POST["trigger_set_time_limited_aliases"])) { | 	if (isset($_POST["trigger_set_time_limited_aliases"])) { | ||||||
| 		set_time_limited_aliases($_POST); | 		set_time_limited_aliases($_POST); | ||||||
| 	} | 	} | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| <?php | <?php | ||||||
| error_reporting(0); | error_reporting(E_ALL); | ||||||
| 
 | 
 | ||||||
| /* | /* | ||||||
| PLEASE USE THE FILE "vars.local.inc.php" TO OVERWRITE SETTINGS AND MAKE THEM PERSISTENT! | PLEASE USE THE FILE "vars.local.inc.php" TO OVERWRITE SETTINGS AND MAKE THEM PERSISTENT! | ||||||
|  | |||||||
| @ -25,4 +25,10 @@ $(document).ready(function() { | |||||||
| 	$.fn.bootstrapSwitch.defaults.onColor = 'success'; | 	$.fn.bootstrapSwitch.defaults.onColor = 'success'; | ||||||
| 	$("[name='tls_out']").bootstrapSwitch(); | 	$("[name='tls_out']").bootstrapSwitch(); | ||||||
| 	$("[name='tls_in']").bootstrapSwitch(); | 	$("[name='tls_in']").bootstrapSwitch(); | ||||||
|  | 
 | ||||||
|  |   // Log modal
 | ||||||
|  |   $('#logModal').on('show.bs.modal', function(e) { | ||||||
|  |   var logText = $(e.relatedTarget).data('log-text'); | ||||||
|  |   $(e.currentTarget).find('#logText').html('<pre>' + logText + '</pre>'); | ||||||
|  |   }); | ||||||
| }); | }); | ||||||
| @ -111,7 +111,9 @@ $lang['user']['alias_valid_until'] = 'Gültig bis'; | |||||||
| $lang['user']['alias_remove_all'] = 'Alle entfernen'; | $lang['user']['alias_remove_all'] = 'Alle entfernen'; | ||||||
| $lang['user']['alias_time_left'] = 'Zeit verbleibend'; | $lang['user']['alias_time_left'] = 'Zeit verbleibend'; | ||||||
| $lang['user']['alias_full_date'] = 'd.m.Y, H:i:s T'; | $lang['user']['alias_full_date'] = 'd.m.Y, H:i:s T'; | ||||||
|  | $lang['user']['syncjob_full_date'] = 'd.m.Y, H:i:s T'; | ||||||
| $lang['user']['alias_select_validity'] = 'Bitte Gültigkeit auswählen'; | $lang['user']['alias_select_validity'] = 'Bitte Gültigkeit auswählen'; | ||||||
|  | $lang['user']['sync_jobs'] = 'Sync Jobs'; | ||||||
| $lang['user']['hour'] = 'Stunde'; | $lang['user']['hour'] = 'Stunde'; | ||||||
| $lang['user']['hours'] = 'Stunden'; | $lang['user']['hours'] = 'Stunden'; | ||||||
| $lang['user']['day'] = 'Tag'; | $lang['user']['day'] = 'Tag'; | ||||||
| @ -151,6 +153,18 @@ $lang['user']['tag_help_explain'] = 'Als Unterordner: Es wird ein Ordner mit dem | |||||||
| In Betreff: Der Name des Tags wird dem Betreff angefügt, etwa "[Facebook] Meine Neuigkeiten".'; | In Betreff: Der Name des Tags wird dem Betreff angefügt, etwa "[Facebook] Meine Neuigkeiten".'; | ||||||
| $lang['user']['tag_help_example'] = 'Beispiel für eine getaggte E-Mail-Adresse: ich<b>+Facebook</b>@example.org'; | $lang['user']['tag_help_example'] = 'Beispiel für eine getaggte E-Mail-Adresse: ich<b>+Facebook</b>@example.org'; | ||||||
| 
 | 
 | ||||||
|  | $lang['user']['encryption'] = 'Verschlüsselung'; | ||||||
|  | $lang['user']['username'] = 'Benutzername'; | ||||||
|  | $lang['user']['password'] = 'Password'; | ||||||
|  | $lang['user']['last_run'] = 'Letzte Ausführung'; | ||||||
|  | $lang['user']['excludes'] = 'Ausschlüsse'; | ||||||
|  | $lang['user']['interval'] = 'Intervall'; | ||||||
|  | $lang['user']['active'] = 'Aktiv'; | ||||||
|  | $lang['user']['action'] = 'Aktion'; | ||||||
|  | $lang['user']['edit'] = 'Bearbeiten'; | ||||||
|  | $lang['user']['remove'] = 'Entfernen'; | ||||||
|  | $lang['user']['create_syncjob'] = 'Neuen Sync-Job erstellen'; | ||||||
|  | 
 | ||||||
| $lang['start']['dashboard'] = '%s - Dashboard'; | $lang['start']['dashboard'] = '%s - Dashboard'; | ||||||
| $lang['start']['start_rc'] = 'Roundcube öffnen'; | $lang['start']['start_rc'] = 'Roundcube öffnen'; | ||||||
| $lang['start']['start_sogo'] = 'SOGo öffnen'; | $lang['start']['start_sogo'] = 'SOGo öffnen'; | ||||||
| @ -219,14 +233,22 @@ $lang['delete']['remove_domain_warning'] = '<b>Warnung:</b> Sie entfernen die Do | |||||||
| $lang['delete']['remove_domainalias_warning'] = '<b>Warnung:</b> Sie entfernen die Alias-Domain <b>%s</b>!'; | $lang['delete']['remove_domainalias_warning'] = '<b>Warnung:</b> Sie entfernen die Alias-Domain <b>%s</b>!'; | ||||||
| $lang['delete']['remove_domainadmin_warning'] = '<b>Warnung:</b> Sie entfernen den Domain-Administrator <b>%s</b>!'; | $lang['delete']['remove_domainadmin_warning'] = '<b>Warnung:</b> Sie entfernen den Domain-Administrator <b>%s</b>!'; | ||||||
| $lang['delete']['remove_alias_warning'] = '<b>Warnung:</b> Sie entfernen die Alias-Adresse <b>%s</b>!'; | $lang['delete']['remove_alias_warning'] = '<b>Warnung:</b> Sie entfernen die Alias-Adresse <b>%s</b>!'; | ||||||
|  | $lang['delete']['remove_syncjob_warning'] = '<b>Warnung:</b> Sie entfernen einen Sync-Job des Benutzers <b>%s</b>!'; | ||||||
| $lang['delete']['remove_mailbox_warning'] = '<b>Warnung:</b> Sie entfernen die Mailbox <b>%s</b>!'; | $lang['delete']['remove_mailbox_warning'] = '<b>Warnung:</b> Sie entfernen die Mailbox <b>%s</b>!'; | ||||||
| $lang['delete']['remove_mailbox_details'] = 'Die Mailbox wird <b>vollständig und permanent</b> entfernt!'; | $lang['delete']['remove_mailbox_details'] = 'Die Mailbox wird <b>vollständig und permanent</b> entfernt!'; | ||||||
| $lang['delete']['remove_domain_details'] = 'Diese Aktion entfernt ebenfalls Domain-Aliasse.<br /><br /><b>Eine Domain muss leer sein, um entfernt zu werden.</b>'; | $lang['delete']['remove_domain_details'] = 'Diese Aktion entfernt ebenfalls Domain-Aliasse.<br /><br /><b>Eine Domain muss leer sein, um entfernt zu werden.</b>'; | ||||||
|  | $lang['delete']['remove_syncjob_details'] = 'Objekte dieses Sync-Jobs werden nicht mehr vom entfernten Server abgeholt.'; | ||||||
| $lang['delete']['remove_alias_details'] = 'Benutzer werden keine Nachrichten mehr von dieser Adresse erhalten und versenden koennen!</b>'; | $lang['delete']['remove_alias_details'] = 'Benutzer werden keine Nachrichten mehr von dieser Adresse erhalten und versenden koennen!</b>'; | ||||||
| $lang['delete']['remove_button'] = 'Entfernen'; | $lang['delete']['remove_button'] = 'Entfernen'; | ||||||
| $lang['delete']['previous'] = 'Vorherige Seite'; | $lang['delete']['previous'] = 'Vorherige Seite'; | ||||||
| 
 | 
 | ||||||
|  | $lang['edit']['syncjob'] = 'Sync-Job bearbeiten'; | ||||||
| $lang['edit']['save'] = 'Änderungen speichern'; | $lang['edit']['save'] = 'Änderungen speichern'; | ||||||
|  | $lang['edit']['username'] = 'Benutzername'; | ||||||
|  | $lang['edit']['hostname'] = 'Servername'; | ||||||
|  | $lang['edit']['encryption'] = 'Verschlüsselungsmethode'; | ||||||
|  | $lang['edit']['mins_interval'] = 'Intervall (min)'; | ||||||
|  | $lang['edit']['exclude'] = 'Elemente ausschließen (Regex)'; | ||||||
| $lang['edit']['archive'] = 'Archiv-Zugriff'; | $lang['edit']['archive'] = 'Archiv-Zugriff'; | ||||||
| $lang['edit']['max_mailboxes'] = 'Max. Mailboxanzahl:'; | $lang['edit']['max_mailboxes'] = 'Max. Mailboxanzahl:'; | ||||||
| $lang['edit']['title'] = 'Objekt bearbeiten'; | $lang['edit']['title'] = 'Objekt bearbeiten'; | ||||||
| @ -265,6 +287,15 @@ $lang['edit']['previous'] = 'Vorherige Seite'; | |||||||
| $lang['edit']['unchanged_if_empty'] = 'Unverändert, wenn leer'; | $lang['edit']['unchanged_if_empty'] = 'Unverändert, wenn leer'; | ||||||
| $lang['edit']['dont_check_sender_acl'] = 'Absender für Domain %s nicht prüfen'; | $lang['edit']['dont_check_sender_acl'] = 'Absender für Domain %s nicht prüfen'; | ||||||
| 
 | 
 | ||||||
|  | $lang['add']['syncjob'] = 'Sync-Job erstellen'; | ||||||
|  | $lang['add']['syncjob_hint'] = 'Passwörter werden unverschlüsselt abgelegt!'; | ||||||
|  | $lang['add']['hostname'] = 'Servername'; | ||||||
|  | $lang['add']['username'] = 'Benutzername'; | ||||||
|  | $lang['add']['enc_method'] = 'Verschlüsselungsmethode'; | ||||||
|  | $lang['add']['mins_interval'] = 'Abrufintervall (Minuten)'; | ||||||
|  | $lang['add']['exclude'] = 'Elemente ausschließen (Regex)'; | ||||||
|  | $lang['add']['delete2duplicates'] = 'Lösche Duplikate im Ziel'; | ||||||
|  | 
 | ||||||
| $lang['add']['title'] = 'Objekt anlegen'; | $lang['add']['title'] = 'Objekt anlegen'; | ||||||
| $lang['add']['domain'] = 'Domain'; | $lang['add']['domain'] = 'Domain'; | ||||||
| $lang['add']['active'] = 'Aktiv'; | $lang['add']['active'] = 'Aktiv'; | ||||||
|  | |||||||
| @ -106,14 +106,16 @@ $lang['user']['alias'] = 'Alias'; | |||||||
| $lang['user']['aliases'] = 'Aliases'; | $lang['user']['aliases'] = 'Aliases'; | ||||||
| $lang['user']['is_catch_all'] = 'Catch-all for domain/s'; | $lang['user']['is_catch_all'] = 'Catch-all for domain/s'; | ||||||
| $lang['user']['aliases_also_send_as'] = 'Also allowed to send as'; | $lang['user']['aliases_also_send_as'] = 'Also allowed to send as'; | ||||||
| $lang['user']['aliases_send_as_all'] = 'Do not check sender access for following domains'; | $lang['user']['aliases_send_as_all'] = 'Do not check sender access for following domain/s'; | ||||||
| $lang['user']['alias_create_random'] = 'Generate random alias'; | $lang['user']['alias_create_random'] = 'Generate random alias'; | ||||||
| $lang['user']['alias_extend_all'] = 'Extend aliases by 1 hour'; | $lang['user']['alias_extend_all'] = 'Extend aliases by 1 hour'; | ||||||
| $lang['user']['alias_valid_until'] = 'Valid until'; | $lang['user']['alias_valid_until'] = 'Valid until'; | ||||||
| $lang['user']['alias_remove_all'] = 'Remove all aliases'; | $lang['user']['alias_remove_all'] = 'Remove all aliases'; | ||||||
| $lang['user']['alias_time_left'] = 'Time left'; | $lang['user']['alias_time_left'] = 'Time left'; | ||||||
| $lang['user']['alias_full_date'] = 'd.m.Y, H:i:s T'; | $lang['user']['alias_full_date'] = 'd.m.Y, H:i:s T'; | ||||||
|  | $lang['user']['syncjob_full_date'] = 'd.m.Y, H:i:s T'; | ||||||
| $lang['user']['alias_select_validity'] = 'Period of validity'; | $lang['user']['alias_select_validity'] = 'Period of validity'; | ||||||
|  | $lang['user']['sync_jobs'] = 'Sync jobs'; | ||||||
| $lang['user']['hour'] = 'Hour'; | $lang['user']['hour'] = 'Hour'; | ||||||
| $lang['user']['hours'] = 'Hours'; | $lang['user']['hours'] = 'Hours'; | ||||||
| $lang['user']['day'] = 'Day'; | $lang['user']['day'] = 'Day'; | ||||||
| @ -153,6 +155,18 @@ $lang['user']['tag_help_explain'] = 'In subfolder: a new subfolder named after t | |||||||
| In subject: the tags name will be prepended to the mails subject, example: "[Facebook] Meine Neuigkeiten".'; | In subject: the tags name will be prepended to the mails subject, example: "[Facebook] Meine Neuigkeiten".'; | ||||||
| $lang['user']['tag_help_example'] = 'Example for a tagged email address: ich<b>+Facebook</b>@example.org'; | $lang['user']['tag_help_example'] = 'Example for a tagged email address: ich<b>+Facebook</b>@example.org'; | ||||||
| 
 | 
 | ||||||
|  | $lang['user']['encryption'] = 'Encyrption'; | ||||||
|  | $lang['user']['username'] = 'Username'; | ||||||
|  | $lang['user']['password'] = 'Password'; | ||||||
|  | $lang['user']['last_run'] = 'Last run'; | ||||||
|  | $lang['user']['excludes'] = 'Excludes'; | ||||||
|  | $lang['user']['interval'] = 'Interval'; | ||||||
|  | $lang['user']['active'] = 'Active'; | ||||||
|  | $lang['user']['action'] = 'Action'; | ||||||
|  | $lang['user']['edit'] = 'Edit'; | ||||||
|  | $lang['user']['remove'] = 'Remove'; | ||||||
|  | $lang['user']['create_syncjob'] = 'Create new sync job'; | ||||||
|  | 
 | ||||||
| $lang['start']['dashboard'] = '%s - dashboard'; | $lang['start']['dashboard'] = '%s - dashboard'; | ||||||
| $lang['start']['start_rc'] = 'Open Roundcube'; | $lang['start']['start_rc'] = 'Open Roundcube'; | ||||||
| $lang['start']['start_sogo'] = 'Open SOGo'; | $lang['start']['start_sogo'] = 'Open SOGo'; | ||||||
| @ -218,27 +232,36 @@ $lang['info']['no_action'] = 'No action applicable'; | |||||||
| 
 | 
 | ||||||
| $lang['delete']['title'] = 'Remove object'; | $lang['delete']['title'] = 'Remove object'; | ||||||
| $lang['delete']['remove_domain_warning'] = '<b>Warning:</b> You are about to remove the domain <b>%s</b>!'; | $lang['delete']['remove_domain_warning'] = '<b>Warning:</b> You are about to remove the domain <b>%s</b>!'; | ||||||
|  | $lang['delete']['remove_syncjob_warning'] = '<b>Warning:</b> You are about to remove a sync job for user <b>%s</b>!'; | ||||||
| $lang['delete']['remove_domainalias_warning'] = '<b>Warning:</b> You are about to remove the domain alias <b>%s</b>!'; | $lang['delete']['remove_domainalias_warning'] = '<b>Warning:</b> You are about to remove the domain alias <b>%s</b>!'; | ||||||
| $lang['delete']['remove_domainadmin_warning'] = '<b>Warning:</b> You are about to remove the domain administrator <b>%s</b>!'; | $lang['delete']['remove_domainadmin_warning'] = '<b>Warning:</b> You are about to remove the domain administrator <b>%s</b>!'; | ||||||
| $lang['delete']['remove_alias_warning'] = '<b>Warning:</b> You are about to remove the alias address <b>%s</b>!'; | $lang['delete']['remove_alias_warning'] = '<b>Warning:</b> You are about to remove the alias address <b>%s</b>!'; | ||||||
| $lang['delete']['remove_mailbox_warning'] = '<b>Warning:</b> You are about to remove the mailbox <b>%s</b>!'; | $lang['delete']['remove_mailbox_warning'] = '<b>Warning:</b> You are about to remove the mailbox <b>%s</b>!'; | ||||||
| $lang['delete']['remove_mailbox_details'] = 'The mailbox will be <b>purged permanently</b>!'; | $lang['delete']['remove_mailbox_details'] = 'The mailbox will be <b>purged permanently</b>!'; | ||||||
| $lang['delete']['remove_domain_details'] = 'This also removes domain aliases.<br /><br /><b>A domain must be empty to be removed.</b>'; | $lang['delete']['remove_domain_details'] = 'This also removes domain aliases.<br /><br /><b>A domain must be empty to be removed.</b>'; | ||||||
|  | $lang['delete']['remove_syncjob_details'] = 'Objects from this sync job will not be pulled from the remote server anymore.'; | ||||||
| $lang['delete']['remove_alias_details'] = 'Users will no longer be able to receive mail for or send mail from this address.</b>'; | $lang['delete']['remove_alias_details'] = 'Users will no longer be able to receive mail for or send mail from this address.</b>'; | ||||||
| $lang['delete']['remove_button'] = 'Remove'; | $lang['delete']['remove_button'] = 'Remove'; | ||||||
| $lang['delete']['previous'] = 'Previous page'; | $lang['delete']['previous'] = 'Previous page'; | ||||||
| 
 | 
 | ||||||
|  | $lang['edit']['syncjob'] = 'Edit sync job'; | ||||||
|  | $lang['edit']['save'] = 'Save changes'; | ||||||
|  | $lang['edit']['username'] = 'Save changes'; | ||||||
|  | $lang['edit']['hostname'] = 'Hostname'; | ||||||
|  | $lang['edit']['encryption'] = 'Encryption'; | ||||||
|  | $lang['edit']['mins_interval'] = 'Interval (min)'; | ||||||
|  | $lang['edit']['exclude'] = 'Exclude objects (regex)'; | ||||||
| $lang['edit']['save'] = 'Save changes'; | $lang['edit']['save'] = 'Save changes'; | ||||||
| $lang['edit']['archive'] = 'Archive access'; | $lang['edit']['archive'] = 'Archive access'; | ||||||
| $lang['edit']['max_mailboxes'] = 'Max. possible mailboxes:'; | $lang['edit']['max_mailboxes'] = 'Max. possible mailboxes'; | ||||||
| $lang['edit']['title'] = 'Edit object'; | $lang['edit']['title'] = 'Edit object'; | ||||||
| $lang['edit']['target_address'] = 'Goto address/es <small>(comma-separated)</small>:'; | $lang['edit']['target_address'] = 'Goto address/es <small>(comma-separated)</small>'; | ||||||
| $lang['edit']['active'] = 'Active'; | $lang['edit']['active'] = 'Active'; | ||||||
| $lang['edit']['target_domain'] = 'Target domain:'; | $lang['edit']['target_domain'] = 'Target domain'; | ||||||
| $lang['edit']['password'] = 'Password:'; | $lang['edit']['password'] = 'Password'; | ||||||
| $lang['edit']['ratelimit'] = 'Outgoing rate limit/h:'; | $lang['edit']['ratelimit'] = 'Outgoing rate limit/h'; | ||||||
| $lang['danger']['ratelimt_less_one'] = 'Outgoing rate limit/h must not be less than 1'; | $lang['danger']['ratelimt_less_one'] = 'Outgoing rate limit/h must not be less than 1'; | ||||||
| $lang['edit']['password_repeat'] = 'Confirmation password (repeat):'; | $lang['edit']['password_repeat'] = 'Confirmation password (repeat)'; | ||||||
| $lang['edit']['domain_admin'] = 'Edit domain administrator'; | $lang['edit']['domain_admin'] = 'Edit domain administrator'; | ||||||
| $lang['edit']['domain'] = 'Edit domain'; | $lang['edit']['domain'] = 'Edit domain'; | ||||||
| $lang['edit']['alias_domain'] = 'Alias domain'; | $lang['edit']['alias_domain'] = 'Alias domain'; | ||||||
| @ -247,14 +270,14 @@ $lang['edit']['domains'] = 'Domains'; | |||||||
| $lang['edit']['destroy'] = 'Manual data input'; | $lang['edit']['destroy'] = 'Manual data input'; | ||||||
| $lang['edit']['alias'] = 'Edit alias'; | $lang['edit']['alias'] = 'Edit alias'; | ||||||
| $lang['edit']['mailbox'] = 'Edit mailbox'; | $lang['edit']['mailbox'] = 'Edit mailbox'; | ||||||
| $lang['edit']['description'] = 'Description:'; | $lang['edit']['description'] = 'Description'; | ||||||
| $lang['edit']['max_aliases'] = 'Max. aliases:'; | $lang['edit']['max_aliases'] = 'Max. aliases'; | ||||||
| $lang['edit']['max_quota'] = 'Max. quota per mailbox (MiB):'; | $lang['edit']['max_quota'] = 'Max. quota per mailbox (MiB)'; | ||||||
| $lang['edit']['domain_quota'] = 'Domain quota:'; | $lang['edit']['domain_quota'] = 'Domain quota'; | ||||||
| $lang['edit']['backup_mx_options'] = 'Backup MX options:'; | $lang['edit']['backup_mx_options'] = 'Backup MX options'; | ||||||
| $lang['edit']['relay_domain'] = 'Relay domain'; | $lang['edit']['relay_domain'] = 'Relay domain'; | ||||||
| $lang['edit']['relay_all'] = 'Relay all recipients'; | $lang['edit']['relay_all'] = 'Relay all recipients'; | ||||||
| $lang['edit']['dkim_signature'] = 'DKIM signature:'; | $lang['edit']['dkim_signature'] = 'DKIM signature'; | ||||||
| $lang['edit']['dkim_record_info'] = '<small>Please add a TXT record with the given value to your DNS settings.</small>'; | $lang['edit']['dkim_record_info'] = '<small>Please add a TXT record with the given value to your DNS settings.</small>'; | ||||||
| $lang['edit']['relay_all_info'] = '<small>If you choose <b>not</b> to relay all recipients, you will need to add a ("blind") mailbox for every single recipient that should be relayed.</small>'; | $lang['edit']['relay_all_info'] = '<small>If you choose <b>not</b> to relay all recipients, you will need to add a ("blind") mailbox for every single recipient that should be relayed.</small>'; | ||||||
| $lang['edit']['full_name'] = 'Full name'; | $lang['edit']['full_name'] = 'Full name'; | ||||||
| @ -267,6 +290,15 @@ $lang['edit']['previous'] = 'Previous page'; | |||||||
| $lang['edit']['unchanged_if_empty'] = 'If unchanged leave blank'; | $lang['edit']['unchanged_if_empty'] = 'If unchanged leave blank'; | ||||||
| $lang['edit']['dont_check_sender_acl'] = 'Do not check sender for domain %s'; | $lang['edit']['dont_check_sender_acl'] = 'Do not check sender for domain %s'; | ||||||
| 
 | 
 | ||||||
|  | $lang['add']['syncjob'] = 'Add sync job'; | ||||||
|  | $lang['add']['syncjob_hint'] = 'Be aware that passwords need to be saved plain-text!'; | ||||||
|  | $lang['add']['hostname'] = 'Hostname'; | ||||||
|  | $lang['add']['username'] = 'Username'; | ||||||
|  | $lang['add']['enc_method'] = 'Encryption method'; | ||||||
|  | $lang['add']['mins_interval'] = 'Polling interval (minutes)'; | ||||||
|  | $lang['add']['exclude'] = 'Exclude objects (regex)'; | ||||||
|  | $lang['add']['delete2duplicates'] = 'Delete duplicates on destination'; | ||||||
|  | 
 | ||||||
| $lang['add']['title'] = 'Add object'; | $lang['add']['title'] = 'Add object'; | ||||||
| $lang['add']['domain'] = 'Domain'; | $lang['add']['domain'] = 'Domain'; | ||||||
| $lang['add']['active'] = 'Active'; | $lang['add']['active'] = 'Active'; | ||||||
|  | |||||||
| @ -9,7 +9,6 @@ if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == 'user | |||||||
| ?>
 | ?>
 | ||||||
| <div class="container"> | <div class="container"> | ||||||
| <h3><?=$lang['user']['mailbox_settings'];?></h3>
 | <h3><?=$lang['user']['mailbox_settings'];?></h3>
 | ||||||
| <p class="help-block"><?=$lang['user']['did_you_know'];?></p>
 |  | ||||||
| 
 | 
 | ||||||
| <div class="panel panel-default"> | <div class="panel panel-default"> | ||||||
| <div class="panel-heading"><?=$lang['user']['mailbox_details'];?></div>
 | <div class="panel-heading"><?=$lang['user']['mailbox_details'];?></div>
 | ||||||
| @ -26,13 +25,13 @@ if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == 'user | |||||||
|       <div class="form-group"> |       <div class="form-group"> | ||||||
|         <label class="control-label col-sm-3" for="user_new_pass"><?=$lang['user']['new_password'];?></label>
 |         <label class="control-label col-sm-3" for="user_new_pass"><?=$lang['user']['new_password'];?></label>
 | ||||||
|         <div class="col-sm-5"> |         <div class="col-sm-5"> | ||||||
|         <input type="password" class="form-control" pattern=".{6,}" name="user_new_pass" id="user_new_pass" autocomplete="off" disabled="disabled" required> |         <input type="password" class="form-control" name="user_new_pass" id="user_new_pass" autocomplete="off" disabled="disabled" required> | ||||||
|         </div> |         </div> | ||||||
|       </div> |       </div> | ||||||
|       <div class="form-group"> |       <div class="form-group"> | ||||||
|         <label class="control-label col-sm-3" for="user_new_pass2"><?=$lang['user']['new_password_repeat'];?></label>
 |         <label class="control-label col-sm-3" for="user_new_pass2"><?=$lang['user']['new_password_repeat'];?></label>
 | ||||||
|         <div class="col-sm-5"> |         <div class="col-sm-5"> | ||||||
|         <input type="password" class="form-control" pattern=".{6,}" name="user_new_pass2" id="user_new_pass2" disabled="disabled" autocomplete="off" required> |         <input type="password" class="form-control" name="user_new_pass2" id="user_new_pass2" disabled="disabled" autocomplete="off" required> | ||||||
|         <p class="help-block"><?=$lang['user']['new_password_description'];?></p>
 |         <p class="help-block"><?=$lang['user']['new_password_description'];?></p>
 | ||||||
|         </div> |         </div> | ||||||
|       </div> |       </div> | ||||||
| @ -102,6 +101,7 @@ if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == 'user | |||||||
| 	<li role="presentation" class="active"><a href="#SpamAliases" aria-controls="SpamAliases" role="tab" data-toggle="tab"><?=$lang['user']['spam_aliases'];?></a></li>
 | 	<li role="presentation" class="active"><a href="#SpamAliases" aria-controls="SpamAliases" role="tab" data-toggle="tab"><?=$lang['user']['spam_aliases'];?></a></li>
 | ||||||
| 	<li role="presentation"><a href="#Spamfilter" aria-controls="Spamfilter" role="tab" data-toggle="tab"><?=$lang['user']['spamfilter'];?></a></li>
 | 	<li role="presentation"><a href="#Spamfilter" aria-controls="Spamfilter" role="tab" data-toggle="tab"><?=$lang['user']['spamfilter'];?></a></li>
 | ||||||
| 	<li role="presentation"><a href="#TLSPolicy" aria-controls="TLSPolicy" role="tab" data-toggle="tab"><?=$lang['user']['tls_policy'];?></a></li>
 | 	<li role="presentation"><a href="#TLSPolicy" aria-controls="TLSPolicy" role="tab" data-toggle="tab"><?=$lang['user']['tls_policy'];?></a></li>
 | ||||||
|  | 	<li role="presentation"><a href="#Syncjobs" aria-controls="Syncjobs" role="tab" data-toggle="tab"><?=$lang['user']['sync_jobs'];?></a></li>
 | ||||||
| </ul> | </ul> | ||||||
| <hr> | <hr> | ||||||
| 
 | 
 | ||||||
| @ -364,8 +364,96 @@ if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == 'user | |||||||
| 			</div> | 			</div> | ||||||
| 		</form> | 		</form> | ||||||
| 	</div> | 	</div> | ||||||
|  | 	<div role="tabpanel" class="tab-pane" id="Syncjobs"> | ||||||
|  | 		<table class="table table-striped sortable-theme-bootstrap" data-sortable id="timelimitedaliases"> | ||||||
|  | 			<thead> | ||||||
|  | 			<tr> | ||||||
|  | 				<th class="sort-table" style="min-width: 96px;">Server:Port</th> | ||||||
|  | 				<th class="sort-table" style="min-width: 96px;"><?=$lang['user']['encryption'];?></th>
 | ||||||
|  | 				<th class="sort-table" style="min-width: 96px;"><?=$lang['user']['username'];?></th>
 | ||||||
|  | 				<th class="sort-table" style="min-width: 35px;"><?=$lang['user']['excludes'];?></th>
 | ||||||
|  | 				<th class="sort-table" style="min-width: 35px;"><?=$lang['user']['interval'];?></th>
 | ||||||
|  | 				<th class="sort-table" style="min-width: 35px;"><?=$lang['user']['last_run'];?></th>
 | ||||||
|  | 				<th class="sort-table" style="min-width: 35px;">Log</th> | ||||||
|  | 				<th class="sort-table" style="max-width: 35px;"><?=$lang['user']['active'];?></th>
 | ||||||
|  | 				<th style="text-align: right; min-width: 200px;" data-sortable="false"><?=$lang['user']['action'];?></th>
 | ||||||
|  | 			</tr> | ||||||
|  | 			</thead> | ||||||
|  | 			<tbody> | ||||||
|  | 			<?php | ||||||
|  | 			try { | ||||||
|  | 				$stmt = $pdo->prepare("SELECT *, CONCAT(LEFT(`password1`, 3), '…') as `password1_short`
 | ||||||
|  | 						FROM `imapsync` | ||||||
|  | 							WHERE `user2` = :username");
 | ||||||
|  | 				$stmt->execute(array(':username' => $username)); | ||||||
|  | 				$rows = $stmt->fetchAll(PDO::FETCH_ASSOC); | ||||||
|  | 			} | ||||||
|  | 			catch(PDOException $e) { | ||||||
|  | 				$_SESSION['return'] = array( | ||||||
|  | 					'type' => 'danger', | ||||||
|  | 					'msg' => 'MySQL: '.$e | ||||||
|  | 				); | ||||||
|  | 			} | ||||||
|  | 			if(!empty($rows)): | ||||||
|  | 			while ($row = array_shift($rows)): | ||||||
|  | 			?>
 | ||||||
|  | 				<tr id="data"> | ||||||
|  | 				<td><?=htmlspecialchars($row['host1'] . ':' . $row['port1']);?></td>
 | ||||||
|  | 				<td><?=htmlspecialchars($row['enc1']);?></td>
 | ||||||
|  | 				<td><?=htmlspecialchars($row['user1']);?></td>
 | ||||||
|  | 				<td><?=($row['exclude'] == '') ? '✘' : $row['exclude'];?></td>
 | ||||||
|  | 				<td><?=htmlspecialchars($row['mins_interval']);?> min</td>
 | ||||||
|  | 				<td><?=(empty($row['last_run'])) ? '✘' : htmlspecialchars(date($lang['user']['syncjob_full_date'], strtotime($row['last_run'])));?></td>
 | ||||||
|  | 				<td> | ||||||
|  |         <?php | ||||||
|  |         if (empty($row['returned_text'])) { | ||||||
|  |           echo '✘'; | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |         ?>
 | ||||||
|  |           <a href="#logModal" data-toggle="modal" data-log-text="<?=htmlspecialchars($row['returned_text']);?>">Open logs</a> | ||||||
|  |         <?php | ||||||
|  |         } | ||||||
|  |         ?>
 | ||||||
|  |         </td> | ||||||
|  | 				<td><?=($row['active'] == '1') ? '✔' : '✘';?></td>
 | ||||||
|  |         <td style="text-align: right;"> | ||||||
|  |           <div class="btn-group"> | ||||||
|  |             <a href="/edit.php?syncjob=<?=urlencode($row['id']);?>" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-pencil"></span> <?=$lang['user']['edit'];?></a>
 | ||||||
|  |             <a href="/delete.php?syncjob=<?=urlencode($row['id']);?>" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span> <?=$lang['user']['remove'];?></a>
 | ||||||
|  |           </div> | ||||||
|  |         </td> | ||||||
|  | 				</tr> | ||||||
|  | 			<?php | ||||||
|  | 			endwhile; | ||||||
|  | 			else: | ||||||
|  | 			?>
 | ||||||
|  | 				<tr id="no-data"><td colspan="9" style="text-align: center; font-style: italic;"><?=$lang['user']['no_record'];?></td></tr>
 | ||||||
|  | 			<?php | ||||||
|  | 			endif;	 | ||||||
|  | 			?>
 | ||||||
|  | 			</tbody> | ||||||
|  |       <tfoot> | ||||||
|  |         <tr id="no-data"> | ||||||
|  |           <td colspan="9" style="text-align: center; font-style: normal; border-top: 1px solid #e7e7e7;"> | ||||||
|  |             <a href="/add.php?syncjob"><?=$lang['user']['create_syncjob'];?></a>
 | ||||||
|  |           </td> | ||||||
|  |         </tr> | ||||||
|  |       </tfoot> | ||||||
|  | 		</table> | ||||||
|  | 		</div> | ||||||
|  | 	</div> | ||||||
| </div> | </div> | ||||||
| <br /> | <br /> | ||||||
|  | <div class="modal fade" id="logModal" tabindex="-1" role="dialog" aria-labelledby="logTextLabel"> | ||||||
|  |   <div class="modal-dialog modal-lg" role="document"> | ||||||
|  |     <div class="modal-content"> | ||||||
|  |       <div class="modal-body"> | ||||||
|  |         <span id="logText"></span> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |   </div> | ||||||
|  | </div> | ||||||
| </div> <!-- /container --> | </div> <!-- /container --> | ||||||
| <script src="js/sorttable.js"></script> | <script src="js/sorttable.js"></script> | ||||||
| <script src="js/user.js"></script> | <script src="js/user.js"></script> | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 andryyy
						andryyy