@drax/identity-vue 0.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +61 -0
- package/package.json +65 -0
- package/src/assets/base.css +86 -0
- package/src/assets/logo.svg +1 -0
- package/src/assets/main.css +35 -0
- package/src/combobox/PermissionCombobox.vue +38 -0
- package/src/combobox/RoleCombobox.vue +37 -0
- package/src/components/IdentityChangeOwnPassword/IdentityChangeOwnPassword.vue +139 -0
- package/src/components/IdentityLogin/IdentityLogin.vue +124 -0
- package/src/components/IdentityProfileAvatar/IdentityProfileAvatar.vue +38 -0
- package/src/components/IdentityProfileDrawer/IdentityProfileDrawer.vue +82 -0
- package/src/components/IdentityProfileView/IdentityProfileView.vue +31 -0
- package/src/components/PermissionSelector/PermissionSelector.vue +89 -0
- package/src/composables/useAuth.ts +53 -0
- package/src/composables/useI18nValidation.ts +11 -0
- package/src/composables/useRole.ts +93 -0
- package/src/composables/useUser.ts +96 -0
- package/src/cruds/role-crud/RoleCrud.vue +165 -0
- package/src/cruds/role-crud/RoleList.vue +110 -0
- package/src/cruds/user-crud/UserCrud.vue +222 -0
- package/src/cruds/user-crud/UserList.vue +100 -0
- package/src/forms/RoleForm.vue +44 -0
- package/src/forms/UserCreateForm.vue +101 -0
- package/src/forms/UserEditForm.vue +87 -0
- package/src/forms/UserPasswordForm.vue +81 -0
- package/src/i18n/I18n.ts +10 -0
- package/src/i18n/I18nMessages.ts +21 -0
- package/src/icons/IconCommunity.vue +7 -0
- package/src/index.ts +51 -0
- package/src/pages/RoleCrudPage.vue +12 -0
- package/src/pages/UserCrudPage.vue +12 -0
- package/src/stores/auth/AuthStore.ts +38 -0
- package/src/views/RoleView.vue +32 -0
- package/src/views/UserView.vue +34 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import {ref, defineModel, type PropType, computed} from "vue";
|
|
3
|
+
import type {IClientInputError} from "@drax/common-front";
|
|
4
|
+
import type {IUser, IUserPassword} from "@drax/identity-front";
|
|
5
|
+
import {useI18nValidation} from "../composables/useI18nValidation";
|
|
6
|
+
import {useI18n} from "vue-i18n";
|
|
7
|
+
|
|
8
|
+
const {t} = useI18n()
|
|
9
|
+
const {$ta} = useI18nValidation()
|
|
10
|
+
|
|
11
|
+
let newPasswordVisibility = ref(false)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
const props = defineProps({
|
|
15
|
+
inputErrors: {
|
|
16
|
+
type: Object as PropType<IClientInputError>,
|
|
17
|
+
default: () => ({id: "", newPassword: ""})
|
|
18
|
+
},
|
|
19
|
+
passwordChanged: {
|
|
20
|
+
type: Boolean,
|
|
21
|
+
default: false
|
|
22
|
+
}
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
const form = defineModel<IUserPassword>({
|
|
26
|
+
type: Object as PropType<IUserPassword>,
|
|
27
|
+
default: () => ({newPassword: "", confirmPassword: ""})
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
function confirmPasswordRule(value: string) {
|
|
31
|
+
return form.value.newPassword === form.value.confirmPassword || t('validation.password.confirmed')
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
</script>
|
|
36
|
+
|
|
37
|
+
<template>
|
|
38
|
+
|
|
39
|
+
<v-sheet v-if="passwordChanged">
|
|
40
|
+
<v-alert type="success">
|
|
41
|
+
{{ $t('user.passwordChanged') }}
|
|
42
|
+
</v-alert>
|
|
43
|
+
</v-sheet>
|
|
44
|
+
<v-sheet v-else>
|
|
45
|
+
<form ref="changeUserPassword">
|
|
46
|
+
|
|
47
|
+
<div class="text-subtitle-1 text-medium-emphasis">{{ $t('user.newPassword') }}</div>
|
|
48
|
+
<v-text-field
|
|
49
|
+
variant="outlined"
|
|
50
|
+
id="new-password-input"
|
|
51
|
+
v-model="form.newPassword"
|
|
52
|
+
:type="newPasswordVisibility ? 'text': 'password'"
|
|
53
|
+
required
|
|
54
|
+
prepend-inner-icon="mdi-lock-outline"
|
|
55
|
+
:append-inner-icon="newPasswordVisibility ? 'mdi-eye-off': 'mdi-eye'"
|
|
56
|
+
@click:append-inner="newPasswordVisibility = !newPasswordVisibility"
|
|
57
|
+
autocomplete="new-password"
|
|
58
|
+
:error-messages="$ta(inputErrors.newPassword)"
|
|
59
|
+
></v-text-field>
|
|
60
|
+
<div class="text-subtitle-1 text-medium-emphasis">{{ $t('user.confirmPassword') }}</div>
|
|
61
|
+
<v-text-field
|
|
62
|
+
variant="outlined"
|
|
63
|
+
id="confirm-password-input"
|
|
64
|
+
v-model="form.confirmPassword"
|
|
65
|
+
:type="newPasswordVisibility ? 'text': 'password'"
|
|
66
|
+
required
|
|
67
|
+
prepend-inner-icon="mdi-lock-outline"
|
|
68
|
+
:append-inner-icon="newPasswordVisibility ? 'mdi-eye-off': 'mdi-eye'"
|
|
69
|
+
@click:append-inner="newPasswordVisibility = !newPasswordVisibility"
|
|
70
|
+
autocomplete="new-password"
|
|
71
|
+
:error-messages="$ta(inputErrors.confirmPassword)"
|
|
72
|
+
:rules="[confirmPasswordRule]"
|
|
73
|
+
></v-text-field>
|
|
74
|
+
</form>
|
|
75
|
+
</v-sheet>
|
|
76
|
+
|
|
77
|
+
</template>
|
|
78
|
+
|
|
79
|
+
<style scoped>
|
|
80
|
+
|
|
81
|
+
</style>
|
package/src/i18n/I18n.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import {commonValidationI18n, identityValidationI18n} from "@drax/i18n-share"
|
|
2
|
+
import merge from 'deepmerge'
|
|
3
|
+
|
|
4
|
+
const mainMsg = {
|
|
5
|
+
en: {
|
|
6
|
+
main: {
|
|
7
|
+
home: 'Home',
|
|
8
|
+
}
|
|
9
|
+
},
|
|
10
|
+
es: {
|
|
11
|
+
main: {
|
|
12
|
+
home: 'Principal',
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const messages = merge.all([mainMsg,commonValidationI18n, identityValidationI18n])
|
|
18
|
+
|
|
19
|
+
console.log("messages",messages)
|
|
20
|
+
|
|
21
|
+
export default messages
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor">
|
|
3
|
+
<path
|
|
4
|
+
d="M15 4a1 1 0 1 0 0 2V4zm0 11v-1a1 1 0 0 0-1 1h1zm0 4l-.707.707A1 1 0 0 0 16 19h-1zm-4-4l.707-.707A1 1 0 0 0 11 14v1zm-4.707-1.293a1 1 0 0 0-1.414 1.414l1.414-1.414zm-.707.707l-.707-.707.707.707zM9 11v-1a1 1 0 0 0-.707.293L9 11zm-4 0h1a1 1 0 0 0-1-1v1zm0 4H4a1 1 0 0 0 1.707.707L5 15zm10-9h2V4h-2v2zm2 0a1 1 0 0 1 1 1h2a3 3 0 0 0-3-3v2zm1 1v6h2V7h-2zm0 6a1 1 0 0 1-1 1v2a3 3 0 0 0 3-3h-2zm-1 1h-2v2h2v-2zm-3 1v4h2v-4h-2zm1.707 3.293l-4-4-1.414 1.414 4 4 1.414-1.414zM11 14H7v2h4v-2zm-4 0c-.276 0-.525-.111-.707-.293l-1.414 1.414C5.42 15.663 6.172 16 7 16v-2zm-.707 1.121l3.414-3.414-1.414-1.414-3.414 3.414 1.414 1.414zM9 12h4v-2H9v2zm4 0a3 3 0 0 0 3-3h-2a1 1 0 0 1-1 1v2zm3-3V3h-2v6h2zm0-6a3 3 0 0 0-3-3v2a1 1 0 0 1 1 1h2zm-3-3H3v2h10V0zM3 0a3 3 0 0 0-3 3h2a1 1 0 0 1 1-1V0zM0 3v6h2V3H0zm0 6a3 3 0 0 0 3 3v-2a1 1 0 0 1-1-1H0zm3 3h2v-2H3v2zm1-1v4h2v-4H4zm1.707 4.707l.586-.586-1.414-1.414-.586.586 1.414 1.414z"
|
|
5
|
+
/>
|
|
6
|
+
</svg>
|
|
7
|
+
</template>
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import IdentityLogin from "./components/IdentityLogin/IdentityLogin.vue";
|
|
2
|
+
import IdentityProfileAvatar from "./components/IdentityProfileAvatar/IdentityProfileAvatar.vue";
|
|
3
|
+
import IdentityProfileDrawer from "./components/IdentityProfileDrawer/IdentityProfileDrawer.vue";
|
|
4
|
+
import IdentityProfileView from "./components/IdentityProfileView/IdentityProfileView.vue";
|
|
5
|
+
import UserCrud from "./cruds/user-crud/UserCrud.vue";
|
|
6
|
+
import UserList from "./cruds/user-crud/UserList.vue";
|
|
7
|
+
import UserCrudPage from "./pages/UserCrudPage.vue";
|
|
8
|
+
import UserCreateForm from "./forms/UserCreateForm.vue";
|
|
9
|
+
import UserEditForm from "./forms/UserEditForm.vue";
|
|
10
|
+
import RoleForm from "./forms/RoleForm.vue";
|
|
11
|
+
|
|
12
|
+
import RoleCrud from "./cruds/role-crud/RoleCrud.vue";
|
|
13
|
+
import RoleList from "./cruds/role-crud/RoleList.vue";
|
|
14
|
+
import RoleCrudPage from "./pages/RoleCrudPage.vue";
|
|
15
|
+
|
|
16
|
+
import {useAuth} from "./composables/useAuth.js";
|
|
17
|
+
import {useUser} from "./composables/useUser.js";
|
|
18
|
+
import {useRole} from "./composables/useRole.js";
|
|
19
|
+
import {useAuthStore} from "./stores/auth/AuthStore.js";
|
|
20
|
+
|
|
21
|
+
export {
|
|
22
|
+
//Vue Components
|
|
23
|
+
IdentityLogin,
|
|
24
|
+
IdentityProfileAvatar,
|
|
25
|
+
IdentityProfileView,
|
|
26
|
+
IdentityProfileDrawer,
|
|
27
|
+
|
|
28
|
+
//Forms
|
|
29
|
+
UserCreateForm,
|
|
30
|
+
UserEditForm,
|
|
31
|
+
RoleForm,
|
|
32
|
+
|
|
33
|
+
//Vue Composables
|
|
34
|
+
useAuth,
|
|
35
|
+
useUser,
|
|
36
|
+
useRole,
|
|
37
|
+
|
|
38
|
+
//Cruds
|
|
39
|
+
UserCrud,
|
|
40
|
+
UserList,
|
|
41
|
+
|
|
42
|
+
RoleCrud,
|
|
43
|
+
RoleList,
|
|
44
|
+
|
|
45
|
+
//Pages
|
|
46
|
+
UserCrudPage,
|
|
47
|
+
RoleCrudPage,
|
|
48
|
+
|
|
49
|
+
//Stores
|
|
50
|
+
useAuthStore
|
|
51
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// Utilities
|
|
2
|
+
import { defineStore } from 'pinia'
|
|
3
|
+
import type {IAuthUser} from "@drax/identity-front";
|
|
4
|
+
import type from 'pinia-plugin-persistedstate'
|
|
5
|
+
import {AuthHelper} from "@drax/identity-front";
|
|
6
|
+
|
|
7
|
+
export const useAuthStore = defineStore('AuthStore', {
|
|
8
|
+
state: () => ({
|
|
9
|
+
accessToken: null as string | null,
|
|
10
|
+
authUser: null as IAuthUser | null,
|
|
11
|
+
}),
|
|
12
|
+
getters:{
|
|
13
|
+
isAuth: (state): boolean => {
|
|
14
|
+
//TODO verify token
|
|
15
|
+
return !!state.accessToken
|
|
16
|
+
},
|
|
17
|
+
hasPermission: (state) => (permission:string) => {
|
|
18
|
+
return state.authUser && state.authUser.role && state.authUser.role.permissions ? state.authUser.role.permissions.includes(permission) : false
|
|
19
|
+
},
|
|
20
|
+
tokenIsValid: (state) => () => {
|
|
21
|
+
return state.accessToken ? AuthHelper.isJWTValid(state.accessToken) : false
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
actions:{
|
|
25
|
+
setAccessToken(accessToken:string){
|
|
26
|
+
this.accessToken = accessToken
|
|
27
|
+
},
|
|
28
|
+
setAuthUser(authUser:IAuthUser){
|
|
29
|
+
this.authUser = authUser
|
|
30
|
+
},
|
|
31
|
+
clearAuth(){
|
|
32
|
+
this.accessToken = null
|
|
33
|
+
this.authUser = null
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
persist: true
|
|
38
|
+
})
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type {PropType} from "vue";
|
|
3
|
+
import type {IRole} from "@drax/identity-front";
|
|
4
|
+
|
|
5
|
+
const props = defineProps({
|
|
6
|
+
role:{
|
|
7
|
+
type: Object as PropType<IRole>,
|
|
8
|
+
required: true,
|
|
9
|
+
}
|
|
10
|
+
})
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<template>
|
|
14
|
+
<v-sheet border class="position-relative d-flex justify-center align-center" height="150">
|
|
15
|
+
<v-sheet class="text-center">
|
|
16
|
+
<h6 class="text-h6">{{$t ? $t('role.name') : 'Name'}} : {{ role.name }}</h6>
|
|
17
|
+
<h6 class="text-h6 text-grey">Permisos</h6>
|
|
18
|
+
|
|
19
|
+
<v-chip v-for="permission in role.permissions"
|
|
20
|
+
:key="permission" color="green"
|
|
21
|
+
class="ma-1"
|
|
22
|
+
>
|
|
23
|
+
{{$t ? $t(`permission.${permission}`) : permission }}
|
|
24
|
+
</v-chip>
|
|
25
|
+
</v-sheet>
|
|
26
|
+
</v-sheet>
|
|
27
|
+
|
|
28
|
+
</template>
|
|
29
|
+
|
|
30
|
+
<style scoped>
|
|
31
|
+
|
|
32
|
+
</style>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type {PropType} from "vue";
|
|
3
|
+
import type {IUser} from "@drax/identity-front";
|
|
4
|
+
import IdentityProfileAvatar from "../components/IdentityProfileAvatar/IdentityProfileAvatar.vue";
|
|
5
|
+
|
|
6
|
+
const props = defineProps({
|
|
7
|
+
user:{
|
|
8
|
+
type: Object as PropType<IUser>,
|
|
9
|
+
required: true,
|
|
10
|
+
}
|
|
11
|
+
})
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<template>
|
|
15
|
+
<v-sheet border class="position-relative d-flex justify-center align-center" height="150">
|
|
16
|
+
<v-sheet class="position-absolute bg-surface-light w-100 top-0" height="65"></v-sheet>
|
|
17
|
+
<v-sheet class="text-center">
|
|
18
|
+
<identity-profile-avatar :avatar-size="70"></identity-profile-avatar>
|
|
19
|
+
<h6 class="text-h6">{{ user.username }}</h6>
|
|
20
|
+
</v-sheet>
|
|
21
|
+
</v-sheet>
|
|
22
|
+
|
|
23
|
+
<v-divider></v-divider>
|
|
24
|
+
<v-sheet class="d-flex justify-center align-center" height="50">
|
|
25
|
+
<v-sheet class="text-center">
|
|
26
|
+
<h6 class="text-caption">{{ user.email }}</h6>
|
|
27
|
+
<h6 class="text-subtitle-2">role: {{ user.role?.name }}</h6>
|
|
28
|
+
</v-sheet>
|
|
29
|
+
</v-sheet>
|
|
30
|
+
</template>
|
|
31
|
+
|
|
32
|
+
<style scoped>
|
|
33
|
+
|
|
34
|
+
</style>
|