@necrolab/dashboard 0.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +45 -0
- package/.eslintrc.js +24 -0
- package/.prettierignore +1 -0
- package/.prettierrc +10 -0
- package/.vscode/extensions.json +3 -0
- package/ICONS.md +21 -0
- package/README.md +65 -0
- package/backend/api.js +430 -0
- package/backend/auth.js +62 -0
- package/backend/batching.js +43 -0
- package/backend/endpoints.js +343 -0
- package/backend/index.js +23 -0
- package/backend/mock-data.js +66 -0
- package/backend/mock-src/classes/logger.js +112 -0
- package/backend/mock-src/classes/utils.js +42 -0
- package/backend/mock-src/ticketmaster.js +92 -0
- package/backend/validator.js +62 -0
- package/config/configs.json +20 -0
- package/config/filter.json +3 -0
- package/config/presale.csv +3 -0
- package/config/proxies.txt +6 -0
- package/config/used-codes.json +4 -0
- package/index.html +114 -0
- package/index.js +2 -0
- package/jsconfig.json +16 -0
- package/package.json +48 -0
- package/postcss.config.js +6 -0
- package/postinstall.js +9 -0
- package/public/android-chrome-192x192.png +0 -0
- package/public/android-chrome-512x512.png +0 -0
- package/public/apple-touch-icon.png +0 -0
- package/public/favicon-16x16.png +0 -0
- package/public/favicon-32x32.png +0 -0
- package/public/favicon.ico +0 -0
- package/public/flags/ae.svg +1 -0
- package/public/flags/at.svg +1 -0
- package/public/flags/au.svg +1 -0
- package/public/flags/be.svg +1 -0
- package/public/flags/ch.svg +1 -0
- package/public/flags/cz.svg +1 -0
- package/public/flags/de.svg +1 -0
- package/public/flags/dk.svg +1 -0
- package/public/flags/es.svg +1 -0
- package/public/flags/nl.svg +1 -0
- package/public/flags/no.svg +1 -0
- package/public/flags/nz.svg +1 -0
- package/public/flags/pl.svg +1 -0
- package/public/flags/se.svg +1 -0
- package/public/flags/uk.svg +1 -0
- package/public/flags/us.svg +1 -0
- package/public/img/award.svg +3 -0
- package/public/img/background.svg +14 -0
- package/public/img/bag_w.svg +12 -0
- package/public/img/banks/amex.svg +4 -0
- package/public/img/banks/mastercard.svg +4 -0
- package/public/img/banks/visa.svg +4 -0
- package/public/img/camera.svg +3 -0
- package/public/img/close.svg +3 -0
- package/public/img/controls/disable.svg +5 -0
- package/public/img/controls/enable.svg +5 -0
- package/public/img/groups.svg +3 -0
- package/public/img/hand.svg +3 -0
- package/public/img/key.svg +3 -0
- package/public/img/logo.png +0 -0
- package/public/img/logo_icon.png +0 -0
- package/public/img/logo_icon_2.png +0 -0
- package/public/img/logo_trans.png +0 -0
- package/public/img/loyalty.svg +3 -0
- package/public/img/mail.svg +3 -0
- package/public/img/pencil.svg +3 -0
- package/public/img/profile.svg +4 -0
- package/public/img/reload.svg +3 -0
- package/public/img/sandclock.svg +25 -0
- package/public/img/save.svg +5 -0
- package/public/img/savings.svg +3 -0
- package/public/img/scanner.svg +3 -0
- package/public/img/sell.svg +3 -0
- package/public/img/shield.svg +3 -0
- package/public/img/ski.svg +3 -0
- package/public/img/stadium.svg +8 -0
- package/public/img/stadium_w.svg +8 -0
- package/public/img/timer.svg +3 -0
- package/public/manifest.json +27 -0
- package/public/robots.txt +2 -0
- package/run +10 -0
- package/src/App.vue +307 -0
- package/src/assets/css/_input.scss +197 -0
- package/src/assets/css/main.scss +269 -0
- package/src/assets/css/tailwind.css +3 -0
- package/src/assets/img/award.svg +3 -0
- package/src/assets/img/background.svg +11 -0
- package/src/assets/img/camera.svg +3 -0
- package/src/assets/img/close.svg +3 -0
- package/src/assets/img/eyes/closed.svg +13 -0
- package/src/assets/img/eyes/open.svg +12 -0
- package/src/assets/img/groups.svg +3 -0
- package/src/assets/img/hand.svg +3 -0
- package/src/assets/img/key.svg +3 -0
- package/src/assets/img/logo.png +0 -0
- package/src/assets/img/logo_icon.png +0 -0
- package/src/assets/img/logo_icon_2.png +0 -0
- package/src/assets/img/logo_trans.png +0 -0
- package/src/assets/img/loyalty.svg +3 -0
- package/src/assets/img/mail.svg +3 -0
- package/src/assets/img/pencil.svg +3 -0
- package/src/assets/img/reload.svg +3 -0
- package/src/assets/img/savings.svg +3 -0
- package/src/assets/img/scanner.svg +3 -0
- package/src/assets/img/sell.svg +3 -0
- package/src/assets/img/shield.svg +3 -0
- package/src/assets/img/ski.svg +3 -0
- package/src/assets/img/square_check.svg +5 -0
- package/src/assets/img/square_uncheck.svg +5 -0
- package/src/assets/img/stadium.svg +8 -0
- package/src/assets/img/timer.svg +3 -0
- package/src/assets/img/wildcard.svg +7 -0
- package/src/components/Auth/LoginForm.vue +48 -0
- package/src/components/Editors/Account/Account.vue +119 -0
- package/src/components/Editors/Account/AccountCreator.vue +147 -0
- package/src/components/Editors/Account/AccountView.vue +87 -0
- package/src/components/Editors/Account/CreateAccount.vue +106 -0
- package/src/components/Editors/Profile/CreateProfile.vue +321 -0
- package/src/components/Editors/Profile/Profile.vue +142 -0
- package/src/components/Editors/Profile/ProfileCountryChooser.vue +75 -0
- package/src/components/Editors/Profile/ProfileView.vue +96 -0
- package/src/components/Editors/TagLabel.vue +16 -0
- package/src/components/Editors/TagToggle.vue +41 -0
- package/src/components/Filter/Filter.vue +409 -0
- package/src/components/Filter/FilterPreview.vue +236 -0
- package/src/components/Filter/PriceSortToggle.vue +105 -0
- package/src/components/Table/Header.vue +5 -0
- package/src/components/Table/Row.vue +5 -0
- package/src/components/Table/Table.vue +14 -0
- package/src/components/Table/index.js +4 -0
- package/src/components/Tasks/CheckStock.vue +62 -0
- package/src/components/Tasks/Controls/DesktopControls.vue +73 -0
- package/src/components/Tasks/Controls/MobileControls.vue +32 -0
- package/src/components/Tasks/Controls/index.js +3 -0
- package/src/components/Tasks/CreateTaskAXS.vue +339 -0
- package/src/components/Tasks/CreateTaskTM.vue +459 -0
- package/src/components/Tasks/MassEdit.vue +50 -0
- package/src/components/Tasks/QuickSettings.vue +167 -0
- package/src/components/Tasks/ScrapeVenue.vue +42 -0
- package/src/components/Tasks/Stats.vue +66 -0
- package/src/components/Tasks/Task.vue +296 -0
- package/src/components/Tasks/TaskLabel.vue +20 -0
- package/src/components/Tasks/TaskView.vue +126 -0
- package/src/components/Tasks/Utilities.vue +33 -0
- package/src/components/icons/Award.vue +8 -0
- package/src/components/icons/Bag.vue +8 -0
- package/src/components/icons/BagWhite.vue +8 -0
- package/src/components/icons/Box.vue +8 -0
- package/src/components/icons/Camera.vue +8 -0
- package/src/components/icons/Cart.vue +8 -0
- package/src/components/icons/Check.vue +5 -0
- package/src/components/icons/Checkmark.vue +11 -0
- package/src/components/icons/Click.vue +8 -0
- package/src/components/icons/Close.vue +21 -0
- package/src/components/icons/CloseX.vue +5 -0
- package/src/components/icons/Console.vue +13 -0
- package/src/components/icons/Down.vue +8 -0
- package/src/components/icons/Edit.vue +13 -0
- package/src/components/icons/Event.vue +8 -0
- package/src/components/icons/Expand.vue +8 -0
- package/src/components/icons/Filter.vue +13 -0
- package/src/components/icons/Gear.vue +8 -0
- package/src/components/icons/Group.vue +8 -0
- package/src/components/icons/Hand.vue +8 -0
- package/src/components/icons/Key.vue +21 -0
- package/src/components/icons/Logout.vue +13 -0
- package/src/components/icons/Loyalty.vue +8 -0
- package/src/components/icons/Mail.vue +8 -0
- package/src/components/icons/Menu.vue +8 -0
- package/src/components/icons/Pause.vue +5 -0
- package/src/components/icons/Pencil.vue +21 -0
- package/src/components/icons/Play.vue +8 -0
- package/src/components/icons/Plus.vue +8 -0
- package/src/components/icons/Profile.vue +18 -0
- package/src/components/icons/Reload.vue +7 -0
- package/src/components/icons/Sandclock.vue +33 -0
- package/src/components/icons/Savings.vue +8 -0
- package/src/components/icons/Scanner.vue +8 -0
- package/src/components/icons/Scrape.vue +8 -0
- package/src/components/icons/Sell.vue +21 -0
- package/src/components/icons/Shield.vue +8 -0
- package/src/components/icons/Shrink.vue +8 -0
- package/src/components/icons/Ski.vue +8 -0
- package/src/components/icons/Spinner.vue +42 -0
- package/src/components/icons/SquareCheck.vue +18 -0
- package/src/components/icons/SquareUncheck.vue +18 -0
- package/src/components/icons/Stadium.vue +13 -0
- package/src/components/icons/StadiumWhite.vue +13 -0
- package/src/components/icons/Status.vue +8 -0
- package/src/components/icons/Tag.vue +8 -0
- package/src/components/icons/Tasks.vue +13 -0
- package/src/components/icons/Ticket.vue +8 -0
- package/src/components/icons/Timer.vue +8 -0
- package/src/components/icons/Trash.vue +8 -0
- package/src/components/icons/Up.vue +10 -0
- package/src/components/icons/Wildcard.vue +18 -0
- package/src/components/icons/index.js +111 -0
- package/src/components/ui/Modal.vue +61 -0
- package/src/components/ui/Navbar.vue +207 -0
- package/src/components/ui/ReconnectIndicator.vue +90 -0
- package/src/components/ui/Splash.vue +24 -0
- package/src/components/ui/controls/CountryChooser.vue +87 -0
- package/src/components/ui/controls/EyeToggle.vue +11 -0
- package/src/components/ui/controls/atomic/Checkbox.vue +28 -0
- package/src/components/ui/controls/atomic/Dropdown.vue +138 -0
- package/src/components/ui/controls/atomic/LoadingButton.vue +45 -0
- package/src/components/ui/controls/atomic/MultiDropdown.vue +262 -0
- package/src/components/ui/controls/atomic/Switch.vue +84 -0
- package/src/libs/Filter.js +593 -0
- package/src/libs/ansii.js +565 -0
- package/src/libs/panzoom.js +1413 -0
- package/src/main.js +23 -0
- package/src/registerServiceWorker.js +32 -0
- package/src/router/index.js +65 -0
- package/src/stores/cities.json +1 -0
- package/src/stores/connection.js +399 -0
- package/src/stores/countries.js +88 -0
- package/src/stores/logger.js +103 -0
- package/src/stores/requests.js +88 -0
- package/src/stores/sampleData.js +1034 -0
- package/src/stores/ui.js +584 -0
- package/src/stores/utils.js +554 -0
- package/src/types/index.js +42 -0
- package/src/utils/debug.js +1 -0
- package/src/views/Accounts.vue +191 -0
- package/src/views/Console.vue +224 -0
- package/src/views/Editor.vue +785 -0
- package/src/views/FilterBuilder.vue +785 -0
- package/src/views/Login.vue +27 -0
- package/src/views/Profiles.vue +209 -0
- package/src/views/Tasks.vue +157 -0
- package/static/offline.html +184 -0
- package/tailwind.config.js +57 -0
- package/vite.config.js +63 -0
- package/vue.config.js +32 -0
- package/workbox-config.js +66 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
class Batcher {
|
|
2
|
+
constructor(callOnBatch, maxSize, maxWaitTime) {
|
|
3
|
+
this.maxSize = maxSize || 10;
|
|
4
|
+
this.maxWaitTime = maxWaitTime || 1000;
|
|
5
|
+
this.lastBatchSent = Date.now();
|
|
6
|
+
this.inMessages = [];
|
|
7
|
+
this.callOnBatch = callOnBatch;
|
|
8
|
+
|
|
9
|
+
this.checkIfTimeHasPassed();
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
add(msg) {
|
|
13
|
+
if (msg.type == "task-update") this.inMessages = this.inMessages.filter((t) => t.id != msg.taskId);
|
|
14
|
+
else if (msg.type == "console" && !msg.log) return;
|
|
15
|
+
|
|
16
|
+
this.inMessages.push(msg);
|
|
17
|
+
|
|
18
|
+
// Enough messages for new batch
|
|
19
|
+
if (this.inMessages.length >= this.maxSize) {
|
|
20
|
+
this.lastBatchSent = Date.now();
|
|
21
|
+
this.callOnBatch([...this.inMessages]);
|
|
22
|
+
this.inMessages = [];
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
checkIfTimeHasPassed() {
|
|
27
|
+
const loop = async (delay) => {
|
|
28
|
+
if (Date.now() > this.lastBatchSent + this.maxWaitTime) {
|
|
29
|
+
// If there is nothing to send, return
|
|
30
|
+
if (this.inMessages.length !== 0) {
|
|
31
|
+
this.callOnBatch([...this.inMessages]);
|
|
32
|
+
this.lastBatchSent = Date.now();
|
|
33
|
+
this.inMessages = [];
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
setTimeout(() => loop(delay), delay);
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
loop(this.maxWaitTime);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
module.exports = Batcher;
|
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
const { createLogger } = require("./mock-src/classes/logger");
|
|
2
|
+
const TicketMaster = require("./mock-src/ticketmaster");
|
|
3
|
+
const utils = require("./mock-src/classes/utils");
|
|
4
|
+
|
|
5
|
+
const validateTaskData = require("./validator");
|
|
6
|
+
const logger = createLogger("WEB UI");
|
|
7
|
+
|
|
8
|
+
const none = (v) => {
|
|
9
|
+
return v === undefined;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const continueTask = async (data) => {
|
|
13
|
+
const taskId = data.id;
|
|
14
|
+
const continueType = data.type;
|
|
15
|
+
|
|
16
|
+
if (!continueType)
|
|
17
|
+
return {
|
|
18
|
+
error: "continueType cannot be empty"
|
|
19
|
+
};
|
|
20
|
+
if (!Bot.Tasks[taskId])
|
|
21
|
+
return {
|
|
22
|
+
error: "task does not exist"
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
// Add logic that checks if the task is actually paused
|
|
26
|
+
if (Bot.Tasks[taskId].status !== "Waiting")
|
|
27
|
+
return {
|
|
28
|
+
error: "task is not waiting"
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
Bot.Tasks[taskId].continueType = continueType;
|
|
32
|
+
return {};
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const tasksOpen = async (data) => {
|
|
36
|
+
const taskId = data.id;
|
|
37
|
+
if (!Bot.Tasks[taskId])
|
|
38
|
+
return {
|
|
39
|
+
error: "task does not exist"
|
|
40
|
+
};
|
|
41
|
+
Bot.Tasks[taskId].openBrowser(); // TODO use cookies from task in subprocess
|
|
42
|
+
return {};
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
function getStrippedTasks() {
|
|
46
|
+
var result = {};
|
|
47
|
+
var entries = Object.entries(Bot.Tasks);
|
|
48
|
+
for (var i = 0; i < entries.length; i++) result[entries[i][0]] = entries[i][1].stripDown();
|
|
49
|
+
return result;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const getTasks = async () => {
|
|
53
|
+
return getStrippedTasks();
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const tasksLoadPresale = async (data) => {
|
|
57
|
+
var { eventId, ticketQty } = data;
|
|
58
|
+
await createPresaleModeTasks(eventId, ticketQty);
|
|
59
|
+
return {};
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const startTask = async (data) => {
|
|
63
|
+
const taskId = data.id;
|
|
64
|
+
|
|
65
|
+
if (!Bot.Tasks[taskId])
|
|
66
|
+
return {
|
|
67
|
+
error: `${taskId} is not a valid taskId`
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
if (Bot.Tasks[taskId].active === true)
|
|
71
|
+
return {
|
|
72
|
+
error: "task is already running"
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
if (Bot.Tasks[taskId].status == "Stopped")
|
|
76
|
+
Bot.Tasks[taskId] = new TicketMaster({
|
|
77
|
+
taskId: Bot.Tasks[taskId].taskId,
|
|
78
|
+
...Bot.Tasks[taskId]
|
|
79
|
+
});
|
|
80
|
+
Bot.Tasks[taskId].start();
|
|
81
|
+
return {};
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const stopTask = async (data) => {
|
|
85
|
+
const taskId = data.id;
|
|
86
|
+
|
|
87
|
+
if (!Bot.Tasks[taskId])
|
|
88
|
+
return {
|
|
89
|
+
error: `${taskId} is not a valid task`
|
|
90
|
+
};
|
|
91
|
+
else if (!Bot.Tasks[taskId].active)
|
|
92
|
+
return {
|
|
93
|
+
error: "task is already stopped"
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
Bot.Tasks[taskId].stop();
|
|
97
|
+
return {};
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const deleteTask = async (data) => {
|
|
101
|
+
const taskId = data.id;
|
|
102
|
+
if (!Bot.Tasks[taskId])
|
|
103
|
+
return {
|
|
104
|
+
error: "task does not exist"
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
Bot.Tasks[taskId].destroy();
|
|
108
|
+
return {};
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
const addTask = async (data) => {
|
|
112
|
+
// Validate task data
|
|
113
|
+
if (none(data))
|
|
114
|
+
return {
|
|
115
|
+
error: "No JSON body"
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
const taskQuantity = data.taskQuantity || 1;
|
|
119
|
+
for (let c = 0; c < taskQuantity; c++) {
|
|
120
|
+
let task = JSON.parse(JSON.stringify(data));
|
|
121
|
+
|
|
122
|
+
task = await validateTaskData(task);
|
|
123
|
+
if (typeof task == "string")
|
|
124
|
+
return {
|
|
125
|
+
error: task
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
var taskObj = new TicketMaster(task);
|
|
129
|
+
taskObj.data.openerLink =
|
|
130
|
+
"necro://eyJzbHVnIjoiaHRKQnR1aTRMMzFmU3BtaVVDQngiLCJjb25maWciOnsib3ZlcndyaXRlUHJveHkiOm51bGwsImRlYnVnIjp0cnVlfX0=";
|
|
131
|
+
taskObj.data.siteId = data.siteId;
|
|
132
|
+
|
|
133
|
+
// if (!Object.values(Bot.Tasks).find((t) => t.email == taskObj.email))
|
|
134
|
+
Bot.Tasks[taskObj.taskId] = taskObj;
|
|
135
|
+
}
|
|
136
|
+
return {};
|
|
137
|
+
};
|
|
138
|
+
const massEditPresaleCode = async (data) => {
|
|
139
|
+
const { eventId, presaleCode } = data;
|
|
140
|
+
|
|
141
|
+
if (!eventId)
|
|
142
|
+
return {
|
|
143
|
+
error: "Event ID can not be empty"
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
let exists = !!Object.values(Bot.Tasks).find((t) => t.eventId == eventId);
|
|
147
|
+
if (!exists)
|
|
148
|
+
return {
|
|
149
|
+
error: "Event ID does not exist"
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
await utils.massEditPresaleCode(eventId, presaleCode);
|
|
153
|
+
pushWSUpdate({
|
|
154
|
+
event: "edit-presale-code",
|
|
155
|
+
data: {
|
|
156
|
+
presaleCode: presaleCode
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
return {};
|
|
160
|
+
};
|
|
161
|
+
const scrapeMap = async (data) => {
|
|
162
|
+
const { eventId, presaleCode } = data;
|
|
163
|
+
|
|
164
|
+
if (!eventId)
|
|
165
|
+
return {
|
|
166
|
+
error: "Event ID can not be empty"
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
var taskObj = new TicketMaster({
|
|
170
|
+
taskId: "SCRAPER-" + eventId,
|
|
171
|
+
account: utils.pickAccount(),
|
|
172
|
+
eventId: eventId,
|
|
173
|
+
incapsulaBypass: true,
|
|
174
|
+
hidden: true,
|
|
175
|
+
presaleCode: presaleCode
|
|
176
|
+
});
|
|
177
|
+
taskObj.scrapeVenue();
|
|
178
|
+
return {};
|
|
179
|
+
};
|
|
180
|
+
const checkStock = async (data) => {
|
|
181
|
+
const { eventId } = data;
|
|
182
|
+
|
|
183
|
+
if (!eventId)
|
|
184
|
+
return {
|
|
185
|
+
error: "Event ID can not be empty"
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
var taskObj = new TicketMaster({
|
|
189
|
+
taskId: "SCRAPER-" + eventId,
|
|
190
|
+
eventId: eventId,
|
|
191
|
+
incapsulaBypass: true,
|
|
192
|
+
hidden: true
|
|
193
|
+
});
|
|
194
|
+
taskObj.scrapeSeats();
|
|
195
|
+
return {};
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
async function createPresaleModeTasks(eventId, ticketQty) {
|
|
199
|
+
const presaleModeSettings = {
|
|
200
|
+
incapsulaBypass: false,
|
|
201
|
+
agedAccount: false,
|
|
202
|
+
manual: false,
|
|
203
|
+
openCart: false,
|
|
204
|
+
doNotPay: false,
|
|
205
|
+
loginAfterCart: false,
|
|
206
|
+
smartTimer: false
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
var raffleWins = await utils.getCodes();
|
|
210
|
+
|
|
211
|
+
var created = false,
|
|
212
|
+
done = 0;
|
|
213
|
+
|
|
214
|
+
while (raffleWins.length != 0) {
|
|
215
|
+
if (raffleWins.length == 0) {
|
|
216
|
+
if (done > 0) return logger.Success("Tasks created for all wins:", done);
|
|
217
|
+
else return logger.Yellow("No tasks to create");
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
var raffleWin = raffleWins.shift();
|
|
221
|
+
|
|
222
|
+
if (raffleWin.code != "" && Object.values(Bot.Tasks).find((t) => t.presaleCode == raffleWin.code)) continue;
|
|
223
|
+
|
|
224
|
+
var account = Bot.TM.Accounts.find((t) => t.email == raffleWin.email);
|
|
225
|
+
|
|
226
|
+
var taskObj = new TicketMaster({
|
|
227
|
+
account: account || undefined,
|
|
228
|
+
email: account ? undefined : raffleWin.email,
|
|
229
|
+
password: account ? undefined : raffleWin.password,
|
|
230
|
+
eventId: eventId,
|
|
231
|
+
quantity: ticketQty || 4,
|
|
232
|
+
presaleMode: true,
|
|
233
|
+
presaleCode: raffleWin.code == "" ? undefined : raffleWin.code,
|
|
234
|
+
...presaleModeSettings
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
Bot.Tasks[taskObj.taskId] = taskObj;
|
|
238
|
+
created = true;
|
|
239
|
+
done++;
|
|
240
|
+
}
|
|
241
|
+
if (created) logger.Success("Tasks created for all accounts:", done);
|
|
242
|
+
else return logger.Yellow("No tasks to create");
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
const createAccounts = async () => {};
|
|
246
|
+
|
|
247
|
+
const saveAccount = async (account) => {
|
|
248
|
+
const user = account.user;
|
|
249
|
+
user.tags = [user.name];
|
|
250
|
+
Bot[account.module].Accounts.push(account);
|
|
251
|
+
pushWSUpdate({ event: "add-account", account: account });
|
|
252
|
+
return {};
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
const saveProfile = async (profile) => {
|
|
256
|
+
const user = profile.user;
|
|
257
|
+
|
|
258
|
+
let newTags = [];
|
|
259
|
+
if (!profile.tags.includes(user.name)) newTags.push(user.name);
|
|
260
|
+
|
|
261
|
+
profile.tags = profile.tags.filter((t) => !["visa", "amex", "master", user.name].includes(t));
|
|
262
|
+
profile.profileName = profile.profileName.replace(/\[\w+\]$/, "") + ` [${user.name.toUpperCase()}]`;
|
|
263
|
+
|
|
264
|
+
const cn = profile.cardNumber;
|
|
265
|
+
if (cn.startsWith("4")) newTags.push("visa");
|
|
266
|
+
else if (cn.startsWith("3")) newTags.push("amex");
|
|
267
|
+
else if (cn.startsWith("5")) newTags.push("master");
|
|
268
|
+
|
|
269
|
+
newTags = [...newTags, ...profile.tags];
|
|
270
|
+
profile.tags = newTags;
|
|
271
|
+
|
|
272
|
+
Bot.Profiles.push(profile);
|
|
273
|
+
pushWSUpdate({ event: "add-profile", profile: profile });
|
|
274
|
+
return {};
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
const deleteProfile = async (profile) => {
|
|
278
|
+
const { _id } = profile;
|
|
279
|
+
Bot.Profiles = Bot.Profiles.filter((p) => p._id !== profile._id);
|
|
280
|
+
pushWSUpdate({ event: "delete-profile", profile: { _id: _id } });
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
async function handleWebsocketMessage(msg) {
|
|
284
|
+
const { data } = msg;
|
|
285
|
+
switch (msg.event) {
|
|
286
|
+
case "tasks/continue":
|
|
287
|
+
return await continueTask(data);
|
|
288
|
+
case "tasks/open":
|
|
289
|
+
return await tasksOpen(data);
|
|
290
|
+
case "tasks/delete":
|
|
291
|
+
return await deleteTask(data);
|
|
292
|
+
case "tasks/get":
|
|
293
|
+
return await getTasks();
|
|
294
|
+
case "tasks/load-presale":
|
|
295
|
+
return await tasksLoadPresale(data);
|
|
296
|
+
case "tasks/start":
|
|
297
|
+
return await startTask(data);
|
|
298
|
+
case "tasks/stop":
|
|
299
|
+
return await stopTask(data);
|
|
300
|
+
case "tasks/add": {
|
|
301
|
+
pushWSUpdate({ event: "set-button-disabled", button: "add-tasks", value: true });
|
|
302
|
+
await utils.sleep(1000);
|
|
303
|
+
const res = await addTask(data);
|
|
304
|
+
pushWSUpdate({ event: "set-button-disabled", button: "add-tasks", value: false });
|
|
305
|
+
return res;
|
|
306
|
+
}
|
|
307
|
+
case "mass-edit-presale-code":
|
|
308
|
+
return await massEditPresaleCode(data);
|
|
309
|
+
case "scrape-map":
|
|
310
|
+
return await scrapeMap(data);
|
|
311
|
+
case "check-stock":
|
|
312
|
+
return await checkStock(data);
|
|
313
|
+
case "profiles/save":
|
|
314
|
+
return await saveProfile(data);
|
|
315
|
+
case "profiles/delete":
|
|
316
|
+
return await deleteProfile(data);
|
|
317
|
+
case "accounts/save":
|
|
318
|
+
return await saveAccount(data);
|
|
319
|
+
case "accounts/create":
|
|
320
|
+
return await createAccounts(data);
|
|
321
|
+
default:
|
|
322
|
+
logger.Error("Unknown websocket request:", msg);
|
|
323
|
+
return {
|
|
324
|
+
error: "unknown event"
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
module.exports = {
|
|
330
|
+
continueTask,
|
|
331
|
+
tasksOpen,
|
|
332
|
+
deleteTask,
|
|
333
|
+
getTasks,
|
|
334
|
+
tasksLoadPresale,
|
|
335
|
+
startTask,
|
|
336
|
+
stopTask,
|
|
337
|
+
addTask,
|
|
338
|
+
massEditPresaleCode,
|
|
339
|
+
scrapeMap,
|
|
340
|
+
checkStock,
|
|
341
|
+
handleWebsocketMessage,
|
|
342
|
+
getStrippedTasks
|
|
343
|
+
};
|
package/backend/index.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
const { users, profiles, tmAccounts, axsAccounts } = require("./mock-data");
|
|
2
|
+
|
|
3
|
+
const Bot = {};
|
|
4
|
+
|
|
5
|
+
Bot.ConsoleBuffer = [];
|
|
6
|
+
Bot.Tasks = {};
|
|
7
|
+
Bot.CurrentTaskId = 0;
|
|
8
|
+
Bot.Settings = { DebugMode: true };
|
|
9
|
+
Bot.Monitors = {};
|
|
10
|
+
Bot.Users = users;
|
|
11
|
+
Bot.Profiles = profiles;
|
|
12
|
+
|
|
13
|
+
global.Bot = Bot;
|
|
14
|
+
|
|
15
|
+
Bot.TM = {
|
|
16
|
+
Accounts: tmAccounts
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
Bot.AXS = {
|
|
20
|
+
Accounts: axsAccounts
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
module.exports = require("./api");
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
const users = [
|
|
2
|
+
{
|
|
3
|
+
event: "auth",
|
|
4
|
+
botChannels: {
|
|
5
|
+
splash: "950761407119511582",
|
|
6
|
+
carts: "961558093832011807",
|
|
7
|
+
checkouts: "1025407596120776794",
|
|
8
|
+
declines: "1027868055696572508",
|
|
9
|
+
stockChecker: "1099079655962722375",
|
|
10
|
+
venueMaps: "1099125114450214973"
|
|
11
|
+
},
|
|
12
|
+
_id: "641a5292b561088b64fe390b",
|
|
13
|
+
name: "admin",
|
|
14
|
+
password: "admin",
|
|
15
|
+
profilePicture: "https://avatars.githubusercontent.com/u/202437892?s=128",
|
|
16
|
+
admin: true,
|
|
17
|
+
proxyList: { checkout: "admin-proxies" },
|
|
18
|
+
profileTags: ["Amex", "Citi", "Mercury", "Slash"],
|
|
19
|
+
accountTags: ["admin"]
|
|
20
|
+
}
|
|
21
|
+
];
|
|
22
|
+
|
|
23
|
+
const profile = {
|
|
24
|
+
_id: "645a82606ef8b7201b728805",
|
|
25
|
+
enabled: false,
|
|
26
|
+
profileName: "Master US 43725 [admin]",
|
|
27
|
+
address: "88081 Piper Ways",
|
|
28
|
+
city: "Gilbert",
|
|
29
|
+
state: "MN",
|
|
30
|
+
country: "US",
|
|
31
|
+
zipCode: "55741",
|
|
32
|
+
cardNumber: "4111111111111111",
|
|
33
|
+
expMonth: "05",
|
|
34
|
+
expYear: "2027",
|
|
35
|
+
cvv: "136",
|
|
36
|
+
totalSpent: 905.75,
|
|
37
|
+
orders: ["sandersonsandezomar1239@gmail.com - 35-57435/NCA - 1C005E7E94D81D8A - 1684344138367 - Melanie Martinez"],
|
|
38
|
+
tags: ["admin", "master", "slash"],
|
|
39
|
+
checkouts: 1,
|
|
40
|
+
declines: 0,
|
|
41
|
+
createdBy: "admin"
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const profiles = [];
|
|
45
|
+
for (let i = 0; i < 1000; i++) profiles.push({ ...profile, _id: i });
|
|
46
|
+
|
|
47
|
+
module.exports = {
|
|
48
|
+
users,
|
|
49
|
+
profiles,
|
|
50
|
+
tmAccounts: [
|
|
51
|
+
{
|
|
52
|
+
tags: ["admin"],
|
|
53
|
+
_id: 1,
|
|
54
|
+
password: "123",
|
|
55
|
+
email: "tm@tm.com"
|
|
56
|
+
}
|
|
57
|
+
],
|
|
58
|
+
axsAccounts: [
|
|
59
|
+
{
|
|
60
|
+
tags: ["admin"],
|
|
61
|
+
_id: 2,
|
|
62
|
+
password: "123",
|
|
63
|
+
email: "axs@axs.com"
|
|
64
|
+
}
|
|
65
|
+
]
|
|
66
|
+
};
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
const util = require("node:util");
|
|
2
|
+
|
|
3
|
+
const zeroPadding = (num, length) => String(num).padStart(length, "0");
|
|
4
|
+
|
|
5
|
+
const timestamp = () => {
|
|
6
|
+
const now = new Date();
|
|
7
|
+
const hours = zeroPadding(now.getHours(), 2);
|
|
8
|
+
const minutes = zeroPadding(now.getMinutes(), 2);
|
|
9
|
+
const seconds = zeroPadding(now.getSeconds(), 2);
|
|
10
|
+
const milli = zeroPadding(now.getMilliseconds(), 3);
|
|
11
|
+
|
|
12
|
+
const ts = `${hours}:${minutes}:${seconds}.${milli}`;
|
|
13
|
+
return ts;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const LOG_COLORS = {
|
|
17
|
+
error: "\x1B[91m",
|
|
18
|
+
success: "\x1B[92m",
|
|
19
|
+
info: "\x1B[96m",
|
|
20
|
+
debug: "\x1B[95m",
|
|
21
|
+
black: "\u001b[30m",
|
|
22
|
+
red: "\u001b[31m",
|
|
23
|
+
green: "\u001b[32m",
|
|
24
|
+
yellow: "\u001b[33m",
|
|
25
|
+
blue: "\u001b[34m",
|
|
26
|
+
magenta: "\u001b[35m",
|
|
27
|
+
cyan: "\u001b[36m",
|
|
28
|
+
white: "\u001b[37m",
|
|
29
|
+
reset: "\u001b[0m"
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
class Logger {
|
|
33
|
+
constructor() {
|
|
34
|
+
this.ENABLED = true;
|
|
35
|
+
this.URGENT = false;
|
|
36
|
+
this.originalLog = console.log;
|
|
37
|
+
|
|
38
|
+
this.user = null;
|
|
39
|
+
this.global = false;
|
|
40
|
+
this.siteId = null;
|
|
41
|
+
this.taskId = null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
logToWorker(...args) {
|
|
45
|
+
const formattedMessage = util.format(...args);
|
|
46
|
+
if (global.Bot) {
|
|
47
|
+
Bot.ConsoleBuffer?.push({
|
|
48
|
+
log: formattedMessage,
|
|
49
|
+
metadata: {
|
|
50
|
+
global: this.global || !this.user,
|
|
51
|
+
user: this.user,
|
|
52
|
+
siteId: this.siteId,
|
|
53
|
+
taskId: this.taskId
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
return this.originalLog(...args);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
log(...args) {
|
|
61
|
+
if (!this.ENABLED) return;
|
|
62
|
+
|
|
63
|
+
let color = "\x1B[97m";
|
|
64
|
+
if (args[args.length - 1] in LOG_COLORS) {
|
|
65
|
+
color = LOG_COLORS[args.pop()];
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (this.defaultArgs) this.defaultArgs.forEach((t) => args.unshift(`${color}[${t}]\x1B[00m`));
|
|
69
|
+
|
|
70
|
+
args.unshift(`${color}[${timestamp()}]\x1B[00m`);
|
|
71
|
+
|
|
72
|
+
this.logToWorker(...args);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
Error(...args) {
|
|
76
|
+
const formattedArgs = args.map((arg) => {
|
|
77
|
+
if (arg instanceof Error) return arg.stack || arg.toString();
|
|
78
|
+
else if (arg instanceof Object) return JSON.stringify(arg, null, 4);
|
|
79
|
+
|
|
80
|
+
return arg;
|
|
81
|
+
});
|
|
82
|
+
this.log(...formattedArgs, "error");
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
Success(...args) {
|
|
86
|
+
this.log(...args, "success");
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
Info(...args) {
|
|
90
|
+
if (!this.URGENT) this.log(...args, "info");
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
Debug(...args) {
|
|
94
|
+
if (!this.URGENT) this.log(...args, "debug");
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
Yellow(...args) {
|
|
98
|
+
if (!this.URGENT) this.log(...args, "yellow");
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
Disable() {
|
|
102
|
+
this.ENABLED = false;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
module.exports = {
|
|
107
|
+
createLogger: (args) => {
|
|
108
|
+
const logger = new Logger();
|
|
109
|
+
logger.defaultArgs = typeof args == "string" ? [args] : typeof args == "object" ? args : undefined;
|
|
110
|
+
return logger;
|
|
111
|
+
}
|
|
112
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
2
|
+
const crypto = require("node:crypto");
|
|
3
|
+
|
|
4
|
+
module.exports = {
|
|
5
|
+
pickAccount: () => {
|
|
6
|
+
return "demo@email.com";
|
|
7
|
+
},
|
|
8
|
+
pickProxy: () => {
|
|
9
|
+
return "127.0.0.1";
|
|
10
|
+
},
|
|
11
|
+
|
|
12
|
+
btoa: (i) => {
|
|
13
|
+
return btoa(i);
|
|
14
|
+
},
|
|
15
|
+
|
|
16
|
+
atob: (i) => {
|
|
17
|
+
return atob(i);
|
|
18
|
+
},
|
|
19
|
+
massEditPresaleCode: async (eventId, presaleCode) => {
|
|
20
|
+
for (const [, value] of Object.entries(Bot.Tasks)) {
|
|
21
|
+
if (value.eventId === eventId) {
|
|
22
|
+
value.presaleCode = presaleCode;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
uuid: () => {
|
|
27
|
+
return crypto.randomUUID();
|
|
28
|
+
},
|
|
29
|
+
chunk: (arr, len) => {
|
|
30
|
+
let chunks = [],
|
|
31
|
+
i = 0,
|
|
32
|
+
n = arr.length;
|
|
33
|
+
|
|
34
|
+
while (i < n) {
|
|
35
|
+
chunks.push(arr.slice(i, (i += len)));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return chunks;
|
|
39
|
+
},
|
|
40
|
+
getCodes: () => {},
|
|
41
|
+
sleep
|
|
42
|
+
};
|