index.vue 3.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
<!--
  - Copyright 2014-2018 the original author or authors.
  -
  - Licensed under the Apache License, Version 2.0 (the "License");
  - you may not use this file except in compliance with the License.
  - You may obtain a copy of the License at
  -
  -     http://www.apache.org/licenses/LICENSE-2.0
  -
  - Unless required by applicable law or agreed to in writing, software
  - distributed under the License is distributed on an "AS IS" BASIS,
  - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  - See the License for the specific language governing permissions and
  - limitations under the License.
  -->

<template>
18 19 20 21 22 23 24 25 26
  <section class="section" :class="{ 'is-loading' : !hasLoaded}">
    <div class="container" v-if="hasLoaded">
      <div v-if="error" class="message is-danger">
        <div class="message-body">
          <strong>
            <font-awesome-icon class="has-text-danger" icon="exclamation-triangle"/>
            Fetching audit events failed.
          </strong>
          <p v-text="error.message"/>
27
        </div>
28
      </div>
29 30 31 32 33
      <div v-if="isOldAuditevents" class="message is-warning">
        <div class="message-body">
          <p>Audit Log is not supported for Spring Boot 1.x applications.</p>
        </div>
      </div>
34 35 36
      <auditevents-list v-if="events" :instance="instance" :events="events"/>
    </div>
  </section>
37 38 39 40
</template>

<script>
  import subscribing from '@/mixins/subscribing';
41
  import Instance from '@/services/instance';
42 43
  import {Observable} from '@/utils/rxjs';
  import AuditeventsList from '@/views/instances/auditevents/auditevents-list';
44
  import _ from 'lodash';
45 46 47
  import moment from 'moment';

  class Auditevent {
48 49
    constructor({timestamp, ...event}) {
      Object.assign(this, event);
Johannes Edmeier committed
50
      this.timestamp = moment(timestamp);
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
    }

    get key() {
      return `${this.timestamp}-${this.type}-${this.principal}`;
    }

    get remoteAddress() {
      return this.data && this.data.details && this.data.details.remoteAddress || null;
    }

    get sessionId() {
      return this.data && this.data.details && this.data.details.sessionId || null;
    }

    isSuccess() {
66
      return this.type.toLowerCase().includes('success');
67 68 69
    }

    isFailure() {
70
      return this.type.toLowerCase().includes('failure');
71 72 73 74
    }
  }

  export default {
75 76 77 78 79 80
    props: {
      instance: {
        type: Instance,
        required: true
      }
    },
81 82 83
    mixins: [subscribing],
    components: {AuditeventsList},
    data: () => ({
84 85
      hasLoaded: false,
      error: null,
86
      events: null,
87
      isOldAuditevents: false
88 89 90 91 92 93 94 95 96 97 98 99 100
    }),
    methods: {
      async fetchAuditevents() {
        const response = await this.instance.fetchAuditevents(this.lastTimestamp);
        const converted = response.data.events.map(event => new Auditevent(event));
        converted.reverse();
        if (converted.length > 0) {
          this.lastTimestamp = converted[0].timestamp;
        }
        return converted;
      },
      createSubscription() {
        const vm = this;
101 102 103 104 105 106 107 108 109 110 111 112
        vm.lastTimestamp = moment(0);
        vm.error = null;
        return Observable.timer(0, 5000)
          .concatMap(this.fetchAuditevents)
          .subscribe({
            next: events => {
              vm.hasLoaded = true;
              vm.addEvents(events);
            },
            error: error => {
              vm.hasLoaded = true;
              console.warn('Fetching audit events failed:', error);
113 114 115 116 117
              if (error.response.headers['content-type'].includes('application/vnd.spring-boot.actuator.v2')) {
                vm.error = error;
              } else {
                vm.isOldAuditevents = true;
              }
118 119
            }
          });
120 121 122
      },
      addEvents(events) {
        this.events = _.uniqBy(this.events ? events.concat(this.events) : events, event => event.key);
123 124 125
      }
    }
  }
126
</script>