Replace the notify store with 2fauth/ui notifier & 2fauth/stores parser

This commit is contained in:
Bubka
2025-06-23 14:53:17 +02:00
parent 6f419cfbcb
commit 16a1a9077d
39 changed files with 192 additions and 203 deletions

5
resources/js/app.js vendored
View File

@ -75,10 +75,11 @@ app
.component('Kicker', Kicker) .component('Kicker', Kicker)
// Global error handling // Global error handling
// import { useNotifyStore } from '@/stores/notify' // import { useNotify } from '@2fauth/ui'
// if (process.env.NODE_ENV != 'development') { // if (process.env.NODE_ENV != 'development') {
// app.config.errorHandler = (err) => { // app.config.errorHandler = (err) => {
// useNotifyStore().error(err) // useNotify().parse(err)
// router.push({ name: 'genericError' })
// } // }
// } // }

View File

@ -2,11 +2,11 @@
import SearchBox from '@/components/SearchBox.vue' import SearchBox from '@/components/SearchBox.vue'
import userService from '@/services/userService' import userService from '@/services/userService'
import Spinner from '@/components/Spinner.vue' import Spinner from '@/components/Spinner.vue'
import { useNotifyStore } from '@/stores/notify'
import { FontAwesomeLayers } from '@fortawesome/vue-fontawesome' import { FontAwesomeLayers } from '@fortawesome/vue-fontawesome'
import { UseColorMode } from '@vueuse/components' import { UseColorMode } from '@vueuse/components'
import { useErrorHandler } from '@2fauth/stores'
const notify = useNotifyStore() const errorHandler = useErrorHandler()
const $2fauth = inject('2fauth') const $2fauth = inject('2fauth')
const props = defineProps({ const props = defineProps({
@ -106,7 +106,8 @@
orderIsDesc.value == true ? sortDesc() : sortAsc() orderIsDesc.value == true ? sortDesc() : sortAsc()
}) })
.catch(error => { .catch(error => {
notify.error(error) errorHandler.parse(error)
router.push({ name: 'genericError' })
}) })
.finally(() => { .finally(() => {
isFetching.value = false isFetching.value = false

View File

@ -1,9 +1,9 @@
<script setup> <script setup>
import { useNotifyStore } from '@/stores/notify' import { useNotify } from '@2fauth/ui'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
const { t } = useI18n() const { t } = useI18n()
const notify = useNotifyStore() const notify = useNotify()
const { copy } = useClipboard({ legacy: true }) const { copy } = useClipboard({ legacy: true })
const props = defineProps({ const props = defineProps({

View File

@ -5,13 +5,15 @@
import Dots from '@/components/Dots.vue' import Dots from '@/components/Dots.vue'
import twofaccountService from '@/services/twofaccountService' import twofaccountService from '@/services/twofaccountService'
import { useUserStore } from '@/stores/user' import { useUserStore } from '@/stores/user'
import { useNotifyStore } from '@/stores/notify' import { useNotify } from '@2fauth/ui'
import { UseColorMode } from '@vueuse/components' import { UseColorMode } from '@vueuse/components'
import { useDisplayablePassword } from '@/composables/helpers' import { useDisplayablePassword } from '@/composables/helpers'
import { useErrorHandler } from '@2fauth/stores'
const errorHandler = useErrorHandler()
const { t } = useI18n() const { t } = useI18n()
const user = useUserStore() const user = useUserStore()
const notify = useNotifyStore() const notify = useNotify()
const $2fauth = inject('2fauth') const $2fauth = inject('2fauth')
const { copy, copied } = useClipboard({ legacy: true }) const { copy, copied } = useClipboard({ legacy: true })
const route = useRoute() const route = useRoute()
@ -117,10 +119,12 @@
} }
// Case 3 // Case 3
else if (! props.secret) { else if (! props.secret) {
notify.error(new Error(t('error.cannot_create_otp_without_secret'))) errorHandler.parse(new Error(t('error.cannot_create_otp_without_secret')))
router.push({ name: 'genericError' })
} }
else if (! isTimeBased(otpauthParams.value.otp_type) && ! isHMacBased(otpauthParams.value.otp_type)) { else if (! isTimeBased(otpauthParams.value.otp_type) && ! isHMacBased(otpauthParams.value.otp_type)) {
notify.error(new Error(t('error.not_a_supported_otp_type'))) errorHandler.parse(new Error(t('error.not_a_supported_otp_type')))
router.push({ name: 'genericError' })
} }
try { try {

View File

@ -1,10 +1,10 @@
<script setup> <script setup>
const { copy } = useClipboard({ legacy: true }) const { copy } = useClipboard({ legacy: true })
import { useNotifyStore } from '@/stores/notify' import { useNotify } from '@2fauth/ui'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
const { t } = useI18n() const { t } = useI18n()
const notify = useNotifyStore() const notify = useNotify()
const props = defineProps({ const props = defineProps({
qrContent: String, qrContent: String,

View File

@ -1,6 +1,7 @@
import appSettingService from '@/services/appSettingService' import appSettingService from '@/services/appSettingService'
import { useNotifyStore } from '@/stores/notify'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { useErrorHandler } from '@2fauth/stores'
import { useNotify } from '@2fauth/ui'
/** /**
* Saves a setting on the backend * Saves a setting on the backend
@ -17,14 +18,15 @@ export async function useAppSettingsUpdater(setting, value, returnValidationErro
await appSettingService.update(setting, value, { returnError: true }) await appSettingService.update(setting, value, { returnError: true })
.then(response => { .then(response => {
data = value data = value
useNotifyStore().success({ type: 'is-success', text: t('message.settings.forms.setting_saved') }) useNotify().success({ text: t('message.settings.forms.setting_saved') })
}) })
.catch(err => { .catch(err => {
if( returnValidationError && err.response.status === 422 ) { if( returnValidationError && err.response.status === 422 ) {
error = err error = err
} }
else { else {
useNotifyStore().error(err); useErrorHandler().parse(err)
router.push({ name: 'genericError' })
} }
}) })

View File

@ -3,7 +3,8 @@ import middlewarePipeline from "@/router/middlewarePipeline";
import { useUserStore } from '@/stores/user' import { useUserStore } from '@/stores/user'
import { useTwofaccounts } from '@/stores/twofaccounts' import { useTwofaccounts } from '@/stores/twofaccounts'
import { useAppSettingsStore } from '@/stores/appSettings' import { useAppSettingsStore } from '@/stores/appSettings'
import { useNotifyStore } from '@/stores/notify' import { useNotify } from '@2fauth/ui'
import { useErrorHandler } from '@2fauth/stores'
import authGuard from './middlewares/authGuard' import authGuard from './middlewares/authGuard'
import adminOnly from './middlewares/adminOnly' import adminOnly from './middlewares/adminOnly'
@ -62,8 +63,9 @@ router.beforeEach((to, from, next) => {
const user = useUserStore() const user = useUserStore()
const twofaccounts = useTwofaccounts() const twofaccounts = useTwofaccounts()
const appSettings = useAppSettingsStore() const appSettings = useAppSettingsStore()
const notify = useNotifyStore() const notify = useNotify()
const stores = { user: user, twofaccounts: twofaccounts, appSettings: appSettings, notify: notify } const errorHandler = useErrorHandler()
const stores = { user: user, twofaccounts: twofaccounts, appSettings: appSettings, notify: notify, errorHandler: errorHandler }
const nextMiddleware = {} const nextMiddleware = {}
const context = { to, from, next, nextMiddleware, stores } const context = { to, from, next, nextMiddleware, stores }

View File

@ -3,12 +3,14 @@
*/ */
export default async function adminOnly({ to, next, nextMiddleware, stores }) { export default async function adminOnly({ to, next, nextMiddleware, stores }) {
const { user } = stores const { user } = stores
const { notify } = stores const { errorHandler } = stores
if (! user.isAdmin) { if (! user.isAdmin) {
let err = new Error('unauthorized') let err = new Error('unauthorized')
err.response.status = 403 err.response.status = 403
notify.error(err) errorHandler.parse(err)
router.push({ name: 'genericError' })
} }
else nextMiddleware() else nextMiddleware()
} }

View File

@ -1,7 +1,7 @@
export default function noEmptyError({ to, next, nextMiddleware, stores }) { export default function noEmptyError({ to, next, nextMiddleware, stores }) {
const { notify } = stores const { errorHandler } = stores
if (notify.err == null && ! to.query.err) { if (errorHandler.lastError == null && ! to.query.err) {
// return to home if no err object is set to prevent an empty error message // return to home if no err object is set to prevent an empty error message
next({ name: 'accounts' }); next({ name: 'accounts' });
} }

View File

@ -1,6 +1,6 @@
import axios from "axios" import axios from "axios"
import { useUserStore } from '@/stores/user' import { useUserStore } from '@/stores/user'
import { useNotifyStore } from '@/stores/notify' import { useErrorHandler } from '@2fauth/stores'
export const httpClientFactory = (endpoint = 'api') => { export const httpClientFactory = (endpoint = 'api') => {
let baseURL let baseURL
@ -62,7 +62,9 @@ export const httpClientFactory = (endpoint = 'api') => {
} }
if (error.response && [407].includes(error.response.status)) { if (error.response && [407].includes(error.response.status)) {
useNotifyStore().error(error) useErrorHandler().parse(error)
// TODO : Check if calling router here works as expected
router.push({ name: 'genericError' })
return new Promise(() => {}) return new Promise(() => {})
} }
@ -83,11 +85,14 @@ export const httpClientFactory = (endpoint = 'api') => {
// Not found // Not found
if (error.response.status === 404) { if (error.response.status === 404) {
useNotifyStore().notFound() // TODO : Check if calling router here works as expected
router.push({ name: '404' })
return new Promise(() => {}) return new Promise(() => {})
} }
useNotifyStore().error(error) // TODO : Check if calling router here works as expected
useErrorHandler().parse(error)
router.push({ name: 'genericError' })
return new Promise(() => {}) return new Promise(() => {})
} }
) )

View File

@ -1,6 +1,6 @@
import appSettingService from '@/services/appSettingService' import appSettingService from '@/services/appSettingService'
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import { useNotifyStore } from '@/stores/notify' import { useNotify } from '@2fauth/ui'
export const useAppSettingsStore = defineStore({ export const useAppSettingsStore = defineStore({
id: 'appSettings', id: 'appSettings',
@ -31,7 +31,7 @@ export const useAppSettingsStore = defineStore({
}) })
.catch(error => { .catch(error => {
// TODO : move the t() call from the store // TODO : move the t() call from the store
useNotifyStore().alert({ text: t('error.failed_to_retrieve_app_settings') }) useNotify().alert({ text: t('error.failed_to_retrieve_app_settings') })
}) })
}, },
}, },

View File

@ -1,6 +1,6 @@
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import { useUserStore } from '@/stores/user' import { useUserStore } from '@/stores/user'
import { useNotifyStore } from '@/stores/notify' import { useNotify } from '@2fauth/ui'
import groupService from '@/services/groupService' import groupService from '@/services/groupService'
export const useGroups = defineStore({ export const useGroups = defineStore({
@ -17,7 +17,8 @@ export const useGroups = defineStore({
current(state) { current(state) {
const group = state.items.find(item => item.id === parseInt(useUserStore().preferences.activeGroup)) const group = state.items.find(item => item.id === parseInt(useUserStore().preferences.activeGroup))
return group ? group.name : t('message.all') // TODO : restore translated prompt
return group ? group.name : 'message.all'
}, },
withoutTheAllGroup(state) { withoutTheAllGroup(state) {
@ -47,11 +48,13 @@ export const useGroups = defineStore({
if (index > -1) { if (index > -1) {
this.items[index] = group this.items[index] = group
useNotifyStore().success({ text: t('message.groups.group_name_saved') }) // TODO : restore translated message
useNotify().success({ text: 'message.groups.group_name_saved' })
} }
else { else {
this.items.push(group) this.items.push(group)
useNotifyStore().success({ text: t('message.groups.group_successfully_created') }) // TODO : restore translated message
useNotify().success({ text: 'message.groups.group_successfully_created' })
} }
}, },
@ -78,10 +81,13 @@ export const useGroups = defineStore({
async delete(id) { async delete(id) {
const user = useUserStore() const user = useUserStore()
if (confirm(t('message.groups.confirm.delete'))) { // TODO : restore translated message
// if (confirm(t('message.groups.confirm.delete'))) {
if (confirm('message.groups.confirm.delete')) {
await groupService.delete(id).then(response => { await groupService.delete(id).then(response => {
this.items = this.items.filter(a => a.id !== id) this.items = this.items.filter(a => a.id !== id)
useNotifyStore().success({ text: t('message.groups.group_successfully_deleted') }) // TODO : restore translated message
useNotify().success({ text: 'message.groups.group_successfully_deleted' })
// Reset group filter to 'All' (groupId=0) since the backend has already made // Reset group filter to 'All' (groupId=0) since the backend has already made
// the change automatically. This prevents a new request. // the change automatically. This prevents a new request.

View File

@ -1,86 +0,0 @@
import { defineStore } from 'pinia'
import router from '@/router'
const { notify } = useNotification()
export const useNotifyStore = defineStore({
id: 'notify',
state: () => {
return {
err: null,
message: null,
originalMessage: null,
debug: null,
}
},
getters: {
},
actions: {
parseError(err) {
// TODO : use the new Notify component
// const { t } = useI18n()
this.$reset
this.err = err
// Hnalde axios response error
if (err.response) {
if (err.response.status === 407) {
this.message = t('error.auth_proxy_failed'),
this.originalMessage = t('error.auth_proxy_failed_legend')
}
else if (err.response.status === 403) {
this.message = t('error.unauthorized'),
this.originalMessage = t('error.unauthorized_legend')
}
else if(err.response.data) {
this.message = err.response.data.message,
this.originalMessage = err.response.data.originalMessage ?? null
this.debug = err.response.data.debug ?? null
}
} else {
this.message = err.message
this.debug = err.stack ?? null
}
// else if (err.request) {
//
},
notFound(err) {
router.push({ name: '404' })
},
error(err) {
this.parseError(err)
router.push({ name: 'genericError' })
},
info(notification) {
notify({ type: 'is-info', ...notification})
},
success(notification) {
notify({ type: 'is-success', ...notification})
},
warn(notification) {
notify({ type: 'is-warning', ...notification})
},
alert(notification) {
notify({ type: 'is-danger', ...notification})
},
action(notification) {
notify({ type: 'is-dark', ...notification})
},
clear() {
notify({ clean: true })
}
},
})

View File

@ -1,7 +1,7 @@
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import { startsWithUppercase } from '@/composables/helpers' import { startsWithUppercase } from '@/composables/helpers'
import { useUserStore } from '@/stores/user' import { useUserStore } from '@/stores/user'
import { useNotifyStore } from '@/stores/notify' import { useNotify } from '@2fauth/ui'
import twofaccountService from '@/services/twofaccountService' import twofaccountService from '@/services/twofaccountService'
import { saveAs } from 'file-saver' import { saveAs } from 'file-saver'
@ -155,7 +155,7 @@ export const useTwofaccounts = defineStore({
}) })
this.items = remainingItems this.items = remainingItems
this.selectNone() this.selectNone()
useNotifyStore().success({ text: t('message.twofaccounts.accounts_deleted') }) useNotify().success({ text: t('message.twofaccounts.accounts_deleted') })
}) })
} }
}, },

View File

@ -5,8 +5,9 @@ import router from '@/router'
import { useColorMode } from '@vueuse/core' import { useColorMode } from '@vueuse/core'
import { useTwofaccounts } from '@/stores/twofaccounts' import { useTwofaccounts } from '@/stores/twofaccounts'
import { useGroups } from '@/stores/groups' import { useGroups } from '@/stores/groups'
import { useNotifyStore } from '@/stores/notify' import { useNotify } from '@2fauth/ui'
import { useAppSettingsStore } from '@/stores/appSettings' import { useAppSettingsStore } from '@/stores/appSettings'
import { useErrorHandler } from '@2fauth/stores'
export const useUserStore = defineStore({ export const useUserStore = defineStore({
id: 'user', id: 'user',
@ -63,7 +64,8 @@ export const useUserStore = defineStore({
*/ */
logout(options = {}) { logout(options = {}) {
const { kicked } = options const { kicked } = options
const notify = useNotifyStore() const notify = useNotify()
const errorHandler = useErrorHandler()
// async appLogout(evt) { // async appLogout(evt) {
if (this.$2fauth.config.proxyAuth) { if (this.$2fauth.config.proxyAuth) {
@ -85,7 +87,8 @@ export const useUserStore = defineStore({
// backend has already detect inactivity on its side. In this case we // backend has already detect inactivity on its side. In this case we
// don't want any error to be displayed. // don't want any error to be displayed.
if (error.response.status !== 401) { if (error.response.status !== 401) {
notify.error(error) errorHandler.parse(error)
router.push({ name: 'genericError' })
} }
else this.tossOut() else this.tossOut()
}) })
@ -159,7 +162,7 @@ export const useUserStore = defineStore({
}) })
}) })
.catch(error => { .catch(error => {
const notify = useNotifyStore() const notify = useNotify()
notify.alert({ text: t('error.data_cannot_be_refreshed_from_server') }) notify.alert({ text: t('error.data_cannot_be_refreshed_from_server') })
}) })
} }

View File

@ -1,9 +1,7 @@
<script setup> <script setup>
import { useNotifyStore } from '@/stores/notify' import { useErrorHandler } from '@2fauth/stores'
import { useI18n } from 'vue-i18n'
const { t } = useI18n() const errorHandler = useErrorHandler()
const errorHandler = useNotifyStore()
const router = useRouter() const router = useRouter()
const route = useRoute() const route = useRoute()
@ -25,7 +23,7 @@
onMounted(() => { onMounted(() => {
if (route.query.err) { if (route.query.err) {
errorHandler.message = t('error.' + route.query.err) errorHandler.message = 'error.' + route.query.err
} }
}) })
@ -45,14 +43,14 @@
<modal v-model="showModal" :closable="props.closable"> <modal v-model="showModal" :closable="props.closable">
<div class="error-message" v-if="$route.name == '404' || $route.name == 'notFound'"> <div class="error-message" v-if="$route.name == '404' || $route.name == 'notFound'">
<p class="error-404"></p> <p class="error-404"></p>
<p>{{ $t('error.resource_not_found') }}</p> <p>{{ $t('message.resource_not_found') }}</p>
</div> </div>
<div v-else class="error-message" > <div v-else class="error-message" >
<p class="error-generic"></p> <p class="error-generic"></p>
<p>{{ $t('error.error_occured') }} </p> <p>{{ $t('message.error_occured') }} </p>
<p v-if="errorHandler.message" class="has-text-grey-lighter">{{ errorHandler.message }}</p> <p v-if="errorHandler.message" class="has-text-grey-lighter">{{ $t(errorHandler.message) }}</p>
<p v-if="errorHandler.originalMessage" class="has-text-grey-lighter">{{ errorHandler.originalMessage }}</p> <p v-if="errorHandler.originalMessage" class="has-text-grey-lighter">{{ errorHandler.originalMessage }}</p>
<p v-if="showDebug && errorHandler.debug" class="is-size-7 is-family-code"><br>{{ errorHandler.debug }}</p> <p v-if="showDebug && errorHandler.debug" class="is-size-7 is-family-code pt-3"><br>{{ errorHandler.debug }}</p>
</div> </div>
</modal> </modal>
</div> </div>

View File

@ -2,13 +2,13 @@
import Form from '@/components/formElements/Form' import Form from '@/components/formElements/Form'
import { useUserStore } from '@/stores/user' import { useUserStore } from '@/stores/user'
import { useBusStore } from '@/stores/bus' import { useBusStore } from '@/stores/bus'
import { useNotifyStore } from '@/stores/notify' import { useNotify } from '@2fauth/ui'
import { useTwofaccounts } from '@/stores/twofaccounts' import { useTwofaccounts } from '@/stores/twofaccounts'
const router = useRouter() const router = useRouter()
const user = useUserStore() const user = useUserStore()
const bus = useBusStore() const bus = useBusStore()
const notify = useNotifyStore() const notify = useNotify()
const twofaccounts = useTwofaccounts() const twofaccounts = useTwofaccounts()
const qrcodeInput = ref(null) const qrcodeInput = ref(null)

View File

@ -3,7 +3,7 @@
import systemService from '@/services/systemService' import systemService from '@/services/systemService'
import { useAppSettingsUpdater } from '@/composables/appSettingsUpdater' import { useAppSettingsUpdater } from '@/composables/appSettingsUpdater'
import { useAppSettingsStore } from '@/stores/appSettings' import { useAppSettingsStore } from '@/stores/appSettings'
import { useNotifyStore } from '@/stores/notify' import { useNotify } from '@2fauth/ui'
import { useUserStore } from '@/stores/user' import { useUserStore } from '@/stores/user'
import VersionChecker from '@/components/VersionChecker.vue' import VersionChecker from '@/components/VersionChecker.vue'
import CopyButton from '@/components/CopyButton.vue' import CopyButton from '@/components/CopyButton.vue'
@ -12,7 +12,7 @@
const { t } = useI18n() const { t } = useI18n()
const $2fauth = inject('2fauth') const $2fauth = inject('2fauth')
const user = useUserStore() const user = useUserStore()
const notify = useNotifyStore() const notify = useNotify()
const appSettings = useAppSettingsStore() const appSettings = useAppSettingsStore()
const returnTo = useStorage($2fauth.prefix + 'returnTo', 'accounts') const returnTo = useStorage($2fauth.prefix + 'returnTo', 'accounts')
@ -42,7 +42,7 @@
isClearingCache.value = true; isClearingCache.value = true;
systemService.clearCache().then(response => { systemService.clearCache().then(response => {
useNotifyStore().success({ type: 'is-success', text: t('message.admin.cache_cleared') }) useNotify().success({ text: t('message.admin.cache_cleared') })
}) })
.finally(() => { .finally(() => {
isClearingCache.value = false; isClearingCache.value = false;

View File

@ -3,12 +3,14 @@
import appSettingService from '@/services/appSettingService' import appSettingService from '@/services/appSettingService'
import { useAppSettingsUpdater } from '@/composables/appSettingsUpdater' import { useAppSettingsUpdater } from '@/composables/appSettingsUpdater'
import { useAppSettingsStore } from '@/stores/appSettings' import { useAppSettingsStore } from '@/stores/appSettings'
import { useNotifyStore } from '@/stores/notify' import { useNotify } from '@2fauth/ui'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { useErrorHandler } from '@2fauth/stores'
const errorHandler = useErrorHandler()
const { t } = useI18n() const { t } = useI18n()
const $2fauth = inject('2fauth') const $2fauth = inject('2fauth')
const notify = useNotifyStore() const notify = useNotify()
const appSettings = useAppSettingsStore() const appSettings = useAppSettingsStore()
const returnTo = useStorage($2fauth.prefix + 'returnTo', 'accounts') const returnTo = useStorage($2fauth.prefix + 'returnTo', 'accounts')
@ -46,7 +48,8 @@
}) })
.catch(error => { .catch(error => {
if( error.response.status !== 404 ) { if( error.response.status !== 404 ) {
notify.error(error); errorHandler.parse(error)
router.push({ name: 'genericError' })
} }
}) })
} }

View File

@ -1,13 +1,15 @@
<script setup> <script setup>
import AdminTabs from '@/layouts/AdminTabs.vue' import AdminTabs from '@/layouts/AdminTabs.vue'
import userService from '@/services/userService' import userService from '@/services/userService'
import { useNotifyStore } from '@/stores/notify' import { useNotify } from '@2fauth/ui'
import { UseColorMode } from '@vueuse/components' import { UseColorMode } from '@vueuse/components'
import Spinner from '@/components/Spinner.vue' import Spinner from '@/components/Spinner.vue'
import SearchBox from '@/components/SearchBox.vue' import SearchBox from '@/components/SearchBox.vue'
import { useErrorHandler } from '@2fauth/stores'
const errorHandler = useErrorHandler()
const $2fauth = inject('2fauth') const $2fauth = inject('2fauth')
const notify = useNotifyStore() const notify = useNotify()
const returnTo = useStorage($2fauth.prefix + 'returnTo', 'accounts') const returnTo = useStorage($2fauth.prefix + 'returnTo', 'accounts')
const users = ref([]) const users = ref([])
@ -88,7 +90,8 @@
users.value = response.data users.value = response.data
}) })
.catch(error => { .catch(error => {
notify.error(error) errorHandler.parse(error)
router.push({ name: 'genericError' })
}) })
.finally(() => { .finally(() => {
isFetching.value = false isFetching.value = false

View File

@ -1,7 +1,7 @@
<script setup> <script setup>
import AccessLogViewer from '@/components/AccessLogViewer.vue' import AccessLogViewer from '@/components/AccessLogViewer.vue'
import userService from '@/services/userService' import userService from '@/services/userService'
import { useNotifyStore } from '@/stores/notify' import { useNotify } from '@2fauth/ui'
import { useBusStore } from '@/stores/bus' import { useBusStore } from '@/stores/bus'
const bus = useBusStore() const bus = useBusStore()

View File

@ -1,10 +1,10 @@
<script setup> <script setup>
import Form from '@/components/formElements/Form' import Form from '@/components/formElements/Form'
import { useNotifyStore } from '@/stores/notify' import { useNotify } from '@2fauth/ui'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
const { t } = useI18n() const { t } = useI18n()
const notify = useNotifyStore() const notify = useNotify()
const router = useRouter() const router = useRouter()
const registerForm = reactive(new Form({ const registerForm = reactive(new Form({

View File

@ -2,14 +2,16 @@
import CopyButton from '@/components/CopyButton.vue' import CopyButton from '@/components/CopyButton.vue'
import AccessLogViewer from '@/components/AccessLogViewer.vue' import AccessLogViewer from '@/components/AccessLogViewer.vue'
import userService from '@/services/userService' import userService from '@/services/userService'
import { useNotifyStore } from '@/stores/notify' import { useNotify } from '@2fauth/ui'
import { UseColorMode } from '@vueuse/components' import { UseColorMode } from '@vueuse/components'
import { useUserStore } from '@/stores/user' import { useUserStore } from '@/stores/user'
import { useBusStore } from '@/stores/bus' import { useBusStore } from '@/stores/bus'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { useErrorHandler } from '@2fauth/stores'
const errorHandler = useErrorHandler()
const { t } = useI18n() const { t } = useI18n()
const notify = useNotifyStore() const notify = useNotify()
const router = useRouter() const router = useRouter()
const user = useUserStore() const user = useUserStore()
const bus = useBusStore() const bus = useBusStore()
@ -40,7 +42,8 @@
bus.username = managedUser.value.info.name bus.username = managedUser.value.info.name
}) })
.catch(error => { .catch(error => {
notify.error(error) errorHandler.parse(error)
router.push({ name: 'genericError' })
}) })
.finally(() => { .finally(() => {
isFetching.value = false isFetching.value = false
@ -79,7 +82,10 @@
if(error.response.status === 400) { if(error.response.status === 400) {
notify.alert({ text: error.response.data.reason }) notify.alert({ text: error.response.data.reason })
} }
else notify.error(error) else {
errorHandler.parse(error)
router.push({ name: 'genericError' })
}
}) })
} }
} }
@ -117,7 +123,9 @@
managedUser.value.info.is_admin = true managedUser.value.info.is_admin = true
} }
else { else {
notify.error(error.response) // TODO : check if we should return error.response or error
errorHandler.parse(error.response)
router.push({ name: 'genericError' })
} }
}) })
} }
@ -140,7 +148,9 @@
notify.alert({ text: error.response.data.message }) notify.alert({ text: error.response.data.message })
} }
else { else {
notify.error(error.response) // TODO : check if we should return error.response or error
errorHandler.parse(error)
router.push({ name: 'genericError' })
} }
}) })
} }

View File

@ -2,16 +2,18 @@
import Form from '@/components/formElements/Form' import Form from '@/components/formElements/Form'
import SsoConnectLink from '@/components/SsoConnectLink.vue' import SsoConnectLink from '@/components/SsoConnectLink.vue'
import { useUserStore } from '@/stores/user' import { useUserStore } from '@/stores/user'
import { useNotifyStore } from '@/stores/notify' import { useNotify } from '@2fauth/ui'
import { useAppSettingsStore } from '@/stores/appSettings' import { useAppSettingsStore } from '@/stores/appSettings'
import { webauthnService } from '@/services/webauthn/webauthnService' import { webauthnService } from '@/services/webauthn/webauthnService'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { useErrorHandler } from '@2fauth/stores'
const errorHandler = useErrorHandler()
const { t } = useI18n() const { t } = useI18n()
const $2fauth = inject('2fauth') const $2fauth = inject('2fauth')
const router = useRouter() const router = useRouter()
const user = useUserStore() const user = useUserStore()
const notify = useNotifyStore() const notify = useNotify()
const appSettings = useAppSettingsStore() const appSettings = useAppSettingsStore()
const showWebauthnForm = user.preferences.useWebauthnOnly ? true : useStorage($2fauth.prefix + 'showWebauthnForm', false) const showWebauthnForm = user.preferences.useWebauthnOnly ? true : useStorage($2fauth.prefix + 'showWebauthnForm', false)
const form = reactive(new Form({ const form = reactive(new Form({
@ -67,7 +69,8 @@
notify.alert({text: t('message.auth.forms.authentication_failed'), duration: 10000 }) notify.alert({text: t('message.auth.forms.authentication_failed'), duration: 10000 })
} }
else if( error.response.status !== 422 ) { else if( error.response.status !== 422 ) {
notify.error(error) errorHandler.parse(error)
router.push({ name: 'genericError' })
} }
}) })
.finally(() => { .finally(() => {
@ -110,7 +113,8 @@
form.errors.set(form.extractErrors(error.response)) form.errors.set(form.extractErrors(error.response))
} }
else { else {
notify.error(error) errorHandler.parse(error)
router.push({ name: 'genericError' })
} }
}) })
.finally(() => { .finally(() => {

View File

@ -2,12 +2,14 @@
import Form from '@/components/formElements/Form' import Form from '@/components/formElements/Form'
import { useUserStore } from '@/stores/user' import { useUserStore } from '@/stores/user'
import { webauthnService } from '@/services/webauthn/webauthnService' import { webauthnService } from '@/services/webauthn/webauthnService'
import { useNotifyStore } from '@/stores/notify' import { useNotify } from '@2fauth/ui'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { useErrorHandler } from '@2fauth/stores'
const errorHandler = useErrorHandler()
const { t } = useI18n() const { t } = useI18n()
const user = useUserStore() const user = useUserStore()
const notify = useNotifyStore() const notify = useNotify()
const router = useRouter() const router = useRouter()
const showWebauthnRegistration = ref(false) const showWebauthnRegistration = ref(false)
const deviceId = ref(null) const deviceId = ref(null)
@ -57,7 +59,8 @@
notify.alert({ text: error.response.data.message }) notify.alert({ text: error.response.data.message })
} }
else { else {
notify.error(error); errorHandler.parse(error)
router.push({ name: 'genericError' })
} }
}) })
} }

View File

@ -1,8 +1,10 @@
<script setup> <script setup>
import Form from '@/components/formElements/Form' import Form from '@/components/formElements/Form'
import { useNotifyStore } from '@/stores/notify' import { useNotify } from '@2fauth/ui'
import { useErrorHandler } from '@2fauth/stores'
const notify = useNotifyStore() const errorHandler = useErrorHandler()
const notify = useNotify()
const route = useRoute() const route = useRoute()
const isWebauthnReset = route.name == 'webauthn.lost' const isWebauthnReset = route.name == 'webauthn.lost'
@ -25,7 +27,8 @@
notify.alert({ text: error.response.data.requestFailed, duration:-1 }) notify.alert({ text: error.response.data.requestFailed, duration:-1 })
} }
else if( error.response.status !== 422 ) { else if( error.response.status !== 422 ) {
notify.error(error) errorHandler.parse(error)
router.push({ name: 'genericError' })
} }
}) })
} }

View File

@ -1,8 +1,10 @@
<script setup> <script setup>
import Form from '@/components/formElements/Form' import Form from '@/components/formElements/Form'
import { useNotifyStore } from '@/stores/notify' import { useNotify } from '@2fauth/ui'
import { useErrorHandler } from '@2fauth/stores'
const notify = useNotifyStore() const errorHandler = useErrorHandler()
const notify = useNotify()
const router = useRouter() const router = useRouter()
const route = useRoute() const route = useRoute()
@ -32,7 +34,8 @@
notify.alert({ text: error.response.data.resetFailed, duration:-1 }) notify.alert({ text: error.response.data.resetFailed, duration:-1 })
} }
else if( error.response.status !== 422 ) { else if( error.response.status !== 422 ) {
notify.error(error) errorHandler.parse(error)
router.push({ name: 'genericError' })
} }
}) })
} }

View File

@ -1,11 +1,13 @@
<script setup> <script setup>
import Form from '@/components/formElements/Form' import Form from '@/components/formElements/Form'
import { useNotifyStore } from '@/stores/notify' import { useNotify } from '@2fauth/ui'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { useErrorHandler } from '@2fauth/stores'
const errorHandler = useErrorHandler()
const { t } = useI18n() const { t } = useI18n()
const $2fauth = inject('2fauth') const $2fauth = inject('2fauth')
const notify = useNotifyStore() const notify = useNotify()
const router = useRouter() const router = useRouter()
const route = useRoute() const route = useRoute()
const showWebauthnForm = useStorage($2fauth.prefix + 'showWebauthnForm', false) const showWebauthnForm = useStorage($2fauth.prefix + 'showWebauthnForm', false)
@ -35,7 +37,8 @@
notify.alert({ text: error.response.data.message, duration:-1 }) notify.alert({ text: error.response.data.message, duration:-1 })
} }
else { else {
notify.error(error) errorHandler.parse(error)
router.push({ name: 'genericError' })
} }
}) })
} }

View File

@ -2,13 +2,15 @@
import Form from '@/components/formElements/Form' import Form from '@/components/formElements/Form'
import SettingTabs from '@/layouts/SettingTabs.vue' import SettingTabs from '@/layouts/SettingTabs.vue'
import { useUserStore } from '@/stores/user' import { useUserStore } from '@/stores/user'
import { useNotifyStore } from '@/stores/notify' import { useNotify } from '@2fauth/ui'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { useErrorHandler } from '@2fauth/stores'
const errorHandler = useErrorHandler()
const { t } = useI18n() const { t } = useI18n()
const $2fauth = inject('2fauth') const $2fauth = inject('2fauth')
const user = useUserStore() const user = useUserStore()
const notify = useNotifyStore() const notify = useNotify()
const router = useRouter() const router = useRouter()
const returnTo = useStorage($2fauth.prefix + 'returnTo', 'accounts') const returnTo = useStorage($2fauth.prefix + 'returnTo', 'accounts')
@ -45,7 +47,9 @@
notify.alert({ text: error.response.data.message }) notify.alert({ text: error.response.data.message })
} }
else if( error.response.status !== 422 ) { else if( error.response.status !== 422 ) {
notify.error(error.response) // TODO : check if we should return error.response or error
errorHandler.parse(error.response)
router.push({ name: 'genericError' })
} }
}) })
} }
@ -67,7 +71,9 @@
notify.alert({ text: error.response.data.message }) notify.alert({ text: error.response.data.message })
} }
else if( error.response.status !== 422 ) { else if( error.response.status !== 422 ) {
notify.error(error.response) // TODO : check if we should return error.response or error
errorHandler.parse(error.response)
router.push({ name: 'genericError' })
} }
}) })
} }
@ -88,7 +94,9 @@
notify.alert({ text: error.response.data.message }) notify.alert({ text: error.response.data.message })
} }
else if( error.response.status !== 422 ) { else if( error.response.status !== 422 ) {
notify.error(error.response) // TODO : check if we should return error.response or error
errorHandler.parse(error.response)
router.push({ name: 'genericError' })
} }
}) })
} }

View File

@ -1,11 +1,11 @@
<script setup> <script setup>
import Form from '@/components/formElements/Form' import Form from '@/components/formElements/Form'
import { useNotifyStore } from '@/stores/notify' import { useNotify } from '@2fauth/ui'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
const { t } = useI18n() const { t } = useI18n()
const router = useRouter() const router = useRouter()
const notify = useNotifyStore() const notify = useNotify()
const form = reactive(new Form({ const form = reactive(new Form({
name: t('message.auth.webauthn.my_device') name: t('message.auth.webauthn.my_device')
})) }))

View File

@ -3,16 +3,18 @@
import userService from '@/services/userService' import userService from '@/services/userService'
import SettingTabs from '@/layouts/SettingTabs.vue' import SettingTabs from '@/layouts/SettingTabs.vue'
import { useAppSettingsStore } from '@/stores/appSettings' import { useAppSettingsStore } from '@/stores/appSettings'
import { useNotifyStore } from '@/stores/notify' import { useNotify } from '@2fauth/ui'
import { UseColorMode } from '@vueuse/components' import { UseColorMode } from '@vueuse/components'
import { useUserStore } from '@/stores/user' import { useUserStore } from '@/stores/user'
import Spinner from '@/components/Spinner.vue' import Spinner from '@/components/Spinner.vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { useErrorHandler } from '@2fauth/stores'
const errorHandler = useErrorHandler()
const { t } = useI18n() const { t } = useI18n()
const appSettings = useAppSettingsStore() const appSettings = useAppSettingsStore()
const $2fauth = inject('2fauth') const $2fauth = inject('2fauth')
const notify = useNotifyStore() const notify = useNotify()
const user = useUserStore() const user = useUserStore()
const returnTo = useStorage($2fauth.prefix + 'returnTo', 'accounts') const returnTo = useStorage($2fauth.prefix + 'returnTo', 'accounts')
const { copy } = useClipboard({ legacy: true }) const { copy } = useClipboard({ legacy: true })
@ -61,7 +63,8 @@
// The form is already disabled (see isDisabled) so we do nothing more here // The form is already disabled (see isDisabled) so we do nothing more here
} }
else { else {
notify.error(error) errorHandler.parse(error)
router.push({ name: 'genericError' })
} }
}) })
.finally(() => { .finally(() => {

View File

@ -3,7 +3,7 @@
import userService from '@/services/userService' import userService from '@/services/userService'
import { useUserStore } from '@/stores/user' import { useUserStore } from '@/stores/user'
import { useGroups } from '@/stores/groups' import { useGroups } from '@/stores/groups'
import { useNotifyStore } from '@/stores/notify' import { useNotify } from '@2fauth/ui'
import { useAppSettingsStore } from '@/stores/appSettings' import { useAppSettingsStore } from '@/stores/appSettings'
import { timezones } from './timezones' import { timezones } from './timezones'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
@ -12,7 +12,7 @@
const $2fauth = inject('2fauth') const $2fauth = inject('2fauth')
const user = useUserStore() const user = useUserStore()
const groups = useGroups() const groups = useGroups()
const notify = useNotifyStore() const notify = useNotify()
const appSettings = useAppSettingsStore() const appSettings = useAppSettingsStore()
const returnTo = useStorage($2fauth.prefix + 'returnTo', 'accounts') const returnTo = useStorage($2fauth.prefix + 'returnTo', 'accounts')
@ -124,7 +124,7 @@
*/ */
function savePreference(preference, value) { function savePreference(preference, value) {
userService.updatePreference(preference, value).then(response => { userService.updatePreference(preference, value).then(response => {
useNotifyStore().success({ type: 'is-success', text: t('message.settings.forms.setting_saved') }) useNotify().success({ text: t('message.settings.forms.setting_saved') })
if(preference === 'lang') { if(preference === 'lang') {
user.applyLanguage() user.applyLanguage()

View File

@ -4,16 +4,18 @@
import { webauthnService } from '@/services/webauthn/webauthnService' import { webauthnService } from '@/services/webauthn/webauthnService'
import { useAppSettingsStore } from '@/stores/appSettings' import { useAppSettingsStore } from '@/stores/appSettings'
import { useUserStore } from '@/stores/user' import { useUserStore } from '@/stores/user'
import { useNotifyStore } from '@/stores/notify' import { useNotify } from '@2fauth/ui'
import { UseColorMode } from '@vueuse/components' import { UseColorMode } from '@vueuse/components'
import Spinner from '@/components/Spinner.vue' import Spinner from '@/components/Spinner.vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { useErrorHandler } from '@2fauth/stores'
const errorHandler = useErrorHandler()
const { t } = useI18n() const { t } = useI18n()
const $2fauth = inject('2fauth') const $2fauth = inject('2fauth')
const user = useUserStore() const user = useUserStore()
const appSettings = useAppSettingsStore() const appSettings = useAppSettingsStore()
const notify = useNotifyStore() const notify = useNotify()
const router = useRouter() const router = useRouter()
const returnTo = useStorage($2fauth.prefix + 'returnTo', 'accounts') const returnTo = useStorage($2fauth.prefix + 'returnTo', 'accounts')
@ -57,7 +59,8 @@
notify.alert({ text: error.response.data.message }) notify.alert({ text: error.response.data.message })
} }
else { else {
notify.error(error); errorHandler.parse(error)
router.push({ name: 'genericError' })
} }
}) })
} }
@ -106,7 +109,8 @@
// The form is already disabled (see isDisabled) so we do nothing more here // The form is already disabled (see isDisabled) so we do nothing more here
} }
else { else {
notify.error(error) errorHandler.parse(error)
router.push({ name: 'genericError' })
} }
}) })
.finally(() => { .finally(() => {

View File

@ -11,18 +11,20 @@
import Dots from '@/components/Dots.vue' import Dots from '@/components/Dots.vue'
import { UseColorMode } from '@vueuse/components' import { UseColorMode } from '@vueuse/components'
import { useUserStore } from '@/stores/user' import { useUserStore } from '@/stores/user'
import { useNotifyStore } from '@/stores/notify' import { useNotify } from '@2fauth/ui'
import { useBusStore } from '@/stores/bus' import { useBusStore } from '@/stores/bus'
import { useTwofaccounts } from '@/stores/twofaccounts' import { useTwofaccounts } from '@/stores/twofaccounts'
import { useGroups } from '@/stores/groups' import { useGroups } from '@/stores/groups'
import { useDisplayablePassword } from '@/composables/helpers' import { useDisplayablePassword } from '@/composables/helpers'
import { useSortable, moveArrayElement } from '@vueuse/integrations/useSortable' import { useSortable, moveArrayElement } from '@vueuse/integrations/useSortable'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { useErrorHandler } from '@2fauth/stores'
const errorHandler = useErrorHandler()
const { t } = useI18n() const { t } = useI18n()
const $2fauth = inject('2fauth') const $2fauth = inject('2fauth')
const router = useRouter() const router = useRouter()
const notify = useNotifyStore() const notify = useNotify()
const user = useUserStore() const user = useUserStore()
const bus = useBusStore() const bus = useBusStore()
const { copy, copied } = useClipboard({ legacy: true }) const { copy, copied } = useClipboard({ legacy: true })

View File

@ -4,14 +4,16 @@
import QrContentDisplay from '@/components/QrContentDisplay.vue' import QrContentDisplay from '@/components/QrContentDisplay.vue'
import { useBusStore } from '@/stores/bus' import { useBusStore } from '@/stores/bus'
import { UseColorMode } from '@vueuse/components' import { UseColorMode } from '@vueuse/components'
import { useNotifyStore } from '@/stores/notify' import { useNotify } from '@2fauth/ui'
import { QrcodeStream } from 'vue-qrcode-reader' import { QrcodeStream } from 'vue-qrcode-reader'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { useErrorHandler } from '@2fauth/stores'
const errorHandler = useErrorHandler()
const { t } = useI18n() const { t } = useI18n()
const router = useRouter() const router = useRouter()
const bus = useBusStore() const bus = useBusStore()
const notify = useNotifyStore() const notify = useNotify()
const cameraIsOn = ref(false) const cameraIsOn = ref(false)
const selectedCamera = ref(null) const selectedCamera = ref(null)
@ -55,7 +57,8 @@
} else if (error.name === 'StreamApiNotSupportedError') { } else if (error.name === 'StreamApiNotSupportedError') {
errorPhrase.value = 'stream_api_not_supported' errorPhrase.value = 'stream_api_not_supported'
} else { } else {
notify.error(error) errorHandler.parse(error)
router.push({ name: 'genericError' })
} }
} }

View File

@ -8,10 +8,12 @@
import { useTwofaccounts } from '@/stores/twofaccounts' import { useTwofaccounts } from '@/stores/twofaccounts'
import { useGroups } from '@/stores/groups' import { useGroups } from '@/stores/groups'
import { useBusStore } from '@/stores/bus' import { useBusStore } from '@/stores/bus'
import { useNotifyStore } from '@/stores/notify' import { useNotify } from '@2fauth/ui'
import { UseColorMode } from '@vueuse/components' import { UseColorMode } from '@vueuse/components'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { useErrorHandler } from '@2fauth/stores'
const errorHandler = useErrorHandler()
const { t } = useI18n() const { t } = useI18n()
const $2fauth = inject('2fauth') const $2fauth = inject('2fauth')
const router = useRouter() const router = useRouter()
@ -19,7 +21,7 @@
const user = useUserStore() const user = useUserStore()
const twofaccounts = useTwofaccounts() const twofaccounts = useTwofaccounts()
const bus = useBusStore() const bus = useBusStore()
const notify = useNotifyStore() const notify = useNotify()
const form = reactive(new Form({ const form = reactive(new Form({
service: '', service: '',
account: '', account: '',
@ -389,7 +391,8 @@
} }
else notify.alert({ text: t(error.response.data.message) }) else notify.alert({ text: t(error.response.data.message) })
} else { } else {
notify.error(error) errorHandler.parse(error)
router.push({ name: 'genericError' })
} }
}) })
}) })

View File

@ -4,7 +4,7 @@
import OtpDisplay from '@/components/OtpDisplay.vue' import OtpDisplay from '@/components/OtpDisplay.vue'
import Spinner from '@/components/Spinner.vue' import Spinner from '@/components/Spinner.vue'
import { FormTextarea } from '@2fauth/formcontrols' import { FormTextarea } from '@2fauth/formcontrols'
import { useNotifyStore } from '@/stores/notify' import { useNotify } from '@2fauth/ui'
import { useUserStore } from '@/stores/user' import { useUserStore } from '@/stores/user'
import { useBusStore } from '@/stores/bus' import { useBusStore } from '@/stores/bus'
import { useTwofaccounts } from '@/stores/twofaccounts' import { useTwofaccounts } from '@/stores/twofaccounts'
@ -13,7 +13,7 @@
const { t } = useI18n() const { t } = useI18n()
const $2fauth = inject('2fauth') const $2fauth = inject('2fauth')
const notify = useNotifyStore() const notify = useNotify()
const user = useUserStore() const user = useUserStore()
const bus = useBusStore() const bus = useBusStore()
const twofaccounts = useTwofaccounts() const twofaccounts = useTwofaccounts()

View File

@ -29,7 +29,6 @@
"error.wrong_current_password": "Wrong current password", "error.wrong_current_password": "Wrong current password",
"error.wrong_password": "Wrong password", "error.wrong_password": "Wrong password",
"error.resource_not_found": "Resource not found", "error.resource_not_found": "Resource not found",
"error.error_occured": "An error occured:",
"error.refresh": "Refresh", "error.refresh": "Refresh",
"error.no_valid_otp": "No valid OTP resource in this QR code", "error.no_valid_otp": "No valid OTP resource in this QR code",
"error.something_wrong_with_server": "Something is wrong with your server", "error.something_wrong_with_server": "Something is wrong with your server",
@ -241,7 +240,6 @@
"message.reset_extension_description": "The extension will be stripped of its current configuration and 2FAuth data. It will be available again for rebinding to a 2FAuth user account.", "message.reset_extension_description": "The extension will be stripped of its current configuration and 2FAuth data. It will be available again for rebinding to a 2FAuth user account.",
"message.reset_extension": "Reset extension", "message.reset_extension": "Reset extension",
"message.reset": "Reset", "message.reset": "Reset",
"message.resource_not_found": "Resource not found",
"message.resources": "Resources", "message.resources": "Resources",
"message.retry_or_reset_extension": "You can try to refresh (maybe it was a temporary problem) or you can reset the extension and provide a new token.", "message.retry_or_reset_extension": "You can try to refresh (maybe it was a temporary problem) or you can reset the extension and provide a new token.",
"message.save": "Save", "message.save": "Save",

View File

@ -29,7 +29,6 @@
"error.wrong_current_password": "Mauvais mot de passe (actuel)", "error.wrong_current_password": "Mauvais mot de passe (actuel)",
"error.wrong_password": "Mauvais mot de passe", "error.wrong_password": "Mauvais mot de passe",
"error.resource_not_found": "Ressource introuvable", "error.resource_not_found": "Ressource introuvable",
"error.error_occured": "Une erreur est survenue :",
"error.refresh": "Actualiser", "error.refresh": "Actualiser",
"error.no_valid_otp": "Aucune donnée OTP valide dans ce QR code", "error.no_valid_otp": "Aucune donnée OTP valide dans ce QR code",
"error.something_wrong_with_server": "Il y a un problème avec votre serveur", "error.something_wrong_with_server": "Il y a un problème avec votre serveur",
@ -241,7 +240,6 @@
"message.reset_extension_description": "Toutes les données de configuration et de double authentification seront supprimées. L'extension pourra être reconnectée à un compte utilisateur 2FAuth.", "message.reset_extension_description": "Toutes les données de configuration et de double authentification seront supprimées. L'extension pourra être reconnectée à un compte utilisateur 2FAuth.",
"message.reset_extension": "Réinitialiser l'extension", "message.reset_extension": "Réinitialiser l'extension",
"message.reset": "Réinitialiser", "message.reset": "Réinitialiser",
"message.resource_not_found": "Ressource introuvable",
"message.resources": "Ressources", "message.resources": "Ressources",
"message.retry_or_reset_extension": "Essayez d'actualiser (ce n'était peut-être qu'un problème temporaire) ou alors réinitialisez l'extension et fournissez un nouveau jeton d'accès.", "message.retry_or_reset_extension": "Essayez d'actualiser (ce n'était peut-être qu'un problème temporaire) ou alors réinitialisez l'extension et fournissez un nouveau jeton d'accès.",
"message.save": "Enregistrer", "message.save": "Enregistrer",