mirror of
https://github.com/key-networks/ztncui.git
synced 2024-08-31 04:28:00 +00:00
Some changes, including DNS support (#57)
* remove CDN
* Add a link to "members" in the network detail page
* Show object values as JSON
* remove TLS options
* Minor style improvements
* Show object values as JSON (member_detail)
* Add missing 'const'
* Navbar height fix
* Merge jQuery ready functions
* Change brand
* Merge network pages (name, members, detail) into single page and...
* Show ZT version on controller index page
* Show count of members
* Use <code> tag to display JSON data
* Fix error in some "error" pages caused by missing "navigate" when
rendering nav items, use pug mixin to render nav items.
* Adjust column widths of network list
* Refactor: move duplicated nav code to `head_layout`
* Remove some debug logging code
* Get network members detail parallelly
* Add missing frontend script for members
* Revert "Change brand"
* Remove "members" and "name" pages which are merged into "detail"
* Add DNS support
* Trivial changes (table width etc.)
* Don't try to read TLS cert files when not using HTTPS
* Validate DNS IP
* Downgrade jquery to 3.4.1 to fix nav bar collapse
* Revert "Navbar height fix"
This reverts commit 8edaa9aa81, which
break the nav item height on mobile.
* Add missing margin for some buttons
* Display current DNS configuration above inputs
* Change network rename UI/UX
* Includes 'jquery.min.js' in pkg
* Improve JSON value rendering
* Get peer status of network members
* Display members with peer status
* Show controller itself as "CONTROLLER"
* Display peer address
* Improve login redirection
* pr57: Doc updates; version bump
* pr57: Year update
Co-authored-by: Key Networks <34238649+key-networks@users.noreply.github.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
ztncui - ZeroTier network controller UI
|
||||
Copyright (C) 2017-2018 Key Networks (https://key-networks.com)
|
||||
Copyright (C) 2017-2021 Key Networks (https://key-networks.com)
|
||||
Licensed under GPLv3 - see LICENSE for details.
|
||||
*/
|
||||
|
||||
|
||||
10
src/bin/www
10
src/bin/www
@@ -10,11 +10,6 @@ const http = require('http');
|
||||
const https = require('https');
|
||||
const fs = require('fs');
|
||||
|
||||
const options = {
|
||||
cert: fs.readFileSync('etc/tls/fullchain.pem'),
|
||||
key: fs.readFileSync('etc/tls/privkey.pem')
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ports from environment and store in Express.
|
||||
*/
|
||||
@@ -50,6 +45,11 @@ if (http_all_interfaces) {
|
||||
app.listen(http_port, 'localhost');
|
||||
}
|
||||
|
||||
const options = !https_port ? {} : {
|
||||
cert: fs.readFileSync('etc/tls/fullchain.pem'),
|
||||
key: fs.readFileSync('etc/tls/privkey.pem')
|
||||
};
|
||||
|
||||
const server = https.createServer(options, app);
|
||||
|
||||
if (https_port) {
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
/*
|
||||
ztncui - ZeroTier network controller UI
|
||||
Copyright (C) 2017-2018 Key Networks (https://key-networks.com)
|
||||
Copyright (C) 2017-2021 Key Networks (https://key-networks.com)
|
||||
Licensed under GPLv3 - see LICENSE for details.
|
||||
*/
|
||||
|
||||
const argon2 = require('argon2');
|
||||
const usersController = require('../controllers/usersController');
|
||||
|
||||
hash_check = async function(user, password) {
|
||||
const hash_check = async function(user, password) {
|
||||
let verified = false;
|
||||
try {
|
||||
var users = await usersController.get_users();
|
||||
@@ -43,6 +43,6 @@ exports.restrict = function(req, res, next) {
|
||||
next();
|
||||
} else {
|
||||
req.session.error = 'Access denied!';
|
||||
res.redirect('/login');
|
||||
res.redirect('/login?redirect=' + encodeURIComponent(req.originalUrl));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
ztncui - ZeroTier network controller UI
|
||||
Copyright (C) 2017-2018 Key Networks (https://key-networks.com)
|
||||
Copyright (C) 2017-2021 Key Networks (https://key-networks.com)
|
||||
Licensed under GPLv3 - see LICENSE for details.
|
||||
*/
|
||||
|
||||
@@ -12,6 +12,42 @@ const util = require('util');
|
||||
|
||||
storage.initSync({dir: 'etc/storage'});
|
||||
|
||||
async function get_network_with_members(nwid) {
|
||||
const [network, peers, members] = await Promise.all([
|
||||
zt.network_detail(nwid),
|
||||
zt.peers(),
|
||||
zt.members(nwid)
|
||||
.then(member_ids =>
|
||||
Promise.all(
|
||||
Object.keys(member_ids)
|
||||
.map(id => Promise.all([
|
||||
zt.member_detail(nwid, id),
|
||||
storage.getItem(id)
|
||||
]))
|
||||
)
|
||||
).then(results => results.map(([member, name]) => {
|
||||
member.name = name || '';
|
||||
return member;
|
||||
}))
|
||||
]);
|
||||
for (const member of members) {
|
||||
member.peer = peers.find(x => x.address === member.address);
|
||||
}
|
||||
return {network, members};
|
||||
}
|
||||
|
||||
async function get_network_member(nwid, memberid) {
|
||||
const [network, member, peer, name] = await Promise.all([
|
||||
zt.network_detail(nwid),
|
||||
zt.member_detail(nwid, memberid),
|
||||
zt.peer(memberid),
|
||||
storage.getItem(memberid)
|
||||
]);
|
||||
member.name = name || '';
|
||||
member.peer = peer;
|
||||
return {network, member};
|
||||
}
|
||||
|
||||
// ZT network controller home page
|
||||
exports.index = async function(req, res) {
|
||||
const navigate =
|
||||
@@ -20,11 +56,11 @@ exports.index = async function(req, res) {
|
||||
}
|
||||
|
||||
try {
|
||||
zt_address = await zt.get_zt_address();
|
||||
res.render('index', {title: 'ztncui', navigate: navigate, zt_address: zt_address});
|
||||
const zt_status = await zt.get_zt_status();
|
||||
res.render('index', {title: 'ztncui', navigate: navigate, zt_status});
|
||||
} catch (err) {
|
||||
res.render('index', {title: 'ztncui',
|
||||
navigate: navigate, error: 'ERROR resolving ZT address: ' + err});
|
||||
navigate: navigate, error: 'ERROR getting ZT status: ' + err});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -51,13 +87,15 @@ exports.network_detail = async function(req, res) {
|
||||
whence: '/controller/networks'
|
||||
}
|
||||
|
||||
console.log('NAVIGATE = ' + navigate.toString());
|
||||
console.log(util.inspect(navigate, false, null, true /* enable colors */))
|
||||
|
||||
try {
|
||||
const network = await zt.network_detail(req.params.nwid);
|
||||
const members = await zt.members(req.params.nwid);
|
||||
res.render('network_detail', {title: 'Detail for network', navigate: navigate, network: network, members: members});
|
||||
const [
|
||||
{network, members},
|
||||
zt_address
|
||||
] = await Promise.all([
|
||||
get_network_with_members(req.params.nwid),
|
||||
zt.get_zt_address()
|
||||
]);
|
||||
res.render('network_detail', {title: 'Network ' + network.name, navigate: navigate, network: network, members: members, zt_address: zt_address});
|
||||
} catch (err) {
|
||||
res.render('network_detail', {title: 'Detail for network', navigate: navigate, error: 'Error resolving detail for network ' + req.params.nwid + ': ' + err});
|
||||
}
|
||||
@@ -95,7 +133,7 @@ exports.network_create_post = async function(req, res) {
|
||||
} else {
|
||||
try {
|
||||
const network = await zt.network_create(name);
|
||||
res.redirect('/controller/networks');
|
||||
res.redirect('/controller/network/' + network.nwid);
|
||||
} catch (err) {
|
||||
res.render('network_detail', {title: 'Create Network - error', navigate: navigate, error: 'Error creating network ' + name.name});
|
||||
}
|
||||
@@ -177,21 +215,15 @@ exports.name = async function(req, res) {
|
||||
let name = { name: req.body.name };
|
||||
|
||||
if (errors) {
|
||||
try {
|
||||
const network = await zt.network_detail(req.params.nwid);
|
||||
res.render('name', {title: 'Rename network', navigate: navigate, network: network, name: name, errors: errors});
|
||||
} catch (err) {
|
||||
res.render('name', {title: 'Rename network', navigate: navigate, error: 'Error resolving network detail for network ' + req.params.nwid + ': ' + err});
|
||||
}
|
||||
console.error("network name validation errors", errors);
|
||||
} else {
|
||||
try {
|
||||
const network = await zt.network_object(req.params.nwid, name);
|
||||
res.redirect('/controller/networks');
|
||||
} catch ( err) {
|
||||
res.render('name', {title: 'Rename network', navigate: navigate, error: 'Error renaming network ' + req.params.nwid + ': ' + err});
|
||||
console.error("Error renaming network " + req.params.nwid, err);
|
||||
}
|
||||
}
|
||||
|
||||
res.redirect('/controller/network/' + req.params.nwid);
|
||||
};
|
||||
|
||||
// ipAssignmentPools POST
|
||||
@@ -425,6 +457,35 @@ exports.v6AssignMode = async function (req, res) {
|
||||
}
|
||||
}
|
||||
|
||||
// dns POST
|
||||
exports.dns = async function (req, res) {
|
||||
const navigate = {
|
||||
active: 'networks',
|
||||
whence: ''
|
||||
};
|
||||
|
||||
const dns = {
|
||||
dns: {
|
||||
domain: req.body.domain,
|
||||
servers: req.body.servers
|
||||
.split('\n')
|
||||
.map(x => x.trim())
|
||||
.filter(ip =>
|
||||
new ipaddr.Address4(ip).isValid() ||
|
||||
new ipaddr.Address6(ip).isValid()
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
const network = await zt.network_object(req.params.nwid, dns);
|
||||
navigate.whence = '/controller/network/' + network.nwid;
|
||||
res.render('dns', {title: 'dns', navigate: navigate, network: network});
|
||||
} catch (err) {
|
||||
res.render('dns', {title: 'dns', navigate: navigate, error: 'Error updating dns for network ' + req.params.nwid + ': ' + err});
|
||||
}
|
||||
}
|
||||
|
||||
// Display detail page for specific member
|
||||
exports.member_detail = async function(req, res) {
|
||||
const navigate =
|
||||
@@ -434,15 +495,12 @@ exports.member_detail = async function(req, res) {
|
||||
}
|
||||
|
||||
try {
|
||||
const network = await zt.network_detail(req.params.nwid);
|
||||
const member = await zt.member_detail(req.params.nwid, req.params.id);
|
||||
let name = await storage.getItem(member.id);
|
||||
if (!name) name = '';
|
||||
member.name = name;
|
||||
navigate.whence = '/controller/network/' + network.nwid + '/members';
|
||||
const {network, member} = await get_network_member(req.params.nwid, req.params.id);
|
||||
navigate.whence = '/controller/network/' + network.nwid + '#members';
|
||||
res.render('member_detail', {title: 'Network member detail', navigate: navigate, network: network, member: member});
|
||||
} catch (err) {
|
||||
res.render(req.params.object, {title: req.params.object, navigate: navigate, error: 'Error resolving detail for member ' + req.params.id + ' of network ' + req.params.nwid + ': ' + err});
|
||||
console.error(err);
|
||||
res.render('error', {title: req.params.object, navigate: navigate, error: 'Error resolving detail for member ' + req.params.id + ' of network ' + req.params.nwid + ': ' + err});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -455,12 +513,8 @@ exports.member_object = async function(req, res) {
|
||||
}
|
||||
|
||||
try {
|
||||
const network = await zt.network_detail(req.params.nwid);
|
||||
const member = await zt.member_detail(req.params.nwid, req.params.id);
|
||||
let name = await storage.getItem(member.id);
|
||||
if (!name) name = '';
|
||||
member.name = name;
|
||||
navigate.whence = '/controller/network/' + network.nwid + '/members';
|
||||
const {network, member} = await get_network_member(req.params.nwid, req.params.id);
|
||||
navigate.whence = '/controller/network/' + network.nwid + '#members';
|
||||
res.render(req.params.object, {title: req.params.object, navigate: navigate, network: network, member: member}, function(err, html) {
|
||||
if (err) {
|
||||
if (err.message.indexOf('Failed to lookup view') !== -1 ) {
|
||||
@@ -480,7 +534,7 @@ exports.easy_get = async function(req, res) {
|
||||
const navigate =
|
||||
{
|
||||
active: 'networks',
|
||||
whence: '/controller/networks'
|
||||
whence: '/controller/network/' + req.params.nwid
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -561,7 +615,7 @@ exports.easy_post = async function(req, res) {
|
||||
}
|
||||
}
|
||||
|
||||
// Easy members auth GET or POST
|
||||
// Easy members auth POST
|
||||
exports.members = async function(req, res) {
|
||||
const navigate =
|
||||
{
|
||||
@@ -630,26 +684,6 @@ exports.members = async function(req, res) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const network = await zt.network_detail(req.params.nwid);
|
||||
const member_ids = await zt.members(req.params.nwid);
|
||||
const members = [];
|
||||
for (id in member_ids) {
|
||||
let member = await zt.member_detail(req.params.nwid, id);
|
||||
let name = await storage.getItem(member.id);
|
||||
if (!name) name = '';
|
||||
member.name = name;
|
||||
members.push(member);
|
||||
}
|
||||
|
||||
res.render('members', {title: 'Members of this network', navigate: navigate,
|
||||
network: network, members: members, errors: errors});
|
||||
} catch (err) {
|
||||
res.render('members', {title: 'Members of this network', navigate: navigate,
|
||||
error: 'Error resolving detail for network ' + req.params.nwid
|
||||
+ ': ' + err});
|
||||
}
|
||||
}
|
||||
|
||||
// Member delete GET or POST
|
||||
@@ -673,10 +707,9 @@ exports.member_delete = async function(req, res) {
|
||||
member = await zt.member_detail(req.params.nwid, req.params.id);
|
||||
name = await storage.getItem(member.id);
|
||||
}
|
||||
if (!name) name = '';
|
||||
member.name = name;
|
||||
member.name = name || '';
|
||||
|
||||
navigate.whence = '/controller/network/' + network.nwid + '/members';
|
||||
navigate.whence = '/controller/network/' + network.nwid;
|
||||
res.render('member_delete', {title: 'Delete member from ' + network.name,
|
||||
navigate: navigate, network: network, member: member});
|
||||
} catch (err) {
|
||||
@@ -697,10 +730,8 @@ exports.delete_ip = async function(req, res) {
|
||||
try {
|
||||
const network = await zt.network_detail(req.params.nwid);
|
||||
let member = await zt.member_detail(req.params.nwid, req.params.id);
|
||||
navigate.whence = '/controller/network/' + network.nwid + '/members';
|
||||
let name = await storage.getItem(member.id);
|
||||
if (!name) name = '';
|
||||
member.name = name;
|
||||
navigate.whence = '/controller/network/' + network.nwid;
|
||||
member.name = await storage.getItem(member.id) | '';
|
||||
if (req.params.index) {
|
||||
member = await zt.ipAssignmentDelete(network.nwid, member.id,
|
||||
req.params.index);
|
||||
@@ -758,15 +789,13 @@ exports.assign_ip = async function(req, res) {
|
||||
|
||||
try {
|
||||
let member = await zt.member_detail(req.params.nwid, req.params.id);
|
||||
navigate.whence = '/controller/network/' + network.nwid + '/members';
|
||||
navigate.whence = '/controller/network/' + network.nwid;
|
||||
|
||||
if (!errors) {
|
||||
member = await zt.ipAssignmentAdd(network.nwid, member.id, ipAssignment);
|
||||
}
|
||||
|
||||
let name = await storage.getItem(member.id);
|
||||
if (!name) name = '';
|
||||
member.name = name;
|
||||
member.name = await storage.getItem(member.id) | '';
|
||||
|
||||
res.render('ipAssignments', {title: 'ipAssignments', navigate: navigate,
|
||||
ipAssignment: ipAssignment, network: network, member: member,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
ztncui - ZeroTier network controller UI
|
||||
Copyright (C) 2017-2018 Key Networks (https://key-networks.com)
|
||||
Copyright (C) 2017-2021 Key Networks (https://key-networks.com)
|
||||
Licensed under GPLv3 - see LICENSE for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
ztncui - ZeroTier network controller UI
|
||||
Copyright (C) 2017-2018 Key Networks (https://key-networks.com)
|
||||
Copyright (C) 2017-2021 Key Networks (https://key-networks.com)
|
||||
Licensed under GPLv3 - see LICENSE for details.
|
||||
*/
|
||||
|
||||
@@ -17,7 +17,7 @@ const chmod = util.promisify(fs.chmod);
|
||||
|
||||
let _users = null;
|
||||
|
||||
get_users = async function() {
|
||||
const get_users = async function() {
|
||||
if (_users) {
|
||||
return _users;
|
||||
} else {
|
||||
@@ -31,7 +31,7 @@ get_users = async function() {
|
||||
}
|
||||
exports.get_users = get_users;
|
||||
|
||||
update_users = async function(users) {
|
||||
const update_users = async function(users) {
|
||||
try {
|
||||
await writeFile(passwd_file, JSON.stringify(users), 'utf8');
|
||||
await chmod(passwd_file, 0600);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
ztncui - ZeroTier network controller UI
|
||||
Copyright (C) 2017-2018 Key Networks (https://key-networks.com)
|
||||
Copyright (C) 2017-2021 Key Networks (https://key-networks.com)
|
||||
Licensed under GPLv3 - see LICENSE for details.
|
||||
*/
|
||||
|
||||
@@ -8,9 +8,9 @@ const got = require('got');
|
||||
const ipaddr = require('ip-address');
|
||||
const token = require('./token');
|
||||
|
||||
ZT_ADDR = process.env.ZT_ADDR || 'localhost:9993';
|
||||
const ZT_ADDR = process.env.ZT_ADDR || 'localhost:9993';
|
||||
|
||||
init_options = async function() {
|
||||
const init_options = async function() {
|
||||
let tok = null;
|
||||
|
||||
try {
|
||||
@@ -29,16 +29,21 @@ init_options = async function() {
|
||||
return options;
|
||||
}
|
||||
|
||||
get_zt_address = async function() {
|
||||
const get_zt_status = async function() {
|
||||
const options = await init_options();
|
||||
|
||||
try {
|
||||
const response = await got(ZT_ADDR + '/status', options);
|
||||
return response.body.address;
|
||||
return response.body;
|
||||
} catch(err) {
|
||||
throw(err);
|
||||
}
|
||||
}
|
||||
exports.get_zt_status = get_zt_status;
|
||||
|
||||
const get_zt_address = async function() {
|
||||
return (await get_zt_status()).address;
|
||||
}
|
||||
exports.get_zt_address = get_zt_address;
|
||||
|
||||
exports.network_list = async function() {
|
||||
@@ -68,7 +73,7 @@ exports.network_list = async function() {
|
||||
return networks;
|
||||
}
|
||||
|
||||
network_detail = async function(nwid) {
|
||||
const network_detail = async function(nwid) {
|
||||
const options = await init_options();
|
||||
|
||||
try {
|
||||
@@ -241,7 +246,7 @@ exports.members = async function(nwid) {
|
||||
}
|
||||
}
|
||||
|
||||
member_detail = async function(nwid, id) {
|
||||
const member_detail = async function(nwid, id) {
|
||||
const options = await init_options();
|
||||
|
||||
try {
|
||||
@@ -303,3 +308,22 @@ exports.network_easy_setup = async function(nwid,
|
||||
throw(err);
|
||||
}
|
||||
}
|
||||
|
||||
exports.peers = async function() {
|
||||
const options = await init_options();
|
||||
const response = await got(ZT_ADDR + '/peer', options);
|
||||
return response.body;
|
||||
}
|
||||
|
||||
exports.peer = async function(id) {
|
||||
const options = await init_options();
|
||||
try {
|
||||
const response = await got(ZT_ADDR + '/peer/' + id, options);
|
||||
return response.body;
|
||||
} catch (error) {
|
||||
if (error instanceof got.HTTPError && error.statusCode == 404) {
|
||||
return null;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ztncui",
|
||||
"version": "0.6.6",
|
||||
"version": "0.7.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"start": "node ./bin/www",
|
||||
@@ -19,7 +19,7 @@
|
||||
"got": "^7.1.0",
|
||||
"helmet": "^3.23.0",
|
||||
"ip-address": "^5.8.9",
|
||||
"jquery": "^3.5.1",
|
||||
"jquery": "~3.4.1",
|
||||
"morgan": "~1.9.1",
|
||||
"node-persist": "^2.1.0",
|
||||
"pug": "^2.0.4",
|
||||
@@ -32,7 +32,8 @@
|
||||
"assets": [
|
||||
"views/*",
|
||||
"public/**/*",
|
||||
"etc/**/*"
|
||||
"etc/**/*",
|
||||
"node_modules/jquery/dist/jquery.min.js"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
html, body {
|
||||
height: 100%;
|
||||
font: 16px "Lucida Grande", Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
ztncui - ZeroTier network controller UI
|
||||
Copyright (C) 2017-2018 Key Networks (https://key-networks.com)
|
||||
Copyright (C) 2017-2021 Key Networks (https://key-networks.com)
|
||||
Licensed under GPLv3 - see LICENSE for details.
|
||||
*/
|
||||
|
||||
@@ -10,8 +10,17 @@ const authenticate = auth.authenticate;
|
||||
const restrict = auth.restrict;
|
||||
const router = express.Router();
|
||||
|
||||
/** Redirect logged user to controler page */
|
||||
function guest_only(req, res, next) {
|
||||
if (req.session.user) {
|
||||
res.redirect('/controller');
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
}
|
||||
|
||||
/* GET home page. */
|
||||
router.get('/', function(req, res, next) {
|
||||
router.get('/', guest_only, function(req, res, next) {
|
||||
res.render('front_door', {title: 'ztncui'});
|
||||
});
|
||||
|
||||
@@ -21,7 +30,7 @@ router.get('/logout', function(req, res) {
|
||||
});
|
||||
});
|
||||
|
||||
router.get('/login', function(req, res) {
|
||||
router.get('/login', guest_only, function(req, res) {
|
||||
let message = null;
|
||||
if (req.session.error) {
|
||||
if (req.session.error !== 'Access denied!') {
|
||||
@@ -40,7 +49,7 @@ router.post('/login', async function(req, res) {
|
||||
req.session.user = user;
|
||||
req.session.success = 'Authenticated as ' + user.name;
|
||||
if (user.pass_set) {
|
||||
res.redirect('/controller');
|
||||
res.redirect(req.query.redirect || '/controller');
|
||||
} else {
|
||||
res.redirect('/users/' + user.name + '/password');
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
ztncui - ZeroTier network controller UI
|
||||
Copyright (C) 2017-2018 Key Networks (https://key-networks.com)
|
||||
Copyright (C) 2017-2021 Key Networks (https://key-networks.com)
|
||||
Licensed under GPLv3 - see LICENSE for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
ztncui - ZeroTier network controller UI
|
||||
Copyright (C) 2017-2018 Key Networks (https://key-networks.com)
|
||||
Copyright (C) 2017-2021 Key Networks (https://key-networks.com)
|
||||
Licensed under GPLv3 - see LICENSE for details.
|
||||
*/
|
||||
|
||||
@@ -43,6 +43,9 @@ router.get('/network/:nwid/routes/:target_ip/:target_prefix/delete', restrict, n
|
||||
// POST request for routes
|
||||
router.post('/network/:nwid/routes', restrict, networkController.routes);
|
||||
|
||||
// POST request for dns
|
||||
router.post('/network/:nwid/dns', restrict, networkController.dns);
|
||||
|
||||
// POST request for private
|
||||
router.post('/network/:nwid/private', restrict, networkController.private);
|
||||
|
||||
|
||||
@@ -1,38 +1,18 @@
|
||||
//-
|
||||
ztncui - ZeroTier network controller UI
|
||||
Copyright (C) 2017-2018 Key Networks (https://key-networks.com)
|
||||
Copyright (C) 2017-2021 Key Networks (https://key-networks.com)
|
||||
Licensed under GPLv3 - see LICENSE for details.
|
||||
|
||||
extends head_layout
|
||||
|
||||
block body_content
|
||||
nav.navbar.navbar-inverse.navbar-fixed-top
|
||||
.container-fluid
|
||||
.navbar-header
|
||||
button.navbar-toggle(type='button' data-toggle='collapse' data-target='#BarNav')
|
||||
span.icon-bar
|
||||
span.icon-bar
|
||||
span.icon-bar
|
||||
a.navbar-brand(href='https://key-networks.com' target='_blank')
|
||||
img(src='/images/key-logo.svg' alt='Key Networks logo' height='25px' width='25px' style='display: inline')
|
||||
| Key Networks
|
||||
.collapse.navbar-collapse(id='BarNav')
|
||||
ul.nav.navbar-nav
|
||||
li(class=(navigate.active === 'controller_home'? 'active' : ''))
|
||||
a(href='/controller') Home
|
||||
li(class=(navigate.active === 'users'? 'active' : ''))
|
||||
a(href='/users') Users
|
||||
li(class=(navigate.active === 'networks'? 'active' : ''))
|
||||
a(href='/controller/networks') Networks
|
||||
li(class=(navigate.active === 'add_network'? 'active' : ''))
|
||||
a(href='/controller/network/create') Add network
|
||||
ul.nav.navbar-nav.navbar-right
|
||||
li
|
||||
a(href='/logout')
|
||||
span.glyphicon.glyphicon-log-out
|
||||
| Logout
|
||||
block nav_items
|
||||
+nav_item('controller_home', 'Home', '/controller')
|
||||
+nav_item('users', 'Users', '/users')
|
||||
+nav_item('networks', 'Networks', '/controller/networks')
|
||||
+nav_item('add_network', 'Add network', '/controller/network/create')
|
||||
|
||||
.container(style='margin-top:50px')
|
||||
block body_content
|
||||
.container(style='margin: 50px auto 20px')
|
||||
.row
|
||||
.col-sm-12
|
||||
block content
|
||||
|
||||
57
src/views/dns.pug
Normal file
57
src/views/dns.pug
Normal file
@@ -0,0 +1,57 @@
|
||||
//-
|
||||
ztncui - ZeroTier network controller UI
|
||||
Copyright (C) 2017-2021 Key Networks (https://key-networks.com)
|
||||
Licensed under GPLv3 - see LICENSE for details.
|
||||
|
||||
extends network_layout
|
||||
|
||||
block net_content
|
||||
- const dns = network.dns || {};
|
||||
if (!dns.domain && !(dns.servers && dns.servers.length > 0))
|
||||
.row
|
||||
.col-sm-12
|
||||
b No DNS configuration on this network.
|
||||
else
|
||||
.row
|
||||
.col-sm-2
|
||||
b Domain:
|
||||
.col-sm-10
|
||||
p= dns.domain
|
||||
.row
|
||||
.col-sm-2
|
||||
b Servers:
|
||||
.col-sm-10
|
||||
.row
|
||||
each server in dns.servers
|
||||
.col-sm-12= server
|
||||
|
||||
.row
|
||||
.col-sm-12
|
||||
h3 Change DNS configuration:
|
||||
|
||||
form(method='POST' action='')
|
||||
.form-group.row
|
||||
.col-sm-12
|
||||
label(for='domain') Domain:
|
||||
.col-sm-12
|
||||
input#domain.form-control(type='text' name='domain' value=dns.domain)
|
||||
|
||||
.form-group.row
|
||||
.col-sm-12
|
||||
label(for='servers') Servers:
|
||||
.col-sm-12
|
||||
textarea#servers.form-control(type='text' name='servers' placeholder='(one IP address per line)')
|
||||
= !dns.servers ? '' : dns.servers.join('\n')
|
||||
|
||||
.form-group.row
|
||||
.col-sm-12
|
||||
button.btn.btn-primary(type='submit') Submit
|
||||
= ' '
|
||||
a.btn.btn-default(href=('/controller/network/' + network.nwid) name='cancel' role='button') Cancel
|
||||
|
||||
if errors
|
||||
.row
|
||||
.col-sm-12
|
||||
ul
|
||||
for err in errors
|
||||
li!= err.msg
|
||||
@@ -1,6 +1,6 @@
|
||||
//-
|
||||
ztncui - ZeroTier network controller UI
|
||||
Copyright (C) 2017-2018 Key Networks (https://key-networks.com)
|
||||
Copyright (C) 2017-2021 Key Networks (https://key-networks.com)
|
||||
Licensed under GPLv3 - see LICENSE for details.
|
||||
|
||||
extends login_layout
|
||||
|
||||
@@ -1,8 +1,18 @@
|
||||
//-
|
||||
ztncui - ZeroTier network controller UI
|
||||
Copyright (C) 2017-2018 Key Networks (https://key-networks.com)
|
||||
Copyright (C) 2017-2021 Key Networks (https://key-networks.com)
|
||||
Licensed under GPLv3 - see LICENSE for details.
|
||||
|
||||
mixin nav_item(name, displayName, href)
|
||||
li(class=((navigate && navigate.active === name) ? 'active' : ''))
|
||||
a(href=href) #{displayName}
|
||||
|
||||
mixin json_value(value)
|
||||
- if ((!!value ) && (value.constructor == Object || value.constructor == Array))
|
||||
code(style='white-space: pre;')= JSON.stringify(value, null, 2)
|
||||
- else
|
||||
code= value
|
||||
|
||||
doctype html
|
||||
html(lang='en')
|
||||
head
|
||||
@@ -11,7 +21,26 @@ html(lang='en')
|
||||
meta(name='viewport', content='width=device-width, initial-scale=1')
|
||||
link(rel='stylesheet', href='/bscss/bootstrap.min.css')
|
||||
link(rel='stylesheet', href='/stylesheets/style.css')
|
||||
script(src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js')
|
||||
script(src='/jqjs/jquery.min.js')
|
||||
script(src='/bsjs/bootstrap.min.js')
|
||||
body
|
||||
nav.navbar.navbar-inverse.navbar-fixed-top
|
||||
.container-fluid
|
||||
.navbar-header
|
||||
button.navbar-toggle(type='button' data-toggle='collapse' data-target='#BarNav')
|
||||
span.icon-bar
|
||||
span.icon-bar
|
||||
span.icon-bar
|
||||
a.navbar-brand(href='https://key-networks.com' target='_blank')
|
||||
img(src='/images/key-logo.svg' alt='Key Networks logo' height='25px' width='25px' style='display: inline')
|
||||
| Key Networks
|
||||
.collapse.navbar-collapse(id='BarNav')
|
||||
ul.nav.navbar-nav
|
||||
block nav_items
|
||||
ul.nav.navbar-nav.navbar-right
|
||||
li
|
||||
block nav_login
|
||||
a(href='/logout')
|
||||
span.glyphicon.glyphicon-log-out
|
||||
| Logout
|
||||
block body_content
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//-
|
||||
ztncui - ZeroTier network controller UI
|
||||
Copyright (C) 2017-2018 Key Networks (https://key-networks.com)
|
||||
Copyright (C) 2017-2021 Key Networks (https://key-networks.com)
|
||||
Licensed under GPLv3 - see LICENSE for details.
|
||||
|
||||
extends controller_layout
|
||||
@@ -10,14 +10,13 @@ block content
|
||||
|
||||
h2
|
||||
a(href='https://zerotier.com' target='_blank') ZeroTier
|
||||
| network controller UI
|
||||
|
||||
h3 Network controller details
|
||||
| network controller UI by
|
||||
a(href='https://key-networks.com' target='_blank') Key Networks
|
||||
|
||||
if error
|
||||
b #{error}
|
||||
else
|
||||
h4 This network controller has a ZeroTier address of <b>#{zt_address}</b>
|
||||
|
||||
h4 This network controller has a ZeroTier address of <b>#{zt_status.address}</b>
|
||||
h4 ZeroTier version <b>#{zt_status.version}</b>
|
||||
h4
|
||||
a(href='/controller/networks') List all networks on this network controller
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//-
|
||||
ztncui - ZeroTier network controller UI
|
||||
Copyright (C) 2017-2018 Key Networks (https://key-networks.com)
|
||||
Copyright (C) 2017-2021 Key Networks (https://key-networks.com)
|
||||
Licensed under GPLv3 - see LICENSE for details.
|
||||
|
||||
extends network_layout
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//-
|
||||
ztncui - ZeroTier network controller UI
|
||||
Copyright (C) 2017-2018 Key Networks (https://key-networks.com)
|
||||
Copyright (C) 2017-2021 Key Networks (https://key-networks.com)
|
||||
Licensed under GPLv3 - see LICENSE for details.
|
||||
|
||||
extends network_layout
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//-
|
||||
ztncui - ZeroTier network controller UI
|
||||
Copyright (C) 2017-2018 Key Networks (https://key-networks.com)
|
||||
Copyright (C) 2017-2021 Key Networks (https://key-networks.com)
|
||||
Licensed under GPLv3 - see LICENSE for details.
|
||||
|
||||
extends login_layout
|
||||
|
||||
@@ -1,28 +1,16 @@
|
||||
//-
|
||||
ztncui - ZeroTier network controller UI
|
||||
Copyright (C) 2017-2018 Key Networks (https://key-networks.com)
|
||||
Copyright (C) 2017-2021 Key Networks (https://key-networks.com)
|
||||
Licensed under GPLv3 - see LICENSE for details.
|
||||
|
||||
extends head_layout
|
||||
|
||||
block body_content
|
||||
nav.navbar.navbar-inverse.navbar-fixed-top
|
||||
.container-fluid
|
||||
.navbar-header
|
||||
button.navbar-toggle(type='button' data-toggle='collapse' data-target='#BarNav')
|
||||
span.icon-bar
|
||||
span.icon-bar
|
||||
span.icon-bar
|
||||
a.navbar-brand(href='https://key-networks.com' target='_blank')
|
||||
img(src='/images/key-logo.svg' alt='Key Networks logo' height='25px' width='25px' style='display: inline')
|
||||
| Key Networks
|
||||
.collapse.navbar-collapse(id='BarNav')
|
||||
ul.nav.navbar-nav.navbar-right
|
||||
li
|
||||
a(href='/login')
|
||||
span.glyphicon.glyphicon-log-in
|
||||
| Login
|
||||
block nav_login
|
||||
a(href='/login')
|
||||
span.glyphicon.glyphicon-log-in
|
||||
| Login
|
||||
|
||||
block body_content
|
||||
.container(style='margin-top:50px')
|
||||
.row
|
||||
.col-sm-12
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//-
|
||||
ztncui - ZeroTier network controller UI
|
||||
Copyright (C) 2017-2018 Key Networks (https://key-networks.com)
|
||||
Copyright (C) 2017-2021 Key Networks (https://key-networks.com)
|
||||
Licensed under GPLv3 - see LICENSE for details.
|
||||
|
||||
extends network_layout
|
||||
@@ -9,7 +9,7 @@ block net_content
|
||||
if member.deleted
|
||||
.alert.alert-success
|
||||
strong #{member.name} (#{member.id}) was deleted
|
||||
a.btn.btn-default(href='../../members' name='networks' role='button') Members
|
||||
a.btn.btn-default(href=('/controller/network/' + network.nwid + '#members') name='networks' role='button') Members
|
||||
|
||||
else
|
||||
.alert.alert-info
|
||||
@@ -21,7 +21,7 @@ block net_content
|
||||
form(method='POST' action='')
|
||||
button.btn.btn-primary(type='submit', name='delete') Delete #{member.name} (#{member.id})
|
||||
= ' '
|
||||
a.btn.btn-default(href='/controller/network/' + network.nwid + '/members',
|
||||
a.btn.btn-default(href='/controller/network/' + network.nwid + '#members',
|
||||
name='cancel', role='button') Cancel
|
||||
|
||||
if errors
|
||||
|
||||
@@ -1,32 +1,20 @@
|
||||
//-
|
||||
ztncui - ZeroTier network controller UI
|
||||
Copyright (C) 2017-2018 Key Networks (https://key-networks.com)
|
||||
Copyright (C) 2017-2021 Key Networks (https://key-networks.com)
|
||||
Licensed under GPLv3 - see LICENSE for details.
|
||||
|
||||
extends network_layout
|
||||
|
||||
block net_content
|
||||
h4 for member #{member.name} (#{member.address})
|
||||
h4
|
||||
| for member #{member.name} (#{member.address}) in network
|
||||
|
||||
each value, key in member
|
||||
.row
|
||||
.col-sm-2
|
||||
a(href= member.address + '/' + key) #{key}:
|
||||
a(href=('/controller/network/' + member.nwid + '/member/' + member.address + '/' + key)) #{key}:
|
||||
.col-sm-10
|
||||
- if ((!!value ) && (value.constructor == Object))
|
||||
p {
|
||||
each v2, k2 in value
|
||||
p #{k2}: #{v2},
|
||||
p }
|
||||
- else if ((!!value ) && (value.constructor == Array))
|
||||
p [
|
||||
each elem in value
|
||||
p {
|
||||
each v2, k2 in elem
|
||||
p #{k2}: #{v2},
|
||||
p }
|
||||
p ]
|
||||
- else
|
||||
| #{value}
|
||||
+json_value(value)
|
||||
|
||||
a.btn.btn-default(href='../members' name='networks' role='button') Members
|
||||
a.btn.btn-default(href=('/controller/network/' + member.nwid + "#members") name='networks' role='button' style='margin-top: 10px;')
|
||||
| Members
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
//-
|
||||
ztncui - ZeroTier network controller UI
|
||||
Copyright (C) 2017-2018 Key Networks (https://key-networks.com)
|
||||
Licensed under GPLv3 - see LICENSE for details.
|
||||
|
||||
extends network_layout
|
||||
|
||||
block net_content
|
||||
script.
|
||||
$(function() {
|
||||
$('.authCheck').on('click', function() {
|
||||
$.post('', {'id': this.value, 'auth': this.checked});
|
||||
});
|
||||
});
|
||||
|
||||
$(function() {
|
||||
$('.bridgeCheck').on('click', function() {
|
||||
$.post('', {'id': this.value, 'activeBridge': this.checked});
|
||||
});
|
||||
});
|
||||
|
||||
$(function() {
|
||||
$('.text').on('change', function() {
|
||||
$.post('', {'id': this.name, 'name': this.value});
|
||||
});
|
||||
});
|
||||
|
||||
form(method='POST' action='')
|
||||
table.table.table-responsive.table-striped.table-hover
|
||||
tr
|
||||
td(width='3%')
|
||||
= ''
|
||||
td(width='20%')
|
||||
| Member name
|
||||
td(width='10%')
|
||||
| Member ID
|
||||
td(width='10%')
|
||||
| Authorized
|
||||
td(width='10%')
|
||||
| Active bridge
|
||||
td(width='47%')
|
||||
| IP assignment
|
||||
each member in members
|
||||
tr
|
||||
- let url = '/controller/network/' + network.nwid + '/member/' + member.id
|
||||
td
|
||||
a(href=url + '/delete')
|
||||
i.glyphicon.glyphicon-trash
|
||||
td
|
||||
input.form-control.text(type='text' name=member.id value=member.name)
|
||||
td
|
||||
a(href=url) #{member.id}
|
||||
td
|
||||
input.authCheck(type='checkbox' value=member.id checked=(member.authorized? true : false))
|
||||
td
|
||||
input.bridgeCheck(type='checkbox' value=member.id checked=(member.activeBridge? true : false))
|
||||
td
|
||||
each ipAssignment in member.ipAssignments
|
||||
a(href='/controller/network/' + network.nwid + '/member/' + member.id + '/ipAssignments')
|
||||
each digit in ipAssignment
|
||||
= digit
|
||||
= ' '
|
||||
else
|
||||
a(href='/controller/network/' + network.nwid + '/member/' + member.id + '/ipAssignments')
|
||||
| IP assignment
|
||||
|
||||
else
|
||||
.alert.alert-info
|
||||
strong There are no members on this network - invite users to join #{network.nwid}
|
||||
|
||||
a.btn.btn-default(href='' name='refresh' role='button') Refresh
|
||||
|
||||
if errors
|
||||
ul
|
||||
for err in errors
|
||||
li!= err.msg
|
||||
@@ -1,28 +0,0 @@
|
||||
//-
|
||||
ztncui - ZeroTier network controller UI
|
||||
Copyright (C) 2017-2018 Key Networks (https://key-networks.com)
|
||||
Licensed under GPLv3 - see LICENSE for details.
|
||||
|
||||
extends network_layout
|
||||
|
||||
block net_content
|
||||
form(method='POST' action='')
|
||||
|
||||
.form-group.row
|
||||
.col-sm-2
|
||||
label(for='name') Network name:
|
||||
.col-sm-10
|
||||
input#name.form-control(type='text' name='name' placeholder='New network name' value=(undefined===network.name? '' : network.name))
|
||||
|
||||
.form-group.row
|
||||
.col-sm-12
|
||||
button.btn.btn-primary(type='submit') Submit
|
||||
= ' '
|
||||
a.btn.btn-default(href='/controller/networks' name='cancel' role='button') Cancel
|
||||
|
||||
if errors
|
||||
.row
|
||||
.col-sm-12
|
||||
ul
|
||||
for err in errors
|
||||
li!= err.msg
|
||||
@@ -1,6 +1,6 @@
|
||||
//-
|
||||
ztncui - ZeroTier network controller UI
|
||||
Copyright (C) 2017-2018 Key Networks (https://key-networks.com)
|
||||
Copyright (C) 2017-2021 Key Networks (https://key-networks.com)
|
||||
Licensed under GPLv3 - see LICENSE for details.
|
||||
|
||||
extends controller_layout
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//-
|
||||
ztncui - ZeroTier network controller UI
|
||||
Copyright (C) 2017-2018 Key Networks (https://key-networks.com)
|
||||
Copyright (C) 2017-2021 Key Networks (https://key-networks.com)
|
||||
Licensed under GPLv3 - see LICENSE for details.
|
||||
|
||||
extends network_layout
|
||||
|
||||
@@ -1,44 +1,159 @@
|
||||
//-
|
||||
ztncui - ZeroTier network controller UI
|
||||
Copyright (C) 2017-2018 Key Networks (https://key-networks.com)
|
||||
Copyright (C) 2017-2021 Key Networks (https://key-networks.com)
|
||||
Licensed under GPLv3 - see LICENSE for details.
|
||||
|
||||
extends network_layout
|
||||
|
||||
//- Don't display that title
|
||||
block title
|
||||
|
||||
//- Replace the network title with the editable one
|
||||
block network_title
|
||||
h2
|
||||
| Network
|
||||
a#change-name(href='#')
|
||||
span#name= network.name
|
||||
i.glyphicon.glyphicon-pencil(style='font-size: 20px;')
|
||||
input#name-input.form-control(type='text' style='width: 200px; display: none;')
|
||||
| (#{network.nwid}):
|
||||
script.
|
||||
$(function() {
|
||||
var nwurl = '/controller/network/#{network.nwid}';
|
||||
var name = !{JSON.stringify(network.name)};
|
||||
|
||||
function toggleNameEditor(show) {
|
||||
$('#change-name').css('display', !show ? '' : 'none');
|
||||
$('#name-input').css('display', show ? 'inline-block' : 'none');
|
||||
}
|
||||
|
||||
function submit() {
|
||||
var newName = $('#name-input').val();
|
||||
if (newName != name) {
|
||||
name = newName;
|
||||
$.post(nwurl + '/name', {'name': name})
|
||||
.done(function () {
|
||||
$('#name').text(newName);
|
||||
});
|
||||
}
|
||||
toggleNameEditor(false);
|
||||
}
|
||||
|
||||
$('#change-name').on('click', function() {
|
||||
toggleNameEditor(true);
|
||||
$('#name-input').val(name);
|
||||
$('#name-input').focus();
|
||||
});
|
||||
$('#name-input').on('focusout', submit);
|
||||
$('#name-input').keypress(function (e) {
|
||||
if (e.which == 13) submit();
|
||||
});
|
||||
});
|
||||
|
||||
block net_content
|
||||
if error
|
||||
b #{error}
|
||||
else
|
||||
- if (members !== undefined)
|
||||
h3 Members
|
||||
each value, key in members
|
||||
.row
|
||||
.col-sm-2
|
||||
a(href= network.nwid + '/member/' + key) #{key}
|
||||
.col-sm-10
|
||||
| revision: #{value}
|
||||
- const nwurl = '/controller/network/' + network.nwid;
|
||||
|
||||
h3= title
|
||||
each value, key in network
|
||||
.row
|
||||
.col-sm-2
|
||||
a(href= network.nwid + '/' + key) #{key}:
|
||||
.col-sm-10
|
||||
- if ((!!value ) && (value.constructor == Object))
|
||||
p {
|
||||
each v2, k2 in value
|
||||
p #{k2}: #{v2},
|
||||
p }
|
||||
- else if ((!!value ) && (value.constructor == Array))
|
||||
p [
|
||||
each elem in value
|
||||
p {
|
||||
- if (!!elem)
|
||||
each v2, k2 in elem
|
||||
p #{k2}: #{v2},
|
||||
p },
|
||||
p ]
|
||||
- else
|
||||
| #{value}
|
||||
a.btn.btn-primary(style="margin: 5px" href=(nwurl + '/private') role='button')
|
||||
= network.private ? "Private" : "Public"
|
||||
a.btn.btn-primary(style="margin: 5px" href=(nwurl + '/easy') role='button') Easy setup
|
||||
a.btn.btn-primary(style="margin: 5px" href=(nwurl + '/routes') role='button') Routes
|
||||
a.btn.btn-primary(style="margin: 5px" href=(nwurl + '/ipAssignmentPools') role='button') Assignment Pools
|
||||
a.btn.btn-primary(style="margin: 5px" href=(nwurl + '/v4AssignMode') role='button') IPv4 Assign Mode
|
||||
a.btn.btn-primary(style="margin: 5px" href=(nwurl + '/v6AssignMode') role='button') IPv6 Assign Mode
|
||||
a.btn.btn-primary(style="margin: 5px" href=(nwurl + '/dns') role='button') DNS
|
||||
|
||||
a.btn.btn-default(href='/controller/networks' name='networks' role='button') Networks
|
||||
if (members !== undefined)
|
||||
script.
|
||||
$(function() {
|
||||
const url = "#{nwurl}/members";
|
||||
$('.authCheck').on('click', function() {
|
||||
$.post(url, {'id': this.value, 'auth': this.checked});
|
||||
});
|
||||
$('.bridgeCheck').on('click', function() {
|
||||
$.post(url, {'id': this.value, 'activeBridge': this.checked});
|
||||
});
|
||||
$('.text').on('change', function() {
|
||||
$.post(url, {'id': this.name, 'name': this.value});
|
||||
});
|
||||
});
|
||||
h3#members Members (#{members.length})
|
||||
form(method='POST' action='')
|
||||
table.table.table-responsive.table-striped.table-hover
|
||||
tr
|
||||
td(width='3%')
|
||||
= ''
|
||||
td(width='20%')
|
||||
| Member name
|
||||
td(width='10%')
|
||||
| Member ID
|
||||
td(width='10%')
|
||||
| Authorized
|
||||
td(width='10%')
|
||||
| Active bridge
|
||||
td(width='17%')
|
||||
| IP assignment
|
||||
td(width='17%')
|
||||
| Peer status
|
||||
td(width='13%')
|
||||
| Peer address / latency
|
||||
each member in members
|
||||
- const peer = member.peer;
|
||||
tr
|
||||
- const url = nwurl + '/member/' + member.id
|
||||
td
|
||||
a(href=url + '/delete')
|
||||
i.glyphicon.glyphicon-trash
|
||||
td
|
||||
input.form-control.text(type='text' name=member.id value=member.name)
|
||||
td
|
||||
a(href=url) #{member.id}
|
||||
td
|
||||
input.authCheck(type='checkbox' value=member.id checked=(member.authorized? true : false))
|
||||
td
|
||||
input.bridgeCheck(type='checkbox' value=member.id checked=(member.activeBridge? true : false))
|
||||
td
|
||||
each ipAssignment in member.ipAssignments
|
||||
a(href=nwurl + '/member/' + member.id + '/ipAssignments')
|
||||
each digit in ipAssignment
|
||||
= digit
|
||||
= ' '
|
||||
else
|
||||
a(href=nwurl + '/member/' + member.id + '/ipAssignments')
|
||||
| IP assignment
|
||||
td
|
||||
if (peer && peer.latency != -1 && peer.versionMajor != -1)
|
||||
if (peer.latency != -1)
|
||||
span(style='color: green;')
|
||||
| ONLINE (v#{peer.version})
|
||||
else
|
||||
span(style='color: orange;')
|
||||
| RELAY (v#{peer.version})
|
||||
else if (member.id == zt_address)
|
||||
span(style='color: green;') CONTROLLER
|
||||
else
|
||||
span(style='color: red;') OFFLINE
|
||||
td
|
||||
if (peer)
|
||||
each path in peer.paths
|
||||
- const [ip, port] = path.address.split('/');
|
||||
= ip
|
||||
span(style='color: gray;') /#{port}
|
||||
= ' '
|
||||
if (peer.latency != -1)
|
||||
br
|
||||
| (#{peer.latency} ms)
|
||||
else
|
||||
.alert.alert-info
|
||||
strong There are no members on this network - invite users to join #{network.nwid}
|
||||
|
||||
a.btn.btn-default(href='' name='refresh' role='button') Refresh
|
||||
|
||||
h3#detail Detail for network
|
||||
each value, key in network
|
||||
.row(style='margin: 5px 0;')
|
||||
.col-sm-2
|
||||
a(href= network.nwid + '/' + key) #{key}:
|
||||
.col-sm-10
|
||||
+json_value(value)
|
||||
|
||||
a.btn.btn-default(href='/controller/networks' name='networks' role='button' style='margin-top: 10px;') Networks
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//-
|
||||
ztncui - ZeroTier network controller UI
|
||||
Copyright (C) 2017-2018 Key Networks (https://key-networks.com)
|
||||
Copyright (C) 2017-2021 Key Networks (https://key-networks.com)
|
||||
Licensed under GPLv3 - see LICENSE for details.
|
||||
|
||||
extends network_layout
|
||||
@@ -80,7 +80,7 @@ block net_content
|
||||
.form-group(style='padding-top: 10px')
|
||||
button.btn.btn-primary(type='submit') Submit
|
||||
= ' '
|
||||
a.btn.btn-default(href='/controller/networks' name='cancel' role='button') Cancel
|
||||
a.btn.btn-default(href=('/controller/network/' + network.nwid) name='cancel' role='button') Cancel
|
||||
|
||||
if errors
|
||||
ul
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//-
|
||||
ztncui - ZeroTier network controller UI
|
||||
Copyright (C) 2017-2018 Key Networks (https://key-networks.com)
|
||||
Copyright (C) 2017-2021 Key Networks (https://key-networks.com)
|
||||
Licensed under GPLv3 - see LICENSE for details.
|
||||
|
||||
extends controller_layout
|
||||
@@ -11,10 +11,14 @@ block content
|
||||
else
|
||||
.row
|
||||
.col-sm-10
|
||||
h2
|
||||
a(href='/controller/network/' + network.nwid) #{network.name}
|
||||
| (#{network.nwid}):
|
||||
h3= title
|
||||
block network_title
|
||||
h2
|
||||
| Network
|
||||
a(href='/controller/network/' + network.nwid) #{network.name}
|
||||
| (#{network.nwid}):
|
||||
block title
|
||||
if title
|
||||
h3= title
|
||||
|
||||
.col-sm-2
|
||||
h2.right
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//-
|
||||
ztncui - ZeroTier network controller UI
|
||||
Copyright (C) 2017-2018 Key Networks (https://key-networks.com)
|
||||
Copyright (C) 2017-2021 Key Networks (https://key-networks.com)
|
||||
Licensed under GPLv3 - see LICENSE for details.
|
||||
|
||||
extends controller_layout
|
||||
@@ -11,36 +11,36 @@ block content
|
||||
if error
|
||||
b #{error}
|
||||
else
|
||||
|
||||
table.table.table-responsive.table-striped.table-hover
|
||||
tr
|
||||
th(width='3%')
|
||||
= ''
|
||||
th(width='20%')
|
||||
| Network name
|
||||
th(width='10%')
|
||||
th(width='20%')
|
||||
| Network ID
|
||||
th(width='7%')
|
||||
th(width='8%')
|
||||
= ''
|
||||
th(width='10%')
|
||||
th(width='12%')
|
||||
= ''
|
||||
th(width='50%')
|
||||
th(width='37%')
|
||||
= ''
|
||||
each network in networks
|
||||
- const nwurl = '/controller/network/' + network.nwid;
|
||||
tr
|
||||
td
|
||||
a(href='/controller/network/' + network.nwid + '/delete')
|
||||
a(href=nwurl + '/delete')
|
||||
i.glyphicon.glyphicon-trash
|
||||
td
|
||||
a(href='/controller/network/' + network.nwid + '/name') #{network.name}
|
||||
a(href=nwurl) #{network.name}
|
||||
td
|
||||
= network.nwid
|
||||
td
|
||||
a(href='/controller/network/' + network.nwid) detail
|
||||
a(href=nwurl) detail
|
||||
td
|
||||
a(href='/controller/network/' + network.nwid + '/easy') easy setup
|
||||
a(href=nwurl + '/easy') easy setup
|
||||
td
|
||||
a(href='/controller/network/' + network.nwid + '/members') members
|
||||
a(href=nwurl + "#members") members
|
||||
|
||||
else
|
||||
.alert.alert-info
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//-
|
||||
ztncui - ZeroTier network controller UI
|
||||
Copyright (C) 2017-2018 Key Networks (https://key-networks.com)
|
||||
Copyright (C) 2017-2021 Key Networks (https://key-networks.com)
|
||||
Licensed under GPLv3 - see LICENSE for details.
|
||||
|
||||
extends network_layout
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//-
|
||||
ztncui - ZeroTier network controller UI
|
||||
Copyright (C) 2017-2018 Key Networks (https://key-networks.com)
|
||||
Copyright (C) 2017-2021 Key Networks (https://key-networks.com)
|
||||
Licensed under GPLv3 - see LICENSE for details.
|
||||
|
||||
extends users_layout
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//-
|
||||
ztncui - ZeroTier network controller UI
|
||||
Copyright (C) 2017-2018 Key Networks (https://key-networks.com)
|
||||
Copyright (C) 2017-2021 Key Networks (https://key-networks.com)
|
||||
Licensed under GPLv3 - see LICENSE for details.
|
||||
|
||||
extends network_layout
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//-
|
||||
ztncui - ZeroTier network controller UI
|
||||
Copyright (C) 2017-2018 Key Networks (https://key-networks.com)
|
||||
Copyright (C) 2017-2021 Key Networks (https://key-networks.com)
|
||||
Licensed under GPLv3 - see LICENSE for details.
|
||||
|
||||
extends network_layout
|
||||
@@ -27,22 +27,22 @@ block net_content
|
||||
|
||||
form(method='POST' action='/controller/network/' + network.nwid + '/routes')
|
||||
.form-group.row
|
||||
.col-sm-2
|
||||
.col-sm-12
|
||||
label(for='target') Target:
|
||||
.col-sm-12
|
||||
input#target.form-control(type='text' name='target' placeholder='e.g. 10.11.12.0/24' value=(undefined===route? '' : route.target))
|
||||
|
||||
.form-group.row
|
||||
.col-sm-2
|
||||
.col-sm-12
|
||||
label(for='via') Gateway:
|
||||
.col-sm-12
|
||||
input#via.form-control(type='text' name='via' placeholder='e.g. 172.16.2.1 or leave blank if the target is the ZT network' value=(undefined===route? '' : route.via))
|
||||
|
||||
.form-group.row
|
||||
.col-sm-2
|
||||
.col-sm-12
|
||||
button.btn.btn-primary(type='submit') Submit
|
||||
= ' '
|
||||
a.btn.btn-default(href='/controller/networks' name='cancel' role='button') Cancel
|
||||
a.btn.btn-default(href=('/controller/network/' + network.nwid) name='cancel' role='button') Cancel
|
||||
|
||||
if errors
|
||||
.row
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//-
|
||||
ztncui - ZeroTier network controller UI
|
||||
Copyright (C) 2017-2018 Key Networks (https://key-networks.com)
|
||||
Copyright (C) 2017-2021 Key Networks (https://key-networks.com)
|
||||
Licensed under GPLv3 - see LICENSE for details.
|
||||
|
||||
extends users_layout
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//-
|
||||
ztncui - ZeroTier network controller UI
|
||||
Copyright (C) 2017-2018 Key Networks (https://key-networks.com)
|
||||
Copyright (C) 2017-2021 Key Networks (https://key-networks.com)
|
||||
Licensed under GPLv3 - see LICENSE for details.
|
||||
|
||||
extends users_layout
|
||||
|
||||
@@ -1,35 +1,17 @@
|
||||
//-
|
||||
ztncui - ZeroTier network controller UI
|
||||
Copyright (C) 2017-2018 Key Networks (https://key-networks.com)
|
||||
Copyright (C) 2017-2021 Key Networks (https://key-networks.com)
|
||||
Licensed under GPLv3 - see LICENSE for details.
|
||||
|
||||
extends head_layout
|
||||
|
||||
block body_content
|
||||
nav.navbar.navbar-inverse.navbar-fixed-top
|
||||
.container-fluid
|
||||
.navbar-header
|
||||
button.navbar-toggle(type='button' data-toggle='collapse' data-target='#BarNav')
|
||||
span.icon-bar
|
||||
span.icon-bar
|
||||
span.icon-bar
|
||||
a.navbar-brand(href='https://key-networks.com' target='_blank')
|
||||
img(src='/images/key-logo.svg' alt='Key Networks logo' height='25px' width='25px' style='display: inline')
|
||||
| Key Networks
|
||||
.collapse.navbar-collapse(id='BarNav')
|
||||
ul.nav.navbar-nav
|
||||
li(class=(navigate.active === 'home'? 'active' : ''))
|
||||
a(href='/controller') Home
|
||||
li(class=(navigate.active === 'users'? 'active' : ''))
|
||||
a(href='/users') Users
|
||||
li(class=(navigate.active === 'create_user'? 'active' : ''))
|
||||
a(href='/users/create') Create user
|
||||
ul.nav.navbar-nav.navbar-right
|
||||
li
|
||||
a(href='/logout')
|
||||
span.glyphicon.glyphicon-log-out
|
||||
| Logout
|
||||
block nav_items
|
||||
+nav_item('controller_home', 'Home', '/controller')
|
||||
+nav_item('users', 'Users', '/users')
|
||||
+nav_item('networks', 'Networks', '/controller/networks')
|
||||
+nav_item('create_user', 'Create user', '/users/create')
|
||||
|
||||
block body_content
|
||||
.container(style='margin-top:50px')
|
||||
.row
|
||||
.col-sm-12
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//-
|
||||
ztncui - ZeroTier network controller UI
|
||||
Copyright (C) 2017-2018 Key Networks (https://key-networks.com)
|
||||
Copyright (C) 2017-2021 Key Networks (https://key-networks.com)
|
||||
Licensed under GPLv3 - see LICENSE for details.
|
||||
|
||||
extends network_layout
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//-
|
||||
ztncui - ZeroTier network controller UI
|
||||
Copyright (C) 2017-2018 Key Networks (https://key-networks.com)
|
||||
Copyright (C) 2017-2021 Key Networks (https://key-networks.com)
|
||||
Licensed under GPLv3 - see LICENSE for details.
|
||||
|
||||
extends network_layout
|
||||
|
||||
Reference in New Issue
Block a user