Skip to content

Commit

Permalink
Merge branch 'main' into dev-middleware
Browse files Browse the repository at this point in the history
  • Loading branch information
gruyaume authored Sep 23, 2024
2 parents 68ad64c + 9d3b09d commit 227fd62
Show file tree
Hide file tree
Showing 21 changed files with 1,832 additions and 1,145 deletions.
1,079 changes: 992 additions & 87 deletions ui/package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"test-live": "vitest"
},
"dependencies": {
"@canonical/react-components": "^1.2.3",
"jwt-decode": "^4.0.0",
"next": "14.2.13",
"pkijs": "^3.2.4",
Expand Down
2 changes: 1 addition & 1 deletion ui/src/app/aside.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { SetStateAction, Dispatch, createContext, useContext, ComponentType } from "react"
import { SetStateAction, Dispatch, createContext, useContext } from "react"
import { useAuth } from "./auth/authContext"

type AsideContextType = {
Expand Down
146 changes: 75 additions & 71 deletions ui/src/app/certificate_requests/asideForm.tsx
Original file line number Diff line number Diff line change
@@ -1,96 +1,100 @@
import { useMutation, useQueryClient } from "react-query";
import { extractCSR } from "../utils";
import { csrIsValid } from "../utils";
import { useCookies } from "react-cookie";
import { postCSR } from "../queries";
import { ChangeEvent, useContext, useState } from "react";
import { ChangeEvent, useContext, useState, useEffect } from "react";
import { AsideContext } from "../aside";
import { Textarea, Button, Input, Panel, Form } from "@canonical/react-components";


export default function CertificateRequestsAsidePanel(): JSX.Element {
const asideContext = useContext(AsideContext)
const [cookies, setCookie, removeCookie] = useCookies(['user_token']);
const [errorText, setErrorText] = useState<string>("")
const queryClient = useQueryClient()
const asideContext = useContext(AsideContext);
const [cookies] = useCookies(['user_token']);
const [errorText, setErrorText] = useState<string>("");
const [CSRPEMString, setCSRPEMString] = useState<string>("");
const queryClient = useQueryClient();

const mutation = useMutation(postCSR, {
onSuccess: () => {
setErrorText("")
asideContext.setIsOpen(false)
queryClient.invalidateQueries('csrs')
setErrorText("");
asideContext.setIsOpen(false);
queryClient.invalidateQueries('csrs');
},
onError: (e: Error) => {
setErrorText(e.message)
setErrorText(e.message);
}
})
const [CSRPEMString, setCSRPEMString] = useState<string>("")
});

useEffect(() => {
if (CSRPEMString && !csrIsValid(CSRPEMString)) {
setErrorText("Invalid CSR format");
} else {
setErrorText("");
}
}, [CSRPEMString]);

const handleTextChange = (event: ChangeEvent<HTMLTextAreaElement>) => {
setErrorText("")
setCSRPEMString(event.target.value);
}
};

const handleFileChange = (event: ChangeEvent<HTMLInputElement>) => {
const file = event.target.files?.[0]
const file = event.target.files?.[0];
if (file) {
const reader = new FileReader();
reader.onload = (e: ProgressEvent<FileReader>) => {
if (e.target) {
if (e.target.result) {
setCSRPEMString(e.target.result.toString());
}
if (e.target?.result) {
setCSRPEMString(e.target.result.toString());
}
};
reader.readAsText(file);
}
};
return (
<div className="p-panel" >
<div className="p-panel__header">
<h4 className="p-panel__title">Add a New Certificate Request</h4>
<div className="p-panel__controls">
<button onClick={() => asideContext.setIsOpen(false)} className="p-button--base u-no-margin--bottom has-icon"><i className="p-icon--close"></i></button>
</div>
</div>
<div className="p-panel__content">
<form className="p-form p-form--stacked">
<div className="p-form__group row">
<label htmlFor="textarea">
Enter or upload the CSR in PEM format below
</label>
<textarea id="csr-textarea" name="textarea" rows={10} placeholder="-----BEGIN CERTIFICATE REQUEST-----" onChange={handleTextChange} value={CSRPEMString} />
</div>
<div className="p-form__group row">
<input type="file" name="upload" accept=".pem,.csr" onChange={handleFileChange}></input>
</div>
<div className="p-form__group row">
<SubmitCSR csrText={CSRPEMString} errorText={errorText} onClickFunc={() => mutation.mutate({ authToken: cookies.user_token, csr: CSRPEMString })} />
</div>
</form>
</div>
</div >
)
}

function SubmitCSR({ csrText, errorText, onClickFunc }: { csrText: string, errorText: string, onClickFunc: any }) {
let csrIsValid = false
try {
extractCSR(csrText.trim())
csrIsValid = true
}
catch { }
const validationComponent = csrText == "" ? <></> : csrIsValid ? <div><i className="p-icon--success"></i>Valid CSR</div> : <div><i className="p-icon--error"></i>Invalid CSR</div>
const buttonComponent = csrIsValid ? (
<button className="p-button--positive u-float-right" name="submit" onClick={(e) => { e.preventDefault(); onClickFunc() }} > Submit</button >
) : (
<button className="p-button--positive u-float-right" name="submit" disabled={true} onClick={(e) => { e.preventDefault(); onClickFunc() }} >Submit</button>)
const handleSubmit = () => {
mutation.mutate({ authToken: cookies.user_token, csr: CSRPEMString });
};

return (
<>
{errorText != "" &&
<div className="p-notification--negative">
<div className="p-notification__content">
<h5 className="p-notification__title">Error</h5>
<p className="p-notification__message">{errorText.split("error: ")}</p>
</div>
</div>
<Panel
title="Add a New Certificate Request"
controls={
<Button onClick={() => asideContext.setIsOpen(false)} hasIcon>
<i className="p-icon--close" />
</Button>
}
{validationComponent}
{buttonComponent}
</>
)
}
>
<Form stacked={true}>
<div className="p-form__group row">
<Textarea
name="textarea"
id="csr-textarea"
label="Enter or upload the CSR in PEM format below"
placeholder="-----BEGIN CERTIFICATE REQUEST-----"
rows={10}
onChange={handleTextChange}
value={CSRPEMString}
error={errorText}
/>
</div>
<div className="p-form__group row">
<Input
type="file"
name="upload"
accept=".pem,.csr"
onChange={handleFileChange}
/>
</div>
<div className="p-form__group row">
<Button
appearance="positive"
name="submit"
disabled={!csrIsValid(CSRPEMString)}
onClick={handleSubmit}
>
Submit
</Button>
</div>
</Form>
</Panel>
);
}
Loading

0 comments on commit 227fd62

Please sign in to comment.