setLicenseKeyInput(e.target.value)}
+ placeholder={licenseInfo?.licenseKey || '00000000-0000-0000-0000-000000000000'}
+ type="password"
+ disabled={!loginEnabled || savingLicense}
+ />
+ ) : (
+ /* File upload */
+
+
+ {t('admin.settings.premium.file.label', 'License Certificate File')}
+
+
+ {t('admin.settings.premium.file.description', 'Upload your .lic or .cert license file')}
+
+
+ {(props) => (
+ }
+ disabled={!loginEnabled || savingLicense}
+ >
+ {licenseFile
+ ? licenseFile.name
+ : t('admin.settings.premium.file.choose', 'Choose License File')}
+
+ )}
+
+ {licenseFile && (
+
+ {t('admin.settings.premium.file.selected', 'Selected: {{filename}} ({{size}})', {
+ filename: licenseFile.name,
+ size: (licenseFile.size / 1024).toFixed(2) + ' KB'
+ })}
+
+ )}
+
+ )}
-
diff --git a/frontend/src/proprietary/services/licenseService.ts b/frontend/src/proprietary/services/licenseService.ts
index 867567977..d53129c17 100644
--- a/frontend/src/proprietary/services/licenseService.ts
+++ b/frontend/src/proprietary/services/licenseService.ts
@@ -80,6 +80,10 @@ export interface LicenseInfo {
export interface LicenseSaveResponse {
success: boolean;
licenseType?: string;
+ filename?: string;
+ filePath?: string;
+ enabled?: boolean;
+ maxUsers?: number;
message?: string;
error?: string;
}
@@ -419,6 +423,29 @@ const licenseService = {
}
},
+ /**
+ * Upload license certificate file for offline activation
+ * @param file - The .lic or .cert file to upload
+ * @returns Promise with upload result
+ */
+ async saveLicenseFile(file: File): Promise {
+ try {
+ const formData = new FormData();
+ formData.append('file', file);
+
+ const response = await apiClient.post('/api/v1/admin/license-file', formData, {
+ headers: {
+ 'Content-Type': 'multipart/form-data',
+ },
+ });
+
+ return response.data;
+ } catch (error) {
+ console.error('Error uploading license file:', error);
+ throw error;
+ }
+ },
+
/**
* Get current license information from backend
*/