Compare commits

..

3 commits

Author SHA1 Message Date
22eae92cba
wip: Start work on submitting the cert
Some checks failed
Build / build (pull_request) Successful in 54s
Check formatting / check-formatting (pull_request) Failing after 17s
2025-07-14 22:11:18 +02:00
651c205656
feat: Install tanstack query for Vue 2025-07-14 22:10:51 +02:00
13efdd06b9
wip: Prepare CertificateEditor for submitting a certificate 2025-07-14 21:51:11 +02:00
5 changed files with 107 additions and 31 deletions

View file

@ -14,6 +14,7 @@
}, },
"dependencies": { "dependencies": {
"@mdi/font": "7.4.47", "@mdi/font": "7.4.47",
"@tanstack/vue-query": "^5.83.0",
"core-js": "^3.41.0", "core-js": "^3.41.0",
"iso-3166-1": "^2.1.1", "iso-3166-1": "^2.1.1",
"openapi-fetch": "^0.14.0", "openapi-fetch": "^0.14.0",

View file

@ -11,6 +11,9 @@ importers:
'@mdi/font': '@mdi/font':
specifier: 7.4.47 specifier: 7.4.47
version: 7.4.47 version: 7.4.47
'@tanstack/vue-query':
specifier: ^5.83.0
version: 5.83.0(vue@3.5.13(typescript@5.8.3))
core-js: core-js:
specifier: ^3.41.0 specifier: ^3.41.0
version: 3.41.0 version: 3.41.0
@ -798,6 +801,22 @@ packages:
resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==}
engines: {node: '>=18'} engines: {node: '>=18'}
'@tanstack/match-sorter-utils@8.19.4':
resolution: {integrity: sha512-Wo1iKt2b9OT7d+YGhvEPD3DXvPv2etTusIMhMUoG7fbhmxcXCtIjJDEygy91Y2JFlwGyjqiBPRozme7UD8hoqg==}
engines: {node: '>=12'}
'@tanstack/query-core@5.83.0':
resolution: {integrity: sha512-0M8dA+amXUkyz5cVUm/B+zSk3xkQAcuXuz5/Q/LveT4ots2rBpPTZOzd7yJa2Utsf8D2Upl5KyjhHRY+9lB/XA==}
'@tanstack/vue-query@5.83.0':
resolution: {integrity: sha512-sC3nnFEyAPOV4aGgt36ILrFIoR42UzRb+kqva96tiT3c80PCX99wDnVC5P01uxw6b3PaH7AD60HFFLBMFCKYow==}
peerDependencies:
'@vue/composition-api': ^1.1.2
vue: ^2.6.0 || ^3.3.0
peerDependenciesMeta:
'@vue/composition-api':
optional: true
'@tsconfig/node22@22.0.1': '@tsconfig/node22@22.0.1':
resolution: {integrity: sha512-VkgOa3n6jvs1p+r3DiwBqeEwGAwEvnVCg/hIjiANl5IEcqP3G0u5m8cBJspe1t9qjZRlZ7WFgqq5bJrGdgAKMg==} resolution: {integrity: sha512-VkgOa3n6jvs1p+r3DiwBqeEwGAwEvnVCg/hIjiANl5IEcqP3G0u5m8cBJspe1t9qjZRlZ7WFgqq5bJrGdgAKMg==}
@ -1934,6 +1953,9 @@ packages:
resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==}
engines: {node: '>= 14.18.0'} engines: {node: '>= 14.18.0'}
remove-accents@0.5.0:
resolution: {integrity: sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A==}
request-light@0.7.0: request-light@0.7.0:
resolution: {integrity: sha512-lMbBMrDoxgsyO+yB3sDcrDuX85yYt7sS8BfQd11jtbW/z5ZWgLZRcEGLsLoYw7I0WSUGQBs8CC8ScIxkTX1+6Q==} resolution: {integrity: sha512-lMbBMrDoxgsyO+yB3sDcrDuX85yYt7sS8BfQd11jtbW/z5ZWgLZRcEGLsLoYw7I0WSUGQBs8CC8ScIxkTX1+6Q==}
@ -2502,6 +2524,17 @@ packages:
vscode-uri@3.0.8: vscode-uri@3.0.8:
resolution: {integrity: sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==} resolution: {integrity: sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==}
vue-demi@0.14.10:
resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==}
engines: {node: '>=12'}
hasBin: true
peerDependencies:
'@vue/composition-api': ^1.0.0-rc.1
vue: ^3.0.0-0 || ^2.6.0
peerDependenciesMeta:
'@vue/composition-api':
optional: true
vue-eslint-parser@10.1.3: vue-eslint-parser@10.1.3:
resolution: {integrity: sha512-dbCBnd2e02dYWsXoqX5yKUZlOt+ExIpq7hmHKPb5ZqKcjf++Eo0hMseFTZMLKThrUk61m+Uv6A2YSBve6ZvuDQ==} resolution: {integrity: sha512-dbCBnd2e02dYWsXoqX5yKUZlOt+ExIpq7hmHKPb5ZqKcjf++Eo0hMseFTZMLKThrUk61m+Uv6A2YSBve6ZvuDQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
@ -3235,6 +3268,20 @@ snapshots:
'@sindresorhus/merge-streams@4.0.0': {} '@sindresorhus/merge-streams@4.0.0': {}
'@tanstack/match-sorter-utils@8.19.4':
dependencies:
remove-accents: 0.5.0
'@tanstack/query-core@5.83.0': {}
'@tanstack/vue-query@5.83.0(vue@3.5.13(typescript@5.8.3))':
dependencies:
'@tanstack/match-sorter-utils': 8.19.4
'@tanstack/query-core': 5.83.0
'@vue/devtools-api': 6.6.4
vue: 3.5.13(typescript@5.8.3)
vue-demi: 0.14.10(vue@3.5.13(typescript@5.8.3))
'@tsconfig/node22@22.0.1': {} '@tsconfig/node22@22.0.1': {}
'@types/cookie@0.6.0': {} '@types/cookie@0.6.0': {}
@ -4486,6 +4533,8 @@ snapshots:
readdirp@4.1.2: {} readdirp@4.1.2: {}
remove-accents@0.5.0: {}
request-light@0.7.0: {} request-light@0.7.0: {}
require-directory@2.1.1: {} require-directory@2.1.1: {}
@ -5027,6 +5076,10 @@ snapshots:
vscode-uri@3.0.8: {} vscode-uri@3.0.8: {}
vue-demi@0.14.10(vue@3.5.13(typescript@5.8.3)):
dependencies:
vue: 3.5.13(typescript@5.8.3)
vue-eslint-parser@10.1.3(eslint@9.24.0): vue-eslint-parser@10.1.3(eslint@9.24.0):
dependencies: dependencies:
debug: 4.4.0(supports-color@10.0.0) debug: 4.4.0(supports-color@10.0.0)

View file

@ -1,7 +1,12 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, ref, useId, useTemplateRef } from "vue"; import { ref, useId, useTemplateRef } from "vue";
import CountryListItem from "./CountryListItem.vue"; import CountryListItem from "./CountryListItem.vue";
import { type Country, getAvailableCountries, userCountry } from "../utils/countries.ts"; import { type Country, getAvailableCountries, userCountry } from "../utils/countries.ts";
import { type Schemas } from "../plugins/client.ts";
const { isSubmitting } = defineProps({
isSubmitting: Boolean,
})
const formModel = ref(false); const formModel = ref(false);
const formRef = useTemplateRef("form"); const formRef = useTemplateRef("form");
@ -63,41 +68,40 @@ function addDomain() {
} }
} }
const isSubmitting = ref(false); const emit = defineEmits(["submit"]);
async function submitNewCertificate() { async function submitNewCertificate() {
if (!formRef.value?.validate()) { if (!formRef.value?.validate()) {
return; return;
} }
isSubmitting.value = true; // Extract country code if country is an object
try { const countryCode = typeof country.value === "object" && country.value !== null
// Extract country code if country is an object ? (country.value as Country).alpha2
const countryCode = typeof country.value === "object" && country.value !== null : country.value;
? (country.value as Country).alpha2
: country.value;
// TODO: Implement certificate request submission // Prepare certificate request data
console.log({ const certificateRequest: Schemas["CertificateInfo"] = {
type: "STANDALONE_CERTIFICATE", type: "STANDALONE_CERTIFICATE",
requestedKeyLength: keyLength.value, requestedKeyLength: keyLength.value,
requestedValidityDays: noExpiry.value ? null : validityDays.value, requestedValidityDays: noExpiry.value ? undefined : validityDays.value,
subject: { subject: {
commonName: commonName.value, commonName: commonName.value,
emailAddress: emailAddress.value, emailAddress: emailAddress.value,
organization: organization.value, organization: organization.value,
organizationalUnit: organizationalUnit.value, organizationalUnit: organizationalUnit.value,
country: countryCode, country: countryCode,
state: state.value, state: state.value,
locality: locality.value locality: locality.value
}, },
extension: { extension: {
alternativeDnsNames: domains.value alternativeDnsNames: domains.value
} }
}); };
} finally {
isSubmitting.value = false; emit("submit", {
} certificateRequest
});
} }
</script> </script>

View file

@ -1,10 +1,26 @@
<script setup lang="ts"> <script setup lang="ts">
import CertificateEditor from "@/components/CertificateEditor.vue"; import CertificateEditor from "@/components/CertificateEditor.vue";
import { useMutation } from "@tanstack/vue-query";
import { fetchClient } from "@/plugins/client.ts";
const submitNewCert = useMutation({
mutationKey: ["submit-new-certificate"],
mutationFn: async (certificate) => {
fetchClient.POST("/api/certificates", {
body: certificate,
})
},
})
function submitCertificate({ certificate }) {
submitNewCert.mutate(certificate);
}
</script> </script>
<template> <template>
<v-container> <v-container>
<CertificateEditor /> <CertificateEditor @submit="submitCertificate" :is-submitting="submitNewCert.isPending" />
</v-container> </v-container>
</template> </template>

View file

@ -3,10 +3,12 @@ import router from "../router";
import client from "./client"; import client from "./client";
import type { App } from "vue"; import type { App } from "vue";
import { VueQueryPlugin } from "@tanstack/vue-query";
export function registerPlugins(app: App) { export function registerPlugins(app: App) {
app app
.use(vuetify) .use(vuetify)
.use(router) .use(router)
.use(client); .use(client)
.use(VueQueryPlugin);
} }