mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-05-14 15:08:35 -07:00
Update totp
This commit is contained in:
@@ -1,81 +1,52 @@
|
||||
#include "totp_input_text.h"
|
||||
#include <gui/view_i.h>
|
||||
|
||||
void view_draw(View* view, Canvas* canvas) {
|
||||
furi_assert(view);
|
||||
if(view->draw_callback) {
|
||||
void* data = view_get_model(view);
|
||||
view->draw_callback(canvas, data);
|
||||
view_unlock_model(view);
|
||||
}
|
||||
#include <gui/view_dispatcher.h>
|
||||
#include <gui/modules/text_input.h>
|
||||
|
||||
typedef struct {
|
||||
InputTextResult* result;
|
||||
ViewDispatcher* view_dispatcher;
|
||||
} InputTextContext;
|
||||
|
||||
static void commit_text_input_callback(void* ctx) {
|
||||
InputTextContext* context = ctx;
|
||||
context->result->user_input_length = strnlen(context->result->user_input, INPUT_BUFFER_SIZE);
|
||||
context->result->success = true;
|
||||
view_dispatcher_stop(context->view_dispatcher);
|
||||
}
|
||||
|
||||
bool view_input(View* view, InputEvent* event) {
|
||||
furi_assert(view);
|
||||
if(view->input_callback) {
|
||||
return view->input_callback(event, view->context);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
static bool back_event_callback(void* ctx) {
|
||||
InputTextContext* context = ctx;
|
||||
context->result->success = false;
|
||||
view_dispatcher_stop(context->view_dispatcher);
|
||||
return false;
|
||||
}
|
||||
|
||||
void view_unlock_model(View* view) {
|
||||
furi_assert(view);
|
||||
if(view->model_type == ViewModelTypeLocking) {
|
||||
ViewModelLocking* model = (ViewModelLocking*)(view->model);
|
||||
furi_check(furi_mutex_release(model->mutex) == FuriStatusOk);
|
||||
}
|
||||
}
|
||||
|
||||
static void commit_text_input_callback(void* context) {
|
||||
InputTextSceneState* text_input_state = (InputTextSceneState*)context;
|
||||
if(text_input_state->callback != NULL) {
|
||||
InputTextSceneCallbackResult* result = malloc(sizeof(InputTextSceneCallbackResult));
|
||||
furi_check(result != NULL);
|
||||
result->user_input_length =
|
||||
strnlen(text_input_state->text_input_buffer, INPUT_BUFFER_SIZE);
|
||||
result->user_input = malloc(result->user_input_length + 1);
|
||||
furi_check(result->user_input != NULL);
|
||||
result->callback_data = text_input_state->callback_data;
|
||||
strlcpy(
|
||||
result->user_input,
|
||||
text_input_state->text_input_buffer,
|
||||
result->user_input_length + 1);
|
||||
text_input_state->callback(result);
|
||||
}
|
||||
}
|
||||
|
||||
InputTextSceneState* totp_input_text_activate(InputTextSceneContext* context) {
|
||||
InputTextSceneState* text_input_state = malloc(sizeof(InputTextSceneState));
|
||||
furi_check(text_input_state != NULL);
|
||||
text_input_state->text_input = text_input_alloc();
|
||||
text_input_state->text_input_view = text_input_get_view(text_input_state->text_input);
|
||||
text_input_state->callback = context->callback;
|
||||
text_input_state->callback_data = context->callback_data;
|
||||
text_input_set_header_text(text_input_state->text_input, context->header_text);
|
||||
void totp_input_text(Gui* gui, const char* header_text, InputTextResult* result) {
|
||||
ViewDispatcher* view_dispatcher = view_dispatcher_alloc();
|
||||
TextInput* text_input = text_input_alloc();
|
||||
InputTextContext context = {.result = result, .view_dispatcher = view_dispatcher};
|
||||
text_input_set_header_text(text_input, header_text);
|
||||
text_input_set_result_callback(
|
||||
text_input_state->text_input,
|
||||
text_input,
|
||||
commit_text_input_callback,
|
||||
text_input_state,
|
||||
&text_input_state->text_input_buffer[0],
|
||||
&context,
|
||||
result->user_input,
|
||||
INPUT_BUFFER_SIZE,
|
||||
true);
|
||||
return text_input_state;
|
||||
}
|
||||
|
||||
void totp_input_text_render(Canvas* const canvas, InputTextSceneState* text_input_state) {
|
||||
view_draw(text_input_state->text_input_view, canvas);
|
||||
}
|
||||
view_dispatcher_enable_queue(view_dispatcher);
|
||||
view_dispatcher_add_view(view_dispatcher, 0, text_input_get_view(text_input));
|
||||
|
||||
bool totp_input_text_handle_event(PluginEvent* const event, InputTextSceneState* text_input_state) {
|
||||
if(event->type == EventTypeKey) {
|
||||
view_input(text_input_state->text_input_view, &event->input);
|
||||
}
|
||||
view_dispatcher_attach_to_gui(view_dispatcher, gui, ViewDispatcherTypeFullscreen);
|
||||
|
||||
return true;
|
||||
}
|
||||
view_dispatcher_set_navigation_event_callback(view_dispatcher, &back_event_callback);
|
||||
view_dispatcher_set_event_callback_context(view_dispatcher, &context);
|
||||
view_dispatcher_switch_to_view(view_dispatcher, 0);
|
||||
|
||||
void totp_input_text_free(InputTextSceneState* state) {
|
||||
text_input_free(state->text_input);
|
||||
free(state);
|
||||
view_dispatcher_run(view_dispatcher);
|
||||
|
||||
view_dispatcher_remove_view(view_dispatcher, 0);
|
||||
view_dispatcher_free(view_dispatcher);
|
||||
text_input_free(text_input);
|
||||
}
|
||||
|
||||
@@ -1,36 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <gui/gui.h>
|
||||
#include <gui/view.h>
|
||||
#include <gui/modules/text_input.h>
|
||||
#include "../../../types/plugin_state.h"
|
||||
#include "../../../types/plugin_event.h"
|
||||
|
||||
#define INPUT_BUFFER_SIZE (255)
|
||||
|
||||
typedef struct {
|
||||
char* user_input;
|
||||
char user_input[INPUT_BUFFER_SIZE];
|
||||
size_t user_input_length;
|
||||
void* callback_data;
|
||||
} InputTextSceneCallbackResult;
|
||||
bool success;
|
||||
} InputTextResult;
|
||||
|
||||
typedef void (*InputTextSceneCallback)(InputTextSceneCallbackResult* result);
|
||||
|
||||
typedef struct {
|
||||
InputTextSceneCallback callback;
|
||||
char* header_text;
|
||||
void* callback_data;
|
||||
} InputTextSceneContext;
|
||||
|
||||
typedef struct {
|
||||
TextInput* text_input;
|
||||
View* text_input_view;
|
||||
char text_input_buffer[INPUT_BUFFER_SIZE];
|
||||
InputTextSceneCallback callback;
|
||||
void* callback_data;
|
||||
} InputTextSceneState;
|
||||
|
||||
InputTextSceneState* totp_input_text_activate(InputTextSceneContext* context);
|
||||
void totp_input_text_render(Canvas* const canvas, InputTextSceneState* text_input_state);
|
||||
bool totp_input_text_handle_event(PluginEvent* const event, InputTextSceneState* text_input_state);
|
||||
void totp_input_text_free(InputTextSceneState* state);
|
||||
void totp_input_text(Gui* gui, const char* header_text, InputTextResult* result);
|
||||
|
||||
@@ -13,9 +13,9 @@
|
||||
char* TOKEN_ALGO_LIST[] = {"SHA1", "SHA256", "SHA512", "Steam"};
|
||||
char* TOKEN_DIGITS_TEXT_LIST[] = {"5 digits", "6 digits", "8 digits"};
|
||||
TokenDigitsCount TOKEN_DIGITS_VALUE_LIST[] = {
|
||||
TotpFiveDigitsCount,
|
||||
TotpSixDigitsCount,
|
||||
TotpEightDigitsCount};
|
||||
TokenDigitsCountFive,
|
||||
TokenDigitsCountSix,
|
||||
TokenDigitsCountEight};
|
||||
|
||||
typedef enum {
|
||||
TokenNameTextBox,
|
||||
@@ -33,10 +33,6 @@ typedef struct {
|
||||
size_t token_secret_length;
|
||||
bool saved;
|
||||
Control selected_control;
|
||||
InputTextSceneContext* token_name_input_context;
|
||||
InputTextSceneContext* token_secret_input_context;
|
||||
InputTextSceneState* input_state;
|
||||
bool text_input_mode;
|
||||
int16_t screen_y_offset;
|
||||
TokenHashAlgo algo;
|
||||
uint8_t digits_count_index;
|
||||
@@ -51,24 +47,6 @@ struct TotpAddContext {
|
||||
|
||||
enum TotpIteratorUpdateTokenResultsEx { TotpIteratorUpdateTokenResultInvalidSecret = 1 };
|
||||
|
||||
static void on_token_name_user_comitted(InputTextSceneCallbackResult* result) {
|
||||
SceneState* scene_state = result->callback_data;
|
||||
free(scene_state->token_name);
|
||||
scene_state->token_name = result->user_input;
|
||||
scene_state->token_name_length = result->user_input_length;
|
||||
scene_state->text_input_mode = false;
|
||||
free(result);
|
||||
}
|
||||
|
||||
static void on_token_secret_user_comitted(InputTextSceneCallbackResult* result) {
|
||||
SceneState* scene_state = result->callback_data;
|
||||
free(scene_state->token_secret);
|
||||
scene_state->token_secret = result->user_input;
|
||||
scene_state->token_secret_length = result->user_input_length;
|
||||
scene_state->text_input_mode = false;
|
||||
free(result);
|
||||
}
|
||||
|
||||
static void update_duration_text(SceneState* scene_state) {
|
||||
furi_string_printf(scene_state->duration_text, "%d sec.", scene_state->duration);
|
||||
}
|
||||
@@ -95,6 +73,26 @@ static TotpIteratorUpdateTokenResult add_token_handler(TokenInfo* tokenInfo, con
|
||||
return TotpIteratorUpdateTokenResultSuccess;
|
||||
}
|
||||
|
||||
static void ask_user_input(
|
||||
const PluginState* plugin_state,
|
||||
const char* header,
|
||||
char** user_input,
|
||||
size_t* user_input_length) {
|
||||
InputTextResult input_result;
|
||||
if(*user_input != NULL) {
|
||||
strlcpy(input_result.user_input, *user_input, INPUT_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
totp_input_text(plugin_state->gui, header, &input_result);
|
||||
if(input_result.success) {
|
||||
if(*user_input != NULL) {
|
||||
free(*user_input);
|
||||
}
|
||||
*user_input = strdup(input_result.user_input);
|
||||
*user_input_length = input_result.user_input_length;
|
||||
}
|
||||
}
|
||||
|
||||
void totp_scene_add_new_token_activate(PluginState* plugin_state) {
|
||||
SceneState* scene_state = malloc(sizeof(SceneState));
|
||||
furi_check(scene_state != NULL);
|
||||
@@ -104,34 +102,17 @@ void totp_scene_add_new_token_activate(PluginState* plugin_state) {
|
||||
scene_state->token_secret = "Secret";
|
||||
scene_state->token_secret_length = strlen(scene_state->token_secret);
|
||||
|
||||
scene_state->token_name_input_context = malloc(sizeof(InputTextSceneContext));
|
||||
furi_check(scene_state->token_name_input_context != NULL);
|
||||
scene_state->token_name_input_context->header_text = "Enter token name";
|
||||
scene_state->token_name_input_context->callback_data = scene_state;
|
||||
scene_state->token_name_input_context->callback = on_token_name_user_comitted;
|
||||
|
||||
scene_state->token_secret_input_context = malloc(sizeof(InputTextSceneContext));
|
||||
furi_check(scene_state->token_secret_input_context != NULL);
|
||||
scene_state->token_secret_input_context->header_text = "Enter token secret";
|
||||
scene_state->token_secret_input_context->callback_data = scene_state;
|
||||
scene_state->token_secret_input_context->callback = on_token_secret_user_comitted;
|
||||
|
||||
scene_state->screen_y_offset = 0;
|
||||
|
||||
scene_state->digits_count_index = 1;
|
||||
|
||||
scene_state->input_state = NULL;
|
||||
scene_state->duration = TOTP_TOKEN_DURATION_DEFAULT;
|
||||
scene_state->duration = TokenDurationDefault;
|
||||
scene_state->duration_text = furi_string_alloc();
|
||||
update_duration_text(scene_state);
|
||||
}
|
||||
|
||||
void totp_scene_add_new_token_render(Canvas* const canvas, PluginState* plugin_state) {
|
||||
SceneState* scene_state = plugin_state->current_scene_state;
|
||||
if(scene_state->text_input_mode) {
|
||||
totp_input_text_render(canvas, scene_state->input_state);
|
||||
return;
|
||||
}
|
||||
void totp_scene_add_new_token_render(Canvas* const canvas, const PluginState* plugin_state) {
|
||||
const SceneState* scene_state = plugin_state->current_scene_state;
|
||||
|
||||
ui_control_text_box_render(
|
||||
canvas,
|
||||
@@ -195,31 +176,15 @@ void update_screen_y_offset(SceneState* scene_state) {
|
||||
}
|
||||
}
|
||||
|
||||
bool totp_scene_add_new_token_handle_event(PluginEvent* const event, PluginState* plugin_state) {
|
||||
bool totp_scene_add_new_token_handle_event(
|
||||
const PluginEvent* const event,
|
||||
PluginState* plugin_state) {
|
||||
if(event->type != EventTypeKey) {
|
||||
return true;
|
||||
}
|
||||
|
||||
SceneState* scene_state = plugin_state->current_scene_state;
|
||||
|
||||
if(event->input.type == InputTypeLong && event->input.key == InputKeyBack) {
|
||||
if(scene_state->text_input_mode) {
|
||||
scene_state->text_input_mode = false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(scene_state->text_input_mode) {
|
||||
if(event->input.type == InputTypeShort && event->input.key == InputKeyBack) {
|
||||
PluginEvent long_back_cb_evt = {
|
||||
.type = event->type, .input.key = InputKeyBack, .input.type = InputTypeLong};
|
||||
return totp_input_text_handle_event(&long_back_cb_evt, scene_state->input_state);
|
||||
}
|
||||
|
||||
return totp_input_text_handle_event(event, scene_state->input_state);
|
||||
}
|
||||
|
||||
if(event->input.type == InputTypePress) {
|
||||
switch(event->input.key) {
|
||||
case InputKeyUp:
|
||||
@@ -243,7 +208,11 @@ bool totp_scene_add_new_token_handle_event(PluginEvent* const event, PluginState
|
||||
case InputKeyRight:
|
||||
if(scene_state->selected_control == TokenAlgoSelect) {
|
||||
totp_roll_value_uint8_t(
|
||||
&scene_state->algo, 1, SHA1, STEAM, RollOverflowBehaviorRoll);
|
||||
&scene_state->algo,
|
||||
1,
|
||||
TokenHashAlgoSha1,
|
||||
TokenHashAlgoSteam,
|
||||
RollOverflowBehaviorRoll);
|
||||
} else if(scene_state->selected_control == TokenLengthSelect) {
|
||||
totp_roll_value_uint8_t(
|
||||
&scene_state->digits_count_index, 1, 0, 2, RollOverflowBehaviorRoll);
|
||||
@@ -256,7 +225,11 @@ bool totp_scene_add_new_token_handle_event(PluginEvent* const event, PluginState
|
||||
case InputKeyLeft:
|
||||
if(scene_state->selected_control == TokenAlgoSelect) {
|
||||
totp_roll_value_uint8_t(
|
||||
&scene_state->algo, -1, SHA1, STEAM, RollOverflowBehaviorRoll);
|
||||
&scene_state->algo,
|
||||
-1,
|
||||
TokenHashAlgoSha1,
|
||||
TokenHashAlgoSteam,
|
||||
RollOverflowBehaviorRoll);
|
||||
} else if(scene_state->selected_control == TokenLengthSelect) {
|
||||
totp_roll_value_uint8_t(
|
||||
&scene_state->digits_count_index, -1, 0, 2, RollOverflowBehaviorRoll);
|
||||
@@ -277,22 +250,18 @@ bool totp_scene_add_new_token_handle_event(PluginEvent* const event, PluginState
|
||||
} else if(event->input.type == InputTypeRelease && event->input.key == InputKeyOk) {
|
||||
switch(scene_state->selected_control) {
|
||||
case TokenNameTextBox:
|
||||
if(scene_state->input_state != NULL) {
|
||||
totp_input_text_free(scene_state->input_state);
|
||||
}
|
||||
scene_state->input_state =
|
||||
totp_input_text_activate(scene_state->token_name_input_context);
|
||||
|
||||
scene_state->text_input_mode = true;
|
||||
ask_user_input(
|
||||
plugin_state,
|
||||
"Token name",
|
||||
&scene_state->token_name,
|
||||
&scene_state->token_name_length);
|
||||
break;
|
||||
case TokenSecretTextBox:
|
||||
if(scene_state->input_state != NULL) {
|
||||
totp_input_text_free(scene_state->input_state);
|
||||
}
|
||||
scene_state->input_state =
|
||||
totp_input_text_activate(scene_state->token_secret_input_context);
|
||||
|
||||
scene_state->text_input_mode = true;
|
||||
ask_user_input(
|
||||
plugin_state,
|
||||
"Token secret",
|
||||
&scene_state->token_secret,
|
||||
&scene_state->token_secret_length);
|
||||
break;
|
||||
case TokenAlgoSelect:
|
||||
break;
|
||||
@@ -344,18 +313,8 @@ void totp_scene_add_new_token_deactivate(PluginState* plugin_state) {
|
||||
free(scene_state->token_name);
|
||||
free(scene_state->token_secret);
|
||||
|
||||
free(scene_state->token_name_input_context->header_text);
|
||||
free(scene_state->token_name_input_context);
|
||||
|
||||
free(scene_state->token_secret_input_context->header_text);
|
||||
free(scene_state->token_secret_input_context);
|
||||
|
||||
furi_string_free(scene_state->duration_text);
|
||||
|
||||
if(scene_state->input_state != NULL) {
|
||||
totp_input_text_free(scene_state->input_state);
|
||||
}
|
||||
|
||||
free(plugin_state->current_scene_state);
|
||||
plugin_state->current_scene_state = NULL;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include "../../../types/plugin_event.h"
|
||||
|
||||
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_render(Canvas* const canvas, const PluginState* plugin_state);
|
||||
bool totp_scene_add_new_token_handle_event(
|
||||
const PluginEvent* const event,
|
||||
PluginState* plugin_state);
|
||||
void totp_scene_add_new_token_deactivate(PluginState* plugin_state);
|
||||
|
||||
Reference in New Issue
Block a user