diff --git a/bondoman/app/src/main/AndroidManifest.xml b/bondoman/app/src/main/AndroidManifest.xml index 163f17aa65ac3549f8d2706c30b786b3d461ea27..ba945ac2560be410db4833dc5dd50adea67ff6e1 100644 --- a/bondoman/app/src/main/AndroidManifest.xml +++ b/bondoman/app/src/main/AndroidManifest.xml @@ -41,7 +41,9 @@ </intent-filter> </activity> - <service android:name=".utils.BackgroundService" /> + <service android:name=".utils.CheckExpiryToken" + android:enabled="true" + android:exported="false" /> </application> </manifest> \ No newline at end of file diff --git a/bondoman/app/src/main/java/com/example/bondoman/LoginPage.kt b/bondoman/app/src/main/java/com/example/bondoman/LoginPage.kt index 05a6ddf64ae9fc6099faac884e279922e7f60ac0..be5565dc3482735faaac1e76f5b385ef51c95efb 100644 --- a/bondoman/app/src/main/java/com/example/bondoman/LoginPage.kt +++ b/bondoman/app/src/main/java/com/example/bondoman/LoginPage.kt @@ -47,7 +47,6 @@ class LoginPage : AppCompatActivity() { if(dataLogin != null) { val token = dataLogin.token - Log.d("Login", token) AuthManager.saveToken(this@LoginPage, token) val toMain = Intent(this@LoginPage, MainActivity::class.java) startActivity(toMain) diff --git a/bondoman/app/src/main/java/com/example/bondoman/MainActivity.kt b/bondoman/app/src/main/java/com/example/bondoman/MainActivity.kt index 95c72a7dd7a5b02be3eaecca9f9d39c3accbddf2..08c1b7711c5c1c6e4d8ce781e20e989a37e8ac41 100644 --- a/bondoman/app/src/main/java/com/example/bondoman/MainActivity.kt +++ b/bondoman/app/src/main/java/com/example/bondoman/MainActivity.kt @@ -1,27 +1,17 @@ package com.example.bondoman +import android.content.Intent import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.util.Log -import android.widget.RadioButton -import android.widget.RadioGroup -import androidx.core.content.ContentProviderCompat.requireContext import com.example.bondoman.databinding.ActivityMainBinding import androidx.fragment.app.Fragment -import androidx.lifecycle.ViewModelProvider -import com.example.bondoman.retrofit.Retrofit -import com.example.bondoman.retrofit.endpoint.EndpointCheckExpiry -import com.example.bondoman.retrofit.request.CheckExpiryRequest -import com.example.bondoman.room.Transaction import com.example.bondoman.room.TransactionDB -import com.example.bondoman.room.TransactionDao -import com.example.bondoman.utils.AuthManager +import com.example.bondoman.utils.CheckExpiryToken import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch -import java.text.SimpleDateFormat -import java.util.Date -import java.util.Locale + class MainActivity : AppCompatActivity() { private lateinit var binding: ActivityMainBinding @@ -32,6 +22,9 @@ class MainActivity : AppCompatActivity() { binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) + val serviceIntent = Intent(this, CheckExpiryToken::class.java) + startService(serviceIntent) + binding.bottomNavigationView.setOnNavigationItemSelectedListener { menuItem -> when (menuItem.itemId) { R.id.scan_cam -> replaceFragment(ScanPage(), HeaderScan()) diff --git a/bondoman/app/src/main/java/com/example/bondoman/retrofit/endpoint/EndpointCheckExpiry.kt b/bondoman/app/src/main/java/com/example/bondoman/retrofit/endpoint/EndpointCheckExpiry.kt index 9fbd76db1ca306f74c003442d14dc0776170786d..dc0012d331972761f8c12f201a503b26df36d990 100644 --- a/bondoman/app/src/main/java/com/example/bondoman/retrofit/endpoint/EndpointCheckExpiry.kt +++ b/bondoman/app/src/main/java/com/example/bondoman/retrofit/endpoint/EndpointCheckExpiry.kt @@ -2,12 +2,10 @@ package com.example.bondoman.retrofit.endpoint import com.example.bondoman.retrofit.data.DataExpiry -import com.example.bondoman.retrofit.request.CheckExpiryRequest import retrofit2.Response -import retrofit2.http.Header import retrofit2.http.POST interface EndpointCheckExpiry { @POST("api/auth/token") - suspend fun getExpiry(@Header("Authorization") token: CheckExpiryRequest): Response<DataExpiry> + suspend fun getExpiry(): Response<DataExpiry> } \ No newline at end of file diff --git a/bondoman/app/src/main/java/com/example/bondoman/retrofit/request/CheckExpiryRequest.kt b/bondoman/app/src/main/java/com/example/bondoman/retrofit/request/CheckExpiryRequest.kt index 52c00ea51f21dd39aa13a0523391390b53c33076..049e1a3ee2c4208969fab7c0c9c6d27a0a754cc5 100644 --- a/bondoman/app/src/main/java/com/example/bondoman/retrofit/request/CheckExpiryRequest.kt +++ b/bondoman/app/src/main/java/com/example/bondoman/retrofit/request/CheckExpiryRequest.kt @@ -1,5 +1,5 @@ package com.example.bondoman.retrofit.request data class CheckExpiryRequest( - val token : String + val token: String ) diff --git a/bondoman/app/src/main/java/com/example/bondoman/utils/AuthManager.kt b/bondoman/app/src/main/java/com/example/bondoman/utils/AuthManager.kt index 4e21575e1f47b12751365cf81bf3dabb93b0be6e..ec8c0f12550a6c1806301c50f18e35da84353212 100644 --- a/bondoman/app/src/main/java/com/example/bondoman/utils/AuthManager.kt +++ b/bondoman/app/src/main/java/com/example/bondoman/utils/AuthManager.kt @@ -4,6 +4,7 @@ import android.content.Context import android.content.SharedPreferences import androidx.security.crypto.EncryptedSharedPreferences import androidx.security.crypto.MasterKeys +import kotlinx.coroutines.CoroutineScope import java.nio.charset.StandardCharsets object AuthManager { diff --git a/bondoman/app/src/main/java/com/example/bondoman/utils/BackgroundService.kt b/bondoman/app/src/main/java/com/example/bondoman/utils/BackgroundService.kt deleted file mode 100644 index c47b9a2cb9cdedafd57291c1ecb1a6e8ccd86a1c..0000000000000000000000000000000000000000 --- a/bondoman/app/src/main/java/com/example/bondoman/utils/BackgroundService.kt +++ /dev/null @@ -1,72 +0,0 @@ -package com.example.bondoman.utils - -import android.app.Service -import android.content.Intent -import android.os.Handler -import android.os.IBinder -import android.widget.Toast -import com.example.bondoman.LoginPage -import com.example.bondoman.retrofit.Retrofit -import com.example.bondoman.retrofit.endpoint.EndpointCheckExpiry -import com.example.bondoman.retrofit.request.CheckExpiryRequest -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.launch -import java.time.Instant - -class BackgroundService : Service() { - private val handler = Handler() - private val delayMillis = 30000L - private val currentTime = Instant.now().epochSecond - - private val runnable: Runnable = object : Runnable { - override fun run() { - // Check token expiry logic using Retrofit - GlobalScope.launch(Dispatchers.IO) { - val token = AuthManager.getToken(this@BackgroundService) - val prefixedToken = "Bearer $token" - val request = CheckExpiryRequest(prefixedToken) - val retro = Retrofit.getInstance().create(EndpointCheckExpiry::class.java) - val response = retro.getExpiry(request) - if (response.isSuccessful) { - val dataExpiry = response.body() - if (dataExpiry != null) { - // Handle token expiry logic here - val exp = dataExpiry.exp - if (currentTime > exp) { - AuthManager.deleteToken(this@BackgroundService) - val intent = Intent(this@BackgroundService, LoginPage::class.java) - intent.flags = - Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK - startActivity(intent) - showToast("Token has expired") - } - } - } else { - // Handle unsuccessful response (e.g., token expired) - // For demonstration, we'll just show a toast - showToast("Token is expired") - } - } - } - } - - override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { - // Start the runnable when the service starts - handler.post(runnable) - return START_STICKY - } - - override fun onBind(intent: Intent?): IBinder? { - return null - } - - override fun onDestroy() { - super.onDestroy() - // Remove any pending callbacks to prevent memory leaks - handler.removeCallbacks(runnable) - } - private fun showToast(message: String){ - Toast.makeText(applicationContext, message, Toast.LENGTH_SHORT).show() - } -} \ No newline at end of file diff --git a/bondoman/app/src/main/java/com/example/bondoman/utils/CheckExpiryToken.kt b/bondoman/app/src/main/java/com/example/bondoman/utils/CheckExpiryToken.kt new file mode 100644 index 0000000000000000000000000000000000000000..2a29475cf01b2ba8ff3c882288c3895501bdc963 --- /dev/null +++ b/bondoman/app/src/main/java/com/example/bondoman/utils/CheckExpiryToken.kt @@ -0,0 +1,85 @@ +package com.example.bondoman.utils + +import android.app.Service +import android.content.Intent +import android.os.Handler +import android.os.IBinder +import android.os.Looper +import android.util.Log +import android.widget.Toast +import com.example.bondoman.LoginPage +import com.example.bondoman.retrofit.endpoint.EndpointCheckExpiry +import com.example.bondoman.retrofit.interceptor.AuthInterceptor +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch +import okhttp3.OkHttpClient +import retrofit2.converter.gson.GsonConverterFactory + +class CheckExpiryToken:Service() { + private lateinit var handler: Handler + + override fun onBind(p0: Intent?): IBinder? { + return null + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + val token = AuthManager.getToken(this) ?: "" + + handler = Handler() + GlobalScope.launch(Dispatchers.IO) { + try { + val interceptor = AuthInterceptor(token) + val okHttpClient = OkHttpClient.Builder() + .addInterceptor(interceptor) + .build() + val retro = retrofit2.Retrofit.Builder() + .baseUrl("https://pbd-backend-2024.vercel.app/") + .client(okHttpClient) + .addConverterFactory(GsonConverterFactory.create()) + .build() + + val request = retro.create(EndpointCheckExpiry::class.java) + val response = request.getExpiry() + + + if (response.isSuccessful) { + val dataExpiry = response.body() + if (dataExpiry != null) { + val exp = dataExpiry.exp + val currentTime = System.currentTimeMillis()/1000 + if (currentTime>exp){ + Handler(Looper.getMainLooper()).post { showToast("Token is expired. Please log in.") } + AuthManager.deleteToken(this@CheckExpiryToken) + val intent = Intent(this@CheckExpiryToken, LoginPage::class.java) + intent.flags = + Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK + startActivity(intent) + + } + } + } else { + val intent = Intent(this@CheckExpiryToken, LoginPage::class.java) + intent.flags = + Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK + startActivity(intent) + showToast("Token is expired. Please log in.") + } + } + catch (e: Exception){ + Log.e("CheckExpiry", "Error loading transactions: ${e.message}") + } + } + return START_STICKY + } + + override fun onDestroy() { + super.onDestroy() + } + + private fun showToast(message: String){ + Handler(Looper.getMainLooper()).post { + Toast.makeText(this@CheckExpiryToken, message, Toast.LENGTH_SHORT).show() + } + } +}