22import type { Cert } from ' @/api/cert'
33import { CopyOutlined , InboxOutlined } from ' @ant-design/icons-vue'
44import { useClipboard } from ' @vueuse/core'
5+ import config from ' @/api/config'
56import CodeEditor from ' @/components/CodeEditor'
67import CertificateFileUpload from ' ./CertificateFileUpload.vue'
78
@@ -20,6 +21,85 @@ const data = defineModel<Cert>('data', { required: true })
2021
2122const { copy } = useClipboard ()
2223
24+ // Lazy load nginx config base path
25+ const nginxBasePath = ref <string >(' ' )
26+ const basePathLoaded = ref (false )
27+
28+ async function loadNginxBasePath() {
29+ if (basePathLoaded .value )
30+ return
31+
32+ try {
33+ const res = await config .get_base_path ()
34+ nginxBasePath .value = res .base_path
35+ basePathLoaded .value = true
36+ }
37+ catch (error ) {
38+ console .error (' Failed to load nginx base path:' , error )
39+ message .warning ($gettext (' Failed to load nginx configuration path' ))
40+ }
41+ }
42+
43+ // Generate slug from name or filename
44+ function generateSlug(text : string ): string {
45+ let result = text
46+ .toLowerCase ()
47+ .replace (/ \s + / g , ' _' ) // Replace spaces with underscores
48+ .replace (/ [^ a-z0-9 _. /-] / g , ' ' ) // Remove invalid characters
49+
50+ // Remove leading dots
51+ while (result .startsWith (' .' )) {
52+ result = result .slice (1 )
53+ }
54+
55+ // Remove trailing dots
56+ while (result .endsWith (' .' )) {
57+ result = result .slice (0 , - 1 )
58+ }
59+
60+ return result
61+ }
62+
63+ // Auto-generate certificate paths and name
64+ async function autoGeneratePaths(fileName : string , _type : ' certificate' | ' key' ) {
65+ // Only generate paths in add mode
66+ if (data .value .id )
67+ return
68+
69+ await loadNginxBasePath ()
70+
71+ if (! nginxBasePath .value )
72+ return
73+
74+ // Extract base name from filename (remove extension)
75+ const baseName = fileName .replace (/ \. (crt| pem| cer| cert| key| private)$ / i , ' ' )
76+
77+ // Auto-fill name if empty
78+ if (! data .value .name ) {
79+ data .value .name = baseName
80+ }
81+
82+ // Generate directory name from cert name or filename
83+ const slug = data .value .name
84+ ? generateSlug (data .value .name )
85+ : generateSlug (baseName )
86+
87+ if (! slug )
88+ return
89+
90+ const certDir = ` ${nginxBasePath .value }/ssl/${slug } `
91+
92+ // Auto-fill certificate path if empty
93+ if (! data .value .ssl_certificate_path ) {
94+ data .value .ssl_certificate_path = ` ${certDir }/fullchain.cer `
95+ }
96+
97+ // Auto-fill key path if empty
98+ if (! data .value .ssl_certificate_key_path ) {
99+ data .value .ssl_certificate_key_path = ` ${certDir }/private.key `
100+ }
101+ }
102+
23103async function copyToClipboard(text : string , label : string ) {
24104 if (! text ) {
25105 message .warning ($gettext (' Nothing to copy' ))
@@ -40,13 +120,23 @@ const isDragOverCert = ref(false)
40120const isDragOverKey = ref (false )
41121
42122// Handle certificate file upload
43- function handleCertificateUpload(content : string ) {
123+ function handleCertificateUpload(content : string , fileName ? : string ) {
44124 data .value .ssl_certificate = content
125+
126+ // Auto-generate paths if in add mode
127+ if (fileName ) {
128+ autoGeneratePaths (fileName , ' certificate' )
129+ }
45130}
46131
47132// Handle private key file upload
48- function handlePrivateKeyUpload(content : string ) {
133+ function handlePrivateKeyUpload(content : string , fileName ? : string ) {
49134 data .value .ssl_certificate_key = content
135+
136+ // Auto-generate paths if in add mode
137+ if (fileName ) {
138+ autoGeneratePaths (fileName , ' key' )
139+ }
50140}
51141
52142// Drag and drop handlers
@@ -95,10 +185,10 @@ function handleDrop(e: DragEvent, type: 'certificate' | 'key') {
95185 reader .onload = e => {
96186 const content = e .target ?.result as string
97187 if (type === ' certificate' ) {
98- handleCertificateUpload (content )
188+ handleCertificateUpload (content , file . name )
99189 }
100190 else {
101- handlePrivateKeyUpload (content )
191+ handlePrivateKeyUpload (content , file . name )
102192 }
103193 }
104194 reader .readAsText (file )
@@ -131,7 +221,7 @@ function handleDrop(e: DragEvent, type: 'certificate' | 'key') {
131221 <CertificateFileUpload
132222 v-if =" !readonly"
133223 type =" certificate"
134- @upload =" handleCertificateUpload"
224+ @upload =" (content, fileName) => handleCertificateUpload(content, fileName) "
135225 />
136226
137227 <div
@@ -192,7 +282,7 @@ function handleDrop(e: DragEvent, type: 'certificate' | 'key') {
192282 <CertificateFileUpload
193283 v-if =" !readonly"
194284 type =" key"
195- @upload =" handlePrivateKeyUpload"
285+ @upload =" (content, fileName) => handlePrivateKeyUpload(content, fileName) "
196286 />
197287
198288 <div
0 commit comments