Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expiry date #27

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,12 @@ If you want to gift a Boltcard, make sure to [include the following data](https:
- Otherwise read it with the Bolt-Card app (Read NFC) and paste it to the field.
- Advanced Options
- Card Keys (k0, k1, k2) will be automatically generated if not explicitly set.
- Set to 16 bytes of 0s (00000000000000000000000000000000) to leave the keys in default (empty) state (this is unsecure).
- Set to 16 bytes of 0s (00000000000000000000000000000000) to leave the keys in default (empty) state (this is unsecure, merely for debuging).
- GENERATE KEY button fill the keys randomly.
- Expiry date
- You can set an expiry date on a card. After this date LNbits will not longer allow payment with this card.
- You can enable, extend or disable expiry date anytime just by updating the card (without necessity of rewriting it physicaly).
- Without an expiry date, the card is valid indefinitely.
- Click CREATE CARD button
- Click the QR code button next to a card to view its details. Backup the keys now! They'll be comfortable in your password manager.
- Now you can scan the QR code with the Boltcard app (Create Bolt Card -> SCAN QR CODE).
Expand Down
6 changes: 4 additions & 2 deletions crud.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,10 @@ async def create_card(data: CreateCardData, wallet_id: str) -> Card:
k0,
k1,
k2,
otp
otp,
expiry_date
)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
""",
(
card_id,
Expand All @@ -45,6 +46,7 @@ async def create_card(data: CreateCardData, wallet_id: str) -> Card:
data.k1,
data.k2,
secrets.token_hex(16),
data.expiry_date,
),
)
card = await get_card(card_id)
Expand Down
9 changes: 9 additions & 0 deletions lnurl.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import json
import secrets
from datetime import datetime
from http import HTTPStatus
from urllib.parse import urlparse

Expand Down Expand Up @@ -42,6 +43,14 @@ async def api_scan(p, c, request: Request, external_id: str):
return {"status": "ERROR", "reason": "No card."}
if not card.enable:
return {"status": "ERROR", "reason": "Card is disabled."}
if card.expiry_date != "":
today = datetime.today()
try:
expiry_date = datetime.strptime(card.expiry_date, "%Y/%m/%d")
except:
return {"status": "ERROR", "reason": "Invalid expiry date."}
if today > expiry_date:
return {"status": "ERROR", "reason": "Card expired."}
try:
card_uid, counter = decryptSUN(bytes.fromhex(p), bytes.fromhex(card.k1))
if card.uid.upper() != card_uid.hex().upper():
Expand Down
10 changes: 10 additions & 0 deletions migrations.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,13 @@ async def m001_initial(db):
);
"""
)


async def m002_add_expiry(db):
"""
Special column for webhook endpoints that can be assigned
to each different invoice.
"""

await db.execute("ALTER TABLE boltcards.cards ADD COLUMN expiry_date TEXT")
await db.execute("UPDATE boltcards.cards SET expiry_date = ''")
2 changes: 2 additions & 0 deletions models.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class Card(BaseModel):
prev_k2: str
otp: str
time: int
expiry_date: str

@classmethod
def from_row(cls, row: Row) -> "Card":
Expand All @@ -54,6 +55,7 @@ class CreateCardData(BaseModel):
prev_k0: str = Query(ZERO_KEY)
prev_k1: str = Query(ZERO_KEY)
prev_k2: str = Query(ZERO_KEY)
expiry_date: str = Query("")


class Hit(BaseModel):
Expand Down
14 changes: 13 additions & 1 deletion static/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ new Vue({
data: function () {
return {
toggleAdvanced: false,
toggleExpiry: false,
nfcTagReading: false,
lnurlLink: `${window.location.host}/boltcards/api/v1/scan/`,
cards: [],
Expand All @@ -28,7 +29,8 @@ new Vue({
k1: '',
k2: '',
uid: '',
card_name: ''
card_name: '',
expiry_date: ''
},
temp: {}
},
Expand Down Expand Up @@ -331,6 +333,10 @@ new Vue({
createCard: function (wallet, data) {
var self = this

if (!this.toggleExpiry) {
this.cardDialog.data.expiry_date = ''
}

LNbits.api
.request('POST', '/boltcards/api/v1/cards', wallet.adminkey, data)
.then(function (response) {
Expand All @@ -346,6 +352,8 @@ new Vue({
var card = _.findWhere(this.cards, {id: formId})
this.cardDialog.data = _.clone(card)

this.toggleExpiry = !!this.cardDialog.data.expiry_date

this.cardDialog.temp.k0 = this.cardDialog.data.k0
this.cardDialog.temp.k1 = this.cardDialog.data.k1
this.cardDialog.temp.k2 = this.cardDialog.data.k2
Expand All @@ -355,6 +363,10 @@ new Vue({
updateCard: function (wallet, data) {
var self = this

if (!this.toggleExpiry) {
this.cardDialog.data.expiry_date = ''
}

if (
this.cardDialog.temp.k0 != data.k0 ||
this.cardDialog.temp.k1 != data.k1 ||
Expand Down
9 changes: 9 additions & 0 deletions templates/boltcards/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,15 @@ <h6 class="text-subtitle1 q-my-none">
>Generate keys</q-btn
>
</div>

<q-toggle
v-model="toggleExpiry"
label="Set expiry date"
></q-toggle>
<div v-show="toggleExpiry" class="q-gutter-y-md">
<q-date v-model="cardDialog.data.expiry_date" />
</div>

<div class="row q-mt-lg">
<q-btn
v-if="cardDialog.data.id"
Expand Down