Open walter-0 opened 10 months ago
Someone left a YouTube comment to use their public endpoint, and I think it's a good idea for a lot of these features. If you can find a way to connect it into the extension that'd be awesome to not rely on this duct tapped web scraper.
Link to that endpoint?
The person was talking about that same public graphql endpoint. I think that LeetCode Query repo could work. Maybe we could do something like this: If we don't have their leetcode username we can intercept the http graphql response from leetcode when they get redirected to a problem since in the response it contains the username and then we can save the username in storage so we don't have to intercept it anymore? It's what I was thinking, but definitely mess around with it haha
That will work! Here's the link to the Leetcode API https://leetcode.com/graphql and here's the GraphQL query to check if the user is a premium user or not
query globalData {
userStatus {
isPremium
}
}
However, this might be a privacy concern as you could get any user data displayed on the website using this method, LeetCode doesn't have any documentation for their API but it is public and does not require a token once you know the queries
I think it'll be okay if the data used is publicly accessible, but I have no idea honestly
yeah that's what I was thinking too, trying my best to prevent going through personal details as much as possible, but I think as long as we use public information like their username only, and since these queries are public (for now) hopefully we're fine lol
I worked on this a bit over the weekend and I got stuck here. I'm adding an options page with an input for the user to put in their session cookie so the extension can know which problems they've solved, but I'm not able to get anything from credential.init
.
I'm using this library https://github.com/JacobLinCool/LeetCode-Query/
import { Credential, LeetCode } from "leetcode-query";
import { Storage } from "@plasmohq/storage";
import { useStorage } from "@plasmohq/storage/hook";
const storage = new Storage();
const Options: React.FC = () => {
const [leetcodeSessionCookie, setLeetcodeSessionCookie] =
useStorage<string>("");
const handleSaveUserToken = async () => {
const leetcode = new LeetCode();
const credential = new Credential();
await credential.init(
"YOUR_LEETCODE_SESSION_VALUE"
);
await storage.set("credential", credential);
await storage
.get("credential")
.then((credential) =>
console.log(credential ? credential : "no credential")
);
};
return (
<div>
<h1>Options</h1>
<h2>Leetcode Session Cookie</h2>
<textarea
placeholder="LEETCODE_SESSION"
onChange={(e) => setLeetcodeSessionCookie(e.target.value)}>
{leetcodeSessionCookie}
</textarea>
<button onClick={handleSaveUserToken}>Save</button>
</div>
);
};
export default Options;
whoops my bad about that one. Do we need their credentials for this: AcSubmissionNum. And is it session cookie or csrf token?
That's the thing
I don't know how to say this without sounding like a hacker, but the extension can get anything displayed on Leetcode's website, including their solved problems whether they are a premium subscriber or not, and more personal details
We'll have to be really careful when implementing it, and maybe have a consent form and promise the project will remain open source for anyone to see what data we use. We also can not store anything in a third-party database like MongoDB etc so we'll have to stick to the browser storage
I could walk you through getting the query needed for certain features from Leetcode, As long as it works on your laptop, it should work for the next person
You can also use this extension "GraphQL Playground for Chrome" to try out the queries you find
I don't know enough about making GraphQL APIs to know if this is from Leetcode's end or if the browser takes a request made from an extension as a user's request, but I tried it earlier, and I was able to get every data on my two accounts using the extension
hm that's interesting. Does it still work even if we modify the credential header in the fetch request? It could be possible that when we do this request, since it's on the user's browser, it already has access to their tokens which could be an issue lol.
That could be it. I know Leetcode's API doesn't have a token. I initially thought it was open source but queries like
query globalData {
userStatus {
isPremium
...
}
}
work without getting any information about who the user is, so it's definitely not open source like GItHub's, Maybe they check the cookies that come with the request like you said, that might be it
I'm more into frontend, so I don't know a lot about it, but it definitely shouldn't know I'm the one making the request if it's open source and does not ask for any ID or username
Yup just tested this query out:
const testQuery = ` query globalData {
userStatus {
userId
isSignedIn
isPremium
isVerified
username
}
}`
const testBody = {
query: testQuery
}
await fetch("https://leetcode.com/graphql", {
method: "POST",
body: JSON.stringify(testBody),
headers: {
"Content-Type": "application/json"
},
credentials: "omit" // This should be outside the headers object, ensures no credentials are sent with the fetch request.
})
and on the network tab on the extension it doesn't show any personal information anymore. So it's probably best to have that credential property for any queries we make.
Nice! Got it! I just moved the functionality over to the settings drawer, I will make a PR now and you could add it to the requests!
From what I've seen so far, a lot of the issues here, like these
https://github.com/The-CodingSloth/haha-funny-leetcode-extension/issues/33 https://github.com/The-CodingSloth/haha-funny-leetcode-extension/issues/29 https://github.com/The-CodingSloth/haha-funny-leetcode-extension/issues/20 https://github.com/The-CodingSloth/haha-funny-leetcode-extension/issues/4 https://github.com/The-CodingSloth/haha-funny-leetcode-extension/issues/2
could be fixed by using an API instead of a web scraper. Leetcode has a public graphql endpoint but there is no official documentation on how to use it, however there are open source APIs that people have put together. I'm currently looking into a few different APIs to see if I can connect the extension directly to LC's data for problems and user submissions.
https://github.com/codingsnack/leetcode-api/ https://github.com/JacobLinCool/LeetCode-Query