diff --git a/db/db.go b/db/db.go index cd6e43a..fb5e8ca 100644 --- a/db/db.go +++ b/db/db.go @@ -172,6 +172,7 @@ func Get_card_count_for_name_lnurlp(name string) (int, error) { return card_count, nil } +// gets the last record func Get_card_id_for_name(name string) (int, error) { card_id := 0 @@ -182,7 +183,7 @@ func Get_card_id_for_name(name string) (int, error) { } defer db.Close() - sqlStatement := `select card_id from cards where card_name=$1;` + sqlStatement := `select card_id from cards where card_name=$1 order by card_id desc limit 1;` row := db.QueryRow(sqlStatement, name) err = row.Scan(&card_id) @@ -247,7 +248,7 @@ func Get_cards_blank_uid() ([]Card, error) { // query the database - sqlStatement := `select card_id, k2_cmac_key from cards where uid='' and last_counter_value=0;` + sqlStatement := `select card_id, k2_cmac_key from cards where uid='' and last_counter_value=0 and wiped='N';` rows, err := db.Query(sqlStatement) @@ -371,6 +372,7 @@ func Get_card_from_card_id(card_id int) (*Card, error) { return &c, nil } +// non wiped cards only func Get_card_from_card_name(card_name string) (*Card, error) { c := Card{} @@ -384,7 +386,7 @@ func Get_card_from_card_name(card_name string) (*Card, error) { sqlStatement := `SELECT card_id, k2_cmac_key, uid,` + ` last_counter_value, lnurlw_request_timeout_sec,` + ` lnurlw_enable, tx_limit_sats, day_limit_sats` + - ` FROM cards WHERE card_name=$1;` + ` FROM cards WHERE card_name=$1 AND wiped = 'N';` row := db.QueryRow(sqlStatement, card_name) err = row.Scan( &c.Card_id, @@ -794,14 +796,24 @@ func Insert_card(one_time_code string, k0_auth_key string, k2_cmac_key string, k } defer db.Close() + // ensure any cards with the same card_name are wiped + + sqlStatement := `UPDATE cards SET` + + ` lnurlw_enable = 'N', lnurlp_enable = 'N', email_enable = 'N', wiped = 'Y'` + + ` WHERE card_name = $1;` + res, err := db.Exec(sqlStatement, card_name) + if err != nil { + return err + } + // insert a new record into cards - sqlStatement := `INSERT INTO cards` + + sqlStatement = `INSERT INTO cards` + ` (one_time_code, k0_auth_key, k2_cmac_key, k3, k4, uid, last_counter_value,` + ` lnurlw_request_timeout_sec, tx_limit_sats, day_limit_sats, lnurlw_enable,` + ` one_time_code_used, card_name, uid_privacy, allow_negative_balance)` + ` VALUES ($1, $2, $3, $4, $5, '', 0, 60, $6, $7, $8, 'N', $9, $10, $11);` - res, err := db.Exec(sqlStatement, one_time_code, k0_auth_key, k2_cmac_key, k3, k4, + res, err = db.Exec(sqlStatement, one_time_code, k0_auth_key, k2_cmac_key, k3, k4, tx_limit_sats, day_limit_sats, lnurlw_enable_yn, card_name, uid_privacy_yn, allow_neg_bal_yn) if err != nil { @@ -833,22 +845,15 @@ func Wipe_card(card_name string) (*Card_wipe_info, error) { sqlStatement := `UPDATE cards SET` + ` lnurlw_enable = 'N', lnurlp_enable = 'N', email_enable = 'N', wiped = 'Y'` + ` WHERE card_name = $1;` - res, err := db.Exec(sqlStatement, card_name) + _, err = db.Exec(sqlStatement, card_name) if err != nil { return &card_wipe_info, err } - count, err := res.RowsAffected() - if err != nil { - return &card_wipe_info, err - } - if count != 1 { - return &card_wipe_info, errors.New("not one card record updated") - } - // get card keys + // get card keys for the last card wiped sqlStatement = `SELECT card_id, uid, k0_auth_key, k2_cmac_key, k3, k4` + - ` FROM cards WHERE card_name = $1;` + ` FROM cards WHERE card_name = $1 ORDER BY card_id DESC LIMIT 1;` row := db.QueryRow(sqlStatement, card_name) err = row.Scan( &card_wipe_info.Id, @@ -882,7 +887,7 @@ func Update_card(card_name string, lnurlw_enable bool, tx_limit_sats int, day_li defer db.Close() sqlStatement := `UPDATE cards SET lnurlw_enable = $2, tx_limit_sats = $3, day_limit_sats = $4 ` + - `WHERE card_name = $1;` + `WHERE card_name = $1 AND wiped = 'N';` res, err := db.Exec(sqlStatement, card_name, lnurlw_enable_yn, tx_limit_sats, day_limit_sats) diff --git a/internalapi/createboltcard.go b/internalapi/createboltcard.go index cee8db2..ec4834a 100644 --- a/internalapi/createboltcard.go +++ b/internalapi/createboltcard.go @@ -58,6 +58,12 @@ func Createboltcard(w http.ResponseWriter, r *http.Request) { } card_name := r.URL.Query().Get("card_name") + if card_name == "" { + msg := "createboltcard: the card name must be set" + log.Warn(msg) + resp_err.Write_message(w, msg) + return + } uid_privacy_flag_str := r.URL.Query().Get("uid_privacy") uid_privacy_flag, err := strconv.ParseBool(uid_privacy_flag_str) @@ -77,21 +83,6 @@ func Createboltcard(w http.ResponseWriter, r *http.Request) { return } - // check if card_name already exists - - card_count, err := db.Get_card_name_count(card_name) - if err != nil { - log.Warn(err.Error()) - return - } - - if card_count > 0 { - msg := "createboltcard: the card name already exists in the database" - log.Warn(msg) - resp_err.Write_message(w, msg) - return - } - // log the request log.WithFields(log.Fields{ diff --git a/internalapi/getboltcard.go b/internalapi/getboltcard.go index b0d16e9..aef2847 100644 --- a/internalapi/getboltcard.go +++ b/internalapi/getboltcard.go @@ -18,21 +18,6 @@ func Getboltcard(w http.ResponseWriter, r *http.Request) { } card_name := r.URL.Query().Get("card_name") - // check if card_name exists - - card_count, err := db.Get_card_name_count(card_name) - if err != nil { - log.Warn(err.Error()) - return - } - - if card_count == 0 { - msg := "getboltcard: the card name does not exist in the database" - log.Warn(msg) - resp_err.Write_message(w, msg) - return - } - // log the request log.WithFields(log.Fields{ @@ -42,7 +27,7 @@ func Getboltcard(w http.ResponseWriter, r *http.Request) { c, err := db.Get_card_from_card_name(card_name) if err != nil { - msg := "getboltcard: the card name does not exist in the database" + msg := "getboltcard: a non-wiped card with the card_name does not exist in the database" log.Warn(msg) resp_err.Write_message(w, msg) return diff --git a/internalapi/wipeboltcard.go b/internalapi/wipeboltcard.go index 2166f85..a2d37f3 100644 --- a/internalapi/wipeboltcard.go +++ b/internalapi/wipeboltcard.go @@ -32,7 +32,7 @@ func Wipeboltcard(w http.ResponseWriter, r *http.Request) { card_count, err := db.Get_card_name_count(card_name) if card_count == 0 { - msg := "the card name does not exist in the database" + msg := "wipeboltcard: the card name does not exist in the database" log.Warn(msg) resp_err.Write_message(w, msg) return diff --git a/lnurlw/lnurlw_request.go b/lnurlw/lnurlw_request.go index c3a25e2..fe1a93d 100644 --- a/lnurlw/lnurlw_request.go +++ b/lnurlw/lnurlw_request.go @@ -85,13 +85,18 @@ func setup_card_record(uid string, ctr uint32, uid_bin []byte, ctr_bin []byte, c // check card records for a matching cmac - for i, card := range cards { + for _, card := range cards { + // check the cmac k2_cmac_key, err := hex.DecodeString(card.K2_cmac_key) if err != nil { - return errors.New("card.k2_cmac_key decode failed") + log.WithFields(log.Fields{ + "card.card_id": card.Card_id, + "card.k2_cmac_key": card.K2_cmac_key, + }).Warn("card.k2_cmac_key decode failed - remove the invalid record") + return err } cmac_valid, err := check_cmac(uid_bin, ctr_bin, k2_cmac_key, cmac) @@ -102,7 +107,6 @@ func setup_card_record(uid string, ctr uint32, uid_bin []byte, ctr_bin []byte, c if cmac_valid == true { log.WithFields(log.Fields{ - "i": i, "card.card_id": card.Card_id, "card.k2_cmac_key": card.K2_cmac_key, }).Info("cmac match found") @@ -189,6 +193,7 @@ func parse_request(req *http.Request) (int, error) { } if card_count == 0 { + log.Info("check CMACs and set UID") setup_card_record(uid_str, ctr_int, uid, ctr, ba_c) } diff --git a/sql/create_db.sql b/sql/create_db.sql index f50285b..03c80f7 100644 --- a/sql/create_db.sql +++ b/sql/create_db.sql @@ -20,7 +20,7 @@ CREATE TABLE cards ( tx_limit_sats INT NOT NULL, day_limit_sats INT NOT NULL, lnurlp_enable CHAR(1) NOT NULL DEFAULT 'N', - card_name VARCHAR(100) UNIQUE NOT NULL DEFAULT '', + card_name VARCHAR(100) NOT NULL, email_address VARCHAR(100) DEFAULT '', email_enable CHAR(1) NOT NULL DEFAULT 'N', uid_privacy CHAR(1) NOT NULL DEFAULT 'N',