Merge pull request #54 from KasperskyLab/update-feature

Update from GUI feature
This commit is contained in:
Félix Aimé 2021-02-19 16:45:41 +01:00 committed by GitHub
commit 22c7cf1119
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 410 additions and 117 deletions

View File

@ -1806,6 +1806,16 @@
"integrity": "sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==",
"dev": true
},
"ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"optional": true,
"requires": {
"color-convert": "^2.0.1"
}
},
"cacache": {
"version": "13.0.1",
"resolved": "https://registry.npmjs.org/cacache/-/cacache-13.0.1.tgz",
@ -1832,6 +1842,34 @@
"unique-filename": "^1.1.1"
}
},
"chalk": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
"integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
"dev": true,
"optional": true,
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
}
},
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"optional": true,
"requires": {
"color-name": "~1.1.4"
}
},
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true,
"optional": true
},
"find-cache-dir": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz",
@ -1853,6 +1891,25 @@
"path-exists": "^4.0.0"
}
},
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true,
"optional": true
},
"loader-utils": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
"integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
"dev": true,
"optional": true,
"requires": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
"json5": "^2.1.2"
}
},
"locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
@ -1917,6 +1974,16 @@
"minipass": "^3.1.1"
}
},
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
"optional": true,
"requires": {
"has-flag": "^4.0.0"
}
},
"terser-webpack-plugin": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-2.3.8.tgz",
@ -1933,6 +2000,18 @@
"terser": "^4.6.12",
"webpack-sources": "^1.4.3"
}
},
"vue-loader-v16": {
"version": "npm:vue-loader@16.1.2",
"resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.1.2.tgz",
"integrity": "sha512-8QTxh+Fd+HB6fiL52iEVLKqE9N1JSlMXLR92Ijm6g8PZrwIxckgpqjPDWRP5TWxdiPaHR+alUWsnu1ShQOwt+Q==",
"dev": true,
"optional": true,
"requires": {
"chalk": "^4.1.0",
"hash-sum": "^2.0.0",
"loader-utils": "^2.0.0"
}
}
}
},
@ -11307,87 +11386,6 @@
}
}
},
"vue-loader-v16": {
"version": "npm:vue-loader@16.1.2",
"resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.1.2.tgz",
"integrity": "sha512-8QTxh+Fd+HB6fiL52iEVLKqE9N1JSlMXLR92Ijm6g8PZrwIxckgpqjPDWRP5TWxdiPaHR+alUWsnu1ShQOwt+Q==",
"dev": true,
"optional": true,
"requires": {
"chalk": "^4.1.0",
"hash-sum": "^2.0.0",
"loader-utils": "^2.0.0"
},
"dependencies": {
"ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"optional": true,
"requires": {
"color-convert": "^2.0.1"
}
},
"chalk": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
"integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
"dev": true,
"optional": true,
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
}
},
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"optional": true,
"requires": {
"color-name": "~1.1.4"
}
},
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true,
"optional": true
},
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true,
"optional": true
},
"loader-utils": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
"integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
"dev": true,
"optional": true,
"requires": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
"json5": "^2.1.2"
}
},
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
"optional": true,
"requires": {
"has-flag": "^4.0.0"
}
}
}
},
"vue-router": {
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.4.3.tgz",

View File

@ -55,11 +55,19 @@
this.set_lang();
})
.catch(error => { console.log(error) });
},
get_version: function() {
axios.get('/api/update/get-version', { timeout: 60000 })
.then(response => {
if(response.data.status) window.current_version = response.data.current_version
})
.catch(error => { console.log(error) });
}
},
created: function() {
window.config = {}
this.get_config();
this.get_version();
}
}
</script>

View File

@ -683,6 +683,18 @@ ul {
opacity: 0.1;
}
.update-icon {
background-image: url("data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9JzMwMHB4JyB3aWR0aD0nMzAwcHgnICBmaWxsPSIjZmY4YjAwIiB4bWxuczp4PSJodHRwOi8vbnMuYWRvYmUuY29tL0V4dGVuc2liaWxpdHkvMS4wLyIgeG1sbnM6aT0iaHR0cDovL25zLmFkb2JlLmNvbS9BZG9iZUlsbHVzdHJhdG9yLzEwLjAvIiB4bWxuczpncmFwaD0iaHR0cDovL25zLmFkb2JlLmNvbS9HcmFwaHMvMS4wLyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDEwMCAxMDAiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDEwMCAxMDA7IiB4bWw6c3BhY2U9InByZXNlcnZlIj48c3dpdGNoPjxmb3JlaWduT2JqZWN0IHJlcXVpcmVkRXh0ZW5zaW9ucz0iaHR0cDovL25zLmFkb2JlLmNvbS9BZG9iZUlsbHVzdHJhdG9yLzEwLjAvIiB4PSIwIiB5PSIwIiB3aWR0aD0iMSIgaGVpZ2h0PSIxIj48L2ZvcmVpZ25PYmplY3Q+PGcgaTpleHRyYW5lb3VzPSJzZWxmIj48Zz48cGF0aCBkPSJNNTI3My4xLDI0MDAuMXYtMmMwLTIuOC01LTQtOS43LTRzLTkuNywxLjMtOS43LDR2MmMwLDEuOCwwLjcsMy42LDIsNC45bDUsNC45YzAuMywwLjMsMC40LDAuNiwwLjQsMXY2LjQgICAgIGMwLDAuNCwwLjIsMC43LDAuNiwwLjhsMi45LDAuOWMwLjUsMC4xLDEtMC4yLDEtMC44di03LjJjMC0wLjQsMC4yLTAuNywwLjQtMWw1LjEtNUM1MjcyLjQsMjQwMy43LDUyNzMuMSwyNDAxLjksNTI3My4xLDI0MDAuMXogICAgICBNNTI2My40LDI0MDBjLTQuOCwwLTcuNC0xLjMtNy41LTEuOHYwYzAuMS0wLjUsMi43LTEuOCw3LjUtMS44YzQuOCwwLDcuMywxLjMsNy41LDEuOEM1MjcwLjcsMjM5OC43LDUyNjguMiwyNDAwLDUyNjMuNCwyNDAweiI+PC9wYXRoPjxwYXRoIGQ9Ik01MjY4LjQsMjQxMC4zYy0wLjYsMC0xLDAuNC0xLDFjMCwwLjYsMC40LDEsMSwxaDQuM2MwLjYsMCwxLTAuNCwxLTFjMC0wLjYtMC40LTEtMS0xSDUyNjguNHoiPjwvcGF0aD48cGF0aCBkPSJNNTI3Mi43LDI0MTMuN2gtNC4zYy0wLjYsMC0xLDAuNC0xLDFjMCwwLjYsMC40LDEsMSwxaDQuM2MwLjYsMCwxLTAuNCwxLTFDNTI3My43LDI0MTQuMSw1MjczLjMsMjQxMy43LDUyNzIuNywyNDEzLjd6Ij48L3BhdGg+PHBhdGggZD0iTTUyNzIuNywyNDE3aC00LjNjLTAuNiwwLTEsMC40LTEsMWMwLDAuNiwwLjQsMSwxLDFoNC4zYzAuNiwwLDEtMC40LDEtMUM1MjczLjcsMjQxNy41LDUyNzMuMywyNDE3LDUyNzIuNywyNDE3eiI+PC9wYXRoPjwvZz48cGF0aCBkPSJNNTAsMi41QzIzLjgsMi41LDIuNSwyMy44LDIuNSw1MGMwLDI2LjIsMjEuMyw0Ny41LDQ3LjUsNDcuNVM5Ny41LDc2LjIsOTcuNSw1MEM5Ny41LDIzLjgsNzYuMiwyLjUsNTAsMi41eiBNNDQuNywyNi4zICAgIGMwLTIuOSwyLjQtNS4zLDUuMy01LjNjMi45LDAsNS4zLDIuNCw1LjMsNS4zdjI2LjVjMCwyLjktMi40LDUuMy01LjMsNS4zYy0yLjksMC01LjMtMi40LTUuMy01LjNWMjYuM3ogTTUwLDc4LjcgICAgYy0zLjgsMC02LjktMy4xLTYuOS02LjlzMy4xLTYuOSw2LjktNi45czYuOSwzLjEsNi45LDYuOVM1My44LDc4LjcsNTAsNzguN3oiPjwvcGF0aD48L2c+PC9zd2l0Y2g+PC9zdmc+");
width: 30px;
height: 30px;
display: block;
margin-right: 10px;
margin-top: 10px;
background-size: cover;
opacity: 0.2;
}
.off-icon:hover {
opacity: 0.3;
cursor:pointer;
@ -691,4 +703,21 @@ ul {
.quit-icon:hover {
opacity: 0.3;
cursor:pointer;
}
.update-icon:hover {
opacity: 0.4;
cursor:pointer;
}
sup {
top: -2em;
font-size: 12px;
left: -0.2em;
color: #CCC;
font-family: 'Lobster';
}
.color-green {
color:#35c435;
}

View File

@ -1,19 +1,22 @@
<template>
<div class="controls">
<i class="off-icon" v-on:click="action('shutdown')" v-if="off_available && off_display"></i>
<i class="quit-icon" v-on:click="action('quit')" v-if="quit_available && quit_display"></i>
<div class="controls" v-if="display">
<i class="off-icon" v-on:click="action('shutdown')" v-if="off_available"></i>
<i class="quit-icon" v-on:click="action('quit')" v-if="quit_available"></i>
<i class="update-icon" v-if="update_available&&update_possible" @click="$router.push({ name: 'update' })"></i>
</div>
</template>
<script>
import axios from 'axios'
export default {
name: 'Controls',
data: function (){
return {
off_available : false,
off_display : false,
display: true,
update_available: false,
update_possible: false,
quit_available: false,
quit_display : false
off_available: false
}
},
methods: {
@ -25,6 +28,26 @@ export default {
})
.catch(error => { console.log(error) });
},
check_update: function() {
axios.get('/api/update/check', { timeout: 60000 })
.then(response => {
if(response.data.status) {
if(response.data.message == "A new version is available"){
// Allow to show the warning chip.
this.update_available = true
this.update_possible = true
// Pass the versions as "global vars" through window variable.
window.current_version = response.data.current_version
window.next_version = response.data.next_version
}
} else {
this.update_possible = false
}
})
.catch(error => { console.log(error) });
},
load_config: function() {
axios.get(`/api/misc/config`, { timeout: 60000 })
.then(response => {
@ -36,17 +59,16 @@ export default {
},
watch: {
$route (){
if ( ["capture", "report"].includes(this.$router.currentRoute.name) || screen.height != window.innerHeight ){
this.off_display = false;
this.quit_display = false;
if ( ["capture", "report", "update", "loader"].includes(this.$router.currentRoute.name)){
this.display = false;
} else {
this.off_display = (this.off_available)? true : false;
this.quit_display = (this.quit_available)? true : false;
this.display = true;
}
}
},
created: function() {
this.load_config()
},
this.load_config();
this.check_update();
}
}
</script>

View File

@ -78,5 +78,12 @@
"tap_msg": "Podeu tocar la tecla USB per iniciar una nova captura.",
"capture_download": "La descàrrega de la captura començarà ...",
"start_capture_btn": "Inicia una altra captura"
},
"update": {
"tinycheck_needs": "TinyCheck ha d´actualitzar-se a la propera versió",
"please_click": "Feu click al botó de sota per actualitzar",
"the_process": "El procés pot trigar uns minuts, si us plau esperi ...",
"update_finished": "Actualització finalitzada, actualitzant la interfície...",
"update_it": "Actualitzar ara"
}
}

View File

@ -78,5 +78,12 @@
"tap_msg": "You can tap the USB key to start a new capture.",
"capture_download": "The capture download is going to start...",
"start_capture_btn": "Start another capture"
},
"update": {
"tinycheck_needs": "TinyCheck needs to be updated to the next version",
"please_click": "Please click on the button below to update it.",
"the_process": "The process can take few minutes, please wait...",
"update_finished": "Update finished, let's refresh the interface...",
"update_it": "Update it now"
}
}

View File

@ -78,5 +78,12 @@
"tap_msg": "Puede tocar la llave USB para iniciar una nueva captura",
"capture_download": "La descarga de la captura va a comenzar ...",
"start_capture_btn": "Iniciar otra captura"
},
"update": {
"tinycheck_needs": "TinyCheck debe actualizarse a la próxima versión",
"please_click": "Haga click en el botón de abajo para actualizar",
"the_process": "El proceso puede tardar unos minutos, por favor espere ...",
"update_finished": "Actualización finalizada, actualizando la interfaz...",
"update_it": "Actualizar ahora"
}
}

View File

@ -78,5 +78,12 @@
"tap_msg": "Vous pouvez appuyer sur l'animation pour lancer une nouvelle capture.",
"capture_download": "Le téléchargement de la capture va se lancer...",
"start_capture_btn": "Lancer une nouvelle capture"
},
"update": {
"tinycheck_needs": "Une nouvelle mise à jour de TinyCheck est disponible",
"please_click": "Cliquez sur le bouton ci-dessous pour le mettre à jour",
"the_process": "La mise à jour peut prendre plusieurs minutes, merci d'attendre...",
"update_finished": "Mise à jour terminée, vous allez être redirigé...",
"update_it": "Mettre TinyCheck à jour"
}
}

View File

@ -17,6 +17,12 @@ const routes = [
component: () => import('../views/home.vue'),
props: true
},
{
path: '/update',
name: 'update',
component: () => import('../views/update.vue'),
props: true
},
{
path: '/wifi-select',
name: 'wifi-select',

View File

@ -25,8 +25,7 @@ export default {
question: true,
running: false,
check_alerts: false,
long_waiting: false,
translation: {}
long_waiting: false
}
},
props: {

View File

@ -29,8 +29,7 @@ export default {
loading: false,
stats_interval: false,
chrono_interval: false,
sparklines: false,
translation: {}
sparklines: false
}
},
props: {

View File

@ -55,8 +55,7 @@ export default {
interval: false,
error: false,
reboot_option: window.config.reboot_option,
attempts: 3,
translation: {}
attempts: 3
}
},
methods: {

View File

@ -1,6 +1,6 @@
<template>
<div class="center">
<h3 class="lobster">{{ $t("home.welcome_msg") }}</h3>
<h3 class="lobster">{{ $t("home.welcome_msg") }}<sup>{{current_version}}</sup></h3>
<p>{{ $t("home.help_msg") }}</p>
<button class="btn btn-primary" v-on:click="next()">{{ $t("home.start_btn") }}</button>
</div>
@ -14,7 +14,7 @@ export default {
props: { saved_ssid: String, list_ssids: Array, internet: Boolean },
data() {
return {
translation: {},
current_version:""
}
},
methods: {
@ -31,6 +31,10 @@ export default {
internet: internet } });
}
}
},
created: function() {
if ('current_version' in window)
this.current_version = window.current_version
}
}
</script>

View File

@ -99,8 +99,7 @@ export default {
name: 'report',
data() {
return {
results: true,
translation: {}
results: true
}
},
props: {

View File

@ -144,8 +144,7 @@ export default {
usb: false,
saved: false,
save_usb: false,
init: false,
translation: {}
init: false
}
},
props: {

View File

@ -20,7 +20,7 @@
},
methods: {
internet_check: function() {
axios.get('/api/network/status', { timeout: 10000 })
axios.get('/api/network/status', { timeout: 30000 })
.then(response => {
if (response.data.internet) this.internet = true
if (window.config.iface_out.charAt(0) == 'e') {
@ -32,7 +32,7 @@
.catch(err => (console.log(err)))
},
get_wifi_networks: function() {
axios.get('/api/network/wifi/list', { timeout: 10000 })
axios.get('/api/network/wifi/list', { timeout: 30000 })
.then(response => {
this.list_ssids = response.data.networks
this.goto_home();

View File

@ -0,0 +1,68 @@
<template>
<div class="center">
<p><strong>{{ $t("update.tinycheck_needs") }} ({{next_version}}).</strong><br />
<span v-if="!update_launched">{{ $t("update.please_click") }}</span>
<span v-if="update_launched&&!update_finished">{{ $t("update.the_process") }}</span>
<span v-if="update_launched&&update_finished" class="color-green"> {{ $t("update.update_finished") }}</span>
</p>
<button class="btn btn-primary" :class="[ update_launched ? 'loading' : '' ]" v-on:click="launch_update()" v-if="!update_finished">{{ $t("update.update_it") }}</button>
</div>
</template>
<script>
import axios from 'axios'
export default {
name: 'update',
data() {
return {
translation: {},
update_launched: null,
check_interval: null,
next_version: null,
current_version: null,
update_finished: false
}
},
methods: {
check_version: function() {
axios.get('/api/update/get-version', { timeout: 60000 })
.then(response => {
if(response.data.status) {
if(response.data.current_version == window.next_version){
window.current_version = response.data.current_version
this.update_finished = true
clearInterval(this.check_interval);
setTimeout(function () { window.location.href = "/"; }, 10000)
}
}
})
.catch(error => { console.log(error) });
},
launch_update: function() {
axios.get(`/api/update/process`, { timeout: 60000 })
.then(response => {
if(response.data.status) {
if(response.data.message == "Update successfully launched"){
this.update_launched = true
this.check_interval = setInterval(function(){ this.check_version(); }.bind(this), 3000);
}
}
})
.catch(error => { console.log(error) });
}
},
created: function() {
if ('next_version' in window && 'current_version' in window){
if (window.current_version != window.next_version){
this.next_version = window.next_version
this.current_version = window.current_version
} else {
window.location.href = "/";
}
} else {
window.location.href = "/";
}
}
}
</script>

View File

@ -72,8 +72,7 @@ export default {
virtual_keyboard: window.config.virtual_keyboard,
have_internet: false,
enter_creds: false,
refreshing: false,
translation: {}
refreshing: false
}
},
props: {

View File

@ -50,7 +50,8 @@ frontend:
sparklines: true
virtual_keyboard: true
user_lang: userlang
update: updateoption
# NETWORK -
# Some elements related to the network configuration, such as
# the interfaces (updated during the install), the list of SSIDs

View File

@ -97,6 +97,19 @@ set_kioskmode() {
fi
}
set_update() {
echo -n "[?] Do you want to be able to update TinyCheck from the frontend interface? [Yes/No] "
read answer
if [[ "$answer" =~ ^([yY][eE][sS]|[yY])$ ]]
then
sed -i "s/updateoption/true/g" /usr/share/tinycheck/config.yaml
echo -e "\e[92m [✔] You'll be able to update it from the frontend!\e[39m"
else
sed -i "s/updateoption/false/g" /usr/share/tinycheck/config.yaml
echo -e "\e[92m [✔] You'll need to pass by the console script to update TinyCheck.\e[39m"
fi
}
create_directory() {
# Create the TinyCheck directory and move the whole stuff there.
echo -e "[+] Creating TinyCheck folder under /usr/share/"
@ -104,6 +117,10 @@ create_directory() {
cp -Rf ./* /usr/share/tinycheck
}
get_version() {
git tag | tail -n 1 | xargs echo -n > /usr/share/tinycheck/VERSION
}
generate_certificate() {
# Generating SSL certificate for the backend.
echo -e "[+] Generating SSL certificate for the backend"
@ -444,9 +461,11 @@ else
check_operating_system
check_interfaces
create_directory
get_version
set_userlang
set_credentials
set_kioskmode
set_update
check_dependencies
configure_dnsmask
configure_dhcpcd

View File

@ -0,0 +1,25 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from flask import jsonify, Blueprint
from app.classes.update import Update
update_bp = Blueprint("update", __name__)
@update_bp.route("/check", methods=["GET"])
def check():
""" Check the presence of new version """
return jsonify(Update().check_version())
@update_bp.route("/get-version", methods=["GET"])
def get_version():
""" Check the current version """
return jsonify(Update().get_current_version())
@update_bp.route("/process", methods=["GET"])
def process():
""" Check the presence of new version """
return jsonify(Update().update_instance())

View File

@ -0,0 +1,82 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from app.utils import read_config
import subprocess as sp
import requests
import json
import os
import re
class Update(object):
def __init__(self):
self.project_url = "https://api.github.com/repos/KasperskyLab/TinyCheck/tags"
self.app_path = "/usr/share/tinycheck"
return None
def check_version(self):
"""
Check if a new version of TinyCheck is available
by quering the Github api and comparing the last
tag inside the VERSION file.
:return: dict containing the available versions.
"""
if read_config(("frontend", "update")):
try:
res = requests.get(self.project_url)
res = json.loads(res.content.decode("utf8"))
with open(os.path.join(self.app_path, "VERSION")) as f:
cv = f.read()
if cv != res[0]["name"]:
return {"status": True,
"message": "A new version is available",
"current_version": cv,
"next_version": res[0]["name"]}
else:
return {"status": True,
"message": "This is the latest version",
"current_version": cv}
except:
return {"status": False,
"message": "Something went wrong (no API access nor version file)"}
else:
return {"status": False,
"message": "You don't have rights to do this operation."}
def get_current_version(self):
"""
Get the current version of the TinyCheck instance
:return: dict containing the current version or error.
"""
if read_config(("frontend", "update")):
try:
with open(os.path.join(self.app_path, "VERSION")) as f:
return {"status": True,
"current_version": f.read()}
except:
return {"status": False,
"message": "Something went wrong - no version file ?"}
else:
return {"status": False,
"message": "You don't have rights to do this operation."}
def update_instance(self):
"""
Update the instance by executing the update script.
:return: dict containing the update status.
"""
if read_config(("frontend", "update")):
try:
os.chdir(self.app_path)
sp.Popen(["bash", os.path.join(self.app_path, "update.sh")])
return {"status": True,
"message": "Update successfully launched"}
except:
return {"status": False,
"message": "Issue during the update"}
else:
return {"status": False,
"message": "You don't have rights to do this operation."}

View File

@ -8,6 +8,7 @@ from app.blueprints.device import device_bp
from app.blueprints.analysis import analysis_bp
from app.blueprints.save import save_bp
from app.blueprints.misc import misc_bp
from app.blueprints.update import update_bp
from app.utils import read_config
app = Flask(__name__, template_folder="../../app/frontend/dist")
@ -42,6 +43,7 @@ app.register_blueprint(device_bp, url_prefix='/api/device')
app.register_blueprint(analysis_bp, url_prefix='/api/analysis')
app.register_blueprint(save_bp, url_prefix='/api/save')
app.register_blueprint(misc_bp, url_prefix='/api/misc')
app.register_blueprint(update_bp, url_prefix='/api/update')
if __name__ == '__main__':
if read_config(("frontend", "remote_access")):

View File

@ -40,12 +40,7 @@ elif [ $PWD = "/tmp/tinycheck" ]; then
cd /usr/share/tinycheck/app/frontend/ && npm install && npm run build
cd /usr/share/tinycheck/app/backend/ && npm install && npm run build
echo "[+] Restarting services"
service tinycheck-backend restart
service tinycheck-frontend restart
service tinycheck-watchers restart
# Updating configuration with new values.
echo "[+] Updating current configuration with new values."
if ! grep -q reboot_option /usr/share/tinycheck/config.yaml; then
sed -i 's/frontend:/frontend:\n reboot_option: true/g' /usr/share/tinycheck/config.yaml
fi
@ -66,9 +61,21 @@ elif [ $PWD = "/tmp/tinycheck" ]; then
sed -i 's/analysis:/analysis:\n active: true/g' /usr/share/tinycheck/config.yaml
fi
if ! grep -q update /usr/share/tinycheck/config.yaml; then
sed -i 's/frontend:/frontend:\n update: true/g' /usr/share/tinycheck/config.yaml
fi
if ! grep -q "CN=R3,O=Let's Encrypt,C=US" /usr/share/tinycheck/config.yaml; then
sed -i "s/free_issuers:/free_issuers:\n - CN=R3,O=Let's Encrypt,C=US/g" /usr/share/tinycheck/config.yaml
fi
echo "[+] Restarting services"
service tinycheck-backend restart
service tinycheck-frontend restart
service tinycheck-watchers restart
echo "[+] Updating the TinyCheck version"
cd /tmp/tinycheck && git tag | tail -n 1 | xargs echo -n > /usr/share/tinycheck/VERSION
echo "[+] TinyCheck updated!"
fi