@@ -213,6 +213,159 @@ describe(addAndroidAuth0Manifest, () => {
213213 expect ( dataElement ?. $ [ 'android:host' ] ) . toBe ( 'sample.auth0.com' ) ;
214214 } ) ;
215215
216+ it ( `should remove conflicting broad scheme from other activity intent filter` , ( ) => {
217+ const config = getConfig ( ) ;
218+ const mainApp = AndroidConfig . Manifest . getMainApplicationOrThrow (
219+ config . modResults
220+ ) ;
221+ mainApp . activity = mainApp . activity || [ ] ;
222+ mainApp . activity . push ( {
223+ '$' : {
224+ 'android:name' : '.MainActivity' ,
225+ } ,
226+ 'intent-filter' : [
227+ {
228+ action : [ { $ : { 'android:name' : 'android.intent.action.VIEW' } } ] ,
229+ category : [
230+ { $ : { 'android:name' : 'android.intent.category.DEFAULT' } } ,
231+ {
232+ $ : { 'android:name' : 'android.intent.category.BROWSABLE' } ,
233+ } ,
234+ ] ,
235+ data : [
236+ { $ : { 'android:scheme' : 'smtest' } } ,
237+ { $ : { 'android:scheme' : 'exp+smtest' } } ,
238+ ] ,
239+ } ,
240+ ] ,
241+ } as AndroidConfig . Manifest . ManifestActivity ) ;
242+
243+ const result = addAndroidAuth0Manifest (
244+ [ { domain : 'sample.auth0.com' , customScheme : 'smtest' } ] ,
245+ config ,
246+ 'com.sample.app'
247+ ) ;
248+
249+ const mainApplication = AndroidConfig . Manifest . getMainApplicationOrThrow (
250+ result . modResults
251+ ) ;
252+
253+ // MainActivity should have 'smtest' removed but keep 'exp+smtest'
254+ const mainActivity = mainApplication . activity ?. find (
255+ ( a ) => a . $ [ 'android:name' ] === '.MainActivity'
256+ ) ;
257+ const mainIntentFilter = mainActivity ?. [ 'intent-filter' ] ?. [ 0 ] ;
258+ const schemes = mainIntentFilter ?. data ?. map ( ( d ) => d . $ [ 'android:scheme' ] ) ;
259+ expect ( schemes ) . toEqual ( [ 'exp+smtest' ] ) ;
260+ expect ( schemes ) . not . toContain ( 'smtest' ) ;
261+
262+ // RedirectActivity should still have the auth0 scheme
263+ const redirectActivity = mainApplication . activity ?. find (
264+ ( a ) =>
265+ a . $ [ 'android:name' ] === 'com.auth0.android.provider.RedirectActivity'
266+ ) ;
267+ const redirectIntentFilter = redirectActivity ?. [ 'intent-filter' ] ?. [ 0 ] ;
268+ const redirectData = redirectIntentFilter ?. data ?. [ 0 ] ;
269+ expect ( redirectData ?. $ [ 'android:scheme' ] ) . toBe ( 'smtest' ) ;
270+ expect ( redirectData ?. $ [ 'android:host' ] ) . toBe ( 'sample.auth0.com' ) ;
271+ expect ( redirectData ?. $ [ 'android:pathPrefix' ] ) . toBe (
272+ '/android/com.sample.app/callback'
273+ ) ;
274+ } ) ;
275+
276+ it ( `should not modify other activities when no scheme conflict exists` , ( ) => {
277+ const config = getConfig ( ) ;
278+ const mainApp = AndroidConfig . Manifest . getMainApplicationOrThrow (
279+ config . modResults
280+ ) ;
281+ mainApp . activity = mainApp . activity || [ ] ;
282+ mainApp . activity . push ( {
283+ '$' : {
284+ 'android:name' : '.MainActivity' ,
285+ } ,
286+ 'intent-filter' : [
287+ {
288+ action : [ { $ : { 'android:name' : 'android.intent.action.VIEW' } } ] ,
289+ category : [
290+ { $ : { 'android:name' : 'android.intent.category.DEFAULT' } } ,
291+ {
292+ $ : { 'android:name' : 'android.intent.category.BROWSABLE' } ,
293+ } ,
294+ ] ,
295+ data : [
296+ { $ : { 'android:scheme' : 'myapp' } } ,
297+ { $ : { 'android:scheme' : 'exp+myapp' } } ,
298+ ] ,
299+ } ,
300+ ] ,
301+ } as AndroidConfig . Manifest . ManifestActivity ) ;
302+
303+ const result = addAndroidAuth0Manifest (
304+ [ { domain : 'sample.auth0.com' , customScheme : 'smtest' } ] ,
305+ config ,
306+ 'com.sample.app'
307+ ) ;
308+
309+ const mainApplication = AndroidConfig . Manifest . getMainApplicationOrThrow (
310+ result . modResults
311+ ) ;
312+ const mainActivity = mainApplication . activity ?. find (
313+ ( a ) => a . $ [ 'android:name' ] === '.MainActivity'
314+ ) ;
315+ const mainIntentFilter = mainActivity ?. [ 'intent-filter' ] ?. [ 0 ] ;
316+ const schemes = mainIntentFilter ?. data ?. map ( ( d ) => d . $ [ 'android:scheme' ] ) ;
317+ expect ( schemes ) . toEqual ( [ 'myapp' , 'exp+myapp' ] ) ;
318+ } ) ;
319+
320+ it ( `should not remove scheme data that has a host (specific match)` , ( ) => {
321+ const config = getConfig ( ) ;
322+ const mainApp = AndroidConfig . Manifest . getMainApplicationOrThrow (
323+ config . modResults
324+ ) ;
325+ mainApp . activity = mainApp . activity || [ ] ;
326+ mainApp . activity . push ( {
327+ '$' : {
328+ 'android:name' : '.MainActivity' ,
329+ } ,
330+ 'intent-filter' : [
331+ {
332+ action : [ { $ : { 'android:name' : 'android.intent.action.VIEW' } } ] ,
333+ category : [
334+ { $ : { 'android:name' : 'android.intent.category.DEFAULT' } } ,
335+ {
336+ $ : { 'android:name' : 'android.intent.category.BROWSABLE' } ,
337+ } ,
338+ ] ,
339+ data : [
340+ {
341+ $ : {
342+ 'android:scheme' : 'smtest' ,
343+ 'android:host' : 'myapp.example.com' ,
344+ } ,
345+ } ,
346+ ] ,
347+ } ,
348+ ] ,
349+ } as AndroidConfig . Manifest . ManifestActivity ) ;
350+
351+ const result = addAndroidAuth0Manifest (
352+ [ { domain : 'sample.auth0.com' , customScheme : 'smtest' } ] ,
353+ config ,
354+ 'com.sample.app'
355+ ) ;
356+
357+ const mainApplication = AndroidConfig . Manifest . getMainApplicationOrThrow (
358+ result . modResults
359+ ) ;
360+ const mainActivity = mainApplication . activity ?. find (
361+ ( a ) => a . $ [ 'android:name' ] === '.MainActivity'
362+ ) ;
363+ const mainIntentFilter = mainActivity ?. [ 'intent-filter' ] ?. [ 0 ] ;
364+ const schemes = mainIntentFilter ?. data ?. map ( ( d ) => d . $ [ 'android:scheme' ] ) ;
365+ // Should keep the data element because it has a host (specific match, won't cause disambiguation)
366+ expect ( schemes ) . toEqual ( [ 'smtest' ] ) ;
367+ } ) ;
368+
216369 it ( `should add android:autoVerify="true" when customScheme is https` , ( ) => {
217370 const config = getConfig ( ) ;
218371 const result = addAndroidAuth0Manifest (
0 commit comments