diff --git a/JS/BlueskyAPI.js b/JS/BlueskyAPI.js index d8d0305..771f341 100644 --- a/JS/BlueskyAPI.js +++ b/JS/BlueskyAPI.js @@ -36,26 +36,31 @@ export async function CreatePKCECodeChallenge(CodeVerifier) { // Component 3/4 export async function PARrequest(PAREndpoint, State, ChallengeCode) { - return fetch(PAREndpoint, {method: "POST", body: new URLSearchParams({ response_type: "code", code_challenge_method: "S256", scope: "atproto transition:generic", client_id: "https://fedi.crowdedgames.group/oauth/client-metadata.json", redirect_uri: "https://fedi.crowdedgames.group/HTML/setting.html", code_challenge: ChallengeCode, state: State, login_hint: "crowdedgames.group" }), "Content-Type": "application/x-www-form-urlencoded"}); + return fetch(PAREndpoint, {method: "POST", body: new URLSearchParams({ response_type: "code", code_challenge_method: "S256", scope: "atproto transition:generic", client_id: "https://fedi.crowdedgames.group/oauth/client-metadata.json", redirect_uri: "https://fedi.crowdedgames.group/HTML/setting.html", code_challenge: ChallengeCode, state: State, login_hint: "crowdedgames.group" }), headers: {"Content-Type": "application/x-www-form-urlencoded"}}); +} + +export async function AuthRequest(TokenEndpoint, ChallengeVerifier, code, DPoP) { + return fetch(TokenEndpoint, {method: "POST", body: new URLSearchParams({ grant_type: "authorization_code", code: code, client_id: "https://fedi.crowdedgames.group/oauth/client-metadata.json", redirect_uri: "https://fedi.crowdedgames.group/HTML/setting.html", code_verifier: ChallengeVerifier}), headers: { "DPoP": DPoP, "Content-Type": "application/x-www-form-urlencoded"}}); } // Component 4/4 -export async function ClientDPoP(POSTorGET, RequestURL, DPoPNonce, publicKey) { +export async function ClientDPoP(POSTorGET, RequestURL, DPoPNonce) { let KeyPair = await crypto.subtle.generateKey({name: "ECDSA", namedCurve: "P-256"}, true, ["sign", "verify"]); // Header - var Header = {alg: "HS256", typ: "dpop+jwt", jwk: await crypto.subtle.exportKey("jwk", KeyPair.publicKey).then(function(response) {return response})}; + var Header = {alg: "ES256", typ: "dpop+jwt", jwk: await crypto.subtle.exportKey("jwk", KeyPair.publicKey).then(function(response) {return response})}; // Payload var Payload = {}; Payload.jti = GenerateToken(64); Payload.htm = POSTorGET; Payload.htu = RequestURL; Payload.iat = Math.floor(new Date(Date.now()).getTime() / 1000); + Payload.iss = "https://fedi.crowdedgames.group/oauth/client-metadata.json"; Payload.nonce = DPoPNonce; var sHeader = JSON.stringify(Header); var sPayload = JSON.stringify(Payload); - var JWT = KJUR.jws.JWS.sign("HS256", sHeader, sPayload, "616161"); + var JWT = KJUR.jws.JWS.sign("ES256", sHeader, sPayload, await crypto.subtle.exportKey("jwk", KeyPair.privateKey).then(function(response) {return response})); console.log(JWT); return JWT; } @@ -109,8 +114,15 @@ export async function HandleAuthorization(BlueskyPKCEverifer, BlueskyPKCEchallen document.location.href = "https://bsky.social/oauth/authorize?client_id=https://fedi.crowdedgames.group/oauth/client-metadata.json&request_uri=" + body.request_uri; } -export async function GainTokens() { - +export async function GainTokens(PKCEcodeName, NonceName) { + if ((document.location.href.split("state=").length > 1 && document.location.href.split("iss=").length > 1 && document.location.href.split("code=").length > 1) && document.cookie.split("; ").find((row) => row.startsWith(PKCEcodeName + "="))?.split("=").length > 1) { + let DPoP = ClientDPoP("POST", "https://bsky.social/oauth/token", document.cookie.split("; ").find((row) => row.startsWith(NonceName + "="))?.split("=")[1]); + let PKCE = document.cookie.split("; ").find((row) => row.startsWith(PKCEcodeName + "="))?.split("=")[1]; + let code = document.location.href.split("code=")[1]; + console.log(code); + let Auth = AuthRequest("https://bsky.social/oauth/token", PKCE, code, DPoP); + console.log(AuthRequest); + } } // Stolen from elsewhere. diff --git a/JS/setting.js b/JS/setting.js index 6170cd3..811b3bc 100644 --- a/JS/setting.js +++ b/JS/setting.js @@ -79,12 +79,13 @@ BlueskyLogoutButton.onclick = (event) => { document.cookie = BlueskyPKCEverifer + "=nothing;" + ";samesite=strict;path=/;expires=Thu, 01 Jan 1970 00:00:00 GMT;"; document.cookie = BlueskyPKCEchallenge + "=nothing;" + ";samesite=strict;path=/;expires=Thu, 01 Jan 1970 00:00:00 GMT;"; document.cookie = BlueskyNonce + "=nothing;" + ";samesite=strict;path=/;expires=Thu, 01 Jan 1970 00:00:00 GMT;"; + document.location.href = document.location.href; } // if an access token is found, login. function CheckLogin() { // Check for a mastodon token. - if (document.cookie.split("; ").find((row) => row.startsWith(MastodonAccessToken + "="))?.split("=").length > 1 || document.location.href.split("code=").length == 1) { + if (document.cookie.split("; ").find((row) => row.startsWith(MastodonAccessToken + "="))?.split("=").length > 1 && document.location.href.split("code=").length == 1) { // Swap the buttons MastodonLoginButton.remove(); MastodonWebInput.remove(); @@ -93,14 +94,14 @@ function CheckLogin() { // Auto log in MastodonAPI.GainToken(MastodonWebsite, MastodonClientID, MastodonClientSecret, MastodonAccessToken, MastodonTokenType); } - if ((document.location.href.split("state=").length == 1 && document.location.href.split("iss==").length == 1 && document.location.href.split("code=").length == 1) || || document.cookie.split("; ").find((row) => row.startsWith(BlueskyAccessToken + "="))?.split("=").length > 1) { + if ((document.location.href.split("state=").length == 1 && document.location.href.split("iss=").length == 1 && document.location.href.split("code=").length == 1) && document.cookie.split("; ").find((row) => row.startsWith(BlueskyAccessToken + "="))?.split("=").length > 1) { // Swap the buttons BlueskyLoginButton.remove(); BlueskyWebInput.remove(); BlueskyLogoutButton.setAttribute("style", ""); } else { // Auto log in - BlueskyAPI.GainTokens(); + BlueskyAPI.GainTokens(BlueskyPKCEchallenge, BlueskyNonce); } // Check for a bluesky token. }