change credentials #39

This commit is contained in:
Alireza Ahmadi
2024-02-27 19:53:12 +01:00
parent 8a2407fbd3
commit b0817e9c05
8 changed files with 250 additions and 1 deletions
+20
View File
@@ -70,6 +70,19 @@ func (a *APIHandler) postHandler(c *gin.Context) {
}
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":
loginUser := GetLoginUser(c)
data := map[string]string{}
@@ -104,6 +117,13 @@ func (a *APIHandler) getHandler(c *gin.Context) {
return
}
jsonObj(c, data, nil)
case "users":
users, err := a.UserService.GetUsers()
if err != nil {
jsonMsg(c, "", err)
return
}
jsonObj(c, *users, nil)
case "setting":
data, err := a.SettingService.GetAllSetting()
if err != nil {
+23 -1
View File
@@ -36,7 +36,7 @@ func (s *UserService) CheckUser(username string, password string, remoteIP strin
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{}).
Where("username = ?", username).
Update("last_logins", &lastLoginTxt).Error
@@ -45,3 +45,25 @@ func (s *UserService) CheckUser(username string, password string, remoteIP strin
}
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
}
+1
View File
@@ -55,6 +55,7 @@ const menu = [
{ title: 'pages.outbounds', icon: 'mdi-cloud-upload', path: '/outbounds' },
{ title: 'pages.rules', icon: 'mdi-routes', path: '/rules' },
{ 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' },
]
+96
View File
@@ -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>
+7
View File
@@ -27,6 +27,7 @@ export default {
clients: "Clients",
rules: "Rules",
basics: "Basics",
admins: "Admins",
settings: "Settings",
},
main: {
@@ -84,6 +85,12 @@ export default {
menu: {
logout: "Logout",
},
admin: {
changeCred: "Change credentials",
oldPass: "Current Password",
newUname: "New Username",
newPass: "New Password",
},
setting: {
interface: "Interface",
sub: "Subscription",
+7
View File
@@ -27,6 +27,7 @@ export default {
clients: "کاربران",
rules: "قوانین",
basics: "ترازها",
admins: "ادمین‌ها",
settings: "پیکربندی",
},
main: {
@@ -84,6 +85,12 @@ export default {
menu: {
logout: "خروج",
},
admin: {
changeCred: "ویرایش داده‌ها",
oldPass: "رمز کنونی",
newUname: "نام کاربری جدید",
newPass: "رمز جدید",
},
setting: {
interface: "نما",
sub: "سابسکریپشن",
+5
View File
@@ -44,6 +44,11 @@ const routes = [
name: 'pages.basics',
component: () => import('@/views/Basics.vue'),
},
{
path: '/admins',
name: 'pages.admins',
component: () => import('@/views/Admins.vue'),
},
{
path: '/settings',
name: 'pages.settings',
+91
View File
@@ -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>