<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Nimesh Thakur</title>
    <description>The latest articles on DEV Community by Nimesh Thakur (@toklas495).</description>
    <link>https://dev.to/toklas495</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3625136%2F1d2f18ef-ce8d-430b-b578-26b7537d52c8.png</url>
      <title>DEV Community: Nimesh Thakur</title>
      <link>https://dev.to/toklas495</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/toklas495"/>
    <language>en</language>
    <item>
      <title>I Had a Story. I Turned It Into a Song. Now I'm Building a Community.</title>
      <dc:creator>Nimesh Thakur</dc:creator>
      <pubDate>Tue, 10 Mar 2026 12:03:36 +0000</pubDate>
      <link>https://dev.to/toklas495/i-had-a-story-i-turned-it-into-a-song-now-im-building-a-community-41bf</link>
      <guid>https://dev.to/toklas495/i-had-a-story-i-turned-it-into-a-song-now-im-building-a-community-41bf</guid>
      <description>&lt;p&gt;I read a lot.&lt;/p&gt;

&lt;p&gt;Books, blogs, development docs, ancient texts — Vedas, philosophy, things most people skip.&lt;/p&gt;

&lt;p&gt;After all that reading, one thing became clear:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;We are always free. We are the sky. Clouds pass through. They don't stay.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That thought became a blog.&lt;/p&gt;

&lt;p&gt;Then one day I asked myself — &lt;em&gt;why does it have to stay as words?&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Idea
&lt;/h2&gt;

&lt;p&gt;I'm not a singer.&lt;/p&gt;

&lt;p&gt;No music training. No studio. No experience.&lt;/p&gt;

&lt;p&gt;But I had something real to say.&lt;/p&gt;

&lt;p&gt;And today, that's enough.&lt;/p&gt;




&lt;h2&gt;
  
  
  How I Made My First Song
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Step 1 — Blog became lyrics&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I gave my blog to AI. ChatGPT, Gemini, Claude.&lt;/p&gt;

&lt;p&gt;Asked them to turn it into song lyrics.&lt;/p&gt;

&lt;p&gt;Then I read every version slowly. One test: &lt;em&gt;does this still feel like mine?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If yes — move forward.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2 — Lyrics became a style&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I went back to AI. Described the emotion I wanted.&lt;/p&gt;

&lt;p&gt;It helped me find the right words: beats, mood, instruments, energy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3 — Style became a song&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I put the lyrics and style into &lt;a href="https://suno.com" rel="noopener noreferrer"&gt;Suno AI&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It generated a full song. Vocals. Instruments. Everything.&lt;/p&gt;

&lt;p&gt;In seconds.&lt;/p&gt;

&lt;p&gt;I generated many songs. Listened to all of them. Most were good.&lt;/p&gt;

&lt;p&gt;Then one came on — and I got goosebumps.&lt;/p&gt;

&lt;p&gt;That was the one.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Note on ADO
&lt;/h2&gt;

&lt;p&gt;My favourite singer is &lt;strong&gt;ADO&lt;/strong&gt; — a Japanese artist.&lt;/p&gt;

&lt;p&gt;If you haven't heard her, go listen right now.&lt;/p&gt;

&lt;p&gt;She doesn't just sing. She &lt;em&gt;bleeds&lt;/em&gt; into every note.&lt;/p&gt;

&lt;p&gt;That's what I was chasing. Not technically. Emotionally.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Album
&lt;/h2&gt;

&lt;p&gt;I made 4 songs. Put them on YouTube.&lt;/p&gt;

&lt;p&gt;Not for views. Not for growth. Not for anyone else.&lt;/p&gt;

&lt;p&gt;Just to know — &lt;em&gt;I made this. This came from inside me.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;My two favourites:&lt;/p&gt;

&lt;p&gt;🎵 &lt;a href="https://youtu.be/7k4O2nMlXBo?si=CUscE70Tg11qxkK4" rel="noopener noreferrer"&gt;First Song&lt;/a&gt;&lt;br&gt;
🎵 &lt;a href="https://youtu.be/TUHE3SNeKZg?si=g6xctBw4hubUKv5S" rel="noopener noreferrer"&gt;Fourth Song&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Then a Bigger Question Came
&lt;/h2&gt;

&lt;p&gt;Everyone is chasing goals.&lt;/p&gt;

&lt;p&gt;Timelines. Career ladders. The next milestone.&lt;/p&gt;

&lt;p&gt;Earth is starting to feel like a very serious race track.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What if we made it more interesting?&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  SONGUILD
&lt;/h2&gt;

&lt;p&gt;One month. One song. One community.&lt;/p&gt;

&lt;p&gt;That's it.&lt;/p&gt;

&lt;p&gt;You have 30 days. Make something. Anything.&lt;/p&gt;

&lt;p&gt;A song born from your experience — a project you built, a bug that broke you, a book that changed you, a feeling you couldn't explain.&lt;/p&gt;

&lt;p&gt;At the end of the month, we all gather and review together.&lt;/p&gt;

&lt;p&gt;Not silently. Not with a form. &lt;strong&gt;Together.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What gets rated:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🎵 &lt;strong&gt;Overall Song&lt;/strong&gt; — does it land?&lt;/li&gt;
&lt;li&gt;✍️ &lt;strong&gt;Lyrics&lt;/strong&gt; — is there a real thought behind it?&lt;/li&gt;
&lt;li&gt;🎧 &lt;strong&gt;BGM&lt;/strong&gt; — does the sound match the feeling?&lt;/li&gt;
&lt;li&gt;🎬 &lt;strong&gt;Visuals&lt;/strong&gt; — the YouTube presentation&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  End of month awards:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Best Song&lt;/li&gt;
&lt;li&gt;Best Lyrics&lt;/li&gt;
&lt;li&gt;Best BGM&lt;/li&gt;
&lt;li&gt;Best Visuals&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Why This Is Different
&lt;/h2&gt;

&lt;p&gt;Most challenges are consistency games.&lt;/p&gt;

&lt;p&gt;Post every day. Don't break the streak. Show up even when empty.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SONGUILD is a creativity game.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One month. No daily pressure. No burnout.&lt;/p&gt;

&lt;p&gt;Just: &lt;em&gt;here is a blank canvas — make something real.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  You Don't Need to Be a Singer
&lt;/h2&gt;

&lt;p&gt;I wasn't.&lt;/p&gt;

&lt;p&gt;You just need something worth saying.&lt;/p&gt;

&lt;p&gt;A late night debugging session that taught you patience.&lt;br&gt;
A framework you loved then outgrew.&lt;br&gt;
A moment of clarity at 2am.&lt;br&gt;
Something you read that quietly changed everything.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;That's your song.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Come Join
&lt;/h2&gt;

&lt;p&gt;Right now SONGUILD is small.&lt;/p&gt;

&lt;p&gt;Maybe it's just me when you read this.&lt;/p&gt;

&lt;p&gt;Maybe it's something much bigger.&lt;/p&gt;

&lt;p&gt;Either way — the door is open.&lt;/p&gt;

&lt;p&gt;We're starting with songs. But when the community grows, we grow with it. New formats. New ideas. New ways to create together.&lt;/p&gt;

&lt;p&gt;The song is just the beginning.&lt;/p&gt;




&lt;p&gt;🎮 &lt;strong&gt;Join SONGUILD&lt;/strong&gt; &lt;em&gt;(Discord link in comments)&lt;/em&gt;&lt;br&gt;
🎵 &lt;strong&gt;The album that started it all&lt;/strong&gt; — links above&lt;br&gt;
📖 &lt;strong&gt;The blog that became the first song&lt;/strong&gt; — &lt;a href="https://dev.to/toklas495/the-90-i-missed-while-chasing-the-10-1kdc"&gt;The 90% I Missed&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I'm 21. I read everything I can. I write what I learn. And now — I make songs.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;We are always free. Come create something.&lt;/em&gt;&lt;/p&gt;




</description>
      <category>music</category>
      <category>ai</category>
      <category>community</category>
      <category>discuss</category>
    </item>
    <item>
      <title>The 90% I Missed While Chasing the 10%</title>
      <dc:creator>Nimesh Thakur</dc:creator>
      <pubDate>Sun, 15 Feb 2026 04:16:06 +0000</pubDate>
      <link>https://dev.to/toklas495/the-90-i-missed-while-chasing-the-10-1kdc</link>
      <guid>https://dev.to/toklas495/the-90-i-missed-while-chasing-the-10-1kdc</guid>
      <description>&lt;p&gt;I'm 21. I don't have answers. I don't have a success story to sell you. What I have is a growing pile of questions and a strange sense that I spent years preparing for life instead of actually living it.&lt;/p&gt;

&lt;p&gt;This isn't about productivity hacks or finding your passion. This is about noticing what was always there while I was looking somewhere else.&lt;/p&gt;

&lt;h2&gt;
  
  
  Borrowed Beliefs
&lt;/h2&gt;

&lt;p&gt;As a child, I lived on autopilot with beliefs I never chose. "Study hard today and your future will be good." My parents said it. Teachers repeated it. Society nodded in agreement. So I believed it too, because everyone around me did. When your entire environment validates something, you don't question it. You just accept it as truth.&lt;/p&gt;

&lt;p&gt;I wasn't stupid for believing it. I was a kid. Kids absorb their surroundings like water soaking into cloth.&lt;/p&gt;

&lt;p&gt;Somewhere in 11th and 12th grade, something shifted. I didn't consciously decide to step out of the race, but I did. I stopped caring about rankings and comparisons. I became more curious, more confused, and honestly, more chaotic. I had flaws. Ego. Moments of what I'd call an immature or even 'evil' personality. But I was improving, slowly, without realizing it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Reading That Broke Things Open
&lt;/h2&gt;

&lt;p&gt;Around 17, I started reading. Not because I loved it—I actually hated it at first. Books felt slow and boring compared to movies and YouTube. I started with comics, light stuff like Chacha Chaudhary, just to ease into it.&lt;/p&gt;

&lt;p&gt;But reading did something unexpected. It made me curious about things I'd never questioned before. Who am I? What is society? Why do humans follow this endless cycle: study, job, marriage, children, repeat, death? Why does everyone talk about God but no one asks who created God? Why do animals seem freer than humans, even though we call ourselves intelligent?&lt;/p&gt;

&lt;p&gt;I read things that most people don't stumble into at that age. Tantra Sutra. Books on awareness and consciousness. I wasn't seeking enlightenment. I was just trying to understand why life felt so unnecessarily complicated in my head.&lt;/p&gt;

&lt;p&gt;I also watched things that hit differently. One Piece. Pixar's Soul. These weren't just entertainment—they became mirrors. Luffy doesn't obsess over becoming Pirate King in some distant future. He lives fully while moving toward it. Soul showed me how people can spend their entire lives preparing to live, only to realize they forgot to actually live.&lt;/p&gt;

&lt;p&gt;These didn't make me spiritual or wise. They made me question everything I thought was normal.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Trap of Goals
&lt;/h2&gt;

&lt;p&gt;At 19 and 20, I became obsessed with finding my purpose. I tried everything. Car designing. Army. Navy. Airforce. Cybersecurity. Development. Bug hunting. I kept waiting for something to "click," for some voice inside to say, "Yes, this is it."&lt;/p&gt;

&lt;p&gt;Nothing clicked.&lt;/p&gt;

&lt;p&gt;I wanted to earn millions. Not for cars or luxury. I wanted to fix things—villages, water systems, the environment. I believed that once I had enough money, I could finally do something meaningful.&lt;/p&gt;

&lt;p&gt;I realize now how flawed that was. Action matters more than imagined future money. Waiting for the perfect condition is just another way of not starting.&lt;/p&gt;

&lt;p&gt;Goals became my mental prison. I started living entirely in two places: the past, with regret over what I didn't do, and the future, anxious about what I hadn't achieved yet. The present? I was barely there.&lt;/p&gt;

&lt;p&gt;I thought goals were 90% of life. Work toward something. Achieve it. Move to the next. Repeat until death. That was the formula everyone seemed to follow.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 90% I Wasn't Seeing
&lt;/h2&gt;

&lt;p&gt;Then I realized something that felt obvious once I saw it, but I had missed it for years.&lt;/p&gt;

&lt;p&gt;Goals are maybe 10% of life. Maybe.&lt;/p&gt;

&lt;p&gt;The other 90%? It's everything else.&lt;/p&gt;

&lt;p&gt;It's talking to people and actually listening instead of waiting for your turn to speak. It's eating food and noticing the taste instead of scrolling while you chew. It's walking and feeling the ground under your feet. It's breathing and knowing you're breathing. It's hearing birds in the morning. It's sitting with your family without thinking about tomorrow. It's being present with strangers.&lt;/p&gt;

&lt;p&gt;This 90% doesn't show up on your resume. It doesn't trend on social media. It doesn't make you rich or famous. But it's where life actually happens.&lt;/p&gt;

&lt;p&gt;And I had been missing it. Completely.&lt;/p&gt;

&lt;p&gt;I was so focused on becoming someone in the future that I forgot I already am someone right now. I was treating the present as a waiting room for a better tomorrow that never quite arrived.&lt;/p&gt;

&lt;h2&gt;
  
  
  Witnessing vs. Existing
&lt;/h2&gt;

&lt;p&gt;There's a difference between existing and witnessing.&lt;/p&gt;

&lt;p&gt;Existing is going through the motions. Eating while thinking about work. Walking while replaying a conversation. Breathing without noticing. Reacting to everything out of habit.&lt;/p&gt;

&lt;p&gt;Witnessing is different. When you eat, you actually taste. When you walk, you feel your feet on the earth. When you breathe, you notice the air moving in and out. You act, but you're aware. You respond instead of reacting.&lt;/p&gt;

&lt;p&gt;This isn't some mystical state. It's just being here instead of being lost in your head.&lt;/p&gt;

&lt;p&gt;One Piece taught me this in a way books couldn't. Luffy doesn't postpone joy until he finds the One Piece. He's fully alive in every moment while moving toward his goal. He's present with his crew. He laughs, fights, eats, and lives completely. The journey isn't a burden to endure until he reaches the destination. The journey is the life.&lt;/p&gt;

&lt;p&gt;Soul showed me the opposite—what happens when you're so obsessed with finding your purpose that you forget to live while searching for it. Joe spent his whole life waiting for the one moment that would make everything make sense, only to realize life was happening the whole time, and he wasn't there for it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'm Not Saying
&lt;/h2&gt;

&lt;p&gt;I'm not saying abandon goals. I'm not saying responsibility doesn't matter. I'm not saying sit under a tree and meditate all day.&lt;/p&gt;

&lt;p&gt;I'm saying something simpler.&lt;/p&gt;

&lt;p&gt;Move toward your goals, but don't become psychologically enslaved by them. Work, but don't let work consume the 90% that makes life worth living. Plan for the future, but don't sacrifice the present to an imagined tomorrow.&lt;/p&gt;

&lt;p&gt;Life isn't a problem to solve. It's not a race to win. It's not a puzzle where you finally figure everything out and then relax.&lt;/p&gt;

&lt;p&gt;Life is this. Right now. The breath you just took. The light coming through your window. The sound of the world around you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Still Learning
&lt;/h2&gt;

&lt;p&gt;I'm still figuring this out. I still get lost in my head. I still worry about the future. I still set goals and chase them. But now I'm trying to notice when I'm here and when I'm not.&lt;/p&gt;

&lt;p&gt;I'm learning to witness instead of just exist. To listen instead of just hear. To see instead of just look.&lt;/p&gt;

&lt;p&gt;I don't know if this is wisdom or just confusion that sounds better organized. I'm 21. I have more questions than answers. I have more failures than successes. I have more doubts than certainty.&lt;/p&gt;

&lt;p&gt;But I'm starting to think that's okay.&lt;/p&gt;

&lt;p&gt;Maybe life isn't about having it all figured out. Maybe it's about being present while you figure it out. Maybe the goal isn't to reach some final destination where everything makes sense. Maybe it's to live fully while moving forward, even when nothing makes sense.&lt;/p&gt;

&lt;p&gt;I'm still reading. Still questioning. Still learning. Still missing the present sometimes while thinking about tomorrow.&lt;/p&gt;

&lt;p&gt;But I'm trying.&lt;/p&gt;

&lt;p&gt;And maybe that's enough for now.&lt;/p&gt;

</description>
      <category>motivation</category>
      <category>devjournal</category>
      <category>discuss</category>
      <category>learning</category>
    </item>
    <item>
      <title>404ping: From "It Works" to "It's Actually Really Good" 🚀</title>
      <dc:creator>Nimesh Thakur</dc:creator>
      <pubDate>Sun, 08 Feb 2026 03:45:24 +0000</pubDate>
      <link>https://dev.to/toklas495/404ping-from-it-works-to-its-actually-really-good-18ie</link>
      <guid>https://dev.to/toklas495/404ping-from-it-works-to-its-actually-really-good-18ie</guid>
      <description>&lt;p&gt;&lt;strong&gt;How I spent 3 months turning a simple CLI into something I'm genuinely proud of&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Where We Left Off
&lt;/h2&gt;

&lt;p&gt;Back in November, I wrote about &lt;a href="https://dev.to/toklas495/404ping-v2-the-api-testing-cli-that-went-from-side-project-to-beast-mode-3a6b"&gt;404ping v2&lt;/a&gt; — my lightweight API testing CLI that was basically "curl with memory."&lt;/p&gt;

&lt;p&gt;It could:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Send HTTP requests (obviously)&lt;/li&gt;
&lt;li&gt;Store variables globally or per-collection&lt;/li&gt;
&lt;li&gt;Save requests to collections&lt;/li&gt;
&lt;li&gt;Run saved requests with overrides&lt;/li&gt;
&lt;li&gt;Show different output modes (headers, connection info, TLS details)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;People actually used it. Bug hunters messaged me. Developers starred it on GitHub. I was happy.&lt;/p&gt;

&lt;p&gt;But then I kept using it. And every time I reached for 404ping in my actual workflow, I'd hit a wall and think: &lt;em&gt;"Why can't it just...?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;So I spent the next three months answering that question.&lt;/p&gt;




&lt;h2&gt;
  
  
  The "Why Can't It Just..." Moments
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Moment 1: "Why can't it just SAVE the damn request while I'm testing it?"
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The old way:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Test the request first&lt;/span&gt;
404ping request &lt;span class="o"&gt;{{&lt;/span&gt;host&lt;span class="o"&gt;}}&lt;/span&gt;/api/login &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"email":"test@test.com"}'&lt;/span&gt;

&lt;span class="c"&gt;# Looks good? Now save it (copy-paste hell)&lt;/span&gt;
404ping collection save myapp login &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="o"&gt;{{&lt;/span&gt;host&lt;span class="o"&gt;}}&lt;/span&gt;/api/login &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"email":"test@test.com"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I was literally typing the same request twice. That's stupid.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I built: Quick Save&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Test AND save in one command&lt;/span&gt;
404ping request &lt;span class="o"&gt;{{&lt;/span&gt;host&lt;span class="o"&gt;}}&lt;/span&gt;/api/login &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"email":"test@test.com"}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--save&lt;/span&gt; myapp.login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One flag. Done. The request you just tested is now saved. No copy-paste. No context switching.&lt;/p&gt;

&lt;p&gt;This single feature changed how I use 404ping. Now I just add &lt;code&gt;--save&lt;/code&gt; to everything and build my collection as I explore APIs.&lt;/p&gt;




&lt;h3&gt;
  
  
  Moment 2: "Why can't it just validate the response automatically?"
&lt;/h3&gt;

&lt;p&gt;I was constantly doing this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;404ping run myapp:login
&lt;span class="c"&gt;# Check status code manually&lt;/span&gt;
&lt;span class="c"&gt;# Check if token exists manually&lt;/span&gt;
&lt;span class="c"&gt;# Grep for specific values manually&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What I built: Inline Assertions&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;404ping request https://api.example.com/users/42 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--assert&lt;/span&gt; &lt;span class="s2"&gt;"status=200"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--assert&lt;/span&gt; &lt;span class="s2"&gt;"json.userId=42"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--assert&lt;/span&gt; &lt;span class="s2"&gt;"json.role=admin"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now 404ping tells me if something's wrong. Perfect for smoke tests or CI/CD:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;404ping run myapp:login &lt;span class="nt"&gt;--assert&lt;/span&gt; &lt;span class="s2"&gt;"status=200"&lt;/span&gt; &lt;span class="nt"&gt;--assert&lt;/span&gt; &lt;span class="s2"&gt;"json.token!=null"&lt;/span&gt;
&lt;span class="c"&gt;# Exit code 0 if passes, 1 if fails&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Moment 3: "Why can't it just use the token from the previous request?"
&lt;/h3&gt;

&lt;p&gt;This was the big one. The workflow that made me want to rebuild everything:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before (the painful way):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Login&lt;/span&gt;
404ping run myapp:login
&lt;span class="c"&gt;# Response: {"token": "eyJhbGc..."}&lt;/span&gt;

&lt;span class="c"&gt;# 2. Manually copy token&lt;/span&gt;
404ping &lt;span class="nb"&gt;set &lt;/span&gt;token:eyJhbGc...

&lt;span class="c"&gt;# 3. Use token in next request&lt;/span&gt;
404ping run myapp:get-profile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every. Single. Time. Manual token copying. This is 2025, why am I doing this?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I built: Request Chaining &amp;amp; Variable Extraction&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;404ping sequence auth:login &lt;span class="nb"&gt;users&lt;/span&gt;:me &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--extract&lt;/span&gt; &lt;span class="nv"&gt;token&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;json.token &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--bearer&lt;/span&gt; &lt;span class="o"&gt;{{&lt;/span&gt;runtime.token&lt;span class="o"&gt;}}&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--assert&lt;/span&gt; &lt;span class="s2"&gt;"status=200"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What happens:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Runs &lt;code&gt;auth:login&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Extracts &lt;code&gt;json.token&lt;/code&gt; from response → stores as &lt;code&gt;{{runtime.token}}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Runs &lt;code&gt;users:me&lt;/code&gt; with &lt;code&gt;Authorization: Bearer {{runtime.token}}&lt;/code&gt; header&lt;/li&gt;
&lt;li&gt;Asserts both succeeded&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No manual copying. No intermediate steps. Just declare the flow and it works.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real-world example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;404ping sequence &lt;span class="se"&gt;\&lt;/span&gt;
  auth:login &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nb"&gt;users&lt;/span&gt;:create &lt;span class="se"&gt;\&lt;/span&gt;
  posts:create &lt;span class="se"&gt;\&lt;/span&gt;
  posts:list &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--extract&lt;/span&gt; &lt;span class="nv"&gt;token&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;json.auth.token &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--extract&lt;/span&gt; &lt;span class="nv"&gt;userId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;json.user.id &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--bearer&lt;/span&gt; &lt;span class="o"&gt;{{&lt;/span&gt;runtime.token&lt;span class="o"&gt;}}&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--assert&lt;/span&gt; &lt;span class="s2"&gt;"status=200"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is what made 404ping actually useful for real workflows.&lt;/p&gt;




&lt;h3&gt;
  
  
  Moment 4: "Why can't it just parse the JSON for me?"
&lt;/h3&gt;

&lt;p&gt;I was piping everything to &lt;code&gt;jq&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;404ping run myapp:users | jq &lt;span class="s1"&gt;'.data.users[].email'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What I built: Built-in JSON Filtering&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;404ping request https://api.example.com/posts/1 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--filter&lt;/span&gt; &lt;span class="s2"&gt;"json.comments[*].{author: author.name, text: body}"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And you can extract values directly into variables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;404ping request https://api.example.com/auth &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--extract&lt;/span&gt; &lt;span class="nv"&gt;token&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;json.access_token &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--extract&lt;/span&gt; &lt;span class="nv"&gt;userId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;json.user.id &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--extract&lt;/span&gt; &lt;span class="nv"&gt;trace&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;header.X-Trace-Id
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Extracted values go into &lt;code&gt;{{runtime.*}}&lt;/code&gt; and can be used in chained requests.&lt;/p&gt;




&lt;h3&gt;
  
  
  Moment 5: "Why can't it just switch environments easily?"
&lt;/h3&gt;

&lt;p&gt;Testing across staging/production was painful:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;404ping &lt;span class="nb"&gt;set &lt;/span&gt;host:https://staging-api.myapp.com
&lt;span class="c"&gt;# Test stuff&lt;/span&gt;
404ping &lt;span class="nb"&gt;set &lt;/span&gt;host:https://api.myapp.com
&lt;span class="c"&gt;# Test stuff&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What I built: Environment Profiles&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create &lt;code&gt;.env.staging&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;BASE_URL=https://staging-api.myapp.com
API_KEY=staging_key_123
TIMEOUT=10000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create &lt;code&gt;.env.production&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;BASE_URL=https://api.myapp.com
API_KEY=prod_key_456
TIMEOUT=5000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now switch with one flag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;404ping &lt;span class="nt"&gt;--env&lt;/span&gt; staging run myapp:users
404ping &lt;span class="nt"&gt;--env&lt;/span&gt; production run myapp:users
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can even layer multiple env files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;404ping &lt;span class="nt"&gt;--env&lt;/span&gt; staging &lt;span class="nt"&gt;--env-file&lt;/span&gt; secrets/.overrides.env run billing:charge
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Moment 6: "Why can't it just work with Postman collections?"
&lt;/h3&gt;

&lt;p&gt;My team uses Postman. I wanted to use 404ping. We were stuck in different worlds.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I built: Postman Import/Export&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Import their collection&lt;/span&gt;
404ping postman import team-api.postman.json &lt;span class="nt"&gt;-c&lt;/span&gt; teamapi

&lt;span class="c"&gt;# Work in terminal with 404ping's speed&lt;/span&gt;
404ping run teamapi:login
404ping run teamapi:create-user &lt;span class="nt"&gt;--assert&lt;/span&gt; &lt;span class="s2"&gt;"status=201"&lt;/span&gt;

&lt;span class="c"&gt;# Export back to share updates&lt;/span&gt;
404ping postman &lt;span class="nb"&gt;export &lt;/span&gt;teamapi &lt;span class="nt"&gt;-o&lt;/span&gt; team-api.postman.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now I can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Import team's Postman collections&lt;/li&gt;
&lt;li&gt;Work faster in terminal&lt;/li&gt;
&lt;li&gt;Export when I need to share&lt;/li&gt;
&lt;li&gt;Best of both worlds&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Moment 7: "Why can't it just run scripts before/after requests?"
&lt;/h3&gt;

&lt;p&gt;Sometimes you need custom logic — dynamic signatures, complex validation, custom logging.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I built: Hooks &amp;amp; Scripts&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;404ping request https://api.example.com/orders &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--pre-script&lt;/span&gt; @scripts/add-signature.js &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--post-script&lt;/span&gt; &lt;span class="s2"&gt;"console.log('Order created:', response.data.orderId)"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pre-scripts can modify the request before it's sent.&lt;br&gt;
Post-scripts can validate, log, or extract data from responses.&lt;/p&gt;


&lt;h3&gt;
  
  
  Moment 8: "Why can't it just benchmark this endpoint?"
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before:&lt;/strong&gt; Install &lt;code&gt;ab&lt;/code&gt; or &lt;code&gt;wrk&lt;/code&gt;, figure out syntax, parse output...&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Now:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;404ping request https://api.example.com/heavy &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--benchmark&lt;/span&gt; 10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Runs it 10 times and shows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Min/Median/P95 latency&lt;/li&gt;
&lt;li&gt;Success rate&lt;/li&gt;
&lt;li&gt;Average response size&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Perfect for quick performance checks.&lt;/p&gt;




&lt;h2&gt;
  
  
  What 404ping Actually Is Now
&lt;/h2&gt;

&lt;p&gt;Let me show you a real workflow — the kind I run every day as a bug bounty hunter:&lt;/p&gt;

&lt;h3&gt;
  
  
  Scenario: Testing a new API target
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Setup environment&lt;/span&gt;
404ping &lt;span class="nb"&gt;set &lt;/span&gt;host:https://api.target.com

&lt;span class="c"&gt;# 2. Test and save login endpoint&lt;/span&gt;
404ping request &lt;span class="o"&gt;{{&lt;/span&gt;host&lt;span class="o"&gt;}}&lt;/span&gt;/auth/login &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"email":"test@test.com","password":"password"}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--save&lt;/span&gt; target.login &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--assert&lt;/span&gt; &lt;span class="s2"&gt;"status=200"&lt;/span&gt;

&lt;span class="c"&gt;# 3. Run a full authenticated flow&lt;/span&gt;
404ping sequence target:login &lt;span class="se"&gt;\&lt;/span&gt;
  https://&lt;span class="o"&gt;{{&lt;/span&gt;host&lt;span class="o"&gt;}}&lt;/span&gt;/users/me &lt;span class="se"&gt;\&lt;/span&gt;
  https://&lt;span class="o"&gt;{{&lt;/span&gt;host&lt;span class="o"&gt;}}&lt;/span&gt;/admin/dashboard &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--extract&lt;/span&gt; &lt;span class="nv"&gt;token&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;json.access_token &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--bearer&lt;/span&gt; &lt;span class="o"&gt;{{&lt;/span&gt;runtime.token&lt;span class="o"&gt;}}&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--assert&lt;/span&gt; &lt;span class="s2"&gt;"status=200"&lt;/span&gt;

&lt;span class="c"&gt;# 4. Found IDOR? Test multiple user IDs quickly&lt;/span&gt;
404ping run target:get-user &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="s2"&gt;"{{host}}/users/123"&lt;/span&gt; &lt;span class="nt"&gt;--assert&lt;/span&gt; &lt;span class="s2"&gt;"status=403"&lt;/span&gt;
404ping run target:get-user &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="s2"&gt;"{{host}}/users/456"&lt;/span&gt; &lt;span class="nt"&gt;--assert&lt;/span&gt; &lt;span class="s2"&gt;"status=403"&lt;/span&gt;
404ping run target:get-user &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="s2"&gt;"{{host}}/users/789"&lt;/span&gt; &lt;span class="nt"&gt;--assert&lt;/span&gt; &lt;span class="s2"&gt;"status=200"&lt;/span&gt;

&lt;span class="c"&gt;# 5. Check TLS configuration&lt;/span&gt;
404ping request &lt;span class="o"&gt;{{&lt;/span&gt;host&lt;span class="o"&gt;}}&lt;/span&gt;/secure &lt;span class="nt"&gt;--tls&lt;/span&gt;

&lt;span class="c"&gt;# 6. Benchmark for timing attacks&lt;/span&gt;
404ping request &lt;span class="o"&gt;{{&lt;/span&gt;host&lt;span class="o"&gt;}}&lt;/span&gt;/auth/check &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"user":"admin"}'&lt;/span&gt; &lt;span class="nt"&gt;--benchmark&lt;/span&gt; 100
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's a complete security test workflow in 6 commands. No Postman. No bash scripts. Just 404ping.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Complete Feature List (What You Can Do Now)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Core Functionality:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ HTTP requests (all methods, headers, bodies)&lt;/li&gt;
&lt;li&gt;✅ Global and collection-scoped variables&lt;/li&gt;
&lt;li&gt;✅ Collections for organizing requests&lt;/li&gt;
&lt;li&gt;✅ Quick save with &lt;code&gt;--save&lt;/code&gt; flag&lt;/li&gt;
&lt;li&gt;✅ Run saved requests with overrides&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;New Superpowers:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🧪 &lt;strong&gt;Assertions&lt;/strong&gt; — Validate responses inline (&lt;code&gt;--assert&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;🔗 &lt;strong&gt;Request Chaining&lt;/strong&gt; — Run sequences with variable extraction (&lt;code&gt;sequence&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;📊 &lt;strong&gt;JSON Filtering&lt;/strong&gt; — Parse responses without jq (&lt;code&gt;--filter&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;💾 &lt;strong&gt;Variable Extraction&lt;/strong&gt; — Capture values from responses (&lt;code&gt;--extract&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;🌍 &lt;strong&gt;Environment Profiles&lt;/strong&gt; — Switch environments with &lt;code&gt;--env&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;🔄 &lt;strong&gt;Postman Import/Export&lt;/strong&gt; — Work with team collections&lt;/li&gt;
&lt;li&gt;🪝 &lt;strong&gt;Hooks &amp;amp; Scripts&lt;/strong&gt; — Pre/post request JavaScript (&lt;code&gt;--pre-script&lt;/code&gt;, &lt;code&gt;--post-script&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;⚡ &lt;strong&gt;Benchmarking&lt;/strong&gt; — Performance testing built-in (&lt;code&gt;--benchmark&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;🔐 &lt;strong&gt;Advanced Output Modes&lt;/strong&gt; — &lt;code&gt;--info&lt;/code&gt;, &lt;code&gt;--connection&lt;/code&gt;, &lt;code&gt;--tls&lt;/code&gt;, &lt;code&gt;--debug&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Security &amp;amp; Developer Experience:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🛡️ SSL verification by default (explicit &lt;code&gt;--insecure&lt;/code&gt; to bypass)&lt;/li&gt;
&lt;li&gt;📝 Comprehensive error messages that actually help&lt;/li&gt;
&lt;li&gt;🔍 TLS/SSL certificate inspection&lt;/li&gt;
&lt;li&gt;🌐 Connection debugging&lt;/li&gt;
&lt;li&gt;✅ Input validation and path traversal protection&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  How to Use It (Quick Start)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Installation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/toklas495/404ping.git
&lt;span class="nb"&gt;cd &lt;/span&gt;404ping
npm &lt;span class="nb"&gt;install
&lt;/span&gt;npm run build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Basic Usage
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Simple request&lt;/span&gt;
404ping request https://api.example.com/users

&lt;span class="c"&gt;# POST with data&lt;/span&gt;
404ping request https://api.example.com/login &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"email":"test@test.com","password":"secret"}'&lt;/span&gt;

&lt;span class="c"&gt;# Save while testing&lt;/span&gt;
404ping request &lt;span class="o"&gt;{{&lt;/span&gt;host&lt;span class="o"&gt;}}&lt;/span&gt;/api/login &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"email":"{{email}}"}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--save&lt;/span&gt; myapp.login

&lt;span class="c"&gt;# Run saved request&lt;/span&gt;
404ping run myapp:login

&lt;span class="c"&gt;# Chain requests with token extraction&lt;/span&gt;
404ping sequence myapp:login myapp:profile &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--extract&lt;/span&gt; &lt;span class="nv"&gt;token&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;json.token &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--bearer&lt;/span&gt; &lt;span class="o"&gt;{{&lt;/span&gt;runtime.token&lt;span class="o"&gt;}}&lt;/span&gt;

&lt;span class="c"&gt;# Switch environments&lt;/span&gt;
404ping &lt;span class="nt"&gt;--env&lt;/span&gt; staging run myapp:users

&lt;span class="c"&gt;# Import Postman collection&lt;/span&gt;
404ping postman import api.postman.json &lt;span class="nt"&gt;-c&lt;/span&gt; myproject
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Real Workflow
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Setup&lt;/span&gt;
404ping &lt;span class="nb"&gt;set &lt;/span&gt;host:https://api.myapp.com

&lt;span class="c"&gt;# 2. Test &amp;amp; save requests as you explore&lt;/span&gt;
404ping request &lt;span class="o"&gt;{{&lt;/span&gt;host&lt;span class="o"&gt;}}&lt;/span&gt;/auth/login &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"email":"dev@myapp.com","password":"test123"}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--save&lt;/span&gt; myapp.login &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--assert&lt;/span&gt; &lt;span class="s2"&gt;"status=200"&lt;/span&gt;

&lt;span class="c"&gt;# 3. Run authenticated flows&lt;/span&gt;
404ping sequence myapp:login myapp:get-profile myapp:list-posts &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--extract&lt;/span&gt; &lt;span class="nv"&gt;token&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;json.access_token &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--bearer&lt;/span&gt; &lt;span class="o"&gt;{{&lt;/span&gt;runtime.token&lt;span class="o"&gt;}}&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--assert&lt;/span&gt; &lt;span class="s2"&gt;"status=200"&lt;/span&gt;

&lt;span class="c"&gt;# 4. Debug issues&lt;/span&gt;
404ping run myapp:slow-endpoint &lt;span class="nt"&gt;--info&lt;/span&gt; &lt;span class="nt"&gt;--benchmark&lt;/span&gt; 5

&lt;span class="c"&gt;# 5. Check security&lt;/span&gt;
404ping request &lt;span class="o"&gt;{{&lt;/span&gt;host&lt;span class="o"&gt;}}&lt;/span&gt;/secure &lt;span class="nt"&gt;--tls&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  The Numbers
&lt;/h2&gt;

&lt;p&gt;Since v2:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Change&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Features&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;+8 major features&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Commands&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;request&lt;/code&gt;, &lt;code&gt;run&lt;/code&gt;, &lt;code&gt;set&lt;/code&gt;, &lt;code&gt;vars&lt;/code&gt; → Added &lt;code&gt;sequence&lt;/code&gt;, &lt;code&gt;postman&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Flags&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;+12 new flags (&lt;code&gt;--assert&lt;/code&gt;, &lt;code&gt;--extract&lt;/code&gt;, &lt;code&gt;--filter&lt;/code&gt;, &lt;code&gt;--benchmark&lt;/code&gt;, &lt;code&gt;--env&lt;/code&gt;, etc.)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GitHub Stars&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;6 → Growing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Use Cases&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Testing → Testing + CI/CD + Security Audits + Performance Testing&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;Listen to your own frustration&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Every feature came from me getting annoyed using my own tool. The best product feedback is your own pain.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. &lt;strong&gt;"Just one more flag" compounds quickly&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;--save&lt;/code&gt; seemed small. But it changed everything. Then &lt;code&gt;--extract&lt;/code&gt;. Then &lt;code&gt;--assert&lt;/code&gt;. Small conveniences add up to workflows you couldn't imagine before.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. &lt;strong&gt;Interoperability &amp;gt; Lock-in&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Adding Postman import/export wasn't admitting defeat. It made 404ping more valuable. Now teams can use both.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. &lt;strong&gt;Security should be the default&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;SSL verification on by default. Explicit &lt;code&gt;--insecure&lt;/code&gt; flag. If you want to be insecure, you have to type it out.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. &lt;strong&gt;Documentation is code&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Every new feature came with examples in the README. If users can't figure it out in 30 seconds, it might as well not exist.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;I'm not done. Here's what I'm thinking about:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Maybe Soon:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🔌 &lt;strong&gt;Plugin system&lt;/strong&gt; — Let people extend 404ping however they want&lt;/li&gt;
&lt;li&gt;📊 &lt;strong&gt;Request history&lt;/strong&gt; — See what you ran recently, replay it&lt;/li&gt;
&lt;li&gt;🧬 &lt;strong&gt;Response diffing&lt;/strong&gt; — Compare staging vs production responses&lt;/li&gt;
&lt;li&gt;🎯 &lt;strong&gt;Mock server&lt;/strong&gt; — Spin up mocks from saved responses&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Ideas I'm Exploring:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GraphQL support&lt;/li&gt;
&lt;li&gt;gRPC testing&lt;/li&gt;
&lt;li&gt;WebSocket connections&lt;/li&gt;
&lt;li&gt;Request templating&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But I'm not rushing. I'd rather ship features that work perfectly than half-bake 10 things.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;If you test APIs and you're tired of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Postman eating 600MB of RAM&lt;/li&gt;
&lt;li&gt;Copying tokens between requests manually&lt;/li&gt;
&lt;li&gt;Writing bash scripts to chain API calls&lt;/li&gt;
&lt;li&gt;Remembering curl flags&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Give 404ping a shot:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/toklas495/404ping.git
&lt;span class="nb"&gt;cd &lt;/span&gt;404ping
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm run build
404ping &lt;span class="nt"&gt;--help&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;⭐ &lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/toklas495/404ping" rel="noopener noreferrer"&gt;github.com/toklas495/404ping&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;v2 was "curl with memory."&lt;/p&gt;

&lt;p&gt;Now? 404ping is actually good. It's the tool I reach for first. It's fast, it's powerful, and it gets out of my way.&lt;/p&gt;

&lt;p&gt;If you try it and hate something, tell me. If you love it, tell your friends.&lt;/p&gt;

&lt;p&gt;And if you have ideas? Open an issue. I'm always looking for the next "why can't it just..." moment.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Happy hunting 🎯&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;— Nimesh (toklas495)&lt;/p&gt;




&lt;p&gt;&lt;em&gt;P.S. — If you're using 404ping for bug bounties or in production, I'd genuinely love to hear your story. Success stories fuel late-night coding sessions.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>node</category>
      <category>opensource</category>
      <category>devops</category>
      <category>cybersecurity</category>
    </item>
    <item>
      <title>The Real Story of Account Linking — How I Learned Auth Is a Flow, Not a Login</title>
      <dc:creator>Nimesh Thakur</dc:creator>
      <pubDate>Sun, 01 Feb 2026 07:59:22 +0000</pubDate>
      <link>https://dev.to/toklas495/the-real-story-of-account-linking-how-i-learned-auth-is-a-flow-not-a-login-57bj</link>
      <guid>https://dev.to/toklas495/the-real-story-of-account-linking-how-i-learned-auth-is-a-flow-not-a-login-57bj</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Auth is not a login. Auth is a flow. The moment you understand this, everything clicks.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  01 — It Started Simple
&lt;/h2&gt;

&lt;p&gt;When I first built authentication, I only had one provider: &lt;strong&gt;password login.&lt;/strong&gt; User signs up with email and password. Done. One table. One row. Life was easy.&lt;/p&gt;

&lt;p&gt;Then the product needed Google login. Then GitHub. Then SMS OTP. Then Apple. Suddenly I had five ways for someone to prove they are who they say they are — and I had no idea how to connect them all to the same person.&lt;/p&gt;

&lt;p&gt;My first instinct was naive — and almost every developer does this. When someone logs in via Google, I would just look at the email Google gave me. If that email already existed in my &lt;code&gt;users&lt;/code&gt; table, return that user. If not, create a new one. No linking. No resolution. Just a simple email lookup.&lt;/p&gt;

&lt;p&gt;I thought this was enough. It wasn't.&lt;/p&gt;




&lt;h2&gt;
  
  
  02 — The Crack in the Wall
&lt;/h2&gt;

&lt;p&gt;I started reading docs — Clerk's account linking guide, Auth0's user account linking strategy. And slowly I realized: &lt;strong&gt;my simple email-lookup approach was a security hole.&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;The Attack&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;An attacker signs up with &lt;em&gt;your&lt;/em&gt; email address using a password — but never verifies it. Now your email exists in the system, unverified, with a password hash attached. Later, you try to log in with Google (which &lt;em&gt;has&lt;/em&gt; verified your email). If the system just sees "email exists, return user" — the attacker's unverified account is now yours. &lt;strong&gt;Account takeover. No notification. No trace.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is why you can't just match on email. You need to understand &lt;em&gt;who owns what&lt;/em&gt;, &lt;em&gt;what is verified&lt;/em&gt;, and &lt;em&gt;what needs explicit permission to link.&lt;/em&gt; That's when I started redesigning everything.&lt;/p&gt;




&lt;h2&gt;
  
  
  03 — The New Architecture: Five Tables, Five Responsibilities
&lt;/h2&gt;

&lt;p&gt;Before, I had one big table with email, password, everything crammed together. After reading and thinking, I split it into five clean boundaries. Each table owns exactly one job.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Table&lt;/th&gt;
&lt;th&gt;Owns&lt;/th&gt;
&lt;th&gt;Why It's Separate&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;users&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Who is this person?&lt;/td&gt;
&lt;td&gt;Single source of truth for identity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;credentials&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;What's their password?&lt;/td&gt;
&lt;td&gt;Secrets need their own boundary&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;accounts&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;What external IDs map to them?&lt;/td&gt;
&lt;td&gt;Links Google/GitHub/OTP → one user&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sessions&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Are they logged in now?&lt;/td&gt;
&lt;td&gt;Active session state&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;refresh_tokens&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Can they stay logged in?&lt;/td&gt;
&lt;td&gt;Long-lived auth with rotation&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  The Full Table Map
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Table&lt;/th&gt;
&lt;th&gt;Key Columns&lt;/th&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;users&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;id&lt;/code&gt;, &lt;code&gt;email&lt;/code&gt;, &lt;code&gt;email_verified&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Source of Truth&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;credentials&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;user_id&lt;/code&gt;, &lt;code&gt;password_hash&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Secret Boundary&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;accounts&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;provider&lt;/code&gt;, &lt;code&gt;provider_user_id&lt;/code&gt;, &lt;code&gt;user_id&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Linking Backbone&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sessions&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;session_token&lt;/code&gt;, &lt;code&gt;expires_at&lt;/code&gt;, &lt;code&gt;revoked&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Session Boundary&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;refresh_tokens&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;token_hash&lt;/code&gt;, &lt;code&gt;rotation_count&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Rotation Boundary&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;Key Insight:&lt;/strong&gt; Password login does &lt;strong&gt;not&lt;/strong&gt; create an &lt;code&gt;accounts&lt;/code&gt; row. Only external providers (Google, GitHub, OTP) do. The &lt;code&gt;credentials&lt;/code&gt; table is the password's world. The &lt;code&gt;accounts&lt;/code&gt; table is the external world. They never touch each other directly.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  04 — Auth Is a Flow, Not a Single Function
&lt;/h2&gt;

&lt;p&gt;This was my biggest mental shift. I used to think of auth as one function: &lt;em&gt;"verify credentials, return user."&lt;/em&gt; But when you have multiple providers, auth becomes a &lt;strong&gt;state machine.&lt;/strong&gt; It has steps. It can pause. It can ask for more information. It can fail at different points for different reasons.&lt;/p&gt;

&lt;p&gt;I introduced the concept of an &lt;strong&gt;AuthFlow&lt;/strong&gt; — a temporary state that lives between "the user clicked login" and "the session is created."&lt;/p&gt;

&lt;h3&gt;
  
  
  The Auth Flow — Step by Step
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1️⃣  User clicks "Login with Google"
    └─ AuthFlow created with a unique flowId

2️⃣  Provider authenticates
    └─ Google verifies user → returns identity (sub, email, verified?)

3️⃣  resolveAccount() runs
    └─ The brain. Decides: return user? Create? Or pause?

4a ❌ LINK_REQUIRED — Flow pauses
    └─ Email exists with verified password
    └─ Flow saves state, throws error with flowId
    └─ Frontend shows: "Log in with your password first"

4b ✅ OK — Flow completes
    └─ User resolved. AuthFlow deleted. Session created.

5️⃣  linkAccount() — If paused at 4a
    └─ User proves password ownership
    └─ OAuth identity linked. Flow deleted. Session created.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Code: &lt;code&gt;authenticate()&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;authenticate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;providerName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Step 1: Get the provider (Google, GitHub, password, etc.)&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getProvider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;providerName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Step 2: Provider gives us an identity&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;identity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;authenticate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Step 3: Resolve — find or create user&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolveAccount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;identity&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Step 4a: If linking is needed, pause the flow&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;LINK_REQUIRED&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;updateAuthFlow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;flowId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;LINK_REQUIRED&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;intent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ACCOUNT_LINK&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;identity&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Email already linked. Authenticate with password first.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Step 4b: Flow complete — clean up and create session&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;deleteAuthFlow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;flowId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  05 — &lt;code&gt;resolveAccount&lt;/code&gt; — The Brain of It All
&lt;/h2&gt;

&lt;p&gt;This is where the real logic lives. Every login attempt from an external provider goes through here. It's a decision tree, and every branch matters.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Decision Tree
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Is the provider "password"?
├── Yes → Find user by ID. Return OK ✅
└── No ↓

Does provider + provider_user_id exist in accounts table?
├── Yes → Return that user. OK ✅
└── No ↓

Did the provider give us a VERIFIED email?
├── No  → Create new user with just provider_user_id. OK ✅
└── Yes ↓

Does that email already exist in users table?
├── No  → Create new user + account row. OK ✅
└── Yes ↓

⚡ Does this existing user have a password credential?
├── Yes + email IS verified     → LINK_REQUIRED ❌ (pause flow)
├── Yes + email is NOT verified → DELETE that credential. Ghost account.
│                                  Link and continue. OK ✅
└── No password at all          → Safe to link directly. OK ✅
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;⚡ &lt;strong&gt;Why delete the unverified credential?&lt;/strong&gt; If someone registered with your email but never verified it, that account could belong to an attacker. When Google (or any trusted provider) confirms &lt;em&gt;you&lt;/em&gt; own that email, the unverified password account is a ghost. Keeping it means the attacker could still try to recover it. So we remove it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  The Code: &lt;code&gt;resolveAccount()&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resolveAccount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;identity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AuthResult&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="c1"&gt;// ── Password provider is simple: just find the user ──&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;identity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;password&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;identity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;OK&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// ── Already seen this provider before? Return that user ──&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;existing&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Account&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByProviderAndId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;identity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;identity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;provider_user_id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;existing&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;existing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;OK&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// ── New provider identity. Check if email is verified ──&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;identity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;provider_email&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;verified&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;identity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;provider_email_verified&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;verified&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;existingUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findByEmail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;existingUser&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hasCred&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Cred&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getCred&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;existingUser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hasCred&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// ⚡ The critical split&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;existingUser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email_verified&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;LINK_REQUIRED&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt; &lt;span class="c1"&gt;// Must prove password ownership&lt;/span&gt;

        &lt;span class="c1"&gt;// Unverified + has password = ghost account. Delete it.&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Cred&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;delCred&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hasCred&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setEmailVerified&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;existingUser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="c1"&gt;// Safe to link — no password conflict&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;insertAccount&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;identity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;existingUser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;OK&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;existingUser&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// ── Nothing matched. Create a brand new user ──&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;email_verified&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="nx"&gt;verified&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;full_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;identity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;insertAccount&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;identity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;newUser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;OK&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;newUser&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  06 — &lt;code&gt;linkAccount&lt;/code&gt; — Completing the Paused Flow
&lt;/h2&gt;

&lt;p&gt;When &lt;code&gt;resolveAccount&lt;/code&gt; returns &lt;code&gt;LINK_REQUIRED&lt;/code&gt;, the flow pauses. The frontend shows a password prompt. The user proves they own the existing account. Then &lt;code&gt;linkAccount()&lt;/code&gt; picks up where we left off.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;linkAccount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;flowId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Retrieve the paused flow&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;flow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getAuthFlow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;flowId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;flow&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;flow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;LINK_REQUIRED&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Flow not found or not in LINK_REQUIRED state&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Prove password ownership&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;passwordProvider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getProvider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;password&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;primaryIdentity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;passwordProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;authenticate&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;flow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;identity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;provider_email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;password&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;// Link the OAuth identity to the password user&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;linkAccount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;primaryIdentity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="c1"&gt;// The password user (proven owner)&lt;/span&gt;
    &lt;span class="nx"&gt;flow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;identity&lt;/span&gt;      &lt;span class="c1"&gt;// The OAuth identity waiting to link&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Clean up and create session&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;deleteAuthFlow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;flowId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  07 — The Full Picture: Who Does What
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Function&lt;/th&gt;
&lt;th&gt;Job&lt;/th&gt;
&lt;th&gt;Returns&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;authenticate()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Entry point. Orchestrates the entire flow.&lt;/td&gt;
&lt;td&gt;Session ✅ or Pause ❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;resolveAccount()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Decides what to do with an identity.&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;OK&lt;/code&gt; or &lt;code&gt;LINK_REQUIRED&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;linkAccount()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Resumes a paused flow after password proof.&lt;/td&gt;
&lt;td&gt;Session ✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  08 — What I Took Away
&lt;/h2&gt;

&lt;p&gt;The hardest part wasn't the code. It was understanding &lt;em&gt;why&lt;/em&gt; each decision exists.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Why can't I just match on email?&lt;/strong&gt; Because emails are not proof of ownership — verification is.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Why do I need a separate credentials table?&lt;/strong&gt; Because secrets need their own boundary.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Why does the flow need to pause?&lt;/strong&gt; Because sometimes auth requires two steps, not one.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;✅ &lt;strong&gt;The Three Rules&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Never trust an unverified email as identity.&lt;/strong&gt; An attacker can register it first.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Separate secrets from identity.&lt;/strong&gt; Passwords, tokens, and hashes have their own table. Users are just users.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Auth is a flow, not a function.&lt;/strong&gt; It can pause, branch, and resume. Design for that.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Once I saw auth this way — as a state machine with clean boundaries — everything became logical. Each table has a single job. Each function has a single responsibility. The complexity didn't disappear. It just became &lt;em&gt;visible&lt;/em&gt;, and visible things are things you can reason about.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;If you've been doing the "just check email" approach — it's okay. Now you know. The architecture above is what I moved to, and it handles every edge case I've thrown at it.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>backend</category>
      <category>systemdesign</category>
      <category>typescript</category>
      <category>security</category>
    </item>
    <item>
      <title>The Mirror Trick: Why Knowing Good Habits Changes Nothing</title>
      <dc:creator>Nimesh Thakur</dc:creator>
      <pubDate>Mon, 12 Jan 2026 02:19:44 +0000</pubDate>
      <link>https://dev.to/toklas495/the-mirror-trick-why-knowing-good-habits-changes-nothing-121</link>
      <guid>https://dev.to/toklas495/the-mirror-trick-why-knowing-good-habits-changes-nothing-121</guid>
      <description>&lt;p&gt;Everyone says habits decide your future.&lt;/p&gt;

&lt;p&gt;Read Atomic Habits. Make a to-do list. Wake up at 5 AM. Meditate. Work deeply. Delete Instagram.&lt;/p&gt;

&lt;p&gt;I knew all of this. I read the books. I understood the science.&lt;/p&gt;

&lt;p&gt;But I still scrolled for hours. Still sat all day. Still felt my brain turning to fog.&lt;/p&gt;

&lt;p&gt;Knowing didn't change anything.&lt;/p&gt;

&lt;p&gt;It's like knowing sugar is bad but eating it anyway. The knowledge sits in your head while your hand reaches for the cookie.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your Brain Isn't Resting When You Think It Is
&lt;/h2&gt;

&lt;p&gt;Here's something nobody explains clearly:&lt;/p&gt;

&lt;p&gt;Your brain is like your phone's battery. It drains all day.&lt;/p&gt;

&lt;p&gt;When you watch TV while eating dinner, your brain splits in half. 50% goes to the screen. 50% goes to digesting food. Nothing gets full attention.&lt;/p&gt;

&lt;p&gt;When you study for 4 hours then "relax" by watching a movie, you're not resting. Your brain is working harder. It's tracking characters, emotions, plot twists. That's not a break. That's just different work.&lt;/p&gt;

&lt;p&gt;Same with scrolling after work. You think you're relaxing. But your brain is processing faces, stories, comparisons, dopamine hits. It's sprinting, not resting.&lt;/p&gt;

&lt;p&gt;A 12-year-old gets this immediately when you say: "Your brain is always paying for something. Either with focus or with energy."&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Stopping Never Works
&lt;/h2&gt;

&lt;p&gt;I tried everything.&lt;/p&gt;

&lt;p&gt;App blockers. Timers. Deleting social media. Cold turkey.&lt;/p&gt;

&lt;p&gt;Nothing stuck.&lt;/p&gt;

&lt;p&gt;Here's why: telling your brain "don't do this" is like saying "don't think of a pink elephant."&lt;/p&gt;

&lt;p&gt;Now you're thinking of a pink elephant.&lt;/p&gt;

&lt;p&gt;The brain doesn't obey force. When you block YouTube, you want YouTube more. When you promise to stop masturbating, the urge grows stronger. When you delete Instagram, you think about Instagram.&lt;/p&gt;

&lt;p&gt;Stopping creates tension. Tension creates obsession.&lt;/p&gt;

&lt;p&gt;The harder you fight, the louder the urge screams.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Silent Damage We Ignore
&lt;/h2&gt;

&lt;p&gt;Sitting all day isn't neutral.&lt;/p&gt;

&lt;p&gt;Scrolling isn't harmless "me time."&lt;/p&gt;

&lt;p&gt;Being idle isn't rest.&lt;/p&gt;

&lt;p&gt;Everything costs something.&lt;/p&gt;

&lt;p&gt;When you sit to study, then sit to scroll, then sit to watch TV, then sit to work—your body forgets how to move. Your posture collapses. Your energy disappears.&lt;/p&gt;

&lt;p&gt;Even "doing nothing" costs energy. Sitting idle while your brain spins with thoughts drains you faster than walking 3 kilometers.&lt;/p&gt;

&lt;p&gt;I'm not saying you're bad for doing these things. I'm saying: they're not free. They charge you. And most people don't realize they're paying.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Shift: Stop Being the Actor
&lt;/h2&gt;

&lt;p&gt;One idea changed everything for me.&lt;/p&gt;

&lt;p&gt;It came from a simple concept—don't be the actor in your life. Be the witness.&lt;/p&gt;

&lt;p&gt;What does that mean?&lt;/p&gt;

&lt;p&gt;When you eat, just eat. Not: eat + scroll + think about work.&lt;/p&gt;

&lt;p&gt;When you walk, just walk. Not: walk + make up stories in your head + replay arguments.&lt;/p&gt;

&lt;p&gt;When you're angry, just notice: "Oh, I'm angry." Don't dive into the anger. Don't become the anger.&lt;/p&gt;

&lt;p&gt;Watch your thoughts like clouds passing. You're the sky, not the cloud.&lt;/p&gt;

&lt;p&gt;I know that sounds abstract. Here's the real version:&lt;/p&gt;

&lt;p&gt;Stop reacting to every urge immediately. Put a tiny gap between the urge and the action.&lt;/p&gt;

&lt;p&gt;That gap is where everything changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Simple Trick: Energy In vs Energy Out
&lt;/h2&gt;

&lt;p&gt;I stopped trying to "be disciplined."&lt;/p&gt;

&lt;p&gt;Instead, I started treating my life like a bank account.&lt;/p&gt;

&lt;p&gt;Not money. Energy.&lt;/p&gt;

&lt;p&gt;Some things deposit energy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Walking outside&lt;/li&gt;
&lt;li&gt;Reading a book that makes me think&lt;/li&gt;
&lt;li&gt;15 minutes of silence in the morning&lt;/li&gt;
&lt;li&gt;Working out&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some things withdraw energy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Scrolling for an hour&lt;/li&gt;
&lt;li&gt;Watching movies that don't matter&lt;/li&gt;
&lt;li&gt;Sitting idle&lt;/li&gt;
&lt;li&gt;Masturbating when I'm bored, not because I want to&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nothing is "bad." Nothing is "good."&lt;/p&gt;

&lt;p&gt;The only question: Does this give me energy for tomorrow, or does it take it?&lt;/p&gt;

&lt;h2&gt;
  
  
  The Mirror
&lt;/h2&gt;

&lt;p&gt;I built a simple app. Not a blocker. Not a streak tracker. Just a mirror.&lt;/p&gt;

&lt;p&gt;Here's how it works:&lt;/p&gt;

&lt;p&gt;You list activities. You mark which ones give energy. Which ones drain it.&lt;/p&gt;

&lt;p&gt;Then, whenever you do something, you log it. 50 minutes scrolling YouTube? Log it. 30 minutes walking? Log it.&lt;/p&gt;

&lt;p&gt;The app shows your energy balance. Like a bank statement.&lt;/p&gt;

&lt;p&gt;That's it.&lt;/p&gt;

&lt;p&gt;No shame. No punishment. No streaks to protect.&lt;/p&gt;

&lt;p&gt;Just: "Here's what you did today. Here's how much energy you have left."&lt;/p&gt;

&lt;h2&gt;
  
  
  What Changed Without Trying
&lt;/h2&gt;

&lt;p&gt;After a few days, something weird happened.&lt;/p&gt;

&lt;p&gt;I still wanted to scroll. But before opening YouTube, I thought: "This will drain 50 points."&lt;/p&gt;

&lt;p&gt;Then I thought: "Walking outside gives me 30 points."&lt;/p&gt;

&lt;p&gt;So I walked.&lt;/p&gt;

&lt;p&gt;Not because I forced myself. Because I saw it clearly.&lt;/p&gt;

&lt;p&gt;I still wanted to masturbate sometimes. But I'd think: "This drains 20 points for nothing."&lt;/p&gt;

&lt;p&gt;And the urge just... faded.&lt;/p&gt;

&lt;p&gt;I didn't stop it. Awareness stopped it.&lt;/p&gt;

&lt;p&gt;I started reading more. Not because reading is "good." Because after 40 minutes of reading, I'd log +100 energy, and my brain liked that feeling.&lt;/p&gt;

&lt;p&gt;Meditation increased energy. So I did it more.&lt;/p&gt;

&lt;p&gt;Sitting idle drained energy. So I did it less.&lt;/p&gt;

&lt;p&gt;Nothing was forced. Everything just shifted.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Part Nobody Talks About
&lt;/h2&gt;

&lt;p&gt;I still scroll sometimes. I still watch movies. I still sit.&lt;/p&gt;

&lt;p&gt;I'm not perfect. I'm not "optimized."&lt;/p&gt;

&lt;p&gt;But here's the difference:&lt;/p&gt;

&lt;p&gt;Before, I scrolled and felt bad.&lt;/p&gt;

&lt;p&gt;Now, I scroll and I see it happening. I know the cost. Sometimes I pay it anyway. But I'm awake.&lt;/p&gt;

&lt;p&gt;Before, I'd sit idle and wonder why I felt empty.&lt;/p&gt;

&lt;p&gt;Now, I notice: "I'm sitting idle. My energy is draining."&lt;/p&gt;

&lt;p&gt;And usually, I get up and walk.&lt;/p&gt;

&lt;p&gt;Not because walking is virtuous. Because I can feel the difference.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Habits don't change your life.&lt;/p&gt;

&lt;p&gt;Awareness changes your habits.&lt;/p&gt;

&lt;p&gt;You don't need more discipline. You don't need more willpower.&lt;/p&gt;

&lt;p&gt;You need a mirror.&lt;/p&gt;

&lt;p&gt;When you see clearly, you choose better without trying.&lt;/p&gt;

&lt;p&gt;That's it. That's the whole trick.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;The app I built is called Aware. It's just a mirror. You can try it at aware.404nation.com if you want. Or build your own mirror. Doesn't matter. The tool isn't magic. Seeing clearly is.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>opensource</category>
      <category>devjournal</category>
      <category>typescript</category>
    </item>
    <item>
      <title>The Magic Behind “Login with Google”: How OAuth 2.0 Actually Works</title>
      <dc:creator>Nimesh Thakur</dc:creator>
      <pubDate>Sun, 04 Jan 2026 04:10:54 +0000</pubDate>
      <link>https://dev.to/toklas495/the-magic-behind-login-with-google-how-oauth-20-actually-works-3kll</link>
      <guid>https://dev.to/toklas495/the-magic-behind-login-with-google-how-oauth-20-actually-works-3kll</guid>
      <description>&lt;h2&gt;
  
  
  Introduction: The Magic Login Button
&lt;/h2&gt;

&lt;p&gt;You're on a website. You see "Login with Google" or "Login with GitHub." You click it. Boom — you're logged in. No passwords to remember, no email verification waiting. Just... magic?&lt;/p&gt;

&lt;p&gt;But how does this actually work? Let's take a journey together and understand what happens behind that simple button click.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Google, GitHub, Facebook Are Used
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbnfv3h8k238co0abkkgw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbnfv3h8k238co0abkkgw.png" alt="configcat.com_login_providers" width="458" height="200"&gt;&lt;/a&gt;&lt;br&gt;
First question: Why do we always see Google, GitHub, Facebook, X (Twitter), or Microsoft? Why not any random website?&lt;/p&gt;

&lt;p&gt;The answer is simple: &lt;strong&gt;they have massive user bases&lt;/strong&gt;. Almost everyone has a Google account. Many developers have GitHub accounts. These companies are famous merchants of identity because they already store information about billions of users.&lt;/p&gt;

&lt;p&gt;Think about it — your information is already sitting in Google's servers, tied to your email ID. So why should you sign up on every new website, verify your email again and again? It's exhausting.&lt;/p&gt;

&lt;p&gt;That's the problem these providers solve.&lt;/p&gt;
&lt;h2&gt;
  
  
  Where Our Information Already Lives
&lt;/h2&gt;

&lt;p&gt;Here's the key insight: &lt;strong&gt;you're already logged into your browser&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Whether it's Chrome, Firefox, or Safari, you've probably logged into Google or GitHub on your mobile or desktop. Your authentication already exists. You've already proved who you are to these providers.&lt;/p&gt;

&lt;p&gt;So new companies thought: "Why not leverage this? Why make users create new accounts when they can just use what they already have?"&lt;/p&gt;

&lt;p&gt;And that's how this story begins.&lt;/p&gt;
&lt;h2&gt;
  
  
  Registering a Website as a Client
&lt;/h2&gt;

&lt;p&gt;Let's pause here. Before any website can offer "Login with Google," they need to register themselves.&lt;/p&gt;

&lt;p&gt;Here's what happens:&lt;/p&gt;

&lt;p&gt;A company (let's say Canva) goes to Google and says: "Hey, I want to use your authentication service." They register their website as a &lt;strong&gt;client&lt;/strong&gt; with details like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Application type&lt;/strong&gt;: Is it a website or a native mobile app?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Name&lt;/strong&gt;: What's the application called?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;URL&lt;/strong&gt;: Where does it live?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Redirect URI&lt;/strong&gt;: Where should Google send users back after login?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fls02yaby6f7fsv1z7y6b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fls02yaby6f7fsv1z7y6b.png" alt="google_oauth_client_registration" width="557" height="627"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In return, Google gives them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;client_id&lt;/strong&gt;: A unique identifier (like a username for the website)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;client_secret&lt;/strong&gt;: A password that authenticates the client to Google&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These credentials are crucial. They prove to Google that the request is coming from a legitimate registered client.&lt;/p&gt;
&lt;h2&gt;
  
  
  Clicking "Login with Provider"
&lt;/h2&gt;

&lt;p&gt;Alright, now we're at the moment you click "Login with Google."&lt;/p&gt;

&lt;p&gt;What happens?&lt;/p&gt;

&lt;p&gt;The website (client) &lt;strong&gt;redirects you&lt;/strong&gt; to Google's website. This isn't just a simple redirect though. The client sends several important pieces of information along with you.&lt;/p&gt;
&lt;h2&gt;
  
  
  Authentication and User Consent
&lt;/h2&gt;

&lt;p&gt;You land on Google's page.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvxyl5gjcx7fo84re3kf1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvxyl5gjcx7fo84re3kf1.png" alt="canva_prompt_screen_for_google" width="800" height="330"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First, Google &lt;strong&gt;authenticates you&lt;/strong&gt;. If you're not already logged in, they'll prompt you to enter your email and password.&lt;/p&gt;

&lt;p&gt;Once you're authenticated, Google shows you something like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Canva.com is asking for your email, name, and profile picture. Allow or deny?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is the &lt;strong&gt;authorization&lt;/strong&gt; step. You're deciding what information the client can access.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4jttce9v94fjio7x2zd2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4jttce9v94fjio7x2zd2.png" alt="oauth_scope_allow_deny" width="800" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you click "Allow," Google prepares to share that information with the client. But what happens at a deeper layer?&lt;/p&gt;
&lt;h2&gt;
  
  
  What Is Sent During Redirect (High-Level)
&lt;/h2&gt;

&lt;p&gt;When the client redirected you to Google, they sent several parameters. Let me break them down in simple terms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;state&lt;/strong&gt;: A random token for CSRF protection. It makes every request unique so hackers can't forge requests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;scope&lt;/strong&gt;: What information does the client want? Email? Name? Profile picture?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;client_id&lt;/strong&gt;: Who is asking? This authenticates the client.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;redirect_uri&lt;/strong&gt;: Where should Google send the user back? Google checks this matches what was registered.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;response_type&lt;/strong&gt;: What kind of response does the client want? Usually &lt;code&gt;authorization_code&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;nonce&lt;/strong&gt;: A random value to prevent replay attacks (we'll explain this later).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;code_challenge&lt;/strong&gt; and &lt;strong&gt;code_challenge_method&lt;/strong&gt;: Extra security (PKCE — we'll get to this).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;prompt&lt;/strong&gt;: Should Google ask for authentication every time, or trust existing sessions?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;access_type&lt;/strong&gt;: Should Google provide a refresh token? (Offline vs online access)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Google checks all these parameters, authenticates you, and asks for your consent.&lt;/p&gt;
&lt;h2&gt;
  
  
  Authorization Code and State Check
&lt;/h2&gt;

&lt;p&gt;Once you authorize, Google redirects you back to the client's website. But they don't send your information directly.&lt;/p&gt;

&lt;p&gt;Instead, they send:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;authorization_code&lt;/strong&gt;: A temporary code&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;state&lt;/strong&gt;: The same state token sent earlier&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The client's server receives this callback. First thing they do? &lt;strong&gt;Check the state token&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If the state matches what they sent earlier, it's a valid request. If not, someone's trying to attack them (CSRF attack).&lt;/p&gt;

&lt;p&gt;Now they have an authorization code. But this code alone isn't enough.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why We Don't Use &lt;code&gt;response_type=token&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;You might wonder: "Why not just send the access token directly?"&lt;/p&gt;

&lt;p&gt;Some systems allow &lt;code&gt;response_type=token&lt;/code&gt;, where the provider sends the access token immediately in the URL.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This is not secure.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Why? Because the token would be visible in the browser's address bar, in logs, in history. Anyone with access to the browser could steal it.&lt;/p&gt;

&lt;p&gt;That's why the secure approach uses &lt;code&gt;authorization_code&lt;/code&gt; instead. The real tokens are exchanged server-to-server, hidden from the browser.&lt;/p&gt;
&lt;h2&gt;
  
  
  Server-to-Server Token Exchange
&lt;/h2&gt;

&lt;p&gt;Now the magic happens behind the scenes.&lt;/p&gt;

&lt;p&gt;The client's server makes a &lt;strong&gt;POST request&lt;/strong&gt; to Google's token endpoint. This happens server-to-server, completely hidden from the user's browser.&lt;/p&gt;

&lt;p&gt;They send:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;grant_type&lt;/strong&gt;: Set to &lt;code&gt;authorization_code&lt;/code&gt; (explains how they're authenticating)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;client_id&lt;/strong&gt;: Their identity&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;client_secret&lt;/strong&gt;: Their password (for authentication)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;redirect_uri&lt;/strong&gt;: For validation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;code&lt;/strong&gt;: The authorization code they just received&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;code_verifier&lt;/strong&gt;: Extra security (PKCE — hold on)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Google checks everything. If it's all valid, they respond with a JSON containing the real tokens.&lt;/p&gt;
&lt;h2&gt;
  
  
  PKCE and Why It Exists
&lt;/h2&gt;

&lt;p&gt;Let's pause here. What if a hacker somehow steals the authorization code?&lt;/p&gt;

&lt;p&gt;Think about it. The code is sent via redirect in the URL. If someone intercepts it, they could potentially exchange it for tokens.&lt;/p&gt;

&lt;p&gt;That's where &lt;strong&gt;PKCE&lt;/strong&gt; (Proof Key for Code Exchange) comes in.&lt;/p&gt;

&lt;p&gt;Here's how it works:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Before the redirect&lt;/strong&gt;, the client generates a random string (32 bytes or more). This is the &lt;code&gt;code_verifier&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;They hash it using SHA256. This becomes the &lt;code&gt;code_challenge&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;They send the &lt;code&gt;code_challenge&lt;/code&gt; and &lt;code&gt;code_challenge_method&lt;/code&gt; to Google during the initial redirect.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Google stores this hash.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Later, during the token exchange, the client sends the original &lt;code&gt;code_verifier&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Google hashes it with the same method and compares it to the stored &lt;code&gt;code_challenge&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If they match, the request is valid. If not, someone stole the code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This makes the flow nearly unbeatable.&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Tokens We Receive
&lt;/h2&gt;

&lt;p&gt;If everything checks out, Google responds with JSON containing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;access_token&lt;/strong&gt;: Used to access user information&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;refresh_token&lt;/strong&gt;: Used to get new access tokens when they expire&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;scope&lt;/strong&gt;: What information is included&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;id_token&lt;/strong&gt;: A JWT token containing user information (only with OpenID Connect)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Many providers like GitHub don't use OpenID Connect, so they might not send an &lt;code&gt;id_token&lt;/code&gt;. We'll talk about that in a moment.&lt;/p&gt;
&lt;h2&gt;
  
  
  ID Token Verification
&lt;/h2&gt;

&lt;p&gt;If we receive an &lt;code&gt;id_token&lt;/code&gt;, we need to verify it.&lt;/p&gt;

&lt;p&gt;Why? Because it's a JWT (JSON Web Token), and we need to ensure it's actually from Google and hasn't been tampered with.&lt;/p&gt;

&lt;p&gt;Here's the process:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Get Google's public JWKS (JSON Web Key Set) URI&lt;/li&gt;
&lt;li&gt;Verify the signature on the JWT using the public key&lt;/li&gt;
&lt;li&gt;Check the &lt;strong&gt;nonce&lt;/strong&gt; inside the token&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Remember that nonce we sent during the initial redirect? It comes back inside the &lt;code&gt;id_token&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We check if the nonce matches what we sent. If it does, this token was created in response to our specific request. This prevents replay attacks — someone can't reuse an old token.&lt;/p&gt;

&lt;p&gt;Now we have verified user information.&lt;/p&gt;
&lt;h2&gt;
  
  
  Getting User Info When OpenID Is Not Used
&lt;/h2&gt;

&lt;p&gt;What if the provider doesn't support OpenID Connect? (Like GitHub)&lt;/p&gt;

&lt;p&gt;No problem. We use the &lt;code&gt;access_token&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We make a simple GET request to the provider's user info endpoint with the access token in the Authorization header:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Authorization: Bearer [access_token]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The provider responds with the user's email, name, and other information we requested.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Login: User Creation and Session
&lt;/h2&gt;

&lt;p&gt;Now we have everything:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User's email&lt;/li&gt;
&lt;li&gt;User's name&lt;/li&gt;
&lt;li&gt;Verified information&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The server does a few final steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create or get user&lt;/strong&gt;: Check if this user already exists in our database. If yes, log them in. If no, create a new account.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Account linking&lt;/strong&gt;: Link this provider account to our user record.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Store tokens&lt;/strong&gt;: Save the access token and refresh token securely.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Session creation&lt;/strong&gt;: Create a session for the user.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And... done! The user is logged in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing Thoughts
&lt;/h2&gt;

&lt;p&gt;We've journeyed through a lot:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why providers like Google exist&lt;/li&gt;
&lt;li&gt;How websites register as clients&lt;/li&gt;
&lt;li&gt;What happens during redirect&lt;/li&gt;
&lt;li&gt;Security measures like state, nonce, and PKCE&lt;/li&gt;
&lt;li&gt;Token exchange behind the scenes&lt;/li&gt;
&lt;li&gt;Verification and user creation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This flow might seem complex, but each piece exists for a reason — mostly security.&lt;/p&gt;

&lt;p&gt;I've touched on many concepts here. There's even more depth to explore (like the full RFC 6749 specification at &lt;a href="https://datatracker.ietf.org/doc/rfc6749/" rel="noopener noreferrer"&gt;https://datatracker.ietf.org/doc/rfc6749/&lt;/a&gt;), but this gives you the journey from click to login.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Flow (Simplified)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User                    Client (Canva)              Provider (Google)
  |                          |                              |
  |--Click "Login" ---------&amp;gt;|                              |
  |                          |                              |
  |&amp;lt;--Redirect with params---|                              |
  |  (state, scope, client_id, nonce, code_challenge)       |
  |                                                         |
  |--Redirected to Google----------------------------------&amp;gt;|
  |                                                         |
  |&amp;lt;--Authentication &amp;amp; consent screen-----------------------|
  |                                                         |
  |--User approves-----------------------------------------&amp;gt;|
  |                                                         |
  |&amp;lt;--Redirect with code &amp;amp; state----------------------------|
  |                                                         |
  |--Return to client--------------------------------------&amp;gt;|
  |                          |                              |
  |                          |--POST request---------------&amp;gt;|
  |                          | (code, client_id,            |
  |                          |  client_secret,              |
  |                          |  code_verifier)              |
  |                          |                              |
  |                          |&amp;lt;--Tokens (access, refresh,   |
  |                          |    id_token)---------------  |
  |                          |                              |
  |                          |--Verify id_token------------&amp;gt;|
  |                          |   or fetch user info         |
  |                          |                              |
  |&amp;lt;--User logged in---------|                              |
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






</description>
      <category>webdev</category>
      <category>oauth</category>
      <category>security</category>
      <category>backend</category>
    </item>
    <item>
      <title>JWT Is Not Secure — Until You Understand JWS and JWE</title>
      <dc:creator>Nimesh Thakur</dc:creator>
      <pubDate>Sun, 28 Dec 2025 04:19:21 +0000</pubDate>
      <link>https://dev.to/toklas495/jwt-is-not-secure-until-you-understand-jws-and-jwe-124</link>
      <guid>https://dev.to/toklas495/jwt-is-not-secure-until-you-understand-jws-and-jwe-124</guid>
      <description>&lt;h2&gt;
  
  
  Start Here
&lt;/h2&gt;

&lt;p&gt;JWTs are not secure by default.&lt;/p&gt;

&lt;p&gt;They're fast. Stateless. Powerful. But easy to break if you don't understand what you're actually doing.&lt;/p&gt;

&lt;p&gt;Most developers copy-paste &lt;code&gt;jwt.verify(token, secret)&lt;/code&gt; and move on. That's where the problems start.&lt;/p&gt;

&lt;h2&gt;
  
  
  The JOSE Family
&lt;/h2&gt;

&lt;p&gt;JWT stands for JSON Web Token. It's part of JOSE: &lt;strong&gt;JSON Object Signing and Encryption&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Two things matter:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JWS (JSON Web Signature)&lt;/strong&gt; — Signs data. Anyone can read it, but tampering is detectable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JWE (JSON Web Encryption)&lt;/strong&gt; — Encrypts data. Only the recipient can read it.&lt;/p&gt;

&lt;p&gt;Most JWTs are JWS because you rarely need to hide the payload. You just need proof it hasn't been modified.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a JWT Actually Looks Like
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;eyJhbGci...  .  eyJzdWIi...  .  2Xh3n...
   header         payload      signature
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each part is base64url-encoded JSON:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HEADER              PAYLOAD              SIGNATURE
{ "alg": "HS256" }  { "sub": "user_123" }  HMAC(header + payload)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Visual breakdown:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────┐
│   HEADER    │ → Algorithm + metadata
├─────────────┤
│   PAYLOAD   │ → Your claims (readable!)
├─────────────┤
│  SIGNATURE  │ → Proof of integrity
└─────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The payload is NOT encrypted.&lt;/strong&gt; Base64 is encoding, not encryption. Anyone can decode and read it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;atob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;eyJzdWIiOiJ1c2VyXzEyMyJ9&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// {"sub":"user_123"}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The signature is what protects you. It proves the token came from someone with the key and hasn't been modified.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Header
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"alg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"HS256"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"kid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"f47ac10b-58cc-4372-a567-0e02b2c3d479"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;code&gt;alg&lt;/code&gt;&lt;/strong&gt; — How it's signed (HS256, RS256, ES256)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;kid&lt;/code&gt;&lt;/strong&gt; — Which key was used (UUID only, never a path or URL)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;jku&lt;/code&gt;&lt;/strong&gt; — URL to fetch keys (never trust this from the token)&lt;/p&gt;

&lt;p&gt;Rule: Don't make security decisions based on header values. Attackers control headers too.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Payload
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sub"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"user_5839"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"exp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1640995200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"iss"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://auth.yourapp.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"aud"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://api.yourapp.com"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;code&gt;exp&lt;/code&gt;&lt;/strong&gt; — Expiration (mandatory)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;iss&lt;/code&gt;&lt;/strong&gt; — Who issued it&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;aud&lt;/code&gt;&lt;/strong&gt; — Who it's for&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;jti&lt;/code&gt;&lt;/strong&gt; — Unique ID (for logout/blacklisting)&lt;/p&gt;

&lt;p&gt;Don't put secrets here. Passwords, API keys, SSNs—none of that belongs in a JWT.&lt;/p&gt;

&lt;h2&gt;
  
  
  When JWE Makes Sense
&lt;/h2&gt;

&lt;p&gt;JWE encrypts the payload:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;header.encrypted_key.iv.ciphertext.tag
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use it when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tokens pass through untrusted intermediaries&lt;/li&gt;
&lt;li&gt;Compliance requires encryption at rest&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Skip it when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You're using HTTPS (already encrypted in transit)&lt;/li&gt;
&lt;li&gt;You control both issuer and verifier&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most systems don't need JWE.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Security Breaks
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Algorithm Confusion
&lt;/h3&gt;

&lt;p&gt;Token says &lt;code&gt;"alg": "HS256"&lt;/code&gt; but your server expects RS256. If your code doesn't enforce the algorithm, attackers can forge tokens.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Vulnerable&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;decoded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;publicKey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The "none" Algorithm
&lt;/h3&gt;

&lt;p&gt;Token with &lt;code&gt;"alg": "none"&lt;/code&gt; and no signature. Some libraries accept this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;eyJhbGciOiJub25lIn0.eyJzdWIiOiJhZG1pbiJ9.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Trusting Headers
&lt;/h3&gt;

&lt;p&gt;Using &lt;code&gt;kid&lt;/code&gt; from the token to load keys:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"kid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"../../etc/passwd"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"kid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://attacker.com/keys"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you do &lt;code&gt;loadKey(header.kid)&lt;/code&gt; without validation, you're in trouble.&lt;/p&gt;

&lt;h3&gt;
  
  
  Skipping Claim Validation
&lt;/h3&gt;

&lt;p&gt;Verifying the signature isn't enough. You must validate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Algorithm matches what you expect&lt;/li&gt;
&lt;li&gt;Token hasn't expired&lt;/li&gt;
&lt;li&gt;Issuer is correct&lt;/li&gt;
&lt;li&gt;Audience is correct&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Fetching Keys from Untrusted URLs
&lt;/h3&gt;

&lt;p&gt;Token's &lt;code&gt;jku&lt;/code&gt; points to &lt;code&gt;https://evil.com/keys&lt;/code&gt;. Your server fetches keys from there, "verifies" the attacker's token.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Verify Correctly
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;algorithms&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;RS256&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;              &lt;span class="c1"&gt;// Hardcode this&lt;/span&gt;
  &lt;span class="na"&gt;issuer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://auth.yourapp.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Hardcode this&lt;/span&gt;
  &lt;span class="na"&gt;audience&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.yourapp.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Hardcode this&lt;/span&gt;
  &lt;span class="na"&gt;maxAge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;30m&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rules:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Explicitly set allowed algorithms&lt;/li&gt;
&lt;li&gt;Validate issuer and audience&lt;/li&gt;
&lt;li&gt;Never trust &lt;code&gt;jku&lt;/code&gt; from the token—configure JWKS URL server-side&lt;/li&gt;
&lt;li&gt;Use UUIDs for &lt;code&gt;kid&lt;/code&gt;, not paths or URLs&lt;/li&gt;
&lt;li&gt;Keep access tokens short (15-30 min)&lt;/li&gt;
&lt;li&gt;Use longer refresh tokens with revocation support&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The Mental Model
&lt;/h2&gt;

&lt;p&gt;A JWT is a signed statement.&lt;/p&gt;

&lt;p&gt;The signature proves integrity and authenticity. It doesn't prove the token should be accepted.&lt;/p&gt;

&lt;p&gt;You decide that by validating the claims.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thought
&lt;/h2&gt;

&lt;p&gt;Tools don't fail. Understanding fails.&lt;/p&gt;

&lt;p&gt;Most JWT vulnerabilities come from trusting input you shouldn't trust or skipping validation you should enforce.&lt;/p&gt;

&lt;p&gt;Configure strictly. Validate everything. Never assume the library handles security for you.&lt;/p&gt;

&lt;p&gt;The difference between safe and broken is understanding what the signature actually proves.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Reference: RFC 7515 (JWS), RFC 7516 (JWE), RFC 7519 (JWT)&lt;/em&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>security</category>
      <category>backend</category>
      <category>webdev</category>
    </item>
    <item>
      <title>When Sleep Became a Problem</title>
      <dc:creator>Nimesh Thakur</dc:creator>
      <pubDate>Thu, 25 Dec 2025 09:32:09 +0000</pubDate>
      <link>https://dev.to/toklas495/when-sleep-became-a-problem-17j1</link>
      <guid>https://dev.to/toklas495/when-sleep-became-a-problem-17j1</guid>
      <description>&lt;p&gt;Sleep was a nightmare for me once.&lt;/p&gt;

&lt;p&gt;Not the kind where you wake up scared.&lt;br&gt;&lt;br&gt;
The kind where you're scared to fall asleep.&lt;/p&gt;

&lt;p&gt;This is what happened. And what I learned.&lt;/p&gt;




&lt;h2&gt;
  
  
  It Started in 9th Class
&lt;/h2&gt;

&lt;p&gt;I don't know what triggered it.&lt;/p&gt;

&lt;p&gt;I was just... tense. Worried about nothing specific. My mind felt busy even when idle.&lt;/p&gt;

&lt;p&gt;Then one night, something strange happened.&lt;/p&gt;




&lt;h2&gt;
  
  
  What It Felt Like
&lt;/h2&gt;

&lt;p&gt;I fell asleep. But only my body did.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What happened:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;My eyes stayed open&lt;/li&gt;
&lt;li&gt;My ears kept working
&lt;/li&gt;
&lt;li&gt;My mind was fully awake&lt;/li&gt;
&lt;li&gt;My body was completely frozen&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I could see my room. Hear everything around me. But I couldn't move. Not my hand. Not my legs. Nothing.&lt;/p&gt;

&lt;p&gt;My brain tried to make sense of it. When your mind can't explain something, it fills in the gaps. Creates shapes. Presences. Things that feel real because you're seeing them with open eyes.&lt;/p&gt;

&lt;p&gt;I thought: "This is a dream."&lt;br&gt;&lt;br&gt;
Then I realized: "This isn't a dream."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;That was the scary part.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Pattern (9th to 12th Class)
&lt;/h2&gt;

&lt;p&gt;This became my daily routine:&lt;/p&gt;

&lt;h3&gt;
  
  
  At Night:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;First sleep: 2-3 minutes&lt;/li&gt;
&lt;li&gt;Paralysis would happen&lt;/li&gt;
&lt;li&gt;After that: normal sleep&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Afternoon Naps:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Worse&lt;/li&gt;
&lt;li&gt;Lasted 2 to 15 minutes&lt;/li&gt;
&lt;li&gt;Same experience every time&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Hardest Part:
&lt;/h3&gt;

&lt;p&gt;Most people don't know when they fall asleep.&lt;br&gt;&lt;br&gt;
They just... disappear into it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I knew. Every single time.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It felt like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Going deeper and deeper into my own mind&lt;/li&gt;
&lt;li&gt;Like something drilling inward&lt;/li&gt;
&lt;li&gt;Then suddenly: silence&lt;/li&gt;
&lt;li&gt;Then: frozen&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  When Awareness Became Too Much
&lt;/h2&gt;

&lt;p&gt;During army training in Uttarakhand, I started noticing something.&lt;/p&gt;

&lt;p&gt;I watched how others slept:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;They lay down&lt;/li&gt;
&lt;li&gt;They disappeared
&lt;/li&gt;
&lt;li&gt;They woke up&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Simple. No drama.&lt;/p&gt;

&lt;h3&gt;
  
  
  My Experience Was Different:
&lt;/h3&gt;

&lt;p&gt;I was aware of &lt;em&gt;everything&lt;/em&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Going into sleep&lt;/li&gt;
&lt;li&gt;Being in sleep
&lt;/li&gt;
&lt;li&gt;Coming out of sleep&lt;/li&gt;
&lt;li&gt;Even my own breathing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I could hear myself snore. Feel my breathing stop for a second. Then air rushing through my mouth with sound.&lt;/p&gt;

&lt;p&gt;I researched it. Found out it's normal:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Muscles relax during sleep&lt;/li&gt;
&lt;li&gt;They block airflow briefly&lt;/li&gt;
&lt;li&gt;You push air through&lt;/li&gt;
&lt;li&gt;Creates sound&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;But being aware of everything while sleeping isn't peaceful.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It's like standing at a door instead of walking through it.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Figured Out
&lt;/h2&gt;

&lt;p&gt;The problem wasn't sleep.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The problem was my mind not knowing how to let go.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Normal sleep = trust and let go&lt;br&gt;&lt;br&gt;
My sleep = watch everything, stay alert&lt;/p&gt;

&lt;p&gt;I couldn't rest because I wouldn't stop observing.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Actually Helped
&lt;/h2&gt;

&lt;p&gt;After 12th, I started reading. Philosophy. Meditation. Yoga.&lt;/p&gt;

&lt;p&gt;Not to "fix" sleep.&lt;br&gt;&lt;br&gt;
To understand what was happening.&lt;/p&gt;

&lt;h3&gt;
  
  
  What I Learned:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;How sleep works:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Brain paralyzes your body during sleep&lt;/li&gt;
&lt;li&gt;This is normal&lt;/li&gt;
&lt;li&gt;Prevents you from acting out dreams&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What wasn't normal:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;My awareness staying on during paralysis&lt;/li&gt;
&lt;li&gt;Fear keeping me alert&lt;/li&gt;
&lt;li&gt;Creating a loop&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The real issue:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stressed mind&lt;/li&gt;
&lt;li&gt;Too much pressure&lt;/li&gt;
&lt;li&gt;Fear feeding more fear&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What Changed:
&lt;/h3&gt;

&lt;p&gt;Meditation taught me something simple:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to stay calm while being aware.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not fighting awareness.&lt;br&gt;&lt;br&gt;
Not fighting fear.&lt;br&gt;&lt;br&gt;
Just... being okay with both.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The result:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Less fear = fewer episodes&lt;/li&gt;
&lt;li&gt;Less tension = easier sleep&lt;/li&gt;
&lt;li&gt;Eventually: it just faded&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No dramatic ending. Just gradual peace.&lt;/p&gt;




&lt;h2&gt;
  
  
  Looking Back
&lt;/h2&gt;

&lt;p&gt;Those experiences weren't my enemy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;They were signals.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Signals that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;My mind was under pressure&lt;/li&gt;
&lt;li&gt;I was holding too tight&lt;/li&gt;
&lt;li&gt;I didn't trust rest&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I didn't beat sleep by fighting it.&lt;br&gt;&lt;br&gt;
I understood what was really happening.&lt;/p&gt;




&lt;h2&gt;
  
  
  What This Taught Me
&lt;/h2&gt;

&lt;p&gt;Some problems don't go away when you force them.&lt;/p&gt;

&lt;p&gt;They go away when you understand them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The difference:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fighting vs. understanding&lt;/li&gt;
&lt;li&gt;Controlling vs. allowing
&lt;/li&gt;
&lt;li&gt;Staying tense vs. learning to release&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This applies to more than just sleep.&lt;/p&gt;




&lt;h2&gt;
  
  
  Today
&lt;/h2&gt;

&lt;p&gt;Sleep is normal now.&lt;/p&gt;

&lt;p&gt;Not perfect. Just normal.&lt;/p&gt;

&lt;p&gt;And normal feels like a gift.&lt;/p&gt;




&lt;h2&gt;
  
  
  One Last Thing
&lt;/h2&gt;

&lt;p&gt;We live in a world that values control.&lt;/p&gt;

&lt;p&gt;Productivity. Optimization. Awareness of everything.&lt;/p&gt;

&lt;p&gt;But sometimes the answer isn't more control.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sometimes it's less.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Rest isn't something you force.&lt;br&gt;&lt;br&gt;
It's something you allow.&lt;/p&gt;

&lt;p&gt;The deepest healing begins not when fear ends —&lt;br&gt;&lt;br&gt;
but when understanding begins.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This is a personal experience, not medical advice. If you're experiencing something similar, talk to a professional.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>mentalhealth</category>
      <category>productivity</category>
      <category>discuss</category>
      <category>motivation</category>
    </item>
    <item>
      <title>The Day I Stopped Chasing Everything and Found My One Thing</title>
      <dc:creator>Nimesh Thakur</dc:creator>
      <pubDate>Sun, 21 Dec 2025 02:49:00 +0000</pubDate>
      <link>https://dev.to/toklas495/the-day-i-stopped-chasing-everything-and-found-my-one-thing-2o97</link>
      <guid>https://dev.to/toklas495/the-day-i-stopped-chasing-everything-and-found-my-one-thing-2o97</guid>
      <description>&lt;p&gt;So let me tell you a story. It's mine, but honestly, it might be yours too.&lt;/p&gt;

&lt;p&gt;When I was a kid, I used to draw cars and bikes all day. Like, REALLY draw them. Every detail. The curves, the engines, the wheels. I'd sit there for hours just sketching, and I thought to myself, "Yeah, this is it. I'm going to be a car designer." That was the plan. That was my passion. Or so I thought.&lt;/p&gt;

&lt;p&gt;Then 9th class happened.&lt;/p&gt;

&lt;p&gt;I don't know what got into me, but suddenly I was obsessed with the army. I'd watch these videos of Para Commandos and think, "Forget cars, man. I want to do THIS." Me and my best friend, we got serious about it. We trained for 4 months straight. Physical training, studying, the whole deal. We were ready for NDA. We were PUMPED.&lt;/p&gt;

&lt;p&gt;And then... we didn't get selected. Neither of us.&lt;/p&gt;

&lt;p&gt;That hurt. But we didn't give up completely. We figured, okay, let's do BTech. At least then we'll have a shot at CDS or technical entry later. We chose Cyber Security as our specialization. Made sense, right? Technical degree, still a path to the army if we wanted it.&lt;/p&gt;

&lt;p&gt;But here's where things get weird.&lt;/p&gt;

&lt;p&gt;I'm sitting there in this Cyber Security program, and I'm thinking, "If I'm learning this stuff anyway, why not actually TRY this field?" So I decided to pick up coding. First language? Java. And I picked Java for the dumbest reason possible - I didn't know how to set up VSCode, Python, or C++. But Java? Java just... worked. First try. So I went with it.&lt;/p&gt;

&lt;p&gt;I dove into Java. Learned data structures and algorithms. Did all the problems. And honestly? I didn't enjoy it. At all. But I kept going because, you know, that's what you're supposed to do, right?&lt;/p&gt;

&lt;p&gt;Then I tried web development. That was a bit better. Then app development - and oh man, I thought THIS was it. This was my calling. I could see myself building apps, creating cool stuff. I was so excited.&lt;/p&gt;

&lt;p&gt;Until I tried to open Android Studio on my 4GB Dell Inspiron laptop.&lt;/p&gt;

&lt;p&gt;The laptop literally couldn't handle it. It was like watching a car trying to fly. Just... no. Dream over.&lt;/p&gt;

&lt;p&gt;So I moved on to computer networks. And you know what? I actually enjoyed this one. Learning about Wireshark, tcpdump, tracing packets, monitoring network traffic - it was interesting. I was learning real stuff that made sense.&lt;/p&gt;

&lt;p&gt;Then I discovered binary pentesting. I read this book called "Hacker: The Art of Exploitation" and my mind was blown. Stack, heap, buffer overflow, format string vulnerabilities, shellcode - all this deep technical stuff that most people never touch. I was hooked.&lt;/p&gt;

&lt;p&gt;And that led me to web pentesting. THIS, I thought, was my passion. Finally. I'd found it.&lt;/p&gt;

&lt;p&gt;I went deep. Like, REALLY deep. I was reading books non-stop - I must have read 60+ books during this whole journey. Everything from hacking to web security to penetration testing. I learned Burp Suite, PortSwigger Academy, HackTheBox, Caido, subfinder, amass, and probably 500 other tools. GitHub became my second home because I was git cloning new tools every single day. I got so familiar with Git that I could probably do it in my sleep.&lt;/p&gt;

&lt;p&gt;I even started building my own tools. I dropped JavaScript and went all in on Python and Bash for scripting. I became really good at it. Like, damn good. I could automate anything, build anything. I felt powerful.&lt;/p&gt;

&lt;p&gt;Then came bug bounty hunting.&lt;/p&gt;

&lt;p&gt;I loved the idea. No degree required, no certification needed - just find bugs in real systems and get paid. It was perfect. Or so I thought.&lt;/p&gt;

&lt;p&gt;I spent 6 to 7 months grinding. And I mean GRINDING. I found 50+ bugs. Fifty bugs. You know how many were accepted? One. Just one. A rate limit bypass in Yatra.com.&lt;/p&gt;

&lt;p&gt;They paid me $50.&lt;/p&gt;

&lt;p&gt;Fifty dollars for half a year of work.&lt;/p&gt;

&lt;p&gt;I burned out. Completely. I was exhausted, frustrated, and questioning everything. But during that burnout, I had this idea. What if there was one platform where every hacker could share resources, tools, ideas, strategies - everything in one place? A single platform for the entire community.&lt;/p&gt;

&lt;p&gt;I didn't know backend development, but I thought, "Why not give it a shot?" I called my friend who knew frontend, and I told him I'd handle the backend. So I learned backend development. I read books about Node.js, design patterns, data structures - all of it. And I actually built the application.&lt;/p&gt;

&lt;p&gt;Then I did something bold. I reached out to some of the biggest names in hacking - Samcurry, Nahamsec, Gareth Heyes - probably messaged around 500 hackers in total. I wanted to know if this idea could work.&lt;/p&gt;

&lt;p&gt;Out of 500, one person replied. Gareth Heyes.&lt;/p&gt;

&lt;p&gt;He said, "It's impossible to get all hackers to contribute to one single platform."&lt;/p&gt;

&lt;p&gt;And that was it. The dream died right there.&lt;/p&gt;

&lt;p&gt;But here's the thing - while building that backend, I noticed something. Something I couldn't ignore.&lt;/p&gt;

&lt;p&gt;I LOVED building authentication and authorization systems. Not the entire backend. Just auth. The flows, the security models, the system design, all those tiny intricate details that most people don't even think about. I could spend hours designing auth flows and not even notice the time passing. My friend, the one doing frontend? He didn't get it. He couldn't understand why I was so obsessed with these details.&lt;/p&gt;

&lt;p&gt;But I did. I saw it all clearly.&lt;/p&gt;

&lt;p&gt;And that's when it hit me.&lt;/p&gt;

&lt;p&gt;You know how in nature, every animal has ONE thing they're great at? A lion has its teeth. An eagle has its claws. An elephant has its trunk. A peacock has its tail. Nobody has everything. Each creature has one unique strength.&lt;/p&gt;

&lt;p&gt;Even if you look at gods - Shiva is the destroyer, Brahma is the creator, Vishnu is the preserver. Each one has their role. Their ONE thing.&lt;/p&gt;

&lt;p&gt;Bruce Lee said something that stuck with me: "I don't fear the man who has practiced 10,000 kicks. I fear the man who has practiced one kick 10,000 times."&lt;/p&gt;

&lt;p&gt;And I realized - I'd been trying to practice 10,000 kicks this whole time.&lt;/p&gt;

&lt;p&gt;Look at my journey: Car designer → Army → Java → DSA → Web Development → App Development → Networks → Binary Pentesting → Web Pentesting → Bug Bounty → Backend Development → Authentication &amp;amp; Authorization.&lt;/p&gt;

&lt;p&gt;I kept compressing. Narrowing down. Moving toward something, not away from things. And I didn't even realize it until that moment.&lt;/p&gt;

&lt;p&gt;But here's where the real battle started - the battle between my mind and my heart.&lt;/p&gt;

&lt;p&gt;My mind kept telling me: "Bro, focus on DSA. Learn the full backend stack. Be practical. Get any job. Everyone says you need to know everything."&lt;/p&gt;

&lt;p&gt;But my heart was saying: "You light up when you work on auth. That's your signal."&lt;/p&gt;

&lt;p&gt;And I kept thinking about Arjun from the Mahabharata. You know that story, right? Where Dronacharya asks all his students what they see when aiming at a bird on a tree. Everyone describes the whole scene - the bird, the tree, the branches, the sky.&lt;/p&gt;

&lt;p&gt;But Arjun? Arjun says, "I see only the eye of the bird."&lt;/p&gt;

&lt;p&gt;That's when I made my decision.&lt;/p&gt;

&lt;p&gt;Authentication and Authorization is my bird's eye. That's my one thing. I don't need to be a full-stack developer. I don't need to master DevOps, or frontend frameworks, or database administration. I need to go so deep into this ONE thing that when people think about auth, they think of me.&lt;/p&gt;

&lt;p&gt;So that's what I'm doing now. I'm practicing authentication and authorization every single day. I'm aiming for IAM roles, AuthN/AuthZ specialist positions. Is it risky? Maybe. Is it conventional? Not at all. But here's what I know for sure:&lt;/p&gt;

&lt;p&gt;The world doesn't need another developer who knows a little bit of everything. The world needs people who go DEEP. Who become THE person for one specific thing.&lt;/p&gt;

&lt;p&gt;And that's the earth fact nobody tells you - nobody masters everything. Nobody CAN master everything. And that's not a weakness. That's actually your freedom. Freedom to say "this is my thing" and ignore all the noise telling you to learn more, do more, be more.&lt;/p&gt;

&lt;p&gt;So if you're reading this and you're jumping between technologies, feeling scattered, wondering if you should add "just one more skill" to your resume... stop for a second.&lt;/p&gt;

&lt;p&gt;Ask yourself: What do you keep coming back to? What makes you lose track of time? What do your friends not understand but you see with complete clarity?&lt;/p&gt;

&lt;p&gt;That's your signal. That's your one thing.&lt;/p&gt;

&lt;p&gt;Go practice that one kick 10,000 times.&lt;/p&gt;

&lt;p&gt;Trust me, it's worth it.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;What's your one thing? I'd genuinely love to hear about it in the comments.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cybersecurity</category>
      <category>career</category>
      <category>webdev</category>
      <category>developers</category>
    </item>
    <item>
      <title>I Crashed My Server with Promise.all() - Here's How I Built a 121 RPS Fuzzer Instead</title>
      <dc:creator>Nimesh Thakur</dc:creator>
      <pubDate>Sun, 14 Dec 2025 04:21:52 +0000</pubDate>
      <link>https://dev.to/toklas495/i-crashed-my-server-with-promiseall-heres-how-i-built-a-121-rps-fuzzer-instead-32ob</link>
      <guid>https://dev.to/toklas495/i-crashed-my-server-with-promiseall-heres-how-i-built-a-121-rps-fuzzer-instead-32ob</guid>
      <description>&lt;h2&gt;
  
  
  The Journey of Making 404fuzz Blazingly Fast ⚡
&lt;/h2&gt;

&lt;p&gt;When I started building &lt;a href="https://github.com/toklas495/404fuzz" rel="noopener noreferrer"&gt;404fuzz&lt;/a&gt;, I had one goal: &lt;strong&gt;make it fast&lt;/strong&gt;. Really fast. But I quickly learned that speed in Node.js isn't just about throwing more requests at a server. It's about understanding how Node.js &lt;em&gt;actually&lt;/em&gt; works.&lt;/p&gt;

&lt;p&gt;Let me take you on the journey from my first "obvious" solution to a fuzzer that achieves &lt;strong&gt;121 RPS&lt;/strong&gt; on modest hardware.&lt;/p&gt;




&lt;h2&gt;
  
  
  Chapter 1: The Promise.all() Trap 🪤
&lt;/h2&gt;

&lt;h3&gt;
  
  
  My First Thought
&lt;/h3&gt;

&lt;p&gt;"Easy! I'll just load all my wordlist paths and fire them all at once with &lt;code&gt;Promise.all()&lt;/code&gt;!"&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// My first naive approach&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;wordlist&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;admin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;backup&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;config&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...];&lt;/span&gt; &lt;span class="c1"&gt;// 10,000 paths&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;promises&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;wordlist&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;promises&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Fire everything!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Brutal Reality
&lt;/h3&gt;

&lt;p&gt;This crashed everything. My laptop froze. The target server probably hated me. &lt;strong&gt;What went wrong?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here's what I learned: &lt;strong&gt;Promise.all() is NOT parallel execution.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Understanding Node.js: Concurrent, Not Parallel 🔄
&lt;/h2&gt;

&lt;p&gt;Let me explain with a diagram:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────────────────────┐
│          Node.js Single Thread                  │
├─────────────────────────────────────────────────┤
│                                                 │
│  Your Code (Asynchronous)                        │
│         ↓                                       │
│  Event Demultiplexer (Receives all events)     │
│         ↓                                       │
│  Event Queue [Event1, Event2, Event3, ...]     │
│         ↓                                       │
│  Event Loop (while(queue.length &amp;gt; 0))          │
│    ├─ Takes Event1                             │
│    ├─ Executes Callback                        │
│    ├─ Returns immediately (non-blocking!)      │
│    └─ Takes Event2...                          │
│                                                 │
└─────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; Node.js is &lt;strong&gt;concurrent&lt;/strong&gt; (non-blocking), not &lt;strong&gt;parallel&lt;/strong&gt; (multiple things at once).&lt;/p&gt;

&lt;p&gt;When you do &lt;code&gt;Promise.all()&lt;/code&gt; with 10,000 requests:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;❌ You don't get 10,000 parallel threads&lt;/li&gt;
&lt;li&gt;❌ You DO get 10,000 open connections&lt;/li&gt;
&lt;li&gt;❌ You DO consume massive memory&lt;/li&gt;
&lt;li&gt;❌ You DO overwhelm both your system and the target&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt; System crash, memory exhaustion, or you become an accidental DDoS attacker.&lt;/p&gt;




&lt;h2&gt;
  
  
  Chapter 2: The Queue Model - Controlled Chaos 🎯
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Better Approach
&lt;/h3&gt;

&lt;p&gt;I needed &lt;strong&gt;bounded concurrency&lt;/strong&gt; - control how many requests run at once, queue the rest.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌────────────────────────────────────────┐
│      Wordlist (10,000 paths)           │
└────────────┬───────────────────────────┘
             ↓
┌────────────────────────────────────────┐
│         Request Queue                  │
│  [req1, req2, req3, req4, req5, ...]   │
└────────────┬───────────────────────────┘
             ↓
┌────────────────────────────────────────┐
│    Concurrency Limit (e.g., 50)       │
│                                        │
│  [Active1] [Active2] ... [Active50]   │
│      ↓          ↓            ↓         │
│   Response  Response     Response      │
│      ↓          ↓            ↓         │
│  Next from queue (req51)               │
└────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Implementation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RequestQueue&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;concurrency&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;concurrency&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;concurrency&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;running&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;queue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// If we're at limit, queue it&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;running&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;concurrency&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;queue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;running&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;task&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;running&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="c1"&gt;// Release next queued task&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;queue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resolve&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;queue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shift&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Results
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;✅ Memory stays stable&lt;/li&gt;
&lt;li&gt;✅ Target server doesn't die&lt;/li&gt;
&lt;li&gt;✅ Predictable resource usage&lt;/li&gt;
&lt;li&gt;✅ You can tune with &lt;code&gt;-t&lt;/code&gt; flag (concurrency level)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;But I wanted MORE speed.&lt;/strong&gt; Time for the next level.&lt;/p&gt;




&lt;h2&gt;
  
  
  Chapter 3: Multi-Core Power - The Cluster Model 💪
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Problem
&lt;/h3&gt;

&lt;p&gt;Node.js is single-threaded. My i5 processor has 8 cores. I'm using only &lt;strong&gt;12.5%&lt;/strong&gt; of my CPU!&lt;/p&gt;

&lt;h3&gt;
  
  
  The Solution: Node.js Cluster Module
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────────────────────┐
│            Primary Process (Master)             │
│                                                 │
│  - Loads wordlist                               │
│  - Splits work among workers                    │
│  - Collects results                             │
└────────────┬───────────────────────┬────────────┘
             │                       │
      ┌──────┴──────┐         ┌──────┴──────┐
      ↓             ↓         ↓             ↓
┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────┐
│ Worker 1 │  │ Worker 2 │  │ Worker 3 │  │ Worker 4 │
│          │  │          │  │          │  │          │
│  Queue   │  │  Queue   │  │  Queue   │  │  Queue   │
│  Model   │  │  Model   │  │  Model   │  │  Model   │
│  (-t 10) │  │  (-t 10) │  │  (-t 10) │  │  (-t 10) │
└──────────┘  └──────────┘  └──────────┘  └──────────┘
     ↓             ↓              ↓             ↓
   Target       Target         Target        Target
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Implementation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Primary process&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isPrimary&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;numWorkers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getCoreCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cores&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// -c flag&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;workload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;splitWordlist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;wordlist&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;numWorkers&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;numWorkers&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;worker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fork&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;workload&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="na"&gt;concurrency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;threads&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Worker process&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isWorker&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;paths&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;concurrency&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;queue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;RequestQueue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;concurrency&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;paths&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;queue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;fuzzPath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Chapter 4: The Sweet Spot - Balancing Act ⚖️
&lt;/h2&gt;

&lt;p&gt;Here's where it gets interesting. &lt;strong&gt;More workers ≠ More speed&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Complexity
&lt;/h3&gt;

&lt;p&gt;You're now balancing TWO variables:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Clusters (&lt;code&gt;-c&lt;/code&gt;)&lt;/strong&gt;: Number of worker processes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Concurrency (&lt;code&gt;-t&lt;/code&gt;)&lt;/strong&gt;: Requests per worker&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What I Discovered
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Configuration              RPS     Why?
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
-c 8  -t 2                 ~65     Too much IPC overhead
-c 4  -t 5                 ~95     Better balance
-c 2  -t 10               ~121     SWEET SPOT! ⭐
-c 1  -t 20                ~85     Bottlenecked by single process
-c all -t 20              ~70     IPC kills performance
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The Pattern:&lt;/strong&gt; Fewer workers + higher concurrency = faster!&lt;/p&gt;

&lt;h3&gt;
  
  
  Why?
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Fewer Workers (e.g., -c 2):
┌──────────────┐
│   Worker 1   │───┐
│   -t 10      │   │  Less communication
│   (10 reqs)  │   ├─&amp;gt; overhead between
└──────────────┘   │  processes
                   │
┌──────────────┐   │
│   Worker 2   │───┘
│   -t 10      │
│   (10 reqs)  │
└──────────────┘

More Workers (e.g., -c 8):
┌────────┐┌────────┐┌────────┐┌────────┐
│Worker 1││Worker 2││Worker 3││Worker 4│
│ -t 2   ││ -t 2   ││ -t 2   ││ -t 2   │
└───┬────┘└───┬────┘└───┬────┘└───┬────┘
    │         │         │         │
    └─────────┴─────────┴─────────┘
         High IPC (Inter-Process
         Communication) overhead!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Chapter 5: Putting It All Together 🎯
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Final Architecture
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌───────────────────────────────────────────────┐
│         404fuzz Primary Process                │
│                                                │
│  1. Load wordlist                              │
│  2. Parse target &amp;amp; options                     │
│  3. Calculate optimal worker count (-c flag)   │
│  4. Split wordlist into chunks                 │
│  5. Spawn workers                              │
└────────────┬──────────────────────────────────┘
             │
      ┌──────┴──────┐
      ↓             ↓
┌─────────────┐  ┌─────────────┐
│  Worker 1   │  │  Worker 2   │
│             │  │             │
│  ┌────────┐ │  │  ┌────────┐ │
│  │ Queue  │ │  │  │ Queue  │ │
│  │ Model  │ │  │  │ Model  │ │
│  │ (-t N) │ │  │  │ (-t N) │ │
│  └───┬────┘ │  │  └───┬────┘ │
│      ↓      │  │      ↓      │
│   [10 reqs] │  │   [10 reqs] │
└──────┬──────┘  └──────┬──────┘
       ↓                ↓
     Target          Target
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Usage Examples
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Fast &amp;amp; balanced (recommended)&lt;/span&gt;
404fuzz  https://target.com &lt;span class="nt"&gt;-w&lt;/span&gt; wordlist.txt &lt;span class="nt"&gt;-c&lt;/span&gt; 2 &lt;span class="nt"&gt;-t&lt;/span&gt; 10

&lt;span class="c"&gt;# Maximum concurrency, fewer workers&lt;/span&gt;
404fuzz  https://target.com &lt;span class="nt"&gt;-w&lt;/span&gt; wordlist.txt &lt;span class="nt"&gt;-c&lt;/span&gt; half &lt;span class="nt"&gt;-t&lt;/span&gt; 20

&lt;span class="c"&gt;# Use all cores (not always faster!)&lt;/span&gt;
404fuzz  https://target.com &lt;span class="nt"&gt;-w&lt;/span&gt; wordlist.txt &lt;span class="nt"&gt;-c&lt;/span&gt; all &lt;span class="nt"&gt;-t&lt;/span&gt; 5

&lt;span class="c"&gt;# Single core for testing&lt;/span&gt;
404fuzz  https://target.com &lt;span class="nt"&gt;-w&lt;/span&gt; wordlist.txt &lt;span class="nt"&gt;-c&lt;/span&gt; 1 &lt;span class="nt"&gt;-t&lt;/span&gt; 50
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  The Results 📊
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Hardware:&lt;/strong&gt; Dell 7290, i5 8th Gen, 8GB RAM, 256GB SSD&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Performance:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Peak RPS: &lt;strong&gt;121 requests/second&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Memory usage: Stable (~200-300MB)&lt;/li&gt;
&lt;li&gt;CPU usage: Efficient (50-60% on 2 cores)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Comparison:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Approach                    RPS    Memory   Crashed?
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Promise.all() (naive)       N/A    &amp;gt;2GB     YES 💥
Queue only (single core)    ~45    ~150MB   No
Queue + Cluster (optimal)   ~121   ~250MB   No ✅
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Key Takeaways 🎓
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Node.js is concurrent, not parallel&lt;/strong&gt; - Understanding the event loop is crucial&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unbounded concurrency is dangerous&lt;/strong&gt; - Always implement a queue with limits&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;More workers ≠ better performance&lt;/strong&gt; - IPC overhead is real&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sweet spot exists&lt;/strong&gt; - Fewer workers + higher concurrency often wins&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Experimentation is key&lt;/strong&gt; - Every system is different, test your configs!&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Try 404fuzz Yourself
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Clone the repository&lt;/span&gt;
git clone https://github.com/toklas495/404fuzz.git
&lt;span class="nb"&gt;cd &lt;/span&gt;404fuzz

&lt;span class="c"&gt;# Install dependencies&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt;

&lt;span class="c"&gt;# Build and link globally&lt;/span&gt;
npm run build

&lt;span class="c"&gt;# Verify installation&lt;/span&gt;
404fuzz

&lt;span class="c"&gt;# Start fuzzing with recommended settings&lt;/span&gt;
404fuzz https://target.com/FUZZ &lt;span class="nt"&gt;-w&lt;/span&gt; /path/to/wordlist.txt &lt;span class="nt"&gt;-c&lt;/span&gt; 2 &lt;span class="nt"&gt;-t&lt;/span&gt; 10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;⭐ &lt;a href="https://github.com/toklas495/404fuzz" rel="noopener noreferrer"&gt;GitHub Repository&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What's Next?
&lt;/h2&gt;

&lt;p&gt;Now that we've achieved speed, the next step is adding &lt;strong&gt;intelligence&lt;/strong&gt; - making 404fuzz learn from responses, adapt its strategies, and discover paths smarter, not just faster.&lt;/p&gt;

&lt;p&gt;But that's a story for another blog post. 😉&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built with ❤️ and lots of trial &amp;amp; error. If this helped you understand Node.js concurrency better, drop a ⭐ on the repo!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>node</category>
      <category>tooling</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Building 404fuzz: A Multi-Core Fuzzer That Never Gets Tired</title>
      <dc:creator>Nimesh Thakur</dc:creator>
      <pubDate>Sat, 06 Dec 2025 06:35:44 +0000</pubDate>
      <link>https://dev.to/toklas495/building-404fuzz-a-multi-core-fuzzer-that-never-gets-tired-hk4</link>
      <guid>https://dev.to/toklas495/building-404fuzz-a-multi-core-fuzzer-that-never-gets-tired-hk4</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Most people think fuzzers are just “tools that send fast requests.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That’s true.&lt;/p&gt;

&lt;p&gt;But building a &lt;strong&gt;fuzzer that is fast, memory-safe, multi-core, stream-based, and developer-friendly&lt;/strong&gt; is a completely different challenge.&lt;/p&gt;

&lt;p&gt;This is the story of how &lt;strong&gt;404fuzz&lt;/strong&gt; was born — not from copying ffuf — but from &lt;strong&gt;real hacking pain, real performance problems, and real engineering trade-offs&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 The Problem That Started Everything
&lt;/h2&gt;

&lt;p&gt;As a bug bounty hunter, I faced the same issue again and again:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📂 Huge wordlists (millions of lines)&lt;/li&gt;
&lt;li&gt;🐌 Tools eating RAM&lt;/li&gt;
&lt;li&gt;💥 Crashes on large scans&lt;/li&gt;
&lt;li&gt;🧠 Too many duplicate responses&lt;/li&gt;
&lt;li&gt;⚠️ Rate-limit (429) killing scans&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;🧱 Tools that were either:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;too dumb&lt;/li&gt;
&lt;li&gt;or too heavy like a scanner&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;I didn’t want:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Another Burp&lt;/li&gt;
&lt;li&gt;Another Nuclei&lt;/li&gt;
&lt;li&gt;Another slow Python fuzzer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I wanted:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;✅ A &lt;strong&gt;dumb but insanely fast fuzzer&lt;/strong&gt;, with just enough intelligence to save my time.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That’s how &lt;strong&gt;404fuzz&lt;/strong&gt; started.&lt;/p&gt;




&lt;h2&gt;
  
  
  🐜 Philosophy of 404fuzz
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;“Like an ant, 404fuzz never gets tired.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;404fuzz follows only &lt;strong&gt;three core rules&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;⚡ &lt;strong&gt;Speed is non-negotiable&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;🧩 &lt;strong&gt;Memory safety comes first&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;🎯 &lt;strong&gt;Hunter decides what’s interesting — not the tool&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;❌ No heavy “AI logic”&lt;/li&gt;
&lt;li&gt;❌ No scanning rules&lt;/li&gt;
&lt;li&gt;❌ No auto-vulnerability detection&lt;/li&gt;
&lt;li&gt;✅ Just &lt;strong&gt;pure high-performance fuzzing&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ⚙️ How 404fuzz Actually Works (Internals)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ✅ 1. Streaming Wordlist (No Memory Bombs)
&lt;/h3&gt;

&lt;p&gt;Instead of loading the entire wordlist into memory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;streamWordlist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;workerId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;totalWorkers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="k"&gt;await &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;line&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;rl&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;totalWorkers&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;workerId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can fuzz with &lt;strong&gt;million-line wordlists&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;RAM stays stable&lt;/li&gt;
&lt;li&gt;Each worker gets its &lt;strong&gt;own shard&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  ✅ 2. Concurrency Without Promise.all Memory Leaks
&lt;/h3&gt;

&lt;p&gt;Instead of doing this ❌:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;404fuzz uses a &lt;strong&gt;real queue-based concurrency model&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FuzzQueue&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;concurrency&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;running&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;queue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;running&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;concurrency&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;queue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;running&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;task&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;running&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;queue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;queue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shift&lt;/span&gt;&lt;span class="p"&gt;()();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Stable memory&lt;/li&gt;
&lt;li&gt;✅ Controlled throughput&lt;/li&gt;
&lt;li&gt;✅ No unhandled promise explosions&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  ✅ 3. Multi-Core Parallelism with Cluster
&lt;/h3&gt;

&lt;p&gt;404fuzz doesn’t fake performance with async only.&lt;/p&gt;

&lt;p&gt;It uses:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Node.js cluster&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;One worker per CPU core&lt;/li&gt;
&lt;li&gt;Automatic wordlist sharding&lt;/li&gt;
&lt;li&gt;Real RPS aggregation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is why 404fuzz scales like ffuf.&lt;/p&gt;




&lt;h3&gt;
  
  
  ✅ 4. Live Dashboard (Like htop, but for Fuzzing)
&lt;/h3&gt;

&lt;p&gt;Real-time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;RPS&lt;/li&gt;
&lt;li&gt;Progress&lt;/li&gt;
&lt;li&gt;ETA&lt;/li&gt;
&lt;li&gt;Error rates&lt;/li&gt;
&lt;li&gt;Worker stats&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No log spam.&lt;br&gt;
No blind fuzzing.&lt;/p&gt;




&lt;h2&gt;
  
  
  🎯 What 404fuzz Is (And Is Not)
&lt;/h2&gt;

&lt;p&gt;✅ IS:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;fast fuzzer&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;research tool&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;behavioral explorer&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;payload testing engine&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;❌ IS NOT:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A vulnerability scanner&lt;/li&gt;
&lt;li&gt;A Burp replacement&lt;/li&gt;
&lt;li&gt;A rule-based exploitation engine&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;404fuzz will always stay a &lt;strong&gt;fuzzer first&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 The Real Pain: 70% Duplicate Responses
&lt;/h2&gt;

&lt;p&gt;Every hunter knows this pain:&lt;/p&gt;

&lt;p&gt;You fuzz 100,000 payloads…&lt;/p&gt;

&lt;p&gt;And you get:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Same 404 page again and again&lt;/li&gt;
&lt;li&gt;Same JSON error template&lt;/li&gt;
&lt;li&gt;Same WAF response&lt;/li&gt;
&lt;li&gt;Same backend validation message&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;📉 70–90% results are &lt;strong&gt;noise&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Filtering such results manually is painful and slow.&lt;/p&gt;




&lt;h2&gt;
  
  
  ✅ The Next Smart Step (Not “AI Brain”)
&lt;/h2&gt;

&lt;p&gt;I &lt;strong&gt;deliberately decided NOT to make 404fuzz a scanner.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead, the near-future focus is only on:&lt;/p&gt;

&lt;h3&gt;
  
  
  🧠 1. Smart Response Deduplication
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Merge identical backend behaviors&lt;/li&gt;
&lt;li&gt;Group payloads by same response signature&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Show:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ unique behaviors&lt;/li&gt;
&lt;li&gt;📊 how many payloads hit the same logic&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;This reduces:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Noise&lt;/li&gt;
&lt;li&gt;Output size&lt;/li&gt;
&lt;li&gt;Mental fatigue&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  🛑 2. Simple 429 (Rate-Limit) Handling
&lt;/h3&gt;

&lt;p&gt;No AI.&lt;br&gt;
No guessing.&lt;/p&gt;

&lt;p&gt;Just:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Detect 429&lt;/li&gt;
&lt;li&gt;Respect &lt;code&gt;Retry-After&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Delay intelligently&lt;/li&gt;
&lt;li&gt;Continue scan safely&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧑‍🤝‍🧑 Why I’m Writing This: Open Source Collaboration
&lt;/h2&gt;

&lt;p&gt;404fuzz is &lt;strong&gt;fully open source&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://github.com/toklas495/404fuzz" rel="noopener noreferrer"&gt;https://github.com/toklas495/404fuzz&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This project is for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Bug bounty hunters&lt;/li&gt;
&lt;li&gt;Security engineers&lt;/li&gt;
&lt;li&gt;Node.js devs&lt;/li&gt;
&lt;li&gt;Tool builders&lt;/li&gt;
&lt;li&gt;Performance nerds&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can contribute in many ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Core engine improvements&lt;/li&gt;
&lt;li&gt;✅ New output modes&lt;/li&gt;
&lt;li&gt;✅ Deduplication logic&lt;/li&gt;
&lt;li&gt;✅ Rate-limit handling&lt;/li&gt;
&lt;li&gt;✅ Dashboard features&lt;/li&gt;
&lt;li&gt;✅ Docs &amp;amp; testing&lt;/li&gt;
&lt;li&gt;✅ Bug fixes&lt;/li&gt;
&lt;li&gt;✅ Performance benchmarks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is not a “solo ego tool.”&lt;br&gt;
I want this to become a &lt;strong&gt;community-powered fuzzer&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  🐜 Final Words
&lt;/h2&gt;

&lt;p&gt;404fuzz exists because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We needed &lt;strong&gt;speed without stupidity&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;We needed &lt;strong&gt;simplicity without weakness&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;We needed a tool that respects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;developers&lt;/li&gt;
&lt;li&gt;hunters&lt;/li&gt;
&lt;li&gt;and system performance&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;If you believe:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fuzzing should stay fast&lt;/li&gt;
&lt;li&gt;Tools should stay hackable&lt;/li&gt;
&lt;li&gt;Open source should stay collaborative&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then I invite you to build this with me.&lt;/p&gt;

&lt;p&gt;⭐ Star&lt;br&gt;
🐛 Report issues&lt;br&gt;
💡 Propose features&lt;br&gt;
🔧 Send PRs&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://github.com/toklas495/404fuzz" rel="noopener noreferrer"&gt;https://github.com/toklas495/404fuzz&lt;/a&gt;&lt;/p&gt;




</description>
      <category>bugbounty</category>
      <category>opensource</category>
      <category>node</category>
      <category>infosec</category>
    </item>
    <item>
      <title>404ping v2 — The API Testing CLI That Went From Side-Project to Beast Mode 💥</title>
      <dc:creator>Nimesh Thakur</dc:creator>
      <pubDate>Sat, 29 Nov 2025 12:10:16 +0000</pubDate>
      <link>https://dev.to/toklas495/404ping-v2-the-api-testing-cli-that-went-from-side-project-to-beast-mode-3a6b</link>
      <guid>https://dev.to/toklas495/404ping-v2-the-api-testing-cli-that-went-from-side-project-to-beast-mode-3a6b</guid>
      <description>&lt;p&gt;&lt;strong&gt;curl + Postman + brain = 404ping&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When I built &lt;strong&gt;404ping v0.0.1&lt;/strong&gt;, it was a tiny experiment.&lt;br&gt;
I just wanted a simple CLI tool that let me test APIs quickly — without opening Postman or remembering curl flags.&lt;/p&gt;

&lt;p&gt;That first version could only:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Send simple HTTP requests&lt;/li&gt;
&lt;li&gt;Store a few variables&lt;/li&gt;
&lt;li&gt;Handle basic collections&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s it.&lt;br&gt;
But the response from developers and bug hunters was insane — people loved the speed &amp;amp; simplicity.&lt;br&gt;
So I went back to the lab. And now, after countless commits, refactors, and caffeine, &lt;strong&gt;404ping v2 is here&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;And it’s not an upgrade…&lt;br&gt;
&lt;strong&gt;It’s a transformation.&lt;/strong&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  🚀 Introducing 404ping v2
&lt;/h2&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Lightweight API Testing CLI — curl with a brain 🧠&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;No GUI. No accounts. No cloud sync.&lt;br&gt;
Just pure, fast, developer-focused power.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install
npm run build
404ping request https://api.example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ✨ New Version Highlights
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;curl&lt;/th&gt;
&lt;th&gt;Postman&lt;/th&gt;
&lt;th&gt;404ping&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Lightweight CLI&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GUI Required&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Variables&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅ (global &amp;amp; scoped)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Collections&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅ (CLI-based)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Save &amp;amp; reuse requests&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TLS / SSL inspection&lt;/td&gt;
&lt;td&gt;⚠️&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Debug connection / TLS / timing&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;⚠️&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Output modes&lt;/td&gt;
&lt;td&gt;⚠️&lt;/td&gt;
&lt;td&gt;⚠️&lt;/td&gt;
&lt;td&gt;🔥&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Secure by default&lt;/td&gt;
&lt;td&gt;⚠️&lt;/td&gt;
&lt;td&gt;⚠️&lt;/td&gt;
&lt;td&gt;🔐&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🧨 What’s New in v2 (Massive Upgrade)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🔄 &lt;strong&gt;Smart Saved Requests&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Save requests with just one flag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;404ping request &lt;span class="o"&gt;{{&lt;/span&gt;host&lt;span class="o"&gt;}}&lt;/span&gt;/api/login &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"email":"{{email}}"}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--save&lt;/span&gt; myapp.login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run anytime:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;404ping run myapp:login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Override &amp;amp; save:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;404ping run myapp:login &lt;span class="nt"&gt;-u&lt;/span&gt; https://staging.api.com/login &lt;span class="nt"&gt;--save&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  🧬 &lt;strong&gt;Variable System: global + collection&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;404ping &lt;span class="nb"&gt;set &lt;/span&gt;host:https://api.myapp.com token:abc123
404ping request &lt;span class="o"&gt;{{&lt;/span&gt;host&lt;span class="o"&gt;}}&lt;/span&gt;/users/me &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer {{token}}"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Scoped:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;404ping &lt;span class="nb"&gt;set &lt;/span&gt;myapp.token:xyz myapp.host:https://api.myapp.com
404ping request &lt;span class="o"&gt;{{&lt;/span&gt;myapp.host&lt;span class="o"&gt;}}&lt;/span&gt;/users
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  📁 &lt;strong&gt;Collections — Project API management like Postman, but CLI&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;404ping collection create myapp
404ping collection save myapp login &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="o"&gt;{{&lt;/span&gt;host&lt;span class="o"&gt;}}&lt;/span&gt;/auth/login &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"email":"{{email}}"}'&lt;/span&gt;
404ping collection show myapp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  🎯 &lt;strong&gt;Advanced Output Modes&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;404ping request https://api.example.com &lt;span class="nt"&gt;--info&lt;/span&gt;        &lt;span class="c"&gt;# Full analysis mode&lt;/span&gt;
404ping request https://api.example.com &lt;span class="nt"&gt;--connection&lt;/span&gt; &lt;span class="c"&gt;# Network info&lt;/span&gt;
404ping request https://api.example.com &lt;span class="nt"&gt;--tls&lt;/span&gt;        &lt;span class="c"&gt;# SSL certificate details&lt;/span&gt;
404ping request https://api.example.com &lt;span class="nt"&gt;--debug&lt;/span&gt;      &lt;span class="c"&gt;# Everything&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  🔐 &lt;strong&gt;Security-focused&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;✔ SSL verify by default&lt;br&gt;
✔ TLS breakdown&lt;br&gt;
✔ Input validation&lt;br&gt;
✔ Path traversal protection&lt;br&gt;
✔ Explains failure reasons&lt;/p&gt;


&lt;h2&gt;
  
  
  🧪 Real-World Workflow Example
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;404ping &lt;span class="nb"&gt;set &lt;/span&gt;host:https://api.myapp.com token:abc123
404ping collection create myapp

404ping request &lt;span class="o"&gt;{{&lt;/span&gt;host&lt;span class="o"&gt;}}&lt;/span&gt;/auth/login &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"email":"dev@myapp.com","password":"hello"}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--save&lt;/span&gt; myapp.login

404ping run myapp:login &lt;span class="nt"&gt;--info&lt;/span&gt;
404ping &lt;span class="nb"&gt;set &lt;/span&gt;token:eyJhbGc...         &lt;span class="c"&gt;# update token after login&lt;/span&gt;
404ping run myapp:profile &lt;span class="nt"&gt;--connection&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🤝 Why I Built It (Personal Note)
&lt;/h2&gt;

&lt;p&gt;I created 404ping because:&lt;/p&gt;

&lt;p&gt;➡ &lt;strong&gt;Postman is too heavy&lt;/strong&gt;&lt;br&gt;
➡ &lt;strong&gt;curl is too raw &amp;amp; hard to reuse&lt;/strong&gt;&lt;br&gt;
➡ &lt;strong&gt;I wanted something fast, scriptable, hacker-friendly&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now it has:&lt;/p&gt;

&lt;p&gt;🔥 Collections&lt;br&gt;
🔥 Variables&lt;br&gt;
🔥 Saved requests&lt;br&gt;
🔥 TLS inspecting&lt;br&gt;
🔥 Debug view&lt;br&gt;
🔥 Secure defaults&lt;br&gt;
🔥 And &lt;em&gt;zero&lt;/em&gt; GUI&lt;/p&gt;

&lt;p&gt;This is my tribute to terminal developers who prefer typing over clicking.&lt;/p&gt;


&lt;h2&gt;
  
  
  💡 Who Should Use 404ping?
&lt;/h2&gt;

&lt;p&gt;👨‍💻 Backend developers&lt;br&gt;
🛡 Bug bounty hunters&lt;br&gt;
🧪 QA testers&lt;br&gt;
⚙ DevOps / CI pipelines&lt;br&gt;
🖥 Terminal lovers&lt;br&gt;
🌎 Anyone tired of Postman’s 600MB RAM usage&lt;/p&gt;


&lt;h2&gt;
  
  
  🧠 Future Roadmap
&lt;/h2&gt;

&lt;p&gt;📦 Export / Import Postman Collections&lt;br&gt;
🔗 Request chaining (use previous responses)&lt;br&gt;
📄 &lt;code&gt;.env&lt;/code&gt; support&lt;br&gt;
🧪 Assertions for automated tests&lt;/p&gt;


&lt;h2&gt;
  
  
  📥 Installation
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/toklas495/404ping.git
&lt;span class="nb"&gt;cd &lt;/span&gt;404ping
npm &lt;span class="nb"&gt;install
&lt;/span&gt;npm run build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🔥 Final Words
&lt;/h2&gt;

&lt;p&gt;From a small v0.0.1 idea&lt;br&gt;
to a production-ready API testing CLI—&lt;br&gt;
&lt;strong&gt;404ping became something I am proud of.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you’re tired of fighting Postman or writing curl novels,&lt;br&gt;
give &lt;strong&gt;404ping v2&lt;/strong&gt; a try.&lt;/p&gt;

&lt;p&gt;⭐ Star it if you like it&lt;br&gt;
🛠 Contribute ideas&lt;br&gt;
🐞 Report issues&lt;br&gt;
💬 PRs welcome&lt;/p&gt;

&lt;p&gt;👉 GitHub: &lt;code&gt;github.com/toklas495/404ping&lt;/code&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  🎤 Call to action
&lt;/h2&gt;

&lt;p&gt;If this tool helps you:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;⭐ Give a star on GitHub
🎭 Share with dev friends
🔧 Try your first collection today
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>webdev</category>
      <category>opensource</category>
      <category>bugbounty</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
