diff --git a/.github/workflows/cmake-multi-platform.yml b/.github/workflows/cmake-multi-platform.yml index a0b477b..2309018 100644 --- a/.github/workflows/cmake-multi-platform.yml +++ b/.github/workflows/cmake-multi-platform.yml @@ -58,15 +58,20 @@ jobs: sudo apt update sudo apt install -y cmake ninja-build gcc-13 g++-13 clang-17 lldb-17 lld-17 libc++-17-dev libc++abi-17-dev \ libomp-17-dev libgcrypt20 openssl libreadline8 libsodium23 libsodium-dev + + + - uses: actions/checkout@v3 # Install BLAKE3 - name: Build BLAKE3 run: | - git clone https://github.com/BLAKE3-team/BLAKE3.git - cd BLAKE3/c - cmake -B build -DCMAKE_C_COMPILER=${{ matrix.c_compiler }} -G Ninja - sudo cmake --build build --config Release --target install -j 4 - + OS=${{ matrix.os }} + COMMAND="./scripts/install-blake3.sh ${{ matrix.c_compiler }}" + if [ "$OS" == "macos-13" ]; then + $COMMAND + elif [ "$OS" == "ubuntu-latest" ]; then + sudo $COMMAND + fi - uses: actions/checkout@v3 diff --git a/buildscript.sh b/scripts/buildscript.sh similarity index 100% rename from buildscript.sh rename to scripts/buildscript.sh diff --git a/install_blake3.sh b/scripts/install-blake3.sh similarity index 100% rename from install_blake3.sh rename to scripts/install-blake3.sh diff --git a/src/passwordManager/passwordManager.cpp b/src/passwordManager/passwordManager.cpp index f7fda75..37f468d 100644 --- a/src/passwordManager/passwordManager.cpp +++ b/src/passwordManager/passwordManager.cpp @@ -26,6 +26,7 @@ #include #include #include +#include namespace fs = std::filesystem; using string = std::string; @@ -69,6 +70,17 @@ inline constexpr void printPasswordDetails(const auto &pw, const bool &isStrong } +/// \brief This function computes the strength of each password in the provided list of passwords. +/// +/// The function iterates over the list of passwords and for each password, it checks if the password is strong or not. +/// The result of this check (a boolean value) is stored in the corresponding index in the pwStrengths vector. +/// A password is considered strong if it meets certain criteria defined in the isPasswordStrong function. +/// +/// \param passwords A vector of tuples, where each tuple represents a password record. +/// \param pwStrengths A vector of boolean values where each element represents the strength of the corresponding password +/// in the passwords vector. It is resized to match the size of the passwords vector. +/// +/// \note This function is always inlined by the compiler. inline constexpr void computeStrengths #if __clang__ [[clang::always_inline]] @@ -504,6 +516,7 @@ inline void importPasswords(privacy::vector &passwords, std::ve privacy::vector duplicates; duplicates.reserve(imports.size()); + // Find the passwords that already exist in the database std::ranges::set_intersection(imports, passwords, std::back_inserter(duplicates), [](const auto &pw1, const auto &pw2) { return comparator(pw1, pw2); @@ -631,21 +644,31 @@ inline void analyzePasswords(privacy::vector &passwords, std::v true); } else printColor("No weak passwords found. Keep it up!\n", 'g', true); - // Print sites with reused passwords - std::size_t reused{0}; + // Find reused passwords + using PasswordSites = std::pair>; + std::multimap> countMap; + for (const auto &entry: passwordMap) { - const std::unordered_set &sites = entry.second; + const auto &sites = entry.second; if (const auto &x = sites.size(); x > 1) { - printColor("Password '", 'y'); - printColor(entry.first, 'r'); - printColor(std::format("' is reused on {} sites:", x), 'y', true); - for (const auto &site: sites) - printColor(site + "\n", 'm'); - - std::cout << std::endl; - ++reused; + countMap.insert(std::make_pair(x, PasswordSites(entry.first, sites))); } } + + // Print reused passwords in descending order of counts + std::size_t reused{0}; + for (const auto &[count, password_sites]: countMap) { + printColor("Password '", 'y'); + printColor(password_sites.first, 'r'); + printColor(std::format("' is reused on {} sites:", count), 'y', true); + for (const auto &site: password_sites.second) + printColor(site + "\n", 'm'); + + std::cout << std::endl; + ++reused; + } + + // Print summary if (reused) { printColor(std::format("{} password{} been reused.", reused, reused == 1 ? " has" : "s have"), 'r', true);