Compare commits
No commits in common. "feat/openApiIntegration" and "main" have entirely different histories.
feat/openA
...
main
22 changed files with 24 additions and 606 deletions
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -39,7 +39,4 @@ out/
|
||||||
|
|
||||||
### Test files ###
|
### Test files ###
|
||||||
sqLiteDb.db
|
sqLiteDb.db
|
||||||
dev/
|
dev/
|
||||||
|
|
||||||
### Development settings ###
|
|
||||||
application.properties
|
|
|
@ -1,8 +1,8 @@
|
||||||
plugins {
|
plugins {
|
||||||
java
|
java
|
||||||
id("org.springframework.boot") version "3.5.0"
|
id("org.springframework.boot") version "3.3.5"
|
||||||
id("io.spring.dependency-management") version "1.1.7"
|
id("io.spring.dependency-management") version "1.1.6"
|
||||||
id("com.diffplug.spotless") version "7.0.4"
|
id("com.diffplug.spotless") version "6.25.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "io.github.markl4yg.hca"
|
group = "io.github.markl4yg.hca"
|
||||||
|
@ -42,7 +42,6 @@ dependencies {
|
||||||
|
|
||||||
implementation("org.springframework.boot:spring-boot-starter-security")
|
implementation("org.springframework.boot:spring-boot-starter-security")
|
||||||
implementation("org.springframework.boot:spring-boot-starter-web")
|
implementation("org.springframework.boot:spring-boot-starter-web")
|
||||||
implementation("org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.9")
|
|
||||||
|
|
||||||
implementation("org.flywaydb:flyway-core")
|
implementation("org.flywaydb:flyway-core")
|
||||||
|
|
||||||
|
|
3
frontend/.gitignore
vendored
3
frontend/.gitignore
vendored
|
@ -20,6 +20,3 @@ pnpm-debug.log*
|
||||||
*.njsproj
|
*.njsproj
|
||||||
*.sln
|
*.sln
|
||||||
*.sw?
|
*.sw?
|
||||||
|
|
||||||
# Generated source files
|
|
||||||
src/generated/
|
|
|
@ -8,7 +8,6 @@
|
||||||
"build": "run-p type-check \"build-only {@}\" --",
|
"build": "run-p type-check \"build-only {@}\" --",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"build-only": "vite build",
|
"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",
|
"type-check": "vue-tsc --build --force",
|
||||||
"lint": "eslint . --fix"
|
"lint": "eslint . --fix"
|
||||||
},
|
},
|
||||||
|
@ -17,8 +16,7 @@
|
||||||
"core-js": "^3.41.0",
|
"core-js": "^3.41.0",
|
||||||
"roboto-fontface": "*",
|
"roboto-fontface": "*",
|
||||||
"vue": "^3.5.13",
|
"vue": "^3.5.13",
|
||||||
"vuetify": "^3.8.1",
|
"vuetify": "^3.8.1"
|
||||||
"openapi-fetch": "^0.14.0"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/js": "^9.24.0",
|
"@eslint/js": "^9.24.0",
|
||||||
|
@ -33,7 +31,6 @@
|
||||||
"eslint-plugin-vue": "^10.0.0",
|
"eslint-plugin-vue": "^10.0.0",
|
||||||
"msw": "^2.7.4",
|
"msw": "^2.7.4",
|
||||||
"npm-run-all2": "^7.0.2",
|
"npm-run-all2": "^7.0.2",
|
||||||
"openapi-typescript": "^7.8.0",
|
|
||||||
"sass": "1.86.3",
|
"sass": "1.86.3",
|
||||||
"sass-embedded": "^1.86.3",
|
"sass-embedded": "^1.86.3",
|
||||||
"typescript": "^5.8.3",
|
"typescript": "^5.8.3",
|
||||||
|
|
198
frontend/pnpm-lock.yaml
generated
198
frontend/pnpm-lock.yaml
generated
|
@ -14,9 +14,6 @@ importers:
|
||||||
core-js:
|
core-js:
|
||||||
specifier: ^3.41.0
|
specifier: ^3.41.0
|
||||||
version: 3.41.0
|
version: 3.41.0
|
||||||
openapi-fetch:
|
|
||||||
specifier: ^0.14.0
|
|
||||||
version: 0.14.0
|
|
||||||
roboto-fontface:
|
roboto-fontface:
|
||||||
specifier: '*'
|
specifier: '*'
|
||||||
version: 0.10.0
|
version: 0.10.0
|
||||||
|
@ -63,9 +60,6 @@ importers:
|
||||||
npm-run-all2:
|
npm-run-all2:
|
||||||
specifier: ^7.0.2
|
specifier: ^7.0.2
|
||||||
version: 7.0.2
|
version: 7.0.2
|
||||||
openapi-typescript:
|
|
||||||
specifier: ^7.8.0
|
|
||||||
version: 7.8.0(typescript@5.8.3)
|
|
||||||
sass:
|
sass:
|
||||||
specifier: 1.86.3
|
specifier: 1.86.3
|
||||||
version: 1.86.3
|
version: 1.86.3
|
||||||
|
@ -99,10 +93,6 @@ importers:
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
|
|
||||||
'@babel/code-frame@7.27.1':
|
|
||||||
resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==}
|
|
||||||
engines: {node: '>=6.9.0'}
|
|
||||||
|
|
||||||
'@babel/helper-string-parser@7.25.9':
|
'@babel/helper-string-parser@7.25.9':
|
||||||
resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==}
|
resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
|
@ -111,10 +101,6 @@ packages:
|
||||||
resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==}
|
resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
|
|
||||||
'@babel/helper-validator-identifier@7.27.1':
|
|
||||||
resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==}
|
|
||||||
engines: {node: '>=6.9.0'}
|
|
||||||
|
|
||||||
'@babel/parser@7.26.2':
|
'@babel/parser@7.26.2':
|
||||||
resolution: {integrity: sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==}
|
resolution: {integrity: sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==}
|
||||||
engines: {node: '>=6.0.0'}
|
engines: {node: '>=6.0.0'}
|
||||||
|
@ -514,16 +500,6 @@ packages:
|
||||||
resolution: {integrity: sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==}
|
resolution: {integrity: sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==}
|
||||||
engines: {node: '>= 10.0.0'}
|
engines: {node: '>= 10.0.0'}
|
||||||
|
|
||||||
'@redocly/ajv@8.11.2':
|
|
||||||
resolution: {integrity: sha512-io1JpnwtIcvojV7QKDUSIuMN/ikdOUd1ReEnUnMKGfDVridQZ31J0MmIuqwuRjWDZfmvr+Q0MqCcfHM2gTivOg==}
|
|
||||||
|
|
||||||
'@redocly/config@0.22.2':
|
|
||||||
resolution: {integrity: sha512-roRDai8/zr2S9YfmzUfNhKjOF0NdcOIqF7bhf4MVC5UxpjIysDjyudvlAiVbpPHp3eDRWbdzUgtkK1a7YiDNyQ==}
|
|
||||||
|
|
||||||
'@redocly/openapi-core@1.34.3':
|
|
||||||
resolution: {integrity: sha512-3arRdUp1fNx55itnjKiUhO6t4Mf91TsrTIYINDNLAZPS0TPd5YpiXRctwjel0qqWoOOhjA34cZ3m4dksLDFUYg==}
|
|
||||||
engines: {node: '>=18.17.0', npm: '>=9.5.0'}
|
|
||||||
|
|
||||||
'@rollup/rollup-android-arm-eabi@4.40.0':
|
'@rollup/rollup-android-arm-eabi@4.40.0':
|
||||||
resolution: {integrity: sha512-+Fbls/diZ0RDerhE8kyC6hjADCXA1K4yVNlH0EYfd2XjyH0UGgzaQ8MlT0pCXAThfxv3QUAczHaL+qSv1E4/Cg==}
|
resolution: {integrity: sha512-+Fbls/diZ0RDerhE8kyC6hjADCXA1K4yVNlH0EYfd2XjyH0UGgzaQ8MlT0pCXAThfxv3QUAczHaL+qSv1E4/Cg==}
|
||||||
cpu: [arm]
|
cpu: [arm]
|
||||||
|
@ -842,20 +818,12 @@ packages:
|
||||||
engines: {node: '>=0.4.0'}
|
engines: {node: '>=0.4.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
agent-base@7.1.3:
|
|
||||||
resolution: {integrity: sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==}
|
|
||||||
engines: {node: '>= 14'}
|
|
||||||
|
|
||||||
ajv@6.12.6:
|
ajv@6.12.6:
|
||||||
resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
|
resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
|
||||||
|
|
||||||
alien-signals@1.0.13:
|
alien-signals@1.0.13:
|
||||||
resolution: {integrity: sha512-OGj9yyTnJEttvzhTUWuscOvtqxq5vrhF7vL9oS0xJ2mK0ItPYP1/y+vCFebfxoEyAz0++1AIwJ5CMr+Fk3nDmg==}
|
resolution: {integrity: sha512-OGj9yyTnJEttvzhTUWuscOvtqxq5vrhF7vL9oS0xJ2mK0ItPYP1/y+vCFebfxoEyAz0++1AIwJ5CMr+Fk3nDmg==}
|
||||||
|
|
||||||
ansi-colors@4.1.3:
|
|
||||||
resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==}
|
|
||||||
engines: {node: '>=6'}
|
|
||||||
|
|
||||||
ansi-escapes@4.3.2:
|
ansi-escapes@4.3.2:
|
||||||
resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==}
|
resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
@ -930,9 +898,6 @@ packages:
|
||||||
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
|
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
change-case@5.4.4:
|
|
||||||
resolution: {integrity: sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==}
|
|
||||||
|
|
||||||
character-parser@2.2.0:
|
character-parser@2.2.0:
|
||||||
resolution: {integrity: sha512-+UqJQjFEFaTAs3bNsF2j2kEN1baG/zghZbdqoYEDxGZtJo9LBzl1A+m0D4n3qKx8N2FNv8/Xp6yV9mQmBuptaw==}
|
resolution: {integrity: sha512-+UqJQjFEFaTAs3bNsF2j2kEN1baG/zghZbdqoYEDxGZtJo9LBzl1A+m0D4n3qKx8N2FNv8/Xp6yV9mQmBuptaw==}
|
||||||
|
|
||||||
|
@ -959,9 +924,6 @@ packages:
|
||||||
color-name@1.1.4:
|
color-name@1.1.4:
|
||||||
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
|
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
|
||||||
|
|
||||||
colorette@1.4.0:
|
|
||||||
resolution: {integrity: sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==}
|
|
||||||
|
|
||||||
colorjs.io@0.5.2:
|
colorjs.io@0.5.2:
|
||||||
resolution: {integrity: sha512-twmVoizEW7ylZSN32OgKdXRmo1qg+wT5/6C3xu5b9QsWzSFAhHLn2xd8ro0diCsKfCj1RdaTP/nrcW+vAoQPIw==}
|
resolution: {integrity: sha512-twmVoizEW7ylZSN32OgKdXRmo1qg+wT5/6C3xu5b9QsWzSFAhHLn2xd8ro0diCsKfCj1RdaTP/nrcW+vAoQPIw==}
|
||||||
|
|
||||||
|
@ -1229,10 +1191,6 @@ packages:
|
||||||
headers-polyfill@4.0.3:
|
headers-polyfill@4.0.3:
|
||||||
resolution: {integrity: sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==}
|
resolution: {integrity: sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==}
|
||||||
|
|
||||||
https-proxy-agent@7.0.6:
|
|
||||||
resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==}
|
|
||||||
engines: {node: '>= 14'}
|
|
||||||
|
|
||||||
ignore@5.3.2:
|
ignore@5.3.2:
|
||||||
resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
|
resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
|
||||||
engines: {node: '>= 4'}
|
engines: {node: '>= 4'}
|
||||||
|
@ -1248,10 +1206,6 @@ packages:
|
||||||
resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
|
resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
|
||||||
engines: {node: '>=0.8.19'}
|
engines: {node: '>=0.8.19'}
|
||||||
|
|
||||||
index-to-position@1.1.0:
|
|
||||||
resolution: {integrity: sha512-XPdx9Dq4t9Qk1mTMbWONJqU7boCoumEH7fRET37HX5+khDUl3J2W6PdALxhILYlIYx2amlwYcRPp28p0tSiojg==}
|
|
||||||
engines: {node: '>=18'}
|
|
||||||
|
|
||||||
is-binary-path@2.1.0:
|
is-binary-path@2.1.0:
|
||||||
resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
|
resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
@ -1289,13 +1243,6 @@ packages:
|
||||||
resolution: {integrity: sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==}
|
resolution: {integrity: sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==}
|
||||||
engines: {node: '>=16'}
|
engines: {node: '>=16'}
|
||||||
|
|
||||||
js-levenshtein@1.1.6:
|
|
||||||
resolution: {integrity: sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==}
|
|
||||||
engines: {node: '>=0.10.0'}
|
|
||||||
|
|
||||||
js-tokens@4.0.0:
|
|
||||||
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
|
|
||||||
|
|
||||||
js-yaml@4.1.0:
|
js-yaml@4.1.0:
|
||||||
resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
|
resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
@ -1310,9 +1257,6 @@ packages:
|
||||||
json-schema-traverse@0.4.1:
|
json-schema-traverse@0.4.1:
|
||||||
resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
|
resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
|
||||||
|
|
||||||
json-schema-traverse@1.0.0:
|
|
||||||
resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
|
|
||||||
|
|
||||||
json-stable-stringify-without-jsonify@1.0.1:
|
json-stable-stringify-without-jsonify@1.0.1:
|
||||||
resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
|
resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
|
||||||
|
|
||||||
|
@ -1377,10 +1321,6 @@ packages:
|
||||||
minimatch@3.1.2:
|
minimatch@3.1.2:
|
||||||
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
|
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
|
||||||
|
|
||||||
minimatch@5.1.6:
|
|
||||||
resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==}
|
|
||||||
engines: {node: '>=10'}
|
|
||||||
|
|
||||||
minimatch@9.0.5:
|
minimatch@9.0.5:
|
||||||
resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
|
resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
|
||||||
engines: {node: '>=16 || 14 >=14.17'}
|
engines: {node: '>=16 || 14 >=14.17'}
|
||||||
|
@ -1444,18 +1384,6 @@ packages:
|
||||||
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
|
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
openapi-fetch@0.14.0:
|
|
||||||
resolution: {integrity: sha512-PshIdm1NgdLvb05zp8LqRQMNSKzIlPkyMxYFxwyHR+UlKD4t2nUjkDhNxeRbhRSEd3x5EUNh2w5sJYwkhOH4fg==}
|
|
||||||
|
|
||||||
openapi-typescript-helpers@0.0.15:
|
|
||||||
resolution: {integrity: sha512-opyTPaunsklCBpTK8JGef6mfPhLSnyy5a0IN9vKtx3+4aExf+KxEqYwIy3hqkedXIB97u357uLMJsOnm3GVjsw==}
|
|
||||||
|
|
||||||
openapi-typescript@7.8.0:
|
|
||||||
resolution: {integrity: sha512-1EeVWmDzi16A+siQlo/SwSGIT7HwaFAVjvMA7/jG5HMLSnrUOzPL7uSTRZZa4v/LCRxHTApHKtNY6glApEoiUQ==}
|
|
||||||
hasBin: true
|
|
||||||
peerDependencies:
|
|
||||||
typescript: ^5.x
|
|
||||||
|
|
||||||
optionator@0.9.4:
|
optionator@0.9.4:
|
||||||
resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
|
resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
|
||||||
engines: {node: '>= 0.8.0'}
|
engines: {node: '>= 0.8.0'}
|
||||||
|
@ -1475,10 +1403,6 @@ packages:
|
||||||
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
|
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
|
|
||||||
parse-json@8.3.0:
|
|
||||||
resolution: {integrity: sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==}
|
|
||||||
engines: {node: '>=18'}
|
|
||||||
|
|
||||||
path-browserify@1.0.1:
|
path-browserify@1.0.1:
|
||||||
resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==}
|
resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==}
|
||||||
|
|
||||||
|
@ -1521,10 +1445,6 @@ packages:
|
||||||
pkg-types@2.1.0:
|
pkg-types@2.1.0:
|
||||||
resolution: {integrity: sha512-wmJwA+8ihJixSoHKxZJRBQG1oY8Yr9pGLzRmSsNms0iNWyHHAlZCa7mmKiFR10YPZuz/2k169JiS/inOjBCZ2A==}
|
resolution: {integrity: sha512-wmJwA+8ihJixSoHKxZJRBQG1oY8Yr9pGLzRmSsNms0iNWyHHAlZCa7mmKiFR10YPZuz/2k169JiS/inOjBCZ2A==}
|
||||||
|
|
||||||
pluralize@8.0.0:
|
|
||||||
resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==}
|
|
||||||
engines: {node: '>=4'}
|
|
||||||
|
|
||||||
postcss-selector-parser@6.1.2:
|
postcss-selector-parser@6.1.2:
|
||||||
resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==}
|
resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
|
@ -1585,10 +1505,6 @@ packages:
|
||||||
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
|
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
require-from-string@2.0.2:
|
|
||||||
resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
|
|
||||||
engines: {node: '>=0.10.0'}
|
|
||||||
|
|
||||||
requires-port@1.0.0:
|
requires-port@1.0.0:
|
||||||
resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==}
|
resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==}
|
||||||
|
|
||||||
|
@ -1790,10 +1706,6 @@ packages:
|
||||||
resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
|
resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
supports-color@10.0.0:
|
|
||||||
resolution: {integrity: sha512-HRVVSbCCMbj7/kdWF9Q+bbckjBHLtHMEoJWlkmYzzdwhYMkjkOwubLM6t7NbWKjgKamGDrWL1++KrjUO1t9oAQ==}
|
|
||||||
engines: {node: '>=18'}
|
|
||||||
|
|
||||||
supports-color@7.2.0:
|
supports-color@7.2.0:
|
||||||
resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
|
resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
@ -1846,10 +1758,6 @@ packages:
|
||||||
resolution: {integrity: sha512-yCxltHW07Nkhv/1F6wWBr8kz+5BGMfP+RbRSYFnegVb0qV/UMT0G0ElBloPVerqn4M2ZV80Ir1FtCcYv1cT6vQ==}
|
resolution: {integrity: sha512-yCxltHW07Nkhv/1F6wWBr8kz+5BGMfP+RbRSYFnegVb0qV/UMT0G0ElBloPVerqn4M2ZV80Ir1FtCcYv1cT6vQ==}
|
||||||
engines: {node: '>=16'}
|
engines: {node: '>=16'}
|
||||||
|
|
||||||
type-fest@4.41.0:
|
|
||||||
resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==}
|
|
||||||
engines: {node: '>=16'}
|
|
||||||
|
|
||||||
typescript-auto-import-cache@0.3.5:
|
typescript-auto-import-cache@0.3.5:
|
||||||
resolution: {integrity: sha512-fAIveQKsoYj55CozUiBoj4b/7WpN0i4o74wiGY5JVUEoD0XiqDk1tJqTEjgzL2/AizKQrXxyRosSebyDzBZKjw==}
|
resolution: {integrity: sha512-fAIveQKsoYj55CozUiBoj4b/7WpN0i4o74wiGY5JVUEoD0XiqDk1tJqTEjgzL2/AizKQrXxyRosSebyDzBZKjw==}
|
||||||
|
|
||||||
|
@ -1921,9 +1829,6 @@ packages:
|
||||||
resolution: {integrity: sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w==}
|
resolution: {integrity: sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
|
|
||||||
uri-js-replace@1.0.1:
|
|
||||||
resolution: {integrity: sha512-W+C9NWNLFOoBI2QWDp4UT9pv65r2w5Cx+3sTYFvtMdDBxkKt1syCqsUdSFAChbEe1uK5TfS04wt/nGwmaeIQ0g==}
|
|
||||||
|
|
||||||
uri-js@4.4.1:
|
uri-js@4.4.1:
|
||||||
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
|
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
|
||||||
|
|
||||||
|
@ -2149,9 +2054,6 @@ packages:
|
||||||
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
|
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
yaml-ast-parser@0.0.43:
|
|
||||||
resolution: {integrity: sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A==}
|
|
||||||
|
|
||||||
yaml@2.7.1:
|
yaml@2.7.1:
|
||||||
resolution: {integrity: sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ==}
|
resolution: {integrity: sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ==}
|
||||||
engines: {node: '>= 14'}
|
engines: {node: '>= 14'}
|
||||||
|
@ -2175,18 +2077,10 @@ packages:
|
||||||
|
|
||||||
snapshots:
|
snapshots:
|
||||||
|
|
||||||
'@babel/code-frame@7.27.1':
|
|
||||||
dependencies:
|
|
||||||
'@babel/helper-validator-identifier': 7.27.1
|
|
||||||
js-tokens: 4.0.0
|
|
||||||
picocolors: 1.1.1
|
|
||||||
|
|
||||||
'@babel/helper-string-parser@7.25.9': {}
|
'@babel/helper-string-parser@7.25.9': {}
|
||||||
|
|
||||||
'@babel/helper-validator-identifier@7.25.9': {}
|
'@babel/helper-validator-identifier@7.25.9': {}
|
||||||
|
|
||||||
'@babel/helper-validator-identifier@7.27.1': {}
|
|
||||||
|
|
||||||
'@babel/parser@7.26.2':
|
'@babel/parser@7.26.2':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/types': 7.26.0
|
'@babel/types': 7.26.0
|
||||||
|
@ -2502,29 +2396,6 @@ snapshots:
|
||||||
'@parcel/watcher-win32-x64': 2.5.1
|
'@parcel/watcher-win32-x64': 2.5.1
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@redocly/ajv@8.11.2':
|
|
||||||
dependencies:
|
|
||||||
fast-deep-equal: 3.1.3
|
|
||||||
json-schema-traverse: 1.0.0
|
|
||||||
require-from-string: 2.0.2
|
|
||||||
uri-js-replace: 1.0.1
|
|
||||||
|
|
||||||
'@redocly/config@0.22.2': {}
|
|
||||||
|
|
||||||
'@redocly/openapi-core@1.34.3(supports-color@10.0.0)':
|
|
||||||
dependencies:
|
|
||||||
'@redocly/ajv': 8.11.2
|
|
||||||
'@redocly/config': 0.22.2
|
|
||||||
colorette: 1.4.0
|
|
||||||
https-proxy-agent: 7.0.6(supports-color@10.0.0)
|
|
||||||
js-levenshtein: 1.1.6
|
|
||||||
js-yaml: 4.1.0
|
|
||||||
minimatch: 5.1.6
|
|
||||||
pluralize: 8.0.0
|
|
||||||
yaml-ast-parser: 0.0.43
|
|
||||||
transitivePeerDependencies:
|
|
||||||
- supports-color
|
|
||||||
|
|
||||||
'@rollup/rollup-android-arm-eabi@4.40.0':
|
'@rollup/rollup-android-arm-eabi@4.40.0':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
@ -2903,8 +2774,6 @@ snapshots:
|
||||||
|
|
||||||
acorn@8.14.1: {}
|
acorn@8.14.1: {}
|
||||||
|
|
||||||
agent-base@7.1.3: {}
|
|
||||||
|
|
||||||
ajv@6.12.6:
|
ajv@6.12.6:
|
||||||
dependencies:
|
dependencies:
|
||||||
fast-deep-equal: 3.1.3
|
fast-deep-equal: 3.1.3
|
||||||
|
@ -2914,8 +2783,6 @@ snapshots:
|
||||||
|
|
||||||
alien-signals@1.0.13: {}
|
alien-signals@1.0.13: {}
|
||||||
|
|
||||||
ansi-colors@4.1.3: {}
|
|
||||||
|
|
||||||
ansi-escapes@4.3.2:
|
ansi-escapes@4.3.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
type-fest: 0.21.3
|
type-fest: 0.21.3
|
||||||
|
@ -2988,8 +2855,6 @@ snapshots:
|
||||||
ansi-styles: 4.3.0
|
ansi-styles: 4.3.0
|
||||||
supports-color: 7.2.0
|
supports-color: 7.2.0
|
||||||
|
|
||||||
change-case@5.4.4: {}
|
|
||||||
|
|
||||||
character-parser@2.2.0:
|
character-parser@2.2.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
is-regex: 1.2.1
|
is-regex: 1.2.1
|
||||||
|
@ -3024,8 +2889,6 @@ snapshots:
|
||||||
|
|
||||||
color-name@1.1.4: {}
|
color-name@1.1.4: {}
|
||||||
|
|
||||||
colorette@1.4.0: {}
|
|
||||||
|
|
||||||
colorjs.io@0.5.2: {}
|
colorjs.io@0.5.2: {}
|
||||||
|
|
||||||
concat-map@0.0.1: {}
|
concat-map@0.0.1: {}
|
||||||
|
@ -3054,11 +2917,9 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
ms: 2.1.3
|
ms: 2.1.3
|
||||||
|
|
||||||
debug@4.4.0(supports-color@10.0.0):
|
debug@4.4.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
ms: 2.1.3
|
ms: 2.1.3
|
||||||
optionalDependencies:
|
|
||||||
supports-color: 10.0.0
|
|
||||||
|
|
||||||
deep-is@0.1.4: {}
|
deep-is@0.1.4: {}
|
||||||
|
|
||||||
|
@ -3309,13 +3170,6 @@ snapshots:
|
||||||
|
|
||||||
headers-polyfill@4.0.3: {}
|
headers-polyfill@4.0.3: {}
|
||||||
|
|
||||||
https-proxy-agent@7.0.6(supports-color@10.0.0):
|
|
||||||
dependencies:
|
|
||||||
agent-base: 7.1.3
|
|
||||||
debug: 4.4.0(supports-color@10.0.0)
|
|
||||||
transitivePeerDependencies:
|
|
||||||
- supports-color
|
|
||||||
|
|
||||||
ignore@5.3.2: {}
|
ignore@5.3.2: {}
|
||||||
|
|
||||||
immutable@5.0.2: {}
|
immutable@5.0.2: {}
|
||||||
|
@ -3327,8 +3181,6 @@ snapshots:
|
||||||
|
|
||||||
imurmurhash@0.1.4: {}
|
imurmurhash@0.1.4: {}
|
||||||
|
|
||||||
index-to-position@1.1.0: {}
|
|
||||||
|
|
||||||
is-binary-path@2.1.0:
|
is-binary-path@2.1.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
binary-extensions: 2.3.0
|
binary-extensions: 2.3.0
|
||||||
|
@ -3361,10 +3213,6 @@ snapshots:
|
||||||
|
|
||||||
isexe@3.1.1: {}
|
isexe@3.1.1: {}
|
||||||
|
|
||||||
js-levenshtein@1.1.6: {}
|
|
||||||
|
|
||||||
js-tokens@4.0.0: {}
|
|
||||||
|
|
||||||
js-yaml@4.1.0:
|
js-yaml@4.1.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
argparse: 2.0.1
|
argparse: 2.0.1
|
||||||
|
@ -3375,8 +3223,6 @@ snapshots:
|
||||||
|
|
||||||
json-schema-traverse@0.4.1: {}
|
json-schema-traverse@0.4.1: {}
|
||||||
|
|
||||||
json-schema-traverse@1.0.0: {}
|
|
||||||
|
|
||||||
json-stable-stringify-without-jsonify@1.0.1: {}
|
json-stable-stringify-without-jsonify@1.0.1: {}
|
||||||
|
|
||||||
json5@2.2.3: {}
|
json5@2.2.3: {}
|
||||||
|
@ -3435,10 +3281,6 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
brace-expansion: 1.1.11
|
brace-expansion: 1.1.11
|
||||||
|
|
||||||
minimatch@5.1.6:
|
|
||||||
dependencies:
|
|
||||||
brace-expansion: 2.0.1
|
|
||||||
|
|
||||||
minimatch@9.0.5:
|
minimatch@9.0.5:
|
||||||
dependencies:
|
dependencies:
|
||||||
brace-expansion: 2.0.1
|
brace-expansion: 2.0.1
|
||||||
|
@ -3511,22 +3353,6 @@ snapshots:
|
||||||
|
|
||||||
object-assign@4.1.1: {}
|
object-assign@4.1.1: {}
|
||||||
|
|
||||||
openapi-fetch@0.14.0:
|
|
||||||
dependencies:
|
|
||||||
openapi-typescript-helpers: 0.0.15
|
|
||||||
|
|
||||||
openapi-typescript-helpers@0.0.15: {}
|
|
||||||
|
|
||||||
openapi-typescript@7.8.0(typescript@5.8.3):
|
|
||||||
dependencies:
|
|
||||||
'@redocly/openapi-core': 1.34.3(supports-color@10.0.0)
|
|
||||||
ansi-colors: 4.1.3
|
|
||||||
change-case: 5.4.4
|
|
||||||
parse-json: 8.3.0
|
|
||||||
supports-color: 10.0.0
|
|
||||||
typescript: 5.8.3
|
|
||||||
yargs-parser: 21.1.1
|
|
||||||
|
|
||||||
optionator@0.9.4:
|
optionator@0.9.4:
|
||||||
dependencies:
|
dependencies:
|
||||||
deep-is: 0.1.4
|
deep-is: 0.1.4
|
||||||
|
@ -3550,12 +3376,6 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
callsites: 3.1.0
|
callsites: 3.1.0
|
||||||
|
|
||||||
parse-json@8.3.0:
|
|
||||||
dependencies:
|
|
||||||
'@babel/code-frame': 7.27.1
|
|
||||||
index-to-position: 1.1.0
|
|
||||||
type-fest: 4.41.0
|
|
||||||
|
|
||||||
path-browserify@1.0.1: {}
|
path-browserify@1.0.1: {}
|
||||||
|
|
||||||
path-exists@4.0.0: {}
|
path-exists@4.0.0: {}
|
||||||
|
@ -3588,8 +3408,6 @@ snapshots:
|
||||||
exsolve: 1.0.4
|
exsolve: 1.0.4
|
||||||
pathe: 2.0.3
|
pathe: 2.0.3
|
||||||
|
|
||||||
pluralize@8.0.0: {}
|
|
||||||
|
|
||||||
postcss-selector-parser@6.1.2:
|
postcss-selector-parser@6.1.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
cssesc: 3.0.0
|
cssesc: 3.0.0
|
||||||
|
@ -3649,8 +3467,6 @@ snapshots:
|
||||||
|
|
||||||
require-directory@2.1.1: {}
|
require-directory@2.1.1: {}
|
||||||
|
|
||||||
require-from-string@2.0.2: {}
|
|
||||||
|
|
||||||
requires-port@1.0.0: {}
|
requires-port@1.0.0: {}
|
||||||
|
|
||||||
resolve-from@4.0.0: {}
|
resolve-from@4.0.0: {}
|
||||||
|
@ -3825,8 +3641,6 @@ snapshots:
|
||||||
|
|
||||||
strip-json-comments@3.1.1: {}
|
strip-json-comments@3.1.1: {}
|
||||||
|
|
||||||
supports-color@10.0.0: {}
|
|
||||||
|
|
||||||
supports-color@7.2.0:
|
supports-color@7.2.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
has-flag: 4.0.0
|
has-flag: 4.0.0
|
||||||
|
@ -3873,8 +3687,6 @@ snapshots:
|
||||||
|
|
||||||
type-fest@4.31.0: {}
|
type-fest@4.31.0: {}
|
||||||
|
|
||||||
type-fest@4.41.0: {}
|
|
||||||
|
|
||||||
typescript-auto-import-cache@0.3.5:
|
typescript-auto-import-cache@0.3.5:
|
||||||
dependencies:
|
dependencies:
|
||||||
semver: 7.6.3
|
semver: 7.6.3
|
||||||
|
@ -3911,7 +3723,7 @@ snapshots:
|
||||||
unplugin-vue-components@28.5.0(@babel/parser@7.27.0)(vue@3.5.13(typescript@5.8.3)):
|
unplugin-vue-components@28.5.0(@babel/parser@7.27.0)(vue@3.5.13(typescript@5.8.3)):
|
||||||
dependencies:
|
dependencies:
|
||||||
chokidar: 3.6.0
|
chokidar: 3.6.0
|
||||||
debug: 4.4.0(supports-color@10.0.0)
|
debug: 4.4.0
|
||||||
local-pkg: 1.1.1
|
local-pkg: 1.1.1
|
||||||
magic-string: 0.30.17
|
magic-string: 0.30.17
|
||||||
mlly: 1.7.4
|
mlly: 1.7.4
|
||||||
|
@ -3959,8 +3771,6 @@ snapshots:
|
||||||
|
|
||||||
upath@2.0.1: {}
|
upath@2.0.1: {}
|
||||||
|
|
||||||
uri-js-replace@1.0.1: {}
|
|
||||||
|
|
||||||
uri-js@4.4.1:
|
uri-js@4.4.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
punycode: 2.3.1
|
punycode: 2.3.1
|
||||||
|
@ -4105,7 +3915,7 @@ snapshots:
|
||||||
|
|
||||||
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
|
||||||
eslint: 9.24.0
|
eslint: 9.24.0
|
||||||
eslint-scope: 8.2.0
|
eslint-scope: 8.2.0
|
||||||
eslint-visitor-keys: 4.2.0
|
eslint-visitor-keys: 4.2.0
|
||||||
|
@ -4172,8 +3982,6 @@ snapshots:
|
||||||
|
|
||||||
y18n@5.0.8: {}
|
y18n@5.0.8: {}
|
||||||
|
|
||||||
yaml-ast-parser@0.0.43: {}
|
|
||||||
|
|
||||||
yaml@2.7.1: {}
|
yaml@2.7.1: {}
|
||||||
|
|
||||||
yargs-parser@21.1.1: {}
|
yargs-parser@21.1.1: {}
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
rounded="lg"
|
rounded="lg"
|
||||||
title="Manage your certificates"
|
title="Manage your certificates"
|
||||||
variant="text"
|
variant="text"
|
||||||
to="/certificates"
|
to="/cert-request"
|
||||||
/>
|
/>
|
||||||
</v-col>
|
</v-col>
|
||||||
|
|
||||||
|
|
|
@ -1,34 +0,0 @@
|
||||||
<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>
|
|
|
@ -1,49 +0,0 @@
|
||||||
<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>
|
|
|
@ -1,11 +0,0 @@
|
||||||
<script setup lang="ts">
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<h2>New certificate</h2>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
|
|
||||||
</style>
|
|
|
@ -1,18 +0,0 @@
|
||||||
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,12 +1,10 @@
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"composite": true,
|
"composite": true,
|
||||||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
||||||
"noUncheckedIndexedAccess": true,
|
|
||||||
|
|
||||||
"baseUrl": ".",
|
"baseUrl": ".",
|
||||||
"paths": {
|
"paths": {
|
||||||
|
|
3
frontend/typed-router.d.ts
vendored
3
frontend/typed-router.d.ts
vendored
|
@ -20,8 +20,5 @@ 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>>,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
package de.mlessmann.certassist.config;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
|
||||||
import com.fasterxml.jackson.annotation.PropertyAccessor;
|
|
||||||
import com.fasterxml.jackson.databind.MapperFeature;
|
|
||||||
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
public class JacksonConfiguration {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Customizes the objectMapper so that ONLY specifically annotated fields are serialized.
|
|
||||||
* Other fields MUST NOT be serialized since they may contain sensitive information!
|
|
||||||
*/
|
|
||||||
@Bean
|
|
||||||
public Jackson2ObjectMapperBuilderCustomizer customizeObjectMapper() {
|
|
||||||
return builder -> builder
|
|
||||||
.featuresToDisable(
|
|
||||||
MapperFeature.AUTO_DETECT_FIELDS,
|
|
||||||
MapperFeature.AUTO_DETECT_GETTERS,
|
|
||||||
MapperFeature.AUTO_DETECT_IS_GETTERS
|
|
||||||
)
|
|
||||||
.serializationInclusion(JsonInclude.Include.NON_EMPTY)
|
|
||||||
.visibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE)
|
|
||||||
.visibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.NONE)
|
|
||||||
.visibility(PropertyAccessor.GETTER, JsonAutoDetect.Visibility.NONE)
|
|
||||||
.visibility(PropertyAccessor.IS_GETTER, JsonAutoDetect.Visibility.NONE)
|
|
||||||
.visibility(PropertyAccessor.SETTER, JsonAutoDetect.Visibility.PUBLIC_ONLY)
|
|
||||||
.visibility(PropertyAccessor.CREATOR, JsonAutoDetect.Visibility.PUBLIC_ONLY)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
package de.mlessmann.certassist.config;
|
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
|
||||||
import org.springframework.security.web.SecurityFilterChain;
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
@RequiredArgsConstructor(onConstructor_ = @Autowired)
|
|
||||||
public class SecurityConfiguration {
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public SecurityFilterChain securityFilters(HttpSecurity http) throws Exception {
|
|
||||||
// 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/**", "/v3/api-docs.yaml", "/swagger-ui/**", "/swagger-ui.html")
|
|
||||||
.permitAll());
|
|
||||||
return http.build();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
package de.mlessmann.certassist.config;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import io.swagger.v3.core.jackson.ModelResolver;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configuration for Springdoc OpenAPI to respect Jackson annotations.
|
|
||||||
* This ensures that only properties that are visible to Jackson (annotated with @JsonProperty)
|
|
||||||
* are included in the OpenAPI schema.
|
|
||||||
*/
|
|
||||||
@Configuration
|
|
||||||
public class SpringdocConfiguration {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a ModelResolver that uses the same ObjectMapper as the application.
|
|
||||||
* This ensures that Springdoc respects the same visibility settings as Jackson.
|
|
||||||
*
|
|
||||||
* @param objectMapper the configured ObjectMapper from JacksonConfiguration
|
|
||||||
* @return a ModelResolver that uses the application's ObjectMapper
|
|
||||||
*/
|
|
||||||
@Bean
|
|
||||||
public ModelResolver modelResolver(ObjectMapper objectMapper) {
|
|
||||||
return new ModelResolver(objectMapper);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,21 +1,17 @@
|
||||||
package de.mlessmann.certassist.models;
|
package de.mlessmann.certassist.models;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
import de.mlessmann.certassist.web.JsonIsoOffsetDate;
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
import jakarta.validation.constraints.Min;
|
import jakarta.validation.constraints.Min;
|
||||||
import jakarta.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
import lombok.*;
|
|
||||||
import org.hibernate.proxy.HibernateProxy;
|
|
||||||
|
|
||||||
import java.time.OffsetDateTime;
|
import java.time.OffsetDateTime;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import lombok.*;
|
||||||
|
import org.hibernate.proxy.HibernateProxy;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(uniqueConstraints = {@UniqueConstraint(columnNames = {"fingerprint"})})
|
@Table(uniqueConstraints = { @UniqueConstraint(columnNames = { "fingerprint" }) })
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@ToString
|
@ToString
|
||||||
|
@ -29,10 +25,8 @@ public class Certificate {
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Enumerated(EnumType.STRING)
|
@Enumerated(EnumType.STRING)
|
||||||
@JsonProperty
|
|
||||||
private CertificateType type;
|
private CertificateType type;
|
||||||
|
|
||||||
@JsonProperty
|
|
||||||
private String trustingAuthority;
|
private String trustingAuthority;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -45,26 +39,17 @@ public class Certificate {
|
||||||
@Min(-1)
|
@Min(-1)
|
||||||
private int requestedKeyLength;
|
private int requestedKeyLength;
|
||||||
|
|
||||||
@JsonIsoOffsetDate
|
|
||||||
private OffsetDateTime notBefore;
|
private OffsetDateTime notBefore;
|
||||||
@JsonIsoOffsetDate
|
|
||||||
private OffsetDateTime notAfter;
|
private OffsetDateTime notAfter;
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@JsonProperty
|
|
||||||
private String subjectCommonName;
|
private String subjectCommonName;
|
||||||
|
|
||||||
@JsonProperty
|
|
||||||
private String subjectEmailAddress;
|
private String subjectEmailAddress;
|
||||||
@JsonProperty
|
|
||||||
private String subjectOrganization;
|
private String subjectOrganization;
|
||||||
@JsonProperty
|
|
||||||
private String subjectOrganizationalUnit;
|
private String subjectOrganizationalUnit;
|
||||||
@JsonProperty
|
|
||||||
private String subjectCountry;
|
private String subjectCountry;
|
||||||
@JsonProperty
|
|
||||||
private String subjectState;
|
private String subjectState;
|
||||||
@JsonProperty
|
|
||||||
private String subjectLocality;
|
private String subjectLocality;
|
||||||
|
|
||||||
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
|
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
|
||||||
|
@ -84,8 +69,6 @@ public class Certificate {
|
||||||
private byte[] fullchain;
|
private byte[] fullchain;
|
||||||
|
|
||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
@JsonProperty
|
|
||||||
@Schema(description = "The certificate fingerprint. The algorithm used to derive the fingerprint is determined by OpenSSL")
|
|
||||||
private String fingerprint;
|
private String fingerprint;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -93,11 +76,11 @@ public class Certificate {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null) return false;
|
if (o == null) return false;
|
||||||
Class<?> oEffectiveClass = o instanceof HibernateProxy
|
Class<?> oEffectiveClass = o instanceof HibernateProxy
|
||||||
? ((HibernateProxy) o).getHibernateLazyInitializer().getPersistentClass()
|
? ((HibernateProxy) o).getHibernateLazyInitializer().getPersistentClass()
|
||||||
: o.getClass();
|
: o.getClass();
|
||||||
Class<?> thisEffectiveClass = this instanceof HibernateProxy
|
Class<?> thisEffectiveClass = this instanceof HibernateProxy
|
||||||
? ((HibernateProxy) this).getHibernateLazyInitializer().getPersistentClass()
|
? ((HibernateProxy) this).getHibernateLazyInitializer().getPersistentClass()
|
||||||
: this.getClass();
|
: this.getClass();
|
||||||
if (thisEffectiveClass != oEffectiveClass) return false;
|
if (thisEffectiveClass != oEffectiveClass) return false;
|
||||||
Certificate that = (Certificate) o;
|
Certificate that = (Certificate) o;
|
||||||
return getId() != null && Objects.equals(getId(), that.getId());
|
return getId() != null && Objects.equals(getId(), that.getId());
|
||||||
|
@ -106,7 +89,7 @@ public class Certificate {
|
||||||
@Override
|
@Override
|
||||||
public final int hashCode() {
|
public final int hashCode() {
|
||||||
return this instanceof HibernateProxy
|
return this instanceof HibernateProxy
|
||||||
? ((HibernateProxy) this).getHibernateLazyInitializer().getPersistentClass().hashCode()
|
? ((HibernateProxy) this).getHibernateLazyInitializer().getPersistentClass().hashCode()
|
||||||
: getClass().hashCode();
|
: getClass().hashCode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
package de.mlessmann.certassist.repositories;
|
package de.mlessmann.certassist.repositories;
|
||||||
|
|
||||||
import de.mlessmann.certassist.models.Certificate;
|
import de.mlessmann.certassist.models.Certificate;
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.repository.CrudRepository;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
public interface CertificateRepository extends JpaRepository<Certificate, String> {
|
public interface CertificateRepository extends CrudRepository<Certificate, String> {
|
||||||
|
|
||||||
Certificate findByFingerprintIs(String fingerprint);
|
Certificate findByFingerprintIs(String fingerprint);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,100 +0,0 @@
|
||||||
package de.mlessmann.certassist.web;
|
|
||||||
|
|
||||||
import de.mlessmann.certassist.models.Certificate;
|
|
||||||
import de.mlessmann.certassist.models.CertificateInfo;
|
|
||||||
import de.mlessmann.certassist.models.CertificateInfoSubject;
|
|
||||||
import de.mlessmann.certassist.repositories.CertificateRepository;
|
|
||||||
import de.mlessmann.certassist.service.CertificateCreationService;
|
|
||||||
import de.mlessmann.certassist.web.dto.PrivateKey;
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
|
||||||
import io.swagger.v3.oas.annotations.media.Content;
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import org.springdoc.core.annotations.ParameterObject;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.data.domain.Pageable;
|
|
||||||
import org.springframework.http.ResponseEntity;
|
|
||||||
import org.springframework.util.MimeTypeUtils;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/api")
|
|
||||||
@RequiredArgsConstructor(onConstructor_ = @Autowired)
|
|
||||||
public class CertificatesEndpoint {
|
|
||||||
|
|
||||||
public static final String MIME_PEM_FILE = "application/x-pem-file";
|
|
||||||
private final CertificateRepository certificateRepository;
|
|
||||||
private final CertificateCreationService certificateCreationService;
|
|
||||||
|
|
||||||
@GetMapping("/certificates")
|
|
||||||
@Operation(description = "Fetches certificates", responses = {
|
|
||||||
@ApiResponse(responseCode = "200", description = "Contains the returned certificates of the requested page.")
|
|
||||||
})
|
|
||||||
public ResponseEntity<DocumentedPage<Certificate>> getCertificates(@ParameterObject Pageable pageable) {
|
|
||||||
var certificates = certificateRepository.findAll(pageable);
|
|
||||||
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."),
|
|
||||||
@ApiResponse(responseCode = "200", description = "Returns the newly created certificate.")
|
|
||||||
})
|
|
||||||
public ResponseEntity<Certificate> createCertificate(@RequestBody CertificateInfo request) {
|
|
||||||
var createdCertificate = certificateCreationService.createCertificate(
|
|
||||||
CertificateInfo.builder()
|
|
||||||
.type(CertificateInfo.RequestType.STANDALONE_CERTIFICATE)
|
|
||||||
.issuer(CertificateInfoSubject.builder()
|
|
||||||
.commonName("Test")
|
|
||||||
)
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
return ResponseEntity.ok(createdCertificate);
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping(value = "/certificates/{cert}/privateKey", produces = {
|
|
||||||
MimeTypeUtils.APPLICATION_JSON_VALUE,
|
|
||||||
MIME_PEM_FILE
|
|
||||||
})
|
|
||||||
@Operation(description = "Fetches the private key corresponding to the provided certificate.",
|
|
||||||
responses = {
|
|
||||||
@ApiResponse(responseCode = "200", content = {
|
|
||||||
@Content(mediaType = MimeTypeUtils.APPLICATION_JSON_VALUE,
|
|
||||||
schema = @Schema(implementation = PrivateKey.class)),
|
|
||||||
@Content(mediaType = MIME_PEM_FILE,
|
|
||||||
schema = @Schema(type = "string", description = "PEM formatted private key content"))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
public ResponseEntity<Object> getCertificatePrivateKey(
|
|
||||||
@RequestHeader("Accept") String acceptType,
|
|
||||||
@PathVariable String cert
|
|
||||||
) {
|
|
||||||
var requestedCert = certificateRepository.findByFingerprintIs(cert);
|
|
||||||
|
|
||||||
if (MimeTypeUtils.APPLICATION_JSON_VALUE.equals(acceptType)) {
|
|
||||||
String pemContent = new String(requestedCert.getPrivateKey(), StandardCharsets.UTF_8);
|
|
||||||
var pKey = new PrivateKey(pemContent);
|
|
||||||
return ResponseEntity.ok(pKey);
|
|
||||||
} else if (MIME_PEM_FILE.equals(acceptType)) {
|
|
||||||
String pemContent = new String(requestedCert.getPrivateKey(), StandardCharsets.UTF_8);
|
|
||||||
return ResponseEntity.ok(pemContent);
|
|
||||||
} else {
|
|
||||||
return ResponseEntity.badRequest().build();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
package de.mlessmann.certassist.web;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
import org.springframework.data.domain.Page;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public interface DocumentedPage<T> extends Page<T> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@JsonProperty
|
|
||||||
@Schema(description = "The content of the paginated response. See nested type for more information.")
|
|
||||||
List<T> getContent();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@JsonProperty("size")
|
|
||||||
@Schema(description = "How many items there are in this current page.")
|
|
||||||
int getNumberOfElements();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@JsonProperty
|
|
||||||
@Schema(description = "How many pages are currently available in total.")
|
|
||||||
int getTotalPages();
|
|
||||||
|
|
||||||
static <T> DocumentedPage<T> of(Page<T> page) {
|
|
||||||
return (DocumentedPage<T>) page;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
package de.mlessmann.certassist.web;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
import java.time.format.DateTimeFormatter;
|
|
||||||
|
|
||||||
@JacksonAnnotationsInside
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@Target({ElementType.FIELD, ElementType.PARAMETER})
|
|
||||||
@JsonProperty
|
|
||||||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX")
|
|
||||||
public @interface JsonIsoOffsetDate {
|
|
||||||
}
|
|
|
@ -1,11 +0,0 @@
|
||||||
package de.mlessmann.certassist.web.dto;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
|
|
||||||
@Schema(description = "Represents the private key of a certificate.")
|
|
||||||
public record PrivateKey(
|
|
||||||
@JsonProperty
|
|
||||||
@Schema(description = "The content of the private key as it would be in a .pem file.")
|
|
||||||
String pemContent) {
|
|
||||||
}
|
|
Loading…
Add table
Reference in a new issue