diff --git a/apps/student/build.gradle b/apps/student/build.gradle index 644403aff7..df8c0ecaa2 100644 --- a/apps/student/build.gradle +++ b/apps/student/build.gradle @@ -50,8 +50,8 @@ android { applicationId "com.instructure.candroid" minSdkVersion Versions.MIN_SDK targetSdkVersion Versions.TARGET_SDK - versionCode = 257 - versionName = '7.0.1' + versionCode = 258 + versionName = '7.0.2' vectorDrawables.useSupportLibrary = true multiDexEnabled = true diff --git a/apps/student/src/main/java/com/instructure/student/di/ApplicationModule.kt b/apps/student/src/main/java/com/instructure/student/di/ApplicationModule.kt new file mode 100644 index 0000000000..38d3f681b2 --- /dev/null +++ b/apps/student/src/main/java/com/instructure/student/di/ApplicationModule.kt @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2023 - present Instructure, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * + */ + +package com.instructure.student.di + +import com.instructure.pandautils.utils.LogoutHelper +import com.instructure.student.util.StudentLogoutHelper +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent + +@Module +@InstallIn(SingletonComponent::class) +class ApplicationModule { + + @Provides + fun provideLogoutHelper(): LogoutHelper { + return StudentLogoutHelper() + } +} \ No newline at end of file diff --git a/apps/student/src/main/java/com/instructure/student/util/StudentLogoutHelper.kt b/apps/student/src/main/java/com/instructure/student/util/StudentLogoutHelper.kt new file mode 100644 index 0000000000..620eb7d127 --- /dev/null +++ b/apps/student/src/main/java/com/instructure/student/util/StudentLogoutHelper.kt @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2023 - present Instructure, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * + */ + +package com.instructure.student.util + +import com.instructure.loginapi.login.tasks.LogoutTask +import com.instructure.pandautils.room.offline.DatabaseProvider +import com.instructure.pandautils.utils.LogoutHelper +import com.instructure.student.tasks.StudentLogoutTask + +class StudentLogoutHelper : LogoutHelper { + override fun logout(databaseProvider: DatabaseProvider) { + StudentLogoutTask(LogoutTask.Type.LOGOUT, databaseProvider = databaseProvider).execute() + } +} \ No newline at end of file diff --git a/apps/teacher/src/main/java/com/instructure/teacher/di/ApplicationModule.kt b/apps/teacher/src/main/java/com/instructure/teacher/di/ApplicationModule.kt index c4cd8b0482..dba25af48c 100644 --- a/apps/teacher/src/main/java/com/instructure/teacher/di/ApplicationModule.kt +++ b/apps/teacher/src/main/java/com/instructure/teacher/di/ApplicationModule.kt @@ -16,12 +16,13 @@ */ package com.instructure.teacher.di +import com.instructure.pandautils.utils.LogoutHelper +import com.instructure.teacher.utils.TeacherLogoutHelper import com.instructure.teacher.utils.TeacherPrefs import dagger.Module import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent -import javax.inject.Singleton /** * Module that provides all the application scope dependencies, that are not related to other module. @@ -34,4 +35,9 @@ class ApplicationModule { fun provideTeacherPrefs(): TeacherPrefs { return TeacherPrefs } + + @Provides + fun provideLogoutHelper(): LogoutHelper { + return TeacherLogoutHelper() + } } \ No newline at end of file diff --git a/apps/teacher/src/main/java/com/instructure/teacher/utils/TeacherLogoutHelper.kt b/apps/teacher/src/main/java/com/instructure/teacher/utils/TeacherLogoutHelper.kt new file mode 100644 index 0000000000..aa905c8d21 --- /dev/null +++ b/apps/teacher/src/main/java/com/instructure/teacher/utils/TeacherLogoutHelper.kt @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2023 - present Instructure, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * + */ + +package com.instructure.teacher.utils + +import com.instructure.loginapi.login.tasks.LogoutTask +import com.instructure.pandautils.room.offline.DatabaseProvider +import com.instructure.pandautils.utils.LogoutHelper +import com.instructure.teacher.tasks.TeacherLogoutTask + +class TeacherLogoutHelper : LogoutHelper { + + override fun logout(databaseProvider: DatabaseProvider) { + TeacherLogoutTask(LogoutTask.Type.LOGOUT).execute() + } +} \ No newline at end of file diff --git a/libs/canvas-api-2/src/main/java/com/instructure/canvasapi2/utils/ApiPrefs.kt b/libs/canvas-api-2/src/main/java/com/instructure/canvasapi2/utils/ApiPrefs.kt index 33d12155f4..d7fcb748d6 100644 --- a/libs/canvas-api-2/src/main/java/com/instructure/canvasapi2/utils/ApiPrefs.kt +++ b/libs/canvas-api-2/src/main/java/com/instructure/canvasapi2/utils/ApiPrefs.kt @@ -65,7 +65,7 @@ object ApiPrefs : PrefManager(PREFERENCE_FILE_NAME) { /* Non-masquerading Prefs */ internal var originalDomain by StringPref("", "domain") - private var originalUser: User? by GsonPref(User::class.java, null, "user") + private var originalUser: User? by GsonPref(User::class.java, null, "user", false) var selectedLocale by StringPref(ACCOUNT_LOCALE) @@ -84,7 +84,7 @@ object ApiPrefs : PrefManager(PREFERENCE_FILE_NAME) { var isMasqueradingFromQRCode by BooleanPref() var masqueradeId by LongPref(-1L) internal var masqueradeDomain by StringPref() - internal var masqueradeUser: User? by GsonPref(User::class.java, null, "masq-user") + internal var masqueradeUser: User? by GsonPref(User::class.java, null, "masq-user", false) // Used to determine if a student can generate a pairing code, saved during splash var canGeneratePairingCode by NBooleanPref() diff --git a/libs/canvas-api-2/src/main/java/com/instructure/canvasapi2/utils/PrefUtils.kt b/libs/canvas-api-2/src/main/java/com/instructure/canvasapi2/utils/PrefUtils.kt index c836664ff0..eed66ffbfd 100644 --- a/libs/canvas-api-2/src/main/java/com/instructure/canvasapi2/utils/PrefUtils.kt +++ b/libs/canvas-api-2/src/main/java/com/instructure/canvasapi2/utils/PrefUtils.kt @@ -390,7 +390,8 @@ class ColorPref(@ColorRes defaultValue: Int, keyName: String? = null) : Pref( private val klazz: Class, defaultValue: T? = null, - keyName: String? = null + private val keyName: String? = null, + private val async: Boolean = true ) : Pref(defaultValue, keyName) { private var cachedObject: T? = null @@ -413,6 +414,14 @@ class GsonPref( } return this } + + override fun setValue(thisRef: PrefManager, property: KProperty<*>, value: T?) { + if (async) { + super.setValue(thisRef, property, value) + } else { + thisRef.editor.setValue(keyName ?: property.name, value).commit() + } + } } /** diff --git a/libs/login-api-2/src/main/java/com/instructure/loginapi/login/viewmodel/LoginViewModel.kt b/libs/login-api-2/src/main/java/com/instructure/loginapi/login/viewmodel/LoginViewModel.kt index 562e9cf516..3cbfbd4573 100644 --- a/libs/login-api-2/src/main/java/com/instructure/loginapi/login/viewmodel/LoginViewModel.kt +++ b/libs/login-api-2/src/main/java/com/instructure/loginapi/login/viewmodel/LoginViewModel.kt @@ -49,7 +49,6 @@ class LoginViewModel @Inject constructor( fun checkLogin(checkToken: Boolean, checkElementary: Boolean): LiveData> { viewModelScope.launch { try { - waitForUser() val offlineEnabled = featureFlagProvider.offlineEnabled() val offlineLogin = offlineEnabled && !networkStateProvider.isOnline() if (checkToken && !offlineLogin) { @@ -71,14 +70,6 @@ class LoginViewModel @Inject constructor( return loginResultAction } - // We need to wait for the user to be set in ApiPrefs - private suspend fun waitForUser() { - repeat(30) { - if (apiPrefs.user != null) return - delay(100) - } - } - private suspend fun checkTermsAcceptance(canvasForElementary: Boolean, offlineLogin: Boolean = false) { val authenticatedSession = oauthManager.getAuthenticatedSessionAsync("${apiPrefs.fullDomain}/users/self").await() val requiresTermsAcceptance = authenticatedSession.dataOrNull?.requiresTermsAcceptance ?: false diff --git a/libs/pandautils/src/main/java/com/instructure/pandautils/di/OfflineDatabaseProviderModule.kt b/libs/pandautils/src/main/java/com/instructure/pandautils/di/OfflineDatabaseProviderModule.kt index fea3f2b3d2..9f902d14a0 100644 --- a/libs/pandautils/src/main/java/com/instructure/pandautils/di/OfflineDatabaseProviderModule.kt +++ b/libs/pandautils/src/main/java/com/instructure/pandautils/di/OfflineDatabaseProviderModule.kt @@ -19,8 +19,10 @@ package com.instructure.pandautils.di import android.content.Context +import com.google.firebase.crashlytics.FirebaseCrashlytics import com.instructure.pandautils.room.offline.DatabaseProvider import com.instructure.pandautils.room.offline.OfflineDatabaseProvider +import com.instructure.pandautils.utils.LogoutHelper import dagger.Module import dagger.Provides import dagger.hilt.InstallIn @@ -34,7 +36,7 @@ class OfflineDatabaseProviderModule { @Provides @Singleton - fun provideOfflineDatabaseProvider(@ApplicationContext context: Context): DatabaseProvider { - return OfflineDatabaseProvider(context) + fun provideOfflineDatabaseProvider(@ApplicationContext context: Context, logoutHelper: LogoutHelper, firebaseCrashlytics: FirebaseCrashlytics): DatabaseProvider { + return OfflineDatabaseProvider(context, logoutHelper, firebaseCrashlytics) } } \ No newline at end of file diff --git a/libs/pandautils/src/main/java/com/instructure/pandautils/room/offline/OfflineDatabaseProvider.kt b/libs/pandautils/src/main/java/com/instructure/pandautils/room/offline/OfflineDatabaseProvider.kt index f429f63454..020eff3ee9 100644 --- a/libs/pandautils/src/main/java/com/instructure/pandautils/room/offline/OfflineDatabaseProvider.kt +++ b/libs/pandautils/src/main/java/com/instructure/pandautils/room/offline/OfflineDatabaseProvider.kt @@ -18,16 +18,32 @@ package com.instructure.pandautils.room.offline import android.content.Context +import android.widget.Toast +import androidx.appcompat.app.AlertDialog import androidx.room.Room +import com.google.firebase.crashlytics.FirebaseCrashlytics +import com.instructure.pandautils.R +import com.instructure.pandautils.utils.LogoutHelper +import com.instructure.pandautils.utils.toast private const val OFFLINE_DB_PREFIX = "offline-db-" -class OfflineDatabaseProvider(private val context: Context) : DatabaseProvider { +class OfflineDatabaseProvider( + private val context: Context, + private val logoutHelper: LogoutHelper, + private val firebaseCrashlytics: FirebaseCrashlytics +) : DatabaseProvider { private val dbMap = mutableMapOf() override fun getDatabase(userId: Long?): OfflineDatabase { - if (userId == null) throw IllegalStateException("You can't access the database while logged out") + if (userId == null) { + logoutHelper.logout(this) + firebaseCrashlytics.recordException(IllegalStateException("You can't access the database while logged out")) + return Room.databaseBuilder(context, OfflineDatabase::class.java, "dummy-db") + .addMigrations(*offlineDatabaseMigrations) + .build() + } return dbMap.getOrPut(userId) { Room.databaseBuilder(context, OfflineDatabase::class.java, "$OFFLINE_DB_PREFIX$userId") diff --git a/libs/pandautils/src/main/java/com/instructure/pandautils/utils/LogoutHelper.kt b/libs/pandautils/src/main/java/com/instructure/pandautils/utils/LogoutHelper.kt new file mode 100644 index 0000000000..dc2a418863 --- /dev/null +++ b/libs/pandautils/src/main/java/com/instructure/pandautils/utils/LogoutHelper.kt @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2023 - present Instructure, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * + */ + +package com.instructure.pandautils.utils + +import com.instructure.pandautils.room.offline.DatabaseProvider + +interface LogoutHelper { + + fun logout(databaseProvider: DatabaseProvider) +} \ No newline at end of file