This commit is contained in:
disclearing 2022-09-15 03:43:05 +01:00
commit ebb8265533
53 changed files with 9641 additions and 0 deletions

110
uLicense-1.2.6/README.md Normal file
View File

@ -0,0 +1,110 @@
# °º¤ø,¸¸,ø¤º°`°º¤ø,¸,ø¤°º¤ø,¸¸,ø¤º°`°º¤ø,¸°º¤ø,¸¸,ø¤º°`°º¤ø,¸,ø¤°º¤ø,¸¸,ø¤º°`°º¤ø,¸
Thanks for purchasing uLicense! <3
Startup guide:
I assume you have a solid understanding of linux & you know how to setup
a VPS or any other server to host on. You should have tmux or screen
so you have have one "window" for dashboard and one for Discord.
example: tmux a -t bot, tmux a -t dashboard. You can also run both,
Discord bot and Dashboard from one instance by installing required
node modules in main folder "npm install" & "npm start".
If you need any help with setup, please join our Discord-server
for support & questions: https://discord.gg/3bPF2GkeN5
There is channel for #support-tickets and you can also get your customer role in Discord 😊
# BEFORE YOU DO ANYTHING
1. Make sure you have Node installed in your system. You can check your node version using
"node -v" and node package manager using npm -v. Node version should be 12.0.0 or higher!
When you have Nodejs in your system you should update NPM(node package manager) to latest.
=> npm install -g npm@latest
Node tutorial: https://www.digitalocean.com/community/tutorials/how-to-install-node-js-on-debian-10
=> If you have a Windows machine, download Node.js here:
Windows: https://nodejs.org/en/download/
2. Setup MongoDB in your system.
Mongodb tutorial: https://docs.mongodb.com/manual/tutorial/install-mongodb-on-debian/
=> If you setup uLicense on a Windows machine, download mongodb community server!
Windows: https://www.mongodb.com/try/download/community
3. TMUX/Screen is preferred for linux. You can have 2 instances (one for bot, and one for dashboard)
or you can run both from one instance by downloading main folder Node modules and
using start script from there => npm install & npm start
4. Remember that you can get support from our Discord. Link is on top of this readme file.
There are no stupid questions. You can ask literally anything!
# DASHBOARD GUIDE
1. Make sure you have Node installed in your system. Check: https://nodejs.org/en/
=> type "node -v" and "npm -v" in your terminal. Both should give your versions.
2. Go inside dashboard and type "npm i" into your terminal.
3. Open .env- file inside dashboard and fill in your information.
=> Port should be 80 unless you have a solid reason for using other port
4. Make sure you have MongoDB installed and your connection string inside .env is valid!
=> Don't leave any fields empty inside .env
=> If you have your database in the same server, connection string should be this:
=> mongodb://localhost:27017/YOUR_DATABASE_NAME
You can replace YOUR_DATABASE_NAME with anything you want!
5. Run "npm start" in your terminal. Panel should be running after that. Default port is 80.
6. You should get API key on your first start logged to console! Save this, because you need
it later. Now if you have received dashboard message in your console, dashboard should be running
on your IP. If you have Windows machine, dashboard is located in: http://localhost/
# You should have solid firewall in your VPS/Dedicated. Cloudflare is also recommended!
# DISCORD BOT GUIDE
1. Create Discord bot application in and get your bot token: https://discord.com/developers/applications
2. Fill in your details in config.json inside discord folder
3. Run "npm i" in your terminal (inside discord folder)
4. Run "npm start" and bot should be running.
5. MAKE SURE YOU SETUP YOUR DISCORDID IN DASHBOARDS "SETTINGS" MENU.
=> DISCORD BOT WILL ONLY WORK FOR THAT ID
# USING JAVA CLASS / API
1. You can access uLicense API by using 'POST' request. This is pre implemented in Java class.
2. Default route for api is: http://YOUR_DOMAIN/api/v1
=> When using the API you need to have your API key in the "Authorization" header.
Different API responses [Note that logging these in clientside is not recommended]:
FAILED_AUTHENTICATION // Wrong API key or wrong licensekey
EXPIRED_LICENSE // Expired licensekey
MAXIMUM_IPS // Maximum IPs reached
INVALID_PLUGIN // Wrong plugin name
SUCCESSFUL_AUTHENTICATION // Successful authentication
BLACKLISTED_AUTH // Blacklisted IP or HWID
3. You can get your API key from MongoDB. You can use something like MongoDB compass for easy access.
=> API key is randomly generated in first startup and stored in database.
4. You need to include these values in your post request by default:
{
"hwid": "HardwareID",
"license": "Licensekey",
"plugin": "Plugin name",
"version": "1.0.0",
}
5. Node.js / javascript / LUA [FiveM] documentation can be found in our Discord-server! Join there!
# °º¤ø,¸¸,ø¤º°`°º¤ø,¸,ø¤°º¤ø,¸¸,ø¤º°`°º¤ø,¸°º¤ø,¸¸,ø¤º°`°º¤ø,¸,ø¤°º¤ø,¸¸,ø¤º°`°º¤ø,¸
%%**NONCE**%%

View File

@ -0,0 +1,356 @@
package dev.license.ulicense;
import org.bukkit.plugin.Plugin;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import javax.net.ssl.HttpsURLConnection;
import java.io.*;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.Instant;
import java.util.Base64;
import java.util.Enumeration;
import java.util.Scanner;
public class ULicense {
private Plugin plugin;
private String productKey;
private String server;
private String authorization;
private static final String UNKNOWN = "unknown";
private static String OS = System.getProperty("os.name").toLowerCase();
public ULicense(Plugin plugin, String licenseKey, String validationServer, String authorization) {
this.plugin = plugin;
this.productKey = licenseKey;
this.server = validationServer;
this.authorization = authorization;
}
public boolean verify() {
System.out.println("--------------------> Login <--------------------");
System.out.println(" |- Verifying your license...");
System.out.println(" ");
String[] respo = isValid();
System.out.println(respo[0]);
if (respo[0].equals("2")) {
System.out.println(" |- Your license is valid.");
System.out.println("-------------------------------------------------");
return true;
} else if (respo[0].equals("3")) {
System.out.println(" |- Your license is valid, but version is outdated.");
System.out.println(" ");
System.out.println(" |- Your version: " + plugin.getDescription().getVersion());
System.out.println(" |- Latest version: " + respo[1].split("#")[1]);
System.out.println("-------------------------------------------------");
return true;
} else {
System.out.println(" |- Your license is invalid.");
System.out.println(" ");
System.out.println(" |- Reason: " + respo[1]);
System.out.println("-------------------------------------------------");
return false;
}
}
private String requestServer(String productKey) throws IOException {
URL url = new URL(server);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("User-Agent", "uLicense");
con.setDoInput(true);
con.setDoOutput(true);
con.setUseCaches(false);
String hwid = getMac();
String outString = "{\"hwid\":\"password\",\"license\":\"key\",\"plugin\":\"NiceCar\",\"version\":\"dogpoop\"}";
//Align HWID again here if someone tries to spoof it
outString = outString
.replaceAll("password", getHWID())
.replaceAll("key", productKey)
.replaceAll("NiceCar", plugin.getName())
.replaceAll("dogpoop", plugin.getDescription().getVersion());
byte[] out = outString.getBytes(StandardCharsets.UTF_8);
int length = out.length;
con.setFixedLengthStreamingMode(length);
con.setRequestProperty("Authorization", this.authorization);
con.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
con.connect();
try(OutputStream os = con.getOutputStream()) {
os.write(out);
}
if(!url.getHost().equals(con.getURL().getHost())) return "successful_authentication";
try (BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()))) {
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
return response.toString();
}
}
private String requestServerHTTPS(String productKey) throws IOException {
URL url = new URL(server);
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("User-Agent", "uLicense");
con.setDoInput(true);
con.setDoOutput(true);
con.setUseCaches(false);
String hwid = getMac();
String outString = "{\"hwid\":\"password\",\"license\":\"key\",\"plugin\":\"NiceCar\",\"version\":\"dogpoop\"}";
//Align HWID again here if someone tries to spoof it
outString = outString
.replaceAll("password", getHWID())
.replaceAll("key", productKey)
.replaceAll("NiceCar", plugin.getName())
.replaceAll("dogpoop", plugin.getDescription().getVersion());
byte[] out = outString.getBytes(StandardCharsets.UTF_8);
int length = out.length;
con.setFixedLengthStreamingMode(length);
con.setRequestProperty("Authorization", this.authorization);
con.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
con.connect();
try(OutputStream os = con.getOutputStream()) {
os.write(out);
}
if(!url.getHost().equals(con.getURL().getHost())) return "successful_authentication";
try (BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()))) {
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
return response.toString();
}
}
public String[] isValid() {
try {
String response;
if(server.contains("http")) {
response = requestServer(productKey);
} else {
response = requestServerHTTPS(productKey);
}
if(!response.contains("{")) {
return new String[]{"1", "ODD_RESULT"};
}
int respLength = response.length();
String hash = null;
String version = null;
JSONParser parser = new JSONParser();
JSONObject json = (JSONObject) parser.parse(response);
String neekeri = json.get("msg").toString();
String status = json.get("status").toString();
if(status.contains("success")) {
hash = json.get("neekeri").toString();
version = json.get("version").toString();
}
if(version != null && !version.equals(plugin.getDescription().getVersion())) {
return new String[]{"3", "OUTDATED_VERSION#" + version};
}
if(hash != null && version != null) {
String[] aa = hash.split("694201337");
String hashed = aa[0];
String decoded = new String(Base64.getDecoder().decode(hashed));
if(!decoded.equals(productKey.substring(0, 2) + productKey.substring(productKey.length() - 2) + authorization.substring(0, 2))) {
return new String[]{"1", "FAILED_AUTHENTICATION"};
}
String time = String.valueOf(Instant.now().getEpochSecond());
String unix = time.substring(0, time.length() - 2);
long t = Long.parseLong(unix);
long hashT = Long.parseLong(aa[1]);
if(Math.abs(t - hashT) > 1) {
return new String[]{"1", "FAILED_AUTHENTICATION"};
}
}
int statusLength = status.length();
if(!isValidLength(statusLength)) {
return new String[]{"1", neekeri};
}
final boolean valid = status.contains("success") && response.contains("success") && String.valueOf(statusLength).equals("7");
return new String[]{valid ? "2" : "1", neekeri};
} catch (IOException | ParseException ex) {
ex.printStackTrace();
return new String[]{"1", "ERROR"};
}
}
public boolean isValidLength(int reps) {
return reps == 7;
}
//Spoofed methods to trick cracker
public boolean isValidLength22(int reps) {
return reps == 11;
}
public boolean isValidLength222(int reps) {
return reps == 44;
}
public boolean isValidLength2222(int reps) {
return reps == 48;
}
public String getMac() throws SocketException {
Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
StringBuilder sb = new StringBuilder();
while (networkInterfaces.hasMoreElements()) {
NetworkInterface ni = networkInterfaces.nextElement();
byte[] hardwareAddress = ni.getHardwareAddress();
if (hardwareAddress != null) {
for (byte address : hardwareAddress) {
sb.append(String.format("%02X", address));
}
return sb.toString();
}
}
return null;
}
public static String getHWID() {
try {
if (isWindows()) {
return getWindowsIdentifier();
} else if (isMac()) {
return getMacOsIdentifier();
} else if (isLinux()) {
return getLinuxMacAddress();
} else {
return UNKNOWN;
}
} catch (Exception e) {
return UNKNOWN;
}
}
private static boolean isWindows() {
return (OS.contains("win"));
}
private static boolean isMac() {
return (OS.contains("mac"));
}
private static boolean isLinux() {
return (OS.contains("inux"));
}
private static String getLinuxMacAddress() throws FileNotFoundException, NoSuchAlgorithmException {
File machineId = new File("/var/lib/dbus/machine-id");
if (!machineId.exists()) {
machineId = new File("/etc/machine-id");
}
if (!machineId.exists()) {
return UNKNOWN;
}
Scanner scanner = null;
try {
scanner = new Scanner(machineId);
String id = scanner.useDelimiter("\\A").next();
return hexStringify(sha256Hash(id.getBytes()));
} finally {
if (scanner != null) {
scanner.close();
}
}
}
private static String getMacOsIdentifier() throws SocketException, NoSuchAlgorithmException {
NetworkInterface networkInterface = NetworkInterface.getByName("en0");
byte[] hardwareAddress = networkInterface.getHardwareAddress();
return hexStringify(sha256Hash(hardwareAddress));
}
private static String getWindowsIdentifier() throws IOException, NoSuchAlgorithmException {
Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec(new String[]{"wmic", "csproduct", "get", "UUID"});
String result = null;
InputStream is = process.getInputStream();
Scanner sc = new Scanner(process.getInputStream());
try {
while (sc.hasNext()) {
String next = sc.next();
if (next.contains("UUID")) {
result = sc.next().trim();
break;
}
}
} finally {
is.close();
}
return result == null ? UNKNOWN : hexStringify(sha256Hash(result.getBytes()));
}
/**
* Compute the SHA-256 hash of the given byte array
*
* @param data the byte array to hash
* @return the hashed byte array
* @throws NoSuchAlgorithmException
*/
public static byte[] sha256Hash(byte[] data) throws NoSuchAlgorithmException {
MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
return messageDigest.digest(data);
}
/**
* Convert a byte array to its hex-string
*
* @param data the byte array to convert
* @return the hex-string of the byte array
*/
public static String hexStringify(byte[] data) {
StringBuilder stringBuilder = new StringBuilder();
for (byte singleByte : data) {
stringBuilder.append(Integer.toString((singleByte & 0xff) + 0x100, 16).substring(1));
}
return stringBuilder.toString();
}
}

View File

@ -0,0 +1,23 @@
# Your MongoDB url. For Discord Bot, use config.yml inside Discord folder.
MONGODB_URL = YOUR_MONGODB_URL
# Your login credentials. Fill in all the fields.
# When you start up the server for the first time,
# it will create you an account based on these values.
LOGIN_EMAIL = YOUR_LOGIN_EMAIL
LOGIN_PASSWORD = YOUR_LOGIN_PASSWORD
LOGIN_NAME = YOUR_LOGIN_NAME
# This is only needed if you want to use automatic client names based on Discord username!
BOT_TOKEN = YOUR_DISCORD_TOKEN
SERVER_PORT = YOUR_PORT
# Access_token and refresh_token needs any long random hash.
# Generate random hash using something like: https://passwordsgenerator.net/
# Use default settings, length 40+
# IT REALLY DOESNT MATTER WHAT YOU PUT HERE IF IT IS JUST RANDOM. THIS IS JUST RANDOM "SECRET HASH" FOR REFRESH_TOKEN AND ACCESS_TOKEN
# DO NOT CHANGE THESE VALUES AFTER FIRST TIME SET, SINCE THESE ARE NEEDED FOR DECRYPTION
ENCRYPT_SECRET= YOUR_ENCRYPT_SECRET
ACCESS_TOKEN_SECRET = YOUR_ACCESS_TOKEN
REFRESH_TOKEN_SECRET = YOUR_REFRESH_TOKEN

View File

@ -0,0 +1,24 @@
{
"files": {
"main.css": "/static/css/main.5564dd3d.chunk.css",
"main.js": "/static/js/main.eb34d015.chunk.js",
"main.js.map": "/static/js/main.eb34d015.chunk.js.map",
"runtime-main.js": "/static/js/runtime-main.c012fedc.js",
"runtime-main.js.map": "/static/js/runtime-main.c012fedc.js.map",
"static/css/2.fe708519.chunk.css": "/static/css/2.fe708519.chunk.css",
"static/js/2.2e9ceecd.chunk.js": "/static/js/2.2e9ceecd.chunk.js",
"static/js/2.2e9ceecd.chunk.js.map": "/static/js/2.2e9ceecd.chunk.js.map",
"index.html": "/index.html",
"static/css/2.fe708519.chunk.css.map": "/static/css/2.fe708519.chunk.css.map",
"static/css/main.5564dd3d.chunk.css.map": "/static/css/main.5564dd3d.chunk.css.map",
"static/js/2.2e9ceecd.chunk.js.LICENSE.txt": "/static/js/2.2e9ceecd.chunk.js.LICENSE.txt",
"static/media/lisenssi.d6b702d9.png": "/static/media/lisenssi.d6b702d9.png"
},
"entrypoints": [
"static/js/runtime-main.c012fedc.js",
"static/css/2.fe708519.chunk.css",
"static/js/2.2e9ceecd.chunk.js",
"static/css/main.5564dd3d.chunk.css",
"static/js/main.eb34d015.chunk.js"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

View File

@ -0,0 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="./logo.png"/><link rel="apple-touch-icon" href="/logo192.png"/><link rel="manifest" href="/manifest.json"/><link href="/static/css/2.fe708519.chunk.css" rel="stylesheet"><link href="/static/css/main.5564dd3d.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(e){function t(t){for(var n,l,i=t[0],f=t[1],a=t[2],p=0,s=[];p<i.length;p++)l=i[p],Object.prototype.hasOwnProperty.call(o,l)&&o[l]&&s.push(o[l][0]),o[l]=0;for(n in f)Object.prototype.hasOwnProperty.call(f,n)&&(e[n]=f[n]);for(c&&c(t);s.length;)s.shift()();return u.push.apply(u,a||[]),r()}function r(){for(var e,t=0;t<u.length;t++){for(var r=u[t],n=!0,i=1;i<r.length;i++){var f=r[i];0!==o[f]&&(n=!1)}n&&(u.splice(t--,1),e=l(l.s=r[0]))}return e}var n={},o={1:0},u=[];function l(t){if(n[t])return n[t].exports;var r=n[t]={i:t,l:!1,exports:{}};return e[t].call(r.exports,r,r.exports,l),r.l=!0,r.exports}l.m=e,l.c=n,l.d=function(e,t,r){l.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},l.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},l.t=function(e,t){if(1&t&&(e=l(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(l.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var n in e)l.d(r,n,function(t){return e[t]}.bind(null,n));return r},l.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return l.d(t,"a",t),t},l.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},l.p="/";var i=this.webpackJsonpclient=this.webpackJsonpclient||[],f=i.push.bind(i);i.push=t,i=i.slice();for(var a=0;a<i.length;a++)t(i[a]);var c=f;r()}([])</script><script src="/static/js/2.2e9ceecd.chunk.js"></script><script src="/static/js/main.eb34d015.chunk.js"></script></body></html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

View File

@ -0,0 +1,8 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"start_url": "./index.html",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}

View File

@ -0,0 +1,3 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:

View File

@ -0,0 +1,2 @@
.Dropdown-root{position:relative}.Dropdown-control{position:relative;overflow:hidden;background-color:#fff;border:1px solid #ccc;border-radius:2px;box-sizing:border-box;color:#333;cursor:default;outline:none;padding:8px 52px 8px 10px;transition:all .2s ease}.Dropdown-control:hover{box-shadow:0 1px 0 rgba(0,0,0,.06)}.Dropdown-arrow{border-color:#999 transparent transparent;border-style:solid;border-width:5px 5px 0;content:" ";display:block;height:0;margin-top:-ceil(2.5);position:absolute;right:10px;top:14px;width:0}.is-open .Dropdown-arrow{border-color:transparent transparent #999;border-width:0 5px 5px}.Dropdown-menu{background-color:#fff;border:1px solid #ccc;box-shadow:0 1px 0 rgba(0,0,0,.06);box-sizing:border-box;margin-top:-1px;max-height:200px;overflow-y:auto;position:absolute;top:100%;width:100%;z-index:1000;-webkit-overflow-scrolling:touch}.Dropdown-menu .Dropdown-group>.Dropdown-title{padding:8px 10px;color:#333;font-weight:700;text-transform:capitalize}.Dropdown-option{box-sizing:border-box;color:rgba(51,51,51,.8);cursor:pointer;display:block;padding:8px 10px}.Dropdown-option:last-child{border-bottom-right-radius:2px;border-bottom-left-radius:2px}.Dropdown-option.is-selected,.Dropdown-option:hover{background-color:#f2f9fc;color:#333}.Dropdown-noresults{box-sizing:border-box;color:#ccc;cursor:default;display:block;padding:8px 10px}
/*# sourceMappingURL=2.fe708519.chunk.css.map */

View File

@ -0,0 +1 @@
{"version":3,"sources":["webpack://node_modules/react-dropdown/style.css"],"names":[],"mappings":"AAAA,eACE,iBACF,CAEA,kBACE,iBAAkB,CAClB,eAAgB,CAChB,qBAAuB,CACvB,qBAAsB,CACtB,iBAAkB,CAClB,qBAAsB,CACtB,UAAW,CACX,cAAe,CACf,YAAa,CACb,yBAA0B,CAC1B,uBACF,CAEA,wBACE,kCACF,CAEA,gBAGE,yCAAuB,CAAvB,kBAAuB,CAAvB,sBAAuB,CACvB,WAAY,CACZ,aAAc,CACd,QAAS,CACT,qBAAsB,CACtB,iBAAkB,CAClB,UAAW,CACX,QAAS,CACT,OACF,CAEA,yBACE,yCAA0C,CAC1C,sBACF,CAEA,eACE,qBAAuB,CACvB,qBAAsB,CACtB,kCAAuC,CACvC,qBAAsB,CACtB,eAAgB,CAChB,gBAAiB,CACjB,eAAgB,CAChB,iBAAkB,CAClB,QAAS,CACT,UAAW,CACX,YAAa,CACb,gCACF,CAEA,+CACE,gBAAiB,CACjB,UAA0B,CAC1B,eAAiB,CACjB,yBACF,CAEA,iBACE,qBAAsB,CACtB,uBAA4B,CAC5B,cAAe,CACf,aAAc,CACd,gBACF,CAEA,4BACE,8BAA+B,CAC9B,6BACH,CAOA,oDACE,wBAAyB,CACzB,UACF,CAEA,oBACE,qBAAsB,CACtB,UAAW,CACX,cAAe,CACf,aAAc,CACd,gBACF","file":"2.fe708519.chunk.css","sourcesContent":[".Dropdown-root {\n position: relative;\n}\n\n.Dropdown-control {\n position: relative;\n overflow: hidden;\n background-color: white;\n border: 1px solid #ccc;\n border-radius: 2px;\n box-sizing: border-box;\n color: #333;\n cursor: default;\n outline: none;\n padding: 8px 52px 8px 10px;\n transition: all 200ms ease;\n}\n\n.Dropdown-control:hover {\n box-shadow: 0 1px 0 rgba(0, 0, 0, 0.06);\n}\n\n.Dropdown-arrow {\n border-color: #999 transparent transparent;\n border-style: solid;\n border-width: 5px 5px 0;\n content: ' ';\n display: block;\n height: 0;\n margin-top: -ceil(2.5);\n position: absolute;\n right: 10px;\n top: 14px;\n width: 0\n}\n\n.is-open .Dropdown-arrow {\n border-color: transparent transparent #999;\n border-width: 0 5px 5px;\n}\n\n.Dropdown-menu {\n background-color: white;\n border: 1px solid #ccc;\n box-shadow: 0 1px 0 rgba(0, 0, 0, 0.06);\n box-sizing: border-box;\n margin-top: -1px;\n max-height: 200px;\n overflow-y: auto;\n position: absolute;\n top: 100%;\n width: 100%;\n z-index: 1000;\n -webkit-overflow-scrolling: touch;\n}\n\n.Dropdown-menu .Dropdown-group > .Dropdown-title{\n padding: 8px 10px;\n color: rgba(51, 51, 51, 1);\n font-weight: bold;\n text-transform: capitalize;\n}\n\n.Dropdown-option {\n box-sizing: border-box;\n color: rgba(51, 51, 51, 0.8);\n cursor: pointer;\n display: block;\n padding: 8px 10px;\n}\n\n.Dropdown-option:last-child {\n border-bottom-right-radius: 2px;\n border-bottom-left-radius: 2px;\n}\n\n.Dropdown-option:hover {\n background-color: #f2f9fc;\n color: #333;\n}\n\n.Dropdown-option.is-selected {\n background-color: #f2f9fc;\n color: #333;\n}\n\n.Dropdown-noresults {\n box-sizing: border-box;\n color: #ccc;\n cursor: default;\n display: block;\n padding: 8px 10px;\n}\n"]}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,83 @@
/*
object-assign
(c) Sindre Sorhus
@license MIT
*/
/*!
Copyright (c) 2017 Jed Watson.
Licensed under the MIT License (MIT), see
http://jedwatson.github.io/classnames
*/
/** @license React v0.20.1
* scheduler.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/** @license React v16.13.1
* react-is.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/** @license React v17.0.1
* react-dom.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/** @license React v17.0.1
* react-jsx-runtime.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/** @license React v17.0.1
* react.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**!
* @fileOverview Kickass library to create and place poppers near their reference elements.
* @version 1.16.1
* @license
* Copyright (c) 2016 Federico Zivolo and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
//! moment.js

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,2 @@
!function(e){function t(t){for(var n,l,i=t[0],f=t[1],a=t[2],p=0,s=[];p<i.length;p++)l=i[p],Object.prototype.hasOwnProperty.call(o,l)&&o[l]&&s.push(o[l][0]),o[l]=0;for(n in f)Object.prototype.hasOwnProperty.call(f,n)&&(e[n]=f[n]);for(c&&c(t);s.length;)s.shift()();return u.push.apply(u,a||[]),r()}function r(){for(var e,t=0;t<u.length;t++){for(var r=u[t],n=!0,i=1;i<r.length;i++){var f=r[i];0!==o[f]&&(n=!1)}n&&(u.splice(t--,1),e=l(l.s=r[0]))}return e}var n={},o={1:0},u=[];function l(t){if(n[t])return n[t].exports;var r=n[t]={i:t,l:!1,exports:{}};return e[t].call(r.exports,r,r.exports,l),r.l=!0,r.exports}l.m=e,l.c=n,l.d=function(e,t,r){l.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},l.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},l.t=function(e,t){if(1&t&&(e=l(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(l.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var n in e)l.d(r,n,function(t){return e[t]}.bind(null,n));return r},l.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return l.d(t,"a",t),t},l.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},l.p="/";var i=this.webpackJsonpclient=this.webpackJsonpclient||[],f=i.push.bind(i);i.push=t,i=i.slice();for(var a=0;a<i.length;a++)t(i[a]);var c=f;r()}([]);
//# sourceMappingURL=runtime-main.c012fedc.js.map

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,21 @@
const jwt = require('jsonwebtoken');
const auth = (req, res, next) => {
try {
const token = req.header('Authorization');
if (!token)
return res.status(400).json({ msg: 'Invalid Authentication.' });
jwt.verify(token, process.env.ACCESS_TOKEN_SECRET, (err, user) => {
if (err)
return res.status(400).json({ msg: 'Invalid Authentication.' });
req.user = user;
next();
});
} catch (err) {
return res.status(500).json({ msg: err.message });
}
};
module.exports = auth;

View File

@ -0,0 +1,41 @@
const crypto = require('crypto');
const algorithm = 'aes-256-ctr';
const secretKey = process.env.ENCRYPT_SECRET;
const key = crypto
.createHash('sha256')
.update(String(secretKey))
.digest('base64')
.substr(0, 32);
const iv = crypto.randomBytes(16);
const encrypt = (text) => {
const cipher = crypto.createCipheriv(algorithm, key, iv);
const encrypted = Buffer.concat([cipher.update(text), cipher.final()]);
return {
iv: iv.toString('hex'),
content: encrypted.toString('hex'),
};
};
const decrypt = (hash) => {
const decipher = crypto.createDecipheriv(
algorithm,
key,
Buffer.from(hash.iv, 'hex')
);
const decrpyted = Buffer.concat([
decipher.update(Buffer.from(hash.content, 'hex')),
decipher.final(),
]);
return decrpyted.toString();
};
module.exports = {
encrypt,
decrypt,
};

View File

@ -0,0 +1,20 @@
const mongoose = require('mongoose');
const blacklistSchema = new mongoose.Schema(
{
blacklisted: {
type: String,
},
requests: {
type: Number,
default: 0,
},
region: {
type: String,
},
},
{
timestamps: true,
}
);
module.exports = mongoose.model('Blacklist', blacklistSchema);

View File

@ -0,0 +1,56 @@
const mongoose = require('mongoose');
const licensehistorySchema = new mongoose.Schema({
year: {
type: Number,
},
january: {
type: Number,
default: 0,
},
february: {
type: Number,
default: 0,
},
march: {
type: Number,
default: 0,
},
april: {
type: Number,
default: 0,
},
may: {
type: Number,
default: 0,
},
june: {
type: Number,
default: 0,
},
july: {
type: Number,
default: 0,
},
august: {
type: Number,
default: 0,
},
september: {
type: Number,
default: 0,
},
october: {
type: Number,
default: 0,
},
november: {
type: Number,
default: 0,
},
december: {
type: Number,
default: 0,
},
});
module.exports = mongoose.model('Licensehistory', licensehistorySchema);

View File

@ -0,0 +1,16 @@
const mongoose = require('mongoose');
const pluginsSchema = new mongoose.Schema(
{
plugin: {
type: String,
},
version: {
type: String,
},
},
{
timestamps: true,
}
);
module.exports = mongoose.model('Plugins', pluginsSchema);

View File

@ -0,0 +1,16 @@
const mongoose = require('mongoose');
const requestSchema = new mongoose.Schema({
date: {
type: String,
},
requests: {
type: Number,
default: 0,
},
rejected: {
type: Number,
default: 0,
},
});
module.exports = mongoose.model('Dailyrequests', requestSchema);

View File

@ -0,0 +1,44 @@
const mongoose = require('mongoose');
const userSchema = new mongoose.Schema(
{
name: {
type: String,
required: [true, 'Please enter your name!'],
trim: true,
},
discordwebhook: {
type: String,
},
DiscordID: {
type: String,
},
email: {
type: String,
required: [true, 'Please enter your email!'],
trim: true,
unique: true,
},
password: {
type: String,
required: [true, 'Please enter your password!'],
},
role: {
type: Number,
default: 0,
},
lastlogin: {
type: String,
},
APIkey: {
type: String,
},
licenses: {
type: Array,
},
},
{
timestamps: true,
}
);
module.exports = mongoose.model('Users', userSchema);

2303
uLicense-1.2.6/dashboard/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,29 @@
{
"name": "backend",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"start": "nodemon server.js"
},
"author": "kassq",
"license": "ISC",
"dependencies": {
"axios": "^0.21.1",
"bcrypt": "^5.0.0",
"cookie-parser": "^1.4.5",
"cors": "^2.8.5",
"discord-webhook-node": "^1.1.8",
"dotenv": "^8.2.0",
"express": "^4.17.1",
"express-rate-limit": "^5.2.5",
"helmet": "^4.4.1",
"is-ip": "^3.1.0",
"jsonwebtoken": "^8.5.1",
"moment": "^2.29.1",
"mongoose": "^5.11.8",
"node-fetch": "^2.6.1",
"nodemon": "^2.0.6",
"request": "^2.88.2"
}
}

View File

@ -0,0 +1,493 @@
const router = require('express').Router();
const Users = require('../models/userModel');
const Blacklist = require('../models/blacklistModel');
const Dailyrequests = require('../models/requestModel');
const Plugins = require('../models/pluginModel.js');
const { Webhook, MessageBuilder } = require('discord-webhook-node');
const moment = require('moment');
const rateLimit = require('express-rate-limit');
const { decrypt } = require('../middleware/crypto');
const apiLimit = rateLimit({
windowMs: 15 * 60 * 1000,
max: 30,
});
router.post('/v1', apiLimit, async (req, res) => {
try {
let now = new Date();
const dateExists = await Dailyrequests.findOne({
date: now.toLocaleDateString(),
});
const AddOneToRejected = async () => {
try {
let now = new Date();
if (!dateExists) {
let date = now.toLocaleDateString();
let requests = 0;
let rejected = 1;
const newDate = new Dailyrequests({
date,
requests,
rejected,
});
await newDate.save();
} else {
await Dailyrequests.findOneAndUpdate(
{ date: now.toLocaleDateString() },
{ $inc: { rejected: 1 } }
);
}
} catch (error) {
return console.log(error);
}
};
if (!req.headers.authorization) {
return res.json({
msg: 'FAILED_AUTHENTICATION',
status: 'failed',
});
} else {
if (
!req.body.hwid ||
!req.body.license ||
!req.body.plugin ||
!req.body.version
) {
return res.json({
msg: 'FAILED_AUTHENTICATION',
status: 'failed',
});
}
let ip = req.headers['x-forwarded-for'] || req.socket.remoteAddress;
if (ip.substr(0, 7) == '::ffff:') {
ip = ip.substr(7);
}
const ApiCheck = await Users.findOne({
APIkey: req.headers.authorization,
});
if (
!ApiCheck ||
req.headers.authorization.toLowerCase() === 'none'
) {
return res.json({
msg: 'FAILED_AUTHENTICATION',
status: 'failed',
});
}
let blacklistedArray = [req.body.hwid, ip];
const BlacklistCheck = await Blacklist.findOne({
blacklisted: blacklistedArray,
});
if (BlacklistCheck) {
await Blacklist.findOneAndUpdate(
{ blacklisted: blacklistedArray },
{ $inc: { requests: 1 } }
);
if (ApiCheck.discordwebhook) {
const userWebhookURL = new Webhook(
`${ApiCheck.discordwebhook}`
);
const blacklistEmbed = new MessageBuilder()
.setTitle(`Blacklisted IP/HWID`)
.setTimestamp()
.setColor('#ff0000')
.addField('License', `${req.body.license}`)
.addField('IP-Address', `${ip}`)
.addField('HWID', `${req.body.hwid}`)
.addField('Version', `${req.body.version}`)
.setFooter(
`uLicense | Made by @kassq`,
'https://cdn.discordapp.com/attachments/729088611986702508/795962314015899668/lisenssi.png'
);
userWebhookURL.send(blacklistEmbed);
return res.json({
msg: 'BLACKLISTED_AUTH',
status: 'failed',
});
} else {
return res.json({
msg: 'BLACKLISTED_AUTH',
status: 'failed',
});
}
}
let Licensebody;
let Clientname;
for (let f = 0; f < ApiCheck.licenses.length; f++) {
let licenseToSearch = ApiCheck.licenses[f].licensekey;
let key = decrypt(licenseToSearch);
if (key === req.body.license) {
Licensebody = licenseToSearch;
Clientname = ApiCheck.licenses[f].clientname;
break;
}
}
if (!Licensebody || Licensebody === undefined) {
if (ApiCheck) {
if (ApiCheck.discordwebhook) {
const userWebhookURL = new Webhook(
`${ApiCheck.discordwebhook}`
);
const successembed = new MessageBuilder()
.setTitle(`Failed authentication`)
.setTimestamp()
.setColor('#F8C300')
.addField('License', `${req.body.license}`)
.addField('IP-Address', `${ip}`)
.addField('HWID', `${req.body.hwid}`)
.addField('Version', `${req.body.version}`)
.setFooter(
`uLicense | Made by @kassq`,
'https://cdn.discordapp.com/attachments/729088611986702508/795962314015899668/lisenssi.png'
);
userWebhookURL.send(successembed);
await console.log(
`\u001b[36m=> [${new Date().toLocaleTimeString()}] Someone tried to start server, but failed authentication!\n=> [DETAILS ] IP: ${ip} | HWID: ${
req.body.hwid
} | License: ${req.body.license}`
);
AddOneToRejected();
return res.json({
msg: 'FAILED_AUTHENTICATION',
status: 'failed',
});
} else {
AddOneToRejected();
return res.json({
msg: 'FAILED_AUTHENTICATION',
status: 'failed',
});
}
} else {
return res.json({ msg: 'Error occurred!' });
}
} else if (Licensebody) {
const IPcap = await Users.findOne({
APIkey: req.headers.authorization,
'licenses.licensekey': Licensebody,
});
let licenseArray = IPcap.licenses;
const result = licenseArray.find(
(element) =>
element.licensekey.iv === Licensebody.iv &&
element.licensekey.content === Licensebody.content
);
if (result.expires !== 'Never') {
const today = moment();
if (moment(result.expires).isBefore(today) === true) {
if (IPcap.discordwebhook) {
const userWebhookURL = new Webhook(
`${IPcap.discordwebhook}`
);
const successembed = new MessageBuilder()
.setTitle(`Expired license key`)
.setTimestamp()
.setColor('#BC0057')
.addField('License', `${req.body.license}`)
.addField('Client:', `${Clientname}`)
.addField(
'DiscordID:',
`${result.discordID || 'None'}`
)
.addField('Plugin', `${req.body.plugin}`)
.addField('IP-Address', `${ip}`)
.addField('HWID', `${req.body.hwid}`)
.addField('Version', `${req.body.version}`)
.addField(
'Expired',
`${today.diff(
result.expires,
'days'
)} days ago`
)
.setFooter(
`uLicense | Made by @kassq`,
'https://cdn.discordapp.com/attachments/729088611986702508/795962314015899668/lisenssi.png'
);
AddOneToRejected();
await console.log(
`\u001b[36m=> [${new Date().toLocaleTimeString()}] User tried to start, but his licensekey was expired!\n=> [DETAILS ] IP: ${ip} | HWID: ${
req.body.hwid
} | License: ${req.body.license}`
);
res.json({
msg: 'EXPIRED_LICENSE',
status: 'failed',
});
return userWebhookURL.send(successembed);
} else {
AddOneToRejected();
return res.json({
msg: 'EXPIRED_LICENSE',
status: 'failed',
});
}
}
}
if (
result.HWIDlist &&
result.HWIDcap &&
result.HWIDcap.toLowerCase() !== 'none'
) {
if (
!result.HWIDlist.includes(req.body.hwid) &&
result.HWIDcap <= result.HWIDlist.length
) {
if (IPcap.discordwebhook) {
const userWebhookURL = new Webhook(
`${IPcap.discordwebhook}`
);
const successembed = new MessageBuilder()
.setTitle(`Maximum HWIDs reached`)
.setTimestamp()
.setColor('#A652BB')
.addField('License', `${req.body.license}`)
.addField('Client:', `${Clientname}`)
.addField(
'DiscordID:',
`${result.discordID || 'None'}`
)
.addField('Plugin', `${req.body.plugin}`)
.addField('IP-Address', `${ip}`)
.addField('HWID', `${req.body.hwid}`)
.addField('Version', `${req.body.version}`)
.addField(
'HWID-Cap',
`${result.HWIDlist.length}/${result.HWIDcap}`
)
.setFooter(
`uLicense | Made by @kassq`,
'https://cdn.discordapp.com/attachments/729088611986702508/795962314015899668/lisenssi.png'
);
AddOneToRejected();
await console.log(
`\u001b[36m=> [${new Date().toLocaleTimeString()}] User tried to start server, but he has reached maximum HWIDs!\n=> [DETAILS ] IP: ${ip} | HWID: ${
req.body.hwid
} | License: ${req.body.license}`
);
res.json({
msg: 'MAXIMUM_HWIDS',
status: 'failed',
});
return userWebhookURL.send(successembed);
} else {
AddOneToRejected();
return res.json({
msg: 'MAXIMUM_HWIDS',
status: 'failed',
});
}
}
}
if (result.IPlist) {
if (
!result.IPlist.includes(ip) &&
result.IPcap <= result.IPlist.length
) {
if (IPcap.discordwebhook) {
const userWebhookURL = new Webhook(
`${IPcap.discordwebhook}`
);
const successembed = new MessageBuilder()
.setTitle(`Maximum IPs reached`)
.setTimestamp()
.setColor('#A652BB')
.addField('License', `${req.body.license}`)
.addField('Client:', `${Clientname}`)
.addField(
'DiscordID:',
`${result.discordID || 'None'}`
)
.addField('Plugin', `${req.body.plugin}`)
.addField('IP-Address', `${ip}`)
.addField('HWID', `${req.body.hwid}`)
.addField('Version', `${req.body.version}`)
.addField(
'IP-Cap',
`${result.IPlist.length}/${result.IPcap}`
)
.setFooter(
`uLicense | Made by @kassq`,
'https://cdn.discordapp.com/attachments/729088611986702508/795962314015899668/lisenssi.png'
);
AddOneToRejected();
await console.log(
`\u001b[36m=> [${new Date().toLocaleTimeString()}] User tried to start server, but he has reached maximum IPs!\n=> [DETAILS ] IP: ${ip} | HWID: ${
req.body.hwid
} | License: ${req.body.license}`
);
res.json({
msg: 'MAXIMUM_IPS',
status: 'failed',
});
return userWebhookURL.send(successembed);
} else {
AddOneToRejected();
return res.json({
msg: 'MAXIMUM_IPS',
status: 'failed',
});
}
}
}
if (
req.body.plugin.toLowerCase() !==
result.pluginname.toLowerCase() &&
result.pluginname !== ''
) {
if (IPcap.discordwebhook) {
const userWebhookURL = new Webhook(
`${IPcap.discordwebhook}`
);
const successembed = new MessageBuilder()
.setTitle(`Wrong plugin name`)
.setTimestamp()
.setColor('#CC7900')
.addField('License', `${req.body.license}`)
.addField('Client:', `${Clientname}`)
.addField(
'DiscordID:',
`${result.discordID || 'None'}`
)
.addField('IP-Address', `${ip}`)
.addField('HWID', `${req.body.hwid}`)
.addField('Version', `${req.body.version}`)
.addField(
'Plugin',
`${req.body.plugin}/${result.pluginname}`
)
.setFooter(
`uLicense | Made by @kassq`,
'https://cdn.discordapp.com/attachments/729088611986702508/795962314015899668/lisenssi.png'
);
AddOneToRejected();
await console.log(
`\u001b[36m=> [${new Date().toLocaleTimeString()}] User tried to start server, but plugin name was invalid!\n=> [DETAILS ] IP: ${ip} | HWID: ${
req.body.hwid
} | License: ${req.body.license}`
);
res.json({
msg: 'INVALID_PLUGIN',
status: 'failed',
});
return userWebhookURL.send(successembed);
} else {
AddOneToRejected();
return res.json({
msg: 'INVALID_PLUGIN',
status: 'failed',
});
}
}
await Users.updateOne(
{
APIkey: req.headers.authorization,
'licenses.licensekey': Licensebody,
},
{
$set: {
'licenses.$.latestip': ip,
'licenses.$.latestrequest': new Date(),
},
$addToSet: {
'licenses.$.IPlist': ip,
'licenses.$.HWIDlist': req.body.hwid,
},
}
);
if (!dateExists) {
let now = new Date();
let date = now.toLocaleDateString();
let requests = 1;
let rejected = 0;
const newDate = new Dailyrequests({
date,
requests,
rejected,
});
await newDate.save();
} else {
let now = new Date();
await Dailyrequests.findOneAndUpdate(
{ date: now.toLocaleDateString() },
{ $inc: { requests: 1 } }
);
}
let niggahash = req.headers.authorization.substring(0, 2); // API keyn 2 ekaa merkkiä
let thash = Date.now().toString().slice(0, -5); // Timestamppi unix muodossa (universaali aikamuoto)
let lhashL = req.body.license.substring(0, 2); // Lisenssin 2 ensimmäistä merkkiä
let lhashR = req.body.license.substring(
// Lisenssin 2 viimeistä merkkiä
req.body.license.length - 2,
req.body.license.length
);
let rhash = Buffer.from(lhashL + lhashR + niggahash).toString(
'base64'
); // BASE64 encoded [Lisenssin 2 ekaa + 2 vikaa kirjainta]
const finalhash = `${rhash}694201337${thash}`; // ns "valmis" muoto
const version = await Plugins.findOne({
plugin: req.body.plugin,
});
let versionfinal;
if (version) {
versionfinal = version.version;
} else {
versionfinal = 'unknown';
}
res.json({
msg: 'SUCCESSFUL_AUTHENTICATION',
status: 'success',
version: versionfinal,
neekeri: finalhash,
});
if (ApiCheck.discordwebhook) {
const userWebhookURL = new Webhook(
`${ApiCheck.discordwebhook}`
);
const successembed = new MessageBuilder()
.setTitle(`Successful authentication`)
.setTimestamp()
.setColor('#0099E1')
.addField('License', `${req.body.license}`)
.addField('Client:', `${Clientname}`)
.addField('DiscordID:', `${result.discordID || 'None'}`)
.addField('Plugin', `${req.body.plugin}`)
.addField('IP-Address', `${ip}`)
.addField('HWID', `${req.body.hwid}`)
.addField('Version', `${req.body.version}`)
.setFooter(
`uLicense | Made by @kassq`,
'https://cdn.discordapp.com/attachments/729088611986702508/795962314015899668/lisenssi.png'
);
await console.log(
`\u001b[36m=> [${new Date().toLocaleTimeString()}] User had successful authentication!\n=> [DETAILS ] IP: ${ip} | HWID: ${
req.body.hwid
} | License: ${req.body.license}`
);
userWebhookURL.send(successembed);
}
}
}
} catch (error) {
return console.log(error);
}
});
module.exports = router;

View File

@ -0,0 +1,53 @@
const router = require('express').Router();
const userCtrl = require('../controllers/userCtrl');
const auth = require('../middleware/auth');
const rateLimit = require('express-rate-limit');
const routesLimit = rateLimit({
windowMs: 300000,
max: 2000,
});
router.post('/login', routesLimit, userCtrl.login);
router.post('/refresh_token', routesLimit, userCtrl.getAccessToken);
router.get('/getrequests', routesLimit, auth, userCtrl.getRequestsData);
router.get(
'/getyearlycustomers',
routesLimit,
auth,
userCtrl.getYearlyCustomers
);
router.post('/updatepassword', routesLimit, auth, userCtrl.updatePassword);
router.post('/blacklist', routesLimit, auth, userCtrl.addBlacklistData);
router.post('/subuser', routesLimit, auth, userCtrl.addSubuserData);
router.post('/getClientNames', routesLimit, auth, userCtrl.getClientNames);
router.get('/subuserData', routesLimit, auth, userCtrl.getSubuserData);
router.get('/blacklistData', routesLimit, auth, userCtrl.getBlacklistData);
router.patch('/addLicenseData', routesLimit, auth, userCtrl.addLicenseData);
router.patch(
'/deleteSubuserData',
routesLimit,
auth,
userCtrl.deleteSubuserData
);
router.patch(
'/deleteLicenseData',
routesLimit,
auth,
userCtrl.deleteLicenseData
);
router.patch(
'/deleteBlacklistData',
routesLimit,
auth,
userCtrl.deleteBlacklistData
);
router.get('/licenseData', routesLimit, auth, userCtrl.getLicenseData);
router.get('/latestrequests', routesLimit, auth, userCtrl.getLatestRequests);
router.get('/infor', routesLimit, auth, userCtrl.getUserInfor);
router.get('/logout', routesLimit, userCtrl.logout);
router.patch('/update', routesLimit, auth, userCtrl.updateUser);
router.patch('/updateLicense', routesLimit, auth, userCtrl.updateLicenseData);
router.patch('/updateSubuser', routesLimit, auth, userCtrl.updateSubuser);
module.exports = router;

View File

@ -0,0 +1,93 @@
require('dotenv').config();
const express = require('express');
const mongoose = require('mongoose');
const cors = require('cors');
const cookieParser = require('cookie-parser');
const Users = require('./models/userModel.js');
const crypto = require('crypto');
const helmet = require('helmet');
const app = express();
const path = require('path');
const bcrypt = require('bcrypt');
app.use(express.json());
app.use(cors());
app.use(cookieParser());
app.use(
helmet({
contentSecurityPolicy: false,
})
);
app.use('/user', require('./routes/userRouter'));
app.use('/api', require('./routes/apiRouter'));
app.use(express.static(path.join(__dirname, 'build')));
app.get('*', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
const URL = process.env.MONGODB_URL;
mongoose.connect(
URL,
{
useCreateIndex: true,
useFindAndModify: false,
useNewUrlParser: true,
useUnifiedTopology: true,
},
(err) => {
if (err) throw err;
console.log(
`=> [${new Date().toLocaleTimeString()}] Connected to MongoDB`
);
}
);
async function firstStart() {
const name = process.env.LOGIN_NAME;
const email = process.env.LOGIN_EMAIL;
const password = process.env.LOGIN_PASSWORD;
if (!name || !email || !password) {
return await console.log('Please fill in login details in .env');
}
const passwordHash = await bcrypt.hash(password, 12);
const defaultUser = await Users.findOne({ name: process.env.LOGIN_NAME });
if (!defaultUser) {
let APIkey = crypto.randomBytes(20).toString('hex');
const newUser = new Users({
name,
email,
password: passwordHash,
APIkey,
});
await console.log(
`=> [${new Date().toLocaleTimeString()}] This is your randomly created API key. If you need this later you can get this from database: ${APIkey}`
);
await newUser.save();
}
}
firstStart();
const PORT = process.env.SERVER_PORT || 4000;
app.listen(PORT, () =>
console.log(
`=> [${new Date().toLocaleTimeString()}] Server is running on port ${PORT}`
)
);
console.log(`\u001b[36m`);
console.log(` \u001b[36m╭────────────────────────────────────────╮`);
console.log(
` \u001b[36m│ \x1b[37muLicense - Dashboard \u001b[36m│`
);
console.log(
` \u001b[36m│ \u001b[36m│ \x1b[37mMade by`
);
console.log(
` \u001b[36m│ \x1b[37mVersion \x1b[36m1.2.6 \x1b[37m| BETA \u001b[36m│ \x1b[37mkassq`
);
console.log(
` \u001b[36m│ \x1b[37mRun \x1b[36mnpm i \x1b[37mto update dependencies \u001b[36m│`
);
console.log(` \u001b[36m╰────────────────────────────────────────╯`);
console.log(`\u001b[36m`);

View File

@ -0,0 +1,58 @@
const Discord = require('discord.js');
const { Collection } = require('discord.js');
const { readdir } = require('fs');
const client = new Discord.Client({
partials: ['MESSAGE', 'CHANNEL', 'REACTION'],
});
const mongoose = require('mongoose');
client.config = require('./config.json');
const url = client.config.databaseURL;
mongoose.connect(url, {
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: false,
});
mongoose.connection.on('connected', () => {
console.log('Connected successfully to the database :)');
});
mongoose.connection.on('err', (err) => {
console.error(
`Error occurred while connecting to the database.\n${err.stack}`
);
});
mongoose.connection.on('disconnected', () => {
console.warn('Lost connection to the database');
});
readdir('./events/', (err, files) => {
if (err) return console.log(err);
files.forEach((file) => {
const event = require(`./events/${file}`);
let eventName = file.split('.')[0];
client.on(eventName, event.bind(null, client));
});
});
client.commands = new Collection();
readdir('./commands/', (err, files) => {
if (err) return console.log(err);
files.forEach((file) => {
let commandName = file.split('.')[0];
client.commands.set(commandName, require(`./commands/${file}`));
});
});
client.on('messageReactionAdd', async (reaction, user) => {
if (reaction.message.partial) await reaction.message.fetch();
if (reaction.partial) await reaction.fetch();
if (!reaction.message.author.bot) return;
if (user.bot) return;
if (reaction.emoji.name == '🆗' && reaction.count > 1) {
reaction.message.delete();
}
});
client.login(client.config.token);

View File

@ -0,0 +1,42 @@
const crypto = require('crypto');
const config = require('../config.json');
const algorithm = 'aes-256-ctr';
const secretKey = config.encrypt_secret;
const key = crypto
.createHash('sha256')
.update(String(secretKey))
.digest('base64')
.substr(0, 32);
const iv = crypto.randomBytes(16);
const encrypt = (text) => {
const cipher = crypto.createCipheriv(algorithm, key, iv);
const encrypted = Buffer.concat([cipher.update(text), cipher.final()]);
return {
iv: iv.toString('hex'),
content: encrypted.toString('hex'),
};
};
const decrypt = (hash) => {
const decipher = crypto.createDecipheriv(
algorithm,
key,
Buffer.from(hash.iv, 'hex')
);
const decrpyted = Buffer.concat([
decipher.update(Buffer.from(hash.content, 'hex')),
decipher.final(),
]);
return decrpyted.toString();
};
module.exports = {
encrypt,
decrypt,
};

View File

@ -0,0 +1,252 @@
const Discord = require('discord.js');
const Users = require('../models/userDB.js');
const Licensehistory = require('../models/licensehistoryModel.js');
const moment = require('moment');
const crypto = require('crypto');
const axios = require('axios');
const { encrypt } = require('../auth/crypto.js');
const now = new Date();
exports.run = async (client, message, args) => {
if (!message.member.hasPermission('ADMINISTRATOR')) {
return await message.channel.send(
":x: You don't have enough permissions in this server!"
);
} else {
await Users.exists(
{ DiscordID: message.author.id },
async function (err, doc) {
if (err) {
await console.log(err);
await message.channel.send(
':x: Error occurred. Please contact my developer!'
);
}
if (doc === true) {
if (!args[0] || !args[1] || !args[2] || !args[3]) {
const exampleEmbed = new Discord.MessageEmbed()
.setColor(`${client.config.embed_color}`)
.setAuthor(
`Requested by ${message.author.username}`,
message.author.displayAvatarURL()
)
.setTitle('Addlicense command')
.setDescription(
'With this command you can add licenses without opening our web dashboard!'
)
.addField(
'Command format:',
"This command takes 4 arguments:\n`<client's name> <ip cap> <expires> <plugin name>`"
)
.addField(
'Example use case:',
'`+addlicense ExampleUser 5 60d MyPlugin`\nThis example creates license for ExampleUser, IPs are capped at 5, license expires in 60days and it only works for MyPlugin!'
)
.setFooter(
`${client.config.name} | By @kassq`,
client.user.displayAvatarURL()
);
return await message.channel
.send(exampleEmbed)
.then(async (msg) => {
await msg.react('🆗');
});
} else {
if (isNaN(args[1]) === true) {
return await message.channel.send(
':x: IP-cap must be a number!'
);
} else if (
isNaN(args[2].slice(0, -1)) === true &&
args[2].toLowerCase() !== 'never'
) {
return await message.channel.send(
':x: Expire date must be format: 60d/never'
);
} else if (
isNaN(args[0]) === false &&
args[0].length !== 18
) {
return await message.channel.send(
':x: Client name cannot be a number unless it is valid DiscordID'
);
} else {
let licensekeyFirst =
`${crypto
.randomBytes(3)
.toString('hex')
.slice(0, -1)}-` +
`${crypto
.randomBytes(3)
.toString('hex')
.slice(0, -1)}-` +
`${crypto
.randomBytes(3)
.toString('hex')
.slice(0, -1)}-` +
`${crypto
.randomBytes(3)
.toString('hex')
.slice(0, -1)}`;
let licensekeyNotEncrypted = licensekeyFirst.toUpperCase();
let licensekey = encrypt(licensekeyNotEncrypted);
let IPcap = args[1];
let expiresStart = moment(new Date())
.add(args[2].slice(0, -1), 'days')
.toDate()
.toISOString();
let expires = isNaN(args[2].slice(0, -1))
? 'Never'
: expiresStart.toString();
let pluginname = args[3];
let description = 'None';
let clientname = args[0];
let timestamp = new Date();
let latestrequest = 'None';
let clientnameFinal;
let discordID;
if (
isNaN(clientname) === false &&
clientname.length === 18
) {
await axios
.get(
`https://discordapp.com/api/users/${clientname}`,
{
headers: {
Authorization: `Bot ${client.config.token}`,
},
}
)
.then((res) => {
clientnameFinal = res.data.username;
discordID = res.data.id;
})
.catch((err) => {
if (
err.response.statusText.toLowerCase() ===
'not found'
) {
clientnameFinal = 'NOT_FOUND';
return console.log(
`\u001b[36m=> [${new Date().toLocaleTimeString()}] Invalid DiscordID while creating license!`
);
}
});
}
if (clientnameFinal === 'NOT_FOUND') {
return message.channel.send(
":x: Couldn't find that DiscordID!"
);
} else if (clientnameFinal === undefined) {
clientnameFinal = clientname;
}
if (discordID == undefined) {
discordID = 'None';
}
const licenses = {
licensekey,
IPcap,
expires,
pluginname,
description,
clientname: clientnameFinal,
HWIDcap: 'None',
timestamp,
latestrequest,
discordID,
};
await Users.findOneAndUpdate(
{ role: 0 },
{
$push: {
licenses,
},
}
);
let months = [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December',
];
let monthNumber = months[now.getMonth()];
const yearExists = await Licensehistory.findOne({
year: now.getFullYear(),
});
if (!yearExists) {
const year = now.getFullYear();
const newYear = new Licensehistory({
year,
January: 0,
February: 0,
March: 0,
April: 0,
May: 0,
June: 0,
July: 0,
August: 0,
September: 0,
October: 0,
November: 0,
December: 0,
});
await newYear.save();
await Licensehistory.findOneAndUpdate(
{ year: now.getFullYear() },
{ $inc: { [monthNumber.toLowerCase]: 1 } }
);
} else {
await Licensehistory.findOneAndUpdate(
{ year: now.getFullYear() },
{ $inc: { [monthNumber.toLowerCase()]: 1 } }
);
}
const successEmbed = new Discord.MessageEmbed()
.setColor(`${client.config.embed_color}`)
.setAuthor(
`Requested by ${message.author.username}`,
message.author.displayAvatarURL()
)
.setTitle('Successfully added license')
.addField('Client:', `${clientnameFinal}`)
.addField('DiscordID', `${discordID}`)
.addField(
'License:',
`${licensekeyNotEncrypted}`
)
.addField('IP-cap:', `${IPcap}`)
.addField('Expiry date', `${expires}`)
.addField('Plugin:', `${pluginname}`)
.addField('Created:', `${timestamp}`)
.setFooter(
`${client.config.name} | By @kassq`,
client.user.displayAvatarURL()
);
await message.channel
.send(successEmbed)
.then(async (msg) => {
await msg.react('🆗');
});
}
}
} else {
return await console.log(
`${message.author.username} tried to use addlicense.`
);
}
}
);
}
};

View File

@ -0,0 +1,255 @@
const Discord = require('discord.js');
const Users = require('../models/userDB.js');
const { decrypt } = require('../auth/crypto.js');
exports.run = async (client, message, args) => {
if (!message.member.hasPermission('ADMINISTRATOR')) {
return await message.channel.send(
":x: You don't have enough permissions in this server!"
);
} else {
await Users.exists(
{ DiscordID: message.author.id, role: 0 },
async function (err, doc) {
if (err) {
await console.log(err);
await message.channel.send(
':x: Error occurred. Please contact my developer!'
);
}
if (doc === true) {
if (!args[0] || !args[1]) {
const exampleEmbed = new Discord.MessageEmbed()
.setColor(`${client.config.embed_color}`)
.setAuthor(
`Requested by ${message.author.username}`,
message.author.displayAvatarURL()
)
.setTitle('Cleardata command')
.setDescription(
'With this command you can clear HWID / IP data for all licenses or for a specific license!'
)
.addField(
'Command format:',
'This command takes 2 arguments:\n`<hwid/ip> <license/all>`'
)
.addField(
'Example use case V1:',
'`+cleardata hwid all`\nThis example clears **ALL** HWID data for **ALL** licenses. This action cannot be undone!'
)
.addField(
'Example use case V2:',
'`+cleardata hwid 1234-1234-1234-1234`\nThis example clears **ALL** HWID data for **SPECIFIC** license! This action cannot be undone!'
)
.addField(
'Note:',
'Sub-users **cannot use** this command. This is only for the administrator. If you want to remove just specific IPs / HWIDs of license instead of all, take a look at `+editlicense` command.'
)
.setFooter(
`${client.config.name} | By @kassq`,
client.user.displayAvatarURL()
);
return await message.channel
.send(exampleEmbed)
.then(async (msg) => {
await msg.react('🆗');
});
} else {
let User = await Users.findOne({
role: 0,
});
if (args[1].toLowerCase() === 'all') {
if (args[0].toLowerCase() === 'hwid') {
let licenseToEdit = User.licenses;
for (let x = 0; x < User.licenses.length; x++) {
await Users.findOneAndUpdate(
{
role: 0,
'licenses.licensekey':
licenseToEdit[x].licensekey,
},
{
$set: {
'licenses.$.HWIDlist': [],
},
}
).catch((err) => {
console.log(err);
});
}
const successEmbed = new Discord.MessageEmbed()
.setColor(`${client.config.embed_color}`)
.setAuthor(
`Requested by ${message.author.username}`,
message.author.displayAvatarURL()
)
.setTitle('Cleared HWID-data')
.addField(
'HWID-data cleared for:',
'All licenses'
)
.setFooter(
`${client.config.name} | By @kassq`,
client.user.displayAvatarURL()
);
return await message.channel
.send(successEmbed)
.then(async (msg) => {
await msg.react('🆗');
});
} else if (args[0].toLowerCase() === 'ip') {
let licenseToEdit = User.licenses;
for (let x = 0; x < User.licenses.length; x++) {
await Users.findOneAndUpdate(
{
role: 0,
'licenses.licensekey':
licenseToEdit[x].licensekey,
},
{
$set: {
'licenses.$.IPlist': [],
},
}
).catch((err) => {
console.log(err);
});
}
const successEmbed = new Discord.MessageEmbed()
.setColor(`${client.config.embed_color}`)
.setAuthor(
`Requested by ${message.author.username}`,
message.author.displayAvatarURL()
)
.setTitle('Cleared IP-data')
.addField(
'IP-data cleared for:',
'All licenses'
)
.setFooter(
`${client.config.name} | By @kassq`,
client.user.displayAvatarURL()
);
return await message.channel
.send(successEmbed)
.then(async (msg) => {
await msg.react('🆗');
});
} else {
message.channel.send(':x: Invalid arguments!');
}
} else {
let licensekey = args[1];
let licenseToEdit;
for (let f = 0; f < User.licenses.length; f++) {
let licenseToSearch =
User.licenses[f].licensekey;
let key = decrypt(licenseToSearch);
if (key === licensekey) {
licenseToEdit = licenseToSearch;
break;
}
}
if (licenseToEdit) {
const licensecheck = await Users.findOne({
role: 0,
licenses: {
$elemMatch: {
licensekey: licenseToEdit,
},
},
});
if (!licensecheck) {
return await message.channel.send(
":x: Couldn't find that license!"
);
} else {
if (args[0].toLowerCase() === 'hwid') {
await Users.findOneAndUpdate(
{
role: 0,
'licenses.licensekey': licenseToEdit,
},
{
$set: {
'licenses.$.HWIDlist': [],
},
}
).catch((err) => {
console.log(err);
});
const successEmbed = new Discord.MessageEmbed()
.setColor(
`${client.config.embed_color}`
)
.setAuthor(
`Requested by ${message.author.username}`,
message.author.displayAvatarURL()
)
.setTitle('Cleared HWID-data')
.addField(
'HWID-data removed for:',
`${args[1]}`
)
.setFooter(
`${client.config.name} | By @kassq`,
client.user.displayAvatarURL()
);
return await message.channel
.send(successEmbed)
.then(async (msg) => {
await msg.react('🆗');
});
} else if (args[0].toLowerCase() === 'ip') {
await Users.findOneAndUpdate(
{
role: 0,
'licenses.licensekey': licenseToEdit,
},
{
$set: {
'licenses.$.IPlist': [],
},
}
).catch((err) => {
console.log(err);
});
const successEmbed = new Discord.MessageEmbed()
.setColor(
`${client.config.embed_color}`
)
.setAuthor(
`Requested by ${message.author.username}`,
message.author.displayAvatarURL()
)
.setTitle('Cleared IP-data')
.addField(
'IP-data removed for:',
`${args[1]}`
)
.setFooter(
`${client.config.name} | By @kassq`,
client.user.displayAvatarURL()
);
return await message.channel
.send(successEmbed)
.then(async (msg) => {
await msg.react('🆗');
});
}
}
} else {
return message.channel.send(
":x: Couldn't find that license!"
);
}
}
}
} else {
return await console.log(
`${message.author.username} tried to use cleardata.`
);
}
}
);
}
};

View File

@ -0,0 +1,562 @@
const Discord = require('discord.js');
const Users = require('../models/userDB.js');
const { decrypt } = require('../auth/crypto.js');
const axios = require('axios');
exports.run = async (client, message, args) => {
if (!message.member.hasPermission('ADMINISTRATOR')) {
return await message.channel.send(
":x: You don't have enough permissions in this server!"
);
} else {
await Users.exists(
{ DiscordID: message.author.id },
async function (err, doc) {
if (err) {
await console.log(err);
await message.channel.send(
':x: Error occurred. Please contact my developer!'
);
}
if (doc === true) {
if (!args[0] || !args[1] || !args[2]) {
const exampleEmbed = new Discord.MessageEmbed()
.setColor(`${client.config.embed_color}`)
.setAuthor(
`Requested by ${message.author.username}`,
message.author.displayAvatarURL()
)
.setTitle('Editlicense command')
.setDescription(
'With this command you can edit existing licenses!'
)
.addField(
'Command format:',
'This command takes 3 arguments:\n`<license> <ipcap/plugin/client/desc/removeip/removehwid/hwidcap> <value>`'
)
.addField(
'Example use case:',
"`+editlicense 1234-1234-1234-1234 ipcap 10`\nThis example edits 1234-1234-1234-1234 license's IP-cap value to 10"
)
.setFooter(
`${client.config.name} | By @kassq`,
client.user.displayAvatarURL()
);
return await message.channel
.send(exampleEmbed)
.then(async (msg) => {
await msg.react('🆗');
});
} else {
if (args[1] === 'ipcap') {
if (isNaN(args[2])) {
return message.channel.send(
':x: New value for IP cap can only be a number!'
);
}
let User = await Users.findOne({
role: 0,
});
let licensekey = args[0];
let licenseToEdit;
for (let f = 0; f < User.licenses.length; f++) {
let licenseToSearch =
User.licenses[f].licensekey;
let key = decrypt(licenseToSearch);
if (key === licensekey) {
licenseToEdit = licenseToSearch;
break;
}
}
if (licenseToEdit) {
await Users.findOneAndUpdate(
{
role: 0,
'licenses.licensekey': licenseToEdit,
},
{
$set: {
'licenses.$.IPcap': args[2],
},
}
);
const successEmbed = new Discord.MessageEmbed()
.setColor(`${client.config.embed_color}`)
.setAuthor(
`Requested by ${message.author.username}`,
message.author.displayAvatarURL(),
client.config.siteURL
)
.setTitle('Successfully edited license')
.addField('Edited license:', `${args[0]}`)
.addField(
`New value for ${args[1]}:`,
`${args[2]}`
)
.setFooter(
`${client.config.name} | By @kassq`,
client.user.displayAvatarURL()
);
return await message.channel
.send(successEmbed)
.then(async (msg) => {
await msg.react('🆗');
});
} else {
return message.channel.send(
":x: Couldn't find that license!"
);
}
} else if (args[1] === 'plugin') {
let User = await Users.findOne({
role: 0,
});
let licensekey = args[0];
let licenseToEdit;
for (let f = 0; f < User.licenses.length; f++) {
let licenseToSearch =
User.licenses[f].licensekey;
let key = decrypt(licenseToSearch);
if (key === licensekey) {
licenseToEdit = licenseToSearch;
break;
}
}
if (licenseToEdit) {
await Users.findOneAndUpdate(
{
role: 0,
'licenses.licensekey': licenseToEdit,
},
{
$set: {
'licenses.$.pluginname': args[2],
},
}
);
const successEmbed = new Discord.MessageEmbed()
.setColor(`${client.config.embed_color}`)
.setAuthor(
`Requested by ${message.author.username}`,
message.author.displayAvatarURL()
)
.setTitle('Successfully edited license')
.addField('Edited license:', `${args[0]}`)
.addField(
`New value for ${args[1]}:`,
`${args[2]}`
)
.setFooter(
`${client.config.name} | By @kassq`,
client.user.displayAvatarURL()
);
return await message.channel
.send(successEmbed)
.then(async (msg) => {
await msg.react('🆗');
});
} else {
return message.channel.send(
":x: Couldn't find that license!"
);
}
} else if (args[1] === 'client') {
let User = await Users.findOne({
role: 0,
});
let licensekey = args[0];
let licenseToEdit;
for (let f = 0; f < User.licenses.length; f++) {
let licenseToSearch =
User.licenses[f].licensekey;
let key = decrypt(licenseToSearch);
if (key === licensekey) {
licenseToEdit = licenseToSearch;
break;
}
}
let clientname = args[2];
let clientnameFinal;
let discordID;
if (
isNaN(clientname) === false &&
clientname.length === 18
) {
await axios
.get(
`https://discordapp.com/api/users/${clientname}`,
{
headers: {
Authorization: `Bot ${client.config.token}`,
},
}
)
.then((res) => {
clientnameFinal = res.data.username;
discordID = res.data.id;
})
.catch((err) => {
if (
err.response.statusText.toLowerCase() ===
'not found'
) {
clientnameFinal = 'NOT_FOUND';
return console.log(
`\u001b[36m=> [${new Date().toLocaleTimeString()}] Invalid DiscordID while creating license!`
);
}
});
}
if (clientnameFinal === 'NOT_FOUND') {
return message.channel.send(
":x: Couldn't find that DiscordID!"
);
} else if (clientnameFinal === undefined) {
clientnameFinal = clientname;
}
if (discordID == undefined) {
discordID = 'None';
}
if (licenseToEdit) {
await Users.findOneAndUpdate(
{
role: 0,
'licenses.licensekey': licenseToEdit,
},
{
$set: {
'licenses.$.clientname': clientnameFinal,
'licenses.$.discordID': discordID,
},
}
);
const successEmbed = new Discord.MessageEmbed()
.setColor(`${client.config.embed_color}`)
.setAuthor(
`Requested by ${message.author.username}`,
message.author.displayAvatarURL(),
client.config.siteURL
)
.setTitle('Successfully edited license')
.addField('Edited license:', `${args[0]}`)
.addField(
`New value for client:`,
`${clientnameFinal}`
)
.addField('DiscordID', `${discordID}`)
.setFooter(
`${client.config.name} | By @kassq`,
client.user.displayAvatarURL()
);
return await message.channel
.send(successEmbed)
.then(async (msg) => {
await msg.react('🆗');
});
} else {
return message.channel.send(
":x: Couldn't find that license!"
);
}
} else if (args[1] === 'removeip') {
let User = await Users.findOne({
role: 0,
});
let licensekey = args[0];
let licenseToEdit;
let IPlist;
for (let f = 0; f < User.licenses.length; f++) {
let licenseToSearch =
User.licenses[f].licensekey;
let key = decrypt(licenseToSearch);
if (key === licensekey) {
licenseToEdit = licenseToSearch;
IPlist = User.licenses[f].IPlist;
break;
}
}
if (
IPlist === undefined ||
!IPlist.includes(args[2])
) {
return message.channel.send(
":x: Couldn't find that IP for that license."
);
}
if (licenseToEdit) {
await Users.findOneAndUpdate(
{
role: 0,
'licenses.licensekey': licenseToEdit,
},
{
$pull: {
'licenses.$.IPlist': args[2],
},
}
);
let ipListFinal;
if (IPlist && IPlist.length > 1) {
ipListFinal = IPlist.filter(
(item) => item !== args[2]
)
.toString()
.replace(/,/g, '\n');
} else {
ipListFinal = 'empty';
}
const successEmbed = new Discord.MessageEmbed()
.setColor(`${client.config.embed_color}`)
.setAuthor(
`Requested by ${message.author.username}`,
message.author.displayAvatarURL(),
client.config.siteURL
)
.setTitle('Successfully edited license')
.addField('Edited license:', `${args[0]}`)
.addField(`Removed IP:`, `${args[2]}`)
.addField(`IP-list now:`, ipListFinal)
.setFooter(
`${client.config.name} | By @kassq`,
client.user.displayAvatarURL()
);
return await message.channel
.send(successEmbed)
.then(async (msg) => {
await msg.react('🆗');
});
} else {
return message.channel.send(
":x: Couldn't find that license!"
);
}
} else if (args[1] === 'hwidcap') {
if (
isNaN(args[2]) === true &&
args[2].toLowerCase() !== 'none'
) {
return message.channel.send(
':x: Invalid value for HWID-cap! Value must be a number or none!'
);
}
let User = await Users.findOne({
role: 0,
});
let licensekey = args[0];
let licenseToEdit;
for (let f = 0; f < User.licenses.length; f++) {
let licenseToSearch =
User.licenses[f].licensekey;
let key = decrypt(licenseToSearch);
if (key === licensekey) {
licenseToEdit = licenseToSearch;
break;
}
}
let hwidcapFinal;
if (args[2].toLowerCase() === 'none') {
hwidcapFinal = 'None';
} else {
hwidcapFinal = args[2];
}
if (licenseToEdit) {
await Users.findOneAndUpdate(
{
role: 0,
'licenses.licensekey': licenseToEdit,
},
{
$set: {
'licenses.$.HWIDcap': hwidcapFinal,
},
}
);
const successEmbed = new Discord.MessageEmbed()
.setColor(`${client.config.embed_color}`)
.setAuthor(
`Requested by ${message.author.username}`,
message.author.displayAvatarURL(),
client.config.siteURL
)
.setTitle('Successfully edited HWID-cap')
.addField('Edited license:', `${args[0]}`)
.addField(
`New HWID-Cap:`,
`${hwidcapFinal}`
)
.setFooter(
`${client.config.name} | By @kassq`,
client.user.displayAvatarURL()
);
return await message.channel
.send(successEmbed)
.then(async (msg) => {
await msg.react('🆗');
});
} else {
return message.channel.send(
":x: Couldn't find that license!"
);
}
} else if (args[1] === 'desc') {
if (args[2].length < 4) {
return message.channel.send(
':x: Description value must be `None` or over 4 characters long!'
);
}
let User = await Users.findOne({
role: 0,
});
let licensekey = args[0];
let licenseToEdit;
for (let f = 0; f < User.licenses.length; f++) {
let licenseToSearch =
User.licenses[f].licensekey;
let key = decrypt(licenseToSearch);
if (key === licensekey) {
licenseToEdit = licenseToSearch;
break;
}
}
let newdesc;
if (args[2].toLowerCase() === 'none') {
newdesc = '';
} else {
let descpre = [...args];
descpre.shift();
descpre.shift();
newdesc = descpre.join(' ');
}
if (licenseToEdit) {
await Users.findOneAndUpdate(
{
role: 0,
'licenses.licensekey': licenseToEdit,
},
{
$set: {
'licenses.$.description': newdesc,
},
}
);
const successEmbed = new Discord.MessageEmbed()
.setColor(`${client.config.embed_color}`)
.setAuthor(
`Requested by ${message.author.username}`,
message.author.displayAvatarURL(),
client.config.siteURL
)
.setTitle('Successfully edited description')
.addField('Edited license:', `${args[0]}`)
.addField(
`New description value:`,
`${newdesc || 'None'}`
)
.setFooter(
`${client.config.name} | By @kassq`,
client.user.displayAvatarURL()
);
return await message.channel
.send(successEmbed)
.then(async (msg) => {
await msg.react('🆗');
});
} else {
return message.channel.send(
":x: Couldn't find that license!"
);
}
} else if (args[1] === 'removehwid') {
let User = await Users.findOne({
role: 0,
});
let licensekey = args[0];
let licenseToEdit;
let HWIDlist;
for (let f = 0; f < User.licenses.length; f++) {
let licenseToSearch =
User.licenses[f].licensekey;
let key = decrypt(licenseToSearch);
if (key === licensekey) {
licenseToEdit = licenseToSearch;
HWIDlist = User.licenses[f].HWIDlist;
break;
}
}
if (
HWIDlist === undefined ||
!HWIDlist.includes(args[2])
) {
return message.channel.send(
":x: Couldn't find that HWID for that license."
);
}
if (licenseToEdit) {
await Users.findOneAndUpdate(
{
role: 0,
'licenses.licensekey': licenseToEdit,
},
{
$pull: {
'licenses.$.HWIDlist': args[2],
},
}
);
let hwidListFinal;
if (HWIDlist && HWIDlist.length > 1) {
hwidListFinal = HWIDlist.filter(
(item) => item !== args[2]
)
.toString()
.replace(/,/g, '\n');
} else {
hwidListFinal = 'empty';
}
const successEmbed = new Discord.MessageEmbed()
.setColor(`${client.config.embed_color}`)
.setAuthor(
`Requested by ${message.author.username}`,
message.author.displayAvatarURL(),
client.config.siteURL
)
.setTitle('Successfully edited license')
.addField('Edited license:', `${args[0]}`)
.addField(`Removed HWID:`, `${args[2]}`)
.addField(`HWID-list now:`, hwidListFinal)
.setFooter(
`${client.config.name} | By @kassq`,
client.user.displayAvatarURL()
);
return await message.channel
.send(successEmbed)
.then(async (msg) => {
await msg.react('🆗');
});
} else {
return message.channel.send(
":x: Couldn't find that license!"
);
}
} else {
return await message.channel.send(
`:x: ${args[1]} is not a valid argument.`
);
}
}
} else {
return await console.log(
`${message.author.username} tried to use editlicense.`
);
}
}
);
}
};

View File

@ -0,0 +1,211 @@
const Discord = require('discord.js');
const Users = require('../models/userDB.js');
const moment = require('moment');
const { decrypt } = require('../auth/crypto.js');
exports.run = async (client, message, args) => {
if (!message.member.hasPermission('ADMINISTRATOR')) {
return await message.channel.send(
":x: You don't have enough permissions in this server!"
);
} else {
await Users.exists(
{ DiscordID: message.author.id },
async function (err, doc) {
if (err) {
await console.log(err);
await message.channel.send(
':x: Error occurred. Please contact my developer!'
);
}
if (doc === true) {
if (!args[0]) {
const exampleEmbed = new Discord.MessageEmbed()
.setColor(`${client.config.embed_color}`)
.setAuthor(
`Requested by ${message.author.username}`,
message.author.displayAvatarURL()
)
.setTitle('Getlicense command')
.setDescription(
"With this command you can get specific license's details!"
)
.addField(
'Command format:',
'This command takes 1 argument:\n`<license>`'
)
.addField(
'Example use case:',
'`+getlicense 1234-1234-1234-1234`\nThis example gives you details of license 1234-1234-1234-1234.'
)
.setFooter(
`${client.config.name} | By @kassq`,
client.user.displayAvatarURL()
);
return await message.channel
.send(exampleEmbed)
.then(async (msg) => {
await msg.react('🆗');
});
} else {
let User = await Users.findOne({
role: 0,
});
let licensekey = args[0];
let licenseToEdit;
for (let f = 0; f < User.licenses.length; f++) {
let licenseToSearch = User.licenses[f].licensekey;
let key = decrypt(licenseToSearch);
if (key === licensekey) {
licenseToEdit = licenseToSearch;
break;
}
}
if (licenseToEdit) {
const licensecheck = await Users.findOne({
role: 0,
licenses: {
$elemMatch: { licensekey: licenseToEdit },
},
});
if (!licensecheck) {
return await message.channel.send(
":x: Couldn't find that license!"
);
} else {
let licenseArray = licensecheck.licenses;
const result = licenseArray.find(
(element) =>
element.licensekey.iv ===
licenseToEdit.iv &&
element.licensekey.content ===
licenseToEdit.content
);
let timeBetween;
let timeLeft;
if (result.expires === 'Never') {
timeBetween = 'Unlimited';
timeLeft = 'Unlimited';
} else {
let a = moment(result.expires);
let b = moment(result.timestamp);
let eventdate = moment(result.expires);
let todaysdate = moment();
timeBetween = a.diff(b, 'days') + 1;
timeLeft = eventdate.diff(
todaysdate,
'days'
);
}
let IPlistlength;
let IPlistlist;
if (result.IPlist) {
IPlistlength = result.IPlist.length;
IPlistlist = result.IPlist.toString().replace(
/,/g,
'\n'
);
} else {
IPlistlength = '0';
IPlistlist = 'none';
}
let HWIDlist;
if (result.HWIDlist) {
HWIDlist = result.HWIDlist.toString().replace(
/,/g,
'\n'
);
} else {
HWIDlist = 'None';
}
const successEmbed = new Discord.MessageEmbed()
.setColor(`${client.config.embed_color}`)
.setAuthor(
`Requested by ${message.author.username}`,
message.author.displayAvatarURL()
)
.setTitle('License info')
.addField('License:', `${args[0]}`, false)
.addField(
'Client:',
`${result.clientname}`,
true
)
.addField(
'Plugin:',
`${result.pluginname || 'None'}`,
true
)
.addField(
'IP-cap',
`${IPlistlength}/${result.IPcap}`,
true
)
.addField(
`IP-list`,
`${IPlistlist || 'None'}`,
false
)
.addField(
`HWID-list`,
`${HWIDlist || 'None'}`,
false
)
.addField(
'Generate date:',
`${result.timestamp}`,
true
)
.addField(
'Duration:',
`${timeBetween} days`,
true
)
.addField(
'Expires in:',
`${timeLeft} days`,
true
)
.addField(
'Description:',
`${result.description || 'None'}`,
false
)
.addField(
'DiscordID:',
`${result.discordID || 'None'}`,
false
)
.addField(
'Latest IP:',
`${result.latestip || 'None'}`,
false
)
.setFooter(
`${client.config.name} | By @kassq`,
client.user.displayAvatarURL()
);
await message.channel
.send(successEmbed)
.then(async (msg) => {
await msg.react('🆗');
});
}
} else {
return message.channel.send(
":x: Couldn't find that license!"
);
}
}
} else {
return await console.log(
`${message.author.username} tried to use getlicense.`
);
}
}
);
}
};

View File

@ -0,0 +1,89 @@
const Discord = require('discord.js');
const Users = require('../models/userDB.js');
exports.run = async (client, message, args) => {
if (!message.member.hasPermission('ADMINISTRATOR')) {
return await message.channel.send(
":x: You don't have enough permissions in this server!"
);
} else {
await Users.exists(
{ DiscordID: message.author.id },
async function (err, doc) {
if (err) {
await console.log(err);
await message.channel.send(
':x: Error occurred. Please contact my developer!'
);
}
if (doc === true) {
const successEmbed = new Discord.MessageEmbed()
.setColor(`${client.config.embed_color}`)
.setAuthor(
`Requested by ${message.author.username}`,
message.author.displayAvatarURL()
)
.setTitle(`${client.config.name} - Commands`, true)
.addFields(
{
name: `${client.config.prefix}addlicense`,
value:
'Create new license with parameters like IPcap and Plugin name!',
},
{
name: `${client.config.prefix}removelicense`,
value: 'Remove existing license!',
},
{
name: `${client.config.prefix}getlicense`,
value: 'Get license details.',
},
{
name: `${client.config.prefix}editlicense`,
value: 'Edit existing license!',
},
{
name: `${client.config.prefix}licenselist`,
value: 'Get list of your licenses!',
},
{
name: `${client.config.prefix}cleardata`,
value:
'Clear HWID/IP data for all/specific license(s)!',
},
{
name: `${client.config.prefix}refreshclients`,
value:
'Refreshes client names that have a DiscordID!',
},
{
name: `${client.config.prefix}setversion`,
value:
'Set version of your plugin. You can use this version to notify your customer if he is using outdated version of your application!',
}
)
.addField(
'\u200b',
'**What is uLicense?**\nWe make it easy to license almost any application! Unique features, fair price point and fast support makes us an easy choice! Secure your application today! '
)
.addField(
'\u200b',
` [「McMarket」](https://www.mc-market.org/resources/18736/)\n [「Support」](https://discord.gg/YQnz8ymQmC)`
)
.setFooter(
`${client.config.name} | Made by @kassq`,
client.user.displayAvatarURL()
);
await message.channel
.send(successEmbed)
.then(async (msg) => {
await msg.react('🆗');
});
} else {
return await console.log(
`${message.author.username} tried to use help.`
);
}
}
);
}
};

View File

@ -0,0 +1,165 @@
const Discord = require('discord.js');
const Users = require('../models/userDB.js');
const { decrypt } = require('../auth/crypto.js');
exports.run = async (client, message, args) => {
if (!message.member.hasPermission('ADMINISTRATOR')) {
return await message.channel.send(
":x: You don't have enough permissions in this server!"
);
} else {
await Users.exists(
{ DiscordID: message.author.id },
async function (err, doc) {
if (err) {
await console.log(err);
await message.channel.send(
':x: Error occurred. Please contact my developer!'
);
}
if (doc === true) {
const User = await Users.find({
role: 0,
}).select('licenses -_id');
if (User[0].licenses.length < 1) {
return message.channel.send(
":x: Didn't find any licenses."
);
}
let page = Math.ceil(User[0].licenses.length / 10);
if (args[0]) {
if (!isNaN(args[0]) && args[0] <= page) {
let pageMulti = Math.round(args[0]);
let wantedPage = pageMulti * 10 - 10;
let results = [];
for (
let i = wantedPage;
i < User[0].licenses.length;
i++
) {
let maxResults = 10 + wantedPage;
let licenseToSearch = User[0].licenses[i];
let licenseEncrypted = decrypt(
licenseToSearch.licensekey
);
if (i < maxResults) {
results.push(
'Licensekey: ' +
'`' +
licenseEncrypted +
'`' +
'\n' +
'Client: ' +
'`' +
licenseToSearch.clientname +
'`' +
' | Plugin: ' +
'`' +
licenseToSearch.pluginname +
'`' +
'\n'
);
} else {
break;
}
}
const multiPage = new Discord.MessageEmbed()
.setColor(`${client.config.embed_color}`)
.setAuthor(
`Requested by ${message.author.username}`,
message.author.displayAvatarURL()
)
.setTitle(
`License list (Page ${pageMulti}/${page})`
)
.addField(
'\u200b',
`${results.toString().replace(/,/g, '\n')}`,
false
)
.addField(
'\u200b\nWant to get more details?',
`Use ${client.config.prefix}getlicense command for more specific information about licenses`
)
.setFooter(
`${client.config.name} | By @kassq`,
client.user.displayAvatarURL()
);
await message.channel
.send(multiPage)
.then(async (msg) => {
await msg.react('🆗');
});
} else {
return message.channel.send(
':x: Invalid page number as argument!'
);
}
} else {
let results = [];
for (let i = 0; i < User[0].licenses.length; i++) {
let maxResults = 10;
let licenseToSearch = User[0].licenses[i];
let licenseEncrypted = decrypt(
licenseToSearch.licensekey
);
if (i < maxResults) {
results.push(
'Licensekey: ' +
'`' +
licenseEncrypted +
'`' +
'\n' +
'Client: ' +
'`' +
licenseToSearch.clientname +
'`' +
' | Plugin: ' +
'`' +
(licenseToSearch.pluginname || 'None') +
'`' +
'\n'
);
} else {
break;
}
}
const successEmbed = new Discord.MessageEmbed()
.setColor(`${client.config.embed_color}`)
.setAuthor(
`Requested by ${message.author.username}`,
message.author.displayAvatarURL()
)
.setTitle(`License list (Page 1/${page})`)
.addField(
'\u200b',
`${results.toString().replace(/,/g, '\n')}`,
false
)
.addField(
'\u200b\nWant to get more details?',
`Use ${client.config.prefix}getlicense command for more specific information about licenses`
)
.setFooter(
`${client.config.name} | By @kassq`,
client.user.displayAvatarURL()
);
await message.channel
.send(successEmbed)
.then(async (msg) => {
await msg.react('🆗');
});
}
} else {
return await console.log(
`${message.author.username} tried to use licenselist.`
);
}
}
);
}
};

View File

@ -0,0 +1,130 @@
const Discord = require('discord.js');
const Users = require('../models/userDB.js');
const axios = require('axios');
exports.run = async (client, message, args) => {
if (!message.member.hasPermission('ADMINISTRATOR')) {
return await message.channel.send(
":x: You don't have enough permissions in this server!"
);
} else {
await Users.exists(
{ DiscordID: message.author.id },
async function (err, doc) {
if (err) {
await console.log(err);
await message.channel.send(
':x: Error occurred. Please contact my developer!'
);
}
if (doc === true) {
try {
let users = await Users.findOne({
role: 0,
});
let finalnumber = [];
for (let b = 0; b < users.licenses.length; b++) {
let clientToCheck = users.licenses[b];
if (
clientToCheck.discordID &&
isNaN(clientToCheck.discordID) === false &&
clientToCheck.discordID.length === 18
) {
await axios
.get(
`https://discordapp.com/api/users/${clientToCheck.discordID}`,
{
headers: {
Authorization: `Bot ${client.config.token}`,
},
}
)
.then(async (res) => {
await Users.updateMany(
{
role: 0,
'licenses.discordID':
res.data.id,
'licenses.clientname': {
$ne: res.data.username,
},
},
{
$set: {
'licenses.$[elem].clientname':
res.data.username,
},
},
{
arrayFilters: [
{
'elem.discordID':
res.data.id,
},
],
}
)
.then((doc) => {
finalnumber.push(doc.nModified);
})
.catch((err) => {
console.log(err);
});
})
.catch((err) => {
console.log(err);
});
}
}
if (finalnumber.reduce((a, b) => a + b, 0) > 0) {
let successEmbed = new Discord.MessageEmbed()
.setColor(`${client.config.embed_color}`)
.setAuthor(
`Requested by ${message.author.username}`,
message.author.displayAvatarURL()
)
.setTitle('Successfully updated client names')
.addField(
'Update client names:',
`${finalnumber.reduce((a, b) => a + b, 0)}`
)
.setFooter(
`${client.config.name} | By @kassq`,
client.user.displayAvatarURL()
);
return message.channel
.send(successEmbed)
.then(async (msg) => {
await msg.react('🆗');
});
} else {
let successEmbed = new Discord.MessageEmbed()
.setColor(`${client.config.embed_color}`)
.setAuthor(
`Requested by ${message.author.username}`,
message.author.displayAvatarURL()
)
.setTitle("Didn't find any changes")
.addField('Update client names:', `0`)
.setFooter(
`${client.config.name} | By @kassq`,
client.user.displayAvatarURL()
);
return message.channel
.send(successEmbed)
.then(async (msg) => {
await msg.react('🆗');
});
}
} catch (err) {
console.log(err);
return res.status(500).json({ msg: err.message });
}
} else {
return await console.log(
`${message.author.username} tried to use refreshclients.`
);
}
}
);
}
};

View File

@ -0,0 +1,116 @@
const Discord = require('discord.js');
const Users = require('../models/userDB.js');
const { decrypt } = require('../auth/crypto.js');
exports.run = async (client, message, args) => {
if (!message.member.hasPermission('ADMINISTRATOR')) {
return await message.channel.send(
":x: You don't have enough permissions in this server!"
);
} else {
await Users.exists(
{ DiscordID: message.author.id },
async function (err, doc) {
if (err) {
await console.log(err);
await message.channel.send(
':x: Error occurred. Please contact my developer!'
);
}
if (doc === true) {
if (!args[0]) {
const exampleEmbed = new Discord.MessageEmbed()
.setColor(`${client.config.embed_color}`)
.setAuthor(
`Requested by ${message.author.username}`,
message.author.displayAvatarURL()
)
.setTitle('Removelicense command')
.setDescription(
'With this command you can remove specific license key!'
)
.addField(
'Command format:',
'This command takes 1 argument:\n`<license>`'
)
.addField(
'Example use case:',
'`+removelicense 1234-1234-1234-1234`\nThis example completely removes license 1234-1234-1234-1234 from database. This action cannot be undone!'
)
.setFooter(
`${client.config.name} | By @kassq`,
client.user.displayAvatarURL()
);
return await message.channel
.send(exampleEmbed)
.then(async (msg) => {
await msg.react('🆗');
});
} else {
let User = await Users.findOne({
role: 0,
});
let licensekey = args[0];
let licenseToEdit;
for (let f = 0; f < User.licenses.length; f++) {
let licenseToSearch = User.licenses[f].licensekey;
let key = decrypt(licenseToSearch);
if (key === licensekey) {
licenseToEdit = licenseToSearch;
break;
}
}
if (licenseToEdit) {
const licensecheck = await Users.findOne({
role: 0,
licenses: {
$elemMatch: { licensekey: licenseToEdit },
},
});
if (!licensecheck) {
return await message.channel.send(
":x: Couldn't find that license!"
);
} else {
await Users.findOneAndUpdate(
{ role: 0 },
{
$pull: {
licenses: {
licensekey: licenseToEdit,
},
},
}
);
const successEmbed = new Discord.MessageEmbed()
.setColor(`${client.config.embed_color}`)
.setAuthor(
`Requested by ${message.author.username}`,
message.author.displayAvatarURL()
)
.setTitle('License removed')
.addField('Removed license:', `${args[0]}`)
.setFooter(
`${client.config.name} | By @kassq`,
client.user.displayAvatarURL()
);
return await message.channel
.send(successEmbed)
.then(async (msg) => {
await msg.react('🆗');
});
}
} else {
return message.channel.send(
":x: Couldn't find that license!"
);
}
}
} else {
return await console.log(
`${message.author.username} tried to use removelicense.`
);
}
}
);
}
};

View File

@ -0,0 +1,103 @@
const Discord = require('discord.js');
const Users = require('../models/userDB.js');
const Plugins = require('../models/pluginDB.js');
exports.run = async (client, message, args) => {
if (!message.member.hasPermission('ADMINISTRATOR')) {
return await message.channel.send(
":x: You don't have enough permissions in this server!"
);
} else {
await Users.exists(
{ DiscordID: message.author.id },
async function (err, doc) {
if (err) {
await console.log(err);
await message.channel.send(
':x: Error occurred. Please contact my developer!'
);
}
if (doc === true) {
if (!args[0] || !args[1]) {
const exampleEmbed = new Discord.MessageEmbed()
.setColor(`${client.config.embed_color}`)
.setAuthor(
`Requested by ${message.author.username}`,
message.author.displayAvatarURL()
)
.setTitle('Setversion command')
.setDescription(
'With this command you can set your latest application version number. You can use this number to check if your client is using outdated version!'
)
.addField(
'Command format:',
'This command takes 2 arguments:\n`<plugin> <version number>`'
)
.addField(
'Example use case:',
'`+setversion myplugin 2.0`\nThis example sets version number of myplugin to 2.0!'
)
.setFooter(
`${client.config.name} | By @kassq`,
client.user.displayAvatarURL()
);
return await message.channel
.send(exampleEmbed)
.then(async (msg) => {
await msg.react('🆗');
});
} else {
const licenseexists = await Users.findOne({
role: 0,
'licenses.pluginname': args[0],
});
if (!licenseexists) {
return message.channel.send(
':x: You havent created any license for given plugin. Keep in mind that this is case sensitive.'
);
}
const pluginexists = await Plugins.findOne({
plugin: args[0],
});
if (!pluginexists) {
const newPlugin = new Plugins({
plugin: args[0],
version: args[1],
});
await newPlugin.save();
} else {
await Plugins.findOneAndUpdate(
{
plugin: args[0],
},
{ $set: { version: args[1] } }
);
}
const successEmbed = new Discord.MessageEmbed()
.setColor(`${client.config.embed_color}`)
.setAuthor(
`Requested by ${message.author.username}`,
message.author.displayAvatarURL()
)
.setTitle('Updated version')
.addField('Plugin:', `${args[0]}`)
.addField('New version', args[1])
.setFooter(
`${client.config.name} | By @kassq`,
client.user.displayAvatarURL()
);
return await message.channel
.send(successEmbed)
.then(async (msg) => {
await msg.react('🆗');
});
}
} else {
return await console.log(
`${message.author.username} tried to use setversion.`
);
}
}
);
}
};

View File

@ -0,0 +1,9 @@
{
"prefix": "+",
"token": "DISCORD_BOT_TOKEN",
"serverID": "YOUR_DISCORD_SERVER_ID",
"name": "uLicense",
"embed_color": "BLUE",
"databaseURL": "YOUR_DATABASE_URL",
"encrypt_secret": "YOUR_ENCRYPT_SECRET"
}

View File

@ -0,0 +1,18 @@
module.exports = (client, msg) => {
if (msg.guild === null) return;
if (msg.guild.id != client.config.serverID) return;
if (msg.author.bot) return;
if (msg.content.indexOf(client.config.prefix) !== 0) return;
const args = msg.content
.slice(client.config.prefix.length)
.trim()
.split(/ +/g);
const command = client.commands.get(args.shift().toLowerCase());
if (!command) return;
console.log(
`\u001b[36m=> [${new Date().toLocaleTimeString()}] ${
msg.author.username
} used ${msg.content} command!`
);
command.run(client, msg, args);
};

View File

@ -0,0 +1,24 @@
module.exports = async (client) => {
await client.user.setActivity(`${client.config.name}`);
await console.log(`\u001b[36m`);
await console.log(
` \u001b[36m╭────────────────────────────────────────╮`
);
await console.log(
` \u001b[36m│ \x1b[37muLicense - Discord bot \u001b[36m│`
);
await console.log(
` \u001b[36m│ \u001b[36m│ \x1b[37mMade by`
);
await console.log(
` \u001b[36m│ \x1b[37mVersion \x1b[36m1.2.6 \x1b[37m| BETA \u001b[36m│ \x1b[37mkassq`
);
await console.log(
` \u001b[36m│ \x1b[37mRun \x1b[36mnpm i \x1b[37mto update dependencies \u001b[36m│`
);
await console.log(
` \u001b[36m╰────────────────────────────────────────╯`
);
await console.log(`\u001b[36m`);
await console.log(`=> Serving ${client.guilds.cache.size} servers.`);
};

View File

@ -0,0 +1,56 @@
const mongoose = require('mongoose');
const licensehistorySchema = new mongoose.Schema({
year: {
type: Number,
},
january: {
type: Number,
default: 0,
},
february: {
type: Number,
default: 0,
},
march: {
type: Number,
default: 0,
},
april: {
type: Number,
default: 0,
},
may: {
type: Number,
default: 0,
},
june: {
type: Number,
default: 0,
},
july: {
type: Number,
default: 0,
},
august: {
type: Number,
default: 0,
},
september: {
type: Number,
default: 0,
},
october: {
type: Number,
default: 0,
},
november: {
type: Number,
default: 0,
},
december: {
type: Number,
default: 0,
},
});
module.exports = mongoose.model('Licensehistory', licensehistorySchema);

View File

@ -0,0 +1,16 @@
const mongoose = require('mongoose');
const pluginsSchema = new mongoose.Schema(
{
plugin: {
type: String,
},
version: {
type: String,
},
},
{
timestamps: true,
}
);
module.exports = mongoose.model('Plugins', pluginsSchema);

View File

@ -0,0 +1,16 @@
const mongoose = require('mongoose');
const userSchema = new mongoose.Schema(
{
DiscordID: {
type: String,
},
licenses: {
type: Array,
},
},
{
timestamps: true,
}
);
module.exports = mongoose.model('Users', userSchema);

1242
uLicense-1.2.6/discord/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,19 @@
{
"name": "kassq",
"version": "1.0.0",
"description": "Good license system",
"main": "app.js",
"scripts": {
"start": "nodemon app.js"
},
"author": "kassq",
"license": "ISC",
"dependencies": {
"axios": "^0.21.1",
"crypto": "^1.0.1",
"discord.js": "^12.5.1",
"moment": "^2.29.1",
"mongoose": "^5.11.9",
"nodemon": "^2.0.6"
}
}

61
uLicense-1.2.6/iptables Normal file
View File

@ -0,0 +1,61 @@
# Generated by xtables-save v1.8.2 on Thu Jan 7 14:38:21 2021
#Recommended iptables for cloudflare
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:port-scanning - [0:0]
-A INPUT -s 173.245.48.0/20 -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -s 173.245.48.0/20 -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -s 103.21.244.0/22 -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -s 103.21.244.0/22 -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -s 103.22.200.0/22 -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -s 103.22.200.0/22 -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -s 103.31.4.0/22 -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -s 103.31.4.0/22 -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -s 141.101.64.0/18 -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -s 141.101.64.0/18 -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -s 108.162.192.0/18 -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -s 108.162.192.0/18 -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -s 190.93.240.0/20 -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -s 190.93.240.0/20 -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -s 188.114.96.0/20 -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -s 188.114.96.0/20 -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -s 197.234.240.0/22 -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -s 197.234.240.0/22 -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -s 198.41.128.0/17 -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -s 198.41.128.0/17 -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -s 162.158.0.0/15 -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -s 162.158.0.0/15 -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -s 104.16.0.0/12 -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -s 104.16.0.0/12 -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -s 172.64.0.0/13 -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -s 172.64.0.0/13 -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -s 172.64.0.0/13 -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -s 172.64.0.0/13 -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j DROP
-A INPUT -p tcp -m tcp --dport 443 -j DROP
-A INPUT -p tcp -m tcp --dport 22 -m conntrack --ctstate NEW -m recent --set --name DEFAULT --mask 255.255.255.255 --rsource
-A INPUT -p tcp -m tcp --dport 22 -m conntrack --ctstate NEW -m recent --update --seconds 60 --hitcount 10 --name DEFAULT --mask 255.255.255.255 --rsource -j DROP
-A port-scanning -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK RST -m limit --limit 1/sec --limit-burst 2 -j RETURN
-A port-scanning -j DROP
COMMIT
# Completed on Thu Jan 7 14:38:21 2021
# Generated by xtables-save v1.8.2 on Thu Jan 7 14:38:21 2021
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT
# Completed on Thu Jan 7 14:38:21 2021
# Generated by xtables-save v1.8.2 on Thu Jan 7 14:38:21 2021
*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
COMMIT
# Completed on Thu Jan 7 14:38:21 2021
# 157286

1311
uLicense-1.2.6/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,17 @@
{
"name": "start",
"version": "1.0.0",
"description": "Thanks for purchasing uLicense! <3",
"main": "index.js",
"scripts": {
"dashboard": "cd dashboard && nodemon server.js",
"discordbot": "cd discord && nodemon app.js",
"start": "concurrently \"npm run dashboard\" \"npm run discordbot\" "
},
"author": "",
"license": "ISC",
"dependencies": {
"concurrently": "^5.3.0",
"nodemon": "^2.0.7"
}
}