]>
Commit | Line | Data |
---|---|---|
1 | <?php | |
2 | require_once "../inc/common.php"; | |
3 | require_once "../inc/header.php"; | |
4 | ||
5 | if (!empty($_GET)) | |
6 | { | |
7 | if (isset($_GET['account']) && !isset($_POST['uf_account'])) | |
8 | $_POST['uf_account'] = $_GET['account']; | |
9 | ||
10 | if (isset($_GET['operonly']) && !isset($_POST['operonly'])) | |
11 | $_POST['operonly'] = $_GET['operonly']; | |
12 | ||
13 | if (isset($_GET['servicesonly']) && !isset($_POST['servicesonly'])) | |
14 | $_POST['servicesonly'] = $_GET['servicesonly']; | |
15 | } | |
16 | ||
17 | if (!empty($_POST) && current_user_can(PERMISSION_BAN_USERS)) | |
18 | { | |
19 | require_once "../inc/connection.php"; | |
20 | do_log($_POST); | |
21 | $bantype = (isset($_POST['bantype'])) ? $_POST['bantype'] : NULL; | |
22 | ||
23 | if (isset($_POST['userch'])) { | |
24 | foreach ($_POST["userch"] as $user) | |
25 | { | |
26 | $user = $name = base64_decode($user); | |
27 | ||
28 | if (!$bantype) /* shouldn't happen? */ | |
29 | { | |
30 | Message::Fail("An error occured"); | |
31 | } | |
32 | ||
33 | else | |
34 | { | |
35 | $banlen_w = (isset($_POST['banlen_w'])) ? $_POST['banlen_w'] : NULL; | |
36 | $banlen_d = (isset($_POST['banlen_d'])) ? $_POST['banlen_d'] : NULL; | |
37 | $banlen_h = (isset($_POST['banlen_h'])) ? $_POST['banlen_h'] : NULL; | |
38 | ||
39 | $duration = ""; | |
40 | if (!$banlen_d && !$banlen_h && !$banlen_w) | |
41 | $duration .= "0"; | |
42 | else { | |
43 | if ($banlen_w) | |
44 | $duration .= $banlen_w; | |
45 | if ($banlen_d) | |
46 | $duration .= $banlen_d; | |
47 | if ($banlen_h) | |
48 | $duration .= $banlen_h; | |
49 | } | |
50 | $user = $rpc->user()->get($user); | |
51 | ||
52 | if (!$user && $bantype !== "qline") { | |
53 | Message::Fail("Could not find that user: User not online"); | |
54 | } | |
55 | ||
56 | else | |
57 | { | |
58 | $msg_msg = ($duration == "0" || $duration == "0w0d0h") ? "permanently" : "for " . rpc_convert_duration_string($duration); | |
59 | $reason = (isset($_POST['ban_reason'])) ? $_POST['ban_reason'] : "No reason"; | |
60 | ||
61 | if ($bantype == "qline") | |
62 | $rpc->nameban()->add($name, $reason, $duration); | |
63 | ||
64 | else if ($bantype == "kill") | |
65 | { | |
66 | if ($rpc->user()->kill($user->id, $reason)) | |
67 | Message::Success($user->name . "(*@" . $user->hostname . ") has been killed: $reason"); | |
68 | else | |
69 | Message::Fail("Could not kill $user->name: $rpc->error"); | |
70 | } | |
71 | else if ($rpc->serverban()->add($user->id, $bantype, $duration, $reason)) | |
72 | Message::Success($user->name . " (*@" . $user->hostname . ") has been $bantype" . "d $msg_msg: $reason"); | |
73 | ||
74 | else | |
75 | Message::Fail("Could not add $bantype against $name: $rpc->error"); | |
76 | } | |
77 | } | |
78 | } | |
79 | } | |
80 | } | |
81 | ||
82 | ?> | |
83 | <h4>Users Overview</h4> | |
84 | ||
85 | Click on a username to view more information. | |
86 | ||
87 | <div class="usertable"> | |
88 | <form method="post"> | |
89 | ||
90 | <!-- The user list --> | |
91 | <table id="data_list" class="table-striped display responsive nowrap" style="width:100%"> | |
92 | <thead class="table-primary"> | |
93 | <th scope="col"><input type="checkbox" label='selectall' onClick="toggle_user(this)" /></th> | |
94 | <th scope="col">Nick</th> | |
95 | <th class="countrycol" scope="col">Country</th> | |
96 | <th class="hostname" scope="col">Host / IP</th> | |
97 | <th class="accountcol" scope="col"><span data-toggle="tooltip" data-placement="bottom" title="The services account name, if the user identified to services." style="border-bottom: 1px dotted #000000">Account</span></th> | |
98 | <th class="opercol" scope="col">Oper</th> | |
99 | <th class="uplinkcol" scope="col">Connected to</th> | |
100 | <th class="reputationcol" scope="col"><span id="reputationheader" data-toggle="tooltip" data-placement="bottom" title="The reputation score gets higher when someone with this IP address has been connected in the past weeks. A low reputation score (like <10) is an indication of a new IP." style="border-bottom: 1px dotted #000000">Rep.</span> <a href="https://www.unrealircd.org/docs/Reputation_score" target="_blank">ℹ️</a></th> | |
101 | </thead> | |
102 | </table> | |
103 | ||
104 | <!-- User Actions --> | |
105 | <table class="table table-responsive table-light"> | |
106 | <tr> | |
107 | <td colspan="2"> | |
108 | <label for="bantype">Apply action: </label> | |
109 | <select name="bantype" id="bantype"> | |
110 | <option value=""></option> | |
111 | <optgroup label="Bans"> | |
112 | <option value="gline">GLine</option> | |
113 | <option value="gzline">GZLine</option> | |
114 | <option value="kill">Kill</option> | |
115 | </optgroup> | |
116 | </select></td><td colspan="2"> | |
117 | <label for="banlen_w">Duration: </label> | |
118 | <select name="banlen_w" id="banlen_w"> | |
119 | <?php | |
120 | for ($i = 0; $i <= 56; $i++) | |
121 | { | |
122 | if (!$i) | |
123 | echo "<option value=\"0w\"></option>"; | |
124 | else | |
125 | { | |
126 | $w = ($i == 1) ? "week" : "weeks"; | |
127 | echo "<option value=\"$i" . "w\">$i $w" . "</option>"; | |
128 | } | |
129 | } | |
130 | ?> | |
131 | </select> | |
132 | <select name="banlen_d" id="banlen_d"> | |
133 | <?php | |
134 | for ($i = 0; $i <= 31; $i++) | |
135 | { | |
136 | if (!$i) | |
137 | echo "<option value=\"0d\"></option>"; | |
138 | else | |
139 | { | |
140 | $d = ($i == 1) ? "day" : "days"; | |
141 | echo "<option value=\"$i" . "d\">$i $d" . "</option>"; | |
142 | } | |
143 | } | |
144 | ?> | |
145 | </select> | |
146 | <select name="banlen_h" id="banlen_h"> | |
147 | <?php | |
148 | for ($i = 0; $i <= 24; $i++) | |
149 | { | |
150 | if (!$i) | |
151 | echo "<option value=\"0d\"></option>"; | |
152 | else | |
153 | { | |
154 | $h = ($i == 1) ? "hour" : "hours"; | |
155 | echo "<option value=\"$i" . "h\">$i $h" . "</option>"; | |
156 | } | |
157 | } | |
158 | ||
159 | ?> | |
160 | </select> | |
161 | ||
162 | <br></td><tr><td colspan="3"> | |
163 | ||
164 | <label for="ban_reason">Reason: </label> | |
165 | <input class="form-control" type="text" name="ban_reason" id="ban_reason" value="No reason"> | |
166 | <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#ban_confirmation"> | |
167 | Apply | |
168 | </button></td></table> | |
169 | ||
170 | <!-- Ban confirmation modal --> | |
171 | <div class="modal fade" id="ban_confirmation" tabindex="-1" role="dialog" aria-labelledby="confirmModalCenterTitle" aria-hidden="true"> | |
172 | <div class="modal-dialog modal-dialog-centered" role="document"> | |
173 | <div class="modal-content"> | |
174 | <div class="modal-header"> | |
175 | <h5 class="modal-title" id="ban_confirmation_label">Apply ban</h5> | |
176 | <button type="button" class="close" data-dismiss="modal" aria-label="Close"> | |
177 | <span aria-hidden="true">×</span> | |
178 | </button> | |
179 | </div> | |
180 | <div class="modal-body"> | |
181 | Are you sure you want to do this? | |
182 | ||
183 | </div> | |
184 | <div class="modal-footer"> | |
185 | <button id="CloseButton" type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button> | |
186 | <button type="submit" action="post" class="btn btn-danger">Apply</button> | |
187 | ||
188 | </div> | |
189 | </div> | |
190 | </div> | |
191 | </div> | |
192 | ||
193 | </form> | |
194 | ||
195 | <style> | |
196 | #rclickmenu { | |
197 | position: fixed; | |
198 | z-index: 10000; | |
199 | width: 250px; | |
200 | background: #1b1a1a; | |
201 | border-radius: 5px; | |
202 | transform: scale(0); | |
203 | transform-origin: top left; | |
204 | } | |
205 | #rclickmenu.visible { | |
206 | transform: scale(1); | |
207 | transition: transform 120ms ease-in-out; | |
208 | } | |
209 | #rclickmenu .item { | |
210 | padding: 8px 10px; | |
211 | font-size: 15px; | |
212 | color: #eee; | |
213 | cursor: pointer; | |
214 | border-radius: inherit; | |
215 | } | |
216 | #rclickmenu .item:hover { | |
217 | background: #343434; | |
218 | text-decoration: none; | |
219 | } | |
220 | </style> | |
221 | ||
222 | <div id='rclickmenu' class="nav-item list-group"> | |
223 | <div id="rclick_opt1" class="item list-group-item-action">View details</div> | |
224 | <div id="rclick_opt2" class="item list-group-item-action">Kill</div> | |
225 | <div id="rclick_opt3" class="item list-group-item-action">Copy | |
226 | </div> | |
227 | </div> | |
228 | ||
229 | <script> | |
230 | var rclickmenu = document.getElementById('rclickmenu'); | |
231 | var scopes = document.querySelectorAll('.userselector'); | |
232 | document.addEventListener("click", (e) => | |
233 | { | |
234 | if (e.target.offsetParent != rclickmenu) | |
235 | { | |
236 | rclickmenu.classList.remove("visible"); | |
237 | } | |
238 | }); | |
239 | scopes.forEach((scope) => { | |
240 | scope.addEventListener("contextmenu", (event) => | |
241 | { | |
242 | event.preventDefault(); | |
243 | var { clientX: mouseX, clientY: mouseY } = event; | |
244 | var name = $('#' + scope.id).attr('value') | |
245 | document.getElementById("rclick_opt1").innerHTML = 'View details for ' + name; | |
246 | rclickmenu.style.top = `${mouseY}px`; | |
247 | rclickmenu.style.left = `${mouseX}px`; | |
248 | rclickmenu.classList.remove("visible"); | |
249 | setTimeout(() => { rclickmenu.classList.add("visible"); }); | |
250 | }); | |
251 | }); | |
252 | document.addEventListener('keydown', (event) => { | |
253 | if (event.key === 'Escape') | |
254 | { | |
255 | rclickmenu.classList.remove("visible"); | |
256 | } | |
257 | }); | |
258 | ||
259 | $(document).ready( function () { | |
260 | args = { | |
261 | 'responsive': true, | |
262 | 'fixedHeader': { | |
263 | header: true, | |
264 | headerOffset: 53 | |
265 | }, | |
266 | 'ajax': { | |
267 | 'url': '<?php echo get_config("base_url"); ?>api/users.php', | |
268 | dataSrc: '' | |
269 | }, | |
270 | 'pageLength':100, | |
271 | 'order':[[1,'asc']], | |
272 | 'columns': [ | |
273 | { 'data': 'Select', 'responsivePriority': 1 }, | |
274 | { 'data': 'Nick', 'responsivePriority': 1 }, | |
275 | { 'data': 'Country', 'className':'countrycol', 'responsivePriority': 2 }, | |
276 | { 'data': 'Host/IP', 'className':'hostname', 'responsivePriority': 5 }, | |
277 | { 'data': 'Account', 'className':'accountcol', 'responsivePriority': 3 }, | |
278 | { 'data': 'Oper', 'className':'opercol', 'responsivePriority': 8 }, | |
279 | { 'data': 'Connected to', 'className':'uplinkcol', 'responsivePriority': 6 }, | |
280 | { 'data': 'Reputation', 'className':'reputationcol', 'responsivePriority': 4 }, | |
281 | ], | |
282 | }; | |
283 | /* Hide on mobile */ | |
284 | if (window.innerWidth > 800) | |
285 | { | |
286 | args['dom'] = 'Pfrtip'; | |
287 | args['searchPanes'] = { | |
288 | 'initCollapsed': 'true', | |
289 | 'columns': [2,6], | |
290 | 'dtOpts': { | |
291 | select: { style: 'multi'}, | |
292 | order: [[ 1, "desc" ]] | |
293 | }, | |
294 | } | |
295 | } | |
296 | ||
297 | $('#data_list').DataTable(args); | |
298 | } ); | |
299 | ||
300 | </script> | |
301 | ||
302 | <?php require_once UPATH.'/inc/footer.php'; ?> |