Files
Anders Pitman 2b74f6ee0c Implement selecting tunnel port
This is useful for when you want to use boringproxy more like a
normal reverse proxy, ie if boringproxy and your service are on
the same machine, you can just use the port of the service as the
tunnel port and boringproxy will forward directly to it without
using SSH.

This would normally be used with no client set.
2021-02-16 18:37:31 -07:00

282 lines
11 KiB
Cheetah

<!doctype html>
<html>
<head>
{{.Head}}
<style>
{{range $domain, $tunnel:= .Tunnels}}
#toggle-tunnel-delete-dialog-{{$tunnel.CssId}} {
display: none;
}
#toggle-tunnel-delete-dialog-{{$tunnel.CssId}}:checked + .dialog {
display: block;
}
#toggle-tunnel-hide-deleted-{{$tunnel.CssId}}:checked + .list-item {
/* This is a trick to make the delete request after the delete button is
* clicked. The background will never actually be displayed, because it's
* moved offscreen. */
position: absolute;
left: -999em;
background: url("/delete-tunnel?domain={{$domain}}");
}
#toggle-tunnel-hide-deleted-{{$tunnel.CssId}}:checked ~ .dialog {
display: none;
}
{{end}}
</style>
</head>
<body>
<main>
<input type='checkbox' id='menu-toggle'/>
<label id='menu-label' for='menu-toggle'>Menu</label>
<div class='page' id='/tunnels'>
<div class='menu'>
<a class='menu-item active-tab' href='/#/tunnels'>Tunnels</a>
<a class='menu-item' href='/#/tokens'>Tokens</a>
<!--
<a class='menu-item' href='/#/ssh-keys'>SSH Keys</a>
-->
{{if .IsAdmin}}
<a class='menu-item' href='/#/users'>Users</a>
{{end}}
<a class='menu-item' href='/confirm-logout'>Logout</a>
</div>
<div class='content'>
<div class='list'>
{{range $domain, $tunnel:= .Tunnels}}
<input autocomplete='off' type='checkbox' class='toggle' id='toggle-tunnel-hide-deleted-{{$tunnel.CssId}}'>
<div class='list-item'>
<div>
<a href="https://{{$domain}}">{{$domain}}</a>:{{$tunnel.TunnelPort}} -> {{$tunnel.ClientName}} -> {{$tunnel.ClientAddress}}:{{$tunnel.ClientPort}}
</div>
<a class='button' href="/tunnel-private-key?domain={{$domain}}">Download Private Key</a>
<label class='button' for='toggle-tunnel-delete-dialog-{{$tunnel.CssId}}'>
Delete
</label>
</div>
<input autocomplete='off' type='checkbox' id='toggle-tunnel-delete-dialog-{{$tunnel.CssId}}'>
<div class='dialog'>
<label for='toggle-tunnel-delete-dialog-{{$tunnel.CssId}}' class='dialog__overlay'></label>
<div class='dialog__content'>
<p class='dialog__text'>
Are you sure you want to delete {{$domain}}?
</p>
<div class='button-row'>
<label for='toggle-tunnel-hide-deleted-{{$tunnel.CssId}}' class='button'>
Confirm
</label>
<label for='toggle-tunnel-delete-dialog-{{$tunnel.CssId}}' class='button'>
Cancel
</button>
</div>
</div>
</div>
{{end}}
</div>
<div class='tunnel-adder'>
<h1>Add Tunnel</h1>
<form action="/tunnels" method="POST">
<div class='input'>
<label for="domain">Domain:</label>
<input type="text" id="domain" name="domain" required>
<input type="hidden" id="tunnel-owner" name="owner" value="{{$.UserId}}">
</div>
<div class='input'>
<label for="tunnel-port">Tunnel Port:</label>
<input type="text" id="tunnel-port" name="tunnel-port" value="Random">
</div>
<!--
<div class='input'>
<label for="ssh-key-id-select">SSH Key:</label>
<select id="ssh-key-id-select" name="ssh-key-id">
<option value="generate">Generate</option>
{{range $id, $sshKey := $.SshKeys}}
<option value="{{$id}}">{{$id}}</option>
{{end}}
</select>
</div>
-->
<div class='input'>
<label for="client-name">Client Name:</label>
<select id="client-name" name="client-name">
<option value="none">No client</option>
{{range $id, $client := (index $.Users $.UserId).Clients}}
<option value="{{$id}}">{{$id}}</option>
{{end}}
</select>
</div>
<div class='input'>
<label for="client-addr">Client Address:</label>
<input type="text" id="client-addr" name="client-addr" value='127.0.0.1'>
</div>
<div class='input'>
<label for="client-port">Client Port:</label>
<input type="text" id="client-port" name="client-port">
</div>
<div class='input'>
<label for="allow-external-tcp">Allow External TCP:</label>
<input type="checkbox" id="allow-external-tcp" name="allow-external-tcp">
</div>
<div class='input'>
<label for="password-protect">Password Protect:</label>
<input type="checkbox" id="password-protect" name="password-protect">
<div id='login-inputs'>
<label for="username">Username:</label>
<input type="text" id="username" name="username">
<label for="password">Password:</label>
<input type="password" id="password" name="password">
</div>
</div>
<div class='input'>
<label for="tls-termination">TLS Termination:</label>
<select id="tls-termination" name="tls-termination">
<option value="server">Server</option>
<option value="client">Client</option>
<option value="passthrough">Passthrough</option>
</select>
</div>
<button class='button' type="submit">Submit</button>
</form>
</div>
</div>
</div>
<div class='page' id='/tokens'>
<div class='menu'>
<a class='menu-item' href='/#/tunnels'>Tunnels</a>
<a class='menu-item active-tab' href='/#/tokens'>Tokens</a>
<!--
<a class='menu-item' href='/#/ssh-keys'>SSH Keys</a>
-->
{{if .IsAdmin}}
<a class='menu-item' href='/#/users'>Users</a>
{{end}}
<a class='menu-item' href='/confirm-logout'>Logout</a>
</div>
<div class='content'>
<div class='list'>
{{range $token, $tokenData := .Tokens}}
<div class='list-item'>
<span class='token'>{{$token}} ({{$tokenData.Owner}})</span>
<a href='/login?access_token={{$token}}'>Login link</a>
<img class='qr-code' src='{{index $.QrCodes $token}}' width=100 height=100>
<a href="/confirm-delete-token?token={{$token}}">
<button class='button'>Delete</button>
</a>
</div>
{{end}}
</div>
<div class='token-adder'>
<form action="/tokens" method="POST">
<label for="token-owner">Owner:</label>
<select id="token-owner" name="owner">
{{range $username, $user := .Users}}
<option value="{{$username}}">{{$username}}</option>
{{end}}
</select>
<button class='button' type="submit">Add Token</button>
</form>
</div>
</div>
</div>
<!--
<div class='page' id='/ssh-keys'>
<div class='menu'>
<a class='menu-item' href='/#/tunnels'>Tunnels</a>
<a class='menu-item' href='/#/tokens'>Tokens</a>
<a class='menu-item active-tab' href='/#/ssh-keys'>SSH Keys</a>
{{if .IsAdmin}}
<a class='menu-item' href='/#/users'>Users</a>
{{end}}
<a class='menu-item' href='/confirm-logout'>Logout</a>
</div>
<div class='content'>
<div class='list'>
{{range $id, $sshKey := .SshKeys}}
<div class='list-item'>
<span class='monospace'>{{$id}} ({{$sshKey.Owner}})</span>
<div class='monospace'>{{$sshKey.Key}}</div>
<a href="/delete-ssh-key?id={{$id}}">
<button class='button'>Delete</button>
</a>
</div>
{{end}}
</div>
<div class='ssh-key-adder'>
<h1>Add SSH Key</h1>
<form action="/ssh-keys" method="POST">
<div class='input'>
<label for="ssh-key-id">SSH Key ID:</label>
<input type="text" id="ssh-key-id" name="id" required>
</div>
<div class='input'>
<label for="ssh-key-owner">Owner:</label>
<select id="ssh-key-owner" name="owner">
{{range $username, $user := .Users}}
<option value="{{$username}}">{{$username}}</option>
{{end}}
</select>
</div>
<div class='input'>
<label for="ssh-key">SSH Key:</label>
<textarea id='ssh-key' name='key' rows='8' cols='30'>
</textarea>
</div>
<button class='button' type="submit">Submit</button>
</form>
</div>
</div>
</div>
-->
{{if .IsAdmin}}
<div class='page' id='/users'>
<div class='menu'>
<a class='menu-item' href='/#/tunnels'>Tunnels</a>
<a class='menu-item' href='/#/tokens'>Tokens</a>
<a class='menu-item' href='/#/users'>Users</a>
<a class='menu-item' href='/confirm-logout'>Logout</a>
</div>
<div class='content'>
<div class='list'>
{{range $username, $user := .Users}}
<div class='list-item'>
{{$username}}
<a href="/confirm-delete-user?username={{$username}}">
<button class='button'>Delete</button>
</a>
</div>
{{end}}
</div>
<div class='user-adder'>
<form action="/users" method="POST">
<label for="username">Username:</label>
<input type="text" id="username" name="username" required>
<label for="is-admin">Is Admin:</label>
<input type="checkbox" id="is-admin" name="is-admin">
<button class='button' type="submit">Add User</button>
</form>
</div>
</div>
</div>
{{end}}
</main>
</body>
</html>