<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[SSHing my way through]]></title><description><![CDATA[A collection of concepts and ideas learnt and developed throughout my journey in the tech world]]></description><link>https://blog.yassh.in</link><generator>RSS for Node</generator><lastBuildDate>Thu, 23 Apr 2026 22:14:33 GMT</lastBuildDate><atom:link href="https://blog.yassh.in/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[How I Discovered 74,000 Exposed Profiles: Inside the Mood Indigo Security Disaster]]></title><description><![CDATA[TLDR: The Mood Indigo website had critical security flaws, including unsecured user profile updates, client-side OTP verification, token misuse granting access with just an email, and an exposed database of 74k+ users accessible via a public link. De...]]></description><link>https://blog.yassh.in/how-i-discovered-74000-exposed-profiles-inside-the-mood-indigo-security-disaster</link><guid isPermaLink="true">https://blog.yassh.in/how-i-discovered-74000-exposed-profiles-inside-the-mood-indigo-security-disaster</guid><category><![CDATA[Security]]></category><category><![CDATA[#cybersecurity]]></category><category><![CDATA[Databases]]></category><category><![CDATA[Web Development]]></category><dc:creator><![CDATA[Yash]]></dc:creator><pubDate>Sun, 29 Dec 2024 10:43:28 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1735463782929/71281fa0-68e6-4cd0-8694-1259fd0f8edb.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>TLDR: The Mood Indigo website had critical security flaws, including unsecured user profile updates, client-side OTP verification, token misuse granting access with just an email, and an exposed database of 74k+ users accessible via a public link. Despite reporting these issues multiple times, the team did not respond, and the server remained vulnerable until it was eventually taken down. This highlights the importance of prioritizing security in web development and being cautious with personal data online.</em></p>
<p><code>Disclaimer: I am not targeting any individual, group or organisation, all the data shared below is for archival and educational purposes. Also, no attempt has been made to share the data of affected individuals, the backend server is down as I write this, and has been down for more than 48 hours, hence no URL is accessible.</code></p>
<p>Last year, I attended Mood Indigo to watch <a target="_blank" href="https://www.youtube.com/watch?v=kmjeMrjOjFA">Shreyas</a>’s concert, and this year, they raised the bar by organizing Raftaar Bhai’s performance. Eager to attend, I visited their website and registered myself. While exploring the site, I noticed that although the UI loaded instantly, the data took a considerable amount of time to load. Curiosity sparked within me, and I began to wonder about the reasons behind this delay. Little did I know, this would mark the beginning of my journey into uncovering one of the most insecure websites I have ever come across.</p>
<p>Please note that I have reported the vulnerabilities to the concerned people and the server is down now, so you won’t be able to access the data if you visit these links. Also, I have not HACKED or got UNAUTHORIZED ACCESS to anything, all the mentioned methods were public, just hidden behind client side JavaScript.</p>
<p>Let’s start with simple things, every request which modifies the data should be generally only done via tokens, which are long randomly generated strings used to identify a user on the server side. This ensures that bad actors cannot mess with any of the database fields because tokens are almost impossible to guess or brute force, so with every request, we send a token which works as a mode of authentication. And then the request is processed, but the mood indigo website does not follow the norms.</p>
<p>To make any request related to profile details changes, interaction with point systems, threads or any other such features of the website, you just need the user id of the user and you can do whatever you wish to. Want to change social handles of some user on the mood indigo website? Just send a request to <code>https://ashish.moodi.org/users/update_user_profile</code> with the user id and your request will be processed.</p>
<p><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXfS27LEdpMqfAwXv0pa0NeQJrpnLiUAoa-v-2WbdhfoDIp8q8Ms2Ppm_p-Rrh8A1uMXYREMMPoiokh2j7rVUoCE8sQTllGXj96Otx-1K8TG9P3YC7CulLb2o6HcDOdmH8cU4V5G_Q?key=23tZ3b3cIxwP1XAlrtpk-Lud" alt="Parameters of the change update user profile" class="image--center mx-auto" /></p>
<p>The above image shows the parameters that you need to send to the request uri in order to make the changes, this is from the client side javascript. Again, I would like to put emphasis on the fact that there is no hacking or unauthorised access involved. The whole application and database was basically open to all.</p>
<p>The login process, to log in into the website, you are required to enter your email, password and an OTP is sent to your email which you need to enter, that is verified and then you are granted the permission to use the website. This is the common flow across all the websites, so what is wrong here?</p>
<p>Generally and very logically, the OTPs that are generated and sent on the email are kept on the server itself, you enter the OTP into the website, a request is sent to the server, and the server checks if the OTP that was sent to you on email and the OTP that you entered matches or not. And according to that you are granted access to the website. So here, there is very little that you can do to figure out the OTP. You can brute force it, but that will rate limit you and the IP will be blocked.</p>
<p>In the mood indigo website, the OTPs were being checked on the client side, yes, when you make a request to get an OTP, the OTP is generated and sent to your email, but also to your browser, which is then checked by the browser itself. So, if you haven’t guessed this by now, this beats the whole purpose of OTPs, you can just enter any email address and get the OTP for that email address. Basically, free login into any account. But this was working with accounts that were made with Google Auth, and not custom email-password accounts.</p>
<p>And this OTP verification vulnerability was also found last year in IITB websites by <a target="_blank" href="https://aryanbharti.com/">Aryan Bharti</a>. He also exposed such security failures in the Techfest and Mood Indigo websites, he got no reply from the authorities, and nor did I. I recommend you to check his <a target="_blank" href="https://medium.com/@workaryanbharti/i-hacked-iit-bombays-website-here-s-exactly-how-i-did-it-22b5d18e7336">blog post on this</a>.</p>
<p><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXeeNkwmrM7-e6L85TXei5rf__JO-8Xtq4fJUSaCbEpPdbrxX5MGoCLQDqDsDSah9v1BalOM80zlxYttby2zNynlv2CGUHLxNOkYBJY-z9hxwcT6tF3LUEBeitBGDUZ_8KB_9SUg?key=23tZ3b3cIxwP1XAlrtpk-Lud" alt="Response of a OTP request on my.moodi.org" class="image--center mx-auto" /></p>
<p>The above is the response for a OTP request for login on <code>my.moodi.org</code> website. The request was being sent on <code>https://ashish.moodi.org/email/sendOtp</code> and it will return the OTP as it is, you can just take it from the network tab, paste it in the input and done. We are logged in to the account that we want.</p>
<p>Moving forward, an argument can be made that this compromises only the google auth enabled accounts which were around 74.65% percent accounts present on the website. At least rest of the accounts are secured. That’s exactly where this gets even better. Because, you don’t even need to do all this OTP thing to login to any user account.</p>
<p>We talked about tokens and how they are used for authentication, well mood indigo has tokens and they use it at certain places, but this makes the matter even worse for them. In the general development world, tokens are generated and sent back to the user only if they provide the proper set of email, password and/or OTP. But in the mood indigo website, you only need the email to get the user token, yes, just the email, and you are granted access to the website.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735461769803/7d8a4399-97d0-4f55-9182-81b45ba11eb8.png" alt class="image--center mx-auto" /></p>
<p>Just send the email in a post request to <code>https://ashish.moodi.org/users/getUser</code> and you are logged in, how convenient!</p>
<p>But then you might say, how will we figure out the emails of the user, now, here comes the best part which I had reserved for the end. You don’t have to do all the things that I have mentioned above. Because you can get the whole database of users with all the user data, every single field. You just have to paste <code>https://ashish.moodi.org/ccp/oal</code> in the browser, any browser. And you will receive a massive ~70 MB JSON object which has <strong>data of more than 74798 users</strong>, this number was the last time I checked, it must have grown as mood indigo was happening.</p>
<p>What all fields of data are there you may ask? It consists everything that you gave to the website. Below is an example of one of the 74k+ unfortunate users.</p>
<p><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXdmTZhC78jC3hkewnKhQtX_7FXCbZN6IfDrGtfRbFbtBf9kS27ZIT2cdOaehAJ3626GFZCQX7lOmHZnklyC-3sGWxBB1hMS2UW01oeEkTWv_X__kV0kqCXOFSDYz-dirgkuMnXA?key=23tZ3b3cIxwP1XAlrtpk-Lud" alt /></p>
<p>Now this data is mine, because I also signed up into the website, but you will find at least 74k+ such objects like this. Which has</p>
<ul>
<li><p>Name</p>
</li>
<li><p>Email</p>
</li>
<li><p>Phone Number</p>
</li>
<li><p>Date of birth</p>
</li>
<li><p>Stream, Year of Study</p>
</li>
<li><p>Instagram</p>
</li>
<li><p>Facebook</p>
</li>
<li><p>Twitter</p>
</li>
<li><p>Linkedin</p>
</li>
</ul>
<p>of the users, and only the social media handles were optional, else everything mentioned here was mandatory to be filled as far as I remember. Let me give you some stats from the last data that was accessible to me.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735466760557/d750ccca-4562-4cd4-a2c8-8a48115ea838.png" alt class="image--center mx-auto" /></p>
<p>This was the amount of data that was present on the database.</p>
<p>And funnier thing is, how did I find it? All this 70MB worth of personal data of users was being sent <strong>on each page visit</strong> to render the leaderboard of points which had just 10 spots. Yes, just to show top 10 people who have the most <code>ccpPoints</code>, the whole database was being called and dumped to the user.</p>
<p>Ideally, only 10 records should have been called with only the <code>userName</code> and <code>ccpPoints</code> of the user. Sorted in a descending order based on the <code>ccpPoints</code> but I think that just stays the <strong>ideal case</strong>. The reality is far from ideal and here we are.</p>
<p>Now apart from these, basically the whole website was unsecured and everything was just a post request away but I did not dive into it as it was too much to explore. I just focused on the major problems and I emailed them to the authorities, let’s talk about it now.</p>
<p>I wrote an email with the title ‘Bug report on SEVERE security vulnerabilities in Mood Indigo Website’, and sent it to moodi@iitb.ac.in and two other email ids of the mood indigo team. This email was sent on 23 December 2024 at 15:56. And I also informed on of the top management of the mood indigo team that I have sent the email, he was the one who gave me the email ids. They clearly knew that I have reported these problems with their website.</p>
<p>I sent another follow up email on 23 December 2024 at 20:32 to ask about the update and asking for a formal acknowledgement of the issue in the form of email. But no success.</p>
<p>I sent another email on 24 December 2024 at 16:57, more than 24 hours after the first email, telling them that I am going to contact the IITB officials about it as the moo indigo team is not responding. Yet no response.</p>
<p>After that I wrote one final email to prooffice@iitb.ac.in, director@iitb.ac.in, dean.sa@iitb.ac.in with the title ‘URGENT: Data of 72k students is at stake’ on 25 Dec 2024, 14:22. Informing about the leak and had attached the screenshots of all the conversations. No response yet.</p>
<p>Please note that the servers were up and running while I wrote the emails and the server was last online on 2024-12-26 17:31:01 as per my uptime kuma tracker. And it has been down since then.</p>
<p>I have informed the developer of the website about this blog post and have asked him to make sure the server is down, on whatsapp, no response yet.</p>
<p>And I am not the only one who they haven’t responded to, <a target="_blank" href="https://aryanbharti.com/">Aryan Bharti</a> also got the same treatment when he <a target="_blank" href="https://medium.com/@workaryanbharti/i-hacked-iit-bombays-website-here-s-exactly-how-i-did-it-22b5d18e7336">reported similar issues with their websites last year</a>.</p>
<p>So this is what I discovered this week, and I just hope someone else haven’t found this but that’s nearly impossible, bots and bad actors across the web might have found the data and it might be already up for sale somewhere on the internet.</p>
<p>Please think twice before entering your data on any website on the internet! There is a lot of learning in this case for the users, and the developers. Never take security lightly, it’s not an option, it’s a necessity.</p>
]]></content:encoded></item><item><title><![CDATA[Database-less Password Resets using JWT]]></title><description><![CDATA[I was given a task to setup Authentication for our application and I had a few unsaid restrictions, it was not sensible to modify the database schema if not absolutely necessary because it is a complex database with many connected tables which are co...]]></description><link>https://blog.yassh.in/database-less-password-resets-using-jwt</link><guid isPermaLink="true">https://blog.yassh.in/database-less-password-resets-using-jwt</guid><category><![CDATA[JWT]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[email]]></category><category><![CDATA[passwords]]></category><dc:creator><![CDATA[Yash]]></dc:creator><pubDate>Tue, 26 Nov 2024 15:07:47 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1732631086881/8d4729d6-561f-448b-b816-9b8b773e560e.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I was given a task to setup Authentication for our application and I had a few unsaid restrictions, it was not sensible to modify the database schema if not absolutely necessary because it is a complex database with many connected tables which are coupled tightly.</p>
<p>I was required to create a mechanism for users to reset their passwords using their email ids. Generally while doing this, we generate a random string and store in the database as a token for password reset, which we will verify while performing the reset.</p>
<p>But here I was required to generate password reset links without modifying the schema of the database. Which made me come up with a rather unconventional solution, although non-standard, but this method is <strong>100% secure</strong> and <strong>reliable</strong> to use in production. Let’s see how it works.</p>
<p>When a user submits a password reset request using their username or email, we need to fetch the user’s details on the server side. If the user with the provided username or email exists, we proceed further or we return an error.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1732632042520/f75de23a-2fe7-4850-bb0e-91ff00170ded.png" alt class="image--center mx-auto" /></p>
<p>If the user exists, we get their current password, it does not matter if the password is hashed or not. We will use this current password string as one of the parameters to create a JWT or a Javascript Web Token.</p>
<p>So, if you are not aware of it, a JWT or a Javascript Web Token is a token which can be used for authentication and authorization. The contents of this token can be read by anyone who has access to it, but it can be verified / checked only by the creator of the token, because the creator holds to secret key for the token.</p>
<p>So basically, we need a secret-key to create it which we will use while verifying the token. Normally, we have a secret-key in our <code>.env</code> file which is used to create all the tokens which are spit out by our backend.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1732632672612/a05a17f1-5c44-4df0-9b05-6a8d87239e10.png" alt class="image--center mx-auto" /></p>
<p>You might be wondering why do we have to use the <code>CURRENTPASSWORD + SECRETKEY</code> combination to generate the token instead of just the secret key. And the real cleverness of this approach stays in this simple thing.</p>
<p>If we generate the token just using the secret key, we will be able to use it infinitely till it’s expiry date. Which is harmful for us as it will be a loophole to abuse the reset password system and poses a huge security threat. By using the combination of current password and secret key, we are making it a one time use token. Because <strong>once the password is updated in the database, we can no longer verify the token</strong>, because it was generated with the old password. Even if the user set’s the same password again, it won’t be verifiable until and unless we are not hashing the passwords, which is not recommended at all.</p>
<p>The jwt tokens also have an expiry time which we set at the time of generation, after which the token does not get verified. So we don’t have to implement that separately.</p>
<p>I am writing some pseudo code in javascript on it’s implementation</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> generateToken = <span class="hljs-function">(<span class="hljs-params">username</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> user = db.getUserByUsername(username);
    <span class="hljs-keyword">const</span> claims = {
        <span class="hljs-string">"username"</span>: user.username
    }
    <span class="hljs-keyword">const</span> secret = <span class="hljs-string">`<span class="hljs-subst">${user.password}</span><span class="hljs-subst">${process.env.SECRETKEY}</span>`</span>;
    <span class="hljs-keyword">const</span> token = jwt.(claims, secret);
    <span class="hljs-keyword">return</span> token.compact();
}

<span class="hljs-keyword">const</span> verifyToken = <span class="hljs-function">(<span class="hljs-params">token</span>) =&gt;</span> {
    <span class="hljs-keyword">let</span> verified = <span class="hljs-literal">true</span>;
    <span class="hljs-keyword">const</span> tokenBody = jwt.getBody(token);
    <span class="hljs-keyword">const</span> user = db.getUserByUsername(tokenBody.username);
    <span class="hljs-keyword">const</span> seceret = <span class="hljs-string">`<span class="hljs-subst">${user.password}</span><span class="hljs-subst">${process.env.SECRETKEY}</span>`</span>;
    <span class="hljs-keyword">try</span>{
        jwt.verify(token, secret);
    }<span class="hljs-keyword">catch</span>(e){
        verified = <span class="hljs-literal">false</span>;
    }
    <span class="hljs-keyword">return</span> verified;
}
</code></pre>
<p>Please note that the above code is pseudo code and the actual implementation may have different syntax.</p>
<p>I am personally using the <a target="_blank" href="https://www.npmjs.com/package/njwt">njwt library</a> in nextjs for this. Different languages can have different libraries, but the logic stays the same!</p>
<p>Thank you for reading.</p>
]]></content:encoded></item><item><title><![CDATA[Authentication using NexAuth in NextJS]]></title><description><![CDATA[Authentication in NextJS has been made very simple by the next-auth library, in this post we will go through on how to setup authentication in your NextJS 14 application. We will not be using NextJS 15 because it is not stable yet.
I will not go thro...]]></description><link>https://blog.yassh.in/authentication-using-nexauth-in-nextjs</link><guid isPermaLink="true">https://blog.yassh.in/authentication-using-nexauth-in-nextjs</guid><category><![CDATA[Next.js]]></category><category><![CDATA[authentication]]></category><category><![CDATA[nextauth.js]]></category><category><![CDATA[nextauth]]></category><category><![CDATA[Next]]></category><category><![CDATA[JavaScript]]></category><dc:creator><![CDATA[Yash]]></dc:creator><pubDate>Thu, 31 Oct 2024 17:38:36 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1730394602661/aa775027-84d0-4155-b390-e8f4b549ff87.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Authentication in NextJS has been made very simple by the <code>next-auth</code> library, in this post we will go through on how to setup authentication in your NextJS 14 application. We will not be using NextJS 15 because it is not stable yet.</p>
<p>I will not go through the installation steps of Next project, we will start by installing next-auth library</p>
<pre><code class="lang-bash">npm i next-auth
</code></pre>
<p>Once this is done, we have to create a <code>.env.local</code> file in the project root to store our variables</p>
<pre><code class="lang-plaintext">NEXTAUTH_SECRET=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
NEXTAUTH_URL="http://localhost:3000"

GITHUB_ID=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
GITHUB_SECRET=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

GOOGLE_CLIENT_ID=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
GOOGLE_CLIENT_SECRET=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
</code></pre>
<p>Here, the <code>NEXTAUTH_SECRET</code> can be anything, it is used for encryption, the <code>NEXTAUTH_URL</code> is used to redirect the user after the user is signed in. The <code>GITHUB_ID</code>, <code>GITHUB_SECRET</code>, <code>GOOGLE_CLIENT_ID</code> and <code>GOOGLE_CLIENT_SECRET</code> are the credentials that are to be obtained from those particular websites.</p>
<p><strong>Note:</strong> While setting the credentials in Github, Google and other such auth providers, we have to set the callback url to <code>http://localhost:3000/api/auth/callback/google</code>, here the <code>http://localhost:3000</code> is to be replaced with your domain and the <code>callback/google</code> is to be replaced with your provider name such as <code>github</code>, <code>twitter</code>, etc.</p>
<p>After this, we have to make a file with the path <code>/lib/authOptions.ts</code>, it will be used to export the auth options that we are using in the app</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { NextAuthOptions } <span class="hljs-keyword">from</span> <span class="hljs-string">"next-auth"</span>;
<span class="hljs-keyword">import</span> GithubProvider <span class="hljs-keyword">from</span> <span class="hljs-string">"next-auth/providers/github"</span>;
<span class="hljs-keyword">import</span> GoogleProvider <span class="hljs-keyword">from</span> <span class="hljs-string">"next-auth/providers/google"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> authOptions : NextAuthOptions = {
    providers: [
      GithubProvider({
        clientId: process.env.GITHUB_ID <span class="hljs-keyword">as</span> <span class="hljs-built_in">string</span>,
        clientSecret: process.env.GITHUB_SECRET <span class="hljs-keyword">as</span> <span class="hljs-built_in">string</span>,
      }),
      GoogleProvider({
        clientId: process.env.GOOGLE_CLIENT_ID <span class="hljs-keyword">as</span> <span class="hljs-built_in">string</span>,
        clientSecret: process.env.GOOGLE_CLIENT_SECRET <span class="hljs-keyword">as</span> <span class="hljs-built_in">string</span>,
      }),
    ],
  }
</code></pre>
<p>Here, we are importing the values from our <code>.env.local</code> file that we made earlier.</p>
<p>Moving forward, we need to make one more such file in the path <code>/src/app/api/auth/[…nextauth]/route.ts</code> which will be used for our client side authentication</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> NextAuth <span class="hljs-keyword">from</span> <span class="hljs-string">"next-auth"</span>;
<span class="hljs-keyword">import</span> { authOptions } <span class="hljs-keyword">from</span> <span class="hljs-string">"../../../../../lib/authOptions"</span>;
<span class="hljs-keyword">const</span> handler = NextAuth(authOptions);
<span class="hljs-keyword">export</span> { handler <span class="hljs-keyword">as</span> GET, handler <span class="hljs-keyword">as</span> POST };
</code></pre>
<p>In this file, we are importing the authOptions that we exported.</p>
<p>Moving forward, we need to make a SessionWrapper component which will be used to as a provider in our frontend, due to this component we can use the hooks provided by NextAuth anywhere in our application.</p>
<p>This is the component that I created in the path, <code>/components/SessionWrapper.tsx</code>, the path does not matter, but it should be a tsx or jsx component.</p>
<pre><code class="lang-typescript"><span class="hljs-string">"use client"</span>;

<span class="hljs-keyword">import</span> { SessionProvider } <span class="hljs-keyword">from</span> <span class="hljs-string">'next-auth/react'</span>;
<span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">SessionWrapper</span>(<span class="hljs-params">{children} : {children: React.ReactNode}</span>) </span>{
  <span class="hljs-keyword">return</span> (
    &lt;SessionProvider&gt;
        {children}
    &lt;/SessionProvider&gt;
  )
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> SessionWrapper
</code></pre>
<p>Now we have to use this wrapper in our layout.tsx file in <code>/src/app/layout.tsx</code></p>
<pre><code class="lang-typescript">...
 <span class="hljs-keyword">return</span> (
    &lt;SessionWrapper&gt;
      &lt;html lang=<span class="hljs-string">"en"</span>&gt;
        &lt;body className={inter.className}&gt;{children}&lt;/body&gt;
      &lt;/html&gt;
    &lt;/SessionWrapper&gt;
  );
...
</code></pre>
<p>Now, we are good to use the authentication anywhere in our app, let us see how it is done.</p>
<p>We are provided with a <code>useSession()</code> hook by next-auth which can be used to get a session variable</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> {data: session} = useSession();
</code></pre>
<p>This variable returns false if the user is not signed in, and it contains the user data if the user is logged in.</p>
<p>So we can use this information to build an interface</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">if</span> (session) {
    <span class="hljs-keyword">return</span> (
      &lt;&gt;
        &lt;p&gt;You are logged <span class="hljs-keyword">in</span> <span class="hljs-keyword">as</span>&lt;/p&gt;
        &lt;p&gt;{session.user?.name}&lt;/p&gt;
        &lt;p&gt;{session.user?.email}&lt;/p&gt;
      &lt;/&gt;
    );
  }
  <span class="hljs-keyword">return</span> (
    &lt;&gt;
      &lt;p&gt; You are not logged <span class="hljs-keyword">in</span> please, login&lt;/p&gt;
    &lt;/&gt;
  );
</code></pre>
<p>But, you may ask how do I sign-in and sign-out? NextAuth provides very simple functions for that as well, we just have to import them and use in our app</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { signIn } <span class="hljs-keyword">from</span> <span class="hljs-string">'next-auth/react'</span>;
...
<span class="hljs-keyword">return</span>(
&lt;&gt;
    &lt;p&gt;You are not logged <span class="hljs-keyword">in</span> please, login&lt;/p?&gt;
    &lt;br /&gt;
    &lt;p onClick={<span class="hljs-function">() =&gt;</span> signIn(<span class="hljs-string">"github"</span>)}&gt;Github&lt;/p&gt;
    &lt;br /&gt;
    &lt;p onClick={<span class="hljs-function">() =&gt;</span> signIn(<span class="hljs-string">"google"</span>)}&gt;Google&lt;/p&gt;
&lt;/&gt;
);
</code></pre>
<p>The <code>signOut</code> method is also provided which can be used directly.</p>
<p>Now, we are done with the basics of frontend auth, now for the backend side authentication.</p>
<p>This is an example of an api route which returns the user information.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { getServerSession } <span class="hljs-keyword">from</span> <span class="hljs-string">"next-auth"</span>;
<span class="hljs-keyword">import</span> { NextRequest, NextResponse } <span class="hljs-keyword">from</span> <span class="hljs-string">"next/server"</span>;
<span class="hljs-keyword">import</span> { authOptions } <span class="hljs-keyword">from</span> <span class="hljs-string">"../../../../lib/authOptions"</span>;

<span class="hljs-keyword">const</span> GET = <span class="hljs-keyword">async</span> (request: NextRequest) =&gt; {
    <span class="hljs-keyword">const</span> session = <span class="hljs-keyword">await</span> getServerSession(authOptions);

    <span class="hljs-keyword">if</span>(!session){
        <span class="hljs-keyword">return</span> NextResponse.json({
            <span class="hljs-string">"failed"</span>: <span class="hljs-string">"No session found"</span>
        })
    }

    <span class="hljs-keyword">return</span> NextResponse.json(session);
}

<span class="hljs-keyword">export</span> {GET};
</code></pre>
<p>The response is something like this:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"user"</span>: {
    <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Yash"</span>,
    <span class="hljs-attr">"email"</span>: <span class="hljs-string">"hi@yassh.in"</span>,
    <span class="hljs-attr">"image"</span>: <span class="hljs-string">"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.url.com"</span>
  }
}
</code></pre>
<p>This is enough to get you started with authentication in NextJS 14 using NextAuth library.</p>
]]></content:encoded></item><item><title><![CDATA[Things to remember while deploying Laravel Apps]]></title><description><![CDATA[First thing, which is mentioned even in the official Laravel docs is, do not move the files from the public directory and move them to the root. Do not do it at all, rather add this code to the .htaccess file
<IfModule mod_rewrite.c>
RewriteEngine on...]]></description><link>https://blog.yassh.in/things-to-remember-while-deploying-laravel-apps</link><guid isPermaLink="true">https://blog.yassh.in/things-to-remember-while-deploying-laravel-apps</guid><dc:creator><![CDATA[Yash]]></dc:creator><pubDate>Wed, 24 Jul 2024 17:38:19 GMT</pubDate><content:encoded><![CDATA[<p>First thing, which is mentioned even in the official Laravel docs is, do not move the files from the <strong>public</strong> directory and move them to the root. Do not do it at all, rather add this code to the <code>.htaccess</code> file</p>
<pre><code class="lang-plaintext">&lt;IfModule mod_rewrite.c&gt;
RewriteEngine on
RewriteCond %{REQUEST_URI} !^public
RewriteRule ^(.*)$ public/$1 [L]
&lt;/IfModule&gt;
</code></pre>
]]></content:encoded></item><item><title><![CDATA[Download Torrents using VPS]]></title><description><![CDATA[I am a big fan of Torrents, I have been using it from a long time. But if there is something that I am not a fan of, it is the amount of time your machine has to be powered on while the files are getting downloaded via Torrent. The long wait times ar...]]></description><link>https://blog.yassh.in/download-torrents-using-vps</link><guid isPermaLink="true">https://blog.yassh.in/download-torrents-using-vps</guid><category><![CDATA[deluge]]></category><category><![CDATA[Torrent]]></category><category><![CDATA[vps]]></category><category><![CDATA[Ubuntu]]></category><category><![CDATA[Cloud]]></category><dc:creator><![CDATA[Yash]]></dc:creator><pubDate>Thu, 20 Jun 2024 04:16:16 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1718857841636/b59c6ee6-b24d-499a-a36a-6fbf727b154b.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I am a big fan of Torrents, I have been using it from a long time. But if there is something that I am not a fan of, it is the amount of time your machine has to be powered on while the files are getting downloaded via Torrent. The long wait times are usually due to lack of seeders. And sometimes there are no seeders for hours, in such cases, you and your machine both waste their time and energy waiting.</p>
<p>I always wondered how cool it would be if I can download the torrents on a remote machine first and then transfer it to my device in high speeds. Basically, all the waiting, searching and downloading happens on a remote machine / server and then once the files are downloaded, those are downloaded in our main machine. This saves a lot of time on your main machine and also it gives less headache.</p>
<p>No more keeping the computer on all night for GTA V to download. Let's look at how we will approach this.</p>
<h3 id="heading-setting-up-the-vps">Setting up the VPS</h3>
<p>I am using a VPS from Hetzner as it is the most affordable option that is available, it is easily disposable and it is transparent. The service provider is not really important, we just need a machine which will be publicly accessible and can run Ubuntu.</p>
<p>With our Ubuntu instance in hand, we will first make sure our dependencies and our OS is up to date.</p>
<pre><code class="lang-bash">sudo apt update
sudo apt upgrade
</code></pre>
<p>Once we are updated, we will install our bittorent client Deluge, we will use the web-ui variant as we are on a remote server.</p>
<pre><code class="lang-bash">sudo apt-get install deluged deluge-web deluge-console
</code></pre>
<p>These commands will install and run the deluge-web and our bittorent client is now accessible at <code>ip:8112</code>. In my case it is http://135.181.200.11:8112</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1718854663754/f370a02b-d647-402c-9cb7-e42d7bbf5d85.png" alt class="image--center mx-auto" /></p>
<p>The default password is 'deluge'.</p>
<p>We will be prompted with a screen which will ask us to select a daemon to connect with, we shall select the one that we see on the screen.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1718854766718/704b39eb-1c19-4917-a30c-5b7d9224e475.png" alt class="image--center mx-auto" /></p>
<p>Once done, we are now ready to download our favourite torrents on the server. Fore this tutorial we will be downloading Ubuntu from the official ubuntu website. I copied the .torrent file link from the Ubuntu website.</p>
<p>Now we shall click on the Add button to start a new download</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1718855028221/55fc8bad-d289-41b6-9b7b-4119e22787f2.png" alt class="image--center mx-auto" /></p>
<p>From the prompt that is opened, we will select URL as we did not download the .torrent file or else we can select the File option.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1718855072781/11400c49-7fc2-4e2e-9fa5-5fa87f407c32.png" alt class="image--center mx-auto" /></p>
<p>Once the URL is submitted, our download will start. Not only it is hassle free but the download speeds are also insane on the server.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1718855179051/ee9d4c91-6284-4ede-9c8f-ff95f5a679df.png" alt class="image--center mx-auto" /></p>
<p>But we are not aiming for download speeds, as we will be bottlenecked to the maximum download speed that our VPS provides to us, we are focused on remote downloading which does not require our computer to be active for days and hours.</p>
<p>Once our download is finished, we can pause it, so it does not keep seeding. And then the second part our task arrives.</p>
<h3 id="heading-downloading-the-files-on-the-computer">Downloading the files on the computer</h3>
<p>If we click on preferences, we can see that our files are saved in <code>/var/lib/deluged/Downloads</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1718855428630/671e8f1d-2f33-405b-890d-822f520a847c.png" alt class="image--center mx-auto" /></p>
<p>If we <code>ls</code> into that directory we can see our downloaded file</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1718855540811/f6ee55a8-b1ab-433c-9640-c45e2ab175c0.png" alt class="image--center mx-auto" /></p>
<p>Now, we just have to download this file on our local computer. There are several methods to achieve this. We will make a http server and download our file from the browser. To do it we have to install apache</p>
<pre><code class="lang-bash">sudo apt install apache2
</code></pre>
<p>Once apache is installed, if we visit our IP address, we shall see the default apache page</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1718855697405/d08f357d-ace8-4c7b-9e47-43e9089a80e5.png" alt class="image--center mx-auto" /></p>
<p>The files for apache server are stored under <code>/var/www/html/</code>. We will have to move our file there, to do it we will do</p>
<pre><code class="lang-bash">mv /var/lib/deluged/Downloads/&lt;filename&gt; /var/www/html/&lt;filename&gt;
</code></pre>
<p>In my case, it is <code>mv /var/lib/deluged/Downloads/ubuntu-24.04-desktop-amd64.iso /var/www/html/ubuntu-24.04-desktop-amd64.iso</code>. Now our file is also moved we now can download our file from. <code>ip/filename</code>, in my case it is <a target="_blank" href="http://135.181.200.11/ubuntu-24.04-desktop-amd64.iso"><code>http://135.181.200.11/ubuntu-24.04-desktop-amd64.iso</code></a></p>
<p>We will be greeted with a '403 Forbidden' error as soon as we open this page</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1718856771078/76b5ccd8-ff00-4ce2-ba78-1d75ec65e2f6.png" alt class="image--center mx-auto" /></p>
<p>This is because the Apache does not have enough permissions of this file, we can solve this with one simple command</p>
<pre><code class="lang-bash">chmod -R 777 /var/www/html
</code></pre>
<p>Once again hit the URL and our download shall start instantly!</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1718856909912/312ac09f-f8f1-4014-afa3-f2f3d5ac21f7.png" alt class="image--center mx-auto" /></p>
<p>That's how you torrent a file using VPS!</p>
]]></content:encoded></item></channel></rss>