'use strict'; (function() { var weechat = angular.module('weechat'); var names = 'addresses proxy ipv6 ssl ssl_cert ssl_password ssl_priorities ssl_dhkey_size ssl_fingerprint ssl_verify password capabilities sasl_mechanism sasl_username sasl_password sasl_key sasl_timeout sasl_fail autoconnect autoreconnect autoreconnect_delay nicks nicks_alternate username realname local_hostname usermode command command_delay autojoin autojoin_dynamic autorejoin autorejoin_delay connection_timeout anti_flood_prio_high anti_flood_prio_low away_check away_check_max_nicks msg_kick msg_part msg_quit notify split_msg_max_length charset_message default_chantypes'.split(' '); var secrets = {ssl_password: true, password: true, sasl_password: true}; var booleans = {ipv6:true,ssl:true,ssl_verify:true,autoconnect:true,autoreconnect:true,nicks_alternate:true,autojoin_dynamic:true,autorejoin:true}; weechat.directive('neoServerManager', ['connection', function(connection) { return {restrict: 'E', templateUrl: 'directives/server-manager.html', link: function(scope) { scope.serverManager = {visible:false, loading:false, saving:false, servers:[], selected:null, isNew:false, status:''}; var manager = scope.serverManager; function validName(value) { return /^[A-Za-z0-9][A-Za-z0-9_-]{0,31}$/.test(value || ''); } function safeValue(value) { return typeof value === 'string' && !/[\r\n\0"]/.test(value); } function optionModel(name, row) { return {name:name, description:row&&row.description||'', value:row&&row.value_is_null?String(row.parent_value||''):String(row&&row.value||''), inherited:Boolean(row&&row.value_is_null), secret:Boolean(secrets[name]), boolean:Boolean(booleans[name]), dirty:false}; } function refresh() { manager.loading = true; return connection.requestInfolist('option', 0, 'irc.server.*.addresses').then(function(rows) { manager.servers = rows.map(function(row) { return row.full_name.slice(11, -10); }).filter(validName).sort(); manager.loading = false; }, function() { manager.loading=false; manager.status='Unable to load server settings.'; }); } function select(name) { manager.isNew = false; manager.loading = true; manager.status = ''; Promise.all(names.map(function(option) { if (secrets[option]) return Promise.resolve(optionModel(option, null)); return connection.requestInfolist('option', 0, 'irc.server.' + name + '.' + option).then(function(rows) { return optionModel(option, rows[0]); }); })).then(function(options) { scope.$applyAsync(function() { manager.selected={name:name, originalName:name, options:options}; manager.loading=false; }); }); } scope.newNeoServer = function() { manager.isNew=true; manager.selected={name:'',originalName:'',options:names.map(function(name){return optionModel(name,null);})}; manager.selected.options[0].inherited=false; manager.status=''; }; scope.selectNeoServer = select; scope.closeNeoServerManager = function() { manager.visible=false; manager.selected=null; }; scope.saveNeoServer = function(connectAfter) { var server=manager.selected; if(!server||!validName(server.name)){manager.status='Use a safe server name.';return;} var addresses=server.options[0].value; if(manager.isNew&&!safeValue(addresses)){manager.status='Enter a safe server address.';return;} manager.saving=true; if(manager.isNew) connection.sendCoreCommand('/server add '+server.name+' '+addresses); server.options.forEach(function(option) { if ((!manager.isNew&&!option.dirty)||(manager.isNew&&option.name==='addresses')||option.secret&&!option.value) return; if (!safeValue(option.value)){manager.status='Values cannot contain quotes or control characters.';return;} var full='irc.server.'+server.name+'.'+option.name; if (option.secret) { var secureKey='neobear_'+server.name.toLowerCase()+'_'+option.name; connection.sendCoreCommand('/secure set '+secureKey+' '+option.value); connection.sendCoreCommand('/set '+full+' "${sec.data.'+secureKey+'}"'); } else { connection.sendCoreCommand(option.inherited?'/unset '+full:'/set '+full+' "'+option.value+'"'); } }); connection.sendCoreCommand('/save irc'); if(connectAfter) connection.sendCoreCommand('/connect '+server.name); manager.status='Changes sent to WeeChat. Check the core buffer for any rejected setting.'; manager.saving=false; refresh(); }; scope.$on('neoServerManagerOpen', function(event, name) { manager.visible=true; refresh().then(function(){ if(name) select(name); else scope.$applyAsync(scope.newNeoServer); }); }); }}; }]); }());