22#include " BBE/BrotBoxEngine.h"
33#include " BBE/SimpleProcess.h"
44#include " BBE/AdafruitMacroPadRP2040.h"
5+ #include < sodium/crypto_pwhash_argon2id.h>
56#include < iostream>
67#include < mutex>
78#include < cmath>
@@ -1686,7 +1687,7 @@ class MyGame : public bbe::Game
16861687 ImGui::PushID (i);
16871688 bool toggle = ImGui::Button (" X" );
16881689 ImGui::bbe::tooltip (" Toggle the ignore state of this console message" );
1689- if (toggle)
1690+ if (toggle)
16901691 {
16911692 toggleIgnoreState (log[index]);
16921693 }
@@ -1697,7 +1698,7 @@ class MyGame : public bbe::Game
16971698 }
16981699 else
16991700 {
1700- ImGui::TextColored (ImVec4{1 .0f , 0 .5f , 0 .5f , 1 .0f }, log[index]);
1701+ ImGui::TextColored (ImVec4{ 1 .0f , 0 .5f , 0 .5f , 1 .0f }, log[index]);
17011702 }
17021703 ImGui::PopID ();
17031704 }
@@ -1725,7 +1726,7 @@ class MyGame : public bbe::Game
17251726 generalConfigChanged |= ImGui::SliderFloat (" Base Monitor Brightness 1" , &generalConfig->baseMonitorBrightness1 , 0 .0f , 1 .0f );
17261727 generalConfigChanged |= ImGui::SliderFloat (" Base Monitor Brightness 2" , &generalConfig->baseMonitorBrightness2 , 0 .0f , 1 .0f );
17271728 generalConfigChanged |= ImGui::SliderFloat (" Base Monitor Brightness 3" , &generalConfig->baseMonitorBrightness3 , 0 .0f , 1 .0f );
1728-
1729+
17291730 if (ImGui::Button (" Remember Window Position" ))
17301731 {
17311732 generalConfig->windowSet = true ;
@@ -2027,7 +2028,7 @@ class MyGame : public bbe::Game
20272028 {
20282029 brush.setColorRGB (0 .3f , 0 .3f , 0 .3f , 1 );
20292030 }
2030- brush.sketchRect ( -9 + k * 19 , 35 + (12 - monthIter) * 30 , 15 , 15 );
2031+ brush.sketchRect (-9 + k * 19 , 35 + (12 - monthIter) * 30 , 15 , 15 );
20312032 brush.fillText (3 - 4 + k * 19 , 46 + (12 - monthIter) * 30 , bbe::String (k), 15 , bbe::Anchor::BOTTOM_CENTER);
20322033 }
20332034 }
@@ -2185,6 +2186,88 @@ class MyGame : public bbe::Game
21852186 return bbe::Vector2 (1 );
21862187 }
21872188
2189+ bbe::String normalizeService (const bbe::String& service)
2190+ {
2191+ bbe::String normalizedService = service;
2192+ normalizedService.toLowerCaseInPlace ();
2193+ normalizedService = normalizedService.replace (" " , " " );
2194+ normalizedService = normalizedService.replace (" http://" , " " );
2195+ normalizedService = normalizedService.replace (" https://" , " " );
2196+ if (normalizedService.contains (" /" ))
2197+ {
2198+ normalizedService = normalizedService.substring (0 , normalizedService.search (" /" ));
2199+ }
2200+ if (normalizedService.count (" ." ) > 1 )
2201+ {
2202+ auto normalizedServicesTokens = normalizedService.split (" ." );
2203+ normalizedService = normalizedServicesTokens[normalizedServicesTokens.getLength () - 2 ] + " ." + normalizedServicesTokens[normalizedServicesTokens.getLength () - 1 ];
2204+ }
2205+ return normalizedService;
2206+ }
2207+
2208+ bbe::Vector2 drawPasswordManager ()
2209+ {
2210+ static bbe::String masterPw;
2211+ static bbe::String masterPwRepeat;
2212+ static bbe::String service;
2213+ static bbe::String servicePw;
2214+ bool newHashRequested = false ;
2215+ if (ImGui::bbe::InputText (" Master PW" , masterPw, ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_Password))
2216+ {
2217+ newHashRequested = true ;
2218+ }
2219+ if (ImGui::bbe::InputText (" Master PW Repeat" , masterPwRepeat, ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_Password))
2220+ {
2221+ newHashRequested = true ;
2222+ }
2223+ if (ImGui::bbe::InputText (" Service" , service, ImGuiInputTextFlags_EnterReturnsTrue))
2224+ {
2225+ newHashRequested = true ;
2226+ }
2227+ bbe::String normServ = normalizeService (service);
2228+
2229+ if (newHashRequested && !normServ.isEmpty () && !masterPw.isEmpty () && masterPw == masterPwRepeat)
2230+ {
2231+ unsigned char hash[16 ] = {};
2232+ const bbe::String hashPw = masterPw + " |||" + normServ;
2233+ const int err = crypto_pwhash_argon2id (hash, sizeof (hash), hashPw.getRaw (), hashPw.getLength (), (const unsigned char *)" BrotbEnginePWGv1" , 5 , 256 * 1024 * 1024 , crypto_pwhash_argon2id_ALG_ARGON2ID13);
2234+ if (err != 0 ) bbe::Crash (bbe::Error::NotImplemented, " Implement me properly." );
2235+ servicePw = " " ;
2236+ const bbe::String lower = " abcdefghijklmnopqrstuvwxyz" ;
2237+ const bbe::String upper = " ABCDEFGHIJKLMNOPQRSTUVWXYZ" ;
2238+ const bbe::String digits = " 0123456789" ;
2239+ const bbe::String special = " !@#%*-_=+,.?" ;
2240+ const bbe::String all = lower + upper + digits + special;
2241+ for (size_t i = 0 ; i < sizeof (hash); i++)
2242+ {
2243+ const bbe::String* set = nullptr ;
2244+ // The first char is always lower, second always upper and so on. This is a very simple way to ensure
2245+ // we fulfill the vast majority of pw requirements while not reducing the amount of entropy by a lot.
2246+ if (i == 0 ) set = &lower;
2247+ else if (i == 1 ) set = &upper;
2248+ else if (i == 2 ) set = &digits;
2249+ else if (i == 3 ) set = &special;
2250+ else set = &all;
2251+
2252+ servicePw += (*set)[hash[i] % set->getLength ()];
2253+ }
2254+ }
2255+
2256+ ImGui::Text (" Normalized Service: " + normServ);
2257+ ImGui::Text (" PW: " + bbe::String (" *" ) * servicePw.getLength ());
2258+ if (!servicePw.isEmpty ())
2259+ {
2260+ if (ImGui::Button (" Copy to Clipboard" ))
2261+ {
2262+ setClipboard (servicePw);
2263+ servicePw = " " ;
2264+ }
2265+ }
2266+
2267+
2268+ return bbe::Vector2 (1 );
2269+ }
2270+
21882271 bbe::Vector2 drawTabChatGPT ()
21892272 {
21902273 if (ImGui::bbe::InputText (" API Key" , chatGPTConfig->apiKey , ImGuiInputTextFlags_Password))
@@ -2193,7 +2276,7 @@ class MyGame : public bbe::Game
21932276 // Set the API key in chatGPTComm
21942277 chatGPTComm.key = chatGPTConfig->apiKey ;
21952278 }
2196-
2279+
21972280 static bbe::String ttsInput;
21982281 if (ImGui::bbe::InputText (" TTS Test" , ttsInput, ImGuiInputTextFlags_EnterReturnsTrue))
21992282 {
@@ -2271,7 +2354,7 @@ class MyGame : public bbe::Game
22712354 waitingPrinted = true ;
22722355 }
22732356 }
2274- if (!waitingPrinted) ImGui::Text (" " ); // So that the "Waiting for response" doesn't move part of the GUI.
2357+ if (!waitingPrinted) ImGui::Text (" " ); // So that the "Waiting for response" doesn't move part of the GUI.
22752358
22762359 // Provide a button to purge the conversation
22772360 if (ImGui::Button (" Clear Conversation" ))
@@ -2327,7 +2410,7 @@ class MyGame : public bbe::Game
23272410
23282411 if (ImGui::bbe::InputText (" prompt" , dallEConfig->prompt , ImGuiInputTextFlags_EnterReturnsTrue))
23292412 {
2330- imageFuture = chatGPTComm.createImageAsync (dallEConfig->prompt , { 1792 , 1024 });
2413+ imageFuture = chatGPTComm.createImageAsync (dallEConfig->prompt , { 1792 , 1024 });
23312414 dallEConfig.writeToFile ();
23322415 }
23332416 if (descriptionFuture.valid () && descriptionFuture.wait_for (std::chrono::seconds (0 )) == std::future_status::ready)
@@ -2383,7 +2466,7 @@ class MyGame : public bbe::Game
23832466 }
23842467 }
23852468
2386- brush.drawImage ({ offsetX, offsetY }, image.image .getDimensions ().as <float >() * sizeMult, image.image );
2469+ brush.drawImage ({ offsetX, offsetY }, image.image .getDimensions ().as <float >() * sizeMult, image.image );
23872470
23882471 return bbe::Vector2 (101 , 100 .1f );
23892472 }
@@ -2438,7 +2521,7 @@ class MyGame : public bbe::Game
24382521 infoViewport.WorkSize .x = maxInfoWindowWidth;
24392522 }
24402523
2441- if (!fullscreenTab)
2524+ if (!fullscreenTab)
24422525 {
24432526 ImGui::SetNextWindowPos (infoViewport.WorkPos );
24442527 ImGui::SetNextWindowSize (infoViewport.WorkSize );
@@ -2710,12 +2793,13 @@ class MyGame : public bbe::Game
27102793 // Tab{"Brn-T", "Brain-Teaser", [&]() { return brainTeasers.drawTabBrainTeasers(brush); }},
27112794 Tab{" Stpwtch" , " Stopwatch" , [&]() { return drawTabStopwatch (); }},
27122795 Tab{" MsTrck" , " Mouse Track" , [&]() { return drawTabMouseTracking (brush); }},
2713- Tab{" KybrdTrck " , " Keyboard Track" , [&]() { return drawTabKeyboardTracking (brush); }},
2796+ Tab{" KyTr " , " Keyboard Track" , [&]() { return drawTabKeyboardTracking (brush); }},
27142797#if 0
27152798 Tab{"Terri", "Territorial", [&]() { return drawTabTerri(brush); }},
27162799#endif
27172800 Tab{" Strks" , " Streaks" , [&]() { return drawTabStreaks (brush); }},
27182801 Tab{" Lsts" , " Lists" , [&]() { return drawTabRememberLists (); }},
2802+ Tab{" PW" , " Password Manager" , [&]() { return drawPasswordManager (); }},
27192803 Tab{" GPT" , " ChatGPT" , [&]() { return drawTabChatGPT (); }},
27202804 Tab{" DE" , " DALL E" , [&]() { return drawTabDallE (brush); }},
27212805 // Tab{"Mic", "Microphone Test",[&]() { return drawMicrophoneTest(); }},
0 commit comments