// The name of the backend servers associated with this service.
// This must match the backend names you configured using `fastly backend create`.
const BACKEND_APP_SERVER = "origin_0";
const BACKEND_SECURITY_CHECK = "origin_1";

// Credential prefix length
const PREFIX_LENGTH = 5;

// Login form HTML
const LOGIN_HTML = `<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>Compromised password detection demo</title>
  </head>
  <body>
    <form action="/post" method="post">
      <div class="container">
        <label for="username"><b>Username</b></label>
        <input type="text" placeholder="Enter Username" name="username" required />

        <label for="password"><b>Password</b></label>
        <input type="password" placeholder="Enter Password" name="password" required />

        <button type="submit">Login</button>
      </div>
    </form>
  </body>
</html>
`;

async function handler(event) {
  const req = event.request;
  const url = new URL(req.url);

  // For the demo, serve a basic login form on the root path
  if (req.method === "GET" && url.pathname === "/") {
    return new Response(LOGIN_HTML);
  }

  // parse the body
  let body = await req.text();
  let params = new URLSearchParams(body);
  let plainCred = params.get("password");
  
  if (plainCred) {
    // Generate sha1 hash of credential
    const hashedCred = Array.from(new Uint8Array(await crypto.subtle.digest({name:"sha-1"}, new TextEncoder().encode(plainCred)))).map(b => b.toString(16).padStart(2, "0")).join('').toUpperCase()

    // Split the hash of credential to left and right part at position PREFIX_LENGTH
    let hashLeft = hashedCred.slice(0, PREFIX_LENGTH);
    let hashRight = hashedCred.slice(PREFIX_LENGTH);

    
    // Prepare the request for threat check
    // (If you use HIBP in production please use an API key)
    let apiUrl = `https://api.pwnedpasswords.com/range/${hashLeft}`;
    let apiReq = new Request(apiUrl);

    // Send threat check request to API with the left-hand-side of the SHA1 hash
    let apiRes = await fetch(apiReq, { backend: BACKEND_SECURITY_CHECK });
    let apiResBody = await apiRes.text();

    // Check if the response body contains the right-hand-side of the sha1 hash
    let result = apiResBody.includes(hashRight) ? "compromised-credential" : "safe-credential";

    // Uncomment for debugging. For production use, avoid logging credentials
    // console.log(`Checked credential ${plainCred}, result is ${result}`)
    req.headers.set("fastly-password-status", result);
  }

  // Send request to the primary origin as normal
  return fetch(req, { backend: BACKEND_APP_SERVER, body: params });
}

addEventListener("fetch", (event) => event.respondWith(handler(event)));