/* * Copyright 2024 Harness, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import React from 'react' import * as Yup from 'yup' import { Button, ButtonVariation, Container, Dialog, Formik, FormikForm, FormInput, Layout, Text, useToaster } from '@harnessio/uicore' import { useFormikContext } from 'formik' import { Menu, MenuItem } from '@blueprintjs/core' import { Color } from '@harnessio/design-system' import { useAppContext } from 'AppContext' import Secret from 'cde-gitness/assests/secret.svg?url' import { useGetCDEAPIParams } from 'cde-gitness/hooks/useGetCDEAPIParams' import type { OpenapiCreateGitspaceRequest } from 'services/cde' import { useModalHook } from 'hooks/useModalHook' import { useStrings } from 'framework/strings' import { useConfirmAct } from 'hooks/useConfirmAction' import { getErrorMessage } from 'utils/Utils' import { CDECustomDropdown } from '../CDECustomDropdown/CDECustomDropdown' import { getSelectedExpirationDate } from './CDESSHSelect.utils' import css from './CDESSHSelect.module.scss' export const CDESSHSelect = () => { const { getString } = useStrings() const { showError } = useToaster() const { values, setFieldValue } = useFormikContext() const { accountIdentifier } = useGetCDEAPIParams() const { hooks, currentUser } = useAppContext() const { useListAggregatedTokens, useDeleteToken, useCreateToken } = hooks const { data, loading, refetch } = useListAggregatedTokens({ queryParams: { accountIdentifier, apiKeyType: 'SSH_KEY', parentIdentifier: currentUser.uid } }) const { mutate: createToken } = useCreateToken({ queryParams: { accountIdentifier } }) const { mutate: deleteToken } = useDeleteToken({ queryParams: { accountIdentifier, apiKeyType: 'SSH_KEY', parentIdentifier: currentUser.uid, apiKeyIdentifier: `cdesshkey` } }) const tokenList = data?.data?.content.map((item: { token: any }) => item.token) || [] const [openModal, hideModal] = useModalHook(() => { const expiryOptions = [ { label: getString('cde.sshSelect.30days'), value: '30' }, { label: getString('cde.sshSelect.90days'), value: '90' }, { label: getString('cde.sshSelect.180days'), value: '180' }, { label: getString('cde.sshSelect.noexpiration'), value: '-1' } ] return ( Add an SSH key for secure access to Gitspaces via SSH. SSH key are used to connect securely to workspaces { e.preventDefault() window.open('https://git-scm.com/book/en/v2/Git-on-the-Server-Generating-Your-SSH-Public-Key', '_blank') }}> Learn how to create an SSH Key formName="sshCreate" onSubmit={async value => { try { await createToken({ identifier: value?.sshKeyName.trim(), name: value?.sshKeyName.trim(), description: '', tags: {}, accountIdentifier, apiKeyIdentifier: `cdesshkey`, parentIdentifier: currentUser.uid, apiKeyType: 'SSH_KEY', sshKeyContent: value.sshKeyValue, sshKeyUsage: ['AUTH'], validTo: Date.parse(value?.expiryDate), validFrom: new Date().getTime() }) setFieldValue('ssh_token_identifier', value?.sshKeyName.trim()) hideModal() refetch() } catch (error) { showError(getErrorMessage(error)) hideModal() } }} initialValues={{ sshKeyName: '', sshKeyValue: '', expiryDate: getSelectedExpirationDate('30'), expiry: '30' }} validationSchema={Yup.object().shape({ sshKeyName: Yup.string().required(), sshKeyValue: Yup.string().required() })}> {formikProps => { return ( { formikProps.setFieldValue('expiryDate', getSelectedExpirationDate(item.value.toString())) }} /> ) }} ) }, [accountIdentifier]) const confirmDelete = useConfirmAct() const handleDelete = async (e: React.MouseEvent, tokenId: string): Promise => { e.stopPropagation() confirmDelete({ intent: 'danger', title: getString('cde.sshSelect.deleteToken', { name: tokenId }), message: getString('cde.deleteGitspaceText'), confirmText: getString('delete'), action: async () => { try { await deleteToken(tokenId || '', { headers: { 'content-type': 'application/json' } }) refetch() } catch (err) { showError(getErrorMessage(err)) } } }) } return ( SSH Key By default we will create the SSH key used to login to the Gitspace. You can add keys under Preferences in User Settings } label={{values?.ssh_token_identifier || 'Select SSH Key'}} formikName="ssh_token_identifier" menu={ {tokenList.length ? ( <> {tokenList.map((item: { name: string; identifier: string; apiKeyIdentifier: string }) => { return ( { handleDelete(e, item.identifier) setFieldValue('ssh_token_identifier', undefined) } }}> {item.name} } onClick={() => { setFieldValue('ssh_token_identifier', item.identifier) }} /> ) })} ) : ( There are no keys configured. By default we will create a SSH key to login into Gitspace. )} } /> ) }