mirror of
https://github.com/trailofbits/algo.git
synced 2025-07-13 17:22:56 +02:00
186 lines
6.1 KiB
HTML
186 lines
6.1 KiB
HTML
<!DOCTYPE html>
|
||
<html class="h-100" lang="en">
|
||
|
||
<head>
|
||
<title>Algo VPN</title>
|
||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||
<script src="https://cdn.jsdelivr.net/npm/http-vue-loader@1.4.2/src/httpVueLoader.js"
|
||
integrity="sha256-aOeVxnlZDaiJOHsqNWVOMNsKdiGxgT8kbLp1p1Rv2sc=" crossorigin="anonymous"></script>
|
||
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11/dist/vue.js"
|
||
integrity="sha256-NSuqgY2hCZJUN6hDMFfdxvkexI7+iLxXQbL540RQ/c4=" crossorigin="anonymous"></script>
|
||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.4.1/dist/css/bootstrap.min.css"
|
||
integrity="sha256-L/W5Wfqfa0sdBNIKN9cG6QA5F2qx4qICmU2VgLruv9Y=" crossorigin="anonymous">
|
||
<style>
|
||
.fade-enter-active, .fade-leave-active {
|
||
transition: opacity 300ms ease-in-out;
|
||
}
|
||
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
|
||
opacity: 0;
|
||
}
|
||
.console-item {
|
||
display: block;
|
||
max-height: 10em;
|
||
}
|
||
.console-enter-active, .console-leave-active {
|
||
transition: all 500ms;
|
||
}
|
||
.console-leave-to {
|
||
opacity: 0;
|
||
max-height: 0;
|
||
}
|
||
.console-enter {
|
||
opacity: 0;
|
||
}
|
||
.back-button {
|
||
position: absolute;
|
||
border-radius: 50%;
|
||
left: 1em;
|
||
top: 0.5em;
|
||
}
|
||
.spin {
|
||
animation-name: spin;
|
||
animation-duration: 5000ms;
|
||
animation-iteration-count: infinite;
|
||
animation-delay: 5s;
|
||
animation-timing-function: linear;
|
||
display: inline-block;
|
||
}
|
||
@keyframes spin {
|
||
from {
|
||
transform:rotate(0deg);
|
||
}
|
||
to {
|
||
transform:rotate(360deg);
|
||
}
|
||
}
|
||
</style>
|
||
</head>
|
||
|
||
<body class="d-flex flex-column h-100">
|
||
<div class="container" id="algo">
|
||
<h1 class="mb-5 text-center" v-if="step === 'setup'">Algo VPN Setup</h1>
|
||
<h1 class="mb-5 text-center" v-if="step === 'provider'">
|
||
<button type="button" class="btn btn-secondary back-button" v-on:click="step = 'setup'">←</button>
|
||
<span>☁ Cloud Provider Setup</span>
|
||
</h1>
|
||
<h1 class="mb-5 text-center" v-if="step === 'command'">
|
||
<button type="button" class="btn btn-secondary back-button" v-on:click="step = 'provider'">←</button>
|
||
🧐 Review and Start!
|
||
</h1>
|
||
<h1 class="mb-5 text-center" v-if="step === 'status-running'">
|
||
<span class="spin">🙂</span> Please be patient
|
||
</h1>
|
||
<h1 class="mb-5 text-center" v-if="step === 'status-failed'">
|
||
😢 Set up failed
|
||
</h1>
|
||
<h1 class="mb-5 text-center" v-if="step === 'status-successful'">
|
||
🥳 Congratulations, your Algo server is running!
|
||
</h1>
|
||
<h1 class="mb-5 text-center" v-if="step === 'status-exit'">
|
||
Config files are saved, bye!
|
||
</h1>
|
||
</h1>
|
||
<transition name="fade">
|
||
<div class="row" v-if="step === 'setup'">
|
||
<user-config class="col-md-4 order-md-2 mb-4"></user-config>
|
||
<vpn-setup class="col-md-8 order-md-1"
|
||
v-bind:extra_args="extra_args"
|
||
v-on:submit="step = 'provider'"></vpn-setup>
|
||
</div>
|
||
</transition>
|
||
<transition name="fade">
|
||
<provider-setup v-if="step === 'provider'"
|
||
v-bind:extra_args="extra_args"
|
||
v-on:submit="step = 'command'">
|
||
</provider-setup>
|
||
</transition>
|
||
<transition name="fade">
|
||
<command-preview v-if="step === 'command'"
|
||
v-bind:extra_args="extra_args"
|
||
v-on:submit="start(); step = 'status-running';">
|
||
</command-preview>
|
||
</transition>
|
||
<transition name="fade">
|
||
<status-running v-if="step === 'status-running'"
|
||
v-on:submit="stop(); step = 'setup';"
|
||
v-on:successful="step = 'status-successful'"
|
||
v-on:error="step = 'status-failed'"
|
||
v-on:cancelled="step = 'setup'">
|
||
</status-running>
|
||
</transition>
|
||
<transition name="fade">
|
||
<section v-if="step === 'status-failed'" class="text-center">
|
||
<p>Now it’s time to inspect console output</p>
|
||
<p>Restart console process to try again</p>
|
||
</section>
|
||
</transition>
|
||
<transition name="fade">
|
||
<status-successful v-if="step === 'status-successful'"
|
||
v-on:submit="exit(); step = 'status-exit'" >
|
||
</status-successful>
|
||
</transition>
|
||
</div>
|
||
|
||
<script>
|
||
new window.Vue({
|
||
el: '#algo',
|
||
data: {
|
||
playbook: {},
|
||
step: 'setup',
|
||
extra_args: {
|
||
server_name: 'algo',
|
||
ondemand_cellular: false,
|
||
ondemand_wifi: false,
|
||
dns_adblocking: false,
|
||
ssh_tunneling: false,
|
||
store_pki: false,
|
||
ondemand_wifi_exclude: []
|
||
}
|
||
},
|
||
components: {
|
||
'user-config': window.httpVueLoader('/static/user-config.vue'),
|
||
'vpn-setup': window.httpVueLoader('/static/vpn-setup.vue'),
|
||
'provider-setup': window.httpVueLoader('/static/provider-setup.vue'),
|
||
'command-preview': window.httpVueLoader('/static/command-preview.vue'),
|
||
'status-running': window.httpVueLoader('/static/status-running.vue'),
|
||
'status-successful': window.httpVueLoader('/static/status-done.vue')
|
||
},
|
||
created() {
|
||
fetch("/playbook")
|
||
.then(r => r.json())
|
||
.catch(() => {
|
||
this.step = 'status-failed';
|
||
})
|
||
.then(data => {
|
||
if (data.status && data.status !== 'cancelled'){
|
||
this.step = `status-${data.status}`;
|
||
}
|
||
});
|
||
},
|
||
methods: {
|
||
start: function() {
|
||
fetch("/playbook", {
|
||
method: "POST",
|
||
body: JSON.stringify(this.extra_args),
|
||
headers: {
|
||
"Content-Type": "application/json"
|
||
}
|
||
});
|
||
},
|
||
stop() {
|
||
fetch("/playbook", {
|
||
method: "DELETE"
|
||
});
|
||
},
|
||
exit() {
|
||
fetch("/exit", {
|
||
method: "POST"
|
||
});
|
||
}
|
||
}
|
||
})
|
||
</script>
|
||
</body>
|
||
|
||
</html>
|