import { Fragment, useState } from 'react'; import { faCheck, faCopy } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Dialog, Transition } from '@headlessui/react'; import nacl from 'tweetnacl'; import addServiceToken from '~/pages/api/serviceToken/addServiceToken'; import getLatestFileKey from '~/pages/api/workspace/getLatestFileKey'; import { envMapping } from '../../../public/data/frequentConstants'; import { decryptAssymmetric, encryptAssymmetric } from '../../utilities/cryptography/crypto'; import Button from '../buttons/Button'; import InputField from '../InputField'; import ListBox from '../Listbox'; const expiryMapping = { '1 day': 86400, '7 days': 604800, '1 month': 2592000, '6 months': 15552000, '12 months': 31104000 }; const AddServiceTokenDialog = ({ isOpen, closeModal, workspaceId, workspaceName }) => { const [serviceToken, setServiceToken] = useState(''); const [serviceTokenName, setServiceTokenName] = useState(''); const [serviceTokenEnv, setServiceTokenEnv] = useState('Development'); const [serviceTokenExpiresIn, setServiceTokenExpiresIn] = useState('1 day'); const [serviceTokenCopied, setServiceTokenCopied] = useState(false); const generateServiceToken = async () => { const latestFileKey = await getLatestFileKey({ workspaceId }); const key = decryptAssymmetric({ ciphertext: latestFileKey.latestKey.encryptedKey, nonce: latestFileKey.latestKey.nonce, publicKey: latestFileKey.latestKey.sender.publicKey, privateKey: localStorage.getItem('PRIVATE_KEY') }); // generate new public/private key pair const pair = nacl.box.keyPair(); const publicKey = nacl.util.encodeBase64(pair.publicKey); const privateKey = nacl.util.encodeBase64(pair.secretKey); // encrypt workspace key under newly-generated public key const { ciphertext: encryptedKey, nonce } = encryptAssymmetric({ plaintext: key, publicKey, privateKey }); let newServiceToken = await addServiceToken({ name: serviceTokenName, workspaceId, environment: envMapping[serviceTokenEnv], expiresIn: expiryMapping[serviceTokenExpiresIn], publicKey, encryptedKey, nonce }); const serviceToken = newServiceToken + ',' + privateKey; setServiceToken(serviceToken); }; function copyToClipboard() { // Get the text field var copyText = document.getElementById('serviceToken'); // Select the text field copyText.select(); copyText.setSelectionRange(0, 99999); // For mobile devices // Copy the text inside the text field navigator.clipboard.writeText(copyText.value); setServiceTokenCopied(true); setTimeout(() => setServiceTokenCopied(false), 2000); // Alert the copied text // alert("Copied the text: " + copyText.value); } const closeAddServiceTokenModal = () => { closeModal(); setServiceTokenName(''); setServiceToken(''); }; return (
{serviceToken == '' ? ( Add a service token for {workspaceName}

Specify the name, environment, and expiry period. When a token is generated, you will only be able to see it once before it disappears. Make sure to save it somewhere.

) : ( Copy your service token

Once you close this popup, you will never see your service token again

{serviceToken}
Click to Copy
)}
); }; export default AddServiceTokenDialog;