From e91bf96e743239031d4de2013243279e3054e3e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20Le=C3=9Fmann=20=28=40Mark=2ETwoFive=29?= Date: Sat, 21 Jun 2025 14:06:44 +0200 Subject: [PATCH 1/2] wip: Create some frontend components to test API generation --- frontend/.gitignore | 3 ++ frontend/src/components/Home.vue | 2 +- .../src/pages/certificates/[fingerprint].vue | 34 +++++++++++++ frontend/src/pages/certificates/index.vue | 49 +++++++++++++++++++ frontend/src/pages/certificates/new.vue | 11 +++++ frontend/src/plugins/client.ts | 18 +++++++ frontend/src/plugins/index.ts | 10 ++-- frontend/typed-router.d.ts | 3 ++ .../config/SecurityConfiguration.java | 2 +- .../certassist/web/CertificatesEndpoint.java | 12 +++++ 10 files changed, 138 insertions(+), 6 deletions(-) create mode 100644 frontend/src/pages/certificates/[fingerprint].vue create mode 100644 frontend/src/pages/certificates/index.vue create mode 100644 frontend/src/pages/certificates/new.vue create mode 100644 frontend/src/plugins/client.ts diff --git a/frontend/.gitignore b/frontend/.gitignore index 11f5d71..b5bcb0c 100644 --- a/frontend/.gitignore +++ b/frontend/.gitignore @@ -20,3 +20,6 @@ pnpm-debug.log* *.njsproj *.sln *.sw? + +# Generated source files +src/generated/ \ No newline at end of file diff --git a/frontend/src/components/Home.vue b/frontend/src/components/Home.vue index 64c98ce..4906cef 100644 --- a/frontend/src/components/Home.vue +++ b/frontend/src/components/Home.vue @@ -39,7 +39,7 @@ rounded="lg" title="Manage your certificates" variant="text" - to="/cert-request" + to="/certificates" /> diff --git a/frontend/src/pages/certificates/[fingerprint].vue b/frontend/src/pages/certificates/[fingerprint].vue new file mode 100644 index 0000000..17c9dd8 --- /dev/null +++ b/frontend/src/pages/certificates/[fingerprint].vue @@ -0,0 +1,34 @@ + + + diff --git a/frontend/src/pages/certificates/index.vue b/frontend/src/pages/certificates/index.vue new file mode 100644 index 0000000..924b91b --- /dev/null +++ b/frontend/src/pages/certificates/index.vue @@ -0,0 +1,49 @@ + + + + + diff --git a/frontend/src/pages/certificates/new.vue b/frontend/src/pages/certificates/new.vue new file mode 100644 index 0000000..1837583 --- /dev/null +++ b/frontend/src/pages/certificates/new.vue @@ -0,0 +1,11 @@ + + + + + diff --git a/frontend/src/plugins/client.ts b/frontend/src/plugins/client.ts new file mode 100644 index 0000000..90105c8 --- /dev/null +++ b/frontend/src/plugins/client.ts @@ -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({ + baseUrl: "http://localhost:8080" +}); + +export type Schemas = components["schemas"]; + +// noinspection JSUnusedGlobalSymbols +const $api = { + install: (app: App) => { + app.config.globalProperties.$api = fetchClient; + } +} + +export default $api; diff --git a/frontend/src/plugins/index.ts b/frontend/src/plugins/index.ts index cd3a681..17430da 100644 --- a/frontend/src/plugins/index.ts +++ b/frontend/src/plugins/index.ts @@ -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) { +export function registerPlugins(app: App) { app .use(vuetify) .use(router) + .use(client); } diff --git a/frontend/typed-router.d.ts b/frontend/typed-router.d.ts index 8d7445f..3530519 100644 --- a/frontend/typed-router.d.ts +++ b/frontend/typed-router.d.ts @@ -20,5 +20,8 @@ declare module 'vue-router/auto-routes' { export interface RouteNamedMap { '/': RouteRecordInfo<'/', '/', Record, Record>, '/cert-request': RouteRecordInfo<'/cert-request', '/cert-request', Record, Record>, + '/certificates/': RouteRecordInfo<'/certificates/', '/certificates', Record, Record>, + '/certificates/[fingerprint]': RouteRecordInfo<'/certificates/[fingerprint]', '/certificates/:fingerprint', { fingerprint: ParamValue }, { fingerprint: ParamValue }>, + '/certificates/new': RouteRecordInfo<'/certificates/new', '/certificates/new', Record, Record>, } } diff --git a/src/main/java/de/mlessmann/certassist/config/SecurityConfiguration.java b/src/main/java/de/mlessmann/certassist/config/SecurityConfiguration.java index c30d79f..14c324a 100644 --- a/src/main/java/de/mlessmann/certassist/config/SecurityConfiguration.java +++ b/src/main/java/de/mlessmann/certassist/config/SecurityConfiguration.java @@ -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(); } diff --git a/src/main/java/de/mlessmann/certassist/web/CertificatesEndpoint.java b/src/main/java/de/mlessmann/certassist/web/CertificatesEndpoint.java index 8737584..27bf6b3 100644 --- a/src/main/java/de/mlessmann/certassist/web/CertificatesEndpoint.java +++ b/src/main/java/de/mlessmann/certassist/web/CertificatesEndpoint.java @@ -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 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."), From b6db17e7d8dcb3589775d89b733da3155e91a245 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20Le=C3=9Fmann=20=28=40Mark=2ETwoFive=29?= Date: Sat, 21 Jun 2025 14:07:27 +0200 Subject: [PATCH 2/2] wip: Remove incompatible react package --- frontend/package.json | 4 ++-- frontend/pnpm-lock.yaml | 36 ------------------------------------ 2 files changed, 2 insertions(+), 38 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 958b923..e0386e7 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -8,6 +8,7 @@ "build": "run-p type-check \"build-only {@}\" --", "preview": "vite preview", "build-only": "vite build", + "update-types": "openapi-typescript http://localhost:8080/v3/api-docs.yaml -o src/generated/api-spec.ts", "type-check": "vue-tsc --build --force", "lint": "eslint . --fix" }, @@ -17,8 +18,7 @@ "roboto-fontface": "*", "vue": "^3.5.13", "vuetify": "^3.8.1", - "openapi-fetch": "^0.14.0", - "openapi-react-query": "^0.5.0" + "openapi-fetch": "^0.14.0" }, "devDependencies": { "@eslint/js": "^9.24.0", diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index 2067bd1..3f65013 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -17,9 +17,6 @@ importers: openapi-fetch: specifier: ^0.14.0 version: 0.14.0 - openapi-react-query: - specifier: ^0.5.0 - version: 0.5.0(@tanstack/react-query@5.80.10(react@19.1.0))(openapi-fetch@0.14.0) roboto-fontface: specifier: '*' version: 0.10.0 @@ -627,14 +624,6 @@ packages: cpu: [x64] os: [win32] - '@tanstack/query-core@5.80.10': - resolution: {integrity: sha512-mUNQOtzxkjL6jLbyChZoSBP6A5gQDVRUiPvW+/zw/9ftOAz+H754zCj3D8PwnzPKyHzGkQ9JbH48ukhym9LK1Q==} - - '@tanstack/react-query@5.80.10': - resolution: {integrity: sha512-6zM098J8sLy9oU60XAdzUlAH4wVzoMVsWUWiiE/Iz4fd67PplxeyL4sw/MPcVJJVhbwGGXCsHn9GrQt2mlAzig==} - peerDependencies: - react: ^18 || ^19 - '@tsconfig/node22@22.0.1': resolution: {integrity: sha512-VkgOa3n6jvs1p+r3DiwBqeEwGAwEvnVCg/hIjiANl5IEcqP3G0u5m8cBJspe1t9qjZRlZ7WFgqq5bJrGdgAKMg==} @@ -1458,12 +1447,6 @@ packages: openapi-fetch@0.14.0: resolution: {integrity: sha512-PshIdm1NgdLvb05zp8LqRQMNSKzIlPkyMxYFxwyHR+UlKD4t2nUjkDhNxeRbhRSEd3x5EUNh2w5sJYwkhOH4fg==} - openapi-react-query@0.5.0: - resolution: {integrity: sha512-VtyqiamsbWsdSWtXmj/fAR+m9nNxztsof6h8ZIsjRj8c8UR/x9AIwHwd60IqwgymmFwo7qfSJQ1ZzMJrtqjQVg==} - peerDependencies: - '@tanstack/react-query': ^5.25.0 - openapi-fetch: ^0.14.0 - openapi-typescript-helpers@0.0.15: resolution: {integrity: sha512-opyTPaunsklCBpTK8JGef6mfPhLSnyy5a0IN9vKtx3+4aExf+KxEqYwIy3hqkedXIB97u357uLMJsOnm3GVjsw==} @@ -1583,10 +1566,6 @@ packages: queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - react@19.1.0: - resolution: {integrity: sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==} - engines: {node: '>=0.10.0'} - read-package-json-fast@4.0.0: resolution: {integrity: sha512-qpt8EwugBWDw2cgE2W+/3oxC+KTez2uSVR8JU9Q36TXPAGCaozfQUs59v4j4GFpWTaw0i6hAZSvOmu1J0uOEUg==} engines: {node: ^18.17.0 || >=20.5.0} @@ -2606,13 +2585,6 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.40.0': optional: true - '@tanstack/query-core@5.80.10': {} - - '@tanstack/react-query@5.80.10(react@19.1.0)': - dependencies: - '@tanstack/query-core': 5.80.10 - react: 19.1.0 - '@tsconfig/node22@22.0.1': {} '@types/cookie@0.6.0': {} @@ -3543,12 +3515,6 @@ snapshots: dependencies: openapi-typescript-helpers: 0.0.15 - openapi-react-query@0.5.0(@tanstack/react-query@5.80.10(react@19.1.0))(openapi-fetch@0.14.0): - dependencies: - '@tanstack/react-query': 5.80.10(react@19.1.0) - openapi-fetch: 0.14.0 - openapi-typescript-helpers: 0.0.15 - openapi-typescript-helpers@0.0.15: {} openapi-typescript@7.8.0(typescript@5.8.3): @@ -3668,8 +3634,6 @@ snapshots: queue-microtask@1.2.3: {} - react@19.1.0: {} - read-package-json-fast@4.0.0: dependencies: json-parse-even-better-errors: 4.0.0