diff --git a/net/server/internal/api_contact.go b/net/server/internal/api_contact.go index 270359e4..f935a8f4 100644 --- a/net/server/internal/api_contact.go +++ b/net/server/internal/api_contact.go @@ -23,16 +23,6 @@ func ClearCardNotes(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) } -func GetCardProfileImage(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json; charset=UTF-8") - w.WriteHeader(http.StatusOK) -} - -func GetCards(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json; charset=UTF-8") - w.WriteHeader(http.StatusOK) -} - func GetCloseMessage(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.WriteHeader(http.StatusOK) diff --git a/net/server/internal/api_getCardImage.go b/net/server/internal/api_getCardImage.go new file mode 100644 index 00000000..cfcd56d9 --- /dev/null +++ b/net/server/internal/api_getCardImage.go @@ -0,0 +1,48 @@ +package databag + +import ( + "errors" + "net/http" + "gorm.io/gorm" + "encoding/base64" + "github.com/gorilla/mux" + "databag/internal/store" +) + +func GetCardProfileImage(w http.ResponseWriter, r *http.Request) { + var data []byte + + account, code, err := BearerAppToken(r, false); + if err != nil { + ErrResponse(w, code, err) + return + } + cardId := mux.Vars(r)["cardId"] + + var slot store.CardSlot + if err := store.DB.Preload("Card.Groups").Where("account_id = ? AND card_slot_id = ?", account.ID, cardId).First(&slot).Error; err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + ErrResponse(w, http.StatusNotFound, err) + } else { + ErrResponse(w, http.StatusInternalServerError, err) + } + return + } + if slot.Card == nil { + ErrResponse(w, http.StatusNotFound, errors.New("referenced missing card")) + return + } + if slot.Card.Image == "" { + ErrResponse(w, http.StatusNotFound, errors.New("card image not set")) + return + } + data, err = base64.StdEncoding.DecodeString(slot.Card.Image) + if err != nil { + ErrResponse(w, http.StatusNotFound, errors.New("invalid card image")) + return + } + + w.Header().Set("Content-Type", http.DetectContentType(data)) + w.Write(data); +} + diff --git a/net/server/internal/api_getCards.go b/net/server/internal/api_getCards.go new file mode 100644 index 00000000..51e237ef --- /dev/null +++ b/net/server/internal/api_getCards.go @@ -0,0 +1,51 @@ +package databag + +import ( + "strconv" + "net/http" + "databag/internal/store" +) + +func GetCards(w http.ResponseWriter, r *http.Request) { + var cardRevisionSet bool + var cardRevision int64 + + account, code, err := BearerAppToken(r, false); + if err != nil { + ErrResponse(w, code, err) + return + } + + card := r.FormValue("cardRevision") + if card != "" { + cardRevisionSet = true + if cardRevision, err = strconv.ParseInt(card, 10, 64); err != nil { + ErrResponse(w, http.StatusBadRequest, err) + return + } + } + + var response []*Card + if cardRevisionSet { + var slots []store.CardSlot + if err := store.DB.Where("account_id = ? AND revision > ?", account.ID, cardRevision).Find(&slots).Error; err != nil { + ErrResponse(w, http.StatusInternalServerError, err) + return + } + for _, slot := range slots { + response = append(response, getCardRevisionModel(&slot)) + } + } else { + var slots []store.CardSlot + if err := store.DB.Preload("Card.Groups.GroupSlot").Where("account_id = ? AND card_id != 0", account.ID).Find(&slots).Error; err != nil { + ErrResponse(w, http.StatusInternalServerError, err) + return + } + for _, slot := range slots { + response = append(response, getCardModel(&slot)) + } + } + + w.Header().Set("Card-Revision", strconv.FormatInt(account.CardRevision, 10)) + WriteResponse(w, response) +} diff --git a/net/server/internal/api_setCardProfile.go b/net/server/internal/api_setCardProfile.go index 768c65d9..e2a21fa3 100644 --- a/net/server/internal/api_setCardProfile.go +++ b/net/server/internal/api_setCardProfile.go @@ -33,7 +33,6 @@ func SetCardProfile(w http.ResponseWriter, r *http.Request) { return } -PrintMsg(cardId) slot := store.CardSlot{} if err := store.DB.Preload("Card.Groups").Where("account_id = ? AND card_slot_id = ?", account.ID, cardId).First(&slot).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { diff --git a/net/server/internal/ucContactSync_test.go b/net/server/internal/ucContactSync_test.go index ddfba5c6..e628ced7 100644 --- a/net/server/internal/ucContactSync_test.go +++ b/net/server/internal/ucContactSync_test.go @@ -1,7 +1,9 @@ package databag import ( + "bytes" "testing" + "encoding/base64" "github.com/stretchr/testify/assert" ) @@ -10,6 +12,11 @@ func TestContactSync(t *testing.T) { var msg DataMessage var card Card param := map[string]string{} + var img []byte + var data []byte + var hdr map[string][]string + var res error + var cards []Card // setup testing group set, err := AddTestGroup("contactsync") @@ -18,16 +25,31 @@ func TestContactSync(t *testing.T) { // set profile image image := "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" assert.NoError(t, ApiTestMsg(SetProfileImage, "PUT", "/profile/image", - nil, image, - APP_TOKENAPP, set.A.Token, &profile, nil)) + nil, image, APP_TOKENAPP, set.A.Token, &profile, nil)) // sync profile assert.NoError(t, ApiTestMsg(GetProfileMessage, "GET", "/profile/message", - nil, nil, - APP_TOKENCONTACT, set.B.A.Token, &msg, nil)) + nil, nil, APP_TOKENCONTACT, set.B.A.Token, &msg, nil)) param["cardId"] = set.B.A.CardId assert.NoError(t, ApiTestMsg(SetCardProfile, "PUT", "/contact/cards/{cardId}/profile", - ¶m, &msg, - APP_TOKENAPP, set.B.Token, &card, nil)) + ¶m, &msg, APP_TOKENAPP, set.B.Token, &card, nil)) assert.True(t, card.Data.CardProfile.ImageSet) + data, hdr, res = ApiTestData(GetCardProfileImage, "GET", "/contact/cards/{cardId}/profile/image", + ¶m, &data, APP_TOKENAPP, set.B.Token) + assert.NoError(t, res) + + // compare retrieved image + assert.Equal(t, "image/png", hdr["Content-Type"][0]) + img, err = base64.StdEncoding.DecodeString(image) + assert.NoError(t, err) + assert.Zero(t, bytes.Compare(img, data)) + + // get full card list + assert.NoError(t, ApiTestMsg(GetCards, "GET", "/contact/cards", + nil, nil, APP_TOKENAPP, set.B.Token, &cards, &hdr)) + + PrintMsg(set.B.A.CardId) + PrintMsg(hdr) + PrintMsg(cards) + }