File: //usr/local/CyberCP/emailPremium/templates/emailPremium/SpamAssassin.html
{% extends "baseTemplate/index.html" %}
{% load i18n %}
{% block title %}{% trans "SpamAssassin - CyberPanel" %}{% endblock %}
{% block header_scripts %}
<style>
/* SpamAssassin Specific Styles */
.spamassassin-wrapper {
background: transparent;
padding: 20px;
}
.spamassassin-container {
max-width: 1200px;
margin: 0 auto;
}
/* Page Header */
.page-header {
background: var(--bg-primary, white);
border-radius: 12px;
padding: 25px;
margin-bottom: 25px;
box-shadow: 0 2px 8px rgba(0,0,0,0.08);
border: 1px solid var(--border-secondary, #e8e9ff);
}
.page-header h1 {
font-size: 28px;
font-weight: 700;
color: var(--text-primary, #2f3640);
margin: 0 0 10px 0;
display: flex;
align-items: center;
gap: 15px;
}
.page-header .icon {
width: 48px;
height: 48px;
background: #5856d6;
border-radius: 12px;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 24px;
box-shadow: 0 4px 12px rgba(88,86,214,0.3);
}
.page-header p {
font-size: 15px;
color: var(--text-secondary, #64748b);
margin: 0;
}
/* Documentation Link */
.docs-link {
background: var(--bg-secondary, #f8f9ff);
color: #5856d6;
border: 1px solid var(--border-secondary, #e8e9ff);
padding: 8px 20px;
border-radius: 8px;
font-weight: 600;
font-size: 14px;
cursor: pointer;
transition: all 0.3s ease;
display: inline-flex;
align-items: center;
gap: 8px;
text-decoration: none;
margin-left: 15px;
}
.docs-link:hover {
background: #5856d6;
color: white;
border-color: #5856d6;
transform: translateY(-1px);
text-decoration: none;
}
/* Content Section */
.content-section {
background: var(--bg-primary, white);
border-radius: 12px;
padding: 25px;
margin-bottom: 25px;
box-shadow: 0 2px 8px rgba(0,0,0,0.08);
border: 1px solid var(--border-secondary, #e8e9ff);
}
.section-title {
font-size: 18px;
font-weight: 700;
color: var(--text-primary, #2f3640);
margin-bottom: 20px;
display: flex;
align-items: center;
gap: 10px;
}
.section-title::before {
content: '';
width: 4px;
height: 24px;
background: #5856d6;
border-radius: 2px;
}
/* Installation Section */
.install-section {
text-align: center;
padding: 40px 20px;
}
.install-icon {
width: 80px;
height: 80px;
background: var(--bg-secondary, #f8f9ff);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto 20px;
font-size: 36px;
color: #5856d6;
}
.install-title {
font-size: 24px;
font-weight: 700;
color: var(--text-primary, #2f3640);
margin-bottom: 10px;
}
.install-description {
font-size: 16px;
color: var(--text-secondary, #64748b);
margin-bottom: 25px;
}
.install-btn {
background: #5856d6;
color: white;
border: none;
padding: 12px 32px;
border-radius: 10px;
font-weight: 600;
font-size: 16px;
cursor: pointer;
transition: all 0.3s ease;
display: inline-flex;
align-items: center;
gap: 10px;
box-shadow: 0 4px 12px rgba(88,86,214,0.3);
}
.install-btn:hover {
background: #4644c0;
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(88,86,214,0.4);
}
/* Form Styles */
.form-group {
margin-bottom: 20px;
}
.form-label {
font-size: 14px;
font-weight: 600;
color: var(--text-primary, #2f3640);
margin-bottom: 8px;
display: block;
text-transform: none;
}
.form-control {
width: 100%;
padding: 10px 15px;
border: 1px solid var(--border-secondary, #e8e9ff);
border-radius: 8px;
font-size: 14px;
color: var(--text-primary, #2f3640);
background: var(--bg-primary, white);
transition: all 0.3s ease;
}
.form-control:focus {
outline: none;
border-color: #5856d6;
box-shadow: 0 0 0 3px rgba(88,86,214,0.1);
}
/* Toggle Switch */
.toggle-switch {
position: relative;
display: inline-block;
width: 50px;
height: 26px;
}
.toggle-switch input {
position: absolute;
opacity: 0;
width: 100%;
height: 100%;
margin: 0;
cursor: pointer;
z-index: 2;
}
.toggle-slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: var(--border-secondary, #e8e9ff);
transition: .3s;
border-radius: 26px;
pointer-events: none;
}
.toggle-slider:before {
position: absolute;
content: "";
height: 20px;
width: 20px;
left: 3px;
bottom: 3px;
background-color: var(--bg-primary, white);
transition: .3s;
border-radius: 50%;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
input:checked + .toggle-slider {
background-color: #5856d6;
}
input:checked + .toggle-slider:before {
transform: translateX(24px);
}
/* Save Button */
.save-btn {
background: #5856d6;
color: white;
border: none;
padding: 12px 32px;
border-radius: 8px;
font-weight: 600;
font-size: 15px;
cursor: pointer;
transition: all 0.3s ease;
display: inline-flex;
align-items: center;
gap: 10px;
box-shadow: 0 4px 12px rgba(88,86,214,0.3);
}
.save-btn:hover {
background: #4644c0;
transform: translateY(-1px);
box-shadow: 0 6px 20px rgba(88,86,214,0.4);
}
/* Installation Log */
.install-log {
background: var(--bg-secondary, #f8f9ff);
border: 1px solid var(--border-secondary, #e8e9ff);
border-radius: 8px;
padding: 15px;
margin-top: 20px;
}
.install-log-header {
display: flex;
align-items: center;
gap: 10px;
margin-bottom: 10px;
}
.install-log-title {
font-size: 16px;
font-weight: 600;
color: var(--text-primary, #2f3640);
}
.log-textarea {
width: 100%;
padding: 12px 15px;
border: 1px solid var(--border-secondary, #e8e9ff);
border-radius: 8px;
font-size: 13px;
color: var(--text-primary, #2f3640);
background: var(--bg-primary, white);
resize: vertical;
font-family: 'Monaco', 'Consolas', monospace;
line-height: 1.5;
}
/* Alert Messages */
.alert {
padding: 15px 20px;
border-radius: 8px;
margin-bottom: 20px;
display: flex;
align-items: center;
gap: 12px;
font-size: 14px;
}
.alert-icon {
font-size: 20px;
flex-shrink: 0;
}
.alert-success {
background: var(--alert-success-bg, #d1fae5);
color: var(--alert-success-text, #065f46);
border: 1px solid var(--alert-success-border, #a7f3d0);
}
.alert-success .alert-icon {
color: var(--alert-success-icon, #10b981);
}
.alert-danger {
background: var(--alert-danger-bg, #fee2e2);
color: var(--alert-danger-text, #991b1b);
border: 1px solid var(--alert-danger-border, #fecaca);
}
.alert-danger .alert-icon {
color: var(--alert-danger-icon, #ef4444);
}
/* Loading Spinner */
.loading-spinner {
width: 24px;
height: 24px;
border: 3px solid var(--border-secondary, #e8e9ff);
border-top-color: #5856d6;
border-radius: 50%;
animation: spin 1s linear infinite;
display: inline-block;
margin-left: 10px;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* Help Text */
.help-text {
font-size: 13px;
color: var(--text-muted, #94a3b8);
margin-top: 5px;
}
/* Responsive */
@media (max-width: 768px) {
.spamassassin-wrapper {
padding: 15px;
}
.page-header h1 {
font-size: 24px;
flex-direction: column;
text-align: center;
}
.docs-link {
margin-left: 0;
margin-top: 10px;
}
.content-section {
padding: 20px;
}
.form-group {
margin-bottom: 25px;
}
}
</style>
{% endblock %}
{% block content %}
{% load static %}
{% get_current_language as LANGUAGE_CODE %}
<div class="spamassassin-wrapper">
<div class="spamassassin-container" ng-controller="SpamAssassin">
<!-- Page Header -->
<div class="page-header">
<h1>
<div class="icon">
<i class="fas fa-shield-alt"></i>
</div>
{% trans "SpamAssassin" %}
<a href="http://go.cyberpanel.net/SpamAssassin" target="_blank" class="docs-link">
<i class="fas fa-book"></i>
{% trans "Documentation" %}
</a>
</h1>
<p>{% trans "Configure SpamAssassin settings to protect your email from spam" %}</p>
</div>
{% if checkIfSpamAssassinInstalled == 0 %}
<!-- Installation Section -->
<div class="content-section">
<div class="install-section">
<div class="install-icon">
<i class="fas fa-download"></i>
</div>
<h2 class="install-title">{% trans "SpamAssassin is not installed" %}</h2>
<p class="install-description">{% trans "Install SpamAssassin to protect your email server from spam messages" %}</p>
<button ng-click="installSpamAssassin()" class="install-btn">
<i class="fas fa-download"></i>
{% trans "Install Now" %}
</button>
</div>
<!-- Installation Notifications -->
<div ng-hide="SpamAssassinNotifyBox">
<div ng-hide="failedToStartInallation" class="alert alert-danger">
<i class="fas fa-exclamation-circle alert-icon"></i>
<span>{% trans "Failed to start installation. Error message:" %} {$ errorMessage $}</span>
</div>
<div ng-hide="couldNotConnect" class="alert alert-danger">
<i class="fas fa-wifi alert-icon"></i>
<span>{% trans "Could not connect. Please refresh this page." %}</span>
</div>
<div ng-hide="installationFailed" class="alert alert-danger">
<i class="fas fa-times-circle alert-icon"></i>
<span>{% trans "Installation failed." %} {$ errorMessage $}</span>
</div>
<div ng-hide="SpamAssassinSuccessfullyInstalled" class="alert alert-success">
<i class="fas fa-check-circle alert-icon"></i>
<span>{% trans "SpamAssassin successfully installed, refreshing page in 3 seconds..." %}</span>
</div>
</div>
<!-- Installation Log -->
<div ng-hide="SpamAssassinInstallBox" class="install-log">
<div class="install-log-header">
<i class="fas fa-terminal"></i>
<h3 class="install-log-title">{% trans "Installation Progress" %}</h3>
<span ng-hide="SpamAssassinLoading" class="loading-spinner"></span>
</div>
<textarea ng-model="requestData" rows="15" class="log-textarea" readonly>{{ requestData }}</textarea>
</div>
</div>
{% else %}
<!-- Configuration Section -->
<div class="content-section">
<h2 class="section-title">
{% trans "SpamAssassin Configuration" %}
<span ng-hide="SpamAssassinLoading" class="loading-spinner"></span>
</h2>
<form>
<div class="form-group">
<label class="form-label">
{% trans "Report Safe" %}
<span class="help-text">{% trans "Encapsulate spam messages as attachments" %}</span>
</label>
<label class="toggle-switch">
<input type="checkbox" id="report_safe">
<span class="toggle-slider"></span>
</label>
</div>
<div class="form-group">
<label class="form-label" for="required_hits">
{% trans "Required Hits" %}
<span class="help-text">{% trans "Number of hits required before a mail is considered spam" %}</span>
</label>
<input type="text" class="form-control" id="required_hits" ng-model="required_hits" placeholder="5.0" required>
</div>
<div class="form-group">
<label class="form-label" for="rewrite_header">
{% trans "Rewrite Header" %}
<span class="help-text">{% trans "Text to prepend to the subject of spam messages" %}</span>
</label>
<input type="text" class="form-control" id="rewrite_header" ng-model="rewrite_header" placeholder="Subject [SPAM]" required>
</div>
<div class="form-group">
<label class="form-label" for="required_score">
{% trans "Required Score" %}
<span class="help-text">{% trans "Score threshold for marking messages as spam" %}</span>
</label>
<input type="text" class="form-control" id="required_score" ng-model="required_score" placeholder="5.0" required>
</div>
<div style="margin-top: 30px;">
<button type="button" ng-click="saveSpamAssassinConfigurations()" class="save-btn">
<i class="fas fa-save"></i>
{% trans "Save Changes" %}
</button>
</div>
<!-- Save Notifications -->
<div style="margin-top: 20px;">
<div ng-hide="failedToSave" class="alert alert-danger">
<i class="fas fa-exclamation-circle alert-icon"></i>
<span>{% trans "Failed to save SpamAssassin configurations. Error message:" %} {$ errorMessage $}</span>
</div>
<div ng-hide="successfullySaved" class="alert alert-success">
<i class="fas fa-check-circle alert-icon"></i>
<span>{% trans "SpamAssassin configurations successfully saved." %}</span>
</div>
<div ng-hide="couldNotConnect" class="alert alert-danger">
<i class="fas fa-wifi alert-icon"></i>
<span>{% trans "Could not connect. Please refresh this page." %}</span>
</div>
</div>
</form>
</div>
{% endif %}
</div>
</div>
{% endblock %}