mirror of
https://github.com/lnbits/lnbits-legend.git
synced 2025-02-24 14:51:05 +01:00
Added enable disable card
This commit is contained in:
parent
20dbd879b1
commit
977f9bb8c4
7 changed files with 92 additions and 14 deletions
|
@ -19,12 +19,13 @@ async def create_card(data: CreateCardData, wallet_id: str) -> Card:
|
|||
counter,
|
||||
tx_limit,
|
||||
daily_limit,
|
||||
enable,
|
||||
k0,
|
||||
k1,
|
||||
k2,
|
||||
otp
|
||||
)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
""",
|
||||
(
|
||||
card_id,
|
||||
|
@ -34,6 +35,7 @@ async def create_card(data: CreateCardData, wallet_id: str) -> Card:
|
|||
data.counter,
|
||||
data.tx_limit,
|
||||
data.daily_limit,
|
||||
True,
|
||||
data.k0,
|
||||
data.k1,
|
||||
data.k2,
|
||||
|
@ -104,7 +106,17 @@ async def get_card_by_otp(otp: str) -> Optional[Card]:
|
|||
|
||||
|
||||
async def delete_card(card_id: str) -> None:
|
||||
# Delete cards
|
||||
card = await get_card(card_id)
|
||||
await db.execute("DELETE FROM boltcards.cards WHERE id = ?", (card_id,))
|
||||
# Delete hits
|
||||
hits = await get_hits([card_id])
|
||||
for hit in hits:
|
||||
await db.execute("DELETE FROM boltcards.hits WHERE id = ?", (hit.id,))
|
||||
# Delete refunds
|
||||
refunds = await get_refunds([hit])
|
||||
for refund in refunds:
|
||||
await db.execute("DELETE FROM boltcards.refunds WHERE id = ?", (refund.hit_id,))
|
||||
|
||||
|
||||
async def update_card_counter(counter: int, id: str):
|
||||
|
@ -113,6 +125,12 @@ async def update_card_counter(counter: int, id: str):
|
|||
(counter, id),
|
||||
)
|
||||
|
||||
async def enable_disable_card(enable: bool, id: str) -> Optional[Card]:
|
||||
row = await db.execute(
|
||||
"UPDATE boltcards.cards SET enable = ? WHERE id = ?",
|
||||
(enable, id),
|
||||
)
|
||||
return await get_card(id)
|
||||
|
||||
async def update_card_otp(otp: str, id: str):
|
||||
await db.execute(
|
||||
|
|
|
@ -57,6 +57,8 @@ async def api_scan(p, c, request: Request, card_id: str = None):
|
|||
|
||||
try:
|
||||
card = await get_card_by_uid(card_uid)
|
||||
if not card.enable:
|
||||
return {"status": "ERROR", "reason": "Card is disabled."}
|
||||
card_uid, counter = decryptSUN(bytes.fromhex(p), bytes.fromhex(card.k1))
|
||||
if card.uid.upper() != card_uid.hex().upper():
|
||||
return {"status": "ERROR", "reason": "Card UID mis-match."}
|
||||
|
@ -173,6 +175,8 @@ async def lnurlp_response(req: Request, hit_id: str = Query(None)):
|
|||
card = await get_card(hit.card_id)
|
||||
if not hit:
|
||||
return {"status": "ERROR", "reason": f"LNURL-pay record not found."}
|
||||
if not card.enable:
|
||||
return {"status": "ERROR", "reason": "Card is disabled."}
|
||||
payResponse = {
|
||||
"tag": "payRequest",
|
||||
"callback": req.url_for("boltcards.lnurlp_callback", hit_id=hit_id),
|
||||
|
|
|
@ -12,6 +12,7 @@ async def m001_initial(db):
|
|||
counter INT NOT NULL DEFAULT 0,
|
||||
tx_limit TEXT NOT NULL,
|
||||
daily_limit TEXT NOT NULL,
|
||||
enable BOOL NOT NULL,
|
||||
k0 TEXT NOT NULL DEFAULT '00000000000000000000000000000000',
|
||||
k1 TEXT NOT NULL DEFAULT '00000000000000000000000000000000',
|
||||
k2 TEXT NOT NULL DEFAULT '00000000000000000000000000000000',
|
||||
|
|
|
@ -22,6 +22,7 @@ class Card(BaseModel):
|
|||
counter: int
|
||||
tx_limit: int
|
||||
daily_limit: int
|
||||
enable: bool
|
||||
k0: str
|
||||
k1: str
|
||||
k2: str
|
||||
|
@ -49,6 +50,7 @@ class CreateCardData(BaseModel):
|
|||
counter: int = Query(0)
|
||||
tx_limit: int = Query(0)
|
||||
daily_limit: int = Query(0)
|
||||
enable: bool = Query(...)
|
||||
k0: str = Query(ZERO_KEY)
|
||||
k1: str = Query(ZERO_KEY)
|
||||
k2: str = Query(ZERO_KEY)
|
||||
|
|
|
@ -16,6 +16,7 @@ new Vue({
|
|||
data: function () {
|
||||
return {
|
||||
toggleAdvanced: false,
|
||||
nfcTagReading: false,
|
||||
cards: [],
|
||||
hits: [],
|
||||
refunds: [],
|
||||
|
@ -194,6 +195,7 @@ new Vue({
|
|||
this.generateKeys()
|
||||
},
|
||||
generateKeys: function () {
|
||||
var self = this
|
||||
const genRanHex = size =>
|
||||
[...Array(size)]
|
||||
.map(() => Math.floor(Math.random() * 16).toString(16))
|
||||
|
@ -203,20 +205,17 @@ new Vue({
|
|||
typeof this.cardDialog.data.card_name === 'string' &&
|
||||
this.cardDialog.data.card_name.search('debug') > -1
|
||||
|
||||
this.cardDialog.data.k0 = debugcard
|
||||
self.cardDialog.data.k0 = debugcard
|
||||
? '11111111111111111111111111111111'
|
||||
: genRanHex(32)
|
||||
this.$refs['k0'].value = this.cardDialog.data.k0
|
||||
|
||||
this.cardDialog.data.k1 = debugcard
|
||||
self.cardDialog.data.k1 = debugcard
|
||||
? '22222222222222222222222222222222'
|
||||
: genRanHex(32)
|
||||
this.$refs['k1'].value = this.cardDialog.data.k1
|
||||
|
||||
this.cardDialog.data.k2 = debugcard
|
||||
self.cardDialog.data.k2 = debugcard
|
||||
? '33333333333333333333333333333333'
|
||||
: genRanHex(32)
|
||||
this.$refs['k2'].value = this.cardDialog.data.k2
|
||||
},
|
||||
closeFormDialog: function () {
|
||||
this.cardDialog.data = {}
|
||||
|
@ -288,6 +287,28 @@ new Vue({
|
|||
LNbits.utils.notifyApiError(error)
|
||||
})
|
||||
},
|
||||
enableCard: function (wallet, card_id, enable) {
|
||||
var self = this
|
||||
let fullWallet = _.findWhere(self.g.user.wallets, {
|
||||
id: wallet
|
||||
})
|
||||
LNbits.api
|
||||
.request(
|
||||
'GET',
|
||||
'/boltcards/api/v1/cards/enable/' + card_id + '/' + enable,
|
||||
fullWallet.adminkey
|
||||
)
|
||||
.then(function (response) {
|
||||
console.log(response.data)
|
||||
self.cards = _.reject(self.cards, function (obj) {
|
||||
return obj.id == response.data.id
|
||||
})
|
||||
self.cards.push(mapCards(response.data))
|
||||
})
|
||||
.catch(function (error) {
|
||||
LNbits.utils.notifyApiError(error)
|
||||
})
|
||||
},
|
||||
deleteCard: function (cardId) {
|
||||
let self = this
|
||||
let cards = _.findWhere(this.cards, {id: cardId})
|
||||
|
|
|
@ -65,6 +65,20 @@
|
|||
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||
{{ col.value }}
|
||||
</q-td>
|
||||
<q-td auto-width>
|
||||
<q-btn
|
||||
v-if="props.row.enable"
|
||||
dense
|
||||
@click="enableCard(props.row.wallet, props.row.id, false)"
|
||||
color="pink"
|
||||
>DISABLE</q-btn>
|
||||
<q-btn
|
||||
v-else
|
||||
dense
|
||||
@click="enableCard(props.row.wallet, props.row.id, true)"
|
||||
color="green"
|
||||
>ENABLE</q-btn>
|
||||
</q-td>
|
||||
<q-td auto-width>
|
||||
<q-btn
|
||||
flat
|
||||
|
@ -73,8 +87,7 @@
|
|||
@click="updateCardDialog(props.row.id)"
|
||||
icon="edit"
|
||||
color="light-blue"
|
||||
>
|
||||
</q-btn>
|
||||
><q-tooltip>Edit card</q-tooltip></q-btn>
|
||||
</q-td>
|
||||
<q-td auto-width>
|
||||
<q-btn
|
||||
|
@ -84,7 +97,7 @@
|
|||
@click="deleteCard(props.row.id)"
|
||||
icon="cancel"
|
||||
color="pink"
|
||||
></q-btn>
|
||||
><q-tooltip>Deleting card will also delete all records</q-tooltip></q-btn>
|
||||
</q-td>
|
||||
</q-tr>
|
||||
</template>
|
||||
|
@ -255,7 +268,6 @@
|
|||
|
||||
|
||||
<q-toggle
|
||||
@click="toggleKeys"
|
||||
v-model="toggleAdvanced"
|
||||
label="Show advanced options"
|
||||
></q-toggle>
|
||||
|
@ -263,7 +275,7 @@
|
|||
<q-input
|
||||
filled
|
||||
dense
|
||||
ref="k0"
|
||||
|
||||
v-model.trim="cardDialog.data.k0"
|
||||
type="text"
|
||||
label="Card Auth key (K0)"
|
||||
|
@ -274,7 +286,7 @@
|
|||
<q-input
|
||||
filled
|
||||
dense
|
||||
ref="k1"
|
||||
|
||||
v-model.trim="cardDialog.data.k1"
|
||||
type="text"
|
||||
label="Card Meta key (K1)"
|
||||
|
@ -283,7 +295,7 @@
|
|||
<q-input
|
||||
filled
|
||||
dense
|
||||
ref="k2"
|
||||
|
||||
v-model.trim="cardDialog.data.k2"
|
||||
type="text"
|
||||
label="Card File key (K2)"
|
||||
|
|
|
@ -21,6 +21,7 @@ from .crud import (
|
|||
update_card,
|
||||
update_card_counter,
|
||||
update_card_otp,
|
||||
enable_disable_card,
|
||||
get_refunds,
|
||||
)
|
||||
from .models import CreateCardData
|
||||
|
@ -89,6 +90,25 @@ async def api_card_create_or_update(
|
|||
card = await create_card(wallet_id=wallet.wallet.id, data=data)
|
||||
return card.dict()
|
||||
|
||||
@boltcards_ext.get("/api/v1/cards/enable/{card_id}/{enable}", status_code=HTTPStatus.OK)
|
||||
async def enable_card(
|
||||
card_id,
|
||||
enable,
|
||||
wallet: WalletTypeInfo = Depends(require_admin_key),
|
||||
):
|
||||
card = await get_card(card_id)
|
||||
if not card:
|
||||
raise HTTPException(
|
||||
detail="No card found.", status_code=HTTPStatus.NOT_FOUND
|
||||
)
|
||||
if card.wallet != wallet.wallet.id:
|
||||
raise HTTPException(
|
||||
detail="Not your card.", status_code=HTTPStatus.FORBIDDEN
|
||||
)
|
||||
card = await enable_disable_card(enable=enable, id=card_id)
|
||||
logger.debug(enable)
|
||||
logger.debug(card)
|
||||
return card.dict()
|
||||
|
||||
@boltcards_ext.delete("/api/v1/cards/{card_id}")
|
||||
async def api_card_delete(card_id, wallet: WalletTypeInfo = Depends(require_admin_key)):
|
||||
|
|
Loading…
Add table
Reference in a new issue