wip: Create some frontend components to test API generation
This commit is contained in:
parent
532d37ce81
commit
e91bf96e74
10 changed files with 138 additions and 6 deletions
3
frontend/.gitignore
vendored
3
frontend/.gitignore
vendored
|
@ -20,3 +20,6 @@ pnpm-debug.log*
|
||||||
*.njsproj
|
*.njsproj
|
||||||
*.sln
|
*.sln
|
||||||
*.sw?
|
*.sw?
|
||||||
|
|
||||||
|
# Generated source files
|
||||||
|
src/generated/
|
|
@ -39,7 +39,7 @@
|
||||||
rounded="lg"
|
rounded="lg"
|
||||||
title="Manage your certificates"
|
title="Manage your certificates"
|
||||||
variant="text"
|
variant="text"
|
||||||
to="/cert-request"
|
to="/certificates"
|
||||||
/>
|
/>
|
||||||
</v-col>
|
</v-col>
|
||||||
|
|
||||||
|
|
34
frontend/src/pages/certificates/[fingerprint].vue
Normal file
34
frontend/src/pages/certificates/[fingerprint].vue
Normal 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>
|
49
frontend/src/pages/certificates/index.vue
Normal file
49
frontend/src/pages/certificates/index.vue
Normal 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>
|
11
frontend/src/pages/certificates/new.vue
Normal file
11
frontend/src/pages/certificates/new.vue
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<h2>New certificate</h2>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
18
frontend/src/plugins/client.ts
Normal file
18
frontend/src/plugins/client.ts
Normal 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;
|
|
@ -1,10 +1,12 @@
|
||||||
import vuetify from './vuetify'
|
import vuetify from "./vuetify";
|
||||||
import router from '../router'
|
import router from "../router";
|
||||||
|
import client from "./client";
|
||||||
|
|
||||||
import type { App } from 'vue'
|
import type { App } from "vue";
|
||||||
|
|
||||||
export function registerPlugins (app: App) {
|
export function registerPlugins(app: App) {
|
||||||
app
|
app
|
||||||
.use(vuetify)
|
.use(vuetify)
|
||||||
.use(router)
|
.use(router)
|
||||||
|
.use(client);
|
||||||
}
|
}
|
||||||
|
|
3
frontend/typed-router.d.ts
vendored
3
frontend/typed-router.d.ts
vendored
|
@ -20,5 +20,8 @@ declare module 'vue-router/auto-routes' {
|
||||||
export interface RouteNamedMap {
|
export interface RouteNamedMap {
|
||||||
'/': RouteRecordInfo<'/', '/', Record<never, never>, Record<never, never>>,
|
'/': RouteRecordInfo<'/', '/', Record<never, never>, Record<never, never>>,
|
||||||
'/cert-request': RouteRecordInfo<'/cert-request', '/cert-request', 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>>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ public class SecurityConfiguration {
|
||||||
// Allow unauthenticated access to OpenAPI and swagger documentation.
|
// 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)
|
// This should be removed or at least configurable at some point, but for now, this is fine (tm)
|
||||||
http.authorizeHttpRequests(auth -> auth
|
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());
|
.permitAll());
|
||||||
return http.build();
|
return http.build();
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,18 @@ public class CertificatesEndpoint {
|
||||||
return ResponseEntity.ok(DocumentedPage.of(certificates));
|
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")
|
@PostMapping("/certificates")
|
||||||
@Operation(description = "Requests a new certificate", responses = {
|
@Operation(description = "Requests a new certificate", responses = {
|
||||||
@ApiResponse(responseCode = "400", description = "One of the provided parameters is invalid."),
|
@ApiResponse(responseCode = "400", description = "One of the provided parameters is invalid."),
|
||||||
|
|
Loading…
Add table
Reference in a new issue