Files
json/rc_rewrite.js
2023-10-06 19:45:38 +08:00

289 lines
9.1 KiB
JavaScript

const storageKeyName = "rc_rewrite_ddata";
const jobTitle = "update_rc";
const notificationTitle = "Update RevenueCat JSON"
let URL = "";
// URL = 'https://jsonplaceholder.typicode.com/todos/1';
// URL = "https://stackoverflow.com/questions/38708550/difference-between-return-await-promise-and-return-promise"
// URL = "http://localhost:8000/rc_rewrite_data.json";
// URL = "https://api.jsonbin.io/v3/qs/651be8b30574da7622b3b246";
URL = "https://git.ykz.app/PorridgePi/json/raw/branch/main/rc_rewrite_data.json";
// URL = "https://porridgepi.github.io/json/rc_rewrite_data.json"
requestOpts = {
// mode:'no-cors',
cache: "no-store",
headers: {
// "Origin": "https://git.ykz.app/",
// "Accept": "application/json"
}
}
const isSurge = typeof $httpClient != "undefined";
const isQuanX = typeof $task != "undefined";
const isLoon = typeof $loon != "undefined";
const isJSBox = typeof $app != "undefined" && typeof $http != "undefined";
const isNode = typeof require == "function" && !isJSBox;
function timeout(ms, promise) {
return new Promise((resolve, reject) => {
const timer = setTimeout(() => {
reject(new Error("Timed out after " + String(ms) + "ms"))
}, ms)
promise
.then(value => {
clearTimeout(timer)
resolve(value)
})
.catch(reason => {
clearTimeout(timer)
reject(reason)
})
})
}
async function fetchJSON(url, opts = {}) {
if (isQuanX) {
return fetch(url, {
...opts
})
.then(response => {
if (false && !response.ok) {
console.log("ERROR(fetchJSON): Response not okay, HTTP " + String(response.status) + ' ' + response.statusText);
throw new Error("Response not ok");
}
return response.text()
.then(text => {
try {
return JSON.parse(text);
} catch (err) {
console.log("ERROR(fetchJSON): Response body not JSON" + String(err));
console.log(text);
throw new Error("Response body not JSON");
}
})
});
}
if (isNode) {
var resp = await $http.get(url, opts);
try {
return JSON.parse(resp.body);
} catch (err) {
console.log("ERROR(fetchJSON): Response body not JSON" + String(err));
console.log(text);
throw new Error("Response body not JSON");
}
}
}
async function getRewriteItems() {
try {
let toReturn = JSON.parse($prefs.valueForKey(storageKeyName));
console.log("INFO: Retrieved local copy.")
return toReturn;
} catch (err) {
console.log("ERROR(getRewriteItems): Unable to access local copy - " + err);
console.log("INFO: Fetching new copy...");
try {
if (isQuanX) return await timeout(1000, fetchJSON(URL, requestOpts)); // add await if using nested try-catch - https://stackoverflow.com/a/42750371
if (isNode) return fetchJSON(URL, requestOpts);
} catch (err) {
console.log("ERROR(getRewriteItems): " + err);
throw new Error("Unable to retrieve rewrite items.");
}
}
}
async function onResponse(context, url, request, response) {
console.log("INFO: Running...");
let rewriteItems = {}
try {
rewriteItems = await getRewriteItems();
// console.log(JSON.stringify(rewriteItems));
} catch (err) {
console.log("ERROR(onResponse): " + err);
}
let bundle_id = request.headers["X-Client-Bundle-ID"];
let user_agent = request.headers["User-Agent"];
for (let i = 0; i < rewriteItems.length; i++) {
rewriteItem = rewriteItems[i]
// console.log(JSON.stringify(rewriteItem));
console.log(rewriteItem.name);
let bundleIdMatched = bundle_id != null && bundle_id == rewriteItem.bundle_id
let userAgentMatched = user_agent != null && user_agent.includes(rewriteItem.user_agent)
if (!bundleIdMatched && !userAgentMatched) {
if (i == rewriteItems.length - 1) { // last
console.log(String(bundle_id) + " " + String(user_agent));
break;
}
continue;
}
console.log("MATCHED!");
body = {
...response.body
}
if (body.subscriber == undefined) body.subscriber = {}
console.log(JSON.stringify(body));
let now = new Date();
let MS_PER_MINUTE = 60000;
let timeToUse = new Date(now - 0 * MS_PER_MINUTE); // CAN CHANGE MANUAL DELAY
if (body.request_date == undefined) body.request_date = timeToUse.toISOString().split('.')[0] + "Z";
if (body.request_date_ms == undefined) body.request_date_ms = Date.parse(timeToUse);
if (body.subscriber.first_seen == undefined) body.subscriber.first_seen = timeToUse.toISOString().split('.')[0] + "Z";
if (body.subscriber.last_seen == undefined) body.subscriber.last_seen = timeToUse.toISOString().split('.')[0] + "Z";
if (body.subscriber.management_url == undefined) body.subscriber.management_url = null;
const uuidString = url.slice(-32);
console.log(uuidString)
const uuid = uuidString.replace(/(.{8})(.{4})(.{4})(.{4})(.{12})/g, '$1-$2-$3-$4-$5')
console.log(uuid)
if (body.subscriber.original_app_user_id == undefined) body.subscriber.original_app_user_id = uuid;
if (body.subscriber.original_application_version == undefined) body.subscriber.original_application_version = "0.0";
if (body.subscriber.original_purchase_date == undefined) body.subscriber.original_purchase_date = now.toISOString().split('.')[0] + "Z";
body.subscriber.entitlements = {
...body.subscriber.entitlements
};
body.subscriber.subscriptions = {
...body.subscriber.subscriptions
};
body.subscriber.non_subscriptions = {
...body.subscriber.non_subscriptions
};
body.subscriber.other_purchases = {
...body.subscriber.other_purchases
};
let isSubscription = rewriteItem.new_subscriptions.length > 0;
let isNonSubscription = rewriteItem.new_non_subscriptions.length > 0;
let product_id = ""
console.log(isNonSubscription);
console.log(isSubscription);
console.log(body.subscriber.entitlements);
if (isSubscription) {
product_id = rewriteItem.new_subscriptions[0];
for (const i of rewriteItem.new_subscriptions) {
body.subscriber.subscriptions[i] = {
"auto_resume_date": null,
"billing_issues_detected_at": null,
"expires_date": "2099-12-31T23:59:59Z",
"grace_period_expires_date": null,
"is_sandbox": false,
"original_purchase_date": "2020-01-01T00:00:00Z",
"period_type": "normal",
"purchase_date": "2020-01-01T00:00:00Z",
"refunded_at": null,
"store": "app-store",
"store_transaction_id": "",
"unsubscribe_detected_at": null
}
}
}
if (isNonSubscription) {
product_id = rewriteItem.new_non_subscriptions[0];
for (const i of rewriteItem.new_non_subscriptions) {
body.subscriber.non_subscriptions[i] = {
"is_sandbox": false,
"store_transaction_id": "",
"id": "",
"original_purchase_date": "2020-01-01T00:00:00Z",
"store": "app_store",
"purchase_date": "2020-01-01T00:00:00Z"
}
}
for (const i of rewriteItem.new_other_purchases) {
body.subscriber.other_purchases[i] = {
purchase_date: "2020-01-01T00:00:00Z"
}
}
}
for (const i of rewriteItem.new_entitlements) {
body.subscriber.entitlements[i] = {
"expires_date": null,
"grace_period_expires_date": null,
"product_identifier": product_id,
"purchase_date": "2020-01-01T00:00:00Z"
}
}
response.body = body;
response.statusCode = 200;
response.statusPhrase = "OK";
response.headers["Content-Type"] = "application/json";
console.log(response.body);
break;
}
console.log("INFO: Exiting...");
return response;
}
var $request, $response;
async function main() {
console.log("Starting...");
if (isSurge || isQuanX) {
try {
console.log(JSON.stringify($request));
if (typeof $request == 'undefined') $request = {
url: "",
headers: {
// "X-Client-Bundle-ID": "com.benricemccarthy.obscura-2"
},
body: "{}"
}
console.log(JSON.stringify($request));
if (typeof $response == 'undefined') $response = {
url: "",
headers: {},
body: "{}"
}
url = $request.url;
$request.body = typeof $request.body != "undefined" ? JSON.parse($request.body) : {};
$response.body = typeof $response.body != "undefined" ? JSON.parse($response.body) : {};
} catch (err) {
console.log(err);
}
console.log("starting onResponse");
try {
response = await timeout(3000, onResponse(null, url, $request, $response));
} catch (err) {
console.log(err);
}
if (isQuanX) {
$request.status = "HTTP/1.1 " + $request.statusCode + " " + $request.statusPhrase;
$response.status = "HTTP/1.1 " + $response.statusCode + " " + $response.statusPhrase;
$request.body = JSON.stringify($request.body);
$response.body = JSON.stringify($response.body);
}
$done({
status: $response.status,
headers: $response.headers,
body: $response.body
});
}
}
main();