Группы 2.1
This commit is contained in:
@@ -44,12 +44,12 @@ module.exports = function(app, db) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Таблица с идентификаторами пользователей
|
// Таблица с идентификаторами пользователей
|
||||||
db.run(`
|
db.run(`
|
||||||
CREATE TABLE IF NOT EXISTS idusers (
|
CREATE TABLE IF NOT EXISTS idusers (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
user_id INTEGER NOT NULL,
|
user_id INTEGER NOT NULL,
|
||||||
service_type TEXT NOT NULL, -- 'sberbank', 'yandex', 'ldap', 'other'
|
service_type TEXT NOT NULL, -- 'sberbank', 'yandex', 'ldap', 'other'
|
||||||
external_id TEXT NOT NULL,
|
external_id TEXT, -- СДЕЛАЛИ НЕОБЯЗАТЕЛЬНЫМ
|
||||||
login TEXT, -- Логин LDAP (если есть)
|
login TEXT, -- Логин LDAP (если есть)
|
||||||
ldap_group TEXT, -- Группа LDAP (если есть)
|
ldap_group TEXT, -- Группа LDAP (если есть)
|
||||||
group_id INTEGER, -- Ссылка на группу в idgroups
|
group_id INTEGER, -- Ссылка на группу в idgroups
|
||||||
@@ -59,9 +59,9 @@ module.exports = function(app, db) {
|
|||||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE,
|
FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE,
|
||||||
FOREIGN KEY (group_id) REFERENCES idgroups (id) ON DELETE SET NULL,
|
FOREIGN KEY (group_id) REFERENCES idgroups (id) ON DELETE SET NULL,
|
||||||
UNIQUE(user_id, service_type, external_id)
|
UNIQUE(user_id, service_type, external_id) -- Теперь external_id может быть NULL
|
||||||
)
|
)
|
||||||
`, (err) => {
|
`, (err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.error('❌ Ошибка создания таблицы idusers:', err.message);
|
console.error('❌ Ошибка создания таблицы idusers:', err.message);
|
||||||
reject(err);
|
reject(err);
|
||||||
@@ -510,7 +510,7 @@ module.exports = function(app, db) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// POST /api2/idusers - Создать новый идентификатор пользователя (только админ)
|
// POST /api2/idusers - Создать новый идентификатор пользователя (только админ)
|
||||||
router.post('/api2/idusers', requireAuth, requireAdmin, (req, res) => {
|
router.post('/api2/idusers', requireAuth, requireAdmin, (req, res) => {
|
||||||
const {
|
const {
|
||||||
user_id,
|
user_id,
|
||||||
service_type,
|
service_type,
|
||||||
@@ -522,10 +522,10 @@ module.exports = function(app, db) {
|
|||||||
is_active
|
is_active
|
||||||
} = req.body;
|
} = req.body;
|
||||||
|
|
||||||
// Валидация обязательных полей
|
// Валидация обязательных полей - СДЕЛАЕМ external_id НЕОБЯЗАТЕЛЬНЫМ
|
||||||
if (!user_id || !service_type || !external_id) {
|
if (!user_id || !service_type) {
|
||||||
return res.status(400).json({
|
return res.status(400).json({
|
||||||
error: 'Обязательные поля: user_id, service_type, external_id'
|
error: 'Обязательные поля: user_id, service_type'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -559,14 +559,8 @@ module.exports = function(app, db) {
|
|||||||
return res.status(404).json({ error: 'Указанная группа не найдена' });
|
return res.status(404).json({ error: 'Указанная группа не найдена' });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Проверяем соответствие типа сервиса
|
// УБИРАЕМ проверку соответствия типа сервиса
|
||||||
if (group.service_type !== service_type) {
|
// Теперь группы независимы от сервиса
|
||||||
return res.status(400).json({
|
|
||||||
error: `Тип сервиса группы (${group.service_type}) не соответствует типу сервиса идентификатора (${service_type})`
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Создаем идентификатор
|
|
||||||
createIdUser();
|
createIdUser();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@@ -577,6 +571,9 @@ module.exports = function(app, db) {
|
|||||||
function createIdUser() {
|
function createIdUser() {
|
||||||
const metadataJson = metadata ? JSON.stringify(metadata) : null;
|
const metadataJson = metadata ? JSON.stringify(metadata) : null;
|
||||||
|
|
||||||
|
// Генерируем уникальный external_id если он не предоставлен
|
||||||
|
const finalExternalId = external_id || `temp_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
||||||
|
|
||||||
db.run(
|
db.run(
|
||||||
`INSERT INTO idusers
|
`INSERT INTO idusers
|
||||||
(user_id, service_type, external_id, login, ldap_group, group_id, metadata, is_active)
|
(user_id, service_type, external_id, login, ldap_group, group_id, metadata, is_active)
|
||||||
@@ -584,7 +581,7 @@ module.exports = function(app, db) {
|
|||||||
[
|
[
|
||||||
user_id,
|
user_id,
|
||||||
service_type,
|
service_type,
|
||||||
external_id,
|
finalExternalId,
|
||||||
login || null,
|
login || null,
|
||||||
ldap_group || null,
|
ldap_group || null,
|
||||||
group_id || null,
|
group_id || null,
|
||||||
@@ -611,10 +608,10 @@ module.exports = function(app, db) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// PUT /api2/idusers/:id - Обновить идентификатор пользователя (только админ)
|
// PUT /api2/idusers/:id - Обновить идентификатор пользователя (только админ)
|
||||||
router.put('/api2/idusers/:id', requireAuth, requireAdmin, (req, res) => {
|
router.put('/api2/idusers/:id', requireAuth, requireAdmin, (req, res) => {
|
||||||
const { id } = req.params;
|
const { id } = req.params;
|
||||||
const {
|
const {
|
||||||
user_id,
|
user_id,
|
||||||
@@ -638,6 +635,31 @@ module.exports = function(app, db) {
|
|||||||
return res.status(404).json({ error: 'Идентификатор не найден' });
|
return res.status(404).json({ error: 'Идентификатор не найден' });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Если указана группа и она меняется, проверяем существование новой группы
|
||||||
|
if (group_id !== undefined && group_id !== existing.group_id) {
|
||||||
|
if (group_id) {
|
||||||
|
db.get('SELECT id FROM idgroups WHERE id = ?', [group_id], (err, group) => {
|
||||||
|
if (err) {
|
||||||
|
console.error('❌ Ошибка проверки группы:', err);
|
||||||
|
return res.status(500).json({ error: 'Ошибка проверки группы' });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!group) {
|
||||||
|
return res.status(404).json({ error: 'Указанная группа не найдена' });
|
||||||
|
}
|
||||||
|
|
||||||
|
// УБИРАЕМ проверку соответствия типа сервиса
|
||||||
|
// Теперь группы независимы от сервиса
|
||||||
|
updateIdUser();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
updateIdUser();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
updateIdUser();
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateIdUser() {
|
||||||
// Собираем поля для обновления
|
// Собираем поля для обновления
|
||||||
const updates = [];
|
const updates = [];
|
||||||
const params = [];
|
const params = [];
|
||||||
@@ -660,7 +682,9 @@ module.exports = function(app, db) {
|
|||||||
|
|
||||||
if (external_id !== undefined) {
|
if (external_id !== undefined) {
|
||||||
updates.push('external_id = ?');
|
updates.push('external_id = ?');
|
||||||
params.push(external_id);
|
// Генерируем временный external_id если он пустой
|
||||||
|
const finalExternalId = external_id || `temp_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
||||||
|
params.push(finalExternalId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (login !== undefined) {
|
if (login !== undefined) {
|
||||||
@@ -714,8 +738,9 @@ module.exports = function(app, db) {
|
|||||||
message: 'Идентификатор успешно обновлен'
|
message: 'Идентификатор успешно обновлен'
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// DELETE /api2/idusers/:id - Удалить идентификатор пользователя (только админ)
|
// DELETE /api2/idusers/:id - Удалить идентификатор пользователя (только админ)
|
||||||
router.delete('/api2/idusers/:id', requireAuth, requireAdmin, (req, res) => {
|
router.delete('/api2/idusers/:id', requireAuth, requireAdmin, (req, res) => {
|
||||||
|
|||||||
912
public/doc.html
912
public/doc.html
File diff suppressed because it is too large
Load Diff
373
public/doc.js
373
public/doc.js
@@ -1,26 +1,26 @@
|
|||||||
// Глобальные переменные
|
// Глобальные переменные
|
||||||
let currentUser = null;
|
let currentUser = null;
|
||||||
let isAdmin = false;
|
let isAdmin = false;
|
||||||
let currentTab = 'groups';
|
let currentTab = 'groups';
|
||||||
let groups = [];
|
let groups = [];
|
||||||
let idusers = [];
|
let idusers = [];
|
||||||
let allUsers = [];
|
let allUsers = [];
|
||||||
let currentPage = {
|
let currentPage = {
|
||||||
groups: 1,
|
groups: 1,
|
||||||
idusers: 1
|
idusers: 1
|
||||||
};
|
};
|
||||||
const itemsPerPage = 20;
|
const itemsPerPage = 20;
|
||||||
let deleteCallback = null;
|
let deleteCallback = null;
|
||||||
let deleteParams = null;
|
let deleteParams = null;
|
||||||
|
|
||||||
// Инициализация при загрузке страницы
|
// Инициализация при загрузке страницы
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
checkAuth();
|
checkAuth();
|
||||||
setupEventListeners();
|
setupEventListeners();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Проверка аутентификации
|
// Проверка аутентификации
|
||||||
async function checkAuth() {
|
async function checkAuth() {
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/api/user');
|
const response = await fetch('/api/user');
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
@@ -40,7 +40,7 @@
|
|||||||
loadGroups();
|
loadGroups();
|
||||||
loadAllUsers();
|
loadAllUsers();
|
||||||
loadIdUsers();
|
loadIdUsers();
|
||||||
// loadStats();
|
//loadStats();
|
||||||
} else {
|
} else {
|
||||||
window.location.href = '/';
|
window.location.href = '/';
|
||||||
}
|
}
|
||||||
@@ -48,10 +48,10 @@
|
|||||||
console.error('Ошибка проверки аутентификации:', error);
|
console.error('Ошибка проверки аутентификации:', error);
|
||||||
window.location.href = '/';
|
window.location.href = '/';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Настройка обработчиков событий
|
// Настройка обработчиков событий
|
||||||
function setupEventListeners() {
|
function setupEventListeners() {
|
||||||
// Переключение вкладок
|
// Переключение вкладок
|
||||||
document.querySelectorAll('.tab').forEach(tab => {
|
document.querySelectorAll('.tab').forEach(tab => {
|
||||||
tab.addEventListener('click', function() {
|
tab.addEventListener('click', function() {
|
||||||
@@ -78,10 +78,15 @@
|
|||||||
document.getElementById('iduserServiceTypeFilter').addEventListener('change', filterIdUsers);
|
document.getElementById('iduserServiceTypeFilter').addEventListener('change', filterIdUsers);
|
||||||
document.getElementById('iduserGroupFilter').addEventListener('change', filterIdUsers);
|
document.getElementById('iduserGroupFilter').addEventListener('change', filterIdUsers);
|
||||||
document.getElementById('iduserStatusFilter').addEventListener('change', filterIdUsers);
|
document.getElementById('iduserStatusFilter').addEventListener('change', filterIdUsers);
|
||||||
}
|
|
||||||
|
|
||||||
// Дебаунс для поиска
|
// Обновление опций групп при изменении типа сервиса в форме
|
||||||
function debounce(func, wait) {
|
document.getElementById('iduserServiceType').addEventListener('change', function() {
|
||||||
|
updateGroupOptions();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Дебаунс для поиска
|
||||||
|
function debounce(func, wait) {
|
||||||
let timeout;
|
let timeout;
|
||||||
return function executedFunction(...args) {
|
return function executedFunction(...args) {
|
||||||
const later = () => {
|
const later = () => {
|
||||||
@@ -91,10 +96,10 @@
|
|||||||
clearTimeout(timeout);
|
clearTimeout(timeout);
|
||||||
timeout = setTimeout(later, wait);
|
timeout = setTimeout(later, wait);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Переключение вкладок
|
// Переключение вкладок
|
||||||
function switchTab(tabId) {
|
function switchTab(tabId) {
|
||||||
currentTab = tabId;
|
currentTab = tabId;
|
||||||
|
|
||||||
// Обновляем активные вкладки
|
// Обновляем активные вкладки
|
||||||
@@ -112,10 +117,10 @@
|
|||||||
content.classList.add('active');
|
content.classList.add('active');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Загрузка всех пользователей
|
// Загрузка всех пользователей
|
||||||
async function loadAllUsers() {
|
async function loadAllUsers() {
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/api/users');
|
const response = await fetch('/api/users');
|
||||||
if (!response.ok) throw new Error('Ошибка загрузки пользователей');
|
if (!response.ok) throw new Error('Ошибка загрузки пользователей');
|
||||||
@@ -135,10 +140,10 @@
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка загрузки пользователей:', error);
|
console.error('Ошибка загрузки пользователей:', error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Загрузка групп
|
// Загрузка групп
|
||||||
async function loadGroups() {
|
async function loadGroups() {
|
||||||
try {
|
try {
|
||||||
const tableBody = document.getElementById('groupsTableBody');
|
const tableBody = document.getElementById('groupsTableBody');
|
||||||
tableBody.innerHTML = '<tr><td colspan="8" class="loading"><i class="fas fa-spinner fa-spin"></i> Загрузка групп...</td></tr>';
|
tableBody.innerHTML = '<tr><td colspan="8" class="loading"><i class="fas fa-spinner fa-spin"></i> Загрузка групп...</td></tr>';
|
||||||
@@ -170,10 +175,10 @@
|
|||||||
document.getElementById('groupsTableBody').innerHTML =
|
document.getElementById('groupsTableBody').innerHTML =
|
||||||
'<tr><td colspan="8" class="error">Ошибка загрузки групп: ' + error.message + '</td></tr>';
|
'<tr><td colspan="8" class="error">Ошибка загрузки групп: ' + error.message + '</td></tr>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Отображение групп
|
// Отображение групп
|
||||||
function renderGroups(filteredGroups = null) {
|
function renderGroups(filteredGroups = null) {
|
||||||
const groupsToRender = filteredGroups || groups;
|
const groupsToRender = filteredGroups || groups;
|
||||||
const tableBody = document.getElementById('groupsTableBody');
|
const tableBody = document.getElementById('groupsTableBody');
|
||||||
|
|
||||||
@@ -237,10 +242,10 @@
|
|||||||
|
|
||||||
// Пагинация
|
// Пагинация
|
||||||
renderPagination('groups', totalPages);
|
renderPagination('groups', totalPages);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Фильтрация групп
|
// Фильтрация групп
|
||||||
function filterGroups() {
|
function filterGroups() {
|
||||||
const searchText = document.getElementById('groupSearch').value.toLowerCase();
|
const searchText = document.getElementById('groupSearch').value.toLowerCase();
|
||||||
const serviceType = document.getElementById('groupServiceTypeFilter').value;
|
const serviceType = document.getElementById('groupServiceTypeFilter').value;
|
||||||
const statusFilter = document.getElementById('groupStatusFilter').value;
|
const statusFilter = document.getElementById('groupStatusFilter').value;
|
||||||
@@ -263,10 +268,10 @@
|
|||||||
|
|
||||||
currentPage.groups = 1;
|
currentPage.groups = 1;
|
||||||
renderGroups(filtered);
|
renderGroups(filtered);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Загрузка идентификаторов пользователей
|
// Загрузка идентификаторов пользователей
|
||||||
async function loadIdUsers() {
|
async function loadIdUsers() {
|
||||||
try {
|
try {
|
||||||
const tableBody = document.getElementById('idusersTableBody');
|
const tableBody = document.getElementById('idusersTableBody');
|
||||||
tableBody.innerHTML = '<tr><td colspan="11" class="loading"><i class="fas fa-spinner fa-spin"></i> Загрузка идентификаторов...</td></tr>';
|
tableBody.innerHTML = '<tr><td colspan="11" class="loading"><i class="fas fa-spinner fa-spin"></i> Загрузка идентификаторов...</td></tr>';
|
||||||
@@ -281,10 +286,10 @@
|
|||||||
document.getElementById('idusersTableBody').innerHTML =
|
document.getElementById('idusersTableBody').innerHTML =
|
||||||
'<tr><td colspan="11" class="error">Ошибка загрузки идентификаторов: ' + error.message + '</td></tr>';
|
'<tr><td colspan="11" class="error">Ошибка загрузки идентификаторов: ' + error.message + '</td></tr>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Отображение идентификаторов пользователей
|
// Отображение идентификаторов пользователей
|
||||||
function renderIdUsers(filteredIdUsers = null) {
|
function renderIdUsers(filteredIdUsers = null) {
|
||||||
const idusersToRender = filteredIdUsers || idusers;
|
const idusersToRender = filteredIdUsers || idusers;
|
||||||
const tableBody = document.getElementById('idusersTableBody');
|
const tableBody = document.getElementById('idusersTableBody');
|
||||||
|
|
||||||
@@ -338,7 +343,7 @@
|
|||||||
<small>${iduser.user_login || '-'}</small>
|
<small>${iduser.user_login || '-'}</small>
|
||||||
</td>
|
</td>
|
||||||
<td>${serviceTypeBadge}</td>
|
<td>${serviceTypeBadge}</td>
|
||||||
<td><strong>${iduser.external_id}</strong></td>
|
<td><strong>${iduser.external_id || '-'}</strong></td>
|
||||||
<td>${iduser.login || '-'}</td>
|
<td>${iduser.login || '-'}</td>
|
||||||
<td>${iduser.ldap_group || '-'}</td>
|
<td>${iduser.ldap_group || '-'}</td>
|
||||||
<td>${iduser.group_name || '-'}</td>
|
<td>${iduser.group_name || '-'}</td>
|
||||||
@@ -362,10 +367,10 @@
|
|||||||
|
|
||||||
// Пагинация
|
// Пагинация
|
||||||
renderPagination('idusers', totalPages);
|
renderPagination('idusers', totalPages);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Фильтрация идентификаторов пользователей
|
// Фильтрация идентификаторов пользователей
|
||||||
function filterIdUsers() {
|
function filterIdUsers() {
|
||||||
const searchText = document.getElementById('iduserSearch').value.toLowerCase();
|
const searchText = document.getElementById('iduserSearch').value.toLowerCase();
|
||||||
const serviceType = document.getElementById('iduserServiceTypeFilter').value;
|
const serviceType = document.getElementById('iduserServiceTypeFilter').value;
|
||||||
const groupId = document.getElementById('iduserGroupFilter').value;
|
const groupId = document.getElementById('iduserGroupFilter').value;
|
||||||
@@ -374,7 +379,7 @@
|
|||||||
const filtered = idusers.filter(iduser => {
|
const filtered = idusers.filter(iduser => {
|
||||||
// Поиск по тексту
|
// Поиск по тексту
|
||||||
const matchesSearch = !searchText ||
|
const matchesSearch = !searchText ||
|
||||||
iduser.external_id.toLowerCase().includes(searchText) ||
|
(iduser.external_id && iduser.external_id.toLowerCase().includes(searchText)) ||
|
||||||
(iduser.login && iduser.login.toLowerCase().includes(searchText)) ||
|
(iduser.login && iduser.login.toLowerCase().includes(searchText)) ||
|
||||||
(iduser.user_name && iduser.user_name.toLowerCase().includes(searchText)) ||
|
(iduser.user_name && iduser.user_name.toLowerCase().includes(searchText)) ||
|
||||||
(iduser.user_login && iduser.user_login.toLowerCase().includes(searchText));
|
(iduser.user_login && iduser.user_login.toLowerCase().includes(searchText));
|
||||||
@@ -394,10 +399,10 @@
|
|||||||
|
|
||||||
currentPage.idusers = 1;
|
currentPage.idusers = 1;
|
||||||
renderIdUsers(filtered);
|
renderIdUsers(filtered);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Загрузка статистики
|
// Загрузка статистики
|
||||||
async function loadStats() {
|
async function loadStats() {
|
||||||
try {
|
try {
|
||||||
const statsGrid = document.getElementById('statsGrid');
|
const statsGrid = document.getElementById('statsGrid');
|
||||||
statsGrid.innerHTML = '<div class="loading"><i class="fas fa-spinner fa-spin"></i> Загрузка статистики...</div>';
|
statsGrid.innerHTML = '<div class="loading"><i class="fas fa-spinner fa-spin"></i> Загрузка статистики...</div>';
|
||||||
@@ -412,10 +417,10 @@
|
|||||||
document.getElementById('statsGrid').innerHTML =
|
document.getElementById('statsGrid').innerHTML =
|
||||||
'<div class="error">Ошибка загрузки статистики: ' + error.message + '</div>';
|
'<div class="error">Ошибка загрузки статистики: ' + error.message + '</div>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Отображение статистики
|
// Отображение статистики
|
||||||
function renderStats(stats) {
|
function renderStats(stats) {
|
||||||
const statsGrid = document.getElementById('statsGrid');
|
const statsGrid = document.getElementById('statsGrid');
|
||||||
const tableBody = document.getElementById('statsTableBody');
|
const tableBody = document.getElementById('statsTableBody');
|
||||||
|
|
||||||
@@ -470,10 +475,10 @@
|
|||||||
} else {
|
} else {
|
||||||
tableBody.innerHTML = '<tr><td colspan="5" class="no-data">Нет данных для отображения</td></tr>';
|
tableBody.innerHTML = '<tr><td colspan="5" class="no-data">Нет данных для отображения</td></tr>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Модальное окно для добавления группы
|
// Модальное окно для добавления группы
|
||||||
function showAddGroupModal() {
|
function showAddGroupModal() {
|
||||||
if (!isAdmin) {
|
if (!isAdmin) {
|
||||||
alert('Недостаточно прав');
|
alert('Недостаточно прав');
|
||||||
return;
|
return;
|
||||||
@@ -486,10 +491,10 @@
|
|||||||
document.getElementById('groupMessage').innerHTML = '';
|
document.getElementById('groupMessage').innerHTML = '';
|
||||||
|
|
||||||
document.getElementById('groupModal').classList.add('active');
|
document.getElementById('groupModal').classList.add('active');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Модальное окно для редактирования группы
|
// Модальное окно для редактирования группы
|
||||||
async function editGroup(id) {
|
async function editGroup(id) {
|
||||||
if (!isAdmin) {
|
if (!isAdmin) {
|
||||||
alert('Недостаточно прав');
|
alert('Недостаточно прав');
|
||||||
return;
|
return;
|
||||||
@@ -514,15 +519,15 @@
|
|||||||
console.error('Ошибка загрузки группы:', error);
|
console.error('Ошибка загрузки группы:', error);
|
||||||
alert('Ошибка загрузки группы: ' + error.message);
|
alert('Ошибка загрузки группы: ' + error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Закрытие модального окна группы
|
// Закрытие модального окна группы
|
||||||
function closeGroupModal() {
|
function closeGroupModal() {
|
||||||
document.getElementById('groupModal').classList.remove('active');
|
document.getElementById('groupModal').classList.remove('active');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Сохранение группы
|
// Сохранение группы
|
||||||
async function saveGroup(event) {
|
async function saveGroup(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
if (!isAdmin) {
|
if (!isAdmin) {
|
||||||
@@ -582,10 +587,10 @@
|
|||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Подтверждение удаления группы
|
// Подтверждение удаления группы
|
||||||
function confirmDeleteGroup(id) {
|
function confirmDeleteGroup(id) {
|
||||||
if (!isAdmin) {
|
if (!isAdmin) {
|
||||||
alert('Недостаточно прав');
|
alert('Недостаточно прав');
|
||||||
return;
|
return;
|
||||||
@@ -601,10 +606,10 @@
|
|||||||
deleteParams = { id };
|
deleteParams = { id };
|
||||||
|
|
||||||
document.getElementById('confirmModal').classList.add('active');
|
document.getElementById('confirmModal').classList.add('active');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Удаление группы
|
// Удаление группы
|
||||||
async function deleteGroup(params) {
|
async function deleteGroup(params) {
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`/api2/groups/${params.id}`, {
|
const response = await fetch(`/api2/groups/${params.id}`, {
|
||||||
method: 'DELETE'
|
method: 'DELETE'
|
||||||
@@ -631,10 +636,10 @@
|
|||||||
console.error('Ошибка удаления группы:', error);
|
console.error('Ошибка удаления группы:', error);
|
||||||
alert('Ошибка удаления группы: ' + error.message);
|
alert('Ошибка удаления группы: ' + error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Модальное окно для добавления идентификатора
|
// Модальное окно для добавления идентификатора
|
||||||
function showAddIdUserModal() {
|
function showAddIdUserModal() {
|
||||||
if (!isAdmin) {
|
if (!isAdmin) {
|
||||||
alert('Недостаточно прав');
|
alert('Недостаточно прав');
|
||||||
return;
|
return;
|
||||||
@@ -643,17 +648,33 @@
|
|||||||
document.getElementById('iduserModalTitle').textContent = 'Добавить идентификатор';
|
document.getElementById('iduserModalTitle').textContent = 'Добавить идентификатор';
|
||||||
document.getElementById('iduserId').value = '';
|
document.getElementById('iduserId').value = '';
|
||||||
document.getElementById('iduserForm').reset();
|
document.getElementById('iduserForm').reset();
|
||||||
|
|
||||||
|
// Устанавливаем тип сервиса по умолчанию как LDAP
|
||||||
|
document.getElementById('iduserServiceType').value = 'ldap';
|
||||||
|
|
||||||
document.getElementById('iduserIsActive').checked = true;
|
document.getElementById('iduserIsActive').checked = true;
|
||||||
document.getElementById('iduserMessage').innerHTML = '';
|
document.getElementById('iduserMessage').innerHTML = '';
|
||||||
|
|
||||||
// Обновляем опции групп
|
// Добавляем обработчик для автозаполнения LDAP полей
|
||||||
|
const userIdSelect = document.getElementById('iduserUserId');
|
||||||
|
|
||||||
|
// Удаляем существующие обработчики чтобы избежать дублирования
|
||||||
|
const newUserIdSelect = userIdSelect.cloneNode(true);
|
||||||
|
userIdSelect.parentNode.replaceChild(newUserIdSelect, userIdSelect);
|
||||||
|
|
||||||
|
// Добавляем новый обработчик
|
||||||
|
document.getElementById('iduserUserId').addEventListener('change', function() {
|
||||||
|
autoFillLdapFields(this.value);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Обновляем опции групп (все группы, независимо от сервиса)
|
||||||
updateGroupOptions();
|
updateGroupOptions();
|
||||||
|
|
||||||
document.getElementById('iduserModal').classList.add('active');
|
document.getElementById('iduserModal').classList.add('active');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Модальное окно для редактирования идентификатора
|
// Модальное окно для редактирования идентификатора
|
||||||
async function editIdUser(id) {
|
async function editIdUser(id) {
|
||||||
if (!isAdmin) {
|
if (!isAdmin) {
|
||||||
alert('Недостаточно прав');
|
alert('Недостаточно прав');
|
||||||
return;
|
return;
|
||||||
@@ -668,7 +689,7 @@
|
|||||||
document.getElementById('iduserModalTitle').textContent = 'Редактировать идентификатор';
|
document.getElementById('iduserModalTitle').textContent = 'Редактировать идентификатор';
|
||||||
document.getElementById('iduserId').value = iduser.id;
|
document.getElementById('iduserId').value = iduser.id;
|
||||||
document.getElementById('iduserUserId').value = iduser.user_id;
|
document.getElementById('iduserUserId').value = iduser.user_id;
|
||||||
document.getElementById('iduserExternalId').value = iduser.external_id;
|
document.getElementById('iduserExternalId').value = iduser.external_id || '';
|
||||||
document.getElementById('iduserLogin').value = iduser.login || '';
|
document.getElementById('iduserLogin').value = iduser.login || '';
|
||||||
document.getElementById('iduserLdapGroup').value = iduser.ldap_group || '';
|
document.getElementById('iduserLdapGroup').value = iduser.ldap_group || '';
|
||||||
document.getElementById('iduserServiceType').value = iduser.service_type;
|
document.getElementById('iduserServiceType').value = iduser.service_type;
|
||||||
@@ -681,9 +702,20 @@
|
|||||||
document.getElementById('iduserMetadata').value = '';
|
document.getElementById('iduserMetadata').value = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Обновляем опции групп и выбираем текущую
|
// Обновляем опции групп (все группы) и выбираем текущую
|
||||||
updateGroupOptions().then(() => {
|
await updateGroupOptions();
|
||||||
document.getElementById('iduserGroupId').value = iduser.group_id || '';
|
document.getElementById('iduserGroupId').value = iduser.group_id || '';
|
||||||
|
|
||||||
|
// Добавляем обработчик для автозаполнения LDAP полей
|
||||||
|
const userIdSelect = document.getElementById('iduserUserId');
|
||||||
|
|
||||||
|
// Удаляем существующие обработчики чтобы избежать дублирования
|
||||||
|
const newUserIdSelect = userIdSelect.cloneNode(true);
|
||||||
|
userIdSelect.parentNode.replaceChild(newUserIdSelect, userIdSelect);
|
||||||
|
|
||||||
|
// Добавляем новый обработчик
|
||||||
|
document.getElementById('iduserUserId').addEventListener('change', function() {
|
||||||
|
autoFillLdapFields(this.value);
|
||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById('iduserMessage').innerHTML = '';
|
document.getElementById('iduserMessage').innerHTML = '';
|
||||||
@@ -693,11 +725,50 @@
|
|||||||
console.error('Ошибка загрузки идентификатора:', error);
|
console.error('Ошибка загрузки идентификатора:', error);
|
||||||
alert('Ошибка загрузки идентификатора: ' + error.message);
|
alert('Ошибка загрузки идентификатора: ' + error.message);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Автоматическое заполнение полей LDAP на основе выбранного пользователя
|
||||||
|
function autoFillLdapFields(userId) {
|
||||||
|
if (!userId) return;
|
||||||
|
|
||||||
|
// Находим пользователя в списке всех пользователей
|
||||||
|
const user = allUsers.find(u => u.id == userId);
|
||||||
|
if (!user) return;
|
||||||
|
|
||||||
|
// Проверяем, является ли пользователь LDAP пользователем
|
||||||
|
// Предполагаем, что LDAP пользователи имеют логин в определенном формате
|
||||||
|
// или у них есть специальный атрибут в метаданных
|
||||||
|
const isLdapUser = user.login && (
|
||||||
|
user.login.includes('@') || // LDAP логин часто содержит домен
|
||||||
|
user.service_type === 'ldap' ||
|
||||||
|
(user.metadata && user.metadata.dn) // Имеет Distinguished Name
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isLdapUser) {
|
||||||
|
// Автоматически заполняем логин LDAP если поле пустое
|
||||||
|
if (!document.getElementById('iduserLogin').value.trim()) {
|
||||||
|
document.getElementById('iduserLogin').value = user.login;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Обновление опций групп в зависимости от типа сервиса
|
// Автоматически заполняем группу LDAP из атрибутов пользователя
|
||||||
async function updateGroupOptions() {
|
if (!document.getElementById('iduserLdapGroup').value.trim()) {
|
||||||
const serviceType = document.getElementById('iduserServiceType').value;
|
// Можно извлекать из различных мест:
|
||||||
|
// 1. Из метаданных пользователя
|
||||||
|
// 2. Из атрибута department или ou
|
||||||
|
// 3. Из других полей
|
||||||
|
if (user.metadata && user.metadata.ou) {
|
||||||
|
document.getElementById('iduserLdapGroup').value = user.metadata.ou;
|
||||||
|
} else if (user.department) {
|
||||||
|
document.getElementById('iduserLdapGroup').value = user.department;
|
||||||
|
} else if (user.metadata && user.metadata.memberOf) {
|
||||||
|
document.getElementById('iduserLdapGroup').value = user.metadata.memberOf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обновление опций групп - теперь показывает все группы независимо от типа сервиса
|
||||||
|
async function updateGroupOptions() {
|
||||||
const groupSelect = document.getElementById('iduserGroupId');
|
const groupSelect = document.getElementById('iduserGroupId');
|
||||||
|
|
||||||
// Загружаем группы, если еще не загружены
|
// Загружаем группы, если еще не загружены
|
||||||
@@ -705,38 +776,36 @@
|
|||||||
await loadGroups();
|
await loadGroups();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Фильтруем группы по типу сервиса
|
// Берем все активные группы (без фильтрации по типу сервиса)
|
||||||
const filteredGroups = serviceType ?
|
const activeGroups = groups.filter(g => g.is_active);
|
||||||
groups.filter(g => g.service_type === serviceType && g.is_active) :
|
|
||||||
groups.filter(g => g.is_active);
|
|
||||||
|
|
||||||
// Сохраняем текущее значение
|
// Сохраняем текущее значение
|
||||||
const currentValue = groupSelect.value;
|
const currentValue = groupSelect.value;
|
||||||
|
|
||||||
// Обновляем опции
|
// Обновляем опции
|
||||||
groupSelect.innerHTML = '<option value="">Без группы</option>';
|
groupSelect.innerHTML = '<option value="">Без группы</option>';
|
||||||
filteredGroups.forEach(group => {
|
activeGroups.forEach(group => {
|
||||||
const option = document.createElement('option');
|
const option = document.createElement('option');
|
||||||
option.value = group.id;
|
option.value = group.id;
|
||||||
option.textContent = group.name;
|
option.textContent = `${group.name} (${getServiceTypeName(group.service_type)})`;
|
||||||
groupSelect.appendChild(option);
|
groupSelect.appendChild(option);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Восстанавливаем значение, если оно есть в новых опциях
|
// Восстанавливаем значение, если оно есть в новых опциях
|
||||||
if (currentValue && filteredGroups.some(g => g.id == currentValue)) {
|
if (currentValue && activeGroups.some(g => g.id == currentValue)) {
|
||||||
groupSelect.value = currentValue;
|
groupSelect.value = currentValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Закрытие модального окна идентификатора
|
// Закрытие модального окна идентификатора
|
||||||
function closeIdUserModal() {
|
function closeIdUserModal() {
|
||||||
document.getElementById('iduserModal').classList.remove('active');
|
document.getElementById('iduserModal').classList.remove('active');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Сохранение идентификатора
|
// Сохранение идентификатора
|
||||||
async function saveIdUser(event) {
|
async function saveIdUser(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
if (!isAdmin) {
|
if (!isAdmin) {
|
||||||
@@ -747,6 +816,9 @@
|
|||||||
const iduserId = document.getElementById('iduserId').value;
|
const iduserId = document.getElementById('iduserId').value;
|
||||||
const isEdit = !!iduserId;
|
const isEdit = !!iduserId;
|
||||||
|
|
||||||
|
// Валидация - External ID теперь необязательный
|
||||||
|
const externalId = document.getElementById('iduserExternalId').value.trim();
|
||||||
|
|
||||||
// Парсим метаданные
|
// Парсим метаданные
|
||||||
let metadata = null;
|
let metadata = null;
|
||||||
const metadataText = document.getElementById('iduserMetadata').value.trim();
|
const metadataText = document.getElementById('iduserMetadata').value.trim();
|
||||||
@@ -767,14 +839,35 @@
|
|||||||
const iduserData = {
|
const iduserData = {
|
||||||
user_id: parseInt(document.getElementById('iduserUserId').value),
|
user_id: parseInt(document.getElementById('iduserUserId').value),
|
||||||
service_type: document.getElementById('iduserServiceType').value,
|
service_type: document.getElementById('iduserServiceType').value,
|
||||||
external_id: document.getElementById('iduserExternalId').value,
|
external_id: externalId || null, // Разрешаем null для external_id
|
||||||
login: document.getElementById('iduserLogin').value || undefined,
|
login: document.getElementById('iduserLogin').value.trim() || null,
|
||||||
ldap_group: document.getElementById('iduserLdapGroup').value || undefined,
|
ldap_group: document.getElementById('iduserLdapGroup').value.trim() || null,
|
||||||
group_id: document.getElementById('iduserGroupId').value || undefined,
|
group_id: document.getElementById('iduserGroupId').value || null,
|
||||||
metadata: metadata,
|
metadata: metadata,
|
||||||
is_active: document.getElementById('iduserIsActive').checked
|
is_active: document.getElementById('iduserIsActive').checked
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Проверяем обязательные поля
|
||||||
|
if (!iduserData.user_id) {
|
||||||
|
document.getElementById('iduserMessage').innerHTML = `
|
||||||
|
<div class="error">
|
||||||
|
<i class="fas fa-exclamation-circle"></i>
|
||||||
|
Пожалуйста, выберите пользователя
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!iduserData.service_type) {
|
||||||
|
document.getElementById('iduserMessage').innerHTML = `
|
||||||
|
<div class="error">
|
||||||
|
<i class="fas fa-exclamation-circle"></i>
|
||||||
|
Пожалуйста, выберите тип сервиса
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const url = isEdit ? `/api2/idusers/${iduserId}` : '/api2/idusers';
|
const url = isEdit ? `/api2/idusers/${iduserId}` : '/api2/idusers';
|
||||||
const method = isEdit ? 'PUT' : 'POST';
|
const method = isEdit ? 'PUT' : 'POST';
|
||||||
@@ -817,10 +910,10 @@
|
|||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Подтверждение удаления идентификатора
|
// Подтверждение удаления идентификатора
|
||||||
function confirmDeleteIdUser(id) {
|
function confirmDeleteIdUser(id) {
|
||||||
if (!isAdmin) {
|
if (!isAdmin) {
|
||||||
alert('Недостаточно прав');
|
alert('Недостаточно прав');
|
||||||
return;
|
return;
|
||||||
@@ -830,16 +923,16 @@
|
|||||||
if (!iduser) return;
|
if (!iduser) return;
|
||||||
|
|
||||||
document.getElementById('confirmModalTitle').textContent = 'Удаление идентификатора';
|
document.getElementById('confirmModalTitle').textContent = 'Удаление идентификатора';
|
||||||
document.getElementById('confirmMessage').textContent = `Вы уверены, что хотите удалить идентификатор "${iduser.external_id}" пользователя "${iduser.user_name}"?`;
|
document.getElementById('confirmMessage').textContent = `Вы уверены, что хотите удалить идентификатор "${iduser.external_id || 'без внешнего ID'}" пользователя "${iduser.user_name}"?`;
|
||||||
|
|
||||||
deleteCallback = deleteIdUser;
|
deleteCallback = deleteIdUser;
|
||||||
deleteParams = { id };
|
deleteParams = { id };
|
||||||
|
|
||||||
document.getElementById('confirmModal').classList.add('active');
|
document.getElementById('confirmModal').classList.add('active');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Удаление идентификатора
|
// Удаление идентификатора
|
||||||
async function deleteIdUser(params) {
|
async function deleteIdUser(params) {
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`/api2/idusers/${params.id}`, {
|
const response = await fetch(`/api2/idusers/${params.id}`, {
|
||||||
method: 'DELETE'
|
method: 'DELETE'
|
||||||
@@ -866,10 +959,10 @@
|
|||||||
console.error('Ошибка удаления идентификатора:', error);
|
console.error('Ошибка удаления идентификатора:', error);
|
||||||
alert('Ошибка удаления идентификатора: ' + error.message);
|
alert('Ошибка удаления идентификатора: ' + error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Пагинация
|
// Пагинация
|
||||||
function renderPagination(type, totalPages) {
|
function renderPagination(type, totalPages) {
|
||||||
const paginationDiv = document.getElementById(`${type}Pagination`);
|
const paginationDiv = document.getElementById(`${type}Pagination`);
|
||||||
|
|
||||||
if (totalPages <= 1) {
|
if (totalPages <= 1) {
|
||||||
@@ -906,10 +999,10 @@
|
|||||||
</span>`;
|
</span>`;
|
||||||
|
|
||||||
paginationDiv.innerHTML = html;
|
paginationDiv.innerHTML = html;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Изменение страницы
|
// Изменение страницы
|
||||||
function changePage(type, page) {
|
function changePage(type, page) {
|
||||||
currentPage[type] = page;
|
currentPage[type] = page;
|
||||||
|
|
||||||
if (type === 'groups') {
|
if (type === 'groups') {
|
||||||
@@ -917,36 +1010,36 @@
|
|||||||
} else if (type === 'idusers') {
|
} else if (type === 'idusers') {
|
||||||
filterIdUsers();
|
filterIdUsers();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Подтверждение удаления
|
// Подтверждение удаления
|
||||||
function confirmDelete() {
|
function confirmDelete() {
|
||||||
if (deleteCallback && deleteParams) {
|
if (deleteCallback && deleteParams) {
|
||||||
deleteCallback(deleteParams);
|
deleteCallback(deleteParams);
|
||||||
}
|
}
|
||||||
closeConfirmModal();
|
closeConfirmModal();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Закрытие модального окна подтверждения
|
// Закрытие модального окна подтверждения
|
||||||
function closeConfirmModal() {
|
function closeConfirmModal() {
|
||||||
document.getElementById('confirmModal').classList.remove('active');
|
document.getElementById('confirmModal').classList.remove('active');
|
||||||
deleteCallback = null;
|
deleteCallback = null;
|
||||||
deleteParams = null;
|
deleteParams = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Просмотр метаданных
|
// Просмотр метаданных
|
||||||
function showMetadata(metadata) {
|
function showMetadata(metadata) {
|
||||||
document.getElementById('metadataContent').textContent = metadata;
|
document.getElementById('metadataContent').textContent = metadata;
|
||||||
document.getElementById('metadataModal').classList.add('active');
|
document.getElementById('metadataModal').classList.add('active');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Закрытие модального окна метаданных
|
// Закрытие модального окна метаданных
|
||||||
function closeMetadataModal() {
|
function closeMetadataModal() {
|
||||||
document.getElementById('metadataModal').classList.remove('active');
|
document.getElementById('metadataModal').classList.remove('active');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Выход из системы
|
// Выход из системы
|
||||||
async function logout() {
|
async function logout() {
|
||||||
try {
|
try {
|
||||||
await fetch('/api/logout', {
|
await fetch('/api/logout', {
|
||||||
method: 'POST'
|
method: 'POST'
|
||||||
@@ -956,10 +1049,10 @@
|
|||||||
console.error('Ошибка выхода:', error);
|
console.error('Ошибка выхода:', error);
|
||||||
window.location.href = '/';
|
window.location.href = '/';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Вспомогательные функции
|
// Вспомогательные функции
|
||||||
function formatDate(dateString, type = 'date') {
|
function formatDate(dateString, type = 'date') {
|
||||||
if (!dateString) return '-';
|
if (!dateString) return '-';
|
||||||
|
|
||||||
const date = new Date(dateString);
|
const date = new Date(dateString);
|
||||||
@@ -982,19 +1075,19 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
return date.toLocaleString('ru-RU');
|
return date.toLocaleString('ru-RU');
|
||||||
}
|
}
|
||||||
|
|
||||||
function getServiceTypeName(type) {
|
function getServiceTypeName(type) {
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case 'sberbank': return 'Сбербанк';
|
case 'sberbank': return 'Сбербанк';
|
||||||
case 'yandex': return 'Яндекс';
|
case 'yandex': return 'Яндекс';
|
||||||
case 'ldap': return 'LDAP';
|
case 'ldap': return 'LDAP';
|
||||||
default: return 'Прочие';
|
default: return 'Прочие';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function escapeHtml(text) {
|
function escapeHtml(text) {
|
||||||
const div = document.createElement('div');
|
const div = document.createElement('div');
|
||||||
div.textContent = text;
|
div.textContent = text;
|
||||||
return div.innerHTML;
|
return div.innerHTML;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user