Compare commits

...

56 Commits

Author SHA1 Message Date
58c3f2348a * Mon Dec 30 2024 Jean-Philippe Pialasse <jpp@koozali.org> 11.0.0-33.sme
- host locally flag-icon.min.css 3.5.0 [SME: 12845]
- remove onclick to comply with strict CSP [SME: 12846]
- add CSP rules with specific hash [SME: 12840]
2024-12-31 01:25:04 -05:00
b58f82a332 Fix up user and localnetwork panels and stop menu moving betweek proxy and reboot 2024-12-18 12:08:00 +00:00
8db1279a3e * Tue Dec 17 2024 Brian Read <brianr@koozali.org> 11.0.0-31.sme
- Edit html to avoid w3c html validation warnings [SME: 6278]
2024-12-17 06:35:33 +00:00
1d3d59b5c1 Fix up action commands for user panel 2024-12-16 19:55:15 +00:00
ff9a84dd29 Fix up action commands for pseudonyms and quota 2024-12-16 16:15:03 +00:00
34e7331845 Fix up action commands for port forwarding and printers 2024-12-16 13:55:52 +00:00
dfda47882d Fix up action commands for Ibays and correct groups link 2024-12-16 13:26:19 +00:00
55269fd685 Fix up action commands for Groups and Host panels 2024-12-15 17:17:32 +00:00
1b1b99955b Fix yp html warnings from w3c - mainly empty paragraphs, but also domain lists recast buttons 2024-12-15 10:15:38 +00:00
c6eb08a727 More Fix up html to conform to W3c standards - avoid duplicate id in nav menu 2024-12-14 14:06:56 +00:00
8e70adc797 A bit more header html fixing 2024-12-13 17:52:32 +00:00
2424684d35 Fix up html warned from w3c validator in header and footed 2024-12-13 16:42:42 +00:00
78bb7743c1 Add in letsencrypt and add requires for certificates and lib 2024-12-13 11:52:45 +00:00
87f6a46502 Add in letsencrypt action routines for SM2 panel 2024-12-01 15:36:46 +00:00
a08767919c Add in getmyip script 2024-11-27 16:01:56 +00:00
2b83be6d70 Fix 1267 in remoteaccess panel 2024-11-26 16:38:31 +00:00
6c1b6ed1f4 Add *.bak to .gitignore 2024-11-12 19:20:21 +00:00
3fa8ab5eda Update README with specific Bugzilla links 2024-10-27 14:23:06 +00:00
55465e3081 Update readme bugzilla link to show all outstanding bugs 2024-10-27 12:12:21 +00:00
e5b9a012d9 * Fri Oct 18 2024 Brian Read <brianr@koozali.org> 11.0.0-28.sme
- Add in emailsettings for port 25,465 and 587  [SME: 12750]
- Comment out change to localhost for roundcube in _user_list email icon setting [SME: 12751]
2024-10-18 11:46:27 +01:00
fbdf3170ec Add in _user_list.html.ep change 2024-10-06 09:48:42 +01:00
87d1d072c0 * Fri Oct 04 2024 Brian Read <brianr@koozali.org> 11.0.0-26.sme
- Add in email link to roundcube from user accounts [SME: 12751]
2024-10-04 12:34:34 +01:00
d49db26f26 Add in email link to roundcube from user accounts 2024-10-04 12:14:56 +01:00
c4f9d67abc First shot at Email icon in action col for user accounts 2024-10-02 16:42:58 +01:00
fe62bd3e39 Add curosr change when save or submit pressed 2024-10-02 14:13:47 +01:00
df6d21dbc9 Up release to accomodate messed up build 2024-10-02 09:56:24 +01:00
9c9592f861 Add release number to footer for SM2 2024-10-02 09:12:38 +01:00
4d2097d2da * Tue Sep 24 2024 Jean-Philippe Pialasse <jpp@koozali.org> 11.0.0-22.sme
- fix typos, and tidy tabs [SME: 12744]
2024-09-24 22:06:09 -04:00
44a9ecc0e1 Remove both option for webmail, add in DB re-open in Emailsetting and Portforwarding panels 2024-09-24 17:37:52 +01:00
785ebcfaaf * Mon Sep 23 2024 Jean-Philippe Pialasse <jpp@koozali.org> 11.0.0-20.sme
- webmail switch panel to use roundcube [SME: 12742]
- prevent browser from caching [SME: 12695]
2024-09-23 10:07:08 -04:00
127ea74a8b Add in WithoutCache plugin 2024-09-05 11:57:23 +01:00
b9f6392c1d Update flag to use emojii and fix singleton locale 2024-08-25 11:34:57 +01:00
659f060eb6 Left align submit in Software Install subservient panels 2024-08-22 15:41:04 +01:00
1087a8a5a2 Software Installer panel - move dnf monitoring to /var/cache/dnf.status 2024-08-22 12:17:32 +01:00
6a5a756438 uc DNF to lc dnf in Yum.pm 2024-08-21 16:06:16 +01:00
91ca26de27 Migrate panel for software installer from yum to dnf 2024-08-21 12:39:46 +01:00
8b93232bbe make small changes to the readme 2024-08-16 15:42:40 +02:00
ed1c3e13b1 * Sun Jul 28 2024 Brian Read <brianr@koozali.org> 11.0.0-14.sme
- fix [SME: ]
2024-07-28 17:15:10 +01:00
095a0a1499 * Sun Jul 28 2024 Brian Read <brianr@koozali.org> 11.0.0-13.sme
- Fix sysles.css template - overwrote it by mistake [SME: 12706]
- Also re-organised login and Legacy SM menus and help on top
2024-07-28 17:14:14 +01:00
d16ea6a847 Typo in styles.css template 2024-07-28 16:28:45 +01:00
e70cc67430 * Sun Jul 28 2024 Brian Read <brianr@koozali.org> 11.0.0-12.sme
- correct positio of flag-icon [SME: 12706]
2024-07-28 15:50:26 +01:00
b097acafab yet more adjustment to header button spacing 2024-07-28 15:46:08 +01:00
5d7655a709 and more adjustment to header 2024-07-28 14:19:54 +01:00
a58df95aa9 More position and format for flag-icon 2024-07-28 14:04:49 +01:00
251b454470 Get Flag icon in correct place 2024-07-28 12:13:03 +01:00
174d511899 * Sat Jul 27 2024 Brian Read <brianr@koozali.org> 11.0.0-11.sme
- Add in flag icon indication of locale [SME: 12706]
2024-07-27 22:33:07 +01:00
4be8a1411f Update js code for flag icon 2024-07-27 22:28:01 +01:00
ba431a8a7d Add in js code for flag icon 2024-07-27 22:07:10 +01:00
77a7849898 Add in locale icon in header 2024-07-27 20:03:14 +01:00
fb5b0942d6 * Fri Jul 26 2024 Brian Read <brianr@koozali.org> 11.0.0-10.sme
- fix navigation2.conf to more correctly translate menus [SME: 12714]
2024-07-27 11:22:39 +01:00
5edc830f9b Few more fixes to navigation2.conf 2024-07-27 10:48:00 +01:00
473cb57a47 More fix up for navigation2.conf 2024-07-26 16:31:20 +01:00
55b85496d4 Fix navigation2.conf to correctly re-create translated menus 2024-07-26 15:45:32 +01:00
2fd6f8b630 Update Readme.md 2024-05-26 17:33:03 +02:00
a428e91c92 * Thu May 09 2024 Brian Read <brianr@koozali.org> 11.0.0-9.sme
- Add mojo logo to footer [SME: 12679]
- Fix default for HeaderWeight to avoid noise in logs if no Nav header in file
- Align buttons consistently [SME: 12680]
2024-05-09 17:02:39 +01:00
03955eecea * Tue Apr 30 2024 Jean-Philippe Pialasse <jpp@koozali.org> 11.0.0-8.sme
- create dedicated log files and logrotate [SME: 12664]
2024-04-30 16:28:32 -04:00
72 changed files with 3709 additions and 789 deletions

1
.gitignore vendored
View File

@@ -2,3 +2,4 @@
*.log
*spec-20*
*.tar.xz
*.bak

View File

@@ -13,10 +13,70 @@ SMEServer Koozali developed git repo for smeserver-manager smeserver
<br />https://wiki.koozali.org/Server_Manager_2_Howto_incorporate_a_legacy_contrib
## Bugzilla
Show list of outstanding bugs: [here](https://bugs.koozali.org/buglist.cgi?component=smeserver-manager&product=SME%20Server%2010.X&query_format=advanced&limit=0&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&bug_status=CONFIRMED)
Show list of outstanding bugs:
[All](https://bugs.koozali.org/buglist.cgi?action=wrap&bug_status=UNCONFIRMED&bug_status=CONFIRMED&bug_status=NEEDINFO&bug_status=IN_PROGRESS&bug_status=RESOLVED&bug_status=VERIFIED&cf_package=smeserver-manager&classification=SME+Server&list_id=105756&order=changeddate+DESC%2Ccomponent%2Cpriority%2Cbug_severity&query_format=advanced)
[Confirmed](https://bugs.koozali.org/buglist.cgi?action=wrap&bug_status=CONFIRMED&cf_package=smeserver-manager&classification=SME+Server&order=changeddate+DESC%2Ccomponent%2Cpriority%2Cbug_severity&query_format=advanced)
[Unconfirmed](https://bugs.koozali.org/buglist.cgi?action=wrap&bug_status=UNCONFIRMED&cf_package=smeserver-manager&classification=SME+Server&order=changeddate+DESC%2Ccomponent%2Cpriority%2Cbug_severity&query_format=advanced)
[Need info](https://bugs.koozali.org/buglist.cgi?action=wrap&bug_status=NEEDINFO&cf_package=smeserver-manager&classification=SME+Server&order=changeddate+DESC%2Ccomponent%2Cpriority%2Cbug_severity&query_format=advanced)
[In progress](https://bugs.koozali.org/buglist.cgi?action=wrap&bug_status=IN_PROGRESS&cf_package=smeserver-manager&classification=SME+Server&order=changeddate+DESC%2Ccomponent%2Cpriority%2Cbug_severity&query_format=advanced)
[Resolved](https://bugs.koozali.org/buglist.cgi?action=wrap&bug_status=RESOLVED&cf_package=smeserver-manager&classification=SME+Server&order=changeddate+DESC%2Ccomponent%2Cpriority%2Cbug_severity&query_format=advanced)
[Verified](https://bugs.koozali.org/buglist.cgi?action=wrap&bug_status=VERIFIED&cf_package=smeserver-manager&classification=SME+Server&order=changeddate+DESC%2Ccomponent%2Cpriority%2Cbug_severity&query_format=advanced)
## Description
<br />*This description has been generated by an LLM AI system and cannot be relied on to be fully correct.*
*Once it has been checked, then this comment will be deleted*
<br />
The *smeserver-manager* is a web-based management interface for the SME Server (formerly known as e-smith server and gateway). SME Server is a Linux-based distribution designed for small to medium-sized enterprises, providing a wide range of network services and simplified server management.
It is based on the perl Mojolicious package. Mojolicious is a real-time web framework for Perl, which provides a range of functionalities that make it a powerful and flexible tool for web development.
### Features
#### Web-Based Management Interface:
smeserver-manager provides an intuitive and user-friendly web interface that allows administrators to manage various aspects of the server without needing deep technical knowledge or command-line skills.
#### User and Group Management:
It allows you to easily add, remove, and manage user accounts and groups. The interface simplifies creating email accounts, setting passwords, and configuring user permissions.
#### Network Configuration:
You can configures network settings such as IP addresses, DNS, DHCP, and gateway settings. The interface also provides options for setting up VPNs, remote access, and firewall rules.
#### File Sharing and Storage:
Enables and manages file sharing services like Samba (for Windows file sharing) and NFS (for Unix/Linux file sharing). Administrators can easily create shared folders and manage permissions.
#### Email Services:
Configure and manage email services, including setting up mail domains, user mailboxes, and SMTP/IMAP/POP3 settings. It also provides options for spam and virus filtering.
#### Web Services:
Host and manage websites using the integrated web server (usually Apache). It supports virtual hosting, where multiple websites can be hosted on the same server.
#### Backup and Restore:
Perform backups of essential data and server configurations. The interface provides options for scheduled backups and restoring from backup files.
#### Software Updates and Installation:
Keep the server up-to-date with the latest security patches and software updates. The interface helps in installing and updating software packages and extensions.
#### Monitoring and Reporting:
Monitor server performance and health. The interface provides logs, status reports, and alerts for various server components, including disk usage, network traffic, and system load.
### Installation and Access
Typically, smeserver-manager is installed by default on SME Server. To access the interface:
Open a web browser on a device connected to the same network as the SME Server. Enter the server's IP address or hostname followed by /server-manager in the address bar (e.g., https://192.168.1.1/server-manager).
You will be prompted to log in. Use the administrator credentials set during the SME Server installation.
### Benefits
Simplicity: Makes it easy for non-technical users to manage a server.
Centralized Management: Provides a single point of control for various server functionalities.
Efficiency: Saves time and reduces complexity in server management tasks.
Security: Regular updates and built-in security features ensure the server remains secure.
### Considerations
Learning Curve: While designed to be user-friendly, some features may still require a basic understanding of server and network management concepts.
Dependencies: Relies on specific packages and configurations of SME Server, and may not be directly applicable to other Linux distributions.
### Summary
SMEserver-manager is a powerful tool that brings simplicity and efficiency to server management for small to medium-sized enterprises. By providing a centralized, web-based interface, it allows administrators to manage users, network settings, file sharing, email services, web hosting, and more, all from a single location.

View File

@@ -47,6 +47,9 @@ for my $event ( qw( smeserver-manager-update smanager-refresh bootstrap-console-
event_link('systemd-default', "smeserver-manager-update", '88');
event_link('systemd-reload', "smeserver-manager-update", '89');
templates2events("/etc/rsyslog.conf", "smeserver-manager-update");
safe_symlink("restart",
"root/etc/e-smith/events/smeserver-manager-update/services2adjust/rsyslog");
use esmith::Build::Backup qw(:all);
backup_includes("smeserver-manager", qw(

View File

@@ -33,6 +33,8 @@ use esmith::I18N;
use Data::Dumper; # activate if DEBUG
binmode(STDOUT, ":encoding(UTF-8)");
my $navigation_ignore =
"(\.\.?|Swttheme\.pm|Login\.pm|Request\.pm|Modules\.pm(-.*)?)";
@@ -46,131 +48,193 @@ my @files = grep (!/^${navigation_ignore}$/, readdir (FUNCTIONS));
closedir FUNCTIONS;
my @langs = $i18n->availableLanguages();
#my @langs = ('en', 'fr');
#print Dumper(\@langs);
#my @langs = ('tr'); #Temp override
foreach my $lang (@langs)
{
my $long_lex = SMNGR_LIB.'/'.I18NMODULES."/General/general_$lang.lex";
next unless ( -e $long_lex );
my $long_lex = SMNGR_LIB.'/'.I18NMODULES."/General/general_$lang.lex";
next unless ( -e $long_lex );
open(LEX, '<:encoding(UTF-8)', $long_lex)
or die "Couldn't open ", $long_lex, " for reading.\n";
my @gen_lex = <LEX>;
close LEX;
open(LEX, '<:encoding(UTF-8)', $long_lex)
or die "Couldn't open ", $long_lex, " for reading.\n";
my @gen_lex = <LEX>;
close LEX;
foreach my $file (@files)
{
next if (-d SMNGR_LIB.'/'.WEBFUNCTIONS . "/$file");
# next unless ( $file =~ m/D.*\.pm$/ );
next unless ( $file =~ m/[A-Z].*\.pm$/ );
my $file2 = lc($file);
$file2 =~ s/\.pm$//;
#--------------------------------------------------
# extract heading, description and weight information
# from Mojo controller
#--------------------------------------------------
open(SCRIPT, SMNGR_LIB.'/'.WEBFUNCTIONS . "/$file");
my $heading = undef;
my $description = undef;
my $heading_weight = undef;
my $description_weight = undef;
my $menucat = undef;
my $routes = undef;
while ( <SCRIPT> )
#my @files = ('Portforwarding.pm'); #Temp override
foreach my $file (@files)
{
$heading = $1 if (/^\s*#\s*heading\s*:\s*(.+?)\s*$/);
$description = $1
if (/^\s*#\s*description\s*:\s*(.+?)\s*$/);
($heading_weight, $description_weight) = ($1, $2)
if (/^\s*#\s*navigation\s*:\s*(\d+?)\s+(\d+?)\s*$/);
$menucat = $1
if (/^\s*#\s*menu\s*:\s*(.+?)\s*$/);
next if (-d SMNGR_LIB.'/'.WEBFUNCTIONS . "/$file");
# next unless ( $file =~ m/D.*\.pm$/ );
next unless ( $file =~ m/[A-Z].*\.pm$/ );
last if (defined $heading and
defined $description and
defined $heading_weight and
defined $description_weight and
defined $menucat);
my $file2 = lc($file);
$file2 =~ s/\.pm$//;
#--------------------------------------------------
# extract heading, description and weight information
# from Mojo controller
#--------------------------------------------------
open(SCRIPT, SMNGR_LIB.'/'.WEBFUNCTIONS . "/$file");
my $heading = undef;
my $description = undef;
my $heading_weight = undef;
my $description_weight = undef;
my $menucat = undef;
my $routes = undef;
# routes : end (stop before eof if 'menu' is not here before 'routes'!!!
$routes = $1 if (/^\s*#\s*routes\s*:\s*(.+?)\s*$/);
last if (defined $routes and $routes eq 'end');
while ( <SCRIPT> )
{
$heading = $1 if (/^\s*#\s*heading\s*:\s*(.+?)\s*$/);
$description = $1
if (/^\s*#\s*description\s*:\s*(.+?)\s*$/);
($heading_weight, $description_weight) = ($1, $2)
if (/^\s*#\s*navigation\s*:\s*(\d+?)\s+(\d+?)\s*$/);
$menucat = $1
if (/^\s*#\s*menu\s*:\s*(.+?)\s*$/);
last if (defined $heading and
defined $description and
defined $heading_weight and
defined $description_weight and
defined $menucat);
# routes : end (stop before eof if 'menu' is not here before 'routes'!!!
$routes = $1 if (/^\s*#\s*routes\s*:\s*(.+?)\s*$/);
last if (defined $routes and $routes eq 'end');
}
close SCRIPT;
print "updating script $file for lang $lang\n"if DEBUG;
my $navdb = $navdbs{$lang};
my $navinfo = NAVDIR.'/'.NAVIGATIONDIR . "/navigation.$lang";
$navdb ||= esmith::NavigationDB->open($navinfo);
$navdb ||= esmith::NavigationDB->create($navinfo) or
die "Couldn't create $navinfo\n";
$navdbs{$lang} ||= $navdb;
my $rec = $navdb->get($file2) ||
$navdb->new_record($file2, { type => 'panel' } );
my @panel_lex = ();
$long_lex = SMNGR_LIB.'/'.I18NMODULES.'/'.ucfirst($file2)."/${file2}_$lang.lex";
if ( -e $long_lex ) {
open(LEX, '<:encoding(UTF-8)', $long_lex)
or die "Couldn't open ", $long_lex, " for reading.\n";
@panel_lex = <LEX>;
close LEX;
}
#Extract the prefix for this module
my @keys = values @panel_lex; # Get all values from the array
my $i = 0; # Initialize the index
my $found = 0; # Flag to check if the prefix was found
my $prefix = "xx_"; # Probably never match!!
while ($i < @keys) { # Loop until we run out of entries
my $extracted_value = $keys[$i] || ""; # The current entry
#print("Extracted val: ".$extracted_value."\n");
# Extract prefix from the second value (up to and including the first underscore)
#my ($prefix) = $second_value =~ /^'(.*?_)/; # Match everything up to and including the first underscore
($prefix) = $extracted_value =~ /^'(.*?_)/; # Match everything up to and including the first underscore
if (defined $prefix) {
$found = 1; # Set found flag to true
last; # Exit the loop if prefix is found
} else {
#print("Extracted Val: " . $extracted_value . "\n");
}
$i++; # Increment the index to check the next entry
}
if (!$found) {
print(STDERR "No valid prefix found in any entries: ".$file2." (".$lang.")\n"); # if DEBUG;
$prefix = "xx_"; # Probably never match!!
}
#print("Prefix: ".$prefix." ".$file2." (".$lang.")\n");
my %Lexicon = ();
push(@panel_lex, @gen_lex);
my $top_error = 0;
chomp @panel_lex;
for (@panel_lex) {
next unless $_; # first one empty
my ($k, $v) = split / => /, $_;
# errors on split to $v (use DEBUG to see)
if ( $k and $v ) {
$k =~ s/\'//g;
$v =~ s/\'//g;
$v =~ s/,$//g;
$Lexicon{ lc($k) } = $v;
} else {
$k = "?" unless ($k);
print STDERR "Error for $lang $file2 on $k \n" if DEBUG;
$top_error++;
}
}
if ( $top_error > 0) {
if ( DEBUG ) {
print STDERR "$top_error errors for $lang $file2\n";
# print Dumper(\@panel_lex);
# print Dumper(\%Lexicon);
# exit 1;
}
}
$heading = "" unless defined $heading;
$description = "" unless defined $description;
# Get the base language code from $lang
my $base_lang = (split('-', $lang))[0];
my $loc_heading = process_localization( \%Lexicon, $heading, $lang, $prefix );
my $loc_description = process_localization( \%Lexicon, $description, $lang, $prefix );
$loc_heading =~ s/^\s*(\w.*?)\s*$/$1/;
$loc_description =~ s/^\s*(\w.*?)\s*$/$1/;
$rec->merge_props(
Heading => $loc_heading,
Description => $loc_description,
HeadingWeight => localise( \%Lexicon, $heading_weight ),
DescriptionWeight => localise( \%Lexicon, $description_weight ),
MenuCat => (defined $menucat ? $menucat : 'A'));
}
close SCRIPT;
print "updating script $file for lang $lang\n" if DEBUG;
#warn "trying to close for lang $lang\n";
my $navdb = $navdbs{$lang};
my $navinfo = NAVDIR.'/'.NAVIGATIONDIR . "/navigation.$lang";
$navdb ||= esmith::NavigationDB->open($navinfo);
$navdb ||= esmith::NavigationDB->create($navinfo) or
die "Couldn't create $navinfo\n";
$navdbs{$lang} ||= $navdb;
my $rec = $navdb->get($file2) ||
$navdb->new_record($file2, { type => 'panel' } );
my @panel_lex = ();
$long_lex = SMNGR_LIB.'/'.I18NMODULES.'/'.ucfirst($file2)."/${file2}_$lang.lex";
if ( -e $long_lex ) {
open(LEX, '<:encoding(UTF-8)', $long_lex)
or die "Couldn't open ", $long_lex, " for reading.\n";
@panel_lex = <LEX>;
close LEX;
}
my %Lexicon = ();
push(@panel_lex, @gen_lex);
my $top_error = 0;
chomp @panel_lex;
for (@panel_lex) {
next unless $_; # first one empty
my ($k, $v) = split / => /, $_;
# errors on split to $v (use DEBUG to see)
if ( $k and $v ) {
$k =~ s/\'//g;
$v =~ s/\'//g;
$v =~ s/,$//g;
$Lexicon{ $k } = $v;
} else {
$k = "?" unless ($k);
print STDERR "Error for $lang $file2 on $k \n" if DEBUG;
$top_error++;
}
}
if ( $top_error > 0) {
if ( DEBUG ) {
print STDERR "$top_error errors for $lang $file2\n";
# print Dumper(\@panel_lex);
# print Dumper(\%Lexicon);
# exit 1;
}
}
my $loc_heading = localise( \%Lexicon, $heading );
my $loc_description = localise( \%Lexicon, $description );
$loc_heading =~ s/^\s*(\w.*?)\s*$/$1/;
$loc_description =~ s/^\s*(\w.*?)\s*$/$1/;
$rec->merge_props(
Heading => $loc_heading,
Description => $loc_description,
HeadingWeight => localise( \%Lexicon, $heading_weight ),
DescriptionWeight => localise( \%Lexicon, $description_weight ),
MenuCat => (defined $menucat ? $menucat : 'A'));
}
#warn "trying to close for lang $lang\n";
my $navdb = $navdbs{$lang};
$navdb->close();
$navdb->close();
}
sub localise {
my ($lexicon, $string) = @_;
#print("Looking up:".$string."\n");
$string = "" unless defined $string;
return $lexicon->{$string} || $string;
my $lc_string = lc($string);
my $res = $lexicon->{$lc_string} || $string;
#print("Returning:".$res."\n");
return $res;
}
# Subroutine to process localization
sub process_localization {
my ($lexicon_ref, $heading, $lang, $prefix) = @_;
# Localized heading based on original heading
my $loc_heading = localise($lexicon_ref, $heading);
# Get the base language code from $lang
my $base_lang = (split('-', $lang))[0];
# Check the condition
if ($loc_heading eq $heading && $base_lang ne 'en') {
# Construct the new key by combining the prefix and the original heading
my $key = $prefix . $heading;
# Localize using the constructed key
$loc_heading = localise($lexicon_ref, $key);
# See if it got a hit
if ($loc_heading eq $key){
$loc_heading = $heading;
}
}
return $loc_heading; # Optionally return the localized heading
}

View File

@@ -39,6 +39,17 @@
$OUT .= "# private access by default\n";
$OUT .= " Require ip $localAccess $externalSSLAccess\n";
}
$OUT .= " </Location>\n";
# any smanager script or style added in line should be hashed and added here to run in a modern browser
$OUT .= " Header set Content-Security-Policy \"script-src 'self' 'unsafe-eval' 'unsafe-hashes' "
." 'sha256-X8Qwlk0M9iDTQZqFVpbVcThRjBqQXpwTOZCLX8I+Frk=' 'sha256-inQ04nmqTZI75Z5g/tAzjahedNugPFfrhxHyoFezFkM=' 'sha256-5IsIX+Vbow7wwy2RjR3+5X06R/0CQZPkw3OHj/228cM=' 'sha256-tfVskwioRaNsV75h89itf7FujMgIrodfs1Ea4UAJNpE=' 'sha256-P51OyslUh5bGkoWk9qY+o4Su4HuwNFoQcFCeNxF7Ms8=' ; "
." style-src 'self' 'unsafe-hashes' "
." 'sha256-msdEhWmYTu7vqzGaQHDfvy6lzlDsbKkouwvN2R6Co9E=' 'sha256-a1tyxi1vRpW2Q9+0hM+nBA250/jWJlJdeR43c5r90PI=' 'sha256-iYwYhiMcsGmXCUzLEpEzZNz5dINrlkqf1sLbLhEcqGM=' 'sha256-bOTFT8zacR4Rfja/WIKXgAQQXVaPyG3oBlvAhU4ga8g=' 'sha256-2iGOQeZyvW9G2X+8IhZDG+GPRpXQTxUg/2QxdI+dyEg=' 'sha256-CP93jJ1Y8nMwUoDzFbo1srdgsbADPasAc0Wjig1ahpY=' 'sha256-2iGOQeZyvW9G2X+8IhZDG+GPRpXQTxUg/2QxdI+dyEg=' ;"
." \"\n";
$OUT .= " </Location>\n";
# prevent caching of manager files in browser
$OUT .= " <LocationMatch \"/$place/.+\.(html|cgi)\$\">\n";
$OUT .= " Header set Cache-Control no-store\n";
$OUT .= " </LocationMatch>\n";
}
}

View File

@@ -0,0 +1,4 @@
#smanager
:programname, isequal, "smanager" /var/log/smanager/smanager.log
& stop

View File

@@ -67,5 +67,21 @@ hr.sme-copyrightbar {
color: #8ebe43;
background-color: #8ebe43;
}
/* flag container no flag */
#flag-container span {
font-size: 24px;
}
.fallback-box {
display: inline-block; /* Make it inline-block to fit around the content */
border: 2px solid gray; /* Change the border color as desired */
padding: 10px; /* Add some padding */
border-radius: 10px; /* Round the corners of the box */
font-size: 60px; /* Adjust size if needed */
margin-top: 10px; /* Add some margin */
text-align: center; /* Center text inside the box */
}
HERE
}

View File

@@ -234,7 +234,7 @@ a.menu-title {
width: 100%;
}
#h2e11 {
width: 70%;
width: 50%;
float: left;
}
#h2e12 {
@@ -257,9 +257,9 @@ a.menu-title {
width: 70%;
}
#h2e22,#h2e23 {
#h2e22,#h2e23,#h2e12 {
float: left;
width: 10%;
width: 14em;
text-align: center;
}
@@ -273,6 +273,7 @@ a.menu-title {
left: 2px;
}
/*end*/
EOF
}

View File

@@ -0,0 +1,27 @@
document.addEventListener('DOMContentLoaded', () => {
const flagContainer = document.getElementById('flag-container');
// Function to get the browser's locale
function getBrowserLocale() {
return navigator.language || navigator.userLanguage;
}
// Function to map locale to country code
function getCountryCodeFromLocale(locale) {
const localeParts = locale.split('-');
return localeParts.length > 1 ? localeParts[1] : localeParts[0];
}
// Function to create and display the flag icon
function displayFlagIcon(countryCode) {
const flagIcon = document.createElement('span');
flagIcon.className = `flag-icon flag-icon-${countryCode.toLowerCase()}`;
flagIcon.id = 'flag-icon';
flagContainer.appendChild(flagIcon);
}
// Main logic
const locale = getBrowserLocale();
const countryCode = getCountryCodeFromLocale(locale);
displayFlagIcon(countryCode);
});

View File

@@ -1,4 +1,6 @@
/usr/share/smanager/log/production.log {
/var/log/smanager/smanager.log {
su root root
create 600 root root
weekly
copytruncate
rotate 12

View File

@@ -7,7 +7,7 @@ After=network.target
Type=simple
SyslogIdentifier=smanager
WorkingDirectory=/usr/share/smanager/script
PIDFile=/var/run/smanager.pid
PIDFile=/run/smanager.pid
ExecStartPre=/sbin/e-smith/service-status smanager
ExecStart=/usr/bin/hypnotoad srvmngr -f
ExecStop=/usr/bin/hypnotoad -s srvmngr

View File

@@ -25,8 +25,16 @@ use SrvMngr::Plugin::I18N;
use SrvMngr::I18N;
use SrvMngr::Model::Main;
use SrvMngr::Plugin::WithoutCache;
our $VERSION = '1.420';
#this is overwrittrn with the "release" by the spec file - release can be "99.el8.sme"
our $VERSION = '';
#Extract the release value
if ($VERSION =~ /^(\d+)/) {
$VERSION = $1; # $1 contains the matched numeric digits
} else {
$VERSION = '999' #No leading numeric digits found
}
$VERSION = eval $VERSION;
use Exporter 'import';
@@ -210,6 +218,8 @@ sub setup_plugins {
$self->plugin('TagHelpers');
$self->plugin('RenderFile');
$self->plugin('SrvMngr::Plugin::WithoutCache');
# CSRF protection if production mode
# $self->plugin('Mojolicious::Plugin::CSRFDefender' => {
@@ -624,7 +634,7 @@ sub getNavigation {
{
$heading = $rec->prop('Heading');
$description = $rec->prop('Description');
$headingWeight = $rec->prop('HeadingWeight');
$headingWeight = $rec->prop('HeadingWeight') || 99999; #Stop noise in logs if file in dir does not have nav header.
$descriptionWeight = $rec->prop('DescriptionWeight');
$urlpath = $rec->prop('UrlPath') || '';
$menucat = $rec->prop('MenuCat') || 'A'; # admin menu (default)

View File

@@ -12,6 +12,9 @@ use strict;
use warnings;
use Mojo::Base 'Mojolicious::Controller';
use constant FALSE => 0;
use constant TRUE => 1;
use Locale::gettext;
use SrvMngr::I18N;
@@ -36,7 +39,7 @@ sub main {
my $title = $c->l('mai_FORM_TITLE');
$mai_datas{'trt'} = 'LIST';
$mai_datas{fetchmailmethod} = $cdb->get_prop('fetchmail', 'Method');
$mai_datas{fetchmailmethod} = $c->l($cdb->get_prop('fetchmail', 'Method'));
$c->stash( title => $title, notif => '', mai_datas => \%mai_datas );
$c->render(template => 'emailsettings');
@@ -56,13 +59,16 @@ sub do_display {
my ($notif, $dest) = '';
$mai_datas{'trt'} = $trt;
$cdb = esmith::ConfigDB->open || die "Couldn't open config db";
if ( $trt eq 'ACC' ) {
$dest = 'emailaccess';
$mai_datas{fetchmailmethod} = $cdb->get_prop('fetchmail', 'Method');
}
if ( $trt eq 'ACC' )
{
$dest = 'emailaccess';
$mai_datas{fetchmailmethod} = $cdb->get_prop('fetchmail', 'Method');
}
if ( $trt eq 'FIL' ) {
if ( $trt eq 'FIL' )
{
$dest = 'emailfilter';
$mai_datas{'virusstatus'} = $c->get_virus_status();
$mai_datas{'spamstatus'} = $cdb->get_prop('spamassassin', 'status');
@@ -72,9 +78,10 @@ sub do_display {
$mai_datas{spamsortspam} = $cdb->get_prop('spamassassin', 'SortSpam');
$mai_datas{spamsubjecttag} = $cdb->get_prop('spamassassin', 'SubjectTag');
$mai_datas{spamsubject} = $cdb->get_prop('spamassassin', 'Subject');
}
}
if ( $trt eq 'REC' ) {
if ( $trt eq 'REC' )
{
$dest = 'emailreceive';
$mai_datas{fetchmailmethod} = $cdb->get_prop('fetchmail', 'Method');
$mai_datas{freqoffice} = $cdb->get_prop('fetchmail', 'FreqOffice');
@@ -86,9 +93,10 @@ sub do_display {
$mai_datas{specifyheader} = get_secondary_mail_use_envelope();
$mai_datas{secondarymailenvelope} = $cdb->get_prop('fetchmail', 'SecondaryMailEnvelope');
}
}
if ( $trt eq 'DEL' ) {
if ( $trt eq 'DEL' )
{
$dest = 'emaildeliver';
$mai_datas{emailunknownuser} = $cdb->get_value('EmailUnknownUser') || '"returntosender';
$mai_datas{delegatemailserver} = $cdb->get_value('DelegateMailServer');
@@ -96,7 +104,7 @@ sub do_display {
$mai_datas{smtpauthproxystatus} = $cdb->get_prop('smtp-auth-proxy', 'status') || 'disabled';
$mai_datas{smtpauthproxyuserid} = $cdb->get_prop('smtp-auth-proxy', 'Userid') || '';
$mai_datas{smtpauthproxypassword} = $cdb->get_prop('smtp-auth-proxy', 'Passwd') || '';
}
}
$c->stash( title => $title, notif => $notif, mai_datas => \%mai_datas );
@@ -115,103 +123,113 @@ sub do_update {
my %mai_datas = ();
$mai_datas{trt} = $trt;
$cdb = esmith::ConfigDB->open || die "Couldn't open config db";
my $title = $c->l('mai_FORM_TITLE');
my ($dest, $res, $result) = '';
if ( $trt eq 'ACC' ) {
if ( $trt eq 'ACC' )
{
$dest = 'emailaccess';
# $mai_datas{xxx} = $c->param('XXX');
# controls
# $res = xxxxxxx( $c );
# $result .= $res unless $res eq 'OK';
$dest = 'emailaccess';
# $mai_datas{xxx} = $c->param('XXX');
if ( ! $result )
{
$res = $c->change_settings_access();
$result .= $res unless $res eq 'OK';
if ( ! $result )
{
$result = $c->l('mai_SUCCESS');
}
}
}
# controls
# $res = xxxxxxx( $c );
# $result .= $res unless $res eq 'OK';
if ( $trt eq 'FIL' )
{
$dest = 'emailfilter';
# $mai_datas{xxx} = $c->param('XXX');
# controls
# $res = zzzzzz( $c );
# $result .= $res unless $res eq 'OK';
if ( ! $result ) {
$res = $c->change_settings_access();
$result .= $res unless $res eq 'OK';
if ( ! $result ) {
$result = $c->l('mai_SUCCESS');
}
}
}
if ( ! $result )
{
$res = $c->change_settings_filtering();
$result .= $res unless $res eq 'OK';
if ( ! $result )
{
$result = $c->l('mai_SUCCESS');
}
}
}
if ( $trt eq 'FIL' ) {
if ( $trt eq 'REC' )
{
$dest = 'emailreceive';
# $mai_datas{xxx} = $c->param('XXX');
# controls
# $res = yyyyyyyyy( $c );
# $result .= $res unless $res eq 'OK';
$dest = 'emailfilter';
# $mai_datas{xxx} = $c->param('XXX');
if ( ! $result )
{
$res = $c->change_settings_reception();
$result .= $res unless $res eq 'OK';
if ( ! $result )
{
$result = $c->l('mai_SUCCESS');
}
}
}
# controls
# $res = zzzzzz( $c );
# $result .= $res unless $res eq 'OK';
if ( $trt eq 'DEL' )
{
$dest = 'emaildeliver';
# $mai_datas{xxx} = $c->param('XXX');
# controls
$res = $c->ip_number_or_blank( $c->param('DelegateMailServer') );
$result .= $res . ' DMS <br>' unless $res eq 'OK';
if ( ! $result ) {
$res = $c->change_settings_filtering();
$result .= $res unless $res eq 'OK';
if ( ! $result ) {
$result = $c->l('mai_SUCCESS');
}
}
}
$res = $c->validate_smarthost( $c->param('SMTPSmartHost') );
$result .= $res . ' SH <br>' unless $res eq 'OK';
if ( $trt eq 'REC' ) {
$res = $c->nonblank_if_smtpauth( $c->param('SMTPSmartHost') );
$result .= $res . ' SH <br>' unless $res eq 'OK';
$dest = 'emailreceive';
# $mai_datas{xxx} = $c->param('XXX');
$res = $c->nonblank_if_smtpauth( $c->param('SMTPAUTHPROXY_Userid') );
$result .= $res . ' USR <br>' unless $res eq 'OK';
# controls
# $res = yyyyyyyyy( $c );
# $result .= $res unless $res eq 'OK';
$res = $c->nonblank_if_smtpauth( $c->param('SMTPAUTHPROXY_Passwd') );
$result .= $res . ' PWD <br>' unless $res eq 'OK';
if ( ! $result ) {
$res = $c->change_settings_reception();
$result .= $res unless $res eq 'OK';
if ( ! $result ) {
$result = $c->l('mai_SUCCESS');
}
}
}
if ( $trt eq 'DEL' ) {
$dest = 'emaildeliver';
# $mai_datas{xxx} = $c->param('XXX');
# controls
$res = $c->ip_number_or_blank( $c->param('DelegateMailServer') );
$result .= $res . ' DMS <br>' unless $res eq 'OK';
$res = $c->validate_smarthost( $c->param('SMTPSmartHost') );
$result .= $res . ' SH <br>' unless $res eq 'OK';
$res = $c->nonblank_if_smtpauth( $c->param('SMTPSmartHost') );
$result .= $res . ' SH <br>' unless $res eq 'OK';
$res = $c->nonblank_if_smtpauth( $c->param('SMTPAUTHPROXY_Userid') );
$result .= $res . ' USR <br>' unless $res eq 'OK';
$res = $c->nonblank_if_smtpauth( $c->param('SMTPAUTHPROXY_Passwd') );
$result .= $res . ' PWD <br>' unless $res eq 'OK';
if ( ! $result ) {
$res = $c->change_settings_delivery();
$result .= $res unless $res eq 'OK';
if ( ! $result ) {
$result = $c->l('mai_SUCCESS');
}
}
}
if ( ! $result )
{
$res = $c->change_settings_delivery();
$result .= $res unless $res eq 'OK';
if ( ! $result )
{
$result = $c->l('mai_SUCCESS');
}
}
}
# common part
if ($res ne 'OK') {
$c->stash( error => $result );
$c->stash( title => $title, mai_datas => \%mai_datas );
return $c->render( $dest );
}
if ($res ne 'OK')
{
$c->stash( error => $result );
$c->stash( title => $title, mai_datas => \%mai_datas );
return $c->render( $dest );
}
my $message = "emailsettings updates $trt DONE";
$c->app->log->info($message);
@@ -221,7 +239,6 @@ sub do_update {
};
sub get_virus_status {
my ($c, $localise) = @_;
@@ -249,10 +266,10 @@ sub localise_status {
}
sub get_prop {
sub get_db_prop {
my ($c, $item, $prop, $default) = @_;
return $cdb->get_prop($item, $prop) || $default;
}
@@ -364,6 +381,48 @@ sub get_current_imap_access {
}
sub get_current_smtp_ssl_auth {
my ($c, $localise, $soru, $debug) = @_;
die "Error: \$soru must be either 's' or 'u':$soru.\n" unless $soru eq 's' || $soru eq 'u';
$cdb = esmith::ConfigDB->open || die "Couldn't open config db";
# Initialize variables with default values
my $smtpStatus = 'none';
my $smtpAccess = 'none';
my $smtpAuth = 'disabled'; # assuming 'disabled' as a default
# Fetch SMTP settings based on the value of `$soru`
if ($soru eq "u") {
$smtpStatus = $cdb->get_prop('uqpsmtpd', 'status') || 'enabled'; # Fetch from uqpsmtpd
$smtpAccess = $cdb->get_prop('uqpsmtpd', 'access') || 'public';
$smtpAuth = 'enabled'; # Assuming authentication is enabled in this context
} else {
$smtpStatus = $cdb->get_prop('sqpsmtpd', 'status') || 'enabled'; # Fetch from sqpsmtpd
$smtpAccess = $cdb->get_prop('sqpsmtpd', 'access') || 'public';
$smtpAuth = 'enabled'; # Assuming authentication is enabled in this context
}
# Retrieve SMTP SSL authentication options
my $options = $c->get_smtp_ssl_auth_options();
if ($soru eq "u" && $debug ) {
$c->stash('smtp'=>[$smtpStatus,$smtpAccess,$smtpAuth,$soru,$options->{$smtpAccess},$c->l($options->{$smtpAccess})]);
# die "Stop $soru in get_current_smtp_ssl_auth";
}
# Return appropriate message based on SMTP settings
if ($smtpStatus eq 'enabled' && $smtpAuth eq 'enabled') {
return $localise ? $c->l($options->{$smtpAccess}) : $smtpAccess;
}
return $localise ? $c->l($options->{disabled}) : 'disabled';
}
sub get_current_smtp_auth {
my ($c, $localise) = @_;
@@ -371,16 +430,13 @@ sub get_current_smtp_auth {
my $smtpStatus = $cdb->get_prop('qpsmtpd', 'status') || 'enabled';
my $smtpAuth = $cdb->get_prop('qpsmtpd', 'Authentication') || 'enabled';
my $smtpsStatus = $cdb->get_prop('sqpsmtpd', 'status') || 'enabled';
my $smtpsAuth = $cdb->get_prop('sqpsmtpd', 'Authentication') || 'enabled';
my $options = get_smtp_auth_options();
if ($smtpStatus eq 'enabled' && $smtpAuth eq 'enabled')
if ($smtpStatus eq 'enabled' && $smtpAuth eq 'disabled')
{
return $localise ? $c->l($options->{public}) : 'public';
}
elsif ($smtpsStatus eq 'enabled' && $smtpsAuth eq 'enabled')
elsif ($smtpStatus eq 'enabled' && $smtpAuth eq 'enabled')
{
return $localise ? $c->l($options->{publicSSL}) : 'publicSSL';
}
@@ -388,6 +444,8 @@ sub get_current_smtp_auth {
}
sub get_current_webmail_status {
my ($c, $localise) = @_;
@@ -395,19 +453,16 @@ sub get_current_webmail_status {
# determine status of webmail
my $WebmailStatus = "disabled";
my $IMPStatus = $cdb->get_prop('imp', 'status') || 'disabled';
my $HordeStatus = $cdb->get_prop('horde', 'status') || 'disabled';
my $RoundcubeStatus = $cdb->get_prop('roundcube', 'status') || 'disabled';
my $MysqlStatus = $cdb->get_prop('mariadb', 'status') || 'disabled';
my $PHPStatus = $cdb->get_prop('php', 'status') || 'disabled';
my $PHPStatus = $cdb->get_prop('php81-php-fpm', 'status') || 'disabled';
my $Networkaccess = $cdb->get_prop('horde','access') || 'disabled';
my $Networkaccess = $cdb->get_prop('roundcube','access') || 'disabled';
# all four components must be on for webmail to be working
if ( ( $IMPStatus eq "enabled" )
&& ( $HordeStatus eq "enabled" )
# all 3 components must be on for webmail to be working
if ( ( $RoundcubeStatus eq "enabled" )
&& ( $MysqlStatus eq "enabled" )
&& ( $PHPStatus eq "enabled" )
&& ( $Networkaccess eq "public"))
@@ -415,8 +470,7 @@ sub get_current_webmail_status {
$WebmailStatus = "enabledSSL";
}
elsif ( ( $IMPStatus eq "enabled" )
&& ( $HordeStatus eq "enabled" )
elsif ( ( $RoundcubeStatus eq "enabled" )
&& ( $MysqlStatus eq "enabled" )
&& ( $PHPStatus eq "enabled" )
&& ( $Networkaccess eq "private" ))
@@ -491,13 +545,58 @@ sub get_imap_options {
}
sub get_smtp_auth_opt {
my $c = shift;
return [[ $c->l('mai_SECURE_SMTP') => 'publicSSL'],
[ $c->l('Only allow insecure access') => 'public'],
[ $c->l('DISABLED') => 'disabled']
];
}
sub get_smtp_auth_options {
my $c = shift;
my %options = ( disabled => 'DISABLED', publicSSL => 'mai_SECURE_SMTP', public => 'mai_INSECURE_SMTP');
my %options = ( publicSSL => 'mai_SECURE_SMTP', public => 'Only allow insecure access',disabled => 'DISABLED');
\%options;
return \%options;
}
sub get_smtp_ssl_auth_options {
my $c = shift;
my %options = ( public => 'Allow public access', local => 'Allow local access only',disabled => 'DISABLED');
return \%options;
}
sub get_smtp_ssl_auth_opt {
my $c = shift;
return [[ $c->l('Allow public access') => 'public'],
[ $c->l('Allow local access only') => 'local'],
[ $c->l('DISABLED') => 'disabled']
];
}
sub get_key_by_value {
my ($hash_ref, $target_value) = @_;
# Iterate over the hash
while (my ($key, $value) = each %$hash_ref) {
return $key if $value eq $target_value;
}
return undef; # Return undef if no match is found
}
sub get_value_by_key {
my ($hash_ref, $key) = @_;
return $hash_ref->{$key}; # Return the value associated with the key
}
@@ -507,8 +606,7 @@ sub get_webmail_opt {
return [[ $c->l('DISABLED') => 'disabled' ],
[ $c->l('mai_ENABLED_SECURE_ONLY') => 'enabledSSL' ],
[ $c->l('mai_ONLY_LOCAL_NETWORK_SSL') => 'localnetworkSSL' ],
[ $c->l('mai_ENABLED_BOTH') => 'public' ]];
[ $c->l('mai_ONLY_LOCAL_NETWORK_SSL') => 'localnetworkSSL' ]];
}
@@ -519,10 +617,10 @@ sub get_webmail_options {
my %options = (
disabled => 'DISABLED',
enabledSSL => 'mai_ENABLED_SECURE_ONLY',
localnetworkSSL => 'mai_ONLY_LOCAL_NETWORK_SSL' );
enabledSSL => 'mai_ENABLED_SECURE_ONLY',
localnetworkSSL => 'mai_ONLY_LOCAL_NETWORK_SSL');
\%options;
return \%options;
}
@@ -538,15 +636,6 @@ sub get_retrieval_opt {
}
sub get_smtp_auth_opt {
my $c = shift;
return [[ $c->l('DISABLED') => 'disabled'],
[ $c->l('mai_SECURE_SMTP') => 'publicSSL'],
[ $c->l('mai_INSECURE_SMTP') => 'public']];
}
sub get_emailunknownuser_options {
@@ -658,6 +747,7 @@ sub display_multidrop {
sub change_settings_reception {
my $c = shift;
$cdb = esmith::ConfigDB->open || die "Couldn't open config db";
my $FetchmailMethod = ( $c->param('FetchmailMethod') || 'standard' );
@@ -701,18 +791,47 @@ sub change_settings_reception {
}
}
my $smtpAuth = ($c->param('SMTPAuth') || 'public');
if ($smtpAuth eq 'public') {
$cdb->set_prop("qpsmtpd", "Authentication", "enabled" );
$cdb->set_prop("sqpsmtpd", "Authentication", "enabled" );
} elsif ($smtpAuth eq 'publicSSL') {
$cdb->set_prop("qpsmtpd", "Authentication", "disabled" );
$cdb->set_prop("sqpsmtpd", "Authentication", "enabled" );
} else {
$cdb->set_prop("qpsmtpd", "Authentication", "disabled" );
$cdb->set_prop("sqpsmtpd", "Authentication", "disabled" );
}
# Need code here for all 3 options - 25, 465 ad 587
# Options for 25 are enabled and disabled
# for 465 and 587 are (access) public, local and (status) disabled
#my $smtpAuth = ($c->param('SMTPAuth') || 'public');
#if ($smtpAuth eq 'public') {
#$cdb->set_prop("qpsmtpd", "Authentication", "enabled" );
#$cdb->set_prop("sqpsmtpd", "Authentication", "enabled" );
#} elsif ($smtpAuth eq 'publicSSL') {
#$cdb->set_prop("qpsmtpd", "Authentication", "disabled" );
#$cdb->set_prop("sqpsmtpd", "Authentication", "enabled" );
#} else {
#$cdb->set_prop("qpsmtpd", "Authentication", "disabled" );
#$cdb->set_prop("sqpsmtpd", "Authentication", "disabled" );
#}
my @keys = qw(qpsmtpd uqpsmtpd sqpsmtpd);
foreach my $key (@keys) {
my $param_name = $key eq 'qpsmtpd' ? 'SMTPAuth'
: $key eq 'uqpsmtpd' ? 'uSMTPAuth'
: 'sSMTPAuth'; # Defaults to 'sSMTPAuth' for 'sqpsmtpd'
my $SMTPAuth = $c->param($param_name);
if ($SMTPAuth eq 'disabled') {
$cdb->set_prop($key, 'status', 'disabled');
$cdb->set_prop($key, 'access', 'disabled');
} else {
$cdb->set_prop($key, 'status', 'enabled');
if ($key eq 'qpsmtpd') {
my $auth_status = $SMTPAuth eq 'publicSSL' ? 'enabled' : 'disabled';
$cdb->set_prop($key, 'Authentication', $auth_status);
$cdb->set_prop($key, 'access', 'public');
} else {
$cdb->set_prop($key, 'Authentication', 'enabled');
my $auth_key = ($key eq 'uqpsmtpd') ? 'uSMTPAuth' : 'sSMTPAuth';
my $access_value = $c->param($auth_key) eq 'public' ? 'public' : 'local';
$cdb->set_prop($key, 'access', $access_value);
}
}
}
unless ( system( "/sbin/e-smith/signal-event", "email-update" ) == 0 )
{
return $c->l('mai_ERROR_UPDATING_CONFIGURATION');
@@ -724,6 +843,7 @@ sub change_settings_reception {
sub change_settings_delivery {
my ($c) = shift;
$cdb = esmith::ConfigDB->open || die "Couldn't open config db";
my $EmailUnknownUser = ($c->param('EmailUnknownUser') || 'returntosender');
@@ -752,7 +872,8 @@ sub change_settings_delivery {
sub change_settings_access {
my $c = shift;
$cdb = esmith::ConfigDB->open || die "Couldn't open config db";
my $pop3Access = ($c->param('POPAccess') || 'private');
if ($pop3Access eq 'disabled') {
$cdb->set_prop('pop3', "status", "disabled" );
@@ -802,38 +923,22 @@ sub change_settings_access {
#------------------------------------------------------------
my $webmail = ($c->param('WebMail') || 'disabled');
if ( $webmail eq "enabled" ) {
$cdb->set_prop('php', "status", $webmail );
$cdb->set_prop('mariadb',"status", $webmail );
$cdb->set_prop('imp',"status", $webmail );
$cdb->set_prop('horde', "status", $webmail );
$cdb->set_prop('imp',"access", "full" );
$cdb->set_prop('horde',"access", "public" );
$cdb->set_prop('horde',"HttpsOnly", "no" );
}
elsif ( $webmail eq "enabledSSL" ) {
$cdb->set_prop('php',"status", "enabled" );
if ( $webmail eq "enabledSSL" ) {
$cdb->set_prop('php81-php-fpm',"status", "enabled" );
$cdb->set_prop('mariadb',"status", "enabled" );
$cdb->set_prop('imp',"status", 'enabled' );
$cdb->set_prop('horde',"status", 'enabled' );
$cdb->set_prop('imp',"access", "SSL" );
$cdb->set_prop('horde',"access", "public" );
$cdb->set_prop('horde',"HttpsOnly", "yes" );
$cdb->set_prop('roundcube',"status", 'enabled' );
$cdb->set_prop('roundcube',"access", "public" );
}
elsif ( $webmail eq "localnetworkSSL" ) {
$cdb->set_prop('php',"status", "enabled" );
$cdb->set_prop('php81-php-fpm',"status", "enabled" );
$cdb->set_prop('mariadb',"status", "enabled" );
$cdb->set_prop('imp',"status", 'enabled' );
$cdb->set_prop('horde',"status", 'enabled' );
$cdb->set_prop('imp',"access", "SSL" );
$cdb->set_prop('horde',"access", "private" );
$cdb->set_prop('horde',"HttpsOnly", "yes" );
$cdb->set_prop('roundcube',"status", 'enabled' );
$cdb->set_prop('roundcube',"access", "private" );
}
else {
$cdb->set_prop('imp',"status", 'disabled' );
$cdb->set_prop('horde',"status", 'disabled' );
$cdb->set_prop('roundcube',"status", 'disabled' );
}
unless ( system( "/sbin/e-smith/signal-event", "email-update" ) == 0 ) {
@@ -847,6 +952,8 @@ sub change_settings_access {
sub change_settings_filtering {
my $c = shift;
$cdb = esmith::ConfigDB->open || die "Couldn't open config db";
my $virus_status = ( $c->param('VirusStatus') || 'disabled' );
$cdb->set_prop("qpsmtpd", 'VirusScan', $virus_status);
@@ -860,7 +967,7 @@ sub change_settings_filtering {
Subject
SubjectTag) )
{
$cdb->set_prop('spamassassin', $param, $c->param("Spam$param"));
$cdb->set_prop('spamassassin', $param, $c->param("Spam$param"));
}
my $patterns_status = $c->adjust_patterns() ? 'enabled' : 'disabled';
@@ -868,7 +975,7 @@ sub change_settings_filtering {
unless ( system( "/sbin/e-smith/signal-event", "email-update" ) == 0 )
{
return $c->l('mai_ERROR_UPDATING_CONFIGURATION');
return $c->l('mai_ERROR_UPDATING_CONFIGURATION');
}
return 'OK';
@@ -922,4 +1029,4 @@ sub validate_smarthost {
}
1;
1;

View File

@@ -0,0 +1,472 @@
#
# Generated by SM2Gen version:0.8 Chameleon version:4.5.4 On Python:3.12.3 at 2024-11-16 10:30:16
#
#
# Routines to be edited by the developer to provide content and validation for parameters
# and provison of the control data for table(s)
#
use esmith::util;
use esmith::util::network;
use esmith::ConfigDB;
use esmith::HostsDB;
use esmith::AccountsDB;
use esmith::NetworksDB;
use esmith::DomainsDB;
use constant FALSE => 0;
use constant TRUE => 1;
#The most common ones
our $cdb = esmith::ConfigDB->open() || die("Couldn't open config db");
our $adb = esmith::AccountsDB->open() || die("Couldn't open Accounts db");
our $ndb = esmith::NetworksDB->open() || die("Couldn't open Network db");
our $hdb = esmith::HostsDB->open() || die("Couldn't open Hosts db");
our $ddb = esmith::DomainsDB->open() || die("Couldn't open Domains db");
# Validation routines - parameters for each panel
sub validate_LIST {
my $c = shift;
my $prefix_data = shift; #Data hash as parameter
# Validation for each field
my $ret = "";
if (! TRUE) #validate $c->param('InternalIP')
{$ret .= 'Validation for InternalIP failed';}
if (! TRUE) #validate $c->param('ExternalIP')
{$ret .= 'Validation for ExternalIP failed';}
if (! TRUE) #validate $c->param('InternetIP')
{$ret .= 'Validation for InternetIP failed';}
if (! TRUE) #validate $c->param('Issuer')
{$ret .= 'Validation for Issuer failed';}
if (! TRUE) #validate $c->param('Expiry')
{$ret .= 'Validation for Expiry failed';}
if (! TRUE) #validate $c->param('NotBefore')
{$ret .= 'Validation for NotBefore failed';}
if ($ret eq "") {$ret = 'ok';}
return $ret;
}
sub validate_PARAMS {
my $c = shift;
my $prefix_data = shift; #Data hash as parameter
# Validation for each field
my $ret = "";
if (! TRUE) #validate $c->param('status')
{$ret .= 'Validation for status failed';}
if (! TRUE) #validate $c->param('hookScript')
{$ret .= 'Validation for hookScript failed';}
if (! TRUE) #validate $c->param('hostOverride')
{$ret .= 'Validation for hostOverride failed';}
if (! TRUE) #validate $c->param('ACCEPT_TERMS')
{$ret .= 'Validation for ACCEPT_TERMS failed';}
if (! TRUE) #validate $c->param('API')
{$ret .= 'Validation for API failed';}
if (! TRUE) #validate $c->param('keysize')
{$ret .= 'Validation for keysize failed';}
if (! TRUE) #validate $c->param('configure')
{$ret .= 'Validation for configure failed';}
if (! TRUE) #validate $c->param('Email')
{$ret .= 'Validation for Email failed';}
if ($ret eq "") {$ret = 'ok';}
return $ret;
}
sub validate_CHECKALLDOMAINS {
my $c = shift;
my $prefix_data = shift; #Data hash as parameter
# Validation for each field
my $ret = "";
if (! TRUE) #validate $c->param('AllDomainsCheck')
{$ret .= 'Validation for AllDomainsCheck failed';}
if ($ret eq "") {$ret = 'ok';}
return $ret;
}
sub validate_CHECKALLENABLEDDOMAINS {
my $c = shift;
my $prefix_data = shift; #Data hash as parameter
# Validation for each field
my $ret = "";
if (! TRUE) #validate $c->param('EnabledDomainsCheck')
{$ret .= 'Validation for EnabledDomainsCheck failed';}
if ($ret eq "") {$ret = 'ok';}
return $ret;
}
sub validate_CHECKONEDOMAIN {
my $c = shift;
my $prefix_data = shift; #Data hash as parameter
# Validation for each field
my $ret = "";
if (! TRUE) #validate $c->param('OneDomainToCheck')
{$ret .= 'Validation for OneDomainToCheck failed';}
if (! TRUE) #validate $c->param('OneDomainsCheck')
{$ret .= 'Validation for OneDomainsCheck failed';}
if ($ret eq "") {$ret = 'ok';}
return $ret;
}
# Get singleton data for each panel
sub get_data_for_panel_LIST {
# Return a hash with the fields required which will be loaded into the shared data
my $c = shift;
# my ($reply, $err, $server_cert) = Net::SSLeay::sslcat('localhost', 443, '/');
# my $issuer = Net::SSLeay::X509_NAME_oneline(Net::SSLeay::X509_get_issuer_name($server_cert));
# my $before = Net::SSLeay::P_ASN1_TIME_get_isotime(Net::SSLeay::X509_get_notBefore($server_cert));
# my $expiry = Net::SSLeay::P_ASN1_TIME_get_isotime(Net::SSLeay::X509_get_notAfter($server_cert));
my %ret = (
'Data1'=>'Data for LIST', #Example
# fields from Inputs in LIST $fields['LIST']
'InternalIP'=>$cdb->get_prop('InternalInterface','IPAddress'),
'ExternalIP'=>$cdb->get_prop('ExternalInterface','IPAddress'),
'InternetIP'=>$c->get_my_ip(),
'Issuer'=>'$issuer',
'Expiry'=>'$expiry',
'NotBefore'=>'$before',
);
return %ret;
}
sub get_data_for_panel_PARAMS {
# Return a hash with the fields required which will be loaded into the shared data
my $c = shift;
my %ret = (
'Data1'=>'Data for PARAMS', #Example
# fields from Inputs in PARAMS $fields['PARAMS']
'status'=>$cdb->get_prop('letsencrypt', 'status', 'disabled'),
'hookScript'=>$cdb->get_prop('letsencrypt', 'hookScript', 'disabled'),
'hostOverride'=>$cdb->get_prop('letsencrypt', 'hostOverride', 'disabled'),
'ACCEPT_TERMS'=>$cdb->get_prop('letsencrypt', 'ACCEPT_TERMS', ''),
'API'=>$cdb->get_prop('letsencrypt', 'API', '2'),
'keysize'=>$cdb->get_prop('letsencrypt', 'keysize', '4096'),
'configure'=>$cdb->get_prop('letsencrypt', 'configure', 'none' ),
'email'=>$cdb->get_prop('letsencrypt', 'email')
);
return %ret;
}
sub get_data_for_panel_CHECKALLDOMAINS {
# Return a hash with the fields required which will be loaded into the shared data
my $c = shift;
my %ret = (
'Data1'=>'Data for CHECKALLDOMAINS', #Example
# fields from Inputs in CHECKALLDOMAINS $fields['CHECKALLDOMAINS']
'AllDomainsCheck'=>$c->update_all_domains(),
);
return %ret;
}
sub get_data_for_panel_CHECKALLENABLEDDOMAINS {
# Return a hash with the fields required which will be loaded into the shared data
my $c = shift;
my %ret = (
'Data1'=>'Data for CHECKALLENABLEDDOMAINS', #Example
# fields from Inputs in CHECKALLENABLEDDOMAINS $fields['CHECKALLENABLEDDOMAINS']
'EnabledDomainsCheck'=>$c->update_enabled_domains(),
);
return %ret;
}
sub get_data_for_panel_CHECKONEDOMAIN {
# Return a hash with the fields required which will be loaded into the shared data
my $c = shift;
my %ret = (
'Data1'=>'Data for CHECKONEDOMAIN', #Example
# fields from Inputs in CHECKONEDOMAIN $fields['CHECKONEDOMAIN']
'OneDomainToCheck'=>$c->param("CHECKONEDOMAIN"),
'OneDomainsCheck'=>$c->update_one_domain($c->param("CHECKONEDOMAIN"))
);
return %ret;
}
# Get control data for table(s)
# Define a constant hash for field name mapping
use constant DomainList_FIELD_MAPPING => (
'Table1-Domain name / HOSTNAME' => 'Domain',
'Table1-Brief description' => 'Description',
'Table1-Content' => 'Content',
'Table1-LABEL_NAMESERVERS' => 'Nameservers',
'Table1-LABEL_POINT' => 'Source-for-Table1-LABEL_POINT',
'Table1-LABEL_LECERT' => 'letsencryptSSLcert',
'Table1-IS_IN_CERT' => 'isincert',
'Table1-CHECK' => 'Check'
#'target_field2' => 'source_field2',
# Add more mappings as needed
);
use constant TEST_DOMAIN_LIST => (
{ "domain" => "Domain1","fred" => "fred1" , "description"=>"Description1"},
{ "domain" => "Domain2", "fred" => "fred2", "description"=>"Description2" },
{ "domain" => "Domain3", "fred" => "fred3", "description"=>"Description3" },
# Add more test entries as needed
);
sub actual_DomainList {
my $c = shift;
# Actual code for extracting DomainList
my @list = ();
# my @rv = Net::SSLeay::X509_get_subjectAltNames($server_cert);
# foreach my $element (@rv) {
# next if $element =~ /^\d+$/; ;
# #print $element . "\n";
# push @list, $element;
# }
my @data = ();
my $check = $c->l('Check Domain');
for ($ddb->domains)
{
my $ns = $_->prop('Nameservers') || 'internet';
my $le = $_->prop('letsencryptSSLcert') || 'disabled';#letsencrypt configure all
my $dname= $_->key;
my $isincert = "N";
my $link = $c->create_link("letsencryptd","CHECKONEDOMAIN","");
my $checklink = "<a href='".$link."&CHECKONEDOMAIN=".$_->key."'>".$check."</a>";
#my $checklink = "<a href=''>check</a>";
$isincert = "Y" if ( $dname ~~ @list);
# domain
push @data,
{ Domain => $_->key,
$_->props,
letsencryptSSLcert => $le,
isincert => $isincert,
Check => $checklink,
Nameservers => $ns,
};
#and hosts
for my $h ($hdb->get_hosts_by_domain($dname))
{
next if $ddb->get($h->key);
next unless ($h->prop('HostType') eq "Self" || $h->prop('HostType') eq "Local");
$le = $h->prop('letsencryptSSLcert') || 'disabled';#letsencrypt configure all
$isincert = "N";
$isincert = "Y" if ( $h->key ~~ @list);
push @data,
{ Domain => "--> ". $h->key,
$h->props,
Description=>$h->prop('ExternalIP')|| $h->prop('InternalIP')||"",
Content => $h->prop('HostType'),
isincert => $isincert,
Check => "", #$checklink
Nameservers => $c->l($ns),
}
}
}
return @data;
}
sub get_DomainList {
# Return an array of hashes of the contents for each row and column for DomainList
my $c = shift;
my @source_records = $c->actual_DomainList(); #TEST_DOMAIN_LIST #Replace by code or call to produce contents of table;
my @transformed_records;
my %Field_Mapping = DomainList_FIELD_MAPPING;
# Iterate over each record in the source array
for my $source_record (@source_records) {
my %transformed_record;
# Iterate over each key-value pair in the $Field_Mapping constant
while (my ($target, $source) = each %Field_Mapping) {
# Check if the source field exists in the source record
if (exists $source_record->{$source}) {
# Assign the source field value to the target field in the transformed record
$transformed_record{$target} = $source_record->{$source};
}
}
# Add transformed record to the array if it's not empty
push @transformed_records, \%transformed_record if %transformed_record;
}
return \@transformed_records;
}
# Return hash with values from row in which link clicked on table
sub get_selected_LIST {
my $c = shift;
my $selected = shift; #Parameter is name of selected row.
my $is_new_record = shift; #Indicates new record required (defaults)
my %ret = {};
return $ret;
}
sub get_selected_PARAMS {
my $c = shift;
my $selected = shift; #Parameter is name of selected row.
my $is_new_record = shift; #Indicates new record required (defaults)
my %ret = {};
return $ret;
}
sub get_selected_CHECKALLDOMAINS {
my $c = shift;
my $selected = shift; #Parameter is name of selected row.
my $is_new_record = shift; #Indicates new record required (defaults)
my %ret = {};
return $ret;
}
sub get_selected_CHECKALLENABLEDDOMAINS {
my $c = shift;
my $selected = shift; #Parameter is name of selected row.
my $is_new_record = shift; #Indicates new record required (defaults)
my %ret = {};
return $ret;
}
sub get_selected_CHECKONEDOMAIN {
my $c = shift;
my $selected = shift; #Parameter is name of selected row.
my $is_new_record = shift; #Indicates new record required (defaults)
my %ret = {};
return $ret;
}
#after sucessful modify or create or whatever and submit then perfom (if the params validate)
sub perform_LIST {
my $c = shift;
my $prefix_data = shift; #Data hash as parameter
my $ret = "";
my $db = $cdb; #maybe one of the others
my $dbkey = 'ChangeThis';
if (! TRUE) #copy or perform with value: InternalIP e.g. $db->set_prop($dbkey,'InternalIP',$c->param('InternalIP'),type=>'service'))
{$ret .= 'Perform/save failed for InternalIP';}
if (! TRUE) #copy or perform with value: ExternalIP e.g. $db->set_prop($dbkey,'ExternalIP',$c->param('ExternalIP'),type=>'service'))
{$ret .= 'Perform/save failed for ExternalIP';}
if (! TRUE) #copy or perform with value: InternetIP e.g. $db->set_prop($dbkey,'InternetIP',$c->param('InternetIP'),type=>'service'))
{$ret .= 'Perform/save failed for InternetIP';}
if (! TRUE) #copy or perform with value: Issuer e.g. $db->set_prop($dbkey,'Issuer',$c->param('Issuer'),type=>'service'))
{$ret .= 'Perform/save failed for Issuer';}
if (! TRUE) #copy or perform with value: Expiry e.g. $db->set_prop($dbkey,'Expiry',$c->param('Expiry'),type=>'service'))
{$ret .= 'Perform/save failed for Expiry';}
if (! TRUE) #copy or perform with value: NotBefore e.g. $db->set_prop($dbkey,'NotBefore',$c->param('NotBefore'),type=>'service'))
{$ret .= 'Perform/save failed for NotBefore';}
if ($ret eq "") {$ret = 'ok';}
return $ret;
}
sub perform_PARAMS {
my $c = shift;
my $prefix_data = shift; #Data hash as parameter
my $ret = "";
my $db = $cdb; #maybe one of the others
my $dbkey = 'letsencrypt';
# To make it write to DB as comment, delete this (regex) string in each if statement "TRUE\) \#copy or perform with value: .* e.g."
if (! $db->set_prop($dbkey,'status',$c->param('status'),type=>'service'))
{$ret .= 'Perform/save failed for status';}
if (! $db->set_prop($dbkey,'hookScript',$c->param('hookScript'),type=>'service'))
{$ret .= 'Perform/save failed for hookScript';}
if (! $db->set_prop($dbkey,'hostOverride',$c->param('hostOverride'),type=>'service'))
{$ret .= 'Perform/save failed for hostOverride';}
if (! $db->set_prop($dbkey,'ACCEPT_TERMS',$c->param('ACCEPT_TERMS'),type=>'service'))
{$ret .= 'Perform/save failed for ACCEPT_TERMS';}
if (! $db->set_prop($dbkey,'API',$c->param('API'),type=>'service'))
{$ret .= 'Perform/save failed for API';}
if (! $db->set_prop($dbkey,'keysize',$c->param('keysize'),type=>'service'))
{$ret .= 'Perform/save failed for keysize';}
if (! $db->set_prop($dbkey,'configure',$c->param('configure'),type=>'service'))
{$ret .= 'Perform/save failed for configure';}
if (! $db->set_prop($dbkey,'email',$c->param('email'),type=>'service'))
{$ret .= 'Perform/save failed for email';}
if ($ret eq "") {$ret = 'ok';}
return $ret;
}
sub perform_CHECKALLDOMAINS {
my $c = shift;
my $prefix_data = shift; #Data hash as parameter
my $ret = "";
my $db = $cdb; #maybe one of the others
my $dbkey = 'ChangeThis';
if (! TRUE) #copy or perform with value: AllDomainsCheck e.g. $db->set_prop($dbkey,'AllDomainsCheck',$c->param('AllDomainsCheck'),type=>'service'))
{$ret .= 'Perform/save failed for AllDomainsCheck';}
if ($ret eq "") {$ret = 'ok';}
return $ret;
}
sub perform_CHECKALLENABLEDDOMAINS {
my $c = shift;
my $prefix_data = shift; #Data hash as parameter
my $ret = "";
my $db = $cdb; #maybe one of the others
my $dbkey = 'ChangeThis';
if (! TRUE) #copy or perform with value: EnabledDomainsCheck e.g. $db->set_prop($dbkey,'EnabledDomainsCheck',$c->param('EnabledDomainsCheck'),type=>'service'))
{$ret .= 'Perform/save failed for EnabledDomainsCheck';}
if ($ret eq "") {$ret = 'ok';}
return $ret;
}
sub perform_CHECKONEDOMAIN {
my $c = shift;
my $prefix_data = shift; #Data hash as parameter
my $ret = "";
my $db = $cdb; #maybe one of the others
my $dbkey = 'ChangeThis';
if (! TRUE) #copy or perform with value: OneDomainToCheck e.g. $db->set_prop($dbkey,'OneDomainToCheck',$c->param('OneDomainToCheck'),type=>'service'))
{$ret .= 'Perform/save failed for OneDomainToCheck';}
if (! TRUE) #copy or perform with value: OneDomainsCheck e.g. $db->set_prop($dbkey,'OneDomainsCheck',$c->param('OneDomainsCheck'),type=>'service'))
{$ret .= 'Perform/save failed for OneDomainsCheck';}
if ($ret eq "") {$ret = 'ok';}
return $ret;
}
sub create_link{
# WIP
my ($c,$route, $panel, $index) = @_;
my $link = "$route?trt=$panel&Selected=$index";
return $link;
}
sub get_my_ip
{
my ($self, $item, $prop, $default) = @_;
my $output = `/usr/sbin/e-smith/getmyip`;
return $output || "IP";
}
sub update_one_domain
{
my ($self,$domain) = @_;
return "$domain not domain" unless ($ddb->get($domain) || $hdb->get($domain));
($domain) = ($domain =~ /([\w\p{L}.]+)/);
my $output = `/etc/e-smith/events/actions/letsencrypt-setdomains " " $domain `;
return $output || "-empty-";
}
sub update_all_domains
{
my $self = shift;
my $output = `/etc/e-smith/events/actions/letsencrypt-setdomains "" "" all `;
return $output || "-empty-";
}
sub update_enabled_domains
{
my $self = shift;
my $output = `/etc/e-smith/events/actions/letsencrypt-setdomains "" "" enabled `;
return $output || "-empty-";
}
1;

View File

@@ -0,0 +1,429 @@
package SrvMngr::Controller::Letsencrypt;
#
# Generated by SM2Gen version:0.8 Chameleon version:4.5.4 On Python:3.12.3 at 2024-12-01 15:22:43
#
#----------------------------------------------------------------------
# heading : Network
# description : Letsencrypt certificate
# navigation : 6000 6600
#
# name : letsencrypt, method : get, url : /letsencrypt, ctlact : Letsencrypt#main
# name : letsencryptu, method : post, url : /letsencryptu, ctlact : Letsencrypt#do_update
# name : letsencryptd, method : get, url : /letsencryptd, ctlact : Letsencrypt#do_display
#
# routes : end
#
# Documentation: https://wiki.contribs.org/Letsencrypt
#----------------------------------------------------------------------
#
# Scheme of things:
#
# TBA!!
use strict;
use warnings;
use Mojo::Base 'Mojolicious::Controller';
use constant FALSE => 0;
use constant TRUE => 1;
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session);
use Data::Dumper;
use esmith::util;
use esmith::util::network;
use esmith::ConfigDB;
use esmith::AccountsDB;
use esmith::NetworksDB;
use esmith::HostsDB;
use esmith::DomainsDB;
require '/usr/share/smanager/lib/SrvMngr/Controller/Letsencrypt-Custom.pm'; #The code that is to be added by the developer
sub main {
#
# Initial entry - route is "/<whatever>"
#
#set initial panel
#for initial panel:
#Specifiy panel to enter
#load up _data hash with DB fields
#load up stash with pointer(s) to control fields hash(= get-))
#and a pointer to the prefix_data hash
#render initial panel
my $c = shift;
$c->app->log->info( $c->log_req );
#The most common ones
my $cdb = esmith::ConfigDB->open() || die("Couldn't open config db");
my $adb = esmith::AccountsDB->open() || die("Couldn't open Accounts db");
my $ndb = esmith::NetworksDB->open() || die("Couldn't open Network db");
my $hdb = esmith::HostsDB->open() || die("Couldn't open Hosts db");
my $ddb = esmith::DomainsDB->open() || die("Couldn't open Domains db");
my %lets_data = ();
my $title = $c->l('lets_Letsencrypt_certificate');
my $modul = '';
$lets_data{'trt'} = 'LIST';
#Load any DB entries into the <prefix>_data area so as they are preset in the form
# which DB - this only really works if the initial panel is a PARAMS type panel and not a TABLE
my $db = $cdb; #pickup local or global db or Default to config
$c->do_display($lets_data{'trt'});
}
# Post request with params - submit from the form
sub do_update {
#
# Return after submit pushed on panel (this is a post) - route is "/<whatever>u"
# parameters in the params hash.
#
#load up all params into prefix_data hash:
#By panel (series of if statements - only one executed):
#call validate-PANEL() - return ret = ok or error message
#if validation not ok:
#render back to current panel with error message in stash
#otherwise:
#By panel (series of if statements - only one executed):
#do whatever is required: call perform-PANEL() - return "ok" or Error Message
#call signal-event for any global actions specified (check it exists - error and continue?)
#if action smeserver-<whatever>-update exists
#signal_event smeserver-<whatever>-update
#call signal-event for any specific actions for thids panel (check it exists first - error and continue)
#set success in stash
#if no "nextpanel" entry:
#set firstpanel
#else
#set nextpanel
#call render
my $c = shift;
$c->app->log->info($c->log_req);
my $modul = '';
#The most common ones - you might want to comment out any not used.
my $cdb = esmith::ConfigDB->open() || die("Couldn't open config db");
my $adb = esmith::AccountsDB->open() || die("Couldn't open Accounts db");
my $ndb = esmith::NetworksDB->open() || die("Couldn't open Network db");
my $hdb = esmith::HostsDB->open() || die("Couldn't open Hosts db");
my $ddb = esmith::DomainsDB->open() || die("Couldn't open Domains db");
my %lets_data = ();
my $title = $c->l('lets_Letsencrypt_certificate');
# Accessing all POST parameters
my %params = $c->req->params->to_hash;
# Get number of POST parameters
my $num_params = keys %params;
#Params are available in the hash "params" - copy to the prefix_data hash
#while (my ($key, $value) = each %{$c->req->params->to_hash}) {
# $lets_data{$key} = $value;
#}
# the value of trt will tell you which panel has returned
my $trt = $c->param('trt') || 'LIST'; #hidden control on every form.
my $ret = 'ok';
#Validate the parameters in a custom sub one for each panel (although only one of these will be executed)
my $thispanel;
if ($trt eq 'LIST'){
#Validate form parameters for panel LIST
$ret = $c->validate_LIST(\%lets_data);
$thispanel = 'LIST';
}
if ($trt eq 'PARAMS'){
#Validate form parameters for panel PARAMS
$ret = $c->validate_PARAMS(\%lets_data);
$thispanel = 'PARAMS';
}
if ($trt eq 'CHECKALLDOMAINS'){
#Validate form parameters for panel CHECKALLDOMAINS
$ret = $c->validate_CHECKALLDOMAINS(\%lets_data);
$thispanel = 'CHECKALLDOMAINS';
}
if ($trt eq 'CHECKALLENABLEDDOMAINS'){
#Validate form parameters for panel CHECKALLENABLEDDOMAINS
$ret = $c->validate_CHECKALLENABLEDDOMAINS(\%lets_data);
$thispanel = 'CHECKALLENABLEDDOMAINS';
}
if ($trt eq 'CHECKONEDOMAIN'){
#Validate form parameters for panel CHECKONEDOMAIN
$ret = $c->validate_CHECKONEDOMAIN(\%lets_data);
$thispanel = 'CHECKONEDOMAIN';
}
if ($ret ne "ok"){
$c->do_display($thispanel);
} else {
#Do whatever is needed, including writing values to the DB
if ($trt eq 'LIST'){
#do whatever is required ...
$ret = $c->perform_LIST(\%lets_data);
if ($ret ne "ok") {
# return to the panel with error message
$c->stash(error => $c->l($ret));
$c->stash(
title => $title,
modul => $modul,
lets_data => \%lets_data
);
$c->render(template => "letsencrypt");
} else {
$c->stash( success => $c->l('lets_LIST_panel_action_was_successful')); #A bit bland - edit it in the lex file
}
}
if ($trt eq 'PARAMS'){
#do whatever is required ...
$ret = $c->perform_PARAMS(\%lets_data);
if ($ret ne "ok") {
# return to the panel with error message
$c->stash(error => $c->l($ret));
$c->stash(
title => $title,
modul => $modul,
lets_data => \%lets_data
);
$c->render(template => "letsencrypt");
} else {
$c->stash( success => $c->l('lets_PARAMS_panel_action_was_successful')); #A bit bland - edit it in the lex file
}
}
if ($trt eq 'CHECKALLDOMAINS'){
#do whatever is required ...
$ret = $c->perform_CHECKALLDOMAINS(\%lets_data);
if ($ret ne "ok") {
# return to the panel with error message
$c->stash(error => $c->l($ret));
$c->stash(
title => $title,
modul => $modul,
lets_data => \%lets_data
);
$c->render(template => "letsencrypt");
} else {
$c->stash( success => $c->l('lets_CHECKALLDOMAINS_panel_action_was_successful')); #A bit bland - edit it in the lex file
}
}
if ($trt eq 'CHECKALLENABLEDDOMAINS'){
#do whatever is required ...
$ret = $c->perform_CHECKALLENABLEDDOMAINS(\%lets_data);
if ($ret ne "ok") {
# return to the panel with error message
$c->stash(error => $c->l($ret));
$c->stash(
title => $title,
modul => $modul,
lets_data => \%lets_data
);
$c->render(template => "letsencrypt");
} else {
$c->stash( success => $c->l('lets_CHECKALLENABLEDDOMAINS_panel_action_was_successful')); #A bit bland - edit it in the lex file
}
}
if ($trt eq 'CHECKONEDOMAIN'){
#do whatever is required ...
$ret = $c->perform_CHECKONEDOMAIN(\%lets_data);
if ($ret ne "ok") {
# return to the panel with error message
$c->stash(error => $c->l($ret));
$c->stash(
title => $title,
modul => $modul,
lets_data => \%lets_data
);
$c->render(template => "letsencrypt");
} else {
$c->stash( success => $c->l('lets_CHECKONEDOMAIN_panel_action_was_successful')); #A bit bland - edit it in the lex file
}
}
# and call any signal-events needed
#TBD
# Setup shared data and call panel
if ('none' eq 'none') {
$lets_data{'trt'} = 'LIST';
} else {
$lets_data{'trt'} = 'none';
}
$c->do_display($lets_data{'trt'});
}
}
sub do_display {
#
# Return after link clicked in table (this is a get) - route is "/<whatever>d"
# Expects ?trt=PANEL&selected="TableRowName" plus any other required
#
# OR it maybe a post from the main panel to add a new record
#
#load up all supplied params into prefix_data hash
#call get-selected-PANEL() - returns hash of all relevent parameters
#load up returned hash into prefix_data
#render - to called panel
my ($c,$trt) = @_;
$c->app->log->info($c->log_req);
#The most common ones - you might want to comment out any not used.
my $cdb = esmith::ConfigDB->open() || die("Couldn't open config db");
my $adb = esmith::AccountsDB->open() || die("Couldn't open Accounts db");
my $ndb = esmith::NetworksDB->open() || die("Couldn't open Network db");
my $hdb = esmith::HostsDB->open() || die("Couldn't open Hosts db");
my $ddb = esmith::DomainsDB->open() || die("Couldn't open Domains db");
my %lets_data = ();
my $title = $c->l('lets_Letsencrypt_certificate');
my $modul = "";
# Accessing all parameters
my %params = $c->req->params->to_hash;
# Get number of parameters
my $num_params = keys %params;
#Tag as Post or Get (ie. create new entry or edit existing one
my $is_new_record = ($c->req->method() eq 'POST');
#Params are available in the hash "params" - copy to the prefix_data hash
#while (my ($key, $value) = each %{$c->req->params->to_hash}) {
# $lets_data{$key} = $value;
#}
# the value of trt will tell you which panel has returned
if (! $trt){
$trt = $c->param('trt') || 'LIST'; #Indicates where to go now
}
# Now add in the params from the selected row from the table
my %selectedrow;
if ($trt eq 'LIST'){
#Validate Get selected row (if applicable) LIST
%selectedrow = $c->get_selected_LIST($lets_data{'Selected'},$is_new_record);
}
if ($trt eq 'PARAMS'){
#Validate Get selected row (if applicable) PARAMS
%selectedrow = $c->get_selected_PARAMS($lets_data{'Selected'},$is_new_record);
}
if ($trt eq 'CHECKALLDOMAINS'){
#Validate Get selected row (if applicable) CHECKALLDOMAINS
%selectedrow = $c->get_selected_CHECKALLDOMAINS($lets_data{'Selected'},$is_new_record);
}
if ($trt eq 'CHECKALLENABLEDDOMAINS'){
#Validate Get selected row (if applicable) CHECKALLENABLEDDOMAINS
%selectedrow = $c->get_selected_CHECKALLENABLEDDOMAINS($lets_data{'Selected'},$is_new_record);
}
if ($trt eq 'CHECKONEDOMAIN'){
#Validate Get selected row (if applicable) CHECKONEDOMAIN
%selectedrow = $c->get_selected_CHECKONEDOMAIN($lets_data{'Selected'},$is_new_record);
}
#Copy in the selected row params to the prefix_data hash to pass to the panel
while (my ($key, $value) = each %selectedrow){
$lets_data{$key} = $value;
}
# Where to go now
$lets_data{'trt'} = $trt;
# Set up other shared data according to the panel to go to
if ($trt eq 'LIST'){
# pickup any other contents needed and load them into hash shared with panel
my %returned_hash;
# subroutine returns a hash directly
%returned_hash = $c->get_data_for_panel_LIST();
# Copy each key-value pair from the returned hash to the prefix data hash
while (my ($key, $value) = each %returned_hash) {
$lets_data{$key} = $value;
}
}
if ($trt eq 'PARAMS'){
# pickup any other contents needed and load them into hash shared with panel
my %returned_hash;
# subroutine returns a hash directly
%returned_hash = $c->get_data_for_panel_PARAMS();
# Copy each key-value pair from the returned hash to the prefix data hash
while (my ($key, $value) = each %returned_hash) {
$lets_data{$key} = $value;
}
}
if ($trt eq 'CHECKALLDOMAINS'){
# pickup any other contents needed and load them into hash shared with panel
my %returned_hash;
# subroutine returns a hash directly
%returned_hash = $c->get_data_for_panel_CHECKALLDOMAINS();
# Copy each key-value pair from the returned hash to the prefix data hash
while (my ($key, $value) = each %returned_hash) {
$lets_data{$key} = $value;
}
}
if ($trt eq 'CHECKALLENABLEDDOMAINS'){
# pickup any other contents needed and load them into hash shared with panel
my %returned_hash;
# subroutine returns a hash directly
%returned_hash = $c->get_data_for_panel_CHECKALLENABLEDDOMAINS();
# Copy each key-value pair from the returned hash to the prefix data hash
while (my ($key, $value) = each %returned_hash) {
$lets_data{$key} = $value;
}
}
if ($trt eq 'CHECKONEDOMAIN'){
# pickup any other contents needed and load them into hash shared with panel
my %returned_hash;
# subroutine returns a hash directly
%returned_hash = $c->get_data_for_panel_CHECKONEDOMAIN();
# Copy each key-value pair from the returned hash to the prefix data hash
while (my ($key, $value) = each %returned_hash) {
$lets_data{$key} = $value;
}
}
# and table control fields
$c->stash(DomainList=>$c->get_DomainList());
# Data for panel
$c->stash(
title => $title,
modul => $modul,
lets_data => \%lets_data
);
$c->render(template => "letsencrypt");
}
1;

View File

@@ -171,9 +171,11 @@ sub add_portforward {
#work out which protocol
my $fdb;
if ($proto eq 'TCP') {
$tcp_db = esmith::ConfigDB->open('portforward_tcp') || die "Can't open portforward_tcp database: $!\n";
$fdb = $tcp_db;
}
else {
$udp_db = esmith::ConfigDB->open('portforward_udp') || die "Can't open portforward_udp database: $!\n";
$fdb = $udp_db;
}
#Get the other values

View File

@@ -3,7 +3,7 @@ package SrvMngr::Controller::Proxy;
#----------------------------------------------------------------------
# heading : System
# description : Proxy settings
# navigation : 4000 700
# navigation : 4000 710
#----------------------------------------------------------------------
#
# routes : end
@@ -72,4 +72,4 @@ sub do_update {
};
1;
1;

View File

@@ -26,165 +26,182 @@ use Socket qw( inet_aton );
#our @ISA = qw(esmith::FormMagick Exporter);
our @EXPORT = qw( networkAccess_list passwordLogin_list get_ssh_permit_root_login get_ssh_access get_telnet_mode
get_ftp_access get_ftp_password_login_access
get_value get_prop get_ssh_password_auth
validate_network_and_mask ip_number_or_blank subnet_mask_or_blank
get_ipsecrw_sessions pptp_and_dhcp_range
);
our @EXPORT =
qw( networkAccess_list passwordLogin_list get_ssh_permit_root_login get_ssh_access get_telnet_mode
get_ftp_access get_ftp_password_login_access
get_value get_prop get_ssh_password_auth
validate_network_and_mask ip_number_or_blank subnet_mask_or_blank
get_ipsecrw_sessions pptp_and_dhcp_range
);
# get_pptp_sessions
our $db = esmith::ConfigDB->open || warn "Couldn't open configuration database";
sub main {
my $c = shift;
$c->app->log->info($c->log_req);
$c->app->log->info( $c->log_req );
my $title = $c->l('rma_FORM_TITLE');
my $notif = '';
my $title = $c->l('rma_FORM_TITLE');
my $notif = '';
my %rma_datas = ();
$db = esmith::ConfigDB->open || warn "Couldn't open configuration database";
#$rma_datas{ipsecrwSess} = $c->get_ipsecrw_sessions();
#$rma_datas{pptpSessions} = $c->get_pptp_sessions();
$rma_datas{sshAccess} = $c->get_ssh_access();
$rma_datas{sshPermitRootLogin} = $c->get_ssh_permit_root_login();
$rma_datas{sshAccess} = $c->get_ssh_access();
$rma_datas{sshPermitRootLogin} = $c->get_ssh_permit_root_login();
$rma_datas{sshPasswordAuthentication} = $c->get_ssh_password_auth();
$rma_datas{sshTCPPort} = $c->get_ssh_port();
$rma_datas{ftpAccess} = $c->get_ftp_access();
$rma_datas{ftpPasswordAccess} = $c->get_ftp_password_login_access();
$rma_datas{sshTCPPort} = $c->get_ssh_port();
$rma_datas{ftpAccess} = $c->get_ftp_access();
$rma_datas{ftpPasswordAccess} = $c->get_ftp_password_login_access();
#$rma_datas{telnetAccess} = $c->get_telnet_access;
$c->stash( title => $title, notif => $notif, rma_datas => \%rma_datas );
$c->render(template => 'remoteaccess');
};
$c->render( template => 'remoteaccess' );
}
sub do_action {
my $c = shift;
$c->app->log->info($c->log_req);
$c->app->log->info( $c->log_req );
my $title = $c->l('rma_FORM_TITLE');
my ($result, $res, $trt) = '';
my ( $result, $res, $trt ) = '';
my %rma_datas = ();
$rma_datas{ipsecrwSess} = ($c->param ('IpsecrwSess') || '');
$rma_datas{ipsecrwReset} = ($c->param ('IpsecrwReset') || '');
$db = esmith::ConfigDB->open || warn "Couldn't open configuration database";
$rma_datas{ipsecrwSess} = ( $c->param('IpsecrwSess') || '' );
$rma_datas{ipsecrwReset} = ( $c->param('IpsecrwReset') || '' );
#$rma_datas{pptpSessions} = ($c->param ('PptpSessions') || '0');
$rma_datas{validFromNetwork} = ($c->param ('ValidFromNetwork') || '');
$rma_datas{validFromMask} = ($c->param ('ValidFromMask') || '');
$rma_datas{validFromNetwork} = ( $c->param('ValidFromNetwork') || '' );
$rma_datas{validFromMask} = ( $c->param('ValidFromMask') || '' );
## my @remove = $q->param('validFromRemove'); ???????? the first one only !!
my @vals = $c->param ('Remove_nets');
my @vals = $c->param('Remove_nets');
$rma_datas{remove_nets} = join ',', @vals;
$rma_datas{sshaccess} = ($c->param ('SshAccess') || 'off');
$rma_datas{sshPermitRootLogin} = ($c->param ('SshPermitRootLogin') || 'no');
$rma_datas{sshPasswordAuthentication} = ($c->param ('SshPasswordAuthentication') || 'no');
$rma_datas{sshTCPPort} = ($c->param ('SshTCPPort') || '22');
$rma_datas{sshaccess} = ( $c->param('SshAccess') || 'off' );
$rma_datas{sshPermitRootLogin} =
( $c->param('SshPermitRootLogin') || 'no' );
$rma_datas{sshPasswordAuthentication} =
( $c->param('SshPasswordAuthentication') || 'no' );
$rma_datas{sshTCPPort} = ( $c->param('SshTCPPort') || '22' );
$rma_datas{ftpAccess} = ($c->param ('FtpAccess') || 'off');
$rma_datas{ftpPasswordAccess} = ($c->param ('FtpPasswordAccess') || 'private');
$rma_datas{ftpAccess} = ( $c->param('FtpAccess') || 'off' );
$rma_datas{ftpPasswordAccess} =
( $c->param('FtpPasswordAccess') || 'private' );
$rma_datas{telnetAccess} = ($c->param ('TelnetAccess') || 'off');
$rma_datas{telnetAccess} = ( $c->param('TelnetAccess') || 'off' );
# validate
my $v = $c->validation;
return $c->render('remoteaccess') unless $v->has_data;
#$v->optional('PptpSessions')->num(0, 999)->is_valid;
$v->optional('ValidFromNetwork')->size(7, 15)->is_valid;
$v->optional('ValidFromMask')->size(7, 15)->is_valid;
$v->required('SshTCPPort')->num(1, 65535)->is_valid;
if ( $c->param('ValidFromNetwork') ne "" ) {
$v->optional('ValidFromNetwork')->size( 7, 15 )->is_valid;
}
if ( $c->param('ValidFromMask') ne "" ) {
$v->optional('ValidFromMask')->size( 7, 15 )->is_valid;
}
$v->required('SshTCPPort')->num( 1, 65535 )->is_valid;
$result .= 'field validation error' if $v->has_error;
if ( ! $result ) {
if ( !$result ) {
# controls
#$res = pptp_and_dhcp_range( $c, $rma_datas{pptpSessions} );
#$result .= $res . ' ' unless $res eq 'OK';
# controls
#$res = pptp_and_dhcp_range( $c, $rma_datas{pptpSessions} );
#$result .= $res . ' ' unless $res eq 'OK';
$res = ip_number_or_blank( $c, $rma_datas{validFromNetwork} );
$result .= $res . ' ' unless $res eq 'OK';
$res = ip_number_or_blank( $c, $rma_datas{validFromNetwork} );
$result .= $res . ' ' unless $res eq 'OK';
$res = subnet_mask_or_blank( $c, $rma_datas{validFromMask} );
$result .= $res . ' ' unless $res eq 'OK';
$res = subnet_mask_or_blank( $c, $rma_datas{validFromMask} );
$result .= $res . ' ' unless $res eq 'OK';
$res = validate_network_and_mask( $c, $rma_datas{validFromNetwork}, $rma_datas{validFromMask} );
$result .= $res . ' ' unless $res eq 'OK';
$res = validate_network_and_mask(
$c,
$rma_datas{validFromNetwork},
$rma_datas{validFromMask}
);
$result .= $res . ' ' unless $res eq 'OK';
#$result .= ' blocked for testing !' . $rma_datas{remove_nets};
#$result .= ' blocked for testing !' . $rma_datas{remove_nets};
}
if ( ! $result ) {
if ( !$result ) {
$res = change_settings( $c, %rma_datas );
$result .= $res unless $res eq 'OK';
}
if ( ! $result ) {
$result = $c->l('rma_ACTION_SUCCEEDED');
$trt = 'SUC';
if ( $result eq "" ) {
$result = $c->l('rma_SUCCESS');
$trt = 'SUC';
}
$c->stash( title => $title, notif => $result, rma_datas => \%rma_datas );
if ( $trt ne 'SUC' ) {
return $c->render(template => 'remoteaccess');
#return $c->render( template => 'remoteaccess' );
if ( $trt eq 'SUC' ) {
$c->stash( title => $title,modul => $result);
return $c->render( template => 'module' );
}
$c->redirect_to('/remoteaccess');
};
return $c->render( template => 'remoteaccess' );
#$c->redirect_to('/remoteaccess');
}
sub networkAccess_list {
my $c = shift;
return [[ $c->l('rma_NO_ACCESS') => 'off'],
[ $c->l('NETWORKS_ALLOW_LOCAL') => 'private'],
[ $c->l('NETWORKS_ALLOW_PUBLIC') => 'public']];
return [
[ $c->l('rma_NO_ACCESS') => 'off' ],
[ $c->l('NETWORKS_ALLOW_LOCAL') => 'private' ],
[ $c->l('NETWORKS_ALLOW_PUBLIC') => 'public' ]
];
}
sub passwordLogin_list {
my $c = shift;
return [[$c->l('rma_PASSWORD_LOGIN_PRIVATE') => 'private'],
[$c->l('rma_PASSWORD_LOGIN_PUBLIC') => 'public']];
return [
[ $c->l('rma_PASSWORD_LOGIN_PRIVATE') => 'private' ],
[ $c->l('rma_PASSWORD_LOGIN_PUBLIC') => 'public' ]
];
}
sub get_prop {
my ($c, $item, $prop) = @_;
warn "You must specify a record key" unless $item;
warn "You must specify a property name" unless $prop;
my $record = $db->get($item) or warn "Couldn't get record for $item";
return $record ? $record->prop($prop) : undef;
my ( $c, $item, $prop ) = @_;
warn "You must specify a record key" unless $item;
warn "You must specify a property name" unless $prop;
my $record = $db->get($item) or warn "Couldn't get record for $item";
return $record ? $record->prop($prop) : undef;
}
sub get_value {
my $c = shift;
my $item = shift;
return ($db->get($item)->value());
my $c = shift;
my $item = shift;
return ( $db->get($item)->value() );
}
sub get_ftp_access {
my $status = get_prop('','ftp','status') || 'disabled';
my $status = get_prop( '', 'ftp', 'status' ) || 'disabled';
return 'off' unless $status eq 'enabled';
my $access = get_prop('','ftp','access') || 'private';
return ($access eq 'public') ? 'normal' : 'private';
my $access = get_prop( '', 'ftp', 'access' ) || 'private';
return ( $access eq 'public' ) ? 'normal' : 'private';
}
#sub get_pptp_sessions {
# my $status = get_prop('','pptpd','status');
# if (defined($status) && ($status eq 'enabled')) {
@@ -192,314 +209,317 @@ sub get_ftp_access {
# return '0';
#}
sub get_ssh_permit_root_login {
return(get_prop('','sshd','PermitRootLogin') || 'no');
return ( get_prop( '', 'sshd', 'PermitRootLogin' ) || 'no' );
}
sub get_ssh_password_auth {
return(get_prop('','sshd','PasswordAuthentication') || 'yes');
return ( get_prop( '', 'sshd', 'PasswordAuthentication' ) || 'yes' );
}
sub get_ssh_access {
my $status = get_prop('','sshd','status');
if (defined($status) && ($status eq 'enabled')) {
my $access = get_prop('','sshd','access');
$access = ($access eq 'public') ? 'public' : 'private';
return($access);
}
else {
return('off');
}
my $status = get_prop( '', 'sshd', 'status' );
if ( defined($status) && ( $status eq 'enabled' ) ) {
my $access = get_prop( '', 'sshd', 'access' );
$access = ( $access eq 'public' ) ? 'public' : 'private';
return ($access);
}
else {
return ('off');
}
}
sub get_ssh_port {
return(get_prop('$c','sshd','TCPPort') || '22');
return ( get_prop( '$c', 'sshd', 'TCPPort' ) || '22' );
}
sub get_ftp_password_login_access {
my $status = get_prop('','ftp','status') || 'disabled';
my $status = get_prop( '', 'ftp', 'status' ) || 'disabled';
return 'private' unless $status eq 'enabled';
my $access = get_prop('','ftp','LoginAccess') || 'private';
my $access = get_prop( '', 'ftp', 'LoginAccess' ) || 'private';
return ($access eq 'public') ? 'public' : 'private';
return ( $access eq 'public' ) ? 'public' : 'private';
}
sub get_telnet_mode {
my $telnet = $db->get('telnet');
return('off') unless $telnet;
my $status = $telnet->prop('status') || 'disabled';
return('off') unless $status eq 'enabled';
my $access = $telnet->prop('access') || 'private';
return ($access eq "public") ? "public" : "private";
my $telnet = $db->get('telnet');
return ('off') unless $telnet;
my $status = $telnet->prop('status') || 'disabled';
return ('off') unless $status eq 'enabled';
my $access = $telnet->prop('access') || 'private';
return ( $access eq "public" ) ? "public" : "private";
}
sub get_ipsecrw_sessions {
sub get_ipsecrw_sessions {
my $status = $db->get('ipsec')->prop('RoadWarriorStatus');
if (defined($status) && ($status eq 'enabled')) {
return($db->get('ipsec')->prop('RoadWarriorSessions') || '0');
}
else {
return('0');
}
my $status = $db->get('ipsec')->prop('RoadWarriorStatus');
if ( defined($status) && ( $status eq 'enabled' ) ) {
return ( $db->get('ipsec')->prop('RoadWarriorSessions') || '0' );
}
else {
return ('0');
}
}
sub get_ipsecrw_status {
return undef unless ( $db->get('ipsec'));
return $db->get('ipsec')->prop('RoadWarriorStatus');
return undef unless ( $db->get('ipsec') );
return $db->get('ipsec')->prop('RoadWarriorStatus');
}
sub pptp_and_dhcp_range {
my $c = shift;
my $val = shift || 0;
my $dhcp_status = $db->get_prop('dhcpd','status') || 'disabled';
my $dhcp_end = $db->get_prop('dhcpd','end') || '';
my $dhcp_start = $db->get_prop('dhcpd','start') || '';
my $c = shift;
my $val = shift || 0;
my $dhcp_status = $db->get_prop( 'dhcpd', 'status' ) || 'disabled';
my $dhcp_end = $db->get_prop( 'dhcpd', 'end' ) || '';
my $dhcp_start = $db->get_prop( 'dhcpd', 'start' ) || '';
if ( $dhcp_status eq 'enabled' ) {
my $ip_start = unpack 'N', inet_aton($dhcp_start);
my $ip_end = unpack 'N', inet_aton($dhcp_end);
my $ip_count = $ip_end - $ip_start;
return 'OK' if( $val < $ip_count );
return $c->l('rma_NUMBER_OF_PPTP_CLIENTS_MUST_BE_LESSER_THAN_NUMBER_OF_IP_IN_DHCP_RANGE');
} else {
my $ip_start = unpack 'N', inet_aton($dhcp_start);
my $ip_end = unpack 'N', inet_aton($dhcp_end);
my $ip_count = $ip_end - $ip_start;
return 'OK' if ( $val < $ip_count );
return $c->l(
'rma_NUMBER_OF_PPTP_CLIENTS_MUST_BE_LESSER_THAN_NUMBER_OF_IP_IN_DHCP_RANGE'
);
}
else {
return 'OK';
}
}
sub _get_valid_from {
my $c = shift;
my $c = shift;
my $rec = $db->get('httpd-admin');
return undef unless($rec);
my @vals = (split ',', ($rec->prop('ValidFrom') || ''));
return @vals;
my $rec = $db->get('httpd-admin');
return undef unless ($rec);
my @vals = ( split ',', ( $rec->prop('ValidFrom') || '' ) );
return @vals;
}
sub ip_number_or_blank {
my $c = shift;
my $c = shift;
my $ip = shift;
if (!defined($ip) || $ip eq "") {
return 'OK';
if ( !defined($ip) || $ip eq "" ) {
return 'OK';
}
return ip_number($c, $ip);
return ip_number( $c, $ip );
}
sub subnet_mask_or_blank {
my $c = shift;
my $c = shift;
my $mask = shift;
if (!defined($mask) || $mask eq "") {
if ( !defined($mask) || $mask eq "" ) {
return "OK";
}
chomp $mask ;
chomp $mask;
return ( subnet_mask( $mask ) ne 'OK' ) ? $c->l('rma_INVALID_SUBNET_MASK') . " (" . $mask . ")" : 'OK';
return ( subnet_mask($mask) ne 'OK' )
? $c->l('rma_INVALID_SUBNET_MASK') . " (" . $mask . ")"
: 'OK';
}
sub validate_network_and_mask {
my $c = shift;
my $net = shift || "";
my $mask = shift || "";
my $c = shift;
my $net = shift || "";
my $mask = shift || "";
if ($net xor $mask) {
return $c->l('rma_ERR_INVALID_PARAMS' . " (" . $net."/".$mask . ")");
}
return 'OK';
if ( $net xor $mask ) {
return $c->l(
'rma_ERR_INVALID_PARAMS' . " (" . $net . "/" . $mask . ")" );
}
return 'OK';
}
sub change_settings {
my ($c, %rma_datas) = @_;
my ( $c, %rma_datas ) = @_;
#------------------------------------------------------------
# good; go ahead and change the access.
#------------------------------------------------------------
my $rec = $db->get('telnet');
if($rec) {
if ($rma_datas{telnetAccess} eq "off") {
$rec->set_prop('status','disabled');
} else {
$rec->set_prop('status','enabled');
$rec->set_prop('access', $rma_datas{telnetAccess});
}
if ($rec) {
if ( $rma_datas{telnetAccess} eq "off" ) {
$rec->set_prop( 'status', 'disabled' );
}
else {
$rec->set_prop( 'status', 'enabled' );
$rec->set_prop( 'access', $rma_datas{telnetAccess} );
}
}
$rec = $db->get('sshd') || $db->new_record('sshd', {type => 'service'});
$rec->set_prop('TCPPort', $rma_datas{sshTCPPort});
$rec->set_prop('status', ( $rma_datas{sshaccess} eq "off" ? 'disabled' : 'enabled'));
$rec->set_prop('access', $rma_datas{sshaccess});
$rec->set_prop('PermitRootLogin', $rma_datas{sshPermitRootLogin});
$rec->set_prop('PasswordAuthentication', $rma_datas{sshPasswordAuthentication});
$rec = $db->get('sshd') || $db->new_record( 'sshd', { type => 'service' } );
$rec->set_prop( 'TCPPort', $rma_datas{sshTCPPort} );
$rec->set_prop( 'status',
( $rma_datas{sshaccess} eq "off" ? 'disabled' : 'enabled' ) );
$rec->set_prop( 'access', $rma_datas{sshaccess} );
$rec->set_prop( 'PermitRootLogin', $rma_datas{sshPermitRootLogin} );
$rec->set_prop( 'PasswordAuthentication',
$rma_datas{sshPasswordAuthentication} );
$rec = $db->get('ftp');
if($rec) {
if ($rma_datas{ftpAccess} eq "off") {
$rec->set_prop('status', 'disabled');
$rec->set_prop('access', 'private');
$rec->set_prop('LoginAccess', 'private');
} elsif ($rma_datas{ftpAccess} eq "normal") {
$rec->set_prop('status', 'enabled');
$rec->set_prop('access', 'public');
$rec->set_prop('LoginAccess', $rma_datas{ftpPasswordAccess});
} else {
$rec->set_prop('status', 'enabled');
$rec->set_prop('access', 'private');
$rec->set_prop('LoginAccess', $rma_datas{ftpPasswordAccess});
}
if ($rec) {
if ( $rma_datas{ftpAccess} eq "off" ) {
$rec->set_prop( 'status', 'disabled' );
$rec->set_prop( 'access', 'private' );
$rec->set_prop( 'LoginAccess', 'private' );
}
elsif ( $rma_datas{ftpAccess} eq "normal" ) {
$rec->set_prop( 'status', 'enabled' );
$rec->set_prop( 'access', 'public' );
$rec->set_prop( 'LoginAccess', $rma_datas{ftpPasswordAccess} );
}
else {
$rec->set_prop( 'status', 'enabled' );
$rec->set_prop( 'access', 'private' );
$rec->set_prop( 'LoginAccess', $rma_datas{ftpPasswordAccess} );
}
}
# if ($rma_datas{pptpSessions} == 0) {
# $db->get('pptpd')->set_prop('status', 'disabled');
# } else {
# $db->get('pptpd')->set_prop('status', 'enabled');
# $db->get('pptpd')->set_prop('sessions', $rma_datas{pptpSessions});
# }
# if ($rma_datas{pptpSessions} == 0) {
# $db->get('pptpd')->set_prop('status', 'disabled');
# } else {
# $db->get('pptpd')->set_prop('status', 'enabled');
# $db->get('pptpd')->set_prop('sessions', $rma_datas{pptpSessions});
# }
if ( $rma_datas{validFromNetwork} && $rma_datas{validFromMask} ) {
unless (add_new_valid_from( $c, $rma_datas{validFromNetwork}, $rma_datas{validFromMask} )) {
return $c->l('rma_ERROR_UPDATING_CONFIGURATION') . 'new net';
}
unless (
add_new_valid_from(
$c,
$rma_datas{validFromNetwork},
$rma_datas{validFromMask}
)
)
{
return $c->l('rma_ERROR_UPDATING_CONFIGURATION') . 'new net';
}
}
if ( $rma_datas{remove_nets} ) {
unless (remove_valid_from( $c, $rma_datas{remove_nets} )) {
return $c->l('rma_ERROR_UPDATING_CONFIGURATION') . 'del net';
}
unless ( remove_valid_from( $c, $rma_datas{remove_nets} ) ) {
return $c->l('rma_ERROR_UPDATING_CONFIGURATION') . 'del net';
}
}
# reset ipsec roadwarrior CA,server,client certificates
if ($rma_datas{ipsecrwReset}) {
system('/sbin/e-smith/roadwarrior', 'reset_certs') == 0 or
return $c->l('rma_ERROR_UPDATING_CONFIGURATION') . 'rst ipsec';
if ( $rma_datas{ipsecrwReset} ) {
system( '/sbin/e-smith/roadwarrior', 'reset_certs' ) == 0
or return $c->l('rma_ERROR_UPDATING_CONFIGURATION') . 'rst ipsec';
}
if ( $rma_datas{ipsecrwSess} ) {
set_ipsecrw_sessions( $c, $rma_datas{ipsecrwSess} );
set_ipsecrw_sessions( $c, $rma_datas{ipsecrwSess} );
}
unless ( system( "/sbin/e-smith/signal-event", "remoteaccess-update" ) == 0 ) {
unless (
system( "/sbin/e-smith/signal-event", "remoteaccess-update" ) == 0 )
{
return $c->l('rma_ERROR_UPDATING_CONFIGURATION');
}
return 'OK';
}
sub set_ipsecrw_sessions {
my $c = shift;
my $c = shift;
my $sessions = shift;
if (defined $sessions) {
$db->get('ipsec')->set_prop('RoadWarriorSessions', $sessions);
if (int($sessions) > 0) {
$db->get('ipsec')->set_prop('RoadWarriorStatus', 'enabled');
}
if ( defined $sessions ) {
$db->get('ipsec')->set_prop( 'RoadWarriorSessions', $sessions );
if ( int($sessions) > 0 ) {
$db->get('ipsec')->set_prop( 'RoadWarriorStatus', 'enabled' );
}
}
return '';
}
sub add_new_valid_from {
my $c = shift;
my $net = shift;
my $mask = shift;
my $c = shift;
my $net = shift;
my $mask = shift;
# we transform bit mask to regular mask
$mask = get_reg_mask( $net, $mask );
my $rec = $db->get('httpd-admin');
return $c->error('ERR_NO_RECORD') unless $rec;
# we transform bit mask to regular mask
$mask = get_reg_mask( $net, $mask );
my $prop = $rec->prop('ValidFrom') || '';
my $rec = $db->get('httpd-admin');
return $c->error('ERR_NO_RECORD') unless $rec;
my @vals = split /,/, $prop;
return '' if (grep /^$net\/$mask$/, @vals); # already have this entry
my $prop = $rec->prop('ValidFrom') || '';
if ($prop ne '') {
$prop .= ",$net/$mask";
} else {
$prop = "$net/$mask";
}
my @vals = split /,/, $prop;
return '' if ( grep /^$net\/$mask$/, @vals ); # already have this entry
$rec->set_prop('ValidFrom', $prop);
if ( $prop ne '' ) {
$prop .= ",$net/$mask";
}
else {
$prop = "$net/$mask";
}
return 1;
$rec->set_prop( 'ValidFrom', $prop );
return 1;
}
sub remove_valid_from {
my $c = shift;
my $remove_nets = shift;
my $c = shift;
my $remove_nets = shift;
my @remove = split /,/, $remove_nets;
my @remove = split /,/, $remove_nets;
# my @remove = $c->param('Remove_nets');
my @vals = $c->_get_valid_from();
# my @remove = $c->param('Remove_nets');
my @vals = $c->_get_valid_from();
foreach my $entry (@remove) {
return undef unless $entry;
foreach my $entry (@remove) {
my ($net, $mask) = split (/\//, $entry);
return undef unless $entry;
unless (@vals) {
print STDERR "ERROR: unable to load ValidFrom property from conf db\n";
return undef;
}
my ( $net, $mask ) = split( /\//, $entry );
# what if we don't have a mask because someone added an entry from
# the command line? by the time we get here, the panel will have
# added a 32 bit mask, so we don't know for sure if the value in db
# is $net alone or $net/255.255.255.255. we have to check for both
# in this special case...
@vals = (grep { $entry ne $_ && $net ne $_ } @vals);
}
unless (@vals) {
print STDERR
"ERROR: unable to load ValidFrom property from conf db\n";
return undef;
}
my $prop;
if (@vals) {
$prop = join ',',@vals;
} else {
$prop = '';
}
# what if we don't have a mask because someone added an entry from
# the command line? by the time we get here, the panel will have
# added a 32 bit mask, so we don't know for sure if the value in db
# is $net alone or $net/255.255.255.255. we have to check for both
# in this special case...
@vals = ( grep { $entry ne $_ && $net ne $_ } @vals );
}
$db->get('httpd-admin')->set_prop('ValidFrom', $prop);
my $prop;
if (@vals) {
$prop = join ',', @vals;
}
else {
$prop = '';
}
return 1;
$db->get('httpd-admin')->set_prop( 'ValidFrom', $prop );
return 1;
}
1;
1;

View File

@@ -0,0 +1,46 @@
package SrvMngr::Controller::Roundcubepanel;
#----------------------------------------------------------------------
# heading : System
# description : Roundcube webmail
# navigation : 99999 9999
#----------------------------------------------------------------------
#----------------------------------------------------------------------
# name : roundcubepanel, method : get, url : /roundcubepanel, ctlact : Roundcubepanel#main
#
# routes : end
#----------------------------------------------------------------------
use strict;
use warnings;
use Mojo::Base 'Mojolicious::Controller';
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session);
#use SrvMngr::Model::Main;
sub main {
my $c = shift;
$c->app->log->info($c->log_req);
my $title = $c->l('Roundcube Webmail');
my $roundcube_url = $c->param('url');
my $roundcube_height = $c->param('height') | 600;
$c->stash( title => $title, modul => $roundcube_url, height => $roundcube_height );
$c->render(template => 'roundcube');
}
sub getroundcubeurl {
my $c = shift;
my $url = shift;
return "/smanager/roundcube?url=$url";
}
1;

View File

@@ -23,14 +23,16 @@ use File::Basename;
our $cdb = esmith::ConfigDB->open || die "Couldn't open config db";
my $dnf_status_file = '/var/cache/dnf/dnf.status';
#use File::stat;
our %dbs;
for ( qw(available installed updates) )
{
$dbs{$_} = esmith::ConfigDB->open_ro("yum_$_") or
die "Couldn't open yum_$_ DB\n";
$dbs{$_} = esmith::ConfigDB->open_ro("dnf_$_") or
die "Couldn't open dnf_$_ DB\n";
}
for ( qw(repositories) )
@@ -52,10 +54,11 @@ sub main {
$yum_datas{'trt'} = 'STAT';
if ( -e "/var/run/yum.pid" ) {
if ( $c->is_dnf_running()) {
$yum_datas{'trt'} = 'LOGF';
$dest = 'yumlogfile';
} elsif ($cdb->get_prop('yum', 'LogFile')) {
} elsif ($cdb->get_prop('dnf', 'LogFile')) {
$yum_datas{'trt'} = 'PSTU';
$yum_datas{'reconf'} = $cdb->get_value('UnsavedChanges', 'yes');
$dest = 'yumpostupg';
@@ -83,9 +86,9 @@ sub do_display {
$yum_datas{'trt'} = $trt;
# force $trt if current logfile
if ( -e "/var/run/yum.pid" ) {
if ( $c->is_dnf_running() ) {
$trt = 'LOGF';
} elsif ($cdb->get_prop('yum', 'LogFile')) {
} elsif ($cdb->get_prop('dnf', 'LogFile')) {
$trt = 'PSTU';
}
@@ -106,13 +109,13 @@ sub do_display {
}
if ( $trt eq 'LOGF' ) {
if (-e "/var/run/yum.pid") {
if ($c->is_dnf_running()) {
$dest = 'yumlogfile';
}
}
if ( $trt eq 'PSTU') {
if ($cdb->get_prop('yum', 'LogFile')) {
if ($cdb->get_prop('dnf', 'LogFile')) {
$dest = 'yumpostupg';
$yum_datas{'reconf'} = $cdb->get_value('UnsavedChanges', 'yes');
}
@@ -221,7 +224,7 @@ sub do_update {
if ( $trt eq 'LOGF' ) {
$dest = 'yumlogfile';
if ( ! -e "/var/run/yum.pid") {
if ( ! $c->is_dnf_running()) {
$yum_datas{trt} = 'SUC';
$result = $c->l('yum_SUCCESS');
}
@@ -247,6 +250,24 @@ sub do_update {
};
sub get_dnf_status {
#interrogate status file created and maintained by smeserver.py plugin for dnf.
my ($c) = @_;
my $file_name = $dnf_status_file;
my $content = "resolved";
if ( -e "$file_name") {
open my $fh, '<', $file_name or die "Can't open file: $!";
$content = <$fh>;
close $fh;
}
return $content;
}
sub is_dnf_running {
my ($c) = @_;
my $dnf_status = $c->get_dnf_status();
return $dnf_status ne "resolved" && $dnf_status ne "config" && $dnf_status ne "sack";
}
sub is_empty {
@@ -289,7 +310,7 @@ sub package_functions_enabled {
my ($c) = @_;
return ($cdb->get_prop("yum", "PackageFunctions") eq "enabled");
return ($cdb->get_prop("dnf", "PackageFunctions") eq "enabled");
}
@@ -298,7 +319,7 @@ sub get_status {
my ($c, $prop, $localise) = @_;
my $status = $cdb->get_prop("yum", $prop) || 'disabled';
my $status = $cdb->get_prop("dnf", $prop) || 'disabled';
return $status unless $localise;
@@ -433,7 +454,7 @@ sub change_settings {
PackageFunctions
) )
{
$cdb->set_prop('yum', $param, $c->param("yum_$param"));
$cdb->set_prop("dnf", $param, $c->param("yum_$param"));
}
my $check4updates = $c->param("yum_check4updates");
@@ -441,21 +462,21 @@ sub change_settings {
if ($check4updates ne 'disabled') { $status = 'enabled'; }
$cdb->set_prop('yum', 'check4updates', $check4updates);
$cdb->set_prop("dnf", 'check4updates', $check4updates);
my $deltarpm = $c->param("yum_DeltaRpmProcess");
$cdb->set_prop('yum', 'DeltaRpmProcess', $deltarpm);
$cdb->set_prop("dnf", 'DeltaRpmProcess', $deltarpm);
my $downloadonly = $c->param("yum_DownloadOnly");
if ($downloadonly ne 'disabled') { $status = 'enabled'; }
$cdb->set_prop('yum', 'DownloadOnly', $downloadonly);
$cdb->set_prop("dnf", 'DownloadOnly', $downloadonly);
my $AutoInstallUpdates = $c->param("yum_AutoInstallUpdates");
if ($AutoInstallUpdates ne 'disabled') { $status = 'enabled'; }
$cdb->set_prop('yum', 'AutoInstallUpdates', $AutoInstallUpdates);
$cdb->set_prop('yum', 'status', $status);
$cdb->set_prop("dnf", 'AutoInstallUpdates', $AutoInstallUpdates);
$cdb->set_prop("dnf", 'status', $status);
my %selected = map {$_ => 1} @{$c->every_param('SelectedRepositories')};
@@ -469,7 +490,7 @@ sub change_settings {
$dbs{repositories}->reload;
unless ( system( "/sbin/e-smith/signal-event", "yum-modify" ) == 0 )
unless ( system( "/sbin/e-smith/signal-event", "dnf-modify" ) == 0 )
{
return $c->l('yum_ERROR_UPDATING_CONFIGURATION');
}
@@ -484,11 +505,11 @@ sub do_yum {
for ( qw(SelectedGroups SelectedPackages) )
{
$cdb->set_prop("yum", $_, join(',', (@{$c->every_param($_)} )));
$cdb->set_prop("dnf", $_, join(',', (@{$c->every_param($_)} )));
}
esmith::util::backgroundCommand(0,
"/sbin/e-smith/signal-event", "yum-$function");
"/sbin/e-smith/signal-event", "dnf-$function");
for ( qw(available installed updates) ) {
$dbs{$_}->reload;
@@ -517,7 +538,7 @@ sub format_yum_log {
$cdb->reload;
my $filepage = $cdb->get_prop('yum', 'LogFile');
my $filepage = $cdb->get_prop('dnf', 'LogFile');
return '' unless $filepage and ( -e "$filepage" );
my $out = sprintf "<PRE>";
@@ -537,7 +558,7 @@ sub post_upgrade_reboot {
my $c = shift;
$cdb->get_prop_and_delete('yum', 'LogFile');
$cdb->get_prop_and_delete('dnf', 'LogFile');
$cdb->reload;
if (fork == 0) {
@@ -552,7 +573,7 @@ sub post_upgrade_reboot {
sub show_yum_log {
my $c = shift;
my $out = $c->format_yum_log();
my $yum_log = $cdb->get_prop_and_delete('yum', 'LogFile');
my $yum_log = $cdb->get_prop_and_delete('dnf', 'LogFile');
return $out;
}

View File

@@ -0,0 +1,72 @@
package SrvMngr::I18N::Modules::Letsencrypt::en;
use strict;
use warnings;
use utf8;
use Mojo::Base 'SrvMngr::I18N';
use SrvMngr::I18N::Modules::General::en;
my %lexicon = (
#
# Generated by SM2Gen version: SM2Gen version:0.8 Chameleon version:4.5.4 On Python:3.12.3 at 2024-12-01 15:22:43
#
'lets_Manage_letsencrypt-config_settings:' => 'Manage letsencrypt-config settings',
'lets_HOOKSCRIPT_STATUS' => 'Hookscript Status',
'lets_SERVICE_STATUS' => 'Service Status',
'lets_EMAIL' => 'Email',
'lets_Back' => 'Back',
'lets_Internal_IP' => 'Internal IP',
'lets_Save' => 'Save',
'lets_Issuer' => 'Issuer',
'lets_IS_IN_CERT' => 'Is In cart',
'lets_For_this_Server' => 'For this Server',
'lets_Loop_through_checking_the_letsencrypt' => 'Loop through checking the letsencrypt status for each configured domain',
'lets_Loop_through_checking_the_letsencrypt' => 'Loop through checking the letsencrypt status for each configured domain which is enabled',
'lets_Check_just_one_domain' => 'Check just one domain',
'lets_PARAMS_panel_action_was_successful' => 'PARAMS panel action was successful',
'lets_Check_all_domains' => 'Check all domains',
'lets_LIST_panel_action_was_successful' => 'LIST panel action was successful',
'lets_Status_Report' => 'Status Report',
'lets_LABEL_NAMESERVERS' => 'Label timeservers',
'lets_Loop_through_and_check_the' => 'Loop through and check the letsencrypt status for a specific domain',
'lets_Letsencrypt_certificate' => 'Letsencrypt certificate',
'lets_Error_Status_Report' => 'Error Status Report',
'lets_Not_Before' => 'Not Before',
'lets_Content' => 'Content',
'lets_CONFIG_LETSENCRYPT' => 'confirm Letsencrypt',
'lets_API_STATUS' => 'ape Status',
'lets_ACCEPT_TERMS_STATUS' => 'Accept Terms Status',
'lets_Check_all_enabled_domains' => 'Check all enabled domains',
'lets_All_domains_check_result' => 'All domains check result',
'lets_CHECKALLDOMAINS_panel_action_was_successful' => 'CHECKALLDOMAINS panel action was successful',
'lets_Domains_name' => 'Domains name',
'lets_HOSTOVERRIDE_STATUS' => 'Hostoverride Status',
'lets_List_of_Domains_and_Hosts' => 'List of Domains and Hosts',
'lets_Brief_description' => 'Brief description',
'lets_KEYSIZE_STATUS' => 'Keysize Status',
'lets_Domain_name_/_HOSTNAME' => 'Domain name / HOSTNAME',
'lets_Enabled_domains_check_result' => 'Enabled domains check result',
'lets_CHECKALLENABLEDDOMAINS_panel_action_was_successful' => 'CHECKALLENABLEDDOMAINS panel action was successful',
'lets_Internet_IP' => 'Internet IP',
'lets_Expiry' => 'Expiry',
'lets_CHECK_ALL_DOMAINS' => 'Check All Domains',
'lets_LABEL_POINT' => 'Label Point',
'lets_CHECK' => 'Check',
'lets_CONFIG' => 'Config',
'lets_Current_certificate_details' => 'Current certificate details',
'lets_LABEL_LECERT' => 'Label secret',
'lets_One_domain_check_result' => 'One domain check result',
'lets_CHECKONEDOMAIN_panel_action_was_successful' => 'CHECKONEDOMAIN panel action was successful',
'lets_CONFIGUREMODE_STATUS' => 'Configuremode Status',
'lets_CHECK_ALL_ENABLED_DOMAINS' => 'Check All Enabled Domains',
'lets_External_Interface_IP' => 'External Interface IP',
'lets_APPLY' => 'Apply',
);
our %Lexicon = (
%{ SrvMngr::I18N::Modules::General::en::Lexicon },
%lexicon
);
1;

View File

@@ -0,0 +1,54 @@
#
# Generated by SM2Gen version: SM2Gen version:0.8 Chameleon version:4.5.4 On Python:3.12.3 at 2024-12-01 15:22:43
#
'lets_Manage_letsencrypt-config_settings:' => 'Manage letsencrypt-config settings',
'lets_HOOKSCRIPT_STATUS' => 'Hookscript Status',
'lets_SERVICE_STATUS' => 'Service Status',
'lets_EMAIL' => 'Email',
'lets_Back' => 'Back',
'lets_Internal_IP' => 'Internal IP',
'lets_Save' => 'Save',
'lets_Issuer' => 'Issuer',
'lets_IS_IN_CERT' => 'Is In cart',
'lets_For_this_Server' => 'For this Server',
'lets_Loop_through_checking_the_letsencrypt' => 'Loop through checking the letsencrypt status for each configured domain',
'lets_Loop_through_checking_the_letsencrypt' => 'Loop through checking the letsencrypt status for each configured domain which is enabled',
'lets_Check_just_one_domain' => 'Check just one domain',
'lets_PARAMS_panel_action_was_successful' => 'PARAMS panel action was successful',
'lets_Check_all_domains' => 'Check all domains',
'lets_LIST_panel_action_was_successful' => 'LIST panel action was successful',
'lets_Status_Report' => 'Status Report',
'lets_LABEL_NAMESERVERS' => 'Label timeservers',
'lets_Loop_through_and_check_the' => 'Loop through and check the letsencrypt status for a specific domain',
'lets_Letsencrypt_certificate' => 'Letsencrypt certificate',
'lets_Error_Status_Report' => 'Error Status Report',
'lets_Not_Before' => 'Not Before',
'lets_Content' => 'Content',
'lets_CONFIG_LETSENCRYPT' => 'confirm Letsencrypt',
'lets_API_STATUS' => 'ape Status',
'lets_ACCEPT_TERMS_STATUS' => 'Accept Terms Status',
'lets_Check_all_enabled_domains' => 'Check all enabled domains',
'lets_All_domains_check_result' => 'All domains check result',
'lets_CHECKALLDOMAINS_panel_action_was_successful' => 'CHECKALLDOMAINS panel action was successful',
'lets_Domains_name' => 'Domains name',
'lets_HOSTOVERRIDE_STATUS' => 'Hostoverride Status',
'lets_List_of_Domains_and_Hosts' => 'List of Domains and Hosts',
'lets_Brief_description' => 'Brief description',
'lets_KEYSIZE_STATUS' => 'Keysize Status',
'lets_Domain_name_/_HOSTNAME' => 'Domain name / HOSTNAME',
'lets_Enabled_domains_check_result' => 'Enabled domains check result',
'lets_CHECKALLENABLEDDOMAINS_panel_action_was_successful' => 'CHECKALLENABLEDDOMAINS panel action was successful',
'lets_Internet_IP' => 'Internet IP',
'lets_Expiry' => 'Expiry',
'lets_CHECK_ALL_DOMAINS' => 'Check All Domains',
'lets_LABEL_POINT' => 'Label Point',
'lets_CHECK' => 'Check',
'lets_CONFIG' => 'Config',
'lets_Current_certificate_details' => 'Current certificate details',
'lets_LABEL_LECERT' => 'Label secret',
'lets_One_domain_check_result' => 'One domain check result',
'lets_CHECKONEDOMAIN_panel_action_was_successful' => 'CHECKONEDOMAIN panel action was successful',
'lets_CONFIGUREMODE_STATUS' => 'Configuremode Status',
'lets_CHECK_ALL_ENABLED_DOMAINS' => 'Check All Enabled Domains',
'lets_External_Interface_IP' => 'External Interface IP',
'lets_APPLY' => 'Apply',

View File

@@ -0,0 +1,73 @@
package SrvMngr::Plugin::Cache;
use Mojo::Base -base;
=head1 NAME
Mojolicious::Plugin::Renderer::WithoutCache::Cache - Mojo::Cache that doesn't cache
=head1 VERSION
Version 0.04
=cut
our $VERSION = '0.04';
$VERSION = eval $VERSION;
=head1 SYNOPSIS
You probably don't want to use this directly.
my $cache = Mojolicious::Plugin::Renderer::WithoutCache::Cache->new;
# this cache does nothing
=head1 DESCRIPTION
A cache object that's compatible to Mojo::Cache but does nothing. It does
not save or return any values. It's always empty.
=head1 METHODS
=head2 get
Does nothing. Returns C<undef>.
=cut
sub get {}
=head2 set
Does nothing. Returns C<$self> so chaining is possible.
=cut
sub set { shift; }
=head2 max_keys
Always returns zero. Can't be set. We don't want any keys.
=cut
sub max_keys { 0 }
=head1 AUTHOR
simbabque, C<< <simbabque at cpan.org> >>
=head1 BUGS
Please report any bugs or feature requests through an issue
on github at L<https://github.com/simbabque/Mojolicious-Plugin-Renderer-WithoutCache/issues>.
=head1 LICENSE
Copyright (C) simbabque.
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.
=cut
1;

View File

@@ -0,0 +1,94 @@
package SrvMngr::Plugin::WithoutCache;
use Mojo::Base 'Mojolicious::Plugin';
use SrvMngr::Plugin::Cache;
=head1 NAME
Mojolicious::Plugin::Renderer::WithoutCache - Disable the template cache in your Mojo app
=begin html
<p>
<a href="https://travis-ci.org/simbabque/Mojolicious-Plugin-Renderer-WithoutCache"><img src="https://travis-ci.org/simbabque/Mojolicious-Plugin-Renderer-WithoutCache.svg?branch=master"></a>
<a href='https://coveralls.io/github/simbabque/Mojolicious-Plugin-Renderer-WithoutCache?branch=master'><img src='https://coveralls.io/repos/github/simbabque/Mojolicious-Plugin-Renderer-WithoutCache/badge.svg?branch=master' alt='Coverage Status' /></a>
</p>
=end html
=head1 VERSION
Version 0.04
=cut
our $VERSION = '0.04';
$VERSION = eval $VERSION;
=head1 SYNOPSIS
This plugin turns off the renderer's cache in L<Mojolicious> and L<Mojo::Lite> applications.
use Mojolicious::Lite;
plugin 'Renderer::WithoutCache';
=head1 DESCRIPTION
This does what it says on the box. It turns off caching for the L<Mojolicious::Renderer>
or any other renderer that's inside C<$app-E<gt>renderer> by injecting a cache object that
does not do anything. This is superior to setting the C<max_keys> of L<Mojo::Cache>
to C<0> if you plan to do a lot of uncached requests, because L<Mojolicious::Renderer>
will still try to cache, and every time L<Mojo::Cache> sets a value in the cache it
looks at the C<max_keys>, and then stops.
Doing nothing at all is cheaper. But not a lot really.
=head1 METHODS
=head2 register
Register the plugin in a L<Mojolicious> application.
$plugin->register(Mojolicious->new);
=cut
sub register {
my ( $self, $app ) = @_;
$app->renderer->cache( SrvMngr::Plugin::Cache->new );
}
=head1 AUTHOR
simbabque, C<< <simbabque at cpan.org> >>
=head1 BUGS
Please report any bugs or feature requests through an issue
on github at L<https://github.com/simbabque/Mojolicious-Plugin-Renderer-WithoutCache/issues>.
=head1 SUPPORT
You can find documentation for this module with the perldoc command.
perldoc Mojolicious::Plugin::Renderer::WithoutCache
=head2 Why would I want to turn off the cache?
I don't know.
=head1 ACKNOWLEDGEMENTS
This plugin was inspired by Tom Hunt asking about turning the cache off
on L<Stack Overflow|http://stackoverflow.com/q/41750243/1331451>.
=head1 LICENSE
Copyright (C) simbabque.
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.
=cut
1;

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,90 @@
/*
Generated by SM2Gen version: SM2Gen version:0.8 Chameleon version:4.5.4 On Python:3.12.3 at 2024-12-01 15:22:43
*/
.Letsencrypt-panel {}
.name {}
.rout {}
.grou {}
.link2 {}
.link3 {}
.link4 {}
.endg {}
.subh2 {}
.read4 {}
.read5 {}
.read6 {}
.subh3 {}
.read1 {}
.read2 {}
.read3 {}
.subh4 {}
.tabl1 {}
thead .tabl1 {}
tbody .tabl1 {}
.name {}
.rout {}
.subh {}
.para1 {}
.sele1 {}
.sele2 {}
.sele3 {}
.sele4 {}
.sele5 {}
.sele6 {}
.sele7 {}
.emai8 {}
.subm9 {}
.name {}
.rout {}
.head {}
.subh {}
.text1 {}
.back2 {}
.name {}
.rout {}
.head {}
.subh {}
.text1 {}
.back2 {}
.name {}
.rout {}
.head {}
.subh {}
.read1 {}
.text2 {}
.back3 {}
.inline-buttons {
display: flex; /* Use flexbox to arrange items horizontally */
gap: 10px; /* Optional: Add space between buttons */
}
.inline-buttons .link {
/* Additional styling can be added here if needed */
}
.inline-buttons .link {
display: inline-block; /* Keep links as inline-block for button shape */
padding: 7px 14px; /* Adjusted padding to approximate 70% of the original */
margin: 0; /* Remove margin */
background-color: #efefef; /* Light gray background color */
color: black; /* Text color */
text-decoration: none; /* Remove underline */
border: 2px solid #bbb; /* Thin, light gray border */
border-radius: 3px; /* Slightly rounded corners */
font-size: 11.2px; /* Adjusted font size to approximate 70% of the original */
text-align: center; /* Center the text */
cursor: pointer; /* Pointer cursor on hover */ }
/* Hover and active effects for better interaction */
.inline-buttons .link:hover {
background-color: #d9d9d9; /* Darker shade on hover */
}
.inline-buttons .link:active {
background-color: #c0c0c0; /* Even darker shade on click */
}
span .label {
padding-top:13em;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -0,0 +1,278 @@
document.addEventListener('DOMContentLoaded', () => {
const flagContainer = document.getElementById('flag-container');
async function getCountryName(countryCode) {
try {
const response = await fetch(`https://restcountries.com/v3.1/alpha/${countryCode}`);
if (!response.ok) throw new Error('Country not found');
const data = await response.json();
// Return the name in the native language
return data[0].name.common;
} catch (error) {
console.error(error);
return 'Unknown Country';
}
}
function getFlagEmoji(locale) {
// Split the locale to get the language and country code
const parts = locale.split('-');
let countryCode;
// Handle single subtag (language only) or double subtag (language-country)
if (parts.length === 1) {
countryCode = getCountryCodeFromLanguage(parts[0]);
} else if (parts.length === 2) {
countryCode = parts[1].toLowerCase(); // Use the country code
}
// If country code is not found, set a fallback output
if (!countryCode) {
const fallback = `? ${locale.toUpperCase()}`; // Just a question mark and the full locale
return { flag: fallback, isUnknown: true, countryName: 'Unknown Country' };
}
// Convert the country code to a flag emoji
return {
flag: String.fromCodePoint(...[...countryCode.toUpperCase()].map(char => 0x1F1E6 + char.charCodeAt(0) - 'A'.charCodeAt(0))),
isUnknown: false,
countryCode: countryCode
};
}
function getCountryCodeFromLanguage(language) {
// Map languages to countries (this is an example, extend as needed)
const languageToCountryMap = {
// Add more mappings as needed
"af": "NA",
"agq": "CM",
"ak": "GH",
"am": "ET",
"ar": "01",
"as": "IN",
"asa": "TZ",
"ast": "ES",
"az": "rl",
"bas": "CM",
"be": "BY",
"bem": "ZM",
"bez": "TZ",
"bg": "BG",
"bm": "ML",
"bn": "BD",
"bo": "CN",
"br": "FR",
"brx": "IN",
"bs": "rl",
"ca": "AD",
"ccp": "BD",
"ce": "RU",
"cgg": "UG",
"chr": "US",
"ckb": "IQ",
"cs": "CZ",
"cy": "GB",
"da": "DK",
"dav": "KE",
"de": "DE",
"dje": "NE",
"dsb": "DE",
"dua": "CM",
"dyo": "SN",
"dz": "BT",
"ebu": "KE",
"ee": "GH",
"el": "CY",
"en": "01",
"es": "ES",
"et": "EE",
"eu": "ES",
"ewo": "CM",
"fa": "AF",
"ff": "CM",
"fi": "FI",
"fil": "PH",
"fo": "FO",
"fr": "FR",
"fur": "IT",
"fy": "NL",
"ga": "IE",
"gd": "GB",
"gl": "ES",
"gsw": "CH",
"gu": "IN",
"guz": "KE",
"gv": "IM",
"ha": "GH",
"haw": "US",
"he": "IL",
"hi": "IN",
"hr": "HR",
"hsb": "DE",
"hu": "HU",
"hy": "AM",
"id": "ID",
"ig": "NG",
"ii": "CN",
"is": "IS",
"it": "IT",
"ja": "JP",
"jgo": "CM",
"jmc": "TZ",
"ka": "GE",
"kab": "DZ",
"kam": "KE",
"kde": "TZ",
"kea": "CV",
"khq": "ML",
"ki": "KE",
"kk": "KZ",
"kkj": "CM",
"kl": "GL",
"kln": "KE",
"km": "KH",
"kn": "IN",
"ko": "KP",
"kok": "IN",
"ks": "IN",
"ksb": "TZ",
"ksf": "CM",
"ksh": "DE",
"kw": "GB",
"ky": "KG",
"lag": "TZ",
"lb": "LU",
"lg": "UG",
"lkt": "US",
"ln": "AO",
"lo": "LA",
"lrc": "IQ",
"lt": "LT",
"lu": "CD",
"luo": "KE",
"Luo": "KE",
"luy": "KE",
"lv": "LV",
"mas": "KE",
"mer": "KE",
"mfe": "MU",
"mg": "MG",
"mgh": "MZ",
"mgo": "CM",
"mk": "MK",
"ml": "IN",
"mn": "MN",
"mr": "IN",
"ms": "BN",
"mt": "MT",
"mua": "CM",
"my": "MM",
"mzn": "IR",
"naq": "NA",
"nb": "NO",
"nd": "ZW",
"nds": "DE",
"ne": "IN",
"nl": "NL",
"nmg": "CM",
"nn": "NO",
"nnh": "CM",
"nus": "SS",
"nyn": "UG",
"om": "ET",
"or": "IN",
"os": "GE",
"pa": "ab",
"pl": "PL",
"ps": "AF",
"pt": "PT",
"qu": "BO",
"rm": "CH",
"rn": "BI",
"ro": "RO",
"rof": "TZ",
"ru": "RU",
"rw": "RW",
"rwk": "TZ",
"sah": "RU",
"saq": "KE",
"sbp": "TZ",
"se": "SE",
"seh": "MZ",
"ses": "ML",
"sg": "CF",
"shi": "tn",
"si": "LK",
"sk": "SK",
"sl": "SI",
"smn": "FI",
"sn": "ZW",
"so": "SO",
"sq": "AL",
"sr": "rl",
"sv": "AX",
"sw": "CD",
"ta": "IN",
"te": "IN",
"teo": "KE",
"tg": "TJ",
"th": "TH",
"ti": "ER",
"to": "TO",
"tr": "TR",
"tt": "RU",
"twq": "NE",
"tzm": "MA",
"ug": "CN",
"uk": "UA",
"ur": "IN",
"uz": "ab",
"vai": "tn",
"Vai": "tn",
"vi": "VN",
"vun": "TZ",
"wae": "CH",
"wo": "SN",
"xog": "UG",
"yav": "CM",
"yi": "01",
"yo": "BJ",
"yue": "ns",
"zgh": "MA",
"zh": "ns",
"zu": "ZA"
};
return languageToCountryMap[language] || null;
}
async function displayLocaleAndFlag() {
// Get the browser locale
const userLocale = navigator.language || navigator.userLanguage;
const { flag, isUnknown, countryCode } = getFlagEmoji(userLocale);
// Display the locale and the corresponding flag (or fallback)
//document.getElementById('locale').textContent = `Your Locale: ${userLocale}`;
if (isUnknown) {
const fallbackDiv = document.createElement('div');
fallbackDiv.className = 'fallback-box';
fallbackDiv.textContent = `? ${userLocale.toUpperCase()}`; // Only show ? and locale code inside the box
//document.getElementById('flag-container').textContent = "Flag: ";
document.getElementById('flag-container').appendChild(fallbackDiv);
// Tooltip for fallback
fallbackDiv.title = "Unknown Country"; // Tooltip for fallback
} else {
const countryName = await getCountryName(countryCode);
const flagSpan = document.createElement('span');
flagSpan.textContent = flag; // Use flag emoji
flagSpan.title = countryName; // Tooltip for the flag in country language
//document.getElementById('flag-container').textContent = "Flag: ";
document.getElementById('flag-container').appendChild(flagSpan);
}
}
displayLocaleAndFlag();
});

View File

@@ -13,11 +13,10 @@
<h1><%= $title %></h1>
<!--br><%= $modul %><br-->
<p>
<p><b>
<b>
%=l ('bugr_DO_NOT_PANIC')
</b></p>
</b>
<p>
%=l ('bugr_SME_EXPERIENCE')
</p><p>
@@ -49,7 +48,7 @@
%=l ('bugr_YUM_REPOS')
</li><br></ul>
%=l ('bugr_PRIVACY')
</p><p>
</p>
<% my $btn = l('bugr_CREATE_REPORT'); %>
@@ -57,7 +56,7 @@
%= submit_button "$btn", class => 'action'
% end
</p><p><b>
<p><b>
%=l ('bugr_DONATING')
</b><br><br>
%=l ('bugr_AWARE_SME')
@@ -66,6 +65,7 @@
</b><br><br>
%=l ('bugr_CONSIDER_DONATING')
<br><br>
</p>
%= link_to 'https://wiki.koozali.org/Donate' => begin
%= image '/images/btn_donateCC_LG.gif'
@@ -76,8 +76,7 @@
<br>
%=l ('bugr_THANK_YOU')
</p>
</div>
%end
%end

View File

@@ -15,7 +15,6 @@
<br><%= $modul %><br>
<p>
<% my $btn = l('bugr_Download this report'); %>
%= form_for 'bugreportD' => (method => 'POST') => begin
@@ -25,4 +24,4 @@
</div>
%end
%end

View File

@@ -45,6 +45,7 @@
%= $dat_datas->{now_string}
</b>
</p>
<p>
<br>
<span class=label>
%=l 'dat_NTP_SERVER'
@@ -121,4 +122,4 @@
% end
</div>
%end
%end

View File

@@ -44,25 +44,25 @@
</span><span class=data>
%= text_field 'department' => $dir_datas->{department}, class => 'input'
</span>
</p>
</p><p>
<span class=label>
%=l 'dir_COMPANY', class => 'label'
</span><span class=data>
%= text_field 'company', $dir_datas->{company}, class => 'input'
</span>
</p>
</p><p>
<span class=label>
%=l 'dir_STREET', class => 'label'
</span><span class=data>
%= text_field 'street' => $dir_datas->{street}, class => 'input'
</span>
</p>
</p><p>
<span class=label>
%=l 'dir_CITY', class => 'label'
</span><span class=data>
%= text_field 'city', $dir_datas->{city}, class => 'input'
</span>
</p>
</p><p>
<span class=label>
%=l 'dir_PHONENUMBER', class => 'label'
</span><span class=data>
@@ -85,4 +85,4 @@
% end
</div>
%end
%end

View File

@@ -1,12 +1,17 @@
% layout 'default', title => "Sme server 2 - emailreceive";
% content_for 'module' => begin
% use constant FALSE => 0;
% use constant TRUE => 1;
<div id='module' class='module emailreceive-panel'>
% if ($config->{debug} == 1) {
<p>
%= dumper $c->current_route
%= dumper $mai_datas
%= dumper $c->param('SMTPAuth')
</p>
% }
@@ -26,16 +31,65 @@
%=l 'mai_LABEL_MODE'
</span><span class=input>
% param 'FetchmailMethod' => $mai_datas->{fetchmailmethod} unless param 'FetchmailMethod';
<!--
<pre>
%= dumper $mai_datas->{fetchmailmethod}
%= dumper $c->get_retrieval_opt()
%= param 'FetchmailMethod'
</pre>
-->
%= select_field 'FetchmailMethod' => $c->get_retrieval_opt(), class => 'input'
</span></p>
%=l 'mai_DESC_SMTP_AUTH_CONTROL'
%#=l 'mai_DESC_SMTP_AUTH_CONTROL'
<br />
%= l "SMTP port (25) main purpose is to receive emails from another server, STARTTLS is always offered, but auth if offered is only if STARTTLS is also used by client."
<br />
%= l "SMTPS port (465) will require implicit SSL/TLS then authenticate to send."
<br />
%= l "SMTP Submission port (587) will require STARTTLS, then authenticate to send."
<br />
% my $smtp_mesg=l('SMTP port %u allow client to authenticate:');
<p><span class=label>
%=l 'mai_LABEL_SMTP_AUTH_CONTROL'
%= sprintf($smtp_mesg,$c->get_db_prop('qpsmtpd','TCPPort',25));
</span><span class=input>
% param 'SMTPAuth' => $c->get_current_smtp_auth() unless param 'SMTPAuth';
%= select_field 'SMTPAuth' => $c->get_smtp_auth_opt(), class => 'input'
% param 'SMTPAuth' => $c->get_current_smtp_auth( FALSE ) unless param 'SMTPAuth';
<!--
<pre>
%= dumper $c->get_smtp_auth_opt()
%= dumper $c->get_current_smtp_auth(FALSE)
%= dumper $c->get_db_prop("qpsmtpd","Authentication")
%= param 'SMTPAuth'
</pre>
-->
%= select_field 'SMTPAuth' => $c->get_smtp_auth_opt(), class => 'input'
</span></p>
% my $smtp_mesg=l('SMTPS SSL/TLS auth: port %u status:');
<p><span class=label>
%= sprintf($smtp_mesg,$c->get_db_prop('sqpsmtpd','TCPPort',465));
</span><span class=input>
% param 'sSMTPAuth' => $c->get_current_smtp_ssl_auth(FALSE,'s', TRUE) unless param 'sSMTPAuth';
%= select_field 'sSMTPAuth' => $c->get_smtp_ssl_auth_opt(), class => 'input'
</span></p>
%my $smtp_mesg=l('Submission port %u status:');
<p><span class=label>
%= sprintf($smtp_mesg,$c->get_db_prop('uqpsmtpd','TCPPort',587));
</span><span class=input>
% param 'uSMTPAuth' => $c->get_current_smtp_ssl_auth(FALSE,'u', TRUE) unless param 'uSMTPAuth';
<!--
<pre>
%= dumper $c->get_smtp_ssl_auth_opt()
%= dumper $c->get_current_smtp_ssl_auth(FALSE,'s', TRUE)
%= dumper $c->get_current_smtp_ssl_auth(FALSE,'u', TRUE)
%= dumper $c->get_db_prop("uqpsmtpd","access")
%= param 'uSMTPAuth'
</pre>
-->
%= select_field 'uSMTPAuth' => $c->get_smtp_ssl_auth_opt(), class => 'input'
</span></p>
<hr class="sectionbar" />
@@ -110,4 +164,4 @@
% end
</div>
%end
%end

View File

@@ -1,9 +1,13 @@
% layout 'default', title => "Sme server 2 - emailsettings";
% content_for 'module' => begin
% use constant FALSE => 0;
% use constant TRUE => 1;
<div id='module' class='module emailsettings-panel'>
% if ($config->{debug} == 1) {
% if ($config->{debug} == TRUE) {
<p>
%= dumper $c->current_route
%= dumper $mai_datas
@@ -22,19 +26,19 @@
<p><span class=label>
%=l 'mai_LABEL_POP_ACCESS_CONTROL'
</span><span class=data2>
%= $c->get_current_pop3_access( 1 )
%= $c->get_current_pop3_access( TRUE )
</span></p>
<p><span class=label>
%=l 'mai_LABEL_IMAP_ACCESS_CONTROL'
</span><span class=data2>
%= $c->get_current_imap_access( 1 )
%= $c->get_current_imap_access( TRUE )
</span></p>
<p><span class=label>
%=l 'mai_LABEL_WEBMAIL'
</span><span class=data2>
%= $c->get_current_webmail_status( 1 )
%= $c->get_current_webmail_status( TRUE )
</span></p>
% my $btn = l('mai_DESC_STATE_ACCESS_BUTTON');
@@ -51,19 +55,19 @@
<p><span class=label>
%=l 'mai_LABEL_VIRUS_SCAN'
</span><span class=data2>
%= $c->get_virus_status(1)
%= $c->get_virus_status(TRUE)
</span></p>
<p><span class=label>
%=l 'mai_LABEL_SPAM_SCAN'
</span><span class=data2>
%= $c->get_spam_status(1)
%= $c->get_spam_status(TRUE)
</span></p>
<p><span class=label>
%=l 'mai_LABEL_BLOCK_EXECUTABLE_CONTENT'
</span><span class=data2>
%= $c->get_patterns_status(1)
%= $c->get_patterns_status(TRUE)
</span></p>
% my $btn = l('mai_DESC_STATE_FILTERING_BUTTON');
@@ -83,12 +87,28 @@
%= $mai_datas->{fetchmailmethod}
</span></p>
% my $smtp_mesg=l('SMTP port %u allow client to authenticate:');
<p><span class=label>
%=l 'mai_LABEL_SMTP_AUTH_CONTROL'
%= sprintf($smtp_mesg,$c->get_db_prop('qpsmtpd','TCPPort',25));
</span><span class=data2>
%= $c->get_current_smtp_auth( 1 )
%= $c->get_current_smtp_auth( TRUE )
</span></p>
% my $smtp_mesg=l('SMTPS SSL/TLS auth: port %u status:');
<p><span class=label>
%= sprintf($smtp_mesg,$c->get_db_prop('sqpsmtpd','TCPPort',465));
</span><span class=data2>
%= $c->get_current_smtp_ssl_auth( TRUE, 's', FALSE )
</span></p>
%my $smtp_mesg=l 'Submission port %u status:';
<p><span class=label>
%= sprintf($smtp_mesg,$c->get_db_prop('uqpsmtpd','TCPPort',587));
</span><span class=data2>
%= $c->get_current_smtp_ssl_auth( TRUE,'u', FALSE )
</span></p>
<br />
% my $btn = l('mai_DESC_STATE_RECEPTION_BUTTON');
<div class='center'>
%= submit_button "$btn", class => 'action'
@@ -103,7 +123,7 @@
<p><span class=label>
%=l 'mai_LABEL_UNKNOWN'
</span><span class=data2>
%= $c->get_emailunknownuser_status( 1 )
%= $c->get_emailunknownuser_status( TRUE )
</span></p>
<p><span class=label>
@@ -127,4 +147,4 @@
% end
</div>
%end
%end

View File

@@ -5,7 +5,7 @@
<!-- default +jquery -->
<head>
<title><%= $title %></title>
<link rev="made" href="mailto:bugs%40koozali.org">
<link rel="made" href="mailto:bugs%40koozali.org">
<meta name="copyright" content="(head.tmpl)Copyright 2003-2004 Mitel Corporation">
%= stylesheet '/css/sme_core.css'
%= stylesheet '/css/sme_main.css'
@@ -31,8 +31,23 @@
%= javascript '/js/vfs_fonts.js'
%= javascript '/js/buttons.html5.min.js'
%= javascript '/js/buttons.print.min.js'
%= javascript '/js/flag-by-locale.js'
<link rel="stylesheet" href="/smanager/css/flag-icon.min.css">
%= stylesheet '/css/sme-jquery-overrides.css'
<style>
#busy-indicator {
display: none;
margin-top: 10px;
font-weight: bold;
color: red;
}
.busy {
cursor: wait; /* Change the cursor to a 'wait' cursor */
}
</style>
</head>
@@ -92,6 +107,22 @@
% }
%= javascript '/js/sme-dataTable-setup.js'
<script>
$(document).ready(function() {
// Handle form submission for any form
$('form').on('submit', function(event) {
// Disable the submit button
$(this).find('button[type="submit"], input[type="submit"]').prop('disabled', true);
// Show the busy indicator
// $('#busy-indicator').show();
// Change the cursor to "wait"
$('body').addClass('busy');
});
});
</script>
</body>
</html>

View File

@@ -0,0 +1,69 @@
%#
%# Generated by SM2Gen version:0.8 Chameleon version:4.5.4 On Python:3.12.3 at 2024-12-01 15:22:43
%#
% layout 'default', title => "Sme server 2 - Letsencrypt certificate", share_dir => './';
%# css specific to this panel:
% content_for 'module' => begin
%= stylesheet '/css/letsencrypt.css'
<div id="module" class="module Letsencrypt-panel">
% if ($config->{debug} == 1) {
<pre>
%= dumper $c->current_route
%= dumper $lets_data->{trt}
</pre>
% }
<h1><%=$title%></h1>
% if ( stash('modul')) {
%= $c->render_to_string(inline => stash('modul') );
% }
%if ($c->stash('first')) {
<br><p>
%=$c->render_to_string(inline =>$c->l($c->stash('first')))
</p>
%} elsif ($c->stash('success')) {
<div class='success '>
<h2><%=$c->l('lets_Status_Report') %></h2><p>
%= $c->l($c->stash('success'));
</p>
</div>
%} elsif ($c->stash('error')) {
<div class='sme-error'>
<h2><%=$c->l('lets_Error_Status_Report') %></h2><p>
%= $c->l($c->stash('error'));
</p>
</div>
%}
%#Routing to partials according to trt parameter.
%#This ought to be cascading if/then/elsif, but is easier to just stack the if/then's rather like a case statement'
% if ($lets_data->{trt} eq "LIST") {
%= include 'partials/_lets_LIST'
%}
% if ($lets_data->{trt} eq "PARAMS") {
%= include 'partials/_lets_PARAMS'
%}
% if ($lets_data->{trt} eq "CHECKALLDOMAINS") {
%= include 'partials/_lets_CHECKALLDOMAINS'
%}
% if ($lets_data->{trt} eq "CHECKALLENABLEDDOMAINS") {
%= include 'partials/_lets_CHECKALLENABLEDDOMAINS'
%}
% if ($lets_data->{trt} eq "CHECKONEDOMAIN") {
%= include 'partials/_lets_CHECKONEDOMAIN'
%}
</div>
%end

View File

@@ -46,19 +46,36 @@
%= t td => (class => 'sme-border') => $domain->{'Content'}
%= t td => (class => 'sme-border') => l('dom_' . $domain->{'Nameservers'})
% my $actionModify = "<a href='domains2?CsrfDef=TOKEN&trt=UPD&Domain=" . $domain->{Domain} . "'>" . "<button class='sme-modify-button' title=".l('MODIFY').">".l('MODIFY')."</button>" . "</a>";
% my $removable = ($domain->{Removable} || 'yes');
% my $actionRemove = '&nbsp;';
% if ($removable eq 'yes') {
% $actionRemove = "<a href='domains2?CsrfDef=TOKEN&trt=DEL&Domain=" . $domain->{Domain} . "'>" . "<button class='sme-remove-button' title=".l('REMOVE').">".l('REMOVE')."</button>" . "</a>";
% }
<td class='sme-border' style="min-width:15em">
<%= $c->render_to_string(inline => $actionModify) %> <%= $c->render_to_string(inline => $actionRemove) %>
</td>
</tr>
%# my $actionModify = "<a href='domains2?CsrfDef=TOKEN&trt=UPD&Domain=" . $domain->{Domain} . "'>" . "<button class='sme-modify-button' title=".l('MODIFY').">".l('MODIFY')."</button>" . "</a>";
%my $modify_text = l('MODIFY'); # Localized text
%my $csrf_token = "TOKEN"; # CSRF token for security
%my $domain_name = $domain->{Domain}; # Domain name extracted from the data structure
%my $actionModify = qq{
% <a href="domains2?CsrfDef=$csrf_token&trt=UPD&Domain=$domain_name">
% <button type='button' class='sme-modify-button' title='$modify_text' >
% $modify_text
% </button>
% </a>
%};
%my $removable = ($domain->{Removable} || 'yes');
%my $actionRemove = '&nbsp;';
%if ($removable eq 'yes') {
%my $remove_text = l('REMOVE'); # Localized text
%my $csrf_token = "TOKEN"; # CSRF token for security
%my $domain_name = $domain->{Domain}; # Domain name extracted from the data structure
%$actionRemove = qq{
% <a href="domains2?CsrfDef=$csrf_token&trt=DEL&Domain=$domain_name">
% <button type='button' class='sme-remove-button' title='$remove_text' >
% $remove_text
% </button>
% </a>
%};
%# $actionRemove = "<a href='domains2?CsrfDef=TOKEN&trt=DEL&Domain=" . $domain->{Domain} . "'>" . "<button class='sme-remove-button' title=".l('REMOVE').">".l('REMOVE')."</button>" . "</a>";
%};
<td class='sme-border' style="min-width:15em">
<%= $c->render_to_string(inline => $actionModify) %> <%= $c->render_to_string(inline => $actionRemove) %>
</td>
</tr>
% }
</tbody>

View File

@@ -1,11 +1,11 @@
<div id="footer">
<HR class="sme-copyrightbar">
<a href="https://mojolicious.org" target="_blank"><img src="images/sme-mojo-logo-white.png" style="position:relative;"></a>
<font class="sme-copyright">
% if ( $c->is_logged_in ) {
SME Server <%= session 'releaseVersion' %> - Manager <%= $c->app->VERSION %>
SME Server <%= session 'releaseVersion' %>-<%= $c->app->VERSION %> Manager II
% }
<br>Copyright 1999-2006 Mitel Corporation<br>
%= session 'copyRight'
<br>Copyright (c) 2013-2024 Koozali Foundation Inc.<br>
</font>
</font>

View File

@@ -39,8 +39,27 @@
%= t td => (class => 'sme-border') => $group->key
%= t td => (class => 'sme-border') => $group->prop('Description')
<td class='sme-border' style="min-width:15em">
<a href='groups2?CsrfDef=TOKEN&trt=UPD&group=<%= $group->key%>'><button class='sme-modify-button' title=<%=l('MODIFY')%>><%=l('MODIFY') %></button></a>
<a href='groups2?CsrfDef=TOKEN&trt=DEL&group=<%= $group->key%>'><button class='sme-remove-button' title=<%=l('REMOVE')%>><%=l('REMOVE') %></button></a>
%my $modify_text = l('MODIFY'); # Localized text
%my $csrf_token = "TOKEN"; # CSRF token for security
%my $group_name = $group->key; # group name extracted from the data structure
%my $actionModify = qq{
% <a href="groups2?CsrfDef=$csrf_token&trt=UPD&group=$group_name">
% <button type='button' class='sme-modify-button' title='$modify_text' >
% $modify_text
% </button>
% </a>
%};
%my $remove_text = l('REMOVE'); # Localized text
%my $csrf_token = "TOKEN"; # CSRF token for security
%my $group_name = $group->key; # group name extracted from the data structure
%my $actionRemove = qq{
% <a href="groups2?CsrfDef=$csrf_token&trt=DEL&group=$group_name">
% <button type='button' class='sme-remove-button' title='$remove_text' >
% $remove_text
% </button>
% </a>
%};
<%= $c->render_to_string(inline => $actionModify) %> <%= $c->render_to_string(inline => $actionRemove) %>
</td>
</tr>
% }

View File

@@ -1,27 +1,128 @@
<style>
#h2l1 {
display: flex; /* Use flexbox layout */
justify-content: space-between; /* Space between child elements */
align-items: center; /* Center items vertically */
}
#h2e11 {
flex: 1; /* Allow the first div to take available space on the left */
}
#h2e12 {
display: flex; /* Make this div a flex container */
align-items: center; /* Vertically center content in this div */
margin-left: 20px; /* Add margin to the left of this div */
}
#flag-container {
display: flex; /* Make this div a flex container */
align-items: center; /* Vertically center content in this div */
margin-left: 20px; /* Add margin to the left of the flag container */
padding-right: 20px; /* Add padding to the right side of the flag container */
}
.flag-icon {
width: 43px;
font-size: 20px;
}
#legacy-button button {
background-color: #98d36e; /* Button background color */
font-weight: lighter; /* Lighter text for the button */
color: #063; /* Button text color */
padding: 5px 10px; /* Padding for the button */
border: none; /* Remove default button border */
border-radius: 4px; /* Rounded corners for button */
cursor: pointer; /* Change cursor on hover */
}
#legacy-button button:hover {
background-color: #82c961; /* Change color on hover */
}
.infobar {
display: flex; /* Use flexbox for alignment */
justify-content: space-between; /* Space between child elements */
align-items: center; /* Center items vertically */
padding: 10px; /* Adjust padding as desired */
}
#h2e21 {
flex: 1; /* Allow the first div to take available space on the left */
}
#h2e22 {
display: flex; /* Make this div a flex container */
justify-content: center; /* Center the help button */
align-items: center; /* Center vertically */
flex: none; /* Prevent this div from growing */
position: relative; /* Relative position for centering */
width: 100px; /* Set a width for the help button container */
}
#h2e23 {
margin-left: auto; /* Push the third div to the right */
}
.login-button {
background-color: #98d36e; /* Button background color */
font-weight: bold; /* Bold text */
xxcolor: #ffffff; /* Button text color */
padding: 8px 12px; /* Adjust padding for button height */
border: none; /* Remove default border */
border-radius: 4px; /* Rounded corners */
cursor: pointer; /* Change cursor on hover */
}
.login-button:hover {
background-color: #82c961; /* Change color on hover */
}
#help-button {
text-decoration: none; /* Remove underline from link */
font-size: 20px; /* Adjust font size as needed */
padding: 8px 12px; /* Add padding to the help link */
background-color: #98d36e; /* Background for visibility */
border-radius: 4px; /* Rounded corners */
color: #000; /* Button text color */
}
#help-button:hover {
background-color: #82c961; /* Change background on hover */
}
</style>
<div id="header2" class="hd2">
<div id="h2l1">
<div id="h2e11">
<a target='_blank' href="http://www.koozali.org"><img src="images/smeserver_logo.jpg" height="40" alt="SME Server"></a>
</div>
<!-- <div id="h2e12"><h5><a href="initial">Server Manager</a>
<a href="/server-manager" target='_blank'>&nbsp &nbsp (Prev SM)</a></h5> -->
<div id="h2e12" style="float:right;"><br><a href="/server-manager" target='_blank'><button style="background-color:#98d36e;font-weight:bold;color:#063;">Legacy SM</button></a></div>
</div>
<div id="h2e11">
<a target='_blank' href="http://www.koozali.org"><img src="images/smeserver_logo.jpg" height="40" alt="SME Server"></a>
</div>
<div id="h2l2" class="infobar">
<div id="h2e21">
<b>
<%= session 'SystemName' %>@<%= session 'DomainName' %></b>
</div>
<div id="h2e22">
<a target="_parent" href="manual">&nbsp;&nbsp;<b> ? </b>&nbsp;&nbsp;</a>&nbsp;
</div>
<div id="h2e23">
% if ( not defined $c->session->{username} ) {
<a target="_parent" href="login"><b>Login</b></a>&nbsp;
% } else {
<a target="_parent" href="logout"><b><%= $c->session->{username} %> Logout</b></a>&nbsp;
% }
</div>
<div id="h2e22">
<button type='button'><a id="help-button" target="_parent" href="manual">?</a></button>
</div>
<div id="h2e12">
<button type='button'><a id="legacy-button" href="/server-manager" target='_blank'>Legacy SM</a></button>
</div>
<div id="h2e23">
% if ( not defined $c->session->{username} ) {
<button type='button' class="login-button"><a target="_parent" href="login">Login</a></button>
% } else {
<button type='button' class="login-button"><a target="_parent" href="logout"><%= $c->session->{username} %> Logout</a></button>
% }
</div>
<div id="flag-container">
<!-- The flag icon will be inserted here -->
</div>
</div>
</div>
<div id="h2l2" class="infobar">
<div id="h2e21">
<b>
<%= session 'SystemName' %>@<%= session 'DomainName' %></b>
</div>
</div>
</div>

View File

@@ -49,25 +49,36 @@
%= t td => (class => 'sme-border') => $_->{'IP'};
%= t td => (class => 'sme-border') => $_->{'MACAddress'};
%= t td => (class => 'sme-border') => $_->{'Comment'};
% my ($actionModify, $actionRemove) = '&nbsp;';
% if ($_->{'static'} ne 'yes') {
% $actionModify = "<a href='hostentriesd?CsrfDef=TOKEN&trt=UPD&Hostname=" . $_->{'HostName'} . "'>" . "<button class='sme-modify-button' title=".l('MODIFY').">".l('MODIFY')."</button>" . "</a>";
% $actionRemove = "<a href='hostentriesd?CsrfDef=TOKEN&trt=DEL&Hostname=" . $_->{'HostName'} . "'>" . "<button class='sme-remove-button' title=".l('REMOVE').">".l('REMOVE')."</button>" . "</a>";
% }
<td class='sme-border' style="min-width:15em">
<%= $c->render_to_string(inline => $actionModify) %>
<%= $c->render_to_string(inline => $actionRemove) %>
%my ($actionModify, $actionRemove) = '&nbsp;';
%my $static = $_->{'static'} || "no";
%if ($static ne 'yes') {
%my $modify_text = l('MODIFY'); # Localized text
%my $csrf_token = "TOKEN"; # CSRF token for security
%my $hostentries_name = $_->{'HostName'}; # hostentries name extracted from the data structure
%$actionModify = qq{
% <a href="hostentriesd?CsrfDef=$csrf_token&trt=UPD&Hostname=$hostentries_name">
% <button type='button' class='sme-modify-button' title='$modify_text' >
% $modify_text
% </button>
% </a>
%};
%my $remove_text = l('REMOVE'); # Localized text
%my $csrf_token = "TOKEN"; # CSRF token for security
%#my $hostentries_name = $_->{'HostName'}; # hostentries name extracted from the data structure
%$actionRemove = qq{
% <a href="hostentriesd?CsrfDef=$csrf_token&trt=DEL&Hostname=$hostentries_name">
% <button type='button' class='sme-remove-button' title='$remove_text' >
% $remove_text
% </button>
% </a>
%};
%}
<%= $c->render_to_string(inline => $actionModify) %> <%= $c->render_to_string(inline => $actionRemove) %>
</td>
</tr>
% }
</tbody>
</table>
</p>
% }
</tbody>
</table>
% }
</div>

View File

@@ -46,29 +46,62 @@
<tr>
%= t td => (class => 'sme-border') => $ibay->key
%= t td => (class => 'sme-border') => $ibay->prop('Name')
% my ($actionModify, $actionResetPw, $actionRemove) = '&nbsp;';
% if ($modifiable eq 'yes') {
% $actionModify = "<a href='ibaysd?CsrfDef=TOKEN&trt=UPD&ibay=" . $ibay->key . "'>" . "<button class='sme-modify-button' title=".l('MODIFY').">".l('MODIFY')."</button>" . "</a>";
% }
% if ($passwordable eq 'yes') {
% if ($ibay->prop('PasswordSet') ne 'yes' && $needPassword) {
%# $actionResetPw .= "<a href='ibaysd?CsrfDef=TOKEN&trt=PWD&ibay=" . $ibay->key . "' class='error'>" . l('PASSWORD_RESET') . "</a>";
% $actionResetPw .= "<a href='ibaysd?CsrfDef=TOKEN&trt=PWD&ibay=" . $ibay->key. "'>" . "<button class='sme-password-button' style ='border-color:red;' title=".l("Reset-Password").">".l("Reset-Password")."</button></a>";
% } else {
% $actionResetPw .= "<a href='ibaysd?CsrfDef=TOKEN&trt=PWD&ibay=" . $ibay->key . "'>" . "<button class='sme-password-button' title=".l("Reset-Password").">".l("Reset-Password")."</button></a>";
%# $actionResetPw .= "<a href='ibaysd?CsrfDef=TOKEN&trt=PWD&ibay=" . $ibay->key . "'>" . l('PASSWORD_RESET') . "</a>";
% }
% $actionResetPw .= '&nbsp';
% }
% if ($removable eq 'yes') {
% $actionRemove = "<a href='ibaysd?CsrfDef=TOKEN&trt=DEL&ibay=" . $ibay->key . "'>" . "<button class='sme-remove-button' title=".l('REMOVE').">".l('REMOVE')."</button>" . "</a>";
% }
<td class='sme-border' style="min-width:20em">
<td class='sme-border' style="min-width:15em">
%my ($actionModify, $actionResetPw, $actionRemove) = '&nbsp;';
%if ($modifiable eq 'yes') {
%my $modify_text = l('MODIFY'); # Localized text
%my $csrf_token = "TOKEN"; # CSRF token for security
%my $ibays_entry_name = $ibay->key; # ibays_entry name extracted from the data structure
%$actionModify = qq{
% <a href="ibaysd?CsrfDef=$csrf_token&trt=UPD&ibay=$ibays_entry_name">
% <button type='button' class='sme-modify-button' title='$modify_text' >
% $modify_text
% </button>
% </a>
%};
%}
%if ($passwordable eq 'yes') {
%my $password_text = l('PASSWORD_RESET'); # Localized text
%my $csrf_token = "TOKEN"; # CSRF token for security
%my $ibays_entry_name = $ibay->key; # ibays_entry name extracted from the data structure
%if ($ibay->prop('PasswordSet') ne 'yes' && $needPassword) {
%$actionResetPw = qq{
% <a href="ibaysd?CsrfDef=$csrf_token&trt=PWD&ibay=$ibays_entry_name">
% <button type='button' class='sme-password-button unset' title="$password_text - currently unset" style = background:pink; >
% $password_text
% </button>
% </a>
%};
%} else {
%$actionResetPw = qq{
% <a href="ibaysd?CsrfDef=$csrf_token&trt=PWD&ibay=$ibays_entry_name">
% <button type='button' class='sme-password-button' title='$password_text' >
% $password_text
% </button>
% </a>
%};
%}
%}
%if ($removable eq 'yes') {
%my $remove_text = l('REMOVE'); # Localized text
%my $csrf_token = "TOKEN"; # CSRF token for security
%my $ibays_entry_name = $ibay->key; # ibays_entry name extracted from the data structure
%$actionRemove = qq{
% <a href="ibaysd?CsrfDef=$csrf_token&trt=DEL&ibays=$ibays_entry_name">
% <button type='button' class='sme-remove-button' title='$remove_text' >
% $remove_text
% </button>
% </a>
%};
%}
<%= $c->render_to_string(inline => $actionModify) %>
<%= $c->render_to_string(inline => $actionResetPw)%>
<%= $c->render_to_string(inline => $actionRemove) %>
</td>
</tr>
</td>
</tr>
% }
</tbody>
</table>

View File

@@ -0,0 +1,45 @@
%#
%# Generated by SM2Gen version:0.8 Chameleon version:4.5.4 On Python:3.12.3 at 2024-12-01 15:22:43
%#
<div id="Letsencrypt-CHECKALLDOMAINS" class="partial Letsencrypt-CHECKALLDOMAINS">
<script>
window.onload = function() {
SelectInput();
};
</script>
% if ($config->{debug} == 1) {
<pre>
%= dumper $lets_data
</pre>
% }
% my $btn = l('lets_APPLY');
%= form_for "letsencryptu" => (method => 'POST') => begin
% param 'trt' => $lets_data->{trt} unless param 'trt';
%= hidden_field 'trt' => $lets_data->{trt}
%# Inputs etc in here.
<h1 class='head'><%=l('lets_Check_all_domains')%></h1>
<h2 class='subh'><%=l('lets_Loop_through_checking_the_letsencrypt')%></h2>
<span class=label>
%=l('lets_All_domains_check_result')
</span><span class=data>
% param 'AllDomainsCheck' => $lets_data->{AllDomainsCheck} unless param 'AllDomainsCheck';
%= text_area 'AllDomainsCheck', cols=>40, rows=>10, Readonly=>'true'
</span><br>
<span class='data'>
%my $back_text = l('lets_Back'); # Localized text
%my $actionBack = qq{
% <a href="letsencryptd">
% <input class='action back' type='submit' value='$back_text'>
% </a>
%};
<%= $c->render_to_string(inline => $actionBack) %>
</span>
%# Probably finally by a submit.
%end
</div>

View File

@@ -0,0 +1,45 @@
%#
%# Generated by SM2Gen version:0.8 Chameleon version:4.5.4 On Python:3.12.3 at 2024-12-01 15:22:43
%#
<div id="Letsencrypt-CHECKALLENABLEDDOMAINS" class="partial Letsencrypt-CHECKALLENABLEDDOMAINS">
<script>
window.onload = function() {
SelectInput();
};
</script>
% if ($config->{debug} == 1) {
<pre>
%= dumper $lets_data
</pre>
% }
% my $btn = l('lets_APPLY');
%= form_for "letsencryptu" => (method => 'POST') => begin
% param 'trt' => $lets_data->{trt} unless param 'trt';
%= hidden_field 'trt' => $lets_data->{trt}
%# Inputs etc in here.
<h1 class='head'><%=l('lets_Check_all_enabled_domains')%></h1>
<h2 class='subh'><%=l('lets_Loop_through_checking_the_letsencrypt')%></h2>
<span class=label>
%=l('lets_Enabled_domains_check_result')
</span><span class=data>
% param 'EnabledDomainsCheck' => $lets_data->{EnabledDomainsCheck} unless param 'EnabledDomainsCheck';
%= text_area 'EnabledDomainsCheck', cols=>40, rows=>10, Readonly=>'true'
</span><br>
<span class='data'>
%my $back_text = l('lets_Back'); # Localized text
%my $actionBack = qq{
% <a href="letsencryptd">
% <input class='action back' type='submit' value='$back_text'>
% </a>
%};
<%= $c->render_to_string(inline => $actionBack) %>
</span>
%# Probably finally by a submit.
%end
</div>

View File

@@ -0,0 +1,52 @@
%#
%# Generated by SM2Gen version:0.8 Chameleon version:4.5.4 On Python:3.12.3 at 2024-12-01 15:22:43
%#
<div id="Letsencrypt-CHECKONEDOMAIN" class="partial Letsencrypt-CHECKONEDOMAIN">
<script>
window.onload = function() {
SelectInput();
};
</script>
% if ($config->{debug} == 1) {
<pre>
%= dumper $lets_data
</pre>
% }
% my $btn = l('lets_APPLY');
%= form_for "letsencryptu" => (method => 'POST') => begin
% param 'trt' => $lets_data->{trt} unless param 'trt';
%= hidden_field 'trt' => $lets_data->{trt}
%# Inputs etc in here.
<h1 class='head'><%=l('lets_Check_just_one_domain')%></h1>
<h2 class='subh'><%=l('lets_Loop_through_and_check_the')%></h2>
<p><span class=label>
%=l('lets_Domains_name')
</span><span class=data>
% param 'OneDomainToCheck' => $lets_data->{OneDomainToCheck} unless param 'OneDomainToCheck';
%= text_field 'OneDomainToCheck', size => '50', class => 'textinput OneDomainToCheck' , pattern=>'.*' , placeholder=>'OneDomainToCheck', Readonly=>'true'
<br></span></p>
<span class=label>
%=l('lets_One_domain_check_result')
</span><span class=data>
% param 'OneDomainsCheck' => $lets_data->{OneDomainsCheck} unless param 'OneDomainsCheck';
%= text_area 'OneDomainsCheck', cols=>40, rows=>10, Readonly=>'true'
</span><br>
<span class='data'>
%my $back_text = l('lets_Back'); # Localized text
%my $actionBack = qq{
% <a href="letsencryptd">
% <input class='action back' type='submit' value='$back_text'>
% </a>
%};
<%= $c->render_to_string(inline => $actionBack) %>
</span>
%# Probably finally by a submit.
%end
</div>

View File

@@ -0,0 +1,126 @@
%#
%# Generated by SM2Gen version:0.8 Chameleon version:4.5.4 On Python:3.12.3 at 2024-12-01 15:22:43
%#
<div id="Letsencrypt-LIST" class="partial Letsencrypt-LIST">
<script>
window.onload = function() {
SelectInput();
};
</script>
% if ($config->{debug} == 1) {
<pre>
%= dumper $lets_data
</pre>
% }
% my $btn = l('lets_APPLY');
%= form_for "letsencryptu" => (method => 'POST') => begin
% param 'trt' => $lets_data->{trt} unless param 'trt';
%= hidden_field 'trt' => $lets_data->{trt}
%# Inputs etc in here.
<div class=inline-buttons>
<a href='letsencryptd?trt=PARAMS' class='link link2'>
%= l('lets_CONFIG')
</a>
%#= link_to l('lets_CONFIG'), 'letsencryptd?trt=PARAMS' , class=>'link link2'
<a href='letsencryptd?trt=CHECKALLDOMAINS' class='link link3'>
%= l('lets_CHECK_ALL_DOMAINS')
</a>
%#= link_to l('lets_CHECK_ALL_DOMAINS'), 'letsencryptd?trt=CHECKALLDOMAINS' , class=>'link link3'
<a href='letsencryptd?trt=CHECKALLENABLEDDOMAINS' class='link link4'>
%= l('lets_CHECK_ALL_ENABLED_DOMAINS')
</a>
%#= link_to l('lets_CHECK_ALL_ENABLED_DOMAINS'), 'letsencryptd?trt=CHECKALLENABLEDDOMAINS' , class=>'link link4'
</div>
<h2 class='subh2'><%=l('lets_For_this_Server')%></h2>
<p><span class=label>
%=l('lets_Internal_IP')
</span><span class=data>
% param 'InternalIP' => $lets_data->{InternalIP} unless param 'InternalIP';
%= text_field 'InternalIP', size => '50', class => 'textinput InternalIP' , pattern=>'.*' , placeholder=>'InternalIP', Readonly=>'true'
<br></span></p>
<p><span class=label>
%=l('lets_External_Interface_IP')
</span><span class=data>
% param 'ExternalIP' => $lets_data->{ExternalIP} unless param 'ExternalIP';
%= text_field 'ExternalIP', size => '50', class => 'textinput ExternalIP' , pattern=>'.*' , placeholder=>'ExternalIP', Readonly=>'true'
<br></span></p>
<p><span class=label>
%=l('lets_Internet_IP')
</span><span class=data>
% param 'InternetIP' => $lets_data->{InternetIP} unless param 'InternetIP';
%= text_field 'InternetIP', size => '50', class => 'textinput InternetIP' , pattern=>'.*' , placeholder=>'InternetIP', Readonly=>'true'
<br></span></p>
<h2 class='subh3'><%=l('lets_Current_certificate_details')%></h2>
<p><span class=label>
%=l('lets_Issuer')
</span><span class=data>
% param 'Issuer' => $lets_data->{Issuer} unless param 'Issuer';
%= text_field 'Issuer', size => '50', class => 'textinput Issuer' , pattern=>'.*' , placeholder=>'Issuer', Readonly=>'true'
<br></span></p>
<p><span class=label>
%=l('lets_Expiry')
</span><span class=data>
% param 'Expiry' => $lets_data->{Expiry} unless param 'Expiry';
%= text_field 'Expiry', size => '50', class => 'textinput Expiry' , pattern=>'.*' , placeholder=>'Expiry', Readonly=>'true'
<br></span></p>
<p><span class=label>
%=l('lets_Not_Before')
</span><span class=data>
% param 'NotBefore' => $lets_data->{NotBefore} unless param 'NotBefore';
%= text_field 'NotBefore', size => '50', class => 'textinput NotBefore' , pattern=>'.*' , placeholder=>'NotBefore', Readonly=>'true'
<br></span></p>
<h2 class='subh4'><%=l('lets_List_of_Domains_and_Hosts')%></h2>
<br /><table class="sme-border TableSort sme-table tabl1 ">
<thead class='tabl1'>
<tr table-head-row>
<th class='sme-border table-head-col table-head-col-Domain name / HOSTNAME '><%=l('lets_Domain_name_/_HOSTNAME')%></th>
<th class='sme-border table-head-col table-head-col-Brief description '><%=l('lets_Brief_description')%></th>
<th class='sme-border table-head-col table-head-col-Content '><%=l('lets_Content')%></th>
<th class='sme-border table-head-col table-head-col-LABEL_NAMESERVERS '><%=l('lets_LABEL_NAMESERVERS')%></th>
<th class='sme-border table-head-col table-head-col-LABEL_POINT '><%=l('lets_LABEL_POINT')%></th>
<th class='sme-border table-head-col table-head-col-LABEL_LECERT '><%=l('lets_LABEL_LECERT')%></th>
<th class='sme-border table-head-col table-head-col-IS_IN_CERT '><%=l('lets_IS_IN_CERT')%></th>
<th class='sme-border table-head-col table-head-col-CHECK '><%=l('lets_CHECK')%></th>
</tr>
</thead>
<tbody class='tabl1'>
% my $control_data = $c->stash('DomainList');
% foreach my $row (@$control_data) {
<tr class='table-row'>
<td class='sme-border table-col table-col-Table1-Domain name / HOSTNAME'><%=$c->render_to_string(inline=>$row->{'Table1-Domain name / HOSTNAME'})%></td>
<td class='sme-border table-col table-col-Table1-Brief description'><%=$c->render_to_string(inline=>$row->{'Table1-Brief description'})%></td>
<td class='sme-border table-col table-col-Table1-Content'><%=$c->render_to_string(inline=>$row->{'Table1-Content'})%></td>
<td class='sme-border table-col table-col-Table1-LABEL_NAMESERVERS'><%=$c->render_to_string(inline=>$row->{'Table1-LABEL_NAMESERVERS'})%></td>
<td class='sme-border table-col table-col-Table1-LABEL_POINT'><%=$c->render_to_string(inline=>$row->{'Table1-LABEL_POINT'})%></td>
<td class='sme-border table-col table-col-Table1-LABEL_LECERT'><%=$c->render_to_string(inline=>$row->{'Table1-LABEL_LECERT'})%></td>
<td class='sme-border table-col table-col-Table1-IS_IN_CERT'><%=$c->render_to_string(inline=>$row->{'Table1-IS_IN_CERT'})%></td>
<td class='sme-border table-col table-col-Table1-CHECK'><%=$c->render_to_string(inline=>$row->{'Table1-CHECK'})%></td>
</tr>
%}
</tbody>
</table>
%# Probably finally by a submit.
%end
</div>

View File

@@ -0,0 +1,97 @@
%#
%# Generated by SM2Gen version:0.8 Chameleon version:4.5.4 On Python:3.12.3 at 2024-12-01 15:22:43
%#
<div id="Letsencrypt-PARAMS" class="partial Letsencrypt-PARAMS">
<script>
window.onload = function() {
SelectInput();
};
</script>
% if ($config->{debug} == 1) {
<pre>
%= dumper $lets_data
</pre>
% }
% my $btn = l('lets_APPLY');
%= form_for "letsencryptu" => (method => 'POST') => begin
% param 'trt' => $lets_data->{trt} unless param 'trt';
%= hidden_field 'trt' => $lets_data->{trt}
%# Inputs etc in here.
<h2 class='subh'><%=l('lets_Manage_letsencrypt-config_settings:')%></h2>
<p class='paragraph para1'>
%=l('lets_CONFIG_LETSENCRYPT')
</p>
<p><span class=label>
%=l('lets_SERVICE_STATUS')
</span><span class=data>
% my @status_options = [['Disabled' => 'disabled'], ['Enabled' => 'enabled'], ['TEST' => 'test']];
% param 'status' => $lets_data->{status} unless param 'status';
%= select_field 'status' => @status_options, class => 'input'
<br></span> </p>
<p><span class=label>
%=l('lets_HOOKSCRIPT_STATUS')
</span><span class=data>
% my @hookScript_options = [['Disabled' => 'disabled'], ['Enabled' => 'enabled']];
% param 'hookScript' => $lets_data->{hookScript} unless param 'hookScript';
%= select_field 'hookScript' => @hookScript_options, class => 'input'
<br></span> </p>
<p><span class=label>
%=l('lets_HOSTOVERRIDE_STATUS')
</span><span class=data>
% my @hostOverride_options = [['Disabled' => 'disabled'], ['Yes' => 'yes']];
% param 'hostOverride' => $lets_data->{hostOverride} unless param 'hostOverride';
%= select_field 'hostOverride' => @hostOverride_options, class => 'input'
<br></span> </p>
<p><span class=label>
%=l('lets_ACCEPT_TERMS_STATUS')
</span><span class=data>
% my @ACCEPT_TERMS_options = [['Disabled' => 'disabled'], ['Yes' => 'yes']];
% param 'ACCEPT_TERMS' => $lets_data->{ACCEPT_TERMS} unless param 'ACCEPT_TERMS';
%= select_field 'ACCEPT_TERMS' => @ACCEPT_TERMS_options, class => 'input'
<br></span> </p>
<p><span class=label>
%=l('lets_API_STATUS')
</span><span class=data>
% my @API_options = [['2' => '2']];
% param 'API' => $lets_data->{API} unless param 'API';
%= select_field 'API' => @API_options, class => 'input'
<br></span> </p>
<p><span class=label>
%=l('lets_KEYSIZE_STATUS')
</span><span class=data>
% my @keysize_options = [['2048' => '2048'], ['3072' => '3072'], ['4096' => '4096']];
% param 'keysize' => $lets_data->{keysize} unless param 'keysize';
%= select_field 'keysize' => @keysize_options, class => 'input'
<br></span> </p>
<p><span class=label>
%=l('lets_CONFIGUREMODE_STATUS')
</span><span class=data>
% my @configure_options = [['ALL' => 'all'], ['Domains' => 'domains'], ['HOSTS' => 'hosts'], ['NONE' => 'none']];
% param 'configure' => $lets_data->{configure} unless param 'configure';
%= select_field 'configure' => @configure_options, class => 'input'
<br></span> </p>
<p><span class=label>
%=l('lets_EMAIL')
</span><span class=data>
% param 'email' => $lets_data->{email} unless param 'email';
%=email_field 'email', class => 'emai8'
</span></p>
<span class='data'>
%= submit_button l('lets_Save'), class => 'action subm9'
</span>
%# Probably finally by a submit.
%end
</div>

View File

@@ -60,9 +60,10 @@
<span class=data>
%=text_field 'networkRouter'
</span><br><br>
<div class='center'>
%= submit_button "$btn", class => 'action'
</div>
<p>
<br>
%= submit_button "$btn", class => 'action'
</p>
%end
</div>

View File

@@ -49,9 +49,11 @@
</span><br><br>
%}
%= hidden_field localnetwork=>$localnetwork
<div class='center'>
%= submit_button "$btn", class => 'action'
</div>
<p>
<br>
%= submit_button "$btn", class => 'action'
</p>
%end
</div>

View File

@@ -1,7 +1,6 @@
<div id='ln_list'>
% my $btn = l('ln_LOCALNETWORK_ADD');
%= form_for '/localnetworksa' => (method => 'POST') => begin
<p>
% my $retref= $c->stash("ret");
% my %ret;
@@ -37,10 +36,12 @@
%= $c->render_to_string(inline => l($ret{ret},$var1,$var2,$var3,$var4,$var5,$var6,$var7));
</div>
%}
<br><br>
<div class='center'>
<p>
<br>
%= submit_button "$btn", class => 'action'
</div>
</p>
% end
<br>
@@ -66,10 +67,10 @@
%=l 'ROUTER'
</th>
<th class='sme-border' '>
<th class='sme-border'>
%=l 'ACTION'
</th>
</tr>
</tr>
</thead><tbody>
% foreach my $localnetwork (@$localnetworks )
% {
@@ -82,18 +83,24 @@
%= t td => (class => 'sme-border') => $localnetwork->prop('Mask')
%= t td => (class => 'sme-border') => $num_hosts
%= t td => (class => 'sme-border') => $localnetwork->prop('Router')
% if ($removable eq "yes") {
<td class='sme-border'>
<a href="localnetworksd?CsrfDef=TOKEN&trt=DEL&localnetwork=<%= $localnetwork->key%>"><button class='sme-remove-button' title="<%=l('REMOVE')%>"><%=l('REMOVE') %></button></a></td>
% } else {
<td class='sme-border'> </td>
%}
%my $actionRemove = '&nbsp;';
%if ($removable eq "yes") {
%my $remove_text = l('REMOVE'); # Localized text
%my $local_network_entry = $localnetwork->key;
%my $csrf_token = "TOKEN"; # CSRF token for security
%$actionRemove = qq{
% <a href="localnetworksd?CsrfDef=$csrf_token&trt=DEL&localnetwork=$local_network_entry">
% <button type='button' class='sme-remove-button' title='$remove_text' >
% $remove_text
% </button>
% </a>
%};
% }
<td class='sme-border'><%= $c->render_to_string(inline => $actionRemove) %></td>
</tr>
% }
</tbody>
</table>
</p>
%= hidden_field 'trt' => $ln_datas->{trt}
%}
</div>

View File

@@ -5,7 +5,7 @@
<!-- <a href='#' id='tognav' class='menu-title'>NAVIGATION</a> -->
<div id='menunav'>
% my $cc = 1;
% my $cc = 200;
% foreach my $h (sort { ($nav{$a}{'WEIGHT'}/$nav{$a}{'COUNT'})
% <=> ($nav{$b}{'WEIGHT'}/$nav{$b}{'COUNT'}) } keys %nav) {
%
@@ -33,4 +33,4 @@
% }
</div>
</div>
</div>

View File

@@ -5,7 +5,7 @@
<!-- ><div><a href='#' id='togadm' class='menu-title'>ADMINISTRATION</a></div> -->
<div id='menuadm'>
% my $cc = 1;
% my $cc = 100;
% foreach my $h (sort { ($nav{$a}{'WEIGHT'}/$nav{$a}{'COUNT'})
% <=> ($nav{$b}{'WEIGHT'}/$nav{$b}{'COUNT'}) } keys %nav) {
<div><a href='#' class='section section-title'><%= $h %></a></div>
@@ -35,4 +35,4 @@
% }
</div>
</div>
</div>

View File

@@ -77,9 +77,11 @@
<span class=data>
%=text_field 'cmmnt'
</span><br><br>
<div class='center'>
%= submit_button "$btn", class => 'action'
</div>
<p>
<br>
%= submit_button "$btn", class => 'action'
</p>
%end
</div>

View File

@@ -57,9 +57,10 @@
%#}
%= hidden_field sport=>$sport
%= hidden_field proto=>$proto
<div class='center'>
%= submit_button "$btn", class => 'action'
</div>
<br>
%= submit_button "$btn", class => 'action'
</p>
%end
</div>

View File

@@ -18,8 +18,6 @@
% my $var5 = @vars[4];
% my $var6 = @vars[5];
%if ($ret{ret} eq "") {
%= $c->render_to_string(inline => l('pf_FIRST_PAGE_DESCRIPTION'));
%} elsif (index($ret{ret},"SUCCESS") != -1) {
@@ -33,21 +31,22 @@
%= $c->l($ret{ret},$var1,$var2,$var3,$var4,$var5,$var6);
</div>
%}
<br><br>
<div class='center'>
<p>
<br>
%= submit_button "$btn", class => 'action'
</div>
</p>
% end
<br>
% if ($empty){
<br>
%=l 'pf_NO_FORWARDS'
% } else {
<br>
%=l 'pf_SHOW_FORWARDS'
<br>
<br><br />
<table class="sme-border TableSort"><thead>
<tr>
<th class='sme-border'>
@@ -94,7 +93,16 @@
%= t td => (class => 'sme-border') => $allow
%= t td => (class => 'sme-border') => $cmmnt
<td class='sme-border'>
<a href="portforwardingd?CsrfDef=TOKEN&trt=DEL&sport=<%= $sport%>&proto=<%= $proto%>"><button class='sme-remove-button' title="<%=l('REMOVE')%>"><%=l('REMOVE') %></button></a>
%my $remove_text = l('REMOVE'); # Localized text
%my $csrf_token = "TOKEN"; # CSRF token for security
%my $actionRemove = qq{
% <a href="portforwardingd?CsrfDef=$csrf_token&trt=DEL&sport=$sport&proto=$proto">
% <button type='button' class='sme-remove-button' title='$remove_text' >
% $remove_text
% </button>
% </a>
%};
<%= $c->render_to_string(inline => $actionRemove) %>
</td>
</tr>
% }
@@ -106,4 +114,3 @@
%= hidden_field 'trt' => $pf_datas->{trt}
</div>

View File

@@ -57,7 +57,19 @@
%= t td => (class => 'sme-border') => $printer->prop('Location')
%= t td => (class => 'sme-border') => $address
%= t td => (class => 'sme-border') => $remoteName
<td class='sme-border'><a href="printers2?CsrfDef=TOKEN&trt=DEL&printer=<%= $printer->key%>"><button class='sme-remove-button' title="<%=l('REMOVE')%>"><%=l('REMOVE') %></button></a></td>
<td class='sme-border'>
%my $remove_text = l('REMOVE'); # Localized text
%my $csrf_token = "TOKEN"; # CSRF token for security
%my $printer_name = $printer->key;
%my $actionRemove = qq{
% <a href="printers2?CsrfDef=$csrf_token&trt=DEL&&printer=$printer_name">
% <button type='button' class='sme-remove-button' title='$remove_text' >
% $remove_text
% </button>
% </a>
%};
<%= $c->render_to_string(inline => $actionRemove) %>
</td>
</tr>
% }
</tbody>

View File

@@ -54,19 +54,37 @@
%= t td => (class => 'sme-border') => $pseudonym->key
%= t td => (class => 'sme-border') => $account
% my ($actionModify, $actionRemove) = '&nbsp;';
% if ($modifiable eq 'yes') {
% $actionModify = "<a href='pseudonyms2?CsrfDef=TOKEN&trt=UPD&pseudonym=" . $pseudonym->key . "'>" . "<button class='sme-modify-button' title=".l('MODIFY').">".l('MODIFY')."</button>" . "</a>";
% }
% if ($removable eq 'yes') {
% $actionRemove = "<a href='pseudonyms2?CsrfDef=TOKEN&trt=DEL&pseudonym=" . $pseudonym->key . "'>" . "<button class='sme-remove-button' title=".l('REMOVE').">".l('REMOVE')."</button>" . "</a>";
% }
<td class='sme-border'>
%my ($actionModify, $actionRemove) = '&nbsp;';
%if ($modifiable eq 'yes') {
%my $modify_text = l('MODIFY'); # Localized text
%my $csrf_token = "TOKEN"; # CSRF token for security
%my $pseudonyms_entry_name = $pseudonym->key; # pseudonyms_entry name extracted from the data structure
%$actionModify = qq{
% <a href="pseudonyms2?CsrfDef=$csrf_token&trt=UPD&pseudonym=$pseudonyms_entry_name">
% <button type='button' class='sme-modify-button' title='$modify_text' >
% $modify_text
% </button>
% </a>
%};
%}
<td class='sme-border' style="min-width:15em">
<%= $c->render_to_string(inline => $actionModify) %>&nbsp;<%= $c->render_to_string(inline => $actionRemove) %>
</td>
</tr>
%if ($removable eq 'yes') {
%my $remove_text = l('REMOVE'); # Localized text
%my $csrf_token = "TOKEN"; # CSRF token for security
%my $pseudonyms_entry_name = $pseudonym->key; # pseudonyms_entry name extracted from the data structure
%$actionRemove = qq{
% <a href="pseudonyms2?CsrfDef=$csrf_token&trt=DEL&pseudonym=$pseudonyms_entry_name">
% <button type='button' class='sme-remove-button' title='$remove_text' >
% $remove_text
% </button>
% </a>
%};
%}
<%= $c->render_to_string(inline => $actionModify) %> <%= $c->render_to_string(inline => $actionRemove) %>
</td>
</tr>
% }
</tbody>
</table>
@@ -76,4 +94,3 @@
</div>

View File

@@ -57,7 +57,19 @@
%= t td => (class => 'sme-border') => sprintf("%.2f", $bs / 1024 )
%= t td => (class => 'sme-border') => sprintf("%.2f", $bh / 1024 )
%= t td => (class => 'sme-border') => sprintf("%.2f", $bc / 1024 )
<td class='sme-border'><a href="quotad?CsrfDef=TOKEN&trt=UPD&user=<%= $user->key%>"><button class='sme-modify-button' title="<%=l('MODIFY')%>"><%=l('MODIFY') %></button></a></td>
<td class='sme-border'>
%my $modify_text = l('MODIFY'); # Localized text
%my $csrf_token = "TOKEN"; # CSRF token for security
%my $quota_user_name = $user->key; # quotas_entry name extracted from the data structure
%my $actionModify = qq{
% <a href="quotad?CsrfDef=$csrf_token&trt=UPD&user=$quota_user_name">
% <button type='button' class='sme-modify-button' title='$modify_text' >
% $modify_text
% </button>
% </a>
%};
<%= $c->render_to_string(inline => $actionModify) %>
</td>
</tr>
% }
</tbody>

View File

@@ -37,7 +37,7 @@
%= $ic
%=l 'quo_FILES'
%=l 'quo_OCCUPYING'
%= $bc
%= $c->toMB($bc)
%=l 'quo_MEGABYTES'
</p>
@@ -81,4 +81,4 @@
% end
</div>
</div>

View File

@@ -4,7 +4,7 @@
<div id='usermenu'>
<a href='#' id='toguser' class='section section-title'>Current User (<%= session 'username' %>)</a>
<div id='menuuser'>
% my $cc = 1;
% my $cc = 300;
% foreach my $h (sort { ($nav{$a}{'WEIGHT'}/$nav{$a}{'COUNT'})
% <=> ($nav{$b}{'WEIGHT'}/$nav{$b}{'COUNT'}) } keys %nav) {
<!-- div class='section'><%= $h %></div -->
@@ -29,4 +29,4 @@
% }
</div>
</div>
</div>

View File

@@ -59,29 +59,88 @@
%= t td => (class => 'sme-border') => "$first $last"
%= t td => (class => 'sme-border') => $vpnaccess
%= t td => (class => 'sme-border') => $fwd
% my ($actionModify, $actionLock, $actionResetPw, $actionRemove) = '&nbsp;';
% if ($username eq 'admin') {
% $actionModify = "<a href='useraccountsd?CsrfDef=TOKEN&trt=UPS&user=" . $username . "'>" . "<button class='sme-modify-button' title=".l("MODIFY").">".l("MODIFY")."</button></a>";
% $actionResetPw = "<a href='useraccountsd?CsrfDef=TOKEN&trt=PWS&user=" . $username . "'>" . "<button class='sme-password-button' title=".l("Reset-Password").">".l("Reset-Password")."</button></a>";
% } else {
% $actionModify = "<a href='useraccountsd?CsrfDef=TOKEN&trt=UPD&user=" . $username . "'>" . "<button class='sme-modify-button' title=".l("MODIFY").">".l("MODIFY")."</button></a>";
% if ($password_set ne 'yes') {
% $actionLock = l('ACCOUNT_LOCKED');
% $actionResetPw = "<a href='useraccountsd?CsrfDef=TOKEN&trt=PWD&user=" . $username . "'>" . "<button class='sme-password-button' style ='border-color:red;' title=".l("Reset-Password").">".l("Reset-Password")."</button></a>";
% } else {
% $actionLock = "<a href='useraccountsd?CsrfDef=TOKEN&trt=LCK&user=" . $username . "'>" . "<button class='sme-lock-button' title=".l('usr_LOCK_ACCOUNT').">".l("usr_LOCK_ACCOUNT")."</button></a>";
% $actionResetPw = "<a href='useraccountsd?CsrfDef=TOKEN&trt=PWD&user=" . $username . "'>" . "<button class='sme-password-button' title=".l("Reset-Password").">".l("Reset-Password")."</button></a>";
% }
% if ( $removable eq 'yes' ) {
% $actionRemove = "<a href='useraccountsd?CsrfDef=TOKEN&trt=DEL&user=" . $username . "'>" . "<button class='sme-remove-button' title=".l("REMOVE").">".l("REMOVE")."</button></a>";
% }
% }
<td class='sme-border' style="min-width:35em">
%my ($actionModify, $actionLock, $actionResetPw, $actionRemove,$actionroundcube) = '&nbsp;';
%my $modify_text = l('MODIFY'); # Localized text
%my $csrf_token = "TOKEN"; # CSRF token for security
%my $useraccounts_user_name = $user->key; # useraccountss_entry name extracted from the data structure
%my $password_text = l("PASSWORD_RESET");
%if ($useraccounts_user_name eq 'admin') {
%$actionModify = qq{
% <a href="useraccountsd?CsrfDef=$csrf_token&trt=UPS&user=$useraccounts_user_name">
% <button type='button' class='sme-modify-button' title='$modify_text'>
% $modify_text
% </button>
% </a>
%};
%} else {
%$actionModify = qq{
% <a href="useraccountsd?CsrfDef=$csrf_token&trt=UPD&user=$useraccounts_user_name">
% <button type='button' class='sme-modify-button' title='$modify_text' >
% $modify_text
% </button>
% </a>
%};
%}
%if ($password_set ne 'yes') {
%$actionLock = l('ACCOUNT_LOCKED');
%$actionResetPw = qq{
% <a href="useraccountsd?CsrfDef=$csrf_token&trt=PWD&user=$useraccounts_user_name">
% <button type='button' class='sme-password-button unset' title="$password_text - currently unset" style = background:pink; >
% $password_text
% </button>
% </a>
%};
%} else {
%my $lock_text = l('ACCOUNT LOCKED'); # Localized text
%my $csrf_token = "TOKEN"; # CSRF token for security
%my $useraccounts_user_name = $user->key; # useraccountss_entry name extracted from the data structure
%$actionLock = qq{
% <a href="useraccountsd?CsrfDef=$csrf_token&trt=LCK&user=$useraccounts_user_name">
% <button type='button' class='sme-lock-button' title='$lock_text' >
% $lock_text
% </button>
% </a>
%};
%$actionResetPw = qq{
% <a href="useraccountsd?CsrfDef=$csrf_token&trt=PWD&user=$useraccounts_user_name">
% <button type='button' class='sme-password-button' title='$password_text' >
% $password_text
% </button>
% </a>
%};
%}
%if ( $removable eq 'yes' ) {
%my $remove_text = l('REMOVE'); # Localized text
%my $csrf_token = "TOKEN"; # CSRF token for security
%$actionRemove = qq{
% <a href="useraccountsd?CsrfDef=$csrf_token&trt=DEL&user=$useraccounts_user_name">
% <button type='button' class='sme-remove-button' title='$remove_text' >
% $remove_text
% </button>
% </a>
%};
%}
%my $thisdomain = session 'SystemName';
%$thisdomain .= ".".session 'DomainName';
%my $roundcube_text = l('Webmail'); # Localized text
%my $csrf_token = "TOKEN"; # CSRF token for security
%my $useraccounts_user_name = $user->key; # useraccountss_entry name extracted from the data structure
%$actionroundcube = qq{
% <a href="roundcubepanel?CsrfDef=$csrf_token&url=https://$thisdomain/roundcube?_user=$useraccounts_user_name">
% <button type='button' class='sme-email-button' title='$roundcube_text' >
% $roundcube_text
% </button>
% </a>
%};
<td class='sme-border' style="min-width:35em">
<%= $c->render_to_string(inline => $actionModify) %>
<%= $c->render_to_string(inline => $actionResetPw) %>
<%= $c->render_to_string(inline => $actionLock) %>
<%= $c->render_to_string(inline => $actionRemove) %>
</td>
<%= $c->render_to_string(inline => $actionroundcube) %>
</td>
</tr>
% }
</tbody>

View File

@@ -12,8 +12,8 @@
% if ( stash 'error' ) {
<br><div class=sme-error>
%= $c->render_to_string(inline => stash 'error')
</div>
%= $c->render_to_string(inline => stash 'error')
</div>
%}
<h1><%= $title%></h1>
@@ -29,5 +29,4 @@
%}
</div>
%end
%end

View File

@@ -52,12 +52,11 @@
<hr class='sectionbar' />
</p>
%}
<!-- percequ include 'partials/_rma_pptp' -->
<p><h2>
<h2>
%= $c->l('rma_VALIDFROM_TITLE', $c->l('rma_REMOTE_MANAGEMENT'));
</h2><br>
%=l 'rma_VALIDFROM_DESC'
@@ -86,7 +85,7 @@
%= t td => (class => 'sme-border') => $net
%= t td => (class => 'sme-border') => $mask
%= t td => (class => 'sme-border') => $numhosts
<td class='sme-border'><input type='checkbox' name='Remove_nets' value='<%= $net.'/'.$mask %>'> </td>
<td class='sme-border'><input type='checkbox' name='Remote_nets' value='<%= $net.'/'.$mask %>'> </td>
</tr>
% }
@@ -102,9 +101,6 @@
%= l('rma_NO_ENTRIES_YET');
</b>
%}
</p>
<p>
%=l 'rma_DESC_VALID_FROM_ENTRIES'
<br><br>
<span class=label>
@@ -118,11 +114,10 @@
</span><span class=data>
%= text_field 'ValidFromMask', class => 'input'
</span>
</p>
<hr class='sectionbar' />
<p><h2>
<h2>
%=l 'rma_TITLE_SSH'
</h2><br>
%=l 'rma_DESC_SSH'
@@ -158,11 +153,10 @@
%= text_field 'SshTCPPort', class => 'input'
</span>
<br>
</p>
<hr class='sectionbar' />
<p><h2>
<h2>
%=l 'rma_TITLE_FTP_ACCESS'
</h2><br>
%= $c->render_to_string(inline => $c->l('rma_DESC_FTP_ACCESS'));
@@ -186,11 +180,9 @@
%= select_field 'FtpPasswordAccess' => $c->passwordLogin_list(), class => 'input'
</span>
<br>
</p>
% my $mode = $c->get_telnet_mode();
% if ( $mode ne 'off') {
<p>
<hr class='sectionbar' />
<h2>
@@ -210,16 +202,13 @@
</span>
<br>
</p>
%}
<div class='center'>
<br>
%= submit_button "$btn", class => 'action'
</div>
% end
</div>
% end
% end

View File

@@ -0,0 +1,39 @@
% layout 'default', title => "Sme server 2 - roundcube";
% content_for 'module' => begin
<div id='roundcube' class='roundcube roundcube-panel'>
% if ($config->{debug} == 1) {
<p>
%= dumper $c->current_route
</p>
% }
% if ( stash 'error' ) {
<br><div class=sme-error>
%= $c->render_to_string(inline => stash 'error')
</div>
%}
<h1> roundcube - <%=$title %></h1><br>
<p>If the roundcube panel does not appear after logging in, then please check your password.</p><br />
% my $thisdomain = session 'SystemName';
% $thisdomain .= ".".session 'DomainName';
% my $url = $c->stash('modul');
% my $username = 'admin';
% if ($url =~ /[?&]_user=([^&]+)/) {
% $username = $1;
%}
<a href="<%= "https://".$thisdomain."/" %>roundcube?_user=<%= $username %>"><button class="sme-fullwindow1-button" width=20em title="<%= l('Full Window') %>"><%= l('Full Window') %></button></a>
% my $height = $c->stash('height') | '600px';
% if ($height !~ /px$/) { $height = $height.'px';}
% if ($url eq "") {
% $url = "https://".$thisdomain."/roundcube";
%}
<object id="roundcube" class="roundcube" data="<%=$url %>" style="width:99%;height:<%= $height %>;" title="<%= $c->stash('title') %>" type="text/html" ><%= $c->stash('title') %> not found</object>
</div>
%end

View File

@@ -66,9 +66,10 @@
</span>
<br><br></p>
<div class='center'>
%= submit_button "$btn", class => 'action'
</div>
<p>
<br>
%= submit_button "$btn", class => 'action'
</p>
% end

View File

@@ -79,9 +79,9 @@
%= hidden_field 'trt' => 'CONF'
<br>
<div class='center'>
<!--<div class='center'>-->
%= submit_button $c->l('SAVE'), class => 'action'
</div>
<!--</div>-->
% end

View File

@@ -47,9 +47,9 @@
%= hidden_field 'trt' => 'INST'
<br><br>
<div class='center'>
<!-- <div class='center'>-->
%= submit_button $c->l('yum_INSTALL_SOFTWARE'), class => 'action'
</div>
<!--</div>-->
% end

View File

@@ -34,9 +34,9 @@
%= hidden_field 'trt' => 'PSTU'
%= hidden_field 'reconf' => $yum_datas->{reconf}
<br>
<div class='center'>
<!-- <div class='center'>-->
%= submit_button "$btn", class => 'action'
</div>
<!--</div>-->
% end

View File

@@ -46,9 +46,9 @@
%= hidden_field 'trt' => 'REMO'
<br>
<div class='center'>
<!--<div class='center'>-->
%= submit_button $c->l('REMOVE'), class => 'action'
</div>
<!--</div>-->
% end

View File

@@ -33,9 +33,9 @@
%= hidden_field 'trt' => 'UPDT'
<br>
<div class='center'>
<!--<div class='center'>-->
%= submit_button $c->l('yum_INSTALL_UPDATES'), class => 'action'
</div>
<!--</div>-->
% end

0
root/var/log/smanager/.gitignore vendored Normal file
View File

View File

@@ -2,7 +2,7 @@ Summary: Sme server navigation module : manager 2
%define name smeserver-manager
Name: %{name}
%define version 11.0.0
%define release 7
%define release 33
Version: %{version}
Release: %{release}%{?dist}
License: GPL
@@ -35,6 +35,8 @@ Requires: perl(DBM::Deep) >= 2.0011-1
Requires: perl(Mojo::JWT) >= 0.08-1
Requires: mutt >= 1.5.21
Requires: smeserver-manager-jsquery >= 1.0
Requires: smeserver-lib >= 11.0
Requires: smeserver-certificates >= 11.0
#Requires: js-jquery > 2.2.4-3 (optional)
Provides: server-manager
@@ -49,6 +51,11 @@ This RPM contributes the navigation bars for the smeserver-manager. New Mojolici
%setup
%build
#extract the release number and drop it in to the version for SM2 footer.
sed -i "s/our \$VERSION = '[^']*'/our \$VERSION = '%{release}'/g" root/usr/share/smanager/lib/SrvMngr.pm
perl createlinks
# Force creation of potentially empty directories
@@ -108,6 +115,94 @@ true
%defattr(-,root,root)
%changelog
* Mon Dec 30 2024 Jean-Philippe Pialasse <jpp@koozali.org> 11.0.0-33.sme
- host locally flag-icon.min.css 3.5.0 [SME: 12845]
- remove onclick to comply with strict CSP [SME: 12846]
- add CSP rules with specific hash [SME: 12840]
* Wed Dec 18 2024 Brian Read <brianr@koozali.org> 11.0.0-32.sme
- Fix for User and localnetwork panel [SME: 6278]
- Fix menu entry for proxy to stop it moving
* Tue Dec 17 2024 Brian Read <brianr@koozali.org> 11.0.0-31.sme
- Edit html to avoid w3c html validation warnings [SME: 6278]
* Fri Dec 13 2024 Brian Read <brianr@koozali.org> 11.0.0-30.sme
- Add in letsencrypt panel, add requires for smeserver-lib and smeserver-certificates [SME: 12810]
* Tue Nov 26 2024 Brian Read <brianr@koozali.org> 11.0.0-29.sme
- Fix remoteaccess panel, reformat pm file and bring success panel into line with other similar panels [SME: 12747]
* Fri Oct 18 2024 Brian Read <brianr@koozali.org> 11.0.0-28.sme
- Add in emailsettings for port 25,465 and 587 [SME: 12750]
- Comment out change to localhost for roundcube in _user_list email icon setting [SME: 12751]
* Sun Oct 06 2024 Brian Read <brianr@koozali.org> 11.0.0-27.sme
- Add in change to _user_list.html.ep for access to roundcube email from useraccounts [SME: 12751]
* Fri Oct 04 2024 Brian Read <brianr@koozali.org> 11.0.0-26.sme
- Add in email link to roundcube from user accounts [SME: 12751]
* Wed Oct 02 2024 Brian Read <brianr@koozali.org> 11.0.0-25.sme
- Add in cursor change when save/submit pressed to indicate processing [SME: 12748]
* Wed Oct 02 2024 Brian Read <brianr@koozali.org> 11.0.0-24.sme
- Messed up build - finger trouble [SME: 12753]
* Wed Oct 02 2024 Brian Read <brianr@koozali.org> 11.0.0-23.sme
- Add release number to footer [SME: 12753]
* Tue Sep 24 2024 Jean-Philippe Pialasse <jpp@koozali.org> 11.0.0-22.sme
- fix typos, and tidy tabs [SME: 12744]
* Mon Sep 23 2024 Brian Read <brianr@koozali.org> 11.0.0-21.sme
- Remove both option for webmail [SME: 12744]
- Add in re-open DB for portforwarding and email settings.
* Mon Sep 23 2024 Jean-Philippe Pialasse <jpp@koozali.org> 11.0.0-20.sme
- webmail switch panel to use roundcube [SME: 12742]
- prevent browser from caching [SME: 12695]
* Thu Sep 05 2024 Brian Read <brianr@koozali.org> 11.0.0-19.sme
- Add in mojo plugin WithoutCache [SME: 12695]
* Sun Aug 25 2024 Brian Read <brianr@koozali.org> 11.0.0-18.sme
- Move flag to emojii from downloaded jpg. Fix singleton locale issue[SME: 12706]
* Thu Aug 22 2024 Brian Read <brianr@koozali.org> 11.0.0-17.sme
- Left Align Software Install panels Submit button [SME: 12727]
* Wed Aug 21 2024 Brian Read <brianr@koozali.org> 11.0.0-16.sme
- Typo uc DNF changed to lc dnf in Yum.pm [SME: 127245]
- Monitor dnf running using dnf status file
* Wed Aug 21 2024 Brian Read <brianr@koozali.org> 11.0.0-15.sme
- Migrate SM2 Software installer panel from use of yum to dnf [SME: 12718]
* Sun Jul 28 2024 Brian Read <brianr@koozali.org> 11.0.0-14.sme
- Version skipped due to operator error! [SME: <none> ]
* Sun Jul 28 2024 Brian Read <brianr@koozali.org> 11.0.0-13.sme
- Fix sysles.css template - overwrote it by mistake [SME: 12706]
- Also re-organised login and Legacy SM menus and help on top
* Sun Jul 28 2024 Brian Read <brianr@koozali.org> 11.0.0-12.sme
- correct positio of flag-icon [SME: 12706]
* Sat Jul 27 2024 Brian Read <brianr@koozali.org> 11.0.0-11.sme
- Add in flag icon indication of locale [SME: 12706]
* Fri Jul 26 2024 Brian Read <brianr@koozali.org> 11.0.0-10.sme
- fix navigation2.conf to more correctly translate menus [SME: 12714]
* Thu May 09 2024 Brian Read <brianr@koozali.org> 11.0.0-9.sme
- Add mojo logo to footer [SME: 12679]
- Fix default for HeaderWeight to avoid noise in logs if no Nav header in file
- Align buttons consistently [SME: 12680]
* Tue Apr 30 2024 Jean-Philippe Pialasse <jpp@koozali.org> 11.0.0-8.sme
- create dedicated log files and logrotate [SME: 12664]
* Tue Apr 30 2024 Brian Read <brianr@koozali.org> 11.0.0-7.sme
- Remove use of hel command and replace by call to BlockDevices lib [SME: 12644]