diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index e534ccf..6ff020a 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -42,4 +42,4 @@ rockcraft pack -v
version=$(yq '.version' rockcraft.yaml)
sudo rockcraft.skopeo --insecure-policy copy oci-archive:gocert_${version}_amd64.rock docker-daemon:gocert:${version}
docker run gocert:${version}
-```
+```
\ No newline at end of file
diff --git a/ui/package-lock.json b/ui/package-lock.json
index af2fb43..2e76764 100644
--- a/ui/package-lock.json
+++ b/ui/package-lock.json
@@ -7,8 +7,10 @@
"name": "gocert",
"dependencies": {
"next": "14.2.3",
+ "pkijs": "^3.1.0",
"react": "^18",
"react-dom": "^18",
+ "react-query": "^3.39.3",
"sass": "^1.77.4",
"vanilla-framework": "^4.11.0"
},
@@ -392,7 +394,6 @@
"version": "7.24.5",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.5.tgz",
"integrity": "sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==",
- "dev": true,
"dependencies": {
"regenerator-runtime": "^0.14.0"
},
@@ -1982,6 +1983,19 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/asn1js": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-3.0.5.tgz",
+ "integrity": "sha512-FVnvrKJwpt9LP2lAMl8qZswRNm3T4q9CON+bxldk2iwk3FFpuwhx2FfinyitizWHsVYyaY+y5JzDR0rCMV5yTQ==",
+ "dependencies": {
+ "pvtsutils": "^1.3.2",
+ "pvutils": "^1.1.3",
+ "tslib": "^2.4.0"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
"node_modules/assertion-error": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
@@ -2039,8 +2053,15 @@
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
- "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
- "dev": true
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
+ },
+ "node_modules/big-integer": {
+ "version": "1.6.52",
+ "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz",
+ "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==",
+ "engines": {
+ "node": ">=0.6"
+ }
},
"node_modules/binary-extensions": {
"version": "2.3.0",
@@ -2057,7 +2078,6 @@
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "dev": true,
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -2074,6 +2094,21 @@
"node": ">=8"
}
},
+ "node_modules/broadcast-channel": {
+ "version": "3.7.0",
+ "resolved": "https://registry.npmjs.org/broadcast-channel/-/broadcast-channel-3.7.0.tgz",
+ "integrity": "sha512-cIAKJXAxGJceNZGTZSBzMxzyOn72cVgPnKx4dc6LRjQgbaJUQqhy5rzL3zbMxkMWsGKkv2hSFkPRMEXfoMZ2Mg==",
+ "dependencies": {
+ "@babel/runtime": "^7.7.2",
+ "detect-node": "^2.1.0",
+ "js-sha3": "0.8.0",
+ "microseconds": "0.2.0",
+ "nano-time": "1.0.0",
+ "oblivious-set": "1.0.0",
+ "rimraf": "3.0.2",
+ "unload": "2.2.0"
+ }
+ },
"node_modules/browserslist": {
"version": "4.23.0",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz",
@@ -2117,6 +2152,14 @@
"node": ">=10.16.0"
}
},
+ "node_modules/bytestreamjs": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/bytestreamjs/-/bytestreamjs-2.0.1.tgz",
+ "integrity": "sha512-U1Z/ob71V/bXfVABvNr/Kumf5VyeQRBEm6Txb0PQ6S7V5GpBM3w4Cbqz/xPDicR5tN0uvDifng8C+5qECeGwyQ==",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
"node_modules/cac": {
"version": "6.7.14",
"resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz",
@@ -2291,8 +2334,7 @@
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
- "dev": true
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
},
"node_modules/confbox": {
"version": "0.1.7",
@@ -2501,6 +2543,11 @@
"node": ">=6"
}
},
+ "node_modules/detect-node": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz",
+ "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g=="
+ },
"node_modules/diff-sequences": {
"version": "29.6.3",
"resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz",
@@ -3397,8 +3444,7 @@
"node_modules/fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
- "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
- "dev": true
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
},
"node_modules/fsevents": {
"version": "2.3.3",
@@ -3836,7 +3882,6 @@
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
- "dev": true,
"dependencies": {
"once": "^1.3.0",
"wrappy": "1"
@@ -3845,8 +3890,7 @@
"node_modules/inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
- "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
- "dev": true
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"node_modules/internal-slot": {
"version": "1.0.7",
@@ -4286,6 +4330,11 @@
"@pkgjs/parseargs": "^0.11.0"
}
},
+ "node_modules/js-sha3": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz",
+ "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q=="
+ },
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -4524,6 +4573,15 @@
"@jridgewell/sourcemap-codec": "^1.4.15"
}
},
+ "node_modules/match-sorter": {
+ "version": "6.3.4",
+ "resolved": "https://registry.npmjs.org/match-sorter/-/match-sorter-6.3.4.tgz",
+ "integrity": "sha512-jfZW7cWS5y/1xswZo8VBOdudUiSd9nifYRWphc9M5D/ee4w4AoXLgBEdRbgVaxbMuagBPeUC5y2Hi8DO6o9aDg==",
+ "dependencies": {
+ "@babel/runtime": "^7.23.8",
+ "remove-accents": "0.5.0"
+ }
+ },
"node_modules/merge-stream": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
@@ -4552,6 +4610,11 @@
"node": ">=8.6"
}
},
+ "node_modules/microseconds": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/microseconds/-/microseconds-0.2.0.tgz",
+ "integrity": "sha512-n7DHHMjR1avBbSpsTBj6fmMGh2AGrifVV4e+WYc3Q9lO+xnSZ3NyhcBND3vzzatt05LFhoKFRxrIyklmLlUtyA=="
+ },
"node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
@@ -4589,7 +4652,6 @@
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "dev": true,
"dependencies": {
"brace-expansion": "^1.1.7"
},
@@ -4633,6 +4695,14 @@
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
},
+ "node_modules/nano-time": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/nano-time/-/nano-time-1.0.0.tgz",
+ "integrity": "sha512-flnngywOoQ0lLQOTRNexn2gGSNuM9bKj9RZAWSzhQ+UJYaAFG9bac4DW9VHjUAzrOaIcajHybCTHe/bkvozQqA==",
+ "dependencies": {
+ "big-integer": "^1.6.16"
+ }
+ },
"node_modules/nanoid": {
"version": "3.3.7",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
@@ -4877,11 +4947,15 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/oblivious-set": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/oblivious-set/-/oblivious-set-1.0.0.tgz",
+ "integrity": "sha512-z+pI07qxo4c2CulUHCDf9lcqDlMSo72N/4rLUpRXf6fu+q8vjt8y0xS+Tlf8NTJDdTXHbdeO1n3MlbctwEoXZw=="
+ },
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
- "dev": true,
"dependencies": {
"wrappy": "1"
}
@@ -4985,7 +5059,6 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
- "dev": true,
"engines": {
"node": ">=0.10.0"
}
@@ -5081,6 +5154,21 @@
"pathe": "^1.1.2"
}
},
+ "node_modules/pkijs": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/pkijs/-/pkijs-3.1.0.tgz",
+ "integrity": "sha512-N+OCWUp6xrg7OkG+4DIiZUOsp3qMztjq8RGCc1hSY92dsUG8cTlAo7pEkfRGjcdyBv2c1Y9bjAzqdTJAlctuNg==",
+ "dependencies": {
+ "asn1js": "^3.0.5",
+ "bytestreamjs": "^2.0.0",
+ "pvtsutils": "^1.3.2",
+ "pvutils": "^1.1.3",
+ "tslib": "^2.4.0"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
"node_modules/possible-typed-array-names": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz",
@@ -5184,6 +5272,22 @@
"node": ">=6"
}
},
+ "node_modules/pvtsutils": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/pvtsutils/-/pvtsutils-1.3.5.tgz",
+ "integrity": "sha512-ARvb14YB9Nm2Xi6nBq1ZX6dAM0FsJnuk+31aUp4TrcZEdKUlSqOqsxJHUPJDNE3qiIp+iUPEIeR6Je/tgV7zsA==",
+ "dependencies": {
+ "tslib": "^2.6.1"
+ }
+ },
+ "node_modules/pvutils": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/pvutils/-/pvutils-1.1.3.tgz",
+ "integrity": "sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ==",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
"node_modules/querystringify": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
@@ -5239,6 +5343,31 @@
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
"dev": true
},
+ "node_modules/react-query": {
+ "version": "3.39.3",
+ "resolved": "https://registry.npmjs.org/react-query/-/react-query-3.39.3.tgz",
+ "integrity": "sha512-nLfLz7GiohKTJDuT4us4X3h/8unOh+00MLb2yJoGTPjxKs2bc1iDhkNx2bd5MKklXnOD3NrVZ+J2UXujA5In4g==",
+ "dependencies": {
+ "@babel/runtime": "^7.5.5",
+ "broadcast-channel": "^3.4.1",
+ "match-sorter": "^6.0.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/tannerlinsley"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ },
+ "peerDependenciesMeta": {
+ "react-dom": {
+ "optional": true
+ },
+ "react-native": {
+ "optional": true
+ }
+ }
+ },
"node_modules/react-refresh": {
"version": "0.14.2",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz",
@@ -5283,8 +5412,7 @@
"node_modules/regenerator-runtime": {
"version": "0.14.1",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
- "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==",
- "dev": true
+ "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
},
"node_modules/regexp.prototype.flags": {
"version": "1.5.2",
@@ -5304,6 +5432,11 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/remove-accents": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.5.0.tgz",
+ "integrity": "sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A=="
+ },
"node_modules/requires-port": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
@@ -5359,7 +5492,6 @@
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
- "dev": true,
"dependencies": {
"glob": "^7.1.3"
},
@@ -5374,7 +5506,6 @@
"version": "7.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
- "dev": true,
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
@@ -6201,6 +6332,15 @@
"node": ">= 4.0.0"
}
},
+ "node_modules/unload": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/unload/-/unload-2.2.0.tgz",
+ "integrity": "sha512-B60uB5TNBLtN6/LsgAf3udH9saB5p7gqJwcFfbOEZ8BcBHnGwCf6G/TGiEqkRAxX7zAFIUtzdrXQSdL3Q/wqNA==",
+ "dependencies": {
+ "@babel/runtime": "^7.6.2",
+ "detect-node": "^2.0.4"
+ }
+ },
"node_modules/update-browserslist-db": {
"version": "1.0.15",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.15.tgz",
@@ -6696,8 +6836,7 @@
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
- "dev": true
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
},
"node_modules/ws": {
"version": "8.17.1",
diff --git a/ui/package.json b/ui/package.json
index 348263e..cbf3c62 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -12,8 +12,10 @@
},
"dependencies": {
"next": "14.2.3",
+ "pkijs": "^3.1.0",
"react": "^18",
"react-dom": "^18",
+ "react-query": "^3.39.3",
"sass": "^1.77.4",
"vanilla-framework": "^4.11.0"
},
diff --git a/ui/src/app/certificate_requests/page.test.tsx b/ui/src/app/certificate_requests/page.test.tsx
deleted file mode 100644
index 50eaaba..0000000
--- a/ui/src/app/certificate_requests/page.test.tsx
+++ /dev/null
@@ -1,8 +0,0 @@
-import { expect, test } from 'vitest'
-import { render, screen } from '@testing-library/react'
-import CertificateRequests from './page'
-
-test('CertificateRequestsPage', () => {
- render(< CertificateRequests />)
- expect(screen.getByRole('table', {})).toBeDefined()
-})
\ No newline at end of file
diff --git a/ui/src/app/certificate_requests/page.tsx b/ui/src/app/certificate_requests/page.tsx
index a0e69a4..70be761 100644
--- a/ui/src/app/certificate_requests/page.tsx
+++ b/ui/src/app/certificate_requests/page.tsx
@@ -1,9 +1,45 @@
"use client"
+import { useQuery } from "react-query"
import { CertificateRequestsTable } from "./table"
+import { getCertificateRequests } from "./queries"
+import { CSREntry } from "./types"
+
+function Error({ msg }: { msg: string }) {
+ return (
+
+
+
+
+
An error occured trying to load certificate requests
+
{msg}
+
+
+
+
+ )
+}
+
+function Loading() {
+ return (
+
+
+
+ )
+}
export default function CertificateRequests() {
+ const query = useQuery('csrs', getCertificateRequests)
+ if (query.status == "loading") { return }
+ if (query.status == "error") { return }
+ const csrs = Array.from(query.data ? query.data : [])
return (
-
+
)
}
\ No newline at end of file
diff --git a/ui/src/app/certificate_requests/queries.ts b/ui/src/app/certificate_requests/queries.ts
new file mode 100644
index 0000000..3702304
--- /dev/null
+++ b/ui/src/app/certificate_requests/queries.ts
@@ -0,0 +1,9 @@
+import { CSREntry } from "./types"
+
+export async function getCertificateRequests(): Promise {
+ const response = await fetch("/api/v1/certificate_requests")
+ if (!response.ok) {
+ throw new Error('Network response was not ok')
+ }
+ return response.json()
+}
\ No newline at end of file
diff --git a/ui/src/app/certificate_requests/row.test.tsx b/ui/src/app/certificate_requests/row.test.tsx
index dbe8269..edabc82 100644
--- a/ui/src/app/certificate_requests/row.test.tsx
+++ b/ui/src/app/certificate_requests/row.test.tsx
@@ -1,11 +1,67 @@
import { expect, test } from 'vitest'
-import { render, screen } from '@testing-library/react'
+import { Dispatch, SetStateAction } from "react"
+import { render, screen, fireEvent } from '@testing-library/react'
import Row from './row'
+const csr =
+{
+ 'ID': 1,
+ 'CSR': `-----BEGIN CERTIFICATE REQUEST-----
+MIIC5zCCAc8CAQAwRzEWMBQGA1UEAwwNMTAuMTUyLjE4My41MzEtMCsGA1UELQwk
+MzlhY2UxOTUtZGM1YS00MzJiLTgwOTAtYWZlNmFiNGI0OWNmMIIBIjANBgkqhkiG
+9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjM5Wz+HRtDveRzeDkEDM4ornIaefe8d8nmFi
+pUat9qCU3U9798FR460DHjCLGxFxxmoRitzHtaR4ew5H036HlGB20yas/CMDgSUI
+69DyAsyPwEJqOWBGO1LL50qXdl5/jOkO2voA9j5UsD1CtWSklyhbNhWMpYqj2ObW
+XcaYj9Gx/TwYhw8xsJ/QRWyCrvjjVzH8+4frfDhBVOyywN7sq+I3WwCbyBBcN8uO
+yae0b/q5+UJUiqgpeOAh/4Y7qI3YarMj4cm7dwmiCVjedUwh65zVyHtQUfLd8nFW
+Kl9775mNBc1yicvKDU3ZB5hZ1MZtpbMBwaA1yMSErs/fh5KaXwIDAQABoFswWQYJ
+KoZIhvcNAQkOMUwwSjBIBgNVHREEQTA/hwQKmLc1gjd2YXVsdC1rOHMtMC52YXVs
+dC1rOHMtZW5kcG9pbnRzLnZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsMA0GCSqGSIb3
+DQEBCwUAA4IBAQCJt8oVDbiuCsik4N5AOJIT7jKsMb+j0mizwjahKMoCHdx+zv0V
+FGkhlf0VWPAdEu3gHdJfduX88WwzJ2wBBUK38UuprAyvfaZfaYUgFJQNC6DH1fIa
+uHYEhvNJBdFJHaBvW7lrSFi57fTA9IEPrB3m/XN3r2F4eoHnaJJqHZmMwqVHck87
+cAQXk3fvTWuikHiCHqqdSdjDYj/8cyiwCrQWpV245VSbOE0WesWoEnSdFXVUfE1+
+RSKeTRuuJMcdGqBkDnDI22myj0bjt7q8eqBIjTiLQLnAFnQYpcCrhc8dKU9IJlv1
+H9Hay4ZO9LRew3pEtlx2WrExw/gpUcWM8rTI
+-----END CERTIFICATE REQUEST-----`,
+ 'Certificate': `-----BEGIN CERTIFICATE-----
+MIIDrDCCApSgAwIBAgIURKr+jf7hj60SyAryIeN++9wDdtkwDQYJKoZIhvcNAQEL
+BQAwOTELMAkGA1UEBhMCVVMxKjAoBgNVBAMMIXNlbGYtc2lnbmVkLWNlcnRpZmlj
+YXRlcy1vcGVyYXRvcjAeFw0yNDAzMjcxMjQ4MDRaFw0yNTAzMjcxMjQ4MDRaMEcx
+FjAUBgNVBAMMDTEwLjE1Mi4xODMuNTMxLTArBgNVBC0MJDM5YWNlMTk1LWRjNWEt
+NDMyYi04MDkwLWFmZTZhYjRiNDljZjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
+AQoCggEBAIzOVs/h0bQ73kc3g5BAzOKK5yGnn3vHfJ5hYqVGrfaglN1Pe/fBUeOt
+Ax4wixsRccZqEYrcx7WkeHsOR9N+h5RgdtMmrPwjA4ElCOvQ8gLMj8BCajlgRjtS
+y+dKl3Zef4zpDtr6APY+VLA9QrVkpJcoWzYVjKWKo9jm1l3GmI/Rsf08GIcPMbCf
+0EVsgq7441cx/PuH63w4QVTsssDe7KviN1sAm8gQXDfLjsmntG/6uflCVIqoKXjg
+If+GO6iN2GqzI+HJu3cJoglY3nVMIeuc1ch7UFHy3fJxVipfe++ZjQXNconLyg1N
+2QeYWdTGbaWzAcGgNcjEhK7P34eSml8CAwEAAaOBnTCBmjAhBgNVHSMEGjAYgBYE
+FN/vgl9cAapV7hH9lEyM7qYS958aMB0GA1UdDgQWBBRJJDZkHr64VqTC24DPQVld
+Ba3iPDAMBgNVHRMBAf8EAjAAMEgGA1UdEQRBMD+CN3ZhdWx0LWs4cy0wLnZhdWx0
+LWs4cy1lbmRwb2ludHMudmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWyHBAqYtzUwDQYJ
+KoZIhvcNAQELBQADggEBAEH9NTwDiSsoQt/QXkWPMBrB830K0dlwKl5WBNgVxFP+
+hSfQ86xN77jNSp2VxOksgzF9J9u/ubAXvSFsou4xdP8MevBXoFJXeqMERq5RW3gc
+WyhXkzguv3dwH+n43GJFP6MQ+n9W/nPZCUQ0Iy7ueAvj0HFhGyZzAE2wxNFZdvCs
+gCX3nqYpp70oZIFDrhmYwE5ij5KXlHD4/1IOfNUKCDmQDgGPLI1tVtwQLjeRq7Hg
+XVelpl/LXTQawmJyvDaVT/Q9P+WqoDiMjrqF6Sy7DzNeeccWVqvqX5TVS6Ky56iS
+Mvo/+PAJHkBciR5Xn+Wg2a+7vrZvT6CBoRSOTozlLSM=
+-----END CERTIFICATE-----`
+}
+
+let actionMenuExpanded = 0
+const setActionMenuExpanded = (val: number) => {
+ actionMenuExpanded = val
+}
+
test('Certificate Requests Table Row', () => {
- render(
)
- expect(screen.getByText('1')).toBeDefined()
-})
-// TODO: when certificate rejected => rejected status
-// TODO: when certificate empty => outstanding status
-// TODO: when certificate anything else => certificate.NotAfter
\ No newline at end of file
+ render(>} />)
+ expect(screen.getByText('10.152.183.53')).toBeDefined() // Common name of CSR
+ expect(screen.getByLabelText('certificate-expiry-date').innerHTML).toMatch(/^Thu Mar 27/)
+ const openActionsButton = screen.getByLabelText("action-menu-button")
+ fireEvent.click(openActionsButton);
+ expect(actionMenuExpanded).toBe(1)
+ render(>} />)
+ expect(screen.getByText('rejected')).toBeDefined()
+ render(>} />)
+ expect(screen.getByText('outstanding')).toBeDefined()
+})
\ No newline at end of file
diff --git a/ui/src/app/certificate_requests/row.tsx b/ui/src/app/certificate_requests/row.tsx
index 0ef4a03..9ca6891 100644
--- a/ui/src/app/certificate_requests/row.tsx
+++ b/ui/src/app/certificate_requests/row.tsx
@@ -1,11 +1,6 @@
import { useState, Dispatch, SetStateAction } from "react"
-const extractCSR = (csrPemString: string) => {
- //TODO
-}
+import { extractCSR, extractCert } from "../utils"
-const extractCert = (certPemString: string) => {
- //TODO
-}
type rowProps = {
id: number,
@@ -18,40 +13,44 @@ type rowProps = {
export default function Row({ id, csr, certificate, ActionMenuExpanded, setActionMenuExpanded }: rowProps) {
const [detailsMenuOpen, setDetailsMenuOpen] = useState(false)
+ const csrObj = extractCSR(csr)
+ const certObj = extractCert(certificate)
+
const toggleActionMenu = () => {
if (ActionMenuExpanded == id) {
setActionMenuExpanded(0)
- }else{
+ } else {
setActionMenuExpanded(id)
}
}
return (
- {id} |
+ {id} |
-
- example.com
+ {csrObj.subjects.find((e) => e.type == "Common Name")?.value}
|
- {certificate == "" ? "outstanding" : (certificate == "rejected" ? "rejected" : "fulfilled")} |
- {certificate == "" ? "" : (certificate == "rejected" ? "" : "date")} |
+ {certificate == "" ? "outstanding" : (certificate == "rejected" ? "rejected" : "fulfilled")} |
+ {certificate == "" ? "" : (certificate == "rejected" ? "" : certObj?.notAfter)} |
-
- |
-
+ |
- Common Name: example.com
- Subject Alternative Names: example.com, 127.0.0.1, 1.2.3.4.5.56
+ Common Name: {csrObj.subjects.find((e) => e.type == "Common Name")?.value}
|
diff --git a/ui/src/app/certificate_requests/table.test.tsx b/ui/src/app/certificate_requests/table.test.tsx
new file mode 100644
index 0000000..6a7c08c
--- /dev/null
+++ b/ui/src/app/certificate_requests/table.test.tsx
@@ -0,0 +1,99 @@
+import { expect, test } from 'vitest'
+import { render, screen } from '@testing-library/react'
+import { CertificateRequestsTable } from './table'
+
+const rows = [
+ {
+ 'ID': 1,
+ 'CSR': `-----BEGIN CERTIFICATE REQUEST-----
+MIICszCCAZsCAQAwFjEUMBIGA1UEAwwLZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3
+DQEBAQUAA4IBDwAwggEKAoIBAQDC5KgrADpuOUPwSh0YLmpWF66VTcciIGC2HcGn
+oJknL7pm5q9qhfWGIdvKKlIA6cBB32jPd0QcYDsx7+AvzEvBuO7mq7v2Q1sPU4Q+
+L0s2pLJges6/cnDWvk/p5eBjDLOqHhUNzpMUga9SgIod8yymTZm3eqQvt1ABdwTg
+FzBs5QdSm2Ny1fEbbcRE+Rv5rqXyJb2isXSujzSuS22VqslDIyqnY5WaLg+pjZyR
++0j13ecJsdh6/MJMUZWheimV2Yv7SFtxzFwbzBMO9YFS098sy4F896eBHLNe9cUC
++d1JDtLaewlMogjHBHAxmP54dhe6vvc78anElKKP4hm5N5nlAgMBAAGgWDBWBgkq
+hkiG9w0BCQ4xSTBHMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcD
+AQYIKwYBBQUHAwIwFgYDVR0RBA8wDYILZXhhbXBsZS5jb20wDQYJKoZIhvcNAQEL
+BQADggEBACP1VKEGVYKoVLMDJS+EZ0CPwIYWsO4xBXgK6atHe8WIChVn/8I7eo60
+cuMDiy4LR70G++xL1tpmYGRbx21r9d/shL2ehp9VdClX06qxlcGxiC/F8eThRuS5
+zHcdNqSVyMoLJ0c7yWHJahN5u2bn1Lov34yOEqGGpWCGF/gT1nEvM+p/v30s89f2
+Y/uPl4g3jpGqLCKTASWJDGnZLroLICOzYTVs5P3oj+VueSUwYhGK5tBnS2x5FHID
+uMNMgwl0fxGMQZjrlXyCBhXBm1k6PmwcJGJF5LQ31c+5aTTMFU7SyZhlymctB8mS
+y+ErBQsRpcQho6Ok+HTXQQUcx7WNcwI=
+-----END CERTIFICATE REQUEST-----`,
+ 'Certificate': ""
+ },
+ {
+ 'ID': 2,
+ 'CSR': `-----BEGIN CERTIFICATE REQUEST-----
+MIIDGjCCAgICAQAwajEVMBMGA1UEAwwMZXhlbXBsYXIuY29tMQswCQYDVQQGEwJV
+UzESMBAGA1UECAwJTG91aXNpYW5hMRQwEgYDVQQHDAtOZXcgT3JsZWFuczEaMBgG
+A1UECgwRQ2VydGlmaWNhdGUgVG9vbHMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
+ggEKAoIBAQDZD+5Kz84PVxW6zUEd0wwWPC4h0vxSMX1kuDM+NibZdgB/kE+g9OI5
+qvK7bOrGrXEs0GOuI4M7pl/6e42+it/oE0v5tWBZxka8J+bqYE5J8NGal/oIgOo7
+evpx5QPFFlJlJOJdH4bFJfp6GMO/3tO3Ip7O0Q3iitTnDA2gJC6aQW7hclVCk4ls
+lWFVyUFRRubKW0/LEmgNl9DNuQyfLp1yB3159r1NiKT9M+/ATrmBYF2ZiCWBWz4C
+ySja6+r4UB/LZYwdp/n7rRtwX1R/B6HPsXw/nGsjU6+OyYS/oDJwNWpT3+dsa7sD
+cSm1SNhJuKwC74nYGfH0y4FNsPW3cpiZAgMBAAGgazBpBgkqhkiG9w0BCQ4xXDBa
+MA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw
+KQYDVR0RBCIwIIIMZXhlbXBsYXIuY29tghB3d3cuZXhlbXBsYXIuY29tMA0GCSqG
+SIb3DQEBCwUAA4IBAQAuqwxmBklZ86ypTkchZJmUsyF8y/THqncFDW8RGWIB3Usi
+tK9qb8EE92MoWboo4m4bcX74y+eUo3xBev6ZZwdScy8OHLhA/MMI8EElpeYt+Hc2
+2gvIs7WNemo3cCTpOtwvROWYpzxMp/z2/Zui9D57oTFcTdBjlJPyU5K4bCz+nNGV
+81ifHK1xAUECfJp1IR7hFv2c2JbkwwD3KSCsyqc+/xtQLbrEPGWF1R0Gp9N1hxKv
+WsDOAOH6qKQKQg3BO/xmRoohC6GL4CuhP7HYGi7+wziNhNZQa4GtE/k9DyIXVtJy
+yuf2PnfXCKnaIWRJNoEqDCZRVMfA5BFSwTPITqyo
+-----END CERTIFICATE REQUEST-----`,
+ 'Certificate': "rejected"
+ },
+ {
+ 'ID': 3,
+ 'CSR': `-----BEGIN CERTIFICATE REQUEST-----
+MIIC5zCCAc8CAQAwRzEWMBQGA1UEAwwNMTAuMTUyLjE4My41MzEtMCsGA1UELQwk
+MzlhY2UxOTUtZGM1YS00MzJiLTgwOTAtYWZlNmFiNGI0OWNmMIIBIjANBgkqhkiG
+9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjM5Wz+HRtDveRzeDkEDM4ornIaefe8d8nmFi
+pUat9qCU3U9798FR460DHjCLGxFxxmoRitzHtaR4ew5H036HlGB20yas/CMDgSUI
+69DyAsyPwEJqOWBGO1LL50qXdl5/jOkO2voA9j5UsD1CtWSklyhbNhWMpYqj2ObW
+XcaYj9Gx/TwYhw8xsJ/QRWyCrvjjVzH8+4frfDhBVOyywN7sq+I3WwCbyBBcN8uO
+yae0b/q5+UJUiqgpeOAh/4Y7qI3YarMj4cm7dwmiCVjedUwh65zVyHtQUfLd8nFW
+Kl9775mNBc1yicvKDU3ZB5hZ1MZtpbMBwaA1yMSErs/fh5KaXwIDAQABoFswWQYJ
+KoZIhvcNAQkOMUwwSjBIBgNVHREEQTA/hwQKmLc1gjd2YXVsdC1rOHMtMC52YXVs
+dC1rOHMtZW5kcG9pbnRzLnZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsMA0GCSqGSIb3
+DQEBCwUAA4IBAQCJt8oVDbiuCsik4N5AOJIT7jKsMb+j0mizwjahKMoCHdx+zv0V
+FGkhlf0VWPAdEu3gHdJfduX88WwzJ2wBBUK38UuprAyvfaZfaYUgFJQNC6DH1fIa
+uHYEhvNJBdFJHaBvW7lrSFi57fTA9IEPrB3m/XN3r2F4eoHnaJJqHZmMwqVHck87
+cAQXk3fvTWuikHiCHqqdSdjDYj/8cyiwCrQWpV245VSbOE0WesWoEnSdFXVUfE1+
+RSKeTRuuJMcdGqBkDnDI22myj0bjt7q8eqBIjTiLQLnAFnQYpcCrhc8dKU9IJlv1
+H9Hay4ZO9LRew3pEtlx2WrExw/gpUcWM8rTI
+-----END CERTIFICATE REQUEST-----`,
+ 'Certificate': `-----BEGIN CERTIFICATE-----
+MIIDrDCCApSgAwIBAgIURKr+jf7hj60SyAryIeN++9wDdtkwDQYJKoZIhvcNAQEL
+BQAwOTELMAkGA1UEBhMCVVMxKjAoBgNVBAMMIXNlbGYtc2lnbmVkLWNlcnRpZmlj
+YXRlcy1vcGVyYXRvcjAeFw0yNDAzMjcxMjQ4MDRaFw0yNTAzMjcxMjQ4MDRaMEcx
+FjAUBgNVBAMMDTEwLjE1Mi4xODMuNTMxLTArBgNVBC0MJDM5YWNlMTk1LWRjNWEt
+NDMyYi04MDkwLWFmZTZhYjRiNDljZjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
+AQoCggEBAIzOVs/h0bQ73kc3g5BAzOKK5yGnn3vHfJ5hYqVGrfaglN1Pe/fBUeOt
+Ax4wixsRccZqEYrcx7WkeHsOR9N+h5RgdtMmrPwjA4ElCOvQ8gLMj8BCajlgRjtS
+y+dKl3Zef4zpDtr6APY+VLA9QrVkpJcoWzYVjKWKo9jm1l3GmI/Rsf08GIcPMbCf
+0EVsgq7441cx/PuH63w4QVTsssDe7KviN1sAm8gQXDfLjsmntG/6uflCVIqoKXjg
+If+GO6iN2GqzI+HJu3cJoglY3nVMIeuc1ch7UFHy3fJxVipfe++ZjQXNconLyg1N
+2QeYWdTGbaWzAcGgNcjEhK7P34eSml8CAwEAAaOBnTCBmjAhBgNVHSMEGjAYgBYE
+FN/vgl9cAapV7hH9lEyM7qYS958aMB0GA1UdDgQWBBRJJDZkHr64VqTC24DPQVld
+Ba3iPDAMBgNVHRMBAf8EAjAAMEgGA1UdEQRBMD+CN3ZhdWx0LWs4cy0wLnZhdWx0
+LWs4cy1lbmRwb2ludHMudmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWyHBAqYtzUwDQYJ
+KoZIhvcNAQELBQADggEBAEH9NTwDiSsoQt/QXkWPMBrB830K0dlwKl5WBNgVxFP+
+hSfQ86xN77jNSp2VxOksgzF9J9u/ubAXvSFsou4xdP8MevBXoFJXeqMERq5RW3gc
+WyhXkzguv3dwH+n43GJFP6MQ+n9W/nPZCUQ0Iy7ueAvj0HFhGyZzAE2wxNFZdvCs
+gCX3nqYpp70oZIFDrhmYwE5ij5KXlHD4/1IOfNUKCDmQDgGPLI1tVtwQLjeRq7Hg
+XVelpl/LXTQawmJyvDaVT/Q9P+WqoDiMjrqF6Sy7DzNeeccWVqvqX5TVS6Ky56iS
+Mvo/+PAJHkBciR5Xn+Wg2a+7vrZvT6CBoRSOTozlLSM=
+-----END CERTIFICATE-----`
+ },
+]
+
+test('CertificateRequestsPage', () => {
+ render(< CertificateRequestsTable csrs={rows} />)
+ expect(screen.getByRole('table', {})).toBeDefined()
+ expect(screen.getByText('example.com')).toBeDefined() // Common Name of one of the CSR's
+})
\ No newline at end of file
diff --git a/ui/src/app/certificate_requests/table.tsx b/ui/src/app/certificate_requests/table.tsx
index 51142d4..e7fe679 100644
--- a/ui/src/app/certificate_requests/table.tsx
+++ b/ui/src/app/certificate_requests/table.tsx
@@ -1,16 +1,30 @@
-import { useContext, useState } from "react"
+import { useContext, useState, Dispatch, SetStateAction } from "react"
import { AsideContext } from "../nav"
import Row from "./row"
+import { CSREntry } from "./types"
-type CSREntry = {
- id: number,
- csr: string,
- certificate: string
+function EmptyState({ asideOpen, setAsideOpen }: { asideOpen: boolean, setAsideOpen: Dispatch> }) {
+ return (
+
+
+
+
+
No CSRs available yet.
+
+
+
+
+
+ )
+}
+
+type TableProps = {
+ csrs: CSREntry[]
}
function sortByCSRStatus(a: CSREntry, b: CSREntry) {
- const aCSRStatus = a.certificate == "" ? "outstanding" : (a.certificate == "rejected" ? "rejected" : "fulfilled")
- const bCSRStatus = b.certificate == "" ? "outstanding" : (b.certificate == "rejected" ? "rejected" : "fulfilled")
+ const aCSRStatus = a.Certificate == "" ? "outstanding" : (a.Certificate == "rejected" ? "rejected" : "fulfilled")
+ const bCSRStatus = b.Certificate == "" ? "outstanding" : (b.Certificate == "rejected" ? "rejected" : "fulfilled")
if (aCSRStatus < bCSRStatus) {
return -1;
} else if (aCSRStatus > bCSRStatus) {
@@ -21,8 +35,8 @@ function sortByCSRStatus(a: CSREntry, b: CSREntry) {
}
function sortByCertStatus(a: CSREntry, b: CSREntry) {
- const aCertStatus = (a.certificate == "" ? "" : (a.certificate == "rejected" ? "" : "date"))
- const bCertStatus = (b.certificate == "" ? "" : (b.certificate == "rejected" ? "" : "date"))
+ const aCertStatus = (a.Certificate == "" ? "" : (a.Certificate == "rejected" ? "" : "date"))
+ const bCertStatus = (b.Certificate == "" ? "" : (b.Certificate == "rejected" ? "" : "date"))
if (aCertStatus < bCertStatus) {
return -1;
} else if (aCertStatus > bCertStatus) {
@@ -32,26 +46,18 @@ function sortByCertStatus(a: CSREntry, b: CSREntry) {
}
}
-export function CertificateRequestsTable() {
+export function CertificateRequestsTable({ csrs: rows }: TableProps) {
const { isOpen: isAsideOpen, setIsOpen: setAsideIsOpen } = useContext(AsideContext)
const [actionsMenuExpanded, setActionsMenuExpanded] = useState(0)
const [sortedColumn, setSortedColumn] = useState('none')
const [sortDescending, setSortDescending] = useState(true)
- const rows = [
- {'id':1, 'csr':"csr1",'certificate':""},
- {'id':2, 'csr':"csr2",'certificate':"rejected"},
- {'id':3, 'csr':"csr3",'certificate':"a real cert"},
- {'id':4, 'csr':"csr3",'certificate':"a real cert"},
- {'id':5, 'csr':"csr3",'certificate':"a real cert"},
- {'id':6, 'csr':"csr3",'certificate':"a real cert"},
- ]
const sortedRows = () => {
switch (sortedColumn) {
case "csr":
- return (sortDescending? rows.sort(sortByCSRStatus).reverse() : rows.sort(sortByCSRStatus))
+ return (sortDescending ? rows.sort(sortByCSRStatus).reverse() : rows.sort(sortByCSRStatus))
case "cert":
- return (sortDescending? rows.sort(sortByCertStatus).reverse() : rows.sort(sortByCertStatus))
+ return (sortDescending ? rows.sort(sortByCertStatus).reverse() : rows.sort(sortByCertStatus))
default:
return rows
}
@@ -61,7 +67,7 @@ export function CertificateRequestsTable() {
Certificate Requests
-
+ {rows.length > 0 && }
@@ -71,8 +77,8 @@ export function CertificateRequestsTable() {
ID |
Details |
- {setSortedColumn('csr');setSortDescending(!sortDescending)}}>CSR Status |
- {setSortedColumn('cert');setSortDescending(!sortDescending)}}>Certificate Expiry Date |
+ { setSortedColumn('csr'); setSortDescending(!sortDescending) }}>CSR Status |
+ { setSortedColumn('cert'); setSortDescending(!sortDescending) }}>Certificate Expiry Date |
Actions |
|
@@ -80,10 +86,11 @@ export function CertificateRequestsTable() {
{
sortedRows().map((row) => (
-
+
)
- )}
+ )}
+ {rows.length == 0 && }
diff --git a/ui/src/app/certificate_requests/types.ts b/ui/src/app/certificate_requests/types.ts
new file mode 100644
index 0000000..8f2704f
--- /dev/null
+++ b/ui/src/app/certificate_requests/types.ts
@@ -0,0 +1,5 @@
+export type CSREntry = {
+ ID: number,
+ CSR: string,
+ Certificate: string
+}
\ No newline at end of file
diff --git a/ui/src/app/nav.test.tsx b/ui/src/app/nav.test.tsx
index 08bb5de..fa0fd1c 100644
--- a/ui/src/app/nav.test.tsx
+++ b/ui/src/app/nav.test.tsx
@@ -1,11 +1,11 @@
import { expect, describe, it } from "vitest";
-import {render, fireEvent, screen} from '@testing-library/react'
+import { render, fireEvent, screen } from '@testing-library/react'
import Navigation from "./nav";
import { CertificateRequestsTable } from "./certificate_requests/table";
describe('Navigation', () => {
it('should open aside when clicking button', () => {
- render()
+ render()
const addCSRButton = screen.getByLabelText(/add-csr-button/i)
expect(screen.getByLabelText(/aside-panel/i).className.endsWith('is-collapsed')).toBe(true)
fireEvent.click(addCSRButton)
diff --git a/ui/src/app/nav.tsx b/ui/src/app/nav.tsx
index d905608..82bf2d7 100644
--- a/ui/src/app/nav.tsx
+++ b/ui/src/app/nav.tsx
@@ -1,6 +1,7 @@
"use client"
-import { SetStateAction, Dispatch, useState, createContext, useEffect , ChangeEvent} from "react"
+import { SetStateAction, Dispatch, useState, createContext, useEffect, ChangeEvent } from "react"
+import { QueryClient, QueryClientProvider } from "react-query";
import Image from "next/image";
type AsideContextType = {
@@ -24,10 +25,10 @@ export function Aside({ isOpen, setIsOpen }: { isOpen: boolean, setIsOpen: Dispa
setCSRPEMString(e.target.result.toString());
}
}
- };
- reader.readAsText(file);
+ };
+ reader.readAsText(file);
}
- };
+ };
return (