mirror of
https://github.com/unraid/api.git
synced 2026-01-07 09:10:05 -06:00
feat: auth web component
This commit is contained in:
@@ -29,7 +29,7 @@ const blacklistedGuid = '154B-00EE-0700-9B50CF819816';
|
||||
// EBLACKLISTED1
|
||||
// EBLACKLISTED2
|
||||
// ENOCONN
|
||||
const state: string = 'TRIAL';
|
||||
const state: string = 'ENOKEYFILE2';
|
||||
|
||||
const uptime = Date.now() - 60 * 60 * 1000; // 1 hour ago
|
||||
let expireTime = 0;
|
||||
@@ -47,7 +47,7 @@ const serverState = {
|
||||
lanIp: '192.168.0.1',
|
||||
locale: 'en',
|
||||
pluginInstalled: true,
|
||||
registered: true,
|
||||
registered: false,
|
||||
site: 'http://localhost:4321',
|
||||
state,
|
||||
uptime,
|
||||
|
||||
4
app.vue
4
app.vue
@@ -13,7 +13,7 @@ onBeforeMount(() => {
|
||||
<div class="flex flex-col gap-6 p-6">
|
||||
<h2>Vue Components</h2>
|
||||
<UserProfileCe :server="serverState" />
|
||||
<ApiLogsCe />
|
||||
<DownloadApiLogsCe />
|
||||
<AuthCe />
|
||||
<KeyActionsCe />
|
||||
<LaunchpadCe />
|
||||
@@ -24,7 +24,7 @@ onBeforeMount(() => {
|
||||
<div class="flex flex-col gap-6 p-6">
|
||||
<h2>Web Components</h2>
|
||||
<connect-user-profile :server="JSON.stringify(serverState)"></connect-user-profile>
|
||||
<connect-api-logs></connect-api-logs>
|
||||
<connect-download-api-logs></connect-download-api-logs>
|
||||
<connect-auth></connect-auth>
|
||||
<connect-key-actions></connect-key-actions>
|
||||
<connect-launchpad></connect-launchpad>
|
||||
|
||||
@@ -1,11 +1,69 @@
|
||||
<script lang="ts" setup>
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { ExclamationTriangleIcon } from '@heroicons/vue/24/solid';
|
||||
import { useServerStore } from '~/store/server';
|
||||
import type { ServerStateDataAction } from '~/types/server';
|
||||
import 'tailwindcss/tailwind.css';
|
||||
import '~/assets/main.css';
|
||||
|
||||
export interface Props {
|
||||
phpRegistered?: boolean;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
phpRegistered: false,
|
||||
});
|
||||
|
||||
const serverStore = useServerStore();
|
||||
const { registered, stateData } = storeToRefs(serverStore);
|
||||
|
||||
// rely on prop before the pinia state kicks in
|
||||
const computedRegistered = computed(() => registered.value === undefined ? !!props.phpRegistered : registered.value);
|
||||
|
||||
// Intended to retrieve sign in and sign out from actions
|
||||
const accountAction = computed((): ServerStateDataAction | undefined => {
|
||||
const allowed = ['signIn', 'signOut'];
|
||||
if (!stateData.value.actions) return;
|
||||
return stateData.value.actions.find(action => allowed.includes(action.name));
|
||||
});
|
||||
// @todo use callback url
|
||||
const stateDataErrorAction = computed(() => {
|
||||
return {
|
||||
click: () => { console.debug('accountServerPayload') },
|
||||
external: true,
|
||||
icon: ExclamationTriangleIcon,
|
||||
name: 'accountServer',
|
||||
text: 'Fix Error',
|
||||
}
|
||||
});
|
||||
|
||||
const button = computed(() => {
|
||||
if (stateData.value.error) return stateDataErrorAction.value;
|
||||
return accountAction.value;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="text-white font-semibold p-4 bg-orange-400 rounded-lg">
|
||||
Auth.ce
|
||||
<div class="whitespace-normal flex flex-col gap-y-16px">
|
||||
<span v-if="stateData.error" class="text-red font-semibold leading-8 max-w-3xl">
|
||||
{{ stateData.error.heading }}
|
||||
<br />
|
||||
{{ stateData.error.message }}
|
||||
</span>
|
||||
<span>
|
||||
<component
|
||||
v-if="button"
|
||||
:is="button.click ? 'button' : 'a'"
|
||||
@click="button.click()"
|
||||
rel="noopener noreferrer"
|
||||
class="text-white text-14px text-center w-full flex-none flex flex-row items-center justify-center gap-x-8px px-8px py-8px cursor-pointer rounded-md bg-gradient-to-r from-red to-orange hover:from-red/60 hover:to-orange/60 focus:from-red/60 focus:to-orange/60"
|
||||
target="_blank"
|
||||
download
|
||||
>
|
||||
<component v-if="button.icon" :is="button.icon" class="flex-shrink-0 w-14px" />
|
||||
{{ button.text }}
|
||||
</component>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -25,14 +25,18 @@ export default defineNuxtConfig({
|
||||
{
|
||||
name: 'ConnectComponents',
|
||||
tags: [
|
||||
{
|
||||
name: 'ConnectUserProfile',
|
||||
path: '@/components/UserProfile.ce',
|
||||
},
|
||||
{
|
||||
name: 'ConnectAuth',
|
||||
path: '@/components/Auth.ce',
|
||||
},
|
||||
{
|
||||
name: 'ConnectCallbackHandler',
|
||||
path: '@/components/CallbackHandler.ce',
|
||||
},
|
||||
{
|
||||
name: 'ConnectDownloadApiLogs',
|
||||
path: '@/components/DownloadApiLogs.ce',
|
||||
},
|
||||
{
|
||||
name: 'ConnectKeyActions',
|
||||
path: '@/components/KeyActions.ce',
|
||||
@@ -49,10 +53,6 @@ export default defineNuxtConfig({
|
||||
name: 'ConnectWanIpCheck',
|
||||
path: '@/components/WanIpCheck.ce',
|
||||
},
|
||||
{
|
||||
name: 'ConnectCallbackHandler',
|
||||
path: '@/components/CallbackHandler.ce',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
106
store/server.ts
106
store/server.ts
@@ -4,6 +4,7 @@ import type {
|
||||
Server,
|
||||
ServerState,
|
||||
ServerStateData,
|
||||
ServerStateDataAction,
|
||||
} from '~/types/server';
|
||||
/**
|
||||
* @see https://stackoverflow.com/questions/73476371/using-pinia-with-vue-js-web-components
|
||||
@@ -29,7 +30,7 @@ export const useServerStore = defineStore('server', () => {
|
||||
const locale = ref<string>('');
|
||||
const name = ref<string>('');
|
||||
const pluginInstalled = ref<boolean>(false);
|
||||
const registered = ref<boolean>(false);
|
||||
const registered = ref<boolean>();
|
||||
const regGen = ref<number>(0);
|
||||
const regGuid = ref<string>('');
|
||||
const site = ref<string>('');
|
||||
@@ -76,15 +77,24 @@ export const useServerStore = defineStore('server', () => {
|
||||
}
|
||||
});
|
||||
|
||||
const signInAction: ServerStateDataAction = {
|
||||
click: () => { console.debug('signIn') },
|
||||
external: true,
|
||||
icon: GlobeAltIcon,
|
||||
name: 'signIn',
|
||||
text: 'Sign In with Unraid.net Account',
|
||||
};
|
||||
const signOutAction: ServerStateDataAction = {
|
||||
click: () => { console.debug('signOut') },
|
||||
external: true,
|
||||
icon: ArrowRightOnRectangleIcon,
|
||||
name: 'signOut',
|
||||
text: 'Sign Out of Unraid.net',
|
||||
};
|
||||
const stateDataDefault: ServerStateData = {
|
||||
actions: [
|
||||
{
|
||||
click: () => { console.debug('signIn') },
|
||||
external: true,
|
||||
icon: GlobeAltIcon,
|
||||
name: 'signIn',
|
||||
text: 'Sign In with Unraid.net Account',
|
||||
},
|
||||
// sign in
|
||||
...(registered.value ? [] : [signInAction]),
|
||||
{
|
||||
click: () => { console.debug('purchase') },
|
||||
external: true,
|
||||
@@ -92,13 +102,8 @@ export const useServerStore = defineStore('server', () => {
|
||||
name: 'purchase',
|
||||
text: 'Purchase Key',
|
||||
},
|
||||
// {
|
||||
// click: () => { console.debug('signOut') },
|
||||
// external: true,
|
||||
// icon: ArrowRightOnRectangleIcon,
|
||||
// name: 'signOut',
|
||||
// text: 'signOut',
|
||||
// },
|
||||
// sign out,
|
||||
...(registered.value ? [signOutAction] : []),
|
||||
],
|
||||
humanReadable: 'Trial',
|
||||
heading: 'Thank you for choosing Unraid OS!',
|
||||
@@ -129,70 +134,99 @@ export const useServerStore = defineStore('server', () => {
|
||||
case 'EGUID':
|
||||
return {
|
||||
...stateDataDefault,
|
||||
error: {
|
||||
heading: `${state.value} temp heading`,
|
||||
message: `${state.value} temp message – this is an error message`,
|
||||
reAuthFix: false,
|
||||
},
|
||||
};
|
||||
case 'EGUID1':
|
||||
return {
|
||||
...stateDataDefault,
|
||||
error: {
|
||||
heading: `${state.value} temp heading`,
|
||||
message: `${state.value} temp message – this is an error message`,
|
||||
reAuthFix: false,
|
||||
},
|
||||
};
|
||||
case 'ENOKEYFILE2':
|
||||
return {
|
||||
...stateDataDefault,
|
||||
error: {
|
||||
heading: `${state.value} temp heading`,
|
||||
message: `${state.value} temp message – this is an error message`,
|
||||
reAuthFix: false,
|
||||
},
|
||||
};
|
||||
case 'ETRIAL':
|
||||
return {
|
||||
...stateDataDefault,
|
||||
error: {
|
||||
heading: `${state.value} temp heading`,
|
||||
message: `${state.value} temp message – this is an error message`,
|
||||
reAuthFix: false,
|
||||
},
|
||||
};
|
||||
case 'ENOKEYFILE1':
|
||||
return {
|
||||
...stateDataDefault,
|
||||
error: {
|
||||
heading: `${state.value} temp heading`,
|
||||
message: `${state.value} temp message – this is an error message`,
|
||||
reAuthFix: false,
|
||||
},
|
||||
};
|
||||
case 'ENOFLASH':
|
||||
return {
|
||||
...stateDataDefault,
|
||||
};
|
||||
case 'ENOFLASH1':
|
||||
return {
|
||||
...stateDataDefault,
|
||||
};
|
||||
case 'ENOFLASH2':
|
||||
return {
|
||||
...stateDataDefault,
|
||||
};
|
||||
case 'ENOFLASH3':
|
||||
return {
|
||||
...stateDataDefault,
|
||||
};
|
||||
case 'ENOFLASH4':
|
||||
return {
|
||||
...stateDataDefault,
|
||||
};
|
||||
case 'ENOFLASH5':
|
||||
return {
|
||||
...stateDataDefault,
|
||||
};
|
||||
case 'ENOFLASH6':
|
||||
return {
|
||||
...stateDataDefault,
|
||||
};
|
||||
case 'ENOFLASH7':
|
||||
return {
|
||||
...stateDataDefault,
|
||||
error: {
|
||||
heading: `${state.value} temp heading`,
|
||||
message: `${state.value} temp message – this is an error message`,
|
||||
reAuthFix: false,
|
||||
},
|
||||
};
|
||||
case 'EBLACKLISTED':
|
||||
return {
|
||||
...stateDataDefault,
|
||||
error: {
|
||||
heading: `${state.value} temp heading`,
|
||||
message: `${state.value} temp message – this is an error message`,
|
||||
reAuthFix: false,
|
||||
},
|
||||
};
|
||||
case 'EBLACKLISTED1':
|
||||
return {
|
||||
...stateDataDefault,
|
||||
error: {
|
||||
heading: `${state.value} temp heading`,
|
||||
message: `${state.value} temp message – this is an error message`,
|
||||
reAuthFix: false,
|
||||
},
|
||||
};
|
||||
case 'EBLACKLISTED2':
|
||||
return {
|
||||
...stateDataDefault,
|
||||
error: {
|
||||
heading: `${state.value} temp heading`,
|
||||
message: `${state.value} temp message – this is an error message`,
|
||||
reAuthFix: false,
|
||||
},
|
||||
};
|
||||
case 'ENOCONN':
|
||||
return {
|
||||
...stateDataDefault,
|
||||
error: {
|
||||
heading: `${state.value} temp heading`,
|
||||
message: `${state.value} temp message – this is an error message`,
|
||||
reAuthFix: false,
|
||||
},
|
||||
};
|
||||
default:
|
||||
return {
|
||||
|
||||
@@ -49,6 +49,7 @@ export default <Partial<Config>>{
|
||||
'6px': '6px',
|
||||
'8px': '8px',
|
||||
'12px': '12px',
|
||||
'14px': '14px',
|
||||
'16px': '16px',
|
||||
'20px': '20px',
|
||||
'24px': '24px',
|
||||
|
||||
Reference in New Issue
Block a user