Reset wallet keys (#2929)
This commit is contained in:
parent
34a959f0bc
commit
432b3a0fe0
7 changed files with 94 additions and 27 deletions
|
|
@ -233,4 +233,14 @@
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-expansion-item>
|
</q-expansion-item>
|
||||||
|
<q-separator></q-separator>
|
||||||
|
<q-card-section>
|
||||||
|
<p v-text="$t('reset_wallet_keys_desc')"></p>
|
||||||
|
<q-btn
|
||||||
|
unelevated
|
||||||
|
color="red-10"
|
||||||
|
@click="resetKeys()"
|
||||||
|
:label="$t('reset_wallet_keys')"
|
||||||
|
></q-btn>
|
||||||
|
</q-card-section>
|
||||||
</q-expansion-item>
|
</q-expansion-item>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
from http import HTTPStatus
|
from http import HTTPStatus
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
from uuid import uuid4
|
||||||
|
|
||||||
from fastapi import (
|
from fastapi import (
|
||||||
APIRouter,
|
APIRouter,
|
||||||
|
|
@ -8,13 +9,10 @@ from fastapi import (
|
||||||
HTTPException,
|
HTTPException,
|
||||||
)
|
)
|
||||||
|
|
||||||
from lnbits.core.models import (
|
from lnbits.core.models import CreateWallet, KeyType, User, Wallet
|
||||||
CreateWallet,
|
|
||||||
KeyType,
|
|
||||||
Wallet,
|
|
||||||
)
|
|
||||||
from lnbits.decorators import (
|
from lnbits.decorators import (
|
||||||
WalletTypeInfo,
|
WalletTypeInfo,
|
||||||
|
check_user_exists,
|
||||||
require_admin_key,
|
require_admin_key,
|
||||||
require_invoice_key,
|
require_invoice_key,
|
||||||
)
|
)
|
||||||
|
|
@ -56,6 +54,20 @@ async def api_update_wallet_name(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@wallet_router.put("/reset/{wallet_id}")
|
||||||
|
async def api_reset_wallet_keys(
|
||||||
|
wallet_id: str, user: User = Depends(check_user_exists)
|
||||||
|
) -> Wallet:
|
||||||
|
wallet = await get_wallet(wallet_id)
|
||||||
|
if not wallet or wallet.user != user.id:
|
||||||
|
raise HTTPException(status_code=HTTPStatus.NOT_FOUND, detail="Wallet not found")
|
||||||
|
|
||||||
|
wallet.adminkey = uuid4().hex
|
||||||
|
wallet.inkey = uuid4().hex
|
||||||
|
await update_wallet(wallet)
|
||||||
|
return wallet
|
||||||
|
|
||||||
|
|
||||||
@wallet_router.patch("")
|
@wallet_router.patch("")
|
||||||
async def api_update_wallet(
|
async def api_update_wallet(
|
||||||
name: Optional[str] = Body(None),
|
name: Optional[str] = Body(None),
|
||||||
|
|
@ -75,13 +87,17 @@ async def api_update_wallet(
|
||||||
return wallet
|
return wallet
|
||||||
|
|
||||||
|
|
||||||
@wallet_router.delete("")
|
@wallet_router.delete("/{wallet_id}")
|
||||||
async def api_delete_wallet(
|
async def api_delete_wallet(
|
||||||
wallet: WalletTypeInfo = Depends(require_admin_key),
|
wallet_id: str, user: User = Depends(check_user_exists)
|
||||||
) -> None:
|
) -> None:
|
||||||
|
wallet = await get_wallet(wallet_id)
|
||||||
|
if not wallet or wallet.user != user.id:
|
||||||
|
raise HTTPException(status_code=HTTPStatus.NOT_FOUND, detail="Wallet not found")
|
||||||
|
|
||||||
await delete_wallet(
|
await delete_wallet(
|
||||||
user_id=wallet.wallet.user,
|
user_id=wallet.user,
|
||||||
wallet_id=wallet.wallet.id,
|
wallet_id=wallet.id,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
2
lnbits/static/bundle.min.js
vendored
2
lnbits/static/bundle.min.js
vendored
File diff suppressed because one or more lines are too long
|
|
@ -505,5 +505,8 @@ window.localisation.en = {
|
||||||
payments_balance_chart: 'Balance Chart',
|
payments_balance_chart: 'Balance Chart',
|
||||||
payments_wallets_chart: 'Wallets Chart',
|
payments_wallets_chart: 'Wallets Chart',
|
||||||
payments_balance_in_out_chart: 'Balance In/Out Chart',
|
payments_balance_in_out_chart: 'Balance In/Out Chart',
|
||||||
payments_count_in_out_chart: 'Count In/Out Chart'
|
payments_count_in_out_chart: 'Count In/Out Chart',
|
||||||
|
reset_wallet_keys: 'Reset Keys',
|
||||||
|
reset_wallet_keys_desc:
|
||||||
|
'Reset the API keys for this wallet. This will invalidate the current keys and generate new ones.'
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -132,15 +132,20 @@ window.LNbits = {
|
||||||
name: name
|
name: name
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
deleteWallet(wallet) {
|
resetWalletKeys(wallet) {
|
||||||
return this.request('delete', '/api/v1/wallet', wallet.adminkey).then(
|
return this.request('put', `/api/v1/wallet/reset/${wallet.id}`).then(
|
||||||
_ => {
|
res => {
|
||||||
let url = new URL(window.location.href)
|
return res.data
|
||||||
url.searchParams.delete('wal')
|
|
||||||
window.location = url
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
deleteWallet(wallet) {
|
||||||
|
return this.request('delete', `/api/v1/wallet/${wallet.id}`).then(_ => {
|
||||||
|
let url = new URL(window.location.href)
|
||||||
|
url.searchParams.delete('wal')
|
||||||
|
window.location = url
|
||||||
|
})
|
||||||
|
},
|
||||||
getPayments(wallet, params) {
|
getPayments(wallet, params) {
|
||||||
return this.request(
|
return this.request(
|
||||||
'get',
|
'get',
|
||||||
|
|
|
||||||
|
|
@ -564,6 +564,40 @@ window.WalletPageLogic = {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
resetKeys() {
|
||||||
|
LNbits.utils
|
||||||
|
.confirmDialog('Are you sure you want to reset your API keys?')
|
||||||
|
.onOk(() => {
|
||||||
|
LNbits.api
|
||||||
|
.resetWalletKeys(this.g.wallet)
|
||||||
|
.then(response => {
|
||||||
|
const {id, adminkey, inkey} = response
|
||||||
|
this.g.wallet = {
|
||||||
|
...this.g.wallet,
|
||||||
|
inkey,
|
||||||
|
adminkey
|
||||||
|
}
|
||||||
|
const walletIndex = this.g.user.wallets.findIndex(
|
||||||
|
wallet => wallet.id === id
|
||||||
|
)
|
||||||
|
if (walletIndex !== -1) {
|
||||||
|
this.g.user.wallets[walletIndex] = {
|
||||||
|
...this.g.user.wallets[walletIndex],
|
||||||
|
inkey,
|
||||||
|
adminkey
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Quasar.Notify.create({
|
||||||
|
timeout: 3500,
|
||||||
|
type: 'positive',
|
||||||
|
message: 'API keys reset!'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
LNbits.utils.notifyApiError(err)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
updateWallet(data) {
|
updateWallet(data) {
|
||||||
LNbits.api
|
LNbits.api
|
||||||
.request('PATCH', '/api/v1/wallet', this.g.wallet.adminkey, data)
|
.request('PATCH', '/api/v1/wallet', this.g.wallet.adminkey, data)
|
||||||
|
|
|
||||||
|
|
@ -35,12 +35,14 @@ async def test_create_account(client, settings: Settings):
|
||||||
assert "user" in result
|
assert "user" in result
|
||||||
|
|
||||||
|
|
||||||
# check POST and DELETE /api/v1/wallet with adminkey:
|
# check POST and DELETE /api/v1/wallet with adminkey and user token:
|
||||||
# create additional wallet and delete it
|
# create additional wallet and delete it
|
||||||
@pytest.mark.anyio
|
@pytest.mark.anyio
|
||||||
async def test_create_wallet_and_delete(client, adminkey_headers_to):
|
async def test_create_wallet_and_delete(
|
||||||
|
client, adminkey_headers_from, user_headers_from
|
||||||
|
):
|
||||||
response = await client.post(
|
response = await client.post(
|
||||||
"/api/v1/wallet", json={"name": "test"}, headers=adminkey_headers_to
|
"/api/v1/wallet", json={"name": "test"}, headers=adminkey_headers_from
|
||||||
)
|
)
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
result = response.json()
|
result = response.json()
|
||||||
|
|
@ -51,20 +53,17 @@ async def test_create_wallet_and_delete(client, adminkey_headers_to):
|
||||||
assert "adminkey" in result
|
assert "adminkey" in result
|
||||||
|
|
||||||
invalid_response = await client.delete(
|
invalid_response = await client.delete(
|
||||||
"/api/v1/wallet",
|
f"/api/v1/wallet/{result['id']}",
|
||||||
headers={
|
headers={
|
||||||
"X-Api-Key": result["inkey"],
|
"X-Api-Key": result["adminkey"],
|
||||||
"Content-type": "application/json",
|
"Content-type": "application/json",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
assert invalid_response.status_code == 401
|
assert invalid_response.status_code == 401
|
||||||
|
|
||||||
response = await client.delete(
|
response = await client.delete(
|
||||||
"/api/v1/wallet",
|
f"/api/v1/wallet/{result['id']}",
|
||||||
headers={
|
headers=user_headers_from,
|
||||||
"X-Api-Key": result["adminkey"],
|
|
||||||
"Content-type": "application/json",
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue