From 383854bd6f0e1c5ea394e70a0aa1f6f98dba5ee3 Mon Sep 17 00:00:00 2001 From: JumpMaster Date: Sun, 6 Apr 2014 04:01:21 -0700 Subject: [PATCH] Version 1.2 Selectable font styles. Name field upped to 20 characters. Improved configuration page including help screen. --- appinfo.json | 28 ++++- resources/fonts/ANDROID_24.ttf | Bin 0 -> 34360 bytes resources/fonts/BD_Cartoon_Shout.ttf | Bin 0 -> 39200 bytes src/hmac.h | 2 +- src/js/pebble-js-app.js | 53 ++++++-- src/main.c | 181 +++++++++++++++++++-------- src/main.h | 32 +++++ 7 files changed, 231 insertions(+), 65 deletions(-) create mode 100644 resources/fonts/ANDROID_24.ttf create mode 100644 resources/fonts/BD_Cartoon_Shout.ttf create mode 100644 src/main.h diff --git a/appinfo.json b/appinfo.json index 413b39e..04c7a4d 100644 --- a/appinfo.json +++ b/appinfo.json @@ -1,8 +1,9 @@ { - "versionLabel": "1.1.1", + "versionLabel": "1.2", "uuid": "1f4d9835-3b9a-4ddd-907e-41a25d06f19c", "appKeys": { "transmit_key": 2, + "font_style": 7, "key_count": 0, "show_message": 4, "request_key": 1, @@ -11,7 +12,7 @@ "timezone": 3 }, "longName": "PebbleAuth", - "versionCode": 3, + "versionCode": 4, "capabilities": [ "configurable" ], @@ -22,6 +23,28 @@ }, "resources": { "media": [ + { + "characterRegex": "[0-9]", + "type": "font", + "name": "FONT_BD_CARTOON_28", + "file": "fonts/BD_Cartoon_Shout.ttf" + }, + { + "type": "font", + "name": "FONT_BD_CARTOON_20", + "file": "fonts/BD_Cartoon_Shout.ttf" + }, + { + "characterRegex": "[0-9]", + "type": "font", + "name": "FONT_DIGITAL_38", + "file": "fonts/ANDROID_24.ttf" + }, + { + "type": "font", + "name": "FONT_DIGITAL_28", + "file": "fonts/ANDROID_24.ttf" + }, { "menuIcon": true, "type": "png", @@ -49,7 +72,6 @@ "file": "fonts/ORBITRON_28.ttf" }, { - "characterRegex": "[0-9A-Z?]", "type": "font", "name": "FONT_BITWISE_32", "file": "fonts/BITWISE_32.ttf" diff --git a/resources/fonts/ANDROID_24.ttf b/resources/fonts/ANDROID_24.ttf new file mode 100644 index 0000000000000000000000000000000000000000..5dbe6f908239d00a9f88c335df3efb9261ecc3cc GIT binary patch literal 34360 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 aTH90WtKf3~!xB(o{SQ8~0z*o$+4w(}L589L literal 0 HcmV?d00001 diff --git a/src/hmac.h b/src/hmac.h index 4119e36..de7f6af 100644 --- a/src/hmac.h +++ b/src/hmac.h @@ -25,4 +25,4 @@ void hmac_sha1(const uint8_t *key, int keyLength, uint8_t *result, int resultLength) __attribute__((visibility("hidden"))); -#endif /* _HMAC_H_ */ +#endif /* _HMAC_H_ */ \ No newline at end of file diff --git a/src/js/pebble-js-app.js b/src/js/pebble-js-app.js index b4cbc2b..2af5f79 100644 --- a/src/js/pebble-js-app.js +++ b/src/js/pebble-js-app.js @@ -1,22 +1,26 @@ var MAX_OTP = 16; +var MAX_LABEL_LENGTH = 20; +var MAX_KEY_LENGTH = 64; + var otp_count = 0; var theme = 0; +var font_style = 0; var timezoneOffset = 0; var message_send_retries = 0; var message_send_max_retries = 5; -var app_version = 3; +var app_version = 4; var debug = false; function loadLocalVariables() { otp_count = parseInt(localStorage.getItem("otp_count")); theme = parseInt(localStorage.getItem("theme")); - timezoneOffset = new Date().getTimezoneOffset(); + font_style = parseInt(localStorage.getItem("font_style")); - if (!otp_count) - otp_count = 0; + timezoneOffset = new Date().getTimezoneOffset(); - if (!theme) - theme = 0; + otp_count = !otp_count ? 0 : otp_count; + theme = !theme ? 0 : theme; + font_style = !font_style ? 0 : font_style; } function sendAppMessage(data) { @@ -50,12 +54,18 @@ Pebble.addEventListener("ready", loadLocalVariables(); // Send timezone, keycount, and theme to watch - sendAppMessage({"key_count":otp_count, "theme":theme, "timezone":timezoneOffset}); + sendAppMessage({ + "key_count":otp_count, + "theme":theme, + "timezone":timezoneOffset, + "font_style":font_style + }); if (debug) { console.log("otp_count="+otp_count); console.log("theme="+theme); console.log("timezoneOffset="+timezoneOffset); + console.log("font_style="+font_style); } } ); @@ -107,7 +117,12 @@ Pebble.addEventListener("appmessage", }); Pebble.addEventListener('showConfiguration', function(e) { - var url = 'http://oncloudvirtual.com/pebble/pebbleauth/?version='+app_version+'&otp_count='+otp_count; + var url = 'http://oncloudvirtual.com/pebble/pebbleauth/v'+ + app_version+'/'+ + '?otp_count='+otp_count+ + '&theme='+theme+ + '&font_style='+font_style; + if (debug) console.log(url); Pebble.openURL(url); @@ -126,10 +141,28 @@ Pebble.addEventListener("webviewclosed", localStorage.setItem("theme",theme); config.theme = theme; } + + if(!isNaN(configuration.font_style) && configuration.font_style != font_style) { + if (debug) + console.log("Font style changed:"+configuration.font_style); + + font_style = configuration.font_style; + localStorage.setItem("font_style",font_style); + config.font_style = font_style; + } if(configuration.label && configuration.secret) { - var secret = configuration.secret.replace(/0/g,"O").replace(/1/g, "I").replace(/\+/g, '').replace(/\s/g, '').toUpperCase(); - var secretPair = configuration.label + ":" + secret; + var secret = configuration.secret + .replace(/0/g,"O") + .replace(/1/g, "I") + .replace(/\+/g, '') + .replace(/\s/g, '') + .toUpperCase() + .substring(0, MAX_KEY_LENGTH); + var label = configuration.label + .replace(/:/g, '') + .substring(0, MAX_LABEL_LENGTH); + var secretPair = label + ":" + secret; var blnKeyExists = false; for (var i=0;i 0 && phone_otp_count < requesting_code) { + requesting_code = 0; if (DEBUG) APP_LOG(APP_LOG_LEVEL_DEBUG, "FINISHED REQUESTING"); } @@ -213,6 +223,11 @@ static void handle_second_tick(struct tm *tick_time, TimeUnits units_changed) { else strcpy(label_text, "NO"); + if (fonts_changed) { + set_fonts(); + fonts_changed = false; + } + GRect start = text_label_rect; start.origin.x = 144; animate_layer(text_layer_get_layer(text_label_layer), AnimationCurveEaseOut, &start, &text_label_rect, 300, 0); @@ -223,7 +238,7 @@ static void handle_second_tick(struct tm *tick_time, TimeUnits units_changed) { strcpy(pin_text, generateCode(otp_keys[otp_selected], timezone_offset)); else strcpy(pin_text, "SECRETS"); - + otp_updated_at_tick = otp_update_tick; finish_refresh = false; @@ -238,6 +253,7 @@ static void handle_second_tick(struct tm *tick_time, TimeUnits units_changed) { GRect start = layer_get_frame(text_layer_get_layer(countdown_layer)); GRect finish = (GRect(0, bounds.size.h-10, bounds.size.w, 10)); float boxsize = (30-(seconds%30))/((double)30); + finish.size.w = finish.size.w * boxsize; if (seconds % 30 == 0) @@ -343,6 +359,7 @@ void select_window_unload(Window *window) { void details_actionbar_up_click_handler(ClickRecognizerRef recognizer, void *context) { otp_default = details_selected_key; + persist_write_int(PS_DEFAULT_KEY, otp_default); if (otp_selected != otp_default) { otp_selected = otp_default; @@ -384,14 +401,14 @@ static void details_window_load(Window *window) { layer_add_child(details_window_layer, text_layer_get_layer(details_key_layer)); text_layer_set_text_color(details_key_layer, fg_color); text_layer_set_text(details_key_layer, otp_keys[details_selected_key]); - title_text_rect = GRect(0, 0, bounds.size.w, 125); + title_text_rect = GRect(0, 0, bounds.size.w, 40); } else - title_text_rect = GRect(0, 55, bounds.size.w, 125); + title_text_rect = GRect(0, 55, bounds.size.w, 40); details_title_layer = text_layer_create(title_text_rect); text_layer_set_background_color(details_title_layer, GColorClear); text_layer_set_text_alignment(details_title_layer, GTextAlignmentLeft); - text_layer_set_font(details_title_layer, font_ORBITRON_28); + text_layer_set_font(details_title_layer, font_label.font); layer_add_child(details_window_layer, text_layer_get_layer(details_title_layer)); @@ -439,10 +456,10 @@ void out_sent_handler(DictionaryIterator *sent, void *context) { if (DEBUG) APP_LOG(APP_LOG_LEVEL_DEBUG, "Outgoing Message Delivered"); - if (requesting_codes) { + if (requesting_code > 0) { if (DEBUG) APP_LOG(APP_LOG_LEVEL_DEBUG, "REQUESTING ANOTHER!"); - request_key(watch_otp_count+1); + request_key(requesting_code++); } } @@ -451,13 +468,13 @@ void out_failed_handler(DictionaryIterator *failed, AppMessageResult reason, voi if (DEBUG) APP_LOG(APP_LOG_LEVEL_DEBUG, "Outgoing Message Failed"); - if (requesting_codes && js_message_retry_count < js_message_max_retry_count) { + if (requesting_code > 0 && js_message_retry_count < js_message_max_retry_count) { js_message_retry_count++; if (DEBUG) APP_LOG(APP_LOG_LEVEL_DEBUG, "RETRY:%d REQUESTING ANOTHER!", js_message_retry_count); - request_key(watch_otp_count+1); + request_key(requesting_code); } } @@ -476,6 +493,54 @@ void set_theme() { text_layer_set_text_color(text_pin_layer, fg_color); } +void set_fonts() { + if (font_label.isCustom) + fonts_unload_custom_font(font_label.font); + + if (font_pin.isCustom) + fonts_unload_custom_font(font_pin.font); + + switch(font_style) + { + case 1 : + font_label.font = fonts_get_system_font(FONT_KEY_GOTHIC_24); + font_label.isCustom = false; + text_label_rect.origin.y = 38; + text_label_rect.size.h = 40; + font_pin.font = fonts_get_system_font(FONT_KEY_BITHAM_34_MEDIUM_NUMBERS); + font_pin.isCustom = false; + break; + case 2 : + font_label.font = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_DIGITAL_28)); + font_label.isCustom = true; + text_label_rect.origin.y = 38; + text_label_rect.size.h = 40; + font_pin.font = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_DIGITAL_38)); + font_pin.isCustom = true; + break; + case 3 : + font_label.font = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_BD_CARTOON_20)); + font_label.isCustom = true; + text_label_rect.origin.y = 32; + text_label_rect.size.h = 22; + font_pin.font = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_BD_CARTOON_28)); + font_pin.isCustom = true; + break; + default : + font_style = 0; + font_label.font = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_ORBITRON_28)); + font_label.isCustom = true; + text_label_rect.origin.y = 30; + text_label_rect.size.h = 40; + font_pin.font = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_BITWISE_32)); + font_pin.isCustom = true; + break; + } + + text_layer_set_font(text_label_layer, font_label.font); + text_layer_set_font(text_pin_layer, font_pin.font); +} + static void in_received_handler(DictionaryIterator *iter, void *context) { // Check for fields you expect to receive if (DEBUG) @@ -486,18 +551,22 @@ static void in_received_handler(DictionaryIterator *iter, void *context) { Tuple *key_delete_tuple = dict_find(iter, JS_DELETE_KEY); Tuple *timezone_tuple = dict_find(iter, JS_TIMEZONE); Tuple *theme_tuple = dict_find(iter, JS_THEME); + Tuple *font_style_tuple = dict_find(iter, JS_FONT_STYLE); // Act on the found fields received if (key_count_tuple) { - if (DEBUG) + if (DEBUG) { + APP_LOG(APP_LOG_LEVEL_DEBUG, "Key count from watch: %d", watch_otp_count); APP_LOG(APP_LOG_LEVEL_DEBUG, "Key count from phone: %d", key_count_tuple->value->int16); + } phone_otp_count = key_count_tuple->value->int16; - if (watch_otp_count == 0 && phone_otp_count > 0) { + //if (watch_otp_count == 0 && phone_otp_count > 0) { + if (watch_otp_count < phone_otp_count) { if (DEBUG) APP_LOG(APP_LOG_LEVEL_DEBUG, "REQUESTING CODES!!!"); - requesting_codes = true; - request_key(watch_otp_count+1); + requesting_code = 1; + request_key(requesting_code++); } } // key_count_tuple @@ -551,6 +620,7 @@ static void in_received_handler(DictionaryIterator *iter, void *context) { int tz_offset = timezone_tuple->value->int16; if (tz_offset != timezone_offset) { timezone_offset = tz_offset; + persist_write_int(PS_TIMEZONE_KEY, timezone_offset); refresh_screen_data(); } if (DEBUG) @@ -558,11 +628,26 @@ static void in_received_handler(DictionaryIterator *iter, void *context) { } // timezone_tuple if (theme_tuple) { - theme = theme_tuple->value->int16; - set_theme(); - if (DEBUG) - APP_LOG(APP_LOG_LEVEL_DEBUG, "Theme: %d", theme); + unsigned int theme_value = theme_tuple->value->int16; + if (theme != theme_value) { + theme = theme_value; + persist_write_int(PS_THEME, theme); + set_theme(); + if (DEBUG) + APP_LOG(APP_LOG_LEVEL_DEBUG, "Theme: %d", theme); + } } // theme_tuple + + if (font_style_tuple) { + unsigned int font_style_value = font_style_tuple->value->int16; + if (font_style != font_style_value) { + font_style = font_style_value; + persist_write_int(PS_FONT_STYLE, font_style); + update_screen_fonts(); + if (DEBUG) + APP_LOG(APP_LOG_LEVEL_DEBUG, "Font style: %d", font_style); + } + } // font_style_tuple } void in_dropped_handler(AppMessageResult reason, void *context) { @@ -575,6 +660,7 @@ void load_persistent_data() { timezone_offset = persist_exists(PS_TIMEZONE_KEY) ? persist_read_int(PS_TIMEZONE_KEY) : 0; theme = persist_exists(PS_THEME) ? persist_read_int(PS_THEME) : 0; otp_default = persist_exists(PS_DEFAULT_KEY) ? persist_read_int(PS_DEFAULT_KEY) : 0; + font_style = persist_exists(PS_FONT_STYLE) ? persist_read_int(PS_FONT_STYLE) : 0; if (persist_exists(PS_SECRET)) { for(int i = 0; i < MAX_OTP; i++) { @@ -588,7 +674,8 @@ void load_persistent_data() { else break; } - } + } else + APP_LOG(APP_LOG_LEVEL_DEBUG, "NO CODES ON WATCH!"); if (otp_default >= watch_otp_count) otp_default = 0; @@ -596,12 +683,6 @@ void load_persistent_data() { otp_selected = otp_default; } -void save_persistent_data() { - persist_write_int(PS_TIMEZONE_KEY, timezone_offset); - persist_write_int(PS_THEME, theme); - persist_write_int(PS_DEFAULT_KEY, otp_default); -} - static void window_load(Window *window) { window_set_click_config_provider(main_window, (ClickConfigProvider) window_config_provider); @@ -611,29 +692,29 @@ static void window_load(Window *window) { countdown_layer = text_layer_create(GRect(0, bounds.size.h-10, 0, 10)); layer_add_child(window_layer, text_layer_get_layer(countdown_layer)); - text_label_rect = GRect(0, 30, bounds.size.w, 125); + text_label_rect = GRect(0, 30, bounds.size.w, 40); GRect text_label_start_rect = text_label_rect; text_label_start_rect.origin.x = 144; text_label_layer = text_layer_create(text_label_start_rect); text_layer_set_background_color(text_label_layer, GColorClear); text_layer_set_text_alignment(text_label_layer, GTextAlignmentLeft); - text_layer_set_font(text_label_layer, font_ORBITRON_28); + text_layer_set_overflow_mode(text_label_layer, GTextOverflowModeWordWrap); text_layer_set_text(text_label_layer, label_text); layer_add_child(window_layer, text_layer_get_layer(text_label_layer)); - text_pin_rect = GRect(0, 60, bounds.size.w, 125); + text_pin_rect = GRect(0, 60, bounds.size.w, 40); GRect text_pin_start_rect = text_pin_rect; text_pin_start_rect.origin.x = 144; text_pin_layer = text_layer_create(text_pin_start_rect); text_layer_set_background_color(text_pin_layer, GColorClear); text_layer_set_text_alignment(text_pin_layer, GTextAlignmentCenter); - text_layer_set_font(text_pin_layer, font_BITWISE_32); text_layer_set_text(text_pin_layer, pin_text); layer_add_child(window_layer, text_layer_get_layer(text_pin_layer)); tick_timer_service_subscribe(SECOND_UNIT, &handle_second_tick); set_theme(); + set_fonts(); refresh_screen_data(); } @@ -648,9 +729,6 @@ void window_unload(Window *window) { void handle_init(void) { load_persistent_data(); - font_ORBITRON_28 = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_ORBITRON_28)); - font_BITWISE_32 = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_BITWISE_32)); - main_window = window_create(); window_set_window_handlers(main_window, (WindowHandlers) { .load = window_load, @@ -676,16 +754,17 @@ void handle_init(void) { app_message_register_outbox_sent(out_sent_handler); app_message_register_outbox_failed(out_failed_handler); - const uint32_t inbound_size = 128; - const uint32_t outbound_size = 128; + const uint32_t inbound_size = 256; + const uint32_t outbound_size = 256; app_message_open(inbound_size, outbound_size); } void handle_deinit(void) { - save_persistent_data(); animation_unschedule_all(); - fonts_unload_custom_font(font_ORBITRON_28); - fonts_unload_custom_font(font_BITWISE_32); + if (font_label.isCustom) + fonts_unload_custom_font(font_label.font); + if (font_pin.isCustom) + fonts_unload_custom_font(font_pin.font); window_destroy(details_window); window_destroy(select_window); window_destroy(main_window); diff --git a/src/main.h b/src/main.h new file mode 100644 index 0000000..6d3e5d5 --- /dev/null +++ b/src/main.h @@ -0,0 +1,32 @@ +// HMAC_SHA1 implementation +// +// Copyright 2010 Google Inc. +// Author: Markus Gutschke +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef _MAIN_H_ +#define _MAIN_H_ + +typedef struct { + GFont font; + bool isCustom; +} AppFont; + + +// define stubs +void window_config_provider(Window *window); +void request_key(int code_id); +void set_fonts(); + +#endif /* _MAIN_H_ */ \ No newline at end of file