Temporarily backport app updates from apps repo

This commit is contained in:
Willy-JL
2023-11-12 11:06:02 +00:00
parent 79e7f491fe
commit e309fa8a88
1498 changed files with 1325977 additions and 20227 deletions

View File

@@ -6,23 +6,23 @@ void canvas_draw_str_ex(
uint8_t y,
const char* text,
size_t text_length,
const FONT_INFO* const font) {
const FontInfo* const font) {
const char* p_ch = text;
char ch;
size_t i = 0;
uint8_t offset_x = x;
uint8_t char_width = font->charInfo[0].width;
uint8_t offset_x_inc = char_width + font->spacePixels;
uint8_t char_width = font->char_info[0].width;
uint8_t offset_x_inc = char_width + font->space_width;
while(i < text_length && (ch = *p_ch) != 0) {
if(ch >= font->startChar && ch <= font->endChar) {
uint8_t char_index = ch - font->startChar;
if(ch >= font->start_char && ch <= font->end_char) {
uint8_t char_index = ch - font->start_char;
canvas_draw_xbm(
canvas,
offset_x,
y,
char_width,
font->height,
&font->data[font->charInfo[char_index].offset]);
&font->data[font->char_info[char_index].offset]);
}
offset_x += offset_x_inc;

View File

@@ -2,7 +2,7 @@
#include <stdint.h>
#include <gui/gui.h>
#include <font_info.h>
#include "../services/fonts/font_info.h"
/**
* @brief Draw string using given font
@@ -19,4 +19,4 @@ void canvas_draw_str_ex(
uint8_t y,
const char* text,
size_t text_length,
const FONT_INFO* const font);
const FontInfo* const font);

View File

@@ -5,6 +5,10 @@
#include "../types/plugin_event.h"
#include "totp_scenes_enum.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Activates scene
* @param plugin_state application state
@@ -38,4 +42,8 @@ bool totp_scene_director_handle_event(PluginEvent* const event, PluginState* con
* @brief Forces screen to be redraw\updated
* @param plugin_state application state
*/
void totp_scene_director_force_redraw(PluginState* const plugin_state);
void totp_scene_director_force_redraw(PluginState* const plugin_state);
#ifdef __cplusplus
}
#endif

View File

@@ -12,6 +12,8 @@
char* TOKEN_ALGO_LIST[] = {"SHA1", "SHA256", "SHA512", "Steam"};
char* TOKEN_DIGITS_TEXT_LIST[] = {"5 digits", "6 digits", "8 digits"};
char* TOKEN_TYPE_LIST[] = {"Time-based (TOTP)", "Counter-based (HOTP)"};
TokenDigitsCount TOKEN_DIGITS_VALUE_LIST[] = {
TokenDigitsCountFive,
TokenDigitsCountSix,
@@ -20,9 +22,10 @@ TokenDigitsCount TOKEN_DIGITS_VALUE_LIST[] = {
typedef enum {
TokenNameTextBox,
TokenSecretTextBox,
TokenTypeSelect,
TokenAlgoSelect,
TokenLengthSelect,
TokenDurationSelect,
TokenDurationOrCounterSelect,
ConfirmButton,
} Control;
@@ -37,7 +40,10 @@ typedef struct {
TokenHashAlgo algo;
uint8_t digits_count_index;
uint8_t duration;
char* initial_counter;
size_t initial_counter_length;
FuriString* duration_text;
TokenType type;
} SceneState;
struct TotpAddContext {
@@ -45,7 +51,10 @@ struct TotpAddContext {
const CryptoSettings* crypto_settings;
};
enum TotpIteratorUpdateTokenResultsEx { TotpIteratorUpdateTokenResultInvalidSecret = 1 };
enum TotpIteratorUpdateTokenResultsEx {
TotpIteratorUpdateTokenResultInvalidSecret = 1,
TotpIteratorUpdateTokenResultInvalidCounter = 2
};
static void update_duration_text(SceneState* scene_state) {
furi_string_printf(scene_state->duration_text, "%d sec.", scene_state->duration);
@@ -53,6 +62,11 @@ static void update_duration_text(SceneState* scene_state) {
static TotpIteratorUpdateTokenResult add_token_handler(TokenInfo* tokenInfo, const void* context) {
const struct TotpAddContext* context_t = context;
if(context_t->scene_state->type == TokenTypeHOTP &&
sscanf(context_t->scene_state->initial_counter, "%" PRIu64, &tokenInfo->counter) != 1) {
return TotpIteratorUpdateTokenResultInvalidCounter;
}
if(!token_info_set_secret(
tokenInfo,
context_t->scene_state->token_secret,
@@ -69,6 +83,7 @@ static TotpIteratorUpdateTokenResult add_token_handler(TokenInfo* tokenInfo, con
tokenInfo->algo = context_t->scene_state->algo;
tokenInfo->digits = TOKEN_DIGITS_VALUE_LIST[context_t->scene_state->digits_count_index];
tokenInfo->duration = context_t->scene_state->duration;
tokenInfo->type = context_t->scene_state->type;
return TotpIteratorUpdateTokenResultSuccess;
}
@@ -93,6 +108,33 @@ static void ask_user_input(
}
}
static void update_screen_y_offset(SceneState* scene_state) {
if(scene_state->selected_control > TokenLengthSelect) {
scene_state->screen_y_offset = 68;
} else if(scene_state->selected_control > TokenAlgoSelect) {
scene_state->screen_y_offset = 51;
} else if(scene_state->selected_control > TokenTypeSelect) {
scene_state->screen_y_offset = 34;
} else if(scene_state->selected_control > TokenSecretTextBox) {
scene_state->screen_y_offset = 17;
} else {
scene_state->screen_y_offset = 0;
}
}
static void
show_invalid_field_message(const PluginState* plugin_state, Control control, const char* text) {
DialogMessage* message = dialog_message_alloc();
SceneState* scene_state = plugin_state->current_scene_state;
dialog_message_set_buttons(message, "Back", NULL, NULL);
dialog_message_set_text(
message, text, SCREEN_WIDTH_CENTER, SCREEN_HEIGHT_CENTER, AlignCenter, AlignCenter);
dialog_message_show(plugin_state->dialogs_app, message);
dialog_message_free(message);
scene_state->selected_control = control;
update_screen_y_offset(scene_state);
}
void totp_scene_add_new_token_activate(PluginState* plugin_state) {
SceneState* scene_state = malloc(sizeof(SceneState));
furi_check(scene_state != NULL);
@@ -101,6 +143,8 @@ void totp_scene_add_new_token_activate(PluginState* plugin_state) {
scene_state->token_name_length = strlen(scene_state->token_name);
scene_state->token_secret = "Secret";
scene_state->token_secret_length = strlen(scene_state->token_secret);
scene_state->initial_counter = "Counter";
scene_state->initial_counter_length = strlen(scene_state->initial_counter);
scene_state->screen_y_offset = 0;
@@ -108,6 +152,7 @@ void totp_scene_add_new_token_activate(PluginState* plugin_state) {
scene_state->duration = TokenDurationDefault;
scene_state->duration_text = furi_string_alloc();
scene_state->type = TokenTypeTOTP;
update_duration_text(scene_state);
}
@@ -124,33 +169,50 @@ void totp_scene_add_new_token_render(Canvas* const canvas, const PluginState* pl
27 - scene_state->screen_y_offset,
scene_state->token_secret,
scene_state->selected_control == TokenSecretTextBox);
ui_control_select_render(
canvas,
0,
44 - scene_state->screen_y_offset,
SCREEN_WIDTH,
TOKEN_TYPE_LIST[scene_state->type],
scene_state->selected_control == TokenTypeSelect);
ui_control_select_render(
canvas,
0,
61 - scene_state->screen_y_offset,
SCREEN_WIDTH,
TOKEN_ALGO_LIST[scene_state->algo],
scene_state->selected_control == TokenAlgoSelect);
ui_control_select_render(
canvas,
0,
61 - scene_state->screen_y_offset,
78 - scene_state->screen_y_offset,
SCREEN_WIDTH,
TOKEN_DIGITS_TEXT_LIST[scene_state->digits_count_index],
scene_state->selected_control == TokenLengthSelect);
ui_control_select_render(
canvas,
0,
78 - scene_state->screen_y_offset,
SCREEN_WIDTH,
furi_string_get_cstr(scene_state->duration_text),
scene_state->selected_control == TokenDurationSelect);
if(scene_state->type == TokenTypeTOTP) {
ui_control_select_render(
canvas,
0,
95 - scene_state->screen_y_offset,
SCREEN_WIDTH,
furi_string_get_cstr(scene_state->duration_text),
scene_state->selected_control == TokenDurationOrCounterSelect);
} else {
ui_control_text_box_render(
canvas,
95 - scene_state->screen_y_offset,
scene_state->initial_counter,
scene_state->selected_control == TokenDurationOrCounterSelect);
}
ui_control_button_render(
canvas,
SCREEN_WIDTH_CENTER - 24,
101 - scene_state->screen_y_offset,
119 - scene_state->screen_y_offset,
48,
13,
"Confirm",
@@ -164,18 +226,6 @@ void totp_scene_add_new_token_render(Canvas* const canvas, const PluginState* pl
canvas_set_font(canvas, FontSecondary);
}
void update_screen_y_offset(SceneState* scene_state) {
if(scene_state->selected_control > TokenLengthSelect) {
scene_state->screen_y_offset = 51;
} else if(scene_state->selected_control > TokenAlgoSelect) {
scene_state->screen_y_offset = 34;
} else if(scene_state->selected_control > TokenSecretTextBox) {
scene_state->screen_y_offset = 17;
} else {
scene_state->screen_y_offset = 0;
}
}
bool totp_scene_add_new_token_handle_event(
const PluginEvent* const event,
PluginState* plugin_state) {
@@ -215,11 +265,24 @@ bool totp_scene_add_new_token_handle_event(
RollOverflowBehaviorRoll);
} else if(scene_state->selected_control == TokenLengthSelect) {
totp_roll_value_uint8_t(
&scene_state->digits_count_index, 1, 0, 2, RollOverflowBehaviorRoll);
} else if(scene_state->selected_control == TokenDurationSelect) {
&scene_state->digits_count_index,
1,
0,
COUNT_OF(TOKEN_DIGITS_TEXT_LIST) - 1,
RollOverflowBehaviorRoll);
} else if(
scene_state->selected_control == TokenDurationOrCounterSelect &&
scene_state->type == TokenTypeTOTP) {
totp_roll_value_uint8_t(
&scene_state->duration, 15, 15, 255, RollOverflowBehaviorStop);
&scene_state->duration, 15, 15, UINT8_MAX, RollOverflowBehaviorStop);
update_duration_text(scene_state);
} else if(scene_state->selected_control == TokenTypeSelect) {
totp_roll_value_uint8_t(
&scene_state->type,
1,
0,
COUNT_OF(TOKEN_TYPE_LIST) - 1,
RollOverflowBehaviorRoll);
}
break;
case InputKeyLeft:
@@ -232,76 +295,88 @@ bool totp_scene_add_new_token_handle_event(
RollOverflowBehaviorRoll);
} else if(scene_state->selected_control == TokenLengthSelect) {
totp_roll_value_uint8_t(
&scene_state->digits_count_index, -1, 0, 2, RollOverflowBehaviorRoll);
} else if(scene_state->selected_control == TokenDurationSelect) {
&scene_state->digits_count_index,
-1,
0,
COUNT_OF(TOKEN_DIGITS_TEXT_LIST) - 1,
RollOverflowBehaviorRoll);
} else if(
scene_state->selected_control == TokenDurationOrCounterSelect &&
scene_state->type == TokenTypeTOTP) {
totp_roll_value_uint8_t(
&scene_state->duration, -15, 15, 255, RollOverflowBehaviorStop);
&scene_state->duration, -15, 15, UINT8_MAX, RollOverflowBehaviorStop);
update_duration_text(scene_state);
} else if(scene_state->selected_control == TokenTypeSelect) {
totp_roll_value_uint8_t(
&scene_state->type,
-1,
0,
COUNT_OF(TOKEN_TYPE_LIST) - 1,
RollOverflowBehaviorRoll);
}
break;
case InputKeyOk:
case InputKeyOk: {
switch(scene_state->selected_control) {
case TokenNameTextBox:
ask_user_input(
plugin_state,
"Token name",
&scene_state->token_name,
&scene_state->token_name_length);
break;
case TokenSecretTextBox:
ask_user_input(
plugin_state,
"Token secret",
&scene_state->token_secret,
&scene_state->token_secret_length);
break;
case TokenAlgoSelect:
break;
case TokenLengthSelect:
break;
case TokenDurationOrCounterSelect:
if(scene_state->type == TokenTypeHOTP) {
ask_user_input(
plugin_state,
"Initial counter",
&scene_state->initial_counter,
&scene_state->initial_counter_length);
}
break;
case ConfirmButton: {
struct TotpAddContext add_context = {
.scene_state = scene_state, .crypto_settings = &plugin_state->crypto_settings};
TokenInfoIteratorContext* iterator_context =
totp_config_get_token_iterator_context(plugin_state);
TotpIteratorUpdateTokenResult add_result = totp_token_info_iterator_add_new_token(
iterator_context, &add_token_handler, &add_context);
if(add_result == TotpIteratorUpdateTokenResultSuccess) {
totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken);
} else if(add_result == TotpIteratorUpdateTokenResultInvalidSecret) {
show_invalid_field_message(
plugin_state, TokenSecretTextBox, "Token secret is invalid");
} else if(add_result == TotpIteratorUpdateTokenResultInvalidCounter) {
show_invalid_field_message(
plugin_state, TokenDurationOrCounterSelect, "Initial counter is invalid");
} else if(add_result == TotpIteratorUpdateTokenResultFileUpdateFailed) {
totp_dialogs_config_updating_error(plugin_state);
}
break;
}
default:
break;
}
break;
}
case InputKeyBack:
totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken);
break;
default:
break;
}
} else if(event->input.type == InputTypeRelease && event->input.key == InputKeyOk) {
switch(scene_state->selected_control) {
case TokenNameTextBox:
ask_user_input(
plugin_state,
"Token name",
&scene_state->token_name,
&scene_state->token_name_length);
break;
case TokenSecretTextBox:
ask_user_input(
plugin_state,
"Token secret",
&scene_state->token_secret,
&scene_state->token_secret_length);
break;
case TokenAlgoSelect:
break;
case TokenLengthSelect:
break;
case TokenDurationSelect:
break;
case ConfirmButton: {
struct TotpAddContext add_context = {
.scene_state = scene_state, .crypto_settings = &plugin_state->crypto_settings};
TokenInfoIteratorContext* iterator_context =
totp_config_get_token_iterator_context(plugin_state);
TotpIteratorUpdateTokenResult add_result = totp_token_info_iterator_add_new_token(
iterator_context, &add_token_handler, &add_context);
if(add_result == TotpIteratorUpdateTokenResultSuccess) {
totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken);
} else if(add_result == TotpIteratorUpdateTokenResultInvalidSecret) {
DialogMessage* message = dialog_message_alloc();
dialog_message_set_buttons(message, "Back", NULL, NULL);
dialog_message_set_text(
message,
"Token secret is invalid",
SCREEN_WIDTH_CENTER,
SCREEN_HEIGHT_CENTER,
AlignCenter,
AlignCenter);
dialog_message_show(plugin_state->dialogs_app, message);
dialog_message_free(message);
scene_state->selected_control = TokenSecretTextBox;
update_screen_y_offset(scene_state);
} else if(add_result == TotpIteratorUpdateTokenResultFileUpdateFailed) {
totp_dialogs_config_updating_error(plugin_state);
}
break;
}
default:
break;
}
}
return true;

View File

@@ -1,8 +1,7 @@
#include "totp_app_settings.h"
#include <math.h>
#include "totp_icons.h"
#include <assets_icons.h>
#include <available_fonts.h>
#include <totp_icons.h>
#include "../../../services/fonts/font_provider.h"
#include "../../canvas_extensions.h"
#include "../../ui_controls.h"
#include "../../common_dialogs.h"
@@ -16,12 +15,8 @@
#include "../../../workers/bt_type_code/bt_type_code.h"
#endif
#ifdef TOTP_BADBT_AUTOMATION_ENABLED
#define AUTOMATION_LIST_MAX_INDEX (3)
#else
#define AUTOMATION_LIST_MAX_INDEX (1)
#endif
#define BAD_KB_LAYOUT_LIST_MAX_INDEX (1)
#include <assets_icons.h>
#define FONT_TEST_STR_LENGTH (7)
static const char* YES_NO_LIST[] = {"NO", "YES"};
@@ -34,7 +29,7 @@ static const char* AUTOMATION_LIST[] = {
"BT and USB"
#endif
};
static const char* BAD_KB_LAYOUT_LIST[] = {"QWERTY", "AZERTY"};
static const char* BAD_KB_LAYOUT_LIST[] = {"QWERTY", "AZERTY", "QWERTZ"};
static const char* FONT_TEST_STR = "0123BCD";
typedef enum {
@@ -57,7 +52,9 @@ typedef struct {
uint16_t y_offset;
AutomationKeyboardLayout automation_kb_layout;
Control selected_control;
uint8_t active_font;
uint8_t active_font_index;
FontInfo* active_font;
uint8_t total_fonts_count;
} SceneState;
void totp_scene_app_settings_activate(PluginState* plugin_state) {
@@ -72,11 +69,17 @@ void totp_scene_app_settings_activate(PluginState* plugin_state) {
scene_state->notification_sound = plugin_state->notification_method & NotificationMethodSound;
scene_state->notification_vibro = plugin_state->notification_method & NotificationMethodVibro;
scene_state->automation_method =
MIN(plugin_state->automation_method, AUTOMATION_LIST_MAX_INDEX);
MIN(plugin_state->automation_method, COUNT_OF(AUTOMATION_LIST) - 1);
scene_state->automation_kb_layout =
MIN(plugin_state->automation_kb_layout, BAD_KB_LAYOUT_LIST_MAX_INDEX);
MIN(plugin_state->automation_kb_layout, COUNT_OF(BAD_KB_LAYOUT_LIST) - 1);
scene_state->active_font = plugin_state->active_font_index;
scene_state->total_fonts_count = totp_font_provider_get_fonts_count();
scene_state->active_font_index = plugin_state->active_font_index;
scene_state->active_font = totp_font_info_alloc();
if(!totp_font_provider_get_font(scene_state->active_font_index, scene_state->active_font)) {
scene_state->active_font_index = 0;
totp_font_provider_get_font(scene_state->active_font_index, scene_state->active_font);
}
}
static void two_digit_to_str(int8_t num, char* str) {
@@ -130,7 +133,7 @@ void totp_scene_app_settings_render(Canvas* const canvas, const PluginState* plu
canvas, 0, 64 - scene_state->y_offset, AlignLeft, AlignTop, "Font");
canvas_set_font(canvas, FontSecondary);
const FONT_INFO* const font = available_fonts[scene_state->active_font];
const FontInfo* const font = scene_state->active_font;
ui_control_select_render(
canvas,
0,
@@ -141,7 +144,7 @@ void totp_scene_app_settings_render(Canvas* const canvas, const PluginState* plu
uint8_t font_x_offset =
SCREEN_WIDTH_CENTER -
(((font->charInfo[0].width + font->spacePixels) * FONT_TEST_STR_LENGTH) >> 1);
(((font->char_info[0].width + font->space_width) * FONT_TEST_STR_LENGTH) >> 1);
uint8_t font_y_offset = 108 - scene_state->y_offset - (font->height >> 1);
canvas_draw_str_ex(
canvas, font_x_offset, font_y_offset, FONT_TEST_STR, FONT_TEST_STR_LENGTH, font);
@@ -265,11 +268,13 @@ bool totp_scene_app_settings_handle_event(
&scene_state->tz_offset_minutes, 15, 0, 45, RollOverflowBehaviorRoll);
} else if(scene_state->selected_control == FontSelect) {
totp_roll_value_uint8_t(
&scene_state->active_font,
&scene_state->active_font_index,
1,
0,
AVAILABLE_FONTS_COUNT - 1,
scene_state->total_fonts_count - 1,
RollOverflowBehaviorRoll);
totp_font_provider_get_font(
scene_state->active_font_index, scene_state->active_font);
} else if(scene_state->selected_control == SoundSwitch) {
scene_state->notification_sound = !scene_state->notification_sound;
} else if(scene_state->selected_control == VibroSwitch) {
@@ -279,14 +284,14 @@ bool totp_scene_app_settings_handle_event(
&scene_state->automation_method,
1,
0,
AUTOMATION_LIST_MAX_INDEX,
COUNT_OF(AUTOMATION_LIST) - 1,
RollOverflowBehaviorRoll);
} else if(scene_state->selected_control == BadKeyboardLayoutSelect) {
totp_roll_value_uint8_t(
&scene_state->automation_kb_layout,
1,
0,
BAD_KB_LAYOUT_LIST_MAX_INDEX,
COUNT_OF(BAD_KB_LAYOUT_LIST) - 1,
RollOverflowBehaviorRoll);
}
break;
@@ -299,11 +304,13 @@ bool totp_scene_app_settings_handle_event(
&scene_state->tz_offset_minutes, -15, 0, 45, RollOverflowBehaviorRoll);
} else if(scene_state->selected_control == FontSelect) {
totp_roll_value_uint8_t(
&scene_state->active_font,
&scene_state->active_font_index,
-1,
0,
AVAILABLE_FONTS_COUNT - 1,
scene_state->total_fonts_count - 1,
RollOverflowBehaviorRoll);
totp_font_provider_get_font(
scene_state->active_font_index, scene_state->active_font);
} else if(scene_state->selected_control == SoundSwitch) {
scene_state->notification_sound = !scene_state->notification_sound;
} else if(scene_state->selected_control == VibroSwitch) {
@@ -313,18 +320,47 @@ bool totp_scene_app_settings_handle_event(
&scene_state->automation_method,
-1,
0,
AUTOMATION_LIST_MAX_INDEX,
COUNT_OF(AUTOMATION_LIST) - 1,
RollOverflowBehaviorRoll);
} else if(scene_state->selected_control == BadKeyboardLayoutSelect) {
totp_roll_value_uint8_t(
&scene_state->automation_kb_layout,
-1,
0,
BAD_KB_LAYOUT_LIST_MAX_INDEX,
COUNT_OF(BAD_KB_LAYOUT_LIST) - 1,
RollOverflowBehaviorRoll);
}
break;
case InputKeyOk:
if(scene_state->selected_control == ConfirmButton) {
plugin_state->timezone_offset = (float)scene_state->tz_offset_hours +
(float)scene_state->tz_offset_minutes / 60.0f;
plugin_state->notification_method =
(scene_state->notification_sound ? NotificationMethodSound :
NotificationMethodNone) |
(scene_state->notification_vibro ? NotificationMethodVibro :
NotificationMethodNone);
plugin_state->automation_method = scene_state->automation_method;
plugin_state->active_font_index = scene_state->active_font_index;
plugin_state->automation_kb_layout = scene_state->automation_kb_layout;
if(!totp_config_file_update_user_settings(plugin_state)) {
totp_dialogs_config_updating_error(plugin_state);
return false;
}
#ifdef TOTP_BADBT_AUTOMATION_ENABLED
if((scene_state->automation_method & AutomationMethodBadBt) == 0 &&
plugin_state->bt_type_code_worker_context != NULL) {
totp_bt_type_code_worker_free(plugin_state->bt_type_code_worker_context);
plugin_state->bt_type_code_worker_context = NULL;
}
#endif
totp_scene_director_activate_scene(plugin_state, TotpSceneTokenMenu);
}
break;
case InputKeyBack: {
totp_scene_director_activate_scene(plugin_state, TotpSceneTokenMenu);
@@ -333,34 +369,6 @@ bool totp_scene_app_settings_handle_event(
default:
break;
}
} else if(
event->input.type == InputTypeRelease && event->input.key == InputKeyOk &&
scene_state->selected_control == ConfirmButton) {
plugin_state->timezone_offset =
(float)scene_state->tz_offset_hours + (float)scene_state->tz_offset_minutes / 60.0f;
plugin_state->notification_method =
(scene_state->notification_sound ? NotificationMethodSound : NotificationMethodNone) |
(scene_state->notification_vibro ? NotificationMethodVibro : NotificationMethodNone);
plugin_state->automation_method = scene_state->automation_method;
plugin_state->active_font_index = scene_state->active_font;
plugin_state->automation_kb_layout = scene_state->automation_kb_layout;
if(!totp_config_file_update_user_settings(plugin_state)) {
totp_dialogs_config_updating_error(plugin_state);
return false;
}
#ifdef TOTP_BADBT_AUTOMATION_ENABLED
if((scene_state->automation_method & AutomationMethodBadBt) == 0 &&
plugin_state->bt_type_code_worker_context != NULL) {
totp_bt_type_code_worker_free(plugin_state->bt_type_code_worker_context);
plugin_state->bt_type_code_worker_context = NULL;
}
#endif
totp_scene_director_activate_scene(plugin_state, TotpSceneTokenMenu);
}
return true;
@@ -369,6 +377,9 @@ bool totp_scene_app_settings_handle_event(
void totp_scene_app_settings_deactivate(PluginState* plugin_state) {
if(plugin_state->current_scene_state == NULL) return;
free(plugin_state->current_scene_state);
SceneState* scene_state = plugin_state->current_scene_state;
totp_font_info_free(scene_state->active_font);
free(scene_state);
plugin_state->current_scene_state = NULL;
}

View File

@@ -1,7 +1,6 @@
#include "totp_scene_authenticate.h"
#include <dialogs/dialogs.h>
#include "totp_icons.h"
#include <assets_icons.h>
#include <totp_icons.h>
#include "../../../types/common.h"
#include "../../constants.h"
#include "../../../services/config/config.h"
@@ -10,6 +9,8 @@
#include "../../../services/crypto/crypto_facade.h"
#include "../../../types/user_pin_codes.h"
#include <assets_icons.h>
#define MAX_CODE_LENGTH CRYPTO_IV_LENGTH
static const uint8_t PIN_ASTERISK_RADIUS = 3;
static const uint8_t PIN_ASTERISK_STEP = (PIN_ASTERISK_RADIUS << 1) + 2;
@@ -111,8 +112,41 @@ bool totp_scene_authenticate_handle_event(
scene_state->code_length++;
}
break;
case InputKeyOk:
case InputKeyOk: {
CryptoSeedIVResult seed_result = totp_crypto_seed_iv(
&plugin_state->crypto_settings,
&scene_state->code_input[0],
scene_state->code_length);
if(seed_result & CryptoSeedIVResultFlagSuccess &&
seed_result & CryptoSeedIVResultFlagNewCryptoVerifyData) {
totp_config_file_update_crypto_signatures(plugin_state);
}
if(totp_crypto_verify_key(&plugin_state->crypto_settings)) {
totp_config_file_ensure_latest_encryption(
plugin_state, &scene_state->code_input[0], scene_state->code_length);
totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken);
} else {
memset(&scene_state->code_input[0], 0, MAX_CODE_LENGTH);
memset(&plugin_state->crypto_settings.iv[0], 0, CRYPTO_IV_LENGTH);
scene_state->code_length = 0;
DialogMessage* message = dialog_message_alloc();
dialog_message_set_buttons(message, "Try again", NULL, NULL);
dialog_message_set_header(
message,
"You entered\ninvalid PIN",
SCREEN_WIDTH_CENTER - 25,
SCREEN_HEIGHT_CENTER - 5,
AlignCenter,
AlignCenter);
dialog_message_set_icon(message, &I_DolphinCommon_56x48, 72, 17);
dialog_message_show(plugin_state->dialogs_app, message);
dialog_message_free(message);
}
break;
}
case InputKeyBack:
if(scene_state->code_length > 0) {
scene_state->code_input[scene_state->code_length - 1] = 0;
@@ -122,39 +156,6 @@ bool totp_scene_authenticate_handle_event(
default:
break;
}
} else if(event->input.type == InputTypeRelease && event->input.key == InputKeyOk) {
CryptoSeedIVResult seed_result = totp_crypto_seed_iv(
&plugin_state->crypto_settings, &scene_state->code_input[0], scene_state->code_length);
if(seed_result & CryptoSeedIVResultFlagSuccess &&
seed_result & CryptoSeedIVResultFlagNewCryptoVerifyData) {
totp_config_file_update_crypto_signatures(plugin_state);
}
if(totp_crypto_verify_key(&plugin_state->crypto_settings)) {
FURI_LOG_D(LOGGING_TAG, "PIN is valid");
totp_config_file_ensure_latest_encryption(
plugin_state, &scene_state->code_input[0], scene_state->code_length);
totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken);
} else {
FURI_LOG_D(LOGGING_TAG, "PIN is NOT valid");
memset(&scene_state->code_input[0], 0, MAX_CODE_LENGTH);
memset(&plugin_state->crypto_settings.iv[0], 0, CRYPTO_IV_LENGTH);
scene_state->code_length = 0;
DialogMessage* message = dialog_message_alloc();
dialog_message_set_buttons(message, "Try again", NULL, NULL);
dialog_message_set_header(
message,
"You entered\ninvalid PIN",
SCREEN_WIDTH_CENTER - 25,
SCREEN_HEIGHT_CENTER - 5,
AlignCenter,
AlignCenter);
dialog_message_set_icon(message, &I_DolphinCommon_56x48, 72, 17);
dialog_message_show(plugin_state->dialogs_app, message);
dialog_message_free(message);
}
}
return true;

View File

@@ -2,10 +2,9 @@
#include <gui/gui.h>
#include <notification/notification.h>
#include <notification/notification_messages.h>
#include "totp_icons.h"
#include <assets_icons.h>
#include <totp_icons.h>
#include <roll_value.h>
#include <available_fonts.h>
#include "../../../services/fonts/font_provider.h"
#include "../../canvas_extensions.h"
#include "../../../types/token_info.h"
#include "../../../types/common.h"
@@ -19,6 +18,8 @@
#include "../../../workers/bt_type_code/bt_type_code.h"
#endif
#include <assets_icons.h>
#define PROGRESS_BAR_MARGIN (3)
#define PROGRESS_BAR_HEIGHT (4)
@@ -38,7 +39,7 @@ typedef struct {
FuriMutex* last_code_update_sync;
TotpGenerateCodeWorkerContext* generate_code_worker_context;
UiPrecalculatedDimensions ui_precalculated_dimensions;
const FONT_INFO* active_font;
FontInfo* active_font;
NotificationApp* notification_app;
} SceneState;
@@ -141,15 +142,14 @@ static void on_new_token_code_generated(bool time_left, void* context) {
SceneState* scene_state = plugin_state->current_scene_state;
const TokenInfo* current_token = totp_token_info_iterator_get_current_token(iterator_context);
const FONT_INFO* const font = scene_state->active_font;
uint8_t char_width = font->charInfo[0].width;
uint8_t char_width = scene_state->active_font->char_info[0].width;
scene_state->ui_precalculated_dimensions.code_total_length =
current_token->digits * (char_width + font->spacePixels);
current_token->digits * (char_width + scene_state->active_font->space_width);
scene_state->ui_precalculated_dimensions.code_offset_x =
(SCREEN_WIDTH - scene_state->ui_precalculated_dimensions.code_total_length) >> 1;
scene_state->ui_precalculated_dimensions.code_offset_y =
SCREEN_HEIGHT_CENTER - (font->height >> 1);
SCREEN_HEIGHT_CENTER - (scene_state->active_font->height >> 1);
if(time_left) {
notification_message(
@@ -189,7 +189,11 @@ void totp_scene_generate_token_activate(PluginState* plugin_state) {
plugin_state->automation_kb_layout);
}
scene_state->active_font = available_fonts[plugin_state->active_font_index];
scene_state->active_font = totp_font_info_alloc();
if(!totp_font_provider_get_font(plugin_state->active_font_index, scene_state->active_font)) {
totp_font_provider_get_font(0, scene_state->active_font);
}
scene_state->notification_app = furi_record_open(RECORD_NOTIFICATION);
scene_state->notification_sequence_automation[0] = NULL;
scene_state->notification_sequence_new_token[0] = NULL;
@@ -253,8 +257,8 @@ void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_
const SceneState* scene_state = (SceneState*)plugin_state->current_scene_state;
canvas_set_font(canvas, FontPrimary);
const char* token_name_cstr =
furi_string_get_cstr(totp_token_info_iterator_get_current_token(iterator_context)->name);
const TokenInfo* token_info = totp_token_info_iterator_get_current_token(iterator_context);
const char* token_name_cstr = furi_string_get_cstr(token_info->name);
uint16_t token_name_width = canvas_string_width(canvas, token_name_cstr);
if(SCREEN_WIDTH - token_name_width > 18) {
canvas_draw_str_aligned(
@@ -275,12 +279,21 @@ void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_
draw_totp_code(canvas, plugin_state);
canvas_draw_box(
canvas,
scene_state->ui_precalculated_dimensions.progress_bar_x,
SCREEN_HEIGHT - PROGRESS_BAR_MARGIN - PROGRESS_BAR_HEIGHT,
scene_state->ui_precalculated_dimensions.progress_bar_width,
PROGRESS_BAR_HEIGHT);
if(token_info->type == TokenTypeTOTP) {
canvas_draw_box(
canvas,
scene_state->ui_precalculated_dimensions.progress_bar_x,
SCREEN_HEIGHT - PROGRESS_BAR_MARGIN - PROGRESS_BAR_HEIGHT,
scene_state->ui_precalculated_dimensions.progress_bar_width,
PROGRESS_BAR_HEIGHT);
} else {
char buffer[21];
snprintf(&buffer[0], sizeof(buffer), "%" PRIu64, token_info->counter);
canvas_set_font(canvas, FontSecondary);
canvas_draw_str_aligned(
canvas, SCREEN_WIDTH_CENTER, SCREEN_HEIGHT - 5, AlignCenter, AlignCenter, buffer);
}
if(totp_token_info_iterator_get_total_count(iterator_context) > 1) {
canvas_draw_icon(canvas, 0, SCREEN_HEIGHT_CENTER - 24, &I_totp_arrow_left_8x9);
canvas_draw_icon(
@@ -357,6 +370,21 @@ bool totp_scene_generate_token_handle_event(
scene_state->notification_app,
get_notification_sequence_automation(plugin_state, scene_state));
return true;
} else if(event->input.key == InputKeyOk) {
TokenInfoIteratorContext* iterator_context =
totp_config_get_token_iterator_context(plugin_state);
const TokenInfo* token_info =
totp_token_info_iterator_get_current_token(iterator_context);
if(token_info->type == TokenTypeHOTP) {
scene_state = (SceneState*)plugin_state->current_scene_state;
totp_token_info_iterator_current_token_inc_counter(iterator_context);
totp_generate_code_worker_notify(
scene_state->generate_code_worker_context,
TotpGenerateCodeWorkerEventForceUpdate);
notification_message(
scene_state->notification_app,
get_notification_sequence_new_token(plugin_state, scene_state));
}
}
#endif
} else if(event->input.type == InputTypePress || event->input.type == InputTypeRepeat) {
@@ -396,14 +424,13 @@ bool totp_scene_generate_token_handle_event(
break;
}
case InputKeyOk:
totp_scene_director_activate_scene(plugin_state, TotpSceneTokenMenu);
break;
case InputKeyBack:
break;
default:
break;
}
} else if(event->input.type == InputTypeRelease && event->input.key == InputKeyOk) {
totp_scene_director_activate_scene(plugin_state, TotpSceneTokenMenu);
}
return true;
@@ -428,6 +455,8 @@ void totp_scene_generate_token_deactivate(PluginState* plugin_state) {
furi_mutex_free(scene_state->last_code_update_sync);
totp_font_info_free(scene_state->active_font);
free(scene_state);
plugin_state->current_scene_state = NULL;
}

View File

@@ -1,8 +1,9 @@
#include "standby.h"
#include "totp_icons.h"
#include <assets_icons.h>
#include <totp_icons.h>
#include "../../constants.h"
#include <assets_icons.h>
void totp_scene_standby_render(Canvas* const canvas) {
canvas_draw_icon(canvas, SCREEN_WIDTH - 56, SCREEN_HEIGHT - 48, &I_DolphinCommon_56x48);
@@ -10,4 +11,4 @@ void totp_scene_standby_render(Canvas* const canvas) {
canvas_draw_str_aligned(canvas, 5, 10, AlignLeft, AlignTop, "CLI command");
canvas_draw_str_aligned(canvas, 5, 24, AlignLeft, AlignTop, "is running now");
}
}

View File

@@ -116,65 +116,65 @@ bool totp_scene_token_menu_handle_event(const PluginEvent* const event, PluginSt
break;
case InputKeyLeft:
break;
case InputKeyOk:
break;
case InputKeyBack: {
totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken);
break;
}
default:
break;
}
} else if(event->input.type == InputTypeRelease && event->input.key == InputKeyOk) {
switch(scene_state->selected_control) {
case AddNewToken: {
case InputKeyOk: {
switch(scene_state->selected_control) {
case AddNewToken: {
#ifdef TOTP_UI_ADD_NEW_TOKEN_ENABLED
totp_scene_director_activate_scene(plugin_state, TotpSceneAddNewToken);
totp_scene_director_activate_scene(plugin_state, TotpSceneAddNewToken);
#else
DialogMessage* message = dialog_message_alloc();
dialog_message_set_buttons(message, "Back", NULL, NULL);
dialog_message_set_header(message, "Information", 0, 0, AlignLeft, AlignTop);
dialog_message_set_text(
message,
"Read here\nhttps://t.ly/8ZOtj\n how to add new token",
SCREEN_WIDTH_CENTER,
SCREEN_HEIGHT_CENTER,
AlignCenter,
AlignCenter);
dialog_message_show(plugin_state->dialogs_app, message);
dialog_message_free(message);
#endif
break;
}
case DeleteToken: {
DialogMessage* message = dialog_message_alloc();
dialog_message_set_buttons(message, "No", NULL, "Yes");
dialog_message_set_header(message, "Confirmation", 0, 0, AlignLeft, AlignTop);
dialog_message_set_text(
message,
"Are you sure want to delete?",
SCREEN_WIDTH_CENTER,
SCREEN_HEIGHT_CENTER,
AlignCenter,
AlignCenter);
DialogMessageButton dialog_result =
DialogMessage* message = dialog_message_alloc();
dialog_message_set_buttons(message, "Back", NULL, NULL);
dialog_message_set_header(message, "Information", 0, 0, AlignLeft, AlignTop);
dialog_message_set_text(
message,
"Read here\nhttps://t.ly/8ZOtj\nhow to add new token",
SCREEN_WIDTH_CENTER,
SCREEN_HEIGHT_CENTER,
AlignCenter,
AlignCenter);
dialog_message_show(plugin_state->dialogs_app, message);
dialog_message_free(message);
TokenInfoIteratorContext* iterator_context =
totp_config_get_token_iterator_context(plugin_state);
if(dialog_result == DialogMessageButtonRight &&
totp_token_info_iterator_get_total_count(iterator_context) > 0) {
if(!totp_token_info_iterator_remove_current_token_info(iterator_context)) {
totp_dialogs_config_updating_error(plugin_state);
return false;
}
dialog_message_free(message);
#endif
break;
}
case DeleteToken: {
DialogMessage* message = dialog_message_alloc();
dialog_message_set_buttons(message, "No", NULL, "Yes");
dialog_message_set_header(message, "Confirmation", 0, 0, AlignLeft, AlignTop);
dialog_message_set_text(
message,
"Are you sure want to delete?",
SCREEN_WIDTH_CENTER,
SCREEN_HEIGHT_CENTER,
AlignCenter,
AlignCenter);
DialogMessageButton dialog_result =
dialog_message_show(plugin_state->dialogs_app, message);
dialog_message_free(message);
TokenInfoIteratorContext* iterator_context =
totp_config_get_token_iterator_context(plugin_state);
if(dialog_result == DialogMessageButtonRight &&
totp_token_info_iterator_get_total_count(iterator_context) > 0) {
if(!totp_token_info_iterator_remove_current_token_info(iterator_context)) {
totp_dialogs_config_updating_error(plugin_state);
return false;
}
totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken);
totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken);
}
break;
}
case AppSettings: {
totp_scene_director_activate_scene(plugin_state, TotpSceneAppSettings);
break;
}
default:
break;
}
break;
}
case AppSettings: {
totp_scene_director_activate_scene(plugin_state, TotpSceneAppSettings);
case InputKeyBack: {
totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken);
break;
}
default:

View File

@@ -1,8 +1,9 @@
#include "ui_controls.h"
#include "totp_icons.h"
#include <assets_icons.h>
#include <totp_icons.h>
#include "constants.h"
#include <assets_icons.h>
#define TEXT_BOX_HEIGHT (13)
#define TEXT_BOX_MARGIN (4)