functioning bot invites

This commit is contained in:
MathMan05 2024-09-25 23:38:53 -05:00
parent 65ad34f629
commit 7b2a4196f4
6 changed files with 278 additions and 7 deletions

View file

@ -13,7 +13,7 @@
<link href="/themes.css" rel="stylesheet" id="lightcss">
</head>
<body class="Dark-theme">
<body class="Dark-theme" style="overflow-y: scroll;">
<div id="titleDiv">
<img src="/logo.svg" width="40">
<h1 id="pageTitle">Jank Client</h1>
@ -58,4 +58,4 @@
</body>
<script src="/home.js" type="module"></script>
</html>
</html>

View file

@ -291,7 +291,7 @@ async function getapiurls(str: string): Promise<
gateway: info.gateway,
cdn: info.cdn,
wellknown: str,
login: url.toString(),
login: info.apiEndpoint,
};
}catch{
const val = stringURLsMap.get(str);

243
src/webpage/oauth2/auth.ts Normal file
View file

@ -0,0 +1,243 @@
import{ getBulkUsers, Specialuser, getapiurls }from"../login.js";
import { Permissions } from "../permissions.js";
type botjsonfetch={
guilds:{
id: string,
name: string,
icon: string,
mfa_level: number,
permissions: string
}[],
"user": {
id: string,
username: string,
avatar: string,
avatar_decoration?: string,
discriminator: string,
public_flags: number
},
application: {
id: string,
name: string,
icon: string|null,
description: string,
summary: string,
type: null,//not sure what this means :P
hook: boolean,
guild_id: null|string,
bot_public: boolean,
bot_require_code_grant: boolean,
verify_key: "IMPLEMENTME",//no clue what this is meant to be :P
flags: number
},
bot: {
id: string,
username: string,
avatar: string|null,
avatar_decoration: null|string,
discriminator: string,
public_flags: number,
bot: boolean,
approximated_guild_count: number
},
authorized: boolean
}
(async ()=>{
const users = getBulkUsers();
const params=new URLSearchParams(window.location.search);
const well = params.get("instance");
const permstr=params.get("permissions");
const joinable: Specialuser[] = [];
for(const key in users.users){
if(Object.prototype.hasOwnProperty.call(users.users, key)){
const user: Specialuser = users.users[key];
if(well && user.serverurls.wellknown.includes(well)){
joinable.push(user);
}
console.log(user);
}
}
let urls: { api: string; cdn: string } | undefined;
if(!joinable.length && well){
const out = await getapiurls(well);
if(out){
urls = out;
for(const key in users.users){
if(Object.prototype.hasOwnProperty.call(users.users, key)){
const user: Specialuser = users.users[key];
if(user.serverurls.api.includes(out.api)){
joinable.push(user);
}
console.log(user);
}
}
}else{
throw new Error(
"Someone needs to handle the case where the servers don't exist"
);
}
}else{
urls = joinable[0].serverurls;
}
if(!joinable.length){
document.getElementById("AcceptInvite")!.textContent = "Create an account to invite the bot";
}
function showGuilds(user:Specialuser){
if(!urls) return;
fetch(urls.api+"/oauth2/authorize/"+window.location.search,{
headers:{
Authorization:user.token
}
}).then(_=>_.json()).then((json:botjsonfetch)=>{
const guilds:botjsonfetch["guilds"]=[];
for(const guild of json.guilds){
const permisions=new Permissions(guild.permissions)
if(permisions.hasPermission("MANAGE_GUILD")){
guilds.push(guild);
}
}
const dialog=document.createElement("dialog");
dialog.classList.add("accountSwitcher");
const h1=document.createElement("h1");
dialog.append(h1);
h1.textContent="Invite to server:";
const select=document.createElement("select");
for(const guild of guilds){
const option=document.createElement("option");
option.textContent=guild.name;
option.value=guild.id;
select.append(option);
}
dialog.append(select);
const button=document.createElement("button");
button.textContent="Invite";
dialog.append(button);
button.onclick=()=>{
const id=select.value;
const params2=new URLSearchParams("");
params2.set("client_id",params.get("client_id") as string)
fetch(urls.api+"/oauth2/authorize?"+params2.toString(),{
method:"POST",
body:JSON.stringify({
authorize:true,
guild_id:id,
permissions:permstr
}),
headers:{
"Content-type": "application/json; charset=UTF-8",
Authorization:user.token,
}
}).then(req=>{
if(req.ok){
alert("Bot added successfully");
}
})
}
document.body.append(dialog);
})
}
function showAccounts(): void{
const table = document.createElement("dialog");
for(const user of joinable){
console.log(user.pfpsrc);
const userinfo = document.createElement("div");
userinfo.classList.add("flexltr", "switchtable");
const pfp = document.createElement("img");
pfp.src = user.pfpsrc;
pfp.classList.add("pfp");
userinfo.append(pfp);
const userDiv = document.createElement("div");
userDiv.classList.add("userinfo");
userDiv.textContent = user.username;
userDiv.append(document.createElement("br"));
const span = document.createElement("span");
span.textContent = user.serverurls.wellknown
.replace("https://", "")
.replace("http://", "");
span.classList.add("serverURL");
userDiv.append(span);
userinfo.append(userDiv);
table.append(userinfo);
userinfo.addEventListener("click", ()=>{
table.remove();
showGuilds(user);
});
}
const td = document.createElement("div");
td.classList.add("switchtable");
td.textContent = "Login or create an account ⇌";
td.addEventListener("click", ()=>{
const l = new URLSearchParams("?");
l.set("goback", window.location.href);
l.set("instance", well!);
window.location.href = "/login?" + l.toString();
});
if(!joinable.length){
const l = new URLSearchParams("?");
l.set("goback", window.location.href);
l.set("instance", well!);
window.location.href = "/login?" + l.toString();
}
table.append(td);
table.classList.add("accountSwitcher");
console.log(table);
document.body.append(table);
}
const user=joinable[0];
if(!user){
return;
}
fetch(urls.api+"/oauth2/authorize/"+window.location.search,{
headers:{
Authorization:user.token
}
}).then(_=>_.json()).then((json:botjsonfetch)=>{
const title=document.getElementById("invitename");
if(title){
title.textContent=`Invite ${json.bot.username} to your servers`
}
const desc=document.getElementById("invitedescription");
if(desc){
desc.textContent=json.application.description;
}
const pfp=document.getElementById("inviteimg") as HTMLImageElement;
if(json.bot.avatar !== null){
pfp.src=`${urls.cdn}/avatars/${json.bot.id}/${json.bot.avatar}.png`;
}else{
const int = Number((BigInt(json.bot.id) >> 22n) % 6n);
pfp.src=`${urls.cdn}/embed/avatars/${int}.png`;
}
const perms=document.getElementById("permsions") as HTMLDivElement;
if(perms&&permstr){
const permisions=new Permissions(permstr)
for(const perm of Permissions.info){
if(permisions.hasPermission(perm.name,false)){
const div=document.createElement("div");
const h2=document.createElement("h2");
h2.textContent=perm.readableName;
div.append(h2,perm.description);
div.classList.add("flexttb");
perms.append(div);
}
}
}
})
document
.getElementById("AcceptInvite")!
.addEventListener("click", showAccounts);
})();

View file

@ -0,0 +1,23 @@
<body class="Dark-theme">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Jank Client</title>
<meta content="Bot Invite" property="og:title">
<meta name="description" content="Invite this bot to your server!">
<meta content="/logo.webp" property="og:image">
<meta content="#4b458c" data-react-helmet="true" name="theme-color">
<link href="/style.css" rel="stylesheet">
<link href="/themes.css" rel="stylesheet" id="lightcss">
</head>
<div>
<div id="invitebody">
<img id="inviteimg" class="pfp"/>
<h1 id="invitename">Bot Name</h1>
<p id="invitedescription">Add Bot</p>
<div id="permsions"><h1>This will allow the bot to:</h1></div>
<button id="AcceptInvite">Add to server</button>
</div>
</div>
<script type="module" src="/oauth2/auth.js"></script>
</body>

View file

@ -309,7 +309,7 @@ class Permissions{
return 0;
}
}
hasPermission(name: string): boolean{
hasPermission(name: string,adminOverride=true): boolean{
if(this.deny){
console.warn(
"This function may of been used in error, think about using getPermision instead"
@ -317,7 +317,7 @@ class Permissions{
}
if(this.getPermissionbit(Permissions.map[name] as number, this.allow))
return true;
if(name != "ADMINISTRATOR")return this.hasPermission("ADMINISTRATOR");
if(name != "ADMINISTRATOR"&&adminOverride)return this.hasPermission("ADMINISTRATOR");
return false;
}
setPermission(name: string, setto: number): void{

View file

@ -21,6 +21,9 @@ body {
box-shadow: inset .03in .35in .2in var(--accent_color);
min-height: 3.6in;
min-width: 7.5cm;
.banner{
position:absolute;
}
}
video{
max-width: 3in;
@ -1810,11 +1813,13 @@ form div{
box-sizing:border-box;
display:flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: .5in .2in;
gap: .1in;
width: 5in;
max-height: 80dvh;
overflow-y: auto;
overflow-x:clip;
align-items: center;
}
#AcceptInvite{
padding: .1in .2in;