Skip to content
This repository has been archived by the owner on Jan 18, 2024. It is now read-only.

[config] permissions plugins #2871

Merged
merged 3 commits into from
Nov 19, 2020
Merged
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
19 changes: 17 additions & 2 deletions packages/config/src/android/Permissions.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ExpoConfig } from '../Config.types';
import { createAndroidManifestPlugin } from '../plugins/android-plugins';
import { ConfigPlugin } from '../Plugin.types';
import { withAndroidManifest } from '../plugins/android-plugins';
import { AndroidManifest, ManifestUsesPermission } from './Manifest';

const USES_PERMISSION = 'uses-permission';
Expand Down Expand Up @@ -43,7 +44,21 @@ export const allPermissions = [
'com.sonyericsson.home.permission.BROADCAST_BADGE',
];

export const withPermissions = createAndroidManifestPlugin(setAndroidPermissions);
export const withPermissions: ConfigPlugin<string[] | void> = (config, permissions) => {
if (Array.isArray(permissions)) {
permissions = permissions.filter(Boolean);
if (!config.android) config.android = {};
if (!config.android.permissions) config.android.permissions = [];
config.android.permissions = [
// @ts-ignore
...new Set(config.android.permissions.concat(permissions)),
];
}
return withAndroidManifest(config, async config => {
config.modResults = await setAndroidPermissions(config, config.modResults);
return config;
});
};

function prefixAndroidPermissionsIfNecessary(permissions: string[]): string[] {
return permissions.map(permission => {
Expand Down
46 changes: 46 additions & 0 deletions packages/config/src/ios/Permissions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { ConfigPlugin } from '../Plugin.types';
import { withInfoPlist } from '../plugins/ios-plugins';
import { InfoPlist } from './IosConfig.types';

/**
* Apply permissions and their respective descriptions to the iOS Info.plist.
* Providing a null description will remove the permission from the Info.plist.
*
* @param config
* @param permissions record of strings where the key matches Info.plist permissions and the values are the permission descriptions.
*/
export const withPermissions: ConfigPlugin<Record<string, string | null>> = (
config,
permissions
) => {
return withInfoPlist(config, async config => {
config.modResults = applyPermissions(permissions, config.modResults);
return config;
});
};

export function applyPermissions(
permissions: Record<string, string | null>,
infoPlist: Record<string, any>
): InfoPlist {
const entries = Object.entries(permissions);
if (entries.length === 0) {
// TODO: Debug warn
// console.warn('[withPermissions] no permissions were provided');
}
for (const [permission, description] of entries) {
if (description == null) {
delete infoPlist[permission];
} else {
const existingPermission = infoPlist[permission];
if (existingPermission && existingPermission !== description) {
// TODO: Debug warn
// console.warn(
// `[withPermissionsIos][conflict] permission "${permission}" is already defined in the Info.plist with description "${existingPermission}"`
// );
}
infoPlist[permission] = description;
}
}
return infoPlist;
}
15 changes: 15 additions & 0 deletions packages/config/src/ios/__tests__/Permissions-test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { applyPermissions } from '../Permissions';

describe(applyPermissions, () => {
it(`applies permissions`, () => {
expect(
applyPermissions(
{ baz: 'new', foo: null, echo: 'delta' },
{
foo: 'bar',
baz: 'fox',
}
)
).toStrictEqual({ baz: 'new', echo: 'delta' });
});
});
2 changes: 2 additions & 0 deletions packages/config/src/ios/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import * as Locales from './Locales';
import * as Name from './Name';
import * as Orientation from './Orientation';
import * as Paths from './Paths';
import * as Permissions from './Permissions';
import * as ProvisioningProfile from './ProvisioningProfile';
import * as RequiresFullScreen from './RequiresFullScreen';
import * as Scheme from './Scheme';
Expand Down Expand Up @@ -41,6 +42,7 @@ export {
Orientation,
Paths,
ProvisioningProfile,
Permissions,
RequiresFullScreen,
Scheme,
Updates,
Expand Down