1464 lines
No EOL
68 KiB
TypeScript
1464 lines
No EOL
68 KiB
TypeScript
import {
|
|
PermissionManager,
|
|
} from "tc-shared/permission/PermissionManager";
|
|
import {PermissionType} from "tc-shared/permission/PermissionType";
|
|
import {ConnectionHandler} from "tc-shared/ConnectionHandler";
|
|
import {createErrorModal, createInfoModal, createInputModal, createModal, Modal} from "tc-shared/ui/elements/Modal";
|
|
import {HTMLPermissionEditor} from "tc-shared/ui/modal/permission/HTMLPermissionEditor";
|
|
import {spawnIconSelect} from "tc-shared/ui/modal/ModalIconSelect";
|
|
import {CanvasPermissionEditor} from "tc-shared/ui/modal/permission/CanvasPermissionEditor";
|
|
import {Settings, settings} from "tc-shared/settings";
|
|
import {ChannelEntry} from "tc-shared/ui/channel";
|
|
import {LogCategory} from "tc-shared/log";
|
|
import {CommandResult, ErrorID} from "tc-shared/connection/ServerConnectionDeclaration";
|
|
import * as log from "tc-shared/log";
|
|
import {Group, GroupManager, GroupTarget, GroupType} from "tc-shared/permission/GroupManager";
|
|
import {spawnYesNo} from "tc-shared/ui/modal/ModalYesNo";
|
|
import * as contextmenu from "tc-shared/ui/elements/ContextMenu";
|
|
import {copy_to_clipboard} from "tc-shared/utils/helpers";
|
|
import {formatMessage} from "tc-shared/ui/frames/chat";
|
|
import {
|
|
senseless_channel_group_permissions,
|
|
senseless_channel_permissions, senseless_client_channel_permissions,
|
|
senseless_client_permissions, senseless_server_group_permissions
|
|
} from "tc-shared/ui/modal/permission/SenselessPermissions";
|
|
import {AbstractPermissionEditor, PermissionEditorMode} from "tc-shared/ui/modal/permission/AbstractPermissionEditor";
|
|
import {tra} from "tc-shared/i18n/localize";
|
|
|
|
declare global {
|
|
interface JQuery<TElement = HTMLElement> {
|
|
dropdown: any;
|
|
}
|
|
}
|
|
|
|
export type OptionsServerGroup = {};
|
|
export type OptionsChannelGroup = {};
|
|
export type OptionsClientPermissions = { unique_id?: string };
|
|
export type OptionsChannelPermissions = { channel_id?: number };
|
|
export type OptionsClientChannelPermissions = OptionsClientPermissions & OptionsChannelPermissions;
|
|
export interface OptionMap {
|
|
"sg": OptionsServerGroup,
|
|
"cg": OptionsChannelGroup,
|
|
"clp": OptionsClientPermissions,
|
|
"chp": OptionsChannelPermissions,
|
|
"clchp": OptionsClientChannelPermissions
|
|
}
|
|
|
|
export function _space() {
|
|
const now = Date.now();
|
|
while(now + 100 > Date.now());
|
|
}
|
|
|
|
export function spawnPermissionEdit<T extends keyof OptionMap>(connection: ConnectionHandler, selected_tab?: T, options?: OptionMap[T]) : Modal {
|
|
options = options || {};
|
|
|
|
const modal = createModal({
|
|
header: function() {
|
|
return tr("Server Permissions");
|
|
},
|
|
body: function () {
|
|
let properties: any = {};
|
|
let tag = $("#tmpl_server_permissions").renderTag(properties);
|
|
|
|
/* build the permission editor */
|
|
const permission_editor: AbstractPermissionEditor = (() => {
|
|
const editor = new HTMLPermissionEditor();
|
|
editor.initialize(connection.permissions.groupedPermissions());
|
|
editor.icon_resolver = async id => {
|
|
const icon = connection.fileManager.icons.load_icon(id);
|
|
await icon.await_loading();
|
|
|
|
const tag = document.createElement("img");
|
|
await new Promise((resolve, reject) => {
|
|
tag.onerror = reject;
|
|
tag.onload = resolve;
|
|
tag.src = icon.loaded_url || "nope";
|
|
});
|
|
return tag;
|
|
};
|
|
editor.icon_selector = current_icon => new Promise<number>(resolve => {
|
|
spawnIconSelect(connection, id => resolve(new Int32Array([id])[0]), current_icon);
|
|
});
|
|
|
|
if(editor instanceof CanvasPermissionEditor)
|
|
setTimeout(() => editor.update_ui(), 500);
|
|
return editor;
|
|
})();
|
|
|
|
const container_tab_list = tag.find(".right > .header");
|
|
{
|
|
const label_current = tag.find(".left .container-selected");
|
|
const create_tab = (tab_entry: JQuery, container_name: string, hidden_permissions: PermissionType[]) => {
|
|
const target_container = tag.find(".body .container." + container_name);
|
|
|
|
tab_entry.on('click', () => {
|
|
/* Using a timeout here prevents unnecessary style calculations required by other click event handlers */
|
|
setTimeout(() => {
|
|
container_tab_list.find(".selected").removeClass("selected");
|
|
tab_entry.addClass("selected");
|
|
label_current.text(tab_entry.find("a").text());
|
|
|
|
/* dont use show() here because it causes a style recalculation */
|
|
for(const element of tag.find(".body .container"))
|
|
(<HTMLElement>element).style.display = "none";
|
|
|
|
permission_editor.set_hidden_permissions(settings.static_global(Settings.KEY_PERMISSIONS_SHOW_ALL) ? undefined : hidden_permissions);
|
|
permission_editor.html_tag()[0].remove();
|
|
target_container.find(".permission-editor").trigger('show');
|
|
target_container.find(".permission-editor").append(permission_editor.html_tag());
|
|
|
|
for(const element of target_container)
|
|
(<HTMLElement>element).style.display = null;
|
|
}, 0);
|
|
});
|
|
};
|
|
|
|
create_tab(container_tab_list.find(".sg"), "container-view-server-groups", senseless_server_group_permissions);
|
|
create_tab(container_tab_list.find(".cg"), "container-view-channel-groups", senseless_channel_group_permissions);
|
|
create_tab(container_tab_list.find(".chp"), "container-view-channel-permissions", senseless_channel_permissions);
|
|
create_tab(container_tab_list.find(".clp"), "container-view-client-permissions", senseless_client_permissions);
|
|
create_tab(container_tab_list.find(".clchp"), "container-view-client-channel-permissions", senseless_client_channel_permissions);
|
|
}
|
|
|
|
apply_server_groups(connection, permission_editor, tag.find(".left .container-view-server-groups"), tag.find(".right .container-view-server-groups"));
|
|
apply_channel_groups(connection, permission_editor, tag.find(".left .container-view-channel-groups"), tag.find(".right .container-view-channel-groups"));
|
|
apply_channel_permission(connection, permission_editor, tag.find(".left .container-view-channel-permissions"), tag.find(".right .container-view-channel-permissions"));
|
|
apply_client_permission(connection, permission_editor, tag.find(".left .container-view-client-permissions"), tag.find(".right .container-view-client-permissions"), selected_tab == "clp" ? <any>options : {});
|
|
apply_client_channel_permission(connection, permission_editor, tag.find(".left .container-view-client-channel-permissions"), tag.find(".right .container-view-client-channel-permissions"), selected_tab == "clchp" ? <any>options : {});
|
|
|
|
setTimeout(() => container_tab_list.find("." + (selected_tab || "sg")).trigger('click'), 0);
|
|
return tag.dividerfy();
|
|
},
|
|
footer: undefined,
|
|
|
|
min_width: "30em",
|
|
height: "80%",
|
|
trigger_tab: false,
|
|
full_size: true
|
|
});
|
|
|
|
const tag = modal.htmlTag;
|
|
tag.find(".modal-body").addClass("modal-permission-editor");
|
|
if(selected_tab)
|
|
setTimeout(() => tag.find(".tab-header .entry[x-id=" + selected_tab + "]").first().trigger("click"), 1);
|
|
tag.find(".btn_close").on('click', () => {
|
|
modal.close();
|
|
});
|
|
|
|
return modal;
|
|
}
|
|
|
|
function build_channel_tree(connection: ConnectionHandler, channel_list: JQuery, selected_channel: number, select_callback: (channel: ChannelEntry, icon_update: (id: number) => any) => any) {
|
|
const root = connection.channelTree.get_first_channel();
|
|
if(!root) return;
|
|
|
|
const build_channel = (channel: ChannelEntry, level: number) => {
|
|
let tag = $.spawn("div").addClass("channel").css("padding-left", "calc(0.25em + " + (level * 16) + "px)").attr("channel-id", channel.channelId);
|
|
let icon_tag = connection.fileManager.icons.generateTag(channel.properties.channel_icon_id);
|
|
icon_tag.appendTo(tag);
|
|
const _update_icon = icon_id => icon_tag.replaceWith(icon_tag = connection.fileManager.icons.generateTag(icon_id));
|
|
|
|
{
|
|
let name = $.spawn("a").text(channel.channelName() + " (" + channel.channelId + ")").addClass("name");
|
|
name.appendTo(tag);
|
|
}
|
|
|
|
tag.on('click', event => {
|
|
channel_list.find(".selected").removeClass("selected");
|
|
tag.addClass("selected");
|
|
select_callback(channel, _update_icon);
|
|
});
|
|
|
|
return tag;
|
|
};
|
|
|
|
const build_channels = (root: ChannelEntry, level: number) => {
|
|
build_channel(root, level).appendTo(channel_list);
|
|
const child_head = root.children(false).find(e => e.channel_previous === undefined);
|
|
if(child_head)
|
|
build_channels(child_head, level + 1);
|
|
if(root.channel_next)
|
|
build_channels(root.channel_next, level)
|
|
};
|
|
build_channels(root, 0);
|
|
|
|
let selected_channel_tag = channel_list.find(".channel[channel-id=" + selected_channel + "]");
|
|
if(!selected_channel_tag || selected_channel_tag.length < 1)
|
|
selected_channel_tag = channel_list.find('.channel').first();
|
|
setTimeout(() => selected_channel_tag.trigger('click'), 0);
|
|
}
|
|
|
|
function apply_client_channel_permission(connection: ConnectionHandler, editor: AbstractPermissionEditor, tab_left: JQuery, tab_right: JQuery, options: OptionsClientChannelPermissions) {
|
|
let current_cldbid: number = 0;
|
|
let current_channel: ChannelEntry;
|
|
|
|
/* the editor */
|
|
{
|
|
const pe_client = tab_right.find(".permission-editor");
|
|
tab_right.on('show', event => {
|
|
editor.set_toggle_button(undefined, undefined);
|
|
pe_client.append(editor.html_tag());
|
|
if(connection.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_CLIENT_PERMISSION_LIST).granted(1)) {
|
|
if(current_cldbid && current_channel)
|
|
editor.set_mode(PermissionEditorMode.VISIBLE);
|
|
else
|
|
editor.set_mode(PermissionEditorMode.UNSET);
|
|
} else {
|
|
editor.set_mode(PermissionEditorMode.NO_PERMISSION);
|
|
return;
|
|
}
|
|
|
|
|
|
editor.set_listener_update(() => {
|
|
if(!current_cldbid || !current_channel) return;
|
|
|
|
connection.permissions.requestClientChannelPermissions(current_cldbid, current_channel.channelId).then(result => {
|
|
editor.set_permissions(result);
|
|
editor.set_mode(PermissionEditorMode.VISIBLE);
|
|
}).catch(error => {
|
|
console.log(error); //TODO handling?
|
|
});
|
|
});
|
|
|
|
/* TODO: Error handling? */
|
|
editor.set_listener(async (permission, value) => {
|
|
if (!current_cldbid)
|
|
throw "unset client";
|
|
if (!current_channel)
|
|
throw "unset channel";
|
|
|
|
if (value.remove) {
|
|
/* remove the permission */
|
|
if (typeof (value.value) !== "undefined") {
|
|
log.info(LogCategory.PERMISSIONS, tr("Removing client channel permission %s. permission.id: %o"),
|
|
permission.name,
|
|
permission.id,
|
|
);
|
|
|
|
await connection.serverConnection.send_command("channelclientdelperm", {
|
|
cldbid: current_cldbid,
|
|
cid: current_channel.channelId,
|
|
permid: permission.id,
|
|
});
|
|
} else {
|
|
log.info(LogCategory.PERMISSIONS, tr("Removing client channel grant permission %s. permission.id: %o"),
|
|
permission.name,
|
|
permission.id_grant(),
|
|
value.granted,
|
|
);
|
|
|
|
await connection.serverConnection.send_command("channelclientdelperm", {
|
|
cldbid: current_cldbid,
|
|
cid: current_channel.channelId,
|
|
permid: permission.id_grant(),
|
|
});
|
|
}
|
|
} else {
|
|
/* add the permission */
|
|
if (typeof (value.value) !== "undefined") {
|
|
log.info(LogCategory.PERMISSIONS, tr("Adding or updating client channel permission %s. permission.{id: %o, value: %o, flag_skip: %o, flag_negate: %o}"),
|
|
permission.name,
|
|
permission.id,
|
|
value.value,
|
|
value.flag_skip,
|
|
value.flag_negate
|
|
);
|
|
|
|
await connection.serverConnection.send_command("channelclientaddperm", {
|
|
cldbid: current_cldbid,
|
|
cid: current_channel.channelId,
|
|
permid: permission.id,
|
|
permvalue: value.value,
|
|
permskip: value.flag_skip,
|
|
permnegated: value.flag_negate
|
|
});
|
|
} else {
|
|
log.info(LogCategory.PERMISSIONS, tr("Adding or updating client channel grant permission %s. permission.{id: %o, value: %o}"),
|
|
permission.name,
|
|
permission.id_grant(),
|
|
value.granted,
|
|
);
|
|
|
|
await connection.serverConnection.send_command("channelclientaddperm", {
|
|
cldbid: current_cldbid,
|
|
cid: current_channel.channelId,
|
|
permid: permission.id_grant(),
|
|
permvalue: value.granted,
|
|
permskip: false,
|
|
permnegated: false
|
|
});
|
|
}
|
|
}
|
|
});
|
|
|
|
/* FIXME: Use cached permissions */
|
|
editor.trigger_update();
|
|
});
|
|
}
|
|
|
|
build_channel_tree(connection, tab_left.find(".list-channel .entries"), options.channel_id || 0, channel => {
|
|
if(current_channel == channel) return;
|
|
|
|
current_channel = channel;
|
|
|
|
/* TODO: Test for visibility */
|
|
editor.trigger_update();
|
|
});
|
|
|
|
{
|
|
|
|
const tag_select = tab_left.find(".client-select");
|
|
const tag_select_uid = tag_select.find("input");
|
|
const tag_select_error = tag_select.find(".invalid-feedback");
|
|
|
|
const tag_client_name = tab_left.find(".client-name");
|
|
const tag_client_uid = tab_left.find(".client-uid");
|
|
const tag_client_dbid = tab_left.find(".client-dbid");
|
|
|
|
|
|
const resolve_client = () => {
|
|
let client_uid = tag_select_uid.val() as string;
|
|
connection.serverConnection.command_helper.info_from_uid(client_uid).then(result => {
|
|
if(!result || result.length == 0) return Promise.reject("invalid data");
|
|
tag_select.removeClass('is-invalid');
|
|
|
|
tag_client_name.val(result[0].client_nickname );
|
|
tag_client_uid.val(result[0].client_unique_id);
|
|
tag_client_dbid.val(result[0].client_database_id);
|
|
|
|
current_cldbid = result[0].client_database_id;
|
|
editor.trigger_update();
|
|
}).catch(error => {
|
|
console.log(error);
|
|
if(error instanceof CommandResult) {
|
|
if(error.id == ErrorID.EMPTY_RESULT)
|
|
error = "unknown client";
|
|
else
|
|
error = error.extra_message || error.message;
|
|
}
|
|
|
|
tag_client_name.val("");
|
|
tag_client_uid.val("");
|
|
tag_client_dbid.val("");
|
|
|
|
tag_select_error.text(error);
|
|
tag_select.addClass('is-invalid');
|
|
editor.set_mode(PermissionEditorMode.UNSET);
|
|
});
|
|
};
|
|
|
|
tag_select_uid.on('change', event => resolve_client());
|
|
if(options.unique_id) {
|
|
tag_select_uid.val(options.unique_id);
|
|
setTimeout(() => resolve_client());
|
|
}
|
|
}
|
|
}
|
|
|
|
function apply_client_permission(connection: ConnectionHandler, editor: AbstractPermissionEditor, tab_left: JQuery, tab_right: JQuery, options: OptionsClientPermissions) {
|
|
let current_cldbid: number = 0;
|
|
|
|
/* the editor */
|
|
{
|
|
const pe_client = tab_right.find("permission-editor.client");
|
|
tab_right.on('show', event => {
|
|
editor.set_toggle_button(undefined, undefined);
|
|
pe_client.append(editor.html_tag());
|
|
if(connection.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_CLIENT_PERMISSION_LIST).granted(1)) {
|
|
if(current_cldbid)
|
|
editor.set_mode(PermissionEditorMode.VISIBLE);
|
|
else
|
|
editor.set_mode(PermissionEditorMode.UNSET);
|
|
} else {
|
|
editor.set_mode(PermissionEditorMode.NO_PERMISSION);
|
|
return;
|
|
}
|
|
|
|
editor.set_listener_update(() => {
|
|
if(!current_cldbid) return;
|
|
|
|
connection.permissions.requestClientPermissions(current_cldbid).then(result => {
|
|
editor.set_permissions(result);
|
|
editor.set_mode(PermissionEditorMode.VISIBLE);
|
|
}).catch(error => {
|
|
console.log(error); //TODO handling?
|
|
});
|
|
});
|
|
|
|
/* TODO: Error handling? */
|
|
editor.set_listener(async (permission, value) => {
|
|
if (!current_cldbid)
|
|
throw "unset client";
|
|
|
|
if (value.remove) {
|
|
/* remove the permission */
|
|
if (typeof (value.value) !== "undefined") {
|
|
log.info(LogCategory.PERMISSIONS, tr("Removing client permission %s. permission.id: %o"),
|
|
permission.name,
|
|
permission.id,
|
|
);
|
|
|
|
await connection.serverConnection.send_command("clientdelperm", {
|
|
cldbid: current_cldbid,
|
|
permid: permission.id,
|
|
});
|
|
} else {
|
|
log.info(LogCategory.PERMISSIONS, tr("Removing client grant permission %s. permission.id: %o"),
|
|
permission.name,
|
|
permission.id_grant(),
|
|
value.granted,
|
|
);
|
|
|
|
await connection.serverConnection.send_command("clientdelperm", {
|
|
cldbid: current_cldbid,
|
|
permid: permission.id_grant(),
|
|
});
|
|
}
|
|
} else {
|
|
/* add the permission */
|
|
if (typeof (value.value) !== "undefined") {
|
|
log.info(LogCategory.PERMISSIONS, tr("Adding or updating client permission %s. permission.{id: %o, value: %o, flag_skip: %o, flag_negate: %o}"),
|
|
permission.name,
|
|
permission.id,
|
|
value.value,
|
|
value.flag_skip,
|
|
value.flag_negate
|
|
);
|
|
|
|
await connection.serverConnection.send_command("clientaddperm", {
|
|
cldbid: current_cldbid,
|
|
permid: permission.id,
|
|
permvalue: value.value,
|
|
permskip: value.flag_skip,
|
|
permnegated: value.flag_negate
|
|
});
|
|
} else {
|
|
log.info(LogCategory.PERMISSIONS, tr("Adding or updating client grant permission %s. permission.{id: %o, value: %o}"),
|
|
permission.name,
|
|
permission.id_grant(),
|
|
value.granted,
|
|
);
|
|
|
|
await connection.serverConnection.send_command("clientaddperm", {
|
|
cldbid: current_cldbid,
|
|
permid: permission.id_grant(),
|
|
permvalue: value.granted,
|
|
permskip: false,
|
|
permnegated: false
|
|
});
|
|
}
|
|
}
|
|
});
|
|
|
|
/* FIXME: Use cached permissions */
|
|
editor.trigger_update();
|
|
});
|
|
}
|
|
|
|
|
|
const tag_select = tab_left.find(".client-select");
|
|
const tag_select_uid = tag_select.find("input");
|
|
const tag_select_error = tag_select.find(".invalid-feedback");
|
|
|
|
const tag_client_name = tab_left.find(".client-name");
|
|
const tag_client_uid = tab_left.find(".client-uid");
|
|
const tag_client_dbid = tab_left.find(".client-dbid");
|
|
|
|
const resolve_client = () => {
|
|
let client_uid = tag_select_uid.val() as string;
|
|
connection.serverConnection.command_helper.info_from_uid(client_uid).then(result => {
|
|
if(!result || result.length == 0) return Promise.reject("invalid data");
|
|
tag_select.removeClass("is-invalid");
|
|
|
|
tag_client_name.val(result[0].client_nickname );
|
|
tag_client_uid.val(result[0].client_unique_id);
|
|
tag_client_dbid.val(result[0].client_database_id);
|
|
|
|
current_cldbid = result[0].client_database_id;
|
|
editor.trigger_update();
|
|
}).catch(error => {
|
|
console.log(error);
|
|
if(error instanceof CommandResult) {
|
|
if(error.id == ErrorID.EMPTY_RESULT)
|
|
error = "unknown client";
|
|
else
|
|
error = error.extra_message || error.message;
|
|
}
|
|
|
|
tag_client_name.val("");
|
|
tag_client_uid.val("");
|
|
tag_client_dbid.val("");
|
|
|
|
tag_select_error.text(error);
|
|
tag_select.addClass("is-invalid");
|
|
editor.set_mode(PermissionEditorMode.UNSET);
|
|
});
|
|
};
|
|
|
|
tag_select_uid.on('change', event => resolve_client());
|
|
if(options.unique_id) {
|
|
tag_select_uid.val(options.unique_id);
|
|
setTimeout(() => resolve_client());
|
|
}
|
|
}
|
|
|
|
function apply_channel_permission(connection: ConnectionHandler, editor: AbstractPermissionEditor, tab_left: JQuery, tab_right: JQuery) {
|
|
let current_channel: ChannelEntry | undefined;
|
|
let update_channel_icon: (id: number) => any;
|
|
|
|
/* the editor */
|
|
{
|
|
const pe_channel = tab_right.find(".permission-editor");
|
|
tab_right.on('show', event => {
|
|
editor.set_toggle_button(undefined, undefined);
|
|
pe_channel.append(editor.html_tag());
|
|
if(connection.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_CHANNEL_PERMISSION_LIST).granted(1))
|
|
editor.set_mode(PermissionEditorMode.VISIBLE);
|
|
else {
|
|
editor.set_mode(PermissionEditorMode.NO_PERMISSION);
|
|
return;
|
|
}
|
|
|
|
editor.set_listener_update(() => {
|
|
if(!current_channel) return;
|
|
|
|
connection.permissions.requestChannelPermissions(current_channel.channelId).then(result => editor.set_permissions(result)).catch(error => {
|
|
editor.set_permissions([]);
|
|
console.log(error); //TODO handling?
|
|
});
|
|
});
|
|
|
|
editor.set_listener(async (permission, value) => {
|
|
if (!current_channel)
|
|
throw "unset channel";
|
|
|
|
if (value.remove) {
|
|
/* remove the permission */
|
|
if (typeof (value.value) !== "undefined") {
|
|
log.info(LogCategory.PERMISSIONS, tr("Removing channel permission %s. permission.id: %o"),
|
|
permission.name,
|
|
permission.id,
|
|
);
|
|
|
|
await connection.serverConnection.send_command("channeldelperm", {
|
|
cid: current_channel.channelId,
|
|
permid: permission.id,
|
|
}).then(e => {
|
|
if(permission.name === "i_icon_id" && update_channel_icon)
|
|
update_channel_icon(undefined);
|
|
return e;
|
|
});
|
|
} else {
|
|
/* TODO Remove this because its totally useless. Remove this from the UI as well */
|
|
log.info(LogCategory.PERMISSIONS, tr("Removing channel grant permission %s. permission.id: %o"),
|
|
permission.name,
|
|
permission.id_grant(),
|
|
value.granted,
|
|
);
|
|
|
|
await connection.serverConnection.send_command("channeldelperm", {
|
|
cid: current_channel.channelId,
|
|
permid: permission.id_grant(),
|
|
});
|
|
}
|
|
} else {
|
|
/* add the permission */
|
|
if (typeof (value.value) !== "undefined") {
|
|
log.info(LogCategory.PERMISSIONS, tr("Adding or updating channel permission %s. permission.{id: %o, value: %o, flag_skip: %o, flag_negate: %o}"),
|
|
permission.name,
|
|
permission.id,
|
|
value.value,
|
|
value.flag_skip,
|
|
value.flag_negate
|
|
);
|
|
|
|
await connection.serverConnection.send_command("channeladdperm", {
|
|
cid: current_channel.channelId,
|
|
permid: permission.id,
|
|
permvalue: value.value,
|
|
permskip: value.flag_skip,
|
|
permnegated: value.flag_negate
|
|
}).then(e => {
|
|
if(permission.name === "i_icon_id" && update_channel_icon)
|
|
update_channel_icon(value.value);
|
|
return e;
|
|
});
|
|
} else {
|
|
/* TODO Remove this because its totally useless. Remove this from the UI as well */
|
|
log.info(LogCategory.PERMISSIONS, tr("Adding or updating channel grant permission %s. permission.{id: %o, value: %o}"),
|
|
permission.name,
|
|
permission.id_grant(),
|
|
value.granted,
|
|
);
|
|
|
|
await connection.serverConnection.send_command("channeladdperm", {
|
|
cid: current_channel.channelId,
|
|
permid: permission.id_grant(),
|
|
permvalue: value.granted,
|
|
permskip: false,
|
|
permnegated: false
|
|
});
|
|
}
|
|
}
|
|
});
|
|
|
|
/* FIXME: Use cached permissions */
|
|
editor.trigger_update();
|
|
});
|
|
}
|
|
|
|
let channel_list = tab_left.find(".list-channel .entries");
|
|
build_channel_tree(connection, channel_list, 0, (channel, update) => {
|
|
current_channel = channel;
|
|
update_channel_icon = update;
|
|
editor.trigger_update();
|
|
});
|
|
}
|
|
|
|
function apply_channel_groups(connection: ConnectionHandler, editor: AbstractPermissionEditor, tab_left: JQuery, tab_right: JQuery) {
|
|
let current_group;
|
|
let update_group_icon: (id: number) => any;
|
|
let update_groups: (selected_group: number) => any;
|
|
let update_buttons: () => any;
|
|
|
|
/* the editor */
|
|
{
|
|
const pe_server = tab_right.find(".permission-editor");
|
|
tab_right.on('show', event => {
|
|
editor.set_toggle_button(undefined, undefined);
|
|
pe_server.append(editor.html_tag());
|
|
if(connection.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_CHANNELGROUP_PERMISSION_LIST).granted(1))
|
|
editor.set_mode(PermissionEditorMode.VISIBLE);
|
|
else {
|
|
editor.set_mode(PermissionEditorMode.NO_PERMISSION);
|
|
return;
|
|
}
|
|
|
|
editor.set_listener_update(() => {
|
|
if(!current_group) return;
|
|
|
|
connection.groups.request_permissions(current_group).then(result => editor.set_permissions(result)).catch(error => {
|
|
console.log(error); //TODO handling?
|
|
});
|
|
});
|
|
|
|
editor.set_listener(async (permission, value) => {
|
|
if (!current_group)
|
|
throw "unset channel group";
|
|
|
|
if (value.remove) {
|
|
/* remove the permission */
|
|
if (typeof (value.value) !== "undefined") {
|
|
log.info(LogCategory.PERMISSIONS, tr("Removing channel group permission %s. permission.id: %o"),
|
|
permission.name,
|
|
permission.id,
|
|
);
|
|
|
|
await connection.serverConnection.send_command("channelgroupdelperm", {
|
|
cgid: current_group.id,
|
|
permid: permission.id,
|
|
}).then(e => {
|
|
if(permission.name === "i_icon_id" && update_group_icon)
|
|
update_group_icon(undefined);
|
|
return e;
|
|
});
|
|
} else {
|
|
log.info(LogCategory.PERMISSIONS, tr("Removing channel group grant permission %s. permission.id: %o"),
|
|
permission.name,
|
|
permission.id_grant(),
|
|
value.granted,
|
|
);
|
|
|
|
await connection.serverConnection.send_command("channelgroupdelperm", {
|
|
cgid: current_group.id,
|
|
permid: permission.id_grant(),
|
|
});
|
|
}
|
|
} else {
|
|
/* add the permission */
|
|
if (typeof (value.value) !== "undefined") {
|
|
log.info(LogCategory.PERMISSIONS, tr("Adding or updating channel group permission %s. permission.{id: %o, value: %o, flag_skip: %o, flag_negate: %o}"),
|
|
permission.name,
|
|
permission.id,
|
|
value.value,
|
|
value.flag_skip,
|
|
value.flag_negate
|
|
);
|
|
|
|
await connection.serverConnection.send_command("channelgroupaddperm", {
|
|
cgid: current_group.id,
|
|
permid: permission.id,
|
|
permvalue: value.value,
|
|
permskip: value.flag_skip,
|
|
permnegated: value.flag_negate
|
|
}).then(e => {
|
|
if(permission.name === "i_icon_id" && update_group_icon)
|
|
update_group_icon(value.value);
|
|
return e;
|
|
});
|
|
} else {
|
|
log.info(LogCategory.PERMISSIONS, tr("Adding or updating channel group grant permission %s. permission.{id: %o, value: %o}"),
|
|
permission.name,
|
|
permission.id_grant(),
|
|
value.granted,
|
|
);
|
|
|
|
await connection.serverConnection.send_command("channelgroupaddperm", {
|
|
cgid: current_group.id,
|
|
permid: permission.id_grant(),
|
|
permvalue: value.granted,
|
|
permskip: false,
|
|
permnegated: false
|
|
});
|
|
}
|
|
}
|
|
});
|
|
|
|
/* FIXME: Use cached permissions */
|
|
editor.trigger_update();
|
|
});
|
|
}
|
|
|
|
/* list all channel groups */
|
|
{
|
|
let group_list = tab_left.find(".list-groups .entries");
|
|
|
|
update_groups = (selected_group: number) => {
|
|
group_list.children().remove();
|
|
|
|
const allow_query_groups = connection.permissions.neededPermission(PermissionType.B_SERVERINSTANCE_MODIFY_QUERYGROUP).granted(1);
|
|
const allow_template_groups = connection.permissions.neededPermission(PermissionType.B_SERVERINSTANCE_MODIFY_TEMPLATES).granted(1);
|
|
for (let group of connection.groups.channelGroups.sort(GroupManager.sorter())) {
|
|
if (group.type == GroupType.QUERY) {
|
|
if (!allow_query_groups)
|
|
continue;
|
|
} else if (group.type == GroupType.TEMPLATE) {
|
|
if (!allow_template_groups)
|
|
continue;
|
|
}
|
|
|
|
let tag = $.spawn("div").addClass("group").attr("group-id", group.id);
|
|
let icon_tag = connection.fileManager.icons.generateTag(group.properties.iconid);
|
|
icon_tag.appendTo(tag);
|
|
const _update_icon = icon_id => icon_tag.replaceWith(icon_tag = connection.fileManager.icons.generateTag(icon_id));
|
|
|
|
{
|
|
let name = $.spawn("a").text(group.name + " (" + group.id + ")").addClass("name");
|
|
if (group.properties.savedb)
|
|
name.addClass("savedb");
|
|
if (connection.channelTree.server.properties.virtualserver_default_channel_group == group.id)
|
|
name.addClass("default");
|
|
name.appendTo(tag);
|
|
}
|
|
tag.appendTo(group_list);
|
|
|
|
tag.on('click', event => {
|
|
current_group = group;
|
|
update_group_icon = _update_icon;
|
|
group_list.find(".selected").removeClass("selected");
|
|
tag.addClass("selected");
|
|
|
|
update_buttons();
|
|
//TODO trigger only if the editor is in channel group mode!
|
|
editor.trigger_update();
|
|
});
|
|
tag.on('contextmenu', event => {
|
|
if(event.isDefaultPrevented())
|
|
return;
|
|
|
|
contextmenu.spawn_context_menu(event.pageX, event.pageY, {
|
|
type: contextmenu.MenuEntryType.ENTRY,
|
|
name: tr("Create a channel group"),
|
|
icon_class: 'client-add',
|
|
invalidPermission: !connection.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_CHANNELGROUP_CREATE).granted(1),
|
|
callback: () => tab_left.find(".button-add").trigger('click')
|
|
}, {
|
|
type: contextmenu.MenuEntryType.ENTRY,
|
|
name: tr("Rename channel group"),
|
|
icon_class: 'client-edit',
|
|
invalidPermission: !connection.permissions.neededPermission(PermissionType.I_CHANNEL_GROUP_MODIFY_POWER).granted(current_group.requiredModifyPower),
|
|
callback: () => tab_left.find(".button-rename").trigger('click')
|
|
}, {
|
|
type: contextmenu.MenuEntryType.ENTRY,
|
|
name: tr("Duplicate channel group"),
|
|
icon_class: 'client-copy',
|
|
callback: () => tab_left.find(".button-duplicate").trigger('click')
|
|
}, {
|
|
type: contextmenu.MenuEntryType.ENTRY,
|
|
name: tr("Delete channel group"),
|
|
icon_class: 'client-delete',
|
|
invalidPermission: !connection.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_CHANNELGROUP_DELETE).granted(1),
|
|
callback: () => tab_left.find(".button-delete").trigger('click')
|
|
});
|
|
event.preventDefault();
|
|
});
|
|
if(group.id === selected_group) {
|
|
setTimeout(() => tag.trigger('click'), 0);
|
|
selected_group = undefined;
|
|
}
|
|
}
|
|
|
|
/* because the server menu is the first which will be shown */
|
|
if(typeof(selected_group) !== "undefined") {
|
|
setTimeout(() => group_list.find('.group').first().trigger('click'), 0);
|
|
}
|
|
};
|
|
|
|
tab_left.find(".list-groups").on('contextmenu', event => {
|
|
if(event.isDefaultPrevented())
|
|
return;
|
|
|
|
contextmenu.spawn_context_menu(event.pageX, event.pageY, {
|
|
type: contextmenu.MenuEntryType.ENTRY,
|
|
name: tr("Create a channel group"),
|
|
icon_class: 'client-add',
|
|
callback: () => tab_left.find(".button-add").trigger('click')
|
|
});
|
|
event.preventDefault();
|
|
});
|
|
}
|
|
|
|
{
|
|
const container_buttons = tab_left.find(".container-buttons");
|
|
|
|
const button_add = container_buttons.find(".button-add");
|
|
const button_rename = container_buttons.find(".button-rename");
|
|
const button_duplicate = container_buttons.find(".button-duplicate");
|
|
const button_delete = container_buttons.find(".button-delete");
|
|
|
|
button_add.prop("disabled", !connection.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_CHANNELGROUP_CREATE).granted(1));
|
|
button_delete.prop("disabled", !connection.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_CHANNELGROUP_CREATE).granted(1));
|
|
update_buttons = () => {
|
|
const permission_modify = current_group && connection.permissions.neededPermission(PermissionType.I_CHANNEL_GROUP_MODIFY_POWER).granted(current_group.requiredModifyPower);
|
|
button_rename.prop("disabled", !permission_modify);
|
|
button_duplicate.prop("disabled", !connection.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_CHANNELGROUP_CREATE).granted(1));
|
|
};
|
|
|
|
button_add.on('click', () => {
|
|
spawnGroupAdd(false, connection.permissions, (name, type) => name.length > 0 && !connection.groups.channelGroups.find(e => e.target == GroupTarget.CHANNEL && e.name.toLowerCase() === name.toLowerCase() && e.type == type) , (name, type) => {
|
|
console.log("Creating channel group: %o, %o", name, type);
|
|
connection.serverConnection.send_command('channelgroupadd', {
|
|
name: name,
|
|
type: type
|
|
}).then(() => {
|
|
createInfoModal(tr("Group created"), tr("The channel group has been created.")).open();
|
|
update_groups(0); //TODO: May get the created group?
|
|
}).catch(error => {
|
|
console.warn(tr("Failed to create channel group: %o"), error);
|
|
if(error instanceof CommandResult) {
|
|
error = error.extra_message || error.message;
|
|
}
|
|
createErrorModal(tr("Failed to create group"), formatMessage(tr("Failed to create group:{:br:}"), error)).open();
|
|
});
|
|
});
|
|
});
|
|
|
|
button_rename.on('click', () => {
|
|
if(!current_group)
|
|
return;
|
|
|
|
createInputModal(tr("Rename group"), tr("Enter the new group name"), name => name.length > 0 && !connection.groups.channelGroups.find(e => e.target == GroupTarget.CHANNEL && e.name.toLowerCase() === name.toLowerCase() && e.type == current_group.type), result => {
|
|
if(typeof(result) !== "string" || !result)
|
|
return;
|
|
connection.serverConnection.send_command('channelgrouprename', {
|
|
cgid: current_group.id,
|
|
name: result
|
|
}).then(() => {
|
|
createInfoModal(tr("Group renamed"), tr("The channel group has been renamed.")).open();
|
|
update_groups(current_group.id);
|
|
}).catch(error => {
|
|
console.warn(tr("Failed to rename channel group: %o"), error);
|
|
if(error instanceof CommandResult) {
|
|
error = error.extra_message || error.message;
|
|
}
|
|
createErrorModal(tr("Failed to rename group"), formatMessage(tr("Failed to rename group:{:br:}"), error)).open();
|
|
});
|
|
}).open();
|
|
});
|
|
|
|
button_duplicate.on('click', () => {
|
|
createErrorModal(tr("Not implemented yet"), tr("This function hasn't been implemented yet!")).open();
|
|
});
|
|
|
|
button_delete.on('click', () => {
|
|
if(!current_group)
|
|
return;
|
|
|
|
spawnYesNo(tr("Are you sure?"), formatMessage(tr("Do you really want to delete the group {}?"), current_group.name), result => {
|
|
if(result !== true)
|
|
return;
|
|
|
|
connection.serverConnection.send_command("channelgroupdel", {
|
|
cgid: current_group.id,
|
|
force: true
|
|
}).then(() => {
|
|
createInfoModal(tr("Group deleted"), tr("The channel group has been deleted.")).open();
|
|
update_groups(0);
|
|
}).catch(error => {
|
|
console.warn(tr("Failed to delete channel group: %o"), error);
|
|
if(error instanceof CommandResult) {
|
|
error = error.extra_message || error.message;
|
|
}
|
|
createErrorModal(tr("Failed to delete group"), formatMessage(tr("Failed to delete group:{:br:}"), error)).open();
|
|
});
|
|
});
|
|
});
|
|
}
|
|
update_groups(0);
|
|
}
|
|
|
|
function apply_server_groups(connection: ConnectionHandler, editor: AbstractPermissionEditor, tab_left: JQuery, tab_right: JQuery) {
|
|
let current_group: Group;
|
|
let current_group_changed: (() => any)[] = [];
|
|
|
|
let update_buttons: () => any;
|
|
/* list all groups */
|
|
|
|
let update_icon: ((icon_id: number) => any)[] = [];
|
|
|
|
let update_groups: (selected_group: number) => any;
|
|
{
|
|
let group_list = tab_left.find(".container-group-list .list-groups .entries");
|
|
let group_list_update_icon: (i: number) => any;
|
|
update_icon.push(i => group_list_update_icon(i));
|
|
|
|
update_groups = (selected_group: number) => {
|
|
group_list.children().remove();
|
|
|
|
const allow_query_groups = connection.permissions.neededPermission(PermissionType.B_SERVERINSTANCE_MODIFY_QUERYGROUP).granted(1);
|
|
const allow_template_groups = connection.permissions.neededPermission(PermissionType.B_SERVERINSTANCE_MODIFY_TEMPLATES).granted(1);
|
|
for(const group of connection.groups.serverGroups.sort(GroupManager.sorter())) {
|
|
if(group.type == GroupType.QUERY) {
|
|
if(!allow_query_groups)
|
|
continue;
|
|
} else if(group.type == GroupType.TEMPLATE) {
|
|
if(!allow_template_groups)
|
|
continue;
|
|
}
|
|
let tag = $.spawn("div").addClass("group").attr("group-id", group.id);
|
|
let icon_tag = connection.fileManager.icons.generateTag(group.properties.iconid);
|
|
icon_tag.appendTo(tag);
|
|
const _update_icon = icon_id => icon_tag.replaceWith(icon_tag = connection.fileManager.icons.generateTag(icon_id));
|
|
|
|
{
|
|
let name = $.spawn("div").text(group.name + " (" + group.id + ")").addClass("name");
|
|
if(group.properties.savedb)
|
|
name.addClass("savedb");
|
|
if(connection.channelTree.server.properties.virtualserver_default_server_group == group.id)
|
|
name.addClass("default");
|
|
name.appendTo(tag);
|
|
}
|
|
tag.appendTo(group_list);
|
|
|
|
tag.on('click', event => {
|
|
if(current_group === group)
|
|
return;
|
|
|
|
current_group = group;
|
|
group_list_update_icon = _update_icon;
|
|
if(update_buttons)
|
|
update_buttons();
|
|
for(const entry of current_group_changed)
|
|
entry();
|
|
|
|
group_list.find(".selected").removeClass("selected");
|
|
tag.addClass("selected");
|
|
editor.trigger_update();
|
|
});
|
|
tag.on('contextmenu', event => {
|
|
if(event.isDefaultPrevented())
|
|
return;
|
|
|
|
contextmenu.spawn_context_menu(event.pageX, event.pageY, {
|
|
type: contextmenu.MenuEntryType.ENTRY,
|
|
name: tr("Create a server group"),
|
|
icon_class: 'client-add',
|
|
invalidPermission: !connection.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_SERVERGROUP_CREATE).granted(1),
|
|
callback: () => tab_left.find(".button-add").trigger('click')
|
|
}, {
|
|
type: contextmenu.MenuEntryType.ENTRY,
|
|
name: tr("Rename server group"),
|
|
icon_class: 'client-edit',
|
|
invalidPermission: !connection.permissions.neededPermission(PermissionType.I_SERVER_GROUP_MODIFY_POWER).granted(current_group.requiredModifyPower),
|
|
callback: () => tab_left.find(".button-rename").trigger('click')
|
|
}, {
|
|
type: contextmenu.MenuEntryType.ENTRY,
|
|
name: tr("Duplicate server group"),
|
|
icon_class: 'client-copy',
|
|
callback: () => tab_left.find(".button-duplicate").trigger('click')
|
|
}, {
|
|
type: contextmenu.MenuEntryType.ENTRY,
|
|
name: tr("Delete server group"),
|
|
icon_class: 'client-delete',
|
|
invalidPermission: !connection.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_SERVERGROUP_DELETE).granted(1),
|
|
callback: () => tab_left.find(".button-delete").trigger('click')
|
|
});
|
|
event.preventDefault();
|
|
});
|
|
|
|
if(group.id === selected_group) {
|
|
setTimeout(() => tag.trigger('click'), 0);
|
|
selected_group = undefined;
|
|
}
|
|
}
|
|
|
|
/* because the server menu is the first which will be shown */
|
|
if(typeof(selected_group) !== "undefined") {
|
|
setTimeout(() => group_list.find('.group').first().trigger('click'), 0);
|
|
}
|
|
};
|
|
|
|
|
|
tab_left.find(".list-groups").on('contextmenu', event => {
|
|
if(event.isDefaultPrevented())
|
|
return;
|
|
|
|
contextmenu.spawn_context_menu(event.pageX, event.pageY, {
|
|
type: contextmenu.MenuEntryType.ENTRY,
|
|
name: tr("Create a server group"),
|
|
icon_class: 'client-add',
|
|
callback: () => tab_left.find(".button-add").trigger('click')
|
|
});
|
|
event.preventDefault();
|
|
});
|
|
}
|
|
{
|
|
const container_buttons = tab_left.find(".container-group-list .container-buttons");
|
|
|
|
const button_add = container_buttons.find(".button-add");
|
|
const button_rename = container_buttons.find(".button-rename");
|
|
const button_duplicate = container_buttons.find(".button-duplicate");
|
|
const button_delete = container_buttons.find(".button-delete");
|
|
|
|
button_add.prop("disabled", !connection.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_SERVERGROUP_CREATE).granted(1));
|
|
button_delete.prop("disabled", !connection.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_SERVERGROUP_DELETE).granted(1));
|
|
update_buttons = () => {
|
|
const permission_modify = current_group && connection.permissions.neededPermission(PermissionType.I_SERVER_GROUP_MODIFY_POWER).granted(current_group.requiredModifyPower);
|
|
button_rename.prop("disabled", !permission_modify);
|
|
button_duplicate.prop("disabled", !connection.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_SERVERGROUP_CREATE).granted(1));
|
|
};
|
|
|
|
button_add.on('click', () => {
|
|
spawnGroupAdd(true, connection.permissions, (name, type) => name.length > 0 && !connection.groups.serverGroups.find(e => e.target == GroupTarget.SERVER && e.name.toLowerCase() === name.toLowerCase() && e.type == type) , (name, type) => {
|
|
console.log("Creating group: %o, %o", name, type);
|
|
connection.serverConnection.send_command('servergroupadd', {
|
|
name: name,
|
|
type: type
|
|
}).then(() => {
|
|
createInfoModal(tr("Group created"), tr("The server group has been created.")).open();
|
|
update_groups(0); //TODO: May get the created group?
|
|
}).catch(error => {
|
|
console.warn(tr("Failed to create server group: %o"), error);
|
|
if(error instanceof CommandResult) {
|
|
error = error.extra_message || error.message;
|
|
}
|
|
createErrorModal(tr("Failed to create group"), formatMessage(tr("Failed to create group:{:br:}"), error)).open();
|
|
});
|
|
});
|
|
});
|
|
|
|
button_rename.on('click', () => {
|
|
if(!current_group)
|
|
return;
|
|
|
|
createInputModal(tr("Rename group"), tr("Enter the new group name"), name => name.length > 0 && !connection.groups.serverGroups.find(e => e.target == GroupTarget.SERVER && e.name.toLowerCase() === name.toLowerCase() && e.type == current_group.type), result => {
|
|
if(typeof(result) !== "string" || !result)
|
|
return;
|
|
connection.serverConnection.send_command('servergrouprename', {
|
|
sgid: current_group.id,
|
|
name: result
|
|
}).then(() => {
|
|
createInfoModal(tr("Group renamed"), tr("The server group has been renamed.")).open();
|
|
update_groups(current_group.id);
|
|
}).catch(error => {
|
|
console.warn(tr("Failed to rename server group: %o"), error);
|
|
if(error instanceof CommandResult) {
|
|
error = error.extra_message || error.message;
|
|
}
|
|
createErrorModal(tr("Failed to rename group"), formatMessage(tr("Failed to rename group:{:br:}"), error)).open();
|
|
});
|
|
}).open();
|
|
});
|
|
|
|
button_duplicate.on('click', () => {
|
|
createErrorModal(tr("Not implemented yet"), tr("This function hasn't been implemented yet!")).open();
|
|
});
|
|
|
|
button_delete.on('click', () => {
|
|
if(!current_group)
|
|
return;
|
|
|
|
spawnYesNo(tr("Are you sure?"), formatMessage(tr("Do you really want to delete the group {}?"), current_group.name), result => {
|
|
if(result !== true)
|
|
return;
|
|
|
|
connection.serverConnection.send_command("servergroupdel", {
|
|
sgid: current_group.id,
|
|
force: true
|
|
}).then(() => {
|
|
createInfoModal(tr("Group deleted"), tr("The server group has been deleted.")).open();
|
|
update_groups(0);
|
|
}).catch(error => {
|
|
console.warn(tr("Failed to delete server group: %o"), error);
|
|
if(error instanceof CommandResult) {
|
|
error = error.extra_message || error.message;
|
|
}
|
|
createErrorModal(tr("Failed to delete group"), formatMessage(tr("Failed to delete group:{:br:}"), error)).open();
|
|
});
|
|
});
|
|
});
|
|
}
|
|
update_groups(0);
|
|
|
|
/* the editor */
|
|
{
|
|
const pe_server = tab_right.find(".permission-editor");
|
|
tab_right.on('show', event => {
|
|
pe_server.append(editor.html_tag());
|
|
if(connection.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_SERVERGROUP_PERMISSION_LIST).granted(1))
|
|
editor.set_mode(PermissionEditorMode.VISIBLE);
|
|
else {
|
|
editor.set_mode(PermissionEditorMode.NO_PERMISSION);
|
|
return;
|
|
}
|
|
editor.set_listener_update(() => {
|
|
console.log("Updating permissions");
|
|
connection.groups.request_permissions(current_group).then(result => editor.set_permissions(result)).catch(error => {
|
|
console.log(error); //TODO handling?
|
|
});
|
|
});
|
|
|
|
editor.set_listener(async (permission, value) => {
|
|
if (!current_group)
|
|
throw "unset server group";
|
|
|
|
if (value.remove) {
|
|
/* remove the permission */
|
|
if (typeof (value.value) !== "undefined") {
|
|
log.info(LogCategory.PERMISSIONS, tr("Removing server group permission %s. permission.id: %o"),
|
|
permission.name,
|
|
permission.id,
|
|
);
|
|
|
|
await connection.serverConnection.send_command("servergroupdelperm", {
|
|
sgid: current_group.id,
|
|
permid: permission.id,
|
|
}).then(e => {
|
|
if(permission.name === "i_icon_id")
|
|
for(const c of update_icon)
|
|
c(0);
|
|
return e;
|
|
});
|
|
} else {
|
|
log.info(LogCategory.PERMISSIONS, tr("Removing server group grant permission %s. permission.id: %o"),
|
|
permission.name,
|
|
permission.id_grant(),
|
|
value.granted,
|
|
);
|
|
|
|
await connection.serverConnection.send_command("servergroupdelperm", {
|
|
sgid: current_group.id,
|
|
permid: permission.id_grant(),
|
|
});
|
|
}
|
|
} else {
|
|
/* add the permission */
|
|
if (typeof (value.value) !== "undefined") {
|
|
log.info(LogCategory.PERMISSIONS, tr("Adding or updating server group permission %s. permission.{id: %o, value: %o, flag_skip: %o, flag_negate: %o}"),
|
|
permission.name,
|
|
permission.id,
|
|
value.value,
|
|
value.flag_skip,
|
|
value.flag_negate
|
|
);
|
|
|
|
await connection.serverConnection.send_command("servergroupaddperm", {
|
|
sgid: current_group.id,
|
|
permid: permission.id,
|
|
permvalue: value.value,
|
|
permskip: value.flag_skip,
|
|
permnegated: value.flag_negate
|
|
}).then(e => {
|
|
if(permission.name === "i_icon_id")
|
|
for(const c of update_icon)
|
|
c(value.value);
|
|
return e;
|
|
});
|
|
} else {
|
|
log.info(LogCategory.PERMISSIONS, tr("Adding or updating server group grant permission %s. permission.{id: %o, value: %o}"),
|
|
permission.name,
|
|
permission.id_grant(),
|
|
value.granted,
|
|
);
|
|
|
|
await connection.serverConnection.send_command("servergroupaddperm", {
|
|
sgid: current_group.id,
|
|
permid: permission.id_grant(),
|
|
permvalue: value.granted,
|
|
permskip: false,
|
|
permnegated: false
|
|
});
|
|
}
|
|
}
|
|
});
|
|
|
|
editor.trigger_update();
|
|
});
|
|
}
|
|
|
|
/* client list */
|
|
{
|
|
//container-client-list container-group-list
|
|
let clients_visible = false;
|
|
let selected_client: {
|
|
tag: JQuery,
|
|
dbid: number
|
|
};
|
|
|
|
const container_client_list = tab_left.find(".container-client-list").addClass("hidden");
|
|
const container_group_list = tab_left.find(".container-group-list");
|
|
|
|
const container_selected_group = container_client_list.find(".container-current-group");
|
|
const container_clients = container_client_list.find(".list-clients .entries");
|
|
|
|
const input_filter = container_client_list.find(".filter-client-list");
|
|
|
|
const button_add = container_client_list.find(".button-add");
|
|
const button_delete = container_client_list.find(".button-delete");
|
|
|
|
const update_filter = () => {
|
|
const filter_text = (input_filter.val() || "").toString().toLowerCase();
|
|
if(!filter_text) {
|
|
container_clients.find(".entry").css('display', 'block');
|
|
} else {
|
|
const entries = container_clients.find(".entry");
|
|
for(const _entry of entries) {
|
|
const entry = $(_entry);
|
|
if(entry.attr("search-string").toLowerCase().indexOf(filter_text) !== -1)
|
|
entry.css('display', 'block');
|
|
else
|
|
entry.css('display', 'none');
|
|
}
|
|
}
|
|
};
|
|
|
|
const update_client_list = () => {
|
|
container_clients.empty();
|
|
button_delete.prop('disabled', true);
|
|
|
|
connection.serverConnection.command_helper.request_clients_by_server_group(current_group.id).then(clients => {
|
|
for(const client of clients) {
|
|
const tag = $.spawn("div").addClass("client").text(client.client_nickname);
|
|
tag.attr("search-string", client.client_nickname + "-" + client.client_unique_identifier + "-" + client.client_database_id);
|
|
container_clients.append(tag);
|
|
|
|
tag.on('click contextmenu', event => {
|
|
container_clients.find(".selected").removeClass("selected");
|
|
tag.addClass("selected");
|
|
|
|
selected_client = {
|
|
tag: tag,
|
|
dbid: client.client_database_id
|
|
};
|
|
button_delete.prop('disabled', false);
|
|
});
|
|
|
|
tag.on('contextmenu', event => {
|
|
if(event.isDefaultPrevented())
|
|
return;
|
|
|
|
event.preventDefault();
|
|
contextmenu.spawn_context_menu(event.pageX, event.pageY, {
|
|
type: contextmenu.MenuEntryType.ENTRY,
|
|
name: tr("Add client"),
|
|
icon_class: 'client-add',
|
|
callback: () => button_add.trigger('click')
|
|
}, {
|
|
type: contextmenu.MenuEntryType.ENTRY,
|
|
name: tr("Remove client"),
|
|
icon_class: 'client-delete',
|
|
callback: () => button_delete.trigger('click')
|
|
}, {
|
|
type: contextmenu.MenuEntryType.ENTRY,
|
|
name: tr("Copy unique id"),
|
|
icon_class: 'client-copy',
|
|
callback: () => copy_to_clipboard(client.client_unique_identifier)
|
|
})
|
|
});
|
|
}
|
|
update_filter();
|
|
}).catch(error => {
|
|
if(error instanceof CommandResult && error.id === ErrorID.PERMISSION_ERROR)
|
|
return;
|
|
console.warn(tr("Failed to receive server group clients for group %d: %o"), current_group.id, error);
|
|
});
|
|
};
|
|
current_group_changed.push(update_client_list);
|
|
|
|
button_delete.on('click', event => {
|
|
const client = selected_client;
|
|
if(!client) return;
|
|
|
|
connection.serverConnection.send_command("servergroupdelclient", {
|
|
sgid: current_group.id,
|
|
cldbid: client.dbid
|
|
}).then(() => {
|
|
selected_client.tag.detach();
|
|
button_delete.prop('disabled', true); /* nothing is selected */
|
|
}).catch(error => {
|
|
console.log(tr("Failed to delete client %o from server group %o: %o"), client.dbid, current_group.id, error);
|
|
if(error instanceof CommandResult)
|
|
error = error.extra_message || error.message;
|
|
createErrorModal(tr("Failed to remove client"), tr("Failed to remove client from server group")).open();
|
|
});
|
|
});
|
|
|
|
button_add.on('click', event => {
|
|
createInputModal(tr("Add client to server group"), tr("Enter the client unique id or database id"), text => {
|
|
if(!text) return false;
|
|
if(!!text.match(/^[0-9]+$/))
|
|
return true;
|
|
try {
|
|
return atob(text).length >= 20;
|
|
} catch(error) {
|
|
return false;
|
|
}
|
|
}, async text => {
|
|
if(typeof(text) !== "string")
|
|
return;
|
|
|
|
let dbid;
|
|
if(!!text.match(/^[0-9]+$/)) {
|
|
dbid = parseInt(text);
|
|
debugger;
|
|
} else {
|
|
try {
|
|
const data = await connection.serverConnection.command_helper.info_from_uid(text.trim());
|
|
dbid = data[0].client_database_id;
|
|
} catch(error) {
|
|
console.log(tr("Failed to resolve client database id from unique id (%s): %o"), text, error);
|
|
if(error instanceof CommandResult)
|
|
error = error.extra_message || error.message;
|
|
createErrorModal(tr("Failed to add client"), formatMessage(tr("Failed to add client to server group\nFailed to resolve database id: {}."), error)).open();
|
|
return;
|
|
}
|
|
}
|
|
if(!dbid) {
|
|
console.log(tr("Failed to resolve client database id from unique id (%s): Client not found"));
|
|
createErrorModal(tr("Failed to add client"), tr("Failed to add client to server group\nClient database id not found")).open();
|
|
return;
|
|
}
|
|
|
|
|
|
connection.serverConnection.send_command("servergroupaddclient", {
|
|
sgid: current_group.id,
|
|
cldbid: dbid
|
|
}).then(() => {
|
|
update_client_list();
|
|
}).catch(error => {
|
|
console.log(tr("Failed to add client %o to server group %o: %o"), dbid, current_group.id, error);
|
|
if(error instanceof CommandResult)
|
|
error = error.extra_message || error.message;
|
|
createErrorModal(tr("Failed to add client"), tra("Failed to add client to server group{:br:}", error)).open();
|
|
});
|
|
}).open();
|
|
});
|
|
|
|
container_client_list.on('contextmenu', event => {
|
|
if(event.isDefaultPrevented())
|
|
return;
|
|
|
|
event.preventDefault();
|
|
contextmenu.spawn_context_menu(event.pageX, event.pageY, {
|
|
type: contextmenu.MenuEntryType.ENTRY,
|
|
name: tr("Add client"),
|
|
icon_class: 'client-add',
|
|
callback: () => button_add.trigger('click')
|
|
})
|
|
});
|
|
|
|
/* icon handler and current group display */
|
|
{
|
|
let update_icon_callback: (i: number) => any;
|
|
update_icon.push(i => update_icon_callback(i));
|
|
|
|
input_filter.on('change keyup', event => update_filter());
|
|
current_group_changed.push(() => {
|
|
container_selected_group.empty();
|
|
if(!current_group) return;
|
|
|
|
let icon_container = $.spawn("div").addClass("icon-container").appendTo(container_selected_group);
|
|
|
|
connection.fileManager.icons.generateTag(current_group.properties.iconid).appendTo(icon_container);
|
|
update_icon_callback = icon => {
|
|
icon_container.empty();
|
|
connection.fileManager.icons.generateTag(icon).appendTo(icon_container);
|
|
};
|
|
$.spawn("div").addClass("name").text(current_group.name + " (" + current_group.id + ")").appendTo(container_selected_group);
|
|
});
|
|
}
|
|
|
|
tab_right.on('show', event => {
|
|
editor.set_toggle_button(() => {
|
|
clients_visible = !clients_visible;
|
|
|
|
container_client_list.toggleClass("hidden", !clients_visible);
|
|
container_group_list.toggleClass("hidden", clients_visible);
|
|
|
|
return clients_visible ? tr("Hide clients in group") : tr("Show clients in group");
|
|
}, clients_visible ? tr("Hide clients in group") : tr("Show clients in group"));
|
|
});
|
|
}
|
|
}
|
|
|
|
function spawnGroupAdd(server_group: boolean, permissions: PermissionManager, valid_name: (name: string, group_type: number) => boolean, callback: (group_name: string, group_type: number) => any) {
|
|
let modal: Modal;
|
|
modal = createModal({
|
|
header: tr("Create a new group"),
|
|
body: () => {
|
|
let tag = $("#tmpl_group_add").renderTag({
|
|
server_group: server_group
|
|
});
|
|
|
|
tag.find(".group-type-template").prop("disabled", !permissions.neededPermission(PermissionType.B_SERVERINSTANCE_MODIFY_TEMPLATES).granted(1));
|
|
tag.find(".group-type-query").prop("disabled", !permissions.neededPermission(PermissionType.B_SERVERINSTANCE_MODIFY_QUERYGROUP).granted(1));
|
|
|
|
const container_name = tag.find(".group-name");
|
|
const button_create = tag.find(".button-create");
|
|
|
|
const group_type = () => (tag.find(".group-type")[0] as HTMLSelectElement).selectedIndex;
|
|
container_name.on('keyup change', (event: Event) => {
|
|
if(event.type === 'keyup') {
|
|
const kevent = event as KeyboardEvent;
|
|
if(!kevent.shiftKey && kevent.key == 'Enter') {
|
|
button_create.trigger('click');
|
|
return;
|
|
}
|
|
}
|
|
const valid = valid_name(container_name.val() as string, group_type());
|
|
button_create.prop("disabled", !valid);
|
|
container_name.parent().toggleClass("is-invalid", !valid);
|
|
}).trigger('change');
|
|
tag.find(".group-type").on('change', () => container_name.trigger('change'));
|
|
|
|
button_create.on('click', event => {
|
|
if(button_create.prop("disabled"))
|
|
return;
|
|
button_create.prop("disabled", true); /* disable double clicking */
|
|
|
|
modal.close();
|
|
callback(container_name.val() as string, group_type());
|
|
});
|
|
return tag;
|
|
},
|
|
footer: null,
|
|
|
|
width: 600
|
|
});
|
|
modal.htmlTag.find(".modal-body").addClass("modal-group-add");
|
|
modal.open_listener.push(() => {
|
|
modal.htmlTag.find(".group-name").focus();
|
|
});
|
|
|
|
modal.open();
|
|
} |