forked from tanquan/clone_jetbra
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjetbra.js
122 lines (112 loc) · 4.05 KB
/
jetbra.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
122
// ==UserScript==
// @name JetBra
// @namespace https://github.com/novice88/jetbra
// @version 3.1
// @license MIT
// @description Add a button on the plugin homepage and click to get the plugin activation code
// @author novice.li
// @match https://plugins.jetbrains.com/*
// @grant GM_setClipboard
// @grant GM_addStyle
// @grant GM_xmlhttpRequest
// @grant window.onurlchange
// @connect noviceli.win
// @connect self
// @connect localhost
// ==/UserScript==
async function findElementWithRetry(cssSelector) {
const maxAttempts = 50;
for (let attempts = 0; attempts < maxAttempts; attempts++) {
const element = document.querySelector(cssSelector);
if (element) {
return element;
}
await new Promise(resolve => setTimeout(resolve, 100));
}
throw new Error(`Element with selector '${cssSelector}' not found after ${maxAttempts} attempts.`);
}
let addButton = async function () {
console.log('JetBra is running');
'use strict';
GM_addStyle(`
.jetbra-button {
background-color: #04AA6D;
border: none;
color: white;
padding: 8px 24px;
text-align: center;
text-decoration: none;
display: inline-block;
border-radius: 16px;
box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
transition-duration: 0.4s;
}
.jetbra-button:hover {
background-color: #057e47;
color: white;
}
`);
const backendBaseUrl = 'https://jetbra.noviceli.win'
// 获取插件的 id
// 如果当前url满足 https://plugins.jetbrains.com/plugin/<pluginId>-xxx 的格式,就直接从url中获取
let url = window.location.href
if (!url.startsWith('https://plugins.jetbrains.com/plugin/')) {
return;
}
// 提取 pluginId
let pluginId = url.split('/')[4].split('-')[0]
console.log('pluginId: ' + pluginId);
let pluginDetail = await fetch('https://plugins.jetbrains.com/api/plugins/' + pluginId).then(r => r.json());
const parentElement = await findElementWithRetry('.plugin-header__controls-panel > div:first-child');
// 如果 parentElement 的孩子中已经有了按钮,就不再添加
if (parentElement.querySelector('.jetbra-button')) {
return;
}
let newElement = document.createElement('div');
newElement.classList.toggle('wt-col-inline');
newElement.innerHTML = `<button class="jetbra-button" type="button">CLICK TO GENERATE ACTIVATION CODE</button>`;
parentElement.appendChild(newElement)
newElement.addEventListener('click', async () => {
if (pluginDetail.purchaseInfo === undefined) {
window.alert('This plugin is not a paid plugin in the market');
return;
}
let data = {
"licenseeName": "Test",
"assigneeName": "novice.li",
"assigneeEmail": "",
"licenseRestriction": "",
"checkConcurrentUse": false,
"products": [{
"code": pluginDetail.purchaseInfo.productCode,
"fallbackDate": "2099-12-30",
"paidUpTo": "2099-12-30",
"extended": false
}],
"metadata": "0120230102PPAA013009",
"hash": "41472961/0:1563609451",
"gracePeriodDays": 7,
"autoProlongated": true,
"isAutoProlongated": true
}
GM_xmlhttpRequest({
method: 'POST',
url: backendBaseUrl + '/generateLicense',
headers: {
'Content-Type': 'application/json'
},
data: JSON.stringify(data),
onload: function (response) {
let license = JSON.parse(response.responseText).license
GM_setClipboard(license, 'text');
window.alert('The activation code has been copied to your clipboard');
}
});
})
};
addButton();
if (window.onurlchange === null) {
window.addEventListener('urlchange', (info) => {
addButton();
});
}