├── .drone.yml ├── .gitignore ├── .travis.yml ├── .vscode └── tasks.json ├── LICENSE.txt ├── README.md ├── com.bixense.PasswordCalculator.desktop ├── com.bixense.PasswordCalculator.json ├── meson.build ├── pwcalculator.png ├── share ├── appdata │ └── com.bixense.PasswordCalculator.appdata.xml └── icons │ └── com.bixense.PasswordCalculator.svg ├── src ├── MyApp.cpp ├── MyApp.hpp ├── MyFrame.cpp ├── MyFrame.hpp ├── main.cpp ├── password.cpp ├── password.hpp └── windows │ ├── installer.nsi │ ├── main.rc │ └── pwcalculator.ico ├── waf └── wscript /.drone.yml: -------------------------------------------------------------------------------- 1 | build: 2 | image: teaci/msys32 3 | shell: mingw32 4 | pull: true 5 | commands: 6 | - pacman -S --needed --noconfirm --noprogressbar mingw-w64-i686-wxWidgets mingw-w64-i686-gcc mingw-w64-i686-pkg-config mingw-w64-i686-openssl mingw-w64-i686-boost mingw-w64-i686-waf python3 7 | - waf configure build --release --color=yes 8 | environment: 9 | - CLICOLOR_FORCE=1 10 | - PYTHONUNBUFFERED=1 11 | - LANG=C.UTF-8 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Waf 2 | /build/ 3 | /.waf*/ 4 | /.lock-waf* 5 | 6 | # Visual Studio Code 7 | /.vscode/.browse* 8 | /.vscode/tags 9 | /.ccls-cache/ 10 | 11 | # Flatpak 12 | /.flatpak-builder/ 13 | /repo/ 14 | 15 | # macOS 16 | .DS_Store 17 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | compiler: 3 | - clang 4 | os: 5 | - linux 6 | - osx 7 | before_install: 8 | - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi 9 | - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install wxmac; fi 10 | addons: 11 | apt: 12 | packages: 13 | - libwxgtk3.0-dev 14 | - libboost-dev 15 | script: 16 | - ./waf configure build 17 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.1.0", 3 | "windows": { 4 | "command": "C:\\msys64\\usr\\bin\\bash" 5 | }, 6 | "linux": { 7 | "command": "/bin/bash" 8 | }, 9 | "args": ["-lc", "cd \"\"${workspaceRoot}\"\" && waf $0 && $@"], 10 | "isShellCommand": true, 11 | "showOutput": "always", 12 | "options": { 13 | "env": { 14 | "LANG": "C.UTF-8", 15 | "PYTHONUNBUFFERD": "1", 16 | "MSYSTEM": "MINGW64" 17 | } 18 | }, 19 | "tasks": [ 20 | { 21 | "taskName": "build", 22 | "isBuildCommand": true, 23 | "problemMatcher": { 24 | "owner": "cpp", 25 | "fileLocation": ["relative", "${workspaceRoot}/build/"], 26 | "pattern": { 27 | "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error|fatal error):\\s+(.*)$", 28 | "file": 1, 29 | "line": 2, 30 | "column": 3, 31 | "severity": 4, 32 | "message": 5 33 | } 34 | } 35 | }, 36 | { 37 | "taskName": "test", 38 | "args": ["./build/unittest"], 39 | "isTestCommand": true, 40 | "problemMatcher": { 41 | "owner": "cpp", 42 | "fileLocation": ["relative", "${workspaceRoot}/build/"], 43 | "pattern": { 44 | "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error|fatal error):\\s+(.*)$", 45 | "file": 1, 46 | "line": 2, 47 | "column": 3, 48 | "severity": 4, 49 | "message": 5 50 | } 51 | } 52 | }, 53 | { 54 | "taskName": "configure" 55 | }, 56 | { 57 | "taskName": "clean" 58 | } 59 | ] 60 | } 61 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 Jan Niklas Hasse 2 | 3 | This software is provided 'as-is', without any express or implied 4 | warranty. In no event will the authors be held liable for any damages 5 | arising from the use of this software. 6 | 7 | Permission is granted to anyone to use this software for any purpose, 8 | including commercial applications, and to alter it and redistribute it 9 | freely, subject to the following restrictions: 10 | 11 | 1. The origin of this software must not be misrepresented; you must not 12 | claim that you wrote the original software. If you use this software 13 | in a product, an acknowledgment in the product documentation would be 14 | appreciated but is not required. 15 | 2. Altered source versions must be plainly marked as such, and must not be 16 | misrepresented as being the original software. 17 | 3. This notice may not be removed or altered from any source distribution. 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Password Calculator [![Build Status](https://travis-ci.org/jhasse/pwcalculator.svg)](https://travis-ci.org/jhasse/pwcalculator) 2 | 3 | This app calculates strong passwords for each alias from your single secret. No need to remember 4 | dozens of passwords any longer and no need for a password manager! Based on this GNOME Shell 5 | extension: https://extensions.gnome.org/extension/825/password-calculator/ 6 | 7 | Icon made by [Madebyoliver](http://www.flaticon.com/authors/madebyoliver) from 8 | [www.flaticon.com](http://www.flaticon.com) is licensed by 9 | [CC 3.0 BY](http://creativecommons.org/licenses/by/3.0/). 10 | 11 | ## Dependencies 12 | 13 | ### Ubuntu Linux 14 | 15 | ```sh 16 | sudo apt install libssl-dev libwxgtk3.0-dev libboost-dev 17 | ``` 18 | 19 | ### Fedora Linux 20 | 21 | ```sh 22 | sudo dnf install gcc-c++ wxGTK3-devel openssl-devel boost-devel 23 | ``` 24 | 25 | ### Windows (MSYS2) 26 | 27 | ```sh 28 | pacman -S mingw-w64-x86_64-wxWidgets mingw-w64-x86_64-waf 29 | ``` 30 | 31 | ### macOS 32 | 33 | ```sh 34 | brew install wxmac dylibbundler 35 | ``` 36 | 37 | ## Build and Run 38 | 39 | ```sh 40 | ./waf configure build # Linux 41 | waf configure build # Windows (MSYS2) 42 | ./build/pwcalculator 43 | ``` 44 | 45 | ## Install (Linux only) 46 | 47 | ```sh 48 | ./waf configure build --release 49 | sudo ./waf install 50 | sudo chmod +x /usr/local/share/applications/com.bixense.PasswordCalculator.desktop 51 | ``` 52 | 53 | ## Creating a Flatpak 54 | 55 | ```sh 56 | flatpak install runtime/org.freedesktop.Sdk//18.08 57 | flatpak install runtime/org.freedesktop.Platform//18.08 58 | flatpak-builder --repo=repo ./build com.bixense.PasswordCalculator.json 59 | flatpak build-bundle repo pwcalculator.flatpak com.bixense.PasswordCalculator 60 | ``` 61 | -------------------------------------------------------------------------------- /com.bixense.PasswordCalculator.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=Password Calculator 3 | Type=Application 4 | Exec=pwcalculator 5 | Icon=com.bixense.PasswordCalculator 6 | Categories=Utility; 7 | -------------------------------------------------------------------------------- /com.bixense.PasswordCalculator.json: -------------------------------------------------------------------------------- 1 | { 2 | "app-id": "com.bixense.PasswordCalculator", 3 | "runtime": "org.freedesktop.Platform", 4 | "runtime-version": "18.08", 5 | "sdk": "org.freedesktop.Sdk", 6 | "command": "pwcalculator", 7 | "finish-args": [ 8 | "--socket=x11", 9 | "--socket=wayland" 10 | ], 11 | "cleanup": [ "/include", "/bin/wx*", "/lib/wx" ], 12 | "modules": [ 13 | { 14 | "name": "wxWidgets", 15 | "rm-configure": true, 16 | "config-opts": "--with-gtk=3 --with-opengl --with-libjpeg --disable-shared --enable-monolithic--with-libtiff --with-libpng --with-zlib --disable-sdltest --enable-unicode --enable-display --enable-propgrid --disable-webkit --disable-webview --disable-webviewwebkit --with-libiconv=/usr", 17 | "cxxflags": [ 18 | "-std=c++11" 19 | ], 20 | "sources": [ 21 | { 22 | "type": "archive", 23 | "url": "https://github.com/wxWidgets/wxWidgets/releases/download/v3.1.0/wxWidgets-3.1.0.tar.bz2", 24 | "sha256": "e082460fb6bf14b7dd6e8ac142598d1d3d0b08a7b5ba402fdbf8711da7e66da8" 25 | }, 26 | { 27 | "type": "script", 28 | "path": "autogen.sh", 29 | "commands": [ 30 | "cp -p /usr/share/automake-*/config.{sub,guess} .", 31 | "autoconf -f -B build/autoconf_prepend-include" 32 | ] 33 | } 34 | ] 35 | }, 36 | { 37 | "name": "boost", 38 | "buildsystem": "simple", 39 | "sources": [ 40 | { 41 | "type": "archive", 42 | "url": "https://dl.bintray.com/boostorg/release/1.64.0/source/boost_1_64_0.tar.bz2", 43 | "sha256": "7bcc5caace97baa948931d712ea5f37038dbb1c5d89b43ad4def4ed7cb683332" 44 | } 45 | ], 46 | "build-commands": [ 47 | "./bootstrap.sh", 48 | "./b2 headers", 49 | "cp -r boost /app/include/boost" 50 | ], 51 | "cleanup": ["*"] 52 | }, 53 | { 54 | "name": "PasswordCalculator", 55 | "buildsystem": "simple", 56 | "build-commands": [ 57 | "./waf configure install --release --prefix=/app --boost-includes=/app/include" 58 | ], 59 | "sources": [ 60 | { 61 | "type": "git", 62 | "path": "." 63 | } 64 | ] 65 | } 66 | ] 67 | } 68 | -------------------------------------------------------------------------------- /meson.build: -------------------------------------------------------------------------------- 1 | project('pwcalculator', 'cpp') 2 | 3 | wx_dep = dependency('wxwidgets') 4 | 5 | executable('demo', [ 6 | 'src/main.cpp', 7 | 'src/MyApp.cpp', 8 | 'src/MyFrame.cpp', 9 | 'src/password.cpp', 10 | ], dependencies : wx_dep) 11 | -------------------------------------------------------------------------------- /pwcalculator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhasse/pwcalculator/4691e1036fb1139b0c6c0ea43e54150493ac01e9/pwcalculator.png -------------------------------------------------------------------------------- /share/appdata/com.bixense.PasswordCalculator.appdata.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | com.bixense.PasswordCalculator.desktop 4 | CC0-1.0 5 | Zlib 6 | Password Calculator 7 | Calculate strong passwords for each alias from your single secret 8 | 9 | 10 |

11 | This app calculates strong passwords for each alias from your single secret. No need to 12 | remember dozens of passwords any longer and no need for a password manager! 13 |

14 |
15 | 16 | 17 | 18 | https://bixense.com/pwcalculator/screenshot.png 19 | 20 | 21 | 22 | 23 | https://bixense.com/pwcalculator/ 24 | 25 | 26 | 27 | 28 | 29 | 30 | pwcalculator 31 | 32 |
33 | -------------------------------------------------------------------------------- /share/icons/com.bixense.PasswordCalculator.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 10 | 12 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /src/MyApp.cpp: -------------------------------------------------------------------------------- 1 | #include "MyApp.hpp" 2 | 3 | #include "MyFrame.hpp" 4 | 5 | bool MyApp::OnInit() { 6 | SetAppName("Password Calculator"); 7 | auto frame = new MyFrame; 8 | frame->Show(true); 9 | return true; 10 | } 11 | -------------------------------------------------------------------------------- /src/MyApp.hpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | class MyApp : public wxApp { 4 | public: 5 | virtual bool OnInit() override; 6 | }; 7 | -------------------------------------------------------------------------------- /src/MyFrame.cpp: -------------------------------------------------------------------------------- 1 | #include "MyFrame.hpp" 2 | 3 | #include "password.hpp" 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | enum { 10 | ID_ALIAS = wxID_HIGHEST + 1, 11 | ID_SECRET, 12 | }; 13 | 14 | MyFrame::MyFrame() 15 | : wxFrame(nullptr, wxID_ANY, wxTheApp->GetAppName()), panel(new wxPanel(this)), 16 | textAlias(new wxTextCtrl( 17 | panel, ID_ALIAS, "", wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER 18 | )), 19 | textSecret(new wxTextCtrl( 20 | panel, ID_SECRET, "", wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER | wxTE_PASSWORD 21 | )), 22 | icon( 23 | wxFileName(wxStandardPaths::Get().GetExecutablePath()).GetPath() + 24 | "/../share/icons/com.bixense.PasswordCalculator.svg" 25 | ) { 26 | #ifdef _WIN32 27 | SetIcon(wxICON(MAINICON)); 28 | #else 29 | SetIcon(icon); 30 | #endif 31 | auto vbox = new wxBoxSizer(wxVERTICAL); 32 | vbox->SetMinSize(200, 0); 33 | 34 | vbox->Add(new wxStaticText(panel, wxID_ANY, "Alias:"), 0, wxLEFT | wxRIGHT | wxTOP, 9); 35 | vbox->AddSpacer(2); 36 | vbox->Add( 37 | textAlias, 38 | 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 9 39 | ); 40 | vbox->Add(new wxStaticText(panel, wxID_ANY, "Secret:"), 0, wxLEFT | wxRIGHT | wxTOP, 9); 41 | vbox->AddSpacer(2); 42 | vbox->Add( 43 | textSecret, 44 | 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 9 45 | ); 46 | auto button = new wxButton(panel, wxID_ANY, "Copy to clipboard"); 47 | Connect( 48 | wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MyFrame::onCopyToClipboard) 49 | ); 50 | Connect(ID_ALIAS, wxEVT_TEXT_ENTER, wxCommandEventHandler(MyFrame::onCopyToClipboard)); 51 | Connect(ID_SECRET, wxEVT_TEXT_ENTER, wxCommandEventHandler(MyFrame::onCopyToClipboard)); 52 | button->SetDefault(); 53 | vbox->AddSpacer(9); 54 | vbox->Add( 55 | button, 1, wxEXPAND | wxALL, 9 56 | ); 57 | panel->SetSizer(vbox); 58 | vbox->SetSizeHints(this); 59 | 60 | SetMenuBar(new wxMenuBar); 61 | } 62 | 63 | void MyFrame::onCopyToClipboard(wxCommandEvent&) { 64 | std::string pw = calculatePassword( 65 | std::string(textSecret->GetLineText(0).ToUTF8()), 66 | std::string(textAlias->GetLineText(0).ToUTF8()) 67 | ); 68 | if (wxTheClipboard->Open()) { 69 | wxTheClipboard->SetData(new wxTextDataObject(pw)); 70 | wxTheClipboard->Flush(); 71 | wxTheClipboard->Close(); 72 | } 73 | textSecret->Clear(); 74 | Iconize(); // minimize 75 | } 76 | -------------------------------------------------------------------------------- /src/MyFrame.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | class MyFrame : public wxFrame { 6 | public: 7 | MyFrame(); 8 | private: 9 | void onCopyToClipboard(wxCommandEvent&); 10 | 11 | wxPanel* panel; 12 | wxTextCtrl* textAlias; 13 | wxTextCtrl* textSecret; 14 | wxTimer timer; 15 | wxIcon icon; 16 | }; 17 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "MyApp.hpp" 2 | 3 | wxIMPLEMENT_APP(MyApp); 4 | -------------------------------------------------------------------------------- /src/password.cpp: -------------------------------------------------------------------------------- 1 | #include "password.hpp" 2 | 3 | #include 4 | #if BOOST_VERSION > 106800 5 | #include 6 | #else 7 | #include 8 | #endif 9 | #include 10 | #include 11 | #include 12 | 13 | std::string encode64(const std::string& val) { 14 | using namespace boost::archive::iterators; 15 | using It = base64_from_binary>; 16 | auto tmp = std::string(It(std::begin(val)), It(std::end(val))); 17 | return tmp.append((3 - val.size() % 3) % 3, '='); 18 | } 19 | 20 | std::string calculatePassword(const std::string& secret, const std::string& alias) { 21 | std::string secretAndAlias = secret + alias; 22 | boost::uuids::detail::sha1 sha1; 23 | sha1.process_bytes(secretAndAlias.c_str(), secretAndAlias.size()); 24 | unsigned int digest[5]; 25 | sha1.get_digest(digest); 26 | std::string hash; 27 | hash.resize(20); 28 | for (size_t i = 0; i < 5; ++i) { 29 | // Swap byte order because of Little Endian 30 | const char* tmp = reinterpret_cast(digest); 31 | hash[i * 4 ] = tmp[i * 4 + 3]; 32 | hash[i * 4 + 1] = tmp[i * 4 + 2]; 33 | hash[i * 4 + 2] = tmp[i * 4 + 1]; 34 | hash[i * 4 + 3] = tmp[i * 4 ]; 35 | } 36 | return encode64(hash).substr(0, 16); 37 | } 38 | -------------------------------------------------------------------------------- /src/password.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | std::string calculatePassword(const std::string& secret, const std::string& alias); 6 | -------------------------------------------------------------------------------- /src/windows/installer.nsi: -------------------------------------------------------------------------------- 1 | ;-------------------------------- 2 | ;Include Modern UI 3 | 4 | !include "MUI2.nsh" 5 | 6 | SetCompressor /SOLID lzma 7 | !define MUI_ICON "pwcalculator.ico" 8 | !define MUI_PRODUCT "Password Calculator" 9 | 10 | ;-------------------------------- 11 | ;General 12 | 13 | Unicode true 14 | 15 | ;Name and file 16 | Name "${MUI_PRODUCT}" 17 | OutFile "${MUI_PRODUCT} Setup.exe" 18 | BrandingText "bixense.com/pwcalculator" 19 | 20 | ;Default installation folder 21 | InstallDir "$LOCALAPPDATA\Programs\${MUI_PRODUCT}" 22 | 23 | ;Get installation folder from registry if available 24 | InstallDirRegKey HKCU "Software\${MUI_PRODUCT}" "" 25 | 26 | ;Request application privileges for Windows Vista 27 | RequestExecutionLevel user 28 | 29 | ;-------------------------------- 30 | ;Pages 31 | 32 | !insertmacro MUI_PAGE_DIRECTORY 33 | !insertmacro MUI_PAGE_INSTFILES 34 | 35 | !insertmacro MUI_UNPAGE_CONFIRM 36 | !insertmacro MUI_UNPAGE_INSTFILES 37 | 38 | !define MUI_FINISHPAGE_RUN "$INSTDIR\pwcalculator.exe" 39 | !insertmacro MUI_PAGE_FINISH 40 | 41 | ;-------------------------------- 42 | ;Languages 43 | 44 | !insertmacro MUI_LANGUAGE "English" 45 | 46 | ;-------------------------------- 47 | ;Reserve Files 48 | 49 | ;If you are using solid compression, files that are required before 50 | ;the actual installation should be stored first in the data block, 51 | ;because this will make your installer start faster. 52 | 53 | !insertmacro MUI_RESERVEFILE_LANGDLL 54 | 55 | ;-------------------------------- 56 | ;Installer Sections 57 | 58 | Section "" SecUninstallPrevious 59 | Call UninstallPrevious 60 | SectionEnd 61 | 62 | Section "" 63 | 64 | Call UninstallPrevious 65 | 66 | SetOutPath "$INSTDIR" 67 | 68 | File C:\msys64\mingw64\bin\libstdc++-6.dll 69 | File C:\msys64\mingw64\bin\wxbase30u_gcc_custom.dll 70 | File C:\msys64\mingw64\bin\wxmsw30u_core_gcc_custom.dll 71 | File C:\msys64\mingw64\bin\libgcc_s_seh-1.dll 72 | File C:\msys64\mingw64\bin\libwinpthread-1.dll 73 | File C:\msys64\mingw64\bin\zlib1.dll 74 | File C:\msys64\mingw64\bin\libjpeg-8.dll 75 | File C:\msys64\mingw64\bin\libpng16-16.dll 76 | File C:\msys64\mingw64\bin\libtiff-5.dll 77 | File C:\msys64\mingw64\bin\liblzma-5.dll 78 | File ..\..\build\pwcalculator.exe 79 | 80 | CreateShortcut "$desktop\${MUI_PRODUCT}.lnk" "$instdir\pwcalculator.exe" 81 | 82 | ;Store installation folder 83 | WriteRegStr HKCU "Software\${MUI_PRODUCT}" "" $INSTDIR 84 | 85 | WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\${MUI_PRODUCT}" \ 86 | "DisplayName" "${MUI_PRODUCT}" 87 | WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\${MUI_PRODUCT}" \ 88 | "UninstallString" "$\"$INSTDIR\uninstall.exe$\"" 89 | WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\${MUI_PRODUCT}" \ 90 | "DisplayIcon" "$INSTDIR\pwcalculator.exe" 91 | WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\${MUI_PRODUCT}" \ 92 | "Publisher" "Bixense" 93 | WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\${MUI_PRODUCT}" \ 94 | "QuietUninstallString" "$\"$INSTDIR\uninstall.exe$\" /S" 95 | WriteUninstaller "$INSTDIR\Uninstall.exe" 96 | 97 | SectionEnd 98 | 99 | Function UninstallPrevious 100 | 101 | DetailPrint "Checking" 102 | ; Check for uninstaller. 103 | ReadRegStr $R0 HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\${MUI_PRODUCT}" \ 104 | "QuietUninstallString" 105 | 106 | ${If} $R0 == "" 107 | Goto Done 108 | ${EndIf} 109 | 110 | DetailPrint "Removing previous installation." 111 | 112 | ; Run the uninstaller silently. 113 | ExecWait $R0 114 | 115 | Done: 116 | 117 | FunctionEnd 118 | 119 | ;-------------------------------- 120 | ;Installer Functions 121 | 122 | Function .onInit 123 | 124 | !insertmacro MUI_LANGDLL_DISPLAY 125 | 126 | FunctionEnd 127 | 128 | ;-------------------------------- 129 | ;Uninstaller Section 130 | 131 | Section "Uninstall" 132 | 133 | Delete "$INSTDIR\Uninstall.exe" 134 | Delete "$desktop\${MUI_PRODUCT}.lnk" 135 | 136 | RMDir /r "$INSTDIR" 137 | 138 | DeleteRegKey /ifempty HKCU "Software\${MUI_PRODUCT}" 139 | DeleteRegKey /ifempty HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\${MUI_PRODUCT}" 140 | 141 | SectionEnd 142 | 143 | ;-------------------------------- 144 | ;Uninstaller Functions 145 | 146 | Function un.onInit 147 | 148 | !insertmacro MUI_UNGETLANGUAGE 149 | 150 | FunctionEnd 151 | -------------------------------------------------------------------------------- /src/windows/main.rc: -------------------------------------------------------------------------------- 1 | #include "wx/msw/wx.rc" 2 | 3 | MAINICON ICON "pwcalculator.ico" 4 | -------------------------------------------------------------------------------- /src/windows/pwcalculator.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhasse/pwcalculator/4691e1036fb1139b0c6c0ea43e54150493ac01e9/src/windows/pwcalculator.ico -------------------------------------------------------------------------------- /waf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhasse/pwcalculator/4691e1036fb1139b0c6c0ea43e54150493ac01e9/waf -------------------------------------------------------------------------------- /wscript: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import os 4 | import shutil 5 | import subprocess 6 | import sys 7 | import tempfile 8 | from waflib import Options, Configure, Logs 9 | Configure.autoconfig = True 10 | 11 | def options(ctx): 12 | ctx.load('compiler_cxx boost') 13 | if sys.platform in ["msys", "win32"]: 14 | ctx.load('winres') 15 | gr = ctx.get_option_group('configure options') 16 | gr.add_option('--release', action='store_true', help='build release binaries') 17 | 18 | def check_flag(ctx, flag): 19 | ctx.env.CXXFLAGS_TMP = '' 20 | if not ctx.check_cxx(cxxflags=[flag], msg="Checking for '{}'".format(flag), mandatory=False, 21 | uselib_store='TMP'): 22 | return False 23 | ctx.env.append_value('CXXFLAGS', ctx.env.CXXFLAGS_TMP) 24 | return True 25 | 26 | def configure(ctx): 27 | ctx.load('compiler_cxx boost') 28 | ctx.check_boost() 29 | if sys.platform in ["msys", "win32"]: 30 | ctx.load('winres') 31 | 32 | if Options.options.release: 33 | ctx.env.CXXFLAGS = ['-O2'] 34 | else: 35 | ctx.env.CXXFLAGS = ['-g'] 36 | 37 | if not check_flag(ctx, '-std=c++11'): 38 | ctx.env.append_value('CXXFLAGS', ['-std=c++0x']) 39 | ctx.env.append_value('CXXFLAGS', ['-Wall', '-Wextra']) 40 | 41 | if ((os.getenv("CLICOLOR", "1") != "0" and sys.stdout.isatty()) or 42 | os.getenv("CLICOLOR_FORCE", "0") != "0"): 43 | check_flag(ctx, '-fdiagnostics-color') 44 | ctx.check_cfg( 45 | path='wx-config', args='--cflags --libs', package='', 46 | uselib_store='WXWIDGETS', msg='Checking for wxWidgets', 47 | ) 48 | 49 | def build(ctx): 50 | source_files = ctx.path.ant_glob('src/*.cpp') 51 | if sys.platform in ["msys", "win32"]: 52 | source_files.append("src/windows/main.rc") 53 | ctx.program( 54 | source=source_files, 55 | target='pwcalculator', 56 | use='WXWIDGETS BOOST', 57 | ) 58 | 59 | ctx.install_files('${PREFIX}/share/applications', 'com.bixense.PasswordCalculator.desktop') 60 | ctx.install_files('${PREFIX}/share/icons', 'share/icons/com.bixense.PasswordCalculator.svg') 61 | ctx.install_files('${PREFIX}/share/appdata', 62 | 'share/appdata/com.bixense.PasswordCalculator.appdata.xml') 63 | 64 | def mac(ctx): 65 | if os.path.exists('Password Calculator.app'): 66 | Logs.warn('Password Calculator.app/ already exists, moving to trash.') 67 | if shutil.which('trash') is None: 68 | ctx.fatal('Please install trash command using `brew install trash`.') 69 | subprocess.check_call(['trash', 'Password Calculator.app']) 70 | 71 | with tempfile.TemporaryDirectory() as d: 72 | iconset = os.path.join(d, 'Password Calculator.iconset') 73 | os.mkdir(iconset) 74 | subprocess.check_call(['sips', '-z', '16', '16', 'pwcalculator.png', '--out', '{}/icon_16x16.png'.format(iconset)]) 75 | subprocess.check_call(['sips', '-z', '32', '32', 'pwcalculator.png', '--out', '{}/icon_16x16@2x.png'.format(iconset)]) 76 | subprocess.check_call(['sips', '-z', '32', '32', 'pwcalculator.png', '--out', '{}/icon_32x32.png'.format(iconset)]) 77 | subprocess.check_call(['sips', '-z', '64', '64', 'pwcalculator.png', '--out', '{}/icon_32x32@2x.png'.format(iconset)]) 78 | subprocess.check_call(['sips', '-z', '128', '128', 'pwcalculator.png', '--out', '{}/icon_128x128.png'.format(iconset)]) 79 | shutil.copyfile('pwcalculator.png', '{}/icon_128x128@2x.png'.format(iconset)) 80 | shutil.copyfile('pwcalculator.png', '{}/icon_256x256.png'.format(iconset)) 81 | subprocess.check_call(['iconutil', '-c', 'icns', iconset]) 82 | 83 | res_dir = 'Password Calculator.app/Contents/Resources/' 84 | os.makedirs(res_dir) 85 | shutil.move(os.path.join(d, 'Password Calculator.icns'), res_dir) 86 | 87 | macos_dir = 'Password Calculator.app/Contents/MacOS/' 88 | os.makedirs(macos_dir) 89 | shutil.copy('build/pwcalculator', macos_dir) 90 | 91 | frameworks_dir = 'Password Calculator.app/Contents/Frameworks/' 92 | os.makedirs(frameworks_dir) 93 | subprocess.check_call(['dylibbundler', '-p', '@executable_path/../Frameworks/', '-x', "'" + macos_dir + 'pwcalculator' + "'", '-b', '-cd', '-d', "'" + frameworks_dir + "'"]) 94 | 95 | for dirpath, dirs, files in os.walk(frameworks_dir): 96 | for f in files: 97 | fn = os.path.join(dirpath, f) 98 | subprocess.check_call([ 99 | 'codesign', '--options=runtime', '--verify', '--verbose', '--sign', 100 | 'Developer ID Application: Jan Niklas Hasse (4DMBNMNYSA)', fn 101 | ]) 102 | 103 | with open('Password Calculator.app/Contents/Info.plist', 'w') as info: 104 | info.write(''' 105 | 106 | 107 | 108 | CFBundleName 109 | Password Calculator 110 | CFBundleDisplayName 111 | Password Calculator 112 | CFBundleIdentifier 113 | com.bixense.PasswordCalculator 114 | CFBundleVersion 115 | 1.0.0 116 | CFBundlePackageType 117 | APPL 118 | CFBundleExecutable 119 | pwcalculator 120 | CFBundleIconFile 121 | Password Calculator 122 | NSPrincipalClass 123 | NSApplication 124 | 125 | ''') 126 | 127 | subprocess.check_call(['codesign', '--options=runtime', '--verify', '--verbose', '--sign', 128 | 'Developer ID Application: Jan Niklas Hasse (4DMBNMNYSA)', 'Password Calculator.app']) 129 | 130 | Logs.info('App Bundle created. Zip it using `zip -r pwcalculator.zip Password\\ Calculator.app`.') 131 | Logs.info('Then run `xcrun altool --notarize-app --primary-bundle-id ' 132 | '"com.bixense.PasswordCalculator" --username --password ' 133 | '--asc-provider --file ' 134 | 'pwcalculator.zip` to notarize the app.') 135 | Logs.info('After notarization finishes, run `xcrun stapler staple Password\\ Calculator.app`') --------------------------------------------------------------------------------