Compare commits

...

11 Commits

Author SHA1 Message Date
774b7ab4ee * Wed Nov 05 2025 Brian Read <brianr@koozali.org> 11.0.0-132.sme
- Supress webmail option on menu and in user accounts if webmail not enabled [SME: 12997]
2025-11-05 12:15:55 +00:00
99dc0a15da * Tue Nov 04 2025 Brian Read <brianr@koozali.org> 11.0.0-131.sme
- Add fix for IE browser local/language detect [SME: 13039]
2025-11-04 16:12:44 +00:00
0dfbdf3d36 * Tue Nov 04 2025 Brian Read <brianr@koozali.org> 11.0.0-130.sme
- Adjust heading so that no white line under theme selector and move theme button in [SME: 13057]
2025-11-04 13:27:51 +00:00
820551b076 * Tue Nov 04 2025 Brian Read <brianr@koozali.org> 11.0.0-129.sme
- Useraccounts: Clean up forward email sub and make sure blank is errored  [SME: 13056]
2025-11-04 13:00:26 +00:00
1a37667a9c * Tue Nov 04 2025 Brian Read <brianr@koozali.org> 11.0.0-128.sme
- Move group table to under others in User accounts setup panel [SME: 13068]
2025-11-04 12:17:51 +00:00
c1aab3eb84 * Tue Nov 04 2025 Brian Read <brianr@koozali.org> 11.0.0-127.sme
- Move same var declations to outside innner scope [SME: 13073]
2025-11-04 11:44:27 +00:00
18442c0145 * Tue Nov 04 2025 Brian Read <brianr@koozali.org> 11.0.0-126.sme
- Remove debugging dump in portforwarding which crashes if no data  [SME: 13243]
2025-11-04 10:12:42 +00:00
5c227a2032 * Mon Nov 03 2025 Brian Read <brianr@koozali.org> 11.0.0-125.sme
- Arrange that Macaddress, InternalIP and comment cleared out when host entry switched to self [SME: 13207]
2025-11-03 11:34:55 +00:00
8e270ef3fd * Fri Oct 24 2025 Brian Read <brianr@koozali.org> 11.0.0-124.sme
- Adjust CSS for logout button to remove overlap of border and rounding [SME: 13247]
2025-10-24 12:41:51 +01:00
a04097bf5a * Fri Oct 24 2025 Brian Read <brianr@koozali.org> 11.0.0-123.sme
- Take out references to js/jquery files now incorporated in the datatables.min.js [SME:13253]
2025-10-24 10:50:46 +01:00
9437dd792a html comment closure leaks onto panel 2025-10-22 09:44:15 +01:00
19 changed files with 153 additions and 82 deletions

View File

@@ -17,6 +17,8 @@ use Data::Validate::IP qw(is_ipv4 is_ipv6);
use constant FALSE => 0; use constant FALSE => 0;
use constant TRUE => 1; use constant TRUE => 1;
our @EXPORT_OK = qw(get_current_webmail_status);
#The most common ones - open DB when required. #The most common ones - open DB when required.
our $cdb; our $cdb;

View File

@@ -116,16 +116,39 @@ sub do_update {
$ndb = esmith::NetworksDB::UTF8->open || die "Couldn't open networks db"; $ndb = esmith::NetworksDB::UTF8->open || die "Couldn't open networks db";
my $notif = ''; my $notif = '';
my $result = ''; my $result = '';
$hos_datas{'name'} = lc $c->param('Name'); # Fetch parameters with forced scalar context and default empty string if undefined
$hos_datas{'domain'} = lc $c->param('Domain'); $hos_datas{'name'} = lc(scalar $c->param('Name') // '');
$hos_datas{'hostname'} = $c->param('Hostname'); $hos_datas{'domain'} = lc(scalar $c->param('Domain') // '');
$hos_datas{'comment'} = $c->param('Comment'); $hos_datas{'hostname'} = scalar $c->param('Hostname') // '';
$hos_datas{'hosttype'} = $c->param('Hosttype'); $hos_datas{'comment'} = scalar $c->param('Comment') // '';
$hos_datas{'internalip'} = $c->param('Internalip'); $hos_datas{'hosttype'} = scalar $c->param('Hosttype') // '';
$hos_datas{'macaddress'} = $c->param('Macaddress'); $hos_datas{'internalip'} = scalar $c->param('Internalip') // '';
$hos_datas{'externalip'} = $c->param('Externalip'); $hos_datas{'externalip'} = scalar $c->param('Externalip') // '';
my $hostname = "$hos_datas{'name'}.$hos_datas{'domain'}"; my $hostname = "$hos_datas{'name'}.$hos_datas{'domain'}";
if (my $hostrec = $hdb->get($hostname)) {
my $hosttype = $hostrec->prop('HostType') // '';
#$c->app->log->info("$hosttype $hos_datas{'hosttype'} $hos_datas{'comment'} $hostrec->prop('Comment')");
# Clear comment if hosttype changes to 'self' and comment was not intentionally changed
if ($hosttype ne 'Self'
&& $hos_datas{'hosttype'} eq 'Self'
&& $hos_datas{'comment'} eq $hostrec->prop('Comment')) {
$hos_datas{'comment'} = '';
}
}
# Clear MAC address if hosttype is 'self', otherwise get from param
if ($hos_datas{'hosttype'} eq 'Self') {
$hos_datas{'macaddress'} = '';
$hos_datas{'internalip'} = '';
#$c->app->log->info("yes $hos_datas{'hosttype'} $hos_datas{'macaddress'}");
} else {
$hos_datas{'macaddress'} = scalar $c->param('Macaddress') // '';
#$c->app->log->info("no $hos_datas{'hosttype'} $hos_datas{'macaddress'}");
}
if ($trt eq 'ADD') { if ($trt eq 'ADD') {
$hos_datas{'hostname'} = $hostname; $hos_datas{'hostname'} = $hostname;

View File

@@ -179,7 +179,7 @@ sub do_update {
$res = $c->pseudonym_clash($first); $res = $c->pseudonym_clash($first);
$result .= $res unless $res eq 'OK'; $result .= $res unless $res eq 'OK';
if ($mail) { if (defined $mail) {
$res = $c->emailforward($mail); $res = $c->emailforward($mail);
$result .= $res unless $res eq 'OK'; $result .= $res unless $res eq 'OK';
} }
@@ -217,7 +217,7 @@ sub do_update {
$res = $c->pseudonym_clash($first); $res = $c->pseudonym_clash($first);
$result .= $res unless $res eq 'OK'; $result .= $res unless $res eq 'OK';
if ($mail) { if (defined $mail) {
$res = $c->emailforward($mail); $res = $c->emailforward($mail);
$result .= $res unless $res eq 'OK'; $result .= $res unless $res eq 'OK';
} }
@@ -554,27 +554,31 @@ sub pseudonym_clash {
sub emailforward { sub emailforward {
my ($c, $data) = @_; my ($c, $data) = @_;
my $response = $c->email_simple($data); #$c->app->log->info("emailformward called with $data!");
if ($response eq "OK") { # Trim whitespace from $data
return "OK"; $data =~ s/^\s+|\s+$//g if defined $data;
} elsif ($data eq "") {
# Blank is ok, only if we're not forwarding, which means that the # Check simple email validation first
# EmailForward param must be set to 'local'. return "OK" if $c->email_simple($data) eq "OK";
# If trimmed data is empty
if ($data eq "") {
my $email_forward = $c->param('EmailForward') || ''; my $email_forward = $c->param('EmailForward') || '';
$email_forward =~ s/^\s+|\s+$//g; $email_forward =~ s/^\s+|\s+$//g;
return 'OK' if $email_forward eq 'local'; return 'OK' if $email_forward eq 'local';
return $c->l('usr_CANNOT_CONTAIN_WHITESPACE'); return $c->l('usr_CANNOT_CONTAIN_WHITESPACE');
} else { }
return $c->l('usr_CANNOT_CONTAIN_WHITESPACE')
if ($data =~ /\s+/);
# Permit a local address. # Reject if $data contains any whitespace inside
return "OK" if $data =~ /^[a-zA-Z][a-zA-Z0-9\._\-]*$/; return $c->l('usr_CANNOT_CONTAIN_WHITESPACE') if $data =~ /\s/;
# Allow local address pattern
return "OK" if $data =~ /^[a-zA-Z][a-zA-Z0-9._-]*$/;
# Otherwise reject for unacceptable chars
return $c->l('usr_UNACCEPTABLE_CHARS'); return $c->l('usr_UNACCEPTABLE_CHARS');
} ## end else [ if ($response eq "OK")] }
} ## end sub emailforward
sub get_groups { sub get_groups {
my ($c) = shift; my ($c) = shift;

View File

@@ -1 +1 @@
'rc_WEBMAIL_DISABLED' => 'Webmail is disabled in Email Settings panel',

View File

@@ -519,3 +519,8 @@ div.roundcube #roundcube{
margin-left: auto!important; margin-left: auto!important;
margin-right: auto; margin-right: auto;
} }
table.incolumn {
margin:auto;
color:red;
}

View File

@@ -63,7 +63,7 @@
position: absolute; position: absolute;
left: 7%; left: 7%;
transform: translateX(-50%); transform: translateX(-50%);
background-color: #4caf50b8; background-color: #4caf50;
color: white !important; color: white !important;
border: none; border: none;
padding: 8px; padding: 8px;
@@ -122,6 +122,7 @@
max-width: 100%; max-width: 100%;
position: relative; position: relative;
margin: auto; margin: auto;
margin-top:-20px;
} }
#header2 { #header2 {
@@ -291,3 +292,7 @@ background-color: #e8f3e1;
.busy { .busy {
cursor: wait; /* Change the cursor to a 'wait' cursor */ cursor: wait; /* Change the cursor to a 'wait' cursor */
} }
#swt_theme {
margin-left:10px;
}

View File

@@ -263,8 +263,12 @@ document.addEventListener('DOMContentLoaded', () => {
function displayLocaleAndFlag() { function displayLocaleAndFlag() {
// Get the browser locale // Get the browser locale
const userLocale = navigator.language || navigator.userLanguage; const userLocale = navigator.languages && navigator.languages.length
? navigator.languages[0]
: navigator.language;
//alert(`User Locale: ${userLocale}`); // Alert the detected locale //alert(`User Locale: ${userLocale}`); // Alert the detected locale
console.log(navigator.languages); // Log language to console
const { flag, isUnknown, countryCode } = getFlagEmoji(userLocale); const { flag, isUnknown, countryCode } = getFlagEmoji(userLocale);

View File

@@ -1 +1 @@
<script src='js/jquery.min.js' type='text/javascript'></script> <!--<script src='js/jquery.min.js' type='text/javascript'></script>-->

View File

@@ -21,12 +21,12 @@
%= javascript '/js/datatables.min.js' %= javascript '/js/datatables.min.js'
%= stylesheet '/js/jquery-ui.min.css' %= stylesheet '/js/jquery-ui.min.css'
%= javascript '/js/jquery-ui.min.js' %= javascript '/js/jquery-ui.min.js'
%= javascript '/js/dataTables.buttons.min.js' %#= javascript '/js/dataTables.buttons.min.js'
%= javascript '/js/jszip.min.js' %#= javascript '/js/jszip.min.js'
%= javascript '/js/pdfmake.min.js' %#= javascript '/js/pdfmake.min.js'
%= javascript '/js/vfs_fonts.js' %= javascript '/js/vfs_fonts.js'
%= javascript '/js/buttons.html5.min.js' %#= javascript '/js/buttons.html5.min.js'
%= javascript '/js/buttons.print.min.js' %#= javascript '/js/buttons.print.min.js'
%= javascript '/js/flag-by-locale.js' %= javascript '/js/flag-by-locale.js'
%= javascript '/js/sme-password.js' %= javascript '/js/sme-password.js'

View File

@@ -35,13 +35,13 @@
% foreach my $group (@$groups) % foreach my $group (@$groups)
% { % {
% my $csrf_token = "TOKEN"; # CSRF token for security
% my $group_name = $group->key; # group name extracted from the data structure
<tr> <tr>
%= t td => ( class => 'sme-border' ) => $group->key %= t td => ( class => 'sme-border' ) => $group->key
%= t td => ( class => 'sme-border' ) => $group->prop('Description') %= t td => ( class => 'sme-border' ) => $group->prop('Description')
<td class='sme-border' style="min-width:15em"> <td class='sme-border' style="min-width:15em">
% my $modify_text = l('MODIFY'); # Localized text % 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{ % my $actionModify = qq{
% <a href="groups2?CsrfDef=$csrf_token&trt=UPD&group=$group_name" % <a href="groups2?CsrfDef=$csrf_token&trt=UPD&group=$group_name"
% class="sme-modify-button unset ui-button ui-corner-all ui-widget ui-button-icon-only" % class="sme-modify-button unset ui-button ui-corner-all ui-widget ui-button-icon-only"
@@ -52,8 +52,6 @@
% </a> % </a>
% }; % };
% my $remove_text = l('REMOVE'); # Localized text % 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{ % my $actionRemove = qq{
% <a href="groups2?CsrfDef=$csrf_token&trt=DEL&group=$group_name" % <a href="groups2?CsrfDef=$csrf_token&trt=DEL&group=$group_name"
% class="sme-remove-button unset ui-button ui-corner-all ui-widget ui-button-icon-only" % class="sme-remove-button unset ui-button ui-corner-all ui-widget ui-button-icon-only"

View File

@@ -4,7 +4,7 @@
% if ( not defined $c->session->{username} ) { % if ( not defined $c->session->{username} ) {
<a class="login-button no-visited-state" target="_parent" href="/smanager/login">Login</a> <a class="login-button no-visited-state" target="_parent" href="/smanager/login">Login</a>
% } else { % } else {
<!--><button type='button' class="login-button"><a class = "no-visited-state" target="_parent" href="/smanager/logout">Logout <%= $c->session->{username} %></a></button>--> <!--<button type='button' class="login-button"><a class = "no-visited-state" target="_parent" href="/smanager/logout">Logout <%= $c->session->{username} %></a></button>xxx-->
<a class="login-button no-visited-state" target="_parent" href="/smanager/logout">Logout <%= $c->session->{username} %></a> <a class="login-button no-visited-state" target="_parent" href="/smanager/logout">Logout <%= $c->session->{username} %></a>
% } % }
<div id="flag-container" class = "flag-style"> <div id="flag-container" class = "flag-style">

View File

@@ -2,14 +2,14 @@
% my %nav = %{ SrvMngr->getNavigation( $c->languages(), 'N' ) }; % my %nav = %{ SrvMngr->getNavigation( $c->languages(), 'N' ) };
<div id='navmenu'> <div id='navmenu'>
<!-- <a href='#' id='tognav' class='menu-title'>NAVIGATION</a> --> <!-- <a href='#' id='tognav' class='menu-title'>NAVIGATION</a> ffff-->
<div id='menunav'> <div id='menunav'>
% my $cc = 200; % my $cc = 200;
% foreach my $h (sort { ($nav{$a}{'WEIGHT'}/$nav{$a}{'COUNT'}) % foreach my $h (sort { ($nav{$a}{'WEIGHT'}/$nav{$a}{'COUNT'})
% <=> ($nav{$b}{'WEIGHT'}/$nav{$b}{'COUNT'}) } keys %nav) { % <=> ($nav{$b}{'WEIGHT'}/$nav{$b}{'COUNT'}) } keys %nav) {
% %
<!-- div class='section section-title'><%= $h %></div --> <!-- div class='section section-title'><%= $h %></div gggg-->
<div><a href='#' class='section section-title'><%= $h %></a></div> <div><a href='#' class='section section-title'><%= $h %></a></div>
<div class='togms'> <div class='togms'>
% my ( $classNew, $target, $href ) = ''; % my ( $classNew, $target, $href ) = '';

View File

@@ -2,7 +2,7 @@
% my %nav = %{ SrvMngr->getNavigation( $c->languages(), 'A' ) }; % my %nav = %{ SrvMngr->getNavigation( $c->languages(), 'A' ) };
<div id='navigat2'> <div id='navigat2'>
<!-- ><div><a href='#' id='togadm' class='menu-title'>ADMINISTRATION</a></div> --> <!-- <div><a href='#' id='togadm' class='menu-title'>ADMINISTRATION</a></div> dddd-->
<div id='menuadm'> <div id='menuadm'>
% my $cc = 100; % my $cc = 100;

View File

@@ -9,7 +9,7 @@
% my $cc = 300; % my $cc = 300;
% foreach my $h (sort { ($nav{$a}{'WEIGHT'}/$nav{$a}{'COUNT'}) % foreach my $h (sort { ($nav{$a}{'WEIGHT'}/$nav{$a}{'COUNT'})
% <=> ($nav{$b}{'WEIGHT'}/$nav{$b}{'COUNT'}) } keys %nav) { % <=> ($nav{$b}{'WEIGHT'}/$nav{$b}{'COUNT'}) } keys %nav) {
<!-- div class='section'><%= $h %></div --> <!-- div class='section'><%= $h %></div> nnnn-->
% my ( $classNew, $target, $href ) = ''; % my ( $classNew, $target, $href ) = '';
% foreach (sort { $a->{'WEIGHT'} <=> $b->{'WEIGHT'} } @{$nav{$h}{'DESCRIPTIONS'}}) { % foreach (sort { $a->{'WEIGHT'} <=> $b->{'WEIGHT'} } @{$nav{$h}{'DESCRIPTIONS'}}) {
% next if ( $_->{'MENUCAT'} ne 'A' && $_->{'MENUCAT'} ne 'U' ); # menu User % next if ( $_->{'MENUCAT'} ne 'A' && $_->{'MENUCAT'} ne 'U' ); # menu User

View File

@@ -1,5 +1,7 @@
<div id='usr_list'> <div id='usr_list'>
% use constant FALSE => 0;
% use constant TRUE => 1;
% my $btn = l('usr_ADD_USER'); % my $btn = l('usr_ADD_USER');
@@ -153,7 +155,9 @@
<%= $c->render_to_string( inline => $actionResetPw ) %> <%= $c->render_to_string( inline => $actionResetPw ) %>
<%= $c->render_to_string( inline => $actionLock ) %> <%= $c->render_to_string( inline => $actionLock ) %>
<%= $c->render_to_string( inline => $actionRemove ) %> <%= $c->render_to_string( inline => $actionRemove ) %>
% if ($c->SrvMngr::Controller::Emailsettings::get_current_webmail_status(FALSE) ne 'disabled'){
<%= $c->render_to_string( inline => $actionroundcube ) %> <%= $c->render_to_string( inline => $actionroundcube ) %>
% }
</td> </td>
</tr> </tr>
% } % }

View File

@@ -131,7 +131,7 @@
%= l 'usr_GROUP_MEMBERSHIPS' %= l 'usr_GROUP_MEMBERSHIPS'
</span> </span>
<span class=data> <span class=data>
<table class="sme-border "><thead> <table class="sme-border incolumn"><thead>
<tr><th class='sme-border'> <tr><th class='sme-border'>
%= l 'usr_MEMBER' %= l 'usr_MEMBER'
</th><th class='sme-border'> </th><th class='sme-border'>

View File

@@ -5,11 +5,8 @@
% if (config->{debug} == 1) { % if (config->{debug} == 1) {
<p> <p>
%= dumper "<pf>" . $c->current_route %= dumper $c->current_route
%= dumper $c->stash("ret") %= dumper $pf_datas
%= dumper $c->stash("portforwarding")
% my $ref = $pf_datas->{portforwarding};
%= dumper $ref->{TCP}->[0] . "</pf>"
</p> </p>
% } % }

View File

@@ -1,8 +1,7 @@
% layout 'default', title => "Sme server 2 - roundcube"; % layout 'default', title => "Sme server 2 - roundcube";
% use constant FALSE => 0;
% use constant TRUE => 1;
% content_for 'module' => begin % content_for 'module' => begin
<div id='roundcube' class='roundcube roundcube-panel module'> <div id='roundcube' class='roundcube roundcube-panel module'>
% if (config->{debug} == 1) { % if (config->{debug} == 1) {
<p> <p>
@@ -15,8 +14,10 @@
</div> </div>
% } % }
<h1><%= $title %></h1><br> <h1><%= $title %></h1><br>
% if ($c->SrvMngr::Controller::Emailsettings::get_current_webmail_status(FALSE) eq 'disabled'){
<%= $c->render_to_string( inline => l('rc_WEBMAIL_DISABLED') ) %>
% } else {
<p>If the Webmail panel does not appear after logging in, then please check your password.</p><br /> <p>If the Webmail panel does not appear after logging in, then please check your password.</p><br />
% my $thisdomain = $c->req->url->to_abs->host; % my $thisdomain = $c->req->url->to_abs->host;
% my $url = $c->stash('modul'); % my $url = $c->stash('modul');
% if (!$url) { % if (!$url) {
@@ -29,12 +30,10 @@
% if (!($url =~ /https:/)) { % if (!($url =~ /https:/)) {
% $url = 'https://' . $url; % $url = 'https://' . $url;
% } % }
<div class='roundcube'> <div class='roundcube'>
<a href="<%= "https://" . $thisdomain . "/" %>roundcube?_user=<%= $username %>"><button class="sme-fullwindow1-button" width=20em title="<%= l('Full Window') %>"><%= l('Full Window') %></button></a> <a href="<%= "https://" . $thisdomain . "/" %>roundcube?_user=<%= $username %>"><button class="sme-fullwindow1-button" width=20em title="<%= l('Full Window') %>"><%= l('Full Window') %></button></a>
<object id="roundcube" data="<%= $url %>" title="<%= $c->stash('title') %>" type="text/html" ><%= $c->stash('title') %> not found</object> <object id="roundcube" data="<%= $url %>" title="<%= $c->stash('title') %>" type="text/html" ><%= $c->stash('title') %> not found</object>
</div> </div>
% }
</div> </div>
% end % end

View File

@@ -2,7 +2,7 @@ Summary: Sme Server Configuration : Manager 2
%define name smeserver-manager %define name smeserver-manager
Name: %{name} Name: %{name}
%define version 11.0.0 %define version 11.0.0
%define release 122 %define release 132
Version: %{version} Version: %{version}
Release: %{release}%{?dist} Release: %{release}%{?dist}
License: GPL License: GPL
@@ -39,7 +39,7 @@ Requires: perl(Mojo::JWT) >= 0.08-1
#Requires: perl(Time::TAI64) >= 2.11 #Requires: perl(Time::TAI64) >= 2.11
Requires: perl(Data::Validate::IP) Requires: perl(Data::Validate::IP)
Requires: mutt >= 1.5.21 Requires: mutt >= 1.5.21
Requires: smeserver-manager-jsquery >= 1.0 Requires: smeserver-manager-jsquery >= 11.0.0-11
Requires: smeserver-certificates >= 11.0 Requires: smeserver-certificates >= 11.0
#Requires: js-jquery > 2.2.4-3 (optional) #Requires: js-jquery > 2.2.4-3 (optional)
@@ -147,6 +147,36 @@ true
%defattr(-,root,root) %defattr(-,root,root)
%changelog %changelog
* Wed Nov 05 2025 Brian Read <brianr@koozali.org> 11.0.0-132.sme
- Supress webmail option on menu and in user accounts if webmail not enabled [SME: 12997]
* Tue Nov 04 2025 Brian Read <brianr@koozali.org> 11.0.0-131.sme
- Add fix for IE browser local/language detect [SME: 13039]
* Tue Nov 04 2025 Brian Read <brianr@koozali.org> 11.0.0-130.sme
- Adjust heading so that no white line under theme selector and move theme button in [SME: 13057]
* Tue Nov 04 2025 Brian Read <brianr@koozali.org> 11.0.0-129.sme
- Useraccounts: Clean up forward email sub and make sure blank is errored [SME: 13056]
* Tue Nov 04 2025 Brian Read <brianr@koozali.org> 11.0.0-128.sme
- Move group table to under others in User accounts setup panel [SME: 13068]
* Tue Nov 04 2025 Brian Read <brianr@koozali.org> 11.0.0-127.sme
- Group panel: Move same var declations to outside innner scope [SME: 13073]
* Tue Nov 04 2025 Brian Read <brianr@koozali.org> 11.0.0-126.sme
- Remove debugging dump in portforwarding which crashes if no data [SME: 13243]
* Mon Nov 03 2025 Brian Read <brianr@koozali.org> 11.0.0-125.sme
- Arrange that Macaddress, InternalIP and comment cleared out when host entry switched to self [SME: 13207]
* Fri Oct 24 2025 Brian Read <brianr@koozali.org> 11.0.0-124.sme
- Adjust CSS for logout button to remove overlap of border and rounding [SME: 13247]
* Fri Oct 24 2025 Brian Read <brianr@koozali.org> 11.0.0-123.sme
- Take out references to js/jquery files now incorporated in the datatables.min.js [SME:13253]
* Tue Oct 21 2025 Brian Read <brianr@koozali.org> 11.0.0-122.sme * Tue Oct 21 2025 Brian Read <brianr@koozali.org> 11.0.0-122.sme
- Correct code to only show user panels when AdminPanels property is empty or non existent [SME: 13082] - Correct code to only show user panels when AdminPanels property is empty or non existent [SME: 13082]