-
-
Notifications
You must be signed in to change notification settings - Fork 623
/
permissions.js
121 lines (94 loc) · 2.97 KB
/
permissions.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import * as R from 'ramda';
import request from './utils/request.js';
import scriptData from './utils/scriptData.js';
import { BASE_URL, constants } from './constants.js';
import createDebug from 'debug';
const debug = createDebug('google-play-scraper:permissions');
function permissions (opts) {
return new Promise(function (resolve, reject) {
if (!opts && !opts.appId) {
throw Error('appId missing');
}
opts.lang = opts.lang || 'en';
processPermissions(opts)
.then(resolve)
.catch(reject);
});
}
function processPermissions (opts) {
const body = `f.req=%5B%5B%5B%22xdSrCf%22%2C%22%5B%5Bnull%2C%5B%5C%22${opts.appId}%5C%22%2C7%5D%2C%5B%5D%5D%5D%22%2Cnull%2C%221%22%5D%5D%5D`;
const url = `${BASE_URL}/_/PlayStoreUi/data/batchexecute?rpcids=qnKhOb&f.sid=-697906427155521722&bl=boq_playuiserver_20190903.08_p0&hl=${opts.lang}&authuser&soc-app=121&soc-platform=1&soc-device=1&_reqid=1065213`;
debug('batchexecute URL: %s', url);
debug('with body: %s', body);
const requestOptions = Object.assign({
url,
method: 'POST',
body,
followRedirect: true,
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
}
}, opts.requestOptions);
return request(requestOptions, opts.throttle)
.then((html) => {
const input = JSON.parse(html.substring(5));
const data = JSON.parse(input[0][2]);
if (data === null) {
return [];
}
return (opts.short)
? processShortPermissionsData(data)
: processPermissionData(data);
});
}
const MAPPINGS = {
permissions: [2],
type: 0
};
function processShortPermissionsData (html) {
if (R.is(String, html)) {
html = scriptData.parse(html);
}
const commonPermissions = html[constants.permission.COMMON];
if (!commonPermissions) {
return [];
}
const validPermissions = commonPermissions.filter(permission => permission.length);
const permissionNames = R.chain(permission => permission[MAPPINGS.type], validPermissions);
return permissionNames;
}
function processPermissionData (html) {
if (R.is(String, html)) {
html = scriptData.parse(html);
}
debug('html %o', html);
const permissions = Object.values(constants.permission).reduce((permissionAccummulator, permission) => {
if (!html[permission]) {
return permissionAccummulator;
}
permissionAccummulator.push(
...R.chain(flatMapPermissions, html[permission])
);
return permissionAccummulator;
}, []);
debug('Permissions %o', permissions);
return permissions;
}
function flatMapPermissions (permission) {
const input = R.path(MAPPINGS.permissions, permission);
if (typeof input === 'undefined') {
return [];
}
const mappings = getPermissionMappings(permission[MAPPINGS.type]);
return R.map(scriptData.extractor(mappings), input);
}
function getPermissionMappings (type) {
return {
permission: [1],
type: {
path: 0,
fun: () => type
}
};
}
export default permissions;