change credentials #39
This commit is contained in:
@@ -70,6 +70,19 @@ func (a *APIHandler) postHandler(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
jsonMsg(c, "", nil)
|
jsonMsg(c, "", nil)
|
||||||
|
case "changePass":
|
||||||
|
id := c.Request.FormValue("id")
|
||||||
|
oldPass := c.Request.FormValue("oldPass")
|
||||||
|
newUsername := c.Request.FormValue("newUsername")
|
||||||
|
newPass := c.Request.FormValue("newPass")
|
||||||
|
err = a.UserService.ChangePass(id, oldPass, newUsername, newPass)
|
||||||
|
if err == nil {
|
||||||
|
logger.Info("change user credentials success")
|
||||||
|
jsonMsg(c, "save", nil)
|
||||||
|
} else {
|
||||||
|
logger.Warning("change user credentials failed:", err)
|
||||||
|
jsonMsg(c, "", err)
|
||||||
|
}
|
||||||
case "save":
|
case "save":
|
||||||
loginUser := GetLoginUser(c)
|
loginUser := GetLoginUser(c)
|
||||||
data := map[string]string{}
|
data := map[string]string{}
|
||||||
@@ -104,6 +117,13 @@ func (a *APIHandler) getHandler(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
jsonObj(c, data, nil)
|
jsonObj(c, data, nil)
|
||||||
|
case "users":
|
||||||
|
users, err := a.UserService.GetUsers()
|
||||||
|
if err != nil {
|
||||||
|
jsonMsg(c, "", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
jsonObj(c, *users, nil)
|
||||||
case "setting":
|
case "setting":
|
||||||
data, err := a.SettingService.GetAllSetting()
|
data, err := a.SettingService.GetAllSetting()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
+23
-1
@@ -36,7 +36,7 @@ func (s *UserService) CheckUser(username string, password string, remoteIP strin
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
lastLoginTxt := time.Now().Format("2006-01-02 15:04:05") + "-" + remoteIP
|
lastLoginTxt := time.Now().Format("2006-01-02 15:04:05") + " " + remoteIP
|
||||||
err = db.Model(model.User{}).
|
err = db.Model(model.User{}).
|
||||||
Where("username = ?", username).
|
Where("username = ?", username).
|
||||||
Update("last_logins", &lastLoginTxt).Error
|
Update("last_logins", &lastLoginTxt).Error
|
||||||
@@ -45,3 +45,25 @@ func (s *UserService) CheckUser(username string, password string, remoteIP strin
|
|||||||
}
|
}
|
||||||
return user
|
return user
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *UserService) GetUsers() (*[]model.User, error) {
|
||||||
|
var users []model.User
|
||||||
|
db := database.GetDB()
|
||||||
|
err := db.Model(model.User{}).Select("id,username,last_logins").Scan(&users).Error
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &users, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *UserService) ChangePass(id string, oldPass string, newUser string, newPass string) error {
|
||||||
|
db := database.GetDB()
|
||||||
|
user := &model.User{}
|
||||||
|
err := db.Model(model.User{}).Where("id = ? AND password = ?", id, oldPass).First(user).Error
|
||||||
|
if err != nil || database.IsNotFound(err) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
user.Username = newUser
|
||||||
|
user.Password = newPass
|
||||||
|
return db.Save(user).Error
|
||||||
|
}
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ const menu = [
|
|||||||
{ title: 'pages.outbounds', icon: 'mdi-cloud-upload', path: '/outbounds' },
|
{ title: 'pages.outbounds', icon: 'mdi-cloud-upload', path: '/outbounds' },
|
||||||
{ title: 'pages.rules', icon: 'mdi-routes', path: '/rules' },
|
{ title: 'pages.rules', icon: 'mdi-routes', path: '/rules' },
|
||||||
{ title: 'pages.basics', icon: 'mdi-application-cog', path: '/basics' },
|
{ title: 'pages.basics', icon: 'mdi-application-cog', path: '/basics' },
|
||||||
|
{ title: 'pages.admins', icon: 'mdi-account-tie', path: '/admins' },
|
||||||
{ title: 'pages.settings', icon: 'mdi-cog', path: '/settings' },
|
{ title: 'pages.settings', icon: 'mdi-cog', path: '/settings' },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,96 @@
|
|||||||
|
<template>
|
||||||
|
<v-dialog transition="dialog-bottom-transition" width="400">
|
||||||
|
<v-card class="rounded-lg">
|
||||||
|
<v-card-title>
|
||||||
|
{{ $t('admin.changeCred') + " " + user.username }}
|
||||||
|
</v-card-title>
|
||||||
|
<v-divider></v-divider>
|
||||||
|
<v-card-text>
|
||||||
|
<v-row>
|
||||||
|
<v-col>
|
||||||
|
<v-text-field v-model="newData.oldPass" :label="$t('admin.oldPass')" :rules="passwordRules" type="password" required></v-text-field>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
<v-row>
|
||||||
|
<v-col>
|
||||||
|
<v-text-field v-model="newData.newUsername" :label="$t('admin.newUname')" :rules="usernameRules" required></v-text-field>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
<v-row>
|
||||||
|
<v-col>
|
||||||
|
<v-text-field v-model="newData.newPass" :label="$t('admin.newPass')" :rules="passwordRules" type="password" required></v-text-field>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</v-card-text>
|
||||||
|
<v-card-actions>
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
<v-btn
|
||||||
|
color="blue-darken-1"
|
||||||
|
variant="outlined"
|
||||||
|
@click="closeModal"
|
||||||
|
>
|
||||||
|
{{ $t('actions.close') }}
|
||||||
|
</v-btn>
|
||||||
|
<v-btn
|
||||||
|
color="blue-darken-1"
|
||||||
|
variant="tonal"
|
||||||
|
@click="saveChanges"
|
||||||
|
>
|
||||||
|
{{ $t('actions.save') }}
|
||||||
|
</v-btn>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</v-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { i18n } from '@/locales'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: ['visible', 'user'],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
newData: {
|
||||||
|
id: 0,
|
||||||
|
oldPass: "",
|
||||||
|
newUsername: "",
|
||||||
|
newPass: ""
|
||||||
|
},
|
||||||
|
usernameRules: [
|
||||||
|
(value: string) => {
|
||||||
|
if (value?.length > 0) return true
|
||||||
|
return i18n.global.t('login.unRules')
|
||||||
|
},
|
||||||
|
],
|
||||||
|
passwordRules: [
|
||||||
|
(value: string) => {
|
||||||
|
if (value?.length > 0) return true
|
||||||
|
return i18n.global.t('login.pwRules')
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
resetData() {
|
||||||
|
this.newData.id = this.$props.user.id
|
||||||
|
this.newData.oldPass = ""
|
||||||
|
this.newData.newUsername = ""
|
||||||
|
this.newData.newPass = ""
|
||||||
|
},
|
||||||
|
closeModal() {
|
||||||
|
this.resetData() // reset
|
||||||
|
this.$emit('close')
|
||||||
|
},
|
||||||
|
saveChanges() {
|
||||||
|
if (this.newData.oldPass == '' || this.newData.newUsername == '' || this.newData.newPass == '') return
|
||||||
|
this.$emit('save', this.newData)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
visible(newValue) { if (newValue) {
|
||||||
|
this.resetData()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -27,6 +27,7 @@ export default {
|
|||||||
clients: "Clients",
|
clients: "Clients",
|
||||||
rules: "Rules",
|
rules: "Rules",
|
||||||
basics: "Basics",
|
basics: "Basics",
|
||||||
|
admins: "Admins",
|
||||||
settings: "Settings",
|
settings: "Settings",
|
||||||
},
|
},
|
||||||
main: {
|
main: {
|
||||||
@@ -84,6 +85,12 @@ export default {
|
|||||||
menu: {
|
menu: {
|
||||||
logout: "Logout",
|
logout: "Logout",
|
||||||
},
|
},
|
||||||
|
admin: {
|
||||||
|
changeCred: "Change credentials",
|
||||||
|
oldPass: "Current Password",
|
||||||
|
newUname: "New Username",
|
||||||
|
newPass: "New Password",
|
||||||
|
},
|
||||||
setting: {
|
setting: {
|
||||||
interface: "Interface",
|
interface: "Interface",
|
||||||
sub: "Subscription",
|
sub: "Subscription",
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ export default {
|
|||||||
clients: "کاربران",
|
clients: "کاربران",
|
||||||
rules: "قوانین",
|
rules: "قوانین",
|
||||||
basics: "ترازها",
|
basics: "ترازها",
|
||||||
|
admins: "ادمینها",
|
||||||
settings: "پیکربندی",
|
settings: "پیکربندی",
|
||||||
},
|
},
|
||||||
main: {
|
main: {
|
||||||
@@ -84,6 +85,12 @@ export default {
|
|||||||
menu: {
|
menu: {
|
||||||
logout: "خروج",
|
logout: "خروج",
|
||||||
},
|
},
|
||||||
|
admin: {
|
||||||
|
changeCred: "ویرایش دادهها",
|
||||||
|
oldPass: "رمز کنونی",
|
||||||
|
newUname: "نام کاربری جدید",
|
||||||
|
newPass: "رمز جدید",
|
||||||
|
},
|
||||||
setting: {
|
setting: {
|
||||||
interface: "نما",
|
interface: "نما",
|
||||||
sub: "سابسکریپشن",
|
sub: "سابسکریپشن",
|
||||||
|
|||||||
@@ -44,6 +44,11 @@ const routes = [
|
|||||||
name: 'pages.basics',
|
name: 'pages.basics',
|
||||||
component: () => import('@/views/Basics.vue'),
|
component: () => import('@/views/Basics.vue'),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/admins',
|
||||||
|
name: 'pages.admins',
|
||||||
|
component: () => import('@/views/Admins.vue'),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/settings',
|
path: '/settings',
|
||||||
name: 'pages.settings',
|
name: 'pages.settings',
|
||||||
|
|||||||
@@ -0,0 +1,91 @@
|
|||||||
|
<template>
|
||||||
|
<AdminModal
|
||||||
|
v-model="editModal.visible"
|
||||||
|
:visible="editModal.visible"
|
||||||
|
:user="editModal.user"
|
||||||
|
@close="closeEditModal"
|
||||||
|
@save="saveEditModal"
|
||||||
|
/>
|
||||||
|
<v-row>
|
||||||
|
<v-col cols="12" sm="4" md="3" lg="2" v-for="(item, index) in <any[]>users" :key="item.id">
|
||||||
|
<v-card rounded="xl" elevation="5" min-width="200" :title="item.username">
|
||||||
|
<v-card-subtitle>
|
||||||
|
Last Login
|
||||||
|
</v-card-subtitle>
|
||||||
|
<v-card-text>
|
||||||
|
<v-row>
|
||||||
|
<v-col>Date</v-col>
|
||||||
|
<v-col dir="ltr">
|
||||||
|
{{ item.lastLogin.split(" ")[0]?? '-' }}
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
<v-row>
|
||||||
|
<v-col>Time</v-col>
|
||||||
|
<v-col dir="ltr">
|
||||||
|
{{ item.lastLogin.split(" ")[1]?? '-' }}
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
<v-row>
|
||||||
|
<v-col>IP</v-col>
|
||||||
|
<v-col dir="ltr">
|
||||||
|
{{ item.lastLogin.split(" ")[2]?? '-' }}
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</v-card-text>
|
||||||
|
<v-divider></v-divider>
|
||||||
|
<v-card-actions style="padding: 0;">
|
||||||
|
<v-btn icon="mdi-account-edit" @click="showEditModal(item)">
|
||||||
|
<v-icon />
|
||||||
|
<v-tooltip activator="parent" location="top" :text="$t('actions.edit')"></v-tooltip>
|
||||||
|
</v-btn>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import AdminModal from '@/layouts/modals/Admin.vue';
|
||||||
|
import HttpUtils from '@/plugins/httputil';
|
||||||
|
import { Ref, ref, inject, onMounted } from 'vue';
|
||||||
|
|
||||||
|
const loading:Ref = inject('loading')?? ref(false)
|
||||||
|
|
||||||
|
const users = ref([])
|
||||||
|
|
||||||
|
onMounted(async () => {loadData()})
|
||||||
|
|
||||||
|
const loadData = async () => {
|
||||||
|
loading.value = true
|
||||||
|
const msg = await HttpUtils.get('api/users')
|
||||||
|
loading.value = false
|
||||||
|
if (msg.success) {
|
||||||
|
users.value = msg.obj
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const editModal = ref({
|
||||||
|
visible: false,
|
||||||
|
user: {},
|
||||||
|
})
|
||||||
|
|
||||||
|
const showEditModal = (user: any) => {
|
||||||
|
editModal.value.user = user
|
||||||
|
editModal.value.visible = true
|
||||||
|
}
|
||||||
|
const closeEditModal = () => {
|
||||||
|
editModal.value.visible = false
|
||||||
|
}
|
||||||
|
const saveEditModal = async (data:any) => {
|
||||||
|
loading.value=true
|
||||||
|
const response = await HttpUtils.post('api/changePass',data)
|
||||||
|
if(response.success){
|
||||||
|
setTimeout(() => {
|
||||||
|
loading.value=false
|
||||||
|
editModal.value.visible = false
|
||||||
|
}, 500)
|
||||||
|
} else {
|
||||||
|
loading.value=false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
Reference in New Issue
Block a user