Просмотр исходного кода

Closing #162 and prepared for OFW catalog (#163)

Alexander Kopachov 2 лет назад
Родитель
Сommit
4c3d75d400

+ 362 - 0
.ofwcatalog/CHANGELOG.md

@@ -0,0 +1,362 @@
+# Changelog
+
+## [v2.2.2](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v2.2.2) - 19 Jun 2023
+
+* Fixed [#158](https://github.com/akopachov/flipper-zero_authenticator/issues/158) 
+* Cosmetic refactoring
+
+
+
+## [v2.2.1](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v2.2.1) - 06 Jun 2023
+
+* Fixed [#155](https://github.com/akopachov/flipper-zero_authenticator/issues/155) 
+* Refactoring
+
+
+
+## [v2.2.0](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v2.2.0) - 05 Jun 2023
+
+* Fixed [#153](https://github.com/akopachov/flipper-zero_authenticator/issues/153) 
+* Updated firmware submodules
+
+
+
+## [v2.1.1](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v2.1.1) - 30 May 2023
+
+* Updated firmware submodules
+* Added some new fonts for supporters 
+
+
+
+## [v2.1.0](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v2.1.0) - 24 May 2023
+
+* Implemented [#148](https://github.com/akopachov/flipper-zero_authenticator/issues/148) 
+* 🧹 Refactoring
+* ** Added nice custom fonts for supporters **
+
+
+
+## [v2.0.3](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v2.0.3) - 29 Apr 2023
+
+* Fixed [#146](https://github.com/akopachov/flipper-zero_authenticator/issues/146) 
+* Updated firmware references
+
+
+
+## [v2.0.2](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v2.0.2) - 28 Apr 2023
+
+* Refactoring & minor improvements
+
+
+
+## [v2.0.1](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v2.0.1) - 26 Apr 2023
+
+* Fixed few bugs I found during day 1 of v2.0.0
+* Refactoring
+* Updated firmware submodules
+
+
+
+## [v2.0.0](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v2.0.0) - 25 Apr 2023
+
+* Reworked token list to make app work smooth with bigger lists of tokens. So right now you can add as much tokens as you need.
+* Improved token list operations to make them more reliable
+* Refactoring
+* Updated firmware submodules
+
+
+
+## [v1.9.2](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v1.9.2) - 13 Apr 2023
+
+* Updated firmware submodules
+
+
+
+## [v1.9.1](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v1.9.1) - 13 Apr 2023
+
+* Improved TOTP code rendering method
+* Added "--clean" flag to custom FBT
+
+
+
+## [v1.9.0](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v1.9.0) - 12 Apr 2023
+
+* Moved token generation into separate thread
+* Refactoring and code cleanup
+
+
+
+## [v1.8.8](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v1.8.8) - 11 Apr 2023
+
+* Xtreme: fixed BT name length according to latest XFW changes (by [@Willy-JL](https://github.com/Willy-JL))
+* Updated firmware submodules
+
+
+
+## [v1.8.7](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v1.8.7) - 07 Apr 2023
+
+* Backup conf file before running "totp pin set" and "totp pin remove" CLI commands ([#123](https://github.com/akopachov/flipper-zero_authenticator/issues/123))
+* Some refactoring ([#120](https://github.com/akopachov/flipper-zero_authenticator/issues/120))
+
+
+
+## [v1.8.6](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v1.8.6) - 06 Apr 2023
+
+* Updated firmware submodules [#118](https://github.com/akopachov/flipper-zero_authenticator/issues/118) 
+
+
+
+## [v1.8.5](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v1.8.5) - 05 Apr 2023
+
+* Fixed [#116](https://github.com/akopachov/flipper-zero_authenticator/issues/116) 
+
+
+
+## [v1.8.4](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v1.8.4) - 05 Apr 2023
+
+* Added Steam guard token support ([#111](https://github.com/akopachov/flipper-zero_authenticator/issues/111))
+* Added Base64-encoded token support
+* Custom font for token
+* Refactoring
+
+
+
+## [v1.8.3](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v1.8.3) - 03 Apr 2023
+
+* Build artifact for [Xtreme](https://github.com/ClaraCrazy/Flipper-Xtreme) firmware ([#113](https://github.com/akopachov/flipper-zero_authenticator/issues/113))
+* Xtreme: custom BT name & MAC which should resolve [#98](https://github.com/akopachov/flipper-zero_authenticator/issues/98)
+
+
+
+## [v1.8.2](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v1.8.2) - 31 Mar 2023
+
+* Implemented [#106](https://github.com/akopachov/flipper-zero_authenticator/issues/106) 
+
+
+
+## [v1.8.1](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v1.8.1) - 31 Mar 2023
+
+* Implemented [#102](https://github.com/akopachov/flipper-zero_authenticator/issues/102) 
+* Implemented [#103](https://github.com/akopachov/flipper-zero_authenticator/issues/103) 
+* Refactoring
+* Minor fixes
+
+
+
+## [v1.8.0](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v1.8.0) - 30 Mar 2023
+
+* Implemented [#95](https://github.com/akopachov/flipper-zero_authenticator/issues/95) 
+* New CLI commands "totp update", "totp lsattr"
+* Refactoring
+
+
+
+## [v1.7.1](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v1.7.1) - 22 Mar 2023
+
+* Updated firmware submodules
+
+
+
+## [v1.7.0](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v1.7.0) - 21 Mar 2023
+
+* Implemented [#89](https://github.com/akopachov/flipper-zero_authenticator/issues/89) 
+* Refactoring
+
+
+
+## [v1.6.5](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v1.6.5) - 09 Mar 2023
+
+* Updated firmware references
+* Updated code to make it compatible with latest firmware changes
+
+
+
+## [v1.6.4](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v1.6.4) - 01 Mar 2023
+
+* Updated firmware references
+
+
+
+## [v1.6.3](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v1.6.3) - 16 Feb 2023
+
+* Fixed [#76](https://github.com/akopachov/flipper-zero_authenticator/issues/76) 
+* Fixed [#77](https://github.com/akopachov/flipper-zero_authenticator/issues/77)
+* Made CLI console output colorful
+* Few refactoring
+
+
+
+## [v1.6.2](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v1.6.2) - 13 Feb 2023
+
+* Updated submodules to make app compatible with latest firmware
+* Cosmetic code changes
+
+
+
+## [v1.6.1](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v1.6.1) - 07 Feb 2023
+
+* Implemented [#70](https://github.com/akopachov/flipper-zero_authenticator/issues/70) 
+
+
+
+## [v1.6.0](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v1.6.0) - 18 Jan 2023
+
+* Implemented [#65](https://github.com/akopachov/flipper-zero_authenticator/issues/65) 
+
+
+
+## [v1.5.6](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v1.5.6) - 09 Jan 2023
+
+* Updated firmwares
+
+
+
+## [v1.5.5](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v1.5.5) - 04 Jan 2023
+
+* Implemented [#58](https://github.com/akopachov/flipper-zero_authenticator/issues/58) 
+* A bit of refactoring
+
+
+
+## [v1.5.4](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v1.5.4) - 02 Jan 2023
+
+* Fixed [#53](https://github.com/akopachov/flipper-zero_authenticator/issues/53) 
+
+
+
+## [v1.5.3](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v1.5.3) - 30 Dec 2022
+
+* Fixed [#51](https://github.com/akopachov/flipper-zero_authenticator/issues/51) 
+
+
+
+## [v1.5.2](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v1.5.2) - 21 Dec 2022
+
+* Config file moved to "/ext/authenticator/totp.conf"
+* Improved the way how config file is getting handled
+* Improved user notification if on error during config file open\read\update
+
+
+
+## [v1.5.1](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v1.5.1) - 01 Dec 2022
+
+* Implemented [#44](https://github.com/akopachov/flipper-zero_authenticator/issues/44) to be compatible with latest API changes
+
+
+
+## [v1.5.0](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v1.5.0) - 23 Nov 2022
+
+* Implemented [#36](https://github.com/akopachov/flipper-zero_authenticator/issues/36) 
+* Refactoring
+
+
+
+## [v1.4.0](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v1.4.0) - 21 Nov 2022
+
+* Implemented [#10](https://github.com/akopachov/flipper-zero_authenticator/issues/10) 
+* Refactoring
+
+
+
+## [v1.3.1](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v1.3.1) - 18 Nov 2022
+
+* Implemented [#30](https://github.com/akopachov/flipper-zero_authenticator/issues/30) 
+* Cosmetic improvements
+
+
+
+## [v1.3.0](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v1.3.0) - 17 Nov 2022
+
+* Implemented [#26](https://github.com/akopachov/flipper-zero_authenticator/issues/26) 
+* Implemented [#28](https://github.com/akopachov/flipper-zero_authenticator/issues/28) 
+* Improved HID worker code
+* Improved navigation using "long press" event
+* Refactoring
+
+
+
+## [v1.2.1](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v1.2.1) - 10 Nov 2022
+
+* Fixed [#24](https://github.com/akopachov/flipper-zero_authenticator/issues/24)
+* Small improvement to the USB mode restore code
+
+
+
+## [v1.2.0](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v1.2.0) - 10 Nov 2022
+
+* Implemented [#21](https://github.com/akopachov/flipper-zero_authenticator/issues/21) 
+
+
+
+## [v1.1.2](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v1.1.2) - 07 Nov 2022
+
+* Integrated PVS Studio scanner and fixed all its complains
+* Updated firmwares
+* Refactoring
+* Dead code eliminated to fix "COMPACT=1 DEBUG=0" build
+* Build artifacts are done with "COMPACT=1 DEBUG=0" build settings
+
+
+
+## [v1.1.1](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v1.1.1) - 02 Nov 2022
+
+* Latest firmwares
+* Refactoring
+* Sonar scan issues fixed
+
+
+
+## [v1.1.0](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v1.1.0) - 26 Oct 2022
+
+* CLI added (thanks to [@br0ziliy](https://github.com/br0ziliy)). [#11](https://github.com/akopachov/flipper-zero_authenticator/issues/11) 
+* Updated firmware submodules to latest
+* Refactoring
+
+
+
+## [v1.0.1](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v1.0.1) - 21 Oct 2022
+
+* Fixed issue [#8](https://github.com/akopachov/flipper-zero_authenticator/issues/8) 
+* Refactoring
+
+
+
+## [v1.0.0](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v1.0.0) - 17 Oct 2022
+
+* Made PIN optional
+* Submodules updated
+* Refactoring
+* Few fixes
+
+
+
+## [v0.0.6](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v0.0.6) - 13 Oct 2022
+
+* Added timezone configuration UI
+* Removed CLI app POC
+* Minor fixes
+
+
+
+## [v0.0.5](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v0.0.5) - 10 Oct 2022
+
+* Separate builds for Official and Unleashed firmwares
+* Updated code to FuriString
+
+
+
+## [v0.0.4](https://github.com/akopachov/flipper-zero_authenticator/releases/tag/v0.0.4) - 05 Oct 2022
+
+* Moved TOTP app to separate folder to segregate it from flipper_firmware code and make it clearer
+* Code refactoring
+* Added SHA1, SHA256 and SHA512 hashing algos
+* Minor improvements
+
+
+## v0.0.2
+
+Ability to add more than one token
+
+## v0.0.1
+
+First POC. SHA1 hashing algorithm and one token.

+ 11 - 0
.ofwcatalog/DESCRIPTION.md

@@ -0,0 +1,11 @@
+# Flipper Authenticator
+
+## Description
+
+Flipper Authenticator is a software-based authenticator that implements two-step verification services using the Time-based One-time Password (TOTP; specified in [RFC 6238](https://www.rfc-editor.org/rfc/rfc6238)) and HMAC-based One-time Password algorithm.
+
+It is like [Google Authenticator](https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2), but for [Flipper Zero](https://flipperzero.one/) device.
+
+## Have questions?
+
+Checkout [Wiki](https://github.com/akopachov/flipper-zero_authenticator/wiki) or ask in [Discord channel](https://discord.gg/flipper-xtreme)

+ 1 - 1
application.fam

@@ -19,7 +19,7 @@ App(
     fap_author="Alexander Kopachov (@akopachov)",
     fap_description="Software-based TOTP authenticator for Flipper Zero device",
     fap_weburl="https://github.com/akopachov/flipper-zero_authenticator",
-    fap_category="Misc",
+    fap_category="Tools",
     fap_icon_assets="images",
     fap_icon="totp_10px.png",
     fap_private_libs=[

+ 36 - 64
ui/scenes/add_new_token/totp_input_text.c

@@ -1,81 +1,53 @@
 #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/view.h>
+#include <gui/modules/text_input.h>
 
-bool view_input(View* view, InputEvent* event) {
-    furi_assert(view);
-    if(view->input_callback) {
-        return view->input_callback(event, view->context);
-    } else {
-        return false;
-    }
-}
+typedef struct {
+    InputTextResult* result;
+    ViewDispatcher* view_dispatcher;
+} InputTextContext;
 
-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* 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);
 }
 
-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);
-    }
+static bool back_event_callback(void* ctx) {
+    InputTextContext* context = ctx;
+    context->result->success = false;
+    view_dispatcher_stop(context->view_dispatcher);
+    return false;
 }
 
-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);
+
+    view_dispatcher_run(view_dispatcher);
 
-void totp_input_text_free(InputTextSceneState* state) {
-    text_input_free(state->text_input);
-    free(state);
+    view_dispatcher_remove_view(view_dispatcher, 0);
+    view_dispatcher_free(view_dispatcher);
+    text_input_free(text_input);
 }

+ 4 - 27
ui/scenes/add_new_token/totp_input_text.h

@@ -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);

+ 33 - 84
ui/scenes/add_new_token/totp_scene_add_new_token.c

@@ -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_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,13 @@ 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:
@@ -277,22 +240,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 +303,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;
 }

+ 2 - 2
ui/scenes/add_new_token/totp_scene_add_new_token.h

@@ -5,6 +5,6 @@
 #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);

+ 1 - 1
workers/bt_type_code/bt_type_code.c

@@ -1,7 +1,7 @@
 #include "bt_type_code.h"
+#include <furi_hal_bt.h>
 #include <furi_hal_bt_hid.h>
 #include <furi_hal_version.h>
-#include <bt/bt_service/bt_i.h>
 #include <furi/core/thread.h>
 #include <furi/core/mutex.h>
 #include <furi/core/string.h>