Skip to content

Commit a938a3c

Browse files
committed
Remove log from interface and restrict sign in and store credentials to the correct email url
1 parent 97f1c23 commit a938a3c

File tree

8 files changed

+83
-34
lines changed

8 files changed

+83
-34
lines changed

app/src/androidTest/java/com/duckduckgo/app/browser/DuckDuckGoUrlDetectorTest.kt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -119,22 +119,22 @@ class DuckDuckGoUrlDetectorTest {
119119
}
120120

121121
@Test
122-
fun whenDomainIsNotDuckDuckGoThenReturnFalse() {
123-
assertFalse(testee.isDuckDuckGoDomain("https://example.com"))
122+
fun whenIsNotDuckDuckGoEmailUrlThenReturnFalse() {
123+
assertFalse(testee.isDuckDuckGoEmailUrl("https://example.com"))
124124
}
125125

126126
@Test
127-
fun whenDomainIsDuckDuckGoThenReturnTrue() {
128-
assertTrue(testee.isDuckDuckGoDomain("https://duckduckgo.com"))
127+
fun whenIsDuckDuckEmailUrlGoThenReturnTrue() {
128+
assertTrue(testee.isDuckDuckGoEmailUrl("https://duckduckgo.com/email"))
129129
}
130130

131131
@Test
132-
fun whenUrlContainsSubdomainAndIsFromDuckDuckGoDomainThenReturnTrue() {
133-
assertTrue(testee.isDuckDuckGoDomain("https://test.duckduckgo.com"))
132+
fun whenUrlContainsSubdomainAndIsFromDuckDuckGoEmailUrlThenReturnTrue() {
133+
assertTrue(testee.isDuckDuckGoEmailUrl("https://test.duckduckgo.com/email"))
134134
}
135135

136136
@Test
137-
fun whenUrlHasNoSchemeAndIsFromDuckDuckGoDomainThenReturnsTrue() {
138-
assertTrue(testee.isDuckDuckGoDomain("duckduckgo.com"))
137+
fun whenUrlHasNoSchemeAndIsFromDuckDuckGoUrlThenReturnsTrue() {
138+
assertTrue(testee.isDuckDuckGoEmailUrl("duckduckgo.com/email"))
139139
}
140140
}

app/src/androidTest/java/com/duckduckgo/app/email/EmailInjectorJsTest.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import androidx.test.filters.SdkSuppress
2222
import androidx.test.platform.app.InstrumentationRegistry
2323
import com.duckduckgo.app.browser.DuckDuckGoUrlDetector
2424
import com.duckduckgo.app.browser.R
25+
import com.duckduckgo.app.global.DispatcherProvider
2526
import com.nhaarman.mockitokotlin2.*
2627
import org.junit.Before
2728
import org.junit.Test
@@ -30,11 +31,12 @@ import java.io.BufferedReader
3031
class EmailInjectorJsTest {
3132

3233
private val mockEmailManager: EmailManager = mock()
34+
private val mockDispatcherProvider: DispatcherProvider = mock()
3335
lateinit var testee: EmailInjectorJs
3436

3537
@Before
3638
fun setup() {
37-
testee = EmailInjectorJs(mockEmailManager, DuckDuckGoUrlDetector())
39+
testee = EmailInjectorJs(mockEmailManager, DuckDuckGoUrlDetector(), mockDispatcherProvider)
3840
}
3941

4042
@UiThreadTest
@@ -44,7 +46,7 @@ class EmailInjectorJsTest {
4446
val jsToEvaluate = getJsToEvaluate()
4547
val webView = spy(WebView(InstrumentationRegistry.getInstrumentation().targetContext))
4648

47-
testee.injectEmailAutofillJs(webView, "https://duckduckgo.com")
49+
testee.injectEmailAutofillJs(webView, "https://duckduckgo.com/email")
4850

4951
verify(webView).evaluateJavascript(jsToEvaluate, null)
5052
}
@@ -56,7 +58,7 @@ class EmailInjectorJsTest {
5658
val jsToEvaluate = getJsToEvaluate()
5759
val webView = spy(WebView(InstrumentationRegistry.getInstrumentation().targetContext))
5860

59-
testee.injectEmailAutofillJs(webView, "https://test.duckduckgo.com")
61+
testee.injectEmailAutofillJs(webView, "https://test.duckduckgo.com/email")
6062

6163
verify(webView).evaluateJavascript(jsToEvaluate, null)
6264
}

app/src/androidTest/java/com/duckduckgo/app/email/EmailJavascriptInterfaceTest.kt

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,50 +16,78 @@
1616

1717
package com.duckduckgo.app.email
1818

19+
import android.webkit.WebView
20+
import com.duckduckgo.app.CoroutineTestRule
21+
import com.duckduckgo.app.browser.DuckDuckGoUrlDetector
1922
import com.nhaarman.mockitokotlin2.mock
23+
import com.nhaarman.mockitokotlin2.never
2024
import com.nhaarman.mockitokotlin2.verify
2125
import com.nhaarman.mockitokotlin2.whenever
2226
import org.junit.Assert.assertEquals
2327
import org.junit.Before
28+
import org.junit.Rule
2429
import org.junit.Test
2530

2631
class EmailJavascriptInterfaceTest {
2732

33+
@get:Rule
34+
val coroutineRule = CoroutineTestRule()
35+
2836
private val mockEmailManager: EmailManager = mock()
37+
private val mockWebView: WebView = mock()
2938
lateinit var testee: EmailJavascriptInterface
3039
private var counter = 0
3140

3241
@Before
3342
fun setup() {
34-
testee = EmailJavascriptInterface(mockEmailManager) { counter++ }
43+
testee = EmailJavascriptInterface(mockEmailManager, { counter++ }, mockWebView, DuckDuckGoUrlDetector(), coroutineRule.testDispatcherProvider)
3544
}
3645

3746
@Test
38-
fun whenIsSignedInThenIsSignedInCalled() {
47+
fun whenIsSignedInAndUrlIsDuckDuckGoEmailThenIsSignedInCalled() {
48+
whenever(mockWebView.url).thenReturn(DUCKDUCKGO_EMAIL_URL)
49+
3950
testee.isSignedIn()
4051

4152
verify(mockEmailManager).isSignedIn()
4253
}
4354

4455
@Test
45-
fun whenStoreCredentialsThenStoreCredentialsCalledWithCorrectParameters() {
56+
fun whenIsSignedInAndUrlIsNotDuckDuckGoEmailThenIsSignedInNotCalled() {
57+
whenever(mockWebView.url).thenReturn(NON_EMAIL_URL)
58+
59+
testee.isSignedIn()
60+
61+
verify(mockEmailManager, never()).isSignedIn()
62+
}
63+
64+
@Test
65+
fun whenStoreCredentialsAndUrlIsDuckDuckGoEmailThenStoreCredentialsCalledWithCorrectParameters() {
66+
whenever(mockWebView.url).thenReturn(DUCKDUCKGO_EMAIL_URL)
67+
4668
testee.storeCredentials("token", "username", "cohort")
4769

4870
verify(mockEmailManager).storeCredentials("token", "username", "cohort")
4971
}
5072

73+
@Test
74+
fun whenStoreCredentialsAndUrlIsNotDuckDuckGoEmailThenStoreCredentialsNotCalled() {
75+
whenever(mockWebView.url).thenReturn(NON_EMAIL_URL)
76+
77+
testee.storeCredentials("token", "username", "cohort")
78+
79+
verify(mockEmailManager, never()).storeCredentials("token", "username", "cohort")
80+
}
81+
5182
@Test
5283
fun whenShowTooltipThenLambdaCalled() {
5384
testee.showTooltip()
5485

5586
assertEquals(1, counter)
5687
}
5788

58-
private fun givenAliasExists() {
59-
whenever(mockEmailManager.getAlias()).thenReturn("alias")
60-
}
61-
62-
private fun givenAliasDoesNotExist() {
63-
whenever(mockEmailManager.getAlias()).thenReturn("")
89+
companion object {
90+
const val DUCKDUCKGO_EMAIL_URL = "https://duckduckgo.com/email"
91+
const val NON_EMAIL_URL = "https://example.com"
6492
}
6593
}

app/src/main/java/com/duckduckgo/app/browser/DuckDuckGoUrlDetector.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@ import javax.inject.Inject
2424

2525
class DuckDuckGoUrlDetector @Inject constructor() {
2626

27-
fun isDuckDuckGoDomain(uri: String): Boolean {
28-
return uri.toUri().baseHost?.contains(AppUrl.Url.HOST) ?: false
27+
fun isDuckDuckGoEmailUrl(url: String): Boolean {
28+
val uri = url.toUri()
29+
return uri.baseHost?.contains(AppUrl.Url.HOST) == true && uri.pathSegments.contains(AppUrl.Url.EMAIL_SEGMENT)
2930
}
3031

3132
fun isDuckDuckGoUrl(uri: String): Boolean {

app/src/main/java/com/duckduckgo/app/email/EmailInjector.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import androidx.annotation.UiThread
2222
import com.duckduckgo.app.browser.DuckDuckGoUrlDetector
2323
import com.duckduckgo.app.browser.R
2424
import com.duckduckgo.app.email.EmailJavascriptInterface.Companion.JAVASCRIPT_INTERFACE_NAME
25+
import com.duckduckgo.app.global.DispatcherProvider
2526
import java.io.BufferedReader
2627

2728
interface EmailInjector {
@@ -30,11 +31,11 @@ interface EmailInjector {
3031
fun injectAddressInEmailField(webView: WebView, alias: String?)
3132
}
3233

33-
class EmailInjectorJs(private val emailManager: EmailManager, private val urlDetector: DuckDuckGoUrlDetector) : EmailInjector {
34+
class EmailInjectorJs(private val emailManager: EmailManager, private val urlDetector: DuckDuckGoUrlDetector, private val dispatcherProvider: DispatcherProvider) : EmailInjector {
3435
private val javaScriptInjector = JavaScriptInjector()
3536

3637
override fun addJsInterface(webView: WebView, onTooltipShown: () -> Unit) {
37-
webView.addJavascriptInterface(EmailJavascriptInterface(emailManager, onTooltipShown), JAVASCRIPT_INTERFACE_NAME)
38+
webView.addJavascriptInterface(EmailJavascriptInterface(emailManager, onTooltipShown, webView, urlDetector, dispatcherProvider), JAVASCRIPT_INTERFACE_NAME)
3839
}
3940

4041
@UiThread
@@ -49,7 +50,7 @@ class EmailInjectorJs(private val emailManager: EmailManager, private val urlDet
4950
webView.evaluateJavascript("javascript:${javaScriptInjector.getAliasFunctions(webView.context, alias)}", null)
5051
}
5152

52-
private fun isDuckDuckGoUrl(url: String?): Boolean = (url != null && urlDetector.isDuckDuckGoDomain(url))
53+
private fun isDuckDuckGoUrl(url: String?): Boolean = (url != null && urlDetector.isDuckDuckGoEmailUrl(url))
5354

5455
private class JavaScriptInjector {
5556
private lateinit var functions: String

app/src/main/java/com/duckduckgo/app/email/EmailJavascriptInterface.kt

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,40 @@
1717
package com.duckduckgo.app.email
1818

1919
import android.webkit.JavascriptInterface
20-
import timber.log.Timber
20+
import android.webkit.WebView
21+
import com.duckduckgo.app.browser.DuckDuckGoUrlDetector
22+
import com.duckduckgo.app.global.DispatcherProvider
23+
import kotlinx.coroutines.runBlocking
2124

2225
class EmailJavascriptInterface(
2326
private val emailManager: EmailManager,
24-
private val showNativeTooltip: () -> Unit
27+
private val showNativeTooltip: () -> Unit,
28+
private val webView: WebView,
29+
private val urlDetector: DuckDuckGoUrlDetector,
30+
private val dispatcherProvider: DispatcherProvider
2531
) {
2632

27-
@JavascriptInterface
28-
fun log(message: String) {
29-
Timber.i("EmailInterface $message")
33+
private fun isUrlFromDuckDuckGoEmail(): Boolean {
34+
return runBlocking(dispatcherProvider.main()) {
35+
val url = webView.url
36+
(url != null && urlDetector.isDuckDuckGoEmailUrl(url))
37+
}
3038
}
3139

3240
@JavascriptInterface
33-
fun isSignedIn(): String = emailManager.isSignedIn().toString()
41+
fun isSignedIn(): String {
42+
return if (isUrlFromDuckDuckGoEmail()) {
43+
emailManager.isSignedIn().toString()
44+
} else {
45+
""
46+
}
47+
}
3448

3549
@JavascriptInterface
3650
fun storeCredentials(token: String, username: String, cohort: String) {
37-
emailManager.storeCredentials(token, username, cohort)
51+
if (isUrlFromDuckDuckGoEmail()) {
52+
emailManager.storeCredentials(token, username, cohort)
53+
}
3854
}
3955

4056
@JavascriptInterface

app/src/main/java/com/duckduckgo/app/email/di/EmailModule.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ class EmailModule {
5050
}
5151

5252
@Provides
53-
fun providesEmailInjector(emailManager: EmailManager, duckDuckGoUrlDetector: DuckDuckGoUrlDetector): EmailInjector {
54-
return EmailInjectorJs(emailManager, duckDuckGoUrlDetector)
53+
fun providesEmailInjector(emailManager: EmailManager, duckDuckGoUrlDetector: DuckDuckGoUrlDetector, dispatcherProvider: DispatcherProvider): EmailInjector {
54+
return EmailInjectorJs(emailManager, duckDuckGoUrlDetector, dispatcherProvider)
5555
}
5656

5757
@Provides

common/src/main/java/com/duckduckgo/app/global/AppUrl.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class AppUrl {
2626
const val ABOUT = "https://$HOST/about"
2727
const val TOSDR = "https://tosdr.org"
2828
const val PIXEL = "https://improving.duckduckgo.com"
29+
const val EMAIL_SEGMENT = "email"
2930
}
3031

3132
object ParamKey {

0 commit comments

Comments
 (0)