You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

482 lines
20 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<html>
<link rel="stylesheet" type="text/css" href="../../lib/css/themes/jquery-ui/redmond/jquery-ui.min.css"/>
<script type="text/javascript" src="../../lib/js/jquery-1.11.1.min.js"></script>
<script type="text/javascript" src="../../socket.io/socket.io.js"></script>
<script type="text/javascript" src="../../lib/js/jquery-ui-1.10.3.full.min.js"></script>
<link rel="stylesheet" type="text/css" href="../../css/adapter.css"/>
<script type="text/javascript" src="../../js/translate.js"></script>
<script type="text/javascript" src="../../js/adapter-settings.js"></script>
<style>
#drop-zone {
width: calc(100% - 10px);
height: calc(100% - 10px);
position: absolute;
opacity: 0.8;
top: 0;
left: 0;
background: #eee;
-webkit-border-radius: 15px;
-moz-border-radius: 15px;
border-radius: 15px;
z-index: 1;
font-size: 32px;
font-weight: bold;
text-align: center;
border: 5px dashed darkgray;
}
.dropZone-error {
background: #faa !important;
color: #f00;
}
</style>
<script type="text/javascript">
var onChange;
systemDictionary = {
"OwnTracks adapter settings": {
"en": "OwnTracks adapter settings",
"de": "OwnTracks adapter settings",
"ru": "Настройки драйвера OwnTracks"
},
"Server settings": {"en": "Server settings", "de": "Server settings", "ru": "Настройки сервера settings"},
"User:": {"en": "User:", "de": "Anwender:", "ru": "Пользователь:"},
"Password:": {"en": "Password:", "de": "Kennwort:", "ru": "Пароль:"},
"Password repeat:": {"en": "Password repeat:", "de": "Kennwort-Wiederholung:", "ru": "Повтор пароля:"},
"Empty name not allowed!": {
"en": "Empty name not allowed!",
"de": "Ohne Namen ist nicht erlaubt!",
"ru": "Пустое имя пользователя не разрешено!"
},
"Ok": {"en": "Ok", "de": "Ok", "ru": "Ok"},
"IP:": {"de": "IP:", "ru": "IP:"},
"Port:": {"de": "Port:", "ru": "Порт:"},
"Secure(HTTPS):": {"de": "Verschlüsselung(HTTPS):", "ru": "Шифрование(HTTPS):"},
"Authentication:": {"de": "Authentifikation:", "ru": "Аутентификация:"},
"Listen on all IPs": {"en": "Listen on all IPs", "de": "An allen IP Adressen hören", "ru": "Открыть сокет на всех IP адресах"},
"help_tip": {
"en": "On save the adapter restarts with new configuration immediately",
"de": "Beim Speichern von Einstellungen der Adapter wird sofort neu gestartet.",
"ru": "Сразу после сохранения настроек драйвер перезапуститься с новыми значениями"
},
"Public certificate:": {"en": "Public certificate:", "de": "Publikzertifikat:", "ru": "'Public' сертификат:"},
"Private certificate:": {"en": "Private certificate:", "de": "Privatzertifikat:", "ru": "'Private' сертификат:"},
"Chained certificate:": {"en": "Chained certificate:", "de": "Kettenzertifikat:", "ru": "'Chained' сертификат:"},
"Let's Encrypt settings": {
"en": "Let's Encrypt settings",
"de": "Einstellungen Let's Encrypt",
"ru": "Настройкт Let's Encrypt"
},
"Use Lets Encrypt certificates:": {
"en": "Use Let's Encrypt certificates:",
"de": "Benutzen Let's Encrypt Zertifikate:",
"ru": "Использовать сертификаты Let's Encrypt:"
},
"Use this instance for automatic update:": {
"en": "Use this instance for automatic update:",
"de": "Benutze diese Instanz für automatische Updates:",
"ru": "Обновлять сертификаты в этом драйвере:"
},
"Port to check the domain:": {
"en": "Port to check the domain:",
"de": "Port um die Domain zu prüfen:",
"ru": "Порт для проверки доменного имени:"
},
"Drop the files here": {"en": "Drop the files here", "de": "Die Datei hier platzieren", "ru": "Перетащить файлы сюда"},
"Unknown file format!": {"en": "Unknown file format!", "de": "Unbekannter Dateiformat!", "ru": "Неизвестный формат файла"},
"Cannot read file!": {"en": "Cannot read file!", "de": "Kann die Datei nicht lesen!", "ru": "Невозможно прочитать файл!"},
"File is too big!": {"en": "File is too big!", "de": "Datei ist zu groß!", "ru": "Слишком большой файл!"}
};
function encrypt(key, value) {
var result = '';
for(var i = 0; i < value.length; i++) {
result += String.fromCharCode(key[i % key.length].charCodeAt(0) ^ value.charCodeAt(i));
}
return result;
}
function decrypt(key, value) {
var result = '';
for(var i = 0; i < value.length; i++) {
result += String.fromCharCode(key[i % key.length].charCodeAt(0) ^ value.charCodeAt(i));
}
return result;
}
function showHideSettings() {
if ($('#secure').prop('checked')) {
$('#_certPublic').show();
$('#_certPrivate').show();
$('#_certChained').show();
$('.le-settings').show();
if ($('#leEnabled').prop('checked')) {
$('.le-sub-settings').show();
if ($('#leUpdate').prop('checked')) {
$('.le-sub-settings-update').show();
} else {
$('.le-sub-settings-update').hide();
}
} else {
$('.le-sub-settings').hide();
}
} else {
$('#_certPublic').hide();
$('#_certPrivate').hide();
$('#_certChained').hide();
$('.le-settings').hide();
}
}
function fileHandler(event) {
event.preventDefault();
var file = event.dataTransfer ? event.dataTransfer.files[0] : event.target.files[0];
var $dz = $('#drop-zone');
if (file.size > 1000000) {
$('#drop-text').html(_('File is too big!'));
$dz.addClass('dropZone-error').animate({opacity: 0}, 1000, function () {
$dz.hide().removeClass('dropZone-error').css({opacity: 1});
showMessage(_('File is too big!'));
$('#drop-text').html(_('Drop the files here'));
});
return false;
}
$dz.show();
var reader = new FileReader();
reader.onload = function (evt) {
var text;
try {
text = evt.target.result; // string has form data:;base64,TEXT==
if ($('#drop-file').data('index') !== null) {
resizeImage(text, function (result) {
var pictures = getPictures();
pictures[$('#drop-file').data('index')].base64 = result;
onChange();
showPictures(pictures);
});
} else {
resizeImage(text, function (result) {
addPicture(null, result);
});
}
$dz.hide().removeClass('dropZone-error').css({opacity: 1});
} catch (err) {
console.error(err);
$('#drop-text').html(_('Cannot read file!'));
$dz.addClass('dropZone-error').animate({opacity: 0}, 1000, function () {
$dz.hide().removeClass('dropZone-error').css({opacity: 1});
showMessage(_('Cannot read file!'));
$('#drop-text').html(_('Drop the files here'));
});
}
};
reader.readAsDataURL(file);
}
function showPictureLine(pictures, i) {
var text = '<tr>';
text += '<td><input type="text" style="width: 100%" class="pictures-value" data-name="name" value="' + pictures[i].name + '" data-index="' + i +'"></td>';
text += '<td>' +
'<img width="64" src="' + pictures[i].base64 + '" class="pictures-value" data-name="base64" data-index="' + i +'" />' +
'<button class="pictures-upload" data-index="' + i +'"></td>';
text += '<td><button class="pictures-delete" data-index="' + i +'"></td>';
text += '</tr>';
return text;
}
function resizeImage(srcBase64, callback) {
var maxW = 64;
var maxH = 64;
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
var cw = canvas.width;
var ch = canvas.height;
var img = new Image;
img.onload = function() {
var iw = img.width;
var ih = img.height;
var scale = Math.min((maxW / iw), (maxH / ih));
var iwScaled = iw*scale;
var ihScaled = ih*scale;
canvas.width = iwScaled;
canvas.height = ihScaled;
ctx.drawImage(img,0,0,iwScaled,ihScaled);
callback(canvas.toDataURL());
};
try {
img.src = srcBase64;
} catch (e) {
callback(srcBase64);
}
}
function showPictures(pictures) {
var text = '';
for (var i = 0; i < pictures.length; i++) {
text += showPictureLine(pictures, i);
}
$('#pictures').html(text);
// init inputs and buttons
$('.pictures-value').change(function () {
onChange();
}).keyup(function () {
$(this).trigger('change');
});
$('.pictures-delete').button({
icons: {
primary: 'ui-icon-trash'
},
text: false
})
.css({width: 18, height: 18, float: 'right', 'margin-top': -5})
.attr('title', _('Delete picture and person'))
.click(function () {
// todo are you sure
var index = $(this).data('index');
var pictures = getPictures();
pictures.splice(index, 1);
showPictures(pictures);
});
$('.pictures-upload').button({
icons: {
primary: 'ui-icon-arrowthickstop-1-s'
},
text: false
})
.attr('title', _('Upload picture'))
.css({width: 18, height: 18, float: 'right', 'margin-top': 20})
.click(function () {
$('#drop-file').data('index', $(this).data('index'));
$('#drop-file').trigger('click');
});
}
function getPictures() {
var pictures = [];
$('.pictures-value').each(function () {
var index = $(this).data('index');
var name = $(this).data('name');
pictures[index] = pictures[index] || {};
if ($(this).prop('tagName') === 'IMG') {
pictures[index][name] = $(this).attr('src');
} else {
pictures[index][name] = $(this).val();
}
});
return pictures;
}
function addPicture(name, base64) {
var pictures = getPictures();
var id = 1;
if (!name) {
var found;
do {
found = false;
name = _('User') + ' ' + id;
for (var i = 0; i < pictures.length; i++) {
if (pictures[i].name === name) {
found = true;
id++
}
}
} while (found);
}
pictures.push({name: name, base64: base64 || ''});
onChange();
showPictures(pictures);
}
// the function loadSettings has to exist ...
function load(settings, _onChange) {
if (!settings) return;
onChange = _onChange;
$('#tabs').tabs({
activate: function (event, ui) {
if (ui.newPanel.selector == '#tabs-2') {
$('#drop-zone').show().css({opacity: 1}).animate({opacity: 0}, 2000, function () {
$('#drop-zone').hide().css({opacity: 1});
});
}
}
});
var $dropZone = $('#adapter-container');
if (typeof(window.FileReader) !== 'undefined' && !$dropZone.data('installed')) {
$dropZone.data('installed', true);
var $dz = $('#drop-zone');
$('#drop-text').html(_('Drop the files here'));
$dropZone[0].ondragover = function() {
$dz.unbind('click');
$dz.show();
return false;
};
$dz.click(function () {
$dz.hide();
});
$dz[0].ondragleave = function() {
$dz.hide();
return false;
};
$dz[0].ondrop = function (e) {
$('#drop-file').data('index', null);
fileHandler(e);
};
}
$('#drop-file').change(fileHandler);
// this functions are loaded from library
getIPs(function(ips) {
for (var i = 0; i < ips.length; i++) {
$('#bind').append('<option value="' + ips[i].address + '">' + ips[i].name + '</option>');
}
$('#bind.value').val(settings.bind);
});
$('.value').each(function () {
var key = $(this).attr('id');
if ($('#' + key + '.value').attr('type') === 'checkbox') {
$('#' + key + '.value').prop('checked', settings[key]).change(function() {
_onChange();
});
} else {
if (key === 'pass') settings[key] = decrypt('Zgfr56gFe87jJOM', settings[key]);
$('#' + key + '.value').val(settings[key]).change(function() {
_onChange();
}).keyup(function() {
_onChange();
});
}
});
settings.pictures = settings.pictures || [];
$('#passRepeat').val($('#pass').val());
// Signal to admin, that no changes yet
_onChange(false);
// this functions are loaded from library
fillSelectCertificates('#certPublic', 'public', settings.certPublic);
fillSelectCertificates('#certPrivate', 'private', settings.certPrivate);
fillSelectCertificates('#certChained', 'chained', settings.certChained);
fillUsers('#defaultUser', settings.defaultUser);
$('#secure').change(showHideSettings);
showPictures(settings.pictures);
$('#add').button({
icons: {
primary: 'ui-icon-plus'
},
text: false
})
.css({width: 18, height: 18, margin: 5})
.attr('title', _('Add picture for person'))
.click(function () {
addPicture();
});
showHideSettings();
}
function save(callback) {
var obj = {};
$('.value').each(function () {
var $this = $(this);
var key = $this.attr('id');
if ($this.attr('type') === 'checkbox') {
obj[key] = $this.prop('checked');
} else {
if (key === 'pass') {
obj[key] = encrypt('Zgfr56gFe87jJOM', $this.val());
} else {
obj[key] = $this.val()
}
}
});
if (!obj.user) {
showMessage(_('Empty name not allowed!'));
return;
}
obj.pictures = getPictures();
callback(obj);
}
</script>
<div id="adapter-container">
<table><tr>
<td><img src="owntracks.png"/></td>
<td><h3 class="translate">OwnTracks adapter settings</h3></td>
</tr></table>
<div id="tabs">
<ul>
<li><a href="#tabs-1" class="translate">General</a></li>
<li><a href="#tabs-2" class="translate">Pictures</a></li>
</ul>
<div id="tabs-1">
<table>
<tr><td colspan="2"><h4 class="translate">Server settings</h4></td></tr>
<tr><td><label class="translate" for="bind">IP:</label></td><td> <select class="value" id="bind"></select></td></tr>
<tr><td><label class="translate" for="port">Port:</label></td><td> <input class="value" id="port" size="5" maxlength="5"/></td></tr>
<tr><td><label class="translate" for="user">User:</label></td><td> <input class="value" id="user"/></td></tr>
<tr><td><label class="translate" for="pass">Password:</label></td><td> <input class="value" id="pass" type="password"/></td></tr>
<tr><td><label class="translate" for="passRepeat">Password repeat:</label></td><td><input id="passRepeat" type="password"/></td></tr>
<!--
<tr><td><label class="translate" for="secure">Secure(HTTPS):</label></td><td> <input class="value" id="secure" type="checkbox" /></td></tr>
<tr id="_certPublic">
<td><label class="translate" for="certPublic">Public certificate:</label></td>
<td><select id="certPublic" class="value"></select></td>
</tr>
<tr id="_certPrivate">
<td><label class="translate" for="certPrivate">Private certificate:</label></td>
<td><select id="certPrivate" class="value"></select></td>
</tr>
<tr id="_certChained">
<td><label class="translate" for="certChained">Chained certificate:</label></td>
<td><select id="certChained" class="value"></select></td>
</tr>
<tr><td colspan="2">&nbsp;</td></tr>
<tr class="le-settings"><td colspan="2"><h3 class="translate">Let's Encrypt settings</h3></tr>
<tr class="le-settings"><td><label for="leEnabled" class="translate">Use Lets Encrypt certificates:</label></td><td><input class="value" id="leEnabled" type="checkbox" /></td></tr>
<tr class="le-settings le-sub-settings"><td><label for="leUpdate" class="translate">Use this instance for automatic update:</label></td><td><input class="value" id="leUpdate" type="checkbox" /></td></tr>
<tr class="le-settings le-sub-settings le-sub-settings-update"><td><label for="lePort" class="translate">Port to check the domain:</label></td><td><input class="value number" id="lePort" type="number" size="5" maxlength="5" /></td></tr>
-->
</table>
</div>
<div id="tabs-2">
<div id="drop-zone" style="display: none"><div style="padding-top: 15%" class="translate" id="drop-text"></div>
<input type="file" id="drop-file" style="display: none">
</div>
<button id="add"></button>
<table style="width: 330px">
<thead>
<tr class="ui-widget-header">
<td class="translate" style="width: 200px">Name</td>
<td class="translate">Picture</td>
<td></td>
</tr>
</thead>
<tbody id="pictures"></tbody>
</table>
</div>
</div>
</div>
</html>