Папки шлюза по сети — два режима: простой (один логин) или через домен (группы и сотрудники bj)
- «Через домен»: сервер bj подключается к домену AD (winbind, один раз — учётной записью администратора домена, bj её не сохраняет); папки igate_exchange(_prod) открыты группам с ролью в bj и доменным сотрудникам bj — своим входом в Windows; краткое имя домена bj берёт из AD (crossRef nETBIOSName). - Список доступа bj сверяет сам: после изменения групп, сотрудников и настроек входа (через несколько секунд) и раз в 15 минут. - «Простой»: как было — один логин и пароль Samba; переход с домена выключает вход через домен (учётная запись компьютера в домене остаётся). - bj-igate-admin share: режимы simple/domain, join (realm, workgroup, admin), проверка списка доступа на недопустимые символы, состояние — mode/joined/realm. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014FsEKyJrYF69Cj9ZXzFLRi
This commit is contained in:
@@ -24,6 +24,9 @@
|
||||
.ct-act .btn[disabled]{opacity:.5;cursor:not-allowed}
|
||||
@media (max-width:760px){.ct-grid{grid-template-columns:minmax(0,1fr)}}
|
||||
.ig-share{margin-top:18px;padding-top:16px;border-top:1px solid var(--border)}
|
||||
.ig-sh-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;margin-top:10px}
|
||||
.ig-sh-grid label.f input{width:100%;box-sizing:border-box}
|
||||
@media (max-width:600px){.ig-sh-grid{grid-template-columns:minmax(0,1fr)}}
|
||||
.ig-addr{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-top:6px}
|
||||
.ig-addr code{font-size:14px;padding:4px 10px;border-radius:8px;background:var(--card);border:1px solid var(--border);user-select:all}
|
||||
.ig-addr .muted{font-size:12.5px}
|
||||
@@ -81,13 +84,29 @@
|
||||
</div>
|
||||
<div class="ig-share" id="ig-share">
|
||||
<h3>Папки шлюза по сети <span class="muted" style="font-weight:400;font-size:13px">— необязательно</span></h3>
|
||||
<p class="muted" style="font-size:13px;margin:8px 0 0">Папки обмена шлюза (INBOX, OUTBOX, SENT, ERRORS) можно открыть по сети Windows — если другие программы организации кладут или забирают файлы через этот шлюз. bj для работы это не нужно. Доступ — по своему логину и паролю, файлы пишутся от имени шлюза.</p>
|
||||
<p class="muted" style="font-size:13px;margin:4px 0 0">Папки обмена шлюза (INBOX, OUTBOX, SENT, ERRORS) можно открыть по сети Windows — если другие программы организации кладут или забирают файлы через этот шлюз. bj для работы это не нужно; файлы пишутся от имени шлюза.</p>
|
||||
<div id="ig-share-st" class="muted" style="font-size:13px;margin-top:8px">Проверяю…</div>
|
||||
<form id="ig-share-f" style="display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;max-width:560px;margin-top:10px">
|
||||
<label style="grid-column:1/-1;display:flex;gap:8px;align-items:center;font-weight:400;margin:0"><input type="checkbox" name="enabled" style="width:auto"> Открыть папки шлюза по сети</label>
|
||||
<label class="f">Логин<input name="user" value="igate-share" autocomplete="off" spellcheck="false"></label>
|
||||
<label class="f">Пароль (от 8 символов)<input name="password" type="password" autocomplete="new-password" spellcheck="false" placeholder="пусто — прежний"></label>
|
||||
<div style="grid-column:1/-1;display:flex;gap:8px;align-items:center;flex-wrap:wrap"><button type="submit" class="btn sm">Сохранить</button><span id="ig-share-out" style="font-size:13px"></span></div>
|
||||
<form id="ig-share-f" class="dq" style="margin-top:12px;max-width:680px">
|
||||
<div class="dq-tiles">
|
||||
<label class="dq-tile"><input type="radio" name="mode" value="simple" checked><span><b>Простой</b><small>Один логин и пароль на всех, кому нужны папки.</small></span></label>
|
||||
<label class="dq-tile" id="ig-sh-dtile"><input type="radio" name="mode" value="domain"><span><b>Через домен</b><small id="ig-sh-dnote">Те же группы и сотрудники домена, что и в bj, — своим входом в Windows, без отдельного пароля. Убрали из группы — доступ пропал.</small></span></label>
|
||||
</div>
|
||||
<label style="display:flex;gap:8px;align-items:center;font-weight:500;margin:12px 0 0"><input type="checkbox" name="enabled" style="width:auto"> Открыть папки шлюза по сети</label>
|
||||
<div id="ig-sh-simple" class="ig-sh-grid">
|
||||
<label class="f">Логин<input name="user" value="igate-share" autocomplete="off" spellcheck="false"></label>
|
||||
<label class="f">Пароль (от 8 символов)<input name="password" type="password" autocomplete="new-password" spellcheck="false" placeholder="пусто — прежний"></label>
|
||||
</div>
|
||||
<div id="ig-sh-domain" hidden>
|
||||
<div id="ig-sh-access" class="muted" style="font-size:13px;margin-top:10px"></div>
|
||||
<div id="ig-sh-join" hidden style="margin-top:10px">
|
||||
<p style="margin:0;font-size:13.5px">Сервер bj ещё не подключён к домену <b id="ig-sh-realm"></b>. Подключить нужно один раз — учётной записью с правом добавлять компьютеры в домен; bj её не сохраняет. В домене появится компьютер <b id="ig-sh-host"></b>.</p>
|
||||
<div class="ig-sh-grid">
|
||||
<label class="f">Администратор домена<input name="admin" autocomplete="off" spellcheck="false" placeholder="например admin или admin@corp.local"></label>
|
||||
<label class="f">Пароль<input name="adminpw" type="password" autocomplete="new-password"></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-top:12px"><button type="submit" class="btn sm" id="ig-sh-save">Сохранить</button><span id="ig-share-out" style="font-size:13px"></span></div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="ig-job" id="ig-job" hidden aria-live="polite">
|
||||
@@ -160,28 +179,54 @@
|
||||
}).catch(function(){});
|
||||
return {watch:watch};
|
||||
})();
|
||||
// доступ к папкам шлюза по сети (Samba): состояние и сохранение
|
||||
// доступ к папкам шлюза по сети (Samba): простой режим или через домен
|
||||
(function(){
|
||||
var f=document.getElementById('ig-share-f'), stl=document.getElementById('ig-share-st'), o=document.getElementById('ig-share-out');
|
||||
if(!f) return;
|
||||
var cur={}, sim=document.getElementById('ig-sh-simple'), dom=document.getElementById('ig-sh-domain'), join=document.getElementById('ig-sh-join'), acc=document.getElementById('ig-sh-access');
|
||||
function mode(){ return f.mode.value; }
|
||||
function sync(){ var d=mode()==='domain'; sim.hidden=d; dom.hidden=!d; join.hidden=!(d && !cur.joined);
|
||||
document.getElementById('ig-sh-save').textContent=(d && !cur.joined)?'Подключить сервер к домену и открыть папки':'Сохранить'; }
|
||||
function addrs(d){ var hosts=[d.ip||location.hostname]; if(d.host && d.host!==hosts[0]) hosts.push(d.host);
|
||||
var names=(d.shares&&d.shares.length)?d.shares:['igate_exchange'], rows=[];
|
||||
names.forEach(function(n){ hosts.forEach(function(h){ var p='\\\\'+h+'\\'+n;
|
||||
rows.push('<div class="ig-addr"><code>'+esc(p)+'</code><button type="button" class="btn sm ghost" data-copy="'+esc(p)+'">Скопировать</button><span class="muted">'+(n.indexOf('prod')>=0?'боевой контур':'тестовый контур TEST3')+(h===d.host?' · по имени сервера':'')+'</span></div>'); }); });
|
||||
return rows.join(''); }
|
||||
function show(d){
|
||||
if(!d.ok){ stl.innerHTML=bad(d.error||'состояние не получено'); return; }
|
||||
if(d.manual){ stl.innerHTML=ok('папки открыты вручную (smb.conf) для '+(d.user||'—')+' — bj их не меняет'); f.hidden=true; return; }
|
||||
cur=d;
|
||||
if(d.manual){ stl.innerHTML=ok('папки открыты вручную (smb.conf) для '+esc(d.user||'—')+' — bj их не меняет'); f.hidden=true; return; }
|
||||
var a=d.access||{}, g=a.groups||[], u=a.users||[];
|
||||
acc.innerHTML=(g.length||u.length)?('Доступ получат: '+(g.length?'группы <b>'+g.map(esc).join('</b>, <b>')+'</b>':'')+(g.length&&u.length?'; ':'')+(u.length?'сотрудники <b>'+u.map(esc).join('</b>, <b>')+'</b>':'')+'. Список — из Настройка → Пользователи, обновляется сам.'):'<span style="color:var(--warn)">В bj пока нет групп и сотрудников домена с доступом — добавьте их в Настройка → Пользователи («Сотрудники из домена»).</span>';
|
||||
var dt=document.getElementById('ig-sh-dtile'), dr=f.querySelector('input[name=mode][value=domain]');
|
||||
dr.disabled=!d.ad_ready; dt.style.opacity=d.ad_ready?'':'.55';
|
||||
if(!d.ad_ready) document.getElementById('ig-sh-dnote').textContent='Сначала подключите домен в bj: Настройка → Пользователи → «Сотрудники из домена».';
|
||||
document.getElementById('ig-sh-realm').textContent=d.ad_domain||d.realm||'';
|
||||
document.getElementById('ig-sh-host').textContent=d.host||'';
|
||||
f.querySelector('input[name=mode][value='+(d.mode==='domain'?'domain':'simple')+']').checked=true;
|
||||
if(d.on){
|
||||
var hosts=[d.ip||location.hostname]; if(d.host && d.host!==hosts[0]) hosts.push(d.host);
|
||||
var names=(d.shares&&d.shares.length)?d.shares:['igate_exchange'];
|
||||
var rows=[]; names.forEach(function(n){ hosts.forEach(function(h){ var p='\\\\'+h+'\\'+n;
|
||||
rows.push('<div class="ig-addr"><code>'+esc(p)+'</code><button type="button" class="btn sm ghost" data-copy="'+esc(p)+'">Скопировать</button><span class="muted">'+(n.indexOf('prod')>=0?'боевой контур':'тестовый контур TEST3')+(h===d.host?' · по имени сервера':'')+'</span></div>'); }); });
|
||||
stl.innerHTML='<div class="stc stc-ok" style="margin-top:4px"><span class="stc-ic"></span><div class="stc-b"><b>Папки открыты по сети</b><small>Вставьте адрес в адресную строку проводника Windows; вход — логин <b>'+esc(d.user||'—')+'</b> и пароль, который задали здесь.</small>'+rows.join('')+'</div></div>';
|
||||
var who=d.mode==='domain'?'Входят сотрудники домена с доступом к bj — своей учётной записью Windows, пароль не спрашивается.':'Вход — логин <b>'+esc(d.user||'—')+'</b> и пароль, который задали здесь.';
|
||||
stl.innerHTML='<div class="stc stc-ok" style="margin-top:4px"><span class="stc-ic"></span><div class="stc-b"><b>Папки открыты по сети'+(d.mode==='domain'?' — через домен '+esc(d.realm||''):'')+'</b><small>Вставьте адрес в адресную строку проводника Windows. '+who+'</small>'+addrs(d)+'</div></div>';
|
||||
stl.querySelectorAll('[data-copy]').forEach(function(b){ b.onclick=function(){ (window.bjCopy||function(t){navigator.clipboard&&navigator.clipboard.writeText(t)})(b.dataset.copy); b.textContent='Скопировано ✓'; setTimeout(function(){b.textContent='Скопировать'},1500); }; });
|
||||
} else stl.innerHTML='<span class="muted">Сейчас закрыты. Отметьте «Открыть папки шлюза по сети», задайте пароль и нажмите «Сохранить» — здесь появится адрес для проводника.</span>';
|
||||
f.enabled.checked=!!d.on; if(d.user) f.user.value=d.user;
|
||||
} else stl.innerHTML='<span class="muted">Сейчас закрыты. Выберите, как входить, отметьте «Открыть папки шлюза по сети» и сохраните — здесь появится адрес для проводника.</span>';
|
||||
f.enabled.checked=!!d.on; if(d.mode!=='domain' && d.user) f.user.value=d.user;
|
||||
sync();
|
||||
}
|
||||
fetch('/admin/setup/igate/share',{cache:'no-store'}).then(function(r){return r.json()}).then(show).catch(function(){ stl.textContent='Состояние не получено.'; });
|
||||
f.addEventListener('submit',function(e){ e.preventDefault(); o.textContent='Сохраняю… (первый раз — установка Samba, до пары минут)';
|
||||
var p=new URLSearchParams(); if(f.enabled.checked) p.set('enabled','1'); p.set('user',f.user.value.trim()); p.set('password',f.password.value);
|
||||
post('/admin/setup/igate/share',p).then(function(d){ o.innerHTML=d.ok?ok(d.output):bad(d.error); f.password.value='';
|
||||
return fetch('/admin/setup/igate/share',{cache:'no-store'}).then(function(r){return r.json()}).then(show); }).catch(function(){ o.innerHTML=bad('не сохранено'); }); });
|
||||
function load(){ return fetch('/admin/setup/igate/share',{cache:'no-store'}).then(function(r){return r.json()}).then(show).catch(function(){ stl.textContent='Состояние не получено.'; }); }
|
||||
f.addEventListener('change',function(e){ if(e.target.name==='mode') sync(); });
|
||||
f.addEventListener('submit',function(e){ e.preventDefault();
|
||||
var p=new URLSearchParams(), url='/admin/setup/igate/share', d=mode()==='domain';
|
||||
if(d && !cur.joined){
|
||||
if(!f.admin.value.trim()||!f.adminpw.value){ o.innerHTML=bad('не заполнено: администратор домена и пароль'); return; }
|
||||
url='/admin/setup/igate/share-join'; p.set('admin',f.admin.value.trim()); p.set('adminpw',f.adminpw.value);
|
||||
o.textContent='Подключаю сервер к домену… (первый раз — установка winbind, до пары минут)';
|
||||
} else {
|
||||
p.set('mode',mode()); if(f.enabled.checked) p.set('enabled','1');
|
||||
if(!d){ p.set('user',f.user.value.trim()); p.set('password',f.password.value); }
|
||||
o.textContent='Сохраняю… (первый раз — установка Samba, до пары минут)';
|
||||
}
|
||||
post(url,p).then(function(r){ o.innerHTML=r.ok?ok(r.output):bad(r.error); f.password.value=''; f.adminpw.value=''; return load(); }).catch(function(){ o.innerHTML=bad('не сохранено'); }); });
|
||||
load();
|
||||
})();
|
||||
var st=null;
|
||||
function load(){
|
||||
|
||||
Reference in New Issue
Block a user