diff --git a/src/assets/styles/pages/_config.scss b/src/assets/styles/pages/_config.scss index cbd564839..ae7aecaa1 100644 --- a/src/assets/styles/pages/_config.scss +++ b/src/assets/styles/pages/_config.scss @@ -1,14 +1,5 @@ -#local-studio { - #config { - .instance-details { - min-height: auto !important; - } - } -} - #config { .instance-details { - min-height: 152px; .card-body { padding-bottom: 0; diff --git a/src/components/instance/status/SystemInfo.js b/src/components/instance/status/SystemInfo.js index d683f0858..98286dfae 100644 --- a/src/components/instance/status/SystemInfo.js +++ b/src/components/instance/status/SystemInfo.js @@ -62,27 +62,27 @@ function SystemInfo() { ) : ( - +
{systemInfo?.totalMemory || '...'}GB
- +
{systemInfo?.usedMemory || '...'}GB
- +
{systemInfo?.freeMemory || '...'}GB
- +
{systemInfo?.cpuCores || '...'}
- +
{systemInfo?.cpuLoad || '...'}%
diff --git a/src/components/instances/list/CardBackLogin.js b/src/components/instances/list/CardBackLogin.js index 1e828776f..a998d9bf8 100644 --- a/src/components/instances/list/CardBackLogin.js +++ b/src/components/instances/list/CardBackLogin.js @@ -5,6 +5,7 @@ import { ErrorBoundary } from 'react-error-boundary'; import useInstanceAuth from '../../../functions/state/instanceAuths'; import handleCloudInstanceUsernameChange from '../../../functions/instances/handleCloudInstanceUsernameChange'; +import login from '../../../functions/api/instance/login'; import userInfo from '../../../functions/api/instance/userInfo'; import ErrorFallback from '../../shared/ErrorFallback'; import addError from '../../../functions/api/lms/addError'; @@ -22,7 +23,21 @@ function CardBackLogin({ compute_stack_id, url, is_ssl, setFlipState, flipState, if (!user || !pass) { setFormState({ error: 'All fields are required' }); } else { - const result = await userInfo({ auth: { user, pass }, url }); + let login_not_supported; + let result; + if (pass) { + // try to log in with the provided credentials + const login_result = await login({ auth: { user, pass }, url }); + if (login_result.error) { + login_not_supported = true; + } else { + result = await userInfo({ url }); + if (result.error) + login_not_supported = true; + } + if (login_not_supported) result = await userInfo({ auth: { user, pass }, url }); + } else + result = await userInfo({ url }); if (is_ssl && is_local && result.error && result.type === 'catch') { setFormState({ error: 'SSL ERROR. ACCEPT SELF-SIGNED CERT?', url }); @@ -46,7 +61,7 @@ function CardBackLogin({ compute_stack_id, url, is_ssl, setFlipState, flipState, } else { setInstanceAuths({ ...instanceAuths, - [compute_stack_id]: { user: formData.user, pass: formData.pass, super: result.role.permission.super_user, structure: result.role.permission.structure_user }, + [compute_stack_id]: { user: formData.user, pass: login_not_supported ? formData.pass : '', super: result.role.permission.super_user, structure: result.role.permission.structure_user }, }); setTimeout(() => setFlipState(false), 100); } diff --git a/src/functions/api/instance/login.js b/src/functions/api/instance/login.js new file mode 100644 index 000000000..2337915b6 --- /dev/null +++ b/src/functions/api/instance/login.js @@ -0,0 +1,9 @@ +import queryInstance from '../queryInstance'; + +export default async ({ auth, url }) => + queryInstance({ + operation: { operation: 'login', username: auth.user, password: auth.pass }, + auth, + url, + timeout: 5000, + }); diff --git a/src/functions/api/queryInstance.js b/src/functions/api/queryInstance.js index fdd294305..932df0250 100644 --- a/src/functions/api/queryInstance.js +++ b/src/functions/api/queryInstance.js @@ -5,14 +5,19 @@ export default async ({ operation, auth, url, timeout = 0, authType = undefined, const controller = new AbortController(); const id = setTimeout(() => (timeout ? controller.abort() : null), timeout); + const headers = { + 'Content-Type': 'application/json' + }; + if (authType === 'token') + headers.Authorization = `Bearer ${auth.token}`; + else if (auth?.pass) + headers.Authorization = `Basic ${btoa(`${auth.user}:${auth.pass}`)}`; const request = await fetch(url, { signal: signal || controller.signal, method: 'POST', body: JSON.stringify(operation), - headers: { - 'Content-Type': 'application/json', - authorization: authType === 'token' ? `Bearer ${auth.token}` : `Basic ${btoa(`${auth.user}:${auth.pass}`)}`, - }, + headers, + credentials: 'include', }); clearTimeout(id); @@ -24,6 +29,7 @@ export default async ({ operation, auth, url, timeout = 0, authType = undefined, error: true, message: response.error, type: 'response', + status: request.status, role_errors: response.main_permissions?.join(', '), access_errors: response.unauthorized_access?.map((e) => ({ schema: e.schema, diff --git a/src/functions/instances/handleInstanceRegistration.js b/src/functions/instances/handleInstanceRegistration.js index ddc55a036..b658fef02 100644 --- a/src/functions/instances/handleInstanceRegistration.js +++ b/src/functions/instances/handleInstanceRegistration.js @@ -27,7 +27,7 @@ export default async ({ instanceAuth, url, is_local, is_ssl, cloud_provider, ins } } - if ((registration.error && registration.message === 'Login failed') || registration.error === 'Login failed') { + if ((registration.status === 401) || registration.error === 'Login failed') { return { status: 'LOGIN FAILED', error: true,