Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add passwordless sudo user management UI #2005

Merged
merged 2 commits into from
Nov 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion react/src/components/UserInfoModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,28 @@

interface Props extends BAIModalProps {}

const UserInfoModal: React.FC<Props> = ({ ...baiModalProps }) => {
const { t } = useTranslation();

const { value, dispatchEvent } = useWebComponentInfo();
let parsedValue: {
open: boolean;
userEmail: string;
};
try {
parsedValue = JSON.parse(value || '');
} catch (error) {
parsedValue = {
open: false,
userEmail: '',
};
}
const { open, userEmail } = parsedValue;

const baiClient = useSuspendedBackendaiClient();
const sudoSessionEnabledSupported = baiClient?.supports(
'sudo-session-enabled',
);

Check warning on line 36 in react/src/components/UserInfoModal.tsx

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement
let totpSupported = false;
let {
data: isManagerSupportingTOTP,
Expand All @@ -47,31 +50,41 @@
);
totpSupported = baiClient?.supports('2FA') && isManagerSupportingTOTP;

const { user } = useLazyLoadQuery<UserInfoModalQuery>(
graphql`
query UserInfoModalQuery($email: String, $isTOTPSupported: Boolean!) {
query UserInfoModalQuery(
$email: String
$isNotSupportSudoSessionEnabled: Boolean!
$isTOTPSupported: Boolean!
) {
user(email: $email) {
email
username
need_password_change
full_name
description
status
domain_name
role
groups {
id
name
}
# TODO: reflect https://github.com/lablup/backend.ai-webui/pull/1999
# support from 23.09.0b1
# https://github.com/lablup/backend.ai/pull/1530
sudo_session_enabled
@skipOnClient(if: $isNotSupportSudoSessionEnabled)
totp_activated @include(if: $isTOTPSupported)
}
}
`,
{
email: userEmail,
isNotSupportSudoSessionEnabled: !sudoSessionEnabledSupported,
isTOTPSupported: totpSupported ?? false,
},
);

Check warning on line 87 in react/src/components/UserInfoModal.tsx

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement

const columnSetting: DescriptionsProps['column'] = {
xxl: 1,
Expand All @@ -82,49 +95,54 @@
xs: 1,
};

return (
<BAIModal
open={open}
onCancel={() => {
dispatchEvent('cancel', null);
}}
centered
title={t('credential.UserDetail')}
footer={[
<Button
key="ok"
type="primary"
onClick={() => {
dispatchEvent('cancel', null);
}}
>
{t('button.OK')}
</Button>,
]}
{...baiModalProps}
>
<br />
<Descriptions
size="small"
column={columnSetting}
title={t('credential.Information')}
labelStyle={{ width: '50%' }}
>
<Descriptions.Item label={t('credential.UserID')}>
{user?.email}
</Descriptions.Item>
<Descriptions.Item label={t('credential.UserName')}>
{user?.username}
</Descriptions.Item>
<Descriptions.Item label={t('credential.FullName')}>
{user?.full_name}
</Descriptions.Item>
<Descriptions.Item label={t('credential.DescActiveUser')}>
{user?.status === 'active' ? t('button.Yes') : t('button.No')}
</Descriptions.Item>
<Descriptions.Item label={t('credential.DescRequirePasswordChange')}>
{user?.need_password_change ? t('button.Yes') : t('button.No')}
</Descriptions.Item>
{sudoSessionEnabledSupported && (

Check warning on line 141 in react/src/components/UserInfoModal.tsx

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🌿 Branch is not covered

Warning! Not covered branch
<Descriptions.Item label={t('credential.EnableSudoSession')}>
{user?.sudo_session_enabled ? t('button.Yes') : t('button.No')}

Check warning on line 143 in react/src/components/UserInfoModal.tsx

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🌿 Branch is not covered

Warning! Not covered branch

Check warning on line 143 in react/src/components/UserInfoModal.tsx

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🌿 Branch is not covered

Warning! Not covered branch
</Descriptions.Item>

Check warning on line 144 in react/src/components/UserInfoModal.tsx

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🌿 Branch is not covered

Warning! Not covered branch
)}
{totpSupported && (
<Descriptions.Item label={t('webui.menu.TotpActivated')}>
<Spin spinning={isLoadingManagerSupportingTOTP}>
Expand Down
30 changes: 30 additions & 0 deletions react/src/components/UserSettingModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,46 +33,49 @@
extraFetchKey?: string;
}

const UserSettingModal: React.FC<Props> = ({
extraFetchKey = '',
...baiModalProps
}) => {
const { t } = useTranslation();
const { value, dispatchEvent } = useWebComponentInfo();
let parsedValue: {
open: boolean;
userEmail: string;
};
try {
parsedValue = JSON.parse(value || '');
} catch (error) {
parsedValue = {
open: false,
userEmail: '',
};
}
const { open, userEmail } = parsedValue;

const [modal, contextHolder] = Modal.useModal();

const [form] = Form.useForm<User>();

const userStatus: UserStatus = {
active: 'Active',
inactive: 'Inactive',
'before-verification': 'Before Verification',
deleted: 'Deleted',
};

const permissionRangeOfRoleChanges: UserRole = {
superadmin: ['superadmin', 'admin', 'user', 'monitor'],
admin: ['admin', 'user', 'monitor'],
};

const [fetchKey, updateFetchKey] = useUpdatableState('initial-fetch');
const deferredMergedFetchKey = useDeferredValue(fetchKey + extraFetchKey);

const baiClient = useSuspendedBackendaiClient();
const sudoSessionEnabledSupported = baiClient?.supports(
'sudo-session-enabled',
);

Check warning on line 78 in react/src/components/UserSettingModal.tsx

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement
let totpSupported = false;
let {
data: isManagerSupportingTOTP,
Expand All @@ -89,75 +92,88 @@
);
totpSupported = baiClient?.supports('2FA') && isManagerSupportingTOTP;

const { user, loggedInUser } = useLazyLoadQuery<UserSettingModalQuery>(
graphql`
query UserSettingModalQuery(
$email: String
$isNotSupportSudoSessionEnabled: Boolean!
$isNotSupportTotp: Boolean!
$loggedInUserEmail: String
) {
user(email: $email) {
email
username
need_password_change
full_name
description
status
domain_name
role
groups {
id
name
}
# TODO: reflect https://github.com/lablup/backend.ai-webui/pull/1999
# support from 23.09.0b1
# https://github.com/lablup/backend.ai/pull/1530
sudo_session_enabled
@skipOnClient(if: $isNotSupportSudoSessionEnabled)
totp_activated @skipOnClient(if: $isNotSupportTotp)
...TOTPActivateModalFragment
}
loggedInUser: user(email: $loggedInUserEmail) {
role
}
}
`,
{
email: userEmail,
isNotSupportSudoSessionEnabled: !sudoSessionEnabledSupported,
isNotSupportTotp: !totpSupported,
loggedInUserEmail: baiClient?.email ?? '',
},
{
fetchKey: deferredMergedFetchKey,
fetchPolicy: 'network-only',
},
);

Check warning on line 139 in react/src/components/UserSettingModal.tsx

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement

const [commitModifyUserSetting, isInFlightCommitModifyUserSetting] =
useMutation<UserSettingModalMutation>(graphql`
mutation UserSettingModalMutation(
$email: String!
$props: ModifyUserInput!
$isNotSupportSudoSessionEnabled: Boolean!
$isNotSupportTotp: Boolean!
) {
modify_user(email: $email, props: $props) {
ok
msg
user {
id
email
username
need_password_change
full_name
description
status
domain_name
role
groups {
id
name
}
# TODO: reflect https://github.com/lablup/backend.ai-webui/pull/1999
# support from 23.09.0b1
# https://github.com/lablup/backend.ai/pull/1530
sudo_session_enabled
@skipOnClient(if: $isNotSupportSudoSessionEnabled)
totp_activated @skipOnClient(if: $isNotSupportTotp)
...TOTPActivateModalFragment
}
}
}
`);

Check warning on line 176 in react/src/components/UserSettingModal.tsx

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement

const mutationToRemoveTotp = useTanMutation({
mutationFn: (email: string) => {
Expand All @@ -168,51 +184,56 @@
const [isOpenTOTPActivateModal, { toggle: toggleTOTPActivateModal }] =
useToggle(false);

const _onOk = () => {
form.validateFields().then(async (values) => {
let input = { ...values };
delete input.email;
input = _.omit(input, ['password_confirm']);
input = _.omitBy(input, (item) => item === undefined || item === '');
if (!sudoSessionEnabledSupported) {
delete input?.sudo_session_enabled;

Check warning on line 194 in react/src/components/UserSettingModal.tsx

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement
}

Check warning on line 195 in react/src/components/UserSettingModal.tsx

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement

Check warning on line 195 in react/src/components/UserSettingModal.tsx

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🌿 Branch is not covered

Warning! Not covered branch
// TOTP setting
if (!totpSupported) {
delete input?.totp_activated;
}

commitModifyUserSetting({
variables: {
email: values?.email || '',
props: input,
isNotSupportSudoSessionEnabled: !sudoSessionEnabledSupported,
isNotSupportTotp: !totpSupported,
},
onCompleted(res) {
if (res?.modify_user?.ok) {
message.success(t('environment.SuccessfullyModified'));
} else {
message.error(res?.modify_user?.msg);
}
dispatchEvent('ok', null);
},
onError(err) {
message.error(err?.message);
},
});

Check warning on line 219 in react/src/components/UserSettingModal.tsx

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement
});

Check warning on line 220 in react/src/components/UserSettingModal.tsx

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement
};

Check warning on line 221 in react/src/components/UserSettingModal.tsx

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement

return (
<BAIModal
open={open}
onCancel={() => {
dispatchEvent('cancel', null);
}}
centered
title={t('credential.ModifyUserDetail')}
destroyOnClose={true}
onOk={_onOk}
confirmLoading={isInFlightCommitModifyUserSetting}
{...baiModalProps}
>
<div>{sudoSessionEnabledSupported ? 'true' : 'false'}</div>

Check warning on line 236 in react/src/components/UserSettingModal.tsx

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🌿 Branch is not covered

Warning! Not covered branch

Check warning on line 236 in react/src/components/UserSettingModal.tsx

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🌿 Branch is not covered

Warning! Not covered branch
<Form
preserve={false}
form={form}
Expand Down Expand Up @@ -304,6 +325,15 @@
>
<Switch />
</Form.Item>
{!!sudoSessionEnabledSupported && (

Check warning on line 328 in react/src/components/UserSettingModal.tsx

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🌿 Branch is not covered

Warning! Not covered branch
<Form.Item
name="sudo_session_enabled"
label={t('credential.EnableSudoSession')}
valuePropName="checked"
>
<Switch />
</Form.Item>

Check warning on line 335 in react/src/components/UserSettingModal.tsx

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🌿 Branch is not covered

Warning! Not covered branch
)}
{!!totpSupported && (
<Form.Item
name="totp_activated"
Expand Down
3 changes: 2 additions & 1 deletion resources/i18n/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,8 @@
"KeypairDetail": "Schlüsselpaar Detail",
"SignoutSeccessfullyFinished": "Die Abmeldung ist erfolgreich abgeschlossen",
"Status": "Status",
"NoUserToDisplay": "Keine Benutzer zum Anzeigen"
"NoUserToDisplay": "Keine Benutzer zum Anzeigen",
"EnableSudoSession": "__NOT_TRANSLATED__"
},
"data": {
"Folders": "Ordner",
Expand Down
3 changes: 2 additions & 1 deletion resources/i18n/el.json
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,8 @@
"KeypairDetail": "Λεπτομέρεια ζεύγους κλειδιών",
"SignoutSeccessfullyFinished": "Η αποσύνδεση ολοκληρώθηκε επιτυχώς",
"Status": "Κατάσταση",
"NoUserToDisplay": "Δεν υπάρχουν χρήστες για εμφάνιση"
"NoUserToDisplay": "Δεν υπάρχουν χρήστες για εμφάνιση",
"EnableSudoSession": "__NOT_TRANSLATED__"
},
"data": {
"Folders": "Φάκελοι",
Expand Down
3 changes: 2 additions & 1 deletion resources/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -597,7 +597,8 @@
"KeypairDetail": "Keypair Detail",
"AdminCanOnlyRemoveTotp": "Only disabling 2FA of other users is possible.",
"KeySeccessfullyDeleted": "KeyPair is seccessfully deleted.",
"SignoutSeccessfullyFinished": "Signout is seccessfully finished"
"SignoutSeccessfullyFinished": "Signout is seccessfully finished",
"EnableSudoSession": "Enable sudo session"
},
"data": {
"Folders": "Folders",
Expand Down
3 changes: 2 additions & 1 deletion resources/i18n/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,8 @@
"PleaseSelectOptions": "Por favor, seleccione al menos una opción o más.",
"PolicyName": "Nombre de la póliza Obligatorio.",
"ValidationFailed": "Validación fallida"
}
},
"EnableSudoSession": "__NOT_TRANSLATED__"
},
"data": {
"Allowslettersnumbersand-_": "Permite letras, números y -_",
Expand Down
3 changes: 2 additions & 1 deletion resources/i18n/fi.json
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,8 @@
"PleaseSelectOptions": "Valitse vähintään yksi tai useampi vaihtoehto.",
"PolicyName": "Vakuutuksen nimi Pakollinen.",
"ValidationFailed": "Validointi epäonnistui"
}
},
"EnableSudoSession": "__NOT_TRANSLATED__"
},
"data": {
"Allowslettersnumbersand-_": "Sallii kirjaimet, numerot ja -_",
Expand Down
3 changes: 2 additions & 1 deletion resources/i18n/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,8 @@
"AdminCanOnlyRemoveTotp": "Seule la désactivation du 2FA des autres utilisateurs est possible.",
"KeySeccessfullyDeleted": "La paire de clés est supprimée successivement.",
"SignoutSeccessfullyFinished": "La signature est terminée en toute sécurité",
"ModifyUserDetail": "Modifier les détails de l'utilisateur"
"ModifyUserDetail": "Modifier les détails de l'utilisateur",
"EnableSudoSession": "__NOT_TRANSLATED__"
},
"data": {
"Folders": "Dossiers",
Expand Down
3 changes: 2 additions & 1 deletion resources/i18n/id.json
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,8 @@
"AdminCanOnlyRemoveTotp": "Hanya menonaktifkan 2FA pengguna lain yang dapat dilakukan.",
"KeySeccessfullyDeleted": "KeyPair dihapus dengan aman.",
"SignoutSeccessfullyFinished": "Keluar dengan aman selesai",
"ModifyUserDetail": "Ubah Detail Pengguna"
"ModifyUserDetail": "Ubah Detail Pengguna",
"EnableSudoSession": "__NOT_TRANSLATED__"
},
"data": {
"Folders": "Folder",
Expand Down
3 changes: 2 additions & 1 deletion resources/i18n/it.json
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,8 @@
"KeypairDetail": "Dettaglio coppia di chiavi",
"SignoutSeccessfullyFinished": "Il signout è terminato in modo sicuro",
"Status": "Stato",
"NoUserToDisplay": "Nessun utente da visualizzare"
"NoUserToDisplay": "Nessun utente da visualizzare",
"EnableSudoSession": "__NOT_TRANSLATED__"
},
"data": {
"Folders": "cartelle",
Expand Down
3 changes: 2 additions & 1 deletion resources/i18n/ja.json
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,8 @@
"KeypairDetail": "キーフェア情報",
"SignoutSeccessfullyFinished": "ユーザーアカウントが正常に削除されました。",
"Status": "状態",
"NoUserToDisplay": "ユーザー情報がありません。"
"NoUserToDisplay": "ユーザー情報がありません。",
"EnableSudoSession": "__NOT_TRANSLATED__"
},
"data": {
"Folders": "フォルダー",
Expand Down
3 changes: 2 additions & 1 deletion resources/i18n/ko.json
Original file line number Diff line number Diff line change
Expand Up @@ -586,7 +586,8 @@
"AdminCanOnlyRemoveTotp": "다른 사용자의 이중 인증은 해제만 가능합니다.",
"KeySeccessfullyDeleted": "키페어가 정상적으로 삭제되었습니다.",
"SignoutSeccessfullyFinished": "사용자 계정이 성공적으로 삭제되었습니다.",
"ModifyUserDetail": "사용자 상세 정보 수정"
"ModifyUserDetail": "사용자 상세 정보 수정",
"EnableSudoSession": "sudo 세션 허용"
},
"data": {
"Folders": "폴더",
Expand Down
6 changes: 4 additions & 2 deletions resources/i18n/mn.json
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,8 @@
"AdminCanOnlyRemoveTotp": "Зөвхөн бусад хэрэглэгчдийн 2FA-г идэвхгүй болгох боломжтой.",
"KeySeccessfullyDeleted": "KeyPair амжилттай устгагдсан.",
"SignoutSeccessfullyFinished": "Гарах ажиллагаа амжилттай дууслаа",
"ModifyUserDetail": "Хэрэглэгчийн мэдээллийг өөрчлөх"
"ModifyUserDetail": "Хэрэглэгчийн мэдээллийг өөрчлөх",
"EnableSudoSession": "__NOT_TRANSLATED__"
},
"data": {
"Folders": "Фолдерууд",
Expand Down Expand Up @@ -898,7 +899,8 @@
"PleaseSelectOption": "Нэг сонголтыг сонгоно уу.",
"RegistrySuccessfullyModified": "Бүртгэл амжилттай өөрчлөгдсөн.",
"ModifyRegistry": "Бүртгэлийг өөрчлөх",
"NoRegistryToDisplay": "Харуулах бүртгэл байхгүй"
"NoRegistryToDisplay": "Харуулах бүртгэл байхгүй",
"ConfirmNoUserName": "__NOT_TRANSLATED__"
},
"resourceGroup": {
"ResourceGroups": "Нөөцийн бүлгүүд",
Expand Down
6 changes: 4 additions & 2 deletions resources/i18n/ms.json
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,8 @@
"KeypairDetail": "Butiran pasangan kekunci",
"SignoutSeccessfullyFinished": "Log keluar telah selesai dengan selamat",
"Status": "Status",
"NoUserToDisplay": "Tiada Pengguna untuk dipaparkan"
"NoUserToDisplay": "Tiada Pengguna untuk dipaparkan",
"EnableSudoSession": "__NOT_TRANSLATED__"
},
"data": {
"Folders": "Folder",
Expand Down Expand Up @@ -898,7 +899,8 @@
"PleaseSelectOption": "Sila pilih satu pilihan.",
"RegistrySuccessfullyModified": "Pendaftaran berjaya diubah suai.",
"NoRegistryToDisplay": "Tiada Pendaftaran untuk dipaparkan",
"ModifyRegistry": "Ubah suai Pendaftaran"
"ModifyRegistry": "Ubah suai Pendaftaran",
"ConfirmNoUserName": "__NOT_TRANSLATED__"
},
"resourceGroup": {
"ResourceGroups": "Kumpulan Sumber",
Expand Down
3 changes: 2 additions & 1 deletion resources/i18n/pl.json
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,8 @@
"KeypairDetail": "Szczegóły pary kluczy",
"SignoutSeccessfullyFinished": "Wylogowanie zostało pomyślnie zakończone",
"Status": "Status",
"NoUserToDisplay": "Brak użytkowników do wyświetlenia"
"NoUserToDisplay": "Brak użytkowników do wyświetlenia",
"EnableSudoSession": "__NOT_TRANSLATED__"
},
"data": {
"Folders": "Lornetka składana",
Expand Down
3 changes: 2 additions & 1 deletion resources/i18n/pt-BR.json
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,8 @@
"KeypairDetail": "Detalhe do par de chaves",
"SignoutSeccessfullyFinished": "O registo foi concluído com êxito",
"Status": "Estado",
"NoUserToDisplay": "Nenhum utilizador a apresentar"
"NoUserToDisplay": "Nenhum utilizador a apresentar",
"EnableSudoSession": "__NOT_TRANSLATED__"
},
"data": {
"Folders": "Pastas",
Expand Down
3 changes: 2 additions & 1 deletion resources/i18n/pt.json
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,8 @@
"KeypairDetail": "Detalhe do par de chaves",
"SignoutSeccessfullyFinished": "O registo foi concluído com êxito",
"Status": "Estado",
"NoUserToDisplay": "Nenhum utilizador a apresentar"
"NoUserToDisplay": "Nenhum utilizador a apresentar",
"EnableSudoSession": "__NOT_TRANSLATED__"
},
"data": {
"Folders": "Pastas",
Expand Down
3 changes: 2 additions & 1 deletion resources/i18n/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,8 @@
"AdminCanOnlyRemoveTotp": "Возможно только отключение 2FA для других пользователей.",
"KeySeccessfullyDeleted": "Пара ключей удалена без последствий.",
"SignoutSeccessfullyFinished": "Выход из системы завершен",
"ModifyUserDetail": "Изменение сведений о пользователе"
"ModifyUserDetail": "Изменение сведений о пользователе",
"EnableSudoSession": "__NOT_TRANSLATED__"
},
"data": {
"Folders": "Папки",
Expand Down
3 changes: 2 additions & 1 deletion resources/i18n/tr.json
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,8 @@
"KeypairDetail": "Anahtar Çifti Detayı",
"SignoutSeccessfullyFinished": "Çıkış işlemi başarıyla tamamlandı",
"Status": "Durum",
"NoUserToDisplay": "Görüntülenecek Kullanıcı Yok"
"NoUserToDisplay": "Görüntülenecek Kullanıcı Yok",
"EnableSudoSession": "__NOT_TRANSLATED__"
},
"data": {
"Folders": "klasörler",
Expand Down
6 changes: 4 additions & 2 deletions resources/i18n/vi.json
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,8 @@
"KeypairDetail": "Chi tiết bàn phím",
"SignoutSeccessfullyFinished": "Đăng xuất đã hoàn tất thành công",
"Status": "Trạng thái",
"NoUserToDisplay": "Không có người dùng để hiển thị"
"NoUserToDisplay": "Không có người dùng để hiển thị",
"EnableSudoSession": "__NOT_TRANSLATED__"
},
"data": {
"Folders": "Thư mục",
Expand Down Expand Up @@ -898,7 +899,8 @@
"PleaseSelectOption": "Làm ơn chọn một giải pháp.",
"RegistrySuccessfullyModified": "Đã sửa đổi sổ đăng ký thành công.",
"NoRegistryToDisplay": "Không có đăng ký để hiển thị",
"ModifyRegistry": "Sửa đổi sổ đăng ký"
"ModifyRegistry": "Sửa đổi sổ đăng ký",
"ConfirmNoUserName": "__NOT_TRANSLATED__"
},
"resourceGroup": {
"ResourceGroups": "Nhóm tài nguyên",
Expand Down
3 changes: 2 additions & 1 deletion resources/i18n/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,8 @@
"KeypairDetail": "配对密钥详情",
"SignoutSeccessfullyFinished": "签出已顺利完成",
"Status": "现状",
"NoUserToDisplay": "无用户显示"
"NoUserToDisplay": "无用户显示",
"EnableSudoSession": "__NOT_TRANSLATED__"
},
"data": {
"Folders": "文件夹",
Expand Down
3 changes: 2 additions & 1 deletion resources/i18n/zh-TW.json
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,8 @@
"KeypairDetail": "配对密钥详情",
"SignoutSeccessfullyFinished": "签出已顺利完成",
"Status": "现状",
"NoUserToDisplay": "无用户显示"
"NoUserToDisplay": "无用户显示",
"EnableSudoSession": "__NOT_TRANSLATED__"
},
"data": {
"Folders": "文件夾",
Expand Down
3 changes: 3 additions & 0 deletions src/lib/backend.ai-client-esm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -660,6 +660,9 @@ class Client {
if (this.isManagerVersionCompatibleWith('23.03.11')) {
this._features['model-serving'] = true;
}
if (this.isManagerVersionCompatibleWith('23.09.0')) {
this._features['sudo-session-enabled'] = true;
}
if (this.isManagerVersionCompatibleWith('23.09.2')) {
this._features['container-registry-gql'] = true;
}
Expand Down