Skip to content
This repository has been archived by the owner on Aug 4, 2024. It is now read-only.

Commit

Permalink
1.7.0 - Added basic user audit log
Browse files Browse the repository at this point in the history
  • Loading branch information
rileyio committed Mar 28, 2019
1 parent 3d05786 commit d2bdf8b
Show file tree
Hide file tree
Showing 7 changed files with 287 additions and 3 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
1.7.0
- Added basic user audit log

1.6.1
- Reverting debugging changes

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "kiera-web",
"version": "1.6.1",
"version": "1.7.0",
"description": "Web portal for kiera-bot",
"main": "index.js",
"author": "Emma (RileyIO)",
Expand Down
2 changes: 2 additions & 0 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ import Login from "./components/login.vue";
import Sidebar from "./components/sidebar.vue";
// Panels
import AuditPanel from "./panels/AuditLog.vue";
import DecisionsPanel from "./panels/DecisionsList.vue";
import PermissionsPanel from "./panels/PermissionsList.vue";
import ServerNotificationsPanel from "./panels/ServerNotifications.vue";
Expand All @@ -101,6 +102,7 @@ export const routes: { [key: string]: any } = {
Login,
Sidebar,
// Panels
AuditPanel,
DecisionsPanel,
PermissionsPanel,
ServerNotificationsPanel,
Expand Down
8 changes: 8 additions & 0 deletions src/components/sidebar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@
<i class="el-icon-tickets"></i>
<span>Decisions Manager</span>
</el-menu-item>
<!-- Menu Item -->
<el-menu-item
index="1-6"
@click="$emit('onPanelChange', { panel: 'AuditPanel', view: 'all' })"
>
<i class="el-icon-news"></i>
<span>Audit Log</span>
</el-menu-item>
</el-menu>
</div>
</template>
Expand Down
249 changes: 249 additions & 0 deletions src/panels/AuditLog.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,249 @@
<template>
<div id="sidebar">
<el-row v-if="state.focusedView === 'all'">
<el-col :span="24">
<div class="grid-content bg-purple-dark">
<div class="h3">Audit Log
<el-button
type="primary"
plain
icon="el-icon-refresh"
size="small"
:loading="loading.isLoading"
@click="getAuditEntries()"
></el-button>
</div>
<span class="panel-description"></span>

<el-table
:data="auditEvents"
style="width: 100%"
v-loading="loading.isLoading"
size="mini"
>
<el-table-column type="expand" prop="allowed">
<!-- <template slot-scope="scope">
<PermissionsSub :data="scope"/>
</template>-->
</el-table-column>
<el-table-column label="Action" prop="details">
<template slot-scope="scope">
<span class="permission-wrapper">
<span>
{{scope.row.name}}
<el-tag
size="mini"
v-if="scope.row.successful === true"
type="success"
>Successful</el-tag>
<el-tag size="mini" v-else type="danger">Invalid</el-tag>
<el-tag size="mini" v-if="scope.row.type === 'api.oauth'" type="warning">Auth</el-tag>
</span>
<span class="row-example">{{scope.row.details}}</span>
</span>
</template>
</el-table-column>
<el-table-column label="Timestamp" prop="details" align="right">
<template slot-scope="scope">
<span class="permission-wrapper">
<span>{{new Date(scope.row.timestamp).toLocaleString()}}</span>
</span>
</template>
</el-table-column>
<el-table-column type="expand">
<template slot-scope="scope">
<el-row :gutter="20">
<el-col :span="4">
<div class="audit-entry">
<div class="details">
<span class="property">name</span>
</div>
<div class="details">
<span class="property">timestamp</span>
</div>
<div class="details">
<span class="property">runtime</span>
</div>
<div class="details">
<span class="property">type</span>
</div>
<div class="details">
<span class="property">where</span>
</div>
<div class="details" v-if="scope.row.guild">
<span class="property">server</span>
</div>
<div class="details" v-if="scope.row.error">
<span class="property">error</span>
</div>
</div>
</el-col>
<el-col :span="20">
<div class="audit-entry">
<div class="details">{{scope.row.name}}</div>
<div class="details">{{scope.row.timestamp}}</div>
<div class="details">{{scope.row.runtime}}ms</div>
<div class="details">{{scope.row.type}}</div>
<div class="details">{{scope.row.where}}</div>
<div
class="details"
v-if="scope.row.guild"
>{{scope.row.guild}}</div>
<div
class="details"
v-if="scope.row.error"
>{{scope.row.error}}</div>
</div>
</el-col>
</el-row>
</template>
</el-table-column>
</el-table>
</div>
</el-col>
</el-row>
</div>
</template>

<script lang="ts">
declare var process: any;
import Vue from "vue";
import Axios from "axios";
import { Component, Prop, Watch } from "vue-property-decorator";
import { state } from "../defaults/app-state";
import { buildRequestHeaders } from "../utils";
import { user } from "../defaults/user";
import { mappedGuilds } from "../defaults/guilds";
import { AuditEntry } from "../types/audit";
@Component({
// components: {
// }
})
export default class AuditPanel extends Vue {
@Prop({ default: () => state })
private state!: typeof state;
@Prop({
default: () => {
return { webToken: "", user: user, guilds: mappedGuilds };
}
})
public bot!: {
webToken: string;
user: typeof user;
guilds: typeof mappedGuilds;
};
@Prop({
default: () => []
})
public auditEvents!: Array<any>;
@Prop({
default: () => {
return { isLoading: true, loaded: false };
}
})
public loading!: { isLoading: boolean; loaded: boolean };
constructor() {
super();
this.getAuditEntries();
}
private async getAuditEntries() {
try {
this.loading.isLoading = true;
const resp = await Axios(`${process.env.BOT_HOST}/audit`, {
method: "POST",
data: {
serverLimited: false
},
headers: buildRequestHeaders()
});
if (resp.status === 200) {
// Merge in gui opts
// (<Array<AuditEntry>>resp.data).map(d => {
// d._deleteVisible = false;
// // Update outcomes with GUI props
// d.options.map(o => {
// o._isUpdating = false;
// o._isChanged = false;
// o._deleteVisible = false;
// o._originalText = o.text;
// return o;
// });
// return d;
// });
// Update cached data
this.auditEvents = resp.data;
console.log(resp.data);
}
} catch (error) {}
// Stop spinner
this.loading.isLoading = false;
}
private copyIDtoClipboard(_id: string) {
var el = <HTMLInputElement>document.getElementById(`roller-${_id}`);
console.log("copy from element:", el);
// Enable temp editing for copy api
el.disabled = false;
el.select();
document.execCommand("copy");
el.disabled = true;
this.$message(`${_id} copied to clipboard`);
}
}
</script>

<style lang="less">
i.header-icon.el-icon-info {
position: absolute;
right: 36px;
}
// Panel
.panel-description {
font-size: 12px;
display: block;
padding: 10px 4px;
}
// Audit specific
.audit-entry {
.details {
font-size: 11px;
margin: 4px 0px;
.property {
color: #f3f3f3;
background-color: #a2a2a2;
padding: 1px 2px;
}
}
}
.row-example {
display: block;
font-size: 11px;
color: #909090;
}
// Text modifiers
span.md {
padding: 2px 4px;
background-color: #e4e7edbd;
font-family: monospace;
font-size: 12px;
color: #484848;
border-radius: 2px;
}
</style>

;
4 changes: 2 additions & 2 deletions src/panels/PermissionsList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
<template slot-scope="scope">
<span class="permission-wrapper">
<span>{{scope.row.command}}</span>
<span class="permissin-example">{{scope.row.example}}</span>
<span class="row-example">{{scope.row.example}}</span>
</span>
</template>
</el-table-column>
Expand Down Expand Up @@ -266,7 +266,7 @@ i.header-icon.el-icon-info {
line-height: 1em;
}
.permissin-example {
.row-example {
display: block;
font-size: 11px;
color: #909090;
Expand Down
22 changes: 22 additions & 0 deletions src/types/audit.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
export type AuditEntryType = '<>'
| 'discord.message.delete'
| 'discord.user.join'
| 'discord.user.leave'
| 'discord.user.nickname'
| 'bot.command'
| 'bot.maintenance'

export type AuditEntryWhere = 'Unknown' | 'Discord' | 'API'

export interface AuditEntry {
name: string
details: string
error: string
guild: { id: string, name: string, channel?: string }
owner: string
runtime: number
successful: boolean
timestamp: string
type: AuditEntryType
where: AuditEntryWhere
}

0 comments on commit d2bdf8b

Please sign in to comment.