wip: Create some frontend components to test API generation

This commit is contained in:
Magnus Leßmann (@Mark.TwoFive) 2025-06-21 14:06:44 +02:00
parent 532d37ce81
commit e91bf96e74
Signed by: Mark.TwoFive
GPG key ID: 58204042FE30B10C
10 changed files with 138 additions and 6 deletions

3
frontend/.gitignore vendored
View file

@ -20,3 +20,6 @@ pnpm-debug.log*
*.njsproj
*.sln
*.sw?
# Generated source files
src/generated/

View file

@ -39,7 +39,7 @@
rounded="lg"
title="Manage your certificates"
variant="text"
to="/cert-request"
to="/certificates"
/>
</v-col>

View file

@ -0,0 +1,34 @@
<script setup lang="ts">
import { onMounted, ref } from "vue";
import { fetchClient, type Schemas } from "@/plugins/client.ts";
import { useRoute } from "vue-router";
const route = useRoute();
const certificate = ref<Schemas["Certificate"] | null>(null);
async function getCertificate() {
const fingerprint = route.params.fingerprint as string;
const response = await fetchClient.GET("/api/certificates/{fingerprint}", {
params: {
path: {
fingerprint,
}
}
});
certificate.value = response.data ?? null;
}
onMounted(() => {
getCertificate()
});
</script>
<template>
<main>
<form v-if="certificate">
<h2>Details des Zertifikats: {{ certificate.fingerprint }}</h2>
</form>
</main>
</template>

View file

@ -0,0 +1,49 @@
<script setup lang="ts">
import { onMounted, ref } from "vue";
import { fetchClient, type Schemas } from "@/plugins/client.ts";
const certificates = ref<Schemas["Certificate"][]>([]);
async function getCertificates() {
const response = await fetchClient.GET("/api/certificates");
certificates.value = response.data?.content ?? [];
}
onMounted(() => {
getCertificates();
});
</script>
<template>
<main>
<h2>Currently known certificates</h2>
<section id="no-certs-found" v-if="certificates.length === 0">
<v-row>
<v-col cols="12" class="text-center">
<h3>There seems to be nothing in here.</h3>
<p>Why don't you start with one of the following options.</p>
<v-row>
<v-col cols="12" md="6">
<v-btn primary>Request new certificate</v-btn>
</v-col>
<v-col cols="12" md="6">
<v-btn>Import an existing certificate</v-btn>
</v-col>
</v-row>
</v-col>
</v-row>
</section>
<section aria-label="Bekannte Zertifikate">
<ul v-if="certificates.length > 0">
<li v-for="cert in certificates" :key="cert.fingerprint">
<p>{{ cert.fingerprint }}</p>
</li>
</ul>
</section>
</main>
</template>
<style scoped>
</style>

View file

@ -0,0 +1,11 @@
<script setup lang="ts">
</script>
<template>
<h2>New certificate</h2>
</template>
<style scoped>
</style>

View file

@ -0,0 +1,18 @@
import createFetchClient from "openapi-fetch";
import type { components, paths } from "@/generated/api-spec.ts";
import type { App } from "vue";
export const fetchClient = createFetchClient<paths>({
baseUrl: "http://localhost:8080"
});
export type Schemas = components["schemas"];
// noinspection JSUnusedGlobalSymbols
const $api = {
install: (app: App) => {
app.config.globalProperties.$api = fetchClient;
}
}
export default $api;

View file

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

View file

@ -20,5 +20,8 @@ declare module 'vue-router/auto-routes' {
export interface RouteNamedMap {
'/': RouteRecordInfo<'/', '/', Record<never, never>, Record<never, never>>,
'/cert-request': RouteRecordInfo<'/cert-request', '/cert-request', Record<never, never>, Record<never, never>>,
'/certificates/': RouteRecordInfo<'/certificates/', '/certificates', Record<never, never>, Record<never, never>>,
'/certificates/[fingerprint]': RouteRecordInfo<'/certificates/[fingerprint]', '/certificates/:fingerprint', { fingerprint: ParamValue<true> }, { fingerprint: ParamValue<false> }>,
'/certificates/new': RouteRecordInfo<'/certificates/new', '/certificates/new', Record<never, never>, Record<never, never>>,
}
}

View file

@ -16,7 +16,7 @@ public class SecurityConfiguration {
// Allow unauthenticated access to OpenAPI and swagger documentation.
// This should be removed or at least configurable at some point, but for now, this is fine (tm)
http.authorizeHttpRequests(auth -> auth
.requestMatchers("/v3/api-docs/**", "/swagger-ui/**", "/swagger-ui.html")
.requestMatchers("/v3/api-docs/**", "/v3/api-docs.yaml", "/swagger-ui/**", "/swagger-ui.html")
.permitAll());
return http.build();
}

View file

@ -38,6 +38,18 @@ public class CertificatesEndpoint {
return ResponseEntity.ok(DocumentedPage.of(certificates));
}
@GetMapping("/certificates/{fingerprint}")
@Operation(
description = "Fetches a single certificate by the provided fingerprint",
responses = {
@ApiResponse(responseCode = "200")
}
)
public ResponseEntity<Certificate> getCertificate(@PathVariable String fingerprint) {
var certificate = certificateRepository.findByFingerprintIs(fingerprint);
return ResponseEntity.ok(certificate);
}
@PostMapping("/certificates")
@Operation(description = "Requests a new certificate", responses = {
@ApiResponse(responseCode = "400", description = "One of the provided parameters is invalid."),