Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for auth API v2 #5305

Open
wants to merge 27 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
1397abb
remove account deletion internal setting
lmac012 Nov 20, 2024
6090906
add storage for auth v2 tokens
lmac012 Oct 25, 2024
3f26c47
show more info in subs settings to facilitate testing
lmac012 Nov 20, 2024
92fc7e1
add FF for auth api v2
lmac012 Oct 26, 2024
e1b4075
implement PKCE generator
lmac012 Oct 25, 2024
ea16003
add netowrking layer for accessing auth api v2
lmac012 Oct 26, 2024
5d90789
add tests for AuthClientImpl
lmac012 Nov 7, 2024
92a50b9
remove redundant .also{} usage
lmac012 Oct 31, 2024
2349f05
use auth v2 when purchasing new subscription
lmac012 Oct 31, 2024
6a1a17a
fix SubscriptionManager tests
lmac012 Nov 8, 2024
21fdbad
add store login endpoint to AuthClient
lmac012 Nov 5, 2024
5078315
add auth v2 store login
lmac012 Nov 12, 2024
30259b4
fire correct pixels when account creation using auth v2 fails
lmac012 Nov 12, 2024
3ad9f56
deprecate methods that will be removed after migrating to auth v2
lmac012 Nov 14, 2024
491a669
run RealSubscriptionManager tests with auth v2 enabled
lmac012 Nov 15, 2024
567c891
add more tests for the updated getAccessToken() logic
lmac012 Nov 18, 2024
13de9ba
add v1 migration endpoint to AuthClient
lmac012 Nov 18, 2024
343df8d
add migration path from v1 auth api
lmac012 Nov 18, 2024
8bcc1b2
add weekly token refresh job
lmac012 Nov 19, 2024
672dfc1
make fetchAndStoreAllData() no-op when using auth v2
lmac012 Nov 19, 2024
2e332b7
update SubscriptionChecker to work with auth v2
lmac012 Nov 21, 2024
ff38d83
fix a few nits in SubscriptionChecker
lmac012 Nov 21, 2024
563131d
refresh access token after adding/editing account email
lmac012 Nov 21, 2024
1609812
fix clearing entitlements on signing out
lmac012 Nov 21, 2024
9b60e5c
refresh subscription data before re-purchase when signed using auth v2
lmac012 Nov 21, 2024
8fb36d2
use v2 access token for serp promo cookie
lmac012 Nov 21, 2024
42da941
remove auth-jwt module and move its contents to subscriptions-impl
lmac012 Nov 22, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -384,9 +384,6 @@ dependencies {

implementation project(':breakage-reporting-impl')

implementation project(":auth-jwt-api")
implementation project(":auth-jwt-impl")

// Deprecated. TODO: Stop using this artifact.
implementation "androidx.legacy:legacy-support-v4:_"
debugImplementation Square.leakCanary.android
Expand Down
Empty file removed auth-jwt/auth-jwt-api/.gitignore
Empty file.
31 changes: 0 additions & 31 deletions auth-jwt/auth-jwt-api/build.gradle

This file was deleted.

67 changes: 0 additions & 67 deletions auth-jwt/auth-jwt-impl/build.gradle

This file was deleted.

9 changes: 0 additions & 9 deletions auth-jwt/readme.md

This file was deleted.

6 changes: 6 additions & 0 deletions subscriptions/subscriptions-impl/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@ dependencies {
implementation Square.okHttp3.okHttp
implementation AndroidX.security.crypto

implementation "io.jsonwebtoken:jjwt-api:_"
runtimeOnly "io.jsonwebtoken:jjwt-impl:_"
runtimeOnly("io.jsonwebtoken:jjwt-orgjson:_") {
exclude(group: 'org.json', module: 'json') // provided by Android natively
}

// Testing dependencies
testImplementation project(':feature-toggles-test')
testImplementation project(path: ':common-test')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@ interface PrivacyProFeature {

@Toggle.DefaultValue(true)
fun serpPromoCookie(): Toggle

@Toggle.DefaultValue(false)
fun authApiV2(): Toggle
}

@ContributesBinding(AppScope::class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import androidx.work.Constraints
import androidx.work.CoroutineWorker
import androidx.work.ExistingPeriodicWorkPolicy
import androidx.work.NetworkType
import androidx.work.PeriodicWorkRequest
import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkManager
import androidx.work.WorkerParameters
Expand All @@ -35,8 +36,8 @@ import com.duckduckgo.subscriptions.api.SubscriptionStatus.UNKNOWN
import com.duckduckgo.subscriptions.impl.RealSubscriptionsChecker.Companion.TAG_WORKER_SUBSCRIPTION_CHECK
import com.squareup.anvil.annotations.ContributesBinding
import com.squareup.anvil.annotations.ContributesMultibinding
import java.util.concurrent.TimeUnit.HOURS
import java.util.concurrent.TimeUnit.MINUTES
import java.time.Duration
import java.time.Instant
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
Expand Down Expand Up @@ -66,21 +67,13 @@ class RealSubscriptionsChecker @Inject constructor(
}

override suspend fun runChecker() {
if (subscriptionsManager.subscriptionStatus() != UNKNOWN) {
PeriodicWorkRequestBuilder<SubscriptionsCheckWorker>(1, HOURS)
.addTag(TAG_WORKER_SUBSCRIPTION_CHECK)
.setConstraints(
Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build(),
)
.setBackoffCriteria(BackoffPolicy.LINEAR, 10, MINUTES)
.build().run {
workManager.enqueueUniquePeriodicWork(
TAG_WORKER_SUBSCRIPTION_CHECK,
ExistingPeriodicWorkPolicy.REPLACE,
this,
)
}
}
if (!subscriptionsManager.isSignedIn()) return

workManager.enqueueUniquePeriodicWork(
TAG_WORKER_SUBSCRIPTION_CHECK,
ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
buildSubscriptionCheckPeriodicWorkRequest(),
)
}

companion object {
Expand All @@ -101,18 +94,48 @@ class SubscriptionsCheckWorker(

override suspend fun doWork(): Result {
return try {
if (subscriptionsManager.subscriptionStatus() != UNKNOWN) {
subscriptionsManager.fetchAndStoreAllData()
val subscription = subscriptionsManager.getSubscription()
if (subscription?.status == null || subscription.status == UNKNOWN) {
workManager.cancelAllWorkByTag(TAG_WORKER_SUBSCRIPTION_CHECK)
if (subscriptionsManager.isSignedIn()) {
if (subscriptionsManager.isSignedInV2()) {
subscriptionsManager.refreshSubscriptionData()
val subscription = subscriptionsManager.getSubscription()
if (subscription?.isActive() == true) {
// No need to refresh active subscription in the background. Delay next refresh to the expiry/renewal time.
// It will still get refreshed when the app goes to the foreground.
val expiresOrRenewsAt = Instant.ofEpochMilli(subscription.expiresOrRenewsAt)
if (expiresOrRenewsAt > Instant.now()) {
workManager.enqueueUniquePeriodicWork(
TAG_WORKER_SUBSCRIPTION_CHECK,
ExistingPeriodicWorkPolicy.UPDATE,
buildSubscriptionCheckPeriodicWorkRequest(nextScheduleTimeOverride = expiresOrRenewsAt),
)
}
}
} else {
subscriptionsManager.fetchAndStoreAllData()
val subscription = subscriptionsManager.getSubscription()
if (subscription?.status == null || subscription.status == UNKNOWN) {
workManager.cancelUniqueWork(TAG_WORKER_SUBSCRIPTION_CHECK)
}
}
} else {
workManager.cancelAllWorkByTag(TAG_WORKER_SUBSCRIPTION_CHECK)
workManager.cancelUniqueWork(TAG_WORKER_SUBSCRIPTION_CHECK)
}
Result.success()
} catch (e: Exception) {
Result.failure()
}
}
}

private fun buildSubscriptionCheckPeriodicWorkRequest(nextScheduleTimeOverride: Instant? = null): PeriodicWorkRequest =
PeriodicWorkRequestBuilder<SubscriptionsCheckWorker>(Duration.ofHours(1))
.setConstraints(
Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build(),
)
.setBackoffCriteria(BackoffPolicy.LINEAR, Duration.ofMinutes(10))
.apply {
if (nextScheduleTimeOverride != null) {
setNextScheduleTimeOverride(nextScheduleTimeOverride.toEpochMilli())
}
}
.build()
Loading
Loading