Create Lists

This commit is contained in:
Zarak Khan 2024-02-28 11:16:09 +05:00
parent c478ae5121
commit 0d853a0943
35 changed files with 2636 additions and 80 deletions

View File

@ -252,18 +252,21 @@ newapp.controller('CreateV2BackupV2', function ($scope, $http, $timeout, $compil
newapp.controller('ConfigureV2BackupV2', function ($scope, $http, $timeout) {
$scope.cyberpanelLoading = true;
$scope.selectbackuptype = function () {
var backuptype = $scope.v2backuptype;
// Reset cyberpanelLoading to false initially
$scope.cyberpanelLoading = false;
var backuptype = $scope.v2backuptype
if (backuptype === 'GDrive') {
// Show GdriveModal
$scope.cyberpanelLoading = true;
$('#GdriveModal').modal('show');
document.getElementById('GDrive').classList.remove('hidden'); // Show the modal
} else if (backuptype === 'SFTP') {
// Show SFTPModal (if you have defined it similarly)
$scope.cyberpanelLoading = true;
$('#SFTPModal').modal('show');
// Add logic to show SFTPModal if needed
}
}
};
$scope.setupAccount = function () {

View File

@ -38,6 +38,121 @@
</select>
</div>
</div>
<div id="GDrive" tabindex="-1"
class="hidden overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-50 justify-center items-center w-full md:inset-0 h-[calc(100%-1rem)] max-h-full">
<div class="relative p-4 w-full max-w-2xl max-h-full">
<div class="relative bg-white shadow dark:bg-gray-700">
<div class="flex items-center bg-blue-400 px-4 py-4">
<p class="font-bold">Convert Child Domain to Normal Website</p>
<button type="button" data-modal-toggle="edit"
class="absolute top-2 end-1 text-black bg-transparent hover:text-black rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center"
data-modal-hide="edit">
<svg class="w-3 h-3" aria-hidden="true"
xmlns="http://www.w3.org/2000/svg" fill="none"
viewBox="0 0 14 14">
<path stroke="currentColor" stroke-linecap="round"
stroke-linejoin="round" stroke-width="2"
d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6"/>
</svg>
<span class="sr-only">Close modal</span>
</button>
</div>
<div class="p-4 md:p-5">
<form name="containerSettingsForm">
<div ng-hide="installationDetailsForm"
class="flex mt-4 py-2 px-6">
<div>
<p class="font-semibold w-60">Domain Name</p>
</div>
<div>
<input name="dom" type="text"
class="w-80 bg-gray-100 rounded px-2 py-1"
ng-model="domainName"
placeholder="{% trans "Do not enter WWW, it will be auto created!" %}"
readonly>
</div>
</div>
</form>
<div class="flex justify-end mt-3">
<button ng-click="convert()"
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
Convert
</button>
<button data-modal-toggle="edit"
data-modal-hide="edit"
class="ml-2 bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 rounded">
Close
</button>
</div>
</div>
</div>
</div>
</div>
<div id="SFTPModal" class="modal fade" role="dialog">
<div class="modal-dialog modal-lg">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">&times;
</button>
<h4 class="modal-title">{% trans "Set up account" %}</h4>
</div>
<div class="modal-body">
<form name="containerSettingsForm" action="/" class="form-horizontal">
<div ng-hide="installationDetailsForm" class="form-group">
<label class="col-sm-3 control-label">{% trans "Repo Name" %}</label>
<div class="col-sm-6">
<input name="reponame" type="text" class="form-control"
ng-model="reponame">
</div>
</div>
<div ng-hide="installationDetailsForm" class="form-group">
<label class="col-sm-3 control-label">{% trans "Host Name" %}</label>
<div class="col-sm-6">
<input name="accountName" type="text" class="form-control"
ng-model="hostName">
</div>
</div>
<div ng-hide="installationDetailsForm" class="form-group">
<label class="col-sm-3 control-label">{% trans "Username" %}</label>
<div class="col-sm-6">
<input name="accountName" type="text" class="form-control"
ng-model="UserName">
</div>
</div>
<div ng-hide="installationDetailsForm" class="form-group">
<label class="col-sm-3 control-label">{% trans "Password" %}</label>
<div class="col-sm-6">
<input name="accountName" type="text" class="form-control"
ng-model="sfptpasswd">
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary"
ng-click="ConfigerSFTP()">Save <img
ng-hide="cyberpanelLoading"
src="{% static 'images/loading.gif' %}">
</button>
<button type="button" ng-disabled="savingSettings"
class="btn btn-default" data-dismiss="modal">
Close
</button>
</div>
</div>
</div>
</div>
{# <div>#}
{# <div class="flex justify-center mt-6 mb-2">#}
{# <button id="CreateV2BackupButton" ng-click="CreateV2BackupButton()"#}

View File

@ -57,7 +57,7 @@
<p class="font-semibold w-60">Backup Content</p>
</div>
<div>
<div class="checkbox">
<div>
<label>
<input ng-model="websiteData" type="checkbox" value="">
Data
@ -70,7 +70,7 @@
<p class="font-semibold w-60"></p>
</div>
<div>
<div class="checkbox">
<div>
<label>
<input ng-model="websiteDatabases" type="checkbox" value="">
Databases
@ -83,7 +83,7 @@
<p class="font-semibold w-60"></p>
</div>
<div>
<div class="checkbox">
<div>
<label>
<input ng-model="websiteEmails" type="checkbox" value="">
Emails

View File

@ -93,7 +93,7 @@
<p class="font-semibold w-60"></p>
</div>
<div>
<div class="checkbox">
<div>
<label>
<input ng-model="websiteDatabases" type="checkbox" value="">
Databases
@ -106,7 +106,7 @@
<p class="font-semibold w-60"></p>
</div>
<div>
<div class="checkbox">
<div>
<label>
<input ng-model="websiteEmails" type="checkbox" value="">
Emails

View File

@ -87,7 +87,7 @@
<p class="font-semibold w-60"></p>
</div>
<div>
<div class="checkbox">
<div>
<label>
<input ng-model="websiteEmails" type="checkbox" value="">
Emails
@ -183,11 +183,342 @@
<td ng-bind="record.numberOfSites" class="px-6 py-4">
</td>
<td class="px-6 py-4">
Delete Edit
</td>
<a onclick="return false;"
ng-click="delSchedule(record.id)"
class="bg-red-500 hover:bg-red-700 text-white font-bold py-1 px-2 rounded"
href="#">{% trans "Delete" %}
</a>
{# <a onclick="return false;"#}
{# ng-click="editInitial(record.id)"#}
{# class="bg-orange-500 hover:bg-orange-700 text-white font-bold py-1 px-2 rounded"#}
{# href="#" data-modal-target="edit"#}
{# data-modal-toggle="edit">{% trans "EDIT" %}#}
{# </a>#}
{# <div id="edit" tabindex="-1"#}
{# class="hidden overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-50 justify-center items-center w-full md:inset-0 h-[calc(100%-1rem)] max-h-full">#}
{# <div class="relative p-4 w-full max-w-2xl max-h-full">#}
{# <div class="relative bg-white shadow dark:bg-gray-700">#}
{# <div class="flex items-center bg-blue-400 px-4 py-4">#}
{# <p class="font-bold">Edit Job</p>#}
{# <img ng-hide="cyberpanelLoading"#}
{# src="{% static 'images/loading.gif' %}">#}
{# <button type="button" data-modal-toggle="edit"#}
{# class="absolute top-2 end-1 text-black bg-transparent hover:text-black rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center"#}
{# data-modal-hide="edit">#}
{# <svg class="w-3 h-3" aria-hidden="true"#}
{# xmlns="http://www.w3.org/2000/svg" fill="none"#}
{# viewBox="0 0 14 14">#}
{# <path stroke="currentColor" stroke-linecap="round"#}
{# stroke-linejoin="round" stroke-width="2"#}
{# d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6"/>#}
{# </svg>#}
{# <span class="sr-only">Close modal</span>#}
{# </button>#}
{# </div>#}
{# <div class="p-4 md:p-5">#}
{# <form name="containerSettingsForm">#}
{# <div ng-hide="installationDetailsForm"#}
{# class="flex mt-4 py-2 px-6">#}
{# <div>#}
{# <p class="font-semibold w-60">Job ID</p>#}
{# </div>#}
{# <div>#}
{# <input name="name" type="number"#}
{# class="w-80 bg-gray-100 rounded px-2 py-1"#}
{# ng-model="jobID" readonly>#}
{# </div>#}
{# </div>#}
{# <div ng-hide="installationDetailsForm"#}
{# class="flex py-2 px-6">#}
{# <div>#}
{# <p class="font-semibold w-60">Data</p>#}
{# </div>#}
{# <div>#}
{# <input ng-model="$parent.websiteData"#}
{# type="checkbox" value="">#}
{# Data#}
{# </div>#}
{# </div>#}
{# <div ng-hide="installationDetailsForm"#}
{# class="flex py-2 px-6">#}
{# <div>#}
{# <p class="font-semibold w-60">Databases</p>#}
{# </div>#}
{# <div>#}
{# <label>#}
{# <input ng-model="$parent.websiteDatabases"#}
{# type="checkbox" value="">#}
{# Databases#}
{# </label>#}
{# </div>#}
{# </div>#}
{# <div ng-hide="installationDetailsForm"#}
{# class="flex py-2 px-6">#}
{# <div>#}
{# <p class="font-semibold w-60">Emails</p>#}
{# </div>#}
{# <div>#}
{# <label>#}
{# <input ng-model="$parent.websiteEmails"#}
{# type="checkbox" value="">#}
{# Emails#}
{# </label>#}
{# </div>#}
{# </div>#}
{# </form>#}
{# <div ng-hide="installationDetailsForm" class="flex justify-center mt-3">#}
{# <button ng-click="saveChanges()"#}
{# class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">#}
{# Save Changes#}
{# </button>#}
{# </div>#}
{# <ul class="flex py-2 justify-center">#}
{# <li id="dns_tab_button"#}
{# class="hover:bg-orange-200 border-2 border-black rounded-l-3xl px-2 py-2 w-60 cursor-pointer active"#}
{# onclick="showTab1('sites')">#}
{# <a class="flex justify-center">#}
{# <p class="text-2xl font-bold">Sites</p>#}
{# </a>#}
{# </li>#}
{# <li id="api_tab_button"#}
{# class="hover:bg-orange-200 border-2 border-black rounded-r-3xl px-2 py-2 w-60 cursor-pointer"#}
{# onclick="showTab1('add_sites')">#}
{# <a class="flex justify-center">#}
{# <p class="text-2xl font-bold">Add Sites</p>#}
{# </a>#}
{# </li>#}
{# </ul>#}
{# <div id="sites" class="tab-content1">#}
{# <div class="relative py-5 overflow-x-auto">#}
{# <table class="w-full text-sm text-left rtl:text-right">#}
{# <thead>#}
{# <tr class="bg-gray-200 mt-6 w-full rounded-t-lg border-b-2 border-gray-400">#}
{# <th scope="col" class="px-6 py-3">#}
{# ID#}
{# </th>#}
{# <th scope="col" class="px-6 py-3">#}
{# Website#}
{# </th>#}
{# <th scope="col" class="px-6 py-3">#}
{# Actions#}
{# </th>#}
{# </tr>#}
{# </thead>#}
{# <tbody ng-repeat="record in websites track by $index"#}
{# class="border shadow-lg py-3 px-6 rounded-b-lg">#}
{# <tr>#}
{# <td ng-bind="record.id" class="px-6 py-4">#}
{# </td>#}
{# <td ng-bind="record.website" class="px-6 py-4">#}
{# </td>#}
{# <td class="px-6 py-4">#}
{# <a onclick="return false;"#}
{# ng-click="removeSite(record.website)"#}
{# class="bg-red-500 hover:bg-red-700 text-white font-bold py-1 px-2 rounded"#}
{# href="#">{% trans "Delete" %}#}
{# </a>#}
{# </td>#}
{# </tr>#}
{# </tbody>#}
{# </table>#}
{# </div>#}
{# </div>#}
{# <div id="add_sites" class="tab-content1">#}
{# <div ng-hide="installationDetailsForm"#}
{# class="flex mt-4 py-2 px-6">#}
{# <div class="flex items-center">#}
{# <p class="font-semibold w-60">Select Site</p>#}
{# <img ng-hide="cyberpanelLoading"#}
{# src="{% static 'images/loading.gif' %}">#}
{# </div>#}
{# <div>#}
{# <select ng-model="$parent.websiteToBeAdded"#}
{# class="w-80 bg-gray-100 rounded px-2 py-1">#}
{# {% for items in websiteList %}#}
{# <option>{{ items }}</option>#}
{# {% endfor %}#}
{# </select>#}
{# </div>#}
{# </div>#}
{# <div ng-hide="savebtn" class="flex justify-center mt-3">#}
{# <button ng-click="addWebsite()"#}
{# class="bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded">#}
{# Add#}
{# </button>#}
{# </div>#}
{# </div>#}
{# </div>#}
{# </div>#}
{# </div>#}
{# </div>#}
{# </td>#}
</tr>
</tbody>
</table>
</div>
</div>
<a onclick="return false;"
ng-click="editInitial(record.id)"
class="bg-orange-500 hover:bg-orange-700 text-white font-bold py-1 px-2 rounded"
href="#" data-modal-target="edit"
data-modal-toggle="edit">{% trans "EDIT" %}
</a>
<div id="edit" tabindex="-1"
class="hidden overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-50 justify-center items-center w-full md:inset-0 h-[calc(100%-1rem)] max-h-full">
<div class="relative p-4 w-full max-w-2xl max-h-full">
<div class="relative bg-white shadow dark:bg-gray-700">
<div class="flex items-center bg-blue-400 px-4 py-4">
<p class="font-bold">Edit Job</p>
<img ng-hide="cyberpanelLoading"
src="{% static 'images/loading.gif' %}">
<button type="button" data-modal-toggle="edit"
class="absolute top-2 end-1 text-black bg-transparent hover:text-black rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center"
data-modal-hide="edit">
<svg class="w-3 h-3" aria-hidden="true"
xmlns="http://www.w3.org/2000/svg" fill="none"
viewBox="0 0 14 14">
<path stroke="currentColor" stroke-linecap="round"
stroke-linejoin="round" stroke-width="2"
d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6"/>
</svg>
<span class="sr-only">Close modal</span>
</button>
</div>
<div class="p-4 md:p-5">
<form name="containerSettingsForm">
<div ng-hide="installationDetailsForm"
class="flex mt-4 py-2 px-6">
<div>
<p class="font-semibold w-60">Job ID</p>
</div>
<div>
<input name="name" type="number"
class="w-80 bg-gray-100 rounded px-2 py-1"
ng-model="jobID" readonly>
</div>
</div>
<div ng-hide="installationDetailsForm"
class="flex py-2 px-6">
<div>
<p class="font-semibold w-60">Data</p>
</div>
<div>
<input ng-model="$parent.websiteData"
type="checkbox" value="">
Data
</div>
</div>
<div ng-hide="installationDetailsForm"
class="flex py-2 px-6">
<div>
<p class="font-semibold w-60">Databases</p>
</div>
<div>
<label>
<input ng-model="$parent.websiteDatabases"
type="checkbox" value="">
Databases
</label>
</div>
</div>
<div ng-hide="installationDetailsForm"
class="flex py-2 px-6">
<div>
<p class="font-semibold w-60">Emails</p>
</div>
<div>
<label>
<input ng-model="$parent.websiteEmails"
type="checkbox" value="">
Emails
</label>
</div>
</div>
</form>
<div ng-hide="installationDetailsForm" class="flex justify-center mt-3">
<button ng-click="saveChanges()"
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
Save Changes
</button>
</div>
<ul class="flex py-2 justify-center">
<li id="dns_tab_button"
class="hover:bg-orange-200 border-2 border-black rounded-l-3xl px-2 py-2 w-60 cursor-pointer active"
onclick="showTab1('sites')">
<a class="flex justify-center">
<p class="text-2xl font-bold">Sites</p>
</a>
</li>
<li id="api_tab_button"
class="hover:bg-orange-200 border-2 border-black rounded-r-3xl px-2 py-2 w-60 cursor-pointer"
onclick="showTab1('add_sites')">
<a class="flex justify-center">
<p class="text-2xl font-bold">Add Sites</p>
</a>
</li>
</ul>
<div id="sites" class="tab-content1">
<div class="relative py-5 overflow-x-auto">
<table class="w-full text-sm text-left rtl:text-right">
<thead>
<tr class="bg-gray-200 mt-6 w-full rounded-t-lg border-b-2 border-gray-400">
<th scope="col" class="px-6 py-3">
ID
</th>
<th scope="col" class="px-6 py-3">
Website
</th>
<th scope="col" class="px-6 py-3">
Actions
</th>
</tr>
</thead>
<tbody ng-repeat="record in websites track by $index"
class="border shadow-lg py-3 px-6 rounded-b-lg">
<tr>
<td ng-bind="record.id" class="px-6 py-4">
</td>
<td ng-bind="record.website" class="px-6 py-4">
</td>
<td class="px-6 py-4">
<a onclick="return false;"
ng-click="removeSite(record.website)"
class="bg-red-500 hover:bg-red-700 text-white font-bold py-1 px-2 rounded"
href="#">{% trans "Delete" %}
</a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div id="add_sites" class="tab-content1" style="display: none;">
<div ng-hide="installationDetailsForm"
class="flex mt-4 py-2 px-6">
<div class="flex items-center">
<p class="font-semibold w-60">Select Site</p>
<img ng-hide="cyberpanelLoading"
src="{% static 'images/loading.gif' %}">
</div>
<div>
<select ng-model="$parent.websiteToBeAdded"
class="w-80 bg-gray-100 rounded px-2 py-1">
{% for items in websiteList %}
<option>{{ items }}</option>
{% endfor %}
</select>
</div>
</div>
<div ng-hide="savebtn" class="flex justify-center mt-3">
<button ng-click="addWebsite()"
class="bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded">
Add
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</td>
{% endblock %}

View File

@ -127,7 +127,94 @@
<td ng-bind="record.date" class="px-6 py-4">
</td>
<td class="px-6 py-4">
Restore
{# <a onclick="return false;"#}
{# class="bg-orange-500 hover:bg-orange-700 text-white font-bold py-1 px-2 rounded"#}
{# href="#" data-modal-target="edit"#}
{# data-modal-toggle="edit">{% trans " Restore Points" %}#}
{# </a>#}
{# <div id="edit" tabindex="-1"#}
{# class="hidden overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-50 justify-center items-center w-full md:inset-0 h-[calc(100%-1rem)] max-h-full">#}
{# <div class="relative p-4 w-full max-w-2xl max-h-full">#}
{# <div class="relative bg-white shadow dark:bg-gray-700">#}
{# <div class="flex items-center bg-blue-400 px-4 py-4">#}
{# <p class="font-bold">Restore Points</p>#}
{# <img ng-hide="cyberpanelLoading"#}
{# src="{% static 'images/loading.gif' %}">#}
{# <button type="button" data-modal-toggle="edit"#}
{# class="absolute top-2 end-1 text-black bg-transparent hover:text-black rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center"#}
{# data-modal-hide="edit">#}
{# <svg class="w-3 h-3" aria-hidden="true"#}
{# xmlns="http://www.w3.org/2000/svg" fill="none"#}
{# viewBox="0 0 14 14">#}
{# <path stroke="currentColor" stroke-linecap="round"#}
{# stroke-linejoin="round" stroke-width="2"#}
{# d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6"/>#}
{# </svg>#}
{# <span class="sr-only">Close modal</span>#}
{# </button>#}
{# </div>#}
{# <div class="p-4 md:p-5">#}
{# <div class="relative py-5 overflow-x-auto">#}
{# <table class="w-full text-sm text-left rtl:text-right">#}
{# <thead>#}
{# <tr class="bg-gray-200 mt-6 w-full rounded-t-lg border-b-2 border-gray-400">#}
{# <th scope="col" class="px-6 py-3">#}
{# Job ID#}
{# </th>#}
{# <th scope="col" class="px-6 py-3">#}
{# Snapshot ID#}
{# </th>#}
{# <th scope="col" class="px-6 py-3">#}
{# Type#}
{# </th>#}
{# <th scope="col" class="px-6 py-3">#}
{# Destination#}
{# </th>#}
{# <th scope="col" class="px-6 py-3">#}
{# Action#}
{# </th>#}
{# </tr>#}
{# </thead>#}
{# <tbody ng-repeat="job in jobs track by $index"#}
{# class="border shadow-lg py-3 px-6 rounded-b-lg">#}
{# <tr>#}
{# <td ng-bind="job.id" class="px-6 py-4">#}
{# </td>#}
{# <td ng-bind="job.snapshotid" class="px-6 py-4">#}
{# </td>#}
{# <td ng-bind="job.type" class="px-6 py-4">#}
{# </td>#}
{# <td ng-bind="job.destination" class="px-6 py-4">#}
{# </td>#}
{# <td class="px-6 py-4">#}
{# <a ng-click="restorePoint(job.id, 0)"#}
{# class="btn btn-border btn-alt border-green btn-link font-green"#}
{# title=""><span>Restore</span></a>#}
{# </td>#}
{# </tr>#}
{# </tbody>#}
{# </table>#}
{# </div>#}
{# <div ng-hide="restoreSt">#}
{# <div>#}
{# <div>#}
{# <textarea ng-model="status"#}
{# class="w-full"#}
{# rows="7"></textarea>#}
{# </div>#}
{# </div>#}
{# </div>#}
{# <div class="flex justify-end mt-3">#}
{# <button data-modal-toggle="edit"#}
{# data-modal-hide="edit"#}
{# class="ml-2 bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 rounded">#}
{# Close#}
{# </button>#}
{# </div>#}
{# </div>#}
{# </div>#}
{# </div>#}
{# </div>#}
</td>
<td ng-click="deleteBackup(record.id)" class="px-6 py-4">
<img class="ml-2 cursor-pointer" src="{% static 'images/delete.png' %}">
@ -137,4 +224,92 @@
</table>
</div>
</div>
<a onclick="return false;"
class="bg-orange-500 hover:bg-orange-700 text-white font-bold py-1 px-2 rounded"
href="#" data-modal-target="edit"
data-modal-toggle="edit">{% trans " Restore Points" %}
</a>
<div id="edit" tabindex="-1"
class="hidden overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-50 justify-center items-center w-full md:inset-0 h-[calc(100%-1rem)] max-h-full">
<div class="relative p-4 w-full max-w-2xl max-h-full">
<div class="relative bg-white shadow dark:bg-gray-700">
<div class="flex items-center bg-blue-400 px-4 py-4">
<p class="font-bold">Restore Points</p>
<img ng-hide="cyberpanelLoading"
src="{% static 'images/loading.gif' %}">
<button type="button" data-modal-toggle="edit"
class="absolute top-2 end-1 text-black bg-transparent hover:text-black rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center"
data-modal-hide="edit">
<svg class="w-3 h-3" aria-hidden="true"
xmlns="http://www.w3.org/2000/svg" fill="none"
viewBox="0 0 14 14">
<path stroke="currentColor" stroke-linecap="round"
stroke-linejoin="round" stroke-width="2"
d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6"/>
</svg>
<span class="sr-only">Close modal</span>
</button>
</div>
<div class="p-4 md:p-5">
<div class="relative py-5 overflow-x-auto">
<table class="w-full text-sm text-left rtl:text-right">
<thead>
<tr class="bg-gray-200 mt-6 w-full rounded-t-lg border-b-2 border-gray-400">
<th scope="col" class="px-6 py-3">
Job ID
</th>
<th scope="col" class="px-6 py-3">
Snapshot ID
</th>
<th scope="col" class="px-6 py-3">
Type
</th>
<th scope="col" class="px-6 py-3">
Destination
</th>
<th scope="col" class="px-6 py-3">
Action
</th>
</tr>
</thead>
<tbody ng-repeat="job in jobs track by $index"
class="border shadow-lg py-3 px-6 rounded-b-lg">
<tr>
<td ng-bind="job.id" class="px-6 py-4">
</td>
<td ng-bind="job.snapshotid" class="px-6 py-4">
</td>
<td ng-bind="job.type" class="px-6 py-4">
</td>
<td ng-bind="job.destination" class="px-6 py-4">
</td>
<td class="px-6 py-4">
<a ng-click="restorePoint(job.id, 0)"
class="btn btn-border btn-alt border-green btn-link font-green"
title=""><span>Restore</span></a>
</td>
</tr>
</tbody>
</table>
</div>
<div ng-hide="restoreSt">
<div>
<div class="border">
<textarea ng-model="status"
class="w-full"
rows="7"></textarea>
</div>
</div>
</div>
<div class="flex justify-end mt-3">
<button data-modal-toggle="edit"
data-modal-hide="edit"
class="ml-2 bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 rounded">
Close
</button>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -23,7 +23,7 @@
<div class="panel-body">
<h3 class="title-hero">
{% trans "Backup Website" %} <img ng-hide="cyberpanelLoading"
src="{% static 'images/loading.gif' %}">
src="{% static 'images/loading.gif' %}">
</h3>
<div class="example-box-wrapper">
@ -109,7 +109,7 @@
<td ng-bind="record.path"></td>
<td>
<a ng-click="restorePoint(record.id, record.path)"
class="btn btn-border btn-alt border-green btn-link font-green"
class="bg-orange-500 hover:bg-orange-700 text-white font-bold py-1 px-2 rounded"
title=""><span>Restore</span></a>
</td>
</tr>

View File

@ -18,7 +18,7 @@
</div>
<p class="text-xs text-gray-600 py-2 font-semibold">On this page you can set up your Backup destinations. (SFTP)
</p>
<div class="py-4">
<div class="flex items-center py-4">
<p class="text-xl font-bold">Set up Backup Destinations.</p>
<img ng-hide="cyberpanelLoading"
src="{% static 'images/loading.gif' %}">

View File

@ -15,7 +15,7 @@
</div>
</div>
<p class="text-xs text-gray-600 py-2 font-semibold">This page can be used to Backup your websites</p>
<div class="py-4">
<div class="flex items-center py-4">
<p class="text-xl font-bold">Backup Website</p>
<img ng-hide="backupLoading" src="{% static 'images/loading.gif' %}">
</div>

View File

@ -16,7 +16,7 @@
</div>
<p class="text-xs text-gray-600 py-2 font-semibold">This feature can import website(s) from remote server
</p>
<div class="py-4">
<div class="flex items-center py-4">
<p class="text-xl font-bold">Remote Backups</p>
<img ng-hide="backupLoading" src="{% static 'images/loading.gif' %}">
</div>

View File

@ -17,7 +17,7 @@
<p class="text-xs text-gray-600 py-2 font-semibold">This page can be used to restore your websites, Backup
should be generated from CyberPanel Backup generation tool, it will detect all Backups under <strong>/home/backup</strong>.
</p>
<div class="py-4">
<div class="flex items-center py-4">
<p class="text-xl font-bold">Restore Website</p>
<img ng-hide="restoreLoading" src="{% static 'images/loading.gif' %}">
</div>

View File

@ -197,6 +197,29 @@ class EmailMarketingManager:
except KeyError as msg:
return redirect(loadLoginPage)
def manageListsV2(self):
try:
userID = self.request.session['userID']
currentACL = ACLManager.loadedACL(userID)
admin = Administrator.objects.get(pk=userID)
if ACLManager.checkOwnership(self.domain, admin, currentACL) == 1:
pass
else:
return ACLManager.loadError()
if emACL.checkIfEMEnabled(admin.userName) == 0:
return ACLManager.loadError()
listNames = emACL.getEmailsLists(self.domain)
proc = httpProc(self.request, 'emailMarketing/manageListsV2.html',
{'listNames': listNames, 'domain': self.domain})
return proc.render()
except KeyError as msg:
return redirect(loadLoginPage)
def configureVerify(self):
try:
@ -721,6 +744,20 @@ class EmailMarketingManager:
except KeyError as msg:
return redirect(loadLoginPage)
def composeEmailMessageV2(self):
try:
userID = self.request.session['userID']
admin = Administrator.objects.get(pk=userID)
if emACL.checkIfEMEnabled(admin.userName) == 0:
return ACLManager.loadErrorJson()
proc = httpProc(self.request, 'emailMarketing/composeMessagesV2.html',
None)
return proc.render()
except KeyError as msg:
return redirect(loadLoginPage)
def saveEmailTemplate(self):
try:
userID = self.request.session['userID']
@ -780,6 +817,31 @@ class EmailMarketingManager:
except KeyError as msg:
return redirect(loadLoginPage)
def sendEmailsV2(self):
try:
userID = self.request.session['userID']
admin = Administrator.objects.get(pk=userID)
if emACL.checkIfEMEnabled(admin.userName) == 0:
return ACLManager.loadErrorJson()
currentACL = ACLManager.loadedACL(userID)
templateNames = emACL.allTemplates(currentACL, admin)
hostNames = emACL.allSMTPHosts(currentACL, admin)
listNames = emACL.allEmailsLists(currentACL, admin)
Data = {}
Data['templateNames'] = templateNames
Data['hostNames'] = hostNames
Data['listNames'] = listNames
proc = httpProc(self.request, 'emailMarketing/sendEmailsV2.html',
Data)
return proc.render()
except KeyError as msg:
return redirect(loadLoginPage)
def templatePreview(self):
try:
userID = self.request.session['userID']

View File

@ -2,6 +2,22 @@ var emailListURL = "/emailMarketing/" + $("#domainNamePageV2").text() + "/emailL
$("#emailListsV2").attr("href", emailListURL);
$("#emailListsChildV2").attr("href", emailListURL);
var manageListsURL = "/emailMarketing/" + $("#domainNamePageV2").text() + "/manageListsV2";
$("#manageListsV2").attr("href", manageListsURL);
$("#manageListsChildV2").attr("href", manageListsURL);
var sendEmailsURL = "/emailMarketing/sendEmailsV2";
$("#sendEmailsPageV2").attr("href", sendEmailsURL);
$("#sendEmailsPageChildV2").attr("href", sendEmailsURL);
var composeEmailURL = "/emailMarketing/composeEmailMessageV2";
$("#composeEmailsV2").attr("href", composeEmailURL);
$("#composeEmailsChildV2").attr("href", composeEmailURL);
var smtpHostsURL = "/emailMarketing/" + $("#domainNamePageV2").text() + "/manageSMTPV2";
$("#manageSMTPHostsV2").attr("href", smtpHostsURL);
$("#manageSMTPHostsChildV2").attr("href", smtpHostsURL);
newapp.controller('createEmailListV2', function ($scope, $http, $timeout) {
$scope.installationDetailsForm = false;
@ -391,5 +407,876 @@ newapp.controller('manageSMTPHostsCTRLV2', function ($scope, $http) {
}
};
});
newapp.controller('manageEmailListsV2', function ($scope, $http, $timeout) {
$scope.installationDetailsForm = true;
$scope.installationProgress = true;
$scope.cyberPanelLoading = true;
$scope.goBackDisable = true;
$scope.verificationStatus = true;
var statusFile;
var path;
$scope.goBack = function () {
$scope.installationDetailsForm = false;
$scope.installationProgress = true;
$scope.cyberPanelLoading = true;
$scope.goBackDisable = true;
$("#installProgress").css("width", "0%");
};
$scope.createEmailList = function () {
$scope.installationDetailsForm = true;
$scope.installationProgress = false;
$scope.cyberPanelLoading = false;
$scope.goBackDisable = true;
$scope.currentStatus = "Starting to load email addresses..";
url = "/emailMarketing/submitEmailList";
var data = {
domain: $("#domainNamePage").text(),
path: $scope.path,
listName: $scope.listName
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
function ListInitialDatas(response) {
if (response.data.status === 1) {
statusFile = response.data.tempStatusPath;
getInstallStatus();
} else {
$scope.installationDetailsForm = true;
$scope.cyberPanelLoading = true;
$scope.goBackDisable = false;
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'
});
}
};
function getInstallStatus() {
url = "/websites/installWordpressStatus";
var data = {
statusFile: statusFile,
domainName: $("#domainNamePage").text()
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
function ListInitialDatas(response) {
if (response.data.abort === 1) {
if (response.data.installStatus === 1) {
$scope.installationDetailsForm = true;
$scope.installationProgress = false;
$scope.cyberPanelLoading = true;
$scope.goBackDisable = false;
$scope.currentStatus = 'Emails successfully loaded.';
$timeout.cancel();
} else {
$scope.installationDetailsForm = true;
$scope.installationProgress = false;
$scope.cyberPanelLoading = true;
$scope.goBackDisable = false;
$scope.currentStatus = response.data.error_message;
}
} else {
$scope.installPercentage = response.data.installationProgress;
$scope.currentStatus = response.data.currentStatus;
$timeout(getInstallStatus, 1000);
}
}
function cantLoadInitialDatas(response) {
$scope.cyberPanelLoading = true;
new PNotify({
title: 'Operation Failed!',
text: 'Could not connect to server, please refresh this page',
type: 'error'
});
}
}
///
$scope.currentRecords = true;
$scope.recordstoShow = 50;
var globalPage;
$scope.fetchRecords = function () {
$scope.fetchEmails(globalPage);
};
$scope.fetchEmails = function (page) {
globalPage = page;
listVerificationStatus();
$scope.cyberPanelLoading = false;
url = "/emailMarketing/fetchEmails";
var data = {
'listName': $scope.listName,
'recordstoShow': $scope.recordstoShow,
'page': page
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
function ListInitialDatas(response) {
$scope.cyberPanelLoading = true;
if (response.data.status === 1) {
$scope.currentRecords = false;
$scope.records = JSON.parse(response.data.data);
$scope.pagination = response.data.pagination;
$scope.verificationButton = false;
} else {
new PNotify({
title: 'Operation Failed!',
text: response.data.error_message,
type: 'error'
});
}
}
function cantLoadInitialDatas(response) {
$scope.cyberPanelLoading = false;
new PNotify({
title: 'Operation Failed!',
text: 'Could not connect to server, please refresh this page',
type: 'error'
});
}
};
$scope.deleteList = function () {
$scope.cyberPanelLoading = false;
url = "/emailMarketing/deleteList";
var data = {
listName: $scope.listName
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
function ListInitialDatas(response) {
$scope.cyberPanelLoading = true;
if (response.data.status === 1) {
new PNotify({
title: 'Success!',
text: 'Emails Successfully Deleted.',
type: 'success'
});
} else {
$scope.cyberPanelLoading = false;
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.showAddEmails = function () {
$scope.installationDetailsForm = false;
$scope.verificationStatus = true;
};
// List Verification
$scope.startVerification = function () {
$scope.currentStatusVerification = 'Email verification job started..';
$scope.installationDetailsForm = true;
$scope.verificationStatus = false;
$scope.verificationButton = true;
$scope.cyberPanelLoading = false;
url = "/emailMarketing/emailVerificationJob";
var data = {
listName: $scope.listName
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
function ListInitialDatas(response) {
if (response.data.status === 1) {
listVerificationStatus();
$scope.verificationButton = true;
} else {
$scope.cyberPanelLoading = true;
$scope.verificationButton = false;
new PNotify({
title: 'Operation Failed!',
text: response.data.error_message,
type: 'error'
});
}
}
function cantLoadInitialDatas(response) {
$scope.cyberPanelLoading = true;
$scope.verificationButton = false;
new PNotify({
title: 'Operation Failed!',
text: 'Could not connect to server, please refresh this page',
type: 'error'
});
}
};
var globalCounter = 0;
function listVerificationStatus() {
$scope.verificationButton = true;
$scope.cyberPanelLoading = false;
url = "/websites/installWordpressStatus";
var data = {
domain: $("#domainNamePage").text(),
statusFile: "/home/cyberpanel/" + $("#domainNamePage").text() + "/" + $scope.listName
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
function ListInitialDatas(response) {
if (response.data.abort === 1) {
if (response.data.installStatus === 1) {
$scope.cyberPanelLoading = true;
$scope.verificationButton = false;
$scope.currentStatusVerification = 'Emails successfully verified.';
$timeout.cancel();
} else {
if (response.data.error_message.search('No such file') > -1) {
$scope.verificationButton = false;
return;
}
$scope.verificationButton = true;
$scope.cyberPanelLoading = false;
$scope.verificationStatus = false;
$scope.currentStatusVerification = response.data.error_message;
}
} else {
if (response.data.currentStatus.search('No such file') > -1) {
$scope.cyberPanelLoading = true;
$scope.deleteTemplateBTN = false;
$scope.sendEmailBTN = false;
$scope.sendEmailsView = true;
$scope.jobStatus = true;
$scope.goBackDisable = false;
$timeout.cancel();
return;
}
$scope.currentStatusVerification = response.data.currentStatus;
$timeout(listVerificationStatus, 1000);
$scope.verificationStatus = false;
}
}
function cantLoadInitialDatas(response) {
$scope.cyberPanelLoading = true;
new PNotify({
title: 'Operation Failed!',
text: 'Could not connect to server, please refresh this page',
type: 'error'
});
}
}
// Delete Email from list
$scope.deleteEmail = function (id) {
$scope.cyberPanelLoading = false;
url = "/emailMarketing/deleteEmail";
var data = {
id: id
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
function ListInitialDatas(response) {
$scope.cyberPanelLoading = true;
$scope.fetchEmails(globalPage);
if (response.data.status === 1) {
$scope.fetchEmails(globalPage);
new PNotify({
title: 'Success.',
text: 'Email Successfully deleted.',
type: 'success'
});
} 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.currentPageLogs = 1;
$scope.recordsToShowLogs = 10;
$scope.fetchLogs = function () {
$scope.cyberPanelLoading = false;
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
var data = {
listName: $scope.listName,
page: $scope.currentPageLogs,
recordsToShow: $scope.recordsToShowLogs
};
url = "/emailMarketing/fetchVerifyLogs";
$http.post(url, data, config).then(ListInitialData, cantLoadInitialData);
function ListInitialData(response) {
$scope.cyberPanelLoading = true;
if (response.data.status === 1) {
$scope.recordsLogs = JSON.parse(response.data.logs);
$scope.paginationLogs = response.data.pagination;
$scope.totalEmails = response.data.totalEmails;
$scope.verified = response.data.verified;
$scope.notVerified = response.data.notVerified;
} else {
new PNotify({
title: 'Error!',
text: response.data.error_message,
type: 'error'
});
}
}
function cantLoadInitialData(response) {
$scope.cyberPanelLoading = true;
new PNotify({
title: 'Operation Failed!',
text: 'Could not connect to server, please refresh this page',
type: 'error'
});
}
};
});
newapp.controller('sendEmailsCTRLV2', function ($scope, $http, $timeout) {
$scope.cyberPanelLoading = true;
$scope.availableFunctions = true;
$scope.sendEmailsView = true;
$scope.jobStatus = true;
// Button
$scope.deleteTemplateBTN = false;
$scope.sendEmailBTN = false;
$scope.templateSelected = function () {
$scope.availableFunctions = false;
$scope.sendEmailsView = true;
$scope.previewLink = '/emailMarketing/preview/' + $scope.selectedTemplate;
$scope.jobStatus = true;
emailJobStatus();
};
$scope.sendEmails = function () {
$scope.sendEmailsView = false;
$scope.fetchJobs();
};
$scope.fetchJobs = function () {
$scope.cyberPanelLoading = false;
url = "/emailMarketing/fetchJobs";
var data = {
'selectedTemplate': $scope.selectedTemplate
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
function ListInitialDatas(response) {
$scope.cyberPanelLoading = true;
if (response.data.status === 1) {
$scope.currentRecords = false;
$scope.records = JSON.parse(response.data.data);
} else {
new PNotify({
title: 'Operation Failed!',
text: response.data.error_message,
type: 'error'
});
}
}
function cantLoadInitialDatas(response) {
$scope.cyberPanelLoading = false;
new PNotify({
title: 'Operation Failed!',
text: 'Could not connect to server, please refresh this page',
type: 'error'
});
}
};
$scope.startEmailJob = function () {
$scope.cyberPanelLoading = false;
$scope.deleteTemplateBTN = true;
$scope.sendEmailBTN = true;
$scope.sendEmailsView = true;
$scope.goBackDisable = true;
url = "/emailMarketing/startEmailJob";
var data = {
'selectedTemplate': $scope.selectedTemplate,
'listName': $scope.listName,
'host': $scope.host,
'verificationCheck': $scope.verificationCheck,
'unsubscribeCheck': $scope.unsubscribeCheck
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
function ListInitialDatas(response) {
$scope.cyberPanelLoading = true;
if (response.data.status === 1) {
emailJobStatus();
} else {
$scope.cyberPanelLoading = true;
$scope.deleteTemplateBTN = false;
$scope.sendEmailBTN = false;
$scope.sendEmailsView = false;
$scope.jobStatus = true;
$scope.goBackDisable = false;
new PNotify({
title: 'Operation Failed!',
text: response.data.error_message,
type: 'error'
});
}
}
function cantLoadInitialDatas(response) {
$scope.cyberPanelLoading = false;
new PNotify({
title: 'Operation Failed!',
text: 'Could not connect to server, please refresh this page',
type: 'error'
});
}
};
function emailJobStatus() {
$scope.cyberPanelLoading = false;
$scope.deleteTemplateBTN = true;
$scope.sendEmailBTN = true;
$scope.sendEmailsView = true;
$scope.jobStatus = false;
$scope.goBackDisable = true;
url = "/websites/installWordpressStatus";
var data = {
domain: 'example.com',
statusFile: "/home/cyberpanel/" + $scope.selectedTemplate + "_pendingJob"
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
function ListInitialDatas(response) {
if (response.data.abort === 1) {
if (response.data.installStatus === 1) {
$scope.cyberPanelLoading = true;
$scope.deleteTemplateBTN = false;
$scope.sendEmailBTN = false;
$scope.sendEmailsView = true;
$scope.jobStatus = false;
$scope.goBackDisable = false;
$scope.currentStatus = 'Emails successfully sent.';
$scope.fetchJobs();
$timeout.cancel();
} else {
if (response.data.error_message.search('No such file') > -1) {
$scope.cyberPanelLoading = true;
$scope.deleteTemplateBTN = false;
$scope.sendEmailBTN = false;
$scope.sendEmailsView = true;
$scope.jobStatus = true;
$scope.goBackDisable = false;
return;
}
$scope.cyberPanelLoading = true;
$scope.deleteTemplateBTN = false;
$scope.sendEmailBTN = false;
$scope.sendEmailsView = true;
$scope.jobStatus = false;
$scope.goBackDisable = false;
$scope.currentStatus = response.data.error_message;
}
} else {
if (response.data.currentStatus.search('No such file') > -1) {
$scope.cyberPanelLoading = true;
$scope.deleteTemplateBTN = false;
$scope.sendEmailBTN = false;
$scope.sendEmailsView = true;
$scope.jobStatus = true;
$scope.goBackDisable = false;
$timeout.cancel();
return;
}
$scope.currentStatus = response.data.currentStatus;
$timeout(emailJobStatus, 1000);
$scope.cyberPanelLoading = false;
$scope.deleteTemplateBTN = true;
$scope.sendEmailBTN = true;
$scope.sendEmailsView = true;
$scope.jobStatus = false;
$scope.goBackDisable = true;
}
}
function cantLoadInitialDatas(response) {
$scope.cyberPanelLoading = true;
new PNotify({
title: 'Operation Failed!',
text: 'Could not connect to server, please refresh this page.',
type: 'error'
});
}
}
$scope.goBack = function () {
$scope.cyberPanelLoading = true;
$scope.deleteTemplateBTN = false;
$scope.sendEmailBTN = false;
$scope.sendEmailsView = false;
$scope.jobStatus = true;
};
$scope.deleteTemplate = function () {
$scope.cyberPanelLoading = false;
url = "/emailMarketing/deleteTemplate";
var data = {
selectedTemplate: $scope.selectedTemplate
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
function ListInitialDatas(response) {
$scope.cyberPanelLoading = true;
if (response.data.status === 1) {
new PNotify({
title: 'Success.',
text: 'Template Successfully deleted.',
type: 'success'
});
} 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.deleteJob = function (id) {
$scope.cyberPanelLoading = false;
url = "/emailMarketing/deleteJob";
var data = {
id: id
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
function ListInitialDatas(response) {
$scope.cyberPanelLoading = true;
$scope.fetchJobs();
if (response.data.status === 1) {
new PNotify({
title: 'Success.',
text: 'Template Successfully deleted.',
type: 'success'
});
} 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'
});
}
};
});

View File

@ -11,7 +11,7 @@
<p class="text-xs text-gray-600 py-2 font-semibold">On this page you can compose email message to be sent
out later.</p>
</div>
<div class="py-4">
<div class="flex items-center py-4">
<p class="text-xl font-bold">Compose Email Message</p>
<img ng-hide="cyberPanelLoading" src="{% static 'images/loading.gif' %}">
</div>
@ -60,17 +60,17 @@
</div>
</div>
</div>
<div ng-hide="request" class="py-2 px-6">
<div ng-hide="request" class="w-full">
<div>
<textarea placeholder="Paste your email message, any format is accepted. (HTML or Plain)"
ng-model="emailMessage" rows="15" class="border"></textarea>
ng-model="emailMessage" rows="15" class="border w-full"></textarea>
</div>
</div>
</div>
<div ng-hide="installationProgress" class="flex justify-center">
<div ng-hide="installationProgress" class="flex justify-center mt-2">
<button ng-click="saveTemplate()"
class="bg-orange-500 px-3 py-4 rounded-lg text-xl font-semibold text-white">
class="bg-orange-500 px-3 py-2 rounded-lg text-xl font-semibold text-white">
Save Template
</button>
</div>

View File

@ -5,7 +5,7 @@
{% load static %}
<div ng-controller="manageEmailLists" class="p-8">
<div ng-controller="manageEmailListsV2" class="p-8">
<div>
<div class="flex justify-between items-center">
<div>
@ -19,7 +19,7 @@
</div>
</div>
<div>
<div class="py-4">
<div class="flex items-center py-4">
<p class="text-xl font-bold">Manage Email Lists</p>
<img ng-hide="cyberPanelLoading"
src="{% static 'images/loading.gif' %}">

View File

@ -12,7 +12,7 @@
used to send emails.</p>
</div>
<div>
<div class="py-4">
<div class="flex items-center py-4">
<p class="text-xl font-bold">Manage SMTP Hosts</p>
<img ng-hide="cyberPanelLoading" src="{% static 'images/loading.gif' %}">
</div>
@ -53,9 +53,9 @@
</div>
</div>
</div>
<div ng-hide="installationProgress" class="flex justify-center">
<div ng-hide="installationProgress" class="flex justify-center mt-2">
<button ng-click="saveSMTPHost()"
class="bg-orange-500 px-3 py-4 rounded-lg text-xl font-semibold text-white">
class="bg-orange-500 px-3 py-2 rounded-lg text-xl font-semibold text-white">
Save Host
</button>
</div>

View File

@ -0,0 +1,220 @@
{% extends "baseTemplate/newBase.html" %}
{% load i18n %}
{% block titleNew %}{% trans "Home - CyberPanel" %}{% endblock %}
{% block newContent %}
{% load static %}
<div ng-controller="sendEmailsCTRLV2" class="p-8">
<div>
<div class="flex justify-between items-center">
<div>
<div>
<p class="text-4xl font-bold">Send Emails</p>
<p class="text-xs text-gray-600 py-2 font-semibold">On this page you can send emails to the
lists you created using SMTP Hosts.</p>
</div>
</div>
</div>
</div>
<div>
<div class="flex items-center py-4">
<p class="text-xl font-bold">Send Emails</p>
<img ng-hide="cyberPanelLoading" src="{% static 'images/loading.gif' %}">
</div>
<hr>
<div>
<div class="flex mt-4 py-2 px-6">
<div>
<p class="font-semibold w-60">Select Template</p>
</div>
<div>
<select ng-change="templateSelected()" ng-model="selectedTemplate"
class="w-80 bg-gray-100 rounded px-2 py-1">
{% for items in templateNames %}
<option>{{ items }}</option>
{% endfor %}
</select>
</div>
</div>
{# <div ng-hide="availableFunctions" class="form-group">#}
{##}
{# <div ng-hide="mailConfigured==1">#}
{# <div class="flex justify-center bg-red-500 rounded-lg text-white px-2 py-1 font-semibold">#}
{# <p>{% trans "SSL for email is not configured properly, you may get Self-Signed error on mail clients such as Outlook and Thunderbird. More details " %}<a#}
{# href="https://cyberpanel.net/docs/6-self-signed-ssl-error-on-outlook-thunderbird/">here</a>.#}
{# </p>#}
{# </div>#}
{# <a target="_blank" href="" class="flex justify-center mt-3">#}
{# <button ng-click='fixMailSSL()' class="bg-orange-500 text-white font-semibold px-2 py-1">Fix#}
{# Now#}
{# </button>#}
{# </a>#}
{# </div>#}
{##}
{# <div class="py-4">#}
{# <p class="text-xl font-bold">Details To Configure Mail Clients</p>#}
{# </div>#}
{# <div>#}
{# <div>#}
{# <div ng-hide="creationBox" class="relative py-5 overflow-x-auto">#}
{# <table class="w-full text-sm text-left rtl:text-right">#}
{# <thead>#}
{# <tr>#}
{# <th scope="col" class="px-6 py-3">#}
{# Emails#}
{# </th>#}
{# <th scope="col" class="px-6 py-3">#}
{# Disk Usage#}
{# </th>#}
{# <th scope="col" class="px-6 py-3">#}
{# Actions#}
{# </th>#}
{# </tr>#}
{# </thead>#}
{# <tbody ng-repeat="record in records track by $index"#}
{# class="border shadow-lg py-3 px-6 rounded-b-lg">#}
{# <tr>#}
{# <td ng-bind="record.email" class="px-6 py-4">#}
{# </td>#}
{# <td ng-bind="record.DiskUsage" class="px-6 py-4">#}
{# </td>#}
{# <td class="flex gap-2 px-6 py-4">#}
{# <button ng-click="changePasswordInitial(record.email)"#}
{# class="bg-orange-500 text-white font-semibold px-2 py-1">Change#}
{# Password#}
{# </button>#}
{# <button ng-click="deleteEmailAccountFinal(record.email)"#}
{# class="bg-red-500 text-white font-semibold px-2 py-1">Delete#}
{# </button>#}
{# </td>#}
{# </tr>#}
{# </tbody>#}
{# </table>#}
{# </div>#}
{# </div>#}
{# <div>#}
{# <div ng-hide="creationBox" class="relative py-5 overflow-x-auto">#}
{# <table class="w-full text-sm text-left rtl:text-right">#}
{# <div class="bg-gray-200 mt-6 w-full rounded-t-lg border-b-2 border-gray-400">#}
{# <p class="font-bold px-4 py-1">POP3</p>#}
{# </div>#}
{# <thead>#}
{# <tr>#}
{# <th scope="col" class="px-6 py-3">#}
{# Server Hostname#}
{# </th>#}
{# <th scope="col" class="px-6 py-3">#}
{# Port#}
{# </th>#}
{# <th scope="col" class="px-6 py-3">#}
{# Port#}
{# </th>#}
{# <th scope="col" class="px-6 py-3">#}
{# SSL#}
{# </th>#}
{# </tr>#}
{# </thead>#}
{# <tbody class="border shadow-lg py-3 px-6 rounded-b-lg">#}
{# <tr>#}
{# <td class="px-6 py-4">#}
{# {$ serverHostname $}#}
{# </td>#}
{# <td class="px-6 py-4">#}
{# 110#}
{# </td>#}
{# <td class="px-6 py-4">#}
{# 995 (SSL)#}
{# </td>#}
{# <td class="px-6 py-4">#}
{# STARTTLS#}
{# </td>#}
{# </tr>#}
{# </tbody>#}
{# </table>#}
{# </div>#}
{# <div ng-hide="creationBox" class="relative py-5 overflow-x-auto">#}
{# <table class="w-full text-sm text-left rtl:text-right">#}
{# <div class="bg-gray-200 mt-6 w-full rounded-t-lg border-b-2 border-gray-400">#}
{# <p class="font-bold px-4 py-1">IMAP</p>#}
{# </div>#}
{# <thead>#}
{# <tr>#}
{# <th scope="col" class="px-6 py-3">#}
{# Server Hostname#}
{# </th>#}
{# <th scope="col" class="px-6 py-3">#}
{# Port#}
{# </th>#}
{# <th scope="col" class="px-6 py-3">#}
{# Port#}
{# </th>#}
{# <th scope="col" class="px-6 py-3">#}
{# SSL#}
{# </th>#}
{# </tr>#}
{# </thead>#}
{# <tbody class="border shadow-lg py-3 px-6 rounded-b-lg">#}
{# <tr>#}
{# <td class="px-6 py-4">#}
{# {$ serverHostname $}#}
{# </td>#}
{# <td class="px-6 py-4">#}
{# 143#}
{# </td>#}
{# <td class="px-6 py-4">#}
{# 993 (SSL)#}
{# </td>#}
{# <td class="px-6 py-4">#}
{# STARTTLS#}
{# </td>#}
{# </tr>#}
{# </tbody>#}
{# </table>#}
{# </div>#}
{# <div ng-hide="creationBox" class="relative py-5 overflow-x-auto">#}
{# <table class="w-full text-sm text-left rtl:text-right">#}
{# <div class="bg-gray-200 mt-6 w-full rounded-t-lg border-b-2 border-gray-400">#}
{# <p class="font-bold px-4 py-1">SMTP</p>#}
{# </div>#}
{# <thead>#}
{# <tr>#}
{# <th scope="col" class="px-6 py-3">#}
{# Server Hostname#}
{# </th>#}
{# <th scope="col" class="px-6 py-3">#}
{# Port#}
{# </th>#}
{# <th scope="col" class="px-6 py-3">#}
{# Port#}
{# </th>#}
{# <th scope="col" class="px-6 py-3">#}
{# 465 SSL#}
{# </th>#}
{# </tr>#}
{# </thead>#}
{# <tbody class="border shadow-lg py-3 px-6 rounded-b-lg">#}
{# <tr>#}
{# <td class="px-6 py-4">#}
{# {$ serverHostname $}#}
{# </td>#}
{# <td class="px-6 py-4">#}
{# 25#}
{# </td>#}
{# <td class="px-6 py-4">#}
{# 587 (SSL)#}
{# </td>#}
{# <td class="px-6 py-4">#}
{# STARTTLS#}
{# </td>#}
{# </tr>#}
{# </tbody>#}
{# </table>#}
{# </div>#}
{# </div>#}
{# </div>#}
{# </div>#}
</div>
</div>
</div>
{% endblock %}

View File

@ -11,8 +11,9 @@ urlpatterns = [
url(r'^(?P<domain>(.*))/emailListsV2$', views.createEmailListV2, name='createEmailListV2'),
url(r'^submitEmailList$', views.submitEmailList, name='submitEmailList'),
url(r'^(?P<domain>(.*))/manageLists$', views.manageLists, name='manageLists'),
url(r'^(?P<domain>(.*))/manageListsV2$', views.manageListsV2, name='manageListsV2'),
url(r'^(?P<domain>(.*))/manageSMTP$', views.manageSMTP, name='manageSMTP'),
url(r'^V2/(?P<domain>(.*))/manageSMTPV2$', views.manageSMTPV2, name='manageSMTPV2'),
url(r'^(?P<domain>(.*))/manageSMTPV2$', views.manageSMTPV2, name='manageSMTPV2'),
url(r'^(?P<domain>(.*))/configureVerify$', views.configureVerify, name='configureVerify'),
url(r'^fetchEmails$', views.fetchEmails, name='fetchEmails'),
url(r'^deleteList$', views.deleteList, name='deleteList'),
@ -22,8 +23,10 @@ urlpatterns = [
url(r'^fetchSMTPHosts$', views.fetchSMTPHosts, name='fetchSMTPHosts'),
url(r'^smtpHostOperations$', views.smtpHostOperations, name='smtpHostOperations'),
url(r'^composeEmailMessage$', views.composeEmailMessage, name='composeEmailMessage'),
url(r'^composeEmailMessageV2$', views.composeEmailMessageV2, name='composeEmailMessageV2'),
url(r'^saveEmailTemplate$', views.saveEmailTemplate, name='saveEmailTemplate'),
url(r'^sendEmails$', views.sendEmails, name='sendEmails'),
url(r'^sendEmailsV2$', views.sendEmailsV2, name='sendEmailsV2'),
url(r'^preview/(?P<templateName>[-\w]+)/$', views.templatePreview, name='templatePreview'),
url(r'^fetchJobs$', views.fetchJobs, name='fetchJobs'),
url(r'^startEmailJob$', views.startEmailJob, name='startEmailJob'),

View File

@ -71,6 +71,15 @@ def manageLists(request, domain):
return redirect(loadLoginPage)
def manageListsV2(request, domain):
try:
userID = request.session['userID']
emm = EmailMarketingManager(request, domain)
return emm.manageListsV2()
except KeyError:
return redirect(loadLoginPage)
def configureVerify(request, domain):
try:
userID = request.session['userID']
@ -188,6 +197,15 @@ def composeEmailMessage(request):
return redirect(loadLoginPage)
def composeEmailMessageV2(request):
try:
userID = request.session['userID']
emm = EmailMarketingManager(request)
return emm.composeEmailMessageV2()
except KeyError:
return redirect(loadLoginPage)
def saveEmailTemplate(request):
try:
userID = request.session['userID']
@ -206,6 +224,15 @@ def sendEmails(request):
return redirect(loadLoginPage)
def sendEmailsV2(request):
try:
userID = request.session['userID']
emm = EmailMarketingManager(request)
return emm.sendEmailsV2()
except KeyError:
return redirect(loadLoginPage)
def templatePreview(request, templateName):
try:
userID = request.session['userID']

View File

@ -140,7 +140,7 @@ newapp.controller('EmailDebuugerV2', function ($scope, $http, $timeout, $window)
$scope.Port993 = report.Port993;
$scope.Port995 = report.Port995;
//document.getElementById('MailSSLURL').href = 'https://' + report.serverHostName + ":" + report.port + '/cloudAPI/access?token=' + report.token + "&serverUserName=" + report.userName + '&redirect=/manageSSL/sslForMailServer';
document.getElementById('MailSSLURL').href = '/manageSSL/sslForMailServer';
document.getElementById('MailSSLURLV2').href = '/manageSSL/V2/sslForMailServerV2';
$scope.ReportStatus = false;

View File

@ -117,7 +117,7 @@
{$ MailSSL $}
</td>
<td class="px-6 py-3">
<a id="MailSSLURL" target="_blank" href="#">
<a id="MailSSLURLV2" target="_blank" href="#">
<button data-toggle="modal" title="Manage CyberPanel" type="button"
class="bg-orange-500 text-white font-bold px-2 py-1">
Issue Now

View File

@ -12,7 +12,7 @@
will be set as the path to ftp account.</p>
</div>
<div>
<div class="py-4">
<div class="flex items-center py-4">
<p class="text-xl font-bold">Create FTP Account</p>
<img ng-hide="ftpLoading" src="{% static 'images/loading.gif' %}">
</div>

View File

@ -12,7 +12,7 @@
password.</p>
</div>
<div>
<div class="py-4">
<div class="flex items-center py-4">
<p class="text-xl font-bold">Change Email Password</p>
<img ng-hide="emailLoading"
src="{% static 'images/loading.gif' %}">

View File

@ -13,10 +13,12 @@
class="bg-blue-400 px-2 py-1 text-white font-semibold ml-3"
title=""><span>{% trans "DKIM Docs" %}</span></a>
</div>
<p class="text-xs text-gray-600 py-2 font-semibold">This page can be used to generate and view DKIM keys for
Domains</p>
</div>
{% if openDKIMInstalled == 0 %}
<div>
<div class="py-4">
<div class="flex items-center py-4">
<p class="text-xl font-bold">DKIM Manager</p>
<img ng-hide="manageDKIMLoading" src="{% static 'images/loading.gif' %}">
</div>
@ -63,9 +65,10 @@
{% else %}
<div class="panel-body">
<h3 class="content-box-header">
{% trans "DKIM Manager" %} <img ng-hide="manageDKIMLoading" src="{% static 'images/loading.gif' %}">
</h3>
<div class="flex items-center py-4">
<p class="text-xl font-bold">DKIM Manager</p>
<img ng-hide="manageDKIMLoading" src="{% static 'images/loading.gif' %}">
</div>
<div class="example-box-wrapper">
<form action="/" class="form-horizontal bordered-row panel-body">

View File

@ -99,9 +99,75 @@
<td ng-bind="record.DiskUsage" class="px-6 py-4">
</td>
<td class="flex gap-2 px-6 py-4">
<button ng-click="changePasswordInitial(record.email)"
class="bg-orange-500 text-white font-semibold px-2 py-1">Change Password
</button>
<a onclick="return false;"
ng-click="changePasswordInitial(record.email)"
class="bg-orange-500 text-white font-semibold px-2 py-1"
href="#" data-modal-target="edit"
data-modal-toggle="edit">{% trans "Change Password" %}
</a>
<div id="edit" tabindex="-1"
class="hidden overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-50 justify-center items-center w-full md:inset-0 h-[calc(100%-1rem)] max-h-full">
<div class="relative p-4 w-full max-w-2xl max-h-full">
<div class="relative bg-white shadow dark:bg-gray-700">
<div class="flex items-center bg-blue-400 px-4 py-4">
<p class="font-bold">Change Password</p>
<img ng-hide="cyberpanelLoading"
src="{% static 'images/loading.gif' %}">
<button type="button" data-modal-toggle="edit"
class="absolute top-2 end-1 text-black bg-transparent hover:text-black rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center"
data-modal-hide="edit">
<svg class="w-3 h-3" aria-hidden="true"
xmlns="http://www.w3.org/2000/svg" fill="none"
viewBox="0 0 14 14">
<path stroke="currentColor" stroke-linecap="round"
stroke-linejoin="round" stroke-width="2"
d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6"/>
</svg>
<span class="sr-only">Close modal</span>
</button>
</div>
<div class="p-4 md:p-5">
<form name="containerSettingsForm">
<div ng-hide="installationDetailsForm"
class="flex mt-4 py-2 px-6">
<div>
<p class="font-semibold w-60">Email</p>
</div>
<div>
<input name="name" type="text"
class="w-80 bg-gray-100 rounded px-2 py-1"
ng-model="email" readonly>
</div>
</div>
<div ng-hide="installationDetailsForm"
class="flex py-2 px-6">
<div>
<p class="font-semibold w-60">Password</p>
</div>
<div>
<div class="col-sm-6">
<input type="password"
class="w-80 bg-gray-100 rounded px-2 py-1"
ng-model="$parent.password">
</div>
</div>
</div>
</form>
<div class="flex justify-end mt-3">
<button ng-click="changePassword()"
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
Save
</button>
<button data-modal-toggle="edit"
data-modal-hide="edit"
class="ml-2 bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 rounded">
Close
</button>
</div>
</div>
</div>
</div>
</div>
<button ng-click="deleteEmailAccountFinal(record.email)"
class="bg-red-500 text-white font-semibold px-2 py-1">Delete
</button>
@ -233,4 +299,73 @@
</div>
{% endif %}
</div>
<a onclick="return false;"
ng-click="changePasswordInitial(record.email)"
class="bg-orange-500 text-white font-semibold px-2 py-1"
href="#" data-modal-target="edit"
data-modal-toggle="edit">{% trans "Change Password" %}
</a>
<div id="edit" tabindex="-1"
class="hidden overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-50 justify-center items-center w-full md:inset-0 h-[calc(100%-1rem)] max-h-full">
<div class="relative p-4 w-full max-w-2xl max-h-full">
<div class="relative bg-white shadow dark:bg-gray-700">
<div class="flex items-center bg-blue-400 px-4 py-4">
<p class="font-bold">Change Password</p>
<img ng-hide="cyberpanelLoading"
src="{% static 'images/loading.gif' %}">
<button type="button" data-modal-toggle="edit"
class="absolute top-2 end-1 text-black bg-transparent hover:text-black rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center"
data-modal-hide="edit">
<svg class="w-3 h-3" aria-hidden="true"
xmlns="http://www.w3.org/2000/svg" fill="none"
viewBox="0 0 14 14">
<path stroke="currentColor" stroke-linecap="round"
stroke-linejoin="round" stroke-width="2"
d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6"/>
</svg>
<span class="sr-only">Close modal</span>
</button>
</div>
<div class="p-4 md:p-5">
<form name="containerSettingsForm">
<div ng-hide="installationDetailsForm"
class="flex mt-4 py-2 px-6">
<div>
<p class="font-semibold w-60">Email</p>
</div>
<div>
<input name="name" type="text"
class="w-80 bg-gray-100 rounded px-2 py-1"
ng-model="email" readonly>
</div>
</div>
<div ng-hide="installationDetailsForm"
class="flex py-2 px-6">
<div>
<p class="font-semibold w-60">Password</p>
</div>
<div>
<div class="col-sm-6">
<input type="password"
class="w-80 bg-gray-100 rounded px-2 py-1"
ng-model="$parent.password">
</div>
</div>
</div>
</form>
<div class="flex justify-end mt-3">
<button ng-click="changePassword()"
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
Save
</button>
<button data-modal-toggle="edit"
data-modal-hide="edit"
class="ml-2 bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 rounded">
Close
</button>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -7389,6 +7389,371 @@ function DeleteBackupfileConfigNow(url) {
window.location.href = url;
}
newapp.controller('sshAccessV2', function ($scope, $http, $timeout) {
$scope.wpInstallLoading = true;
$scope.setupSSHAccess = function () {
$scope.wpInstallLoading = false;
url = "/websites/saveSSHAccessChanges";
var data = {
domain: $("#domainName").text(),
externalApp: $("#externalApp").text(),
password: $scope.password
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
function ListInitialDatas(response) {
$scope.wpInstallLoading = true;
if (response.data.status === 1) {
new PNotify({
title: 'Success',
text: 'Changes Successfully Applied.',
type: 'success'
});
} else {
new PNotify({
title: 'Error!',
text: response.data.error_message,
type: 'error'
});
}
}
function cantLoadInitialDatas(response) {
new PNotify({
title: 'Error!',
text: 'Could not connect to server, please refresh this page.',
type: 'error'
});
}
};
/// SSH Key at user level
$scope.keyBox = true;
$scope.saveKeyBtn = true;
$scope.addKey = function () {
$scope.showKeyBox = true;
$scope.keyBox = false;
$scope.saveKeyBtn = false;
};
function populateCurrentKeys() {
url = "/websites/getSSHConfigs";
var data = {
domain: $("#domainName").text(),
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
function ListInitialDatas(response) {
if (response.data.status === 1) {
$scope.records = JSON.parse(response.data.data);
}
}
function cantLoadInitialDatas(response) {
$scope.couldNotConnect = false;
}
}
populateCurrentKeys();
$scope.deleteKey = function (key) {
$scope.wpInstallLoading = false;
url = "/websites/deleteSSHKey";
var data = {
domain: $("#domainName").text(),
key: key,
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
function ListInitialDatas(response) {
$scope.wpInstallLoading = true;
if (response.data.delete_status === 1) {
new PNotify({
title: 'Success',
text: 'Key deleted successfully.',
type: 'success'
});
populateCurrentKeys();
} else {
new PNotify({
title: 'Error!',
text: response.data.error_message,
type: 'error'
});
}
}
function cantLoadInitialDatas(response) {
$scope.wpInstallLoading = true;
new PNotify({
title: 'Error!',
text: 'Could not connect to server, please refresh this page.',
type: 'error'
});
}
}
$scope.saveKey = function (key) {
$scope.wpInstallLoading = false;
url = "/websites/addSSHKey";
var data = {
domain: $("#domainName").text(),
key: $scope.keyData,
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
function ListInitialDatas(response) {
$scope.wpInstallLoading = true;
if (response.data.add_status === 1) {
new PNotify({
title: 'Success',
text: 'Key added successfully.',
type: 'success'
});
populateCurrentKeys();
} else {
new PNotify({
title: 'Error!',
text: response.data.error_message,
type: 'error'
});
}
}
function cantLoadInitialDatas(response) {
new PNotify({
title: 'Error!',
text: 'Could not connect to server, please refresh this page.',
type: 'error'
});
}
}
});
newapp.controller('cloneWebsiteV2', function ($scope, $http, $timeout, $window) {
$('form').submit(function (e) {
e.preventDefault();
});
$scope.cyberpanelLoading = true;
$scope.installationDetailsForm = false;
$scope.installationProgress = true;
$scope.goBackDisable = true;
$scope.cloneEnter = function ($event) {
var keyCode = $event.which || $event.keyCode;
if (keyCode === 13) {
$scope.cyberpanelLoading = false;
$scope.startCloning();
}
};
var statusFile;
$scope.startCloning = function () {
$scope.cyberpanelLoading = false;
$scope.installationDetailsForm = true;
$scope.installationProgress = false;
$scope.goBackDisable = true;
$scope.currentStatus = "Cloning started..";
url = "/websites/startCloning";
var data = {
masterDomain: $("#domainName").text(),
domainName: $scope.domain
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
function ListInitialDatas(response) {
if (response.data.status === 1) {
statusFile = response.data.tempStatusPath;
getCreationStatus();
} else {
$scope.cyberpanelLoading = true;
$scope.installationDetailsForm = true;
$scope.installationProgress = false;
$scope.goBackDisable = false;
$scope.currentStatus = response.data.error_message;
}
}
function cantLoadInitialDatas(response) {
$scope.cyberpanelLoading = true;
$scope.installationDetailsForm = true;
$scope.installationProgress = false;
$scope.goBackDisable = false;
}
};
$scope.goBack = function () {
$scope.cyberpanelLoading = true;
$scope.installationDetailsForm = false;
$scope.installationProgress = true;
$scope.goBackDisable = true;
$("#installProgress").css("width", "0%");
};
function getCreationStatus() {
url = "/websites/installWordpressStatus";
var data = {
statusFile: statusFile
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
function ListInitialDatas(response) {
if (response.data.abort === 1) {
if (response.data.installStatus === 1) {
$scope.cyberpanelLoading = true;
$scope.installationDetailsForm = true;
$scope.installationProgress = false;
$scope.goBackDisable = false;
$("#installProgress").css("width", "100%");
$scope.installPercentage = "100";
$scope.currentStatus = response.data.currentStatus;
$timeout.cancel();
} else {
$scope.cyberpanelLoading = true;
$scope.installationDetailsForm = true;
$scope.installationProgress = false;
$scope.goBackDisable = false;
$scope.currentStatus = response.data.error_message;
$("#installProgress").css("width", "0%");
$scope.installPercentage = "0";
$scope.goBackDisable = false;
}
} else {
$("#installProgress").css("width", response.data.installationProgress + "%");
$scope.installPercentage = response.data.installationProgress;
$scope.currentStatus = response.data.currentStatus;
$timeout(getCreationStatus, 1000);
}
}
function cantLoadInitialDatas(response) {
$scope.cyberpanelLoading = true;
$scope.installationDetailsForm = true;
$scope.installationProgress = false;
$scope.goBackDisable = false;
}
}
});

View File

@ -23,7 +23,7 @@
</div>
<div>
<div class="flex py-4">
<div class="flex items-center py-4">
<p class="text-xl font-bold">Plugin Buckets</p>
<img ng-hide="cyberpanelLoading"
src="{% static 'images/loading.gif' %}">

View File

@ -601,7 +601,7 @@
<div class="mt-4 px-4">
<ul class="flex gap-10">
<a href="/websites/V2/{{ wpsite.owner.domain }}">
<a href="/v2Websites/{{ wpsite.owner.domain }}">
<li class="flex items-center">
<div>
<svg width="20" height="20" viewBox="0 0 40 40" fill="none"

View File

@ -6,21 +6,20 @@
{% load static %}
<div ng-controller="manageGITV2" class="p-8">
<div>
<p class="text-4xl font-bold">Manage GIT - <a target="_blank"
href="https://go.cyberpanel.net/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></p>
<p class="text-xs text-gray-600 py-2 font-semibold">Manage and track folders via Git
for {{ domainName }}.</p>
<div class="flex items-center">
<p class="text-4xl font-bold">Manage GIT -</p>
<a target="_blank"
href="https://go.cyberpanel.net/manageGit"
class="bg-blue-200 px-2 font-bold mt-2 ml-3"
title=""><span>{% trans "Git Docs" %}</span></a>
</div>
<div>a
<div class="py-4">
<h3 class="title-hero">
{% trans "Manage and track folders via Git for " %} <span id="domain">{{ domainName }}</span>. <img
ng-hide="cyberpanelLoading" src="{% static 'images/loading.gif' %}">
</h3>
<p class="text-xs text-gray-600 py-2 font-semibold">Manage and track folders via Git
for {{ domainName }}.</p>
<div>
<div class="flex items-center py-4">
<p class="text-xl font-bold">Manage and track folders via Git for <span
id="domain">{{ domainName }}</span></p>
<img ng-hide="cyberpanelLoading" src="{% static 'images/loading.gif' %}">
</div>
<hr>
<div>
@ -38,18 +37,23 @@
</div>
</div>
<p ng-hide="gitTracking">{% trans "This folder does not have Git tracking, click below to initiate a repository and start tracking files." %}</p>
<button ng-hide="gitTracking" style="margin-left: 2%" type="button"
class="bg-orange-500 px-3 py-4 rounded-lg text-xl font-semibold text-white"
ng-click="initRepo()">
Init Repo
</button>
<button data-toggle="modal" data-target="#attachExistingRepo" ng-disabled="home==0"
ng-hide="gitTracking" style="margin-left: 2%" type="button"
class="bg-orange-500 px-3 py-4 rounded-lg text-xl font-semibold text-white">
Attach Existing Repo <img
ng-hide="cyberpanelLoading" src="{% static 'images/loading.gif' %}">
</button>
<div class="flex gap-2">
<div>
<button ng-hide="gitTracking" type="button"
class="bg-orange-500 px-3 py-2 mt-2 rounded-lg text-xl font-semibold text-white"
ng-click="initRepo()">
Init Repo
</button>
</div>
<div class="flex items-center">
<button data-toggle="modal" data-target="#attachExistingRepo" ng-disabled="home==0"
ng-hide="gitTracking" type="button"
class="bg-orange-500 px-3 py-2 mt-2 rounded-lg text-xl font-semibold text-white">
Attach Existing Repo
</button>
<img ng-hide="cyberpanelLoading" src="{% static 'images/loading.gif' %}">
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,71 @@
{% extends "baseTemplate/newBase.html" %}
{% load i18n %}
{% block titleNew %}{% trans "Home - CyberPanel" %}{% endblock %}
{% block newContent %}
{% load static %}
<div ng-controller="cloneWebsiteV2" class="p-8">
<div class="flex items-center">
<p class="text-4xl font-bold">Set up Staging Enviroment</p>
</div>
<p class="text-xs text-gray-600 py-2 font-semibold">Set up staging enviroment for
{{ domainName }}. Any domain that you will choose here will be created as child-domain for this master
site. </p>
<div>
<div class="flex items-center py-4">
<p class="text-xl font-bold">Set up staging enviroment for <span id="domainName">{{ domainName }}</span>
</p>
<img ng-hide="cyberpanelLoading" src="{% static 'images/loading.gif' %}"> -
</div>
<hr>
<form name="websiteCreationForm" action="/" id="createPackages">
<p ng-hide="installationDetailsForm" class="text-xs text-gray-600 py-2 font-semibold">Domain that you
will enter below will be created as child-domain to
<spam id="domainName">{{ domainName }}</spam>
.
</p>
<hr>
<div>
<div ng-hide="installationDetailsForm" class="flex mt-4 py-2 px-6">
<div>
<p class="font-semibold w-48">Domain</p>
</div>
<div>
<input ng-keypress="cloneEnter($event)" type="text"
class="w-80 bg-gray-100 rounded px-2 py-1" ng-model="domain"
required>
</div>
</div>
</div>
<div ng-hide="installationDetailsForm" class="flex justify-center mt-2">
<button type="button"
class="bg-orange-500 px-3 py-2 mt-2 rounded-lg text-xl font-semibold text-white"
ng-click="startCloning()">
Start Cloning
</button>
</div>
<div ng-hide="installationProgress">
<div class="col-sm-7">
<div class="flex justify-center font-bold text-xl">
<h2>{$ currentStatus $}</h2>
</div>
<div class="w-full bg-gray-100 rounded-full mt-3">
<div id="installProgress"
class="bg-green-600 text-xs font-medium text-white text-center p-2 leading-none rounded-full"
style="width:0%">
</div>
</div>
</div>
</div>
<div ng-hide="installationProgress" class="flex justify-center mt-3">
<div class="col-sm-4">
<button type="button" ng-disabled="goBackDisable" ng-click="goBack()"
class="bg-blue-500 px-3 py-2 rounded-lg text-xl font-semibold text-white">{% trans "Go Back" %}</button>
</div>
</div>
</form>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,103 @@
{% extends "baseTemplate/newBase.html" %}
{% load i18n %}
{% block titleNew %}{% trans "Home - CyberPanel" %}{% endblock %}
{% block newContent %}
{% load static %}
<div ng-controller="sshAccessV2" class="p-8">
<div class="flex items-center">
<p class="text-4xl font-bold">SSH Access -</p>
</div>
<p class="text-xs text-gray-600 py-2 font-semibold">Set up SSH access and enable/disable CageFS
for {{ domainName }} CageFS require CloudLinux OS. </p>
<div>
<div class="flex items-center py-4">
<p class="text-xl font-bold">Set up SSH access for <span
id="domain">{{ domainName }}</span></p>
<img ng-hide="wpInstallLoading"
src="{% static 'images/loading.gif' %}"> -
<a target="_blank"
href="https://go.cyberpanel.net/SFTPAccess"
class="bg-blue-200 px-2 font-bold mt-2 ml-3"
title=""><span>SFTP Docs</span></a>
</div>
<hr>
<form name="websiteCreationForm" action="/" id="createPackages">
<p ng-hide="installationDetailsForm" class="text-xs text-gray-600 py-2 font-semibold">SSH user for
<spam id="domainName">{{ domainName }}</spam>
is <span id="externalApp">{{ externalApp }}</span>
</p>
<hr>
<div>
<div class="flex mt-4 py-2 px-6">
<div>
<p class="font-semibold w-48">Password</p>
</div>
<div>
<input type="password" class="w-80 bg-gray-100 rounded px-2 py-1" ng-model="password"
required>
</div>
</div>
</div>
<div class="flex justify-center mt-2">
<button ng-hide="installationDetailsForm" type="button"
class="bg-orange-500 px-3 py-2 mt-2 rounded-lg text-xl font-semibold text-white"
ng-click="setupSSHAccess()">
Save Changes
</button>
</div>
<div class="relative py-8 overflow-x-auto">
<table class="w-full text-sm text-left rtl:text-right">
<thead>
<tr>
<th scope="col" class="px-6 py-3 text-xl">
User Name
</th>
<th scope="col" class="px-6 py-3 text-xl">
Key
</th>
<th scope="col" class="px-6 py-3 text-xl">
Delete
</th>
</tr>
</thead>
<tbody ng-repeat="record in records track by $index"
class="border shadow-lg py-3 px-6 rounded-b-lg">
<tr>
<td ng-bind="record.userName" class="px-6 py-4">
root
</td>
<td ng-bind="record.key" class="px-6 py-4">
</td>
<td ng-click="deleteKey(record.key)" class="px-6 py-4">
<div class="text-red-500 font-bold">X</div>
</td>
</tr>
</tbody>
</table>
</div>
<div ng-hide="keyBox">
<div>
<textarea placeholder="Paste your public key here..." ng-model="keyData"
rows="6" class="w-full">{{ logs }}</textarea>
</div>
</div>
<div class="flex justify-center" ng-hide="showKeyBox">
<div>
<button type="button" ng-click="addKey()"
class="bg-orange-500 px-3 py-2 mt-2 rounded-lg text-xl font-semibold text-white">{% trans "Add Key" %}</button>
</div>
</div>
<div class="flex justify-center" ng-hide="saveKeyBtn">
<div>
<button type="button" ng-click="saveKey()"
class="bg-orange-500 px-3 py-2 mt-2 rounded-lg text-xl font-semibold text-white">{% trans "Save" %}</button>
</div>
</div>
</form>
</div>
</div>
{% endblock %}

View File

@ -27,19 +27,19 @@
</div>
<div class="flex lg:flex-row sm:flex-col gap-4">
<div class="sm:mt-6">
<a href="/websites/{{ domain }}/sshAccess"
<a href="/v2Websites/{{ domain }}/sshAccessV2"
class="bg-orange-500 px-3 py-3 rounded-lg text-xl font-semibold text-white">Set Up
SSH/SFTP
Access
</a>
</div>
<div class="sm:mt-6">
<a href="/websites/{{ domain }}/setupStaging"
<a href="/v2Websites/{{ domain }}/setupStagingV2"
class="bg-orange-500 px-3 py-3 rounded-lg text-xl font-semibold text-white">Clone/Staging
</a>
</div>
<div class="sm:mt-6">
<a href="/websites/{{ domain }}/manageGIT"
<a href="/v2Websites/{{ domain }}/manageGIT"
class="bg-orange-500 px-3 py-3 rounded-lg text-xl font-semibold text-white">Manage Git
</a>
</div>
@ -960,7 +960,7 @@
</div>
</div>
</a>
<li class="px-3 py-3">
<a id="manageListsV2" target="_self" title="{% trans 'Manage Lists' %}" class="px-3 py-3">
<div class="flex items-center">
<div>
<svg width="20" height="20" viewBox="0 0 40 40" fill="none"
@ -977,8 +977,8 @@
<p class="px-2 font-bold" style="font-size: 70%;">Manage Lists</p>
</div>
</div>
</li>
<li class="px-3 py-3">
</a>
<a id="manageSMTPHostsV2" target="_self" title="{% trans 'SMTP Hosts' %}" class="px-3 py-3">
<div class="flex items-center">
<div>
<svg width="20" height="20" viewBox="0 0 40 40" fill="none"
@ -999,8 +999,8 @@
<p class="px-2 font-bold" style="font-size: 70%;">SMTP Hosts</p>
</div>
</div>
</li>
<li class="px-3 py-3">
</a>
<a id="composeEmailsV2" target="_self" title="{% trans 'Compose Message' %}" class="px-3 py-3">
<div class="flex items-center">
<div>
@ -1020,8 +1020,8 @@
<p class="px-2 font-bold" style="font-size: 70%;">Compose</p>
</div>
</div>
</li>
<li class="px-3 py-3">
</a>
<a id="sendEmailsPageV2" target="_self" title="{% trans 'Send Emails' %}" class="px-3 py-3">
<div class="flex items-center">
<div>
<svg width="20" height="20" viewBox="0 0 40 40" fill="none"
@ -1042,7 +1042,7 @@
<p class="px-2 font-bold" style="font-size: 70%;">Send Emails</p>
</div>
</div>
</li>
</a>
</ul>
</div>
</div>

View File

@ -1794,6 +1794,15 @@ def sshAccess(request, domain):
return redirect(loadLoginPage)
def sshAccessV2(request, domain):
try:
userID = request.session['userID']
wm = WebsiteManager(domain)
return wm.sshAccessV2(request, userID)
except KeyError:
return redirect(loadLoginPage)
def saveSSHAccessChanges(request):
try:
userID = request.session['userID']
@ -1812,6 +1821,15 @@ def setupStaging(request, domain):
return redirect(loadLoginPage)
def setupStagingV2(request, domain):
try:
userID = request.session['userID']
wm = WebsiteManager(domain)
return wm.setupStagingV2(request, userID)
except KeyError:
return redirect(loadLoginPage)
def startCloning(request):
try:
userID = request.session['userID']

View File

@ -5357,6 +5357,22 @@ StrictHostKeyChecking no
{'domainName': self.domain, 'externalApp': externalApp})
return proc.render()
def sshAccessV2(self, request=None, userID=None, data=None):
currentACL = ACLManager.loadedACL(userID)
admin = Administrator.objects.get(pk=userID)
if ACLManager.checkOwnership(self.domain, admin, currentACL) == 1:
pass
else:
return ACLManager.loadError()
website = Websites.objects.get(domain=self.domain)
externalApp = website.externalApp
proc = httpProc(request, 'websiteFunctions/sshAccessV2.html',
{'domainName': self.domain, 'externalApp': externalApp})
return proc.render()
def saveSSHAccessChanges(self, userID=None, data=None):
try:
@ -5411,6 +5427,22 @@ StrictHostKeyChecking no
{'domainName': self.domain, 'externalApp': externalApp})
return proc.render()
def setupStagingV2(self, request=None, userID=None, data=None):
currentACL = ACLManager.loadedACL(userID)
admin = Administrator.objects.get(pk=userID)
if ACLManager.checkOwnership(self.domain, admin, currentACL) == 1:
pass
else:
return ACLManager.loadError()
website = Websites.objects.get(domain=self.domain)
externalApp = website.externalApp
proc = httpProc(request, 'websiteFunctions/setupStagingV2.html',
{'domainName': self.domain, 'externalApp': externalApp})
return proc.render()
def startCloning(self, userID=None, data=None):
try:

View File

@ -179,6 +179,8 @@ urlpatterns = [
### Manage GIT
url(r'^(?P<domain>(.*))/manageGIT$', views.manageGITV2, name='manageGIT'),
url(r'^(?P<domain>(.*))/sshAccessV2$', views.sshAccessV2, name='sshAccessV2'),
url(r'^(?P<domain>(.*))/setupStagingV2$', views.setupStagingV2, name='setupStagingV2'),
url(r'^(?P<domain>(.*))/webhook$', views.webhook, name='webhook'),
url(r'^fetchFolderDetails$', views.fetchFolderDetails, name='fetchFolderDetails'),
url(r'^initRepo$', views.initRepo, name='initRepo'),