1{"version":3,"file":"Permissions.js","names":["USES_PERMISSION","withPermissions","config","permissions","Array","isArray","filter","Boolean","android","Set","concat","withAndroidManifest","modResults","setAndroidPermissions","withBlockedPermissions","resolvedPermissions","prefixAndroidPermissionsIfNecessary","permission","includes","ensureToolsAvailable","addBlockedPermissions","withInternalBlockedPermissions","blockedPermissions","length","androidManifest","manifest","ensureBlockedPermission","manifestPermissions","e","$","push","map","getAndroidPermissions","providedPermissions","permissionsToAdd","hasOwnProperty","forEach","isPermissionAlreadyRequested","addPermissionToManifest","some","removePermissions","permissionNames","targetNames","ensurePermissionNameFormat","nextPermissions","attribute","value","name","addPermission","permissionName","usesPermissions","ensurePermissions","getPermissions","results","targetName","ensurePermission","com","split","pop","toUpperCase","join","permissionObject"],"sources":["../../src/android/Permissions.ts"],"sourcesContent":["import { ExpoConfig } from '@expo/config-types';\n\nimport { ConfigPlugin } from '../Plugin.types';\nimport { withAndroidManifest } from '../plugins/android-plugins';\nimport { AndroidManifest, ensureToolsAvailable, ManifestUsesPermission } from './Manifest';\n\nconst USES_PERMISSION = 'uses-permission';\n\nexport const withPermissions: ConfigPlugin<string[] | void> = (config, permissions) => {\n if (Array.isArray(permissions)) {\n permissions = permissions.filter(Boolean);\n if (!config.android) config.android = {};\n if (!config.android.permissions) config.android.permissions = [];\n config.android.permissions = [\n // @ts-ignore\n ...new Set(config.android.permissions.concat(permissions)),\n ];\n }\n return withAndroidManifest(config, async (config) => {\n config.modResults = await setAndroidPermissions(config, config.modResults);\n return config;\n });\n};\n\n/** Given a permission or list of permissions, block permissions in the final `AndroidManifest.xml` to ensure no installed library or plugin can add them. */\nexport const withBlockedPermissions: ConfigPlugin<string[] | string> = (config, permissions) => {\n const resolvedPermissions = prefixAndroidPermissionsIfNecessary(\n (Array.isArray(permissions) ? permissions : [permissions]).filter(Boolean)\n );\n\n if (config?.android?.permissions && Array.isArray(config.android.permissions)) {\n // Remove any static config permissions\n config.android.permissions = prefixAndroidPermissionsIfNecessary(\n config.android.permissions\n ).filter((permission) => !resolvedPermissions.includes(permission));\n }\n\n return withAndroidManifest(config, async (config) => {\n config.modResults = ensureToolsAvailable(config.modResults);\n config.modResults = addBlockedPermissions(config.modResults, resolvedPermissions);\n return config;\n });\n};\n\nexport const withInternalBlockedPermissions: ConfigPlugin = (config) => {\n // Only add permissions if the user defined the property and added some values\n // this ensures we don't add the `tools:*` namespace extraneously.\n if (config.android?.blockedPermissions?.length) {\n return withBlockedPermissions(config, config.android.blockedPermissions);\n }\n\n return config;\n};\n\nexport function addBlockedPermissions(androidManifest: AndroidManifest, permissions: string[]) {\n if (!Array.isArray(androidManifest.manifest['uses-permission'])) {\n androidManifest.manifest['uses-permission'] = [];\n }\n\n for (const permission of prefixAndroidPermissionsIfNecessary(permissions)) {\n androidManifest.manifest['uses-permission'] = ensureBlockedPermission(\n androidManifest.manifest['uses-permission'],\n permission\n );\n }\n\n return androidManifest;\n}\n\n/**\n * Filter any existing permissions matching the provided permission name, then add a\n * restricted permission to overwrite any extra permissions that may be added in a\n * third-party package's AndroidManifest.xml.\n *\n * @param manifestPermissions manifest `uses-permissions` array.\n * @param permission `android:name` of the permission to restrict\n * @returns\n */\nfunction ensureBlockedPermission(\n manifestPermissions: ManifestUsesPermission[],\n permission: string\n) {\n // Remove permission if it currently exists\n manifestPermissions = manifestPermissions.filter((e) => e.$['android:name'] !== permission);\n\n // Add a permission with tools:node to overwrite any existing permission and ensure it's removed upon building.\n manifestPermissions.push({\n $: { 'android:name': permission, 'tools:node': 'remove' },\n });\n return manifestPermissions;\n}\n\nfunction prefixAndroidPermissionsIfNecessary(permissions: string[]): string[] {\n return permissions.map((permission) => {\n if (!permission.includes('.')) {\n return `android.permission.${permission}`;\n }\n return permission;\n });\n}\n\nexport function getAndroidPermissions(config: Pick<ExpoConfig, 'android'>): string[] {\n return config.android?.permissions ?? [];\n}\n\nexport function setAndroidPermissions(\n config: Pick<ExpoConfig, 'android'>,\n androidManifest: AndroidManifest\n) {\n const permissions = getAndroidPermissions(config);\n const providedPermissions = prefixAndroidPermissionsIfNecessary(permissions);\n const permissionsToAdd = [...providedPermissions];\n\n if (!androidManifest.manifest.hasOwnProperty('uses-permission')) {\n androidManifest.manifest['uses-permission'] = [];\n }\n // manifest.manifest['uses-permission'] = [];\n\n const manifestPermissions = androidManifest.manifest['uses-permission'] ?? [];\n\n permissionsToAdd.forEach((permission) => {\n if (!isPermissionAlreadyRequested(permission, manifestPermissions)) {\n addPermissionToManifest(permission, manifestPermissions);\n }\n });\n\n return androidManifest;\n}\n\nexport function isPermissionAlreadyRequested(\n permission: string,\n manifestPermissions: ManifestUsesPermission[]\n): boolean {\n return manifestPermissions.some((e) => e.$['android:name'] === permission);\n}\n\nexport function addPermissionToManifest(\n permission: string,\n manifestPermissions: ManifestUsesPermission[]\n) {\n manifestPermissions.push({ $: { 'android:name': permission } });\n return manifestPermissions;\n}\n\nexport function removePermissions(androidManifest: AndroidManifest, permissionNames?: string[]) {\n const targetNames = permissionNames ? permissionNames.map(ensurePermissionNameFormat) : null;\n const permissions = androidManifest.manifest[USES_PERMISSION] || [];\n const nextPermissions = [];\n for (const attribute of permissions) {\n if (targetNames) {\n // @ts-ignore: name isn't part of the type\n const value = attribute.$['android:name'] || attribute.$.name;\n if (!targetNames.includes(value)) {\n nextPermissions.push(attribute);\n }\n }\n }\n\n androidManifest.manifest[USES_PERMISSION] = nextPermissions;\n}\n\nexport function addPermission(androidManifest: AndroidManifest, permissionName: string): void {\n const usesPermissions: ManifestUsesPermission[] = androidManifest.manifest[USES_PERMISSION] || [];\n usesPermissions.push({\n $: { 'android:name': permissionName },\n });\n androidManifest.manifest[USES_PERMISSION] = usesPermissions;\n}\n\nexport function ensurePermissions(\n androidManifest: AndroidManifest,\n permissionNames: string[]\n): { [permission: string]: boolean } {\n const permissions = getPermissions(androidManifest);\n\n const results: { [permission: string]: boolean } = {};\n for (const permissionName of permissionNames) {\n const targetName = ensurePermissionNameFormat(permissionName);\n if (!permissions.includes(targetName)) {\n addPermission(androidManifest, targetName);\n results[permissionName] = true;\n } else {\n results[permissionName] = false;\n }\n }\n return results;\n}\n\nexport function ensurePermission(\n androidManifest: AndroidManifest,\n permissionName: string\n): boolean {\n const permissions = getPermissions(androidManifest);\n const targetName = ensurePermissionNameFormat(permissionName);\n\n if (!permissions.includes(targetName)) {\n addPermission(androidManifest, targetName);\n return true;\n }\n return false;\n}\n\nexport function ensurePermissionNameFormat(permissionName: string): string {\n if (permissionName.includes('.')) {\n const com = permissionName.split('.');\n const name = com.pop() as string;\n return [...com, name.toUpperCase()].join('.');\n } else {\n // If shorthand form like `WRITE_CONTACTS` is provided, expand it to `android.permission.WRITE_CONTACTS`.\n return ensurePermissionNameFormat(`android.permission.${permissionName}`);\n }\n}\n\nexport function getPermissions(androidManifest: AndroidManifest): string[] {\n const usesPermissions: { [key: string]: any }[] = androidManifest.manifest[USES_PERMISSION] || [];\n const permissions = usesPermissions.map((permissionObject) => {\n return permissionObject.$['android:name'] || permissionObject.$.name;\n });\n return permissions;\n}\n"],"mappings":"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"}