paivana

HTTP paywall reverse proxy
Log | Files | Refs | README | LICENSE

paywall.html (2206B)


      1 <!DOCTYPE html>
      2 
      3 <html lang="en">
      4   <head>
      5     <meta charset="utf-8" />
      6     <script>
      7       function makeBadInsecureId(length) {
      8         var result = "";
      9         var characters =
     10           "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
     11         var charactersLength = characters.length;
     12         for (var i = 0; i < length; i++) {
     13           result += characters.charAt(
     14             Math.floor(Math.random() * charactersLength)
     15           );
     16         }
     17         return result;
     18       }
     19       function waitMs(n) {
     20         return new Promise((resolve, reject) => {
     21           setTimeout(() => resolve(), n);
     22         });
     23       }
     24       addEventListener("DOMContentLoaded", async (event) => {
     25         // Bad for testing, only works with http
     26         //const paivana_id = crypto.randomUUID();
     27 
     28         const paivanaId = makeBadInsecureId(16);
     29         const proto = window.location.protocol;
     30         const suffix = proto === "http:" ? "+http" : "";
     31 
     32         const host = window.location.host;
     33         document
     34           .getElementById("talerlink")
     35           .setAttribute(
     36             "href",
     37             `taler${suffix}://pay-template/${host}/.well-known/paivana/paywall?session_id=${paivanaId}`
     38           );
     39 
     40         while (true) {
     41           const start = performance.now();
     42           try {
     43             const res = await fetch(
     44               `${proto}//${host}/.well-known/paivana/paivanas/${paivanaId}?timeout_ms=30000`
     45             );
     46             if (res.status === 200) {
     47               location.reload();
     48             } else {
     49               console.log("payment not ready yet");
     50             }
     51           } catch (e) {
     52             console.log("oops", e);
     53           }
     54           // FIXME: Wait depending on how long we needed
     55           const durMs = performance.now() - start;
     56           const remMs = Math.round(30000 - durMs);
     57           if (remMs > 0) {
     58             console.log(`long-poller returned early, waiting for ${remMs}ms`);
     59             await waitMs(remMs);
     60           } else {
     61             console.log(`trying again immediately`);
     62           }
     63         }
     64       });
     65     </script>
     66   </head>
     67   <body>
     68     <h1>Payment Required</h1>
     69     <a id="talerlink" href="...">Taler Payment</a>
     70   </body>
     71 </html>