├── LICENSE ├── README.md ├── doc ├── pebbleauth_qr.png ├── pebbleauth_watch1_50.png ├── pebbleauth_watch2_50.png ├── pebbleauth_watch3_50.png └── pebbleauth_watch4_50.png ├── html ├── v20 │ ├── assets │ │ ├── Thumbs.db │ │ ├── font_style_1.png │ │ ├── font_style_2.png │ │ ├── font_style_3.png │ │ └── font_style_4.png │ ├── index.htm │ └── script.js ├── v21 │ ├── assets │ │ ├── Thumbs.db │ │ ├── font_style_1.png │ │ ├── font_style_2.png │ │ ├── font_style_3.png │ │ └── font_style_4.png │ ├── index.htm │ └── script.js ├── v22 │ ├── assets │ │ ├── Thumbs.db │ │ ├── font_style_1.png │ │ ├── font_style_2.png │ │ ├── font_style_3.png │ │ └── font_style_4.png │ ├── index.htm │ └── script.js ├── v23 │ ├── assets │ │ ├── Thumbs.db │ │ ├── og │ │ │ ├── font_style_1.png │ │ │ ├── font_style_2.png │ │ │ ├── font_style_3.png │ │ │ ├── font_style_4.png │ │ │ └── multi_code_layout.png │ │ └── time │ │ │ ├── font_style_1.png │ │ │ ├── font_style_2.png │ │ │ ├── font_style_3.png │ │ │ ├── font_style_4.png │ │ │ └── multi_code_layout.png │ ├── index.htm │ ├── pebble-og.css │ ├── pebble-time.css │ └── script.js ├── v24 │ ├── OLD │ │ ├── assets │ │ │ ├── Thumbs.db │ │ │ ├── og │ │ │ │ ├── font_style_1.png │ │ │ │ ├── font_style_2.png │ │ │ │ ├── font_style_3.png │ │ │ │ ├── font_style_4.png │ │ │ │ └── multi_code_layout.png │ │ │ └── time │ │ │ │ ├── font_style_1.png │ │ │ │ ├── font_style_2.png │ │ │ │ ├── font_style_3.png │ │ │ │ ├── font_style_4.png │ │ │ │ └── multi_code_layout.png │ │ ├── index.htm │ │ ├── pebble-og.css │ │ ├── pebble-time.css │ │ └── script.js │ ├── assets │ │ ├── Thumbs.db │ │ ├── og │ │ │ ├── font_style_1.png │ │ │ ├── font_style_2.png │ │ │ ├── font_style_3.png │ │ │ ├── font_style_4.png │ │ │ ├── multi_code_layout.png │ │ │ ├── screenshot_holder_1.png │ │ │ └── screenshot_holder_2.png │ │ └── time │ │ │ ├── font_style_1.png │ │ │ ├── font_style_2.png │ │ │ ├── font_style_3.png │ │ │ ├── font_style_4.png │ │ │ ├── multi_code_layout.png │ │ │ └── screenshot_holder_3.png │ ├── index.htm │ ├── pebble-1.css │ ├── pebble-2.css │ ├── pebble-3.css │ └── script.js ├── v25 │ ├── OLD │ │ ├── assets │ │ │ ├── Thumbs.db │ │ │ ├── og │ │ │ │ ├── font_style_1.png │ │ │ │ ├── font_style_2.png │ │ │ │ ├── font_style_3.png │ │ │ │ ├── font_style_4.png │ │ │ │ └── multi_code_layout.png │ │ │ └── time │ │ │ │ ├── font_style_1.png │ │ │ │ ├── font_style_2.png │ │ │ │ ├── font_style_3.png │ │ │ │ ├── font_style_4.png │ │ │ │ └── multi_code_layout.png │ │ ├── index.htm │ │ ├── pebble-og.css │ │ ├── pebble-time.css │ │ └── script.js │ ├── assets │ │ ├── Thumbs.db │ │ ├── og │ │ │ ├── font_style_1.png │ │ │ ├── font_style_2.png │ │ │ ├── font_style_3.png │ │ │ ├── font_style_4.png │ │ │ ├── multi_code_layout.png │ │ │ ├── screenshot_holder_1.png │ │ │ └── screenshot_holder_2.png │ │ └── time │ │ │ ├── font_style_1.png │ │ │ ├── font_style_2.png │ │ │ ├── font_style_3.png │ │ │ ├── font_style_4.png │ │ │ ├── multi_code_layout.png │ │ │ └── screenshot_holder_3.png │ ├── index.htm │ ├── pebble-1.css │ ├── pebble-2.css │ ├── pebble-3.css │ └── script.js ├── v4 │ ├── assets │ │ ├── Thumbs.db │ │ ├── font_style_1.png │ │ ├── font_style_2.png │ │ ├── font_style_3.png │ │ └── font_style_4.png │ ├── index.htm │ └── script.js ├── v5 │ ├── assets │ │ ├── Thumbs.db │ │ ├── font_style_1.png │ │ ├── font_style_2.png │ │ ├── font_style_3.png │ │ └── font_style_4.png │ ├── index.htm │ └── script.js ├── v6 │ ├── assets │ │ ├── Thumbs.db │ │ ├── font_style_1.png │ │ ├── font_style_2.png │ │ ├── font_style_3.png │ │ └── font_style_4.png │ └── index.htm └── v7 │ ├── assets │ ├── Thumbs.db │ ├── font_style_1.png │ ├── font_style_2.png │ ├── font_style_3.png │ └── font_style_4.png │ ├── index.htm │ └── script.js ├── package.json ├── resources ├── fonts │ ├── BD_Cartoon_Shout.ttf │ ├── BITWISE_32.ttf │ ├── DS-DIGIB.TTF │ ├── ORBITRON_28.ttf │ └── UNISPACE_20.ttf └── images │ ├── Padlock_aplite.png │ ├── Padlock_aplite~color.png │ ├── Pebble_Bin.png │ ├── Pebble_Bin~color.png │ ├── Pebble_Star2.png │ ├── Pebble_Star2~color.png │ ├── SimpleFadeBottom.png │ ├── SimpleFadeTop.png │ └── auth_icon.png ├── src ├── c │ ├── base32.c │ ├── base32.h │ ├── display.h │ ├── display_round.c │ ├── display_square.c │ ├── dod_window.c │ ├── dod_window.h │ ├── google-authenticator.c │ ├── google-authenticator.h │ ├── hmac.c │ ├── hmac.h │ ├── main.c │ ├── main.h │ ├── multi_code_window.c │ ├── multi_code_window.h │ ├── select_window.c │ ├── select_window.h │ ├── sha1.c │ ├── sha1.h │ ├── single_code_window.c │ └── single_code_window.h └── pkjs │ ├── app.js │ └── config.js └── wscript /README.md: -------------------------------------------------------------------------------- 1 | QuickAuth 2 | ========== 3 | 4 | Google Authenticator for the Pebble smart watch! 5 | 6 |     7 | 8 | The app can store up to 16 keys. You must use 20 or less characters for the label although not all fonts can display 20 characters on the tiny Pebble screen. It's been tested with 128 character keys which should cover all uses! When adding any keys, known incorrect characters are corrected and spaces are removed. Once the keys have been uploaded they'll be saved on the watch and will only be removed during an upgrade. But don't worry the keys are also stored in the Pebble phone app and reloaded in the event of an upgrade or factory reset of the watch. 9 | 10 | The authentication codes are based on time and timezones are also automatically handled. (In case of time zone errors, just reboot your phone and watch.) 11 | 12 | There's a [great guide by Adam Zeis](http://www.connectedly.com/how-get-your-two-step-verification-codes-your-pebble) that explains how to setup the app to work with your Google account. 13 | 14 | Happy two-factoring! 15 | 16 | 17 | ### GET IT HERE 18 | 19 |  20 | 21 | [](http://pblweb.com/appstore/53131df8bb31cf87cd00019a) -------------------------------------------------------------------------------- /doc/pebbleauth_qr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/doc/pebbleauth_qr.png -------------------------------------------------------------------------------- /doc/pebbleauth_watch1_50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/doc/pebbleauth_watch1_50.png -------------------------------------------------------------------------------- /doc/pebbleauth_watch2_50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/doc/pebbleauth_watch2_50.png -------------------------------------------------------------------------------- /doc/pebbleauth_watch3_50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/doc/pebbleauth_watch3_50.png -------------------------------------------------------------------------------- /doc/pebbleauth_watch4_50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/doc/pebbleauth_watch4_50.png -------------------------------------------------------------------------------- /html/v20/assets/Thumbs.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v20/assets/Thumbs.db -------------------------------------------------------------------------------- /html/v20/assets/font_style_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v20/assets/font_style_1.png -------------------------------------------------------------------------------- /html/v20/assets/font_style_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v20/assets/font_style_2.png -------------------------------------------------------------------------------- /html/v20/assets/font_style_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v20/assets/font_style_3.png -------------------------------------------------------------------------------- /html/v20/assets/font_style_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v20/assets/font_style_4.png -------------------------------------------------------------------------------- /html/v20/script.js: -------------------------------------------------------------------------------- 1 | $(function () { 2 | $('#foreground-color').on('click', function (event) { 3 | changeForeground = true; 4 | highlightColorBox($(this)); 5 | }); 6 | }); 7 | 8 | $(function () { 9 | $('#background-color').on('click', function (event) { 10 | changeForeground = false; 11 | highlightColorBox($(this)); 12 | }); 13 | }); 14 | 15 | $(function () { 16 | $('#color-picker .color-box').on('click', function (event) { 17 | var selected_color = rgb2hex($(this).css("background-color")); 18 | 19 | if (changeForeground) 20 | $('#foreground-color').css('background-color', selected_color); 21 | else 22 | $('#background-color').css('background-color', selected_color); 23 | $( "#color-picker" ).popup( "close" ); 24 | }); 25 | }); 26 | 27 | $(function () { 28 | $("#confirm_delete_all").click(function() { 29 | console.log("Deleting all"); 30 | var options = {}; 31 | options.delete_all = 1; 32 | var location = "pebblejs://close#" + encodeURIComponent(JSON.stringify(options)); 33 | document.location = location; 34 | }); 35 | }); 36 | 37 | $(function () { 38 | $("#cancel").click(function() { 39 | console.log("Cancelling"); 40 | document.location = "pebblejs://close"; 41 | }); 42 | }); 43 | 44 | $(function () { 45 | $("#save").click(function() { 46 | console.log("Submit"); 47 | 48 | var options = saveOptions(); 49 | 50 | if (options.secret && base32length(options.secret) < 10) { 51 | alert("Secret key value is too short"); 52 | } 53 | else if (options.secret && options.label.length === 0) { 54 | alert("Please enter a label"); 55 | } 56 | else { 57 | var return_to = getQueryParam('return_to', 'pebblejs://close#'); 58 | var location = return_to + encodeURIComponent(JSON.stringify(options)); 59 | console.log("Warping to:"); 60 | console.log(location); 61 | document.location = location; 62 | } 63 | }); 64 | }); 65 | 66 | function highlightColorBox($colorButton) { 67 | selectedColor = rgb2hex($colorButton.css("background-color")); 68 | 69 | var i; 70 | for (i = 1; i <= 13; i++) 71 | { 72 | $('#color-row'+i).children().removeClass("selected-color-box"); 73 | } 74 | $('#color-box-'+selectedColor.substring(1).toUpperCase()).addClass("selected-color-box"); 75 | } 76 | 77 | //Function to convert hex format to a rgb color 78 | function rgb2hex(rgb){ 79 | rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/); 80 | return ("#" + 81 | ("0" + parseInt(rgb[1],10).toString(16)).slice(-2) + 82 | ("0" + parseInt(rgb[2],10).toString(16)).slice(-2) + 83 | ("0" + parseInt(rgb[3],10).toString(16)).slice(-2)).toUpperCase(); 84 | } 85 | 86 | function queryObj() { 87 | var result = {}, keyValuePairs = location.search.slice(1).split('&'); 88 | 89 | keyValuePairs.forEach(function(keyValuePair) { 90 | keyValuePair = keyValuePair.split('='); 91 | result[keyValuePair[0]] = keyValuePair[1] || ''; 92 | }); 93 | 94 | return result; 95 | } 96 | 97 | function getQueryParam(variable, default_) { 98 | var query = location.search.substring(1); 99 | var vars = query.split('&'); 100 | for (var i = 0; i < vars.length; i++) { 101 | var pair = vars[i].split('='); 102 | if (pair[0] == variable) 103 | return decodeURIComponent(pair[1]); 104 | } 105 | return default_ || false; 106 | } 107 | 108 | function isNumber(n) { 109 | return !isNaN(parseFloat(n)) && isFinite(n); 110 | } 111 | 112 | // Base32 decoder from https://github.com/agnoster/base32-js/blob/master/lib/base32.js by Isaac Wolkerstorfer 113 | var alphabet = '0123456789abcdefghjkmnpqrtuvwxyz' 114 | var alias = { o:0, i:1, l:1, s:5 } 115 | 116 | var lookup = function() { 117 | var table = {} 118 | // Invert 'alphabet' 119 | for (var i = 0; i < alphabet.length; i++) { 120 | table[alphabet[i]] = i 121 | } 122 | // Splice in 'alias' 123 | for (var key in alias) { 124 | if (!alias.hasOwnProperty(key)) continue 125 | table[key] = table['' + alias[key]] 126 | } 127 | lookup = function() { return table } 128 | return table 129 | } 130 | 131 | function Decoder() { 132 | var skip = 0 // how many bits we have from the previous character 133 | var byte = 0 // current byte we're producing 134 | 135 | this.output = '' 136 | 137 | // Consume a character from the stream, store 138 | // the output in this.output. As before, better 139 | // to use update(). 140 | this.readChar = function(char) { 141 | if (typeof char != 'string'){ 142 | if (typeof char == 'number') { 143 | char = String.fromCharCode(char) 144 | } 145 | } 146 | char = char.toLowerCase() 147 | var val = lookup()[char] 148 | if (typeof val == 'undefined') { 149 | // character does not exist in our lookup table 150 | return // skip silently. An alternative would be: 151 | // throw Error('Could not find character "' + char + '" in lookup table.') 152 | } 153 | val <<= 3 // move to the high bits 154 | byte |= val >>> skip 155 | skip += 5 156 | if (skip >= 8) { 157 | // we have enough to preduce output 158 | this.output += String.fromCharCode(byte) 159 | skip -= 8 160 | if (skip > 0) byte = (val << (5 - skip)) & 255 161 | else byte = 0 162 | } 163 | 164 | } 165 | 166 | this.finish = function(check) { 167 | var output = this.output + (skip < 0 ? alphabet[bits >> 3] : '') + (check ? '$' : '') 168 | this.output = '' 169 | return output 170 | } 171 | } 172 | 173 | Decoder.prototype.update = function(input, flush) { 174 | for (var i = 0; i < input.length; i++) { 175 | this.readChar(input[i]) 176 | } 177 | var output = this.output 178 | this.output = '' 179 | if (flush) { 180 | output += this.finish() 181 | } 182 | return output 183 | } 184 | 185 | // Base32-encoded string goes in, decoded data comes out. 186 | function decode(input) { 187 | var decoder = new Decoder() 188 | var output = decoder.update(input, true) 189 | return output 190 | } 191 | 192 | function base32length(secret) { 193 | return decode(secret).length; 194 | } 195 | 196 | function saveOptions() { 197 | 198 | var options = {}; 199 | 200 | options.theme = parseInt($("input[name=theme]:checked").val(), 10); 201 | options.font_style = parseInt($("input[name=font_style]:checked").val(), 10); 202 | options.idle_timeout = parseInt($("#idle_timeout").val(), 10); 203 | 204 | var colors = rgb2hex($('#background-color').css("background-color")).replace("#", ''); 205 | colors = colors + rgb2hex($('#foreground-color').css("background-color")).replace("#", ''); 206 | options.basalt_colors = colors; 207 | 208 | if ($("#keysecret").val()) { 209 | options.label = $("#keyname").val(); 210 | options.secret = $("#keysecret").val().replace(/\s/g, ''); 211 | } 212 | 213 | return options; 214 | } 215 | 216 | $("document").ready(function() { 217 | var watch_version = getQueryParam("watch_version", 1); 218 | 219 | if (watch_version >= 3) { 220 | var basalt_colors = getQueryParam("basalt_colors", 0); 221 | basalt_colors = basalt_colors.length == 12 ? basalt_colors : "00AAFFFFFFFF"; 222 | $('#background-color').css('background-color', "#"+basalt_colors.substring(0,6)); 223 | $('#foreground-color').css('background-color', "#"+basalt_colors.substring(6,12)); 224 | $('#time-foreground').removeClass("hidden"); 225 | $('#time-background').removeClass("hidden"); 226 | } else { 227 | var theme = getQueryParam("theme", 0); 228 | theme = parseInt(isNumber(theme) && theme <= 1 ? theme : 0); 229 | $('#theme').removeClass("hidden"); 230 | $('#theme_'+theme).prop( "checked", true ).checkboxradio("refresh"); 231 | } 232 | 233 | var otp_count = getQueryParam("otp_count", 0); 234 | var font_style = getQueryParam("font_style", 0); 235 | var idle_timeout = getQueryParam("idle_timeout", 300); 236 | 237 | font_style = parseInt(isNumber(font_style) && font_style <= 3 ? font_style : 0); 238 | idle_timeout = parseInt(isNumber(idle_timeout) && (idle_timeout >= 0 || idle_timeout == 60 || idle_timeout == 120 || idle_timeout == 300 || idle_timeout == 600) ? idle_timeout : 300); 239 | 240 | $('#font_style_'+font_style).prop( "checked", true ).checkboxradio("refresh"); 241 | $("#idle_timeout").val(idle_timeout).selectmenu("refresh"); 242 | 243 | otp_count = parseInt(isNumber(otp_count) ? otp_count : 0); 244 | var slots_remaining = 16 - otp_count; 245 | 246 | if (slots_remaining === 0) { 247 | document.getElementById("keyname").disabled=true; 248 | document.getElementById("keysecret").disabled=true; 249 | } 250 | document.getElementById("footer").innerHTML=document.getElementById("footer").innerHTML.replace("NUM_SPACES", slots_remaining); 251 | }); -------------------------------------------------------------------------------- /html/v21/assets/Thumbs.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v21/assets/Thumbs.db -------------------------------------------------------------------------------- /html/v21/assets/font_style_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v21/assets/font_style_1.png -------------------------------------------------------------------------------- /html/v21/assets/font_style_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v21/assets/font_style_2.png -------------------------------------------------------------------------------- /html/v21/assets/font_style_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v21/assets/font_style_3.png -------------------------------------------------------------------------------- /html/v21/assets/font_style_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v21/assets/font_style_4.png -------------------------------------------------------------------------------- /html/v21/script.js: -------------------------------------------------------------------------------- 1 | $(function () { 2 | $('#foreground-color').on('click', function (event) { 3 | changeForeground = true; 4 | highlightColorBox($(this)); 5 | }); 6 | }); 7 | 8 | $(function () { 9 | $('#background-color').on('click', function (event) { 10 | changeForeground = false; 11 | highlightColorBox($(this)); 12 | }); 13 | }); 14 | 15 | $(function () { 16 | $('#color-picker .color-box').on('click', function (event) { 17 | var selected_color = rgb2hex($(this).css("background-color")); 18 | 19 | if (changeForeground) 20 | $('#foreground-color').css('background-color', selected_color); 21 | else 22 | $('#background-color').css('background-color', selected_color); 23 | $( "#color-picker" ).popup( "close" ); 24 | }); 25 | }); 26 | 27 | $(function () { 28 | $("#confirm_delete_all").click(function() { 29 | console.log("Deleting all"); 30 | var options = {}; 31 | options.delete_all = 1; 32 | var location = "pebblejs://close#" + encodeURIComponent(JSON.stringify(options)); 33 | document.location = location; 34 | }); 35 | }); 36 | 37 | $(function () { 38 | $("#cancel").click(function() { 39 | console.log("Cancelling"); 40 | document.location = "pebblejs://close"; 41 | }); 42 | }); 43 | 44 | $(function () { 45 | $("#save").click(function() { 46 | console.log("Submit"); 47 | 48 | var options = saveOptions(); 49 | 50 | if (options.secret && base32length(options.secret) < 10) { 51 | alert("Secret key value is too short"); 52 | } 53 | else if (options.secret && options.label.length === 0) { 54 | alert("Please enter a label"); 55 | } 56 | else { 57 | var return_to = getQueryParam('return_to', 'pebblejs://close#'); 58 | var location = return_to + encodeURIComponent(JSON.stringify(options)); 59 | console.log("Warping to:"); 60 | console.log(location); 61 | document.location = location; 62 | } 63 | }); 64 | }); 65 | 66 | function highlightColorBox($colorButton) { 67 | selectedColor = rgb2hex($colorButton.css("background-color")); 68 | 69 | var i; 70 | for (i = 1; i <= 13; i++) 71 | { 72 | $('#color-row'+i).children().removeClass("selected-color-box"); 73 | } 74 | $('#color-box-'+selectedColor.substring(1).toUpperCase()).addClass("selected-color-box"); 75 | } 76 | 77 | //Function to convert hex format to a rgb color 78 | function rgb2hex(rgb){ 79 | rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/); 80 | return ("#" + 81 | ("0" + parseInt(rgb[1],10).toString(16)).slice(-2) + 82 | ("0" + parseInt(rgb[2],10).toString(16)).slice(-2) + 83 | ("0" + parseInt(rgb[3],10).toString(16)).slice(-2)).toUpperCase(); 84 | } 85 | 86 | function queryObj() { 87 | var result = {}, keyValuePairs = location.search.slice(1).split('&'); 88 | 89 | keyValuePairs.forEach(function(keyValuePair) { 90 | keyValuePair = keyValuePair.split('='); 91 | result[keyValuePair[0]] = keyValuePair[1] || ''; 92 | }); 93 | 94 | return result; 95 | } 96 | 97 | function getQueryParam(variable, default_) { 98 | var query = location.search.substring(1); 99 | var vars = query.split('&'); 100 | for (var i = 0; i < vars.length; i++) { 101 | var pair = vars[i].split('='); 102 | if (pair[0] == variable) 103 | return decodeURIComponent(pair[1]); 104 | } 105 | return default_ || false; 106 | } 107 | 108 | function isNumber(n) { 109 | return !isNaN(parseFloat(n)) && isFinite(n); 110 | } 111 | 112 | // Base32 decoder from https://github.com/agnoster/base32-js/blob/master/lib/base32.js by Isaac Wolkerstorfer 113 | var alphabet = '0123456789abcdefghjkmnpqrtuvwxyz' 114 | var alias = { o:0, i:1, l:1, s:5 } 115 | 116 | var lookup = function() { 117 | var table = {} 118 | // Invert 'alphabet' 119 | for (var i = 0; i < alphabet.length; i++) { 120 | table[alphabet[i]] = i 121 | } 122 | // Splice in 'alias' 123 | for (var key in alias) { 124 | if (!alias.hasOwnProperty(key)) continue 125 | table[key] = table['' + alias[key]] 126 | } 127 | lookup = function() { return table } 128 | return table 129 | } 130 | 131 | function Decoder() { 132 | var skip = 0 // how many bits we have from the previous character 133 | var byte = 0 // current byte we're producing 134 | 135 | this.output = '' 136 | 137 | // Consume a character from the stream, store 138 | // the output in this.output. As before, better 139 | // to use update(). 140 | this.readChar = function(char) { 141 | if (typeof char != 'string'){ 142 | if (typeof char == 'number') { 143 | char = String.fromCharCode(char) 144 | } 145 | } 146 | char = char.toLowerCase() 147 | var val = lookup()[char] 148 | if (typeof val == 'undefined') { 149 | // character does not exist in our lookup table 150 | return // skip silently. An alternative would be: 151 | // throw Error('Could not find character "' + char + '" in lookup table.') 152 | } 153 | val <<= 3 // move to the high bits 154 | byte |= val >>> skip 155 | skip += 5 156 | if (skip >= 8) { 157 | // we have enough to preduce output 158 | this.output += String.fromCharCode(byte) 159 | skip -= 8 160 | if (skip > 0) byte = (val << (5 - skip)) & 255 161 | else byte = 0 162 | } 163 | 164 | } 165 | 166 | this.finish = function(check) { 167 | var output = this.output + (skip < 0 ? alphabet[bits >> 3] : '') + (check ? '$' : '') 168 | this.output = '' 169 | return output 170 | } 171 | } 172 | 173 | Decoder.prototype.update = function(input, flush) { 174 | for (var i = 0; i < input.length; i++) { 175 | this.readChar(input[i]) 176 | } 177 | var output = this.output 178 | this.output = '' 179 | if (flush) { 180 | output += this.finish() 181 | } 182 | return output 183 | } 184 | 185 | // Base32-encoded string goes in, decoded data comes out. 186 | function decode(input) { 187 | var decoder = new Decoder() 188 | var output = decoder.update(input, true) 189 | return output 190 | } 191 | 192 | function base32length(secret) { 193 | return decode(secret).length; 194 | } 195 | 196 | function saveOptions() { 197 | 198 | var options = {}; 199 | 200 | options.theme = parseInt($("input[name=theme]:checked").val(), 10); 201 | options.font_style = parseInt($("input[name=font_style]:checked").val(), 10); 202 | options.idle_timeout = parseInt($("#idle_timeout").val(), 10); 203 | 204 | var colors = rgb2hex($('#background-color').css("background-color")).replace("#", ''); 205 | colors = colors + rgb2hex($('#foreground-color').css("background-color")).replace("#", ''); 206 | options.basalt_colors = colors; 207 | 208 | if ($("#keysecret").val()) { 209 | options.label = $("#keyname").val(); 210 | options.secret = $("#keysecret").val().replace(/\s/g, ''); 211 | } 212 | 213 | return options; 214 | } 215 | 216 | $("document").ready(function() { 217 | var watch_version = getQueryParam("watch_version", 1); 218 | 219 | if (watch_version >= 3) { 220 | var basalt_colors = getQueryParam("basalt_colors", 0); 221 | basalt_colors = basalt_colors.length == 12 ? basalt_colors : "00AAFFFFFFFF"; 222 | $('#background-color').css('background-color', "#"+basalt_colors.substring(0,6)); 223 | $('#foreground-color').css('background-color', "#"+basalt_colors.substring(6,12)); 224 | $('#time-foreground').removeClass("hidden"); 225 | $('#time-background').removeClass("hidden"); 226 | } else { 227 | var theme = getQueryParam("theme", 0); 228 | theme = parseInt(isNumber(theme) && theme <= 1 ? theme : 0); 229 | $('#theme').removeClass("hidden"); 230 | $('#theme_'+theme).prop( "checked", true ).checkboxradio("refresh"); 231 | } 232 | 233 | var otp_count = getQueryParam("otp_count", 0); 234 | var font_style = getQueryParam("font_style", 0); 235 | var idle_timeout = getQueryParam("idle_timeout", 300); 236 | 237 | font_style = parseInt(isNumber(font_style) && font_style <= 3 ? font_style : 0); 238 | idle_timeout = parseInt(isNumber(idle_timeout) && (idle_timeout >= 0 || idle_timeout == 60 || idle_timeout == 120 || idle_timeout == 300 || idle_timeout == 600) ? idle_timeout : 300); 239 | 240 | $('#font_style_'+font_style).prop( "checked", true ).checkboxradio("refresh"); 241 | $("#idle_timeout").val(idle_timeout).selectmenu("refresh"); 242 | 243 | otp_count = parseInt(isNumber(otp_count) ? otp_count : 0); 244 | var slots_remaining = 16 - otp_count; 245 | 246 | if (slots_remaining === 0) { 247 | document.getElementById("keyname").disabled=true; 248 | document.getElementById("keysecret").disabled=true; 249 | } 250 | document.getElementById("footer").innerHTML=document.getElementById("footer").innerHTML.replace("NUM_SPACES", slots_remaining); 251 | }); -------------------------------------------------------------------------------- /html/v22/assets/Thumbs.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v22/assets/Thumbs.db -------------------------------------------------------------------------------- /html/v22/assets/font_style_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v22/assets/font_style_1.png -------------------------------------------------------------------------------- /html/v22/assets/font_style_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v22/assets/font_style_2.png -------------------------------------------------------------------------------- /html/v22/assets/font_style_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v22/assets/font_style_3.png -------------------------------------------------------------------------------- /html/v22/assets/font_style_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v22/assets/font_style_4.png -------------------------------------------------------------------------------- /html/v22/script.js: -------------------------------------------------------------------------------- 1 | $(function () { 2 | $('#foreground-color').on('click', function (event) { 3 | changeForeground = true; 4 | highlightColorBox($(this)); 5 | }); 6 | }); 7 | 8 | $(function () { 9 | $('#background-color').on('click', function (event) { 10 | changeForeground = false; 11 | highlightColorBox($(this)); 12 | }); 13 | }); 14 | 15 | $(function () { 16 | $('#color-picker .color-box').on('click', function (event) { 17 | var selected_color = rgb2hex($(this).css("background-color")); 18 | 19 | if (changeForeground) 20 | $('#foreground-color').css('background-color', selected_color); 21 | else 22 | $('#background-color').css('background-color', selected_color); 23 | $( "#color-picker" ).popup( "close" ); 24 | }); 25 | }); 26 | 27 | $(function () { 28 | $("#confirm_delete_all").click(function() { 29 | console.log("Deleting all"); 30 | var options = {}; 31 | options.delete_all = 1; 32 | var location = "pebblejs://close#" + encodeURIComponent(JSON.stringify(options)); 33 | document.location = location; 34 | }); 35 | }); 36 | 37 | $(function () { 38 | $("#cancel").click(function() { 39 | console.log("Cancelling"); 40 | document.location = "pebblejs://close"; 41 | }); 42 | }); 43 | 44 | $(function () { 45 | $("#save").click(function() { 46 | console.log("Submit"); 47 | 48 | var options = saveOptions(); 49 | 50 | if (options.secret && base32length(options.secret) < 10) { 51 | alert("Secret key value is too short"); 52 | } 53 | else if (options.secret && options.label.length === 0) { 54 | alert("Please enter a label"); 55 | } 56 | else { 57 | var return_to = getQueryParam('return_to', 'pebblejs://close#'); 58 | var location = return_to + encodeURIComponent(JSON.stringify(options)); 59 | console.log("Warping to:"); 60 | console.log(location); 61 | document.location = location; 62 | } 63 | }); 64 | }); 65 | 66 | function highlightColorBox($colorButton) { 67 | selectedColor = rgb2hex($colorButton.css("background-color")); 68 | 69 | var i; 70 | for (i = 1; i <= 13; i++) 71 | { 72 | $('#color-row'+i).children().removeClass("selected-color-box"); 73 | } 74 | $('#color-box-'+selectedColor.substring(1).toUpperCase()).addClass("selected-color-box"); 75 | } 76 | 77 | //Function to convert hex format to a rgb color 78 | function rgb2hex(rgb){ 79 | rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/); 80 | return ("#" + 81 | ("0" + parseInt(rgb[1],10).toString(16)).slice(-2) + 82 | ("0" + parseInt(rgb[2],10).toString(16)).slice(-2) + 83 | ("0" + parseInt(rgb[3],10).toString(16)).slice(-2)).toUpperCase(); 84 | } 85 | 86 | function queryObj() { 87 | var result = {}, keyValuePairs = location.search.slice(1).split('&'); 88 | 89 | keyValuePairs.forEach(function(keyValuePair) { 90 | keyValuePair = keyValuePair.split('='); 91 | result[keyValuePair[0]] = keyValuePair[1] || ''; 92 | }); 93 | 94 | return result; 95 | } 96 | 97 | function getQueryParam(variable, default_) { 98 | var query = location.search.substring(1); 99 | var vars = query.split('&'); 100 | for (var i = 0; i < vars.length; i++) { 101 | var pair = vars[i].split('='); 102 | if (pair[0] == variable) 103 | return decodeURIComponent(pair[1]); 104 | } 105 | return default_ || false; 106 | } 107 | 108 | function isNumber(n) { 109 | return !isNaN(parseFloat(n)) && isFinite(n); 110 | } 111 | 112 | // Base32 decoder from https://github.com/agnoster/base32-js/blob/master/lib/base32.js by Isaac Wolkerstorfer 113 | var alphabet = '0123456789abcdefghjkmnpqrtuvwxyz' 114 | var alias = { o:0, i:1, l:1, s:5 } 115 | 116 | var lookup = function() { 117 | var table = {} 118 | // Invert 'alphabet' 119 | for (var i = 0; i < alphabet.length; i++) { 120 | table[alphabet[i]] = i 121 | } 122 | // Splice in 'alias' 123 | for (var key in alias) { 124 | if (!alias.hasOwnProperty(key)) continue 125 | table[key] = table['' + alias[key]] 126 | } 127 | lookup = function() { return table } 128 | return table 129 | } 130 | 131 | function Decoder() { 132 | var skip = 0 // how many bits we have from the previous character 133 | var byte = 0 // current byte we're producing 134 | 135 | this.output = '' 136 | 137 | // Consume a character from the stream, store 138 | // the output in this.output. As before, better 139 | // to use update(). 140 | this.readChar = function(char) { 141 | if (typeof char != 'string'){ 142 | if (typeof char == 'number') { 143 | char = String.fromCharCode(char) 144 | } 145 | } 146 | char = char.toLowerCase() 147 | var val = lookup()[char] 148 | if (typeof val == 'undefined') { 149 | // character does not exist in our lookup table 150 | return // skip silently. An alternative would be: 151 | // throw Error('Could not find character "' + char + '" in lookup table.') 152 | } 153 | val <<= 3 // move to the high bits 154 | byte |= val >>> skip 155 | skip += 5 156 | if (skip >= 8) { 157 | // we have enough to preduce output 158 | this.output += String.fromCharCode(byte) 159 | skip -= 8 160 | if (skip > 0) byte = (val << (5 - skip)) & 255 161 | else byte = 0 162 | } 163 | 164 | } 165 | 166 | this.finish = function(check) { 167 | var output = this.output + (skip < 0 ? alphabet[bits >> 3] : '') + (check ? '$' : '') 168 | this.output = '' 169 | return output 170 | } 171 | } 172 | 173 | Decoder.prototype.update = function(input, flush) { 174 | for (var i = 0; i < input.length; i++) { 175 | this.readChar(input[i]) 176 | } 177 | var output = this.output 178 | this.output = '' 179 | if (flush) { 180 | output += this.finish() 181 | } 182 | return output 183 | } 184 | 185 | // Base32-encoded string goes in, decoded data comes out. 186 | function decode(input) { 187 | var decoder = new Decoder() 188 | var output = decoder.update(input, true) 189 | return output 190 | } 191 | 192 | function base32length(secret) { 193 | return decode(secret).length; 194 | } 195 | 196 | function saveOptions() { 197 | 198 | var options = {}; 199 | 200 | options.theme = parseInt($("input[name=theme]:checked").val(), 10); 201 | options.font_style = parseInt($("input[name=font_style]:checked").val(), 10); 202 | options.idle_timeout = parseInt($("#idle_timeout").val(), 10); 203 | 204 | var colors = rgb2hex($('#background-color').css("background-color")).replace("#", ''); 205 | colors = colors + rgb2hex($('#foreground-color').css("background-color")).replace("#", ''); 206 | options.basalt_colors = colors; 207 | 208 | if ($("#keysecret").val()) { 209 | options.label = $("#keyname").val(); 210 | options.secret = $("#keysecret").val().replace(/\s/g, ''); 211 | } 212 | 213 | return options; 214 | } 215 | 216 | $("document").ready(function() { 217 | var watch_version = getQueryParam("watch_version", 1); 218 | 219 | if (watch_version >= 3) { 220 | var basalt_colors = getQueryParam("basalt_colors", 0); 221 | basalt_colors = basalt_colors.length == 12 ? basalt_colors : "00AAFFFFFFFF"; 222 | $('#background-color').css('background-color', "#"+basalt_colors.substring(0,6)); 223 | $('#foreground-color').css('background-color', "#"+basalt_colors.substring(6,12)); 224 | $('#time-foreground').removeClass("hidden"); 225 | $('#time-background').removeClass("hidden"); 226 | } else { 227 | var theme = getQueryParam("theme", 0); 228 | theme = parseInt(isNumber(theme) && theme <= 1 ? theme : 0); 229 | $('#theme').removeClass("hidden"); 230 | $('#theme_'+theme).prop( "checked", true ).checkboxradio("refresh"); 231 | } 232 | 233 | var otp_count = getQueryParam("otp_count", 0); 234 | var font_style = getQueryParam("font_style", 0); 235 | var idle_timeout = getQueryParam("idle_timeout", 300); 236 | 237 | font_style = parseInt(isNumber(font_style) && font_style <= 3 ? font_style : 0); 238 | idle_timeout = parseInt(isNumber(idle_timeout) && (idle_timeout >= 0 || idle_timeout == 60 || idle_timeout == 120 || idle_timeout == 300 || idle_timeout == 600) ? idle_timeout : 300); 239 | 240 | $('#font_style_'+font_style).prop( "checked", true ).checkboxradio("refresh"); 241 | $("#idle_timeout").val(idle_timeout).selectmenu("refresh"); 242 | 243 | otp_count = parseInt(isNumber(otp_count) ? otp_count : 0); 244 | var slots_remaining = 16 - otp_count; 245 | 246 | if (slots_remaining === 0) { 247 | document.getElementById("keyname").disabled=true; 248 | document.getElementById("keysecret").disabled=true; 249 | } 250 | document.getElementById("footer").innerHTML=document.getElementById("footer").innerHTML.replace("NUM_SPACES", slots_remaining); 251 | }); -------------------------------------------------------------------------------- /html/v23/assets/Thumbs.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v23/assets/Thumbs.db -------------------------------------------------------------------------------- /html/v23/assets/og/font_style_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v23/assets/og/font_style_1.png -------------------------------------------------------------------------------- /html/v23/assets/og/font_style_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v23/assets/og/font_style_2.png -------------------------------------------------------------------------------- /html/v23/assets/og/font_style_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v23/assets/og/font_style_3.png -------------------------------------------------------------------------------- /html/v23/assets/og/font_style_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v23/assets/og/font_style_4.png -------------------------------------------------------------------------------- /html/v23/assets/og/multi_code_layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v23/assets/og/multi_code_layout.png -------------------------------------------------------------------------------- /html/v23/assets/time/font_style_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v23/assets/time/font_style_1.png -------------------------------------------------------------------------------- /html/v23/assets/time/font_style_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v23/assets/time/font_style_2.png -------------------------------------------------------------------------------- /html/v23/assets/time/font_style_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v23/assets/time/font_style_3.png -------------------------------------------------------------------------------- /html/v23/assets/time/font_style_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v23/assets/time/font_style_4.png -------------------------------------------------------------------------------- /html/v23/assets/time/multi_code_layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v23/assets/time/multi_code_layout.png -------------------------------------------------------------------------------- /html/v23/pebble-og.css: -------------------------------------------------------------------------------- 1 | .font_1_screenshot { 2 | background-image: url(assets/og/font_style_1.png); 3 | height: 168px; 4 | width: 144px; 5 | } 6 | .font_2_screenshot { 7 | background-image: url(assets/og/font_style_2.png); 8 | height: 168px; 9 | width: 144px; 10 | } 11 | .font_3_screenshot { 12 | background-image: url(assets/og/font_style_3.png); 13 | height: 168px; 14 | width: 144px; 15 | } 16 | .font_4_screenshot { 17 | background-image: url(assets/og/font_style_4.png); 18 | height: 168px; 19 | width: 144px; 20 | } 21 | .multi_code_layout_screenshot { 22 | background-image: url(assets/og/multi_code_layout.png); 23 | height: 168px; 24 | width: 144px; 25 | } -------------------------------------------------------------------------------- /html/v23/pebble-time.css: -------------------------------------------------------------------------------- 1 | .font_1_screenshot { 2 | background-image: url(assets/time/font_style_1.png); 3 | height: 168px; 4 | width: 144px; 5 | } 6 | .font_2_screenshot { 7 | background-image: url(assets/time/font_style_2.png); 8 | height: 168px; 9 | width: 144px; 10 | } 11 | .font_3_screenshot { 12 | background-image: url(assets/time/font_style_3.png); 13 | height: 168px; 14 | width: 144px; 15 | } 16 | .font_4_screenshot { 17 | background-image: url(assets/time/font_style_4.png); 18 | height: 168px; 19 | width: 144px; 20 | } 21 | .multi_code_layout_screenshot { 22 | background-image: url(assets/time/multi_code_layout.png); 23 | height: 168px; 24 | width: 144px; 25 | } -------------------------------------------------------------------------------- /html/v23/script.js: -------------------------------------------------------------------------------- 1 | $(function () { 2 | $('#foreground-color').on('click', function (event) { 3 | changeForeground = true; 4 | highlightColorBox($(this)); 5 | }); 6 | }); 7 | 8 | $(function () { 9 | $('#background-color').on('click', function (event) { 10 | changeForeground = false; 11 | highlightColorBox($(this)); 12 | }); 13 | }); 14 | 15 | $(function () { 16 | $('#color-picker .color-box').on('click', function (event) { 17 | var selected_color = rgb2hex($(this).css("background-color")); 18 | 19 | if (changeForeground) 20 | $('#foreground-color').css('background-color', selected_color); 21 | else 22 | $('#background-color').css('background-color', selected_color); 23 | $( "#color-picker" ).popup( "close" ); 24 | }); 25 | }); 26 | 27 | $(function () { 28 | $("#confirm_delete_all").click(function() { 29 | console.log("Deleting all"); 30 | var options = {}; 31 | options.delete_all = 1; 32 | var location = "pebblejs://close#" + encodeURIComponent(JSON.stringify(options)); 33 | document.location = location; 34 | }); 35 | }); 36 | 37 | $(function () { 38 | $("#cancel").click(function() { 39 | console.log("Cancelling"); 40 | document.location = "pebblejs://close"; 41 | }); 42 | }); 43 | 44 | $(function () { 45 | $("#save").click(function() { 46 | console.log("Submit"); 47 | 48 | var options = saveOptions(); 49 | 50 | if (options.secret && base32length(options.secret) < 10) { 51 | alert("Secret key value is too short"); 52 | } 53 | else if (options.secret && options.label.length === 0) { 54 | alert("Please enter a label"); 55 | } 56 | else { 57 | var return_to = getQueryParam('return_to', 'pebblejs://close#'); 58 | var location = return_to + encodeURIComponent(JSON.stringify(options)); 59 | console.log("Warping to:"); 60 | console.log(location); 61 | document.location = location; 62 | } 63 | }); 64 | }); 65 | 66 | function highlightColorBox($colorButton) { 67 | selectedColor = rgb2hex($colorButton.css("background-color")); 68 | 69 | var i; 70 | for (i = 1; i <= 13; i++) 71 | { 72 | $('#color-row'+i).children().removeClass("selected-color-box"); 73 | } 74 | $('#color-box-'+selectedColor.substring(1).toUpperCase()).addClass("selected-color-box"); 75 | } 76 | 77 | //Function to convert hex format to a rgb color 78 | function rgb2hex(rgb){ 79 | rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/); 80 | return ("#" + 81 | ("0" + parseInt(rgb[1],10).toString(16)).slice(-2) + 82 | ("0" + parseInt(rgb[2],10).toString(16)).slice(-2) + 83 | ("0" + parseInt(rgb[3],10).toString(16)).slice(-2)).toUpperCase(); 84 | } 85 | 86 | function queryObj() { 87 | var result = {}, keyValuePairs = location.search.slice(1).split('&'); 88 | 89 | keyValuePairs.forEach(function(keyValuePair) { 90 | keyValuePair = keyValuePair.split('='); 91 | result[keyValuePair[0]] = keyValuePair[1] || ''; 92 | }); 93 | 94 | return result; 95 | } 96 | 97 | function getQueryParam(variable, default_) { 98 | var query = location.search.substring(1); 99 | var vars = query.split('&'); 100 | for (var i = 0; i < vars.length; i++) { 101 | var pair = vars[i].split('='); 102 | if (pair[0] == variable) 103 | return decodeURIComponent(pair[1]); 104 | } 105 | return default_ || false; 106 | } 107 | 108 | function isNumber(n) { 109 | return !isNaN(parseFloat(n)) && isFinite(n); 110 | } 111 | 112 | // Base32 decoder from https://github.com/agnoster/base32-js/blob/master/lib/base32.js by Isaac Wolkerstorfer 113 | var alphabet = '0123456789abcdefghjkmnpqrtuvwxyz' 114 | var alias = { o:0, i:1, l:1, s:5 } 115 | 116 | var lookup = function() { 117 | var table = {} 118 | // Invert 'alphabet' 119 | for (var i = 0; i < alphabet.length; i++) { 120 | table[alphabet[i]] = i 121 | } 122 | // Splice in 'alias' 123 | for (var key in alias) { 124 | if (!alias.hasOwnProperty(key)) continue 125 | table[key] = table['' + alias[key]] 126 | } 127 | lookup = function() { return table } 128 | return table 129 | } 130 | 131 | function Decoder() { 132 | var skip = 0 // how many bits we have from the previous character 133 | var byte = 0 // current byte we're producing 134 | 135 | this.output = '' 136 | 137 | // Consume a character from the stream, store 138 | // the output in this.output. As before, better 139 | // to use update(). 140 | this.readChar = function(char) { 141 | if (typeof char != 'string'){ 142 | if (typeof char == 'number') { 143 | char = String.fromCharCode(char) 144 | } 145 | } 146 | char = char.toLowerCase() 147 | var val = lookup()[char] 148 | if (typeof val == 'undefined') { 149 | // character does not exist in our lookup table 150 | return // skip silently. An alternative would be: 151 | // throw Error('Could not find character "' + char + '" in lookup table.') 152 | } 153 | val <<= 3 // move to the high bits 154 | byte |= val >>> skip 155 | skip += 5 156 | if (skip >= 8) { 157 | // we have enough to preduce output 158 | this.output += String.fromCharCode(byte) 159 | skip -= 8 160 | if (skip > 0) byte = (val << (5 - skip)) & 255 161 | else byte = 0 162 | } 163 | 164 | } 165 | 166 | this.finish = function(check) { 167 | var output = this.output + (skip < 0 ? alphabet[bits >> 3] : '') + (check ? '$' : '') 168 | this.output = '' 169 | return output 170 | } 171 | } 172 | 173 | Decoder.prototype.update = function(input, flush) { 174 | for (var i = 0; i < input.length; i++) { 175 | this.readChar(input[i]) 176 | } 177 | var output = this.output 178 | this.output = '' 179 | if (flush) { 180 | output += this.finish() 181 | } 182 | return output 183 | } 184 | 185 | // Base32-encoded string goes in, decoded data comes out. 186 | function decode(input) { 187 | var decoder = new Decoder() 188 | var output = decoder.update(input, true) 189 | return output 190 | } 191 | 192 | function base32length(secret) { 193 | return decode(secret).length; 194 | } 195 | 196 | function saveOptions() { 197 | 198 | var options = {}; 199 | 200 | options.theme = parseInt($("input[name=theme]:checked").val(), 10); 201 | options.font_style = parseInt($("input[name=font_style]:checked").val(), 10); 202 | options.idle_timeout = parseInt($("#idle_timeout").val(), 10); 203 | options.window_layout = parseInt($("input[name=window_layout]:checked").val(), 10); 204 | 205 | var colors = rgb2hex($('#background-color').css("background-color")).replace("#", ''); 206 | colors = colors + rgb2hex($('#foreground-color').css("background-color")).replace("#", ''); 207 | options.basalt_colors = colors; 208 | 209 | if ($("#keysecret").val()) { 210 | options.label = $("#keyname").val(); 211 | options.secret = $("#keysecret").val().replace(/\s/g, ''); 212 | } 213 | 214 | return options; 215 | } 216 | 217 | $("document").ready(function() { 218 | var watch_version = getQueryParam("watch_version", 1); 219 | 220 | if (watch_version >= 3) { 221 | document.getElementById('pebble-stylesheet').setAttribute('href', 'pebble-time.css'); 222 | var basalt_colors = getQueryParam("basalt_colors", 0); 223 | basalt_colors = basalt_colors.length == 12 ? basalt_colors : "00AAFFFFFFFF"; 224 | $('#background-color').css('background-color', "#"+basalt_colors.substring(0,6)); 225 | $('#foreground-color').css('background-color', "#"+basalt_colors.substring(6,12)); 226 | $('#time-foreground').removeClass("hidden"); 227 | $('#time-background').removeClass("hidden"); 228 | } else { 229 | var theme = getQueryParam("theme", 0); 230 | theme = parseInt(isNumber(theme) && theme <= 1 ? theme : 0); 231 | $('#theme').removeClass("hidden"); 232 | $('#theme_'+theme).prop( "checked", true ).checkboxradio("refresh"); 233 | } 234 | 235 | var otp_count = getQueryParam("otp_count", 0); 236 | var font_style = getQueryParam("font_style", 0); 237 | var idle_timeout = getQueryParam("idle_timeout", 300); 238 | var window_layout = getQueryParam("window_layout", 0); 239 | 240 | font_style = parseInt(isNumber(font_style) && font_style <= 3 ? font_style : 0); 241 | idle_timeout = parseInt(isNumber(idle_timeout) && (idle_timeout >= 0 || idle_timeout == 60 || idle_timeout == 120 || idle_timeout == 300 || idle_timeout == 600) ? idle_timeout : 300); 242 | window_layout = parseInt(isNumber(window_layout) && window_layout <= 3 ? window_layout : 0); 243 | 244 | $('#font_style_'+font_style).prop( "checked", true ).checkboxradio("refresh"); 245 | $("#idle_timeout").val(idle_timeout).selectmenu("refresh"); 246 | $('#window_layout_'+window_layout).prop( "checked", true ).checkboxradio("refresh"); 247 | 248 | otp_count = parseInt(isNumber(otp_count) ? otp_count : 0); 249 | var slots_remaining = 16 - otp_count; 250 | 251 | if (slots_remaining === 0) { 252 | document.getElementById("keyname").disabled=true; 253 | document.getElementById("keysecret").disabled=true; 254 | } 255 | document.getElementById("footer").innerHTML=document.getElementById("footer").innerHTML.replace("NUM_SPACES", slots_remaining); 256 | }); -------------------------------------------------------------------------------- /html/v24/OLD/assets/Thumbs.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v24/OLD/assets/Thumbs.db -------------------------------------------------------------------------------- /html/v24/OLD/assets/og/font_style_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v24/OLD/assets/og/font_style_1.png -------------------------------------------------------------------------------- /html/v24/OLD/assets/og/font_style_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v24/OLD/assets/og/font_style_2.png -------------------------------------------------------------------------------- /html/v24/OLD/assets/og/font_style_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v24/OLD/assets/og/font_style_3.png -------------------------------------------------------------------------------- /html/v24/OLD/assets/og/font_style_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v24/OLD/assets/og/font_style_4.png -------------------------------------------------------------------------------- /html/v24/OLD/assets/og/multi_code_layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v24/OLD/assets/og/multi_code_layout.png -------------------------------------------------------------------------------- /html/v24/OLD/assets/time/font_style_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v24/OLD/assets/time/font_style_1.png -------------------------------------------------------------------------------- /html/v24/OLD/assets/time/font_style_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v24/OLD/assets/time/font_style_2.png -------------------------------------------------------------------------------- /html/v24/OLD/assets/time/font_style_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v24/OLD/assets/time/font_style_3.png -------------------------------------------------------------------------------- /html/v24/OLD/assets/time/font_style_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v24/OLD/assets/time/font_style_4.png -------------------------------------------------------------------------------- /html/v24/OLD/assets/time/multi_code_layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v24/OLD/assets/time/multi_code_layout.png -------------------------------------------------------------------------------- /html/v24/OLD/pebble-og.css: -------------------------------------------------------------------------------- 1 | .font_1_screenshot { 2 | background-image: url(assets/og/font_style_1.png); 3 | height: 168px; 4 | width: 144px; 5 | } 6 | .font_2_screenshot { 7 | background-image: url(assets/og/font_style_2.png); 8 | height: 168px; 9 | width: 144px; 10 | } 11 | .font_3_screenshot { 12 | background-image: url(assets/og/font_style_3.png); 13 | height: 168px; 14 | width: 144px; 15 | } 16 | .font_4_screenshot { 17 | background-image: url(assets/og/font_style_4.png); 18 | height: 168px; 19 | width: 144px; 20 | } 21 | .multi_code_layout_screenshot { 22 | background-image: url(assets/og/multi_code_layout.png); 23 | height: 168px; 24 | width: 144px; 25 | } -------------------------------------------------------------------------------- /html/v24/OLD/pebble-time.css: -------------------------------------------------------------------------------- 1 | .font_1_screenshot { 2 | background-image: url(assets/time/font_style_1.png); 3 | height: 168px; 4 | width: 144px; 5 | } 6 | .font_2_screenshot { 7 | background-image: url(assets/time/font_style_2.png); 8 | height: 168px; 9 | width: 144px; 10 | } 11 | .font_3_screenshot { 12 | background-image: url(assets/time/font_style_3.png); 13 | height: 168px; 14 | width: 144px; 15 | } 16 | .font_4_screenshot { 17 | background-image: url(assets/time/font_style_4.png); 18 | height: 168px; 19 | width: 144px; 20 | } 21 | .multi_code_layout_screenshot { 22 | background-image: url(assets/time/multi_code_layout.png); 23 | height: 168px; 24 | width: 144px; 25 | } -------------------------------------------------------------------------------- /html/v24/OLD/script.js: -------------------------------------------------------------------------------- 1 | $(function () { 2 | $('#foreground-color').on('click', function (event) { 3 | changeForeground = true; 4 | highlightColorBox($(this)); 5 | }); 6 | }); 7 | 8 | $(function () { 9 | $('#background-color').on('click', function (event) { 10 | changeForeground = false; 11 | highlightColorBox($(this)); 12 | }); 13 | }); 14 | 15 | $(function () { 16 | $('#color-picker .color-box').on('click', function (event) { 17 | var selected_color = rgb2hex($(this).css("background-color")); 18 | 19 | if (changeForeground) 20 | $('#foreground-color').css('background-color', selected_color); 21 | else 22 | $('#background-color').css('background-color', selected_color); 23 | $( "#color-picker" ).popup( "close" ); 24 | }); 25 | }); 26 | 27 | $(function () { 28 | $("#confirm_delete_all").click(function() { 29 | console.log("Deleting all"); 30 | var options = {}; 31 | options.delete_all = 1; 32 | var location = "pebblejs://close#" + encodeURIComponent(JSON.stringify(options)); 33 | document.location = location; 34 | }); 35 | }); 36 | 37 | $(function () { 38 | $("#cancel").click(function() { 39 | console.log("Cancelling"); 40 | document.location = "pebblejs://close"; 41 | }); 42 | }); 43 | 44 | $(function () { 45 | $("#save").click(function() { 46 | console.log("Submit"); 47 | 48 | var options = saveOptions(); 49 | 50 | if (options.secret && base32length(options.secret) < 10) { 51 | alert("Secret key value is too short"); 52 | } 53 | else if (options.secret && options.label.length === 0) { 54 | alert("Please enter a label"); 55 | } 56 | else { 57 | var return_to = getQueryParam('return_to', 'pebblejs://close#'); 58 | var location = return_to + encodeURIComponent(JSON.stringify(options)); 59 | console.log("Warping to:"); 60 | console.log(location); 61 | document.location = location; 62 | } 63 | }); 64 | }); 65 | 66 | function highlightColorBox($colorButton) { 67 | selectedColor = rgb2hex($colorButton.css("background-color")); 68 | 69 | var i; 70 | for (i = 1; i <= 13; i++) 71 | { 72 | $('#color-row'+i).children().removeClass("selected-color-box"); 73 | } 74 | $('#color-box-'+selectedColor.substring(1).toUpperCase()).addClass("selected-color-box"); 75 | } 76 | 77 | //Function to convert hex format to a rgb color 78 | function rgb2hex(rgb){ 79 | rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/); 80 | return ("#" + 81 | ("0" + parseInt(rgb[1],10).toString(16)).slice(-2) + 82 | ("0" + parseInt(rgb[2],10).toString(16)).slice(-2) + 83 | ("0" + parseInt(rgb[3],10).toString(16)).slice(-2)).toUpperCase(); 84 | } 85 | 86 | function queryObj() { 87 | var result = {}, keyValuePairs = location.search.slice(1).split('&'); 88 | 89 | keyValuePairs.forEach(function(keyValuePair) { 90 | keyValuePair = keyValuePair.split('='); 91 | result[keyValuePair[0]] = keyValuePair[1] || ''; 92 | }); 93 | 94 | return result; 95 | } 96 | 97 | function getQueryParam(variable, default_) { 98 | var query = location.search.substring(1); 99 | var vars = query.split('&'); 100 | for (var i = 0; i < vars.length; i++) { 101 | var pair = vars[i].split('='); 102 | if (pair[0] == variable) 103 | return decodeURIComponent(pair[1]); 104 | } 105 | return default_ || false; 106 | } 107 | 108 | function isNumber(n) { 109 | return !isNaN(parseFloat(n)) && isFinite(n); 110 | } 111 | 112 | // Base32 decoder from https://github.com/agnoster/base32-js/blob/master/lib/base32.js by Isaac Wolkerstorfer 113 | var alphabet = '0123456789abcdefghjkmnpqrtuvwxyz' 114 | var alias = { o:0, i:1, l:1, s:5 } 115 | 116 | var lookup = function() { 117 | var table = {} 118 | // Invert 'alphabet' 119 | for (var i = 0; i < alphabet.length; i++) { 120 | table[alphabet[i]] = i 121 | } 122 | // Splice in 'alias' 123 | for (var key in alias) { 124 | if (!alias.hasOwnProperty(key)) continue 125 | table[key] = table['' + alias[key]] 126 | } 127 | lookup = function() { return table } 128 | return table 129 | } 130 | 131 | function Decoder() { 132 | var skip = 0 // how many bits we have from the previous character 133 | var byte = 0 // current byte we're producing 134 | 135 | this.output = '' 136 | 137 | // Consume a character from the stream, store 138 | // the output in this.output. As before, better 139 | // to use update(). 140 | this.readChar = function(char) { 141 | if (typeof char != 'string'){ 142 | if (typeof char == 'number') { 143 | char = String.fromCharCode(char) 144 | } 145 | } 146 | char = char.toLowerCase() 147 | var val = lookup()[char] 148 | if (typeof val == 'undefined') { 149 | // character does not exist in our lookup table 150 | return // skip silently. An alternative would be: 151 | // throw Error('Could not find character "' + char + '" in lookup table.') 152 | } 153 | val <<= 3 // move to the high bits 154 | byte |= val >>> skip 155 | skip += 5 156 | if (skip >= 8) { 157 | // we have enough to preduce output 158 | this.output += String.fromCharCode(byte) 159 | skip -= 8 160 | if (skip > 0) byte = (val << (5 - skip)) & 255 161 | else byte = 0 162 | } 163 | 164 | } 165 | 166 | this.finish = function(check) { 167 | var output = this.output + (skip < 0 ? alphabet[bits >> 3] : '') + (check ? '$' : '') 168 | this.output = '' 169 | return output 170 | } 171 | } 172 | 173 | Decoder.prototype.update = function(input, flush) { 174 | for (var i = 0; i < input.length; i++) { 175 | this.readChar(input[i]) 176 | } 177 | var output = this.output 178 | this.output = '' 179 | if (flush) { 180 | output += this.finish() 181 | } 182 | return output 183 | } 184 | 185 | // Base32-encoded string goes in, decoded data comes out. 186 | function decode(input) { 187 | var decoder = new Decoder() 188 | var output = decoder.update(input, true) 189 | return output 190 | } 191 | 192 | function base32length(secret) { 193 | return decode(secret).length; 194 | } 195 | 196 | function saveOptions() { 197 | 198 | var options = {}; 199 | 200 | options.theme = parseInt($("input[name=theme]:checked").val(), 10); 201 | options.font_style = parseInt($("input[name=font_style]:checked").val(), 10); 202 | options.idle_timeout = parseInt($("#idle_timeout").val(), 10); 203 | options.window_layout = parseInt($("input[name=window_layout]:checked").val(), 10); 204 | 205 | var colors = rgb2hex($('#background-color').css("background-color")).replace("#", ''); 206 | colors = colors + rgb2hex($('#foreground-color').css("background-color")).replace("#", ''); 207 | options.basalt_colors = colors; 208 | 209 | if ($("#keysecret").val()) { 210 | options.label = $("#keyname").val(); 211 | options.secret = $("#keysecret").val().replace(/\s/g, ''); 212 | } 213 | 214 | return options; 215 | } 216 | 217 | $("document").ready(function() { 218 | var watch_version = getQueryParam("watch_version", 1); 219 | 220 | if (watch_version >= 3) { 221 | document.getElementById('pebble-stylesheet').setAttribute('href', 'pebble-time.css'); 222 | var basalt_colors = getQueryParam("basalt_colors", 0); 223 | basalt_colors = basalt_colors.length == 12 ? basalt_colors : "00AAFFFFFFFF"; 224 | $('#background-color').css('background-color', "#"+basalt_colors.substring(0,6)); 225 | $('#foreground-color').css('background-color', "#"+basalt_colors.substring(6,12)); 226 | $('#time-foreground').removeClass("hidden"); 227 | $('#time-background').removeClass("hidden"); 228 | } else { 229 | var theme = getQueryParam("theme", 0); 230 | theme = parseInt(isNumber(theme) && theme <= 1 ? theme : 0); 231 | $('#theme').removeClass("hidden"); 232 | $('#theme_'+theme).prop( "checked", true ).checkboxradio("refresh"); 233 | } 234 | 235 | var otp_count = getQueryParam("otp_count", 0); 236 | var font_style = getQueryParam("font_style", 0); 237 | var idle_timeout = getQueryParam("idle_timeout", 300); 238 | var window_layout = getQueryParam("window_layout", 0); 239 | 240 | font_style = parseInt(isNumber(font_style) && font_style <= 3 ? font_style : 0); 241 | idle_timeout = parseInt(isNumber(idle_timeout) && (idle_timeout >= 0 || idle_timeout == 60 || idle_timeout == 120 || idle_timeout == 300 || idle_timeout == 600) ? idle_timeout : 300); 242 | window_layout = parseInt(isNumber(window_layout) && window_layout <= 3 ? window_layout : 0); 243 | 244 | $('#font_style_'+font_style).prop( "checked", true ).checkboxradio("refresh"); 245 | $("#idle_timeout").val(idle_timeout).selectmenu("refresh"); 246 | $('#window_layout_'+window_layout).prop( "checked", true ).checkboxradio("refresh"); 247 | 248 | otp_count = parseInt(isNumber(otp_count) ? otp_count : 0); 249 | var slots_remaining = 16 - otp_count; 250 | 251 | if (slots_remaining === 0) { 252 | document.getElementById("keyname").disabled=true; 253 | document.getElementById("keysecret").disabled=true; 254 | } 255 | document.getElementById("footer").innerHTML=document.getElementById("footer").innerHTML.replace("NUM_SPACES", slots_remaining); 256 | }); -------------------------------------------------------------------------------- /html/v24/assets/Thumbs.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v24/assets/Thumbs.db -------------------------------------------------------------------------------- /html/v24/assets/og/font_style_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v24/assets/og/font_style_1.png -------------------------------------------------------------------------------- /html/v24/assets/og/font_style_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v24/assets/og/font_style_2.png -------------------------------------------------------------------------------- /html/v24/assets/og/font_style_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v24/assets/og/font_style_3.png -------------------------------------------------------------------------------- /html/v24/assets/og/font_style_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v24/assets/og/font_style_4.png -------------------------------------------------------------------------------- /html/v24/assets/og/multi_code_layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v24/assets/og/multi_code_layout.png -------------------------------------------------------------------------------- /html/v24/assets/og/screenshot_holder_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v24/assets/og/screenshot_holder_1.png -------------------------------------------------------------------------------- /html/v24/assets/og/screenshot_holder_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v24/assets/og/screenshot_holder_2.png -------------------------------------------------------------------------------- /html/v24/assets/time/font_style_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v24/assets/time/font_style_1.png -------------------------------------------------------------------------------- /html/v24/assets/time/font_style_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v24/assets/time/font_style_2.png -------------------------------------------------------------------------------- /html/v24/assets/time/font_style_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v24/assets/time/font_style_3.png -------------------------------------------------------------------------------- /html/v24/assets/time/font_style_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v24/assets/time/font_style_4.png -------------------------------------------------------------------------------- /html/v24/assets/time/multi_code_layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v24/assets/time/multi_code_layout.png -------------------------------------------------------------------------------- /html/v24/assets/time/screenshot_holder_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v24/assets/time/screenshot_holder_3.png -------------------------------------------------------------------------------- /html/v24/pebble-1.css: -------------------------------------------------------------------------------- 1 | .screenshot_holder { 2 | background-image: url(assets/og/screenshot_holder_1.png); 3 | padding-top: 104px; 4 | height: 372px; 5 | width: 236px; 6 | background-repeat: no-repeat; 7 | } 8 | 9 | .font_1_screenshot { 10 | background-image: url(assets/og/font_style_1.png); 11 | height: 168px; 12 | width: 144px; 13 | margin-left: auto; 14 | margin-right: auto; 15 | } 16 | 17 | .font_2_screenshot { 18 | background-image: url(assets/og/font_style_2.png); 19 | height: 168px; 20 | width: 144px; 21 | margin-left: auto; 22 | margin-right: auto; 23 | } 24 | .font_3_screenshot { 25 | background-image: url(assets/og/font_style_3.png); 26 | height: 168px; 27 | width: 144px; 28 | margin-left: auto; 29 | margin-right: auto; 30 | } 31 | .font_4_screenshot { 32 | background-image: url(assets/og/font_style_4.png); 33 | height: 168px; 34 | width: 144px; 35 | margin-left: auto; 36 | margin-right: auto; 37 | } 38 | 39 | .multi_code_layout_screenshot { 40 | background-image: url(assets/og/multi_code_layout.png); 41 | height: 168px; 42 | width: 144px; 43 | margin-left: auto; 44 | margin-right: auto; 45 | } -------------------------------------------------------------------------------- /html/v24/pebble-2.css: -------------------------------------------------------------------------------- 1 | .screenshot_holder { 2 | background-image: url(assets/og/screenshot_holder_2.png); 3 | padding-top: 104px; 4 | height: 372px; 5 | width: 236px; 6 | background-repeat: no-repeat; 7 | } 8 | 9 | .font_1_screenshot { 10 | background-image: url(assets/og/font_style_1.png); 11 | height: 168px; 12 | width: 144px; 13 | margin-left: auto; 14 | margin-right: auto; 15 | } 16 | 17 | .font_2_screenshot { 18 | background-image: url(assets/og/font_style_2.png); 19 | height: 168px; 20 | width: 144px; 21 | margin-left: auto; 22 | margin-right: auto; 23 | } 24 | .font_3_screenshot { 25 | background-image: url(assets/og/font_style_3.png); 26 | height: 168px; 27 | width: 144px; 28 | margin-left: auto; 29 | margin-right: auto; 30 | } 31 | .font_4_screenshot { 32 | background-image: url(assets/og/font_style_4.png); 33 | height: 168px; 34 | width: 144px; 35 | margin-left: auto; 36 | margin-right: auto; 37 | } 38 | 39 | .multi_code_layout_screenshot { 40 | background-image: url(assets/og/multi_code_layout.png); 41 | height: 168px; 42 | width: 144px; 43 | margin-left: auto; 44 | margin-right: auto; 45 | } -------------------------------------------------------------------------------- /html/v24/pebble-3.css: -------------------------------------------------------------------------------- 1 | .screenshot_holder { 2 | background-image: url(assets/time/screenshot_holder_3.png); 3 | padding-top: 91px; 4 | height: 244px; 5 | width: 244px; 6 | background-repeat: no-repeat; 7 | } 8 | 9 | .font_1_screenshot { 10 | background-image: url(assets/time/font_style_1.png); 11 | height: 168px; 12 | width: 144px; 13 | margin-left: auto; 14 | margin-right: auto; 15 | } 16 | 17 | .font_2_screenshot { 18 | background-image: url(assets/time/font_style_2.png); 19 | height: 168px; 20 | width: 144px; 21 | margin-left: auto; 22 | margin-right: auto; 23 | } 24 | .font_3_screenshot { 25 | background-image: url(assets/time/font_style_3.png); 26 | height: 168px; 27 | width: 144px; 28 | margin-left: auto; 29 | margin-right: auto; 30 | } 31 | .font_4_screenshot { 32 | background-image: url(assets/time/font_style_4.png); 33 | height: 168px; 34 | width: 144px; 35 | margin-left: auto; 36 | margin-right: auto; 37 | } 38 | 39 | .multi_code_layout_screenshot { 40 | background-image: url(assets/time/multi_code_layout.png); 41 | height: 168px; 42 | width: 144px; 43 | margin-left: auto; 44 | margin-right: auto; 45 | } -------------------------------------------------------------------------------- /html/v24/script.js: -------------------------------------------------------------------------------- 1 | $(function () { 2 | $('#foreground-color').on('click', function (event) { 3 | changeForeground = true; 4 | highlightColorBox($(this)); 5 | }); 6 | }); 7 | 8 | $(function () { 9 | $('#background-color').on('click', function (event) { 10 | changeForeground = false; 11 | highlightColorBox($(this)); 12 | }); 13 | }); 14 | 15 | $(function () { 16 | $('#color-picker .color-box').on('click', function (event) { 17 | var selected_color = rgb2hex($(this).css("background-color")); 18 | 19 | if (changeForeground) 20 | $('#foreground-color').css('background-color', selected_color); 21 | else 22 | $('#background-color').css('background-color', selected_color); 23 | $( "#color-picker" ).popup( "close" ); 24 | }); 25 | }); 26 | 27 | $(function () { 28 | $("#confirm_delete_all").click(function() { 29 | console.log("Deleting all"); 30 | var options = {}; 31 | options.delete_all = 1; 32 | var location = "pebblejs://close#" + encodeURIComponent(JSON.stringify(options)); 33 | document.location = location; 34 | }); 35 | }); 36 | 37 | $(function () { 38 | $("#cancel").click(function() { 39 | console.log("Cancelling"); 40 | document.location = "pebblejs://close"; 41 | }); 42 | }); 43 | 44 | $(function () { 45 | $("#save").click(function() { 46 | console.log("Submit"); 47 | 48 | var options = saveOptions(); 49 | 50 | if (options.secret && base32length(options.secret) < 10) { 51 | alert("Secret key value is too short"); 52 | } 53 | else if (options.secret && options.label.length === 0) { 54 | alert("Please enter a label"); 55 | } 56 | else { 57 | var return_to = getQueryParam('return_to', 'pebblejs://close#'); 58 | var location = return_to + encodeURIComponent(JSON.stringify(options)); 59 | console.log("Warping to:"); 60 | console.log(location); 61 | document.location = location; 62 | } 63 | }); 64 | }); 65 | 66 | function highlightColorBox($colorButton) { 67 | selectedColor = rgb2hex($colorButton.css("background-color")); 68 | 69 | var i; 70 | for (i = 1; i <= 13; i++) 71 | { 72 | $('#color-row'+i).children().removeClass("selected-color-box"); 73 | } 74 | $('#color-box-'+selectedColor.substring(1).toUpperCase()).addClass("selected-color-box"); 75 | } 76 | 77 | //Function to convert hex format to a rgb color 78 | function rgb2hex(rgb){ 79 | rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/); 80 | return ("#" + 81 | ("0" + parseInt(rgb[1],10).toString(16)).slice(-2) + 82 | ("0" + parseInt(rgb[2],10).toString(16)).slice(-2) + 83 | ("0" + parseInt(rgb[3],10).toString(16)).slice(-2)).toUpperCase(); 84 | } 85 | 86 | function queryObj() { 87 | var result = {}, keyValuePairs = location.search.slice(1).split('&'); 88 | 89 | keyValuePairs.forEach(function(keyValuePair) { 90 | keyValuePair = keyValuePair.split('='); 91 | result[keyValuePair[0]] = keyValuePair[1] || ''; 92 | }); 93 | 94 | return result; 95 | } 96 | 97 | function getQueryParam(variable, default_) { 98 | var query = location.search.substring(1); 99 | var vars = query.split('&'); 100 | for (var i = 0; i < vars.length; i++) { 101 | var pair = vars[i].split('='); 102 | if (pair[0] == variable) 103 | return decodeURIComponent(pair[1]); 104 | } 105 | return default_ || false; 106 | } 107 | 108 | function isNumber(n) { 109 | return !isNaN(parseFloat(n)) && isFinite(n); 110 | } 111 | 112 | // Base32 decoder from https://github.com/agnoster/base32-js/blob/master/lib/base32.js by Isaac Wolkerstorfer 113 | var alphabet = '0123456789abcdefghjkmnpqrtuvwxyz' 114 | var alias = { o:0, i:1, l:1, s:5 } 115 | 116 | var lookup = function() { 117 | var table = {} 118 | // Invert 'alphabet' 119 | for (var i = 0; i < alphabet.length; i++) { 120 | table[alphabet[i]] = i 121 | } 122 | // Splice in 'alias' 123 | for (var key in alias) { 124 | if (!alias.hasOwnProperty(key)) continue 125 | table[key] = table['' + alias[key]] 126 | } 127 | lookup = function() { return table } 128 | return table 129 | } 130 | 131 | function Decoder() { 132 | var skip = 0 // how many bits we have from the previous character 133 | var byte = 0 // current byte we're producing 134 | 135 | this.output = '' 136 | 137 | // Consume a character from the stream, store 138 | // the output in this.output. As before, better 139 | // to use update(). 140 | this.readChar = function(char) { 141 | if (typeof char != 'string'){ 142 | if (typeof char == 'number') { 143 | char = String.fromCharCode(char) 144 | } 145 | } 146 | char = char.toLowerCase() 147 | var val = lookup()[char] 148 | if (typeof val == 'undefined') { 149 | // character does not exist in our lookup table 150 | return // skip silently. An alternative would be: 151 | // throw Error('Could not find character "' + char + '" in lookup table.') 152 | } 153 | val <<= 3 // move to the high bits 154 | byte |= val >>> skip 155 | skip += 5 156 | if (skip >= 8) { 157 | // we have enough to preduce output 158 | this.output += String.fromCharCode(byte) 159 | skip -= 8 160 | if (skip > 0) byte = (val << (5 - skip)) & 255 161 | else byte = 0 162 | } 163 | 164 | } 165 | 166 | this.finish = function(check) { 167 | var output = this.output + (skip < 0 ? alphabet[bits >> 3] : '') + (check ? '$' : '') 168 | this.output = '' 169 | return output 170 | } 171 | } 172 | 173 | Decoder.prototype.update = function(input, flush) { 174 | for (var i = 0; i < input.length; i++) { 175 | this.readChar(input[i]) 176 | } 177 | var output = this.output 178 | this.output = '' 179 | if (flush) { 180 | output += this.finish() 181 | } 182 | return output 183 | } 184 | 185 | // Base32-encoded string goes in, decoded data comes out. 186 | function decode(input) { 187 | var decoder = new Decoder() 188 | var output = decoder.update(input, true) 189 | return output 190 | } 191 | 192 | function base32length(secret) { 193 | return decode(secret).length; 194 | } 195 | 196 | function saveOptions() { 197 | 198 | var options = {}; 199 | 200 | options.theme = parseInt($("input[name=theme]:checked").val(), 10); 201 | options.font_style = parseInt($("input[name=font_style]:checked").val(), 10); 202 | options.idle_timeout = parseInt($("#idle_timeout").val(), 10); 203 | options.window_layout = parseInt($("input[name=window_layout]:checked").val(), 10); 204 | 205 | var colors = rgb2hex($('#background-color').css("background-color")).replace("#", ''); 206 | colors = colors + rgb2hex($('#foreground-color').css("background-color")).replace("#", ''); 207 | options.basalt_colors = colors; 208 | 209 | if ($("#keysecret").val()) { 210 | options.label = $("#keyname").val(); 211 | options.secret = $("#keysecret").val().replace(/\W/g, ''); 212 | } 213 | 214 | return options; 215 | } 216 | 217 | $("document").ready(function() { 218 | var watch_version = getQueryParam("watch_version", 1); 219 | 220 | if (watch_version >= 3) { 221 | var basalt_colors = getQueryParam("basalt_colors", 0); 222 | basalt_colors = basalt_colors.length == 12 ? basalt_colors : "00AAFFFFFFFF"; 223 | $('#background-color').css('background-color', "#"+basalt_colors.substring(0,6)); 224 | $('#foreground-color').css('background-color', "#"+basalt_colors.substring(6,12)); 225 | $('#time-foreground').removeClass("hidden"); 226 | $('#time-background').removeClass("hidden"); 227 | } else { 228 | var theme = getQueryParam("theme", 0); 229 | theme = parseInt(isNumber(theme) && theme <= 1 ? theme : 0); 230 | $('#theme').removeClass("hidden"); 231 | $('#theme_'+theme).prop( "checked", true ).checkboxradio("refresh"); 232 | } 233 | 234 | if (watch_version >= 2 && watch_version <= 3) { 235 | document.getElementById('pebble-stylesheet').setAttribute('href', 'pebble-'+watch_version+'.css'); 236 | } else if (watch_version > 3) { 237 | document.getElementById('pebble-stylesheet').setAttribute('href', 'pebble-3.css'); 238 | } else { 239 | document.getElementById('pebble-stylesheet').setAttribute('href', 'pebble-1.css'); 240 | } 241 | 242 | var otp_count = getQueryParam("otp_count", 0); 243 | var font_style = getQueryParam("font_style", 0); 244 | var idle_timeout = getQueryParam("idle_timeout", 300); 245 | var window_layout = getQueryParam("window_layout", 0); 246 | 247 | font_style = parseInt(isNumber(font_style) && font_style <= 3 ? font_style : 0); 248 | idle_timeout = parseInt(isNumber(idle_timeout) && (idle_timeout >= 0 || idle_timeout == 60 || idle_timeout == 120 || idle_timeout == 300 || idle_timeout == 600) ? idle_timeout : 300); 249 | window_layout = parseInt(isNumber(window_layout) && window_layout <= 3 ? window_layout : 0); 250 | 251 | $('#font_style_'+font_style).prop( "checked", true ).checkboxradio("refresh"); 252 | $("#idle_timeout").val(idle_timeout).selectmenu("refresh"); 253 | $('#window_layout_'+window_layout).prop( "checked", true ).checkboxradio("refresh"); 254 | 255 | otp_count = parseInt(isNumber(otp_count) ? otp_count : 0); 256 | var slots_remaining = 16 - otp_count; 257 | 258 | if (slots_remaining === 0) { 259 | document.getElementById("keyname").disabled=true; 260 | document.getElementById("keysecret").disabled=true; 261 | } 262 | document.getElementById("footer").innerHTML=document.getElementById("footer").innerHTML.replace("NUM_SPACES", slots_remaining); 263 | }); -------------------------------------------------------------------------------- /html/v25/OLD/assets/Thumbs.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v25/OLD/assets/Thumbs.db -------------------------------------------------------------------------------- /html/v25/OLD/assets/og/font_style_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v25/OLD/assets/og/font_style_1.png -------------------------------------------------------------------------------- /html/v25/OLD/assets/og/font_style_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v25/OLD/assets/og/font_style_2.png -------------------------------------------------------------------------------- /html/v25/OLD/assets/og/font_style_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v25/OLD/assets/og/font_style_3.png -------------------------------------------------------------------------------- /html/v25/OLD/assets/og/font_style_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v25/OLD/assets/og/font_style_4.png -------------------------------------------------------------------------------- /html/v25/OLD/assets/og/multi_code_layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v25/OLD/assets/og/multi_code_layout.png -------------------------------------------------------------------------------- /html/v25/OLD/assets/time/font_style_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v25/OLD/assets/time/font_style_1.png -------------------------------------------------------------------------------- /html/v25/OLD/assets/time/font_style_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v25/OLD/assets/time/font_style_2.png -------------------------------------------------------------------------------- /html/v25/OLD/assets/time/font_style_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v25/OLD/assets/time/font_style_3.png -------------------------------------------------------------------------------- /html/v25/OLD/assets/time/font_style_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v25/OLD/assets/time/font_style_4.png -------------------------------------------------------------------------------- /html/v25/OLD/assets/time/multi_code_layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v25/OLD/assets/time/multi_code_layout.png -------------------------------------------------------------------------------- /html/v25/OLD/pebble-og.css: -------------------------------------------------------------------------------- 1 | .font_1_screenshot { 2 | background-image: url(assets/og/font_style_1.png); 3 | height: 168px; 4 | width: 144px; 5 | } 6 | .font_2_screenshot { 7 | background-image: url(assets/og/font_style_2.png); 8 | height: 168px; 9 | width: 144px; 10 | } 11 | .font_3_screenshot { 12 | background-image: url(assets/og/font_style_3.png); 13 | height: 168px; 14 | width: 144px; 15 | } 16 | .font_4_screenshot { 17 | background-image: url(assets/og/font_style_4.png); 18 | height: 168px; 19 | width: 144px; 20 | } 21 | .multi_code_layout_screenshot { 22 | background-image: url(assets/og/multi_code_layout.png); 23 | height: 168px; 24 | width: 144px; 25 | } -------------------------------------------------------------------------------- /html/v25/OLD/pebble-time.css: -------------------------------------------------------------------------------- 1 | .font_1_screenshot { 2 | background-image: url(assets/time/font_style_1.png); 3 | height: 168px; 4 | width: 144px; 5 | } 6 | .font_2_screenshot { 7 | background-image: url(assets/time/font_style_2.png); 8 | height: 168px; 9 | width: 144px; 10 | } 11 | .font_3_screenshot { 12 | background-image: url(assets/time/font_style_3.png); 13 | height: 168px; 14 | width: 144px; 15 | } 16 | .font_4_screenshot { 17 | background-image: url(assets/time/font_style_4.png); 18 | height: 168px; 19 | width: 144px; 20 | } 21 | .multi_code_layout_screenshot { 22 | background-image: url(assets/time/multi_code_layout.png); 23 | height: 168px; 24 | width: 144px; 25 | } -------------------------------------------------------------------------------- /html/v25/OLD/script.js: -------------------------------------------------------------------------------- 1 | $(function () { 2 | $('#foreground-color').on('click', function (event) { 3 | changeForeground = true; 4 | highlightColorBox($(this)); 5 | }); 6 | }); 7 | 8 | $(function () { 9 | $('#background-color').on('click', function (event) { 10 | changeForeground = false; 11 | highlightColorBox($(this)); 12 | }); 13 | }); 14 | 15 | $(function () { 16 | $('#color-picker .color-box').on('click', function (event) { 17 | var selected_color = rgb2hex($(this).css("background-color")); 18 | 19 | if (changeForeground) 20 | $('#foreground-color').css('background-color', selected_color); 21 | else 22 | $('#background-color').css('background-color', selected_color); 23 | $( "#color-picker" ).popup( "close" ); 24 | }); 25 | }); 26 | 27 | $(function () { 28 | $("#confirm_delete_all").click(function() { 29 | console.log("Deleting all"); 30 | var options = {}; 31 | options.delete_all = 1; 32 | var location = "pebblejs://close#" + encodeURIComponent(JSON.stringify(options)); 33 | document.location = location; 34 | }); 35 | }); 36 | 37 | $(function () { 38 | $("#cancel").click(function() { 39 | console.log("Cancelling"); 40 | document.location = "pebblejs://close"; 41 | }); 42 | }); 43 | 44 | $(function () { 45 | $("#save").click(function() { 46 | console.log("Submit"); 47 | 48 | var options = saveOptions(); 49 | 50 | if (options.secret && base32length(options.secret) < 10) { 51 | alert("Secret key value is too short"); 52 | } 53 | else if (options.secret && options.label.length === 0) { 54 | alert("Please enter a label"); 55 | } 56 | else { 57 | var return_to = getQueryParam('return_to', 'pebblejs://close#'); 58 | var location = return_to + encodeURIComponent(JSON.stringify(options)); 59 | console.log("Warping to:"); 60 | console.log(location); 61 | document.location = location; 62 | } 63 | }); 64 | }); 65 | 66 | function highlightColorBox($colorButton) { 67 | selectedColor = rgb2hex($colorButton.css("background-color")); 68 | 69 | var i; 70 | for (i = 1; i <= 13; i++) 71 | { 72 | $('#color-row'+i).children().removeClass("selected-color-box"); 73 | } 74 | $('#color-box-'+selectedColor.substring(1).toUpperCase()).addClass("selected-color-box"); 75 | } 76 | 77 | //Function to convert hex format to a rgb color 78 | function rgb2hex(rgb){ 79 | rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/); 80 | return ("#" + 81 | ("0" + parseInt(rgb[1],10).toString(16)).slice(-2) + 82 | ("0" + parseInt(rgb[2],10).toString(16)).slice(-2) + 83 | ("0" + parseInt(rgb[3],10).toString(16)).slice(-2)).toUpperCase(); 84 | } 85 | 86 | function queryObj() { 87 | var result = {}, keyValuePairs = location.search.slice(1).split('&'); 88 | 89 | keyValuePairs.forEach(function(keyValuePair) { 90 | keyValuePair = keyValuePair.split('='); 91 | result[keyValuePair[0]] = keyValuePair[1] || ''; 92 | }); 93 | 94 | return result; 95 | } 96 | 97 | function getQueryParam(variable, default_) { 98 | var query = location.search.substring(1); 99 | var vars = query.split('&'); 100 | for (var i = 0; i < vars.length; i++) { 101 | var pair = vars[i].split('='); 102 | if (pair[0] == variable) 103 | return decodeURIComponent(pair[1]); 104 | } 105 | return default_ || false; 106 | } 107 | 108 | function isNumber(n) { 109 | return !isNaN(parseFloat(n)) && isFinite(n); 110 | } 111 | 112 | // Base32 decoder from https://github.com/agnoster/base32-js/blob/master/lib/base32.js by Isaac Wolkerstorfer 113 | var alphabet = '0123456789abcdefghjkmnpqrtuvwxyz' 114 | var alias = { o:0, i:1, l:1, s:5 } 115 | 116 | var lookup = function() { 117 | var table = {} 118 | // Invert 'alphabet' 119 | for (var i = 0; i < alphabet.length; i++) { 120 | table[alphabet[i]] = i 121 | } 122 | // Splice in 'alias' 123 | for (var key in alias) { 124 | if (!alias.hasOwnProperty(key)) continue 125 | table[key] = table['' + alias[key]] 126 | } 127 | lookup = function() { return table } 128 | return table 129 | } 130 | 131 | function Decoder() { 132 | var skip = 0 // how many bits we have from the previous character 133 | var byte = 0 // current byte we're producing 134 | 135 | this.output = '' 136 | 137 | // Consume a character from the stream, store 138 | // the output in this.output. As before, better 139 | // to use update(). 140 | this.readChar = function(char) { 141 | if (typeof char != 'string'){ 142 | if (typeof char == 'number') { 143 | char = String.fromCharCode(char) 144 | } 145 | } 146 | char = char.toLowerCase() 147 | var val = lookup()[char] 148 | if (typeof val == 'undefined') { 149 | // character does not exist in our lookup table 150 | return // skip silently. An alternative would be: 151 | // throw Error('Could not find character "' + char + '" in lookup table.') 152 | } 153 | val <<= 3 // move to the high bits 154 | byte |= val >>> skip 155 | skip += 5 156 | if (skip >= 8) { 157 | // we have enough to preduce output 158 | this.output += String.fromCharCode(byte) 159 | skip -= 8 160 | if (skip > 0) byte = (val << (5 - skip)) & 255 161 | else byte = 0 162 | } 163 | 164 | } 165 | 166 | this.finish = function(check) { 167 | var output = this.output + (skip < 0 ? alphabet[bits >> 3] : '') + (check ? '$' : '') 168 | this.output = '' 169 | return output 170 | } 171 | } 172 | 173 | Decoder.prototype.update = function(input, flush) { 174 | for (var i = 0; i < input.length; i++) { 175 | this.readChar(input[i]) 176 | } 177 | var output = this.output 178 | this.output = '' 179 | if (flush) { 180 | output += this.finish() 181 | } 182 | return output 183 | } 184 | 185 | // Base32-encoded string goes in, decoded data comes out. 186 | function decode(input) { 187 | var decoder = new Decoder() 188 | var output = decoder.update(input, true) 189 | return output 190 | } 191 | 192 | function base32length(secret) { 193 | return decode(secret).length; 194 | } 195 | 196 | function saveOptions() { 197 | 198 | var options = {}; 199 | 200 | options.theme = parseInt($("input[name=theme]:checked").val(), 10); 201 | options.font_style = parseInt($("input[name=font_style]:checked").val(), 10); 202 | options.idle_timeout = parseInt($("#idle_timeout").val(), 10); 203 | options.window_layout = parseInt($("input[name=window_layout]:checked").val(), 10); 204 | 205 | var colors = rgb2hex($('#background-color').css("background-color")).replace("#", ''); 206 | colors = colors + rgb2hex($('#foreground-color').css("background-color")).replace("#", ''); 207 | options.basalt_colors = colors; 208 | 209 | if ($("#keysecret").val()) { 210 | options.label = $("#keyname").val(); 211 | options.secret = $("#keysecret").val().replace(/\s/g, ''); 212 | } 213 | 214 | return options; 215 | } 216 | 217 | $("document").ready(function() { 218 | var watch_version = getQueryParam("watch_version", 1); 219 | 220 | if (watch_version >= 3) { 221 | document.getElementById('pebble-stylesheet').setAttribute('href', 'pebble-time.css'); 222 | var basalt_colors = getQueryParam("basalt_colors", 0); 223 | basalt_colors = basalt_colors.length == 12 ? basalt_colors : "00AAFFFFFFFF"; 224 | $('#background-color').css('background-color', "#"+basalt_colors.substring(0,6)); 225 | $('#foreground-color').css('background-color', "#"+basalt_colors.substring(6,12)); 226 | $('#time-foreground').removeClass("hidden"); 227 | $('#time-background').removeClass("hidden"); 228 | } else { 229 | var theme = getQueryParam("theme", 0); 230 | theme = parseInt(isNumber(theme) && theme <= 1 ? theme : 0); 231 | $('#theme').removeClass("hidden"); 232 | $('#theme_'+theme).prop( "checked", true ).checkboxradio("refresh"); 233 | } 234 | 235 | var otp_count = getQueryParam("otp_count", 0); 236 | var font_style = getQueryParam("font_style", 0); 237 | var idle_timeout = getQueryParam("idle_timeout", 300); 238 | var window_layout = getQueryParam("window_layout", 0); 239 | 240 | font_style = parseInt(isNumber(font_style) && font_style <= 3 ? font_style : 0); 241 | idle_timeout = parseInt(isNumber(idle_timeout) && (idle_timeout >= 0 || idle_timeout == 60 || idle_timeout == 120 || idle_timeout == 300 || idle_timeout == 600) ? idle_timeout : 300); 242 | window_layout = parseInt(isNumber(window_layout) && window_layout <= 3 ? window_layout : 0); 243 | 244 | $('#font_style_'+font_style).prop( "checked", true ).checkboxradio("refresh"); 245 | $("#idle_timeout").val(idle_timeout).selectmenu("refresh"); 246 | $('#window_layout_'+window_layout).prop( "checked", true ).checkboxradio("refresh"); 247 | 248 | otp_count = parseInt(isNumber(otp_count) ? otp_count : 0); 249 | var slots_remaining = 16 - otp_count; 250 | 251 | if (slots_remaining === 0) { 252 | document.getElementById("keyname").disabled=true; 253 | document.getElementById("keysecret").disabled=true; 254 | } 255 | document.getElementById("footer").innerHTML=document.getElementById("footer").innerHTML.replace("NUM_SPACES", slots_remaining); 256 | }); -------------------------------------------------------------------------------- /html/v25/assets/Thumbs.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v25/assets/Thumbs.db -------------------------------------------------------------------------------- /html/v25/assets/og/font_style_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v25/assets/og/font_style_1.png -------------------------------------------------------------------------------- /html/v25/assets/og/font_style_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v25/assets/og/font_style_2.png -------------------------------------------------------------------------------- /html/v25/assets/og/font_style_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v25/assets/og/font_style_3.png -------------------------------------------------------------------------------- /html/v25/assets/og/font_style_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v25/assets/og/font_style_4.png -------------------------------------------------------------------------------- /html/v25/assets/og/multi_code_layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v25/assets/og/multi_code_layout.png -------------------------------------------------------------------------------- /html/v25/assets/og/screenshot_holder_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v25/assets/og/screenshot_holder_1.png -------------------------------------------------------------------------------- /html/v25/assets/og/screenshot_holder_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v25/assets/og/screenshot_holder_2.png -------------------------------------------------------------------------------- /html/v25/assets/time/font_style_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v25/assets/time/font_style_1.png -------------------------------------------------------------------------------- /html/v25/assets/time/font_style_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v25/assets/time/font_style_2.png -------------------------------------------------------------------------------- /html/v25/assets/time/font_style_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v25/assets/time/font_style_3.png -------------------------------------------------------------------------------- /html/v25/assets/time/font_style_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v25/assets/time/font_style_4.png -------------------------------------------------------------------------------- /html/v25/assets/time/multi_code_layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v25/assets/time/multi_code_layout.png -------------------------------------------------------------------------------- /html/v25/assets/time/screenshot_holder_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v25/assets/time/screenshot_holder_3.png -------------------------------------------------------------------------------- /html/v25/pebble-1.css: -------------------------------------------------------------------------------- 1 | .screenshot_holder { 2 | background-image: url(assets/og/screenshot_holder_1.png); 3 | padding-top: 104px; 4 | height: 372px; 5 | width: 236px; 6 | background-repeat: no-repeat; 7 | } 8 | 9 | .font_1_screenshot { 10 | background-image: url(assets/og/font_style_1.png); 11 | height: 168px; 12 | width: 144px; 13 | margin-left: auto; 14 | margin-right: auto; 15 | } 16 | 17 | .font_2_screenshot { 18 | background-image: url(assets/og/font_style_2.png); 19 | height: 168px; 20 | width: 144px; 21 | margin-left: auto; 22 | margin-right: auto; 23 | } 24 | .font_3_screenshot { 25 | background-image: url(assets/og/font_style_3.png); 26 | height: 168px; 27 | width: 144px; 28 | margin-left: auto; 29 | margin-right: auto; 30 | } 31 | .font_4_screenshot { 32 | background-image: url(assets/og/font_style_4.png); 33 | height: 168px; 34 | width: 144px; 35 | margin-left: auto; 36 | margin-right: auto; 37 | } 38 | 39 | .multi_code_layout_screenshot { 40 | background-image: url(assets/og/multi_code_layout.png); 41 | height: 168px; 42 | width: 144px; 43 | margin-left: auto; 44 | margin-right: auto; 45 | } -------------------------------------------------------------------------------- /html/v25/pebble-2.css: -------------------------------------------------------------------------------- 1 | .screenshot_holder { 2 | background-image: url(assets/og/screenshot_holder_2.png); 3 | padding-top: 104px; 4 | height: 372px; 5 | width: 236px; 6 | background-repeat: no-repeat; 7 | } 8 | 9 | .font_1_screenshot { 10 | background-image: url(assets/og/font_style_1.png); 11 | height: 168px; 12 | width: 144px; 13 | margin-left: auto; 14 | margin-right: auto; 15 | } 16 | 17 | .font_2_screenshot { 18 | background-image: url(assets/og/font_style_2.png); 19 | height: 168px; 20 | width: 144px; 21 | margin-left: auto; 22 | margin-right: auto; 23 | } 24 | .font_3_screenshot { 25 | background-image: url(assets/og/font_style_3.png); 26 | height: 168px; 27 | width: 144px; 28 | margin-left: auto; 29 | margin-right: auto; 30 | } 31 | .font_4_screenshot { 32 | background-image: url(assets/og/font_style_4.png); 33 | height: 168px; 34 | width: 144px; 35 | margin-left: auto; 36 | margin-right: auto; 37 | } 38 | 39 | .multi_code_layout_screenshot { 40 | background-image: url(assets/og/multi_code_layout.png); 41 | height: 168px; 42 | width: 144px; 43 | margin-left: auto; 44 | margin-right: auto; 45 | } -------------------------------------------------------------------------------- /html/v25/pebble-3.css: -------------------------------------------------------------------------------- 1 | .screenshot_holder { 2 | background-image: url(assets/time/screenshot_holder_3.png); 3 | padding-top: 91px; 4 | height: 244px; 5 | width: 244px; 6 | background-repeat: no-repeat; 7 | } 8 | 9 | .font_1_screenshot { 10 | background-image: url(assets/time/font_style_1.png); 11 | height: 168px; 12 | width: 144px; 13 | margin-left: auto; 14 | margin-right: auto; 15 | } 16 | 17 | .font_2_screenshot { 18 | background-image: url(assets/time/font_style_2.png); 19 | height: 168px; 20 | width: 144px; 21 | margin-left: auto; 22 | margin-right: auto; 23 | } 24 | .font_3_screenshot { 25 | background-image: url(assets/time/font_style_3.png); 26 | height: 168px; 27 | width: 144px; 28 | margin-left: auto; 29 | margin-right: auto; 30 | } 31 | .font_4_screenshot { 32 | background-image: url(assets/time/font_style_4.png); 33 | height: 168px; 34 | width: 144px; 35 | margin-left: auto; 36 | margin-right: auto; 37 | } 38 | 39 | .multi_code_layout_screenshot { 40 | background-image: url(assets/time/multi_code_layout.png); 41 | height: 168px; 42 | width: 144px; 43 | margin-left: auto; 44 | margin-right: auto; 45 | } -------------------------------------------------------------------------------- /html/v25/script.js: -------------------------------------------------------------------------------- 1 | $(function () { 2 | $('#foreground-color').on('click', function (event) { 3 | changeForeground = true; 4 | highlightColorBox($(this)); 5 | }); 6 | }); 7 | 8 | $(function () { 9 | $('#background-color').on('click', function (event) { 10 | changeForeground = false; 11 | highlightColorBox($(this)); 12 | }); 13 | }); 14 | 15 | $(function () { 16 | $('#color-picker .color-box').on('click', function (event) { 17 | var selected_color = rgb2hex($(this).css("background-color")); 18 | 19 | if (changeForeground) 20 | $('#foreground-color').css('background-color', selected_color); 21 | else 22 | $('#background-color').css('background-color', selected_color); 23 | $( "#color-picker" ).popup( "close" ); 24 | }); 25 | }); 26 | 27 | $(function () { 28 | $("#confirm_delete_all").click(function() { 29 | console.log("Deleting all"); 30 | var options = {}; 31 | options.delete_all = 1; 32 | var location = "pebblejs://close#" + encodeURIComponent(JSON.stringify(options)); 33 | document.location = location; 34 | }); 35 | }); 36 | 37 | $(function () { 38 | $("#cancel").click(function() { 39 | console.log("Cancelling"); 40 | document.location = "pebblejs://close"; 41 | }); 42 | }); 43 | 44 | $(function () { 45 | $("#save").click(function() { 46 | console.log("Submit"); 47 | 48 | var options = saveOptions(); 49 | 50 | if (options.secret && base32length(options.secret) < 10) { 51 | alert("Secret key value is too short"); 52 | } 53 | else if (options.secret && options.label.length === 0) { 54 | alert("Please enter a label"); 55 | } 56 | else { 57 | var return_to = getQueryParam('return_to', 'pebblejs://close#'); 58 | var location = return_to + encodeURIComponent(JSON.stringify(options)); 59 | console.log("Warping to:"); 60 | console.log(location); 61 | document.location = location; 62 | } 63 | }); 64 | }); 65 | 66 | function highlightColorBox($colorButton) { 67 | selectedColor = rgb2hex($colorButton.css("background-color")); 68 | 69 | var i; 70 | for (i = 1; i <= 13; i++) 71 | { 72 | $('#color-row'+i).children().removeClass("selected-color-box"); 73 | } 74 | $('#color-box-'+selectedColor.substring(1).toUpperCase()).addClass("selected-color-box"); 75 | } 76 | 77 | //Function to convert hex format to a rgb color 78 | function rgb2hex(rgb){ 79 | rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/); 80 | return ("#" + 81 | ("0" + parseInt(rgb[1],10).toString(16)).slice(-2) + 82 | ("0" + parseInt(rgb[2],10).toString(16)).slice(-2) + 83 | ("0" + parseInt(rgb[3],10).toString(16)).slice(-2)).toUpperCase(); 84 | } 85 | 86 | function queryObj() { 87 | var result = {}, keyValuePairs = location.search.slice(1).split('&'); 88 | 89 | keyValuePairs.forEach(function(keyValuePair) { 90 | keyValuePair = keyValuePair.split('='); 91 | result[keyValuePair[0]] = keyValuePair[1] || ''; 92 | }); 93 | 94 | return result; 95 | } 96 | 97 | function getQueryParam(variable, default_) { 98 | var query = location.search.substring(1); 99 | var vars = query.split('&'); 100 | for (var i = 0; i < vars.length; i++) { 101 | var pair = vars[i].split('='); 102 | if (pair[0] == variable) 103 | return decodeURIComponent(pair[1]); 104 | } 105 | return default_ || false; 106 | } 107 | 108 | function isNumber(n) { 109 | return !isNaN(parseFloat(n)) && isFinite(n); 110 | } 111 | 112 | // Base32 decoder from https://github.com/agnoster/base32-js/blob/master/lib/base32.js by Isaac Wolkerstorfer 113 | var alphabet = '0123456789abcdefghjkmnpqrtuvwxyz' 114 | var alias = { o:0, i:1, l:1, s:5 } 115 | 116 | var lookup = function() { 117 | var table = {} 118 | // Invert 'alphabet' 119 | for (var i = 0; i < alphabet.length; i++) { 120 | table[alphabet[i]] = i 121 | } 122 | // Splice in 'alias' 123 | for (var key in alias) { 124 | if (!alias.hasOwnProperty(key)) continue 125 | table[key] = table['' + alias[key]] 126 | } 127 | lookup = function() { return table } 128 | return table 129 | } 130 | 131 | function Decoder() { 132 | var skip = 0 // how many bits we have from the previous character 133 | var byte = 0 // current byte we're producing 134 | 135 | this.output = '' 136 | 137 | // Consume a character from the stream, store 138 | // the output in this.output. As before, better 139 | // to use update(). 140 | this.readChar = function(char) { 141 | if (typeof char != 'string'){ 142 | if (typeof char == 'number') { 143 | char = String.fromCharCode(char) 144 | } 145 | } 146 | char = char.toLowerCase() 147 | var val = lookup()[char] 148 | if (typeof val == 'undefined') { 149 | // character does not exist in our lookup table 150 | return // skip silently. An alternative would be: 151 | // throw Error('Could not find character "' + char + '" in lookup table.') 152 | } 153 | val <<= 3 // move to the high bits 154 | byte |= val >>> skip 155 | skip += 5 156 | if (skip >= 8) { 157 | // we have enough to preduce output 158 | this.output += String.fromCharCode(byte) 159 | skip -= 8 160 | if (skip > 0) byte = (val << (5 - skip)) & 255 161 | else byte = 0 162 | } 163 | 164 | } 165 | 166 | this.finish = function(check) { 167 | var output = this.output + (skip < 0 ? alphabet[bits >> 3] : '') + (check ? '$' : '') 168 | this.output = '' 169 | return output 170 | } 171 | } 172 | 173 | Decoder.prototype.update = function(input, flush) { 174 | for (var i = 0; i < input.length; i++) { 175 | this.readChar(input[i]) 176 | } 177 | var output = this.output 178 | this.output = '' 179 | if (flush) { 180 | output += this.finish() 181 | } 182 | return output 183 | } 184 | 185 | // Base32-encoded string goes in, decoded data comes out. 186 | function decode(input) { 187 | var decoder = new Decoder() 188 | var output = decoder.update(input, true) 189 | return output 190 | } 191 | 192 | function base32length(secret) { 193 | return decode(secret).length; 194 | } 195 | 196 | function saveOptions() { 197 | 198 | var options = {}; 199 | 200 | options.theme = parseInt($("input[name=theme]:checked").val(), 10); 201 | options.font_style = parseInt($("input[name=font_style]:checked").val(), 10); 202 | options.idle_timeout = parseInt($("#idle_timeout").val(), 10); 203 | options.window_layout = parseInt($("input[name=window_layout]:checked").val(), 10); 204 | 205 | var colors = rgb2hex($('#background-color').css("background-color")).replace("#", ''); 206 | colors = colors + rgb2hex($('#foreground-color').css("background-color")).replace("#", ''); 207 | options.basalt_colors = colors; 208 | 209 | if ($("#keysecret").val()) { 210 | options.label = $("#keyname").val(); 211 | options.secret = $("#keysecret").val().replace(/\W/g, ''); 212 | } 213 | 214 | return options; 215 | } 216 | 217 | $("document").ready(function() { 218 | var watch_version = getQueryParam("watch_version", 1); 219 | 220 | if (watch_version >= 3) { 221 | var basalt_colors = getQueryParam("basalt_colors", 0); 222 | basalt_colors = basalt_colors.length == 12 ? basalt_colors : "00AAFFFFFFFF"; 223 | $('#background-color').css('background-color', "#"+basalt_colors.substring(0,6)); 224 | $('#foreground-color').css('background-color', "#"+basalt_colors.substring(6,12)); 225 | $('#time-foreground').removeClass("hidden"); 226 | $('#time-background').removeClass("hidden"); 227 | } else { 228 | var theme = getQueryParam("theme", 0); 229 | theme = parseInt(isNumber(theme) && theme <= 1 ? theme : 0); 230 | $('#theme').removeClass("hidden"); 231 | $('#theme_'+theme).prop( "checked", true ).checkboxradio("refresh"); 232 | } 233 | 234 | if (watch_version >= 2 && watch_version <= 3) { 235 | document.getElementById('pebble-stylesheet').setAttribute('href', 'pebble-'+watch_version+'.css'); 236 | } else if (watch_version > 3) { 237 | document.getElementById('pebble-stylesheet').setAttribute('href', 'pebble-3.css'); 238 | } else { 239 | document.getElementById('pebble-stylesheet').setAttribute('href', 'pebble-1.css'); 240 | } 241 | 242 | var otp_count = getQueryParam("otp_count", 0); 243 | var font_style = getQueryParam("font_style", 0); 244 | var idle_timeout = getQueryParam("idle_timeout", 300); 245 | var window_layout = getQueryParam("window_layout", 0); 246 | 247 | font_style = parseInt(isNumber(font_style) && font_style <= 3 ? font_style : 0); 248 | idle_timeout = parseInt(isNumber(idle_timeout) && (idle_timeout >= 0 || idle_timeout == 60 || idle_timeout == 120 || idle_timeout == 300 || idle_timeout == 600) ? idle_timeout : 300); 249 | window_layout = parseInt(isNumber(window_layout) && window_layout <= 3 ? window_layout : 0); 250 | 251 | $('#font_style_'+font_style).prop( "checked", true ).checkboxradio("refresh"); 252 | $("#idle_timeout").val(idle_timeout).selectmenu("refresh"); 253 | $('#window_layout_'+window_layout).prop( "checked", true ).checkboxradio("refresh"); 254 | 255 | otp_count = parseInt(isNumber(otp_count) ? otp_count : 0); 256 | var slots_remaining = 16 - otp_count; 257 | 258 | if (slots_remaining === 0) { 259 | document.getElementById("keyname").disabled=true; 260 | document.getElementById("keysecret").disabled=true; 261 | } 262 | document.getElementById("footer").innerHTML=document.getElementById("footer").innerHTML.replace("NUM_SPACES", slots_remaining); 263 | }); -------------------------------------------------------------------------------- /html/v4/assets/Thumbs.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v4/assets/Thumbs.db -------------------------------------------------------------------------------- /html/v4/assets/font_style_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v4/assets/font_style_1.png -------------------------------------------------------------------------------- /html/v4/assets/font_style_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v4/assets/font_style_2.png -------------------------------------------------------------------------------- /html/v4/assets/font_style_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v4/assets/font_style_3.png -------------------------------------------------------------------------------- /html/v4/assets/font_style_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JumpMaster/QuickAuth/1ec47bfd593959b251436e7481226f7913915a8c/html/v4/assets/font_style_4.png -------------------------------------------------------------------------------- /html/v4/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 |This application allows you to get your one time code codes straight from your Pebble Smartwatch.
92 |Many websites support two-factor authentication to enhance your security including Facebook, Dropbox, AWS, and all of Google's services.
93 |If you don't already have Google Authenticator installed on your smartphone I would recommend you install it as a backup. To get your codes using PebbleAuth simply go through the setup process on the website such as Facebook. You will either get a QR code to scan or be given a key which is a random 14-64 character long string. Scan the barcode or enter the key into your Google Authenticator app. If you were given a key you can enter this straight into the configuration page here. If you were given a QR code there'll usually be a link to get a key for "other devices". Enter this key into the the configuration page and you're good to go!
94 |The font styles and theme are global and can be changed without entering a new key. The Name field can be up to 20 characters long although only Style 2 supports showing that many characters.
95 |Happy Two-Factoring!
96 |A new version of PebbleAuth has been released. To update please unload PebbleAuth from the Pebble App, then load it again from your locker.
101 |Don't worry. Your keys will not be removed in the process.
102 |This application allows you to get your one time code codes straight from your Pebble Smartwatch.
92 |Many websites support two-factor authentication to enhance your security including Facebook, Dropbox, AWS, and all of Google's services.
93 |If you don't already have Google Authenticator installed on your smartphone I would recommend you install it as a backup. To get your codes using PebbleAuth simply go through the setup process on the website such as Facebook. You will either get a QR code to scan or be given a key which is a random 14-64 character long string. Scan the barcode or enter the key into your Google Authenticator app. If you were given a key you can enter this straight into the configuration page here. If you were given a QR code there'll usually be a link to get a key for "other devices". Enter this key into the the configuration page and you're good to go!
94 |The font styles and theme are global and can be changed without entering a new key. The Name field can be up to 20 characters long although only Style 2 supports showing that many characters.
95 |Happy Two-Factoring!
96 |A new version of PebbleAuth has been released. To update please unload PebbleAuth from the Pebble App, then load it again from your locker.
101 |Don't worry. Your keys will not be removed in the process.
102 |This application allows you to get your one time code codes straight from your Pebble Smartwatch.
103 |Many websites support two-factor authentication to enhance your security including Facebook, Dropbox, AWS, and all of Google's services.
104 |If you don't already have Google Authenticator installed on your smartphone I would recommend you install it as a backup. To get your codes using PebbleAuth simply go through the setup process on the website such as Facebook. You will either get a QR code to scan or be given a key which is a random 14-64 character long string. Scan the barcode or enter the key into your Google Authenticator app. If you were given a key you can enter this straight into the configuration page here. If you were given a QR code there'll usually be a link to get a key for "other devices". Enter this key into the the configuration page and you're good to go!
105 |The font styles and theme are global and can be changed without entering a new key. The Name field can be up to 20 characters long although only Style 2 supports showing that many characters.
106 |Happy Two-Factoring!
107 |A new version of PebbleAuth has been released. To update please unload PebbleAuth from the Pebble App, then load it again from your locker.
112 |Don't worry. Your keys will not be removed in the process.
113 |This cannot be undone!
129 |This application allows you to get your one time code codes straight from your Pebble Smartwatch.
103 |Many websites support two-factor authentication to enhance your security including Facebook, Dropbox, AWS, and all of Google's services.
104 |If you don't already have Google Authenticator installed on your smartphone I would recommend you install it as a backup. To get your codes using PebbleAuth simply go through the setup process on the website such as Facebook. You will either get a QR code to scan or be given a key which is a random 14-64 character long string. Scan the barcode or enter the key into your Google Authenticator app. If you were given a key you can enter this straight into the configuration page here. If you were given a QR code there'll usually be a link to get a key for "other devices". Enter this key into the the configuration page and you're good to go!
105 |The font styles and theme are global and can be changed without entering a new key. The Name field can be up to 20 characters long although only Style 2 supports showing that many characters.
106 |Happy Two-Factoring!
107 |A new version of PebbleAuth has been released. To update please unload PebbleAuth from the Pebble App, then load it again from your locker.
112 |Don't worry. Your keys will not be removed in the process.
113 |This cannot be undone!
129 |