mirror of
https://github.com/unraid/api.git
synced 2025-12-31 21:49:57 -06:00
fix: parsing of ssoEnabled in state.php (#1455)
read `ssoSubIds` in state.php from `api.json` <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a new query to check if Single Sign-On (SSO) is enabled. * Updated UI components to dynamically reflect SSO availability via live data. * **Refactor** * Streamlined internal handling of SSO status detection for improved reliability and maintainability. * **Tests** * Enhanced tests for SSO button behavior with mocked live data and added edge case coverage for SSO callback handling. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -1666,6 +1666,7 @@ type Query {
|
|||||||
disk(id: PrefixedID!): Disk!
|
disk(id: PrefixedID!): Disk!
|
||||||
rclone: RCloneBackupSettings!
|
rclone: RCloneBackupSettings!
|
||||||
settings: Settings!
|
settings: Settings!
|
||||||
|
isSSOEnabled: Boolean!
|
||||||
|
|
||||||
"""List all installed plugins with their metadata"""
|
"""List all installed plugins with their metadata"""
|
||||||
plugins: [Plugin!]!
|
plugins: [Plugin!]!
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ import { GraphQLJSON } from 'graphql-scalars';
|
|||||||
|
|
||||||
import { ENVIRONMENT } from '@app/environment.js';
|
import { ENVIRONMENT } from '@app/environment.js';
|
||||||
import { LifecycleService } from '@app/unraid-api/app/lifecycle.service.js';
|
import { LifecycleService } from '@app/unraid-api/app/lifecycle.service.js';
|
||||||
|
import { Public } from '@app/unraid-api/auth/public.decorator.js';
|
||||||
|
import { SsoUserService } from '@app/unraid-api/auth/sso-user.service.js';
|
||||||
import {
|
import {
|
||||||
Settings,
|
Settings,
|
||||||
UnifiedSettings,
|
UnifiedSettings,
|
||||||
@@ -22,7 +24,10 @@ import { ApiSettings } from '@app/unraid-api/graph/resolvers/settings/settings.s
|
|||||||
|
|
||||||
@Resolver(() => Settings)
|
@Resolver(() => Settings)
|
||||||
export class SettingsResolver {
|
export class SettingsResolver {
|
||||||
constructor(private readonly apiSettings: ApiSettings) {}
|
constructor(
|
||||||
|
private readonly apiSettings: ApiSettings,
|
||||||
|
private readonly ssoUserService: SsoUserService
|
||||||
|
) {}
|
||||||
|
|
||||||
@Query(() => Settings)
|
@Query(() => Settings)
|
||||||
async settings() {
|
async settings() {
|
||||||
@@ -45,6 +50,12 @@ export class SettingsResolver {
|
|||||||
id: 'unified-settings',
|
id: 'unified-settings',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Query(() => Boolean)
|
||||||
|
@Public()
|
||||||
|
public async isSSOEnabled(): Promise<boolean> {
|
||||||
|
return this.ssoUserService.getSsoUsers().then((users) => users.length > 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Resolver(() => UnifiedSettings)
|
@Resolver(() => UnifiedSettings)
|
||||||
|
|||||||
@@ -6,6 +6,9 @@
|
|||||||
*/
|
*/
|
||||||
class ApiConfig
|
class ApiConfig
|
||||||
{
|
{
|
||||||
|
/** Home of API-specific configuration files */
|
||||||
|
public const CONFIG_DIR = '/boot/config/plugins/dynamix.my.servers/configs';
|
||||||
|
|
||||||
private static $scriptsDir = "/usr/local/share/dynamix.unraid.net/scripts";
|
private static $scriptsDir = "/usr/local/share/dynamix.unraid.net/scripts";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -27,9 +30,9 @@ class ApiConfig
|
|||||||
{
|
{
|
||||||
$output = [];
|
$output = [];
|
||||||
$exitCode = 0;
|
$exitCode = 0;
|
||||||
|
|
||||||
exec($command, $output, $exitCode);
|
exec($command, $output, $exitCode);
|
||||||
|
|
||||||
return implode("\n", $output);
|
return implode("\n", $output);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,7 +48,7 @@ class ApiConfig
|
|||||||
}
|
}
|
||||||
|
|
||||||
$apiUtilsScript = self::getApiUtilsScript();
|
$apiUtilsScript = self::getApiUtilsScript();
|
||||||
|
|
||||||
if (!is_executable($apiUtilsScript)) {
|
if (!is_executable($apiUtilsScript)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -53,10 +56,10 @@ class ApiConfig
|
|||||||
$escapedScript = escapeshellarg($apiUtilsScript);
|
$escapedScript = escapeshellarg($apiUtilsScript);
|
||||||
$escapedPlugin = escapeshellarg($pluginName);
|
$escapedPlugin = escapeshellarg($pluginName);
|
||||||
$command = "$escapedScript is_api_plugin_enabled $escapedPlugin 2>/dev/null";
|
$command = "$escapedScript is_api_plugin_enabled $escapedPlugin 2>/dev/null";
|
||||||
|
|
||||||
$exitCode = 0;
|
$exitCode = 0;
|
||||||
self::executeCommand($command, $exitCode);
|
self::executeCommand($command, $exitCode);
|
||||||
|
|
||||||
return $exitCode === 0;
|
return $exitCode === 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,22 +79,43 @@ class ApiConfig
|
|||||||
public static function getApiVersion()
|
public static function getApiVersion()
|
||||||
{
|
{
|
||||||
$apiUtilsScript = self::getApiUtilsScript();
|
$apiUtilsScript = self::getApiUtilsScript();
|
||||||
|
|
||||||
if (!is_executable($apiUtilsScript)) {
|
if (!is_executable($apiUtilsScript)) {
|
||||||
return 'unknown';
|
return 'unknown';
|
||||||
}
|
}
|
||||||
|
|
||||||
$escapedScript = escapeshellarg($apiUtilsScript);
|
$escapedScript = escapeshellarg($apiUtilsScript);
|
||||||
$command = "$escapedScript get_api_version 2>/dev/null";
|
$command = "$escapedScript get_api_version 2>/dev/null";
|
||||||
|
|
||||||
$exitCode = 0;
|
$exitCode = 0;
|
||||||
$output = self::executeCommand($command, $exitCode);
|
$output = self::executeCommand($command, $exitCode);
|
||||||
|
|
||||||
if ($exitCode !== 0) {
|
if ($exitCode !== 0) {
|
||||||
return 'unknown';
|
return 'unknown';
|
||||||
}
|
}
|
||||||
|
|
||||||
$version = trim($output);
|
$version = trim($output);
|
||||||
return !empty($version) ? $version : 'unknown';
|
return !empty($version) ? $version : 'unknown';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class ApiUserConfig
|
||||||
|
{
|
||||||
|
public const CONFIG_PATH = ApiConfig::CONFIG_DIR . '/api.json';
|
||||||
|
|
||||||
|
public static function getConfig()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return json_decode(file_get_contents(self::CONFIG_PATH), true) ?? [];
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function isSSOEnabled()
|
||||||
|
{
|
||||||
|
$config = self::getConfig();
|
||||||
|
return !empty($config['ssoSubIds'] ?? '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -202,7 +202,7 @@ class ServerState
|
|||||||
$this->registered = !empty($connectConfig['apikey']) && $this->connectPluginInstalled;
|
$this->registered = !empty($connectConfig['apikey']) && $this->connectPluginInstalled;
|
||||||
$this->registeredTime = $connectConfig['regWizTime'] ?? '';
|
$this->registeredTime = $connectConfig['regWizTime'] ?? '';
|
||||||
$this->username = $connectConfig['username'] ?? '';
|
$this->username = $connectConfig['username'] ?? '';
|
||||||
$this->ssoEnabled = !empty($connectConfig['ssoSubIds'] ?? '');
|
$this->ssoEnabled = ApiUserConfig::isSSOEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getConnectKnownOrigins()
|
private function getConnectKnownOrigins()
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
* SsoButton Component Test Coverage
|
* SsoButton Component Test Coverage
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { useQuery } from '@vue/apollo-composable';
|
||||||
import { flushPromises, mount } from '@vue/test-utils';
|
import { flushPromises, mount } from '@vue/test-utils';
|
||||||
|
|
||||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||||
@@ -15,6 +16,11 @@ const BrandButtonStub = {
|
|||||||
props: ['disabled', 'variant', 'class'],
|
props: ['disabled', 'variant', 'class'],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Mock the GraphQL composable
|
||||||
|
vi.mock('@vue/apollo-composable', () => ({
|
||||||
|
useQuery: vi.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
vi.mock('~/helpers/urls', () => ({
|
vi.mock('~/helpers/urls', () => ({
|
||||||
ACCOUNT: 'http://mock-account-url.net',
|
ACCOUNT: 'http://mock-account-url.net',
|
||||||
}));
|
}));
|
||||||
@@ -60,10 +66,13 @@ const mockUsernameField = { value: '' };
|
|||||||
|
|
||||||
describe('SsoButton.ce.vue', () => {
|
describe('SsoButton.ce.vue', () => {
|
||||||
let querySelectorSpy: MockInstance;
|
let querySelectorSpy: MockInstance;
|
||||||
|
let mockUseQuery: Mock;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(async () => {
|
||||||
vi.restoreAllMocks();
|
vi.restoreAllMocks();
|
||||||
|
|
||||||
|
mockUseQuery = useQuery as Mock;
|
||||||
|
|
||||||
(sessionStorage.getItem as Mock).mockReturnValue(null);
|
(sessionStorage.getItem as Mock).mockReturnValue(null);
|
||||||
(sessionStorage.setItem as Mock).mockClear();
|
(sessionStorage.setItem as Mock).mockClear();
|
||||||
mockForm.requestSubmit.mockClear();
|
mockForm.requestSubmit.mockClear();
|
||||||
@@ -73,6 +82,7 @@ describe('SsoButton.ce.vue', () => {
|
|||||||
mockLocation.search = '';
|
mockLocation.search = '';
|
||||||
mockLocation.href = '';
|
mockLocation.href = '';
|
||||||
(fetch as Mock).mockClear();
|
(fetch as Mock).mockClear();
|
||||||
|
mockUseQuery.mockClear();
|
||||||
|
|
||||||
// Spy on document.querySelector and provide mock implementation
|
// Spy on document.querySelector and provide mock implementation
|
||||||
querySelectorSpy = vi.spyOn(document, 'querySelector');
|
querySelectorSpy = vi.spyOn(document, 'querySelector');
|
||||||
@@ -93,9 +103,12 @@ describe('SsoButton.ce.vue', () => {
|
|||||||
vi.restoreAllMocks();
|
vi.restoreAllMocks();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders the button when ssoenabled prop is true (boolean)', () => {
|
it('renders the button when SSO is enabled via GraphQL', () => {
|
||||||
|
mockUseQuery.mockReturnValue({
|
||||||
|
result: { value: { isSSOEnabled: true } },
|
||||||
|
});
|
||||||
|
|
||||||
const wrapper = mount(SsoButton, {
|
const wrapper = mount(SsoButton, {
|
||||||
props: { ssoenabled: true },
|
|
||||||
global: {
|
global: {
|
||||||
stubs: { BrandButton: BrandButtonStub },
|
stubs: { BrandButton: BrandButtonStub },
|
||||||
},
|
},
|
||||||
@@ -105,33 +118,12 @@ describe('SsoButton.ce.vue', () => {
|
|||||||
expect(wrapper.text()).toContain('Log In With Unraid.net');
|
expect(wrapper.text()).toContain('Log In With Unraid.net');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders the button when ssoenabled prop is true (string)', () => {
|
it('does not render the button when SSO is disabled via GraphQL', () => {
|
||||||
const wrapper = mount(SsoButton, {
|
mockUseQuery.mockReturnValue({
|
||||||
props: { ssoenabled: 'true' },
|
result: { value: { isSSOEnabled: false } },
|
||||||
global: {
|
|
||||||
stubs: { BrandButton: BrandButtonStub },
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
expect(wrapper.findComponent(BrandButtonStub).exists()).toBe(true);
|
|
||||||
expect(wrapper.text()).toContain('or');
|
|
||||||
expect(wrapper.text()).toContain('Log In With Unraid.net');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('renders the button when ssoEnabled prop is true', () => {
|
|
||||||
const wrapper = mount(SsoButton, {
|
const wrapper = mount(SsoButton, {
|
||||||
props: { ssoEnabled: true },
|
|
||||||
global: {
|
|
||||||
stubs: { BrandButton: BrandButtonStub },
|
|
||||||
},
|
|
||||||
});
|
|
||||||
expect(wrapper.findComponent(BrandButtonStub).exists()).toBe(true);
|
|
||||||
expect(wrapper.text()).toContain('or');
|
|
||||||
expect(wrapper.text()).toContain('Log In With Unraid.net');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('does not render the button when ssoenabled prop is false', () => {
|
|
||||||
const wrapper = mount(SsoButton, {
|
|
||||||
props: { ssoenabled: false },
|
|
||||||
global: {
|
global: {
|
||||||
stubs: { BrandButton: BrandButtonStub },
|
stubs: { BrandButton: BrandButtonStub },
|
||||||
},
|
},
|
||||||
@@ -140,9 +132,12 @@ describe('SsoButton.ce.vue', () => {
|
|||||||
expect(wrapper.text()).not.toContain('or');
|
expect(wrapper.text()).not.toContain('or');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not render the button when ssoEnabled prop is false', () => {
|
it('does not render the button when GraphQL result is null/undefined', () => {
|
||||||
|
mockUseQuery.mockReturnValue({
|
||||||
|
result: { value: null },
|
||||||
|
});
|
||||||
|
|
||||||
const wrapper = mount(SsoButton, {
|
const wrapper = mount(SsoButton, {
|
||||||
props: { ssoEnabled: false },
|
|
||||||
global: {
|
global: {
|
||||||
stubs: { BrandButton: BrandButtonStub },
|
stubs: { BrandButton: BrandButtonStub },
|
||||||
},
|
},
|
||||||
@@ -151,7 +146,11 @@ describe('SsoButton.ce.vue', () => {
|
|||||||
expect(wrapper.text()).not.toContain('or');
|
expect(wrapper.text()).not.toContain('or');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not render the button when props are not provided', () => {
|
it('does not render the button when GraphQL result is undefined', () => {
|
||||||
|
mockUseQuery.mockReturnValue({
|
||||||
|
result: { value: undefined },
|
||||||
|
});
|
||||||
|
|
||||||
const wrapper = mount(SsoButton, {
|
const wrapper = mount(SsoButton, {
|
||||||
global: {
|
global: {
|
||||||
stubs: { BrandButton: BrandButtonStub },
|
stubs: { BrandButton: BrandButtonStub },
|
||||||
@@ -162,8 +161,11 @@ describe('SsoButton.ce.vue', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('navigates to the external SSO URL on button click', async () => {
|
it('navigates to the external SSO URL on button click', async () => {
|
||||||
|
mockUseQuery.mockReturnValue({
|
||||||
|
result: { value: { isSSOEnabled: true } },
|
||||||
|
});
|
||||||
|
|
||||||
const wrapper = mount(SsoButton, {
|
const wrapper = mount(SsoButton, {
|
||||||
props: { ssoenabled: true },
|
|
||||||
global: {
|
global: {
|
||||||
stubs: { BrandButton: BrandButtonStub },
|
stubs: { BrandButton: BrandButtonStub },
|
||||||
},
|
},
|
||||||
@@ -186,6 +188,10 @@ describe('SsoButton.ce.vue', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('handles SSO callback in onMounted hook successfully', async () => {
|
it('handles SSO callback in onMounted hook successfully', async () => {
|
||||||
|
mockUseQuery.mockReturnValue({
|
||||||
|
result: { value: { isSSOEnabled: true } },
|
||||||
|
});
|
||||||
|
|
||||||
const mockCode = 'mock_auth_code';
|
const mockCode = 'mock_auth_code';
|
||||||
const mockState = 'mock_session_state_value';
|
const mockState = 'mock_session_state_value';
|
||||||
const mockAccessToken = 'mock_access_token_123';
|
const mockAccessToken = 'mock_access_token_123';
|
||||||
@@ -199,7 +205,6 @@ describe('SsoButton.ce.vue', () => {
|
|||||||
|
|
||||||
// Mount the component so that onMounted hook is called
|
// Mount the component so that onMounted hook is called
|
||||||
mount(SsoButton, {
|
mount(SsoButton, {
|
||||||
props: { ssoenabled: true },
|
|
||||||
global: {
|
global: {
|
||||||
stubs: { BrandButton: BrandButtonStub },
|
stubs: { BrandButton: BrandButtonStub },
|
||||||
},
|
},
|
||||||
@@ -225,6 +230,10 @@ describe('SsoButton.ce.vue', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('handles SSO callback error in onMounted hook', async () => {
|
it('handles SSO callback error in onMounted hook', async () => {
|
||||||
|
mockUseQuery.mockReturnValue({
|
||||||
|
result: { value: { isSSOEnabled: true } },
|
||||||
|
});
|
||||||
|
|
||||||
const mockCode = 'mock_auth_code_error';
|
const mockCode = 'mock_auth_code_error';
|
||||||
const mockState = 'mock_session_state_error';
|
const mockState = 'mock_session_state_error';
|
||||||
|
|
||||||
@@ -235,7 +244,6 @@ describe('SsoButton.ce.vue', () => {
|
|||||||
(fetch as Mock).mockRejectedValueOnce(fetchError);
|
(fetch as Mock).mockRejectedValueOnce(fetchError);
|
||||||
const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
||||||
const wrapper = mount(SsoButton, {
|
const wrapper = mount(SsoButton, {
|
||||||
props: { ssoenabled: true },
|
|
||||||
global: {
|
global: {
|
||||||
stubs: { BrandButton: BrandButtonStub },
|
stubs: { BrandButton: BrandButtonStub },
|
||||||
},
|
},
|
||||||
@@ -261,4 +269,52 @@ describe('SsoButton.ce.vue', () => {
|
|||||||
|
|
||||||
consoleErrorSpy.mockRestore();
|
consoleErrorSpy.mockRestore();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('handles SSO callback when state does not match', async () => {
|
||||||
|
mockUseQuery.mockReturnValue({
|
||||||
|
result: { value: { isSSOEnabled: true } },
|
||||||
|
});
|
||||||
|
|
||||||
|
const mockCode = 'mock_auth_code';
|
||||||
|
const mockState = 'mock_session_state_value';
|
||||||
|
const differentState = 'different_state_value';
|
||||||
|
|
||||||
|
mockLocation.search = `?code=${mockCode}&state=${mockState}`;
|
||||||
|
(sessionStorage.getItem as Mock).mockReturnValue(differentState);
|
||||||
|
|
||||||
|
const wrapper = mount(SsoButton, {
|
||||||
|
global: {
|
||||||
|
stubs: { BrandButton: BrandButtonStub },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await flushPromises();
|
||||||
|
|
||||||
|
// Should not make any fetch calls when state doesn't match
|
||||||
|
expect(fetch).not.toHaveBeenCalled();
|
||||||
|
expect(mockForm.requestSubmit).not.toHaveBeenCalled();
|
||||||
|
expect(wrapper.findComponent(BrandButtonStub).text()).toBe('Log In With Unraid.net');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handles SSO callback when no code is present', async () => {
|
||||||
|
mockUseQuery.mockReturnValue({
|
||||||
|
result: { value: { isSSOEnabled: true } },
|
||||||
|
});
|
||||||
|
|
||||||
|
mockLocation.search = '?state=some_state';
|
||||||
|
(sessionStorage.getItem as Mock).mockReturnValue('some_state');
|
||||||
|
|
||||||
|
const wrapper = mount(SsoButton, {
|
||||||
|
global: {
|
||||||
|
stubs: { BrandButton: BrandButtonStub },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await flushPromises();
|
||||||
|
|
||||||
|
// Should not make any fetch calls when no code is present
|
||||||
|
expect(fetch).not.toHaveBeenCalled();
|
||||||
|
expect(mockForm.requestSubmit).not.toHaveBeenCalled();
|
||||||
|
expect(wrapper.findComponent(BrandButtonStub).text()).toBe('Log In With Unraid.net');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,22 +1,20 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, onMounted, ref } from 'vue';
|
import { computed, onMounted, ref } from 'vue';
|
||||||
|
import { useQuery } from '@vue/apollo-composable';
|
||||||
|
import { SSO_ENABLED } from '~/store/account.fragment';
|
||||||
|
|
||||||
import { BrandButton } from '@unraid/ui';
|
import { BrandButton } from '@unraid/ui';
|
||||||
import { ACCOUNT } from '~/helpers/urls';
|
import { ACCOUNT } from '~/helpers/urls';
|
||||||
|
|
||||||
export interface Props {
|
|
||||||
ssoenabled?: boolean | string;
|
|
||||||
ssoEnabled?: boolean;
|
|
||||||
}
|
|
||||||
const props = defineProps<Props>();
|
|
||||||
|
|
||||||
type CurrentState = 'loading' | 'idle' | 'error';
|
type CurrentState = 'loading' | 'idle' | 'error';
|
||||||
|
|
||||||
const currentState = ref<CurrentState>('idle');
|
const currentState = ref<CurrentState>('idle');
|
||||||
const error = ref<string | null>(null);
|
const error = ref<string | null>(null);
|
||||||
|
|
||||||
|
const { result } = useQuery(SSO_ENABLED);
|
||||||
|
|
||||||
const isSsoEnabled = computed<boolean>(
|
const isSsoEnabled = computed<boolean>(
|
||||||
() => props['ssoenabled'] === true || props['ssoenabled'] === 'true' || props.ssoEnabled
|
() => result.value?.isSSOEnabled ?? false
|
||||||
);
|
);
|
||||||
|
|
||||||
const getInputFields = (): {
|
const getInputFields = (): {
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ type Documents = {
|
|||||||
"\n query ListRCloneRemotes {\n rclone {\n remotes {\n name\n type\n parameters\n config\n }\n }\n }\n": typeof types.ListRCloneRemotesDocument,
|
"\n query ListRCloneRemotes {\n rclone {\n remotes {\n name\n type\n parameters\n config\n }\n }\n }\n": typeof types.ListRCloneRemotesDocument,
|
||||||
"\n mutation ConnectSignIn($input: ConnectSignInInput!) {\n connectSignIn(input: $input)\n }\n": typeof types.ConnectSignInDocument,
|
"\n mutation ConnectSignIn($input: ConnectSignInInput!) {\n connectSignIn(input: $input)\n }\n": typeof types.ConnectSignInDocument,
|
||||||
"\n mutation SignOut {\n connectSignOut\n }\n": typeof types.SignOutDocument,
|
"\n mutation SignOut {\n connectSignOut\n }\n": typeof types.SignOutDocument,
|
||||||
|
"\n query IsSSOEnabled {\n isSSOEnabled\n }\n": typeof types.IsSsoEnabledDocument,
|
||||||
"\n fragment PartialCloud on Cloud {\n error\n apiKey {\n valid\n error\n }\n cloud {\n status\n error\n }\n minigraphql {\n status\n error\n }\n relay {\n status\n error\n }\n }\n": typeof types.PartialCloudFragmentDoc,
|
"\n fragment PartialCloud on Cloud {\n error\n apiKey {\n valid\n error\n }\n cloud {\n status\n error\n }\n minigraphql {\n status\n error\n }\n relay {\n status\n error\n }\n }\n": typeof types.PartialCloudFragmentDoc,
|
||||||
"\n query cloudState {\n cloud {\n ...PartialCloud\n }\n }\n": typeof types.CloudStateDocument,
|
"\n query cloudState {\n cloud {\n ...PartialCloud\n }\n }\n": typeof types.CloudStateDocument,
|
||||||
"\n query serverState {\n config {\n error\n valid\n }\n info {\n os {\n hostname\n }\n }\n owner {\n avatar\n username\n }\n registration {\n state\n expiration\n keyFile {\n contents\n }\n updateExpiration\n }\n vars {\n regGen\n regState\n configError\n configValid\n }\n }\n": typeof types.ServerStateDocument,
|
"\n query serverState {\n config {\n error\n valid\n }\n info {\n os {\n hostname\n }\n }\n owner {\n avatar\n username\n }\n registration {\n state\n expiration\n keyFile {\n contents\n }\n updateExpiration\n }\n vars {\n regGen\n regState\n configError\n configValid\n }\n }\n": typeof types.ServerStateDocument,
|
||||||
@@ -82,6 +83,7 @@ const documents: Documents = {
|
|||||||
"\n query ListRCloneRemotes {\n rclone {\n remotes {\n name\n type\n parameters\n config\n }\n }\n }\n": types.ListRCloneRemotesDocument,
|
"\n query ListRCloneRemotes {\n rclone {\n remotes {\n name\n type\n parameters\n config\n }\n }\n }\n": types.ListRCloneRemotesDocument,
|
||||||
"\n mutation ConnectSignIn($input: ConnectSignInInput!) {\n connectSignIn(input: $input)\n }\n": types.ConnectSignInDocument,
|
"\n mutation ConnectSignIn($input: ConnectSignInInput!) {\n connectSignIn(input: $input)\n }\n": types.ConnectSignInDocument,
|
||||||
"\n mutation SignOut {\n connectSignOut\n }\n": types.SignOutDocument,
|
"\n mutation SignOut {\n connectSignOut\n }\n": types.SignOutDocument,
|
||||||
|
"\n query IsSSOEnabled {\n isSSOEnabled\n }\n": types.IsSsoEnabledDocument,
|
||||||
"\n fragment PartialCloud on Cloud {\n error\n apiKey {\n valid\n error\n }\n cloud {\n status\n error\n }\n minigraphql {\n status\n error\n }\n relay {\n status\n error\n }\n }\n": types.PartialCloudFragmentDoc,
|
"\n fragment PartialCloud on Cloud {\n error\n apiKey {\n valid\n error\n }\n cloud {\n status\n error\n }\n minigraphql {\n status\n error\n }\n relay {\n status\n error\n }\n }\n": types.PartialCloudFragmentDoc,
|
||||||
"\n query cloudState {\n cloud {\n ...PartialCloud\n }\n }\n": types.CloudStateDocument,
|
"\n query cloudState {\n cloud {\n ...PartialCloud\n }\n }\n": types.CloudStateDocument,
|
||||||
"\n query serverState {\n config {\n error\n valid\n }\n info {\n os {\n hostname\n }\n }\n owner {\n avatar\n username\n }\n registration {\n state\n expiration\n keyFile {\n contents\n }\n updateExpiration\n }\n vars {\n regGen\n regState\n configError\n configValid\n }\n }\n": types.ServerStateDocument,
|
"\n query serverState {\n config {\n error\n valid\n }\n info {\n os {\n hostname\n }\n }\n owner {\n avatar\n username\n }\n registration {\n state\n expiration\n keyFile {\n contents\n }\n updateExpiration\n }\n vars {\n regGen\n regState\n configError\n configValid\n }\n }\n": types.ServerStateDocument,
|
||||||
@@ -226,6 +228,10 @@ export function graphql(source: "\n mutation ConnectSignIn($input: ConnectSignI
|
|||||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||||
*/
|
*/
|
||||||
export function graphql(source: "\n mutation SignOut {\n connectSignOut\n }\n"): (typeof documents)["\n mutation SignOut {\n connectSignOut\n }\n"];
|
export function graphql(source: "\n mutation SignOut {\n connectSignOut\n }\n"): (typeof documents)["\n mutation SignOut {\n connectSignOut\n }\n"];
|
||||||
|
/**
|
||||||
|
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||||
|
*/
|
||||||
|
export function graphql(source: "\n query IsSSOEnabled {\n isSSOEnabled\n }\n"): (typeof documents)["\n query IsSSOEnabled {\n isSSOEnabled\n }\n"];
|
||||||
/**
|
/**
|
||||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1264,6 +1264,7 @@ export type Query = {
|
|||||||
docker: Docker;
|
docker: Docker;
|
||||||
flash: Flash;
|
flash: Flash;
|
||||||
info: Info;
|
info: Info;
|
||||||
|
isSSOEnabled: Scalars['Boolean']['output'];
|
||||||
logFile: LogFileContent;
|
logFile: LogFileContent;
|
||||||
logFiles: Array<LogFile>;
|
logFiles: Array<LogFile>;
|
||||||
me: UserAccount;
|
me: UserAccount;
|
||||||
@@ -2199,6 +2200,11 @@ export type SignOutMutationVariables = Exact<{ [key: string]: never; }>;
|
|||||||
|
|
||||||
export type SignOutMutation = { __typename?: 'Mutation', connectSignOut: boolean };
|
export type SignOutMutation = { __typename?: 'Mutation', connectSignOut: boolean };
|
||||||
|
|
||||||
|
export type IsSsoEnabledQueryVariables = Exact<{ [key: string]: never; }>;
|
||||||
|
|
||||||
|
|
||||||
|
export type IsSsoEnabledQuery = { __typename?: 'Query', isSSOEnabled: boolean };
|
||||||
|
|
||||||
export type PartialCloudFragment = { __typename?: 'Cloud', error?: string | null, apiKey: { __typename?: 'ApiKeyResponse', valid: boolean, error?: string | null }, cloud: { __typename?: 'CloudResponse', status: string, error?: string | null }, minigraphql: { __typename?: 'MinigraphqlResponse', status: MinigraphStatus, error?: string | null }, relay?: { __typename?: 'RelayResponse', status: string, error?: string | null } | null } & { ' $fragmentName'?: 'PartialCloudFragment' };
|
export type PartialCloudFragment = { __typename?: 'Cloud', error?: string | null, apiKey: { __typename?: 'ApiKeyResponse', valid: boolean, error?: string | null }, cloud: { __typename?: 'CloudResponse', status: string, error?: string | null }, minigraphql: { __typename?: 'MinigraphqlResponse', status: MinigraphStatus, error?: string | null }, relay?: { __typename?: 'RelayResponse', status: string, error?: string | null } | null } & { ' $fragmentName'?: 'PartialCloudFragment' };
|
||||||
|
|
||||||
export type CloudStateQueryVariables = Exact<{ [key: string]: never; }>;
|
export type CloudStateQueryVariables = Exact<{ [key: string]: never; }>;
|
||||||
@@ -2251,6 +2257,7 @@ export const GetRCloneConfigFormDocument = {"kind":"Document","definitions":[{"k
|
|||||||
export const ListRCloneRemotesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ListRCloneRemotes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"rclone"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"remotes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"parameters"}},{"kind":"Field","name":{"kind":"Name","value":"config"}}]}}]}}]}}]} as unknown as DocumentNode<ListRCloneRemotesQuery, ListRCloneRemotesQueryVariables>;
|
export const ListRCloneRemotesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ListRCloneRemotes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"rclone"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"remotes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"parameters"}},{"kind":"Field","name":{"kind":"Name","value":"config"}}]}}]}}]}}]} as unknown as DocumentNode<ListRCloneRemotesQuery, ListRCloneRemotesQueryVariables>;
|
||||||
export const ConnectSignInDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"ConnectSignIn"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ConnectSignInInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"connectSignIn"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}]}]}}]} as unknown as DocumentNode<ConnectSignInMutation, ConnectSignInMutationVariables>;
|
export const ConnectSignInDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"ConnectSignIn"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ConnectSignInInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"connectSignIn"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}]}]}}]} as unknown as DocumentNode<ConnectSignInMutation, ConnectSignInMutationVariables>;
|
||||||
export const SignOutDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"SignOut"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"connectSignOut"}}]}}]} as unknown as DocumentNode<SignOutMutation, SignOutMutationVariables>;
|
export const SignOutDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"SignOut"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"connectSignOut"}}]}}]} as unknown as DocumentNode<SignOutMutation, SignOutMutationVariables>;
|
||||||
|
export const IsSsoEnabledDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"IsSSOEnabled"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"isSSOEnabled"}}]}}]} as unknown as DocumentNode<IsSsoEnabledQuery, IsSsoEnabledQueryVariables>;
|
||||||
export const CloudStateDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"cloudState"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"cloud"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"PartialCloud"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"PartialCloud"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Cloud"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"error"}},{"kind":"Field","name":{"kind":"Name","value":"apiKey"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"valid"}},{"kind":"Field","name":{"kind":"Name","value":"error"}}]}},{"kind":"Field","name":{"kind":"Name","value":"cloud"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"error"}}]}},{"kind":"Field","name":{"kind":"Name","value":"minigraphql"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"error"}}]}},{"kind":"Field","name":{"kind":"Name","value":"relay"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"error"}}]}}]}}]} as unknown as DocumentNode<CloudStateQuery, CloudStateQueryVariables>;
|
export const CloudStateDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"cloudState"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"cloud"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"PartialCloud"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"PartialCloud"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Cloud"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"error"}},{"kind":"Field","name":{"kind":"Name","value":"apiKey"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"valid"}},{"kind":"Field","name":{"kind":"Name","value":"error"}}]}},{"kind":"Field","name":{"kind":"Name","value":"cloud"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"error"}}]}},{"kind":"Field","name":{"kind":"Name","value":"minigraphql"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"error"}}]}},{"kind":"Field","name":{"kind":"Name","value":"relay"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"error"}}]}}]}}]} as unknown as DocumentNode<CloudStateQuery, CloudStateQueryVariables>;
|
||||||
export const ServerStateDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"serverState"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"config"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"error"}},{"kind":"Field","name":{"kind":"Name","value":"valid"}}]}},{"kind":"Field","name":{"kind":"Name","value":"info"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"os"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"hostname"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"owner"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"avatar"}},{"kind":"Field","name":{"kind":"Name","value":"username"}}]}},{"kind":"Field","name":{"kind":"Name","value":"registration"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"state"}},{"kind":"Field","name":{"kind":"Name","value":"expiration"}},{"kind":"Field","name":{"kind":"Name","value":"keyFile"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"contents"}}]}},{"kind":"Field","name":{"kind":"Name","value":"updateExpiration"}}]}},{"kind":"Field","name":{"kind":"Name","value":"vars"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"regGen"}},{"kind":"Field","name":{"kind":"Name","value":"regState"}},{"kind":"Field","name":{"kind":"Name","value":"configError"}},{"kind":"Field","name":{"kind":"Name","value":"configValid"}}]}}]}}]} as unknown as DocumentNode<ServerStateQuery, ServerStateQueryVariables>;
|
export const ServerStateDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"serverState"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"config"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"error"}},{"kind":"Field","name":{"kind":"Name","value":"valid"}}]}},{"kind":"Field","name":{"kind":"Name","value":"info"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"os"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"hostname"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"owner"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"avatar"}},{"kind":"Field","name":{"kind":"Name","value":"username"}}]}},{"kind":"Field","name":{"kind":"Name","value":"registration"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"state"}},{"kind":"Field","name":{"kind":"Name","value":"expiration"}},{"kind":"Field","name":{"kind":"Name","value":"keyFile"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"contents"}}]}},{"kind":"Field","name":{"kind":"Name","value":"updateExpiration"}}]}},{"kind":"Field","name":{"kind":"Name","value":"vars"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"regGen"}},{"kind":"Field","name":{"kind":"Name","value":"regState"}},{"kind":"Field","name":{"kind":"Name","value":"configError"}},{"kind":"Field","name":{"kind":"Name","value":"configValid"}}]}}]}}]} as unknown as DocumentNode<ServerStateQuery, ServerStateQueryVariables>;
|
||||||
export const GetThemeDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"getTheme"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"publicTheme"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"showBannerImage"}},{"kind":"Field","name":{"kind":"Name","value":"showBannerGradient"}},{"kind":"Field","name":{"kind":"Name","value":"headerBackgroundColor"}},{"kind":"Field","name":{"kind":"Name","value":"showHeaderDescription"}},{"kind":"Field","name":{"kind":"Name","value":"headerPrimaryTextColor"}},{"kind":"Field","name":{"kind":"Name","value":"headerSecondaryTextColor"}}]}}]}}]} as unknown as DocumentNode<GetThemeQuery, GetThemeQueryVariables>;
|
export const GetThemeDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"getTheme"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"publicTheme"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"showBannerImage"}},{"kind":"Field","name":{"kind":"Name","value":"showBannerGradient"}},{"kind":"Field","name":{"kind":"Name","value":"headerBackgroundColor"}},{"kind":"Field","name":{"kind":"Name","value":"showHeaderDescription"}},{"kind":"Field","name":{"kind":"Name","value":"headerPrimaryTextColor"}},{"kind":"Field","name":{"kind":"Name","value":"headerSecondaryTextColor"}}]}}]}}]} as unknown as DocumentNode<GetThemeQuery, GetThemeQueryVariables>;
|
||||||
@@ -187,7 +187,7 @@ watch(
|
|||||||
<div class="bg-background">
|
<div class="bg-background">
|
||||||
<hr class="border-black dark:border-white" />
|
<hr class="border-black dark:border-white" />
|
||||||
<h2 class="text-xl font-semibold font-mono">SSO Button Component</h2>
|
<h2 class="text-xl font-semibold font-mono">SSO Button Component</h2>
|
||||||
<SsoButtonCe :ssoenabled="serverState.ssoEnabled" />
|
<SsoButtonCe />
|
||||||
</div>
|
</div>
|
||||||
<div class="bg-background">
|
<div class="bg-background">
|
||||||
<hr class="border-black dark:border-white" />
|
<hr class="border-black dark:border-white" />
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ onBeforeMount(() => {
|
|||||||
<!-- uncomment to test modals <unraid-modals />-->
|
<!-- uncomment to test modals <unraid-modals />-->
|
||||||
<hr class="border-black dark:border-white" />
|
<hr class="border-black dark:border-white" />
|
||||||
<h3 class="text-lg font-semibold font-mono">SSOSignInButtonCe</h3>
|
<h3 class="text-lg font-semibold font-mono">SSOSignInButtonCe</h3>
|
||||||
<unraid-sso-button :ssoenabled="serverState.ssoEnabled" />
|
<unraid-sso-button />
|
||||||
<hr class="border-black dark:border-white" />
|
<hr class="border-black dark:border-white" />
|
||||||
<h3 class="text-lg font-semibold font-mono">ApiKeyManagerCe</h3>
|
<h3 class="text-lg font-semibold font-mono">ApiKeyManagerCe</h3>
|
||||||
<unraid-api-key-manager />
|
<unraid-api-key-manager />
|
||||||
|
|||||||
@@ -11,3 +11,9 @@ export const CONNECT_SIGN_OUT = graphql(/* GraphQL */`
|
|||||||
connectSignOut
|
connectSignOut
|
||||||
}
|
}
|
||||||
`);
|
`);
|
||||||
|
|
||||||
|
export const SSO_ENABLED = graphql(/* GraphQL */`
|
||||||
|
query IsSSOEnabled {
|
||||||
|
isSSOEnabled
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
|||||||
Reference in New Issue
Block a user