/usr/share/usermin/authentic-theme
Edit: /usr/share/usermin/authentic-theme/navigation-lib.pl (64628B)
#
# Authentic Theme (https://github.com/authentic-theme/authentic-theme)
# Copyright Ilia Rostovtsev
# Licensed under MIT (https://github.com/authentic-theme/authentic-theme/blob/master/LICENSE)
#
use strict;
our (%in, $root_directory, %gconfig, %gaccess, $base_remote_user, $remote_user, $theme_webprefix, $theme_server_webprefix,
$xnav, %theme_text, %theme_config, $get_user_level, $http_x_url, $server_x_goto);
# Detects the state of navigation menu on initial load
# Returns navigation tab name and right page defaults
sub nav_detector
{
# Get tab and dependent right page
my $tab;
my $page;
# Get goto if the page been reloaded
my $req_goto;
if (!http_x_request()) {
$req_goto = $server_x_goto;
}
my $prod = get_product_name();
my $mod_def = get_default_module();
my $mod_rt_access = &webmin_user_is_admin();
my $prd_cm = "cloudmin";
my $mod_cm = "server-manager";
my $mod_cm_available = foreign_available($mod_cm);
my $mod_cm_access = $get_user_level eq '4';
my $prd_vm = "virtualmin";
my $mod_vm = "virtual-server";
my $mod_vm_available = foreign_available($mod_vm);
my $mod_vm_access = $get_user_level eq '2';
my $prd_mb = "webmail";
my $mod_mb = "mailbox";
my $mod_mb_available = foreign_available($mod_mb);
my $mod_um_access = $get_user_level eq '3';
my $prd_db = "dashboard";
my $prd_db_mode = 0;
my $page_index = "index.cgi";
my $page_sysinfo = "sysinfo.cgi";
my $page_sysinfo_def = "$theme_webprefix/$page_sysinfo";
my $nav_def_tab = $theme_config{"settings_right_default_tab_$prod"};
# If we have goto substitute default
if ($req_goto) {
if ($req_goto =~ /\/$mod_cm\// ||
$mod_cm_access)
{
$nav_def_tab = $prd_cm;
} elsif ($req_goto =~ /\/$mod_vm\// ||
$mod_vm_access)
{
$nav_def_tab = $prd_vm;
} elsif ($req_goto =~ /\/$mod_mb\//) {
$nav_def_tab = $prd_mb;
} else {
$nav_def_tab = $prod;
}
# Page should be what was it reload on
$page = $req_goto;
# For modes with dashboard switch
if ($page =~ /$page_sysinfo/ &&
( $mod_cm_access ||
$mod_vm_access ||
(!$mod_cm_available &&
!$mod_vm_available &&
!$mod_mb_available)))
{
$nav_def_tab = $prd_db;
}
}
# If no goto and defaults not set
else {
# Validate if default goto is allowed for the given user
$mod_def = undef
if ($mod_def &&
(!foreign_available($mod_def) ||
!-r "$root_directory/$mod_def/$page_index"));
if (!$nav_def_tab) {
# Define default tab
if ($mod_cm_available) {
$nav_def_tab = $prd_cm;
} elsif ($mod_vm_available) {
$nav_def_tab = $prd_vm;
} elsif ($mod_mb_available) {
$nav_def_tab = $prd_mb;
} else {
$nav_def_tab = $prod;
}
}
# If default set and if module available
my $page_def = $theme_config{"settings_${prod}_default_module"};
if (($nav_def_tab eq $prd_cm && !$mod_cm_available) ||
($nav_def_tab eq $prd_vm && !$mod_vm_available) ||
($nav_def_tab eq $prd_mb && !$mod_mb_available) ||
($nav_def_tab eq $prod &&
!$mod_cm_available &&
!$mod_vm_available &&
!$mod_mb_available &&
!$page_def))
{
# Cloudmin mode
if ($mod_cm_available && $mod_rt_access) {
$nav_def_tab = $prd_cm;
}
# Virtualmin mode
elsif ($mod_vm_available && $mod_rt_access) {
$nav_def_tab = $prd_vm;
}
# This is the single product switch mode
else {
$nav_def_tab = $prd_db;
$prd_db_mode = 1;
}
}
# Check if specific single switch mode first
if ($mod_cm_access || $mod_vm_access) {
$nav_def_tab = $prd_vm;
}
# Check if real product is set
elsif ($nav_def_tab eq '/') {
$nav_def_tab = $prod;
}
# Define default page for Webmin/Usermin
if ($nav_def_tab eq $prod || $nav_def_tab eq $prd_db) {
if ($mod_def) {
$page = "$theme_webprefix/$mod_def/$page_index";
$nav_def_tab = $prod;
} else {
# If default Webmin/Usermin module is actually set
if ($page_def && $page_def ne $page_sysinfo) {
$page = "$theme_webprefix/$page_def";
}
# Define safe default
else {
$page = "$page_sysinfo_def";
$nav_def_tab = $prd_db if ($prd_db_mode);
}
}
}
# Define for modules
else {
my $type_cm = (($mod_cm_available && $nav_def_tab eq $prd_cm) || $mod_cm_access);
my $type_vm = (($mod_vm_available && $nav_def_tab eq $prd_vm) || $mod_vm_access);
my $prod_target =
$type_cm ? $prd_cm :
$type_vm ? $prd_vm :
undef;
if ($prod_target) {
$page = $theme_config{"settings_right_${prod_target}_default"};
if ($page eq $page_index) {
$page =
$type_cm ? "$theme_webprefix/$mod_cm/$page_index" :
$type_vm ? "$theme_webprefix/$mod_vm/$page_index" :
$page_sysinfo_def;
}
# If set to domain/server id, try using it
elsif ($page =~ /^(\d+)$/) {
my $id_ = "$1";
my $id;
if ($id_ ||
# Cloudmin default server's id is '0'
$id_ eq '0')
{
if ($type_cm) {
$id = nav_cloudmin_server_available($id_, 'id');
} elsif ($type_vm) {
$id = nav_virtualmin_domain_available($id_, 'id');
}
}
# If current user has access to domain/server
if ($id ||
# Cloudmin default server's id is '0'
$id eq '0')
{
my $vm_file = $mod_vm_access ? 'view_domain.cgi' : 'summary_domain.cgi';
$page =
$type_cm ? "$theme_webprefix/$mod_cm/edit_serv.cgi?id=$id" :
$type_vm ? "$theme_webprefix/$mod_vm/$vm_file?dom=$id" :
$page_sysinfo_def;
}
# Fallback to default for user
else {
$page = $page_sysinfo_def;
}
} else {
# If default page is not set assume dashboard
$page = $page_sysinfo_def;
}
}
# If default page is not set assume dashboard
else {
$page = $page_sysinfo_def;
}
}
# In case of Usermin
if ($mod_um_access) {
if ($nav_def_tab eq $prod) {
$page = $mod_def eq $mod_mb ? $page_sysinfo_def : "$theme_webprefix/$mod_def/$page_index";
} elsif ($nav_def_tab eq $prd_mb) {
$page = "$theme_webprefix/$mod_mb/$page_index?id=INBOX";
}
}
# For modes with dashboard switch
if ($page =~ /$page_sysinfo/ &&
( $mod_cm_access ||
$mod_vm_access ||
(!$mod_cm_available &&
!$mod_vm_available &&
!$mod_mb_available)))
{
$nav_def_tab = $prd_db;
}
}
# For modes with dashboard switch and various options presets
if ($mod_cm_access || $mod_vm_access) {
if ($page =~ /$page_sysinfo/) {
$nav_def_tab = $prd_db;
} elsif ($mod_cm_access) {
$nav_def_tab = $prd_cm;
} elsif ($mod_vm_access) {
$nav_def_tab = $prd_vm;
}
}
# Temporary patch to address older, existing user configuration
$nav_def_tab = $prd_mb if ($nav_def_tab eq 'mail');
# If Dashboard mode is set
$nav_def_tab = "$1" eq $mod_vm ? $prd_vm : $prd_cm
if ($page =~ /$page_sysinfo\?[\w]{3}\=($mod_vm|$mod_cm)/);
# Return detected tab and page
$tab = $nav_def_tab;
$page = $page;
# Do we have navigation goto request for a module with its own switch?
if ($page) {
my ($nmod) = $page =~ /[?&]nmod=([0-9a-zA-Z-]+)/;
if (($nmod eq $mod_vm || $nmod eq $mod_cm) && foreign_available($nmod)) {
if ($nmod eq $mod_vm) {
$tab = $prd_vm; # Override to use Virtualmin tab
} elsif ($nmod eq $mod_cm) {
$tab = $prd_cm; # Override to use Cloudmin tab
}
}
}
return ($tab, $page);
}
sub nav_webmin_menu
{
my ($page) = @_;
my $rv;
$rv = nav_search();
my @menus = list_modules_webmin_menu();
my $unused = $theme_config{'settings_leftmenu_section_hide_unused_modules'} eq 'true';
my $nomailbox = $theme_config{'settings_mail_ui'} ne 'false' ? 1 : 0;
my $extra_links;
foreach my $menu (@menus) {
next if ($menu->{'id'} eq 'unused' && $unused);
if ($menu->{'type'} eq 'cat') {
$rv .= nav_cat($menu->{'id'}, $menu->{'desc'});
$rv .= "\n";
} elsif ($menu->{'type'} eq 'item' &&
$menu->{'desc'})
{
$rv .= nav_menu_link($menu->{'link'}, $menu->{'desc'}, 'fa-link');
}
}
if (!$extra_links++) {
if (&webmin_user_is_admin() || $theme_config{'settings_theme_config_admins_only_privileged'} ne 'true') {
$rv .= nav_cat_link("/tconfig.cgi", $theme_text{'settings_right_theme_left_configuration_title'}, 'hidden');
}
if (&webmin_user_is_admin()) {
$rv .=
nav_cat_link("/settings-editor_read.cgi", $theme_text{'settings_right_theme_left_extensions_title'}, 'hidden');
$rv .= nav_cat_link("/settings-logos.cgi", $theme_text{'settings_right_theme_left_logo_title'}, 'hidden');
$rv .=
nav_cat_link("/settings-backgrounds.cgi", $theme_text{'settings_right_theme_left_background_title'}, 'hidden');
}
}
if (&foreign_available("webmin") &&
$theme_config{'settings_leftmenu_section_hide_refresh_modules'} ne 'true')
{
$rv .= nav_menu_link('/webmin/refresh_modules.cgi', $theme_text{'left_refresh_modules'}, 'fa-refresh');
}
$rv .= nav_link_sysinfo($get_user_level eq '3');
$rv .= nav_link_netdata();
$rv .= nav_theme_links();
$rv .= nav_links();
$rv .= nav_menu_html_snippet();
$rv .= nav_detect_page($page);
$rv .= nav_detect_script();
return $rv;
}
sub nav_virtualmin_menu
{
my ($page) = @_;
my $mod = 'virtual-server';
my $def = nav_get_server_id($mod);
my @menu = list_combined_webmin_menu({ 'dom' => "$def" }, \%in, $mod);
my $menu = nav_list_combined_menu([$mod], \@menu, undef, undef, $page);
my $rv = $menu->{'before'};
$rv .= nav_link_sysinfo(undef, $mod);
$rv .= nav_link_sysstat();
$rv .= $menu->{'after'}
if ($menu->{'after'});
$rv .= nav_theme_links();
$rv .= nav_links($menu->{'mode'}, $mod);
$rv .= nav_menu_html_snippet();
$rv .= nav_detect_page($page, 1);
$rv .= nav_detect_script(1);
return $rv;
}
sub nav_cloudmin_menu
{
my ($page) = @_;
my $mod = 'server-manager';
my $def = nav_get_server_id($mod);
my @menu = list_combined_webmin_menu({ 'server' => "$def" }, \%in, $mod);
my $menu = nav_list_combined_menu([$mod], \@menu, undef, undef, $page);
my $rv = $menu->{'before'};
$rv .= nav_link_sysinfo(undef, $mod);
$rv .= nav_theme_links();
$rv .= nav_links($menu->{'mode'}, $mod);
$rv .= nav_menu_html_snippet();
$rv .= nav_detect_page($page);
$rv .= nav_detect_script();
return $rv;
}
sub nav_mailbox_menu
{
my ($page) = @_;
my $mod = 'mailbox';
my $nofolders = $theme_config{'settings_mail_ui'} ne 'false' ? 1 : 0;
my @menu = list_combined_webmin_menu({ 'nofolders' => $nofolders });
my $menu = nav_list_combined_menu([$mod, 'changepass'], \@menu, undef, undef, $page);
my $rv = $menu->{'before'};
$rv .= nav_menu_link("/uconfig.cgi?$mod", $theme_text{'theme_left_mail_prefs'}, 'fa-cog');
$rv .= nav_link_sysinfo('user');
$rv .= nav_theme_links();
$rv .= nav_links();
$rv .= nav_menu_html_snippet();
$rv .= nav_detect_page($page);
$rv .= nav_detect_script();
return $rv;
}
sub nav_menu
{
my ($tab_mode) = @_;
my ($tab, $page) = nav_detector();
my $rv;
if ($tab eq 'cloudmin' ||
$tab_mode eq 'cloudmin')
{
$rv = nav_cloudmin_menu($page);
} elsif ($tab eq 'virtualmin' ||
$tab_mode eq 'virtualmin')
{
$rv = nav_virtualmin_menu($page);
} elsif ($tab eq 'webmail') {
$rv = nav_mailbox_menu($page);
} else {
$rv = nav_webmin_menu($page);
}
if ($page =~ m{/link\.cgi}) {
# X10101
$rv .= <<'SCRIPT';
SCRIPT
}
return $rv;
}
sub nav_get_server_id
{
my ($module) = @_;
my $default;
# Try to find default
my $module_ =
$module eq 'virtual-server' ? 'virtualmin' :
$module eq 'server-manager' ? 'cloudmin' :
$module;
if ($theme_config{ 'settings_right_' . $module_ . '_default' } =~ /^(\d+)$/) {
$default = "$1";
}
# If we have goto substitute default
if ($server_x_goto =~ /\/$module\// &&
($server_x_goto =~ /dom=(\d+)/ || $server_x_goto =~ /id=(\d+)/))
{
my $id_ = "$1";
if ($id_ =~ /^(\d+)$/) {
$default = "$id_";
}
}
return $default;
}
sub nav_set_last_id
{
my ($link) = @_;
if ($link && $link =~ /(id|dom)=(\d+)/) {
return "vars.navigation.select.last='$2';";
}
return undef;
}
sub nav_detect_page
{
my ($page, $set_last) = @_;
my $rv;
if ($page) {
$page = quote_escape($page);
$page =~ s/&/&/g;
my $last_id = $set_last ? nav_set_last_id($page) : undef;
if ($last_id) {
$last_id = "";
}
$rv .= "$last_id\n";
}
return $rv;
}
sub nav_detect_script
{
# Get goto hidden li element
my ($set_last) = @_;
my $rv;
if ($server_x_goto) {
my $link = quote_escape($server_x_goto);
$link =~ s/&/&/g;
my $last_id = $set_last ? nav_set_last_id($link) : undef;
$rv =
"\n";
}
return $rv;
}
sub nav_menu_link
{
my ($link, $text, $icon, $hidden, $after) = @_;
my $external_link = ($link =~ /^(http:\/\/|https:\/\/|ftp:\/\/|ftps:\/\/)/);
if ($icon !~ /\s+/) {
$icon = "fa fa-fw $icon";
}
if ($after) {
$after = " data-after";
}
if ($hidden) {
$hidden = " hidden";
}
$link = "/$link" if (!$external_link && $link !~ /^\//);
$link = ($external_link ? $link : "$theme_webprefix$link");
return
" $text\n";
}
sub nav_cat_link
{
my ($link, $label, $hidden) = @_;
my $rv;
my $external_link = ($link =~ /^(http:\/\/|https:\/\/|ftp:\/\/|ftps:\/\/)/);
$link = "/$link" if (!$external_link && $link !~ /^\//);
$rv = '' . "\n";
$rv .= ' ' . &filter_javascript($label) . '' . "\n";
$rv .= "\n";
return $rv;
}
sub nav_cat
{
my ($c, $label) = @_;
my %icon_table = ('webmin' => 'fa-cog',
'usermin' => 'fa-cog',
'settings' => 'fa-cog',
'global_setting' => 'fa-cog',
'cat_settings' => 'fa-cog',
'system' => 'fa2 fa2-system',
'cat_system' => 'fa2 fa2-system',
'servers' => 'fa2 fa2-server',
'other' => 'fa2 fa2-tools',
'info' => 'fa-info',
'hardware' => 'fa2 fa2-disk',
'global_hardware' => 'fa2 fa2-disk',
'global_storage' => 'fa2 fa2-disk',
'cluster' => 'fa2 fa2-cluster',
'global_cluster' => 'fa-power-off',
'unused' => 'fa-puzzle-piece',
'global_unused' => 'fa-puzzle-piece',
'mail' => 'fa2 fa2-email scaled1_5',
'global_mail' => 'fa2 fa2-email scaled1_5',
'email' => 'fa2 fa2-email scaled1_5',
'global_email' => 'fa2 fa2-email scaled1_5',
'login' => 'fa-user',
'global_login' => 'fa-user',
'apps' => 'fa2 fa2-server',
'global_apps' => 'fa2 fa2-server',
'custom' => 'fa2 fa2-system',
'global_custom' => 'fa2 fa2-system',
'net' => 'fa2 fa2-network',
'ip' => 'fa2 fa2-network',
'global_ip' => 'fa2 fa2-network',
'check' => 'fa-user-md',
'global_check' => 'fa-user-md',
'add' => 'fa-plus',
'global_add' => 'fa-plus',
'backup' => 'fa-backup fa-1_15x',
'global_backup' => 'fa-backup fa-1_15x',
'global_server' => 'fa-cogs',
'cat_server' => 'fa-cogs',
'global_system' => 'fa-cogs',
'global_delete' => 'fa-plug',
'cat_delete' => 'fa-plug',
'global_logs' => 'fa-file-text',
'cat_logs' => 'fa-file-text',
'global_services' => 'fa-puzzle-piece',
'cat_services' => 'fa-puzzle-piece',
'cat_dns' => 'fa2 fa2-dns scaled1_5',
'cat_dnsreg' => 'fa2 fa2-domain scaled1_5',
'cat_mail' => 'fa2 fa2-email-open scaled1_5',
'cat_web' => 'fa2 fa2-web scaled1_5',
'create_new' => 'fa-plus',
'create_add' => 'fa-plus',
'create_create' => 'fa-server-add',
'global_gce' => 'fa-google',
'global_ec2' => 'fa2 fa2-amazon scaled1_5',
'global_hosts' => 'fa-globe',
'global_docker' => 'fa2 fa2-docker margined-left--1 margined-right-1',
'global_virtualmin' => 'fa-virtualmin scaled1_5',
'global_owners' => 'fa-users',
'global_monitor' => 'fa2 fa2-system',
'global_settings' => 'fa-cloud',
'cat_manage' => 'fa2 fa2-tools',
'cat_res' => 'fa-share-alt',
'global_admin' => 'fa-key',
'cat_admin' => 'fa-key',
'global_power' => 'fa-power-off',
'cat_power' => 'fa-power-off',
'cat_webmin' => 'fa-webmin webmin-cat-menu',);
my $icon = $icon_table{$c} || 'fa-link';
if ($label) {
my $rv;
# Show link to close or open catgory
$rv = "\n";
$rv .= "";
$rv .= " @{[&filter_javascript($label)]}\n";
$rv .= '' . "\n";
return $rv;
}
}
sub nav_search
{
my $new_layout = shift;
my $rv = "
";
if (-r "$root_directory/webmin_search.cgi" && $gaccess{'webminsearch'}) {
$rv = "\n";
}
return $rv;
}
sub nav_link_sysinfo
{
my ($user, $mod) = @_;
$mod = "?mod=$mod" if ($mod);
return
nav_menu_link("/sysinfo.cgi$mod",
$user ? $theme_text{'body_header1'} : $theme_text{'theme_xhred_titles_dashboard'},
($user ? 'fa-user-circle' : 'fa-dashboard'),
$theme_config{'settings_sysinfo_link_mini'} eq 'true', 1)
if (dashboard_switch() ne '1');
}
sub nav_link_sysstat
{
my $link;
if (&webmin_user_is_admin()) {
if (-d $root_directory . "/virtual-server/pro/timeplot") {
$link = 'virtual-server/pro';
} elsif (-d $root_directory . "/server-manager/timeplot") {
$link = 'server-manager';
}
if ($link) {
return nav_menu_link("/$link/history.cgi", $theme_text{'left_statistics'}, 'fa-area-chart', 0, 1);
}
}
}
sub nav_link_netdata
{
my $link;
if (&webmin_user_is_admin()) {
if (has_command('netdata') &&
$theme_config{'settings_leftmenu_netdata'} ne 'false')
{
($theme_config{'settings_leftmenu_netdata_link'} ? ($link = $theme_config{'settings_leftmenu_netdata_link'}) :
($link = 'http://' . get_system_hostname() . ':19999'));
}
if ($link) {
my $rv;
$rv = "\n";
return $rv;
}
}
}
sub nav_theme_links
{
my $extra = $theme_config{'settings_leftmenu_custom_links'};
my $rv = "";
if ($extra) {
$extra = replace('\'', '"', un_urlize($extra, 1));
if ($extra && $extra =~ m/"extra":/) {
my ($extra) = $extra =~ /\{(?:\{.*\}|[^{])*\}/sg;
my $extra_json = convert_from_json($extra);
foreach my $e (@{ $extra_json->{'extra'} }) {
if (length($e->{"link"}) && (!length($e->{"level"}) || string_contains($e->{"level"}, $get_user_level))) {
my $target = $e->{"target"};
if ($target) {
$target = " target=\"$target\"";
}
if ($e->{"port"}) {
my $host = $e->{"host"};
if (!$host) {
$host = get_env('http_host');
$host =~ s/:(\d+)$/:$e->{'port'}/;
} else {
$host .= ":$e->{'port'}";
}
my $proto = $e->{'protocol'} ? "$e->{'protocol'}://" : "//";
$e->{"link"} = "$proto$host$e->{'link'}";
}
my $type = string_contains($e->{'link'}, '//') ? '' : 'data-linked';
my $type_class = $type ? "navigation_module_trigger" : "navigation_external_link";
$rv .= ' ';
utf8::encode($e->{'title'});
$rv .= $e->{'title'};
$rv .= '';
}
}
}
}
return $rv;
}
# Sort Virtualmin domain menu links in a predictable order, even when some links
# are missing, which is a somewhat hacky way to achieve the expected behavior,
# as the API currently does not provide a way to precisely control the order of
# domain links returned from other plugins
sub nav_sort_virtualmin_shortcuts
{
my ($items) = @_;
return $items if (ref($items) ne 'ARRAY');
my $item_rank = sub {
my ($item) = @_;
return undef if (ref($item) ne 'HASH' || $item->{'type'} ne 'item');
my $link = $item->{'link'} || '';
# Keep key Virtualmin actions in a predictable order even when some
# links are missing
return 0 if ($link =~ /virtual-server\/(view_domain|summary_domain)\.cgi/);
return 1 if ($link =~ /virtual-server\/list_users\.cgi/);
return 2 if ($link =~ /virtual-server\/list_databases\.cgi/);
return 3 if ($link =~ /virtualmin-podman\/list_containers\.cgi/);
return 4 if ($link =~ /virtual-server\/list_scripts\.cgi/);
return 5 if ($link =~ /filemin\/index\.cgi/);
return 6 if ($link =~ /xterm\/index\.cgi/);
return undef;
};
my @candidate_indexes;
foreach my $index (0 .. $#$items) {
push(@candidate_indexes, $index)
if (defined($item_rank->($items->[$index])));
}
return $items if (@candidate_indexes < 2);
my @sorted_items = map { $_->{'item'} }
sort { $a->{'rank'} <=> $b->{'rank'} || $a->{'index'} <=> $b->{'index'} }
map { {
'index' => $_,
'rank' => $item_rank->($items->[$_]),
'item' => $items->[$_] }
} @candidate_indexes;
my @sorted_menu = @$items;
foreach my $position (0 .. $#candidate_indexes) {
$sorted_menu[$candidate_indexes[$position]] = $sorted_items[$position];
}
return \@sorted_menu;
}
# Return HTML menu structure for given module
sub nav_list_combined_menu
{
my ($modules, $items, $id, $group, $page) = @_;
my ($nav_pos, $extra_links, $rv, $rv_after, $login_mode);
my $search_bar = '';
my $gwp = sub {
my ($link, $mod) = @_;
# Link could but shouldn't end with just &
$link =~ s/&$//;
if ($link) {
if (!string_starts_with($link, "http") &&
!string_starts_with($link, "ftp") &&
!string_starts_with($link, "www") &&
!string_starts_with($link, "../"))
{
$link = "/$link" if (!string_starts_with($link, "/"));
$link = "$theme_webprefix$link"
if ($link !~ /^\Q$theme_webprefix\E/);
# Add module reference to all non module links
if ($mod && $link !~ /$mod\// && $link !~ /[?&]nmod=/ &&
!string_contains($link, "config.cgi")) {
my $sep = ($link =~ /\?/) ? '&' : '?';
$link .= "${sep}nmod=$mod";
}
}
}
return $link;
};
# Support upcoming change to navigation menu in Virtualmin
my $vm_new_format = grep { $_->{'format'} eq 'new' &&
$_->{'module'} eq 'virtual-server' } @$items;
my $vm_has_menu = grep { $_->{'type'} eq 'menu' &&
$_->{'module'} eq 'virtual-server' } @$items;
my $is_vm = grep { $_->{'module'} eq 'virtual-server' } @$items;
my $vm_has_new_domform = grep { $_->{'format'} eq 'link-new' &&
$_->{'module'} eq 'virtual-server' } @$items;
if (!$group && $is_vm) {
$items = nav_sort_virtualmin_shortcuts($items);
}
if ($vm_new_format) {
if ($vm_has_new_domform) {
my @vm_hr = grep { $_->{'type'} eq 'hr' &&
$_->{'module'} eq 'virtual-server' } @$items;
if (@vm_hr > 2) {
$items = [ grep { $_ != $vm_hr[0] } @$items ];
$items = [ grep { $_ != $vm_hr[1] } @$items ] if (!$vm_has_menu);
}
}
$search_bar = nav_search($vm_new_format);
}
my $known_module = $modules ? $modules->[-1] : undef;
foreach my $item (@$items) {
if ((grep {$_ eq $item->{'module'}} @{$modules}) || $group) {
my $link = &$gwp($item->{'link'}, $item->{'module'} || $known_module);
my $icon;
my $rv_after_local;
if ($item->{'type'} eq 'item' &&
$link !~ /virtual-server\/pro\/history\.cgi/)
{
# Define an icon for the link/accordion
if ($link =~ /virtual-server\/index\.cgi/ ||
$link =~ /server-manager\/index\.cgi/)
{
$icon = '';
} elsif ($link =~ /\/virtualmin-wp-workbench/)
{
$icon = '';
} elsif ($link =~ /\/virtual-server\/edit_newvalidate\.cgi/ &&
!&webmin_user_is_admin())
{
$icon = '';
} elsif ($link =~ /mailbox\/list_folders\.cgi/ ||
$link =~ /mailbox\/list_ifolders\.cgi/)
{
$icon = '';
} elsif ($link =~ /mailbox\/list_addresses\.cgi/) {
$icon = '';
} elsif ($link =~ /filter\/edit_forward\.cgi/) {
$icon = '';
} elsif ($link =~ /filter\/edit_auto\.cgi/) {
$icon = '';
} elsif ($link =~ /filter/) {
$icon = '';
} elsif ($link =~ /mailbox\/edit_sig\.cgi/) {
$icon = '';
} elsif ($link =~ /mailbox\/index\.cgi?id=/) {
$icon = '';
} elsif ($link =~ /\/#demo_history$/) {
$icon = '';
$rv_after_local = $link;
}
if ($get_user_level == 1) {
if ($link =~ /\/virtual-server\/edit_pass\.cgi/ &&
$link !~ /\/virtual-server\/edit_pass\.cgi\?/)
{
$icon = '';
} elsif ($link =~ /\/virtual-server\/edit_newplan\.cgi/) {
$icon = '';
} elsif ($link =~ /\/virtual-server\/edit_newresels\.cgi/) {
$icon = '';
} elsif ($link =~ /\/virtual-server\/bwgraph\.cgi/ && $id ne 'cat_logs') {
$icon = '';
}
}
if ($link =~ /\/virtual-server\/domain_form\.cgi/) {
if ($link =~ /to=/) {
$icon = '';
} elsif ($link =~ /parentuser/) {
$icon = '';
} else {
$icon = '';
}
} elsif ($link =~ /\/virtual-server\/edit_domain\.cgi/ ||
$link =~ /\/server-manager\/edit_serv\.cgi/)
{
$icon = '';
} elsif ($link =~ /\/virtual-server\/(view_domain|summary_domain)\.cgi/ ) {
$icon = '';
} elsif ($link =~ /\/virtual-server\/list_users\.cgi/) {
$icon = '';
} elsif ($link =~ /\/virtual-server\/list_aliases\.cgi/ && $id ne 'cat_mail') {
$icon = '';
} elsif ($link =~ /\/virtual-server\/list_databases\.cgi/) {
$icon = '';
} elsif ($link =~ /\/server-manager\/mass_update_form\.cgi/)
{
$icon = '';
} elsif ($link =~ /\/virtual-server\/list_scripts\.cgi/)
{
$icon = '';
} elsif ($link =~ /\/virtualmin-podman/) {
if ($link =~ /list_containers.cgi/) {
$icon = '';
} else {
$icon = '';
}
} elsif ($link =~ /\/filemin\/index\.cgi/) {
$icon = '';
} elsif ($link =~ /\/xterm\/index\.cgi\?user/) {
$icon = '';
} elsif ($link =~ /\/virtual-server\/edit_html\.cgi/) {
$icon = '';
} elsif ($link =~ /\/server-manager\/edit_pass\.cgi/ ||
$link =~ /\/virtual-server\/edit_pass\.cgi$/ ||
$link =~ /\/changepass\/$/)
{
$icon = '';
} elsif ($link =~ /\/server-manager\/save_serv\.cgi/ && $link =~ /recheck=1/) {
$icon = '';
} elsif ($link =~ /\/server-manager\/create_form\.cgi/ && !$group) {
$icon = '';
} elsif ($link =~ /\/server-manager\/save_serv\.cgi/) {
if ($link =~ /refresh=1/) {
$icon = '';
} elsif ($link =~ /regen=1/) {
$icon = '';
}
} elsif (
($link =~ /^http:\/\// || $link =~ /^https:\/\// || $link =~ /^ftp:\/\// || $link =~ /^ftps:\/\//) &&
$link !~ /virtualmin\.com\/docs\/professional/)
{
$icon = '';
} elsif ($link =~ /\.\.\/servers\/link\.cgi/) {
$icon = '';
}
# Set variable in case it hasn't been set before
if (!length $link) {
$icon = undef;
}
my $rv_;
$rv_ = '{'inactive'} ? " data-link-inactive" : "") . ' data-linked'
.
( $item->{'target'} ? ' class="navigation_external"' :
''
) .
'>' . "\n";
$rv_ .=
'{'target'}) ? "class=\"navigation_module_trigger\" " :
''
) .
'href="' . $link . '">' .
($icon =~ /' . $item->{'desc'} . '' . "\n";
$rv_ .= '' . "\n";
$rv_ .= "\n";
if ($rv_after_local) {
$rv_after .= $rv_;
} else {
$rv .= $rv_;
}
} elsif ($item->{'type'} eq 'html') {
if (trim(html_strip($item->{'html'}))) {
$rv .= '';
}
} elsif ($item->{'type'} eq 'text' && $item->{'json'}) {
$login_mode =
"$theme_text{'theme_global_access_level'}: @{[html_escape($item->{'json'}->{'level'})]}";
} elsif ($item->{'type'} eq 'text' && $item->{'desc'}) {
if ($login_mode++ == 1) {
$login_mode =
"$theme_text{'theme_global_access_level'}: @{[html_escape($item->{'desc'})]}";
}
} elsif ($item->{'type'} eq 'cat') {
$rv .= nav_cat($item->{'id'}, $item->{'desc'});
$rv .= '' . "\n";
my $menu = nav_list_combined_menu([$item->{'module'}], $item->{'members'}, $item->{'id'}, 'group');
$rv .= $menu->{'before'};
if (($item->{'id'} eq 'global_setting' || $item->{'id'} eq 'global_settings') &&
&webmin_user_is_admin() &&
!$extra_links++)
{
$rv .=
nav_cat_link("/tconfig.cgi", $theme_text{'settings_right_theme_left_configuration_title'}, 'hidden');
$rv .= nav_cat_link("/settings-editor_read.cgi",
$theme_text{'settings_right_theme_left_extensions_title'}, 'hidden');
$rv .=
nav_cat_link("/settings-logos.cgi", $theme_text{'settings_right_theme_left_logo_title'}, 'hidden');
$rv .= nav_cat_link("/settings-backgrounds.cgi",
$theme_text{'theme_xhred_settings_right_theme_bgs_title'}, 'hidden');
if (check_pro_package('vm') eq '1' &&
$item->{'module'} eq 'virtual-server')
{
$rv .= nav_cat_link("/virtual-server/licence.cgi", $theme_text{'right_vlcheck'}, 1);
}
if (check_pro_package('cm') eq '1' &&
$item->{'module'} eq 'server-manager')
{
$rv .= nav_cat_link("/server-manager/licence.cgi", $theme_text{'right_slcheck'}, 1);
}
} elsif (!&webmin_user_is_admin() &&
$theme_config{'settings_theme_config_admins_only_privileged'} ne 'true' &&
!$extra_links++)
{
$rv .= nav_cat_link("/tconfig.cgi", $theme_text{'settings_right_theme_left_configuration_title'}, 1);
}
$rv .= "
\n";
} elsif ($item->{'type'} eq 'hr') {
$nav_pos++;
my $no_vm_menu_class = $is_vm && !$vm_has_menu ? ' no_vm_menu' : '';
my $separator = "";
if ($vm_new_format) {
if ($nav_pos eq '2' || $no_vm_menu_class) {
$rv .= $separator;
}
}
else {
if ($nav_pos eq '2') {
$rv .= nav_search($vm_new_format);
}
}
} elsif (($item->{'type'} eq 'menu' || $item->{'type'} eq 'input') &&
$item->{'module'} ne 'mailbox')
{
# For with an input of some kind
if ($item->{'cgi'}) {
$rv .= "