MX
2023-04-26 23:50:37 +03:00
parent 6c0c0bd0be
commit 451ec9cba0
62 changed files with 2025 additions and 1679 deletions

View File

@@ -4,17 +4,18 @@
#include "../../scene_director.h"
#include "totp_input_text.h"
#include "../../../types/token_info.h"
#include <linked_list.h>
#include "../../../services/config/config.h"
#include "../../ui_controls.h"
#include "../../common_dialogs.h"
#include <roll_value.h>
#include "../../../types/nullable.h"
#include "../generate_token/totp_scene_generate_token.h"
char* TOKEN_ALGO_LIST[] = {"SHA1", "SHA256", "SHA512", "Steam"};
char* TOKEN_DIGITS_TEXT_LIST[] = {"5 digits", "6 digits", "8 digits"};
TokenDigitsCount TOKEN_DIGITS_VALUE_LIST[] = {TOTP_5_DIGITS, TOTP_6_DIGITS, TOTP_8_DIGITS};
TokenDigitsCount TOKEN_DIGITS_VALUE_LIST[] = {
TotpFiveDigitsCount,
TotpSixDigitsCount,
TotpEightDigitsCount};
typedef enum {
TokenNameTextBox,
@@ -36,7 +37,6 @@ typedef struct {
InputTextSceneContext* token_secret_input_context;
InputTextSceneState* input_state;
uint32_t input_started_at;
TotpNullable_uint16_t current_token_index;
int16_t screen_y_offset;
TokenHashAlgo algo;
uint8_t digits_count_index;
@@ -44,6 +44,13 @@ typedef struct {
FuriString* duration_text;
} SceneState;
struct TotpAddContext {
SceneState* scene_state;
uint8_t* iv;
};
enum TotpIteratorUpdateTokenResultsEx { TotpIteratorUpdateTokenResultInvalidSecret = 1 };
static void on_token_name_user_comitted(InputTextSceneCallbackResult* result) {
SceneState* scene_state = result->callback_data;
free(scene_state->token_name);
@@ -66,9 +73,29 @@ static void update_duration_text(SceneState* scene_state) {
furi_string_printf(scene_state->duration_text, "%d sec.", scene_state->duration);
}
void totp_scene_add_new_token_activate(
PluginState* plugin_state,
const TokenAddEditSceneContext* context) {
static TotpIteratorUpdateTokenResult add_token_handler(TokenInfo* tokenInfo, const void* context) {
const struct TotpAddContext* context_t = context;
if(!token_info_set_secret(
tokenInfo,
context_t->scene_state->token_secret,
context_t->scene_state->token_secret_length,
PlainTokenSecretEncodingBase32,
context_t->iv)) {
return TotpIteratorUpdateTokenResultInvalidSecret;
}
furi_string_set_strn(
tokenInfo->name,
context_t->scene_state->token_name,
context_t->scene_state->token_name_length + 1);
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;
return TotpIteratorUpdateTokenResultSuccess;
}
void totp_scene_add_new_token_activate(PluginState* plugin_state) {
SceneState* scene_state = malloc(sizeof(SceneState));
furi_check(scene_state != NULL);
plugin_state->current_scene_state = scene_state;
@@ -97,12 +124,6 @@ void totp_scene_add_new_token_activate(
scene_state->duration = TOTP_TOKEN_DURATION_DEFAULT;
scene_state->duration_text = furi_string_alloc();
update_duration_text(scene_state);
if(context == NULL) {
TOTP_NULLABLE_NULL(scene_state->current_token_index);
} else {
TOTP_NULLABLE_VALUE(scene_state->current_token_index, context->current_token_index);
}
}
void totp_scene_add_new_token_render(Canvas* const canvas, PluginState* plugin_state) {
@@ -260,38 +281,16 @@ bool totp_scene_add_new_token_handle_event(PluginEvent* const event, PluginState
case TokenDurationSelect:
break;
case ConfirmButton: {
TokenInfo* tokenInfo = token_info_alloc();
bool token_secret_set = token_info_set_secret(
tokenInfo,
scene_state->token_secret,
scene_state->token_secret_length,
PLAIN_TOKEN_ENCODING_BASE32,
&plugin_state->iv[0]);
struct TotpAddContext add_context = {
.iv = plugin_state->iv, .scene_state = scene_state};
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(token_secret_set) {
tokenInfo->name = malloc(scene_state->token_name_length + 1);
furi_check(tokenInfo->name != NULL);
strlcpy(
tokenInfo->name, scene_state->token_name, scene_state->token_name_length + 1);
tokenInfo->algo = scene_state->algo;
tokenInfo->digits = TOKEN_DIGITS_VALUE_LIST[scene_state->digits_count_index];
tokenInfo->duration = scene_state->duration;
TOTP_LIST_INIT_OR_ADD(plugin_state->tokens_list, tokenInfo, furi_check);
plugin_state->tokens_count++;
if(totp_config_file_save_new_token(tokenInfo) != TotpConfigFileUpdateSuccess) {
token_info_free(tokenInfo);
totp_dialogs_config_updating_error(plugin_state);
return false;
}
GenerateTokenSceneContext generate_scene_context = {
.current_token_index = plugin_state->tokens_count - 1};
totp_scene_director_activate_scene(
plugin_state, TotpSceneGenerateToken, &generate_scene_context);
} else {
token_info_free(tokenInfo);
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(
@@ -305,7 +304,10 @@ bool totp_scene_add_new_token_handle_event(PluginEvent* const event, PluginState
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:
@@ -313,14 +315,7 @@ bool totp_scene_add_new_token_handle_event(PluginEvent* const event, PluginState
}
break;
case InputKeyBack:
if(!scene_state->current_token_index.is_null) {
GenerateTokenSceneContext generate_scene_context = {
.current_token_index = scene_state->current_token_index.value};
totp_scene_director_activate_scene(
plugin_state, TotpSceneGenerateToken, &generate_scene_context);
} else {
totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken, NULL);
}
totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken);
break;
default:
break;

View File

@@ -4,13 +4,7 @@
#include "../../../types/plugin_state.h"
#include "../../../types/plugin_event.h"
typedef struct {
uint16_t current_token_index;
} TokenAddEditSceneContext;
void totp_scene_add_new_token_activate(
PluginState* plugin_state,
const TokenAddEditSceneContext* context);
void totp_scene_add_new_token_activate(PluginState* plugin_state);
void totp_scene_add_new_token_render(Canvas* const canvas, PluginState* plugin_state);
bool totp_scene_add_new_token_handle_event(PluginEvent* const event, PluginState* plugin_state);
void totp_scene_add_new_token_deactivate(PluginState* plugin_state);

View File

@@ -9,7 +9,6 @@
#include "../../../services/config/config.h"
#include "../../../services/convert/convert.h"
#include <roll_value.h>
#include "../../../types/nullable.h"
#include "../../../features_config.h"
#ifdef TOTP_BADBT_TYPE_ENABLED
#include "../../../workers/bt_type_code/bt_type_code.h"
@@ -40,21 +39,13 @@ typedef struct {
bool badbt_enabled;
#endif
uint8_t y_offset;
TotpNullable_uint16_t current_token_index;
Control selected_control;
} SceneState;
void totp_scene_app_settings_activate(
PluginState* plugin_state,
const AppSettingsSceneContext* context) {
void totp_scene_app_settings_activate(PluginState* plugin_state) {
SceneState* scene_state = malloc(sizeof(SceneState));
furi_check(scene_state != NULL);
plugin_state->current_scene_state = scene_state;
if(context != NULL) {
TOTP_NULLABLE_VALUE(scene_state->current_token_index, context->current_token_index);
} else {
TOTP_NULLABLE_NULL(scene_state->current_token_index);
}
float off_int;
float off_dec = modff(plugin_state->timezone_offset, &off_int);
@@ -281,8 +272,7 @@ bool totp_scene_app_settings_handle_event(
AutomationMethodNone;
#endif
if(totp_config_file_update_user_settings(plugin_state) !=
TotpConfigFileUpdateSuccess) {
if(!totp_config_file_update_user_settings(plugin_state)) {
totp_dialogs_config_updating_error(plugin_state);
return false;
}
@@ -294,25 +284,11 @@ bool totp_scene_app_settings_handle_event(
}
#endif
if(!scene_state->current_token_index.is_null) {
TokenMenuSceneContext generate_scene_context = {
.current_token_index = scene_state->current_token_index.value};
totp_scene_director_activate_scene(
plugin_state, TotpSceneTokenMenu, &generate_scene_context);
} else {
totp_scene_director_activate_scene(plugin_state, TotpSceneTokenMenu, NULL);
}
totp_scene_director_activate_scene(plugin_state, TotpSceneTokenMenu);
}
break;
case InputKeyBack: {
if(!scene_state->current_token_index.is_null) {
TokenMenuSceneContext generate_scene_context = {
.current_token_index = scene_state->current_token_index.value};
totp_scene_director_activate_scene(
plugin_state, TotpSceneTokenMenu, &generate_scene_context);
} else {
totp_scene_director_activate_scene(plugin_state, TotpSceneTokenMenu, NULL);
}
totp_scene_director_activate_scene(plugin_state, TotpSceneTokenMenu);
break;
}
default:

View File

@@ -4,13 +4,7 @@
#include "../../../types/plugin_state.h"
#include "../../../types/plugin_event.h"
typedef struct {
uint16_t current_token_index;
} AppSettingsSceneContext;
void totp_scene_app_settings_activate(
PluginState* plugin_state,
const AppSettingsSceneContext* context);
void totp_scene_app_settings_activate(PluginState* plugin_state);
void totp_scene_app_settings_render(Canvas* const canvas, const PluginState* plugin_state);
bool totp_scene_app_settings_handle_event(
const PluginEvent* const event,

View File

@@ -114,12 +114,18 @@ bool totp_scene_authenticate_handle_event(
scene_state->code_length++;
}
break;
case InputKeyOk:
totp_crypto_seed_iv(plugin_state, &scene_state->code_input[0], scene_state->code_length);
case InputKeyOk: {
CryptoSeedIVResult seed_result = totp_crypto_seed_iv(
plugin_state, &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)) {
FURI_LOG_D(LOGGING_TAG, "PIN is valid");
totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken, NULL);
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);
@@ -140,6 +146,7 @@ bool totp_scene_authenticate_handle_event(
dialog_message_free(message);
}
break;
}
case InputKeyBack:
if(scene_state->code_length > 0) {
scene_state->code_input[scene_state->code_length - 1] = 0;

View File

@@ -31,9 +31,7 @@ typedef struct {
} UiPrecalculatedDimensions;
typedef struct {
uint16_t current_token_index;
char last_code[TOTP_TOKEN_DIGITS_MAX_COUNT + 1];
TokenInfo* current_token;
TotpUsbTypeCodeWorkerContext* usb_type_code_worker_context;
NotificationMessage const** notification_sequence_new_token;
NotificationMessage const** notification_sequence_automation;
@@ -128,19 +126,21 @@ static const NotificationSequence*
return (NotificationSequence*)scene_state->notification_sequence_automation;
}
static void update_totp_params(PluginState* const plugin_state) {
static void update_totp_params(PluginState* const plugin_state, size_t token_index) {
SceneState* scene_state = (SceneState*)plugin_state->current_scene_state;
if(scene_state->current_token_index < plugin_state->tokens_count) {
scene_state->current_token =
list_element_at(plugin_state->tokens_list, scene_state->current_token_index)->data;
TokenInfoIteratorContext* iterator_context =
totp_config_get_token_iterator_context(plugin_state);
if(totp_token_info_iterator_go_to(iterator_context, token_index)) {
totp_generate_code_worker_notify(
scene_state->generate_code_worker_context, TotpGenerateCodeWorkerEventForceUpdate);
}
}
static void draw_totp_code(Canvas* const canvas, const SceneState* const scene_state) {
uint8_t code_length = scene_state->current_token->digits;
static void draw_totp_code(Canvas* const canvas, const PluginState* const plugin_state) {
const SceneState* scene_state = plugin_state->current_scene_state;
const TokenInfoIteratorContext* iterator_context =
totp_config_get_token_iterator_context(plugin_state);
uint8_t code_length = totp_token_info_iterator_get_current_token(iterator_context)->digits;
uint8_t offset_x = scene_state->ui_precalculated_dimensions.code_offset_x;
uint8_t char_width = modeNine_15ptFontInfo.charInfo[0].width;
uint8_t offset_x_inc = scene_state->ui_precalculated_dimensions.code_offset_x_inc;
@@ -163,10 +163,18 @@ static void draw_totp_code(Canvas* const canvas, const SceneState* const scene_s
static void on_new_token_code_generated(bool time_left, void* context) {
const PluginState* plugin_state = context;
const TokenInfoIteratorContext* iterator_context =
totp_config_get_token_iterator_context(plugin_state);
if(totp_token_info_iterator_get_total_count(iterator_context) == 0) {
return;
}
SceneState* scene_state = plugin_state->current_scene_state;
const TokenInfo* current_token = totp_token_info_iterator_get_current_token(iterator_context);
uint8_t char_width = modeNine_15ptFontInfo.charInfo[0].width;
scene_state->ui_precalculated_dimensions.code_total_length =
scene_state->current_token->digits * (char_width + modeNine_15ptFontInfo.spacePixels);
current_token->digits * (char_width + modeNine_15ptFontInfo.spacePixels);
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_x_inc =
@@ -192,43 +200,9 @@ static void on_code_lifetime_updated_generated(float code_lifetime_percent, void
PROGRESS_BAR_MARGIN;
}
void totp_scene_generate_token_activate(
PluginState* plugin_state,
const GenerateTokenSceneContext* context) {
if(!plugin_state->token_list_loaded) {
TokenLoadingResult token_load_result = totp_config_file_load_tokens(plugin_state);
if(token_load_result != TokenLoadingResultSuccess) {
DialogMessage* message = dialog_message_alloc();
dialog_message_set_buttons(message, NULL, "Okay", NULL);
if(token_load_result == TokenLoadingResultWarning) {
dialog_message_set_text(
message,
"Unable to load some tokens\nPlease review conf file",
SCREEN_WIDTH_CENTER,
SCREEN_HEIGHT_CENTER,
AlignCenter,
AlignCenter);
} else if(token_load_result == TokenLoadingResultError) {
dialog_message_set_text(
message,
"Unable to load tokens\nPlease review conf file",
SCREEN_WIDTH_CENTER,
SCREEN_HEIGHT_CENTER,
AlignCenter,
AlignCenter);
}
dialog_message_show(plugin_state->dialogs_app, message);
dialog_message_free(message);
}
}
void totp_scene_generate_token_activate(PluginState* plugin_state) {
SceneState* scene_state = malloc(sizeof(SceneState));
furi_check(scene_state != NULL);
if(context == NULL || context->current_token_index > plugin_state->tokens_count) {
scene_state->current_token_index = 0;
} else {
scene_state->current_token_index = context->current_token_index;
}
plugin_state->current_scene_state = scene_state;
FURI_LOG_D(LOGGING_TAG, "Timezone set to: %f", (double)plugin_state->timezone_offset);
@@ -254,10 +228,11 @@ void totp_scene_generate_token_activate(
scene_state->last_code_update_sync);
}
#endif
const TokenInfoIteratorContext* iterator_context =
totp_config_get_token_iterator_context(plugin_state);
scene_state->generate_code_worker_context = totp_generate_code_worker_start(
scene_state->last_code,
&scene_state->current_token,
totp_token_info_iterator_get_current_token(iterator_context),
scene_state->last_code_update_sync,
plugin_state->timezone_offset,
plugin_state->iv);
@@ -270,11 +245,14 @@ void totp_scene_generate_token_activate(
&on_code_lifetime_updated_generated,
scene_state);
update_totp_params(plugin_state);
update_totp_params(
plugin_state, totp_token_info_iterator_get_current_token_index(iterator_context));
}
void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_state) {
if(plugin_state->tokens_count == 0) {
const TokenInfoIteratorContext* iterator_context =
totp_config_get_token_iterator_context(plugin_state);
if(totp_token_info_iterator_get_total_count(iterator_context) == 0) {
canvas_draw_str_aligned(
canvas,
SCREEN_WIDTH_CENTER,
@@ -295,7 +273,9 @@ 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);
uint16_t token_name_width = canvas_string_width(canvas, scene_state->current_token->name);
const char* token_name_cstr =
furi_string_get_cstr(totp_token_info_iterator_get_current_token(iterator_context)->name);
uint16_t token_name_width = canvas_string_width(canvas, token_name_cstr);
if(SCREEN_WIDTH - token_name_width > 18) {
canvas_draw_str_aligned(
canvas,
@@ -303,22 +283,17 @@ void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_
SCREEN_HEIGHT_CENTER - 20,
AlignCenter,
AlignCenter,
scene_state->current_token->name);
token_name_cstr);
} else {
canvas_draw_str_aligned(
canvas,
9,
SCREEN_HEIGHT_CENTER - 20,
AlignLeft,
AlignCenter,
scene_state->current_token->name);
canvas, 9, SCREEN_HEIGHT_CENTER - 20, AlignLeft, AlignCenter, token_name_cstr);
canvas_set_color(canvas, ColorWhite);
canvas_draw_box(canvas, 0, SCREEN_HEIGHT_CENTER - 24, 9, 9);
canvas_draw_box(canvas, SCREEN_WIDTH - 10, SCREEN_HEIGHT_CENTER - 24, 9, 9);
canvas_set_color(canvas, ColorBlack);
}
draw_totp_code(canvas, scene_state);
draw_totp_code(canvas, plugin_state);
canvas_draw_box(
canvas,
@@ -326,11 +301,10 @@ void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_
SCREEN_HEIGHT - PROGRESS_BAR_MARGIN - PROGRESS_BAR_HEIGHT,
scene_state->ui_precalculated_dimensions.progress_bar_width,
PROGRESS_BAR_HEIGHT);
if(plugin_state->tokens_count > 1) {
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(
canvas, SCREEN_WIDTH - 9, SCREEN_HEIGHT_CENTER - 24, &I_totp_arrow_right_8x9);
canvas, SCREEN_WIDTH - 8, SCREEN_HEIGHT_CENTER - 24, &I_totp_arrow_right_8x9);
}
#ifdef TOTP_AUTOMATION_ICONS_ENABLED
@@ -351,7 +325,7 @@ void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_
#ifdef TOTP_BADBT_TYPE_ENABLED
if(plugin_state->automation_method & AutomationMethodBadBt &&
plugin_state->bt_type_code_worker_context != NULL &&
plugin_state->bt_type_code_worker_context->is_advertising) {
totp_bt_type_code_worker_is_advertising(plugin_state->bt_type_code_worker_context)) {
canvas_draw_icon(
canvas,
SCREEN_WIDTH_CENTER +
@@ -379,10 +353,12 @@ bool totp_scene_generate_token_handle_event(
if(event->input.key == InputKeyDown &&
plugin_state->automation_method & AutomationMethodBadUsb) {
scene_state = (SceneState*)plugin_state->current_scene_state;
const TokenInfoIteratorContext* iterator_context =
totp_config_get_token_iterator_context(plugin_state);
totp_usb_type_code_worker_notify(
scene_state->usb_type_code_worker_context,
TotpUsbTypeCodeWorkerEventType,
scene_state->current_token->automation_features);
totp_token_info_iterator_get_current_token(iterator_context)->automation_features);
notification_message(
plugin_state->notification_app,
get_notification_sequence_automation(plugin_state, scene_state));
@@ -393,10 +369,12 @@ bool totp_scene_generate_token_handle_event(
event->input.key == InputKeyUp &&
plugin_state->automation_method & AutomationMethodBadBt) {
scene_state = (SceneState*)plugin_state->current_scene_state;
const TokenInfoIteratorContext* iterator_context =
totp_config_get_token_iterator_context(plugin_state);
totp_bt_type_code_worker_notify(
plugin_state->bt_type_code_worker_context,
TotpBtTypeCodeWorkerEventType,
scene_state->current_token->automation_features);
totp_token_info_iterator_get_current_token(iterator_context)->automation_features);
notification_message(
plugin_state->notification_app,
get_notification_sequence_automation(plugin_state, scene_state));
@@ -409,37 +387,43 @@ bool totp_scene_generate_token_handle_event(
return true;
}
scene_state = (SceneState*)plugin_state->current_scene_state;
switch(event->input.key) {
case InputKeyUp:
break;
case InputKeyDown:
break;
case InputKeyRight:
totp_roll_value_uint16_t(
&scene_state->current_token_index,
case InputKeyRight: {
const TokenInfoIteratorContext* iterator_context =
totp_config_get_token_iterator_context(plugin_state);
size_t current_token_index =
totp_token_info_iterator_get_current_token_index(iterator_context);
totp_roll_value_size_t(
&current_token_index,
1,
0,
plugin_state->tokens_count - 1,
totp_token_info_iterator_get_total_count(iterator_context) - 1,
RollOverflowBehaviorRoll);
update_totp_params(plugin_state);
update_totp_params(plugin_state, current_token_index);
break;
case InputKeyLeft:
totp_roll_value_uint16_t(
&scene_state->current_token_index,
}
case InputKeyLeft: {
const TokenInfoIteratorContext* iterator_context =
totp_config_get_token_iterator_context(plugin_state);
size_t current_token_index =
totp_token_info_iterator_get_current_token_index(iterator_context);
totp_roll_value_size_t(
&current_token_index,
-1,
0,
plugin_state->tokens_count - 1,
totp_token_info_iterator_get_total_count(iterator_context) - 1,
RollOverflowBehaviorRoll);
update_totp_params(plugin_state);
update_totp_params(plugin_state, current_token_index);
break;
}
case InputKeyOk:
if(plugin_state->tokens_count == 0) {
totp_scene_director_activate_scene(plugin_state, TotpSceneTokenMenu, NULL);
} else {
TokenMenuSceneContext ctx = {.current_token_index = scene_state->current_token_index};
totp_scene_director_activate_scene(plugin_state, TotpSceneTokenMenu, &ctx);
}
totp_scene_director_activate_scene(plugin_state, TotpSceneTokenMenu);
break;
case InputKeyBack:
break;

View File

@@ -4,13 +4,7 @@
#include "../../../types/plugin_state.h"
#include "../../../types/plugin_event.h"
typedef struct {
uint16_t current_token_index;
} GenerateTokenSceneContext;
void totp_scene_generate_token_activate(
PluginState* plugin_state,
const GenerateTokenSceneContext* context);
void totp_scene_generate_token_activate(PluginState* plugin_state);
void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_state);
bool totp_scene_generate_token_handle_event(
const PluginEvent* const event,

View File

@@ -0,0 +1,12 @@
#include "standby.h"
#include <totp_icons.h>
#include "../../constants.h"
void totp_scene_standby_render(Canvas* const canvas) {
canvas_draw_icon(canvas, SCREEN_WIDTH - 56, SCREEN_HEIGHT - 48, &I_DolphinCommon_56x48);
canvas_set_font(canvas, FontPrimary);
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

@@ -0,0 +1,5 @@
#pragma once
#include <gui/gui.h>
void totp_scene_standby_render(Canvas* const canvas);

View File

@@ -6,12 +6,10 @@
#include "../../constants.h"
#include "../../scene_director.h"
#include "../../../services/config/config.h"
#include <linked_list.h>
#include "../../../types/token_info.h"
#include "../generate_token/totp_scene_generate_token.h"
#include "../add_new_token/totp_scene_add_new_token.h"
#include "../app_settings/totp_app_settings.h"
#include "../../../types/nullable.h"
#include <roll_value.h>
#define SCREEN_HEIGHT_THIRD (SCREEN_HEIGHT / 3)
@@ -21,25 +19,19 @@ typedef enum { AddNewToken, DeleteToken, AppSettings } Control;
typedef struct {
Control selected_control;
TotpNullable_uint16_t current_token_index;
} SceneState;
void totp_scene_token_menu_activate(
PluginState* plugin_state,
const TokenMenuSceneContext* context) {
void totp_scene_token_menu_activate(PluginState* plugin_state) {
SceneState* scene_state = malloc(sizeof(SceneState));
furi_check(scene_state != NULL);
plugin_state->current_scene_state = scene_state;
if(context != NULL) {
TOTP_NULLABLE_VALUE(scene_state->current_token_index, context->current_token_index);
} else {
TOTP_NULLABLE_NULL(scene_state->current_token_index);
}
}
void totp_scene_token_menu_render(Canvas* const canvas, PluginState* plugin_state) {
const SceneState* scene_state = (SceneState*)plugin_state->current_scene_state;
if(scene_state->current_token_index.is_null) {
const TokenInfoIteratorContext* iterator_context =
totp_config_get_token_iterator_context(plugin_state);
if(totp_token_info_iterator_get_total_count(iterator_context) == 0) {
ui_control_button_render(
canvas,
SCREEN_WIDTH_CENTER - 36,
@@ -95,22 +87,28 @@ bool totp_scene_token_menu_handle_event(const PluginEvent* const event, PluginSt
}
switch(event->input.key) {
case InputKeyUp:
case InputKeyUp: {
const TokenInfoIteratorContext* iterator_context =
totp_config_get_token_iterator_context(plugin_state);
totp_roll_value_uint8_t(
&scene_state->selected_control, -1, AddNewToken, AppSettings, RollOverflowBehaviorRoll);
if(scene_state->selected_control == DeleteToken &&
scene_state->current_token_index.is_null) {
totp_token_info_iterator_get_total_count(iterator_context) == 0) {
scene_state->selected_control--;
}
break;
case InputKeyDown:
}
case InputKeyDown: {
const TokenInfoIteratorContext* iterator_context =
totp_config_get_token_iterator_context(plugin_state);
totp_roll_value_uint8_t(
&scene_state->selected_control, 1, AddNewToken, AppSettings, RollOverflowBehaviorRoll);
if(scene_state->selected_control == DeleteToken &&
scene_state->current_token_index.is_null) {
totp_token_info_iterator_get_total_count(iterator_context) == 0) {
scene_state->selected_control++;
}
break;
}
case InputKeyRight:
break;
case InputKeyLeft:
@@ -118,14 +116,7 @@ bool totp_scene_token_menu_handle_event(const PluginEvent* const event, PluginSt
case InputKeyOk:
switch(scene_state->selected_control) {
case AddNewToken: {
if(scene_state->current_token_index.is_null) {
totp_scene_director_activate_scene(plugin_state, TotpSceneAddNewToken, NULL);
} else {
TokenAddEditSceneContext add_new_token_scene_context = {
.current_token_index = scene_state->current_token_index.value};
totp_scene_director_activate_scene(
plugin_state, TotpSceneAddNewToken, &add_new_token_scene_context);
}
totp_scene_director_activate_scene(plugin_state, TotpSceneAddNewToken);
break;
}
case DeleteToken: {
@@ -142,34 +133,21 @@ bool totp_scene_token_menu_handle_event(const PluginEvent* const event, PluginSt
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 &&
!scene_state->current_token_index.is_null) {
TokenInfo* tokenInfo = NULL;
plugin_state->tokens_list = list_remove_at(
plugin_state->tokens_list,
scene_state->current_token_index.value,
(void**)&tokenInfo);
plugin_state->tokens_count--;
furi_check(tokenInfo != NULL);
token_info_free(tokenInfo);
if(totp_full_save_config_file(plugin_state) != TotpConfigFileUpdateSuccess) {
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, NULL);
totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken);
}
break;
}
case AppSettings: {
if(!scene_state->current_token_index.is_null) {
AppSettingsSceneContext app_settings_context = {
.current_token_index = scene_state->current_token_index.value};
totp_scene_director_activate_scene(
plugin_state, TotpSceneAppSettings, &app_settings_context);
} else {
totp_scene_director_activate_scene(plugin_state, TotpSceneAppSettings, NULL);
}
totp_scene_director_activate_scene(plugin_state, TotpSceneAppSettings);
break;
}
default:
@@ -177,14 +155,7 @@ bool totp_scene_token_menu_handle_event(const PluginEvent* const event, PluginSt
}
break;
case InputKeyBack: {
if(!scene_state->current_token_index.is_null) {
GenerateTokenSceneContext generate_scene_context = {
.current_token_index = scene_state->current_token_index.value};
totp_scene_director_activate_scene(
plugin_state, TotpSceneGenerateToken, &generate_scene_context);
} else {
totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken, NULL);
}
totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken);
break;
}
default:

View File

@@ -4,13 +4,7 @@
#include "../../../types/plugin_state.h"
#include "../../../types/plugin_event.h"
typedef struct {
uint16_t current_token_index;
} TokenMenuSceneContext;
void totp_scene_token_menu_activate(
PluginState* plugin_state,
const TokenMenuSceneContext* context);
void totp_scene_token_menu_activate(PluginState* plugin_state);
void totp_scene_token_menu_render(Canvas* const canvas, PluginState* plugin_state);
bool totp_scene_token_menu_handle_event(const PluginEvent* const event, PluginState* plugin_state);
void totp_scene_token_menu_deactivate(PluginState* plugin_state);