Skip to content
Snippets Groups Projects
Verified Commit 0f2b456a authored by Martin Weise's avatar Martin Weise
Browse files

Added SSO

parent c2e016de
Branches
No related tags found
No related merge requests found
No preview for this file type
...@@ -11,32 +11,35 @@ ...@@ -11,32 +11,35 @@
<v-tab <v-tab
:text="$t('toolbars.user.authentication')" :text="$t('toolbars.user.authentication')"
to="/user/authentication" /> to="/user/authentication" />
<v-tab
:text="$t('toolbars.user.developer')"
to="/user/developer" />
</v-tabs> </v-tabs>
</template> </template>
</v-toolbar> </v-toolbar>
</div> </div>
</template> </template>
<script setup>
definePageMeta({
middleware: ['auth']
})
const { $oidc } = useNuxtApp()
</script>
<script> <script>
import { useUserStore } from '@/stores/user'
export default { export default {
data () { data () {
return { return {
tab: null, tab: null
userStore: useUserStore()
} }
}, },
computed: { computed: {
user () { user () {
return this.userStore.getUser return this.$oidc.user
}, },
roles () { roles () {
return this.userStore.getRoles if (!this.user || !this.user.realm_access) {
return []
} }
return this.user.realm_access.roles
},
} }
} }
</script> </script>
import axios, {type AxiosInstance} from 'axios' import axios, {type AxiosInstance} from 'axios'
import {useUserStore} from '@/stores/user'
let instance: AxiosInstance | null = null; let instance: AxiosInstance | null = null;
export const useAxiosInstance = () => { export const useAxiosInstance = () => {
const config = useRuntimeConfig();
const userStore = useUserStore() const userStore = useUserStore()
const config = useRuntimeConfig();
if (!instance) { if (!instance) {
instance = axios.create({ instance = axios.create({
timeout: 90_000, timeout: 90_000,
...@@ -19,37 +18,8 @@ export const useAxiosInstance = () => { ...@@ -19,37 +18,8 @@ export const useAxiosInstance = () => {
}); });
instance.interceptors.request.use((config) => { instance.interceptors.request.use((config) => {
const token = userStore.getToken const token = userStore.getToken
const refreshToken = userStore.getRefreshToken
if (!token || !refreshToken) {
return config
}
const authenticationService = useAuthenticationService()
if (authenticationService.isExpiredToken(refreshToken)) {
console.warn('Refresh token is expired: trigger logout of user')
userStore.logout()
return config
}
if (!authenticationService.isExpiredToken(token)) {
config.headers.Authorization = `Bearer ${token}` config.headers.Authorization = `Bearer ${token}`
return config return config
}
console.warn('Access token expired: request a new one')
const userService = useUserService()
return userService.refreshToken(refreshToken)
.then((response: KeycloakOpenIdTokenDto) => {
userStore.setToken(response.access_token)
userStore.setRefreshToken(response.refresh_token)
console.debug('new access token expires:', authenticationService.tokenToExpiryDate(response.access_token))
config.headers.Authorization = `Bearer ${response.access_token}`
return config
})
.catch((error: ApiErrorDto) => {
if (error.code === 'error.user.credentials') {
console.warn('User session expired.')
userStore.logout()
}
return config
});
}) })
} }
return instance; return instance;
......
...@@ -90,16 +90,16 @@ ...@@ -90,16 +90,16 @@
@click:append-inner="retrieve" /> @click:append-inner="retrieve" />
<v-spacer /> <v-spacer />
<v-btn <v-btn
v-if="!user" v-if="!$oidc.isLoggedIn"
class="mr-2" class="mr-2"
color="secondary" color="secondary"
variant="flat" variant="flat"
prepend-icon="mdi-login" prepend-icon="mdi-login"
to="/login"> @click="$oidc.login()">
{{ $t('navigation.login') }} {{ $t('navigation.login') }}
</v-btn> </v-btn>
<v-btn <v-btn
v-if="!user" v-if="!$oidc.isLoggedIn"
color="primary" color="primary"
variant="flat" variant="flat"
prepend-icon="mdi-account-plus" prepend-icon="mdi-account-plus"
...@@ -107,12 +107,12 @@ ...@@ -107,12 +107,12 @@
{{ $t('navigation.signup') }} {{ $t('navigation.signup') }}
</v-btn> </v-btn>
<v-btn <v-btn
v-if="user" v-if="$oidc.user"
to="/user" to="/user"
variant="plain" variant="plain"
:text="user.username" /> :text="$oidc.user.preferred_username" />
<v-menu <v-menu
v-if="user" v-if="$oidc.isLoggedIn"
location="bottom"> location="bottom">
<template v-slot:activator="{ props }"> <template v-slot:activator="{ props }">
<v-btn <v-btn
...@@ -121,20 +121,19 @@ ...@@ -121,20 +121,19 @@
</template> </template>
<v-list> <v-list>
<v-list-item <v-list-item
v-if="user" v-if="$oidc.user"
exact exact
:to="`/search?type=database&owner.username=${user.username}`"> :to="`/search?type=database&owner.username=${$oidc.user.username}`">
{{ $t('navigation.databases') + ' ' + $t('navigation.mine')}} {{ $t('navigation.databases') + ' ' + $t('navigation.mine')}}
</v-list-item> </v-list-item>
<v-list-item <v-list-item
v-if="user" v-if="$oidc.user"
exact exact
:to="`/search?type=identifier&identifiers.creator.username=${user.username}`"> :to="`/search?type=identifier&identifiers.creator.username=${$oidc.user.username}`">
{{ $t('navigation.identifiers') + ' ' + $t('navigation.mine') }} {{ $t('navigation.identifiers') + ' ' + $t('navigation.mine') }}
</v-list-item> </v-list-item>
<v-list-item <v-list-item
v-if="user" @click="logout()">
@click="logout">
{{ $t('navigation.logout') }} {{ $t('navigation.logout') }}
</v-list-item> </v-list-item>
</v-list> </v-list>
...@@ -144,12 +143,17 @@ ...@@ -144,12 +143,17 @@
<v-main> <v-main>
<v-container> <v-container>
<slot /> <slot />
<pre>{{ accessToken }}</pre>
<pre>$oidc.isLoggedIn={{ $oidc.isLoggedIn }}</pre>
<pre v-if="$oidc.isLoggedIn" style="background:green;">$oidc.user={{$oidc.user}}</pre>
</v-container> </v-container>
</v-main> </v-main>
</v-app> </v-app>
</template> </template>
<script setup> <script setup>
const { $oidc } = useNuxtApp()
const accessToken = useCookie('oidc._access_token')
const config = useRuntimeConfig() const config = useRuntimeConfig()
useServerHead({ useServerHead({
title: config.public.title title: config.public.title
...@@ -158,7 +162,6 @@ useServerHead({ ...@@ -158,7 +162,6 @@ useServerHead({
<script> <script>
import { useUserStore } from '@/stores/user' import { useUserStore } from '@/stores/user'
import { useCacheStore } from '@/stores/cache' import { useCacheStore } from '@/stores/cache'
export default { export default {
data () { data () {
return { return {
...@@ -172,31 +175,20 @@ export default { ...@@ -172,31 +175,20 @@ export default {
loadingSearch: false, loadingSearch: false,
loadingDatabases: false, loadingDatabases: false,
search: null, search: null,
userStore: useUserStore(),
cacheStore: useCacheStore()
} }
}, },
computed: { computed: {
token () {
return this.userStore.getToken
},
user () {
return this.userStore.getUser
},
locale () {
return this.userStore.getLocale
},
messages () { messages () {
return this.cacheStore.getMessages const cacheStore = useCacheStore()
return cacheStore.getMessages
}, },
table () { table () {
return this.cacheStore.getTable const cacheStore = useCacheStore()
return cacheStore.getTable
}, },
database () { database () {
return this.cacheStore.getDatabase const cacheStore = useCacheStore()
}, return cacheStore.getDatabase
roles () {
return this.userStore.getRoles
}, },
version () { version () {
return this.$config.public.version return this.$config.public.version
...@@ -231,22 +223,23 @@ export default { ...@@ -231,22 +223,23 @@ export default {
return return
} }
/* load database and optional access */ /* load database and optional access */
const cacheStore = useCacheStore()
this.cacheStore.setRouteDatabase(newObj.database_id) this.cacheStore.setRouteDatabase(newObj.database_id)
if (this.user) { if (this.user) {
this.userStore.setRouteAccess(newObj.database_id) const userStore = useUserStore()
userStore.setRouteAccess(newObj.database_id)
} }
if (!newObj.table_id) { if (!newObj.table_id) {
return return
} }
/* load table */ /* load table */
this.cacheStore.setRouteTable(newObj.database_id, newObj.table_id) cacheStore.setRouteTable(newObj.database_id, newObj.table_id)
}, },
deep: true, deep: true,
immediate: true immediate: true
} }
}, },
mounted () { mounted () {
this.initEnvironment()
if (this.$route.query && this.$route.query.q) { if (this.$route.query && this.$route.query.q) {
this.search = this.$route.query.q this.search = this.$route.query.q
} }
...@@ -254,7 +247,8 @@ export default { ...@@ -254,7 +247,8 @@ export default {
return return
} }
this.setTheme() this.setTheme()
this.cacheStore.reloadMessages() const cacheStore = useCacheStore()
cacheStore.reloadMessages()
}, },
methods: { methods: {
login () { login () {
...@@ -263,23 +257,12 @@ export default { ...@@ -263,23 +257,12 @@ export default {
}, },
logout () { logout () {
this.$vuetify.theme.global.name = 'tuwThemeLight' this.$vuetify.theme.global.name = 'tuwThemeLight'
this.userStore.logout() this.$oidc.logout()
this.$router.push('/database')
}, },
retrieve () { retrieve () {
console.debug('performing fuzzy search') console.debug('performing fuzzy search')
this.$router.push({ path: '/search', query: { q: this.search } }) this.$router.push({ path: '/search', query: { q: this.search } })
}, },
initEnvironment () {
if (this.token && !this.user) {
console.error('Something went wrong with loading the user: reset user cache')
this.userStore.logout()
}
if (!this.locale) {
this.userStore.setLocale('en')
}
this.$i18n.locale = this.locale
},
setTheme () { setTheme () {
switch (this.user.attributes.theme) { switch (this.user.attributes.theme) {
case 'dark': case 'dark':
...@@ -295,10 +278,6 @@ export default { ...@@ -295,10 +278,6 @@ export default {
this.$vuetify.theme.global.name = 'tuwThemeDarkContrast' this.$vuetify.theme.global.name = 'tuwThemeDarkContrast'
break break
} }
},
setLocale (code) {
this.userStore.setLocale(code)
this.$i18n.locale = this.locale
} }
} }
} }
......
export default defineNuxtRouteMiddleware((to, from) => {
if (import.meta.server) { return }
const { $oidc } = useNuxtApp()
if (!$oidc.isLoggedIn) {
$oidc.login(to.fullPath)
}
})
...@@ -2,6 +2,7 @@ import { transformAssetUrls } from 'vite-plugin-vuetify' ...@@ -2,6 +2,7 @@ import { transformAssetUrls } from 'vite-plugin-vuetify'
const proxy: any = {} const proxy: any = {}
/* proxies the backend calls, >>NOT<< the frontend calls (clicking) */ /* proxies the backend calls, >>NOT<< the frontend calls (clicking) */
if (process.env.NODE_ENV === 'development') { if (process.env.NODE_ENV === 'development') {
const api = 'http://localhost' const api = 'http://localhost'
...@@ -19,8 +20,7 @@ if (process.env.NODE_ENV === 'development') { ...@@ -19,8 +20,7 @@ if (process.env.NODE_ENV === 'development') {
/** /**
* https://nuxt.com/docs/guide/concepts/rendering#hybrid-rendering * https://nuxt.com/docs/guide/concepts/rendering#hybrid-rendering
*/ */
const routeRules = { const routeRules = {}
}
export default defineNuxtConfig({ export default defineNuxtConfig({
app: { app: {
...@@ -36,6 +36,41 @@ export default defineNuxtConfig({ ...@@ -36,6 +36,41 @@ export default defineNuxtConfig({
} }
}, },
openidConnect: {
addPlugin: true,
op: {
issuer: 'http://localhost/api/auth/realms/dbrepo',
clientId: 'dbrepo-client',
clientSecret: 'MUwRc7yfXSJwX8AdRMWaQC3Nep1VjwgG',
scope: [
'openid',
'roles',
'attributes'
]
},
config: {
debug: false,
response_type: 'code',
secret: 'oidc._sessionid',
isCookieUserInfo: false, // whether save userinfo into cookie.
cookie: { loginName: '' },
cookiePrefix: 'oidc._',
cookieEncrypt: true,
cookieEncryptKey: 'bfnuxt9c2470cb477d907b1e0917oidc',
cookieEncryptIV: 'ab83667c72eec9e4',
cookieEncryptALGO: 'aes-256-cbc',
cookieMaxAge: 24 * 60 * 60, // default one day
hasCookieRefreshExpireDate: false, // Set this to true if your provider has an refresh_expires_in date for the refresh token
cookieRefreshDefaultMaxAge: 24 * 60 * 60, // default one day if the hasCookieRefreshExpireDate is false
cookieFlags: {
access_token: {
httpOnly: true,
secure: false
}
}
}
},
build: { build: {
transpile: ['vuetify'], transpile: ['vuetify'],
}, },
...@@ -48,6 +83,21 @@ export default defineNuxtConfig({ ...@@ -48,6 +83,21 @@ export default defineNuxtConfig({
], ],
runtimeConfig: { runtimeConfig: {
openidConnect: {
op: {
issuer: '',
clientId: '',
clientSecret: '',
},
config: {
cookieFlags: {
access_token: {
httpOnly: true,
secure: false
}
}
}
},
public: { public: {
commit: '', commit: '',
title: 'Database Repository', title: 'Database Repository',
...@@ -122,7 +172,8 @@ export default defineNuxtConfig({ ...@@ -122,7 +172,8 @@ export default defineNuxtConfig({
modules: [ modules: [
'@pinia/nuxt', '@pinia/nuxt',
'@pinia-plugin-persistedstate/nuxt', '@pinia-plugin-persistedstate/nuxt',
'@nuxtjs/i18n' '@nuxtjs/i18n',
'nuxt-openid-connect'
], ],
pinia: { pinia: {
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
"merkle-json": "^2.6.0", "merkle-json": "^2.6.0",
"moment": "^2.30.1", "moment": "^2.30.1",
"nuxt": "^3.10.3", "nuxt": "^3.10.3",
"nuxt-openid-connect": "^0.8.1",
"parse-md": "^3.0.3", "parse-md": "^3.0.3",
"pinia": "^2.1.7", "pinia": "^2.1.7",
"qs": "^6.11.2", "qs": "^6.11.2",
......
...@@ -60,6 +60,11 @@ ...@@ -60,6 +60,11 @@
</div> </div>
</template> </template>
<script setup>
definePageMeta({
middleware: ['auth']
})
</script>
<script> <script>
import UserToolbar from '@/components/user/UserToolbar.vue' import UserToolbar from '@/components/user/UserToolbar.vue'
import { useUserStore } from '@/stores/user' import { useUserStore } from '@/stores/user'
...@@ -112,7 +117,7 @@ export default { ...@@ -112,7 +117,7 @@ export default {
changePassword () { changePassword () {
this.loadingUpdate = true this.loadingUpdate = true
const userService = useUserService() const userService = useUserService()
userService.updatePassword(this.user.id, {'password': this.password}) userService.updatePassword(this.user.sub, {'password': this.password})
.then(() => { .then(() => {
const toast = useToastInstance() const toast = useToastInstance()
toast.success(this.$t('success.user.password')) toast.success(this.$t('success.user.password'))
......
<template>
<div>
<UserToolbar />
<v-window
v-model="tab">
<v-window-item>
<v-card
v-if="canHandleMessages"
:title="$t('pages.settings.subpages.developer.maintenance.title')"
rounded="0"
variant="flat">
<v-data-table
:headers="headers"
:items="messages"
:loading="loadingMessages"
:items-per-page="10">
<template v-slot:item.action="{ item }">
<v-btn
size="x-small"
variant="flat"
:text="$t('pages.settings.subpages.developer.maintenance.modify.text')"
@click="modifyMessage(item)" />
</template>
</v-data-table>
<v-card-text>
<v-btn
size="small"
variant="flat"
:text="$t('pages.settings.subpages.developer.maintenance.add.text')"
:disabled="!canCreateMessage"
@click="createMessage" />
</v-card-text>
</v-card>
<v-divider
v-if="canHandleMessages" />
<v-card
:title="$t('pages.settings.subpages.developer.token.title')"
:subtitle="$t('pages.settings.subpages.developer.token.subtitle')"
variant="flat"
rounded="0">
<v-card-text>
<v-row dense>
<v-col xl="4">
<v-text-field
v-model="accessTokenField"
disabled
:variant="inputVariant"
:label="$t('pages.settings.subpages.developer.token.access.label')" />
</v-col>
<v-col xl="2">
<v-text-field
v-model="tokenExpiry"
disabled
:variant="inputVariant"
:label="expiryLabel(token)" />
</v-col>
</v-row>
<v-row dense>
<v-col xl="4">
<v-text-field
v-model="refreshTokenField"
disabled
:variant="inputVariant"
:label="$t('pages.settings.subpages.developer.token.refresh.label')" />
</v-col>
<v-col xl="2">
<v-text-field
v-model="refreshTokenExpiry"
disabled
:variant="inputVariant"
:label="expiryLabel(refreshToken)" />
</v-col>
</v-row>
</v-card-text>
</v-card>
</v-window-item>
</v-window>
<v-breadcrumbs :items="items" class="pa-0 mt-2" />
<v-dialog
v-model="dialog"
persistent
max-width="640">
<EditMaintenanceMessage
:id="messageId"
@close-dialog="closeDialog" />
</v-dialog>
</div>
</template>
<script>
import UserToolbar from '@/components/user/UserToolbar.vue'
import EditMaintenanceMessage from '@/components/dialogs/EditMaintenanceMessage.vue'
import { formatTimestampUTCLabel, isActiveMessage, timestampsToHumanDifference } from '@/utils'
import { useUserStore } from '@/stores/user'
import { useCacheStore } from '@/stores/cache'
export default {
components: {
UserToolbar,
EditMaintenanceMessage
},
data () {
return {
tab: 0,
accessTokenField: null,
refreshTokenField: null,
headers: [
{ title: this.$t('pages.settings.subpages.developer.maintenance.active'), value: 'active' },
{ title: this.$t('pages.settings.subpages.developer.maintenance.type'), value: 'type' },
{ title: this.$t('pages.settings.subpages.developer.maintenance.message'), value: 'message' },
{ title: this.$t('pages.settings.subpages.developer.maintenance.action'), value: 'action' }
],
items: [
{
title: this.$t('navigation.user'),
to: '/user'
},
{
title: this.$t('toolbars.user.developer'),
to: `/user/developer`,
disabled: true
}
],
messages: [],
loadingMessages: false,
dialog: false,
messageId: null,
userStore: useUserStore(),
cacheStore: useCacheStore()
}
},
computed: {
token () {
return this.userStore.getToken
},
tokenExpiry () {
if (!this.token) {
return null
}
const authenticationService = useAuthenticationService()
return formatTimestampUTCLabel(authenticationService.tokenToExpiryDate(this.token))
},
refreshToken () {
return this.userStore.getRefreshToken
},
refreshTokenExpiry () {
if (!this.refreshToken) {
return null
}
const authenticationService = useAuthenticationService()
return formatTimestampUTCLabel(authenticationService.tokenToExpiryDate(this.refreshToken))
},
user () {
return this.userStore.getUser
},
roles () {
return this.userStore.getRoles
},
canCreateMessage () {
if (!this.roles) {
return false
}
return this.roles.includes('create-maintenance-message')
},
canModifyMessage () {
if (!this.roles) {
return false
}
return this.roles.includes('modify-maintenance-message')
},
canHandleMessages () {
return this.canCreateMessage || this.canModifyMessage
},
inputVariant () {
const runtimeConfig = useRuntimeConfig()
return this.$vuetify.theme.global.name.toLowerCase().endsWith('contrast') ? runtimeConfig.public.variant.input.contrast : runtimeConfig.public.variant.input.normal
},
buttonVariant () {
const runtimeConfig = useRuntimeConfig()
return this.$vuetify.theme.global.name.toLowerCase().endsWith('contrast') ? runtimeConfig.public.variant.button.contrast : runtimeConfig.public.variant.button.normal
}
},
mounted () {
this.loadMessages()
if (!this.token || !this.refreshToken) {
return
}
this.accessTokenField = this.token
this.refreshTokenField = this.refreshToken
},
methods: {
submit () {
},
modifyMessage (message) {
this.messageId = message.id
this.dialog = true
},
createMessage () {
this.messageId = null
this.dialog = true
},
expiryLabel (token) {
const authenticationService = useAuthenticationService()
return this.$t('pages.settings.subpages.developer.token.expiry') + ' ' + timestampsToHumanDifference(Date.now(), authenticationService.tokenToExpiryDate(token))
},
loadMessages () {
const messageService = useMessageService()
messageService.findAll()
.then((messages) => {
this.messages = messages.map((message) => {
message.active = isActiveMessage(message) ? '● true' : 'false'
return message
})
})
.catch(() => {
this.loadingMessages = false
})
.finally(() => {
this.loadingMessages = false
})
},
closeDialog (event) {
if (event.success) {
this.cacheStore.reloadMessages()
}
this.dialog = false
}
}
}
</script>
...@@ -2,27 +2,14 @@ ...@@ -2,27 +2,14 @@
<div /> <div />
</template> </template>
<script setup>
definePageMeta({
middleware: ['auth']
})
</script>
<script> <script>
import { useUserStore } from '@/stores/user'
export default { export default {
data () {
return {
userStore: useUserStore()
}
},
computed: {
token () {
return this.userStore.getToken
},
user () {
return this.userStore.getUser
}
},
mounted () { mounted () {
if (!this.user) {
return
}
this.$router.push('/user/info') this.$router.push('/user/info')
} }
} }
......
...@@ -13,18 +13,17 @@ ...@@ -13,18 +13,17 @@
<v-row dense> <v-row dense>
<v-col md="6"> <v-col md="6">
<v-text-field <v-text-field
v-model="model.id" v-model="user.sub"
readonly readonly
disabled
:variant="inputVariant" :variant="inputVariant"
:label="$t('pages.user.subpages.info.id.label')" :label="$t('pages.user.subpages.info.id.label')" />
append-inner-icon="mdi-content-copy"
@click:append-inner="copy" />
</v-col> </v-col>
</v-row> </v-row>
<v-row dense> <v-row dense>
<v-col md="6"> <v-col md="6">
<v-text-field <v-text-field
v-model="model.username" v-model="user.preferred_username"
disabled disabled
:variant="inputVariant" :variant="inputVariant"
:label="$t('pages.user.subpages.info.username.label')" /> :label="$t('pages.user.subpages.info.username.label')" />
...@@ -124,6 +123,12 @@ ...@@ -124,6 +123,12 @@
</div> </div>
</template> </template>
<script setup>
definePageMeta({
middleware: ['auth']
})
const { $oidc } = useNuxtApp()
</script>
<script> <script>
import UserToolbar from '@/components/user/UserToolbar.vue' import UserToolbar from '@/components/user/UserToolbar.vue'
import { useUserStore } from '@/stores/user' import { useUserStore } from '@/stores/user'
...@@ -143,7 +148,6 @@ export default { ...@@ -143,7 +148,6 @@ export default {
theme: null, theme: null,
orcidLoading: false, orcidLoading: false,
model: { model: {
id: null,
username: null, username: null,
firstname: null, firstname: null,
lastname: null, lastname: null,
...@@ -176,10 +180,13 @@ export default { ...@@ -176,10 +180,13 @@ export default {
}, },
computed: { computed: {
user () { user () {
return this.userStore.getUser return this.$oidc.user
}, },
roles () { roles () {
return this.userStore.getRoles if (!this.user || !this.user.realm_access) {
return []
}
return this.user.realm_access.roles
}, },
locale () { locale () {
return this.userStore.getLocale return this.userStore.getLocale
...@@ -216,14 +223,12 @@ export default { ...@@ -216,14 +223,12 @@ export default {
language: this.model.language, language: this.model.language,
} }
const userService = useUserService() const userService = useUserService()
userService.update(this.user.id, payload) userService.update(this.user.sub, payload)
.then((user) => { .then((user) => {
console.info('Updated user information') console.info('Updated user information')
const toast = useToastInstance() const toast = useToastInstance()
toast.success(this.$t('success.user.info')) toast.success(this.$t('success.user.info'))
this.userStore.setUser(user)
/* language */ /* language */
this.userStore.setLocale(this.model.language)
this.$i18n.locale = this.locale this.$i18n.locale = this.locale
/* theme */ /* theme */
switch (this.model.theme) { switch (this.model.theme) {
...@@ -253,14 +258,12 @@ export default { ...@@ -253,14 +258,12 @@ export default {
return return
} }
this.model = { this.model = {
id: this.user.id,
username: this.user.username,
firstname: this.user.given_name, firstname: this.user.given_name,
lastname: this.user.family_name, lastname: this.user.family_name,
orcid: this.user.attributes.orcid, orcid: this.user.attributes?.orcid,
affiliation: this.user.attributes.affiliation, affiliation: this.user.attributes?.affiliation,
theme: this.user.attributes.theme, theme: this.user.attributes?.theme,
language: this.user.attributes.language language: this.user.attributes?.language
} }
}, },
retrieve () { retrieve () {
...@@ -284,11 +287,6 @@ export default { ...@@ -284,11 +287,6 @@ export default {
.finally(() => { .finally(() => {
this.orcidLoading = false this.orcidLoading = false
}) })
},
copy () {
navigator.clipboard.writeText(this.model.id)
const toast = useToastInstance()
toast.success(this.$t('success.clipboard.user'))
} }
} }
} }
......
...@@ -4,50 +4,22 @@ export const useUserStore = defineStore('user', { ...@@ -4,50 +4,22 @@ export const useUserStore = defineStore('user', {
persist: true, persist: true,
state: () => { state: () => {
return { return {
/** @type String */
token: null,
/** @type String */
refreshToken: null,
roles: [],
user: null,
access: null, access: null,
locale: null /** @type String */
token: null
} }
}, },
getters: { getters: {
getToken: (state) => state.token, getToken: (state) => state.token,
getRefreshToken: (state) => state.refreshToken,
getRoles: (state) => state.roles,
getUser: (state) => state.user,
getAccess: (state) => state.access, getAccess: (state) => state.access,
getLocale: (state) => state.locale
}, },
actions: { actions: {
setToken(token) { setToken(token) {
this.token = token this.token = token
}, },
setRefreshToken(refreshToken) {
this.refreshToken = refreshToken
},
setRoles(roles) {
this.roles = roles
},
setUser(user) {
this.user = user
},
setAccess(access) { setAccess(access) {
this.access = access this.access = access
}, },
setLocale (locale) {
this.locale = locale
},
logout() {
this.token = null
this.refreshToken = null
this.roles = []
this.user = null
this.access = null
},
setRouteAccess(databaseId) { setRouteAccess(databaseId) {
if (!databaseId || !this.user || !this.user.id) { if (!databaseId || !this.user || !this.user.id) {
return return
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment