First commit!
@@ -0,0 +1 @@
|
||||
timeout=60000
|
||||
@@ -0,0 +1,24 @@
|
||||
# tinycheck-new
|
||||
|
||||
## Project setup
|
||||
```
|
||||
npm install
|
||||
```
|
||||
|
||||
### Compiles and hot-reloads for development
|
||||
```
|
||||
npm run serve
|
||||
```
|
||||
|
||||
### Compiles and minifies for production
|
||||
```
|
||||
npm run build
|
||||
```
|
||||
|
||||
### Lints and fixes files
|
||||
```
|
||||
npm run lint
|
||||
```
|
||||
|
||||
### Customize configuration
|
||||
See [Configuration Reference](https://cli.vuejs.org/config/).
|
||||
@@ -0,0 +1,5 @@
|
||||
module.exports = {
|
||||
presets: [
|
||||
'@vue/cli-plugin-babel/preset'
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"python.pythonPath": "/usr/local/opt/python@3.8/bin/python3.8"
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
.canvas-anim{height:120px;margin:0 auto;position:relative;width:205px}.canvas-anim.anim-connect{width:300px}.canvas-anim.anim-connect .icon-usb{animation:slide-right 1s cubic-bezier(.455,.03,.515,.955) infinite alternate both}
|
||||
@@ -0,0 +1 @@
|
||||
#app{overflow-y:visible}
|
||||
@@ -0,0 +1,11 @@
|
||||
/*!
|
||||
*
|
||||
* simple-keyboard v2.32.131
|
||||
* https://github.com/hodgef/simple-keyboard
|
||||
*
|
||||
* Copyright (c) Francisco Hodge (https://github.com/hodgef)
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
*/.hg-theme-default{width:100%;-webkit-user-select:none;user-select:none;box-sizing:border-box;overflow:hidden;touch-action:manipulation}.hg-theme-default .hg-button span{pointer-events:none}.hg-theme-default button.hg-button{border-width:0;outline:0;font-size:inherit}.hg-theme-default{font-family:HelveticaNeue-Light,Helvetica Neue Light,Helvetica Neue,Helvetica,Arial,Lucida Grande,sans-serif;background-color:#ececec;padding:5px;border-radius:5px}.hg-theme-default .hg-button{display:inline-block;flex-grow:1}.hg-theme-default .hg-row{display:flex}.hg-theme-default .hg-row:not(:last-child){margin-bottom:5px}.hg-theme-default .hg-row .hg-button-container,.hg-theme-default .hg-row .hg-button:not(:last-child){margin-right:5px}.hg-theme-default .hg-row>div:last-child{margin-right:0}.hg-theme-default .hg-row .hg-button-container{display:flex}.hg-theme-default .hg-button{box-shadow:0 0 3px -1px rgba(0,0,0,.3);height:40px;border-radius:5px;box-sizing:border-box;padding:5px;background:#fff;border-bottom:1px solid #b5b5b5;cursor:pointer;display:flex;align-items:center;justify-content:center;-webkit-tap-highlight-color:rgba(0,0,0,0)}.hg-theme-default .hg-button.hg-activeButton{background:#efefef}.hg-theme-default.hg-layout-numeric .hg-button{width:33.3%;height:60px;align-items:center;display:flex;justify-content:center}.hg-theme-default .hg-button.hg-button-numpadadd,.hg-theme-default .hg-button.hg-button-numpadenter{height:85px}.hg-theme-default .hg-button.hg-button-numpad0{width:105px}.hg-theme-default .hg-button.hg-button-com{max-width:85px}.hg-theme-default .hg-button.hg-standardBtn.hg-button-at{max-width:45px}.hg-theme-default .hg-button.hg-selectedButton{background:rgba(5,25,70,.53);color:#fff}.hg-theme-default .hg-button.hg-standardBtn[data-skbtn=".com"]{max-width:82px}.hg-theme-default .hg-button.hg-standardBtn[data-skbtn="@"]{max-width:60px}
|
||||
|
After Width: | Height: | Size: 784 KiB |
@@ -0,0 +1,16 @@
|
||||
<svg version="1.1" id="loader-1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="40px" height="40px" viewBox="0 0 40 40" enable-background="new 0 0 40 40" xml:space="preserve">
|
||||
<path opacity="0.2" fill="#000" d="M20.201,5.169c-8.254,0-14.946,6.692-14.946,14.946c0,8.255,6.692,14.946,14.946,14.946
|
||||
s14.946-6.691,14.946-14.946C35.146,11.861,28.455,5.169,20.201,5.169z M20.201,31.749c-6.425,0-11.634-5.208-11.634-11.634
|
||||
c0-6.425,5.209-11.634,11.634-11.634c6.425,0,11.633,5.209,11.633,11.634C31.834,26.541,26.626,31.749,20.201,31.749z"/>
|
||||
<path fill="#f7f8f9" d="M26.013,10.047l1.654-2.866c-2.198-1.272-4.743-2.012-7.466-2.012h0v3.312h0
|
||||
C22.32,8.481,24.301,9.057,26.013,10.047z">
|
||||
<animateTransform attributeType="xml"
|
||||
attributeName="transform"
|
||||
type="rotate"
|
||||
from="0 20 20"
|
||||
to="360 20 20"
|
||||
dur="0.5s"
|
||||
repeatCount="indefinite"/>
|
||||
</path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 970 B |
@@ -0,0 +1,5 @@
|
||||
<svg width="106" height="106" viewBox="0 0 106 106" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="53" cy="53" r="53" fill="#40D8A1"/>
|
||||
<path d="M29 52.5L47.5 70.5" stroke="white" stroke-width="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<line x1="79" y1="40.0711" x2="48.0711" y2="71" stroke="white" stroke-width="10" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 377 B |
@@ -0,0 +1,5 @@
|
||||
<svg width="568" height="179" viewBox="0 0 568 179" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M568 15H425V166H568V15ZM505 42H527V67H505V42ZM505 113H527V138H505V113Z" fill="#D9D9D9"/>
|
||||
<path d="M25 26C25 42.125 6.1371 63.9636 6.00087 89.8798C5.86219 116.263 25 141.356 25 155" stroke="#3A3A3A" stroke-width="10"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M50 0C33.4315 0 20 12.0816 20 26.9849V152.015C20 166.919 33.4315 179 50 179H448C452.418 179 456 175.778 456 171.804V7.19598C456 3.22175 452.418 0 448 0H50ZM260.449 77.4359L284 91.0042L260.449 104.571V94.8762H169.513L192.956 119.585C194.95 121.18 197.563 122.298 200.248 122.359C214.287 122.359 219.225 122.368 219.225 122.368V114.501H242.782V138H219.225V130.122L200.477 130.126C195.204 130.126 189.677 127.242 186.161 123.86C186.259 123.958 186.358 124.068 186.159 123.858C186.082 123.773 161.295 97.6508 161.295 97.6508C159.307 96.0562 156.702 94.9429 154.024 94.8748H124.433C124.398 94.8767 124.364 94.8748 124.329 94.8748H110.951C109.146 103.857 101.202 110.624 91.6709 110.624C80.8066 110.624 72 101.838 72 90.9991C72 80.1635 80.8066 71.3776 91.6709 71.3776C101.2 71.3776 109.144 78.1393 110.949 87.1139H124.566C127.249 87.0501 129.857 85.9382 131.848 84.3454C131.848 84.3454 156.64 58.2211 156.715 58.1375C156.916 57.928 156.816 58.0351 156.72 58.1356C160.237 54.7524 165.761 51.8665 171.034 51.8665L190.487 51.8698C192.096 47.2996 196.419 44 201.558 44C208.059 44 213.334 49.2609 213.334 55.7516C213.334 62.2395 208.058 67.5023 201.558 67.5023C196.419 67.5023 192.096 64.2009 190.487 59.6269C188.113 59.6316 181.664 59.6344 170.803 59.6344C168.118 59.6964 165.509 60.8154 163.514 62.4105L140.076 87.1149H260.449V77.4359Z" fill="#3A3A3A"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
@@ -0,0 +1 @@
|
||||
<!DOCTYPE html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Vue App</title><link href="/css/chunk-0d175fb6.3b87afd9.css" rel="prefetch"><link href="/css/chunk-7cb613d5.030f6319.css" rel="prefetch"><link href="/js/chunk-0d175fb6.abef9fad.js" rel="prefetch"><link href="/js/chunk-2d0b23b3.d02b548c.js" rel="prefetch"><link href="/js/chunk-2d0b6d35.656552d9.js" rel="prefetch"><link href="/js/chunk-2d0baeaa.14768760.js" rel="prefetch"><link href="/js/chunk-2d0cfa15.19c6d0ba.js" rel="prefetch"><link href="/js/chunk-2e6079ad.851ba167.js" rel="prefetch"><link href="/js/chunk-7cb613d5.5349d43e.js" rel="prefetch"><link href="/css/app.f82c83ee.css" rel="preload" as="style"><link href="/css/chunk-vendors.466ce708.css" rel="preload" as="style"><link href="/js/app.3056ab4c.js" rel="preload" as="script"><link href="/js/chunk-vendors.3521aad3.js" rel="preload" as="script"><link href="/css/chunk-vendors.466ce708.css" rel="stylesheet"><link href="/css/app.f82c83ee.css" rel="stylesheet"></head><body><div id="app"></div><script src="/js/chunk-vendors.3521aad3.js"></script><script src="/js/app.3056ab4c.js"></script></body></html>
|
||||
@@ -0,0 +1,2 @@
|
||||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-0d175fb6"],{"192d":function(e,s,t){"use strict";t("fd7d")},9152:function(e,s,t){"use strict";t.r(s);var a=function(){var e=this,s=e._self._c;return s("div",{staticClass:"wrapper"},[e.save_usb&&e.init?s("div",{staticClass:"center"},[s("div",{staticClass:"canvas-anim",class:{"anim-connect":!e.saved&&!e.usb},on:{click:function(s){return e.new_capture()}}},[!e.saved&&e.usb?s("div",{staticClass:"icon-spinner"}):e._e(),e.saved?s("div",{staticClass:"icon-success"}):e._e(),s("div",{staticClass:"icon-usb"}),s("div",{staticClass:"icon-usb-plug"})]),e.saved||e.usb?e._e():s("p",{staticClass:"legend"},[s("br"),e._v(e._s(e.$t("save-capture.please_connect")))]),!e.saved&&e.usb?s("p",{staticClass:"legend"},[s("br"),e._v(e._s(e.$t("save-capture.we_are_saving")))]):e._e(),e.saved?s("p",{staticClass:"legend"},[s("br"),e._v(e._s(e.$t("save-capture.tap_msg")))]):e._e()]):!e.save_usb&&e.init?s("div",{staticClass:"center"},[s("div",[s("p",{staticClass:"legend"},[e._v(e._s(e.$t("save-capture.capture_download"))),s("br"),s("br"),s("br")]),s("button",{staticClass:"btn btn-primary",on:{click:function(s){return e.new_capture()}}},[e._v(e._s(e.$t("save-capture.start_capture_btn")))]),s("iframe",{staticClass:"frame-download",attrs:{src:e.download_url}})])]):e._e()])},n=[],c=(t("14d9"),t("bc3a")),i=t.n(c),u=t("a18c"),o={name:"save-capture",components:{},data(){return{usb:!1,saved:!1,save_usb:!1,init:!1}},props:{capture_token:String},methods:{check_usb:function(){console.log("[save-capture.vue] Checking connected USB device..."),i.a.get("/api/save/usb-check",{timeout:3e4}).then(e=>{e.data.status&&(this.usb=!0,clearInterval(this.interval),this.save_capture())})},save_capture:function(){var e=this.capture_token;console.log("[save-capture.vue] Saving the capture on USB"),i.a.get(`/api/save/save-capture/${e}/usb`,{timeout:3e4}).then(e=>{e.data.status&&(this.saved=!0,console.log("[save-capture.vue] Capture saved, going back to main view"),this.timeout=setTimeout(()=>u["a"].push("/"),6e4))})},new_capture:function(){console.log("[save-capture.vue] Capture saved, generating a new access point"),clearTimeout(this.timeout),u["a"].push({name:"generate-ap"})}},created:function(){console.log("[save-capture.vue] Showing save-capture.vue"),window.config.download_links?(console.log("[save-capture.vue] Using download links instead of USB key"),this.init=!0,this.save_usb=!1,this.download_url=`/api/save/save-capture/${this.capture_token}/url`):(console.log("[save-capture.vue] Using USB key to save the capture"),this.init=!0,this.save_usb=!0,this.interval=setInterval(()=>{this.check_usb()},500))}},r=o,v=(t("192d"),t("2877")),l=Object(v["a"])(r,a,n,!1,null,null,null);s["default"]=l.exports},fd7d:function(e,s,t){}}]);
|
||||
//# sourceMappingURL=chunk-0d175fb6.abef9fad.js.map
|
||||
@@ -0,0 +1,2 @@
|
||||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-2d0b23b3"],{"22da":function(e,t,a){"use strict";a.r(t);var s=function(){var e=this,t=e._self._c;return t("div",{staticClass:"wrapper"},[t("div",{staticClass:"center"},[t("svg",{staticStyle:{margin:"auto",background:"none",display:"block","shape-rendering":"auto"},attrs:{xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",width:"194px",height:"194px",viewBox:"0 0 100 100",preserveAspectRatio:"xMidYMid"}},[t("circle",{attrs:{cx:"50",cy:"50",r:"0",fill:"none",stroke:"#dfdfdf","stroke-width":"1"}},[t("animate",{attrs:{attributeName:"r",repeatCount:"indefinite",dur:"2.941176470588235s",values:"0;43",keyTimes:"0;1",keySplines:"0 0.2 0.8 1",calcMode:"spline",begin:"0s"}}),t("animate",{attrs:{attributeName:"opacity",repeatCount:"indefinite",dur:"2.941176470588235s",values:"1;0",keyTimes:"0;1",keySplines:"0.2 0 0.8 1",calcMode:"spline",begin:"0s"}})]),t("circle",{attrs:{cx:"50",cy:"50",r:"0",fill:"none",stroke:"#dadada","stroke-width":"1"}},[t("animate",{attrs:{attributeName:"r",repeatCount:"indefinite",dur:"2.941176470588235s",values:"0;43",keyTimes:"0;1",keySplines:"0 0.2 0.8 1",calcMode:"spline",begin:"-1.4705882352941175s"}}),t("animate",{attrs:{attributeName:"opacity",repeatCount:"indefinite",dur:"2.941176470588235s",values:"1;0",keyTimes:"0;1",keySplines:"0.2 0 0.8 1",calcMode:"spline",begin:"-1.4705882352941175s"}})])]),e.long_waiting?e._e():t("p",{staticClass:"legend"},[e._v(e._s(e.$t("analysis.please_wait_msg")))]),e.long_waiting?t("p",{staticClass:"legend fade-in"},[e._v(e._s(e.$t("analysis.some_time_msg")))]):e._e()])])},i=[],n=a("a18c"),l=a("bc3a"),r=a.n(l),o={name:"analysis",data(){return{check_alerts:!1,long_waiting:!1}},props:{capture_token:String},methods:{start_analysis:function(){console.log("[analysis.vue] Starting the analysis..."),setTimeout(function(){this.long_waiting=!0}.bind(this),15e3),r.a.get("/api/analysis/start/"+this.capture_token,{timeout:6e4}).then(e=>{"Analysis started"==e.data.message&&(this.check_alerts=setInterval(()=>{this.get_alerts()},500))}).catch(e=>{console.log(e)})},get_alerts:function(){r.a.get("/api/analysis/report/"+this.capture_token,{timeout:6e4}).then(e=>{"No report yet"!=e.data.message?(console.log("[analysis.vue] Got the results analysis, moving to report view"),clearInterval(this.check_alerts),this.long_waiting=!1,n["a"].replace({name:"report",params:{alerts:e.data.alerts,device:e.data.device,methods:e.data.methods,pcap:e.data.pcap,records:e.data.records,capture_token:this.capture_token}})):console.log("[analysis.vue] No analysis results yet")}).catch(e=>{console.log(e)})}},created:function(){console.log("[analysis.vue] Showing analysis.vue"),this.start_analysis()}},c=o,d=a("2877"),p=Object(d["a"])(c,s,i,!1,null,null,null);t["default"]=p.exports}}]);
|
||||
//# sourceMappingURL=chunk-2d0b23b3.d02b548c.js.map
|
||||
@@ -0,0 +1,2 @@
|
||||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-2d0b6d35"],{"1f8b":function(e,t,s){"use strict";s.r(t);var n=function(){var e=this,t=e._self._c;return t("div",{staticClass:"wrapper-dark"},[t("div",{staticClass:"center"},[t("h1",{attrs:{id:"title"}},[e._v(e._s(e.title))]),t("span",{staticClass:"loading loading-lg loadingsplash"}),t("span",{staticClass:"message_splash"},[e._v(e._s(e.message))])])])},a=[],o=s("a18c"),i=s("bc3a"),l=s.n(i),c={name:"splash-screen",components:{},data(){return{internet:!1,message:"",title:"SPYGUARD",letters:["SSS§ṠSSSSS","PPPþ⒫PPPP","YYYÿYYYÿYȲYY","GGḠGGGǤG¬G","UÚUUÜUɄUUU","AAAAÄA¬AAA","RЯRɌRRRɌʭR","DD¬DDDDƋDD"]}},methods:{delete_captures:function(){this.message="Doing some cleaning...",console.log("[splash-screen.vue] Deleting previous captures..."),l.a.get("/api/misc/delete-captures",{timeout:3e4}),setTimeout(function(){this.goto_home()}.bind(this),2e3)},goto_home:function(){console.log("[splash-screen.vue] Going to home..."),this.message="Going to home...",o["a"].replace({name:"home"})},generate_random:function(e=0,t=1e3){let s=t-e,n=Math.random();return n=Math.floor(n*s),n+=e,n}},created:function(){window.access_point="",console.log("[splash-screen.vue] Welcome to SPYGUARD"),setInterval(function(){let e="";this.letters.forEach(t=>{e+=t.charAt(this.generate_random(0,9))}),this.title=e,setTimeout(function(){this.title="SPYGUARD"}.bind(this),this.generate_random(30,100))}.bind(this),this.generate_random(500,4e3)),this.delete_captures()}},r=c,h=s("2877"),u=Object(h["a"])(r,n,a,!1,null,null,null);t["default"]=u.exports}}]);
|
||||
//# sourceMappingURL=chunk-2d0b6d35.656552d9.js.map
|
||||
@@ -0,0 +1,2 @@
|
||||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-2d0baeaa"],{"38f5":function(e,t,a){"use strict";a.r(t);var s=function(){var e=this,t=e._self._c;return t("div",{staticClass:"wrapper"},[t("div",{staticClass:"center"},[0==e.error?t("div",[e.ssid_name?t("div",[t("div",{staticClass:"card apcard",on:{click:function(t){return e.generate_ap()}}},[t("div",{staticClass:"columns"},[t("div",{staticClass:"column col-5"},[t("center",[t("img",{attrs:{src:e.ssid_qr,id:"qrcode"}})])],1),t("div",{staticClass:"divider-vert white-bg",attrs:{"data-content":"OR"}}),t("div",{staticClass:"column col-5"},[t("br"),t("span",{staticClass:"light-grey"},[e._v(e._s(e.$t("generate-ap.network_name"))+" ")]),t("br"),t("h4",[e._v(e._s(e.ssid_name))]),t("span",{staticClass:"light-grey"},[e._v(e._s(e.$t("generate-ap.network_password"))+" ")]),t("br"),t("h4",[e._v(e._s(e.ssid_password))])])])]),t("br"),t("br"),t("br"),t("br"),e._v(" "),t("br"),t("br"),t("br"),t("br"),t("br"),t("br"),t("span",{staticClass:"legend"},[e._v(e._s(e.$t("generate-ap.tap_msg")))])]):t("div",[t("svg",{staticStyle:{margin:"auto",background:"none",display:"block","shape-rendering":"auto"},attrs:{xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",width:"194px",height:"194px",viewBox:"0 0 100 100",preserveAspectRatio:"xMidYMid"}},[t("circle",{attrs:{cx:"50",cy:"50",r:"0",fill:"none",stroke:"#dfdfdf","stroke-width":"1"}},[t("animate",{attrs:{attributeName:"r",repeatCount:"indefinite",dur:"2.941176470588235s",values:"0;43",keyTimes:"0;1",keySplines:"0 0.2 0.8 1",calcMode:"spline",begin:"0s"}}),t("animate",{attrs:{attributeName:"opacity",repeatCount:"indefinite",dur:"2.941176470588235s",values:"1;0",keyTimes:"0;1",keySplines:"0.2 0 0.8 1",calcMode:"spline",begin:"0s"}})]),t("circle",{attrs:{cx:"50",cy:"50",r:"0",fill:"none",stroke:"#dadada","stroke-width":"1"}},[t("animate",{attrs:{attributeName:"r",repeatCount:"indefinite",dur:"2.941176470588235s",values:"0;43",keyTimes:"0;1",keySplines:"0 0.2 0.8 1",calcMode:"spline",begin:"-1.4705882352941175s"}}),t("animate",{attrs:{attributeName:"opacity",repeatCount:"indefinite",dur:"2.941176470588235s",values:"1;0",keyTimes:"0;1",keySplines:"0.2 0 0.8 1",calcMode:"spline",begin:"-1.4705882352941175s"}})])]),t("p",{staticClass:"legend"},[e._v(e._s(e.$t("generate-ap.generate_ap_msg")))])])]):t("div",[t("p",[t("strong",{domProps:{innerHTML:e._s(e.$t("generate-ap.error_msg1"))}}),t("br"),t("br"),t("span",{domProps:{innerHTML:e._s(e.$t("generate-ap.error_msg2"))}}),t("br"),t("br")]),e.reboot_option?t("button",{staticClass:"btn",on:{click:function(t){return e.reboot()}}},[e._v(e._s(e.$t("generate-ap.restart_btn")))]):e._e()])])])},n=[],r=a("bc3a"),i=a.n(r),o=a("a18c"),c={name:"generate-ap",components:{},data(){return{ssid_name:!1,ssid_qr:!1,ssid_password:!1,capture_token:!1,capture_start:!1,interval:!1,error:!1,reboot_option:window.config.reboot_option,attempts:3}},methods:{generate_ap:function(){console.log("[generate-ap.vue] Trying to start a new access point"),clearInterval(this.interval),this.ssid_name=!1,i.a.get("/api/network/ap/start",{timeout:3e4}).then(e=>this.show_ap(e.data))},show_ap:function(e){e.status?(console.log("[generate-ap.vue] Access point created, showing SSID"),window.access_point=e.ssid,this.ssid_name=e.ssid,this.ssid_password=e.password,this.ssid_qr=e.qrcode,this.start_capture()):(console.log("[generate-ap.vue] Issue when creating AP, let's retry"),0!=this.attempts?(setTimeout(function(){this.generate_ap()}.bind(this),1e4),this.attempts-=1):(console.log("[generate-ap.vue] Fatal error when creating AP, showing the error message"),this.error=!0))},start_capture:function(){console.log("[generate-ap.vue] Starting the capture in background"),i.a.get("/api/capture/start",{timeout:3e4}).then(e=>this.get_capture_token(e.data))},reboot:function(){console.log("[generate-ap.vue] Rebooting the device"),i.a.get("/api/misc/reboot",{timeout:3e4}).then(e=>{console.log(e)})},get_capture_token:function(e){e.status&&(console.log("[generate-ap.vue] Capture token retrieved, waiting a device to connect"),this.capture_token=e.capture_token,this.capture_start=Date.now(),this.get_device())},get_device:function(){this.interval=setInterval(()=>{i.a.get("/api/device/get/"+this.capture_token,{timeout:3e4}).then(e=>this.check_device(e.data))},500)},check_device:function(e){if(e.status){console.log("[generate-ap.vue] Device connected, going to capture view."),clearInterval(this.interval);var t=this.capture_token,a=this.capture_start,s=e.name;o["a"].replace({name:"capture",params:{capture_token:t,capture_start:a,device_name:s}})}}},created:function(){console.log("[generate-ap.vue] Showing generate-ap.vue"),this.generate_ap()}},p=c,d=a("2877"),l=Object(d["a"])(p,s,n,!1,null,null,null);t["default"]=l.exports}}]);
|
||||
//# sourceMappingURL=chunk-2d0baeaa.14768760.js.map
|
||||
@@ -0,0 +1,2 @@
|
||||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-2d0cfa15"],{6511:function(t,n,s){"use strict";s.r(n);var e=function(){var t=this,n=t._self._c;return n("div",{staticClass:"wrapper"},[n("div",{staticClass:"center"},[n("h3",{staticClass:"lobster"},[t._v(t._s(t.$t("home.welcome_msg")))]),n("p",[t._v(t._s(t.$t("home.help_msg")))]),n("button",{staticClass:"btn btn-primary",on:{click:function(n){return t.next()}}},[t._v(t._s(t.$t("home.start_btn")))])])])},a=[],c=(s("14d9"),s("a18c")),o={name:"home",methods:{next:function(){c["a"].push({name:"generate-ap"})}}},r=o,i=s("2877"),l=Object(i["a"])(r,e,a,!1,null,null,null);n["default"]=l.exports}}]);
|
||||
//# sourceMappingURL=chunk-2d0cfa15.19c6d0ba.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["webpack:///./src/views/home.vue","webpack:///src/views/home.vue","webpack:///./src/views/home.vue?d449","webpack:///./src/views/home.vue?46ae"],"names":["render","_vm","this","_c","_self","staticClass","_v","_s","$t","on","$event","next","staticRenderFns","name","methods","router","component"],"mappings":"uHAAA,IAAIA,EAAS,WAAkB,IAAIC,EAAIC,KAAKC,EAAGF,EAAIG,MAAMD,GAAG,OAAOA,EAAG,MAAM,CAACE,YAAY,WAAW,CAACF,EAAG,MAAM,CAACE,YAAY,UAAU,CAACF,EAAG,KAAK,CAACE,YAAY,WAAW,CAACJ,EAAIK,GAAGL,EAAIM,GAAGN,EAAIO,GAAG,wBAAwBL,EAAG,IAAI,CAACF,EAAIK,GAAGL,EAAIM,GAAGN,EAAIO,GAAG,qBAAqBL,EAAG,SAAS,CAACE,YAAY,kBAAkBI,GAAG,CAAC,MAAQ,SAASC,GAAQ,OAAOT,EAAIU,UAAU,CAACV,EAAIK,GAAGL,EAAIM,GAAGN,EAAIO,GAAG,2BAErXI,EAAkB,G,wBCWP,GACfC,YACAC,SACAH,gBACAI,aAAAF,wBCjB8U,I,YCO1UG,EAAY,eACd,EACAhB,EACAY,GACA,EACA,KACA,KACA,MAIa,aAAAI,E","file":"js/chunk-2d0cfa15.19c6d0ba.js","sourcesContent":["var render = function render(){var _vm=this,_c=_vm._self._c;return _c('div',{staticClass:\"wrapper\"},[_c('div',{staticClass:\"center\"},[_c('h3',{staticClass:\"lobster\"},[_vm._v(_vm._s(_vm.$t(\"home.welcome_msg\")))]),_c('p',[_vm._v(_vm._s(_vm.$t(\"home.help_msg\")))]),_c('button',{staticClass:\"btn btn-primary\",on:{\"click\":function($event){return _vm.next()}}},[_vm._v(_vm._s(_vm.$t(\"home.start_btn\")))])])])\n}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","<template>\r\n <div class=\"wrapper\">\r\n <div class=\"center\">\r\n <h3 class=\"lobster\">{{ $t(\"home.welcome_msg\") }}</h3>\r\n <p>{{ $t(\"home.help_msg\") }}</p>\r\n <button class=\"btn btn-primary\" v-on:click=\"next()\">{{ $t(\"home.start_btn\") }}</button>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script>\r\nimport router from '../router'\r\n\r\nexport default {\r\n name: 'home',\r\n methods: {\r\n next: function() {\r\n router.push({ name: 'generate-ap' });\r\n }\r\n }\r\n}\r\n</script>\r\n","import mod from \"-!../../node_modules/cache-loader/dist/cjs.js??ref--13-0!../../node_modules/thread-loader/dist/cjs.js!../../node_modules/babel-loader/lib/index.js!../../node_modules/cache-loader/dist/cjs.js??ref--1-0!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./home.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/cache-loader/dist/cjs.js??ref--13-0!../../node_modules/thread-loader/dist/cjs.js!../../node_modules/babel-loader/lib/index.js!../../node_modules/cache-loader/dist/cjs.js??ref--1-0!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./home.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./home.vue?vue&type=template&id=66a1090d&\"\nimport script from \"./home.vue?vue&type=script&lang=js&\"\nexport * from \"./home.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports"],"sourceRoot":""}
|
||||
@@ -0,0 +1,51 @@
|
||||
{
|
||||
"name": "@felixaime/spyguard",
|
||||
"version": "1.0.0",
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve --copy --port=4202",
|
||||
"build": "vue-cli-service build",
|
||||
"lint": "vue-cli-service lint",
|
||||
"vue-i18n-extract": "vue-i18n-extract report -a -v './src/**/*.?(js|vue)' -l './src/locales/*.?(json|yaml|yml)'"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fnando/sparkline": "^0.3.10",
|
||||
"axios": "^0.21.4",
|
||||
"core-js": "^3.6.5",
|
||||
"sass": "^1.27.0",
|
||||
"sass-loader": "^10.0.4",
|
||||
"simple-keyboard": "^2.30.25",
|
||||
"simple-keyboard-layouts": "^3.1.147",
|
||||
"vue": "^2.6.12",
|
||||
"vue-i18n": "^8.22.4",
|
||||
"vue-router": "^3.4.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vue/cli-plugin-babel": "~4.5.6",
|
||||
"@vue/cli-plugin-eslint": "~4.5.6",
|
||||
"@vue/cli-service": "~4.5.6",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"eslint": "^7.9.0",
|
||||
"eslint-plugin-vue": "^6.2.2",
|
||||
"vue-i18n-extract": "1.1.10",
|
||||
"vue-template-compiler": "^2.6.12"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"root": true,
|
||||
"env": {
|
||||
"node": true
|
||||
},
|
||||
"extends": [
|
||||
"plugin:vue/essential",
|
||||
"eslint:recommended"
|
||||
],
|
||||
"parserOptions": {
|
||||
"parser": "babel-eslint"
|
||||
},
|
||||
"rules": {}
|
||||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
"last 2 versions",
|
||||
"not dead"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"python.pythonPath": "/usr/local/opt/python@3.8/bin/python3.8"
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
<template>
|
||||
<div id="app">
|
||||
<Modals />
|
||||
<router-view />
|
||||
<Controls />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
@import './assets/spectre.min.css';
|
||||
@import './assets/custom.css';
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import axios from 'axios'
|
||||
import Controls from "@/components/Controls.vue"
|
||||
import Modals from "@/components/Modals.vue"
|
||||
|
||||
document.title = 'SPYGUARD'
|
||||
|
||||
export default {
|
||||
name: 'app',
|
||||
components: {
|
||||
Controls,
|
||||
Modals
|
||||
}, data() {
|
||||
return {
|
||||
splash: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
set_lang: function() {
|
||||
if (window.config.user_lang) {
|
||||
var lang = window.config.user_lang
|
||||
if (Object.keys(this.$i18n.messages).includes(lang)) {
|
||||
this.$i18n.locale = lang
|
||||
document.querySelector('html').setAttribute('lang', lang)
|
||||
}
|
||||
}
|
||||
},
|
||||
get_config: function() {
|
||||
axios.get('/api/misc/config', { timeout: 60000 })
|
||||
.then(response => {
|
||||
window.config = response.data
|
||||
this.set_lang();
|
||||
})
|
||||
.catch(error => { console.log(error) });
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
$route (){
|
||||
if ( ["loader"].includes(this.$router.currentRoute.name)){
|
||||
this.splash = true;
|
||||
} else {
|
||||
this.splash = false;
|
||||
}
|
||||
}
|
||||
},
|
||||
created: function() {
|
||||
window.config = {}
|
||||
this.get_config();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
After Width: | Height: | Size: 805 KiB |
|
After Width: | Height: | Size: 784 KiB |
@@ -0,0 +1,4 @@
|
||||
<svg width="112" height="195" viewBox="0 0 112 195" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<line x1="3.5" y1="3.5" x2="3.50001" y2="191.5" stroke="black" stroke-width="7" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<rect x="7" width="105" height="195" fill="#F7F8F9"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 294 B |
@@ -0,0 +1,16 @@
|
||||
<svg version="1.1" id="loader-1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="40px" height="40px" viewBox="0 0 40 40" enable-background="new 0 0 40 40" xml:space="preserve">
|
||||
<path opacity="0.2" fill="#000" d="M20.201,5.169c-8.254,0-14.946,6.692-14.946,14.946c0,8.255,6.692,14.946,14.946,14.946
|
||||
s14.946-6.691,14.946-14.946C35.146,11.861,28.455,5.169,20.201,5.169z M20.201,31.749c-6.425,0-11.634-5.208-11.634-11.634
|
||||
c0-6.425,5.209-11.634,11.634-11.634c6.425,0,11.633,5.209,11.633,11.634C31.834,26.541,26.626,31.749,20.201,31.749z"/>
|
||||
<path fill="#f7f8f9" d="M26.013,10.047l1.654-2.866c-2.198-1.272-4.743-2.012-7.466-2.012h0v3.312h0
|
||||
C22.32,8.481,24.301,9.057,26.013,10.047z">
|
||||
<animateTransform attributeType="xml"
|
||||
attributeName="transform"
|
||||
type="rotate"
|
||||
from="0 20 20"
|
||||
to="360 20 20"
|
||||
dur="0.5s"
|
||||
repeatCount="indefinite"/>
|
||||
</path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 970 B |
@@ -0,0 +1,5 @@
|
||||
<svg width="106" height="106" viewBox="0 0 106 106" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="53" cy="53" r="53" fill="#40D8A1"/>
|
||||
<path d="M29 52.5L47.5 70.5" stroke="white" stroke-width="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<line x1="79" y1="40.0711" x2="48.0711" y2="71" stroke="white" stroke-width="10" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 377 B |
@@ -0,0 +1,5 @@
|
||||
<svg width="568" height="179" viewBox="0 0 568 179" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M568 15H425V166H568V15ZM505 42H527V67H505V42ZM505 113H527V138H505V113Z" fill="#D9D9D9"/>
|
||||
<path d="M25 26C25 42.125 6.1371 63.9636 6.00087 89.8798C5.86219 116.263 25 141.356 25 155" stroke="#3A3A3A" stroke-width="10"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M50 0C33.4315 0 20 12.0816 20 26.9849V152.015C20 166.919 33.4315 179 50 179H448C452.418 179 456 175.778 456 171.804V7.19598C456 3.22175 452.418 0 448 0H50ZM260.449 77.4359L284 91.0042L260.449 104.571V94.8762H169.513L192.956 119.585C194.95 121.18 197.563 122.298 200.248 122.359C214.287 122.359 219.225 122.368 219.225 122.368V114.501H242.782V138H219.225V130.122L200.477 130.126C195.204 130.126 189.677 127.242 186.161 123.86C186.259 123.958 186.358 124.068 186.159 123.858C186.082 123.773 161.295 97.6508 161.295 97.6508C159.307 96.0562 156.702 94.9429 154.024 94.8748H124.433C124.398 94.8767 124.364 94.8748 124.329 94.8748H110.951C109.146 103.857 101.202 110.624 91.6709 110.624C80.8066 110.624 72 101.838 72 90.9991C72 80.1635 80.8066 71.3776 91.6709 71.3776C101.2 71.3776 109.144 78.1393 110.949 87.1139H124.566C127.249 87.0501 129.857 85.9382 131.848 84.3454C131.848 84.3454 156.64 58.2211 156.715 58.1375C156.916 57.928 156.816 58.0351 156.72 58.1356C160.237 54.7524 165.761 51.8665 171.034 51.8665L190.487 51.8698C192.096 47.2996 196.419 44 201.558 44C208.059 44 213.334 49.2609 213.334 55.7516C213.334 62.2395 208.058 67.5023 201.558 67.5023C196.419 67.5023 192.096 64.2009 190.487 59.6269C188.113 59.6316 181.664 59.6344 170.803 59.6344C168.118 59.6964 165.509 60.8154 163.514 62.4105L140.076 87.1149H260.449V77.4359Z" fill="#3A3A3A"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="margin: auto; background: none; display: block; shape-rendering: auto;" width="200px" height="200px" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid">
|
||||
<circle cx="50" cy="50" r="0" fill="none" stroke="#f3f3f3" stroke-width="2">
|
||||
<animate attributeName="r" repeatCount="indefinite" dur="1.4925373134328357s" values="0;30" keyTimes="0;1" keySplines="0 0.2 0.8 1" calcMode="spline" begin="-0.7462686567164178s"></animate>
|
||||
<animate attributeName="opacity" repeatCount="indefinite" dur="1.4925373134328357s" values="1;0" keyTimes="0;1" keySplines="0.2 0 0.8 1" calcMode="spline" begin="-0.7462686567164178s"></animate>
|
||||
</circle>
|
||||
<circle cx="50" cy="50" r="0" fill="none" stroke="#d8dddf" stroke-width="2">
|
||||
<animate attributeName="r" repeatCount="indefinite" dur="1.4925373134328357s" values="0;30" keyTimes="0;1" keySplines="0 0.2 0.8 1" calcMode="spline"></animate>
|
||||
<animate attributeName="opacity" repeatCount="indefinite" dur="1.4925373134328357s" values="1;0" keyTimes="0;1" keySplines="0.2 0 0.8 1" calcMode="spline"></animate>
|
||||
</circle>
|
||||
<!-- [ldio] generated by https://loading.io/ --></svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@@ -0,0 +1,179 @@
|
||||
<template>
|
||||
<div class="controls" v-if="display">
|
||||
<i class="battery" :class="[battery_icon]"></i>
|
||||
<div v-if="iface_out.startsWith('wl')" class="dropup">
|
||||
<i :class="[wifi_icon]" class="wifi"></i>
|
||||
<div class="dropup-content">
|
||||
<ul>
|
||||
<li v-for="network in wifi_networks" v-on:click="show_modal_wifi(network.name)" v-bind:key="network">
|
||||
<i :class="[get_wifi_icon(network.signal)]" class="wifi_mini"> </i>{{ network.name }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<i class="iocs-number" v-bind:class="{ 'border-green': iocs_number }">{{ iocs_number }} IOCs</i>
|
||||
<i v-if="ip_address" class="ip_addr" v-bind:class="{ 'border-green': internet }">{{ ip_address }} </i>
|
||||
<i v-else class="ip_addr">Not connected</i>
|
||||
<i class="home-icon" v-on:click="goto_home()"></i>
|
||||
<i class="config-icon" v-on:click="goto_backend()" v-if="backend_option"></i>
|
||||
<i class="shutdown-icon" v-on:click="show_modal_shutdown()" v-if="shutdown_option"></i>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from 'axios'
|
||||
import { EventBus } from "../main.js"
|
||||
|
||||
export default {
|
||||
name: 'Controls',
|
||||
data: function (){
|
||||
return {
|
||||
display: true,
|
||||
update_available: false,
|
||||
update_possible: false,
|
||||
shutdown_option: false,
|
||||
backend_option: false,
|
||||
remote_backend: false,
|
||||
iface_out: "",
|
||||
battery_icon: "",
|
||||
wifi_icon: "",
|
||||
wifi_networks: [],
|
||||
iocs_number: 0,
|
||||
internet: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
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) });
|
||||
},
|
||||
goto_backend: function() {
|
||||
if(this.remote_backend){
|
||||
window.location.href= `https://${location.hostname}:8443`
|
||||
}
|
||||
else {
|
||||
window.location.href= `http://${location.hostname}:8443`
|
||||
}
|
||||
},
|
||||
goto_home: function() {
|
||||
window.location.href = "/"
|
||||
},
|
||||
load_config: function() {
|
||||
setInterval(() => {
|
||||
axios.get(`/api/misc/config`, { timeout: 60000 })
|
||||
.then(response => {
|
||||
this.shutdown_option = response.data.shutdown_option
|
||||
this.backend_option = response.data.backend_option
|
||||
this.remote_backend = response.data.remote_backend
|
||||
this.battery_icon = this.get_battery_icon(response.data.battery_level)
|
||||
this.wifi_icon = this.get_wifi_icon(response.data.wifi_level)
|
||||
this.iocs_number = response.data.iocs_number
|
||||
this.iface_out = response.data.iface_out
|
||||
})
|
||||
.catch(error => { console.log(error) });
|
||||
}, 1000);
|
||||
},
|
||||
get_battery_icon: function(level){
|
||||
if (level == 101){
|
||||
return "battery_charging"
|
||||
} else if (level >= 90) {
|
||||
return "battery_full"
|
||||
} else if (level >= 80) {
|
||||
return "battery_80"
|
||||
} else if (level >= 60) {
|
||||
return "battery_60"
|
||||
} else if (level >= 40) {
|
||||
return "battery_40"
|
||||
} else if (level >= 25) {
|
||||
return "battery_25"
|
||||
} else if (level < 25) {
|
||||
return "battery_15"
|
||||
} else {
|
||||
return "battery_critical"
|
||||
}
|
||||
},
|
||||
get_wifi_icon: function(level){
|
||||
if (level >= 80) {
|
||||
return "wifi_5"
|
||||
} else if (level >= 60) {
|
||||
return "wifi_4"
|
||||
} else if (level >= 40) {
|
||||
return "wifi_3"
|
||||
} else if (level >= 20) {
|
||||
return "wifi_2"
|
||||
} else if (level >= 1) {
|
||||
return "wifi_1"
|
||||
} else {
|
||||
return "wifi_0"
|
||||
}
|
||||
},
|
||||
show_modal_shutdown: function(){
|
||||
EventBus.$emit("showModal", {"action" : "shutdown"})
|
||||
},
|
||||
show_modal_wifi: function(network_name){
|
||||
EventBus.$emit("showModal", {"action" : "wifi", "network_name" : network_name})
|
||||
},
|
||||
get_wifi_networks: function(){
|
||||
setInterval(() => {
|
||||
axios.get('/api/network/wifi/list', { timeout: 10000 })
|
||||
.then(response => {
|
||||
this.wifi_networks = []
|
||||
response.data.networks.forEach( network => {
|
||||
if(network.name != window.access_point){
|
||||
this.wifi_networks.push(network);
|
||||
}
|
||||
})
|
||||
}).catch(error => {
|
||||
console.log(error)
|
||||
});
|
||||
}, 1000);
|
||||
},
|
||||
check_internet: function() {
|
||||
setInterval(() => {
|
||||
axios.get('/api/network/status', { timeout: 30000 })
|
||||
.then(response => {
|
||||
if (response.data.internet){
|
||||
this.internet = true
|
||||
this.ip_address = response.data.ip_out
|
||||
} else {
|
||||
this.internet = false
|
||||
this.ip_address = false
|
||||
}
|
||||
})
|
||||
.catch(err => (console.log(err)))
|
||||
}, 1000);
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
$route (){
|
||||
if ( ["loader"].includes(this.$router.currentRoute.name)){
|
||||
this.display = false;
|
||||
} else {
|
||||
this.display = true;
|
||||
}
|
||||
}
|
||||
},
|
||||
created: function() {
|
||||
this.load_config();
|
||||
this.check_internet();
|
||||
this.get_wifi_networks();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,150 @@
|
||||
<template>
|
||||
<div v-if="display">
|
||||
<div class="blurred-wrapper" v-on:click="hide_modal()"></div>
|
||||
<div class="modal-window" v-if="display_shudown">
|
||||
<div class="modal-content">
|
||||
<p>{{ $t("modals.want_to_quit") }}</p>
|
||||
<button class="btn btn-primary" v-on:click="hide_modal()">{{ $t("modals.no_go_back") }}</button> <button class="btn btn-primary" v-on:click="shutdown()">{{ $t("modals.yes_continue") }}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-window" v-if="display_whitelist">
|
||||
<div class="modal-content">
|
||||
<p v-html="$t('modals.want_to_whitelist').replace('{host}', host)"></p>
|
||||
<button class="btn btn-primary" v-on:click="hide_modal()">{{ $t("modals.no_go_back") }}</button> <button class="btn btn-primary" v-on:click="add_whitelist()">{{ $t("modals.yes_continue") }}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-window" v-if="display_wifi">
|
||||
<div class="modal-content">
|
||||
<p>{{ $t("modals.please_give_the_password") }} <strong>{{ wifi_network }}</strong> </p>
|
||||
|
||||
<div class="form-group">
|
||||
<div @click="show_password" :class="password_class"></div>
|
||||
<input :type="type" class="form-input" id="password" v-model="password" :placeholder="$t('wifi-select.wifi_password')" v-on:click="show_keyboard = true;">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button class="btn width-100" :class="[ wifi_connecting ? 'loading' : '', wifi_success ? 'btn-success' : 'btn-primary', ]" v-on:click="wifi_setup()">{{ btn_wifi_val }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="keyboard_wrapper" v-if="show_keyboard">
|
||||
<SimpleKeyboard @onChange="onChange" @onKeyPress="onKeyPress" :input="input" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from 'axios'
|
||||
import router from '../router'
|
||||
import SimpleKeyboard from "./SimpleKeyboard";
|
||||
import { EventBus } from "../main.js"
|
||||
|
||||
export default {
|
||||
name: 'Modals',
|
||||
data: function (){
|
||||
return {
|
||||
btn_wifi_val: this.$t("wifi-select.connect_to_it"),
|
||||
wifi_connecting: false,
|
||||
error: false,
|
||||
wifi_success: false,
|
||||
password: "",
|
||||
capture_token: "",
|
||||
display_whitelist: false,
|
||||
display_shudown: false,
|
||||
display_wifi: false,
|
||||
display: false,
|
||||
wifi_network: "",
|
||||
show_keyboard: false,
|
||||
input: "",
|
||||
type:"password",
|
||||
password_class:"password-show"
|
||||
}
|
||||
},
|
||||
components: {
|
||||
SimpleKeyboard
|
||||
},
|
||||
methods: {
|
||||
hide_modal: function(){
|
||||
this.display = false;
|
||||
},
|
||||
shutdown: function(){
|
||||
axios.get(`/api/misc/shutdown`, { timeout: 30000 })
|
||||
},
|
||||
add_whitelist: function(){
|
||||
axios.get(`/api/misc/whitelist/${this.host}`, { timeout: 30000 })
|
||||
this.display = false
|
||||
},
|
||||
onChange(input) {
|
||||
this.input = input
|
||||
this.password = this.input;
|
||||
},
|
||||
onKeyPress(button) {
|
||||
if (button == "{enter}") this.show_keyboard = false
|
||||
},
|
||||
onInputChange(input) {
|
||||
this.input = input.target.value;
|
||||
},
|
||||
show_password() {
|
||||
if(this.type === 'password') {
|
||||
this.type = 'text'
|
||||
this.password_class = "password-hide"
|
||||
} else {
|
||||
this.type = 'password'
|
||||
this.password_class = "password-show"
|
||||
}
|
||||
},
|
||||
wifi_setup: function() {
|
||||
if (this.password.length >= 8 ){
|
||||
this.wifi_connecting = true
|
||||
axios.post('/api/network/wifi/setup', { ssid: this.wifi_network, password: this.password }, { timeout: 60000 })
|
||||
.then(response => {
|
||||
if(response.data.status) {
|
||||
this.wifi_success = true
|
||||
this.wifi_connecting = false
|
||||
this.btn_wifi_val = this.$t('wifi-select.wifi_connected')
|
||||
setTimeout(() => {
|
||||
this.display = false
|
||||
this.btn_wifi_val = this.$t("wifi-select.connect_to_it")
|
||||
router.push('generate-ap');
|
||||
}, 1000);
|
||||
} else {
|
||||
this.btn_wifi_val = this.$t('wifi-select.wifi_not_connected')
|
||||
this.wifi_connecting = false
|
||||
setTimeout(() => {
|
||||
this.btn_wifi_val = this.$t("wifi-select.connect_to_it")
|
||||
}, 1000);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
created: function() {
|
||||
EventBus.$on("showModal", args => {
|
||||
this.input = ""
|
||||
if(args.action == "shutdown"){
|
||||
this.show_keyboard = false
|
||||
this.display_wifi = false
|
||||
this.display_shudown = true
|
||||
this.display_whitelist = false
|
||||
this.display = true
|
||||
} else if(args.action == "wifi"){
|
||||
this.wifi_connecting = false
|
||||
this.wifi_success = false
|
||||
this.password = ""
|
||||
this.btnval = this.$t("wifi-select.connect_to_it");
|
||||
this.display_shudown = false
|
||||
this.display_wifi = true
|
||||
this.display_whitelist = false
|
||||
this.wifi_network = args.network_name
|
||||
this.display = true
|
||||
} else if(args.action == "whitelist"){
|
||||
this.show_keyboard = false
|
||||
this.display_wifi = false
|
||||
this.display_shudown = false
|
||||
this.display_whitelist = true
|
||||
this.host = args.host
|
||||
this.display = true
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,70 @@
|
||||
<template>
|
||||
<div :class="keyboardClass"></div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Keyboard from "simple-keyboard";
|
||||
import "simple-keyboard/build/css/index.css";
|
||||
import layout from "simple-keyboard-layouts/build/layouts/french";
|
||||
|
||||
export default {
|
||||
name: "SimpleKeyboard",
|
||||
props: {
|
||||
keyboardClass: {
|
||||
default: "simple-keyboard",
|
||||
type: String
|
||||
},
|
||||
input: {
|
||||
type: String
|
||||
}
|
||||
},
|
||||
data: () => ({
|
||||
keyboard: null
|
||||
}),
|
||||
mounted() {
|
||||
if(window.config.user_lang == "fr"){
|
||||
this.keyboard = new Keyboard({
|
||||
onChange: this.onChange,
|
||||
onKeyPress: this.onKeyPress,
|
||||
...layout
|
||||
});
|
||||
} else {
|
||||
this.keyboard = new Keyboard({
|
||||
onChange: this.onChange,
|
||||
onKeyPress: this.onKeyPress
|
||||
});
|
||||
}
|
||||
|
||||
},
|
||||
methods: {
|
||||
onChange(input) {
|
||||
this.$emit("onChange", input);
|
||||
},
|
||||
onKeyPress(button) {
|
||||
this.$emit("onKeyPress", button);
|
||||
|
||||
/**
|
||||
* If you want to handle the shift and caps lock buttons
|
||||
*/
|
||||
if (button === "{shift}" || button === "{lock}") this.handleShift();
|
||||
},
|
||||
handleShift() {
|
||||
let currentLayout = this.keyboard.options.layoutName;
|
||||
let shiftToggle = currentLayout === "default" ? "shift" : "default";
|
||||
|
||||
this.keyboard.setOptions({
|
||||
layoutName: shiftToggle
|
||||
});
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
input(input) {
|
||||
this.keyboard.setInput(input);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||
<style scoped>
|
||||
</style>
|
||||
@@ -0,0 +1,91 @@
|
||||
{
|
||||
"home": {
|
||||
"welcome_msg": "Willkommen bei SpyGuard.",
|
||||
"help_msg": "Wir helfen Ihnen bei der Überprüfung Ihres Geräts.",
|
||||
"start_btn": "Fangen wir an!"
|
||||
},
|
||||
"analysis": {
|
||||
"question": "Möchten Sie die erfassten Kommunikationsverbindungen analysieren?",
|
||||
"no_btn": "Nein, nur speichern",
|
||||
"yes_btn": "Ja, analysieren",
|
||||
"please_wait_msg": "Bitte warten Sie, während die Analyse läuft …",
|
||||
"some_time_msg": "Dies kann eine Weile dauern …"
|
||||
},
|
||||
"capture": {
|
||||
"intercept_coms_msg": "Abfangen der Kommunikationsverbindungen von ",
|
||||
"stop_btn": "Aufnahme beenden"
|
||||
},
|
||||
"generate-ap": {
|
||||
"network_name": "Netzwerkname",
|
||||
"network_password": "Netzwerkpasswort",
|
||||
"tap_msg": "Tippen Sie auf den weißen Rahmen, um ein neues Netzwerk zu erstellen.",
|
||||
"generate_ap_msg": "Wir erstellen ein temporäres Netzwerk für Sie.",
|
||||
"error_msg1": "Leider sind während der AP-Erstellung <br>einige Fehler aufgetreten.",
|
||||
"error_msg2": "Bitte stellen Sie sicher, dass Ihr Gerät zwei WLAN-Schnittstellen besitzt,<br> und starten Sie es neu, um es erneut zu versuchen.",
|
||||
"restart_btn": "Gerät neu starten"
|
||||
},
|
||||
"report": {
|
||||
"show_full_report": "Vollständigen Bericht anzeigen",
|
||||
"start_new_capture": "Neue Aufnahme starten",
|
||||
"save_capture": "Aufnahme speichern",
|
||||
"save": "Sichern",
|
||||
"print": "Drucken",
|
||||
"numbers": [
|
||||
"null",
|
||||
"eine",
|
||||
"zwei",
|
||||
"drei",
|
||||
"vier",
|
||||
"fünf",
|
||||
"sechs",
|
||||
"sieben",
|
||||
"acht",
|
||||
"neun",
|
||||
"zehn",
|
||||
"elf"
|
||||
],
|
||||
"stalkerware_msg": "Ihr Gerät ist durch Stalkerware<br>kompromittiert; bitte sehen Sie sich den Bericht an.",
|
||||
"location_msg": "Eine Anwendung teilt Ihren<br> aktuellen Standort mit Dritten.",
|
||||
"fine_msg": "Alles sieht gut aus – kein Warnungen.",
|
||||
"high_msg": "Sie haben {nb} Warnung der Stufe \"Hoch\":<br>Ihr Gerät scheint kompromittiert zu sein.",
|
||||
"moderate_msg": "Sie haben {nb} Warnungen der Stufe \"Mittel\":<br>Ihr Gerät könnte kompromittiert sein.",
|
||||
"low_msg": "Sie haben nur {nb} Warnungen der Stufe \"Niedrig\":<br> Überprüfen Sie sie gerne.",
|
||||
"save_report": "Bericht speichern",
|
||||
"report_of": "Bericht zu",
|
||||
"detection_methods": "Nachweismethoden:",
|
||||
"indicators": "Indikatoren",
|
||||
"heuristics": "Anomalien",
|
||||
"active": "Aktiv",
|
||||
"pcap_sha1": "SHA1 erfassen:",
|
||||
"capture_started": "Capture begann mit:",
|
||||
"capture_ended": "Capture endete an:",
|
||||
"high": "Hoch",
|
||||
"moderate": "Mittel",
|
||||
"low": "Niedrig",
|
||||
"uncat_coms_table" : "Kommunikation nicht kategorisiert",
|
||||
"protocol" : "Protokoll",
|
||||
"domain_name" : "Domain",
|
||||
"ip_address": "IP-Adresse:",
|
||||
"port" : "Port"
|
||||
},
|
||||
"wifi-select": {
|
||||
"wifi_connected": "Wi-Fi verbunden",
|
||||
"wifi_not_connected": "Wi-Fi nicht verbunden. Versuchen Sie es erneut.",
|
||||
"wifi_password": "Passwort",
|
||||
"connect_to_it": "Anmelden"
|
||||
},
|
||||
"save-capture": {
|
||||
"please_connect": "Bitte schließen Sie einen USB-Stick an, um Ihre Aufnahme zu speichern.",
|
||||
"we_are_saving": "Wir speichern Ihre Aufnahme.",
|
||||
"tap_msg": "Sie können den USB-Stick antippen, um eine neue Aufnahme zu starten.",
|
||||
"capture_download": "Der Download der Aufnahme beginnt …",
|
||||
"start_capture_btn": "Noch eine Aufnahme starten"
|
||||
},
|
||||
"modals": {
|
||||
"want_to_quit": "Möchten Sie die App schließen?",
|
||||
"no_go_back": "Nein, zurück kommen.",
|
||||
"yes_continue": "Ja, weiter machen",
|
||||
"please_give_the_password": "Bitte geben Sie das Netzwerkpasswort ein: ",
|
||||
"want_to_whitelist" : "Möchten Sie <i class='ioc'>{host}</i> für die nächsten <br />Analysen hinzufügen?"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
{
|
||||
"home": {
|
||||
"welcome_msg": "Welcome to SpyGuard.",
|
||||
"help_msg": "We are going to help you to check your device.",
|
||||
"start_btn": "Let's start!"
|
||||
},
|
||||
"analysis": {
|
||||
"question": "Do you want to analyze the captured communications?",
|
||||
"no_btn": "No, just save them",
|
||||
"yes_btn": "Yes, let's do it",
|
||||
"please_wait_msg": "Please wait during the analysis...",
|
||||
"some_time_msg": "Yes, it can take some time..."
|
||||
},
|
||||
"capture": {
|
||||
"intercept_coms_msg": "Intercepting the communications of ",
|
||||
"stop_btn": "Stop the capture"
|
||||
},
|
||||
"generate-ap": {
|
||||
"network_name": "Network name",
|
||||
"network_password": "Network password",
|
||||
"tap_msg": "Tap the white frame to generate a new network.",
|
||||
"generate_ap_msg": "We generate an ephemeral network for you.",
|
||||
"error_msg1": "Unfortunately, we got some issues <br />during the AP creation.",
|
||||
"error_msg2": "Please verify that you've two WiFi interfaces on your device<br /> and try again by restarting it.",
|
||||
"restart_btn": "Restart the device"
|
||||
},
|
||||
"report": {
|
||||
"show_full_report": "Show the full report",
|
||||
"start_new_capture": "Start a new capture",
|
||||
"save_capture": "Save the capture",
|
||||
"save": "Save",
|
||||
"print": "Print",
|
||||
"numbers": [
|
||||
"zero",
|
||||
"one",
|
||||
"two",
|
||||
"three",
|
||||
"four",
|
||||
"five",
|
||||
"six",
|
||||
"seven",
|
||||
"eight",
|
||||
"nine",
|
||||
"ten",
|
||||
"eleven"
|
||||
],
|
||||
"stalkerware_msg": "Your device is compromised by<br />a Stalkerware, please check the report.",
|
||||
"location_msg": "An application is sharing your<br /> current geolocation with a third party.",
|
||||
"fine_msg": "Everything looks fine, zero alerts.",
|
||||
"high_msg": "You have {nb} high alert,<br />your device seems to be compromised.",
|
||||
"moderate_msg": "You have {nb} moderate alerts,<br />your device might be compromised.",
|
||||
"low_msg": "You have only {nb} low alerts,<br /> don't hesitate to check them.",
|
||||
"save_report": "Save the report",
|
||||
"report_of": "Report of",
|
||||
"detection_methods": "Detection methods:",
|
||||
"indicators": "Indicators",
|
||||
"heuristics": "Anomalies",
|
||||
"active": "Active",
|
||||
"pcap_sha1": "Capture SHA1:",
|
||||
"capture_started": "Capture started on:",
|
||||
"capture_ended": "Capture ended on:",
|
||||
"high": "high",
|
||||
"moderate": "moderate",
|
||||
"low": "low",
|
||||
"uncat_coms_table" : "Uncategorized communications",
|
||||
"protocol" : "Protocol",
|
||||
"domain_name" : "Domain",
|
||||
"ip_address" : "IP Address",
|
||||
"port" : "Port"
|
||||
},
|
||||
"wifi-select": {
|
||||
"wifi_connected": "Wi-Fi connected",
|
||||
"wifi_not_connected": "Wi-Fi not connected. Please retry.",
|
||||
"wifi_password": "Password",
|
||||
"connect_to_it": "Connect to it"
|
||||
},
|
||||
"save-capture": {
|
||||
"please_connect": "Please connect a USB key to save your capture.",
|
||||
"we_are_saving": "We are saving your capture.",
|
||||
"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"
|
||||
},
|
||||
"modals": {
|
||||
"want_to_quit": "Do you want to leave the application?",
|
||||
"no_go_back": "No, go back",
|
||||
"yes_continue": "Yes, continue",
|
||||
"please_give_the_password": "Please enter the password for the network: ",
|
||||
"want_to_whitelist" : "Do you want to add <i class='ioc'>{host}</i> to the whitelist<br /> for the next analysis?"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
{
|
||||
"home": {
|
||||
"welcome_msg": "Bienvenido a SpyGuard.",
|
||||
"help_msg": "Te ayudaremos a revisar tu dispositivo",
|
||||
"start_btn": "¡Empecemos!"
|
||||
},
|
||||
"analysis": {
|
||||
"question": "¿Quieres analizar las comunicaciones capturadas?",
|
||||
"no_btn": "No, solo guárdalos",
|
||||
"yes_btn": "Sí, hagámoslo",
|
||||
"please_wait_msg": "Espere durante el análisis ...",
|
||||
"some_time_msg": "Sí, puede llevar algún tiempo ..."
|
||||
},
|
||||
"capture": {
|
||||
"intercept_coms_msg": "Interceptando las comunicaciones de",
|
||||
"stop_btn": "Detener la captura"
|
||||
},
|
||||
"generate-ap": {
|
||||
"network_name": "Nombre de la red",
|
||||
"network_password": "Contraseña de red",
|
||||
"tap_msg": "Toca el marco blanco para generar una nueva red",
|
||||
"generate_ap_msg": "Generamos una red efímera para ti.",
|
||||
"error_msg1": "Desafortunadamente, tuvimos algunos problemas <br /> durante la creación del AP.",
|
||||
"error_msg2": "Verifique que tenga dos interfaces WiFi en su dispositivo <br /> e intente nuevamente reiniciando.",
|
||||
"restart_btn": "Reinicia el dispositivo"
|
||||
},
|
||||
"report": {
|
||||
"show_full_report": "Mostrar el informe completo",
|
||||
"start_new_capture": "Nueva captura",
|
||||
"save_capture": "Guardar la captura",
|
||||
"save": "Guardar",
|
||||
"print": "Imprimir",
|
||||
"numbers": [
|
||||
"cero",
|
||||
"uno",
|
||||
"dos",
|
||||
"Tres",
|
||||
"cuatro",
|
||||
"cinco",
|
||||
"seis",
|
||||
"Siete",
|
||||
"ocho",
|
||||
"nueve",
|
||||
"diez",
|
||||
"once"
|
||||
],
|
||||
"stalkerware_msg": "Su dispositivo está comprometido por <br /> un Stalkerware, por favor revise el informe.",
|
||||
"location_msg": "Una aplicación está compartiendo su <br /> geolocalización actual con un tercero.",
|
||||
"fine_msg": "Todo parece correcto, cero alertas",
|
||||
"high_msg": "Tiene {nb} alerta máxima, <br /> tu dispositivo parece estar comprometido",
|
||||
"moderate_msg": "Tiene {nb} alertas moderadas, <br /> tu dispositivo puede estar comprometido",
|
||||
"low_msg": "Solo tiene {nb} alertas bajas, <br /> por favor revíselas",
|
||||
"save_report": "Guardar el informe",
|
||||
"report_of": "Informe de",
|
||||
"detection_methods": "Métodos de detección:",
|
||||
"indicators": "Indicadores",
|
||||
"heuristics": "Anomalías",
|
||||
"active": "Activa",
|
||||
"pcap_sha1": "SHA1 de la captura:",
|
||||
"capture_started": "Captura comenzó a:",
|
||||
"capture_ended": "Captura terminó a:",
|
||||
"high": "alta",
|
||||
"moderate": "moderada",
|
||||
"low": "bajo",
|
||||
"uncat_coms_table" : "Sin categorizar Comunicaciones",
|
||||
"protocol" : "Protocolo",
|
||||
"domain_name" : "Dominio",
|
||||
"ip_address" : "Dirección IP ",
|
||||
"port" : "Puerto"
|
||||
},
|
||||
"wifi-select": {
|
||||
"wifi_connected": "Wi-Fi conectada",
|
||||
"wifi_not_connected": "Wi-Fi no conectado. Inténtelo de nuevo.",
|
||||
"wifi_password": "Contraseña",
|
||||
"connect_to_it": "Conectarse"
|
||||
},
|
||||
"save-capture": {
|
||||
"please_connect": "Conecte una llave USB para guardar su captura.",
|
||||
"we_are_saving": "Estamos guardando tu captura.",
|
||||
"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"
|
||||
},
|
||||
"modals": {
|
||||
"want_to_quit": "¿Quieres cerrar la aplicación?",
|
||||
"no_go_back": "No, volver",
|
||||
"yes_continue": "Sí, continuar",
|
||||
"please_give_the_password": "Introduzca la contraseña de la red: ",
|
||||
"want_to_whitelist" : "¿Desea incluir <i class='ioc'>{host}</i><br />en la lista blanca?"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
{
|
||||
"home": {
|
||||
"welcome_msg": "Bienvenue sur SpyGuard.",
|
||||
"help_msg": "Nous allons vous accompagner pour analyser votre appareil.",
|
||||
"start_btn": "Allons-y !"
|
||||
},
|
||||
"analysis": {
|
||||
"question": "Voulez-vous analyser les communications capturées ?",
|
||||
"no_btn": "Non, enregistrez-les.",
|
||||
"yes_btn": "Oui, allons-y !",
|
||||
"please_wait_msg": "Merci d'attendre pendant l'analyse...",
|
||||
"some_time_msg": "Oui, cela peut prendre du temps..."
|
||||
},
|
||||
"capture": {
|
||||
"intercept_coms_msg": "Interception des communications de ",
|
||||
"stop_btn": "Arrêter la capture"
|
||||
},
|
||||
"generate-ap": {
|
||||
"network_name": "Nom du réseau Wi-Fi",
|
||||
"network_password": "Mot de passe",
|
||||
"tap_msg": "Appuyez sur le cadre blanc pour générer un nouveau réseau.",
|
||||
"generate_ap_msg": "Nous générons un réseau Wi-Fi éphémère.",
|
||||
"error_msg1": "Malheureusement, nous rencontrons des problèmes <br />lors de la création du point d'accès.",
|
||||
"error_msg2": "Veuillez vérifier que vous disposez de <br /> deux interfaces WiFi sur votre appareil.",
|
||||
"restart_btn": "Restart the device"
|
||||
},
|
||||
"report": {
|
||||
"show_full_report": "Lire le rapport complet",
|
||||
"start_new_capture": "Nouvelle capture",
|
||||
"save_capture": "Sauvegarder la capture",
|
||||
"save": "Sauvegarder",
|
||||
"print": "Imprimer",
|
||||
"numbers": [
|
||||
"zéro",
|
||||
"une",
|
||||
"deux",
|
||||
"trois",
|
||||
"quatre",
|
||||
"cinq",
|
||||
"six",
|
||||
"sept",
|
||||
"huit",
|
||||
"neuf",
|
||||
"dix",
|
||||
"onze"
|
||||
],
|
||||
"stalkerware_msg": "Votre smartphone est compromis<br /> par un Stalkerware, lisez le rapport.",
|
||||
"location_msg": "Une application dévoile votre<br /> géo-localisation actelle.",
|
||||
"fine_msg": "Aucun flux suspect détecté,<br />vous avez aucune alerte.",
|
||||
"high_msg": "Vous avez {nb} alerte.s élevée.s,<br />votre appareil semble être compromis.",
|
||||
"moderate_msg": "Vous avez {nb} alerte.s moyenne.s,<br />votre appareil est peut-être compromis.",
|
||||
"low_msg": "Vous avez uniquement {nb} alerte.s basse.s<br /> n'hésitez pas à les consulter.",
|
||||
"save_report": "Archiver le rapport",
|
||||
"report_of": "Rapport de",
|
||||
"detection_methods": "Méthodes de détection :",
|
||||
"indicators": "Indicateurs",
|
||||
"heuristics": "Anomalies",
|
||||
"active": "Active",
|
||||
"pcap_sha1": "SHA1 de la capture :",
|
||||
"capture_started": "Capture débutée le :",
|
||||
"capture_ended": "Capture finie le :",
|
||||
"high": "elevée",
|
||||
"moderate": "moyenne",
|
||||
"low": "basse",
|
||||
"uncat_coms_table" : "Communications non catégorisées",
|
||||
"protocol" : "Protocole",
|
||||
"domain_name" : "Domaine",
|
||||
"ip_address" : "Adresse IP",
|
||||
"port" : "Port"
|
||||
},
|
||||
"wifi-select": {
|
||||
"wifi_connected": "Wi-Fi connecté",
|
||||
"wifi_not_connected": "Wi-Fi non connecté. Réessayez.",
|
||||
"wifi_password": "Mot de passe",
|
||||
"connect_to_it": "Se connecter"
|
||||
},
|
||||
"save-capture": {
|
||||
"please_connect": "Connectez une clé USB pour enregistrer votre capture.",
|
||||
"we_are_saving": "Nous enregistrons votre capture.",
|
||||
"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"
|
||||
},
|
||||
"modals": {
|
||||
"want_to_quit": "Voulez-vous fermer l'application ?",
|
||||
"no_go_back": "Non, revenir",
|
||||
"yes_continue": "Oui, continuer",
|
||||
"please_give_the_password": "Veuillez renseigner le mot de passe du réseau : ",
|
||||
"want_to_whitelist" : "Voulez-vous ajouter <i class='ioc'>{host}</i> à la liste blanche<br />pour les prochaines analyses ?"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
{
|
||||
"home": {
|
||||
"welcome_msg": "Benvenuto in SpyGuard.",
|
||||
"help_msg": "Verrà fornita assistenza per il controllo del dispositivo.",
|
||||
"start_btn": "Cominciamo!"
|
||||
},
|
||||
"analysis": {
|
||||
"question": "Analizzare le comunicazioni acquisite?",
|
||||
"no_btn": "No, è sufficiente salvarle",
|
||||
"yes_btn": "Sì, va bene",
|
||||
"please_wait_msg": "Analisi in corso. Attendere...",
|
||||
"some_time_msg": "Sì, l'operazione può richiedere un po' di tempo..."
|
||||
},
|
||||
"capture": {
|
||||
"intercept_coms_msg": "Intercettazione delle comunicazioni di ",
|
||||
"stop_btn": "Interrompi acquisizione"
|
||||
},
|
||||
"generate-ap": {
|
||||
"network_name": "Nome della rete",
|
||||
"network_password": "Password della rete",
|
||||
"tap_msg": "Toccare il riquadro bianco per generare una nuova rete.",
|
||||
"generate_ap_msg": "Viene generata una rete temporanea.",
|
||||
"error_msg1": "Si sono verificati alcuni problemi <br>durante la creazione del punto di accesso.",
|
||||
"error_msg2": "Verificare di disporre di due interfacce Wi-Fi nel dispositivo<br> e riprovare eseguendo il riavvio.",
|
||||
"restart_btn": "Riavvia il dispositivo"
|
||||
},
|
||||
"report": {
|
||||
"show_full_report": "Mostra il rapporto completo",
|
||||
"start_new_capture": "Avvia una nuova acquisizione",
|
||||
"save_capture": "Salva acquisizione",
|
||||
"save": "Salvare",
|
||||
"print": "Stampare",
|
||||
"numbers": [
|
||||
"zero",
|
||||
"uno",
|
||||
"due",
|
||||
"tre",
|
||||
"quattro",
|
||||
"cinque",
|
||||
"sei",
|
||||
"sette",
|
||||
"otto",
|
||||
"nove",
|
||||
"dieci",
|
||||
"undici"
|
||||
],
|
||||
"stalkerware_msg": "Il dispositivo è compromesso da<br>uno stalkerware, controllare il rapporto.",
|
||||
"location_msg": "Un'applicazione condivide la<br /> geolocalizzazione attuale con terze parti.",
|
||||
"fine_msg": "Sembra tutto a posto, <br /> non sono presenti avvisi.",
|
||||
"high_msg": "È presente {nb} avviso con priorità elevata,<br /> il dispositivo sembra compromesso.",
|
||||
"moderate_msg": "Sono presenti {nb} avvisi con priorità moderata, è possibile che il dispositivo sia compromesso.",
|
||||
"low_msg": "Sono presenti solo {nb} avvisi con priorità bassa<br /> da controllare.",
|
||||
"save_report": "Salva il rapporto",
|
||||
"report_of": "Rapporto di",
|
||||
"detection_methods": "Metodi di rilevamento:",
|
||||
"indicators": "Indicatori",
|
||||
"heuristics": "Anomalie",
|
||||
"active": "Attiva",
|
||||
"pcap_sha1": "SHA1 della cattura:",
|
||||
"capture_started": "Cattura è iniziata su:",
|
||||
"capture_ended": "Cattura terminata su:",
|
||||
"high": "elevata",
|
||||
"moderate": "moderata",
|
||||
"low": "bassa",
|
||||
"uncat_coms_table" : "Comunicazioni non categorizzate",
|
||||
"protocol" : "Protocollo",
|
||||
"domain_name" : "Dominio",
|
||||
"ip_address" : "Indirizzo IP",
|
||||
"port" : "Porto"
|
||||
},
|
||||
"wifi-select": {
|
||||
"wifi_connected": "Wi-Fi collegato",
|
||||
"wifi_not_connected": "Wi-Fi non connesso. Riprovare.",
|
||||
"wifi_password": "Password",
|
||||
"connect_to_it": "Connettersi"
|
||||
},
|
||||
"save-capture": {
|
||||
"please_connect": "Collegare una chiave USB per salvare l'acquisizione.",
|
||||
"we_are_saving": "Salvataggio dell'acquisizione in corso.",
|
||||
"tap_msg": "È possible toccare la chiave USB per avviare una nuova acquisizione.",
|
||||
"capture_download": "Il download dell'acquisizione sta per iniziare...",
|
||||
"start_capture_btn": "Avvia un'altra acquisizione"
|
||||
},
|
||||
"modals": {
|
||||
"want_to_quit": "Vuoi chiudere la app?",
|
||||
"no_go_back": "No, tornare",
|
||||
"yes_continue": "Sì, continuare",
|
||||
"please_give_the_password": "Inserire la password della rete:",
|
||||
"want_to_whitelist" : "Vuoi aggiungere <i class='ioc'>{host}</i> alla lista bianca <br /> per le prossime analisi?"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
{
|
||||
"home": {
|
||||
"welcome_msg": "Bem vindo(a) ao SpyGuard.",
|
||||
"help_msg": "Ajudaremos você a verificar o dispositivo.",
|
||||
"start_btn": "Vamos começar!"
|
||||
},
|
||||
"analysis": {
|
||||
"question": "Deseja analisar as comunicações capturadas?",
|
||||
"no_btn": "Não, somente salvá-las",
|
||||
"yes_btn": "Sim, vamos lá",
|
||||
"please_wait_msg": "Aguarde enquanto realizamos a análise...",
|
||||
"some_time_msg": "Sim, isso pode demorar um pouco..."
|
||||
},
|
||||
"capture": {
|
||||
"intercept_coms_msg": "Interceptando as comunicações de ",
|
||||
"stop_btn": "Parar a captura"
|
||||
},
|
||||
"generate-ap": {
|
||||
"network_name": "Nome da rede",
|
||||
"network_password": "Senha da rede",
|
||||
"tap_msg": "Toque no quadro branco para criar uma nova rede.",
|
||||
"generate_ap_msg": "Geramos uma rede temporária para você.",
|
||||
"error_msg1": "Infelizmente, tivemos alguns problemas <br> durante a criação do AP.",
|
||||
"error_msg2": "Verifique se você possui duas interfaces Wi-Fi no dispositivo<br> e tente novamente, reiniciando-o.",
|
||||
"restart_btn": "Reiniciar o dispositivo"
|
||||
},
|
||||
"report": {
|
||||
"show_full_report": "Mostrar o relatório completo",
|
||||
"start_new_capture": "Iniciar nova captura",
|
||||
"save_capture": "Salvar a captura",
|
||||
"save": "Salvar",
|
||||
"print": "Imprimir",
|
||||
"numbers": [
|
||||
"zero",
|
||||
"um",
|
||||
"dois",
|
||||
"três",
|
||||
"quatro",
|
||||
"cinco",
|
||||
"seis",
|
||||
"sete",
|
||||
"oito",
|
||||
"nove",
|
||||
"dez",
|
||||
"onze"
|
||||
],
|
||||
"stalkerware_msg": "Seu dispositivo foi comprometido por<br /> um stalkerware. Verifique o relatório.",
|
||||
"location_msg": "Um aplicativo está compartilhando sua <br /> geolocalização com um terceiro.",
|
||||
"fine_msg": "Tudo parece estar bem, zero alertas.",
|
||||
"high_msg": "Você tem {nb} alerta crítico,<br /> o dispositivo parece estar comprometido.",
|
||||
"moderate_msg": "Você tem {nb} alertas moderados,<br /> o dispositivo pode estar comprometido.",
|
||||
"low_msg": "Você tem apenas {nb} alertas leves,<br /> não deixe de verificá-los.",
|
||||
"save_report": "Salvar o relatório",
|
||||
"report_of": "Relatório de",
|
||||
"detection_methods": "Métodos de detecção:",
|
||||
"indicators": "Indicadores",
|
||||
"heuristics": "Anomalias",
|
||||
"active": "Activa",
|
||||
"pcap_sha1": "SHA1 da captura:",
|
||||
"capture_started": "Captura iniciada em:",
|
||||
"capture_ended": "Captura terminou em:",
|
||||
"high": "crítico",
|
||||
"moderate": "moderado",
|
||||
"low": "leve",
|
||||
"uncat_coms_table" : "Comunicações não categorizadas",
|
||||
"protocol" : "Protocolo",
|
||||
"domain_name" : "Domínio",
|
||||
"ip_address": "Endereço IP:",
|
||||
"port" : "Porto"
|
||||
},
|
||||
"wifi-select": {
|
||||
"wifi_connected": "Wi-Fi conectado",
|
||||
"wifi_not_connected": "Wi-Fi desconectado. Tente novamente.",
|
||||
"wifi_password": "Senha do Wi-Fi",
|
||||
"connect_to_it": "Conectar"
|
||||
},
|
||||
"save-capture": {
|
||||
"please_connect": "Conecte uma chave USB para salvar a captura.",
|
||||
"we_are_saving": "Estamos salvando a captura.",
|
||||
"tap_msg": "Toque na chave USB para iniciar uma nova captura.",
|
||||
"capture_download": "O download da captura vai começar...",
|
||||
"start_capture_btn": "Iniciar nova captura"
|
||||
},
|
||||
"modals": {
|
||||
"want_to_quit": "Deseja fechar o aplicativo?",
|
||||
"no_go_back": "Não, voltar",
|
||||
"yes_continue": "Sim, continuar",
|
||||
"please_give_the_password": "Indicar a senha da rede: ",
|
||||
"want_to_whitelist" : "Você quer adicionar <i class='ioc'>{host}</i> à lista branca <br /> para as próximas análises?"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
{
|
||||
"home": {
|
||||
"welcome_msg": "Добро пожаловать в SpyGuard.",
|
||||
"help_msg": "Мы поможем вам проверить ваше устройство.",
|
||||
"start_btn": "Итак, приступим!"
|
||||
},
|
||||
"analysis": {
|
||||
"question": "Хотите проанализировать зафиксированные подключения?",
|
||||
"no_btn": "Нет, только сохранить",
|
||||
"yes_btn": "Да, проанализировать",
|
||||
"please_wait_msg": "Подождите, идет анализ...",
|
||||
"some_time_msg": "Это может занять некоторое время..."
|
||||
},
|
||||
"capture": {
|
||||
"intercept_coms_msg": "Перехват подключений ",
|
||||
"stop_btn": "Остановить сбор данных"
|
||||
},
|
||||
"generate-ap": {
|
||||
"network_name": "Имя сети",
|
||||
"network_password": "Пароль сети",
|
||||
"tap_msg": "Нажмите на белую рамку, чтобы создать новую сеть.",
|
||||
"generate_ap_msg": "Создастся временная сеть.",
|
||||
"error_msg1": "<br>При создании точки доступа возникли проблемы.",
|
||||
"error_msg2": "Убедитесь, что на вашем устройстве<br> есть два порта Wi-Fi, и повторите попытку, перезагрузив устройство.",
|
||||
"restart_btn": "Перезагрузить устройство"
|
||||
},
|
||||
"report": {
|
||||
"show_full_report": "Показать полный отчет",
|
||||
"start_new_capture": "Начать новый сбор данных",
|
||||
"save_capture": "Сохранить сбор данных",
|
||||
"save": "Сохранить",
|
||||
"print": "Печатать",
|
||||
"numbers": [
|
||||
"ноль",
|
||||
"один",
|
||||
"два",
|
||||
"три",
|
||||
"четыре",
|
||||
"пять",
|
||||
"шесть",
|
||||
"семь",
|
||||
"восемь",
|
||||
"девять",
|
||||
"десять",
|
||||
"одиннадцать"
|
||||
],
|
||||
"stalkerware_msg": "Ваше устройство взломано вредоносным<br /> ПО для слежки. Проверьте отчет.",
|
||||
"location_msg": "Приложение передает вашу<br /> текущую геолокацию третьему лицу.",
|
||||
"fine_msg": "Предупреждения отсутствуют,<br /> система выглядит защищенной.",
|
||||
"high_msg": "У вас {nb} предупреждение высокого уровня.<br /> Вероятно,ваше устройство взломано.",
|
||||
"moderate_msg": "У вас {nb} предупреждение среднего уровня.<br /> Возможно, ваше устройство взломано.",
|
||||
"low_msg": "У вас {nb} предупреждение низкого уровня<br />, проверьте их.",
|
||||
"save_report": "Сохранить отчет",
|
||||
"report_of": "Отчет",
|
||||
"detection_methods": "методы обнаружения:",
|
||||
"indicators": "Показателям",
|
||||
"heuristics": "аномалии",
|
||||
"active": "активное",
|
||||
"pcap_sha1": "SHA1 захват:",
|
||||
"capture_started": "Захват начался:",
|
||||
"capture_ended": "захват закончился:",
|
||||
"high": "высокий",
|
||||
"moderate": "средний",
|
||||
"low": "низкий",
|
||||
"uncat_coms_table" : "Несекретные сообщения",
|
||||
"protocol" : "Протокол",
|
||||
"domain_name" : "домен",
|
||||
"ip_address": "IP-адрес:",
|
||||
"port" : "порт"
|
||||
},
|
||||
"wifi-select": {
|
||||
"wifi_connected": "Подключено к сети Wi-Fi",
|
||||
"wifi_not_connected": "Не подключено к сети Wi-Fi. Повторите попытку.",
|
||||
"tap_keyboard": "Коснитесь виртуальной клавиатуры, чтобы начать",
|
||||
"wifi_password": "Пароль Wi-Fi"
|
||||
},
|
||||
"save-capture": {
|
||||
"please_connect": "Подсоедините USB-ключ, чтобы сохранить результат сбора данных.",
|
||||
"we_are_saving": "Сохранение собранных данных.",
|
||||
"tap_msg": "Коснитесь USB-ключа, чтобы начать новый сбор данных.",
|
||||
"capture_download": "Начинается загрузка собранных данных...",
|
||||
"start_capture_btn": "Начать новый сбор данных"
|
||||
},
|
||||
"modals": {
|
||||
"want_to_quit": "Вы бы хотели уйти?",
|
||||
"no_go_back": "Нет",
|
||||
"yes_continue": "да",
|
||||
"please_give_the_password": "VПожалуйста, введите сетевой пароль: ",
|
||||
"want_to_whitelist" : "Вы хотите добавить <i class='ioc'>{host}</i> в белый список<br />для будущих испытаний?"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import Vue from 'vue'
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
import { i18n } from '@/plugins/i18n'
|
||||
|
||||
Vue.config.productionTip = true
|
||||
Vue.config.devtools = true
|
||||
|
||||
export const EventBus = new Vue();
|
||||
|
||||
new Vue({
|
||||
router,
|
||||
i18n,
|
||||
render: h => h(App)
|
||||
}).$mount('#app')
|
||||
@@ -0,0 +1,18 @@
|
||||
import Vue from 'vue'
|
||||
import VueI18n from 'vue-i18n'
|
||||
|
||||
Vue.use(VueI18n)
|
||||
|
||||
export const i18n = new VueI18n({
|
||||
locale: 'en',
|
||||
fallbackLocale: 'en',
|
||||
messages: {
|
||||
'en': require('@/locales/en.json'),
|
||||
'fr': require('@/locales/fr.json'),
|
||||
'es': require('@/locales/es.json'),
|
||||
'ru': require('@/locales/ru.json'),
|
||||
'pt': require('@/locales/pt.json'),
|
||||
'it': require('@/locales/it.json'),
|
||||
'de': require('@/locales/de.json')
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,58 @@
|
||||
import Vue from 'vue'
|
||||
import VueRouter from 'vue-router'
|
||||
|
||||
|
||||
Vue.use(VueRouter)
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path: '/',
|
||||
name: 'loader',
|
||||
component: () => import('../views/splash-screen.vue'),
|
||||
props: true
|
||||
},
|
||||
{
|
||||
path: '/home',
|
||||
name: 'home',
|
||||
component: () => import('../views/home.vue'),
|
||||
props: true
|
||||
},
|
||||
{
|
||||
path: '/generate-ap',
|
||||
name: 'generate-ap',
|
||||
component: () => import('../views/generate-ap.vue'),
|
||||
props: true
|
||||
},
|
||||
{
|
||||
path: '/capture',
|
||||
name: 'capture',
|
||||
component: () => import('../views/capture.vue'),
|
||||
props: true
|
||||
},
|
||||
{
|
||||
path: '/save-capture',
|
||||
name: 'save-capture',
|
||||
component: () => import('../views/save-capture.vue'),
|
||||
props: true
|
||||
},
|
||||
{
|
||||
path: '/analysis',
|
||||
name: 'analysis',
|
||||
component: () => import('../views/analysis.vue'),
|
||||
props: true
|
||||
},
|
||||
{
|
||||
path: '/report',
|
||||
name: 'report',
|
||||
component: () => import('../views/report.vue'),
|
||||
props: true
|
||||
}
|
||||
]
|
||||
|
||||
const router = new VueRouter({
|
||||
mode: 'history',
|
||||
base: process.env.BASE_URL,
|
||||
routes
|
||||
})
|
||||
|
||||
export default router
|
||||
@@ -0,0 +1,75 @@
|
||||
<template>
|
||||
<div class="wrapper">
|
||||
<div class="center">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="margin: auto; background: none; display: block; shape-rendering: auto;" width="194px" height="194px" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid">
|
||||
<circle cx="50" cy="50" r="0" fill="none" stroke="#dfdfdf" stroke-width="1">
|
||||
<animate attributeName="r" repeatCount="indefinite" dur="2.941176470588235s" values="0;43" keyTimes="0;1" keySplines="0 0.2 0.8 1" calcMode="spline" begin="0s"></animate>
|
||||
<animate attributeName="opacity" repeatCount="indefinite" dur="2.941176470588235s" values="1;0" keyTimes="0;1" keySplines="0.2 0 0.8 1" calcMode="spline" begin="0s"></animate>
|
||||
</circle><circle cx="50" cy="50" r="0" fill="none" stroke="#dadada" stroke-width="1">
|
||||
<animate attributeName="r" repeatCount="indefinite" dur="2.941176470588235s" values="0;43" keyTimes="0;1" keySplines="0 0.2 0.8 1" calcMode="spline" begin="-1.4705882352941175s"></animate>
|
||||
<animate attributeName="opacity" repeatCount="indefinite" dur="2.941176470588235s" values="1;0" keyTimes="0;1" keySplines="0.2 0 0.8 1" calcMode="spline" begin="-1.4705882352941175s"></animate>
|
||||
</circle>
|
||||
</svg>
|
||||
<p class="legend" v-if="!long_waiting">{{ $t("analysis.please_wait_msg") }}</p>
|
||||
<p class="legend fade-in" v-if="long_waiting">{{ $t("analysis.some_time_msg") }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import router from '../router'
|
||||
import axios from 'axios'
|
||||
|
||||
export default {
|
||||
name: 'analysis',
|
||||
data() {
|
||||
return {
|
||||
check_alerts: false,
|
||||
long_waiting: false
|
||||
}
|
||||
},
|
||||
props: {
|
||||
capture_token: String
|
||||
},
|
||||
methods: {
|
||||
start_analysis: function() {
|
||||
console.log("[analysis.vue] Starting the analysis...");
|
||||
setTimeout(function () { this.long_waiting = true }.bind(this), 15000);
|
||||
axios.get(`/api/analysis/start/${this.capture_token}`, { timeout: 60000 })
|
||||
.then(response => {
|
||||
if(response.data.message == 'Analysis started')
|
||||
this.check_alerts = setInterval(() => { this.get_alerts(); }, 500);
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
});
|
||||
},
|
||||
get_alerts: function() {
|
||||
axios.get(`/api/analysis/report/${this.capture_token}`, { timeout: 60000 })
|
||||
.then(response => {
|
||||
if(response.data.message != 'No report yet'){
|
||||
console.log("[analysis.vue] Got the results analysis, moving to report view");
|
||||
clearInterval(this.check_alerts);
|
||||
this.long_waiting = false
|
||||
router.replace({ name: 'report',
|
||||
params: { alerts : response.data.alerts,
|
||||
device : response.data.device,
|
||||
methods : response.data.methods,
|
||||
pcap : response.data.pcap,
|
||||
records : response.data.records,
|
||||
capture_token : this.capture_token } });
|
||||
} else {
|
||||
console.log("[analysis.vue] No analysis results yet");
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
});
|
||||
},
|
||||
},
|
||||
created: function() {
|
||||
console.log("[analysis.vue] Showing analysis.vue");
|
||||
this.start_analysis();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,98 @@
|
||||
<template>
|
||||
<div class="wrapper">
|
||||
<svg id="sparkline" stroke-width="3" :width="sparkwidth" :height="sparkheight" v-if="sparklines"></svg>
|
||||
<div class="center">
|
||||
<div class="footer">
|
||||
<h3 class="timer">{{timer_hours}}:{{timer_minutes}}:{{timer_seconds}}</h3>
|
||||
<p>{{$t("capture.intercept_coms_msg")}} {{device_name}}.</p>
|
||||
<div class="empty-action">
|
||||
<button class="btn btn-primary" v-on:click="stop_capture()">{{$t("capture.stop_btn")}}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from 'axios'
|
||||
import router from '../router'
|
||||
import sparkline from '@fnando/sparkline'
|
||||
|
||||
export default {
|
||||
name: 'capture',
|
||||
components: {},
|
||||
data() {
|
||||
return {
|
||||
timer_hours: "00",
|
||||
timer_minutes: "00",
|
||||
timer_seconds: "00",
|
||||
stats_interval: false,
|
||||
chrono_interval: false,
|
||||
sparklines: false
|
||||
}
|
||||
},
|
||||
props: {
|
||||
capture_token: String,
|
||||
device_name: String
|
||||
},
|
||||
methods: {
|
||||
set_chrono: function() {
|
||||
console.log("[capture.vue] Setting up the chrono")
|
||||
this.chrono_interval = setInterval(() => { this.chrono(); }, 10);
|
||||
},
|
||||
stop_capture: function() {
|
||||
console.log("[capture.vue] Stoping the capture")
|
||||
axios.get('/api/capture/stop', { timeout: 30000 })
|
||||
clearInterval(this.chrono_interval);
|
||||
clearInterval(this.stats_interval);
|
||||
window.access_point = ""
|
||||
var capture_token = this.capture_token
|
||||
router.replace({ name: 'analysis', params: { capture_token: capture_token } });
|
||||
},
|
||||
get_stats: function() {
|
||||
console.log("[capture.vue] Getting capture statistics")
|
||||
axios.get('/api/capture/stats', { timeout: 30000 })
|
||||
.then(response => (this.handle_stats(response.data)))
|
||||
},
|
||||
handle_stats: function(data) {
|
||||
if (data.packets.length) sparkline(document.querySelector('#sparkline'), data.packets);
|
||||
},
|
||||
chrono: function() {
|
||||
var time = Date.now() - this.capture_start
|
||||
this.timer_hours = Math.floor(time / (60 * 60 * 1000));
|
||||
this.timer_hours = (this.timer_hours < 10) ? '0' + this.timer_hours : this.timer_hours
|
||||
time = time % (60 * 60 * 1000);
|
||||
this.timer_minutes = Math.floor(time / (60 * 1000));
|
||||
this.timer_minutes = (this.timer_minutes < 10) ? '0' + this.timer_minutes : this.timer_minutes
|
||||
time = time % (60 * 1000);
|
||||
this.timer_seconds = Math.floor(time / 1000);
|
||||
this.timer_seconds = (this.timer_seconds < 10) ? '0' + this.timer_seconds : this.timer_seconds
|
||||
},
|
||||
setup_sparklines: function() {
|
||||
axios.get('/api/misc/config', { timeout: 60000 })
|
||||
.then(response => {
|
||||
if(response.data.sparklines){
|
||||
console.log("[capture.vue] Setting up sparklines")
|
||||
this.sparklines = true
|
||||
this.sparkwidth = window.screen.width + 'px';
|
||||
this.sparkheight = Math.trunc(window.screen.height / 5) + 'px';
|
||||
this.stats_interval = setInterval(() => { this.get_stats(); }, 500);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error)
|
||||
});
|
||||
}
|
||||
},
|
||||
created: function() {
|
||||
console.log("[capture.vue] Showing capture.vue")
|
||||
|
||||
// Get the config for the sparklines.
|
||||
this.setup_sparklines()
|
||||
|
||||
// Start the chrono and get the first stats.
|
||||
this.capture_start = Date.now()
|
||||
this.set_chrono();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,145 @@
|
||||
<template>
|
||||
<div class="wrapper">
|
||||
<div class="center">
|
||||
<div v-if="(error == false)">
|
||||
<div v-if="ssid_name">
|
||||
<div class="card apcard" v-on:click="generate_ap()">
|
||||
<div class="columns">
|
||||
<div class="column col-5">
|
||||
<center><img :src="ssid_qr" id="qrcode"></center>
|
||||
</div>
|
||||
<div class="divider-vert white-bg" data-content="OR"></div>
|
||||
<div class="column col-5"><br />
|
||||
<span class="light-grey">{{ $t("generate-ap.network_name") }} </span><br />
|
||||
<h4>{{ ssid_name }}</h4>
|
||||
<span class="light-grey">{{ $t("generate-ap.network_password") }} </span><br />
|
||||
<h4>{{ ssid_password }}</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br /><br /><br /><br /> <br /><br /><br /><br /><br /><br />
|
||||
<!-- Requite a CSS MEME for that shit :) -->
|
||||
<span class="legend">{{ $t("generate-ap.tap_msg") }}</span>
|
||||
</div>
|
||||
<div v-else>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="margin: auto; background: none; display: block; shape-rendering: auto;" width="194px" height="194px" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid">
|
||||
<circle cx="50" cy="50" r="0" fill="none" stroke="#dfdfdf" stroke-width="1">
|
||||
<animate attributeName="r" repeatCount="indefinite" dur="2.941176470588235s" values="0;43" keyTimes="0;1" keySplines="0 0.2 0.8 1" calcMode="spline" begin="0s"></animate>
|
||||
<animate attributeName="opacity" repeatCount="indefinite" dur="2.941176470588235s" values="1;0" keyTimes="0;1" keySplines="0.2 0 0.8 1" calcMode="spline" begin="0s"></animate>
|
||||
</circle><circle cx="50" cy="50" r="0" fill="none" stroke="#dadada" stroke-width="1">
|
||||
<animate attributeName="r" repeatCount="indefinite" dur="2.941176470588235s" values="0;43" keyTimes="0;1" keySplines="0 0.2 0.8 1" calcMode="spline" begin="-1.4705882352941175s"></animate>
|
||||
<animate attributeName="opacity" repeatCount="indefinite" dur="2.941176470588235s" values="1;0" keyTimes="0;1" keySplines="0.2 0 0.8 1" calcMode="spline" begin="-1.4705882352941175s"></animate>
|
||||
</circle>
|
||||
</svg>
|
||||
<p class="legend">{{ $t("generate-ap.generate_ap_msg") }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<p>
|
||||
<strong v-html="$t('generate-ap.error_msg1')"></strong>
|
||||
<br /><br />
|
||||
<span v-html="$t('generate-ap.error_msg2')"></span>
|
||||
<br /><br />
|
||||
</p>
|
||||
<button v-if="reboot_option" class="btn" v-on:click="reboot()">{{ $t("generate-ap.restart_btn") }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from 'axios'
|
||||
import router from '../router'
|
||||
|
||||
export default {
|
||||
name: 'generate-ap',
|
||||
components: {},
|
||||
data() {
|
||||
return {
|
||||
ssid_name: false,
|
||||
ssid_qr: false,
|
||||
ssid_password: false,
|
||||
capture_token: false,
|
||||
capture_start: false,
|
||||
interval: false,
|
||||
error: false,
|
||||
reboot_option: window.config.reboot_option,
|
||||
attempts: 3
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
generate_ap: function() {
|
||||
console.log("[generate-ap.vue] Trying to start a new access point");
|
||||
clearInterval(this.interval);
|
||||
this.ssid_name = false
|
||||
axios.get('/api/network/ap/start', { timeout: 30000 })
|
||||
.then(response => (this.show_ap(response.data)))
|
||||
},
|
||||
show_ap: function(data) {
|
||||
if (data.status) {
|
||||
console.log("[generate-ap.vue] Access point created, showing SSID");
|
||||
window.access_point = data.ssid
|
||||
this.ssid_name = data.ssid
|
||||
this.ssid_password = data.password
|
||||
this.ssid_qr = data.qrcode
|
||||
this.start_capture()
|
||||
} else {
|
||||
console.log("[generate-ap.vue] Issue when creating AP, let's retry");
|
||||
if(this.attempts != 0){
|
||||
setTimeout(function () { this.generate_ap() }.bind(this), 10000)
|
||||
this.attempts -= 1;
|
||||
} else {
|
||||
console.log("[generate-ap.vue] Fatal error when creating AP, showing the error message");
|
||||
this.error = true
|
||||
}
|
||||
}
|
||||
},
|
||||
start_capture: function() {
|
||||
console.log("[generate-ap.vue] Starting the capture in background");
|
||||
axios.get('/api/capture/start', { timeout: 30000 })
|
||||
.then(response => (this.get_capture_token(response.data)))
|
||||
},
|
||||
reboot: function() {
|
||||
console.log("[generate-ap.vue] Rebooting the device");
|
||||
axios.get('/api/misc/reboot', { timeout: 30000 })
|
||||
.then(response => { console.log(response)})
|
||||
},
|
||||
get_capture_token: function(data) {
|
||||
if (data.status) {
|
||||
console.log("[generate-ap.vue] Capture token retrieved, waiting a device to connect");
|
||||
this.capture_token = data.capture_token
|
||||
this.capture_start = Date.now()
|
||||
this.get_device()
|
||||
}
|
||||
},
|
||||
get_device: function() {
|
||||
this.interval = setInterval(() => {
|
||||
axios.get(`/api/device/get/${this.capture_token}`, { timeout: 30000 })
|
||||
.then(response => (this.check_device(response.data)))
|
||||
}, 500);
|
||||
},
|
||||
check_device: function(data) {
|
||||
if (data.status) {
|
||||
console.log("[generate-ap.vue] Device connected, going to capture view.");
|
||||
clearInterval(this.interval);
|
||||
var capture_token = this.capture_token
|
||||
var capture_start = this.capture_start
|
||||
var device_name = data.name
|
||||
router.replace({
|
||||
name: 'capture',
|
||||
params: {
|
||||
capture_token: capture_token,
|
||||
capture_start: capture_start,
|
||||
device_name: device_name
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
created: function() {
|
||||
console.log("[generate-ap.vue] Showing generate-ap.vue")
|
||||
this.generate_ap();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
<template>
|
||||
<div class="wrapper">
|
||||
<div class="center">
|
||||
<h3 class="lobster">{{ $t("home.welcome_msg") }}</h3>
|
||||
<p>{{ $t("home.help_msg") }}</p>
|
||||
<button class="btn btn-primary" v-on:click="next()">{{ $t("home.start_btn") }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import router from '../router'
|
||||
|
||||
export default {
|
||||
name: 'home',
|
||||
methods: {
|
||||
next: function() {
|
||||
router.push({ name: 'generate-ap' });
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,195 @@
|
||||
<template>
|
||||
<div>
|
||||
<div v-if="results">
|
||||
<div v-if="grep_keyword('STALKERWARE', 'high')" class="high-wrapper">
|
||||
<div class="center">
|
||||
<h1 class="warning-title" v-html="$t('report.stalkerware_msg')"></h1>
|
||||
<button class="btn btn-report-low-light" v-on:click="new_capture()">{{ $t("report.start_new_capture") }}</button>
|
||||
<button class="btn btn-report-high" @click="show_report=true;results=false;">{{ $t("report.show_full_report") }}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="alerts.high.length >= 1" class="high-wrapper">
|
||||
<div class="center">
|
||||
<h1 class="warning-title" v-html="$t('report.high_msg', { nb: $i18n.messages[$i18n.locale].report.numbers[alerts.high.length] })"></h1>
|
||||
<button class="btn btn-report-low-light" v-on:click="new_capture()">{{ $t("report.start_new_capture") }}</button>
|
||||
<button class="btn btn-report-high" @click="show_report=true;results=false;">{{ $t("report.show_full_report") }}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="alerts.moderate.length >= 1" class="med-wrapper">
|
||||
<div class="center">
|
||||
<h1 class="warning-title" v-html="$t('report.moderate_msg', { nb: $i18n.messages[$i18n.locale].report.numbers[alerts.moderate.length] })"></h1>
|
||||
<button class="btn btn-report-low-light" v-on:click="new_capture()">{{ $t("report.start_new_capture") }}</button>
|
||||
<button class="btn btn-report-moderate" @click="show_report=true;results=false;">{{ $t("report.show_full_report") }}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="alerts.low.length >= 1" class="low-wrapper">
|
||||
<div class="center">
|
||||
<h1 class="warning-title" v-html="$t('report.low_msg', { nb: $i18n.messages[$i18n.locale].report.numbers[alerts.low.length] })"></h1>
|
||||
<button class="btn btn-report-low-light" v-on:click="new_capture()">{{ $t("report.start_new_capture") }}</button>
|
||||
<button class="btn btn-report-low" @click="show_report=true;results=false;">{{ $t("report.show_full_report") }}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="none-wrapper">
|
||||
<div class="center">
|
||||
<h1 class="warning-title" v-html="$t('report.fine_msg')"></h1>
|
||||
<button class="btn btn-report-low-light" @click="show_report=true;results=false;">{{ $t("report.show_full_report") }}</button>
|
||||
<button class="btn btn-report-low" v-on:click="new_capture()">{{ $t("report.start_new_capture") }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="show_report" class="wrapper">
|
||||
<div class="report-wrapper">
|
||||
<div class="device-ctx">
|
||||
<h3 style="margin: 0; padding-left:10px;">{{ $t("report.report_of") }} {{device.name}}</h3>
|
||||
<div class="device-ctx-legend">
|
||||
{{ $t("report.pcap_sha1") }} {{ pcap.SHA1 }}<br />
|
||||
{{ $t("report.capture_started") }} {{ pcap["First packet time"].split(",")[0] }}<br />
|
||||
{{ $t("report.capture_ended") }} {{ pcap["Last packet time"].split(",")[0] }}<br />
|
||||
{{ $t("report.detection_methods") }} {{ detection_methods }}
|
||||
</div>
|
||||
</div>
|
||||
<ul class="alerts">
|
||||
<li class="alert" v-for="alert in alerts.high" :key="alert.message">
|
||||
<div class="alert-header">
|
||||
<span class="high-label">{{ $t("report.high") }}</span>
|
||||
<span class="alert-id">{{ alert.id }}</span>
|
||||
<span class="btn-whitelist" v-on:click="add_whitelist(alert.host)">Add to the whitelist</span>
|
||||
</div>
|
||||
<div class="alert-body">
|
||||
<span class="title">{{ alert.title }}</span>
|
||||
<p class="description">{{ alert.description }}</p>
|
||||
</div>
|
||||
</li>
|
||||
<li class="alert" v-for="alert in alerts.moderate" :key="alert.message">
|
||||
<div class="alert-header">
|
||||
<span class="moderate-label">{{ $t("report.moderate") }}</span>
|
||||
<span class="alert-id">{{ alert.id }}</span>
|
||||
<span class="btn-whitelist" v-on:click="add_whitelist(alert.host)">Add to the whitelist</span>
|
||||
</div>
|
||||
<div class="alert-body">
|
||||
<span class="title">{{ alert.title }}</span>
|
||||
<p class="description">{{ alert.description }}</p>
|
||||
</div>
|
||||
</li>
|
||||
<li class="alert" v-for="alert in alerts.low" :key="alert.message">
|
||||
<div class="alert-header">
|
||||
<span class="moderate-label">{{ $t("report.low") }}</span>
|
||||
<span class="alert-id">{{ alert.id }}</span>
|
||||
<span class="btn-whitelist" v-on:click="add_whitelist(alert.host)">Add to the whitelist</span>
|
||||
</div>
|
||||
<div class="alert-body">
|
||||
<span class="title">{{ alert.title }}</span>
|
||||
<p class="description">{{ alert.description }}</p>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<h5 class="title-report" v-if="uncategorized_records.length>0">{{ $t("report.uncat_coms_table") }}</h5>
|
||||
<div v-if="uncategorized_records.length>0">
|
||||
<table class="table-uncat">
|
||||
<thead>
|
||||
<tr>
|
||||
<td>{{ $t("report.protocol") }}</td>
|
||||
<td>{{ $t("report.domain_name") }}</td>
|
||||
<td>{{ $t("report.ip_address") }}</td>
|
||||
<td>{{ $t("report.port") }}</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr v-for="record in uncategorized_records" :key="record.ip_dst">
|
||||
<td>{{ Object.keys(record.protocols).map(key => record.protocols[key].name).join(", ") }}</td>
|
||||
<td v-on:click="add_whitelist(record.domains[0])">{{ record.domains.join(", ") }}</td>
|
||||
<td v-on:click="add_whitelist(record.ip_dst)">{{ record.ip_dst }}</td>
|
||||
<td>{{ Object.keys(record.protocols).map(key => record.protocols[key].port).join(", ") }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div id="controls-analysis">
|
||||
<div class="column col-6">
|
||||
<button class="btn btn btn-primary width-100" v-on:click="save_capture()">{{ $t("report.save") }}</button>
|
||||
</div>
|
||||
<div class="column col-6">
|
||||
<button class="btn width-100" @click="$router.push('generate-ap')">{{ $t("report.start_new_capture") }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<style>
|
||||
#app {
|
||||
overflow-y: visible;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import router from '../router'
|
||||
import axios from 'axios'
|
||||
import { EventBus } from "../main.js"
|
||||
|
||||
export default {
|
||||
name: 'report',
|
||||
data() {
|
||||
return {
|
||||
results: true,
|
||||
detection_methods: "",
|
||||
uncategorized_records: []
|
||||
}
|
||||
},
|
||||
props: {
|
||||
device: Object,
|
||||
methods: Object,
|
||||
pcap: Object,
|
||||
records: Array,
|
||||
alerts: Array,
|
||||
capture_token: String
|
||||
},
|
||||
methods: {
|
||||
save_capture: function() {
|
||||
console.log("[report.vue] Saving the capture");
|
||||
router.replace({ name: 'save-capture', params: { capture_token: this.capture_token } });
|
||||
},
|
||||
new_capture: function() {
|
||||
console.log("[report.vue] Deleting the capture and creating a new AP");
|
||||
axios.get('/api/misc/delete-captures', { timeout: 30000 })
|
||||
.then(() => { router.push({ name: 'generate-ap' }) })
|
||||
.catch(error => { console.log(error) })
|
||||
},
|
||||
grep_keyword: function(kw, level){
|
||||
try {
|
||||
if(this.alerts[level].length){
|
||||
var idx;
|
||||
var found;
|
||||
this.alerts[level].forEach((a) => {
|
||||
idx = a.title.indexOf(kw)
|
||||
if(!found) found = idx>0;
|
||||
});
|
||||
return found;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} catch (error){ console.log(error); }
|
||||
},
|
||||
get_detection_methods: function(){
|
||||
this.detection_methods += (this.methods.iocs == true)? `☑ ${this.$t("report.indicators")} ` : `☐ ${this.$t("report.indicators")} `
|
||||
this.detection_methods += (this.methods.heuristics == true)? `☑ ${this.$t("report.heuristics")} ` : `☐ ${this.$t("report.heuristics")} `
|
||||
this.detection_methods += (this.methods.active == true)? `☑ ${this.$t("report.active")} ` : `☐ ${this.$t("report.active")} `
|
||||
},
|
||||
add_whitelist: function(host){
|
||||
EventBus.$emit("showModal", {"action" : "whitelist", "host" : host})
|
||||
},
|
||||
get_uncategorized_records: function(){
|
||||
this.records.forEach( r => {
|
||||
if (!r.suspicious && !r.whitelisted){
|
||||
this.uncategorized_records.push(r);
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
created: function() {
|
||||
console.log("[report.vue] Showing report.vue");
|
||||
this.get_detection_methods();
|
||||
this.get_uncategorized_records();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,106 @@
|
||||
<template>
|
||||
<div class="wrapper">
|
||||
<div class="center" v-if="save_usb && init">
|
||||
<div class="canvas-anim" :class="{'anim-connect': !saved && !usb}" v-on:click="new_capture()">
|
||||
<div class="icon-spinner" v-if="!saved && usb"></div>
|
||||
<div class="icon-success" v-if="saved"></div>
|
||||
<div class="icon-usb"></div>
|
||||
<div class="icon-usb-plug"></div>
|
||||
</div>
|
||||
<p class="legend" v-if="!saved && !usb"><br />{{ $t("save-capture.please_connect") }}</p>
|
||||
<p class="legend" v-if="!saved && usb"><br />{{ $t("save-capture.we_are_saving") }}</p>
|
||||
<p class="legend" v-if="saved"><br />{{ $t("save-capture.tap_msg") }}</p>
|
||||
</div>
|
||||
<div class="center" v-else-if="!save_usb && init">
|
||||
<div>
|
||||
<p class="legend">{{ $t("save-capture.capture_download") }}<br /><br /><br /></p>
|
||||
<button class="btn btn-primary" v-on:click="new_capture()">{{ $t("save-capture.start_capture_btn") }}</button>
|
||||
<iframe :src="download_url" class="frame-download"></iframe>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
.canvas-anim {
|
||||
height: 120px;
|
||||
margin: 0 auto;
|
||||
position: relative;
|
||||
width: 205px;
|
||||
|
||||
&.anim-connect {
|
||||
width: 300px;
|
||||
|
||||
.icon-usb {
|
||||
-webkit-animation: slide-right 1s cubic-bezier(0.455, 0.030, 0.515, 0.955) infinite alternate both;
|
||||
animation: slide-right 1s cubic-bezier(0.455, 0.030, 0.515, 0.955) infinite alternate both;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import axios from 'axios'
|
||||
import router from '../router'
|
||||
|
||||
export default {
|
||||
name: 'save-capture',
|
||||
components: {},
|
||||
data() {
|
||||
return {
|
||||
usb: false,
|
||||
saved: false,
|
||||
save_usb: false,
|
||||
init: false
|
||||
}
|
||||
},
|
||||
props: {
|
||||
capture_token: String
|
||||
},
|
||||
methods: {
|
||||
check_usb: function() {
|
||||
console.log("[save-capture.vue] Checking connected USB device...");
|
||||
axios.get(`/api/save/usb-check`, { timeout: 30000 })
|
||||
.then(response => {
|
||||
if(response.data.status) {
|
||||
this.usb = true
|
||||
clearInterval(this.interval)
|
||||
this.save_capture()
|
||||
}
|
||||
})
|
||||
},
|
||||
save_capture: function() {
|
||||
var capture_token = this.capture_token
|
||||
console.log("[save-capture.vue] Saving the capture on USB");
|
||||
axios.get(`/api/save/save-capture/${capture_token}/usb`, { timeout: 30000 })
|
||||
.then(response => {
|
||||
if(response.data.status){
|
||||
this.saved = true
|
||||
console.log("[save-capture.vue] Capture saved, going back to main view");
|
||||
this.timeout = setTimeout(() => router.push('/'), 60000);
|
||||
}
|
||||
})
|
||||
},
|
||||
new_capture: function() {
|
||||
console.log("[save-capture.vue] Capture saved, generating a new access point");
|
||||
clearTimeout(this.timeout);
|
||||
router.push({ name: 'generate-ap' })
|
||||
}
|
||||
},
|
||||
created: function() {
|
||||
console.log("[save-capture.vue] Showing save-capture.vue");
|
||||
if(window.config.download_links){
|
||||
console.log("[save-capture.vue] Using download links instead of USB key");
|
||||
this.init = true
|
||||
this.save_usb = false
|
||||
this.download_url = `/api/save/save-capture/${this.capture_token}/url`
|
||||
} else {
|
||||
console.log("[save-capture.vue] Using USB key to save the capture");
|
||||
this.init = true
|
||||
this.save_usb = true
|
||||
this.interval = setInterval(() => { this.check_usb() }, 500);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,60 @@
|
||||
<template>
|
||||
<div class="wrapper-dark">
|
||||
<div class="center">
|
||||
<h1 id="title">{{ title }}</h1>
|
||||
<span class="loading loading-lg loadingsplash"></span><span class="message_splash">{{message}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import router from '../router'
|
||||
import axios from 'axios'
|
||||
|
||||
export default {
|
||||
name: 'splash-screen',
|
||||
components: {},
|
||||
data() {
|
||||
return {
|
||||
internet: false,
|
||||
message: "",
|
||||
title: "SPYGUARD",
|
||||
letters: ["SSS§ṠSSSSS","PPPþ⒫PPPP","YYYÿYYYÿYȲYY","GGḠGGGǤG¬G","UÚUUÜUɄUUU", "AAAAÄA¬AAA", "RЯRɌRRRɌʭR", "DD¬DDDDƋDD"]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
delete_captures: function() {
|
||||
this.message = "Doing some cleaning..."
|
||||
console.log("[splash-screen.vue] Deleting previous captures...");
|
||||
axios.get('/api/misc/delete-captures', { timeout: 30000 });
|
||||
|
||||
setTimeout(function () { this.goto_home(); }.bind(this), 2000);
|
||||
},
|
||||
goto_home: function() {
|
||||
console.log("[splash-screen.vue] Going to home...");
|
||||
this.message = "Going to home..."
|
||||
router.replace({ name: 'home' });
|
||||
},
|
||||
generate_random: function(min = 0, max = 1000) {
|
||||
let difference = max - min;
|
||||
let rand = Math.random();
|
||||
rand = Math.floor( rand * difference);
|
||||
rand = rand + min;
|
||||
return rand;
|
||||
},
|
||||
},
|
||||
created: function() {
|
||||
window.access_point = ""
|
||||
console.log("[splash-screen.vue] Welcome to SPYGUARD");
|
||||
setInterval(function(){
|
||||
let res = ""
|
||||
this.letters.forEach(l => { res += l.charAt(this.generate_random(0, 9)) })
|
||||
this.title = res;
|
||||
setTimeout(function(){
|
||||
this.title = "SPYGUARD";
|
||||
}.bind(this), this.generate_random(30, 100));
|
||||
}.bind(this), this.generate_random(500, 4000));
|
||||
this.delete_captures();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,11 @@
|
||||
module.exports = {
|
||||
devServer: {
|
||||
proxy: {
|
||||
'^/api': {
|
||||
target: 'http://localhost:8040',
|
||||
ws: true,
|
||||
changeOrigin: true
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||