code to decrypt and login using locally saved credentials

This commit is contained in:
sanjay
2024-03-11 17:08:02 +05:30
parent 3913aedefc
commit 8c4fedfe28
2 changed files with 227 additions and 171 deletions

View File

@@ -15,6 +15,8 @@ import android.net.Uri
import android.os.BatteryManager
import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.provider.Settings
import android.util.Base64
import android.util.Log
import android.view.LayoutInflater
@@ -40,6 +42,7 @@ import com.example.hpostesting.data.model.patient.HemoCubeTestData
import com.example.hpostesting.data.model.patient.UserData
import com.example.hpostesting.data.model.updates.CheckUpdateRequest
import com.example.hpostesting.data.model.updates.DeviceUpdateRequest
import com.example.hpostesting.encryption.Encryption
import com.example.hpostesting.presentation.KitScanActivity
import com.example.hpostesting.presentation.UsbServiceListener
import com.example.hpostesting.presentation.adapter.OfflineUserListAdapter
@@ -151,69 +154,69 @@ class HomeFragment : Fragment() {
}
// Now re-subscribe to allUserData
/* hemoCubeViewModel.allLocalData.observe(viewLifecycleOwner) { originalUserDataList ->
/* hemoCubeViewModel.allLocalData.observe(viewLifecycleOwner) { originalUserDataList ->
Log.d("LOCAL_DB OBSERVE", "OBSERVE CALLED")
Log.d("LOCAL_DB OBSERVE", "OBSERVE CALLED")
val resultList = MolbioV2ResultRequest(mutableListOf())
originalUserDataList.forEach { userData ->
Log.d(
": USER DATA",
originalUserDataList.count().toString() + " : " + userData._id
)
var accessToken = sharedPreference.getString(Constants.ACCESS_TOKEN, "").toString()
// Upload results after processing all userData to avoid duplicates and ensure all modifications are done
if(accessToken.isNotEmpty()) {
if (!userData.molbioFlag && isTokenAvailable && Constants.MOLBIO_INTEGRATION) {
val currentTimeFormatted = SimpleDateFormat(
"yyyy-MM-dd'T'HH:mm:ssZZZZZ",
Locale.getDefault()
).format(Calendar.getInstance().time)
val bufferIntensityThreshold =
Constants.BUFFER_INTENSITY_THRESHOLDS[userData.deviceId]?.toString()
?: "defaultThreshold" // Handle possible nulls safely
resultList.results?.add(
MolbioV2Result(
rawData = userData,
analysisId = userData._id,
analysisDate = currentTimeFormatted,
analysisStatus = userData.classificationResult
?: "defaultStatus", // Handle possible nulls
thresholds = bufferIntensityThreshold,
interpretation = userData.classificationResult
?: "defaultInterpretation", // Handle possible nulls
testId = userData._id,
testTime = currentTimeFormatted,
collectionTime = currentTimeFormatted,
expiryTime = currentTimeFormatted
)
)
}
}
}
Log.d("USER DATA LIST SIZE", resultList.results?.count().toString())
val resultList = MolbioV2ResultRequest(mutableListOf())
originalUserDataList.forEach { userData ->
Log.d(
": USER DATA",
originalUserDataList.count().toString() + " : " + userData._id
)
var accessToken = sharedPreference.getString(Constants.ACCESS_TOKEN, "").toString()
// Upload results after processing all userData to avoid duplicates and ensure all modifications are done
if(accessToken.isNotEmpty()) {
if (!userData.molbioFlag && isTokenAvailable && Constants.MOLBIO_INTEGRATION) {
val currentTimeFormatted = SimpleDateFormat(
"yyyy-MM-dd'T'HH:mm:ssZZZZZ",
Locale.getDefault()
).format(Calendar.getInstance().time)
val bufferIntensityThreshold =
Constants.BUFFER_INTENSITY_THRESHOLDS[userData.deviceId]?.toString()
?: "defaultThreshold" // Handle possible nulls safely
resultList.results?.add(
MolbioV2Result(
rawData = userData,
analysisId = userData._id,
analysisDate = currentTimeFormatted,
analysisStatus = userData.classificationResult
?: "defaultStatus", // Handle possible nulls
thresholds = bufferIntensityThreshold,
interpretation = userData.classificationResult
?: "defaultInterpretation", // Handle possible nulls
testId = userData._id,
testTime = currentTimeFormatted,
collectionTime = currentTimeFormatted,
expiryTime = currentTimeFormatted
)
)
}
}
}
Log.d("USER DATA LIST SIZE", resultList.results?.count().toString())
resultList.results?.forEach { result ->
val userData = result.rawData
Log.d("UserData", userData.toString())
if (userData != null) {
if (!userData.localFlag) {
hemoCubeViewModel.bulkAddResultTestToDb(userData)
resultList.results?.forEach { result ->
val userData = result.rawData
Log.d("UserData", userData.toString())
if (userData != null) {
if (!userData.localFlag) {
hemoCubeViewModel.bulkAddResultTestToDb(userData)
}
}
}
resultList.results?.forEach { result ->
result.rawData?.let { sanitizeDoubleValues(it) }
}
}
}
}
resultList.results?.forEach { result ->
result.rawData?.let { sanitizeDoubleValues(it) }
}
// Then, check if there are any results to upload.
if (resultList.results?.isNotEmpty() == true) {
hemoCubeViewModel.uploadResult(resultList)
Log.d("resultcount1", "Uploading sanitized results")
}
// Then, check if there are any results to upload.
if (resultList.results?.isNotEmpty() == true) {
hemoCubeViewModel.uploadResult(resultList)
Log.d("resultcount1", "Uploading sanitized results")
}
}*/
}*/
hemoCubeViewModel.sendDataToMolbio()
hemoCubeViewModel.sendDataToFirebase()
@@ -310,26 +313,52 @@ class HomeFragment : Fragment() {
var password = sharedPreference.getString(Constants.DEVICE_PASSWORD_API, "").toString()
var userID = sharedPreference.getString(Constants.DEVICE_ID_API, "").toString()
deviceId = sharedPreference.getString(Constants.DEVICE_ID, "").toString()
if(userID.isNotEmpty() && password.isNotEmpty()) {
Log.d("istoken",isTokenAvailable.toString())
if (!isTokenAvailable) {
Log.d("istoken1",isTokenAvailable.toString())
hemoCubeViewModel.login(createLoginRequestData(userID, password))
isTokenAvailable = true
}else if(isTokenAvailable){
Log.d("istoken7",isTokenAvailable.toString())
isTokenAvailable = true
hemoCubeViewModel.startPeriodicCheckUpdate()
hemoCubeViewModel.checkUpdate(createCheckUpdateRequestData())
}else{
if(isTokenExpired(accessToken)) {
Log.d("istoken8",isTokenAvailable.toString())
hemoCubeViewModel.login(createLoginRequestData(userID, password))
}
}
val target = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
val file = File(target, "credentials.txt") //this file contains userID and password to communicate with API.
if (userID.isNotEmpty() && password.isNotEmpty()) {
Log.d("istoken", isTokenAvailable.toString())
if (!isTokenAvailable) {
Log.d("istoken1", isTokenAvailable.toString())
hemoCubeViewModel.login(createLoginRequestData(userID, password))
isTokenAvailable = true
} else if (isTokenAvailable) {
Log.d("istoken7", isTokenAvailable.toString())
isTokenAvailable = true
hemoCubeViewModel.startPeriodicCheckUpdate()
hemoCubeViewModel.checkUpdate(createCheckUpdateRequestData())
} else {
if (isTokenExpired(accessToken)) {
Log.d("istoken8", isTokenAvailable.toString())
hemoCubeViewModel.login(createLoginRequestData(userID, password))
}
}
} else if (userID == "deviceIDAPI" && password == "devicePasswordAPI" && deviceId.isNotEmpty()) {
fetchDeviceCredentials()
} else if (file.exists()) {
val encryptedString = file.readText()
val encryptionKey =
Settings.Secure.getString(context?.contentResolver, Settings.Secure.ANDROID_ID)
val decryptedMessage: String = Encryption.decrypt(encryptedString, encryptionKey)
val credentials = decryptedMessage.split("\n")
userID = credentials[0]
password = credentials[1]
Toast.makeText(context, "DECRYPTED: $credentials", Toast.LENGTH_SHORT).show()
if (!isTokenAvailable) {
hemoCubeViewModel.login(createLoginRequestData(userID, password))
isTokenAvailable = true
} else if (isTokenAvailable) {
isTokenAvailable = true
hemoCubeViewModel.startPeriodicCheckUpdate()
hemoCubeViewModel.checkUpdate(createCheckUpdateRequestData())
} else {
if (isTokenExpired(accessToken)) {
hemoCubeViewModel.login(createLoginRequestData(userID, password))
}
}
} else {
Toast.makeText(
requireContext(),
@@ -344,7 +373,7 @@ class HomeFragment : Fragment() {
updateTokens(response)
response.data.data?.accessToken
isTokenAvailable = true
Log.d("istoken2",isTokenAvailable.toString())
Log.d("istoken2", isTokenAvailable.toString())
}
is Result.Error -> {
@@ -370,7 +399,7 @@ class HomeFragment : Fragment() {
when (it) {
is Result.Success -> {
Log.d("success,","uploded")
Log.d("success,", "uploded")
it.data.data?.forEach { id ->
id.rawData?.let { it1 ->
hemoCubeViewModel.updateMolbioFlag(
@@ -378,7 +407,11 @@ class HomeFragment : Fragment() {
)
}
}
Toast.makeText(activity, "Molbio Result is successfully uploaded", Toast.LENGTH_LONG)
Toast.makeText(
activity,
"Molbio Result is successfully uploaded",
Toast.LENGTH_LONG
)
.show()
}
@@ -429,25 +462,29 @@ class HomeFragment : Fragment() {
hemoCubeViewModel.checkUpdate.observe(viewLifecycleOwner) { response ->
when (response) {
is Result.Success -> {
val updatedversion = response.data.data?.version.toString()
val updatedversion = response.data.data?.version.toString()
val currentversion =
context?.let { ctx ->
val packageInfo = ctx.packageManager.getPackageInfo(ctx.packageName, 0)
val versionName = packageInfo.versionName
val versionCode: Long = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
// From Android P (API level 28), versionCode is deprecated and you should use longVersionCode instead.
packageInfo.longVersionCode
} else {
// For older Android versions, use versionCode (cast it to Long for consistency).
packageInfo.versionCode.toLong()
}
val versionCode: Long =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
// From Android P (API level 28), versionCode is deprecated and you should use longVersionCode instead.
packageInfo.longVersionCode
} else {
// For older Android versions, use versionCode (cast it to Long for consistency).
packageInfo.versionCode.toLong()
}
// Use versionName and versionCode as needed
Log.d("AppInfo", "Version Name: $versionName, Version Code: $versionCode")
Log.d(
"AppInfo",
"Version Name: $versionName, Version Code: $versionCode"
)
}
Log.d("versionnow",currentversion.toString())
Log.d("versionnow",updatedversion.toString())
if(updatedversion > currentversion.toString()){
Log.d("versionnow", currentversion.toString())
Log.d("versionnow", updatedversion.toString())
if (updatedversion > currentversion.toString()) {
hemoCubeViewModel.deviceUpdate(createDeviceUpdateRequestData())
Toast.makeText(
activity,
@@ -455,7 +492,7 @@ class HomeFragment : Fragment() {
Toast.LENGTH_LONG
)
.show()
}else{
} else {
Toast.makeText(
activity,
"App is Up to date",
@@ -491,14 +528,19 @@ class HomeFragment : Fragment() {
val downloadDirectory = "NATS"
val fileName = "nats_certificate.zip"
val unzipDirectoryPath = requireContext().getExternalFilesDir(null)?.absolutePath + "/$downloadDirectory"
val unzipDirectoryPath =
requireContext().getExternalFilesDir(null)?.absolutePath + "/$downloadDirectory"
// Check if the directory with extracted files exists.
val directory = File(unzipDirectoryPath)
if (directory.exists() && directory.isDirectory) {
// Assuming if the directory exists, the certificate has been downloaded and extracted.
// You can add more specific checks here, e.g., checking for specific files within the directory.
Toast.makeText(requireContext(), "NATS certificate already downloaded and extracted.", Toast.LENGTH_SHORT).show()
Toast.makeText(
requireContext(),
"NATS certificate already downloaded and extracted.",
Toast.LENGTH_SHORT
).show()
return@observe
}
val file = downloadFile(url, requireContext(), fileName, downloadDirectory)
@@ -530,7 +572,7 @@ class HomeFragment : Fragment() {
private fun isTokenExpired(token: String): Boolean {
if(token.isNotEmpty()) {
if (token.isNotEmpty()) {
val parts = token.split("\\.".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
val decodedPayload = String(Base64.decode(parts[1], Base64.DEFAULT))
val jsonPayload = JSONObject(decodedPayload)
@@ -539,7 +581,7 @@ class HomeFragment : Fragment() {
val currentTimeSeconds = System.currentTimeMillis() / 1000
return exp <= currentTimeSeconds
}else{
} else {
return false
}
}
@@ -554,7 +596,7 @@ class HomeFragment : Fragment() {
apply()
}
isTokenAvailable = true
Log.d("istoken3",isTokenAvailable.toString())
Log.d("istoken3", isTokenAvailable.toString())
}
private fun createLoginRequestData(userID: String, password: String): LoginRequest {
@@ -697,9 +739,9 @@ class HomeFragment : Fragment() {
putString(Constants.NATS_TOKEN, natsToken)
apply()
}
if (!isTokenAvailable ) {
if (!isTokenAvailable) {
Log.d("istoken0", isTokenAvailable.toString())
hemoCubeViewModel.login(createLoginRequestData(username, password))
hemoCubeViewModel.login(createLoginRequestData(username, password))
}
} ?: Log.e("fetchDeviceCredentials", "Failed to parse device data.")
@@ -904,7 +946,6 @@ class HomeFragment : Fragment() {
}
private fun showUploadDialog(context: Context) {
val builder = AlertDialog.Builder(context)
builder.setTitle(R.string.upload_db_registration_title)
@@ -1117,7 +1158,7 @@ class HomeFragment : Fragment() {
// }
private fun getDeviceId() {
Log.d("HomeFragmentUSb","getDeviceId")
Log.d("HomeFragmentUSb", "getDeviceId")
val handler = activity as? DeviceCommunicationHandler
handler?.sendAndListenToDevice(
HemoCubeCommands.DEVICE_CONFIGURATION_COMMAND,
@@ -1125,9 +1166,10 @@ class HomeFragment : Fragment() {
override fun onUsbRead(data: ByteArray?) {
data?.let {
val receivedData = String(it, Charset.forName("UTF-8"))
Log.d("HomeFragment","USB data"+receivedData)
Log.d("HomeFragment", "USB data" + receivedData)
// Assuming the device ID is the full content of the received data. Adjust if needed.
deviceId = extractDeviceId(receivedData) // Implement this method based on your data format.
deviceId =
extractDeviceId(receivedData) // Implement this method based on your data format.
if (deviceId.isNotEmpty()) {
// Store the deviceId in SharedPreferences
with(sharedPreference.edit()) {
@@ -1144,7 +1186,7 @@ class HomeFragment : Fragment() {
override fun onUsbError(e: Exception?) {
// Handle USB communication error
Log.d("HomeFragment","USB read error"+e.toString())
Log.d("HomeFragment", "USB read error" + e.toString())
}
})
@@ -1156,94 +1198,103 @@ class HomeFragment : Fragment() {
val matchResult = regex.find(receivedData)
return matchResult?.groups?.get(1)?.value ?: ""
}
@SuppressLint("SuspiciousIndentation")
private fun checkForUpdate() {
try {
val db = Firebase.firestore
//val deviceId = deviceId
//val deviceId = deviceId
val deviceRef = db.collection("deviceUpdate").document(Constants.DOCUMENT_ID_FOR_UPDATE)
deviceRef.get().addOnSuccessListener { documentSnapshot ->
if (documentSnapshot.exists()) {
if (documentSnapshot.exists()) {
val deviceData =
documentSnapshot.toObject(DeviceData::class.java)
val deviceData =
documentSnapshot.toObject(DeviceData::class.java)
// deviceData?.let { data ->
// deviceData?.let { data ->
val deviceVersion = deviceData!!.deviceVersion
val deviceUpdateAvailableGlobal= deviceData.deviceUpdateAvailable
val updatePathGlobal= deviceData.updatePath
val deviceVersion = deviceData!!.deviceVersion
val deviceUpdateAvailableGlobal = deviceData.deviceUpdateAvailable
val updatePathGlobal = deviceData.updatePath
db.collection("devices").whereEqualTo("deviceId", deviceId).get().addOnSuccessListener { documentSnapshotNew ->
if (documentSnapshotNew.documents.isNotEmpty()) {
documentSnapshotNew.documents.forEach{
val documentIn = it.toObject(DeviceData::class.java)
db.collection("devices").whereEqualTo("deviceId", deviceId).get()
.addOnSuccessListener { documentSnapshotNew ->
if (documentSnapshotNew.documents.isNotEmpty()) {
documentSnapshotNew.documents.forEach {
val documentIn = it.toObject(DeviceData::class.java)
val globalUpdateIgnore = documentIn!!.globalUpdateIgnore
val deviceUpdateAvailable = documentIn.deviceUpdateAvailable
val globalUpdateDone = documentIn.globalUpdateDone
val updatePath = documentIn.updatePath
if(globalUpdateIgnore){
if(deviceUpdateAvailable){
val update = db.collection("devices").document(it.id).update("deviceUpdateAvailable",false)
update.addOnSuccessListener {
Log.d("HomeFragmentUpdate","Device local update done")
val globalUpdateIgnore = documentIn!!.globalUpdateIgnore
val deviceUpdateAvailable = documentIn.deviceUpdateAvailable
val globalUpdateDone = documentIn.globalUpdateDone
val updatePath = documentIn.updatePath
if (globalUpdateIgnore) {
if (deviceUpdateAvailable) {
val update = db.collection("devices").document(it.id)
.update("deviceUpdateAvailable", false)
update.addOnSuccessListener {
Log.d(
"HomeFragmentUpdate",
"Device local update done"
)
initiateUpdate(updatePath)
}.addOnFailureListener{
Log.e("fetchDeviceUpdate", "update fail.")
}
}else{
Log.d("HomeFragmentUpdate","Device update not available")
}
}else{
if(deviceUpdateAvailableGlobal) {
if (!globalUpdateDone) {
val update =
db.collection("devices").document(it.id)
.update("globalUpdateDone", true)
update.addOnSuccessListener {
Log.d(
"HomeFragmentUpdate",
"Device global update done"
)
initiateUpdate(updatePath)
}.addOnFailureListener {
Log.e("fetchDeviceUpdate", "update fail.")
}
} else {
Log.d(
"HomeFragmentUpdate",
"Device update not available"
)
}
} else {
if (deviceUpdateAvailableGlobal) {
if (!globalUpdateDone) {
val update =
db.collection("devices").document(it.id)
.update("globalUpdateDone", true)
update.addOnSuccessListener {
Log.d(
"HomeFragmentUpdate",
"Device global update done"
)
initiateUpdate(updatePathGlobal)
}.addOnFailureListener {
Log.e(
"fetchDeviceUpdate",
"update fail."
)
}
}
initiateUpdate(updatePathGlobal)
}.addOnFailureListener {
Log.e(
"fetchDeviceUpdate",
"update fail."
)
}
}
}
} else {
Log.e("fetchDeviceUpdate", "Document does not exist.")
}
}.addOnFailureListener { exception ->
Log.e("fetchDeviceUpdate", "Error fetching device data", exception)
}
// Toast.makeText(requireActivity()," true -version."+deviceVersion+"updatePath.."+updatePath,Toast.LENGTH_LONG).show()
} else {
Log.e("fetchDeviceUpdate", "Document does not exist.")
}
}.addOnFailureListener { exception ->
Log.e("fetchDeviceUpdate", "Error fetching device data", exception)
}
// Log for debugging
Log.d(
"fetchDeviceCredentials",
"deviceVersion: $deviceVersion, Password: $deviceUpdateAvailableGlobal, updatePath: $updatePathGlobal"
)
// Toast.makeText(requireActivity()," true -version."+deviceVersion+"updatePath.."+updatePath,Toast.LENGTH_LONG).show()
// Log for debugging
Log.d(
"fetchDeviceCredentials",
"deviceVersion: $deviceVersion, Password: $deviceUpdateAvailableGlobal, updatePath: $updatePathGlobal"
)
// ?: Log.e("fetchDeviceUpdate", "Failed to parse device data.")
} else {
Log.e("fetchDeviceUpdate", "Document does not exist.")
}
} else {
Log.e("fetchDeviceUpdate", "Document does not exist.")
}
}
.addOnFailureListener { exception ->
Log.e("fetchDeviceUpdate", "Error fetching device data", exception)
}
@@ -1265,7 +1316,8 @@ class HomeFragment : Fragment() {
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
request.setDestinationInExternalFilesDir(requireActivity(), "Updates", "update.apk")
val downloadManager = requireActivity().getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
val downloadManager =
requireActivity().getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
downloadId = downloadManager.enqueue(request)
// Register a BroadcastReceiver to receive the download complete event
@@ -1275,12 +1327,15 @@ class HomeFragment : Fragment() {
requireActivity().registerReceiver(downloadReceiver, filter, RECEIVER_EXPORTED)
}
}
private fun extractApkUrl(responseBody: ResponseBody): String {
return responseBody.string()
}
private fun isValidHttpUrl(url: String): Boolean {
return url.startsWith("http://") || url.startsWith("https://")
}
private val downloadReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
val id = intent?.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1)
@@ -1294,8 +1349,11 @@ class HomeFragment : Fragment() {
val file = File(requireActivity().getExternalFilesDir("Updates"), "update.apk")
file.setReadable(true, false) // Ensure the file is readable
val pInfo = requireActivity().baseContext.packageManager.getPackageInfo(requireActivity().baseContext.packageName, 0)
Log.d("HomeFragmentShowInfo",pInfo.packageName.toString())
val pInfo = requireActivity().baseContext.packageManager.getPackageInfo(
requireActivity().baseContext.packageName,
0
)
Log.d("HomeFragmentShowInfo", pInfo.packageName.toString())
val uri: Uri = FileProvider.getUriForFile(
requireActivity(),
"${pInfo.packageName}.fileprovider",
@@ -1318,7 +1376,7 @@ class HomeFragment : Fragment() {
}
override fun onDestroy() {
if(isRegistered) {
if (isRegistered) {
try {
requireActivity().unregisterReceiver(downloadReceiver)
} catch (e: Exception) {

View File

@@ -233,7 +233,7 @@ class DeviceProvisionFragment : Fragment() {
}
private fun encryptAndSaveToFile(username: String, password: String) {
val messageToEncrypt = "deviceID\n$username\n$password"
val messageToEncrypt = "$username\n$password"
val encryptionKey =
Settings.Secure.getString(context?.contentResolver, Settings.Secure.ANDROID_ID)
val encryptedString = Encryption.encrypt(messageToEncrypt, encryptionKey)
@@ -245,12 +245,10 @@ class DeviceProvisionFragment : Fragment() {
file.createNewFile()
}
val fos = FileOutputStream(file)
file.writeText(encryptedString)
Log.d("Encrypted Message", encryptedString)
fos.close()
}
}