Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/undo-ransomware/ransomware_detection.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/views/Recover.vue')
-rw-r--r--src/views/Recover.vue253
1 files changed, 253 insertions, 0 deletions
diff --git a/src/views/Recover.vue b/src/views/Recover.vue
new file mode 100644
index 0000000..a00b5d9
--- /dev/null
+++ b/src/views/Recover.vue
@@ -0,0 +1,253 @@
+<template>
+ <AppContent>
+ <iron-pages :selected="page">
+ <div id="loading" class="page">
+ <paper-spinner active></paper-spinner>
+ </div>
+ <div class="page">
+ <div class="notification-wrapper">
+ <Notification :text.sync="notificationText" @on-close="closeNotification" :visible.sync="visible"></Notification>
+ </div>
+ <Header header="Recover"></Header>
+ <div id="detections" v-if="detected">
+ <div class="detection" v-for="detection in detections" :key="detection.id">
+ <Header :header="'Detection ' + detection.id">
+ <RecoverAction id="recover" label="Recover detected files" v-on:recover="onRecover(detection.id)" primary></RecoverAction>
+ </Header>
+ <v-data-table
+ :ref="'detection' + detection.id"
+ class="ransomware-table"
+ :headers="headers"
+ :items="detection.fileOperations"
+ hide-default-footer
+ >
+ <template v-slot:item.timestamp = "{ item }">
+ <local-time>{{ moment(item.timestamp) }}</local-time>
+ </template>
+ <template v-slot:item.suspicionClass = "{ item }">
+ <iron-icon v-if="item.suspicionClass > 1" style="color: #ED0012;" icon="ransomware:locked"></iron-icon>
+ <iron-icon v-if="item.suspicionClass == 1 && item.type == 'folder'" style="color: #7ED221;" icon="folder"></iron-icon>
+ <iron-icon v-if="item.suspicionClass == 1 && item.type == 'file'" style="color: #7ED221;" icon="editor:insert-drive-file"></iron-icon>
+ <iron-icon v-if="item.suspicionClass < 1 && item.type == 'folder'" style="color: #9B9A9B;" icon="folder"></iron-icon>
+ <iron-icon v-if="item.suspicionClass < 1 && item.type == 'file'" style="color: #9B9A9B;" icon="editor:insert-drive-file"></iron-icon>
+ </template>
+ <template v-slot:item.command = "{ item }">
+ <span v-if="item.command == 1 && item.type == 'file'">File deleted</span>
+ <span v-if="item.command == 1 && item.type == 'folder'">Folder deleted</span>
+ <span v-if="item.command == 2 && item.type == 'file'">File renamed</span>
+ <span v-if="item.command == 2 && item.type == 'folder'">Folder renamed</span>
+ <span v-if="item.command == 3 && item.type == 'file'">File written</span>
+ <span v-if="item.command == 3 && item.type == 'folder'">Folder written</span>
+ <span v-if="item.command == 4 && item.type == 'file'">File read</span>
+ <span v-if="item.command == 4 && item.type == 'folder'">Folder read</span>
+ <span v-if="item.command == 5 && item.type == 'file'">File created</span>
+ <span v-if="item.command == 5 && item.type == 'folder'">Folder created</span>
+ <span v-if="item.command > 5 && item.command < 1 && item.type == 'file'">No information</span>
+ <span v-if="item.command > 5 && item.command < 1 && item.type == 'folder'">No information</span>
+ </template>
+ </v-data-table>
+ </div>
+ </div>
+ <span id="message" v-if="!detected">
+ <iron-icon icon="verified-user"></iron-icon>
+ Nothing found. You are safe.
+ </span>
+ </div>
+ </iron-pages>
+ </AppContent>
+</template>
+
+<script>
+import '@polymer/paper-spinner/paper-spinner.js';
+import '@polymer/iron-pages/iron-pages.js';
+import '@polymer/iron-icon/iron-icon.js';
+import '@polymer/iron-icons/iron-icons.js';
+import '@polymer/iron-icons/editor-icons.js';
+import '../webcomponents/ransomware-icons'
+import 'time-elements/dist/time-elements';
+import moment from 'moment'
+import Notification from '../components/Notification'
+import Header from '../components/Header'
+import RecoverAction from '../components/RecoverAction'
+import AppContent from 'nextcloud-vue/dist/Components/AppContent'
+
+export default {
+ name: 'Recover',
+ components: {
+ AppContent,
+ Header,
+ RecoverAction,
+ Notification
+ },
+ data() {
+ return {
+ detected: 0,
+ detections: [],
+ page: 0,
+ visible: false,
+ notificationText: "",
+ headers: [
+ {
+ text: 'Status',
+ align: 'start',
+ sortable: false,
+ value: 'suspicionClass',
+ },
+ { text: 'Operation', value: 'command' },
+ { text: 'Name', value: 'originalName' },
+ { text: 'File Changed', value: 'timestamp' },
+ ],
+ };
+ },
+ mounted() {
+ this.page = 0;
+ this.fetchDetectionStatus();
+ this.fetchDetections();
+ },
+ methods: {
+ closeNotification() {
+ this.visible = false
+ },
+ notice(text) {
+ this.notificationText = text;
+ this.visible = true;
+
+ },
+ buildNotification(deleted, recovered) {
+ var notificationText = "";
+ if (deleted > 0 && recovered > 0) {
+ notificationText = deleted + " files deleted, " + recovered + " files recovered from backup."
+ }
+ if (recovered > 0 && deleted == 0) {
+ notificationText = recovered + " files recovered from backup."
+ }
+ if (deleted > 0 && recovered == 0) {
+ notificationText = deleted + " files deleted."
+ }
+ if (deleted == 0 && recovered == 0) {
+ notificationText = "No files deleted or recovered."
+ }
+ this.notice(notificationText);
+ },
+ fetchDetectionStatus() {
+ this.$axios({
+ method: 'GET',
+ url: this.detectionsUrl
+ })
+ .then(json => {
+ if (json.data.length > 0) {
+ this.detected = 1;
+ } else {
+ this.page = 1;
+ }
+ })
+ .catch( error => { console.error(error); });
+ },
+ fetchDetections() {
+ this.$axios({
+ method: 'GET',
+ url: this.detectionsUrl
+ })
+ .then(json => {
+ this.detections = json.data;
+ this.page = 1;
+ })
+ .catch( error => { console.error(error); });
+ },
+ onRecover(id) {
+ var itemsToRecover = [];
+ const detectionTable = this.$refs['detection' + id];
+ var items = detectionTable[0].items;
+ for (var i = 0; i < items.length; i++) {
+ itemsToRecover.push(items[i].id);
+ }
+ this.recover(id, itemsToRecover);
+ },
+ remove(id) {
+ for (var i = 0; i < this.detections.length; i++) {
+ if (this.detections[i].id === id) {
+ this.detections.splice(i, 1);
+ }
+ }
+ },
+ async recover(id, ids) {
+ await this.$axios({
+ method: 'PUT',
+ url: this.recoverUrl + '/recover',
+ data: {
+ ids: ids
+ }
+ })
+ .then(response => {
+ switch(response.status) {
+ case 200:
+ this.buildNotification(response.data.deleted, response.data.recovered);
+ if(response.data.filesRecovered.length > 0)
+ this.remove(id);
+ break;
+ default:
+ this.buildNotification(response.data.deleted, response.data.recovered);
+ if(response.data.filesRecovered.length > 0)
+ this.remove(id);
+ break;
+ }
+ })
+ .catch(error => {
+ console.error(error);
+ });
+ },
+ moment: function (date) {
+ return moment.unix(date).format('dddd, MMMM Do YYYY, HH:mm:ss')
+ },
+ datetime: function(date) {
+ return moment.unix(rowData.item.timestamp).format("YYYY-MM-DDTHH:mm:ss.SSS")
+ }
+ },
+ computed: {
+ detectionsUrl() {
+ return OC.generateUrl('/apps/ransomware_detection/api/v1/detection');
+ },
+ recoverUrl() {
+ return OC.generateUrl('/apps/ransomware_detection/api/v1/file-operations')
+ },
+ fileOperationsUrl() {
+ return OC.generateUrl('/apps/ransomware_detection/api/v1/file-operation')
+ }
+ }
+}
+</script>
+
+<style lang="scss">
+ #tables {
+ height: calc(100% - 50px);
+ }
+ #recover {
+ background-color: grey;
+ color: #fff;
+ }
+ #message {
+ display: flex;
+ justify-content: center;
+ font-size: 1.5em;
+ font-weight: bold;
+ }
+ .detection {
+ margin: 10px 0px 0px 0px;
+ }
+ iron-pages {
+ height: 100%;
+ }
+ .page {
+ height: 100%;
+ }
+ #loading {
+ display: flex;
+ align-items: center;
+ height: 90vh;
+ justify-content: center;
+ }
+ .notification-wrapper {
+ display: flex;
+ justify-content: center;
+ }
+</style> \ No newline at end of file