From 7b2a4196f4b85ef8e7b29333e2e804ee966e2501 Mon Sep 17 00:00:00 2001 From: MathMan05 Date: Wed, 25 Sep 2024 23:38:53 -0500 Subject: [PATCH] functioning bot invites --- src/webpage/home.html | 4 +- src/webpage/login.ts | 2 +- src/webpage/oauth2/auth.ts | 243 ++++++++++++++++++++++++++++++ src/webpage/oauth2/authorize.html | 23 +++ src/webpage/permissions.ts | 4 +- src/webpage/style.css | 9 +- 6 files changed, 278 insertions(+), 7 deletions(-) create mode 100644 src/webpage/oauth2/auth.ts create mode 100644 src/webpage/oauth2/authorize.html diff --git a/src/webpage/home.html b/src/webpage/home.html index 8b49090..2482ec4 100644 --- a/src/webpage/home.html +++ b/src/webpage/home.html @@ -13,7 +13,7 @@ - +

Jank Client

@@ -58,4 +58,4 @@ - \ No newline at end of file + diff --git a/src/webpage/login.ts b/src/webpage/login.ts index 8dbefc7..99d66cc 100644 --- a/src/webpage/login.ts +++ b/src/webpage/login.ts @@ -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); diff --git a/src/webpage/oauth2/auth.ts b/src/webpage/oauth2/auth.ts new file mode 100644 index 0000000..4c99019 --- /dev/null +++ b/src/webpage/oauth2/auth.ts @@ -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); +})(); diff --git a/src/webpage/oauth2/authorize.html b/src/webpage/oauth2/authorize.html new file mode 100644 index 0000000..617fcfc --- /dev/null +++ b/src/webpage/oauth2/authorize.html @@ -0,0 +1,23 @@ + + + + + Jank Client + + + + + + + +
+
+ +

Bot Name

+

Add Bot

+

This will allow the bot to:

+ +
+
+ + diff --git a/src/webpage/permissions.ts b/src/webpage/permissions.ts index 483e207..21d80d8 100644 --- a/src/webpage/permissions.ts +++ b/src/webpage/permissions.ts @@ -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{ diff --git a/src/webpage/style.css b/src/webpage/style.css index 3add8c8..b83659d 100644 --- a/src/webpage/style.css +++ b/src/webpage/style.css @@ -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;