0

Convert a string to Base64 format

Hello,
Many calls to a REST API require Basic authentication using a base64 encoding Authorization header (providing a username and password when making a request).

To my knowledge, no function within Ninox directly converts a string (e.g., userName:userPassword) to base64 format.

Because, in my case, the API server asks to change the password every 15 days, I find it challenging to convert the string outside of the Ninox each time manually.

As a workaround, we can first save the string in a text file using the createTextFile() function and then convert it to base64 format using the loadFileAsBase64() function.

loadFileAsBase64(createTextFile(this, "userName:userPassword", "user_credentials.txt"))

Does anyone have a more refined solution?

7 replies

null
    • Ninox developper
    • Jacques_TUR
    • 11 mths ago
    • Reported - view

    you can use btoa() function in JavaScript : https://developer.mozilla.org/fr/docs/Web/API/btoa

      • szormpas
      • 11 mths ago
      • Reported - view

         Hi, I assume that the btoa() function can only work inside the Ninext project, right?

      • Ninox developper
      • Jacques_TUR
      • 11 mths ago
      • Reported - view

       Of course it's easier with Ninext, but it's also possible to do it with an html field by using the onclick event of a button to execute a function that converts to basde64, then updates a field with the function database.update( recId, fieldId, value ). 

      var recId := string(this.Id);
      var fieldId := "C";
      html("
      <button onclick='convert()'>click to converte to base64</button>
      <script>
        function convert() {
          debugger;
          var value = '" + source + "';
          var base64 = btoa(value);
          database.update('" + recId + "', '" + fieldId + "', base64);
        }
      </script>
      ")

      On line 2, is the field id of base64 field. You need to know the id of the field to be updated in order to use this function. To find it, you can use the get schema function in the Ninox Rest API : https://docs.ninox.com/en/api/public-cloud-apis#get-a-schema-for-a-single-database

      I added a "base64 convert" table to the "#upload file from URL" database that I had created to test the import of base64 files from a URL or Rest API external to Ninox.

      • Ninox developper
      • Jacques_TUR
      • 11 mths ago
      • Reported - view

      And with Ninext, it's shorter 😅

      var source := "hello word";
      var base64 := #{:text return btoa(source) }#;
      
    • szormpas
    • 11 mths ago
    • Reported - view

     this is an elegant solution, many thanks for your contribution 🙏

    I have just tried your code with my database and it works as expected 🙂

    I hope Ninox will continue to support the database.update() function or they'll create a native 'convert string to base64' one!

    I have one question regarding security because in my case I will use your code to covert my API user credentials (username + password), does btoa() javascript function store my credentials in browser cache that I need to delete?

      • Ninox developper
      • Jacques_TUR
      • 11 mths ago
      • Reported - view

       I found a clear explanation on this site about Base64: https://base64.guru/learn/base64-algorithm/encode
      With that I was able to recreate encoding and decoding functions in Ninox script (see attached file). 

      To do this, we need ASCII manipulation functions (string operations): 

      - decToHexa: converts an 8-bit decimal number into a hexadecimal value,

      - chr : returns a character from an ASCII code (number),

      - ord: returns the ASCII code of the first character in the string passed as a parameter. 

      These functions are then used by encodeBase64 and decodeBase64.

       

      "----------------------------
      String operations
      -----------------------------";
      function decToHexa(value : number) do
          var hexa := ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"];
          var u := value % 16;
          var d := floor(value / 16);
          item(hexa, d) + item(hexa, u)
      end;
      function chr(ascii : number) do
          urlDecode("%" + decToHexa(ascii))
      end;
      function ord(t : text) do
          var ascii := urlDecode("%00%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%20!%22#$%25&'()*+,-./0123456789:;%3C=%3E?@ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D~%7F%C2%80%C2%81%C2%82%C2%83%C2%84%C2%85%C2%86%C2%87%C2%88%C2%89%C2%8A%C2%8B%C2%8C%C2%8D%C2%8E%C2%8F%C2%90%C2%91%C2%92%C2%93%C2%94%C2%95%C2%96%C2%97%C2%98%C2%99%C2%9A%C2%9B%C2%9C%C2%9D%C2%9E%C2%9F%C2%A0%C2%A1%C2%A2%C2%A3%C2%A4%C2%A5%C2%A6%C2%A7%C2%A8%C2%A9%C2%AA%C2%AB%C2%AC%C2%AD%C2%AE%C2%AF%C2%B0%C2%B1%C2%B2%C2%B3%C2%B4%C2%B5%C2%B6%C2%B7%C2%B8%C2%B9%C2%BA%C2%BB%C2%BC%C2%BD%C2%BE%C2%BF%C3%80%C3%81%C3%82%C3%83%C3%84%C3%85%C3%86%C3%87%C3%88%C3%89%C3%8A%C3%8B%C3%8C%C3%8D%C3%8E%C3%8F%C3%90%C3%91%C3%92%C3%93%C3%94%C3%95%C3%96%C3%97%C3%98%C3%99%C3%9A%C3%9B%C3%9C%C3%9D%C3%9E%C3%9F%C3%A0%C3%A1%C3%A2%C3%A3%C3%A4%C3%A5%C3%A6%C3%A7%C3%A8%C3%A9%C3%AA%C3%AB%C3%AC%C3%AD%C3%AE%C3%AF%C3%B0%C3%B1%C3%B2%C3%B3%C3%B4%C3%B5%C3%B6%C3%B7%C3%B8%C3%B9%C3%BA%C3%BB%C3%BC%C3%BD%C3%BE%C3%BF");
          index(ascii, substr(t, 0, 1))
      end;
      "----------------------------
      base64 functions
      -----------------------------";
      function encodeBase64(value : text) do
          var base64Chars := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
          var base64Result := "";
          var binaryString := value;
          " Convertir la chaîne en une chaîne binaire";
          var b := [{}][false];
          while length(binaryString) > 0 do
              var val := 0;
              var s := slice(binaryString, 0, 3);
              binaryString := slice(binaryString, 3, length(binaryString));
              for i in range(0, 3) do
                  val := val * 256 + ord(text(item(s, i)))
              end;
              var res := "";
              for i in range(0, 4) do
                  var numCar := val % 64;
                  var car := item(base64Chars, numCar);
                  res := car + res;
                  val := floor(val / 64)
              end;
              var nbCode := ceil(length(s) * 8 / 6);
              res := slice(res, 0, nbCode);
              for i in range(nbCode, 4) do
                  res := res + "="
              end;
              base64Result := base64Result + res
          end
      ;
          base64Result
      end;
      function decodeBase64(base64 : text) do
          var base64Chars := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
          var base64String := base64;
          var stringResult := "";
          while length(base64String) > 0 do
              var s := slice(base64String, 0, 4);
              base64String := slice(base64String, 4, length(base64String));
              var val := 0;
              for i in range(0, 4) do
                  val := val * 64;
                  if item(s, i) != "=" then
                      val := val + index(base64Chars, text(item(s, i)))
                  end;
              end;
              var res := "";
              var v := 0;
              for i in range(3, 0) do
                  v := val % 256;
                  if v > 0 then
                      res := chr(val % 256) + res
                  end;
                  val := floor(val / 256);
              end;
              stringResult := stringResult + res
          end
      ;
          stringResult
      end

      Encoding and decoding are limited to 8bit character strings. As with the btoa() JavaScript function (https://developer.mozilla.org/fr/docs/Web/API/btoa), if you are using 16bit unicode characters, such as emotionne, the conversion will not work (and no error will be generated). For strings containing unicode, you must first convert them using encodeURI. Similarly, after decoding, you must use decodeURI to recover the original string.

      • szormpas
      • 11 mths ago
      • Reported - view

         Hi ,

      your coding skills have been recognized by everyone here, but what impresses me most is the way you analyze things so that I can follow your logic even as an amateur low-code user 🙂

      If I understand correctly, you have just created two native functions using the Ninox script!

      My very small contribution to the community will be to exhaustively test their use in real-world conditions and let you know if I encounter any problems with character encoding. So far so good...

      I suggest you create a new post called "New Ninox functions by Jacques" so we can easily follow your implementations!!

Content aside

  • 11 mths agoLast active
  • 7Replies
  • 386Views
  • 3 Following