diff --git a/lnbits/core/models/misc.py b/lnbits/core/models/misc.py index 5aad3fdc9..029b19510 100644 --- a/lnbits/core/models/misc.py +++ b/lnbits/core/models/misc.py @@ -41,6 +41,7 @@ class SimpleStatus(BaseModel): class SimpleItem(BaseModel): id: str name: str + expires_at: int | None = None class DbVersion(BaseModel): diff --git a/lnbits/core/views/auth_api.py b/lnbits/core/views/auth_api.py index 71a792a93..5d5c08d4f 100644 --- a/lnbits/core/views/auth_api.py +++ b/lnbits/core/views/auth_api.py @@ -295,7 +295,10 @@ async def api_create_user_api_token( account.username, api_token_id, data.expiration_time_minutes ) - acl.token_id_list.append(SimpleItem(id=api_token_id, name=data.token_name)) + expires_at = int(time()) + data.expiration_time_minutes * 60 + acl.token_id_list.append( + SimpleItem(id=api_token_id, name=data.token_name, expires_at=expires_at) + ) await update_user_access_control_list(acls) return ApiTokenResponse(id=api_token_id, api_token=api_token) diff --git a/lnbits/static/js/pages/account.js b/lnbits/static/js/pages/account.js index 28dbc38fc..4f2a7515e 100644 --- a/lnbits/static/js/pages/account.js +++ b/lnbits/static/js/pages/account.js @@ -217,6 +217,11 @@ window.PageAccount = { computed: { isUserTouched() { return !_.isEqual(this.g.user, this.untouchedUser) + }, + selectedApiToken() { + return this.selectedApiAcl.token_id_list.find( + token => token.id === this.apiAcl.selectedTokenId + ) } }, methods: { diff --git a/lnbits/templates/pages/account.vue b/lnbits/templates/pages/account.vue index 2373062b3..ac1a5f2e2 100644 --- a/lnbits/templates/pages/account.vue +++ b/lnbits/templates/pages/account.vue @@ -889,6 +889,39 @@ > +
+ + + + +
diff --git a/tests/api/test_auth.py b/tests/api/test_auth.py index aea787cff..82361e6d9 100644 --- a/tests/api/test_auth.py +++ b/tests/api/test_auth.py @@ -1745,10 +1745,14 @@ async def test_api_create_user_api_token_success( ), "Expiration time should be 60 minutes from now." token_id = payload["api_token_id"] - assert any( - token_id in [token.id for token in acl.token_id_list] + stored_token = next( + token for acl in acls.access_control_list - ), "API token should be part of at least one ACL." + for token in acl.token_id_list + if token.id == token_id + ) + assert stored_token.expires_at is not None + assert abs(stored_token.expires_at - expiration_time) <= 1 @pytest.mark.anyio