1
0
Fork 0
mirror of synced 2024-05-28 13:01:14 -04:00
ovpn-admin/frontend/src/main.js

545 lines
16 KiB
JavaScript
Raw Normal View History

2020-05-14 19:13:33 -04:00
import Vue from 'vue';
import axios from 'axios';
2022-12-30 09:25:21 -05:00
import VueQr from 'vue-qr'
import VueCookies from 'vue-cookies'
import BootstrapVue from 'bootstrap-vue'
import Notifications from 'vue-notification'
import VueGoodTablePlugin from 'vue-good-table'
2020-10-29 06:50:19 -04:00
Vue.use(VueCookies)
Vue.use(BootstrapVue)
Vue.use(Notifications)
Vue.use(VueGoodTablePlugin)
2022-12-30 09:25:21 -05:00
Vue.use(VueQr)
2020-05-14 19:13:33 -04:00
2022-12-30 09:25:21 -05:00
let axios_cfg = function(url, data='', type='form') {
2020-05-14 19:13:33 -04:00
if (data == '') {
return {
method: 'get',
url: url
};
} else if (type == 'form') {
return {
method: 'post',
url: url,
data: data,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
};
} else if (type == 'file') {
return {
method: 'post',
url: url,
data: data,
headers: { 'Content-Type': 'multipart/form-data' }
};
2020-10-29 06:50:19 -04:00
} else if (type == 'json') {
return {
method: 'post',
url: url,
data: data,
headers: { 'Content-Type': 'application/json' }
};
2020-05-14 19:13:33 -04:00
}
};
new Vue({
el: '#app',
data: {
2020-10-29 06:50:19 -04:00
columns: [
{
label: 'Name',
field: 'Identity',
// filterable: true,
},
{
label: 'Account Status',
field: 'AccountStatus',
filterable: true,
},
{
label: 'Active Connections',
field: 'Connections',
filterable: true,
},
2020-10-29 06:50:19 -04:00
{
label: 'Expiration Date',
field: 'ExpirationDate',
type: 'date',
dateInputFormat: 'yyyy-MM-dd HH:mm:ss',
dateOutputFormat: 'yyyy-MM-dd HH:mm:ss',
formatFn: function (value) {
return value != "" ? value : ""
}
},
{
label: 'Revocation Date',
field: 'RevocationDate',
type: 'date',
dateInputFormat: 'yyyy-MM-dd HH:mm:ss',
dateOutputFormat: 'yyyy-MM-dd HH:mm:ss',
formatFn: function (value) {
return value != "" ? value : ""
}
},
{
label: 'Actions',
field: 'actions',
sortable: false,
tdClass: 'text-right',
globalSearchDisabled: true,
},
],
rows: [],
actions: [
{
name: 'u-change-password',
label: 'Change password',
class: 'btn-warning',
showWhenStatus: 'Active',
showForServerRole: ['master'],
showForModule: ['passwdAuth'],
},
2022-12-30 09:25:21 -05:00
{
name: 'u-2fa',
label: '2FA',
class: 'btn-success',
showWhenStatus: 'Active',
showForServerRole: ['master'],
showForModule: ['totpAuth'],
},
2020-10-29 06:50:19 -04:00
{
name: 'u-revoke',
label: 'Revoke',
class: 'btn-warning',
showWhenStatus: 'Active',
showForServerRole: ['master'],
showForModule: ["core"],
2020-10-29 06:50:19 -04:00
},
{
name: 'u-delete',
label: 'Delete',
class: 'btn-danger',
showWhenStatus: 'Revoked',
showForServerRole: ['master'],
showForModule: ["core"],
},
{
name: 'u-delete',
label: 'Delete',
class: 'btn-danger',
showWhenStatus: 'Expired',
showForServerRole: ['master'],
showForModule: ["core"],
},
{
name: 'u-rotate',
label: 'Rotate',
class: 'btn-warning',
showWhenStatus: 'Revoked',
showForServerRole: ['master'],
showForModule: ["core"],
},
{
name: 'u-rotate',
label: 'Rotate',
class: 'btn-warning',
showWhenStatus: 'Expired',
showForServerRole: ['master'],
showForModule: ["core"],
},
2020-10-29 06:50:19 -04:00
{
name: 'u-unrevoke',
label: 'Unrevoke',
class: 'btn-primary',
showWhenStatus: 'Revoked',
showForServerRole: ['master'],
showForModule: ["core"],
2020-10-29 06:50:19 -04:00
},
{
name: 'u-download-config',
label: 'Download config',
class: 'btn-info',
showWhenStatus: 'Active',
showForServerRole: ['master', 'slave'],
showForModule: ["core"],
2020-10-29 06:50:19 -04:00
},
{
name: 'u-edit-ccd',
label: 'Edit routes',
class: 'btn-primary',
showWhenStatus: 'Active',
showForServerRole: ['master'],
showForModule: ["ccd"],
},
{
name: 'u-edit-ccd',
label: 'Show routes',
class: 'btn-primary',
showWhenStatus: 'Active',
showForServerRole: ['slave'],
showForModule: ["ccd"],
2020-10-29 06:50:19 -04:00
}
],
filters: {
hideRevoked: true,
},
serverRole: "master",
lastSync: "unknown",
modulesEnabled: [],
2020-05-14 19:13:33 -04:00
u: {
newUserName: '',
newUserPassword: '',
newPassword: '',
2022-12-30 09:25:21 -05:00
modalActionStatus: '',
modalActionMessage: '',
2020-05-14 19:13:33 -04:00
modalNewUserVisible: false,
2020-10-29 06:50:19 -04:00
modalShowCcdVisible: false,
modalChangePasswordVisible: false,
modalRotateUserVisible: false,
modalDeleteUserVisible: false,
2022-12-30 09:25:21 -05:00
modalRegister2faVisible: false,
2020-10-29 06:50:19 -04:00
openvpnConfig: '',
2022-12-30 09:25:21 -05:00
secret: '',
token: '',
twofaurl: '',
2020-10-29 06:50:19 -04:00
ccd: {
Name: '',
ClientAddress: '',
CustomRoutes: []
},
newRoute: {},
2020-05-14 19:13:33 -04:00
}
},
watch: {
},
mounted: function () {
this.getUserData();
this.getServerSetting();
this.filters.hideRevoked = this.$cookies.isKey('hideRevoked') ? (this.$cookies.get('hideRevoked') == "true") : false
2020-05-14 19:13:33 -04:00
},
created() {
2022-12-30 09:25:21 -05:00
let _this = this;
2020-10-29 06:50:19 -04:00
_this.$root.$on('u-revoke', function (msg) {
2022-12-30 09:25:21 -05:00
let data = new URLSearchParams();
2020-10-29 06:50:19 -04:00
data.append('username', _this.username);
2020-05-14 19:13:33 -04:00
axios.request(axios_cfg('api/user/revoke', data, 'form'))
.then(function(response) {
_this.getUserData();
_this.$notify({title: 'User ' + _this.username + ' revoked!', type: 'warn'})
2022-12-30 09:25:21 -05:00
}).catch(function(error) {
console.error()
_this.$notify({title: 'Failed to revoke user ' + _this.username , type: 'error'})
2020-05-14 19:13:33 -04:00
});
})
2020-10-29 06:50:19 -04:00
_this.$root.$on('u-unrevoke', function () {
2022-12-30 09:25:21 -05:00
let data = new URLSearchParams();
2020-10-29 06:50:19 -04:00
data.append('username', _this.username);
2020-05-14 19:13:33 -04:00
axios.request(axios_cfg('api/user/unrevoke', data, 'form'))
.then(function(response) {
_this.getUserData();
_this.$notify({title: 'User ' + _this.username + ' unrevoked!', type: 'success'})
2022-12-30 09:25:21 -05:00
}).catch(function(error) {
console.error()
_this.$notify({title: 'Failed to unrevoke user ' + _this.username , type: 'error'})
2020-05-14 19:13:33 -04:00
});
})
_this.$root.$on('u-rotate', function () {
_this.u.modalRotateUserVisible = true;
2022-12-30 09:25:21 -05:00
let data = new URLSearchParams();
data.append('username', _this.username);
})
_this.$root.$on('u-delete', function () {
_this.u.modalDeleteUserVisible = true;
2022-12-30 09:25:21 -05:00
let data = new URLSearchParams();
data.append('username', _this.username);
})
2020-10-29 06:50:19 -04:00
_this.$root.$on('u-download-config', function () {
2022-12-30 09:25:21 -05:00
let data = new URLSearchParams();
2020-10-29 06:50:19 -04:00
data.append('username', _this.username);
axios.request(axios_cfg('api/user/config/show', data, 'form'))
2020-10-15 12:12:31 -04:00
.then(function(response) {
2020-10-29 06:50:19 -04:00
const blob = new Blob([response.data], { type: 'text/plain' })
const link = document.createElement('a')
link.href = URL.createObjectURL(blob)
link.download = _this.username + ".ovpn"
link.click()
URL.revokeObjectURL(link.href)
2022-12-30 09:25:21 -05:00
}).catch(function(error) {
console.error()
_this.$notify({title: 'Failed to download config for user ' + _this.username , type: 'error'})
});
2020-10-29 06:50:19 -04:00
})
_this.$root.$on('u-edit-ccd', function () {
_this.u.modalShowCcdVisible = true;
2022-12-30 09:25:21 -05:00
let data = new URLSearchParams();
2020-10-29 06:50:19 -04:00
data.append('username', _this.username);
axios.request(axios_cfg('api/user/ccd', data, 'form'))
.then(function(response) {
_this.u.ccd = response.data;
});
})
_this.$root.$on('u-disconnect-user', function () {
2020-10-29 06:50:19 -04:00
_this.u.modalShowCcdVisible = true;
2022-12-30 09:25:21 -05:00
let data = new URLSearchParams();
2020-10-29 06:50:19 -04:00
data.append('username', _this.username);
axios.request(axios_cfg('api/user/disconnect', data, 'form'))
.then(function(response) {
2020-11-20 11:11:58 -05:00
console.log(response.data);
2020-10-15 12:12:31 -04:00
});
})
_this.$root.$on('u-change-password', function () {
_this.u.modalChangePasswordVisible = true;
2022-12-30 09:25:21 -05:00
let data = new URLSearchParams();
data.append('username', _this.username);
})
2022-12-30 09:25:21 -05:00
_this.$root.$on('u-2fa', function () {
_this.u.modalRegister2faVisible = true;
let data = new URLSearchParams();
data.append('username', _this.username);
data.append('secondfactor', _this.secondfactor);
data.append('token', _this.token);
_this.getUserTFAData(data);
})
2020-05-14 19:13:33 -04:00
},
computed: {
customAddressDynamic: function () {
return this.u.ccd.ClientAddress == "dynamic"
2020-05-14 19:13:33 -04:00
},
2022-12-30 09:25:21 -05:00
alertCssClass: function () {
return this.u.modalActionStatus == 200 ? "alert-success" : "alert-danger"
},
revokeFilterText: function() {
return this.filters.hideRevoked ? "Show revoked" : "Hide revoked"
},
filteredRows: function() {
if (this.filters.hideRevoked) {
return this.rows.filter(function(account) {
return account.AccountStatus == "Active"
});
} else {
return this.rows
}
}
2022-12-30 09:25:21 -05:00
},
2020-10-29 06:50:19 -04:00
methods: {
rowStyleClassFn: function(row) {
if (row.ConnectionStatus == 'Connected') {
return 'connected-user'
}
if (row.AccountStatus == 'Revoked') {
return 'revoked-user'
}
if (row.AccountStatus == 'Expired') {
return 'expired-user'
}
return ''
2020-10-29 06:50:19 -04:00
},
2022-12-30 09:25:21 -05:00
2020-10-29 06:50:19 -04:00
rowActionFn: function(e) {
this.username = e.target.dataset.username;
2022-12-30 09:25:21 -05:00
this.secondfactor = e.target.dataset.secondfactor;
2020-10-29 06:50:19 -04:00
this.$root.$emit(e.target.dataset.name);
2020-05-14 19:13:33 -04:00
},
2022-12-30 09:25:21 -05:00
getUserData: function() {
2022-12-30 09:25:21 -05:00
let _this = this;
2020-05-14 19:13:33 -04:00
axios.request(axios_cfg('api/users/list'))
.then(function(response) {
2021-07-16 04:03:12 -04:00
_this.rows = Array.isArray(response.data) ? response.data : [];
});
},
2022-12-30 09:25:21 -05:00
getUserTFAData: function(data) {
let _this = this;
if (!_this.secondfactor) {
axios.request(axios_cfg('api/user/2fa/secret', data, 'form'))
.then(function (response) {
_this.u.secret = response.data;
_this.u.twofaurl = "otpauth://totp/ovpn-" + _this.username + "?secret=" + _this.u.secret + "&issuer=OVPN";
});
}
},
registerUser2faApp: function(username) {
let _this = this;
let data = new URLSearchParams();
data.append('username', username);
data.append('token', _this.u.token);
axios.request(axios_cfg('api/user/2fa/register', data, 'form'))
.then(function(response) {
_this.u.modalActionStatus = 200;
_this.u.modalRegister2faVisible = false;
_this.getUserData();
_this.secondfactor = true;
_this.u.token = "";
_this.u.secret = "";
_this.$notify({title: '2FA application registered for user ' + username, type: 'success'});
})
.catch(function(error) {
_this.u.modalActionStatus = error.response.status;
_this.u.modalActionMessage = error.response.data.message;
_this.$notify({title: 'Register 2FA application for user ' + username + ' failed!', type: 'error'});
})
},
resetUser2faApp: function(username) {
let _this = this;
let data = new URLSearchParams();
data.append('username', username);
data.append('secondfactor', _this.secondfactor);
axios.request(axios_cfg('api/user/2fa/reset', data, 'form'))
.then(function(response) {
_this.u.modalActionStatus = 200;
_this.secondfactor = false;
_this.getUserTFAData(data);
_this.getUserData();
_this.$notify({title: '2FA application reset for user ' + username, type: 'success'});
})
.catch(function(error) {
_this.u.modalActionStatus = error.response.status;
_this.u.modalActionMessage = error.response.data.message;
_this.$notify({title: 'Reset 2FA application for user ' + username + ' failed!', type: 'error'});
})
},
getServerSetting: function() {
2022-12-30 09:25:21 -05:00
let _this = this;
axios.request(axios_cfg('api/server/settings'))
2020-05-14 19:13:33 -04:00
.then(function(response) {
_this.serverRole = response.data.serverRole;
_this.modulesEnabled = response.data.modules;
if (_this.serverRole == "slave") {
axios.request(axios_cfg('api/sync/last/successful'))
.then(function(response) {
_this.lastSync = response.data;
});
}
2020-10-15 12:12:31 -04:00
});
},
createUser: function() {
2022-12-30 09:25:21 -05:00
let _this = this;
2020-10-29 06:50:19 -04:00
2022-12-30 09:25:21 -05:00
_this.u.modalActionMessage = "";
2020-10-29 06:50:19 -04:00
2022-12-30 09:25:21 -05:00
let data = new URLSearchParams();
2020-10-29 06:50:19 -04:00
data.append('username', _this.u.newUserName);
data.append('password', _this.u.newUserPassword);
2020-10-29 06:50:19 -04:00
2021-10-05 11:09:29 -04:00
_this.username = _this.u.newUserName;
2020-05-14 19:13:33 -04:00
axios.request(axios_cfg('api/user/create', data, 'form'))
.then(function(response) {
2022-12-30 09:25:21 -05:00
_this.$notify({title: 'New user ' + _this.username + ' created', type: 'success'});
2020-10-29 06:50:19 -04:00
_this.u.modalNewUserVisible = false;
2020-05-14 19:13:33 -04:00
_this.u.newUserName = '';
_this.u.newUserPassword = '';
_this.getUserData();
2020-10-29 06:50:19 -04:00
})
.catch(function(error) {
2022-12-30 09:25:21 -05:00
_this.u.modalActionMessage = error.response.data;
_this.$notify({title: 'New user ' + _this.username + ' creation failed.', type: 'error'});
2020-05-14 19:13:33 -04:00
});
2020-10-15 12:12:31 -04:00
},
ccdApply: function() {
2022-12-30 09:25:21 -05:00
let _this = this;
2020-10-29 06:50:19 -04:00
2022-12-30 09:25:21 -05:00
_this.u.modalActionStatus= "";
_this.u.modalActionMessage = "";
2020-10-29 06:50:19 -04:00
axios.request(axios_cfg('api/user/ccd/apply', JSON.stringify(_this.u.ccd), 'json'))
2020-10-15 12:12:31 -04:00
.then(function(response) {
2022-12-30 09:25:21 -05:00
_this.u.modalActionStatus = 200;
_this.u.modalActionMessage = response.data;
_this.$notify({title: 'New CCD for user ' + _this.username + ' applied', type: 'success'});
2020-10-29 06:50:19 -04:00
})
.catch(function(error) {
2022-12-30 09:25:21 -05:00
_this.u.modalActionStatus = error.response.status;
_this.u.modalActionMessage = error.response.data.message;
_this.$notify({title: 'Apply new CCD for user ' + _this.username + 'failed ', type: 'error'});
2020-10-15 12:12:31 -04:00
});
},
2022-12-30 09:25:21 -05:00
changeUserPassword: function(username) {
let _this = this;
2022-12-30 09:25:21 -05:00
_this.u.modalActionMessage = "";
2022-12-30 09:25:21 -05:00
let data = new URLSearchParams();
data.append('username', username);
data.append('password', _this.u.newPassword);
axios.request(axios_cfg('api/user/change-password', data, 'form'))
.then(function(response) {
2022-12-30 09:25:21 -05:00
_this.u.modalActionStatus = 200;
_this.u.newPassword = '';
_this.getUserData();
_this.u.modalChangePasswordVisible = false;
2022-12-30 09:25:21 -05:00
_this.$notify({title: 'Password for user ' + username + ' changed!', type: 'success'});
})
.catch(function(error) {
2022-12-30 09:25:21 -05:00
_this.u.modalActionStatus = error.response.status;
_this.u.modalActionMessage = error.response.data.message;
_this.$notify({title: 'Changing password for user ' + username + ' failed!', type: 'error'});
});
},
2022-12-30 09:25:21 -05:00
rotateUser: function(username) {
let _this = this;
2022-12-30 09:25:21 -05:00
_this.u.modalActionMessage = "";
2022-12-30 09:25:21 -05:00
let data = new URLSearchParams();
data.append('username', username);
data.append('password', _this.u.newPassword);
axios.request(axios_cfg('api/user/rotate', data, 'form'))
.then(function(response) {
2022-12-30 09:25:21 -05:00
_this.u.modalActionStatus = 200;
_this.u.newPassword = '';
_this.getUserData();
_this.u.modalRotateUserVisible = false;
2022-12-30 09:25:21 -05:00
_this.$notify({title: 'Certificates for user ' + username + ' rotated!', type: 'success'});
})
.catch(function(error) {
2022-12-30 09:25:21 -05:00
_this.u.modalActionStatus = error.response.status;
_this.u.modalActionMessage = error.response.data.message;
_this.$notify({title: 'Rotate certificates for user ' + username + ' failed!', type: 'error'});
})
},
2022-12-30 09:25:21 -05:00
deleteUser: function(username) {
let _this = this;
_this.u.deleteUserMessage = "";
2022-12-30 09:25:21 -05:00
let data = new URLSearchParams();
data.append('username', username);
axios.request(axios_cfg('api/user/delete', data, 'form'))
.then(function(response) {
2022-12-30 09:25:21 -05:00
_this.u.modalActionStatus = 200;
_this.u.newPassword = '';
_this.getUserData();
_this.u.modalDeleteUserVisible = false;
2022-12-30 09:25:21 -05:00
_this.$notify({title: 'User ' + username + ' deleted!', type: 'success'});
})
.catch(function(error) {
2022-12-30 09:25:21 -05:00
_this.u.modalActionStatus = error.response.status;
_this.u.modalActionMessage = error.response.data.message;
_this.$notify({title: 'Deleting user ' + username + ' failed!', type: 'error'});
})
},
2020-05-14 19:13:33 -04:00
}
2020-05-14 19:13:33 -04:00
})