mirror of
https://github.com/usmannasir/cyberpanel.git
synced 2025-11-06 21:35:55 +01:00
git manager for child-domains
This commit is contained in:
@@ -859,6 +859,9 @@
|
||||
<div class="sidebar-submenu">
|
||||
|
||||
<ul>
|
||||
<li><a href="{% url 'mailQueue' %}"
|
||||
title="{% trans 'Mail Queue' %}"><span>{% trans "Mail Queue" %}</span></a>
|
||||
</li>
|
||||
<li><a href="{% url 'emailPolicyServer' %}"
|
||||
title="{% trans 'Email Policy Server' %}"><span>{% trans "Email Policy Server" %}</span></a>
|
||||
</li>
|
||||
|
||||
@@ -102,7 +102,6 @@ app.controller('listDomains', function($scope,$http) {
|
||||
/* Java script code to list accounts ends here */
|
||||
|
||||
|
||||
|
||||
/* Java script code for email domain page */
|
||||
|
||||
app.controller('emailDomainPage', function($scope,$http, $timeout, $window) {
|
||||
@@ -312,7 +311,6 @@ app.controller('emailDomainPage', function($scope,$http, $timeout, $window) {
|
||||
|
||||
/* Java script code for email domain page */
|
||||
|
||||
|
||||
/* Java script code for Email Page */
|
||||
|
||||
app.controller('emailPage', function($scope,$http, $timeout, $window) {
|
||||
@@ -670,7 +668,6 @@ app.controller('emailPage', function($scope,$http, $timeout, $window) {
|
||||
|
||||
/* Java script code for Email Page */
|
||||
|
||||
|
||||
/* Java script code for SpamAssassin */
|
||||
|
||||
app.controller('SpamAssassin', function($scope, $http, $timeout, $window) {
|
||||
@@ -956,10 +953,8 @@ app.controller('SpamAssassin', function($scope, $http, $timeout, $window) {
|
||||
|
||||
});
|
||||
|
||||
|
||||
/* Java script code for SpamAssassin */
|
||||
|
||||
|
||||
/* Java script code for Email Policy Server */
|
||||
|
||||
app.controller('policyServer', function($scope, $http, $timeout, $window) {
|
||||
@@ -1088,5 +1083,67 @@ app.controller('policyServer', function($scope, $http, $timeout, $window) {
|
||||
|
||||
});
|
||||
|
||||
|
||||
/* Java script code for Email Policy Server */
|
||||
|
||||
/* Java script code to manage mail queue */
|
||||
|
||||
app.controller('mailQueue', function($scope,$http) {
|
||||
|
||||
$scope.currentPage = 1;
|
||||
$scope.recordsToShow = 10;
|
||||
$scope.cyberpanelLoading = true;
|
||||
|
||||
$scope.fetchMailQueue = function () {
|
||||
$scope.cyberpanelLoading = false;
|
||||
var config = {
|
||||
headers: {
|
||||
'X-CSRFToken': getCookie('csrftoken')
|
||||
}
|
||||
};
|
||||
|
||||
var data = {
|
||||
folder: $scope.folder,
|
||||
page: $scope.currentPage,
|
||||
recordsToShow: $scope.recordsToShow
|
||||
};
|
||||
|
||||
dataurl = "/emailPremium/fetchMailQueue";
|
||||
|
||||
$http.post(dataurl, data, config).then(ListInitialDatas, cantLoadInitialDatas);
|
||||
|
||||
function ListInitialDatas(response) {
|
||||
$scope.cyberpanelLoading = true;
|
||||
if (response.data.status === 1) {
|
||||
new PNotify({
|
||||
title: 'Success',
|
||||
text: 'Successfully fetched.',
|
||||
type: 'success'
|
||||
});
|
||||
$scope.queues = JSON.parse(response.data.data);
|
||||
$scope.pagination = response.data.pagination;
|
||||
} else {
|
||||
new PNotify({
|
||||
title: 'Operation Failed!',
|
||||
text: response.data.error_message,
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function cantLoadInitialDatas(response) {
|
||||
$scope.cyberpanelLoading = true;
|
||||
new PNotify({
|
||||
title: 'Operation Failed!',
|
||||
text: 'Could not connect to server, please refresh this page.',
|
||||
type: 'error'
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
$scope.fetchMailQueue();
|
||||
});
|
||||
|
||||
/* Java script code to manage mail queue ends here */
|
||||
113
emailPremium/templates/emailPremium/mailQueue.html
Executable file
113
emailPremium/templates/emailPremium/mailQueue.html
Executable file
@@ -0,0 +1,113 @@
|
||||
{% extends "baseTemplate/index.html" %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Mail Queue - CyberPanel" %}{% endblock %}
|
||||
{% block content %}
|
||||
|
||||
{% load static %}
|
||||
{% get_current_language as LANGUAGE_CODE %}
|
||||
<!-- Current language: {{ LANGUAGE_CODE }} -->
|
||||
|
||||
|
||||
<div class="container">
|
||||
|
||||
<div id="page-title">
|
||||
<h2 id="domainNamePage">{% trans "Mail Queue" %}
|
||||
</h2>
|
||||
<p>{% trans "On this page you manage your server Email Queue." %}</p>
|
||||
</div>
|
||||
|
||||
<div ng-controller="mailQueue" class="panel">
|
||||
<div class="panel-body">
|
||||
|
||||
<h3 class="content-box-header">
|
||||
{% trans "Mail Queue" %} <img
|
||||
ng-hide="cyberpanelLoading" src="{% static 'images/loading.gif' %}">
|
||||
</h3>
|
||||
|
||||
<div class="example-box-wrapper">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-10">
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
<div class="form-group">
|
||||
<select ng-model="recordsToShow"
|
||||
ng-change="fetchGitLogs()"
|
||||
class="form-control" id="example-select">
|
||||
<option>10</option>
|
||||
<option>50</option>
|
||||
<option>100</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table cellpadding="0" cellspacing="0" border="0" class="table table-striped table-bordered"
|
||||
id="datatable-example">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Queue Name</th>
|
||||
<th>Size</th>
|
||||
<th>Sender</th>
|
||||
<th>Recipients</th>
|
||||
<th>Time</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
<tr ng-repeat="queue in queues track by $index">
|
||||
<td><code ng-bind="queue.queue_id"></code></td>
|
||||
<td ng-bind="queue.queue_name"></td>
|
||||
<td ng-bind="queue.message_size"></td>
|
||||
<td ng-bind="queue.sender"></td>
|
||||
<td ng-bind="queue.recipients"></td>
|
||||
<td ng-bind="queue.arrival_time"></td>
|
||||
<!--<td>
|
||||
<img style="margin-right: 4%;" ng-show="web.status==1"
|
||||
title="{% trans 'Limits are being Applied!' %}"
|
||||
src="{% static 'mailServer/vpsON.png' %}">
|
||||
<button ng-click="enableDisableEmailLimits(0, web.domain)" ng-show="web.status==1"
|
||||
class="btn ra-100 btn-danger">{% trans 'Disable' %}</button>
|
||||
<img style="margin-right: 4%;" ng-show="web.status==0"
|
||||
title="{% trans 'Limits are not being applied!' %}"
|
||||
src="{% static 'mailServer/vpsOff.png' %}">
|
||||
<button ng-click="enableDisableEmailLimits(1, web.domain)" ng-show="web.status==0"
|
||||
class="btn ra-100 btn-success">{% trans 'Enable' %}</button>
|
||||
</td>
|
||||
<td>
|
||||
<a href="/emailPremium/{$ web.domain $}">
|
||||
<button class="btn ra-100 btn-blue-alt">{% trans 'Manage' %}</button>
|
||||
</a>
|
||||
</td>-->
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div style="margin-top: 2%" class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="row">
|
||||
<div class="col-md-9">
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<select ng-model="currentPage" class="form-control"
|
||||
ng-change="fetchGitLogs()">
|
||||
<option ng-repeat="page in pagination">{$ $index + 1
|
||||
$}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div> <!-- end row -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
{% endblock %}
|
||||
@@ -33,6 +33,8 @@ urlpatterns = [
|
||||
url(r'^fetchPolicyServerStatus$', views.fetchPolicyServerStatus, name='fetchPolicyServerStatus'),
|
||||
|
||||
url(r'^savePolicyServerStatus$', views.savePolicyServerStatus, name='savePolicyServerStatus'),
|
||||
url(r'^mailQueue$', views.mailQueue, name='mailQueue'),
|
||||
url(r'^fetchMailQueue$', views.fetchMailQueue, name='fetchMailQueue'),
|
||||
|
||||
url(r'^(?P<domain>(.*))$', views.emailLimits, name='emailLimits'),
|
||||
|
||||
|
||||
@@ -1021,3 +1021,54 @@ def saveSpamAssassinConfigurations(request):
|
||||
data_ret = {'saveStatus': 0, 'error_message': str(msg)}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
def mailQueue(request):
|
||||
try:
|
||||
userID = request.session['userID']
|
||||
currentACL = ACLManager.loadedACL(userID)
|
||||
|
||||
if currentACL['admin'] == 1:
|
||||
pass
|
||||
else:
|
||||
return ACLManager.loadError()
|
||||
|
||||
return render(request, 'emailPremium/mailQueue.html')
|
||||
|
||||
except KeyError:
|
||||
return redirect(loadLoginPage)
|
||||
|
||||
def fetchMailQueue(request):
|
||||
try:
|
||||
userID = request.session['userID']
|
||||
currentACL = ACLManager.loadedACL(userID)
|
||||
|
||||
if currentACL['admin'] == 1:
|
||||
pass
|
||||
else:
|
||||
return ACLManager.loadErrorJson()
|
||||
|
||||
data = json.loads(request.body)
|
||||
|
||||
json_data = "["
|
||||
checker = 0
|
||||
|
||||
queues = ProcessUtilities.outputExecutioner('postqueue -j').split('\n')
|
||||
|
||||
for queue in queues:
|
||||
if checker == 0:
|
||||
json_data = json_data + queue
|
||||
checker = 1
|
||||
else:
|
||||
json_data = json_data + ',' + queue
|
||||
|
||||
json_data = json_data.rstrip(',') + ']'
|
||||
final_dic = {'status': 1, 'error_message': "None", "data": json_data}
|
||||
final_json = json.dumps(final_dic)
|
||||
|
||||
return HttpResponse(final_json)
|
||||
|
||||
|
||||
except BaseException as msg:
|
||||
dic = {'status': 0, 'error_message': str(msg)}
|
||||
json_data = json.dumps(dic)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@@ -9,7 +9,11 @@
|
||||
|
||||
<div class="container">
|
||||
<div id="page-title">
|
||||
<h2>{% trans "Manage GIT" %}</h2>
|
||||
<h2>{% trans "Manage GIT" %} - <a target="_blank"
|
||||
href="https://go.cyberpersons.com/ManageGit"
|
||||
style="height: 23px;line-height: 21px;"
|
||||
class="btn btn-border btn-alt border-red btn-link font-red"
|
||||
title=""><span>{% trans "Git Docs" %}</span></a></h2>
|
||||
<p>{% trans "Manage and track folders via Git for " %} {{ domainName }}.</p>
|
||||
</div>
|
||||
|
||||
@@ -230,8 +234,10 @@
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "Commands" %}</label>
|
||||
<div class="col-sm-9">
|
||||
<textarea ng-model="$parent.commands" placeholder="Add Commands to run after every commit, separate commands using comma."
|
||||
rows="4" class="form-control">{$ currentCommands $}</textarea>
|
||||
<textarea ng-model="$parent.commands"
|
||||
placeholder="Add Commands to run after every commit, separate commands using comma."
|
||||
rows="4"
|
||||
class="form-control">{$ currentCommands $}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -246,7 +252,8 @@
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="current-pack ng-binding">Currently: {$ webhookCommandCurrent $}
|
||||
<div class="current-pack ng-binding">Currently: {$ webhookCommandCurrent
|
||||
$}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -2881,8 +2881,8 @@ StrictHostKeyChecking no
|
||||
else:
|
||||
return ACLManager.loadError()
|
||||
|
||||
try:
|
||||
website = Websites.objects.get(domain=self.domain)
|
||||
|
||||
folders = ['/home/%s/public_html' % (self.domain), '/home/%s' % (self.domain), '/home/vmail/%s' % (self.domain)]
|
||||
|
||||
databases = website.databases_set.all()
|
||||
@@ -2891,6 +2891,18 @@ StrictHostKeyChecking no
|
||||
basePath = '/var/lib/mysql/'
|
||||
folders.append('%s%s' % (basePath, database.dbName))
|
||||
|
||||
|
||||
except:
|
||||
self.childWebsite = ChildDomains.objects.get(domain=self.domain)
|
||||
folders = ['/home/%s/public_html' % (self.childWebsite.master.domain), '/home/%s' % (self.childWebsite.master.domain),
|
||||
'/home/vmail/%s' % (self.childWebsite.master.domain), self.childWebsite.path]
|
||||
|
||||
databases = self.childWebsite.master.databases_set.all()
|
||||
|
||||
for database in databases:
|
||||
basePath = '/var/lib/mysql/'
|
||||
folders.append('%s%s' % (basePath, database.dbName))
|
||||
|
||||
return render(request, 'websiteFunctions/manageGIT.html',
|
||||
{'domainName': self.domain, 'folders': folders})
|
||||
except BaseException as msg:
|
||||
@@ -2901,16 +2913,30 @@ StrictHostKeyChecking no
|
||||
vhRoot = '/home/%s' % (self.domain)
|
||||
vmailPath = '/home/vmail/%s' % (self.domain)
|
||||
|
||||
try:
|
||||
website = Websites.objects.get(domain=self.domain)
|
||||
externalApp = website.externalApp
|
||||
except:
|
||||
website = ChildDomains.objects.get(domain=self.domain)
|
||||
externalApp = website.master.externalApp
|
||||
|
||||
if self.folder == domainPath:
|
||||
self.externalApp = website.externalApp
|
||||
self.externalApp = externalApp
|
||||
return 1
|
||||
|
||||
if self.folder == vhRoot:
|
||||
self.externalApp = website.externalApp
|
||||
self.externalApp = externalApp
|
||||
return 1
|
||||
|
||||
try:
|
||||
childDomain = ChildDomains.objects.get(domain=self.domain)
|
||||
|
||||
if self.folder == childDomain.path:
|
||||
return 1
|
||||
|
||||
except:
|
||||
pass
|
||||
|
||||
if self.folder == vmailPath:
|
||||
self.externalApp = 'vmail'
|
||||
return 1
|
||||
@@ -2944,28 +2970,42 @@ StrictHostKeyChecking no
|
||||
else:
|
||||
return ACLManager.loadErrorJson()
|
||||
|
||||
|
||||
try:
|
||||
website = Websites.objects.get(domain=self.domain)
|
||||
self.externalAppLocal = website.externalApp
|
||||
|
||||
## Check if home
|
||||
|
||||
home = 0
|
||||
if self.folder == '/home/%s/public_html' % (self.domain):
|
||||
home = 1
|
||||
|
||||
except:
|
||||
website = ChildDomains.objects.get(domain=self.domain)
|
||||
self.externalAppLocal = website.master.externalApp
|
||||
|
||||
## Check if home
|
||||
|
||||
home = 0
|
||||
if self.folder == website.path:
|
||||
home = 1
|
||||
|
||||
|
||||
gitPath = '%s/.git' % (self.folder)
|
||||
command = 'ls -la %s' % (gitPath)
|
||||
|
||||
if ProcessUtilities.outputExecutioner(command).find('No such file or directory') > -1:
|
||||
|
||||
command = 'cat /home/%s/.ssh/%s.pub' % (self.domain, website.externalApp)
|
||||
command = 'cat /home/%s/.ssh/%s.pub' % (self.domain, self.externalAppLocal)
|
||||
deploymentKey = ProcessUtilities.outputExecutioner(command)
|
||||
|
||||
if deploymentKey.find('No such file or directory') > -1:
|
||||
command = "ssh-keygen -f /home/%s/.ssh/%s -t rsa -N ''" % (self.domain, website.externalApp)
|
||||
ProcessUtilities.executioner(command, website.externalApp)
|
||||
command = "ssh-keygen -f /home/%s/.ssh/%s -t rsa -N ''" % (self.domain, self.externalAppLocal)
|
||||
ProcessUtilities.executioner(command, self.externalAppLocal)
|
||||
|
||||
command = 'cat /home/%s/.ssh/%s.pub' % (self.domain, website.externalApp)
|
||||
command = 'cat /home/%s/.ssh/%s.pub' % (self.domain, self.externalAppLocal)
|
||||
deploymentKey = ProcessUtilities.outputExecutioner(command)
|
||||
|
||||
home = 0
|
||||
if self.folder == '/home/%s/public_html' % (self.domain):
|
||||
home = 1
|
||||
|
||||
data_ret = {'status': 1, 'repo': 0, 'deploymentKey': deploymentKey, 'home': home}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
@@ -2978,20 +3018,20 @@ StrictHostKeyChecking no
|
||||
|
||||
## Fetch key
|
||||
|
||||
command = 'cat /home/%s/.ssh/%s.pub' % (self.domain, website.externalApp)
|
||||
command = 'cat /home/%s/.ssh/%s.pub' % (self.domain, self.externalAppLocal)
|
||||
deploymentKey = ProcessUtilities.outputExecutioner(command)
|
||||
|
||||
if deploymentKey.find('No such file or directory') > -1:
|
||||
command = "ssh-keygen -f /home/%s/.ssh/%s -t rsa -N ''" % (self.domain, website.externalApp)
|
||||
ProcessUtilities.executioner(command, website.externalApp)
|
||||
command = "ssh-keygen -f /home/%s/.ssh/%s -t rsa -N ''" % (self.domain, self.externalAppLocal)
|
||||
ProcessUtilities.executioner(command, self.externalAppLocal)
|
||||
|
||||
command = 'cat /home/%s/.ssh/%s.pub' % (self.domain, website.externalApp)
|
||||
command = 'cat /home/%s/.ssh/%s.pub' % (self.domain, self.externalAppLocal)
|
||||
deploymentKey = ProcessUtilities.outputExecutioner(command)
|
||||
|
||||
## Find Remote if any
|
||||
|
||||
command = 'git -C %s remote -v' % (self.folder)
|
||||
remoteResult = ProcessUtilities.outputExecutioner(command )
|
||||
remoteResult = ProcessUtilities.outputExecutioner(command)
|
||||
|
||||
remote = 1
|
||||
if remoteResult.find('origin') == -1:
|
||||
@@ -3001,17 +3041,11 @@ StrictHostKeyChecking no
|
||||
## Find Total commits on current branch
|
||||
|
||||
command = 'git -C %s rev-list --count HEAD' % (self.folder)
|
||||
totalCommits = ProcessUtilities.outputExecutioner(command )
|
||||
totalCommits = ProcessUtilities.outputExecutioner(command)
|
||||
|
||||
if totalCommits.find('fatal') > -1:
|
||||
totalCommits = '0'
|
||||
|
||||
## Check if home
|
||||
|
||||
home = 0
|
||||
if self.folder == '/home/%s/public_html' % (self.domain):
|
||||
home = 1
|
||||
|
||||
## Fetch Configurations
|
||||
|
||||
gitConfFolder = '/home/cyberpanel/git'
|
||||
@@ -3083,18 +3117,27 @@ StrictHostKeyChecking no
|
||||
else:
|
||||
return ACLManager.loadErrorJson()
|
||||
|
||||
try:
|
||||
website = Websites.objects.get(domain=self.domain)
|
||||
self.adminEmail = website.adminEmail
|
||||
self.firstName = website.admin.firstName
|
||||
self.lastName = website.admin.lastName
|
||||
except:
|
||||
website = ChildDomains.objects.get(domain=self.domain)
|
||||
self.adminEmail = website.master.adminEmail
|
||||
self.firstName = website.master.admin.firstName
|
||||
self.lastName = website.master.admin.lastName
|
||||
|
||||
command = 'git -C %s init' % (self.folder)
|
||||
result = ProcessUtilities.outputExecutioner(command)
|
||||
|
||||
if result.find('Initialized empty Git repository in') > -1:
|
||||
|
||||
command = 'git -C %s config --local user.email %s' % (self.folder, website.adminEmail)
|
||||
command = 'git -C %s config --local user.email %s' % (self.folder, self.adminEmail)
|
||||
ProcessUtilities.executioner(command)
|
||||
|
||||
command = 'git -C %s config --local user.name "%s %s"' % (
|
||||
self.folder, website.admin.firstName, website.admin.lastName)
|
||||
self.folder, self.firstName, self.lastName)
|
||||
ProcessUtilities.executioner(command)
|
||||
|
||||
data_ret = {'status': 1}
|
||||
@@ -3141,9 +3184,14 @@ StrictHostKeyChecking no
|
||||
|
||||
### set default ssh key
|
||||
|
||||
externalApp = Websites.objects.get(domain=self.domain).externalApp
|
||||
try:
|
||||
website = Websites.objects.get(domain=self.domain)
|
||||
self.externalAppLocal = website.adminEmail
|
||||
except:
|
||||
website = ChildDomains.objects.get(domain=self.domain)
|
||||
self.externalAppLocal = website.master.adminEmail
|
||||
|
||||
command = 'git -C %s config --local core.sshCommand "ssh -i /home/%s/.ssh/%s -o "StrictHostKeyChecking=no""' % (self.folder, self.domain, externalApp)
|
||||
command = 'git -C %s config --local core.sshCommand "ssh -i /home/%s/.ssh/%s -o "StrictHostKeyChecking=no""' % (self.folder, self.domain, self.externalAppLocal)
|
||||
ProcessUtilities.executioner(command)
|
||||
|
||||
## Check if remote exists
|
||||
@@ -3158,12 +3206,12 @@ StrictHostKeyChecking no
|
||||
else:
|
||||
command = 'git -C %s remote set-url origin git@%s:%s/%s.git' % (self.folder, self.gitHost, self.gitUsername, self.gitReponame)
|
||||
|
||||
possibleError = ProcessUtilities.outputExecutioner(command )
|
||||
possibleError = ProcessUtilities.outputExecutioner(command)
|
||||
|
||||
## Check if set correctly.
|
||||
|
||||
command = 'git -C %s remote -v' % (self.folder)
|
||||
remoteResult = ProcessUtilities.outputExecutioner(command )
|
||||
remoteResult = ProcessUtilities.outputExecutioner(command)
|
||||
|
||||
if remoteResult.find(self.gitUsername) > -1:
|
||||
data_ret = {'status': 1}
|
||||
@@ -3213,7 +3261,7 @@ StrictHostKeyChecking no
|
||||
return HttpResponse(json_data)
|
||||
|
||||
command = 'git -C %s checkout %s' % (self.folder, self.branchName.strip(' '))
|
||||
commandStatus = ProcessUtilities.outputExecutioner(command )
|
||||
commandStatus = ProcessUtilities.outputExecutioner(command)
|
||||
|
||||
if commandStatus.find('Switched to branch') > -1:
|
||||
data_ret = {'status': 1, 'commandStatus': commandStatus + 'Refreshing page in 3 seconds..'}
|
||||
|
||||
Reference in New Issue
Block a user