mirror of
https://github.com/h44z/wg-portal.git
synced 2026-01-29 06:36:24 +00:00
feat: allow multiple auth sources per user (#500,#477) (#612)
* feat: allow multiple auth sources per user (#500,#477) * only override isAdmin flag if it is provided by the authentication source
This commit is contained in:
@@ -42,7 +42,7 @@ const passwordWeak = computed(() => {
|
||||
})
|
||||
|
||||
const formValid = computed(() => {
|
||||
if (formData.value.Source !== 'db') {
|
||||
if (!formData.value.AuthSources.some(s => s === 'db')) {
|
||||
return true // nothing to validate
|
||||
}
|
||||
if (props.userId !== '#NEW#' && passwordWeak.value) {
|
||||
@@ -70,7 +70,7 @@ watch(() => props.visible, async (newValue, oldValue) => {
|
||||
} else { // fill existing userdata
|
||||
formData.value.Identifier = selectedUser.value.Identifier
|
||||
formData.value.Email = selectedUser.value.Email
|
||||
formData.value.Source = selectedUser.value.Source
|
||||
formData.value.AuthSources = selectedUser.value.AuthSources
|
||||
formData.value.IsAdmin = selectedUser.value.IsAdmin
|
||||
formData.value.Firstname = selectedUser.value.Firstname
|
||||
formData.value.Lastname = selectedUser.value.Lastname
|
||||
@@ -80,6 +80,7 @@ watch(() => props.visible, async (newValue, oldValue) => {
|
||||
formData.value.Password = ""
|
||||
formData.value.Disabled = selectedUser.value.Disabled
|
||||
formData.value.Locked = selectedUser.value.Locked
|
||||
formData.value.PersistLocalChanges = selectedUser.value.PersistLocalChanges
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -133,7 +134,7 @@ async function del() {
|
||||
<template>
|
||||
<Modal :title="title" :visible="visible" @close="close">
|
||||
<template #default>
|
||||
<fieldset v-if="formData.Source==='db'">
|
||||
<fieldset>
|
||||
<legend class="mt-4">{{ $t('modals.user-edit.header-general') }}</legend>
|
||||
<div v-if="props.userId==='#NEW#'" class="form-group">
|
||||
<label class="form-label mt-4">{{ $t('modals.user-edit.identifier.label') }}</label>
|
||||
@@ -141,16 +142,22 @@ async function del() {
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label mt-4">{{ $t('modals.user-edit.source.label') }}</label>
|
||||
<input v-model="formData.Source" class="form-control" disabled="disabled" :placeholder="$t('modals.user-edit.source.placeholder')" type="text">
|
||||
<input v-model="formData.AuthSources" class="form-control" disabled="disabled" :placeholder="$t('modals.user-edit.source.placeholder')" type="text">
|
||||
</div>
|
||||
<div v-if="formData.Source==='db'" class="form-group">
|
||||
<div class="form-group" v-if="formData.AuthSources.some(s => s ==='db')">
|
||||
<label class="form-label mt-4">{{ $t('modals.user-edit.password.label') }}</label>
|
||||
<input v-model="formData.Password" aria-describedby="passwordHelp" class="form-control" :class="{ 'is-invalid': passwordWeak, 'is-valid': formData.Password !== '' && !passwordWeak }" :placeholder="$t('modals.user-edit.password.placeholder')" type="password">
|
||||
<div class="invalid-feedback">{{ $t('modals.user-edit.password.too-weak') }}</div>
|
||||
<small v-if="props.userId!=='#NEW#'" id="passwordHelp" class="form-text text-muted">{{ $t('modals.user-edit.password.description') }}</small>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset v-if="formData.Source==='db'">
|
||||
<fieldset v-if="formData.AuthSources.some(s => s !=='db') && !formData.PersistLocalChanges">
|
||||
<legend class="mt-4">{{ $t('modals.user-edit.header-personal') }}</legend>
|
||||
<div class="alert alert-warning mt-3">
|
||||
{{ $t('modals.user-edit.sync-warning') }}
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset v-if="!formData.AuthSources.some(s => s !=='db') || formData.PersistLocalChanges">
|
||||
<legend class="mt-4">{{ $t('modals.user-edit.header-personal') }}</legend>
|
||||
<div class="form-group">
|
||||
<label class="form-label mt-4">{{ $t('modals.user-edit.email.label') }}</label>
|
||||
@@ -194,10 +201,14 @@ async function del() {
|
||||
<input v-model="formData.Locked" class="form-check-input" type="checkbox">
|
||||
<label class="form-check-label" >{{ $t('modals.user-edit.locked.label') }}</label>
|
||||
</div>
|
||||
<div class="form-check form-switch" v-if="formData.Source==='db'">
|
||||
<div class="form-check form-switch" v-if="!formData.AuthSources.some(s => s !=='db') || formData.PersistLocalChanges">
|
||||
<input v-model="formData.IsAdmin" checked="" class="form-check-input" type="checkbox">
|
||||
<label class="form-check-label">{{ $t('modals.user-edit.admin.label') }}</label>
|
||||
</div>
|
||||
<div class="form-check form-switch" v-if="formData.AuthSources.some(s => s !=='db')">
|
||||
<input v-model="formData.PersistLocalChanges" class="form-check-input" type="checkbox">
|
||||
<label class="form-check-label" >{{ $t('modals.user-edit.persist-local-changes.label') }}</label>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
</template>
|
||||
|
||||
@@ -137,7 +137,7 @@ export function freshUser() {
|
||||
Identifier: "",
|
||||
|
||||
Email: "",
|
||||
Source: "db",
|
||||
AuthSources: ["db"],
|
||||
IsAdmin: false,
|
||||
|
||||
Firstname: "",
|
||||
@@ -155,6 +155,8 @@ export function freshUser() {
|
||||
|
||||
ApiEnabled: false,
|
||||
|
||||
PersistLocalChanges: false,
|
||||
|
||||
PeerCount: 0,
|
||||
|
||||
// Internal values
|
||||
|
||||
@@ -147,7 +147,7 @@
|
||||
"email": "E-Mail",
|
||||
"firstname": "Vorname",
|
||||
"lastname": "Nachname",
|
||||
"source": "Quelle",
|
||||
"sources": "Quellen",
|
||||
"peers": "Peers",
|
||||
"admin": "Admin"
|
||||
},
|
||||
@@ -378,7 +378,11 @@
|
||||
},
|
||||
"admin": {
|
||||
"label": "Ist Administrator"
|
||||
}
|
||||
},
|
||||
"persist-local-changes": {
|
||||
"label": "Lokale Änderungen speichern"
|
||||
},
|
||||
"sync-warning": "Um diesen synchronisierten Benutzer zu bearbeiten, aktivieren Sie die lokale Änderungsspeicherung. Andernfalls werden Ihre Änderungen bei der nächsten Synchronisierung überschrieben."
|
||||
},
|
||||
"interface-view": {
|
||||
"headline": "Konfiguration für Schnittstelle:"
|
||||
|
||||
@@ -147,7 +147,7 @@
|
||||
"email": "E-Mail",
|
||||
"firstname": "Firstname",
|
||||
"lastname": "Lastname",
|
||||
"source": "Source",
|
||||
"sources": "Sources",
|
||||
"peers": "Peers",
|
||||
"admin": "Admin"
|
||||
},
|
||||
@@ -378,7 +378,11 @@
|
||||
},
|
||||
"admin": {
|
||||
"label": "Is Admin"
|
||||
}
|
||||
},
|
||||
"persist-local-changes": {
|
||||
"label": "Persist local changes"
|
||||
},
|
||||
"sync-warning": "To modify this synchronized user, enable local change persistence. Otherwise, your changes will be overwritten during the next synchronization."
|
||||
},
|
||||
"interface-view": {
|
||||
"headline": "Config for Interface:"
|
||||
|
||||
@@ -162,7 +162,7 @@
|
||||
"email": "Correo electrónico",
|
||||
"firstname": "Nombre",
|
||||
"lastname": "Apellido",
|
||||
"source": "Origen",
|
||||
"sources": "Origen",
|
||||
"peers": "Peers",
|
||||
"admin": "Administrador"
|
||||
},
|
||||
|
||||
@@ -137,7 +137,7 @@
|
||||
"email": "E-mail",
|
||||
"firstname": "Prénom",
|
||||
"lastname": "Nom",
|
||||
"source": "Source",
|
||||
"sources": "Sources",
|
||||
"peers": "Pairs",
|
||||
"admin": "Admin"
|
||||
},
|
||||
|
||||
@@ -136,7 +136,7 @@
|
||||
"email": "이메일",
|
||||
"firstname": "이름",
|
||||
"lastname": "성",
|
||||
"source": "소스",
|
||||
"sources": "소스",
|
||||
"peers": "피어",
|
||||
"admin": "관리자"
|
||||
},
|
||||
|
||||
@@ -137,7 +137,7 @@
|
||||
"email": "E-Mail",
|
||||
"firstname": "Primeiro Nome",
|
||||
"lastname": "Último Nome",
|
||||
"source": "Fonte",
|
||||
"sources": "Fonte",
|
||||
"peers": "Peers",
|
||||
"admin": "Administrador"
|
||||
},
|
||||
|
||||
@@ -143,7 +143,7 @@
|
||||
"email": "Электронная почта",
|
||||
"firstname": "Имя",
|
||||
"lastname": "Фамилия",
|
||||
"source": "Источник",
|
||||
"sources": "Источник",
|
||||
"peers": "Пиры",
|
||||
"admin": "Админ"
|
||||
},
|
||||
|
||||
@@ -135,7 +135,7 @@
|
||||
"email": "E-Mail",
|
||||
"firstname": "Ім'я",
|
||||
"lastname": "Прізвище",
|
||||
"source": "Джерело",
|
||||
"sources": "Джерело",
|
||||
"peers": "Піри",
|
||||
"admin": "Адміністратор"
|
||||
},
|
||||
|
||||
@@ -134,7 +134,7 @@
|
||||
"email": "E-Mail",
|
||||
"firstname": "Tên",
|
||||
"lastname": "Họ",
|
||||
"source": "Nguồn",
|
||||
"sources": "Nguồn",
|
||||
"peers": "Peers",
|
||||
"admin": "Quản trị viên"
|
||||
},
|
||||
|
||||
@@ -134,7 +134,7 @@
|
||||
"email": "电子邮件",
|
||||
"firstname": "名",
|
||||
"lastname": "姓",
|
||||
"source": "来源",
|
||||
"sources": "来源",
|
||||
"peers": "节点",
|
||||
"admin": "管理员"
|
||||
},
|
||||
|
||||
@@ -131,7 +131,7 @@ onMounted(() => {
|
||||
<th scope="col">{{ $t('users.table-heading.email') }}</th>
|
||||
<th scope="col">{{ $t('users.table-heading.firstname') }}</th>
|
||||
<th scope="col">{{ $t('users.table-heading.lastname') }}</th>
|
||||
<th class="text-center" scope="col">{{ $t('users.table-heading.source') }}</th>
|
||||
<th class="text-center" scope="col">{{ $t('users.table-heading.sources') }}</th>
|
||||
<th class="text-center" scope="col">{{ $t('users.table-heading.peers') }}</th>
|
||||
<th class="text-center" scope="col">{{ $t('users.table-heading.admin') }}</th>
|
||||
<th scope="col"></th><!-- Actions -->
|
||||
@@ -150,7 +150,7 @@ onMounted(() => {
|
||||
<td>{{user.Email}}</td>
|
||||
<td>{{user.Firstname}}</td>
|
||||
<td>{{user.Lastname}}</td>
|
||||
<td class="text-center"><span class="badge rounded-pill bg-light">{{user.Source}}</span></td>
|
||||
<td><span class="badge bg-light me-1" v-for="src in user.AuthSources" :key="src">{{src}}</span></td>
|
||||
<td class="text-center">{{user.PeerCount}}</td>
|
||||
<td class="text-center">
|
||||
<span v-if="user.IsAdmin" class="text-danger" :title="$t('users.admin')"><i class="fa fa-check-circle"></i></span>
|
||||
|
||||
Reference in New Issue
Block a user