1082815dcSEvan Bacon"use strict";
2082815dcSEvan Bacon
3082815dcSEvan BaconObject.defineProperty(exports, "__esModule", {
4082815dcSEvan Bacon  value: true
5082815dcSEvan Bacon});
6082815dcSEvan Baconexports.addBlockedPermissions = addBlockedPermissions;
7082815dcSEvan Baconexports.addPermission = addPermission;
8082815dcSEvan Baconexports.addPermissionToManifest = addPermissionToManifest;
9082815dcSEvan Baconexports.ensurePermission = ensurePermission;
10082815dcSEvan Baconexports.ensurePermissionNameFormat = ensurePermissionNameFormat;
11082815dcSEvan Baconexports.ensurePermissions = ensurePermissions;
12082815dcSEvan Baconexports.getAndroidPermissions = getAndroidPermissions;
13082815dcSEvan Baconexports.getPermissions = getPermissions;
14082815dcSEvan Baconexports.isPermissionAlreadyRequested = isPermissionAlreadyRequested;
15082815dcSEvan Baconexports.removePermissions = removePermissions;
16082815dcSEvan Baconexports.setAndroidPermissions = setAndroidPermissions;
17082815dcSEvan Baconexports.withPermissions = exports.withInternalBlockedPermissions = exports.withBlockedPermissions = void 0;
18*8a424bebSJames Idefunction _Manifest() {
19*8a424bebSJames Ide  const data = require("./Manifest");
20*8a424bebSJames Ide  _Manifest = function () {
21082815dcSEvan Bacon    return data;
22082815dcSEvan Bacon  };
23082815dcSEvan Bacon  return data;
24082815dcSEvan Bacon}
25*8a424bebSJames Idefunction _androidPlugins() {
26*8a424bebSJames Ide  const data = require("../plugins/android-plugins");
27*8a424bebSJames Ide  _androidPlugins = function () {
28082815dcSEvan Bacon    return data;
29082815dcSEvan Bacon  };
30082815dcSEvan Bacon  return data;
31082815dcSEvan Bacon}
32082815dcSEvan Baconconst USES_PERMISSION = 'uses-permission';
33082815dcSEvan Baconconst withPermissions = (config, permissions) => {
34082815dcSEvan Bacon  if (Array.isArray(permissions)) {
35082815dcSEvan Bacon    permissions = permissions.filter(Boolean);
36082815dcSEvan Bacon    if (!config.android) config.android = {};
37082815dcSEvan Bacon    if (!config.android.permissions) config.android.permissions = [];
38ee216927STomasz Sapeta    config.android.permissions = [
39ee216927STomasz Sapeta    // @ts-ignore
40082815dcSEvan Bacon    ...new Set(config.android.permissions.concat(permissions))];
41082815dcSEvan Bacon  }
42082815dcSEvan Bacon  return (0, _androidPlugins().withAndroidManifest)(config, async config => {
43082815dcSEvan Bacon    config.modResults = await setAndroidPermissions(config, config.modResults);
44082815dcSEvan Bacon    return config;
45082815dcSEvan Bacon  });
46082815dcSEvan Bacon};
47ee216927STomasz Sapeta
48082815dcSEvan Bacon/** Given a permission or list of permissions, block permissions in the final `AndroidManifest.xml` to ensure no installed library or plugin can add them. */
49082815dcSEvan Baconexports.withPermissions = withPermissions;
50082815dcSEvan Baconconst withBlockedPermissions = (config, permissions) => {
51082815dcSEvan Bacon  var _config$android;
528828a4a3SCedric van Putten  const resolvedPermissions = prefixAndroidPermissionsIfNecessary((Array.isArray(permissions) ? permissions : [permissions]).filter(Boolean));
53082815dcSEvan Bacon  if (config !== null && config !== void 0 && (_config$android = config.android) !== null && _config$android !== void 0 && _config$android.permissions && Array.isArray(config.android.permissions)) {
54082815dcSEvan Bacon    // Remove any static config permissions
558828a4a3SCedric van Putten    config.android.permissions = prefixAndroidPermissionsIfNecessary(config.android.permissions).filter(permission => !resolvedPermissions.includes(permission));
56082815dcSEvan Bacon  }
57082815dcSEvan Bacon  return (0, _androidPlugins().withAndroidManifest)(config, async config => {
58082815dcSEvan Bacon    config.modResults = (0, _Manifest().ensureToolsAvailable)(config.modResults);
59082815dcSEvan Bacon    config.modResults = addBlockedPermissions(config.modResults, resolvedPermissions);
60082815dcSEvan Bacon    return config;
61082815dcSEvan Bacon  });
62082815dcSEvan Bacon};
63082815dcSEvan Baconexports.withBlockedPermissions = withBlockedPermissions;
64082815dcSEvan Baconconst withInternalBlockedPermissions = config => {
65082815dcSEvan Bacon  var _config$android2, _config$android2$bloc;
66082815dcSEvan Bacon  // Only add permissions if the user defined the property and added some values
67082815dcSEvan Bacon  // this ensures we don't add the `tools:*` namespace extraneously.
68082815dcSEvan Bacon  if ((_config$android2 = config.android) !== null && _config$android2 !== void 0 && (_config$android2$bloc = _config$android2.blockedPermissions) !== null && _config$android2$bloc !== void 0 && _config$android2$bloc.length) {
69082815dcSEvan Bacon    return withBlockedPermissions(config, config.android.blockedPermissions);
70082815dcSEvan Bacon  }
71082815dcSEvan Bacon  return config;
72082815dcSEvan Bacon};
73082815dcSEvan Baconexports.withInternalBlockedPermissions = withInternalBlockedPermissions;
74082815dcSEvan Baconfunction addBlockedPermissions(androidManifest, permissions) {
75082815dcSEvan Bacon  if (!Array.isArray(androidManifest.manifest['uses-permission'])) {
76082815dcSEvan Bacon    androidManifest.manifest['uses-permission'] = [];
77082815dcSEvan Bacon  }
788828a4a3SCedric van Putten  for (const permission of prefixAndroidPermissionsIfNecessary(permissions)) {
79082815dcSEvan Bacon    androidManifest.manifest['uses-permission'] = ensureBlockedPermission(androidManifest.manifest['uses-permission'], permission);
80082815dcSEvan Bacon  }
81082815dcSEvan Bacon  return androidManifest;
82082815dcSEvan Bacon}
83ee216927STomasz Sapeta
84082815dcSEvan Bacon/**
85082815dcSEvan Bacon * Filter any existing permissions matching the provided permission name, then add a
86082815dcSEvan Bacon * restricted permission to overwrite any extra permissions that may be added in a
87082815dcSEvan Bacon * third-party package's AndroidManifest.xml.
88082815dcSEvan Bacon *
89082815dcSEvan Bacon * @param manifestPermissions manifest `uses-permissions` array.
90082815dcSEvan Bacon * @param permission `android:name` of the permission to restrict
91082815dcSEvan Bacon * @returns
92082815dcSEvan Bacon */
93082815dcSEvan Baconfunction ensureBlockedPermission(manifestPermissions, permission) {
94082815dcSEvan Bacon  // Remove permission if it currently exists
95ee216927STomasz Sapeta  manifestPermissions = manifestPermissions.filter(e => e.$['android:name'] !== permission);
96082815dcSEvan Bacon
97ee216927STomasz Sapeta  // Add a permission with tools:node to overwrite any existing permission and ensure it's removed upon building.
98082815dcSEvan Bacon  manifestPermissions.push({
99082815dcSEvan Bacon    $: {
100082815dcSEvan Bacon      'android:name': permission,
101082815dcSEvan Bacon      'tools:node': 'remove'
102082815dcSEvan Bacon    }
103082815dcSEvan Bacon  });
104082815dcSEvan Bacon  return manifestPermissions;
105082815dcSEvan Bacon}
106082815dcSEvan Baconfunction prefixAndroidPermissionsIfNecessary(permissions) {
107082815dcSEvan Bacon  return permissions.map(permission => {
108082815dcSEvan Bacon    if (!permission.includes('.')) {
109082815dcSEvan Bacon      return `android.permission.${permission}`;
110082815dcSEvan Bacon    }
111082815dcSEvan Bacon    return permission;
112082815dcSEvan Bacon  });
113082815dcSEvan Bacon}
114082815dcSEvan Baconfunction getAndroidPermissions(config) {
115082815dcSEvan Bacon  var _config$android$permi, _config$android3;
116082815dcSEvan Bacon  return (_config$android$permi = (_config$android3 = config.android) === null || _config$android3 === void 0 ? void 0 : _config$android3.permissions) !== null && _config$android$permi !== void 0 ? _config$android$permi : [];
117082815dcSEvan Bacon}
118082815dcSEvan Baconfunction setAndroidPermissions(config, androidManifest) {
119082815dcSEvan Bacon  var _androidManifest$mani;
120082815dcSEvan Bacon  const permissions = getAndroidPermissions(config);
121082815dcSEvan Bacon  const providedPermissions = prefixAndroidPermissionsIfNecessary(permissions);
122082815dcSEvan Bacon  const permissionsToAdd = [...providedPermissions];
123082815dcSEvan Bacon  if (!androidManifest.manifest.hasOwnProperty('uses-permission')) {
124082815dcSEvan Bacon    androidManifest.manifest['uses-permission'] = [];
125ee216927STomasz Sapeta  }
126ee216927STomasz Sapeta  // manifest.manifest['uses-permission'] = [];
127082815dcSEvan Bacon
128082815dcSEvan Bacon  const manifestPermissions = (_androidManifest$mani = androidManifest.manifest['uses-permission']) !== null && _androidManifest$mani !== void 0 ? _androidManifest$mani : [];
129082815dcSEvan Bacon  permissionsToAdd.forEach(permission => {
130082815dcSEvan Bacon    if (!isPermissionAlreadyRequested(permission, manifestPermissions)) {
131082815dcSEvan Bacon      addPermissionToManifest(permission, manifestPermissions);
132082815dcSEvan Bacon    }
133082815dcSEvan Bacon  });
134082815dcSEvan Bacon  return androidManifest;
135082815dcSEvan Bacon}
136082815dcSEvan Baconfunction isPermissionAlreadyRequested(permission, manifestPermissions) {
137082815dcSEvan Bacon  return manifestPermissions.some(e => e.$['android:name'] === permission);
138082815dcSEvan Bacon}
139082815dcSEvan Baconfunction addPermissionToManifest(permission, manifestPermissions) {
140082815dcSEvan Bacon  manifestPermissions.push({
141082815dcSEvan Bacon    $: {
142082815dcSEvan Bacon      'android:name': permission
143082815dcSEvan Bacon    }
144082815dcSEvan Bacon  });
145082815dcSEvan Bacon  return manifestPermissions;
146082815dcSEvan Bacon}
147082815dcSEvan Baconfunction removePermissions(androidManifest, permissionNames) {
148082815dcSEvan Bacon  const targetNames = permissionNames ? permissionNames.map(ensurePermissionNameFormat) : null;
149082815dcSEvan Bacon  const permissions = androidManifest.manifest[USES_PERMISSION] || [];
150082815dcSEvan Bacon  const nextPermissions = [];
151082815dcSEvan Bacon  for (const attribute of permissions) {
152082815dcSEvan Bacon    if (targetNames) {
153082815dcSEvan Bacon      // @ts-ignore: name isn't part of the type
154082815dcSEvan Bacon      const value = attribute.$['android:name'] || attribute.$.name;
155082815dcSEvan Bacon      if (!targetNames.includes(value)) {
156082815dcSEvan Bacon        nextPermissions.push(attribute);
157082815dcSEvan Bacon      }
158082815dcSEvan Bacon    }
159082815dcSEvan Bacon  }
160082815dcSEvan Bacon  androidManifest.manifest[USES_PERMISSION] = nextPermissions;
161082815dcSEvan Bacon}
162082815dcSEvan Baconfunction addPermission(androidManifest, permissionName) {
163082815dcSEvan Bacon  const usesPermissions = androidManifest.manifest[USES_PERMISSION] || [];
164082815dcSEvan Bacon  usesPermissions.push({
165082815dcSEvan Bacon    $: {
166082815dcSEvan Bacon      'android:name': permissionName
167082815dcSEvan Bacon    }
168082815dcSEvan Bacon  });
169082815dcSEvan Bacon  androidManifest.manifest[USES_PERMISSION] = usesPermissions;
170082815dcSEvan Bacon}
171082815dcSEvan Baconfunction ensurePermissions(androidManifest, permissionNames) {
172082815dcSEvan Bacon  const permissions = getPermissions(androidManifest);
173082815dcSEvan Bacon  const results = {};
174082815dcSEvan Bacon  for (const permissionName of permissionNames) {
175082815dcSEvan Bacon    const targetName = ensurePermissionNameFormat(permissionName);
176082815dcSEvan Bacon    if (!permissions.includes(targetName)) {
177082815dcSEvan Bacon      addPermission(androidManifest, targetName);
178082815dcSEvan Bacon      results[permissionName] = true;
179082815dcSEvan Bacon    } else {
180082815dcSEvan Bacon      results[permissionName] = false;
181082815dcSEvan Bacon    }
182082815dcSEvan Bacon  }
183082815dcSEvan Bacon  return results;
184082815dcSEvan Bacon}
185082815dcSEvan Baconfunction ensurePermission(androidManifest, permissionName) {
186082815dcSEvan Bacon  const permissions = getPermissions(androidManifest);
187082815dcSEvan Bacon  const targetName = ensurePermissionNameFormat(permissionName);
188082815dcSEvan Bacon  if (!permissions.includes(targetName)) {
189082815dcSEvan Bacon    addPermission(androidManifest, targetName);
190082815dcSEvan Bacon    return true;
191082815dcSEvan Bacon  }
192082815dcSEvan Bacon  return false;
193082815dcSEvan Bacon}
194082815dcSEvan Baconfunction ensurePermissionNameFormat(permissionName) {
195082815dcSEvan Bacon  if (permissionName.includes('.')) {
196082815dcSEvan Bacon    const com = permissionName.split('.');
197082815dcSEvan Bacon    const name = com.pop();
198082815dcSEvan Bacon    return [...com, name.toUpperCase()].join('.');
199082815dcSEvan Bacon  } else {
200082815dcSEvan Bacon    // If shorthand form like `WRITE_CONTACTS` is provided, expand it to `android.permission.WRITE_CONTACTS`.
201082815dcSEvan Bacon    return ensurePermissionNameFormat(`android.permission.${permissionName}`);
202082815dcSEvan Bacon  }
203082815dcSEvan Bacon}
204082815dcSEvan Baconfunction getPermissions(androidManifest) {
205082815dcSEvan Bacon  const usesPermissions = androidManifest.manifest[USES_PERMISSION] || [];
206082815dcSEvan Bacon  const permissions = usesPermissions.map(permissionObject => {
207082815dcSEvan Bacon    return permissionObject.$['android:name'] || permissionObject.$.name;
208082815dcSEvan Bacon  });
209082815dcSEvan Bacon  return permissions;
210082815dcSEvan Bacon}
211082815dcSEvan Bacon//# sourceMappingURL=Permissions.js.map