mirror of
https://github.com/foss42/apidash.git
synced 2025-12-02 10:49:49 +08:00
Integrate secure storage with Hive and add security notices to code generators
Co-authored-by: animator <615622+animator@users.noreply.github.com>
This commit is contained in:
@@ -89,7 +89,8 @@ func main() {
|
|||||||
HttpRequestModel requestModel,
|
HttpRequestModel requestModel,
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
String result = "";
|
String result = "// SECURITY NOTICE: Please validate all inputs and URLs before use in production\n";
|
||||||
|
result += "// This code is generated for testing purposes\n\n";
|
||||||
var hasBody = false;
|
var hasBody = false;
|
||||||
|
|
||||||
String url = requestModel.url;
|
String url = requestModel.url;
|
||||||
|
|||||||
@@ -92,7 +92,8 @@ import okhttp3.MultipartBody;""";
|
|||||||
HttpRequestModel requestModel,
|
HttpRequestModel requestModel,
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
String result = "";
|
String result = "// SECURITY NOTICE: Please validate all inputs and URLs before use in production\n";
|
||||||
|
result += "// This code is generated for testing purposes\n\n";
|
||||||
bool hasQuery = false;
|
bool hasQuery = false;
|
||||||
bool hasBody = false;
|
bool hasBody = false;
|
||||||
bool hasFormData = false;
|
bool hasFormData = false;
|
||||||
|
|||||||
@@ -80,7 +80,8 @@ import okhttp3.MediaType.Companion.toMediaType""";
|
|||||||
HttpRequestModel requestModel,
|
HttpRequestModel requestModel,
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
String result = "";
|
String result = "// SECURITY NOTICE: Please validate all inputs and URLs before use in production\n";
|
||||||
|
result += "// This code is generated for testing purposes\n\n";
|
||||||
bool hasQuery = false;
|
bool hasQuery = false;
|
||||||
bool hasBody = false;
|
bool hasBody = false;
|
||||||
bool hasFormData = false;
|
bool hasFormData = false;
|
||||||
|
|||||||
@@ -82,7 +82,8 @@ print('Response Body:', response.text)
|
|||||||
String? boundary,
|
String? boundary,
|
||||||
}) {
|
}) {
|
||||||
try {
|
try {
|
||||||
String result = "";
|
String result = "# SECURITY NOTICE: Please validate all inputs and URLs before use in production\n";
|
||||||
|
result += "# This code is generated for testing purposes\n\n";
|
||||||
bool hasQuery = false;
|
bool hasQuery = false;
|
||||||
bool hasHeaders = false;
|
bool hasHeaders = false;
|
||||||
bool hasBody = false;
|
bool hasBody = false;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:hive_flutter/hive_flutter.dart';
|
import 'package:hive_flutter/hive_flutter.dart';
|
||||||
|
import 'secure_credential_storage.dart';
|
||||||
|
|
||||||
enum HiveBoxType { normal, lazy }
|
enum HiveBoxType { normal, lazy }
|
||||||
|
|
||||||
@@ -127,11 +128,110 @@ class HiveHandler {
|
|||||||
environmentBox.put(kKeyEnvironmentBoxIds, ids);
|
environmentBox.put(kKeyEnvironmentBoxIds, ids);
|
||||||
|
|
||||||
dynamic getEnvironment(String id) => environmentBox.get(id);
|
dynamic getEnvironment(String id) => environmentBox.get(id);
|
||||||
Future<void> setEnvironment(
|
|
||||||
String id, Map<String, dynamic>? environmentJson) =>
|
|
||||||
environmentBox.put(id, environmentJson);
|
|
||||||
|
|
||||||
Future<void> deleteEnvironment(String id) => environmentBox.delete(id);
|
/// Sets environment with automatic encryption of secrets
|
||||||
|
Future<void> setEnvironment(
|
||||||
|
String id, Map<String, dynamic>? environmentJson) async {
|
||||||
|
if (environmentJson == null) {
|
||||||
|
return environmentBox.put(id, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a copy to avoid modifying the original
|
||||||
|
final secureEnvData = Map<String, dynamic>.from(environmentJson);
|
||||||
|
|
||||||
|
// Check if values array exists and process secrets
|
||||||
|
if (secureEnvData['values'] is List) {
|
||||||
|
final values = secureEnvData['values'] as List;
|
||||||
|
|
||||||
|
for (var i = 0; i < values.length; i++) {
|
||||||
|
final variable = values[i];
|
||||||
|
|
||||||
|
if (variable is Map &&
|
||||||
|
variable['type'] == 'secret' &&
|
||||||
|
variable['value'] != null &&
|
||||||
|
variable['value'].toString().isNotEmpty) {
|
||||||
|
|
||||||
|
// Store secret in secure storage
|
||||||
|
try {
|
||||||
|
await SecureCredentialStorage.storeEnvironmentSecret(
|
||||||
|
environmentId: id,
|
||||||
|
variableKey: variable['key'] ?? 'unknown_$i',
|
||||||
|
value: variable['value'].toString(),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Replace value with placeholder in Hive
|
||||||
|
secureEnvData['values'][i] = {
|
||||||
|
...variable,
|
||||||
|
'value': '***SECURE***',
|
||||||
|
'isEncrypted': true,
|
||||||
|
};
|
||||||
|
} catch (e) {
|
||||||
|
// If secure storage fails, keep original value but log
|
||||||
|
// In production, consider proper error handling
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return environmentBox.put(id, secureEnvData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets environment with automatic decryption of secrets
|
||||||
|
Future<Map<String, dynamic>?> getEnvironmentSecure(String id) async {
|
||||||
|
final data = environmentBox.get(id);
|
||||||
|
if (data == null) return null;
|
||||||
|
|
||||||
|
// Create a copy to modify
|
||||||
|
final envData = Map<String, dynamic>.from(data);
|
||||||
|
|
||||||
|
// Process encrypted values
|
||||||
|
if (envData['values'] is List) {
|
||||||
|
final values = List.from(envData['values']);
|
||||||
|
|
||||||
|
for (var i = 0; i < values.length; i++) {
|
||||||
|
final variable = values[i];
|
||||||
|
|
||||||
|
if (variable is Map &&
|
||||||
|
variable['isEncrypted'] == true &&
|
||||||
|
variable['type'] == 'secret') {
|
||||||
|
|
||||||
|
// Retrieve secret from secure storage
|
||||||
|
try {
|
||||||
|
final decryptedValue = await SecureCredentialStorage.retrieveEnvironmentSecret(
|
||||||
|
environmentId: id,
|
||||||
|
variableKey: variable['key'] ?? 'unknown_$i',
|
||||||
|
);
|
||||||
|
|
||||||
|
if (decryptedValue != null) {
|
||||||
|
values[i] = {
|
||||||
|
...variable,
|
||||||
|
'value': decryptedValue,
|
||||||
|
'isEncrypted': false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// If decryption fails, keep placeholder
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
envData['values'] = values;
|
||||||
|
}
|
||||||
|
|
||||||
|
return envData;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> deleteEnvironment(String id) async {
|
||||||
|
// Clean up secure storage for this environment
|
||||||
|
try {
|
||||||
|
await SecureCredentialStorage.clearEnvironmentSecrets(
|
||||||
|
environmentId: id,
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
// Log error but continue with deletion
|
||||||
|
}
|
||||||
|
return environmentBox.delete(id);
|
||||||
|
}
|
||||||
|
|
||||||
dynamic getHistoryIds() => historyMetaBox.get(kHistoryBoxIds);
|
dynamic getHistoryIds() => historyMetaBox.get(kHistoryBoxIds);
|
||||||
Future<void> setHistoryIds(List<String>? ids) =>
|
Future<void> setHistoryIds(List<String>? ids) =>
|
||||||
|
|||||||
Reference in New Issue
Block a user