Last active
February 4, 2024 09:58
-
-
Save shibbirweb/5cea9781b062da6bb972503628cc9f59 to your computer and use it in GitHub Desktop.
Android - Kotlin - Retrofit Authorization Token Interceptor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package com.***.data.apis | |
| import android.content.Context | |
| import com.****.data.apis.interceptor.ApiAcceptInterceptor | |
| import com.****.data.apis.interceptor.AuthorizationTokenInterceptor | |
| import okhttp3.OkHttpClient | |
| import retrofit2.Retrofit | |
| import retrofit2.converter.gson.GsonConverterFactory | |
| import java.util.concurrent.TimeUnit | |
| object Api { | |
| const val BASE_URL = "https://api.***.com/api/v1/" | |
| private fun retrofit(context: Context?): Retrofit { | |
| return Retrofit.Builder() | |
| .baseUrl(BASE_URL) | |
| .client(client(context)) | |
| .addConverterFactory(GsonConverterFactory.create()) | |
| .build() | |
| } | |
| private fun client(context: Context?): OkHttpClient { | |
| return OkHttpClient.Builder().apply { | |
| connectTimeout(5, TimeUnit.MINUTES) | |
| readTimeout(5, TimeUnit.MINUTES) | |
| writeTimeout(5, TimeUnit.MINUTES) | |
| addInterceptor(ApiAcceptInterceptor()) | |
| if (context != null) | |
| addInterceptor(AuthorizationTokenInterceptor(context)) | |
| }.build() | |
| } | |
| fun <T> service(context: Context, clazz: Class<T>): T { | |
| return retrofit(context).create(clazz) | |
| } | |
| fun <T> serviceWithoutAuthorization(clazz: Class<T>): T { | |
| return retrofit(null).create(clazz) | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package com.***.utilities.constants | |
| object ApplicationConstants { | |
| // authorization | |
| const val TOKEN = "user_token" | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package com.***.data.apis.endpoints.authentication | |
| import com.***.data.models.project.authentication.* | |
| import com.***.data.models.response.GeneralResponse | |
| import com.***.data.models.response.authentication.IsAlreadyUserExists | |
| import com.***.data.models.response.authentication.LoginResponse | |
| import com.***.data.models.response.authentication.VerifyResponse | |
| import retrofit2.Response | |
| import retrofit2.http.Body | |
| import retrofit2.http.Header | |
| import retrofit2.http.POST | |
| interface AuthenticationApi { | |
| @POST("auth/login") | |
| suspend fun login( | |
| @Body credential: Login | |
| ): Response<LoginResponse> | |
| @POST("auth/register") | |
| suspend fun register( | |
| @Body registration: Registration | |
| ): Response<LoginResponse> | |
| @POST("exists/user-exists-by-credential") | |
| suspend fun isAlreadyUserExists(@Body registration: Registration): Response<IsAlreadyUserExists> | |
| @POST("auth/verify/email") | |
| suspend fun verifyEmail(@Body verify: Verify): Response<VerifyResponse> | |
| @POST("auth/verify/email") | |
| suspend fun verifyEmail( | |
| @Body verify: Verify, | |
| @Header("authorization") authorization: String | |
| ): Response<VerifyResponse> | |
| @POST("auth/verify/phone") | |
| suspend fun verifyPhone(@Body verify: Verify): Response<VerifyResponse> | |
| @POST("auth/verify/phone") | |
| suspend fun verifyPhone( | |
| @Body verify: Verify, | |
| @Header("authorization") authorization: String | |
| ): Response<VerifyResponse> | |
| @POST("auth/resend/verification/email") | |
| suspend fun resendVerificationCodeToEmail(@Header("Authorization") token: String): Response<GeneralResponse> | |
| @POST("auth/resend/verification/phone") | |
| suspend fun resendVerificationCodeToPhone(@Header("Authorization") token: String): Response<GeneralResponse> | |
| @POST("auth/logout") | |
| suspend fun logout(@Body logoutRequest: LogoutRequest): Response<GeneralResponse> | |
| @POST("auth/recovery/email") | |
| suspend fun sendVerificationCodeToEmail(@Body sendRecoveryCodeToEmailRequest: SendRecoveryCodeToEmailRequest): Response<String> | |
| @POST("auth/recovery/phone") | |
| suspend fun sendVerificationCodeToPhone(@Body sendRecoveryCodeToPhoneRequest: SendRecoveryCodeToPhoneRequest): Response<String> | |
| @POST("auth/recovery/password-reset/email") | |
| suspend fun resetPasswordByEmail(@Body resetPasswordByEmailRequest: ResetPasswordByEmailRequest): Response<GeneralResponse> | |
| @POST("auth/recovery/password-reset/phone") | |
| suspend fun resetPasswordByPhone(@Body resetPasswordByPhoneRequest: ResetPasswordByPhoneRequest): Response<GeneralResponse> | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package com.***.data.repository.authentication | |
| import android.content.Context | |
| import com.***.data.apis.Api | |
| import com.***.data.apis.endpoints.authentication.AuthenticationApi | |
| import com.***.data.models.project.authentication.* | |
| import com.***.data.models.response.authentication.IsAlreadyUserExists | |
| import com.***.data.models.response.authentication.LoginResponse | |
| import com.***.data.models.response.authentication.VerifyResponse | |
| import retrofit2.Response | |
| class AuthenticationRepository(private val context: Context) { | |
| private val apiService by lazy { | |
| Api.service(context, AuthenticationApi::class.java) | |
| } | |
| private val apiServiceWithOutAuthorizationTokenInterceptor by lazy { | |
| Api.serviceWithoutAuthorization(AuthenticationApi::class.java) | |
| } | |
| suspend fun login(credential: Login): Response<LoginResponse> { | |
| return apiServiceWithOutAuthorizationTokenInterceptor.login(credential) | |
| } | |
| suspend fun register(registration: Registration): Response<LoginResponse> { | |
| return apiServiceWithOutAuthorizationTokenInterceptor.register(registration) | |
| } | |
| suspend fun isAlreadyUserExists(registration: Registration): Response<IsAlreadyUserExists> { | |
| return apiServiceWithOutAuthorizationTokenInterceptor.isAlreadyUserExists(registration); | |
| } | |
| suspend fun verifyEmail(verify: Verify): Response<VerifyResponse> { | |
| return apiService.verifyEmail(verify) | |
| } | |
| suspend fun verifyEmail(verify: Verify, token: String): Response<VerifyResponse> { | |
| return apiServiceWithOutAuthorizationTokenInterceptor.verifyEmail(verify, "Bearer $token") | |
| } | |
| suspend fun verifyPhone(verify: Verify): Response<VerifyResponse> { | |
| return apiService.verifyPhone(verify) | |
| } | |
| suspend fun verifyPhone(verify: Verify, token: String): Response<VerifyResponse> { | |
| return apiServiceWithOutAuthorizationTokenInterceptor.verifyPhone(verify, "Bearer $token") | |
| } | |
| // resend verification code to email | |
| suspend fun resendVerificationCodeToEmail(token: String) = | |
| apiServiceWithOutAuthorizationTokenInterceptor.resendVerificationCodeToEmail(token) | |
| // resend verification code to phone | |
| suspend fun resendVerificationCodeToPhone(token: String) = | |
| apiServiceWithOutAuthorizationTokenInterceptor.resendVerificationCodeToPhone(token) | |
| // logout | |
| suspend fun logout(logoutRequest: LogoutRequest) = apiService.logout(logoutRequest) | |
| // send verification code to email | |
| suspend fun sendVerificationCodeToEmail(sendRecoveryCodeToEmailRequest: SendRecoveryCodeToEmailRequest) = | |
| apiService.sendVerificationCodeToEmail(sendRecoveryCodeToEmailRequest) | |
| // send verification code to phone | |
| suspend fun sendVerificationCodeToPhone(sendRecoveryCodeToPhoneRequest: SendRecoveryCodeToPhoneRequest) = | |
| apiService.sendVerificationCodeToPhone(sendRecoveryCodeToPhoneRequest) | |
| // reset password by email | |
| suspend fun resetPasswordByEmail(resetPasswordByEmailRequest: ResetPasswordByEmailRequest) = | |
| apiService.resetPasswordByEmail(resetPasswordByEmailRequest) | |
| // reset password by phone | |
| suspend fun resetPasswordByPhone(resetPasswordByPhoneRequest: ResetPasswordByPhoneRequest) = | |
| apiService.resetPasswordByPhone(resetPasswordByPhoneRequest) | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package com.***.data.dataStoreManager | |
| import android.content.Context | |
| import androidx.datastore.core.DataStore | |
| import androidx.datastore.preferences.core.* | |
| import androidx.datastore.preferences.preferencesDataStore | |
| import kotlinx.coroutines.flow.Flow | |
| import kotlinx.coroutines.flow.first | |
| import kotlinx.coroutines.flow.map | |
| // At the top level of your kotlin file: | |
| val Context.userSettingsDataStore: DataStore<Preferences> by preferencesDataStore(name = "user_settings") | |
| object DataStoreManager { | |
| suspend fun saveValue(context: Context, key: String, value: String) { | |
| val wrappedKey = stringPreferencesKey(key) | |
| context.userSettingsDataStore.edit { | |
| it[wrappedKey] = value | |
| } | |
| } | |
| suspend fun saveValue(context: Context, key: String, value: Int) { | |
| val wrappedKey = intPreferencesKey(key) | |
| context.userSettingsDataStore.edit { | |
| it[wrappedKey] = value | |
| } | |
| } | |
| suspend fun saveValue(context: Context, key: String, value: Double) { | |
| val wrappedKey = doublePreferencesKey(key) | |
| context.userSettingsDataStore.edit { | |
| it[wrappedKey] = value | |
| } | |
| } | |
| suspend fun saveValue(context: Context, key: String, value: Long) { | |
| val wrappedKey = longPreferencesKey(key) | |
| context.userSettingsDataStore.edit { | |
| it[wrappedKey] = value | |
| } | |
| } | |
| suspend fun saveValue(context: Context, key: String, value: Boolean) { | |
| val wrappedKey = booleanPreferencesKey(key) | |
| context.userSettingsDataStore.edit { | |
| it[wrappedKey] = value | |
| } | |
| } | |
| suspend fun getStringValue(context: Context, key: String, default: String = ""): String { | |
| val wrappedKey = stringPreferencesKey(key) | |
| val valueFlow: Flow<String> = context.userSettingsDataStore.data.map { | |
| it[wrappedKey] ?: default | |
| } | |
| return valueFlow.first() | |
| } | |
| suspend fun getIntValue(context: Context, key: String, default: Int = 0): Int { | |
| val wrappedKey = intPreferencesKey(key) | |
| val valueFlow: Flow<Int> = context.userSettingsDataStore.data.map { | |
| it[wrappedKey] ?: default | |
| } | |
| return valueFlow.first() | |
| } | |
| suspend fun getDoubleValue(context: Context, key: String, default: Double = 0.0): Double { | |
| val wrappedKey = doublePreferencesKey(key) | |
| val valueFlow: Flow<Double> = context.userSettingsDataStore.data.map { | |
| it[wrappedKey] ?: default | |
| } | |
| return valueFlow.first() | |
| } | |
| suspend fun getLongValue(context: Context, key: String, default: Long = 0L): Long { | |
| val wrappedKey = longPreferencesKey(key) | |
| val valueFlow: Flow<Long> = context.userSettingsDataStore.data.map { | |
| it[wrappedKey] ?: default | |
| } | |
| return valueFlow.first() | |
| } | |
| suspend fun getBooleanValue(context: Context, key: String, default: Boolean = false): Boolean { | |
| val wrappedKey = booleanPreferencesKey(key) | |
| val valueFlow: Flow<Boolean> = context.userSettingsDataStore.data.map { | |
| it[wrappedKey] ?: default | |
| } | |
| return valueFlow.first() | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment