Beta migration
This commit is contained in:
parent
862f7f2296
commit
f388ff86a5
80
main
80
main
|
@ -109,6 +109,14 @@ def check_username_taken(username):
|
||||||
return "error"
|
return "error"
|
||||||
return post["id"]
|
return post["id"]
|
||||||
|
|
||||||
|
def check_sub_taken(sub):
|
||||||
|
conn = get_db_connection()
|
||||||
|
post = conn.execute("SELECT * FROM users WHERE password = ?",
|
||||||
|
(str("OAUTH-" + sub),)).fetchone()
|
||||||
|
conn.close()
|
||||||
|
if post is None:
|
||||||
|
return "error"
|
||||||
|
return post["id"]
|
||||||
|
|
||||||
def get_session(id):
|
def get_session(id):
|
||||||
conn = get_db_connection()
|
conn = get_db_connection()
|
||||||
|
@ -387,22 +395,54 @@ async def apilogin():
|
||||||
"error": "https://http.cat/images/400.jpg"
|
"error": "https://http.cat/images/400.jpg"
|
||||||
}, 400
|
}, 400
|
||||||
|
|
||||||
|
@app.route("/api/migrate", methods=("GET", "POST"))
|
||||||
|
async def migrate():
|
||||||
|
usersession = request.cookies.get("session_DO_NOT_SHARE")
|
||||||
|
if request.method == "POST":
|
||||||
|
data = await request.get_json()
|
||||||
|
sub = data["sub"]
|
||||||
|
password = data["access_token"]
|
||||||
|
userCookie = get_session(usersession)
|
||||||
|
user = get_user(userCookie["id"])
|
||||||
|
if user == "error":
|
||||||
|
return { "error": "User doesn't exist" }, 403
|
||||||
|
|
||||||
|
conn = get_db_connection()
|
||||||
|
subdata = '{"access_token":"' + password + '"}'
|
||||||
|
response = requests.post("https://auth.hectabit.org/api/uniqueid", subdata)
|
||||||
|
if response.status_code == 200:
|
||||||
|
data = response.json()
|
||||||
|
conn.execute("UPDATE users SET password = ? WHERE id = ?",
|
||||||
|
(str("OAUTH-" + data['uniqueid']), user["id"]))
|
||||||
|
else:
|
||||||
|
return {"error": response.json()["error"]}, response.status_code
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
return {"success": "true"}, 200
|
||||||
|
|
||||||
@app.route("/api/oauth", methods=("GET", "POST"))
|
@app.route("/api/oauth", methods=("GET", "POST"))
|
||||||
async def apioauth():
|
async def apioauth():
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
data = await request.get_json()
|
data = await request.get_json()
|
||||||
username = data["username"]
|
username = data["username"]
|
||||||
|
sub = data["sub"]
|
||||||
password = data["access_token"]
|
password = data["access_token"]
|
||||||
|
|
||||||
conn = get_db_connection()
|
conn = get_db_connection()
|
||||||
subdata = '{"access_token":"' + password + '"}'
|
subdata = '{"access_token":"' + password + '"}'
|
||||||
response = requests.post("https://auth.hectabit.org/api/loggedin", subdata)
|
response = requests.post("https://auth.hectabit.org/api/loggedin", subdata)
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
|
userID = check_sub_taken(sub)
|
||||||
|
user = get_user(userID)
|
||||||
|
if user == "error":
|
||||||
userID = check_username_taken(username)
|
userID = check_username_taken(username)
|
||||||
user = get_user(userID)
|
user = get_user(userID)
|
||||||
if user == "error":
|
if user == "error":
|
||||||
conn.execute("INSERT INTO users (username, password, created, htmldescription) VALUES (?, ?, ?, ?)",
|
conn.execute("INSERT INTO users (username, password, created, htmldescription) VALUES (?, ?, ?, ?)",
|
||||||
(username, "OAUTH2", str(time.time()), ""))
|
(username, str("OAUTH-" + sub), str(time.time()), ""))
|
||||||
|
else:
|
||||||
|
if user["password"] != "OAUTH-" + sub:
|
||||||
|
return {"error": "Migration required or username taken"}, 422
|
||||||
else:
|
else:
|
||||||
return {"error": response.json()["error"]}, response.status_code
|
return {"error": response.json()["error"]}, response.status_code
|
||||||
|
|
||||||
|
@ -553,6 +593,38 @@ async def cdn(filename):
|
||||||
else:
|
else:
|
||||||
return "file doesn't exist!!"
|
return "file doesn't exist!!"
|
||||||
|
|
||||||
|
@app.route("/legacysignup", methods=("GET", "POST"))
|
||||||
|
async def legacysignup():
|
||||||
|
usersession = request.cookies.get("session_DO_NOT_SHARE")
|
||||||
|
if usersession:
|
||||||
|
return redirect(url_for("main"))
|
||||||
|
if request.method == "POST":
|
||||||
|
requestData = await request.form
|
||||||
|
|
||||||
|
if not check_username_taken(requestData["username"]) == "error":
|
||||||
|
await flash("Username already taken :3")
|
||||||
|
return redirect(url_for("signup"))
|
||||||
|
|
||||||
|
if not requestData["username"].isalnum():
|
||||||
|
await flash("Username must be alphanumeric :3")
|
||||||
|
return redirect(url_for("signup"))
|
||||||
|
|
||||||
|
if not len(requestData["password"]) > int(PASSWORD_REQUIREMENT):
|
||||||
|
await flash("Password must contain at least " + PASSWORD_REQUIREMENT + " characters")
|
||||||
|
return redirect(url_for("signup"))
|
||||||
|
|
||||||
|
hashedpassword = generate_password_hash(requestData["password"])
|
||||||
|
|
||||||
|
conn = get_db_connection()
|
||||||
|
conn.execute("INSERT INTO users (username, password, created, htmldescription) VALUES (?, ?, ?, ?)",
|
||||||
|
(requestData["username"], hashedpassword, str(time.time()), ""))
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
return redirect(url_for("login"))
|
||||||
|
else:
|
||||||
|
return await render_template("signup.html")
|
||||||
|
|
||||||
@app.route("/signup", methods=("GET", "POST"))
|
@app.route("/signup", methods=("GET", "POST"))
|
||||||
async def signup():
|
async def signup():
|
||||||
usersession = request.cookies.get("session_DO_NOT_SHARE")
|
usersession = request.cookies.get("session_DO_NOT_SHARE")
|
||||||
|
@ -602,7 +674,11 @@ async def login():
|
||||||
|
|
||||||
@app.route("/oauth", methods=("GET", "POST"))
|
@app.route("/oauth", methods=("GET", "POST"))
|
||||||
async def oauth():
|
async def oauth():
|
||||||
|
legacymigrate = request.cookies.get("legacy_migrate")
|
||||||
|
if legacymigrate != "1":
|
||||||
return await render_template("oauth.html")
|
return await render_template("oauth.html")
|
||||||
|
else:
|
||||||
|
return await render_template("migrate.html")
|
||||||
|
|
||||||
@app.route("/settings", methods=("GET", "POST"))
|
@app.route("/settings", methods=("GET", "POST"))
|
||||||
async def settings():
|
async def settings():
|
||||||
|
@ -673,7 +749,7 @@ async def logout():
|
||||||
resp = redirect(url_for("main"))
|
resp = redirect(url_for("main"))
|
||||||
session = request.cookies.get("session_DO_NOT_SHARE")
|
session = request.cookies.get("session_DO_NOT_SHARE")
|
||||||
resp.delete_cookie("session_DO_NOT_SHARE")
|
resp.delete_cookie("session_DO_NOT_SHARE")
|
||||||
|
resp.delete_cookie("prefuser")
|
||||||
return resp
|
return resp
|
||||||
|
|
||||||
@app.errorhandler(500)
|
@app.errorhandler(500)
|
||||||
|
|
|
@ -0,0 +1,151 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/static/css/style.css">
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Login to Burgercat</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="accountform">
|
||||||
|
<br>
|
||||||
|
<a href="/">back</a><br><br>
|
||||||
|
<h1 id="text">Migrate to Burgerauth</h1>
|
||||||
|
<button onclick="authorize()">Link a Burgerauth Account</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function getCookie(name) {
|
||||||
|
var nameEQ = name + "=";
|
||||||
|
var ca = document.cookie.split(';');
|
||||||
|
for (var i = 0; i < ca.length; i++) {
|
||||||
|
var c = ca[i];
|
||||||
|
while (c.charAt(0) === ' ') c = c.substring(1, c.length);
|
||||||
|
if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configuration
|
||||||
|
const clientId = 'jT89GqLCqobN3pb6Rgkk0klDyicUbdjY';
|
||||||
|
const redirectUri = 'https://cat.hectabit.org/oauth';
|
||||||
|
const authorizationEndpoint = 'https://auth.hectabit.org/login';
|
||||||
|
const tokenEndpoint = 'https://auth.hectabit.org/api/tokenauth';
|
||||||
|
const userinfoEndpoint = 'https://auth.hectabit.org/userinfo'; // Added userinfo endpoint
|
||||||
|
|
||||||
|
// Generate a random code verifier
|
||||||
|
function generateCodeVerifier() {
|
||||||
|
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~";
|
||||||
|
const length = 128;
|
||||||
|
return Array.from(crypto.getRandomValues(new Uint8Array(length)))
|
||||||
|
.map((x) => charset[x % charset.length])
|
||||||
|
.join("");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a code challenge from the code verifier using SHA-256
|
||||||
|
async function createCodeChallenge(codeVerifier) {
|
||||||
|
const buffer = new TextEncoder().encode(codeVerifier);
|
||||||
|
const hashArrayBuffer = await crypto.subtle.digest('SHA-256', buffer);
|
||||||
|
const hashBase64 = btoa(String.fromCharCode(...new Uint8Array(hashArrayBuffer)))
|
||||||
|
.replace(/=/g, '')
|
||||||
|
.replace(/\+/g, '-')
|
||||||
|
.replace(/\//g, '_');
|
||||||
|
return hashBase64;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Authorization function with PKCE
|
||||||
|
function authorize() {
|
||||||
|
const codeVerifier = generateCodeVerifier();
|
||||||
|
localStorage.setItem('codeVerifier', codeVerifier); // Store code verifier
|
||||||
|
createCodeChallenge(codeVerifier)
|
||||||
|
.then((codeChallenge) => {
|
||||||
|
const authorizationUrl = `${authorizationEndpoint}?response_type=code&client_id=${clientId}&redirect_uri=${encodeURIComponent(redirectUri)}&code_challenge=${codeChallenge}&code_challenge_method=S256`;
|
||||||
|
window.location.href = authorizationUrl;
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error('Error generating code challenge:', error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the authorization code from the URL
|
||||||
|
function parseCodeFromUrl() {
|
||||||
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
return urlParams.get('code');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exchange authorization code for access token
|
||||||
|
async function exchangeCodeForToken(code) {
|
||||||
|
const codeVerifier = localStorage.getItem('codeVerifier'); // Retrieve code verifier
|
||||||
|
const formData = new URLSearchParams();
|
||||||
|
formData.append('client_id', String(clientId));
|
||||||
|
formData.append('code', String(code));
|
||||||
|
formData.append('redirect_uri', String(redirectUri));
|
||||||
|
formData.append('grant_type', 'authorization_code');
|
||||||
|
formData.append('code_verifier', String(codeVerifier));
|
||||||
|
|
||||||
|
const response = await fetch(tokenEndpoint, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/x-www-form-urlencoded"
|
||||||
|
},
|
||||||
|
body: formData
|
||||||
|
});
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
const accessToken = data.access_token;
|
||||||
|
const idToken = data.id_token;
|
||||||
|
|
||||||
|
// Request userinfo with id_token in bearer format
|
||||||
|
fetch(userinfoEndpoint, {
|
||||||
|
headers: {
|
||||||
|
"Authorization": `Bearer ${idToken}`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
async function doStuff() {
|
||||||
|
if (response.status == 200) {
|
||||||
|
const userinfoData = await response.json();
|
||||||
|
console.log("User:", userinfoData.name)
|
||||||
|
console.log("Sub:", userinfoData.sub);
|
||||||
|
document.getElementById("text").innerText = "Authenticating, " + userinfoData.name;
|
||||||
|
fetch("https://cat.hectabit.org/api/migrate", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
sub: userinfoData.sub,
|
||||||
|
access_token: data.access_token
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
async function doStuff2() {
|
||||||
|
if (response.status == 200) {
|
||||||
|
window.location.replace("/")
|
||||||
|
} else {
|
||||||
|
document.getElementById("text").innerText = "Failed: " + key["error"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
doStuff2()
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
document.getElementById("text").innerText = "Authentication failed"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
doStuff()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Main function to handle OAuth2 flow
|
||||||
|
async function main() {
|
||||||
|
const code = parseCodeFromUrl();
|
||||||
|
if (code) {
|
||||||
|
await exchangeCodeForToken(code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call the main function on page load
|
||||||
|
main();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,169 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/static/css/style.css">
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Login to Burgercat</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="accountform">
|
||||||
|
<br>
|
||||||
|
<a href="/">back</a><br><br>
|
||||||
|
<h1 id="text">Migration</h1>
|
||||||
|
<button onclick="authorize()">Migrate to Burgerauth Account</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function getCookie(name) {
|
||||||
|
var nameEQ = name + "=";
|
||||||
|
var ca = document.cookie.split(';');
|
||||||
|
for (var i = 0; i < ca.length; i++) {
|
||||||
|
var c = ca[i];
|
||||||
|
while (c.charAt(0) === ' ') c = c.substring(1, c.length);
|
||||||
|
if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configuration
|
||||||
|
const clientId = 'jT89GqLCqobN3pb6Rgkk0klDyicUbdjY';
|
||||||
|
const redirectUri = 'https://cat.hectabit.org/oauth';
|
||||||
|
const authorizationEndpoint = 'https://auth.hectabit.org/login';
|
||||||
|
const tokenEndpoint = 'https://auth.hectabit.org/api/tokenauth';
|
||||||
|
const userinfoEndpoint = 'https://auth.hectabit.org/userinfo'; // Added userinfo endpoint
|
||||||
|
|
||||||
|
// Generate a random code verifier
|
||||||
|
function generateCodeVerifier() {
|
||||||
|
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~";
|
||||||
|
const length = 128;
|
||||||
|
return Array.from(crypto.getRandomValues(new Uint8Array(length)))
|
||||||
|
.map((x) => charset[x % charset.length])
|
||||||
|
.join("");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a code challenge from the code verifier using SHA-256
|
||||||
|
async function createCodeChallenge(codeVerifier) {
|
||||||
|
const buffer = new TextEncoder().encode(codeVerifier);
|
||||||
|
const hashArrayBuffer = await crypto.subtle.digest('SHA-256', buffer);
|
||||||
|
const hashBase64 = btoa(String.fromCharCode(...new Uint8Array(hashArrayBuffer)))
|
||||||
|
.replace(/=/g, '')
|
||||||
|
.replace(/\+/g, '-')
|
||||||
|
.replace(/\//g, '_');
|
||||||
|
return hashBase64;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function cuser_authorize() {
|
||||||
|
document.cookie = "prefuser" + "=" + window.prompt("Choose your custom username (cannot be longer than 20 characters)") + "; expires=Session" + "; path=/" + "; samesite=Strict";
|
||||||
|
authorize()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Authorization function with PKCE
|
||||||
|
function authorize() {
|
||||||
|
const codeVerifier = generateCodeVerifier();
|
||||||
|
localStorage.setItem('codeVerifier', codeVerifier); // Store code verifier
|
||||||
|
createCodeChallenge(codeVerifier)
|
||||||
|
.then((codeChallenge) => {
|
||||||
|
const authorizationUrl = `${authorizationEndpoint}?response_type=code&client_id=${clientId}&redirect_uri=${encodeURIComponent(redirectUri)}&code_challenge=${codeChallenge}&code_challenge_method=S256`;
|
||||||
|
window.location.href = authorizationUrl;
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error('Error generating code challenge:', error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the authorization code from the URL
|
||||||
|
function parseCodeFromUrl() {
|
||||||
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
return urlParams.get('code');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exchange authorization code for access token
|
||||||
|
async function exchangeCodeForToken(code) {
|
||||||
|
const codeVerifier = localStorage.getItem('codeVerifier'); // Retrieve code verifier
|
||||||
|
const formData = new URLSearchParams();
|
||||||
|
formData.append('client_id', String(clientId));
|
||||||
|
formData.append('code', String(code));
|
||||||
|
formData.append('redirect_uri', String(redirectUri));
|
||||||
|
formData.append('grant_type', 'authorization_code');
|
||||||
|
formData.append('code_verifier', String(codeVerifier));
|
||||||
|
|
||||||
|
const response = await fetch(tokenEndpoint, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/x-www-form-urlencoded"
|
||||||
|
},
|
||||||
|
body: formData
|
||||||
|
});
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
const accessToken = data.access_token;
|
||||||
|
const idToken = data.id_token;
|
||||||
|
|
||||||
|
// Request userinfo with id_token in bearer format
|
||||||
|
fetch(userinfoEndpoint, {
|
||||||
|
headers: {
|
||||||
|
"Authorization": `Bearer ${idToken}`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
async function doStuff() {
|
||||||
|
if (response.status == 200) {
|
||||||
|
const userinfoData = await response.json();
|
||||||
|
console.log("User:", userinfoData.name)
|
||||||
|
console.log("Sub:", userinfoData.sub);
|
||||||
|
let preferreduser = userinfoData.name
|
||||||
|
if (getCookie("prefuser") != "") {
|
||||||
|
preferreduser = getCookie("prefuser")
|
||||||
|
}
|
||||||
|
document.getElementById("text").innerText = "Authenticating, " + userinfoData.name;
|
||||||
|
fetch("https://cat.hectabit.org/api/migrate", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
username: preferreduser,
|
||||||
|
access_token: data.access_token
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
async function doStuff2() {
|
||||||
|
let key = await response.json()
|
||||||
|
if (response.status == 200) {
|
||||||
|
document.cookie = "session_DO_NOT_SHARE" + "=" + (key["key"] || "") + "; expires=Session" + "; path=/" + "; samesite=Strict";
|
||||||
|
window.location.replace("/")
|
||||||
|
} else if (response.status == 422) {
|
||||||
|
document.getElementById("text").innerText = "Username taken. Migrate or choose a new custom username!"
|
||||||
|
} else {
|
||||||
|
document.getElementById("text").innerText = "Failed: " + key["error"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
doStuff2()
|
||||||
|
});
|
||||||
|
localStorage.setItem("user", preferreduser)
|
||||||
|
} else {
|
||||||
|
document.getElementById("text").innerText = "Authentication failed"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
doStuff()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Main function to handle OAuth2 flow
|
||||||
|
async function main() {
|
||||||
|
if (localStorage.getItem("user") !== null) {
|
||||||
|
document.getElementById("text").innerText = "Welcome back, " + localStorage.getItem("user")
|
||||||
|
}
|
||||||
|
const code = parseCodeFromUrl();
|
||||||
|
if (code) {
|
||||||
|
await exchangeCodeForToken(code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call the main function on page load
|
||||||
|
main();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -13,10 +13,23 @@
|
||||||
<h1 id="text">Login to Burgercat</h1>
|
<h1 id="text">Login to Burgercat</h1>
|
||||||
<button onclick="authorize()">Log in with Burgerauth Account</button>
|
<button onclick="authorize()">Log in with Burgerauth Account</button>
|
||||||
<br><br>
|
<br><br>
|
||||||
|
<button onclick="cuser_authorize()">Log in with Burgerauth Account (custom username)</button>
|
||||||
|
<br><br>
|
||||||
<button onclick="window.location.href = '/login'">Use legacy login</button>
|
<button onclick="window.location.href = '/login'">Use legacy login</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
function getCookie(name) {
|
||||||
|
var nameEQ = name + "=";
|
||||||
|
var ca = document.cookie.split(';');
|
||||||
|
for (var i = 0; i < ca.length; i++) {
|
||||||
|
var c = ca[i];
|
||||||
|
while (c.charAt(0) === ' ') c = c.substring(1, c.length);
|
||||||
|
if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
// Configuration
|
// Configuration
|
||||||
const clientId = 'jT89GqLCqobN3pb6Rgkk0klDyicUbdjY';
|
const clientId = 'jT89GqLCqobN3pb6Rgkk0klDyicUbdjY';
|
||||||
const redirectUri = 'https://cat.hectabit.org/oauth';
|
const redirectUri = 'https://cat.hectabit.org/oauth';
|
||||||
|
@ -44,6 +57,12 @@
|
||||||
return hashBase64;
|
return hashBase64;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function cuser_authorize() {
|
||||||
|
document.cookie = "prefuser" + "=" + window.prompt("Choose your custom username (cannot be longer than 20 characters)") + "; expires=Session" + "; path=/" + "; samesite=Strict";
|
||||||
|
authorize()
|
||||||
|
}
|
||||||
|
|
||||||
// Authorization function with PKCE
|
// Authorization function with PKCE
|
||||||
function authorize() {
|
function authorize() {
|
||||||
const codeVerifier = generateCodeVerifier();
|
const codeVerifier = generateCodeVerifier();
|
||||||
|
@ -98,6 +117,10 @@
|
||||||
const userinfoData = await response.json();
|
const userinfoData = await response.json();
|
||||||
console.log("User:", userinfoData.name)
|
console.log("User:", userinfoData.name)
|
||||||
console.log("Sub:", userinfoData.sub);
|
console.log("Sub:", userinfoData.sub);
|
||||||
|
let preferreduser = userinfoData.name
|
||||||
|
if (getCookie("prefuser") != "") {
|
||||||
|
preferreduser = getCookie("prefuser")
|
||||||
|
}
|
||||||
document.getElementById("text").innerText = "Authenticating, " + userinfoData.name;
|
document.getElementById("text").innerText = "Authenticating, " + userinfoData.name;
|
||||||
fetch("https://cat.hectabit.org/api/oauth", {
|
fetch("https://cat.hectabit.org/api/oauth", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
|
@ -105,8 +128,9 @@
|
||||||
"Content-Type": "application/json"
|
"Content-Type": "application/json"
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
username: userinfoData.name,
|
username: preferreduser,
|
||||||
access_token: data.access_token
|
access_token: data.access_token,
|
||||||
|
sub: userinfoData.sub
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
|
@ -115,14 +139,15 @@
|
||||||
if (response.status == 200) {
|
if (response.status == 200) {
|
||||||
document.cookie = "session_DO_NOT_SHARE" + "=" + (key["key"] || "") + "; expires=Session" + "; path=/" + "; samesite=Strict";
|
document.cookie = "session_DO_NOT_SHARE" + "=" + (key["key"] || "") + "; expires=Session" + "; path=/" + "; samesite=Strict";
|
||||||
window.location.replace("/")
|
window.location.replace("/")
|
||||||
|
} else if (response.status == 422) {
|
||||||
|
document.getElementById("text").innerText = "Username taken. Migrate or choose a new custom username!"
|
||||||
} else {
|
} else {
|
||||||
document.getElementById("text").innerText = "Failed: " + key["error"]
|
document.getElementById("text").innerText = "Failed: " + key["error"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
doStuff2()
|
doStuff2()
|
||||||
});
|
});
|
||||||
localStorage.setItem("user", userinfoData.name)
|
localStorage.setItem("user", preferreduser)
|
||||||
localStorage.setItem("sub", userinfoData.sub)
|
|
||||||
} else {
|
} else {
|
||||||
document.getElementById("text").innerText = "Authentication failed"
|
document.getElementById("text").innerText = "Authentication failed"
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,9 +10,6 @@
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<script>
|
|
||||||
window.location.replace("/oauth")
|
|
||||||
</script>
|
|
||||||
<form class="accountform" method="post">
|
<form class="accountform" method="post">
|
||||||
<br>
|
<br>
|
||||||
<a href="/">back</a>
|
<a href="/">back</a>
|
||||||
|
|
Reference in New Issue