-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcocKeyGen.js
More file actions
156 lines (137 loc) · 5.81 KB
/
Copy pathcocKeyGen.js
File metadata and controls
156 lines (137 loc) · 5.81 KB
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
const axios = require('axios');
const fs = require('fs');
const path = require('path');
const crypto = require('crypto');
class Codebox4chan {
constructor(email, password) {
this.email = email;
this.password = password;
this.apiKey = null;
this.periodicCheckInterval = null;
this.periodicallyCheckAndGenerateKey();
}
async getMyIp() {
const response = await axios.get('https://api.ipify.org?format=json'); //check current ip
return response.data.ip;
}
async login() {
const url = 'https://developer.clashofclans.com/api/login';
const headers = { 'authority': 'developer.clashofclans.com',
'accept': '*/*',
'x-requested-with': 'XMLHttpRequest',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36',
'content-type': 'application/json',
'sec-gpc': '1',
'origin': 'https://developer.clashofclans.com',
'sec-fetch-site': 'same-origin',
'sec-fetch-mode': 'cors',
'sec-fetch-dest': 'empty',
'referer': 'https://developer.clashofclans.com/',
'accept-language': 'en-US,en;q=0.9',
'cookie': 'cookieconsent_status=dismiss' };
const data = { 'email': this.email, 'password': this.password };
const response = await axios.post(url, JSON.stringify(data), { headers });
return response.headers['set-cookie'];
}
async saveApiKeyToFile(apiKey, ip) {
const filePath = path.join(__dirname, 'cocdev.json');
let jsonData = { apiKey, ip };
try {
const existingData = fs.readFileSync(filePath);
const parsedData = JSON.parse(existingData);
jsonData = { ...parsedData, apiKey, ip }; // Update existing data with new values
} catch (error) {
}
fs.writeFileSync(filePath, JSON.stringify(jsonData, null, 2));
}
async loadApiKeyFromFile() {
const filePath = path.join(__dirname, 'cocdev.json');
try {
const rawData = fs.readFileSync(filePath);
const jsonData = JSON.parse(rawData);
return jsonData || null;
} catch (error) {
return null;
}
}
async createKey() {
const apiKeyFromFile = await this.loadApiKeyFromFile();
const currentIp = await this.getMyIp();
if (!apiKeyFromFile || apiKeyFromFile.ip !== currentIp) {
// API key doesn't exist or IP has changed, generate a new key
await this.deleteKey();
const newApiKey = await this.generateApiKey(currentIp);
this.apiKey = newApiKey;
} else {
// Use the existing API key
this.apiKey = apiKeyFromFile.apiKey;
}
// Save the API key to file, whether it's newly generated or existing
await this.saveApiKeyToFile(this.apiKey, currentIp);
return this.apiKey;
}
async periodicallyCheckAndGenerateKey() {
this.periodicCheckInterval = setInterval(async () => {
const currentIp = await this.getMyIp();
const apiKeyFromFile = await this.loadApiKeyFromFile();
if (!apiKeyFromFile || apiKeyFromFile.ip !== currentIp) {
await this.deleteKey();// revoke the token before generating new one
const newApiKey = await this.generateApiKey(currentIp);
this.apiKey = newApiKey;
console.log("New API Key generated:", newApiKey);
} else {
console.log("IP matches existing API Key.");
}
}, 5 * 60 * 1000);// check ip every 5 minutes if the ip don't match to the current ip automatically revokes the old Key and replace with new
}
async generateApiKey(ip) {
const cookie = await this.login();
const url = 'https://developer.clashofclans.com/api/apikey/create';
const headers = { 'authority': 'developer.clashofclans.com',
'accept': '*/*',
'x-requested-with': 'XMLHttpRequest',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36',
'content-type': 'application/json',
'sec-gpc': '1',
'origin': 'https://developer.clashofclans.com',
'sec-fetch-site': 'same-origin',
'sec-fetch-mode': 'cors',
'sec-fetch-dest': 'empty',
'referer': 'https://developer.clashofclans.com/',
'accept-language': 'en-US,en;q=0.9',
'cookie': cookie };
const randomData = crypto.randomBytes(12).toString('hex');
const data = { "name": randomData, "description": randomData, "cidrRanges": [ip], "scopes": null };
const response = await axios.post(url, JSON.stringify(data), { headers });
const newApiKey = response.data.key;
await this.saveApiKeyToFile(newApiKey, ip);
return newApiKey;
}
async deleteKey() {
const apiKeyInfo = await this.loadApiKeyFromFile();
if (!apiKeyInfo || !apiKeyInfo.apiKey) {
console.log('API key information not found.');
return;
}
const cookie = await this.login();
const url = 'https://developer.clashofclans.com/api/apikey/revoke';
const headers = { 'authority': 'developer.clashofclans.com',
'accept': '*/*',
'x-requested-with': 'XMLHttpRequest',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36',
'content-type': 'application/json',
'sec-gpc': '1',
'origin': 'https://developer.clashofclans.com',
'sec-fetch-site': 'same-origin',
'sec-fetch-mode': 'cors',
'sec-fetch-dest': 'empty',
'referer': 'https://developer.clashofclans.com/',
'accept-language': 'en-US,en;q=0.9',
'cookie': cookie };
const data = { "id": apiKeyInfo.apiKey };
const response = await axios.post(url, JSON.stringify(data), { headers });
console.log(response.data);
}
}
const reikodev = new Codebox4chan("example@gmail.com", "kennethpanio");// login your clash of clans developer account replace this with your email and password
reikodev.createKey().then(apiKey => console.log(apiKey)).catch(error => console.error(error));