mirror of
https://github.com/unraid/api.git
synced 2026-01-02 22:50:02 -06:00
feat: WIP global error handling
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { defineStore, createPinia, setActivePinia } from 'pinia';
|
||||
import { useCallbackStore } from './callbackActions';
|
||||
import { useServerStore } from './server';
|
||||
import { useCallbackStore } from '~/store/callbackActions';
|
||||
import { useErrorsStore } from '~/store/errors';
|
||||
import { useServerStore } from '~/store/server';
|
||||
import { WebguiUpdate } from '~/composables/services/webgui';
|
||||
import { ACCOUNT } from '~/helpers/urls';
|
||||
import type { ExternalSignIn, ExternalSignOut } from '~/store/callback';
|
||||
@@ -12,6 +13,7 @@ setActivePinia(createPinia());
|
||||
|
||||
export const useAccountStore = defineStore('account', () => {
|
||||
const callbackStore = useCallbackStore();
|
||||
const errorsStore = useErrorsStore();
|
||||
const serverStore = useServerStore();
|
||||
|
||||
// State
|
||||
@@ -108,26 +110,6 @@ export const useAccountStore = defineStore('account', () => {
|
||||
accountAction.value = action;
|
||||
accountActionStatus.value = 'updating';
|
||||
|
||||
const userPayload = {
|
||||
...(accountAction.value.user
|
||||
? {
|
||||
apikey: accountAction.value.apiKey,
|
||||
// avatar: '',
|
||||
email: accountAction.value.user?.email,
|
||||
regWizTime: `${Date.now()}_${serverStore.guid}`, // set when signing in the first time and never unset for the sake of displaying Sign In/Up in the UPC without needing to validate guid every time
|
||||
username: accountAction.value.user?.preferred_username,
|
||||
}
|
||||
: {
|
||||
accesstoken: '',
|
||||
apikey: '',
|
||||
avatar: '',
|
||||
email: '',
|
||||
idtoken: '',
|
||||
refreshtoken: '',
|
||||
username: '',
|
||||
}),
|
||||
};
|
||||
|
||||
if (!serverStore.registered && !accountAction.value.user) {
|
||||
console.debug('[accountStore.updatePluginConfig] Not registered skipping sign out');
|
||||
accountActionHide.value = true;
|
||||
@@ -136,6 +118,25 @@ export const useAccountStore = defineStore('account', () => {
|
||||
}
|
||||
|
||||
try {
|
||||
const userPayload = {
|
||||
...(accountAction.value.user
|
||||
? {
|
||||
apikey: accountAction.value.apiKey,
|
||||
// avatar: '',
|
||||
email: accountAction.value.user?.email,
|
||||
regWizTime: `${Date.now()}_${serverStore.guid}`, // set when signing in the first time and never unset for the sake of displaying Sign In/Up in the UPC without needing to validate guid every time
|
||||
username: accountAction.value.user?.preferred_username,
|
||||
}
|
||||
: {
|
||||
accesstoken: '',
|
||||
apikey: '',
|
||||
avatar: '',
|
||||
email: '',
|
||||
idtoken: '',
|
||||
refreshtoken: '',
|
||||
username: '',
|
||||
}),
|
||||
};
|
||||
const response = await WebguiUpdate
|
||||
.formUrl({
|
||||
csrf_token: serverStore.csrf,
|
||||
@@ -151,11 +152,13 @@ export const useAccountStore = defineStore('account', () => {
|
||||
.catch(err => {
|
||||
console.debug('[accountStore.updatePluginConfig] WebguiUpdate err', err);
|
||||
accountActionStatus.value = 'failed';
|
||||
errorsStore.setError(err);
|
||||
});
|
||||
return response;
|
||||
} catch(err) {
|
||||
console.debug('[accountStore.updatePluginConfig] WebguiUpdate catch err', err);
|
||||
accountActionStatus.value = 'failed';
|
||||
errorsStore.setError(err);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -108,20 +108,25 @@ export const useCallbackStoreGeneric = (
|
||||
|
||||
const send = (url: string, payload: SendPayloads, sendType?: 'fromUpc' | 'forUpc') => {
|
||||
console.debug('[callback.send]');
|
||||
const stringifiedData = JSON.stringify({
|
||||
actions: [
|
||||
...payload,
|
||||
],
|
||||
sender: window.location.href,
|
||||
type: sendType ?? defaultSendType,
|
||||
});
|
||||
const encryptedMessage = AES.encrypt(stringifiedData, encryptionKey).toString();
|
||||
// build and go to url
|
||||
const destinationUrl = new URL(url);
|
||||
destinationUrl.searchParams.set('data', encodeURI(encryptedMessage));
|
||||
console.debug('[callback.send]', encryptedMessage, destinationUrl);
|
||||
window.location.href = destinationUrl.toString();
|
||||
return;
|
||||
try {
|
||||
const stringifiedData = JSON.stringify({
|
||||
actions: [
|
||||
...payload,
|
||||
],
|
||||
sender: window.location.href,
|
||||
type: sendType ?? defaultSendType,
|
||||
});
|
||||
const encryptedMessage = AES.encrypt(stringifiedData, encryptionKey).toString();
|
||||
// build and go to url
|
||||
const destinationUrl = new URL(url);
|
||||
destinationUrl.searchParams.set('data', encodeURI(encryptedMessage));
|
||||
console.debug('[callback.send]', encryptedMessage, destinationUrl);
|
||||
window.location.href = destinationUrl.toString();
|
||||
return;
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
throw new Error("Unable to create callback event");
|
||||
}
|
||||
};
|
||||
|
||||
const watcher = () => {
|
||||
@@ -133,11 +138,16 @@ export const useCallbackStoreGeneric = (
|
||||
return console.debug('[callback.watcher] no callback to handle');
|
||||
}
|
||||
|
||||
const decryptedMessage = AES.decrypt(callbackValue, encryptionKey);
|
||||
const decryptedData: QueryPayloads = JSON.parse(decryptedMessage.toString(Utf8));
|
||||
console.debug('[callback.watcher]', decryptedMessage, decryptedData);
|
||||
// Parse the data and perform actions
|
||||
callbackActions.redirectToCallbackType(decryptedData);
|
||||
try {
|
||||
const decryptedMessage = AES.decrypt(callbackValue, encryptionKey);
|
||||
const decryptedData: QueryPayloads = JSON.parse(decryptedMessage.toString(Utf8));
|
||||
console.debug('[callback.watcher]', decryptedMessage, decryptedData);
|
||||
// Parse the data and perform actions
|
||||
callbackActions.redirectToCallbackType(decryptedData);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
throw new Error("Couldn't decrypt callback data");
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
@@ -4,15 +4,13 @@ import { addPreventClose, removePreventClose } from '~/composables/preventClose'
|
||||
import { useAccountStore } from '~/store/account';
|
||||
import { useInstallKeyStore } from '~/store/installKey';
|
||||
import { useCallbackStoreGeneric, type ExternalPayload, type ExternalKeyActions, type QueryPayloads } from '~/store/callback';
|
||||
import { remove } from '@vue/shared';
|
||||
// import { useServerStore } from './server';
|
||||
|
||||
export const useCallbackActionsStore = defineStore(
|
||||
'callbackActions',
|
||||
() => {
|
||||
const accountStore = useAccountStore();
|
||||
const installKeyStore = useInstallKeyStore();
|
||||
// const serverStore = useServerStore();
|
||||
|
||||
type CallbackStatus = 'error' | 'loading' | 'ready' | 'success';
|
||||
const callbackStatus = ref<CallbackStatus>('ready');
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { defineStore, createPinia, setActivePinia } from 'pinia';
|
||||
// import { useAccountStore } from './account';
|
||||
// import { useCallbackStore } from './callbackActions';
|
||||
// import { useInstallKeyStore } from './installKey';
|
||||
// import { useServerStore } from './server';
|
||||
// import { useAccountStore } from '~/store/account';
|
||||
// import { useCallbackStore, useCallbackActionsStore } from '~/store/callbackActions';
|
||||
// import { useInstallKeyStore } from '~/store/installKey';
|
||||
// import { useServerStore } from '~/store/server';
|
||||
|
||||
/**
|
||||
* @see https://stackoverflow.com/questions/73476371/using-pinia-with-vue-js-web-components
|
||||
@@ -13,18 +13,29 @@ setActivePinia(createPinia());
|
||||
export const useErrorsStore = defineStore('errors', () => {
|
||||
// const accountStore = useAccountStore();
|
||||
// const callbackStore = useCallbackStore();
|
||||
// const callbackActionsStore = useCallbackActionsStore();
|
||||
// const installKeyStore = useInstallKeyStore();
|
||||
// const serverStore = useServerStore();
|
||||
|
||||
/** @todo type the errors */
|
||||
const errors = ref<any[]>([]);
|
||||
|
||||
const removeError = (index: number) => {
|
||||
errors.value = errors.value.filter((_error, i) => i !== index);
|
||||
};
|
||||
|
||||
const resetErrors = () => {
|
||||
errors.value = [];
|
||||
};
|
||||
|
||||
const setError = (error: any) => {
|
||||
errors.value.push(error);
|
||||
};
|
||||
|
||||
return {
|
||||
errors,
|
||||
removeError,
|
||||
resetErrors,
|
||||
setError,
|
||||
};
|
||||
});
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { defineStore, createPinia, setActivePinia } from 'pinia';
|
||||
import { delay } from 'wretch/middlewares';
|
||||
import { WebguiInstallKey, WebguiUpdateDns } from '~/composables/services/webgui';
|
||||
import { useErrorsStore } from '~/store/errors';
|
||||
import { useServerStore } from '~/store/server';
|
||||
import type { ExternalKeyActions } from '~/store/callback';
|
||||
/**
|
||||
@@ -10,6 +11,7 @@ import type { ExternalKeyActions } from '~/store/callback';
|
||||
setActivePinia(createPinia());
|
||||
|
||||
export const useInstallKeyStore = defineStore('installKey', () => {
|
||||
const errorsStore = useErrorsStore();
|
||||
const serverStore = useServerStore();
|
||||
|
||||
const keyInstallStatus = ref<'failed' | 'installing' | 'ready' | 'success'>('ready');
|
||||
@@ -55,6 +57,7 @@ export const useInstallKeyStore = defineStore('installKey', () => {
|
||||
} catch (error) {
|
||||
console.error('[install] WebguiInstallKey error', error);
|
||||
keyInstallStatus.value = 'failed';
|
||||
errorsStore.setError(error);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user