improvements to the login and register pages
This update adds to the instance picker instances for the user to select from, along with some documentation for instance owners on how to add their own instance to the picker
This commit is contained in:
parent
b2c0adec68
commit
6b09588fb9
6 changed files with 232 additions and 69 deletions
109
.dist/login.js
109
.dist/login.js
|
@ -154,7 +154,30 @@ function adduser(user) {
|
|||
const instancein = document.getElementById("instancein");
|
||||
let timeout;
|
||||
let instanceinfo;
|
||||
const stringURLMap = new Map();
|
||||
const stringURLsMap = new Map();
|
||||
async function getapiurls(str) {
|
||||
if (!URL.canParse(str)) {
|
||||
const val = stringURLMap.get(str);
|
||||
if (val) {
|
||||
str = val;
|
||||
}
|
||||
else {
|
||||
const val = stringURLsMap.get(str);
|
||||
if (val) {
|
||||
const responce = await fetch(val.api + val.api.endsWith("/") ? "" : "/" + "ping");
|
||||
if (responce.ok) {
|
||||
if (val.login) {
|
||||
return val;
|
||||
}
|
||||
else {
|
||||
val.login = val.api;
|
||||
return val;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (str[str.length - 1] !== "/") {
|
||||
str += "/";
|
||||
}
|
||||
|
@ -178,6 +201,19 @@ async function getapiurls(str) {
|
|||
};
|
||||
}
|
||||
catch {
|
||||
const val = stringURLsMap.get(str);
|
||||
if (val) {
|
||||
const responce = await fetch(val.api + val.api.endsWith("/") ? "" : "/" + "ping");
|
||||
if (responce.ok) {
|
||||
if (val.login) {
|
||||
return val;
|
||||
}
|
||||
else {
|
||||
val.login = val.api;
|
||||
return val;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -185,7 +221,9 @@ async function checkInstance(e) {
|
|||
const verify = document.getElementById("verify");
|
||||
try {
|
||||
verify.textContent = "Checking Instance";
|
||||
const instanceinfo = await setInstance(instancein.value);
|
||||
const instanceinfo = await getapiurls(instancein.value);
|
||||
if (instanceinfo) {
|
||||
instanceinfo.value = instancein.value;
|
||||
localStorage.setItem("instanceinfo", JSON.stringify(instanceinfo));
|
||||
verify.textContent = "Instance is all good";
|
||||
if (checkInstance["alt"]) {
|
||||
|
@ -196,6 +234,10 @@ async function checkInstance(e) {
|
|||
verify.textContent = "";
|
||||
}, 3000);
|
||||
}
|
||||
else {
|
||||
verify.textContent = "Invalid Instance, try again";
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
console.log("catch");
|
||||
verify.textContent = "Invalid Instance, try again";
|
||||
|
@ -210,7 +252,13 @@ if (instancein) {
|
|||
timeout = setTimeout(checkInstance, 1000);
|
||||
});
|
||||
if (localStorage.getItem("instanceinfo")) {
|
||||
instancein.value = JSON.parse(localStorage.getItem("instanceinfo")).wellknown;
|
||||
const json = JSON.parse(localStorage.getItem("instanceinfo"));
|
||||
if (json.value) {
|
||||
instancein.value = json.value;
|
||||
}
|
||||
else {
|
||||
instancein.value = json.wellknown;
|
||||
}
|
||||
}
|
||||
else {
|
||||
checkInstance("https://spacebar.chat/");
|
||||
|
@ -316,29 +364,6 @@ async function login(username, password, captcha) {
|
|||
}
|
||||
;
|
||||
}
|
||||
async function setInstance(url) {
|
||||
url = new URL(url);
|
||||
async function attempt(aurl) {
|
||||
const info = await fetch(`${aurl.toString()}${aurl.pathname.includes("api") ? "" : "api"}/policies/instance/domains`)
|
||||
.then((x) => x.json());
|
||||
return {
|
||||
api: info.apiEndpoint,
|
||||
gateway: info.gateway,
|
||||
cdn: info.cdn,
|
||||
wellknown: url,
|
||||
login: aurl.toString()
|
||||
};
|
||||
}
|
||||
try {
|
||||
return await attempt(url);
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
const wellKnown = await fetch(`${url.origin}/.well-known/spacebar`)
|
||||
.then((x) => x.json())
|
||||
.then((x) => new URL(x.api));
|
||||
return await attempt(wellKnown);
|
||||
}
|
||||
async function check(e) {
|
||||
e.preventDefault();
|
||||
let h = await login(e.srcElement[1].value, e.srcElement[2].value, e.srcElement[3].value);
|
||||
|
@ -387,3 +412,37 @@ if (switchurl) {
|
|||
export { checkInstance };
|
||||
trimswitcher();
|
||||
export { mobile, getBulkUsers, getBulkInfo, setTheme, Specialuser, getapiurls, adduser };
|
||||
const datalist = document.getElementById("instances");
|
||||
console.warn(datalist);
|
||||
if (datalist) {
|
||||
fetch("/instances.json").then(_ => _.json()).then((json) => {
|
||||
console.warn(json);
|
||||
if (instancein && instancein.value === "") {
|
||||
instancein.value = json[0].name;
|
||||
setTimeout(checkInstance, 10);
|
||||
}
|
||||
for (const instance of json) {
|
||||
const option = document.createElement("option");
|
||||
option.value = instance.name;
|
||||
if (instance.URL) {
|
||||
stringURLMap.set(option.value, instance.URL);
|
||||
if (instance.URLs) {
|
||||
stringURLsMap.set(instance.URL, instance.URLs);
|
||||
}
|
||||
}
|
||||
else if (instance.URLs) {
|
||||
stringURLsMap.set(option.value, instance.URLs);
|
||||
}
|
||||
else {
|
||||
option.disabled = true;
|
||||
}
|
||||
if (instance.description) {
|
||||
option.label = instance.description;
|
||||
}
|
||||
else {
|
||||
option.label = instance.name;
|
||||
}
|
||||
datalist.append(option);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
35
InstanceInfo.md
Normal file
35
InstanceInfo.md
Normal file
|
@ -0,0 +1,35 @@
|
|||
# How to add your instance to Jank Client
|
||||
inside of webpage you'll see a file called `instances.json` in that file you'll need to add your instance and its information in the following format if you want your instance to be a part of the drop down.
|
||||
```json
|
||||
{
|
||||
"name":<name>,
|
||||
"description"?:<short description>,
|
||||
"descriptionLong"?:<A description for the instance that can be longer>,
|
||||
"src"?:<URL to image repersenting your instance>,
|
||||
"URL"?:<The URL that can be used to get your wellknown>,
|
||||
"URLs"?:{
|
||||
"wellknown":<wellknown URL>,
|
||||
"api":<API URL>,
|
||||
"cdn":<CDN URL>,
|
||||
"gateway":<gateway URL>,
|
||||
"login"?:<The URL that's used for login>
|
||||
},
|
||||
"contactInfo"?:{
|
||||
"dicord"?:<Discord @>,
|
||||
"github"?:<github profile URL>,
|
||||
"email"?:<email address>,
|
||||
"spacebar":?:<spacebar username>,
|
||||
"matrix"?:<matrix account>,
|
||||
"mastodon"?:<mastodon account>
|
||||
}
|
||||
}
|
||||
```
|
||||
anything with a `?` in-front of its `:` are optional, though you must either include `"URL"` or `"URLs"`, but you may include both, though the client will most likely ignore `"URLs"` in favor of `"URL"`, though it may use `"URLs"` as a fallback if `"URL"` does not resolve, do not rely on this behavior.
|
||||
Some of these values may not be used right now, though they will likely be used in the future, so feel free to fill out what you like, though the more you fill out the more information we can give the users about your instance in the future.
|
||||
# Questions
|
||||
## Do I have to do this to let Jank Client connect to my server?
|
||||
No, you may choose to not do this, this just makes it easier for people using Jank Client to find and use your instance as it's in the dropdown menu for instances, though the user may enter any instance they please.
|
||||
## If my instance isn't spacebar is that allowed to be entered?
|
||||
If it's spacebar compatable, yes it may be entered, though if there are too many incompatablities, it may not be included, or may need a warning of sorts.
|
||||
## I'm hosting my own instance of spacebar and would like to change the defualt instance on my instance of Jank Client to my own instance.
|
||||
Just change the first entry in the list to your own, and it should connect without issue.
|
14
webpage/instances.json
Normal file
14
webpage/instances.json
Normal file
|
@ -0,0 +1,14 @@
|
|||
[
|
||||
{
|
||||
"name":"Spacebar Official",
|
||||
"description":"The official instance of spacebar!",
|
||||
"src":"https://cdn.old.server.spacebar.chat/icons/1006649183970562092/fb5218b5dfad5e1c7b452c17ddb1701e.png",
|
||||
"URL":"https://spacebar.chat"
|
||||
},
|
||||
{
|
||||
"name":"Vanilla Games",
|
||||
"description":"The spacebar instance for Vanilla games",
|
||||
"src":"https://vanillaminigames.net/img/favicon.ico",
|
||||
"URL":"https://vanillaminigames.net/"
|
||||
}
|
||||
]
|
|
@ -15,7 +15,7 @@
|
|||
<form id="form" submit="check(e)">
|
||||
<label for="instance"><b>Instance:</b></label><br>
|
||||
<p id="verify"></p>
|
||||
<input type="text" placeholder="Instance URL" name="instance" id="instancein" value="https://spacebar.chat/" id="instancein" required><br><br>
|
||||
<input type="search" list="instances" placeholder="Instance URL" name="instance" id="instancein" value="" id="instancein" required><br><br>
|
||||
|
||||
<label for="uname"><b>Email:</b></label><br>
|
||||
<input type="text" placeholder="Enter email address" name="uname" id="uname" required><br><br>
|
||||
|
@ -31,5 +31,6 @@
|
|||
</form>
|
||||
<a href="/register.html" id="switch">Don't have an account?</a>
|
||||
</div>
|
||||
<datalist id="instances"></datalist>
|
||||
<script src="/login.js" type="module" ></script>
|
||||
</body>
|
||||
|
|
107
webpage/login.ts
107
webpage/login.ts
|
@ -153,7 +153,30 @@ function adduser(user){
|
|||
const instancein=document.getElementById("instancein") as HTMLInputElement;
|
||||
let timeout;
|
||||
let instanceinfo;
|
||||
const stringURLMap=new Map<string,string>();
|
||||
|
||||
const stringURLsMap=new Map<string,{wellknown:string,api:string,cdn:string,gateway:string,login?:string}>();
|
||||
async function getapiurls(str:string):Promise<{api:string,cdn:string,gateway:string,wellknown:string,login:string}|false>{
|
||||
if(!URL.canParse(str)){
|
||||
const val=stringURLMap.get(str);
|
||||
if(val){
|
||||
str=val;
|
||||
}else{
|
||||
const val=stringURLsMap.get(str)
|
||||
if(val){
|
||||
const responce=await fetch(val.api+val.api.endsWith("/")?"":"/"+"ping");
|
||||
if(responce.ok){
|
||||
if(val.login){
|
||||
return val as {wellknown:string,api:string,cdn:string,gateway:string,login:string};
|
||||
}else{
|
||||
val.login=val.api;
|
||||
return val as {wellknown:string,api:string,cdn:string,gateway:string,login:string};
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(str[str.length-1]!=="/"){
|
||||
str+="/"
|
||||
}
|
||||
|
@ -176,6 +199,19 @@ async function getapiurls(str:string):Promise<{api:string,cdn:string,gateway:str
|
|||
login:url.toString()
|
||||
};
|
||||
}catch{
|
||||
const val=stringURLsMap.get(str)
|
||||
if(val){
|
||||
const responce=await fetch(val.api+val.api.endsWith("/")?"":"/"+"ping");
|
||||
if(responce.ok){
|
||||
if(val.login){
|
||||
return val as {wellknown:string,api:string,cdn:string,gateway:string,login:string};
|
||||
}else{
|
||||
val.login=val.api;
|
||||
return val as {wellknown:string,api:string,cdn:string,gateway:string,login:string};
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -184,7 +220,9 @@ async function checkInstance(e:string){
|
|||
const verify=document.getElementById("verify");
|
||||
try{
|
||||
verify.textContent="Checking Instance";
|
||||
const instanceinfo=await setInstance((instancein as HTMLInputElement).value);
|
||||
const instanceinfo=await getapiurls((instancein as HTMLInputElement).value) as {wellknown:string,api:string,cdn:string,gateway:string,login:string, value:string};
|
||||
if(instanceinfo){
|
||||
instanceinfo.value=(instancein as HTMLInputElement).value;
|
||||
localStorage.setItem("instanceinfo",JSON.stringify(instanceinfo));
|
||||
verify.textContent="Instance is all good"
|
||||
if(checkInstance["alt"]){checkInstance["alt"]();}
|
||||
|
@ -192,7 +230,9 @@ async function checkInstance(e:string){
|
|||
console.log(verify.textContent)
|
||||
verify.textContent="";
|
||||
},3000);
|
||||
|
||||
}else{
|
||||
verify.textContent="Invalid Instance, try again"
|
||||
}
|
||||
}catch(e){
|
||||
console.log("catch")
|
||||
verify.textContent="Invalid Instance, try again"
|
||||
|
@ -207,7 +247,12 @@ if(instancein){
|
|||
timeout=setTimeout(checkInstance,1000);
|
||||
});
|
||||
if(localStorage.getItem("instanceinfo")){
|
||||
(instancein as HTMLInputElement).value=JSON.parse(localStorage.getItem("instanceinfo")).wellknown
|
||||
const json=JSON.parse(localStorage.getItem("instanceinfo"));
|
||||
if(json.value){
|
||||
(instancein as HTMLInputElement).value=json.value
|
||||
}else{
|
||||
(instancein as HTMLInputElement).value=json.wellknown
|
||||
}
|
||||
}else{
|
||||
checkInstance("https://spacebar.chat/");
|
||||
}
|
||||
|
@ -306,30 +351,6 @@ async function login(username:string, password:string, captcha:string){
|
|||
console.error('Error:', error);
|
||||
};
|
||||
}
|
||||
async function setInstance(url){
|
||||
url=new URL(url);
|
||||
async function attempt(aurl){
|
||||
const info=await fetch(`${aurl.toString()}${aurl.pathname.includes("api") ? "" : "api"}/policies/instance/domains`)
|
||||
.then((x) => x.json());
|
||||
return {
|
||||
api: info.apiEndpoint,
|
||||
gateway: info.gateway,
|
||||
cdn: info.cdn,
|
||||
wellknown: url,
|
||||
login:aurl.toString()
|
||||
}
|
||||
}
|
||||
try{
|
||||
return await attempt(url);
|
||||
}catch(e){
|
||||
|
||||
}
|
||||
const wellKnown = await fetch(`${url.origin}/.well-known/spacebar`)
|
||||
.then((x) => x.json())
|
||||
.then((x) => new URL(x.api));
|
||||
return await attempt(wellKnown);
|
||||
}
|
||||
|
||||
|
||||
async function check(e){
|
||||
|
||||
|
@ -380,3 +401,35 @@ if(switchurl){
|
|||
export {checkInstance};
|
||||
trimswitcher();
|
||||
export {mobile, getBulkUsers,getBulkInfo,setTheme,Specialuser,getapiurls,adduser}
|
||||
|
||||
const datalist=document.getElementById("instances");
|
||||
console.warn(datalist);
|
||||
if(datalist){
|
||||
fetch("/instances.json").then(_=>_.json()).then((json:{name:string,description?:string,src?:string,URL?:string,URLs:{wellknown:string,api:string,cdn:string,gateway:string,login?:string}}[])=>{
|
||||
console.warn(json);
|
||||
if(instancein&&instancein.value===""){
|
||||
instancein.value=json[0].name;
|
||||
setTimeout(checkInstance,10);
|
||||
}
|
||||
for(const instance of json){
|
||||
const option=document.createElement("option");
|
||||
option.value=instance.name;
|
||||
if(instance.URL){
|
||||
stringURLMap.set(option.value,instance.URL);
|
||||
if(instance.URLs){
|
||||
stringURLsMap.set(instance.URL,instance.URLs);
|
||||
}
|
||||
}else if(instance.URLs){
|
||||
stringURLsMap.set(option.value,instance.URLs);
|
||||
}else{
|
||||
option.disabled=true;
|
||||
}
|
||||
if(instance.description){
|
||||
option.label=instance.description;
|
||||
}else{
|
||||
option.label=instance.name;
|
||||
}
|
||||
datalist.append(option);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
<div>
|
||||
<label for="instance"><b>Instance:</b></label><br>
|
||||
<p id="verify"></p>
|
||||
<input type="text" placeholder="Instance URL" id="instancein" name="instance" value="https://spacebar.chat/" id="instancein" required>
|
||||
<input type="search" list="instances" placeholder="Instance URL" id="instancein" name="instance" value="" id="instancein" required>
|
||||
</div>
|
||||
<div>
|
||||
<label for="uname"><b>Email:</b></label><br>
|
||||
|
@ -55,5 +55,6 @@
|
|||
</form>
|
||||
<a href="/login.html" id="switch">Already have an account?</a>
|
||||
</div>
|
||||
<datalist id="instances"></datalist>
|
||||
<script src="/register.js" type="module"></script>
|
||||
</body>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue