diff --git a/net/server/internal/api_addArticle.go b/net/server/internal/api_addArticle.go index fbe8485b..eb2d69b9 100644 --- a/net/server/internal/api_addArticle.go +++ b/net/server/internal/api_addArticle.go @@ -47,11 +47,11 @@ func AddArticle(w http.ResponseWriter, r *http.Request) { Groups: groups, Labels: labels, }; - if res := store.DB.Save(article).Error; res != nil { + if res := tx.Save(article).Error; res != nil { return res; } - if res := store.DB.Where("article_id = 0 AND account_id = ?", account.ID).First(&slot).Error; res != nil { + if res := tx.Where("article_id = 0 AND account_id = ?", account.ID).First(&slot).Error; res != nil { if errors.Is(res, gorm.ErrRecordNotFound) { slot = &store.ArticleSlot{ ArticleSlotId: uuid.New().String(), @@ -60,17 +60,17 @@ func AddArticle(w http.ResponseWriter, r *http.Request) { ArticleID: article.ID, Article: article, } - if ret := store.DB.Save(slot).Error; ret != nil { + if ret := tx.Save(slot).Error; ret != nil { return ret; } } else { return res } } - if ret := store.DB.Model(slot).Update("article_id", article.ID).Error; ret != nil { + if ret := tx.Model(slot).Update("article_id", article.ID).Error; ret != nil { return ret; } - if ret := store.DB.Preload("Article.Labels.Groups").Where("id = ?", article.ID).First(slot).Error; ret != nil { + if ret := tx.Preload("Article.Labels.Groups").Where("id = ?", article.ID).First(slot).Error; ret != nil { return ret; } if ret := tx.Model(&account).Update("content_revision", account.ContentRevision + 1).Error; ret != nil { diff --git a/net/server/internal/api_addCard.go b/net/server/internal/api_addCard.go index 3176b5c2..c7e87f9e 100644 --- a/net/server/internal/api_addCard.go +++ b/net/server/internal/api_addCard.go @@ -31,68 +31,134 @@ func AddCard(w http.ResponseWriter, r *http.Request) { return } + slot := &store.CardSlot{} var card store.Card - if err := store.DB.Preload("Groups").Where("account_id = ? AND guid = ?", account.ID, guid).First(&card).Error; err != nil { + if err := store.DB.Preload("Card.Groups").Where("account_id = ? AND guid = ?", account.ID, guid).First(&card).Error; err != nil { if !errors.Is(err, gorm.ErrRecordNotFound) { ErrResponse(w, http.StatusInternalServerError, err) return } - // populate new record - card.CardId = uuid.New().String() - card.AccountID = account.Guid - card.Guid = guid - card.Username = identity.Handle - card.Name = identity.Name - card.Description = identity.Description - card.Location = identity.Location - card.Image = identity.Image - card.Version = identity.Version - card.Node = identity.Node - card.ProfileRevision = identity.Revision - card.Status = APP_CARDCONFIRMED - card.ViewRevision = 0 + // create new card data data, res := securerandom.Bytes(APP_TOKENSIZE) if res != nil { - ErrResponse(w, http.StatusInternalServerError, res) + ErrResponse(w, http.StatusInternalServerError, err) return } - card.InToken = hex.EncodeToString(data) + card := &store.Card{ + Guid: guid, + Username: identity.Handle, + Name: identity.Name, + Description: identity.Description, + Location: identity.Location, + Image: identity.Image, + Version: identity.Version, + Node: identity.Node, + ProfileRevision: identity.Revision, + Status: APP_CARDCONFIRMED, + ViewRevision: 0, + InToken: hex.EncodeToString(data), + AccountID: account.Guid, + } + // create new card or update existing + if err = store.DB.Where("account_id = ? AND card_id = 0", account.ID).First(slot).Error; err != nil { + if !errors.Is(err, gorm.ErrRecordNotFound) { + ErrResponse(w, http.StatusInternalServerError, err) + return + } + err = store.DB.Transaction(func(tx *gorm.DB) error { + if res := tx.Save(card).Error; res != nil { + return res + } + slot.CardSlotId = uuid.New().String() + slot.AccountID = account.ID + slot.Revision = account.CardRevision + 1 + slot.CardID = card.ID + slot.Card = card + if res := tx.Save(slot).Error; res != nil { + return res + } + if res := tx.Model(&account).Update("card_revision", account.CardRevision + 1).Error; res != nil { + return res + } + return nil + }) + if err != nil { + ErrResponse(w, http.StatusInternalServerError, err) + return + } + } else { + err = store.DB.Transaction(func(tx *gorm.DB) error { + if res := tx.Save(&card).Error; res != nil { + return res + } + slot.Revision = account.CardRevision + 1 + slot.CardID = card.ID + slot.Card = card + if res := tx.Save(&slot).Error; res != nil { + return res + } + if res := tx.Model(&account).Update("card_revision", account.CardRevision + 1).Error; res != nil { + return res + } + return nil + }) + if err != nil { + ErrResponse(w, http.StatusInternalServerError, err) + return + } + } } else { - if identity.Revision <= card.ProfileRevision { - WriteResponse(w, getCardModel(&card)) - return - } + if identity.Revision > card.ProfileRevision { - // update record if revision changed - card.Username = identity.Handle - card.Name = identity.Name - card.Description = identity.Description - card.Location = identity.Location - card.Image = identity.Image - card.Version = identity.Version - card.Node = identity.Node - card.ProfileRevision = identity.Revision + // update card data + card.Username = identity.Handle + card.Name = identity.Name + card.Description = identity.Description + card.Location = identity.Location + card.Image = identity.Image + card.Version = identity.Version + card.Node = identity.Node + card.ProfileRevision = identity.Revision + + // save contact card + err = store.DB.Transaction(func(tx *gorm.DB) error { + if res := tx.Save(&card).Error; res != nil { + return res + } + if res := store.DB.Where("account_id = ? AND card_id = ?", account.ID, card.ID).First(&slot).Error; res != nil { + if !errors.Is(res, gorm.ErrRecordNotFound) { + return nil + } + slot = &store.CardSlot{ + CardSlotId: uuid.New().String(), + AccountID: account.ID, + Revision: account.CardRevision + 1, + CardID: card.ID, + Card: &card, + } + } else { + slot.Revision = account.CardRevision + 1 + } + if res := tx.Preload("Card").Save(slot).Error; res != nil { + return res + } + if res := tx.Model(&account).Update("card_revision", account.CardRevision + 1).Error; res != nil { + return res + } + return nil + }) + } } - // save contact card - err = store.DB.Transaction(func(tx *gorm.DB) error { - if res := tx.Save(&card).Error; res != nil { - return res - } - if res := tx.Model(&account).Update("card_revision", account.CardRevision + 1).Error; res != nil { - return res - } - return nil - }) if err != nil { ErrResponse(w, http.StatusInternalServerError, err) return } SetStatus(account) - WriteResponse(w, getCardModel(&card)) + WriteResponse(w, getCardModel(slot)) } diff --git a/net/server/internal/api_getCard.go b/net/server/internal/api_getCard.go index c2f2dc87..2a122b23 100644 --- a/net/server/internal/api_getCard.go +++ b/net/server/internal/api_getCard.go @@ -17,8 +17,8 @@ func GetCard(w http.ResponseWriter, r *http.Request) { } cardId := mux.Vars(r)["cardId"] - var card store.Card - if err := store.DB.Preload("Groups").Where("account_id = ? AND card_id = ?", account.Guid, cardId).First(&card).Error; err != nil { + 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 { @@ -27,6 +27,6 @@ func GetCard(w http.ResponseWriter, r *http.Request) { return } - WriteResponse(w, getCardModel(&card)) + WriteResponse(w, getCardModel(&slot)) } diff --git a/net/server/internal/api_getCards.go b/net/server/internal/api_getCards.go index 36a34ce8..dbc7e3b3 100644 --- a/net/server/internal/api_getCards.go +++ b/net/server/internal/api_getCards.go @@ -13,11 +13,15 @@ func GetCards(w http.ResponseWriter, r *http.Request) { return } - var cards []store.Card - if err := store.DB.Where("account_id = ?", account.Guid).Find(&cards).Error; err != nil { + var slots []store.CardSlot + if err := store.DB.Preload("Card").Where("account_id = ?", account.ID).Find(&slots).Error; err != nil { ErrResponse(w, http.StatusInternalServerError, err) return } - WriteResponse(w, &cards) + var response []*Card + for _, slot := range slots { + response = append(response, getCardModel(&slot)) + } + WriteResponse(w, response) } diff --git a/net/server/internal/api_getOpenMessage.go b/net/server/internal/api_getOpenMessage.go index 545b4ad2..da3f31d8 100644 --- a/net/server/internal/api_getOpenMessage.go +++ b/net/server/internal/api_getOpenMessage.go @@ -18,8 +18,8 @@ func GetOpenMessage(w http.ResponseWriter, r *http.Request) { detail := account.AccountDetail cardId := mux.Vars(r)["cardId"] - var card store.Card - if err := store.DB.Where("account_id = ? AND card_id = ?", account.Guid, cardId).First(&card).Error; err != nil { + var slot store.CardSlot + if err := store.DB.Preload("Card").Where("account_id = ? AND card_slot_id = ?", account.ID, cardId).First(&slot).Error; err != nil { if !errors.Is(err, gorm.ErrRecordNotFound) { ErrResponse(w, http.StatusInternalServerError, err) } else { @@ -27,16 +27,20 @@ func GetOpenMessage(w http.ResponseWriter, r *http.Request) { } return } + if slot.Card == nil { + ErrResponse(w, http.StatusNotFound, errors.New("card has been deleted")) + return + } - if card.Status != APP_CARDCONNECTING && card.Status != APP_CARDCONNECTED { + if slot.Card.Status != APP_CARDCONNECTING && slot.Card.Status != APP_CARDCONNECTED { ErrResponse(w, http.StatusMethodNotAllowed, errors.New("invalid card state")) return } connect := &Connect{ - Contact: card.Guid, - Token: card.InToken, - ContentRevision: account.ContentRevision + account.ViewRevision + card.ViewRevision, + Contact: slot.Card.Guid, + Token: slot.Card.InToken, + ContentRevision: account.ContentRevision + account.ViewRevision + slot.Card.ViewRevision, ProfileRevision: account.ProfileRevision, Handle: account.Username, Name: detail.Name, diff --git a/net/server/internal/api_setCardGroup.go b/net/server/internal/api_setCardGroup.go index 2fd33e78..61554603 100644 --- a/net/server/internal/api_setCardGroup.go +++ b/net/server/internal/api_setCardGroup.go @@ -20,17 +20,20 @@ func SetCardGroup(w http.ResponseWriter, r *http.Request) { cardId := params["cardId"] groupId := params["groupId"] - // load referenced card - var card store.Card - if err := store.DB.Where("account_id = ? AND card_id = ?", account.Guid, cardId).First(&card).Error; err != nil { - if !errors.Is(err, gorm.ErrRecordNotFound) { - ErrResponse(w, http.StatusInternalServerError, err) - } else { + var slot store.CardSlot + if err := store.DB.Preload("Card").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("card has been deleted")) + return + } // load referenced group var group store.Group @@ -44,14 +47,17 @@ func SetCardGroup(w http.ResponseWriter, r *http.Request) { } // save and update revision - card.Groups = append(card.Groups, group) - card.ViewRevision += 1 - card.DataRevision += 1 + slot.Card.Groups = append(slot.Card.Groups, group) + slot.Card.ViewRevision += 1 + slot.Revision = account.CardRevision + 1 err = store.DB.Transaction(func(tx *gorm.DB) error { if res := tx.Model(&account).Update("card_revision", account.CardRevision + 1).Error; res != nil { return res } - if res := tx.Preload("Groups").Save(&card).Error; res != nil { + if res := tx.Save(&slot.Card).Error; res != nil { + return res + } + if res := tx.Preload("CardData.Groups").Save(&slot).Error; res != nil { return res } return nil @@ -61,18 +67,9 @@ func SetCardGroup(w http.ResponseWriter, r *http.Request) { return } - cardData := &CardData{ - Revision: card.DataRevision, - Status: card.Status, - Notes: card.Notes, - Token: card.OutToken, - } - for _, group := range card.Groups { - cardData.Groups = append(cardData.Groups, group.GroupId) - } - SetContactViewNotification(account, &card) + SetContactViewNotification(account, slot.Card) SetStatus(account) - WriteResponse(w, cardData) + WriteResponse(w, getCardModel(&slot)) } diff --git a/net/server/internal/api_setCardStatus.go b/net/server/internal/api_setCardStatus.go index 9f98a558..f4c1911d 100644 --- a/net/server/internal/api_setCardStatus.go +++ b/net/server/internal/api_setCardStatus.go @@ -38,8 +38,8 @@ func SetCardStatus(w http.ResponseWriter, r *http.Request) { } // load referenced card - var card store.Card - if err := store.DB.Preload("Groups").Where("account_id = ? AND card_id = ?", account.Guid, cardId).First(&card).Error; err != nil { + 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.StatusInternalServerError, err) } else { @@ -47,27 +47,34 @@ func SetCardStatus(w http.ResponseWriter, r *http.Request) { } return } + if slot.Card == nil { + ErrResponse(w, http.StatusNotFound, errors.New("card has been deleted")) + return + } // update card - card.DataRevision += 1 + slot.Revision = account.CardRevision + 1 if token != "" { - card.OutToken = token + slot.Card.OutToken = token } if status == APP_CARDCONNECTING { - if card.Status != APP_CARDCONNECTING && card.Status != APP_CARDCONNECTED { + if slot.Card.Status != APP_CARDCONNECTING && slot.Card.Status != APP_CARDCONNECTED { data, err := securerandom.Bytes(APP_TOKENSIZE) if err != nil { ErrResponse(w, http.StatusInternalServerError, err) return } - card.InToken = hex.EncodeToString(data) + slot.Card.InToken = hex.EncodeToString(data) } } - card.Status = status + slot.Card.Status = status // save and update contact revision err = store.DB.Transaction(func(tx *gorm.DB) error { - if res := tx.Save(&card).Error; res != nil { + if res := tx.Save(&slot.Card).Error; res != nil { + return res + } + if res := tx.Preload("Card").Save(&slot).Error; res != nil { return res } if res := tx.Model(&account).Update("card_revision", account.CardRevision + 1).Error; res != nil { @@ -81,6 +88,6 @@ func SetCardStatus(w http.ResponseWriter, r *http.Request) { } SetStatus(account) - WriteResponse(w, getCardModel(&card)); + WriteResponse(w, getCardModel(&slot)); } diff --git a/net/server/internal/api_setOpenMessage.go b/net/server/internal/api_setOpenMessage.go index 902ad774..c3023a6a 100644 --- a/net/server/internal/api_setOpenMessage.go +++ b/net/server/internal/api_setOpenMessage.go @@ -42,16 +42,20 @@ func SetOpenMessage(w http.ResponseWriter, r *http.Request) { } // see if card exists - var card store.Card - if err := store.DB.Where("account_id = ? AND guid = ?", account.Guid, guid).First(&card).Error; err != nil { + slot := &store.CardSlot{} + card := &store.Card{} + if err := store.DB.Where("account_id = ? AND guid = ?", account.Guid, guid).First(card).Error; err != nil { if !errors.Is(err, gorm.ErrRecordNotFound) { ErrResponse(w, http.StatusInternalServerError, err) return } - // populate new record - card.CardId = uuid.New().String() - card.AccountID = account.Guid + // create new card + data, res := securerandom.Bytes(APP_TOKENSIZE) + if res != nil { + ErrResponse(w, http.StatusInternalServerError, res) + return + } card.Guid = guid card.Username = connect.Handle card.Name = connect.Name @@ -61,18 +65,61 @@ func SetOpenMessage(w http.ResponseWriter, r *http.Request) { card.Version = connect.Version card.Node = connect.Node card.ProfileRevision = connect.ProfileRevision + card.Status = APP_CARDPENDING card.NotifiedProfile = connect.ProfileRevision card.NotifiedContent = connect.ContentRevision card.NotifiedView = connect.ViewRevision - card.Status = APP_CARDPENDING - card.DataRevision = 1 card.OutToken = connect.Token - data, res := securerandom.Bytes(APP_TOKENSIZE) - if res != nil { - ErrResponse(w, http.StatusInternalServerError, res) - return - } card.InToken = hex.EncodeToString(data) + card.AccountID = account.Guid + + // create new card or update existing + if err = store.DB.Preload("Card").Where("account_id = ? AND card_id = 0", account.ID).First(slot).Error; err != nil { + if !errors.Is(err, gorm.ErrRecordNotFound) { + ErrResponse(w, http.StatusInternalServerError, err) + return + } + err = store.DB.Transaction(func(tx *gorm.DB) error { + if res := tx.Save(card).Error; res != nil { + return res + } + slot.CardSlotId = uuid.New().String() + slot.AccountID = account.ID + slot.Revision = account.CardRevision + 1 + slot.CardID = card.ID + slot.Card = card + if res := tx.Save(slot).Error; res != nil { + return res + } + if res := tx.Model(&account).Update("card_revision", account.CardRevision + 1).Error; res != nil { + return res + } + return nil + }) + if err != nil { + ErrResponse(w, http.StatusInternalServerError, err) + return + } + } else { + err = store.DB.Transaction(func(tx *gorm.DB) error { + if res := tx.Save(card).Error; res != nil { + return res + } + slot.Revision = account.CardRevision + 1 + slot.CardID = card.ID + if res := tx.Save(slot).Error; res != nil { + return res + } + if res := tx.Model(&account).Update("card_revision", account.CardRevision + 1).Error; res != nil { + return res + } + return nil + }) + if err != nil { + ErrResponse(w, http.StatusInternalServerError, err) + return + } + } } else { @@ -105,26 +152,42 @@ func SetOpenMessage(w http.ResponseWriter, r *http.Request) { card.DataRevision += 1 card.OutToken = connect.Token - } - - // save contact card - err = store.DB.Transaction(func(tx *gorm.DB) error { - if res := tx.Save(&card).Error; res != nil { - return res + // save contact card + err = store.DB.Transaction(func(tx *gorm.DB) error { + if res := tx.Save(&card).Error; res != nil { + return res + } + if res := tx.Preload("Card").Where("account_id = ? AND card_id = ?", account.ID, card.ID).First(&slot).Error; res != nil { + if !errors.Is(res, gorm.ErrRecordNotFound) { + return nil + } + slot = &store.CardSlot{ + CardSlotId: uuid.New().String(), + AccountID: account.ID, + Revision: account.CardRevision + 1, + CardID: card.ID, + Card: card, + } + } else { + slot.Revision = account.CardRevision + 1 + } + if res := tx.Preload("Card").Save(slot).Error; res != nil { + return res + } + if res := tx.Model(&account).Update("card_revision", account.CardRevision + 1).Error; res != nil { + return res + } + return nil + }) + if err != nil { + ErrResponse(w, http.StatusInternalServerError, err) + return } - if res := tx.Model(&account).Update("card_revision", account.CardRevision + 1).Error; res != nil { - return res - } - return nil - }) - if err != nil { - ErrResponse(w, http.StatusInternalServerError, err) - return } status := &ContactStatus{ - Token: card.InToken, - Status: card.Status, + Token: slot.Card.InToken, + Status: slot.Card.Status, } SetStatus(&account) WriteResponse(w, &status) diff --git a/net/server/internal/modelUtil.go b/net/server/internal/modelUtil.go index 5403a3cd..800ecef1 100644 --- a/net/server/internal/modelUtil.go +++ b/net/server/internal/modelUtil.go @@ -4,35 +4,40 @@ import ( "databag/internal/store" ) -func getCardModel(card *store.Card) *Card { +func getCardModel(slot *store.CardSlot) *Card { + + if slot.Card == nil { + return &Card{ + CardId: slot.CardSlotId, + } + } // populate group id list var groups []string; - for _, group := range card.Groups { + for _, group := range slot.Card.Groups { groups = append(groups, group.GroupId) } return &Card{ - CardId: card.CardId, - NotifiedProfile: card.NotifiedProfile, - NotifiedContent: card.NotifiedContent, - NotifiedView: card.NotifiedView, - CardProfile: &CardProfile{ - Guid: card.Guid, - Handle: card.Username, - Name: card.Name, - Description: card.Description, - Location: card.Location, - Revision: card.ProfileRevision, - ImageSet: card.Image != "", - Version: card.Version, - Node: card.Node, - }, - CardData: &CardData { - Revision: card.DataRevision, - Status: card.Status, - Notes: card.Notes, - Token: card.OutToken, + CardId: slot.CardSlotId, + CardData: &CardData { + NotifiedProfile: slot.Card.NotifiedProfile, + NotifiedContent: slot.Card.NotifiedContent, + NotifiedView: slot.Card.NotifiedView, + CardProfile: &CardProfile{ + Guid: slot.Card.Guid, + Handle: slot.Card.Username, + Name: slot.Card.Name, + Description: slot.Card.Description, + Location: slot.Card.Location, + Revision: slot.Card.ProfileRevision, + ImageSet: slot.Card.Image != "", + Version: slot.Card.Version, + Node: slot.Card.Node, + }, + Status: slot.Card.Status, + Notes: slot.Card.Notes, + Token: slot.Card.OutToken, Groups: groups, }, } @@ -55,35 +60,34 @@ func getArticleModel(slot *store.ArticleSlot, contact bool, shared bool) *Articl return &Article{ ArticleId: slot.ArticleSlotId, } - } else { + } - var groups []string; - if !contact { - for _, group := range slot.Article.Groups { - groups = append(groups, group.GroupId) - } + var groups []string; + if !contact { + for _, group := range slot.Article.Groups { + groups = append(groups, group.GroupId) } + } - var labels []string; - for _, label := range slot.Article.Labels { - labels = append(labels, label.LabelId) - } + var labels []string; + for _, label := range slot.Article.Labels { + labels = append(labels, label.LabelId) + } - return &Article{ - ArticleId: slot.ArticleSlotId, - ArticleData: &ArticleData{ - DataType: slot.Article.DataType, - Data: slot.Article.Data, - Status: slot.Article.Status, - Labels: labels, - Groups: groups, - TagCount: slot.Article.TagCount, - Created: slot.Article.Created, - Updated: slot.Article.Updated, - TagUpdated: slot.Article.TagUpdated, - TagRevision: slot.Article.TagRevision, - }, - } + return &Article{ + ArticleId: slot.ArticleSlotId, + ArticleData: &ArticleData{ + DataType: slot.Article.DataType, + Data: slot.Article.Data, + Status: slot.Article.Status, + Labels: labels, + Groups: groups, + TagCount: slot.Article.TagCount, + Created: slot.Article.Created, + Updated: slot.Article.Updated, + TagUpdated: slot.Article.TagUpdated, + TagRevision: slot.Article.TagRevision, + }, } } diff --git a/net/server/internal/models.go b/net/server/internal/models.go index 212a4de9..2da2aea4 100644 --- a/net/server/internal/models.go +++ b/net/server/internal/models.go @@ -83,15 +83,15 @@ type Asset struct { type Card struct { CardId string `json:"cardId"` + CardData *CardData `json:"cardData"` +} + +type CardData struct { CardProfile *CardProfile `json:"cardProfile"` CardData *CardData `json:"cardData"` NotifiedProfile int64 `json:"notifiedProfile"` NotifiedContent int64 `json:"notifiedContent"` NotifiedView int64 `json:"notifiedView"` -} - -type CardData struct { - Revision int64 `json:"revision,omitempty"` Status string `json:"status"` Notes string `json:"notes,omitempty"` Token string `json:"token,omitempty"` diff --git a/net/server/internal/store/schema.go b/net/server/internal/store/schema.go index bc04a8a8..a0c82c2a 100644 --- a/net/server/internal/store/schema.go +++ b/net/server/internal/store/schema.go @@ -10,6 +10,7 @@ func AutoMigrate(db *gorm.DB) { db.AutoMigrate(&AccountToken{}); db.AutoMigrate(&Group{}); db.AutoMigrate(&Label{}); + db.AutoMigrate(&CardSlot{}); db.AutoMigrate(&Card{}); db.AutoMigrate(&Asset{}); db.AutoMigrate(&ArticleSlot{}); @@ -135,10 +136,19 @@ type LabelData struct { Data string } +type CardSlot struct { + ID uint `gorm:"primaryKey;not null;unique;autoIncrement"` + CardSlotId string `gorm:"not null;index:cardslot,unique"` + AccountID uint `gorm:"not null;index:cardslot,unique"` + Revision int64 `gorm:"not null"` + CardID uint `gorm:"not null;default:0"` + Card *Card + Account Account +} + type Card struct { ID uint `gorm:"primaryKey;not null;unique;autoIncrement"` - CardId string `gorm:"not null;index:card,unique"` - AccountID string `gorm:"not null;index:card,unique"` + AccountID string `gorm:"not null;index:cardguid,unique"` Guid string `gorm:"not null;index:cardguid,unique"` Username string Name string diff --git a/net/server/internal/testUtil.go b/net/server/internal/testUtil.go index 325372c5..e59401c9 100644 --- a/net/server/internal/testUtil.go +++ b/net/server/internal/testUtil.go @@ -300,7 +300,7 @@ func GetCardToken(account string, cardId string) (token string, err error) { err = errors.New("card not connected") return } - token = card.CardProfile.Guid + "." + card.CardData.Token + token = card.CardData.CardProfile.Guid + "." + card.CardData.Token return } diff --git a/net/server/internal/ucGroupContact_test.go b/net/server/internal/ucGroupContact_test.go index 07fae335..e99da9c9 100644 --- a/net/server/internal/ucGroupContact_test.go +++ b/net/server/internal/ucGroupContact_test.go @@ -15,7 +15,6 @@ func TestGroupContact(t *testing.T) { var cardRevision int64 var revision Revision var vars map[string]string - var cardData CardData var contactRevision int64 var card Card var contactViewRevision int64 @@ -62,18 +61,18 @@ func TestGroupContact(t *testing.T) { SetBearerAuth(r, b) GetCard(w, r) assert.NoError(t, ReadResponse(w, &card)) - contactViewRevision = card.NotifiedView + contactViewRevision = card.CardData.NotifiedView // set contact group r, w, _ = NewRequest("PUT", "/contact/cards/{cardId}/groups/{groupId}", nil) vars = make(map[string]string) vars["groupId"] = group.GroupId - vars["cardId"] = aCard + vars["cardId"] = aCard r = mux.SetURLVars(r, vars) SetBearerAuth(r, a) SetCardGroup(w, r) - assert.NoError(t, ReadResponse(w, &cardData)) - assert.Equal(t, 1, len(cardData.Groups)) + assert.NoError(t, ReadResponse(w, &card)) + assert.Equal(t, 1, len(card.CardData.Groups)) // get contact revision r, w, _ = NewRequest("GET", "/contact/cards/{cardId}", nil) @@ -102,8 +101,8 @@ func TestGroupContact(t *testing.T) { SetBearerAuth(r, b) GetCard(w, r) assert.NoError(t, ReadResponse(w, &card)) - assert.NotEqual(t, contactViewRevision, card.NotifiedView) - contactViewRevision = card.NotifiedView + assert.NotEqual(t, contactViewRevision, card.CardData.NotifiedView) + contactViewRevision = card.CardData.NotifiedView // show group view r, w, _ = NewRequest("GET", "/share/groups", nil) @@ -166,7 +165,7 @@ func TestGroupContact(t *testing.T) { SetBearerAuth(r, b) GetCard(w, r) assert.NoError(t, ReadResponse(w, &card)) - assert.NotEqual(t, contactViewRevision, card.NotifiedView) + assert.NotEqual(t, contactViewRevision, card.CardData.NotifiedView) // show group view r, w, _ = NewRequest("GET", "/share/groups", nil) diff --git a/net/server/internal/ucProfileNotification_test.go b/net/server/internal/ucProfileNotification_test.go index 5e13c7ce..9cc5b23e 100644 --- a/net/server/internal/ucProfileNotification_test.go +++ b/net/server/internal/ucProfileNotification_test.go @@ -26,7 +26,7 @@ func TestProfileNotification(t *testing.T) { GetCards(w, r) assert.NoError(t, ReadResponse(w, &cards)) assert.Equal(t, len(cards), 1) - profileRevision := cards[0].NotifiedProfile + profileRevision := cards[0].CardData.NotifiedProfile // app connects websocket ws, err = StatusConnection(a, &revision); @@ -55,5 +55,5 @@ func TestProfileNotification(t *testing.T) { GetCards(w, r) assert.NoError(t, ReadResponse(w, &cards)) assert.Equal(t, len(cards), 1) - assert.NotEqual(t, profileRevision, cards[0].NotifiedProfile) + assert.NotEqual(t, profileRevision, cards[0].CardData.NotifiedProfile) }