Compare commits

...

38 Commits

Author SHA1 Message Date
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
891fc73ce3 * 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]
2024-04-30 18:23:52 +01:00
e7d7b6afb8 * Mon Apr 29 2024 Brian Read <brianr@koozali.org> 11.0.0-6.sme
- Update layout for table extras [SME: 12656]
2024-04-29 11:08:21 +01:00
1837bc9a18 * Sun Apr 28 2024 Brian Read <brianr@koozali.org> 11.0.0-5.sme
- Ibay create not getting into panel [SME: 12652]
2024-04-28 11:22:17 +01:00
42 changed files with 1373 additions and 418 deletions

View File

@@ -17,6 +17,59 @@ Show list of outstanding bugs: [here](https://bugs.koozali.org/buglist.cgi?compo
## 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

@@ -40,5 +40,10 @@
$OUT .= " Require ip $localAccess $externalSSLAccess\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

@@ -37,6 +37,8 @@ use esmith::BackupHistoryDB;
use esmith::util;
use esmith::lockfile;
use esmith::BlockDevices;
use constant DEBUG => $ENV{MOJO_SMANAGER_DEBUG} || 0;
our $cdb = esmith::ConfigDB->open || die "Couldn't open config db";
@@ -1576,19 +1578,33 @@ sub get_BackupwkDest_options {
my @usbdisks = ();
if ( $VFSType eq 'usb' ) {
foreach my $udi (qx(hal-find-by-property --key volume.fsusage --string filesystem)) {
$udi =~ m/^(\S+)/;
my $devices = esmith::BlockDevices->new ('allowmount' => 'disabled');
my ($valid, $invalid) = $devices->checkBackupDrives(0);
my $is_mounted = qx(hal-get-property --udi $1 --key volume.is_mounted);
if ($is_mounted eq "false\n") {
my $vollbl = qx(hal-get-property --udi $1 --key volume.label);
$vollbl =~ m/^(\S+)/;
if ($vollbl =~ /^\s/) {$vollbl = 'nolabel';}
chomp $vollbl;
push @usbdisks, $vollbl;
if ( ${$valid}[0] ) {
foreach ( @{$valid} ) {
push @usbdisks, $devices->label($_);
}
}
if (!$usbdisks[0]){
push (@usbdisks,$c->l('bac_No suitable local devices found'));
}
$devices->destroy;
#foreach my $udi (qx(hal-find-by-property --key volume.fsusage --string filesystem)) {
#$udi =~ m/^(\S+)/;
#my $is_mounted = qx(hal-get-property --udi $1 --key volume.is_mounted);
#if ($is_mounted eq "false\n") {
#my $vollbl = qx(hal-get-property --udi $1 --key volume.label);
#$vollbl =~ m/^(\S+)/;
#if ($vollbl =~ /^\s/) {$vollbl = 'nolabel';}
#chomp $vollbl;
#push @usbdisks, $vollbl;
#}
#}
# return undef unless ($usbdisks[0]);
}
@@ -1985,31 +2001,50 @@ sub dmount {
return ( qx(/bin/mount -t nfs -o nolock "$host:/$share" $mountdir 2>&1) );
}
elsif ($VFSType eq 'usb') {
my $device = "";
my $blkdev = "";
my $device = "";
my $vollbl = "";
foreach my $udi (qx(hal-find-by-property --key volume.fsusage --string filesystem)) {
$udi =~ m/^(\S+)/;
my $is_mounted = qx(hal-get-property --udi $1 --key volume.is_mounted);
if ($is_mounted eq "false\n") {
$blkdev = qx(hal-get-property --udi $1 --key block.device);
if ($blkdev =~ m/^(\S+)/) {$blkdev = $1;}
}
if ($is_mounted eq "false\n") {
$vollbl = qx(hal-get-property --udi $1 --key volume.label);
$vollbl =~ m/^(\S+)/;
if ($vollbl =~ /^\s/) {$vollbl = 'nolabel';}
}
my $devices = esmith::BlockDevices->new ('allowmount' => 'disabled');
my ($valid, $invalid) = $devices->checkBackupDrives(0);
chomp $vollbl;
chomp $blkdev;
$vollbl = "media/$vollbl";
if ($vollbl eq $share) {
$device = $blkdev;
}
if ( ${$valid}[0] ) {
foreach ( @{$valid} ) {
$vollbl = $devices->label($_);
if ( $share eq "media/$vollbl" ) {
$device = "/dev/$_";
}
}
}
return ( qx(/bin/mount $device "/$share" 2>&1) );
$devices->destroy;
return ( qx (mount $device /$share 2>&1) );
#-------------------------------------------------------------------------------------------------------
#my $device = "";
#my $blkdev = "";
#my $vollbl = "";
#foreach my $udi (qx(hal-find-by-property --key volume.fsusage --string filesystem)) {
#$udi =~ m/^(\S+)/;
#my $is_mounted = qx(hal-get-property --udi $1 --key volume.is_mounted);
#if ($is_mounted eq "false\n") {
#$blkdev = qx(hal-get-property --udi $1 --key block.device);
#if ($blkdev =~ m/^(\S+)/) {$blkdev = $1;}
#}
#if ($is_mounted eq "false\n") {
#$vollbl = qx(hal-get-property --udi $1 --key volume.label);
#$vollbl =~ m/^(\S+)/;
#if ($vollbl =~ /^\s/) {$vollbl = 'nolabel';}
#}
#chomp $vollbl;
#chomp $blkdev;
#$vollbl = "media/$vollbl";
#if ($vollbl eq $share) {
#$device = $blkdev;
#}
#}
#return ( qx(/bin/mount $device "/$share" 2>&1) );
#-------------------------------------------------------------------------------------------------------
} else {
return ("Error while mounting $host/$share : $VFSType not supported.\n");
}

View File

@@ -57,12 +57,14 @@ sub do_display {
$mai_datas{'trt'} = $trt;
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 +74,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 +89,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 +100,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 );
@@ -120,98 +124,107 @@ sub do_update {
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);
@@ -395,19 +408,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 +425,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" ))
@@ -507,8 +516,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 +527,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;
}
@@ -658,6 +666,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' );
@@ -724,6 +733,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 +762,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 +813,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 +842,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 +857,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 +865,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';

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

@@ -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

@@ -1,3 +1,4 @@
'bac_No suitable local devices found' => 'No suitable local devices found',
'bac_BACKUP_TITLE' => 'Backup or restore server data',
'bac_BACKUP_DESC' => '<P>The server provides two ways to back up and restore
your server: using your local desktop or a tape drive.</P>

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;

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

@@ -19,18 +19,35 @@
%= content_for 'refresh'
%= stylesheet '/js/datatables.min.css'
%= javascript '/js/datatables.min.js'
%= stylesheet '/js/jquery-ui.min.css'
%= javascript '/js/jquery-ui.min.js'
%= stylesheet '/js/dataTables.buttons.min.js'
%= stylesheet '/js/jszip.min.js'
%= stylesheet '/js/pdfmake.min.js'
%= stylesheet '/js/vfs_fonts.js'
%= stylesheet '/js/buttons.html5.min.js'
%= stylesheet '/js/buttons.print.min.js'
%= javascript '/js/datatables.min.js'
%= stylesheet '/js/jquery-ui.min.css'
%= javascript '/js/jquery-ui.min.js'
%= javascript '/js/dataTables.buttons.min.js'
%= javascript '/js/jszip.min.js'
%= javascript '/js/pdfmake.min.js'
%= 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="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.5.0/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>
@@ -91,46 +108,21 @@
%= javascript '/js/sme-dataTable-setup.js'
%= javascript begin
//Set menu to initial condition based on localStorage
$(document).ready(function() {
let menunavflag = window.localStorage.getItem('menunav');
if (menunavflag != "false"){
$('#menunav').toggle(true);
} else {
$('#menunav').toggle(false);
}
let menuadmflag = window.localStorage.getItem('menuadm');
if (menuadmflag != "false"){
$('#menuadm').toggle(true);
} else {
$('#menuadm').toggle(false);
}
<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>
let menuuserflag = window.localStorage.getItem('menuuser');
if (menuuserflag != "false"){
$('#menuuser').toggle(true);
} else {
$('#menuuser').toggle(false);
}
var sections = document.getElementsByClassName("section-title");
for (var i = 0, len = sections.length; i < len; i++) {
var jqObj = $(sections[i]);
var $section = jqObj.parent().next('div');
if(!$section.length){
return false;
}
let localStorageTag = "admSection-"+sections[i].innerHTML;
if (window.localStorage.getItem(localStorageTag) != "false"){
$section.toggle(true);
} else {
$section.toggle(false);
}
}
})
%end
</body>
</html>

View File

@@ -1,8 +1,9 @@
<div id="footer">
<div id="footer" width=100%>
<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'

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">
<a id="help-button" target="_parent" href="manual"><button> ? </button></a>
</div>
<div id="h2e12">
<a id="legacy-button" href="/server-manager" target='_blank'><button>Legacy SM</button></a>
</div>
<div id="h2e23">
% if ( not defined $c->session->{username} ) {
<a target="_parent" href="login"><button class="login-button">Login</button></a>
% } else {
<a target="_parent" href="logout"><button class="login-button"><%= $c->session->{username} %> Logout</button></a>
% }
</div>
<div id="flag-container">
<!-- The flag icon will be inserted here -->
</div>
</div>
<div id="h2l2" class="infobar">
<div id="h2e21">
<b>
<%= session 'SystemName' %>@<%= session 'DomainName' %></b>
</div>
</div>
</div>

View File

@@ -9,6 +9,7 @@
<br>
%= submit_button "$btn", class => 'action'
</p>
%= hidden_field 'trt' => 'ADD';
% end
@@ -71,9 +72,7 @@
% }
</tbody>
</table>
<%} %>
%= hidden_field 'trt' => $iba_datas->{trt}
</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

@@ -37,10 +37,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>

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'>

View File

@@ -76,11 +76,17 @@
% $actionRemove = "<a href='useraccountsd?CsrfDef=TOKEN&trt=DEL&user=" . $username . "'>" . "<button class='sme-remove-button' title=".l("REMOVE").">".l("REMOVE")."</button></a>";
% }
% }
%
% my $thisdomain = session 'SystemName';
% $thisdomain .= ".".session 'DomainName';
<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) %>
%# <a href="<%= "https://sme11.thereadclan.me.uk/" %>roundcube?_user=<%= $username %>"><button class="sme-email-button" title="<%= l('EMAIL') %>"><%= l('EMAIL') %></button></a>
<a href="<%= "legacypanel/?url=https://".$thisdomain."/" %>roundcube?_user=<%= $username %>"><button class="sme-email-button" title="<%= l('EMAIL') %>"><%= l('EMAIL') %></button></a>
</td>
</tr>
% }

View File

@@ -213,10 +213,10 @@
</p>
%}
<div class='center'>
<p>
<br>
%= submit_button "$btn", class => 'action'
</div>
</p>
% 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 4
%define release 26
Version: %{version}
Release: %{release}%{?dist}
License: GPL
@@ -49,6 +49,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 +113,78 @@ true
%defattr(-,root,root)
%changelog
* 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]
* Mon Apr 29 2024 Brian Read <brianr@koozali.org> 11.0.0-6.sme
- Update layout for table extras [SME: 12656]
* Sun Apr 28 2024 Brian Read <brianr@koozali.org> 11.0.0-5.sme
- Ibay create not getting into panel [SME: 12652]
* Tue Apr 23 2024 Brian Read <brianr@koozali.org> 11.0.0-4.sme
- add in Nav numbers for Legacypanels.pm and ignore it when generating nav menu [SME:12643]