mirror of
https://gitverse.ru/kpa39l/icq.git
synced 2026-09-29 18:05:10 +00:00
feat: OMEMO по умолчанию, admin_web+BOSH, MUC-модули (vcard_muc, muc_moderation), модули из apt в modules/, scripts/omemo_check.py, backup.sh на Яндекс.Диск
- index.html: omemo_default=true (XEP-0384, встроен в Converse v14) - prosody.cfg.lua: admin_web + bosh (глобальные), MUC: vcard_muc (XEP-0153) + muc_moderation (XEP-0425) - modules/: mod_admin_web (+www_files), mod_http_upload_external, mod_muc_moderation, mod_vcard_muc — из prosody-modules (apt) - scripts/omemo_check.py — проверка OMEMO-бандлов - backup.sh — ежедневный бэкап проекта (data/config/certs/modules/webchat/доки) на /mnt/yandex-disk, ротация 7/30 дней - STATUS/WALKTHROUGH: OMEMO, admin_web, HTTP Upload итоги
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
body {
|
||||
margin: 0
|
||||
}
|
||||
|
||||
a {
|
||||
color: #0000FF
|
||||
}
|
||||
|
||||
#adhocCommands > ul {
|
||||
margin: 0
|
||||
}
|
||||
|
||||
.btn {
|
||||
margin-right: 0.3em
|
||||
}
|
||||
|
||||
.btn:last-child {
|
||||
margin-right: 0
|
||||
}
|
||||
|
||||
#log_container {
|
||||
clear: both;
|
||||
display: none
|
||||
}
|
||||
|
||||
#adhocCommands {
|
||||
border-right: solid 1px
|
||||
}
|
||||
|
||||
#adhocCommands li {
|
||||
list-style: inside
|
||||
}
|
||||
|
||||
#login {
|
||||
float: left;
|
||||
margin: 1em 2em 0 1em;
|
||||
padding-right: 1em;
|
||||
border: solid 1px;
|
||||
background: #eef0f2;
|
||||
color: #000000
|
||||
}
|
||||
|
||||
#main {
|
||||
display: none;
|
||||
margin: 1em
|
||||
}
|
||||
|
||||
#main p {
|
||||
margin: 0
|
||||
}
|
||||
|
||||
#top {
|
||||
clear: both;
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 757px) {
|
||||
#header {
|
||||
background: url(../images/blue_orange.png) repeat-x
|
||||
}
|
||||
}
|
||||
|
||||
#header img {
|
||||
max-width: 100%;
|
||||
height: auto
|
||||
}
|
||||
|
||||
#menu {
|
||||
display: none;
|
||||
color: #454748;
|
||||
font-size: 1.1em;
|
||||
background: #eef0f2;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#menu ul {
|
||||
display: inline;
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding: 0.5em 0
|
||||
}
|
||||
|
||||
#menu li {
|
||||
display: inline;
|
||||
padding: 0 0.5em
|
||||
}
|
||||
|
||||
#menu a {
|
||||
color: #454748;
|
||||
text-decoration: none
|
||||
}
|
||||
|
||||
#menu li a:hover {
|
||||
color: #6197DF;
|
||||
text-decoration: underline
|
||||
}
|
||||
|
||||
#selector {
|
||||
display: inline-block
|
||||
}
|
||||
|
||||
#s2sList h2, #c2sList h2 {
|
||||
color: #4b8ade;
|
||||
margin: 0
|
||||
}
|
||||
|
||||
#s2sList li, #c2sList li {
|
||||
cursor: pointer
|
||||
}
|
||||
|
||||
#host {
|
||||
margin: 0.25em;
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 158 B |
Binary file not shown.
|
After Width: | Height: | Size: 695 B |
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 105 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1,90 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
|
||||
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Prosody Webadmin</title>
|
||||
<link rel="stylesheet" type="text/css" href="css/bootstrap-1.4.0.min.css" />
|
||||
<link rel="stylesheet" type="text/css" href="css/style.css" />
|
||||
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8" />
|
||||
<script type="text/javascript" src="js/jquery-1.10.2.min.js"></script>
|
||||
<script type="text/javascript" src="js/strophe.min.js"></script>
|
||||
<script type="text/javascript" src="js/adhoc.js"></script>
|
||||
<script type="text/javascript" src="js/main.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id='top'>
|
||||
<div id='header'>
|
||||
<img src="images/prosody.png" alt="Prosody"/>
|
||||
</div>
|
||||
<div id='menu'>
|
||||
<ul>
|
||||
<li><a id='adhocMenu' href="#adhoc">General</a></li>
|
||||
<li><a id='serverMenu' href="#s2sList">Servers</a></li>
|
||||
<li><a id='clientMenu' href="#c2sList">Clients</a></li>
|
||||
<li><span id="selector">Host: <select id="host"></select></span></li>
|
||||
<li><a href="#" id='logout'>Logout</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id='login'>
|
||||
<form id='cred' name='cred' class='form-stacked'>
|
||||
<fieldset>
|
||||
<div class='clearfix'>
|
||||
<label for='jid'>JID:</label>
|
||||
<div class='input'>
|
||||
<input type='text' id='jid' />
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearfix'>
|
||||
<label for='pass'>Password:</label>
|
||||
<div class='input'>
|
||||
<input type='password' id='pass' />
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearfix'>
|
||||
<div class='input'>
|
||||
<input type='submit' id='connect' value='Login' class='btn' />
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id='main'>
|
||||
<div id="adhoc">
|
||||
<div class="row">
|
||||
<div id="adhocCommands" class="span4"></div>
|
||||
<div id="adhocDisplay" class="span12"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="s2sList" class="container">
|
||||
<div class="row">
|
||||
<div class="span8">
|
||||
<h2>Incoming S2S connections:</h2>
|
||||
<ul id="s2sin"></ul>
|
||||
</div>
|
||||
<div class="span8">
|
||||
<h2>Outgoing S2S connections:</h2>
|
||||
<ul id="s2sout"></ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="c2sList" class="container">
|
||||
<div class="row">
|
||||
<div class="span16">
|
||||
<h2>Client connections:</h2>
|
||||
<ul id="c2s"></ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id='log_container'>
|
||||
<a id='log_toggle' href='#'>Status Log :</a>
|
||||
<div id='log'></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,252 @@
|
||||
// adhocweb
|
||||
// Copyright (c) 2010-2013 Florian Zeitz
|
||||
// This project is MIT licensed.
|
||||
// http://git.babelmonkeys.de/?p=adhocweb.git;a=blob_plain;f=js/adhoc.js
|
||||
|
||||
Strophe.addNamespace('ADHOC', 'http://jabber.org/protocol/commands')
|
||||
|
||||
function Adhoc (view, readycb) {
|
||||
this.status = {
|
||||
sessionid: null,
|
||||
cmdNode: null,
|
||||
queryJID: null,
|
||||
readycb: readycb,
|
||||
view: view
|
||||
}
|
||||
}
|
||||
|
||||
Adhoc.prototype = {
|
||||
constructor: Adhoc,
|
||||
|
||||
addNote: function (text, type) {
|
||||
if (!type) {
|
||||
type = 'info'
|
||||
}
|
||||
text = text.replace(/\n/g, '<br/>')
|
||||
$(this.status.view).append(`<p class='${type}Note'>${text}</p>`)
|
||||
},
|
||||
|
||||
addForm: function (x) {
|
||||
let self = this
|
||||
let form = $(`<form class='form-stacked' action='#'/>`)
|
||||
form.submit(function (event) {
|
||||
self.executeCommand('execute', self.serializeToDataform('form'),
|
||||
function (e) { self.displayResult(e) })
|
||||
event.preventDefault()
|
||||
})
|
||||
let fieldset = $('<fieldset/>')
|
||||
form.append(fieldset)
|
||||
$(x).find('title').each(function () { $('<legend/>').text($(this).text()).appendTo(fieldset) })
|
||||
$(x).find('instructions').each(function () { $('<p/>').text($(this).text()).appendTo(fieldset) })
|
||||
$(x).find('field').each(function () {
|
||||
let clearfix = $(`<div class='clearfix'/>`)
|
||||
let item = self.buildHTMLField(this)
|
||||
let label = $(this).attr('label')
|
||||
if (label) {
|
||||
$('<label/>').text(label).attr('for', $(this).attr('var')).appendTo(clearfix)
|
||||
}
|
||||
if ($(x).attr('type') === 'result') {
|
||||
item.attr('readonly', true)
|
||||
}
|
||||
clearfix.append(item)
|
||||
fieldset.append(clearfix)
|
||||
})
|
||||
$(self.status.view).append(form)
|
||||
},
|
||||
|
||||
buildHTMLField: function (fld) {
|
||||
let field = $(fld), html = {
|
||||
'hidden': `<input type='hidden'/>`,
|
||||
'boolean': `<input type='checkbox'/>`,
|
||||
'fixed': `<input type='text' readonly='readonly'/>`,
|
||||
'text-single': `<input type='text'/>`,
|
||||
'text-private': `<input type='password'/>`,
|
||||
'text-multi': `<textarea rows='10' cols='70'/>`,
|
||||
'jid-single': `<input type='text'/>`,
|
||||
'jid-multi': `<textarea rows='10' cols='70'/>`,
|
||||
'list-single': `<select/>`,
|
||||
'list-multi': `<select multiple='multiple'/>`,
|
||||
}
|
||||
let type = field.attr('type')
|
||||
let input = $(html[type] || '<input/>')
|
||||
let name = field.attr('var')
|
||||
|
||||
input.addClass('df-item')
|
||||
if (name) {
|
||||
input.attr('name', name)
|
||||
input.attr('id', name)
|
||||
}
|
||||
|
||||
if (field.find('required').length > 0) {
|
||||
input.attr('required', 'required')
|
||||
}
|
||||
|
||||
/* Add possible values to the lists */
|
||||
if (type === 'list-multi' || type === 'list-single') {
|
||||
field.find('option').each(function () {
|
||||
let option = $('<option/>')
|
||||
option.text($(this).attr('label'))
|
||||
option.val($(this).find('value').text())
|
||||
input.append(option)
|
||||
})
|
||||
}
|
||||
|
||||
/* Add/select default values */
|
||||
field.children('value').each(function () {
|
||||
let value = $(this).text()
|
||||
if ((type === 'text-multi') || (type === 'jid-multi')) {
|
||||
input.text(input.text() + value + '\n') /* .append() would work, but doesn't escape */
|
||||
} else if (type === 'list-multi') {
|
||||
input.children(`option[value="${value}"]`).each(function () {
|
||||
$(this).attr('selected', 'selected')
|
||||
})
|
||||
} else {
|
||||
input.val(value)
|
||||
}
|
||||
})
|
||||
|
||||
return input
|
||||
},
|
||||
|
||||
serializeToDataform: function (form) {
|
||||
let st = $build('x', { 'xmlns': 'jabber:x:data', 'type': 'submit' })
|
||||
$(form).find('.df-item').each(function () {
|
||||
st.c('field', { 'var': $(this).attr('name') })
|
||||
if (this.nodeName.toLowerCase() === 'select' && this.multiple) {
|
||||
for (let i = 0; i < this.options.length; i++) {
|
||||
if (this.options[i].selected) {
|
||||
st.c('value').t(this.options[i].text).up()
|
||||
}
|
||||
}
|
||||
} else if (this.nodeName.toLowerCase() === 'textarea') {
|
||||
let sp_value = this.value.split(/\r?\n|\r/g)
|
||||
for (let i = 0; i < sp_value.length; i++) {
|
||||
st.c('value').t(sp_value[i]).up()
|
||||
}
|
||||
} else if (this.nodeName.toLowerCase() === 'input' && this.type === 'checkbox') {
|
||||
if (this.checked) {
|
||||
st.c('value').t('1')
|
||||
} else {
|
||||
st.c('value').t('0')
|
||||
}
|
||||
} else {
|
||||
/* if this has value then */
|
||||
st.c('value').t($(this).val()).up()
|
||||
}
|
||||
st.up()
|
||||
})
|
||||
st.up()
|
||||
return st.tree()
|
||||
},
|
||||
|
||||
displayResult: function (result) {
|
||||
let self = this
|
||||
let status = $(result).find('command').attr('status')
|
||||
let kinds = { 'prev': 'Prev', 'next': 'Next', 'complete': 'Complete' }
|
||||
let actions = $(result).find('actions:first')
|
||||
|
||||
$(self.status.view).empty()
|
||||
$(result).find('command > *').each(function () {
|
||||
if ($(this).is('note')) {
|
||||
self.addNote($(this).text(), $(this).attr('type'))
|
||||
} else if ($(this).is('x[xmlns=jabber:x:data]')) {
|
||||
self.addForm(this)
|
||||
}
|
||||
})
|
||||
if (status === 'executing') {
|
||||
let controls = $(`<div class='actions'/>`)
|
||||
for (let kind in kinds) {
|
||||
let input;
|
||||
(function (type) {
|
||||
input = $(`<input type='button' disabled='disabled' class='btn' value='${kinds[type]}'/>`)
|
||||
.click(function () {
|
||||
self.executeCommand(type, (type !== 'prev') && self.serializeToDataform('form'), function (e) { self.displayResult(e) })
|
||||
}).appendTo(controls)
|
||||
})(kind)
|
||||
if (actions.find(kind).length > 0) {
|
||||
input.removeAttr('disabled')
|
||||
}
|
||||
if (actions.attr('execute') === kind) {
|
||||
input.addClass('primary')
|
||||
}
|
||||
}
|
||||
|
||||
$(`<input type='button' class='btn' value='Cancel'/>`).click(function () {
|
||||
self.cancelCommand(function (e) { self.displayResult(e) })
|
||||
}).appendTo(controls)
|
||||
$(self.status.view + ' fieldset').append(controls)
|
||||
} else {
|
||||
self.status.sessionid = null
|
||||
self.status.cmdNode = null
|
||||
self.status.readycb()
|
||||
}
|
||||
},
|
||||
|
||||
runCommand: function (item, callback) {
|
||||
this.status.cmdNode = $(item).attr('id') /* Save node of executed command */
|
||||
let cb = function (result) {
|
||||
this.status.sessionid = $(result).find('command').attr('sessionid')
|
||||
callback(result)
|
||||
}
|
||||
this.executeCommand('execute', false, cb.bind(this))
|
||||
},
|
||||
|
||||
executeCommand: function (type, childs, callback) {
|
||||
let execIQ
|
||||
if (this.status.sessionid) {
|
||||
execIQ = $iq({ type: 'set', to: this.status.queryJID, id: connection.getUniqueId() })
|
||||
.c('command', { xmlns: Strophe.NS.ADHOC, node: this.status.cmdNode, sessionid: this.status.sessionid, action: type })
|
||||
} else {
|
||||
execIQ = $iq({ type: 'set', to: this.status.queryJID, id: connection.getUniqueId() })
|
||||
.c('command', { xmlns: Strophe.NS.ADHOC, node: this.status.cmdNode, action: type })
|
||||
}
|
||||
if (childs) {
|
||||
execIQ.cnode(childs)
|
||||
}
|
||||
connection.sendIQ(execIQ, callback)
|
||||
},
|
||||
|
||||
cancelCommand: function (callback) {
|
||||
if (this.status.cmdNode == null) return
|
||||
this.executeCommand('cancel', false, callback)
|
||||
this.status.cmdNode = null
|
||||
this.status.sessionid = null
|
||||
},
|
||||
|
||||
getCommandNodes: function (callback) {
|
||||
let self = this
|
||||
let nodesIQ = $iq({ type: 'get', to: self.status.queryJID, id: connection.getUniqueId() }).c('query', { xmlns: Strophe.NS.DISCO_ITEMS, node: Strophe.NS.ADHOC })
|
||||
connection.sendIQ(nodesIQ, function (result) {
|
||||
let items = $('<ul></ul>')
|
||||
$(result).find('item').each(function () {
|
||||
let attrNode = $(this).attr('node')
|
||||
let attrName = $(this).attr('name')
|
||||
$('<li></li>').append($(`<a href='#' id='${attrNode}'>${attrName}</a>`).click(function (event) {
|
||||
self.cancelCommand(function () {})
|
||||
self.runCommand(this, function (result) { self.displayResult(result) })
|
||||
event.preventDefault()
|
||||
})).appendTo(items)
|
||||
})
|
||||
callback(items)
|
||||
})
|
||||
},
|
||||
|
||||
checkFeatures: function (jid, cb, ecb) {
|
||||
if (this.status.sessionid) {
|
||||
this.cancelCommand()
|
||||
}
|
||||
this.status.queryJID = jid
|
||||
let featureIQ = $iq({ type: 'get', to: this.status.queryJID, id: connection.getUniqueId() }).c('query', { xmlns: Strophe.NS.DISCO_INFO })
|
||||
$(this.status.view).empty()
|
||||
|
||||
function callback (result) {
|
||||
if ($(result).find(`feature[var='${trophe.NS.ADHOC}']`).length > 0) {
|
||||
cb(result)
|
||||
} else {
|
||||
ecb(result)
|
||||
}
|
||||
}
|
||||
|
||||
connection.sendIQ(featureIQ, callback, ecb)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,277 @@
|
||||
const BOSH_SERVICE = '/http-bind/'
|
||||
let show_log = false
|
||||
|
||||
Strophe.addNamespace('C2SSTREAM', 'http://prosody.im/streams/c2s')
|
||||
Strophe.addNamespace('S2SSTREAM', 'http://prosody.im/streams/s2s')
|
||||
Strophe.addNamespace('ADMINSUB', 'http://prosody.im/adminsub')
|
||||
Strophe.addNamespace('CAPS', 'http://jabber.org/protocol/caps')
|
||||
|
||||
let localJID = null
|
||||
let connection = null
|
||||
|
||||
let adminsubHost = null
|
||||
let adhocControl = new Adhoc('#adhocDisplay', function () {})
|
||||
|
||||
function log (msg) {
|
||||
let entry = $('<div></div>').append(document.createTextNode(msg))
|
||||
$('#log').append(entry)
|
||||
}
|
||||
|
||||
function rawInput (data) {
|
||||
log('RECV: ' + data)
|
||||
}
|
||||
|
||||
function rawOutput (data) {
|
||||
log('SENT: ' + data)
|
||||
}
|
||||
|
||||
function _cbNewS2S (e) {
|
||||
let items = e.getElementsByTagName('item')
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
let item = items[i]
|
||||
let id = item.attributes.getNamedItem('id').value
|
||||
let jid = item.getElementsByTagName('session')[0].attributes.getNamedItem('jid').value
|
||||
let infos = item.getElementsByTagName('info')
|
||||
|
||||
let entry = $(`<li id="${id}">${jid}</li>`)
|
||||
let tmp = item.getElementsByTagName('encrypted')[0]
|
||||
if (tmp) {
|
||||
if (tmp.getElementsByTagName('valid')[0]) {
|
||||
entry.append('<img src="images/secure.png" title="encrypted (certificate valid)" alt=" (secure) (encrypted)" />')
|
||||
} else {
|
||||
entry.append('<img src="images/encrypted.png" title="encrypted (certificate invalid)" alt=" (encrypted)" />')
|
||||
}
|
||||
}
|
||||
if (item.getElementsByTagName('compressed')[0]) {
|
||||
entry.append('<img src="images/compressed.png" title="compressed" alt=" (compressed)" />')
|
||||
}
|
||||
let metadata = $('<ul/>').css('display', 'none')
|
||||
entry.on('click', function () {
|
||||
$(this).find('ul').slideToggle()
|
||||
})
|
||||
metadata.appendTo(entry)
|
||||
for (let j = 0; j < infos.length; j++) {
|
||||
let info = infos[j]
|
||||
let infoName = info.attributes.getNamedItem('name').value
|
||||
let infoText = info.textContent
|
||||
metadata.append(`<li><b>${infoName}:</b> ${infoText}</li>`)
|
||||
}
|
||||
if (infos.length == 0) {
|
||||
metadata.append('<li>No information available</li>')
|
||||
}
|
||||
|
||||
if (items[i].getElementsByTagName('out')[0]) {
|
||||
entry.appendTo('#s2sout')
|
||||
} else {
|
||||
entry.appendTo('#s2sin')
|
||||
}
|
||||
}
|
||||
let retract = e.getElementsByTagName('retract')[0]
|
||||
if (retract) {
|
||||
let id = retract.attributes.getNamedItem('id').value
|
||||
$('#' + id).remove()
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
function _cbNewC2S (e) {
|
||||
let items = e.getElementsByTagName('item')
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
let item = items[i]
|
||||
let id = item.attributes.getNamedItem('id').value
|
||||
let jid = item.getElementsByTagName('session')[0].attributes.getNamedItem('jid').value
|
||||
let infos = item.getElementsByTagName('info')
|
||||
|
||||
let entry = $(`<li id="${id}">${jid}</li>`)
|
||||
let tmp = item.getElementsByTagName('encrypted')[0]
|
||||
if (tmp) {
|
||||
entry.append('<img src="images/encrypted.png" title="encrypted" alt=" (encrypted)" />')
|
||||
}
|
||||
if (item.getElementsByTagName('compressed')[0]) {
|
||||
entry.append('<img src="images/compressed.png" title="compressed" alt=" (compressed)" />')
|
||||
}
|
||||
let metadata = $('<ul/>').css('display', 'none')
|
||||
entry.on('click', function () {
|
||||
$(this).find('ul').slideToggle()
|
||||
})
|
||||
metadata.appendTo(entry)
|
||||
for (let j = 0; j < infos.length; j++) {
|
||||
let info = infos[j]
|
||||
metadata.append('<li><b>' + info.attributes.getNamedItem('name').value + ':</b> ' + info.textContent + '</li>')
|
||||
}
|
||||
if (infos.length == 0) {
|
||||
metadata.append('<li>No information available</li>')
|
||||
}
|
||||
entry.appendTo('#c2s')
|
||||
}
|
||||
let retract = e.getElementsByTagName('retract')[0]
|
||||
if (retract) {
|
||||
let id = retract.attributes.getNamedItem('id').value
|
||||
$('#' + id).remove()
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
function _cbAdminSub (e) {
|
||||
let node = e.getElementsByTagName('items')[0].attributes.getNamedItem('node').value
|
||||
if (node == Strophe.NS.C2SSTREAM) {
|
||||
_cbNewC2S(e)
|
||||
} else if (node == Strophe.NS.S2SSTREAM) {
|
||||
_cbNewS2S(e)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
function onConnect (status) {
|
||||
if (status == Strophe.Status.CONNECTING) {
|
||||
log('Strophe is connecting.')
|
||||
} else if (status == Strophe.Status.CONNFAIL) {
|
||||
alert('Connection failed (Wrong host?)')
|
||||
log('Strophe failed to connect.')
|
||||
showConnect()
|
||||
} else if (status == Strophe.Status.DISCONNECTING) {
|
||||
log('Strophe is disconnecting.')
|
||||
} else if (status == Strophe.Status.DISCONNECTED) {
|
||||
log('Strophe is disconnected.')
|
||||
showConnect()
|
||||
} else if (status == Strophe.Status.AUTHFAIL) {
|
||||
alert('Wrong username and/or password')
|
||||
log('Authentication failed')
|
||||
if (connection) {
|
||||
connection.disconnect()
|
||||
}
|
||||
} else if (status == Strophe.Status.CONNECTED) {
|
||||
log('Strophe is connected.')
|
||||
connection.sendIQ($iq({ to: connection.domain, type: 'get', id: connection.getUniqueId() })
|
||||
.c('adminsub', { xmlns: Strophe.NS.ADMINSUB })
|
||||
.c('adminfor'), function (e) {
|
||||
let domainpart = Strophe.getDomainFromJid(connection.jid)
|
||||
let items = e.getElementsByTagName('item')
|
||||
if (items.length == 0) {
|
||||
alert('You are not an administrator')
|
||||
connection.disconnect()
|
||||
return false
|
||||
}
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
let host = $(items[i]).text()
|
||||
$('<option/>').text(host).prop('selected', host == domainpart).appendTo('#host')
|
||||
}
|
||||
showDisconnect()
|
||||
adminsubHost = $('#host').val()
|
||||
adhocControl.checkFeatures(adminsubHost,
|
||||
function () {
|
||||
adhocControl.getCommandNodes(function (result) {
|
||||
$('#adhocDisplay').empty()
|
||||
$('#adhocCommands').html(result)
|
||||
})
|
||||
},
|
||||
function () {
|
||||
$('#adhocCommands').empty()
|
||||
$('#adhocDisplay').html('<p>This host does not support commands</p>')
|
||||
}
|
||||
)
|
||||
connection.addHandler(_cbAdminSub, Strophe.NS.ADMINSUB + '#event', 'message')
|
||||
connection.send($iq({ to: adminsubHost, type: 'set', id: connection.getUniqueId() }).c('adminsub', { xmlns: Strophe.NS.ADMINSUB })
|
||||
.c('subscribe', { node: Strophe.NS.C2SSTREAM }))
|
||||
connection.send($iq({ to: adminsubHost, type: 'set', id: connection.getUniqueId() }).c('adminsub', { xmlns: Strophe.NS.ADMINSUB })
|
||||
.c('subscribe', { node: Strophe.NS.S2SSTREAM }))
|
||||
connection.sendIQ($iq({ to: adminsubHost, type: 'get', id: connection.getUniqueId() }).c('adminsub', { xmlns: Strophe.NS.ADMINSUB })
|
||||
.c('items', { node: Strophe.NS.S2SSTREAM }), _cbNewS2S)
|
||||
connection.sendIQ($iq({ to: adminsubHost, type: 'get', id: connection.getUniqueId() }).c('adminsub', { xmlns: Strophe.NS.ADMINSUB })
|
||||
.c('items', { node: Strophe.NS.C2SSTREAM }), _cbNewC2S)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function showConnect () {
|
||||
$('#login').show()
|
||||
$('#menu').hide()
|
||||
$('#main').hide()
|
||||
$('#s2sin').empty()
|
||||
$('#s2sout').empty()
|
||||
$('#c2s').empty()
|
||||
$('#host').empty()
|
||||
}
|
||||
|
||||
function showDisconnect () {
|
||||
$('#s2sList').hide()
|
||||
$('#c2sList').hide()
|
||||
$('#login').hide()
|
||||
|
||||
$('#menu').show()
|
||||
$('#main').show()
|
||||
$('#adhoc').show()
|
||||
}
|
||||
|
||||
$(document).ready(function () {
|
||||
connection = new Strophe.Connection(BOSH_SERVICE)
|
||||
if (show_log) {
|
||||
$('#log_container').show()
|
||||
connection.rawInput = rawInput
|
||||
connection.rawOutput = rawOutput
|
||||
}
|
||||
|
||||
$('#log_toggle').click(function () {
|
||||
$('#log').toggle()
|
||||
})
|
||||
|
||||
$('#cred').on('submit', function (event) {
|
||||
let button = $('#connect').get(0)
|
||||
let jid = $('#jid')
|
||||
let pass = $('#pass')
|
||||
localJID = jid.get(0).value
|
||||
|
||||
$('#log').empty()
|
||||
connection.connect(localJID, pass.get(0).value, onConnect)
|
||||
event.preventDefault()
|
||||
})
|
||||
|
||||
$('#logout').click(function (event) {
|
||||
connection.disconnect()
|
||||
event.preventDefault()
|
||||
})
|
||||
|
||||
$('#adhocMenu, #serverMenu, #clientMenu').click(function (event) {
|
||||
event.preventDefault()
|
||||
let tab = $(this).attr('href')
|
||||
$('#main > div').hide()
|
||||
$(tab).fadeIn('fast')
|
||||
})
|
||||
|
||||
$('#host').on('change', function (event) {
|
||||
connection.send($iq({ to: adminsubHost, type: 'set', id: connection.getUniqueId() }).c('adminsub', { xmlns: Strophe.NS.ADMINSUB })
|
||||
.c('unsubscribe', { node: Strophe.NS.C2SSTREAM }))
|
||||
connection.send($iq({ to: adminsubHost, type: 'set', id: connection.getUniqueId() }).c('adminsub', { xmlns: Strophe.NS.ADMINSUB })
|
||||
.c('unsubscribe', { node: Strophe.NS.S2SSTREAM }))
|
||||
adminsubHost = $(this).val()
|
||||
adhocControl.checkFeatures(adminsubHost,
|
||||
function () {
|
||||
adhocControl.getCommandNodes(function (result) {
|
||||
$('#adhocDisplay').empty()
|
||||
$('#adhocCommands').html(result)
|
||||
})
|
||||
},
|
||||
function () {
|
||||
$('#adhocCommands').empty()
|
||||
$('#adhocDisplay').html('<p>This host does not support commands</p>')
|
||||
})
|
||||
$('#s2sin').empty()
|
||||
$('#s2sout').empty()
|
||||
$('#c2s').empty()
|
||||
connection.send($iq({ to: adminsubHost, type: 'set', id: connection.getUniqueId() }).c('adminsub', { xmlns: Strophe.NS.ADMINSUB })
|
||||
.c('subscribe', { node: Strophe.NS.C2SSTREAM }))
|
||||
connection.send($iq({ to: adminsubHost, type: 'set', id: connection.getUniqueId() }).c('adminsub', { xmlns: Strophe.NS.ADMINSUB })
|
||||
.c('subscribe', { node: Strophe.NS.S2SSTREAM }))
|
||||
connection.sendIQ($iq({ to: adminsubHost, type: 'get', id: connection.getUniqueId() }).c('adminsub', { xmlns: Strophe.NS.ADMINSUB })
|
||||
.c('items', { node: Strophe.NS.S2SSTREAM }), _cbNewS2S)
|
||||
connection.sendIQ($iq({ to: adminsubHost, type: 'get', id: connection.getUniqueId() }).c('adminsub', { xmlns: Strophe.NS.ADMINSUB })
|
||||
.c('items', { node: Strophe.NS.C2SSTREAM }), _cbNewC2S)
|
||||
})
|
||||
})
|
||||
|
||||
window.onunload = window.onbeforeunload = function () {
|
||||
if (connection) {
|
||||
connection.disconnect();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user