Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,9 @@ To use the SDK with Expo, configure the app at build time by providing the `doma
| API | Description |
| ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| domain | Mandatory: Provide the Auth0 domain that can be found at the [Application Settings](https://manage.auth0.com/#/applications) |
| customScheme | Optional: Custom scheme to build the callback URL with. The value provided here should be passed to the `customScheme` option parameter of the `authorize` and `clearSession` methods. The custom scheme should be a unique, all lowercase value with no special characters. |
| customScheme | Optional: Custom scheme to build the callback URL with. The value provided here should be passed to the `customScheme` option parameter of the `authorize` and `clearSession` methods. The custom scheme should be a unique, all lowercase value with no special characters. To use Android App Links, set this value to `"https"`. |

**Note:** When using `customScheme: "https"` for Android App Links, the plugin will automatically add `android:autoVerify="true"` to the intent-filter in your Android manifest to enable automatic verification of App Links.

Now you can run the application using `expo run:android` or `expo run:ios`.

Expand Down
95 changes: 95 additions & 0 deletions src/plugin/__tests__/withAuth0-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,101 @@ describe(addAndroidAuth0Manifest, () => {
expect(dataElement?.$['android:scheme']).toBe('com.custom.scheme');
expect(dataElement?.$['android:host']).toBe('sample.auth0.com');
});

it(`should add android:autoVerify="true" when customScheme is https`, () => {
const config = getConfig();
const result = addAndroidAuth0Manifest(
[
{
domain: 'sample.auth0.com',
customScheme: 'https',
},
],
config,
'com.auth0.testapp'
);

// Access the RedirectActivity to check if autoVerify is correctly added
const mainApplication = AndroidConfig.Manifest.getMainApplicationOrThrow(
result.modResults
);
const redirectActivity = mainApplication.activity?.find(
(activity) =>
activity.$['android:name'] ===
'com.auth0.android.provider.RedirectActivity'
);

const intentFilter = redirectActivity?.['intent-filter']?.[0];

expect(intentFilter?.$).toBeDefined();
expect(intentFilter?.$?.['android:autoVerify']).toBe('true');

const dataElement = intentFilter?.data?.[0];
expect(dataElement?.$['android:scheme']).toBe('https');
expect(dataElement?.$['android:host']).toBe('sample.auth0.com');
});

it(`should add android:autoVerify="true" when customScheme is http`, () => {
const config = getConfig();
const result = addAndroidAuth0Manifest(
[
{
domain: 'sample.auth0.com',
customScheme: 'http',
},
],
config,
'com.auth0.testapp'
);

// Access the RedirectActivity to check if autoVerify is correctly added
const mainApplication = AndroidConfig.Manifest.getMainApplicationOrThrow(
result.modResults
);
const redirectActivity = mainApplication.activity?.find(
(activity) =>
activity.$['android:name'] ===
'com.auth0.android.provider.RedirectActivity'
);

const intentFilter = redirectActivity?.['intent-filter']?.[0];

expect(intentFilter?.$).toBeDefined();
expect(intentFilter?.$?.['android:autoVerify']).toBe('true');

const dataElement = intentFilter?.data?.[0];
expect(dataElement?.$['android:scheme']).toBe('http');
expect(dataElement?.$['android:host']).toBe('sample.auth0.com');
});

it(`should not add android:autoVerify when customScheme is not http/https`, () => {
const config = getConfig();
const result = addAndroidAuth0Manifest(
[
{
domain: 'sample.auth0.com',
customScheme: 'com.custom.scheme',
},
],
config,
'com.auth0.testapp'
);

// Access the RedirectActivity
const mainApplication = AndroidConfig.Manifest.getMainApplicationOrThrow(
result.modResults
);
const redirectActivity = mainApplication.activity?.find(
(activity) =>
activity.$['android:name'] ===
'com.auth0.android.provider.RedirectActivity'
);

const intentFilter = redirectActivity?.['intent-filter']?.[0];

// autoVerify should not be present for non-http(s) schemes
expect(intentFilter?.$?.['android:autoVerify']).toBeUndefined();
});
});

describe(addIOSAuth0ConfigInInfoPList, () => {
Expand Down
21 changes: 18 additions & 3 deletions src/plugin/withAuth0.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,15 @@ export const addAndroidAuth0Manifest = (
if (auth0Configs.length === 0) {
throw new Error(`No auth0 domain specified in expo config`);
}
// Check if any config uses https/http scheme for App Links
const hasAppLinks = auth0Configs.some(
(config) =>
config.customScheme === 'https' || config.customScheme === 'http'
);

const intentFilterContent = [
{
...(hasAppLinks && { $: { 'android:autoVerify': 'true' as AndroidConfig.Manifest.StringBoolean } }),
action: [{ $: { 'android:name': 'android.intent.action.VIEW' } }],
category: [
{ $: { 'android:name': 'android.intent.category.DEFAULT' } },
Expand Down Expand Up @@ -61,17 +67,26 @@ export const addAndroidAuth0Manifest = (
'tools:node': 'replace',
'android:exported': 'true',
},
'intent-filter': intentFilterContent,
'intent-filter': intentFilterContent as AndroidConfig.Manifest.ManifestIntentFilter[],
};
mainApplication.activity = mainApplication.activity || [];
mainApplication.activity.push(redirectActivity);
}

redirectActivity['intent-filter'] =
redirectActivity['intent-filter'] || intentFilterContent;
redirectActivity['intent-filter'] || intentFilterContent as AndroidConfig.Manifest.ManifestIntentFilter[];
const intentFilter = redirectActivity['intent-filter'][0] || {};
if (!intentFilter) {
throw new Error('Failed to create intent filter');
}
intentFilter.data = intentFilter.data || [];

// Add android:autoVerify="true" for App Links
if (hasAppLinks) {
intentFilter.$ = intentFilter.$ || {};
intentFilter.$['android:autoVerify'] = 'true' as AndroidConfig.Manifest.StringBoolean;
}

// Add data elements for each auth0Config
auth0Configs.forEach((config) => {
if (config.domain == null) {
Expand Down