package expo.modules.esimmanager import android.app.Service import android.content.Intent import android.os.IBinder import android.service.euicc.ICarrierEuiccProvisioningService import android.service.euicc.IGetActivationCodeCallback import android.util.Log class CarrierEuiccProvisioningService : Service() { override fun onBind(intent: Intent): IBinder { return binder } private val binder = object : ICarrierEuiccProvisioningService.Stub() { override fun getActivationCode(callback: IGetActivationCodeCallback?) { callback?.onSuccess(activationCode) } override fun getActivationCodeForEid(eid: String?, callback: IGetActivationCodeCallback?) { callback?.onSuccess(activationCode) } } companion object { var activationCode = "" private set fun setActivationCode(value: String) { try { val validatedCode = validateAndFormatLpaCode(value) activationCode = validatedCode Log.d("CarrierEuiccProvisioningService", "Activation code set successfully") } catch (e: IllegalArgumentException) { Log.e("CarrierEuiccProvisioningService", "Invalid activation code: ${e.message}") throw e } } private fun validateAndFormatLpaCode(code: String): String { if (code.isBlank()) { throw IllegalArgumentException("Activation code cannot be empty") } if (code.length > 1000) { throw IllegalArgumentException("Activation code too long (max 1000 characters)") } val dangerousChars = listOf("<", ">", "\"", "'", "&", "script", "javascript") for (char in dangerousChars) { if (code.contains(char, ignoreCase = true)) { throw IllegalArgumentException("Activation code contains invalid characters") } } val formattedCode = if (code.startsWith("LPA:")) { code } else { "LPA:$code" } if (!isValidLpaFormat(formattedCode)) { throw IllegalArgumentException("Invalid LPA code format. Expected: LPA:1\$server\$code") } return formattedCode } private fun isValidLpaFormat(code: String): Boolean { val pattern = Regex("^LPA:\\d+\\$[^\\$]+\\$[A-Z0-9-]+$") if (!pattern.matches(code)) { return false } val parts = code.split("$") if (parts.size != 3) { return false } if (parts[0] != "LPA:1") { return false } if (parts[1].isBlank()) { return false } if (parts[2].isBlank()) { return false } return true } fun clearActivationCode() { activationCode = "" Log.d("CarrierEuiccProvisioningService", "Activation code cleared") } } }