Compare commits
6 Commits
main
...
developmen
Author | SHA1 | Date | |
---|---|---|---|
db94e9fe49 | |||
9389d0c7e4 | |||
daf54267b4 | |||
acd6d2e9e2 | |||
cbdf039eab | |||
fa52034fb7 |
@ -5,3 +5,7 @@ ANNOUNCEMENT_KEY=text.
|
|||||||
GROQ_API_KEY=["groq_api"]
|
GROQ_API_KEY=["groq_api"]
|
||||||
NTFY_ALERT=ntfy_channel
|
NTFY_ALERT=ntfy_channel
|
||||||
DATA_PATH=where_to_store_data
|
DATA_PATH=where_to_store_data
|
||||||
|
NODE_ENV=production
|
||||||
|
DISCORD_AI_WEBHOOK=discord_webhook_url
|
||||||
|
PROCESSING_SERVER=https://git.ceres.rip/selenite/processing
|
||||||
|
PROCESSING_SERVER_SECRET=secret
|
25
accounts/music.js
Normal file
25
accounts/music.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import Soundcloud from 'lucida/streamers/soundcloud/main.js'
|
||||||
|
let clientId = process.env.SOUNDCLOUD_CLIENT_ID;
|
||||||
|
|
||||||
|
let sc = new Soundcloud({
|
||||||
|
// oauthToken: clientId
|
||||||
|
})
|
||||||
|
|
||||||
|
async function search(query) {
|
||||||
|
let data = sc.search(query);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
async function download(url) {
|
||||||
|
try {
|
||||||
|
const info = await sc.getByUrl(url);
|
||||||
|
|
||||||
|
const { stream } = await info.getStream();
|
||||||
|
|
||||||
|
return stream.path;
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Stream error:', err)
|
||||||
|
return(err.message || 'Failed to stream track')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { search, download };
|
@ -4,6 +4,7 @@ import sanitizeHtml from "sanitize-html";
|
|||||||
import sharp from "sharp";
|
import sharp from "sharp";
|
||||||
import { accs } from "../database.js";
|
import { accs } from "../database.js";
|
||||||
import { getUserFromCookie, isBanned, decryptCookie, verifyCookie } from "./manage.js";
|
import { getUserFromCookie, isBanned, decryptCookie, verifyCookie } from "./manage.js";
|
||||||
|
import { download } from "./music.js";
|
||||||
|
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import relativeTime from "dayjs/plugin/relativeTime.js";
|
import relativeTime from "dayjs/plugin/relativeTime.js";
|
||||||
@ -37,8 +38,8 @@ let rawProfileHTML = fs.readFileSync("./html/profile.html").toString();
|
|||||||
let rawEditProfileHTML = fs.readFileSync("./html/profile_edit.html").toString();
|
let rawEditProfileHTML = fs.readFileSync("./html/profile_edit.html").toString();
|
||||||
let profile404 = fs.readFileSync("./html/profile_404.html").toString();
|
let profile404 = fs.readFileSync("./html/profile_404.html").toString();
|
||||||
let profileBan = fs.readFileSync("./html/profile_ban.html").toString();
|
let profileBan = fs.readFileSync("./html/profile_ban.html").toString();
|
||||||
let gamesJSON = JSON.parse(fs.readFileSync("./selenite/data/games.json").toString());
|
let gamesJSON = JSON.parse(fs.readFileSync("./public/resources/games.json").toString());
|
||||||
let appsJSON = JSON.parse(fs.readFileSync("./selenite/data/apps.json").toString());
|
let appsJSON = JSON.parse(fs.readFileSync("./public/resources/apps.json").toString());
|
||||||
let profileReadyJSON = {};
|
let profileReadyJSON = {};
|
||||||
for (let i = 0; i < gamesJSON.length; i++) {
|
for (let i = 0; i < gamesJSON.length; i++) {
|
||||||
profileReadyJSON[gamesJSON[i].directory] = { name: gamesJSON[i].name, image: gamesJSON[i].image };
|
profileReadyJSON[gamesJSON[i].directory] = { name: gamesJSON[i].name, image: gamesJSON[i].image };
|
||||||
@ -193,21 +194,53 @@ async function editProfile(body, token, admin) {
|
|||||||
let fileType = (await fileTypeFromBuffer(pfp))["ext"];
|
let fileType = (await fileTypeFromBuffer(pfp))["ext"];
|
||||||
if (["png", "jpg", "gif", "avif", "webp", "tiff"].includes(fileType)) {
|
if (["png", "jpg", "gif", "avif", "webp", "tiff"].includes(fileType)) {
|
||||||
let url;
|
let url;
|
||||||
let dir = `${process.env.DATA_PATH}/data/${existingAccount.id}/`;
|
let dir = `${process.env.DATA_PATH}/data/${userData.id}/`;
|
||||||
let uuid = crypto.randomUUID();
|
let uuid = crypto.randomUUID();
|
||||||
let path = `${process.env.DATA_PATH}/data/${existingAccount.id}/${uuid}.webp`;
|
let path = `${process.env.DATA_PATH}/data/${userData.id}/${uuid}.webp`;
|
||||||
url = `/data/${existingAccount.id}/${uuid}.webp`;
|
url = `/data/${userData.id}/${uuid}.webp`;
|
||||||
fs.mkdirSync(dir, { recursive: true });
|
fs.mkdirSync(dir, { recursive: true });
|
||||||
fs.writeFileSync(path, "");
|
fs.writeFileSync(path, "");
|
||||||
await sharp(pfp, { animated: fileType == "gif" })
|
await sharp(pfp, { animated: fileType == "gif" })
|
||||||
.resize({ width: 300, withoutEnlargement: true })
|
.resize({ width: 300, withoutEnlargement: true })
|
||||||
.webp({ quality: 70, effort: 4 })
|
.webp({ quality: 70, effort: 4 })
|
||||||
.toFile(path);
|
.toFile(path);
|
||||||
await fs.unlink(`${__dirname}/${existingAccount.pfp_url}`, () => {});
|
await fs.unlink(`${__dirname}/${userData.pfp_url}`, () => {});
|
||||||
const updateAccount = accs.query(`UPDATE accounts SET pfp_url = $url WHERE username = $user`)
|
const updateAccount = accs.query(`UPDATE accounts SET pfp_url = $url WHERE username = $user`)
|
||||||
updateAccount.get({ $url: url, $user: user });
|
updateAccount.get({ $url: url, $user: user });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (body.artist) {
|
||||||
|
let checkStatus = new Request({
|
||||||
|
url: process.env.PROCESSING_SERVER + "/status"
|
||||||
|
});
|
||||||
|
let checkStatusRequest = await fetch(checkStatus);
|
||||||
|
if(checkStatusRequest.status != 200) {
|
||||||
|
return { success: false, err: "processing server is down, try again later"};
|
||||||
|
}
|
||||||
|
let path = await download(body.url);
|
||||||
|
console.log("exit download");
|
||||||
|
let file = Bun.file(path);
|
||||||
|
let request = new Request({
|
||||||
|
url: process.env.PROCESSING_SERVER + "/process",
|
||||||
|
method: "POST",
|
||||||
|
body: await file.arrayBuffer(),
|
||||||
|
headers: {
|
||||||
|
"X-Authentication": process.env.PROCESSING_SERVER_SECRET
|
||||||
|
}
|
||||||
|
});
|
||||||
|
console.log("created request");
|
||||||
|
let oggFile = await fetch(request);
|
||||||
|
console.log("finished request");
|
||||||
|
let filePath = `/data/${userData.id}/${crypto.randomUUID()}.ogg`;
|
||||||
|
await Bun.write(process.env.DATA_PATH + filePath, oggFile);
|
||||||
|
const updateAccount = accs.query(`UPDATE accounts SET music = $music WHERE username = $user`)
|
||||||
|
updateAccount.get({ $music: JSON.stringify({
|
||||||
|
path: filePath,
|
||||||
|
name: body.title,
|
||||||
|
artist: body.artist
|
||||||
|
}), $user: user });
|
||||||
|
console.log("database");
|
||||||
|
}
|
||||||
|
|
||||||
return { success: true };
|
return { success: true };
|
||||||
}
|
}
|
||||||
@ -228,6 +261,7 @@ async function generateAccountPage(name, cookie, admin) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let modifiedHTML = rawProfileHTML;
|
let modifiedHTML = rawProfileHTML;
|
||||||
|
let songData = JSON.parse(userData.music) || false;
|
||||||
modifiedHTML = modifiedHTML.replaceAll("{{ name }}", sanitizeHtml(userData.name, allowNone));
|
modifiedHTML = modifiedHTML.replaceAll("{{ name }}", sanitizeHtml(userData.name, allowNone));
|
||||||
modifiedHTML = modifiedHTML.replaceAll("{{ join_date }}", dayjs(userData.createdAt).fromNow());
|
modifiedHTML = modifiedHTML.replaceAll("{{ join_date }}", dayjs(userData.createdAt).fromNow());
|
||||||
modifiedHTML = modifiedHTML.replaceAll("{{ about }}", sanitizeHtml(userData.about, sanitizeConfig) || "No about me available..");
|
modifiedHTML = modifiedHTML.replaceAll("{{ about }}", sanitizeHtml(userData.about, sanitizeConfig) || "No about me available..");
|
||||||
@ -235,7 +269,15 @@ async function generateAccountPage(name, cookie, admin) {
|
|||||||
modifiedHTML = modifiedHTML.replaceAll("{{ user_pfp }}", userData.pfp_url || "/img/user.svg");
|
modifiedHTML = modifiedHTML.replaceAll("{{ user_pfp }}", userData.pfp_url || "/img/user.svg");
|
||||||
modifiedHTML = modifiedHTML.replaceAll("{{ custom_css }}", userData.custom_css || "");
|
modifiedHTML = modifiedHTML.replaceAll("{{ custom_css }}", userData.custom_css || "");
|
||||||
modifiedHTML = modifiedHTML.replaceAll("{{ online_time }}", dayjs(userData.last_login).fromNow());
|
modifiedHTML = modifiedHTML.replaceAll("{{ online_time }}", dayjs(userData.last_login).fromNow());
|
||||||
modifiedHTML = modifiedHTML.replaceAll("{{ played_games }}", buildGameHTML(userData));
|
modifiedHTML = modifiedHTML.replaceAll("{{ username }}", sanitizeHtml(userData.username, allowNone));
|
||||||
|
if(songData) {
|
||||||
|
modifiedHTML = modifiedHTML.replaceAll("{{ song_title }}", sanitizeHtml(songData.name, allowNone));
|
||||||
|
modifiedHTML = modifiedHTML.replaceAll("{{ song_artist }}", sanitizeHtml(songData.artist, allowNone));
|
||||||
|
modifiedHTML = modifiedHTML.replaceAll("{{ song_url }}", sanitizeHtml(songData.path, allowNone));
|
||||||
|
modifiedHTML = modifiedHTML.replaceAll("{{ is_music }}", "true");
|
||||||
|
} else {
|
||||||
|
modifiedHTML = modifiedHTML.replaceAll("{{ is_music }}", "false");
|
||||||
|
}
|
||||||
let badges_html = "";
|
let badges_html = "";
|
||||||
|
|
||||||
if (userData.badges !== null) {
|
if (userData.badges !== null) {
|
||||||
@ -260,6 +302,7 @@ async function generateAccountPage(name, cookie, admin) {
|
|||||||
return modified_ban;
|
return modified_ban;
|
||||||
}
|
}
|
||||||
let modifiedHTML = rawEditProfileHTML;
|
let modifiedHTML = rawEditProfileHTML;
|
||||||
|
let songData = JSON.parse(userData.music) || false;
|
||||||
modifiedHTML = modifiedHTML.replaceAll("{{ name }}", sanitizeHtml(userData.name, sanitizeConfig));
|
modifiedHTML = modifiedHTML.replaceAll("{{ name }}", sanitizeHtml(userData.name, sanitizeConfig));
|
||||||
modifiedHTML = modifiedHTML.replaceAll("{{ username }}", userData.username);
|
modifiedHTML = modifiedHTML.replaceAll("{{ username }}", userData.username);
|
||||||
modifiedHTML = modifiedHTML.replaceAll("{{ join_date }}", dayjs(userData.createdAt).fromNow());
|
modifiedHTML = modifiedHTML.replaceAll("{{ join_date }}", dayjs(userData.createdAt).fromNow());
|
||||||
@ -269,7 +312,14 @@ async function generateAccountPage(name, cookie, admin) {
|
|||||||
modifiedHTML = modifiedHTML.replaceAll("{{ url_gen }}", `https://selenite.cc/u/${userData.username}`);
|
modifiedHTML = modifiedHTML.replaceAll("{{ url_gen }}", `https://selenite.cc/u/${userData.username}`);
|
||||||
modifiedHTML = modifiedHTML.replaceAll("{{ online_time }}", dayjs(userData.last_login).fromNow());
|
modifiedHTML = modifiedHTML.replaceAll("{{ online_time }}", dayjs(userData.last_login).fromNow());
|
||||||
modifiedHTML = modifiedHTML.replaceAll("{{ css_edit }}", (userData.badges ? userData.badges.length : 0) > 0 ? '<img src="/img/edit.svg" id="edit" />' : "");
|
modifiedHTML = modifiedHTML.replaceAll("{{ css_edit }}", (userData.badges ? userData.badges.length : 0) > 0 ? '<img src="/img/edit.svg" id="edit" />' : "");
|
||||||
modifiedHTML = modifiedHTML.replaceAll("{{ played_games }}", buildGameHTML(userData));
|
if(songData) {
|
||||||
|
modifiedHTML = modifiedHTML.replaceAll("{{ song_title }}", sanitizeHtml(songData.name, allowNone));
|
||||||
|
modifiedHTML = modifiedHTML.replaceAll("{{ song_artist }}", sanitizeHtml(songData.artist, allowNone));
|
||||||
|
modifiedHTML = modifiedHTML.replaceAll("{{ song_url }}", sanitizeHtml(songData.path, allowNone));
|
||||||
|
modifiedHTML = modifiedHTML.replaceAll("{{ is_music }}", "true");
|
||||||
|
} else {
|
||||||
|
modifiedHTML = modifiedHTML.replaceAll("{{ is_music }}", "false");
|
||||||
|
}
|
||||||
let badges_html = "";
|
let badges_html = "";
|
||||||
|
|
||||||
if (userData.badges !== null) {
|
if (userData.badges !== null) {
|
||||||
@ -282,43 +332,7 @@ async function generateAccountPage(name, cookie, admin) {
|
|||||||
return modifiedHTML;
|
return modifiedHTML;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function buildGameHTML(existingAccount) {
|
|
||||||
if (existingAccount.playedgames) {
|
|
||||||
let games = JSON.parse(existingAccount.playedgames);
|
|
||||||
let sortedGames = Object.keys(games).sort((a, b) => games[b] - games[a]);
|
|
||||||
let return_data = [];
|
|
||||||
if (Object.keys(games).length < 10) {
|
|
||||||
for (let i = 0; i < sortedGames.length; i++) {
|
|
||||||
try {
|
|
||||||
let origin = gamesExceptions[sortedGames[i]] ? "sppa" : "semag";
|
|
||||||
sortedGames[i] = gamesExceptions[sortedGames[i]] ? gamesExceptions[sortedGames[i]] : sortedGames[i];
|
|
||||||
return_data[i] = { name: profileReadyJSON[sortedGames[i]].name, image: profileReadyJSON[sortedGames[i]].image, path: sortedGames[i], origin: origin, valid: true };
|
|
||||||
} catch (e) {
|
|
||||||
return_data[i] = { valid: false };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (let i = 0; i < 10; i++) {
|
|
||||||
try {
|
|
||||||
let origin = gamesExceptions[sortedGames[i]] ? "sppa" : "semag";
|
|
||||||
sortedGames[i] = gamesExceptions[sortedGames[i]] ? gamesExceptions[sortedGames[i]] : sortedGames[i];
|
|
||||||
return_data[i] = { name: profileReadyJSON[sortedGames[i]].name, image: profileReadyJSON[sortedGames[i]].image, path: sortedGames[i], origin: origin, valid: true };
|
|
||||||
} catch (e) {
|
|
||||||
return_data[i] = { valid: false };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let return_html = "";
|
|
||||||
for (let i = 0; i < Object.keys(return_data).length; i++) {
|
|
||||||
if (return_data[i].valid) {
|
|
||||||
return_html += `<div class="played-game"><img src="/${return_data[i].origin}/${return_data[i].path}/${return_data[i].image}"/><p>${return_data[i].name}</p></div>`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return return_html;
|
|
||||||
} else {
|
|
||||||
return "<h3>Play some games to view things appear here!</h3>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
async function getUsers(page, search) {
|
async function getUsers(page, search) {
|
||||||
let amount = 12;
|
let amount = 12;
|
||||||
if (!page) {
|
if (!page) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html class="sl-theme-dark" lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<!-- initialize theme vars
|
<!-- initialize theme vars
|
||||||
https://coolors.co/10002b-240046-3c096c-5a189a-7b2cbf-9d4edd-c77dff-e0aaff -->
|
https://coolors.co/10002b-240046-3c096c-5a189a-7b2cbf-9d4edd-c77dff-e0aaff -->
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html class="sl-theme-dark" lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<!-- initialize theme vars
|
<!-- initialize theme vars
|
||||||
https://coolors.co/10002b-240046-3c096c-5a189a-7b2cbf-9d4edd-c77dff-e0aaff -->
|
https://coolors.co/10002b-240046-3c096c-5a189a-7b2cbf-9d4edd-c77dff-e0aaff -->
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html class="sl-theme-dark" lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<!-- initialize theme vars
|
<!-- initialize theme vars
|
||||||
https://coolors.co/10002b-240046-3c096c-5a189a-7b2cbf-9d4edd-c77dff-e0aaff -->
|
https://coolors.co/10002b-240046-3c096c-5a189a-7b2cbf-9d4edd-c77dff-e0aaff -->
|
||||||
@ -14,7 +14,8 @@
|
|||||||
|
|
||||||
<script src="https://js.hcaptcha.com/1/api.js" async defer></script>
|
<script src="https://js.hcaptcha.com/1/api.js" async defer></script>
|
||||||
|
|
||||||
<link rel="stylesheet" href="/style.css" />
|
<link rel="stylesheet" href="/css/main.css" />
|
||||||
|
<link rel="stylesheet" href="/css/pages.css" />
|
||||||
|
|
||||||
<!-- seo + other things -->
|
<!-- seo + other things -->
|
||||||
<title>Login | Selenite</title>
|
<title>Login | Selenite</title>
|
||||||
@ -60,27 +61,17 @@
|
|||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<alerts> </alerts>
|
<alerts> </alerts>
|
||||||
<body id="noscroll">
|
<body>
|
||||||
<header>
|
<h2>login..</h2>
|
||||||
<a href="/index.html">Home</a>
|
|
||||||
<a href="/bookmarklets.html">Bookmarklets</a>
|
|
||||||
<a href="/projects.html">Games</a>
|
|
||||||
<a href="/apps.html">Apps</a>
|
|
||||||
<a href="/settings.html">Settings</a>
|
|
||||||
<a id="blank" href="#">Open Blank</a>
|
|
||||||
<a href="/u/" class="usericon"><img src="/img/user.svg" /></a>
|
|
||||||
</header>
|
|
||||||
<main id="main" class="noscroll">
|
|
||||||
<h2>Login to your account</h2>
|
|
||||||
<form onsubmit="return false;" id="login">
|
<form onsubmit="return false;" id="login">
|
||||||
<input type="text" id="username" placeholder="username" />
|
<input type="text" id="username" placeholder="username" />
|
||||||
<input type="password" id="password" placeholder="password" />
|
<input type="password" id="password" placeholder="password" />
|
||||||
<br />
|
<br />
|
||||||
<a href="/reset">Forgot password?</a> or <a href="/register">Create a free account</a><br />
|
|
||||||
<div class="h-captcha" id="hcaptcha" data-sitekey="1774ec96-39be-4fb0-9e82-f4c62354b8fa"></div>
|
<div class="h-captcha" id="hcaptcha" data-sitekey="1774ec96-39be-4fb0-9e82-f4c62354b8fa"></div>
|
||||||
<button type="submit" value="Submit">Login</button>
|
<a href="/reset">forgot password?</a><br />
|
||||||
|
<a href="/register">create a free account</a><br />
|
||||||
|
<button type="submit" value="Submit">login</button>
|
||||||
</form>
|
</form>
|
||||||
</main>
|
|
||||||
<popups>
|
<popups>
|
||||||
<div id="popup" style="display: none">
|
<div id="popup" style="display: none">
|
||||||
<h1 id="title"></h1>
|
<h1 id="title"></h1>
|
||||||
@ -88,13 +79,5 @@
|
|||||||
<button id="close">X</button>
|
<button id="close">X</button>
|
||||||
</div>
|
</div>
|
||||||
</popups>
|
</popups>
|
||||||
<footer class="noscroll">
|
|
||||||
<a href="https://gitlab.com/skysthelimit.dev/selenite">Source</a>
|
|
||||||
<a href="https://discord.gg/7jyufnwJNf">Discord</a>
|
|
||||||
<a href="/suggest.html">Suggestions & Bugs</a>
|
|
||||||
<a href="/contact.html">Contact</a>
|
|
||||||
<a href="/support.html">Donate</a>
|
|
||||||
<a href="/about.html">About</a>
|
|
||||||
</footer>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -1,67 +1,139 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html class="sl-theme-dark" lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<!-- initialize theme vars
|
<!-- initialize theme vars
|
||||||
https://coolors.co/10002b-240046-3c096c-5a189a-7b2cbf-9d4edd-c77dff-e0aaff -->
|
https://coolors.co/10002b-240046-3c096c-5a189a-7b2cbf-9d4edd-c77dff-e0aaff -->
|
||||||
|
|
||||||
<meta content="{{ name }}" property="og:title" />
|
|
||||||
<meta content="{{ about_none }}" property="og:description" />
|
|
||||||
<meta content="{{ user_pfp }}" property="og:image" />
|
|
||||||
<meta content="#c77dff" data-react-helmet="true" name="theme-color" />
|
|
||||||
<!-- initialize externals -->
|
<!-- initialize externals -->
|
||||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.0/jquery.min.js"></script>
|
<meta property="og:title" content="Selenite" />
|
||||||
<script src=" https://cdn.jsdelivr.net/npm/js-cookie@3.0.5/dist/js.cookie.min.js "></script>
|
<meta property="description" content="Selenite is the best unblocked games site. With over 400 games and an account system, no other websites come close to Selenite." />
|
||||||
|
<meta name="keywords" content="proxy, web proxy, unblock websites, unblock chromebook, free web proxy, proxy list, proxy sites, un block chromebook, online proxy, proxy server, proxysite, proxy youtube, bypass securly, bypass iboss, bypass lightspeed filter, chromebooks, unblock youtube, youtube proxy, unblocked youtube, youtube unblocked, unblock games, selenite, unblocked games, free games">
|
||||||
|
<meta content="/favicon.png" property="og:image" />
|
||||||
|
<meta content="#c77dff" data-react-helmet="true" name="theme-color" />
|
||||||
|
<meta name="googlebot" content="index, follow, snippet" />
|
||||||
|
<link rel="canonical" href="https://selenite.cc/" />
|
||||||
|
<meta property="og:description" content="Selenite is the best unblocked games site. With over 400 games and an account system, no other websites come close to Selenite." />
|
||||||
|
<meta property="og:title" content="Selenite">
|
||||||
|
<meta property="og:type" content="website">
|
||||||
|
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{
|
||||||
|
"@context": "https://schema.org",
|
||||||
|
"@type": "Organization",
|
||||||
|
"name": "Selenite",
|
||||||
|
"alternateName": "selenite.cc",
|
||||||
|
"url": "https://selenite.cc",
|
||||||
|
"logo": "https://selenite.cc/favicon.png",
|
||||||
|
"sameAs": [
|
||||||
|
"https://github.com/selenite-cc",
|
||||||
|
"https://youtube.com/@selenitecc",
|
||||||
|
"https://tiktok.com/@selenitecc",
|
||||||
|
"https://selenite.cc",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
<!-- initialize my stuff -->
|
<!-- initialize my stuff -->
|
||||||
<script src="/js/all.min.js"></script>
|
<script src="/js/all.js"></script>
|
||||||
<script src="/js/main.js"></script>
|
<script src="/js/main.js"></script>
|
||||||
|
|
||||||
<link rel="stylesheet" href="/style.css" />
|
<link rel="stylesheet" href="/css/main.css" />
|
||||||
|
<link rel="stylesheet" href="/css/pages.css" />
|
||||||
|
<link rel="stylesheet" href="/css/profile.css" />
|
||||||
|
<link rel="manifest" href="/manifest.json" />
|
||||||
<!-- seo + other things -->
|
<!-- seo + other things -->
|
||||||
<style>{{ custom_css }}</style>
|
|
||||||
<title>{{ name }}'s Profile | Selenite</title>
|
<title>{{ name }}'s Profile | Selenite</title>
|
||||||
<link rel="icon" href="/favicon.ico" />
|
<link rel="icon" href="/favicon.ico" />
|
||||||
|
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-3415518411898563" crossorigin="anonymous"></script>
|
||||||
|
<script>
|
||||||
|
document.addEventListener("DOMContentLoaded", ()=>{
|
||||||
|
let music = {{ is_music }};
|
||||||
|
let audioObject;
|
||||||
|
if(music) {
|
||||||
|
let url = "{{ song_url }}";
|
||||||
|
audioObject = new Audio(url);
|
||||||
|
audioObject.addEventListener("loadeddata", () => {
|
||||||
|
document.getElementById("totalLength").innerText = `${Math.floor(audioObject.duration/60)}:${String(Math.floor(audioObject.duration%60)).padStart(2, "0")}`;
|
||||||
|
document.getElementById("playbar").value = 0;
|
||||||
|
})
|
||||||
|
document.getElementById("enter").addEventListener("click", async ()=>{
|
||||||
|
document.getElementById("enter").style.backgroundColor = "#00000000"
|
||||||
|
document.getElementById("enter").style.backdropFilter = "blur(0px)"
|
||||||
|
document.getElementById("enter").style.opacity = "0";
|
||||||
|
setTimeout(() => {
|
||||||
|
audioObject.play();
|
||||||
|
audioObject.loop = true;
|
||||||
|
}, 500)
|
||||||
|
setTimeout( () => {
|
||||||
|
document.getElementById("enter").style.display = "none";
|
||||||
|
}, 950);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
document.getElementById("enter").style.display = "none";
|
||||||
|
document.querySelectorAll("section")[0].querySelectorAll(".profile-element")[1].style.display = "none";
|
||||||
|
}
|
||||||
|
document.getElementById("playPause").addEventListener("click", ()=>{
|
||||||
|
if(audioObject.paused) {
|
||||||
|
document.getElementById("playPause").src = "/img/pause.svg";
|
||||||
|
audioObject.play();
|
||||||
|
} else {
|
||||||
|
document.getElementById("playPause").src = "/img/play.svg";
|
||||||
|
audioObject.pause();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
document.getElementById("mute").addEventListener("click", ()=>{
|
||||||
|
if(audioObject.volume == 0) {
|
||||||
|
document.getElementById("mute").src = "/img/volume.svg";
|
||||||
|
audioObject.volume = 1;
|
||||||
|
} else {
|
||||||
|
document.getElementById("mute").src = "/img/muted.svg";
|
||||||
|
audioObject.volume = 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
document.getElementById("playbar").addEventListener("input", (e) => {
|
||||||
|
audioObject.currentTime = document.getElementById("playbar").value/1000*audioObject.duration;
|
||||||
|
document.getElementById("playbar").value = (audioObject.currentTime / audioObject.duration) * 1000;
|
||||||
|
});
|
||||||
|
audioObject.addEventListener("timeupdate", (e) => {
|
||||||
|
document.getElementById("totalLength").innerText = `${Math.floor(audioObject.duration/60)}:${String(Math.floor(audioObject.duration%60)).padStart(2, "0")}`
|
||||||
|
document.getElementById("curPos").innerText = `${Math.floor(audioObject.currentTime/60)}:${String(Math.floor(audioObject.currentTime%60)).padStart(2, "0")}`
|
||||||
|
document.getElementById("playbar").value = (audioObject.currentTime / audioObject.duration) * 1000;
|
||||||
|
})
|
||||||
|
})
|
||||||
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<alerts> </alerts>
|
<alerts> </alerts>
|
||||||
<body class="profile">
|
<body>
|
||||||
<header>
|
<div id="enter"><h1 class="title">click to enter</h1><p>this user selected a song, please mute the tab if you don't want to listen</p></div>
|
||||||
<a href="/index.html">Home</a>
|
<h1 class="title">{{ name }}'s profile</h1>
|
||||||
<a href="/bookmarklets.html">Bookmarklets</a>
|
<section>
|
||||||
<a href="/projects.html">Games</a>
|
<img src="{{ user_pfp }}" class="pfp" />
|
||||||
<a href="/apps.html">Apps</a>
|
<div class="profile-element">
|
||||||
<a href="/settings.html">Settings</a>
|
<h1>{{ name }}</h1>
|
||||||
<a id="blank" href="#">Open Blank</a>
|
<p>/u/{{ username }}</p>
|
||||||
<a href="/u/" class="usericon"><img src="/img/user.svg" /></a>
|
<div class="badges">{{ badges }}</div>
|
||||||
</header>
|
|
||||||
<main>
|
|
||||||
<div class="profile top">
|
|
||||||
<img src="{{ user_pfp }}" class="pfp" />
|
|
||||||
<div class="profile top text">
|
|
||||||
<h1>{{ name }}</h1>
|
|
||||||
<div class="samerow">{{ badges }}</div>
|
|
||||||
<h2>Joined {{ join_date }}</h2>
|
|
||||||
<h2>Last online {{ online_time }}</h2>
|
|
||||||
</div>
|
|
||||||
<div class="profile top text right">
|
|
||||||
<h1>About Me</h1>
|
|
||||||
<h2 class="about">{{ about }}</h2>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="profile played">
|
<div class="profile-element">
|
||||||
<h2>Top Games:</h2>
|
<h2>{{ song_title }}</h2>
|
||||||
<div id="played-games">
|
<h3>{{ song_artist }}</h3>
|
||||||
{{ played_games }}
|
<div class="samerow">
|
||||||
</div>
|
<p id="curPos">0:00</p>
|
||||||
|
<input type="range" id="playbar" min="1" max="1000" />
|
||||||
|
<p id="totalLength">9:99</p>
|
||||||
|
</div>
|
||||||
|
<div class="samerow">
|
||||||
|
<img id="playPause" src="/img/pause.svg" class="controls"/>
|
||||||
|
<img id="mute" src="/img/volume.svg" class="controls"/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
<div class="profile-element">
|
||||||
<footer>
|
<h2>Joined {{ join_date }}</h2>
|
||||||
<a href="https://gitlab.com/skysthelimit.dev/selenite">Source</a>
|
<h2>Last online {{ online_time }}</h2>
|
||||||
<a href="https://discord.gg/7jyufnwJNf">Discord</a>
|
</div>
|
||||||
<a href="/suggest.html">Suggestions & Bugs</a>
|
</section>
|
||||||
<a href="/contact.html">Contact</a>
|
<section class="column">
|
||||||
<a href="/support.html">Donate</a>
|
<h1>about me</h1>
|
||||||
<a href="/about.html">About</a>
|
<p>{{ about }}</p>
|
||||||
</footer>
|
</section>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html class="sl-theme-dark" lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<!-- initialize theme vars
|
<!-- initialize theme vars
|
||||||
https://coolors.co/10002b-240046-3c096c-5a189a-7b2cbf-9d4edd-c77dff-e0aaff -->
|
https://coolors.co/10002b-240046-3c096c-5a189a-7b2cbf-9d4edd-c77dff-e0aaff -->
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html class="sl-theme-dark" lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<!-- initialize theme vars
|
<!-- initialize theme vars
|
||||||
https://coolors.co/10002b-240046-3c096c-5a189a-7b2cbf-9d4edd-c77dff-e0aaff -->
|
https://coolors.co/10002b-240046-3c096c-5a189a-7b2cbf-9d4edd-c77dff-e0aaff -->
|
||||||
|
@ -1,25 +1,73 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html class="sl-theme-dark" lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<!-- initialize theme vars
|
<!-- initialize theme vars
|
||||||
https://coolors.co/10002b-240046-3c096c-5a189a-7b2cbf-9d4edd-c77dff-e0aaff -->
|
https://coolors.co/10002b-240046-3c096c-5a189a-7b2cbf-9d4edd-c77dff-e0aaff -->
|
||||||
|
|
||||||
<!-- initialize externals -->
|
<!-- initialize externals -->
|
||||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.0/jquery.min.js"></script>
|
<meta property="og:title" content="Selenite" />
|
||||||
<script src=" https://cdn.jsdelivr.net/npm/js-cookie@3.0.5/dist/js.cookie.min.js "></script>
|
<meta property="description" content="Selenite is the best unblocked games site. With over 400 games and an account system, no other websites come close to Selenite." />
|
||||||
|
<meta name="keywords" content="proxy, web proxy, unblock websites, unblock chromebook, free web proxy, proxy list, proxy sites, un block chromebook, online proxy, proxy server, proxysite, proxy youtube, bypass securly, bypass iboss, bypass lightspeed filter, chromebooks, unblock youtube, youtube proxy, unblocked youtube, youtube unblocked, unblock games, selenite, unblocked games, free games">
|
||||||
|
<meta content="/favicon.png" property="og:image" />
|
||||||
|
<meta content="#c77dff" data-react-helmet="true" name="theme-color" />
|
||||||
|
<meta name="googlebot" content="index, follow, snippet" />
|
||||||
|
<link rel="canonical" href="https://selenite.cc/" />
|
||||||
|
<meta property="og:description" content="Selenite is the best unblocked games site. With over 400 games and an account system, no other websites come close to Selenite." />
|
||||||
|
<meta property="og:title" content="Selenite">
|
||||||
|
<meta property="og:type" content="website">
|
||||||
|
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{
|
||||||
|
"@context": "https://schema.org",
|
||||||
|
"@type": "Organization",
|
||||||
|
"name": "Selenite",
|
||||||
|
"alternateName": "selenite.cc",
|
||||||
|
"url": "https://selenite.cc",
|
||||||
|
"logo": "https://selenite.cc/favicon.png",
|
||||||
|
"sameAs": [
|
||||||
|
"https://github.com/selenite-cc",
|
||||||
|
"https://youtube.com/@selenitecc",
|
||||||
|
"https://tiktok.com/@selenitecc",
|
||||||
|
"https://selenite.cc",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
<!-- initialize my stuff -->
|
<!-- initialize my stuff -->
|
||||||
<script src="/js/all.min.js"></script>
|
<script src="/js/all.js"></script>
|
||||||
<script src="/js/main.js"></script>
|
<script src="/js/main.js"></script>
|
||||||
|
|
||||||
<link rel="stylesheet" href="/style.css" />
|
<link rel="stylesheet" href="/css/main.css" />
|
||||||
|
<link rel="stylesheet" href="/css/pages.css" />
|
||||||
|
<link rel="stylesheet" href="/css/profile.css" />
|
||||||
|
<link rel="manifest" href="/manifest.json" />
|
||||||
<!-- seo + other things -->
|
<!-- seo + other things -->
|
||||||
<title>{{ name }}'s Profile | Selenite</title>
|
<title>{{ name }}'s Profile | Selenite</title>
|
||||||
<link rel="icon" href="/favicon.ico" />
|
<link rel="icon" href="/favicon.ico" />
|
||||||
|
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-3415518411898563" crossorigin="anonymous"></script>
|
||||||
|
<!-- <script>
|
||||||
|
let audioObject;
|
||||||
|
document.addEventListener("DOMContentLoaded", ()=>{
|
||||||
|
let music = false; // {{ is_music }}
|
||||||
|
if(music) {
|
||||||
|
let url = "/api/music/download?url=https://soundcloud.com/archive5077/fostered-alcoholism-grayskies"; // {{ music_url }}
|
||||||
|
let audioObject = new Audio(url);
|
||||||
|
document.getElementById("enter").addEventListener("click", async ()=>{
|
||||||
|
document.getElementById("enter").style.backgroundColor = "#00000000"
|
||||||
|
document.getElementById("enter").style.backdropFilter = "blur(0px)"
|
||||||
|
document.getElementById("enter").style.opacity = "0";
|
||||||
|
setTimeout( () => {
|
||||||
|
document.getElementById("enter").style.display = "none";
|
||||||
|
audioObject.play();
|
||||||
|
}, 700);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script> -->
|
||||||
<script>
|
<script>
|
||||||
let username = "{{ username }}";
|
let username = "{{ username }}";
|
||||||
let userData;
|
let userData;
|
||||||
|
let songData;
|
||||||
(async () => {
|
(async () => {
|
||||||
userData = await (await fetch("/u/raw")).json();
|
userData = await (await fetch("/u/raw")).json();
|
||||||
})();
|
})();
|
||||||
@ -53,6 +101,9 @@
|
|||||||
console.log("promise finished");
|
console.log("promise finished");
|
||||||
body = { pfp: fileData };
|
body = { pfp: fileData };
|
||||||
console.log("body set");
|
console.log("body set");
|
||||||
|
} else if (state == "song") {
|
||||||
|
body = songData;
|
||||||
|
console.log("body set");
|
||||||
} else if (state == "clearpfp") {
|
} else if (state == "clearpfp") {
|
||||||
body = { pfp: "del" };
|
body = { pfp: "del" };
|
||||||
} else if (state == "close") {
|
} else if (state == "close") {
|
||||||
@ -79,10 +130,12 @@
|
|||||||
document.getElementById("title").innerText = "Upload successful!";
|
document.getElementById("title").innerText = "Upload successful!";
|
||||||
document.getElementById("text").style.display = "none";
|
document.getElementById("text").style.display = "none";
|
||||||
document.getElementById("popup").style.display = "flex";
|
document.getElementById("popup").style.display = "flex";
|
||||||
|
document.getElementById("blur").style.display = "flex";
|
||||||
} else {
|
} else {
|
||||||
document.getElementById("title").innerText = "Upload failed. This probably means something bad happened, send an email to support@selenite.cc or ping @skysthelimit.dev";
|
document.getElementById("title").innerText = "Upload failed. This probably means something bad happened, send an email to support@selenite.cc or ping @skysthelimit.dev";
|
||||||
document.getElementById("text").style.display = "none";
|
document.getElementById("text").style.display = "none";
|
||||||
document.getElementById("popup").style.display = "flex";
|
document.getElementById("popup").style.display = "flex";
|
||||||
|
document.getElementById("blur").style.display = "flex";
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
} else if (state == "download") {
|
} else if (state == "download") {
|
||||||
@ -105,11 +158,13 @@
|
|||||||
document.getElementById("title").innerText = "Download successful!";
|
document.getElementById("title").innerText = "Download successful!";
|
||||||
document.getElementById("text").style.display = "none";
|
document.getElementById("text").style.display = "none";
|
||||||
document.getElementById("popup").style.display = "flex";
|
document.getElementById("popup").style.display = "flex";
|
||||||
|
document.getElementById("blur").style.display = "flex";
|
||||||
} else {
|
} else {
|
||||||
document.getElementById("title").innerText = "Download failed.";
|
document.getElementById("title").innerText = "Download failed.";
|
||||||
document.getElementById("body-text").innerText = data.reason;
|
document.getElementById("body-text").innerText = data.reason;
|
||||||
document.getElementById("body-text").style.display = "flex";
|
document.getElementById("body-text").style.display = "flex";
|
||||||
document.getElementById("popup").style.display = "flex";
|
document.getElementById("popup").style.display = "flex";
|
||||||
|
document.getElementById("blur").style.display = "flex";
|
||||||
}
|
}
|
||||||
console.log(data);
|
console.log(data);
|
||||||
data = JSON.parse(data.data);
|
data = JSON.parse(data.data);
|
||||||
@ -131,7 +186,19 @@
|
|||||||
}
|
}
|
||||||
console.log("sending");
|
console.log("sending");
|
||||||
body.username = username;
|
body.username = username;
|
||||||
await fetch("/api/profile/edit", {
|
document.getElementById("title").innerText = "processing...";
|
||||||
|
document.getElementById("pfp_upload").style.display = "none";
|
||||||
|
document.getElementById("pfp_reminder").style.display = "none";
|
||||||
|
document.getElementById("body-text").style.display = "none";
|
||||||
|
document.getElementById("clear").style.display = "none";
|
||||||
|
document.getElementById("text").style.display = "none";
|
||||||
|
document.getElementById("counter").style.display = "none";
|
||||||
|
document.getElementById("submit").style.display = "none";
|
||||||
|
document.getElementById("search").style.display = "none";
|
||||||
|
document.querySelector("results").style.display = "none";
|
||||||
|
document.getElementById("popup").style.display = "flex";
|
||||||
|
document.getElementById("blur").style.display = "flex";
|
||||||
|
let data = await fetch("/api/profile/edit", {
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-type": "application/json; charset=UTF-8",
|
"Content-type": "application/json; charset=UTF-8",
|
||||||
@ -140,9 +207,24 @@
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
mode: "cors",
|
mode: "cors",
|
||||||
});
|
});
|
||||||
console.log("sent");
|
let resp = await data.json();
|
||||||
document.getElementById("popup").style.display = "none";
|
if(data.status == 200) {
|
||||||
location.reload();
|
location.reload();
|
||||||
|
} else {
|
||||||
|
document.getElementById("title").innerText = "error!";
|
||||||
|
document.getElementById("pfp_upload").style.display = "none";
|
||||||
|
document.getElementById("pfp_reminder").style.display = "none";
|
||||||
|
document.getElementById("body-text").style.display = "flex";
|
||||||
|
document.getElementById("body-text").innerText = resp.err;
|
||||||
|
document.getElementById("clear").style.display = "none";
|
||||||
|
document.getElementById("text").style.display = "none";
|
||||||
|
document.getElementById("counter").style.display = "none";
|
||||||
|
document.getElementById("submit").style.display = "none";
|
||||||
|
document.getElementById("search").style.display = "none";
|
||||||
|
document.querySelector("results").style.display = "none";
|
||||||
|
document.getElementById("popup").style.display = "flex";
|
||||||
|
document.getElementById("blur").style.display = "flex";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
document.addEventListener("DOMContentLoaded", async () => {
|
document.addEventListener("DOMContentLoaded", async () => {
|
||||||
document.getElementById("pfp_upload").addEventListener("change", (e) => {
|
document.getElementById("pfp_upload").addEventListener("change", (e) => {
|
||||||
@ -153,71 +235,108 @@
|
|||||||
});
|
});
|
||||||
document.getElementById("submit").addEventListener("click", await setProfile);
|
document.getElementById("submit").addEventListener("click", await setProfile);
|
||||||
document.getElementById("clear").addEventListener("click", async()=>{state="clearpfp";await setProfile()});
|
document.getElementById("clear").addEventListener("click", async()=>{state="clearpfp";await setProfile()});
|
||||||
document.querySelectorAll("#edit").forEach((element) => {
|
document.getElementById("pfp").addEventListener("click", () => {
|
||||||
element.addEventListener("click", (e) => {
|
state = "pfp";
|
||||||
console.log(e.target.parentElement.children[0].id);
|
document.getElementById("title").innerText = "upload a new profile picture";
|
||||||
if (e.target.parentElement.children[0].id == "name") {
|
document.getElementById("pfp_upload").style.display = "flex";
|
||||||
state = "name";
|
document.getElementById("pfp_reminder").style.display = "flex";
|
||||||
document.getElementById("title").innerText = "Set your name.";
|
document.getElementById("body-text").style.display = "none";
|
||||||
document.getElementById("text").setAttribute("maxlength", "20");
|
document.getElementById("clear").style.display = "flex";
|
||||||
document.getElementById("pfp_upload").style.display = "none";
|
document.getElementById("text").style.display = "none";
|
||||||
document.getElementById("pfp_reminder").style.display = "none";
|
document.getElementById("counter").style.display = "none";
|
||||||
document.getElementById("body-text").style.display = "none";
|
document.getElementById("submit").style.display = "flex";
|
||||||
document.getElementById("clear").style.display = "none";
|
document.getElementById("popup").style.display = "flex";
|
||||||
document.getElementById("text").style.display = "flex";
|
document.getElementById("blur").style.display = "flex";
|
||||||
document.getElementById("text").value = userData["name"];
|
document.getElementById("search").style.display = "none";
|
||||||
document.getElementById("counter").innerText = `${document.getElementById("text").value.length} / ${document.getElementById("text").attributes.maxlength.value}`;
|
document.querySelector("results").style.display = "none";
|
||||||
document.getElementById("counter").style.display = "flex";
|
|
||||||
document.getElementById("submit").style.display = "flex";
|
|
||||||
document.getElementById("popup").style.display = "flex";
|
|
||||||
} else if (e.target.parentElement.children[0].id == "bio") {
|
|
||||||
state = "bio";
|
|
||||||
document.getElementById("title").innerText = "Set your about me.";
|
|
||||||
document.getElementById("text").setAttribute("maxlength", "200");
|
|
||||||
document.getElementById("pfp_upload").style.display = "none";
|
|
||||||
document.getElementById("pfp_reminder").style.display = "none";
|
|
||||||
document.getElementById("body-text").style.display = "none";
|
|
||||||
document.getElementById("clear").style.display = "none";
|
|
||||||
document.getElementById("text").style.display = "flex";
|
|
||||||
document.getElementById("text").value = userData["about"];
|
|
||||||
document.getElementById("counter").innerText = `${document.getElementById("text").value.length} / ${document.getElementById("text").attributes.maxlength.value}`;
|
|
||||||
document.getElementById("counter").style.display = "flex";
|
|
||||||
document.getElementById("submit").style.display = "flex";
|
|
||||||
document.getElementById("popup").style.display = "flex";
|
|
||||||
} else if (e.target.parentElement.children[0].id == "custom") {
|
|
||||||
state = "custom";
|
|
||||||
document.getElementById("title").innerText = "Set your custom CSS.";
|
|
||||||
document.getElementById("text").setAttribute("maxlength", "2048");
|
|
||||||
document.getElementById("pfp_upload").style.display = "none";
|
|
||||||
document.getElementById("pfp_reminder").style.display = "none";
|
|
||||||
document.getElementById("body-text").style.display = "none";
|
|
||||||
document.getElementById("clear").style.display = "none";
|
|
||||||
document.getElementById("text").style.display = "flex";
|
|
||||||
document.getElementById("text").value = userData["css"];
|
|
||||||
document.getElementById("counter").innerText = `${document.getElementById("text").value.length} / ${document.getElementById("text").attributes.maxlength.value}`;
|
|
||||||
document.getElementById("counter").style.display = "flex";
|
|
||||||
document.getElementById("submit").style.display = "flex";
|
|
||||||
document.getElementById("popup").style.display = "flex";
|
|
||||||
} else if (e.target.parentElement.children[0].id == "pfp") {
|
|
||||||
state = "pfp";
|
|
||||||
document.getElementById("title").innerText = "Set your new profile picture.";
|
|
||||||
document.getElementById("pfp_upload").style.display = "flex";
|
|
||||||
document.getElementById("pfp_reminder").style.display = "flex";
|
|
||||||
document.getElementById("body-text").style.display = "none";
|
|
||||||
document.getElementById("clear").style.display = "flex";
|
|
||||||
document.getElementById("text").style.display = "none";
|
|
||||||
document.getElementById("counter").style.display = "none";
|
|
||||||
document.getElementById("submit").style.display = "flex";
|
|
||||||
document.getElementById("popup").style.display = "flex";
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
document.getElementById("name").addEventListener("click", () => {
|
||||||
|
state = "name";
|
||||||
|
document.getElementById("title").innerText = "change your name";
|
||||||
|
document.getElementById("text").setAttribute("maxlength", "20");
|
||||||
|
document.getElementById("pfp_upload").style.display = "none";
|
||||||
|
document.getElementById("pfp_reminder").style.display = "none";
|
||||||
|
document.getElementById("body-text").style.display = "none";
|
||||||
|
document.getElementById("clear").style.display = "none";
|
||||||
|
document.getElementById("text").style.display = "flex";
|
||||||
|
document.getElementById("text").value = userData["name"];
|
||||||
|
document.getElementById("counter").innerText = `${document.getElementById("text").value.length} / ${document.getElementById("text").attributes.maxlength.value}`;
|
||||||
|
document.getElementById("counter").style.display = "flex";
|
||||||
|
document.getElementById("submit").style.display = "flex";
|
||||||
|
document.getElementById("popup").style.display = "flex";
|
||||||
|
document.getElementById("blur").style.display = "flex";
|
||||||
|
document.getElementById("search").style.display = "none";
|
||||||
|
document.querySelector("results").style.display = "none";
|
||||||
|
});
|
||||||
|
document.getElementById("about").addEventListener("click", () => {
|
||||||
|
state = "bio";
|
||||||
|
document.getElementById("title").innerText = "change your about me";
|
||||||
|
document.getElementById("text").setAttribute("maxlength", "200");
|
||||||
|
document.getElementById("pfp_upload").style.display = "none";
|
||||||
|
document.getElementById("pfp_reminder").style.display = "none";
|
||||||
|
document.getElementById("body-text").style.display = "none";
|
||||||
|
document.getElementById("clear").style.display = "none";
|
||||||
|
document.getElementById("text").style.display = "flex";
|
||||||
|
document.getElementById("text").value = userData["about"];
|
||||||
|
document.getElementById("counter").innerText = `${document.getElementById("text").value.length} / ${document.getElementById("text").attributes.maxlength.value}`;
|
||||||
|
document.getElementById("counter").style.display = "flex";
|
||||||
|
document.getElementById("submit").style.display = "flex";
|
||||||
|
document.getElementById("popup").style.display = "flex";
|
||||||
|
document.getElementById("blur").style.display = "flex";
|
||||||
|
document.getElementById("search").style.display = "none";
|
||||||
|
document.querySelector("results").style.display = "none";
|
||||||
|
});
|
||||||
|
document.getElementById("song").addEventListener("click", () => {
|
||||||
|
state = "song";
|
||||||
|
document.getElementById("title").innerText = "pick a song";
|
||||||
|
document.getElementById("text").setAttribute("maxlength", "2048");
|
||||||
|
document.getElementById("pfp_upload").style.display = "none";
|
||||||
|
document.getElementById("pfp_reminder").style.display = "none";
|
||||||
|
document.getElementById("body-text").style.display = "none";
|
||||||
|
document.getElementById("clear").style.display = "none";
|
||||||
|
document.getElementById("text").style.display = "none";
|
||||||
|
document.getElementById("counter").style.display = "none";
|
||||||
|
document.getElementById("submit").style.display = "none";
|
||||||
|
document.getElementById("popup").style.display = "flex";
|
||||||
|
document.getElementById("blur").style.display = "flex";
|
||||||
|
document.getElementById("search").style.display = "flex";
|
||||||
|
document.querySelector("results").style.display = "flex";
|
||||||
|
})
|
||||||
document.getElementById("close").addEventListener("click", () => {
|
document.getElementById("close").addEventListener("click", () => {
|
||||||
document.getElementById("popup").style.display = "none";
|
document.getElementById("popup").style.display = "none";
|
||||||
|
document.getElementById("blur").style.display = "none";
|
||||||
});
|
});
|
||||||
document.getElementById("text").addEventListener("input", () => {
|
document.getElementById("text").addEventListener("input", () => {
|
||||||
document.getElementById("counter").innerText = `${document.getElementById("text").value.length} / ${document.getElementById("text").attributes.maxlength.value}`;
|
document.getElementById("counter").innerText = `${document.getElementById("text").value.length} / ${document.getElementById("text").attributes.maxlength.value}`;
|
||||||
});
|
});
|
||||||
|
document.getElementById("search").addEventListener("input", async ()=>{
|
||||||
|
if(document.getElementById("search").value.length > 0) {
|
||||||
|
let query = document.getElementById("search").value;
|
||||||
|
let results = await fetch("/api/music/search?q=" + encodeURIComponent(document.getElementById("search").value));
|
||||||
|
let json = await results.json();
|
||||||
|
if(document.getElementById("search").value == query) {
|
||||||
|
document.querySelector("results").display = "flex";
|
||||||
|
console.log("searched")
|
||||||
|
let i = 0;
|
||||||
|
json.tracks.forEach((e)=>{
|
||||||
|
document.querySelectorAll("result")[i].querySelector("h2").innerText = e.title;
|
||||||
|
document.querySelectorAll("result")[i].querySelectorAll("p")[0].innerText = e.artists[0].name;
|
||||||
|
document.querySelectorAll("result")[i].querySelectorAll("p")[1].innerText = e.url.slice(22);
|
||||||
|
document.querySelectorAll("result")[i].setAttribute("data-url", e.url);
|
||||||
|
document.querySelectorAll("result")[i].style.display = "flex";
|
||||||
|
i++;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
document.querySelectorAll("result").forEach((e) => {
|
||||||
|
e.removeAttribute("data-url");
|
||||||
|
e.querySelector("h2").innerText = null;
|
||||||
|
e.querySelectorAll("p")[0].innerText = null;
|
||||||
|
e.querySelectorAll("p")[1].innerText = null;
|
||||||
|
e.style.display = "none";
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
document.getElementById("upload").addEventListener("click", async () => {
|
document.getElementById("upload").addEventListener("click", async () => {
|
||||||
state = "upload";
|
state = "upload";
|
||||||
document.getElementById("title").innerText = "Warning";
|
document.getElementById("title").innerText = "Warning";
|
||||||
@ -230,6 +349,7 @@
|
|||||||
document.getElementById("counter").style.display = "none";
|
document.getElementById("counter").style.display = "none";
|
||||||
document.getElementById("submit").style.display = "flex";
|
document.getElementById("submit").style.display = "flex";
|
||||||
document.getElementById("popup").style.display = "flex";
|
document.getElementById("popup").style.display = "flex";
|
||||||
|
document.getElementById("blur").style.display = "flex";
|
||||||
});
|
});
|
||||||
document.getElementById("download").addEventListener("click", async () => {
|
document.getElementById("download").addEventListener("click", async () => {
|
||||||
state = "download";
|
state = "download";
|
||||||
@ -243,79 +363,84 @@
|
|||||||
document.getElementById("counter").style.display = "none";
|
document.getElementById("counter").style.display = "none";
|
||||||
document.getElementById("submit").style.display = "flex";
|
document.getElementById("submit").style.display = "flex";
|
||||||
document.getElementById("popup").style.display = "flex";
|
document.getElementById("popup").style.display = "flex";
|
||||||
|
document.getElementById("blur").style.display = "flex";
|
||||||
|
});
|
||||||
|
document.querySelectorAll("result").forEach(async e => {
|
||||||
|
e.addEventListener("click", async (element) => {
|
||||||
|
songData = {
|
||||||
|
url: e.getAttribute("data-url"),
|
||||||
|
title: e.childNodes[0].innerText,
|
||||||
|
artist: e.childNodes[1].innerText,
|
||||||
|
}
|
||||||
|
console.log(songData);
|
||||||
|
await setProfile();
|
||||||
|
})
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<alerts> </alerts>
|
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<div id="blur"></div>
|
||||||
<a href="/index.html">Home</a>
|
<div id="popup" style="display: none">
|
||||||
<a href="/bookmarklets.html">Bookmarklets</a>
|
<h1 id="title"></h1>
|
||||||
<a href="/projects.html">Games</a>
|
<p id="body-text"></p>
|
||||||
<a href="/apps.html">Apps</a>
|
<input type="text" id="text" />
|
||||||
<a href="/settings.html">Settings</a>
|
<input type="text" id="search" placeholder="search a song title here.."/>
|
||||||
<a id="blank" href="#">Open Blank</a>
|
<results id="results">
|
||||||
<a href="/u/" class="usericon"><img src="/img/user.svg" /></a>
|
<result><h2></h2><p></p><p></p></result>
|
||||||
</header>
|
<result><h2></h2><p></p><p></p></result>
|
||||||
<main>
|
<result><h2></h2><p></p><p></p></result>
|
||||||
<!-- <a class="friend-icon" href="/friends"><img src="/img/friend.svg"></a> -->
|
<result><h2></h2><p></p><p></p></result>
|
||||||
<input type="text" readonly value="{{ url_gen }}" />
|
<result><h2></h2><p></p><p></p></result>
|
||||||
<div class="samerow">
|
<result><h2></h2><p></p><p></p></result>
|
||||||
<button id="download">Download Backup</button>
|
<result><h2></h2><p></p><p></p></result>
|
||||||
<button id="upload">Upload Backup</button>
|
<result><h2></h2><p></p><p></p></result>
|
||||||
|
<result><h2></h2><p></p><p></p></result>
|
||||||
|
<result><h2></h2><p></p><p></p></result>
|
||||||
|
</results>
|
||||||
|
<p id="counter">0 / 0</p>
|
||||||
|
<input type="file" id="pfp_upload" name="filename" accept=".png,.jpg,.jpeg,.gif,.avif,.webp,.tiff,.svg" />
|
||||||
|
<p id="pfp_reminder">4 MB file upload max</p>
|
||||||
|
<button id="clear">Clear Profile Picture</button>
|
||||||
|
<button id="submit">Submit</button>
|
||||||
|
<button id="close">X</button>
|
||||||
|
</div>
|
||||||
|
<div class="samerow">
|
||||||
|
<button id="download">Download Backup</button>
|
||||||
|
<button id="upload">Upload Backup</button>
|
||||||
|
</div>
|
||||||
|
<h1 class="title">{{ name }}'s profile</h1>
|
||||||
|
<h3>click on one of the following areas to edit</h3>
|
||||||
|
<h3>profile picture, name, song, and about me</h3>
|
||||||
|
<p style="font-size: 16px;">share your profile at {{ url_gen }}</p>
|
||||||
|
<section>
|
||||||
|
<img src="{{ user_pfp }}" class="pfp edit" id="pfp" />
|
||||||
|
<div class="profile-element edit" id="name">
|
||||||
|
<h1>{{ name }}</h1>
|
||||||
|
<p>/u/{{ username }}</p>
|
||||||
|
<div class="badges">{{ badges }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div class="profile-element edit" id="song">
|
||||||
<div id="custom"></div>
|
<h2>{{ song_title }}</h2>
|
||||||
{{ css_edit }}
|
<h3>{{ song_artist }}</h3>
|
||||||
|
<div class="samerow">
|
||||||
|
<p id="curPos">0:00</p>
|
||||||
|
<input type="range" id="playbar" min="1" max="1000" />
|
||||||
|
<p id="totalLength">9:99</p>
|
||||||
|
</div>
|
||||||
|
<div class="samerow">
|
||||||
|
<img id="playPause" src="/img/pause.svg" class="controls"/>
|
||||||
|
<img id="mute" src="/img/volume.svg" class="controls"/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="profile top">
|
<div class="profile-element">
|
||||||
<img src="{{ user_pfp }}" class="pfp" id="pfp" />
|
<h2>Joined {{ join_date }}</h2>
|
||||||
<img src="/img/edit.svg" id="edit" />
|
<h2>Last online {{ online_time }}</h2>
|
||||||
<div class="profile top text">
|
|
||||||
<div class="samerow edit" id="name">
|
|
||||||
<h1 id="name">{{ name }}</h1>
|
|
||||||
<img src="/img/edit.svg" id="edit" />
|
|
||||||
</div>
|
|
||||||
<div class="samerow">{{ badges }}</div>
|
|
||||||
<h2>Joined {{ join_date }}</h2>
|
|
||||||
<h2>Last online {{ online_time }}</h2>
|
|
||||||
</div>
|
|
||||||
<div class="profile top text right">
|
|
||||||
<div class="samerow edit" id="about">
|
|
||||||
<h1 id="bio">Bio</h1>
|
|
||||||
<img src="/img/edit.svg" id="edit" />
|
|
||||||
</div>
|
|
||||||
<h2 id="about">{{ about }}</h2>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="profile played">
|
</section>
|
||||||
<h2>Top Games:</h2>
|
<section class="column edit" id="about">
|
||||||
<div id="played-games">
|
<h1>about me</h1>
|
||||||
{{ played_games }}
|
<p class="about">{{ about }}</p>
|
||||||
</div>
|
</section>
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
<popups>
|
|
||||||
<div id="popup" style="display: none">
|
|
||||||
<h1 id="title"></h1>
|
|
||||||
<p id="body-text"></p>
|
|
||||||
<input type="text" id="text" />
|
|
||||||
<p id="counter">0 / 0</p>
|
|
||||||
<input type="file" id="pfp_upload" name="filename" accept=".png,.jpg,.jpeg,.gif,.avif,.webp,.tiff,.svg" />
|
|
||||||
<p id="pfp_reminder">4 MB file upload max</p>
|
|
||||||
<button id="clear">Clear Profile Picture</button>
|
|
||||||
<button id="submit">Submit</button>
|
|
||||||
<button id="close">X</button>
|
|
||||||
</div>
|
|
||||||
</popups>
|
|
||||||
<footer>
|
|
||||||
<a href="https://gitlab.com/skysthelimit.dev/selenite">Source</a>
|
|
||||||
<a href="https://discord.gg/7jyufnwJNf">Discord</a>
|
|
||||||
<a href="/suggest.html">Suggestions & Bugs</a>
|
|
||||||
<a href="/contact.html">Contact</a>
|
|
||||||
<a href="/support.html">Donate</a>
|
|
||||||
<a href="/about.html">About</a>
|
|
||||||
</footer>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html class="sl-theme-dark" lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<!-- initialize theme vars
|
<!-- initialize theme vars
|
||||||
https://coolors.co/10002b-240046-3c096c-5a189a-7b2cbf-9d4edd-c77dff-e0aaff -->
|
https://coolors.co/10002b-240046-3c096c-5a189a-7b2cbf-9d4edd-c77dff-e0aaff -->
|
||||||
@ -14,91 +14,82 @@
|
|||||||
|
|
||||||
<script src="https://js.hcaptcha.com/1/api.js" async defer></script>
|
<script src="https://js.hcaptcha.com/1/api.js" async defer></script>
|
||||||
|
|
||||||
<link rel="stylesheet" href="/style.css" />
|
<link rel="stylesheet" href="/css/main.css" />
|
||||||
|
<link rel="stylesheet" href="/css/pages.css" />
|
||||||
|
|
||||||
<!-- seo + other things -->
|
<!-- seo + other things -->
|
||||||
<title>Register | Selenite</title>
|
<title>Login | Selenite</title>
|
||||||
<link rel="icon" href="/favicon.ico" />
|
<link rel="icon" href="/favicon.ico" />
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener("DOMContentLoaded", () => {
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
document.getElementById("close").addEventListener("click", () => {
|
document.getElementById("close").addEventListener("click", () => {
|
||||||
document.getElementById("popup").style.display = "none";
|
document.getElementById("popup").style.display = "none";
|
||||||
if (document.getElementById("title").innerText == "Registered successfully") {
|
if (document.getElementById("title").innerText == "Registered successfully") {
|
||||||
location.href = "/login";
|
location.href = "/login";
|
||||||
}
|
}
|
||||||
});
|
|
||||||
document.getElementById("register").addEventListener("click", async () => {
|
|
||||||
let username = document.getElementById("username").value;
|
|
||||||
let password = document.getElementById("password").value;
|
|
||||||
let captcha = document.getElementById("hcaptcha").firstChild.dataset.hcaptchaResponse;
|
|
||||||
if (!document.getElementById("hcaptcha").firstChild.dataset.hcaptchaResponse) {
|
|
||||||
document.getElementById("title").innerText = "Failed to register";
|
|
||||||
document.getElementById("reason").innerText = "You have not done the CAPTCHA. Please complete the CAPTCHA before continuing.";
|
|
||||||
document.getElementById("popup").style.display = "flex";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (username.length < 17 && username.length > 2 && !/[^a-zA-Z0-9._-]/.test(username)) {
|
|
||||||
} else {
|
|
||||||
document.getElementById("title").innerText = "Failed to register";
|
|
||||||
document.getElementById("reason").innerText = "Your username is invalid. Please make your username within the limits described.";
|
|
||||||
document.getElementById("popup").style.display = "flex";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!/^((?=\S*?[A-Z])(?=\S*?[a-z])(?=\S*?[0-9]).{5,})\S$/.test(password)) {
|
|
||||||
document.getElementById("title").innerText = "Failed to register";
|
|
||||||
document.getElementById("reason").innerText = "Your password is invalid. Please make your password within the limits described.";
|
|
||||||
document.getElementById("popup").style.display = "flex";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let data = await (
|
|
||||||
await fetch("/register", {
|
|
||||||
method: "POST",
|
|
||||||
body: JSON.stringify({
|
|
||||||
username: username,
|
|
||||||
password: password,
|
|
||||||
"h-captcha-response": captcha,
|
|
||||||
}),
|
|
||||||
headers: {
|
|
||||||
"Content-type": "application/json; charset=UTF-8",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
).json();
|
|
||||||
console.log(data);
|
|
||||||
if (data.success) {
|
|
||||||
document.getElementById("title").innerText = "Registered successfully";
|
|
||||||
document.getElementById("reason").innerText = `Please save the following, this is required to reset your password.\n\n${data.key}\n\nExit to continue`;
|
|
||||||
} else {
|
|
||||||
console.log("Error: ", data.reason);
|
|
||||||
document.getElementById("title").innerText = "Failed to register";
|
|
||||||
document.getElementById("reason").innerText = data.reason;
|
|
||||||
}
|
|
||||||
document.getElementById("popup").style.display = "flex";
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
document.getElementById("register").addEventListener("click", async () => {
|
||||||
|
let username = document.getElementById("username").value;
|
||||||
|
let password = document.getElementById("password").value;
|
||||||
|
let captcha = document.getElementById("hcaptcha").firstChild.dataset.hcaptchaResponse;
|
||||||
|
if (!document.getElementById("hcaptcha").firstChild.dataset.hcaptchaResponse) {
|
||||||
|
document.getElementById("title").innerText = "Failed to register";
|
||||||
|
document.getElementById("reason").innerText = "You have not done the CAPTCHA. Please complete the CAPTCHA before continuing.";
|
||||||
|
document.getElementById("popup").style.display = "flex";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (username.length < 17 && username.length > 2 && !/[^a-zA-Z0-9._-]/.test(username)) {
|
||||||
|
} else {
|
||||||
|
document.getElementById("title").innerText = "Failed to register";
|
||||||
|
document.getElementById("reason").innerText = "Your username is invalid. Please make your username within the limits described.";
|
||||||
|
document.getElementById("popup").style.display = "flex";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!/^((?=\S*?[A-Z])(?=\S*?[a-z])(?=\S*?[0-9]).{5,})\S$/.test(password)) {
|
||||||
|
document.getElementById("title").innerText = "Failed to register";
|
||||||
|
document.getElementById("reason").innerText = "Your password is invalid. Please make your password within the limits described.";
|
||||||
|
document.getElementById("popup").style.display = "flex";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let data = await (
|
||||||
|
await fetch("/register", {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify({
|
||||||
|
username: username,
|
||||||
|
password: password,
|
||||||
|
"h-captcha-response": captcha,
|
||||||
|
}),
|
||||||
|
headers: {
|
||||||
|
"Content-type": "application/json; charset=UTF-8",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
).json();
|
||||||
|
console.log(data);
|
||||||
|
if (data.success) {
|
||||||
|
document.getElementById("title").innerText = "Registered successfully";
|
||||||
|
document.getElementById("reason").innerText = `Please save the following, this is required to reset your password.\n\n${data.key}\n\nExit to continue`;
|
||||||
|
} else {
|
||||||
|
console.log("Error: ", data.reason);
|
||||||
|
document.getElementById("title").innerText = "Failed to register";
|
||||||
|
document.getElementById("reason").innerText = data.reason;
|
||||||
|
}
|
||||||
|
document.getElementById("popup").style.display = "flex";
|
||||||
|
});
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<alerts> </alerts>
|
<alerts> </alerts>
|
||||||
<body id="noscroll">
|
<body>
|
||||||
<header>
|
<h2>register..</h2>
|
||||||
<a href="/index.html">Home</a>
|
<div>
|
||||||
<a href="/bookmarklets.html">Bookmarklets</a>
|
|
||||||
<a href="/projects.html">Games</a>
|
|
||||||
<a href="/apps.html">Apps</a>
|
|
||||||
<a href="/settings.html">Settings</a>
|
|
||||||
<a id="blank" href="#">Open Blank</a>
|
|
||||||
<a href="/u/" class="usericon"><img src="/img/user.svg" /></a>
|
|
||||||
</header>
|
|
||||||
<main id="main" class="noscroll">
|
|
||||||
<h2>Register a new account</h2>
|
|
||||||
<input type="text" id="username" placeholder="username" />
|
<input type="text" id="username" placeholder="username" />
|
||||||
<p>3-16 characters<br />capital, lowercase, numbers, dash, underscore, and dots allowed</p>
|
<p>3-16 characters<br />capital, lowercase, numbers, dash, underscore, and dots allowed</p>
|
||||||
<input type="password" id="password" placeholder="password" />
|
<input type="password" id="password" placeholder="password" />
|
||||||
<p>6+ characters<br />one uppercase, lowercase, and number at least</p>
|
<p>6+ characters<br />one uppercase, lowercase, and number at least</p>
|
||||||
<div class="h-captcha" id="hcaptcha" data-sitekey="1774ec96-39be-4fb0-9e82-f4c62354b8fa"></div>
|
<div class="h-captcha" id="hcaptcha" data-sitekey="1774ec96-39be-4fb0-9e82-f4c62354b8fa"></div>
|
||||||
<p><a href="/login">Or login</a></p>
|
<p><a href="/login">already have an account? login here.</a></p>
|
||||||
<button type="submit" value="Submit" id="register">Register</button>
|
<button type="submit" value="Submit" id="register">create an account</button>
|
||||||
</main>
|
</div>
|
||||||
<popups>
|
<popups>
|
||||||
<div id="popup" style="display: none">
|
<div id="popup" style="display: none">
|
||||||
<h1 id="title"></h1>
|
<h1 id="title"></h1>
|
||||||
@ -106,13 +97,5 @@
|
|||||||
<button id="close">X</button>
|
<button id="close">X</button>
|
||||||
</div>
|
</div>
|
||||||
</popups>
|
</popups>
|
||||||
<footer class="noscroll">
|
|
||||||
<a href="https://gitlab.com/skysthelimit.dev/selenite">Source</a>
|
|
||||||
<a href="https://discord.gg/7jyufnwJNf">Discord</a>
|
|
||||||
<a href="/suggest.html">Suggestions & Bugs</a>
|
|
||||||
<a href="/contact.html">Contact</a>
|
|
||||||
<a href="/support.html">Donate</a>
|
|
||||||
<a href="/about.html">About</a>
|
|
||||||
</footer>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html class="sl-theme-dark" lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<!-- initialize theme vars
|
<!-- initialize theme vars
|
||||||
https://coolors.co/10002b-240046-3c096c-5a189a-7b2cbf-9d4edd-c77dff-e0aaff -->
|
https://coolors.co/10002b-240046-3c096c-5a189a-7b2cbf-9d4edd-c77dff-e0aaff -->
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html class="sl-theme-dark" lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<!-- initialize theme vars
|
<!-- initialize theme vars
|
||||||
https://coolors.co/10002b-240046-3c096c-5a189a-7b2cbf-9d4edd-c77dff-e0aaff -->
|
https://coolors.co/10002b-240046-3c096c-5a189a-7b2cbf-9d4edd-c77dff-e0aaff -->
|
||||||
@ -42,17 +42,93 @@
|
|||||||
|
|
||||||
<link rel="stylesheet" href="/css/main.css" />
|
<link rel="stylesheet" href="/css/main.css" />
|
||||||
<link rel="stylesheet" href="/css/pages.css" />
|
<link rel="stylesheet" href="/css/pages.css" />
|
||||||
|
<link rel="stylesheet" href="/css/users.css" />
|
||||||
<link rel="manifest" href="/manifest.json" />
|
<link rel="manifest" href="/manifest.json" />
|
||||||
<!-- seo + other things -->
|
<!-- seo + other things -->
|
||||||
<title>Selenite</title>
|
<title>Selenite</title>
|
||||||
|
<script>
|
||||||
|
async function loadUsers(query, page) {
|
||||||
|
let above = false;
|
||||||
|
let below = false;
|
||||||
|
let data = await (await fetch(`/api/getUsers?page=${page - 1}&query=${query}`)).json();
|
||||||
|
let users = data['users'];
|
||||||
|
let url = new URL(location.href);
|
||||||
|
|
||||||
|
pages = Math.floor(data.count / 12);
|
||||||
|
document.getElementById("users").innerHTML = "";
|
||||||
|
for (let i = 0; i < Object.keys(users).length; i++) {
|
||||||
|
document.getElementById("users").innerHTML += `<a href="/u/${users[i].username}" class="users"><img class="pfp" src="${users[i].pfp_url}"/><div class="user_info"><h1>${users[i].name}</h1><p>${users[i].about}</p></div></a>`;
|
||||||
|
}
|
||||||
|
document.getElementById("pages").innerHTML = "";
|
||||||
|
for (let i = 1; i < pages + 1; i++) {
|
||||||
|
if (i + 6 > page && i - 6 < page) {
|
||||||
|
let curPage = parseInt(page);
|
||||||
|
let element = document.createElement("a");
|
||||||
|
if (!(i == curPage)) {
|
||||||
|
url.searchParams.set("page", i);
|
||||||
|
element.setAttribute("href", url);
|
||||||
|
}
|
||||||
|
element.setAttribute("class", `pages-btn`);
|
||||||
|
element.innerText = i;
|
||||||
|
document.getElementById("pages").append(element);
|
||||||
|
} else {
|
||||||
|
if (i + 6 > page) {
|
||||||
|
above = true;
|
||||||
|
}
|
||||||
|
if (i - 6 < page) {
|
||||||
|
below = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (above) {
|
||||||
|
let element = document.createElement("a");
|
||||||
|
element.setAttribute("class", "pages-btn");
|
||||||
|
element.innerText = "...";
|
||||||
|
document.getElementById("pages").append(element);
|
||||||
|
}
|
||||||
|
if (below) {
|
||||||
|
let element = document.createElement("a");
|
||||||
|
element.setAttribute("class", "pages-btn");
|
||||||
|
element.innerText = "...";
|
||||||
|
document.getElementById("pages").prepend(element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let pages;
|
||||||
|
document.addEventListener("DOMContentLoaded", async () => {
|
||||||
|
let params = location.search.substring(1).split("&");
|
||||||
|
let query;
|
||||||
|
let page;
|
||||||
|
if (params) {
|
||||||
|
for (let i = 0; i < params.length; i++) {
|
||||||
|
if (params[i].startsWith("query")) {
|
||||||
|
query = params[i].substring(6);
|
||||||
|
}
|
||||||
|
if (params[i].startsWith("page")) {
|
||||||
|
page = params[i].substring(5);
|
||||||
|
if (isNaN(page)) {
|
||||||
|
page = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await loadUsers(query ? query : "", page ? page : 0);
|
||||||
|
document.getElementById("search").addEventListener("keydown", async (e) => {
|
||||||
|
if (e.key == "Enter") {
|
||||||
|
let url = new URL(location.href);
|
||||||
|
url.searchParams.set("query", document.getElementById("search").value);
|
||||||
|
url.searchParams.set("page", 1);
|
||||||
|
location.href = url;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
<link rel="icon" href="/favicon.ico" />
|
<link rel="icon" href="/favicon.ico" />
|
||||||
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-3415518411898563" crossorigin="anonymous"></script>
|
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-3415518411898563" crossorigin="anonymous"></script>
|
||||||
</head>
|
</head>
|
||||||
<alerts> </alerts>
|
<alerts> </alerts>
|
||||||
<body>
|
<body>
|
||||||
<h1 class="title">users</h1>
|
<h1 class="title">users</h1>
|
||||||
<div id="users">
|
<div id="users"></div>
|
||||||
|
<div id="pages"></div>
|
||||||
</div>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html class="sl-theme-dark" lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<!-- initialize theme vars
|
<!-- initialize theme vars
|
||||||
https://coolors.co/10002b-240046-3c096c-5a189a-7b2cbf-9d4edd-c77dff-e0aaff -->
|
https://coolors.co/10002b-240046-3c096c-5a189a-7b2cbf-9d4edd-c77dff-e0aaff -->
|
||||||
|
167
index.js
167
index.js
@ -1,4 +1,3 @@
|
|||||||
const io = require('@pm2/io')
|
|
||||||
import { log } from "./log.js";
|
import { log } from "./log.js";
|
||||||
import bodyParser from "body-parser";
|
import bodyParser from "body-parser";
|
||||||
import express from "express";
|
import express from "express";
|
||||||
@ -10,6 +9,7 @@ import mime from "mime-types";
|
|||||||
import compression from "compression";
|
import compression from "compression";
|
||||||
import { accs, infdb, polytrack } from "./database.js";
|
import { accs, infdb, polytrack } from "./database.js";
|
||||||
import { } from "./accounts/friend.js";
|
import { } from "./accounts/friend.js";
|
||||||
|
import { search, download } from "./accounts/music.js";
|
||||||
import { banUser, removeAccount, verifyCookie, getUserFromCookie, createAccount, resetPassword, loginAccount, addBadge } from "./accounts/manage.js";
|
import { banUser, removeAccount, verifyCookie, getUserFromCookie, createAccount, resetPassword, loginAccount, addBadge } from "./accounts/manage.js";
|
||||||
import { } from "./accounts/misc.js";
|
import { } from "./accounts/misc.js";
|
||||||
import { getRawData, generateAccountPage, editProfile, saveData, getUsers, isAdmin, retrieveData } from "./accounts/profile.js";
|
import { getRawData, generateAccountPage, editProfile, saveData, getUsers, isAdmin, retrieveData } from "./accounts/profile.js";
|
||||||
@ -26,34 +26,17 @@ app.use(cookieParser());
|
|||||||
app.use(express.json({ limit: "10mb" }));
|
app.use(express.json({ limit: "10mb" }));
|
||||||
app.use(express.urlencoded({ extended: false }));
|
app.use(express.urlencoded({ extended: false }));
|
||||||
app.use(express.text());
|
app.use(express.text());
|
||||||
let requests = 0;
|
|
||||||
const requestsPerSec = io.meter({
|
|
||||||
name: 'req/sec',
|
|
||||||
id: 'app/requests/sec'
|
|
||||||
});
|
|
||||||
const requestsPerMin = io.meter({
|
|
||||||
name: 'req/min',
|
|
||||||
id: 'app/requests/min'
|
|
||||||
});
|
|
||||||
app.use("/", (req, res, next) => {
|
app.use("/", (req, res, next) => {
|
||||||
requestsPerSec.mark();
|
|
||||||
requestsPerMin.mark();
|
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
const sockets = io.metric({
|
|
||||||
name: 'Open Websockets',
|
|
||||||
id: 'app/requests/sockets',
|
|
||||||
});
|
|
||||||
// setInterval(()=>{
|
// setInterval(()=>{
|
||||||
|
|
||||||
// }, 1000)
|
// }, 1000)
|
||||||
import WebSocket, { WebSocketServer } from "ws";
|
import WebSocket, { WebSocketServer } from "ws";
|
||||||
import { request } from "node:http";
|
|
||||||
const wss = new WebSocketServer({ noServer: true });
|
const wss = new WebSocketServer({ noServer: true });
|
||||||
let openSockets = 0;
|
let openSockets = 0;
|
||||||
wss.on("connection", function connection(ws, req, res) {
|
wss.on("connection", function connection(ws, req, res) {
|
||||||
openSockets++;
|
openSockets++;
|
||||||
sockets.set(openSockets);
|
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
ws.send("ping");
|
ws.send("ping");
|
||||||
}, 30000);
|
}, 30000);
|
||||||
@ -77,32 +60,11 @@ wss.on("connection", function connection(ws, req, res) {
|
|||||||
if (ws.id) {
|
if (ws.id) {
|
||||||
const updateAccount = accs.query(`UPDATE accounts SET last_login = $login WHERE username = $user`)
|
const updateAccount = accs.query(`UPDATE accounts SET last_login = $login WHERE username = $user`)
|
||||||
updateAccount.get({ $login: new Date().toUTCString(), $user: ws.id });
|
updateAccount.get({ $login: new Date().toUTCString(), $user: ws.id });
|
||||||
if (message.substring(4)) {
|
|
||||||
const existingAccount = accs.query(`SELECT * FROM accounts WHERE username LIKE $1`)
|
|
||||||
let userData = existingAccount.get({ $1: ws.id });
|
|
||||||
if (userData == null) {
|
|
||||||
return { success: false, reason: "The account doesn't exist." };
|
|
||||||
}
|
|
||||||
let games;
|
|
||||||
if (userData.playedgames) {
|
|
||||||
games = JSON.parse(userData.playedgames);
|
|
||||||
} else {
|
|
||||||
games = {};
|
|
||||||
}
|
|
||||||
if (games[message.substring(4)]) {
|
|
||||||
games[message.substring(4)] += 30;
|
|
||||||
} else {
|
|
||||||
games[message.substring(4)] = 30;
|
|
||||||
}
|
|
||||||
const updateAccount = accs.query(`UPDATE accounts SET playedgames = $playedgames WHERE username = $user`)
|
|
||||||
updateAccount.get({ $playedgames: JSON.stringify(games), $user: ws.id });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ws.on("close", () => {openSockets--;
|
ws.on("close", () => {openSockets--;});
|
||||||
sockets.set(openSockets);});
|
|
||||||
});
|
});
|
||||||
app.post(
|
app.post(
|
||||||
"/api/event",
|
"/api/event",
|
||||||
@ -120,11 +82,6 @@ app.post(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
// app.use("*.json", async (req, res, next) => {
|
|
||||||
// optimize json
|
|
||||||
// console.log("got data");
|
|
||||||
// next()
|
|
||||||
// });
|
|
||||||
app.post("/register", async (req, res) => {
|
app.post("/register", async (req, res) => {
|
||||||
let status = await createAccount(req.body.username, req.body.password, req.body["h-captcha-response"]);
|
let status = await createAccount(req.body.username, req.body.password, req.body["h-captcha-response"]);
|
||||||
if (status["success"]) {
|
if (status["success"]) {
|
||||||
@ -227,110 +184,6 @@ app.get("/api/chat/recent", async (req, res) => {
|
|||||||
// get last 50 recent messages
|
// get last 50 recent messages
|
||||||
// offset by a page param
|
// offset by a page param
|
||||||
})
|
})
|
||||||
app.get("/api/infinite/get", async (req, res, next) => {
|
|
||||||
if (req.query[1] && req.query[2]) {
|
|
||||||
let success = false;
|
|
||||||
let data;
|
|
||||||
try {
|
|
||||||
let search1Query = infdb.query(`SELECT * FROM caches WHERE 1 = $one AND 2 = $two`)
|
|
||||||
let search1 = await search1Query.get({ $one: req.query[1], $two: req.query[2] });
|
|
||||||
console.log(search1);
|
|
||||||
if (search1 && search1.length > 0) {
|
|
||||||
data = { item: search1[0].result_item, emoji: search1[0].result_emoji, new: false };
|
|
||||||
success = true;
|
|
||||||
} else {
|
|
||||||
let search2Query = infdb.query(`SELECT * FROM caches WHERE 1 = $two AND 2 = $one`)
|
|
||||||
let search2 = await search2Query.get({ $one: req.query[1], $two: req.query[2] });
|
|
||||||
console.log(search2);
|
|
||||||
if (search2 && search2.length > 0) {
|
|
||||||
data = { item: search2[0].result_item, emoji: search2[0].result_emoji, new: false };
|
|
||||||
success = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
}
|
|
||||||
if (success) {
|
|
||||||
console.log("success");
|
|
||||||
res.send(data);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
data = await infiniteCraft(req.query[1], req.query[2]);
|
|
||||||
try {
|
|
||||||
let parse = JSON.parse(data);
|
|
||||||
let keys = Object.keys(parse);
|
|
||||||
if (keys.indexOf("item") > -1 && keys.indexOf("emoji") > -1) {
|
|
||||||
parse.new = true;
|
|
||||||
data = parse;
|
|
||||||
const createCached = infdb.query(`INSERT INTO caches (1, 2, result_item, result_emoji) VALUES ($one, $two, $item, $emoji)`)
|
|
||||||
createCached.run({ $one: req.query[1], $two: req.query[2], $item: data.item, $emoji: data.emoji });
|
|
||||||
res.send(data);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
data = { item: "N/A", emoji: "N/A" };
|
|
||||||
res.send(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
app.use("/semag/polytrack/data/", async (req, res, next) => {
|
|
||||||
let path = req.path.substring(1, req.path.length);
|
|
||||||
if(path == "user") {
|
|
||||||
res.sendStatus(200);
|
|
||||||
} else if(path == "leaderboard") {
|
|
||||||
let data = {};
|
|
||||||
|
|
||||||
if(req.method == "POST") {
|
|
||||||
req.body.split("&").forEach((item) => {
|
|
||||||
data[item.split("=")[0]] = item.split("=")[1]
|
|
||||||
});
|
|
||||||
console.log(data);
|
|
||||||
const getExistingRuns = polytrack.query(`SELECT * FROM polytrack WHERE userid = $usrid AND trackid = $trackid`);
|
|
||||||
let existingRuns = getExistingRuns.all({ $usrid: data["userToken"], $trackid: data["trackId"] });
|
|
||||||
let saveRun = true;
|
|
||||||
if(existingRuns !== null) {
|
|
||||||
existingRuns.forEach((item) => {
|
|
||||||
if(saveRun) {
|
|
||||||
if(data.frames > item.frames) {
|
|
||||||
saveRun = false;
|
|
||||||
} else {
|
|
||||||
let deleteRun = polytrack.query(`DELETE FROM polytrack WHERE id = $id`);
|
|
||||||
deleteRun.run({ $id: item.id })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if(saveRun) {
|
|
||||||
const addRun = polytrack.query(`INSERT INTO polytrack (trackid, username, colors, recording, frames, userid) VALUES ($id, $usr, $clr, $record, $frames, $usrid)`)
|
|
||||||
let runData = addRun.run({ $id: data["trackId"], $usr: data["name"], $clr: data["carColors"], $record: data["recording"], $usrid: data["userToken"], $frames: data["frames"] });
|
|
||||||
console.log("run", runData);
|
|
||||||
res.send(runData.lastInsertRowid);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let leaderboard = polytrack.query(`SELECT * FROM polytrack WHERE trackid = $id LIMIT $limit OFFSET $offset`).all({ $id: req.query.trackId, $limit: req.query.amount, $offset: req.query.skip })
|
|
||||||
console.log(leaderboard);
|
|
||||||
let returnValue = {"total": leaderboard.length, "entries":[]}
|
|
||||||
for(let i = 0; i<leaderboard.length;i++) {
|
|
||||||
returnValue["entries"][i] = {};
|
|
||||||
returnValue["entries"][i]["id"] = leaderboard[i]["id"];
|
|
||||||
returnValue["entries"][i]["name"] = decodeURIComponent(leaderboard[i]["username"]);
|
|
||||||
returnValue["entries"][i]["carColors"] = leaderboard[i]["colors"];
|
|
||||||
returnValue["entries"][i]["frames"] = leaderboard[i]["frames"];
|
|
||||||
returnValue["entries"][i]["verifiedState"] = true;
|
|
||||||
returnValue["entries"][i]["isSelf"] = false;
|
|
||||||
}
|
|
||||||
res.send(returnValue);
|
|
||||||
}
|
|
||||||
} else if(path == "recording") {
|
|
||||||
let recordingQuery = polytrack.query(`SELECT * FROM polytrack WHERE id = $id`).get({ $id: req.query.recordingId });
|
|
||||||
res.send({
|
|
||||||
"recording": recordingQuery.recording,
|
|
||||||
"frames": recordingQuery.frames,
|
|
||||||
"verifiedState": true,
|
|
||||||
"carColors": recordingQuery.colors
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
app.use("/api/account/load", async (req, res, next) => {
|
app.use("/api/account/load", async (req, res, next) => {
|
||||||
if (req.cookies.token && (await verifyCookie(req.cookies.token))) {
|
if (req.cookies.token && (await verifyCookie(req.cookies.token))) {
|
||||||
let status = await retrieveData(req.cookies.token);
|
let status = await retrieveData(req.cookies.token);
|
||||||
@ -387,7 +240,7 @@ app.use("/ai", async (req, res, next) => {
|
|||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
app.use("/", express.static("./selenite", { extensions: ["html"] }));
|
app.use("/", express.static("./public", { extensions: ["html"] }));
|
||||||
app.use("/data/:id/:file", async (req, res) => {
|
app.use("/data/:id/:file", async (req, res) => {
|
||||||
const id = path.basename(req.params.id);
|
const id = path.basename(req.params.id);
|
||||||
const file = path.basename(req.params.file);
|
const file = path.basename(req.params.file);
|
||||||
@ -400,6 +253,9 @@ app.use("/data/:id/:file", async (req, res) => {
|
|||||||
if (mime.lookup(filePath) == "image/webp") {
|
if (mime.lookup(filePath) == "image/webp") {
|
||||||
res.type("image/webp");
|
res.type("image/webp");
|
||||||
res.status(200).send(image);
|
res.status(200).send(image);
|
||||||
|
} else if (mime.lookup(filePath) == "audio/ogg") {
|
||||||
|
res.type("audio/ogg");
|
||||||
|
res.status(200).send(image);
|
||||||
} else {
|
} else {
|
||||||
res.status(404).send("File not found");
|
res.status(404).send("File not found");
|
||||||
}
|
}
|
||||||
@ -477,6 +333,15 @@ app.post("/api/admin/ban", async (req, res) => {
|
|||||||
let status = await banUser(req.body.name, req.body.reason, req.cookies.token);
|
let status = await banUser(req.body.name, req.body.reason, req.cookies.token);
|
||||||
res.status(200).send(status);
|
res.status(200).send(status);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
app.use("/api/music/search", async (req, res, next) => {
|
||||||
|
res.status(200).send(await search(req.query.q))
|
||||||
|
});
|
||||||
|
|
||||||
|
app.use("/api/music/download", async (req, res, next) => {
|
||||||
|
res.status(200).send(await download(req.query.url))
|
||||||
|
});
|
||||||
const server = app.listen(port, () => {
|
const server = app.listen(port, () => {
|
||||||
console.log(log.success("Express is online."));
|
console.log(log.success("Express is online."));
|
||||||
console.log("- " + log.info("http://localhost:" + port));
|
console.log("- " + log.info("http://localhost:" + port));
|
||||||
@ -490,6 +355,6 @@ server.on("upgrade", (request, socket, head) => {
|
|||||||
app.use(async (req, res) => {
|
app.use(async (req, res) => {
|
||||||
res
|
res
|
||||||
.type("text/html")
|
.type("text/html")
|
||||||
.send(await fs.readFile(`./selenite/404.html`))
|
.send(await fs.readFile(`./public/404.html`))
|
||||||
.status(404);
|
.status(404);
|
||||||
});
|
});
|
||||||
|
207
package-lock.json
generated
207
package-lock.json
generated
@ -21,6 +21,7 @@
|
|||||||
"fast-glob": "^3.3.2",
|
"fast-glob": "^3.3.2",
|
||||||
"file-type": "^19.0.0",
|
"file-type": "^19.0.0",
|
||||||
"install": "^0.13.0",
|
"install": "^0.13.0",
|
||||||
|
"lucida": "^2.0.0-54",
|
||||||
"mime-types": "^2.1.35",
|
"mime-types": "^2.1.35",
|
||||||
"node-html-parser": "^6.1.13",
|
"node-html-parser": "^6.1.13",
|
||||||
"openai": "^4.85.3",
|
"openai": "^4.85.3",
|
||||||
@ -40,6 +41,15 @@
|
|||||||
"tslib": "^2.4.0"
|
"tslib": "^2.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@fastify/busboy": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@img/sharp-darwin-arm64": {
|
"node_modules/@img/sharp-darwin-arm64": {
|
||||||
"version": "0.33.4",
|
"version": "0.33.4",
|
||||||
"resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.4.tgz",
|
"resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.4.tgz",
|
||||||
@ -569,6 +579,70 @@
|
|||||||
"integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==",
|
"integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==",
|
||||||
"license": "Apache-2.0"
|
"license": "Apache-2.0"
|
||||||
},
|
},
|
||||||
|
"node_modules/@protobufjs/aspromise": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==",
|
||||||
|
"license": "BSD-3-Clause"
|
||||||
|
},
|
||||||
|
"node_modules/@protobufjs/base64": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==",
|
||||||
|
"license": "BSD-3-Clause"
|
||||||
|
},
|
||||||
|
"node_modules/@protobufjs/codegen": {
|
||||||
|
"version": "2.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz",
|
||||||
|
"integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==",
|
||||||
|
"license": "BSD-3-Clause"
|
||||||
|
},
|
||||||
|
"node_modules/@protobufjs/eventemitter": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==",
|
||||||
|
"license": "BSD-3-Clause"
|
||||||
|
},
|
||||||
|
"node_modules/@protobufjs/fetch": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==",
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
|
"dependencies": {
|
||||||
|
"@protobufjs/aspromise": "^1.1.1",
|
||||||
|
"@protobufjs/inquire": "^1.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@protobufjs/float": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==",
|
||||||
|
"license": "BSD-3-Clause"
|
||||||
|
},
|
||||||
|
"node_modules/@protobufjs/inquire": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==",
|
||||||
|
"license": "BSD-3-Clause"
|
||||||
|
},
|
||||||
|
"node_modules/@protobufjs/path": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==",
|
||||||
|
"license": "BSD-3-Clause"
|
||||||
|
},
|
||||||
|
"node_modules/@protobufjs/pool": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==",
|
||||||
|
"license": "BSD-3-Clause"
|
||||||
|
},
|
||||||
|
"node_modules/@protobufjs/utf8": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==",
|
||||||
|
"license": "BSD-3-Clause"
|
||||||
|
},
|
||||||
"node_modules/@tokenizer/token": {
|
"node_modules/@tokenizer/token": {
|
||||||
"version": "0.3.0",
|
"version": "0.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz",
|
||||||
@ -664,9 +738,9 @@
|
|||||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
||||||
},
|
},
|
||||||
"node_modules/axios": {
|
"node_modules/axios": {
|
||||||
"version": "1.7.4",
|
"version": "1.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz",
|
"resolved": "https://registry.npmjs.org/axios/-/axios-1.10.0.tgz",
|
||||||
"integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==",
|
"integrity": "sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"follow-redirects": "^1.15.6",
|
"follow-redirects": "^1.15.6",
|
||||||
@ -674,6 +748,17 @@
|
|||||||
"proxy-from-env": "^1.1.0"
|
"proxy-from-env": "^1.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/blowfish-cbc": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/blowfish-cbc/-/blowfish-cbc-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-o1JN6g6+ATW/4k7q1BZzy14VqLxwYa1mCii47qT4kmAaYD0NAfdM6/pz6uizbhTra/xunsPQI27LZt08OQS4sA==",
|
||||||
|
"deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.",
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"node-addon-api": "^8.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/body-parser": {
|
"node_modules/body-parser": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.0.2.tgz",
|
||||||
@ -1661,6 +1746,21 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"node_modules/image-size": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/image-size/-/image-size-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-rH+46sQJ2dlwfjfhCyNx5thzrv+dtmBIhPHk0zgRUukHzZ/kRueTJXoYYsclBaKcSMBWuGbOFXtioLpzTb5euw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"queue": "6.0.2"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"image-size": "bin/image-size.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/inflection": {
|
"node_modules/inflection": {
|
||||||
"version": "1.13.4",
|
"version": "1.13.4",
|
||||||
"resolved": "https://registry.npmjs.org/inflection/-/inflection-1.13.4.tgz",
|
"resolved": "https://registry.npmjs.org/inflection/-/inflection-1.13.4.tgz",
|
||||||
@ -1754,11 +1854,39 @@
|
|||||||
"integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==",
|
"integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/librespot": {
|
||||||
|
"version": "0.2.22",
|
||||||
|
"resolved": "https://registry.npmjs.org/librespot/-/librespot-0.2.22.tgz",
|
||||||
|
"integrity": "sha512-szLknWSrgF+mRuypNXQTmdq8PGGhgPRAazm8sJmD8wiCAbtO9LYHihZhQcRmCzmVz818sRHZM/BU6K6XslXSHQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"protobufjs": "^7.2.5",
|
||||||
|
"undici": "^5.27.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/librespot/node_modules/undici": {
|
||||||
|
"version": "5.29.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/undici/-/undici-5.29.0.tgz",
|
||||||
|
"integrity": "sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@fastify/busboy": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/lodash": {
|
"node_modules/lodash": {
|
||||||
"version": "4.17.21",
|
"version": "4.17.21",
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
||||||
},
|
},
|
||||||
|
"node_modules/long": {
|
||||||
|
"version": "5.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz",
|
||||||
|
"integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==",
|
||||||
|
"license": "Apache-2.0"
|
||||||
|
},
|
||||||
"node_modules/lru-cache": {
|
"node_modules/lru-cache": {
|
||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||||
@ -1771,6 +1899,19 @@
|
|||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/lucida": {
|
||||||
|
"version": "2.0.0-54",
|
||||||
|
"resolved": "https://registry.npmjs.org/lucida/-/lucida-2.0.0-54.tgz",
|
||||||
|
"integrity": "sha512-3Y24WkCI1Ks6EjOAElYAeYXkxT/HtunEW+SnhDKFb681B/QEMhS/EzLzFi8D5l95/pOVODUZQMMxYNKmMMC1fQ==",
|
||||||
|
"license": "OQL",
|
||||||
|
"dependencies": {
|
||||||
|
"blowfish-cbc": "^1.0.1",
|
||||||
|
"image-size": "^1.1.1",
|
||||||
|
"librespot": "^0.2.21",
|
||||||
|
"undici": "^6.19.4",
|
||||||
|
"xmldom-qsa": "^1.1.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/media-typer": {
|
"node_modules/media-typer": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
|
||||||
@ -1897,6 +2038,15 @@
|
|||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/node-addon-api": {
|
||||||
|
"version": "8.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.4.0.tgz",
|
||||||
|
"integrity": "sha512-D9DI/gXHvVmjHS08SVch0Em8G5S1P+QWtU31appcKT/8wFSPRcdHadIFSAntdMMVM5zz+/DL+bL/gz3UDppqtg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": "^18 || ^20 || >= 21"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/node-domexception": {
|
"node_modules/node-domexception": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
|
||||||
@ -2125,6 +2275,30 @@
|
|||||||
"node": "^10 || ^12 || >=14"
|
"node": "^10 || ^12 || >=14"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/protobufjs": {
|
||||||
|
"version": "7.5.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.3.tgz",
|
||||||
|
"integrity": "sha512-sildjKwVqOI2kmFDiXQ6aEB0fjYTafpEvIBs8tOR8qI4spuL9OPROLVu2qZqi/xgCfsHIwVqlaF8JBjWFHnKbw==",
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
|
"dependencies": {
|
||||||
|
"@protobufjs/aspromise": "^1.1.2",
|
||||||
|
"@protobufjs/base64": "^1.1.2",
|
||||||
|
"@protobufjs/codegen": "^2.0.4",
|
||||||
|
"@protobufjs/eventemitter": "^1.1.0",
|
||||||
|
"@protobufjs/fetch": "^1.1.0",
|
||||||
|
"@protobufjs/float": "^1.0.2",
|
||||||
|
"@protobufjs/inquire": "^1.1.0",
|
||||||
|
"@protobufjs/path": "^1.1.2",
|
||||||
|
"@protobufjs/pool": "^1.1.0",
|
||||||
|
"@protobufjs/utf8": "^1.1.0",
|
||||||
|
"@types/node": ">=13.7.0",
|
||||||
|
"long": "^5.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/proxy-addr": {
|
"node_modules/proxy-addr": {
|
||||||
"version": "2.0.7",
|
"version": "2.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
||||||
@ -2157,6 +2331,15 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/queue": {
|
||||||
|
"version": "6.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz",
|
||||||
|
"integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"inherits": "~2.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/queue-microtask": {
|
"node_modules/queue-microtask": {
|
||||||
"version": "1.2.3",
|
"version": "1.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
||||||
@ -2826,6 +3009,15 @@
|
|||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/undici": {
|
||||||
|
"version": "6.21.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/undici/-/undici-6.21.3.tgz",
|
||||||
|
"integrity": "sha512-gBLkYIlEnSp8pFbT64yFgGE6UIB9tAkhukC23PmMDCe5Nd+cRqKxSjw5y54MK2AZMgZfJWMaNE4nYUHgi1XEOw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18.17"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/undici-types": {
|
"node_modules/undici-types": {
|
||||||
"version": "5.26.5",
|
"version": "5.26.5",
|
||||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
||||||
@ -2924,6 +3116,15 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/xmldom-qsa": {
|
||||||
|
"version": "1.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/xmldom-qsa/-/xmldom-qsa-1.1.3.tgz",
|
||||||
|
"integrity": "sha512-IJBOczBpAYrIBJFFsmCBwfBhwe4zdMR3Xz0ZBX0OFtgO49rLy/BWbhkegOwsthdBWb1gUtFK6ZZnGdT8ZqPRBA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/yallist": {
|
"node_modules/yallist": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
"fast-glob": "^3.3.2",
|
"fast-glob": "^3.3.2",
|
||||||
"file-type": "^19.0.0",
|
"file-type": "^19.0.0",
|
||||||
"install": "^0.13.0",
|
"install": "^0.13.0",
|
||||||
|
"lucida": "^2.0.0-54",
|
||||||
"mime-types": "^2.1.35",
|
"mime-types": "^2.1.35",
|
||||||
"node-html-parser": "^6.1.13",
|
"node-html-parser": "^6.1.13",
|
||||||
"openai": "^4.85.3",
|
"openai": "^4.85.3",
|
||||||
|
Reference in New Issue
Block a user