📖 Przegląd

Moduł SecureStorage zapewnia bezpieczne przechowywanie wrażliwych danych używając EncryptedSharedPreferences z szyfrowaniem AES-256. Idealny do przechowywania tokenów API, danych użytkownika i innych poufnych informacji.

✅ Bezpieczeństwo: Dane są szyfrowane za pomocą AES256-GCM. Klucze przechowywane są w Android Keystore.
Szybki przykład
// Zapisywanie
ADict.SecureStorage.put("api_token", "secret123")
ADict.SecureStorage.put("user_id", 12345)

// Odczytywanie
val token = ADict.SecureStorage.getString("api_token")
val userId = ADict.SecureStorage.getInt("user_id", 0)

💾 Zapisywanie danych

put(key: String, value: Any?)

Zapisz wartość z automatycznym wykrywaniem typu.

putString(key: String, value: String)

Zapisz String.

putInt(key: String, value: Int)

Zapisz Int.

putLong(key: String, value: Long)

Zapisz Long.

putFloat(key: String, value: Float)

Zapisz Float.

putBoolean(key: String, value: Boolean)

Zapisz Boolean.

Zapisywanie danych
// Automatyczne wykrywanie typu
ADict.SecureStorage.put("token", "abc123")
ADict.SecureStorage.put("user_id", 12345)
ADict.SecureStorage.put("is_premium", true)
ADict.SecureStorage.put("balance", 99.99f)

// Typowane metody
ADict.SecureStorage.putString("api_key", "sk_live_xxx")
ADict.SecureStorage.putInt("login_count", 5)
ADict.SecureStorage.putLong("last_sync", System.currentTimeMillis())
ADict.SecureStorage.putBoolean("notifications_enabled", true)

// Usunięcie przez null
ADict.SecureStorage.put("temp_data", null)

📖 Odczytywanie danych

getString(key: String, default: String? = null): String?

Pobierz String.

getInt(key: String, default: Int = 0): Int

Pobierz Int.

getLong(key: String, default: Long = 0L): Long

Pobierz Long.

getFloat(key: String, default: Float = 0f): Float

Pobierz Float.

getBoolean(key: String, default: Boolean = false): Boolean

Pobierz Boolean.

Odczytywanie danych
// Z wartościami domyślnymi
val token = ADict.SecureStorage.getString("api_token") // null jeśli brak
val userId = ADict.SecureStorage.getInt("user_id", -1) // -1 jeśli brak
val isPremium = ADict.SecureStorage.getBoolean("is_premium", false)
val lastSync = ADict.SecureStorage.getLong("last_sync", 0L)

// Sprawdzenie czy klucz istnieje
if (ADict.SecureStorage.contains("api_token")) {
    val token = ADict.SecureStorage.getString("api_token")!!
    makeApiCall(token)
}

🔧 Narzędzia

contains(key: String): Boolean

Sprawdź czy klucz istnieje.

remove(key: String)

Usuń wartość.

clear()

Wyczyść wszystkie dane.

getAllKeys(): Set<String>

Pobierz wszystkie klucze.

getAll(): Map<String, Any?>

Pobierz wszystkie wartości.

⭐ Specjalne właściwości

SecureStorage oferuje wbudowane właściwości dla typowych przypadków użycia:

apiToken: String?

Get/set dla tokenu API.

ADict.SecureStorage.apiToken = "Bearer abc123"
val token = ADict.SecureStorage.apiToken

refreshToken: String?

Get/set dla refresh tokenu.

userId: String?

Get/set dla ID użytkownika.

clearTokens()

Wyczyść wszystkie tokeny (apiToken i refreshToken).

clearUserData()

Wyczyść dane użytkownika (tokeny + userId).

Zarządzanie sesją
// Logowanie
fun onLoginSuccess(response: LoginResponse) {
    ADict.SecureStorage.apiToken = response.accessToken
    ADict.SecureStorage.refreshToken = response.refreshToken
    ADict.SecureStorage.userId = response.userId
}

// Sprawdzenie sesji
fun isLoggedIn(): Boolean {
    return ADict.SecureStorage.apiToken != null
}

// Refresh tokenu
fun refreshAccessToken() {
    val refreshToken = ADict.SecureStorage.refreshToken ?: return
    api.refresh(refreshToken) { newToken ->
        ADict.SecureStorage.apiToken = newToken
    }
}

// Wylogowanie
fun logout() {
    ADict.SecureStorage.clearUserData()
    // lub bardziej szczegółowo:
    // ADict.SecureStorage.clearTokens()
    // ADict.SecureStorage.remove("userId")
}

💡 Przykłady praktyczne

Pełna obsługa autentykacji

AuthManager
object AuthManager {
    private const val KEY_USER_EMAIL = "user_email"
    private const val KEY_USER_NAME = "user_name"
    private const val KEY_TOKEN_EXPIRES = "token_expires"

    val isLoggedIn: Boolean
        get() = ADict.SecureStorage.apiToken != null

    val currentUserId: String?
        get() = ADict.SecureStorage.userId

    val currentUserEmail: String?
        get() = ADict.SecureStorage.getString(KEY_USER_EMAIL)

    fun saveSession(session: UserSession) {
        ADict.SecureStorage.apiToken = session.accessToken
        ADict.SecureStorage.refreshToken = session.refreshToken
        ADict.SecureStorage.userId = session.userId
        ADict.SecureStorage.putString(KEY_USER_EMAIL, session.email)
        ADict.SecureStorage.putString(KEY_USER_NAME, session.name)
        ADict.SecureStorage.putLong(KEY_TOKEN_EXPIRES, session.expiresAt)
    }

    fun isTokenExpired(): Boolean {
        val expiresAt = ADict.SecureStorage.getLong(KEY_TOKEN_EXPIRES, 0L)
        return System.currentTimeMillis() > expiresAt
    }

    fun getAuthHeader(): String? {
        return ADict.SecureStorage.apiToken?.let { "Bearer $it" }
    }

    fun logout() {
        ADict.SecureStorage.clearUserData()
        ADict.SecureStorage.remove(KEY_USER_EMAIL)
        ADict.SecureStorage.remove(KEY_USER_NAME)
        ADict.SecureStorage.remove(KEY_TOKEN_EXPIRES)
    }
}

// Użycie w OkHttp Interceptor
class AuthInterceptor : Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        val request = chain.request().newBuilder()

        AuthManager.getAuthHeader()?.let { authHeader ->
            request.addHeader("Authorization", authHeader)
        }

        return chain.proceed(request.build())
    }
}

Przechowywanie ustawień wrażliwych

Ustawienia aplikacji
object SecureSettings {
    // PIN aplikacji
    var appPin: String?
        get() = ADict.SecureStorage.getString("app_pin")
        set(value) {
            if (value != null) ADict.SecureStorage.putString("app_pin", value)
            else ADict.SecureStorage.remove("app_pin")
        }

    // Biometria
    var biometricEnabled: Boolean
        get() = ADict.SecureStorage.getBoolean("biometric_enabled", false)
        set(value) = ADict.SecureStorage.putBoolean("biometric_enabled", value)

    // Klucze szyfrowania
    fun saveEncryptionKey(key: ByteArray) {
        ADict.SecureStorage.putString("encryption_key", Base64.encodeToString(key, Base64.DEFAULT))
    }

    fun getEncryptionKey(): ByteArray? {
        return ADict.SecureStorage.getString("encryption_key")?.let {
            Base64.decode(it, Base64.DEFAULT)
        }
    }
}

📚 API Reference

Metoda Opis
put(key, value)Zapisz (auto-type)
putString(key, value)Zapisz String
putInt(key, value)Zapisz Int
putLong(key, value)Zapisz Long
putFloat(key, value)Zapisz Float
putBoolean(key, value)Zapisz Boolean
getString(key, default)Pobierz String
getInt(key, default)Pobierz Int
getLong(key, default)Pobierz Long
getFloat(key, default)Pobierz Float
getBoolean(key, default)Pobierz Boolean
contains(key)Sprawdź istnienie
remove(key)Usuń wartość
clear()Wyczyść wszystko
getAllKeys()Pobierz klucze
getAll()Pobierz wszystkie wartości
apiTokenProperty: token API
refreshTokenProperty: refresh token
userIdProperty: ID użytkownika
clearTokens()Wyczyść tokeny
clearUserData()Wyczyść dane użytkownika