They MITM the real sign-in on NPM. So NPM actually sent them a 2FA but the user entered it on the phishing site. The attacker then relayed that to the real NPM.