mirror of
https://github.com/balzack/databag.git
synced 2025-02-12 03:29:16 +00:00
restructuring card with slots
This commit is contained in:
parent
84285194a7
commit
9d1f407653
@ -47,11 +47,11 @@ func AddArticle(w http.ResponseWriter, r *http.Request) {
|
|||||||
Groups: groups,
|
Groups: groups,
|
||||||
Labels: labels,
|
Labels: labels,
|
||||||
};
|
};
|
||||||
if res := store.DB.Save(article).Error; res != nil {
|
if res := tx.Save(article).Error; res != nil {
|
||||||
return res;
|
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) {
|
if errors.Is(res, gorm.ErrRecordNotFound) {
|
||||||
slot = &store.ArticleSlot{
|
slot = &store.ArticleSlot{
|
||||||
ArticleSlotId: uuid.New().String(),
|
ArticleSlotId: uuid.New().String(),
|
||||||
@ -60,17 +60,17 @@ func AddArticle(w http.ResponseWriter, r *http.Request) {
|
|||||||
ArticleID: article.ID,
|
ArticleID: article.ID,
|
||||||
Article: article,
|
Article: article,
|
||||||
}
|
}
|
||||||
if ret := store.DB.Save(slot).Error; ret != nil {
|
if ret := tx.Save(slot).Error; ret != nil {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return res
|
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;
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
if ret := tx.Model(&account).Update("content_revision", account.ContentRevision + 1).Error; ret != nil {
|
if ret := tx.Model(&account).Update("content_revision", account.ContentRevision + 1).Error; ret != nil {
|
||||||
|
@ -31,68 +31,134 @@ func AddCard(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
slot := &store.CardSlot{}
|
||||||
var card store.Card
|
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) {
|
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
ErrResponse(w, http.StatusInternalServerError, err)
|
ErrResponse(w, http.StatusInternalServerError, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// populate new record
|
// create new card data
|
||||||
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
|
|
||||||
data, res := securerandom.Bytes(APP_TOKENSIZE)
|
data, res := securerandom.Bytes(APP_TOKENSIZE)
|
||||||
if res != nil {
|
if res != nil {
|
||||||
ErrResponse(w, http.StatusInternalServerError, res)
|
ErrResponse(w, http.StatusInternalServerError, err)
|
||||||
return
|
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 {
|
} else {
|
||||||
|
|
||||||
if identity.Revision <= card.ProfileRevision {
|
if identity.Revision > card.ProfileRevision {
|
||||||
WriteResponse(w, getCardModel(&card))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// update record if revision changed
|
// update card data
|
||||||
card.Username = identity.Handle
|
card.Username = identity.Handle
|
||||||
card.Name = identity.Name
|
card.Name = identity.Name
|
||||||
card.Description = identity.Description
|
card.Description = identity.Description
|
||||||
card.Location = identity.Location
|
card.Location = identity.Location
|
||||||
card.Image = identity.Image
|
card.Image = identity.Image
|
||||||
card.Version = identity.Version
|
card.Version = identity.Version
|
||||||
card.Node = identity.Node
|
card.Node = identity.Node
|
||||||
card.ProfileRevision = identity.Revision
|
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 {
|
if err != nil {
|
||||||
ErrResponse(w, http.StatusInternalServerError, err)
|
ErrResponse(w, http.StatusInternalServerError, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
SetStatus(account)
|
SetStatus(account)
|
||||||
WriteResponse(w, getCardModel(&card))
|
WriteResponse(w, getCardModel(slot))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,8 +17,8 @@ func GetCard(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
cardId := mux.Vars(r)["cardId"]
|
cardId := mux.Vars(r)["cardId"]
|
||||||
|
|
||||||
var card store.Card
|
var slot store.CardSlot
|
||||||
if err := store.DB.Preload("Groups").Where("account_id = ? AND card_id = ?", account.Guid, cardId).First(&card).Error; err != nil {
|
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) {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
ErrResponse(w, http.StatusNotFound, err)
|
ErrResponse(w, http.StatusNotFound, err)
|
||||||
} else {
|
} else {
|
||||||
@ -27,6 +27,6 @@ func GetCard(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteResponse(w, getCardModel(&card))
|
WriteResponse(w, getCardModel(&slot))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,11 +13,15 @@ func GetCards(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var cards []store.Card
|
var slots []store.CardSlot
|
||||||
if err := store.DB.Where("account_id = ?", account.Guid).Find(&cards).Error; err != nil {
|
if err := store.DB.Preload("Card").Where("account_id = ?", account.ID).Find(&slots).Error; err != nil {
|
||||||
ErrResponse(w, http.StatusInternalServerError, err)
|
ErrResponse(w, http.StatusInternalServerError, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteResponse(w, &cards)
|
var response []*Card
|
||||||
|
for _, slot := range slots {
|
||||||
|
response = append(response, getCardModel(&slot))
|
||||||
|
}
|
||||||
|
WriteResponse(w, response)
|
||||||
}
|
}
|
||||||
|
@ -18,8 +18,8 @@ func GetOpenMessage(w http.ResponseWriter, r *http.Request) {
|
|||||||
detail := account.AccountDetail
|
detail := account.AccountDetail
|
||||||
cardId := mux.Vars(r)["cardId"]
|
cardId := mux.Vars(r)["cardId"]
|
||||||
|
|
||||||
var card store.Card
|
var slot store.CardSlot
|
||||||
if err := store.DB.Where("account_id = ? AND card_id = ?", account.Guid, cardId).First(&card).Error; err != nil {
|
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) {
|
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
ErrResponse(w, http.StatusInternalServerError, err)
|
ErrResponse(w, http.StatusInternalServerError, err)
|
||||||
} else {
|
} else {
|
||||||
@ -27,16 +27,20 @@ func GetOpenMessage(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
return
|
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"))
|
ErrResponse(w, http.StatusMethodNotAllowed, errors.New("invalid card state"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
connect := &Connect{
|
connect := &Connect{
|
||||||
Contact: card.Guid,
|
Contact: slot.Card.Guid,
|
||||||
Token: card.InToken,
|
Token: slot.Card.InToken,
|
||||||
ContentRevision: account.ContentRevision + account.ViewRevision + card.ViewRevision,
|
ContentRevision: account.ContentRevision + account.ViewRevision + slot.Card.ViewRevision,
|
||||||
ProfileRevision: account.ProfileRevision,
|
ProfileRevision: account.ProfileRevision,
|
||||||
Handle: account.Username,
|
Handle: account.Username,
|
||||||
Name: detail.Name,
|
Name: detail.Name,
|
||||||
|
@ -20,17 +20,20 @@ func SetCardGroup(w http.ResponseWriter, r *http.Request) {
|
|||||||
cardId := params["cardId"]
|
cardId := params["cardId"]
|
||||||
groupId := params["groupId"]
|
groupId := params["groupId"]
|
||||||
|
|
||||||
|
|
||||||
// load referenced card
|
// load referenced card
|
||||||
var card store.Card
|
var slot store.CardSlot
|
||||||
if err := store.DB.Where("account_id = ? AND card_id = ?", account.Guid, cardId).First(&card).Error; err != nil {
|
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) {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
ErrResponse(w, http.StatusInternalServerError, err)
|
|
||||||
} else {
|
|
||||||
ErrResponse(w, http.StatusNotFound, err)
|
ErrResponse(w, http.StatusNotFound, err)
|
||||||
|
} else {
|
||||||
|
ErrResponse(w, http.StatusInternalServerError, err)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if slot.Card == nil {
|
||||||
|
ErrResponse(w, http.StatusNotFound, errors.New("card has been deleted"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// load referenced group
|
// load referenced group
|
||||||
var group store.Group
|
var group store.Group
|
||||||
@ -44,14 +47,17 @@ func SetCardGroup(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// save and update revision
|
// save and update revision
|
||||||
card.Groups = append(card.Groups, group)
|
slot.Card.Groups = append(slot.Card.Groups, group)
|
||||||
card.ViewRevision += 1
|
slot.Card.ViewRevision += 1
|
||||||
card.DataRevision += 1
|
slot.Revision = account.CardRevision + 1
|
||||||
err = store.DB.Transaction(func(tx *gorm.DB) error {
|
err = store.DB.Transaction(func(tx *gorm.DB) error {
|
||||||
if res := tx.Model(&account).Update("card_revision", account.CardRevision + 1).Error; res != nil {
|
if res := tx.Model(&account).Update("card_revision", account.CardRevision + 1).Error; res != nil {
|
||||||
return res
|
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 res
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -61,18 +67,9 @@ func SetCardGroup(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
cardData := &CardData{
|
SetContactViewNotification(account, slot.Card)
|
||||||
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)
|
|
||||||
SetStatus(account)
|
SetStatus(account)
|
||||||
WriteResponse(w, cardData)
|
WriteResponse(w, getCardModel(&slot))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -38,8 +38,8 @@ func SetCardStatus(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// load referenced card
|
// load referenced card
|
||||||
var card store.Card
|
var slot store.CardSlot
|
||||||
if err := store.DB.Preload("Groups").Where("account_id = ? AND card_id = ?", account.Guid, cardId).First(&card).Error; err != nil {
|
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) {
|
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
ErrResponse(w, http.StatusInternalServerError, err)
|
ErrResponse(w, http.StatusInternalServerError, err)
|
||||||
} else {
|
} else {
|
||||||
@ -47,27 +47,34 @@ func SetCardStatus(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if slot.Card == nil {
|
||||||
|
ErrResponse(w, http.StatusNotFound, errors.New("card has been deleted"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// update card
|
// update card
|
||||||
card.DataRevision += 1
|
slot.Revision = account.CardRevision + 1
|
||||||
if token != "" {
|
if token != "" {
|
||||||
card.OutToken = token
|
slot.Card.OutToken = token
|
||||||
}
|
}
|
||||||
if status == APP_CARDCONNECTING {
|
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)
|
data, err := securerandom.Bytes(APP_TOKENSIZE)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ErrResponse(w, http.StatusInternalServerError, err)
|
ErrResponse(w, http.StatusInternalServerError, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
card.InToken = hex.EncodeToString(data)
|
slot.Card.InToken = hex.EncodeToString(data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
card.Status = status
|
slot.Card.Status = status
|
||||||
|
|
||||||
// save and update contact revision
|
// save and update contact revision
|
||||||
err = store.DB.Transaction(func(tx *gorm.DB) error {
|
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
|
return res
|
||||||
}
|
}
|
||||||
if res := tx.Model(&account).Update("card_revision", account.CardRevision + 1).Error; res != nil {
|
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)
|
SetStatus(account)
|
||||||
WriteResponse(w, getCardModel(&card));
|
WriteResponse(w, getCardModel(&slot));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,16 +42,20 @@ func SetOpenMessage(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// see if card exists
|
// see if card exists
|
||||||
var card store.Card
|
slot := &store.CardSlot{}
|
||||||
if err := store.DB.Where("account_id = ? AND guid = ?", account.Guid, guid).First(&card).Error; err != nil {
|
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) {
|
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
ErrResponse(w, http.StatusInternalServerError, err)
|
ErrResponse(w, http.StatusInternalServerError, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// populate new record
|
// create new card
|
||||||
card.CardId = uuid.New().String()
|
data, res := securerandom.Bytes(APP_TOKENSIZE)
|
||||||
card.AccountID = account.Guid
|
if res != nil {
|
||||||
|
ErrResponse(w, http.StatusInternalServerError, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
card.Guid = guid
|
card.Guid = guid
|
||||||
card.Username = connect.Handle
|
card.Username = connect.Handle
|
||||||
card.Name = connect.Name
|
card.Name = connect.Name
|
||||||
@ -61,18 +65,61 @@ func SetOpenMessage(w http.ResponseWriter, r *http.Request) {
|
|||||||
card.Version = connect.Version
|
card.Version = connect.Version
|
||||||
card.Node = connect.Node
|
card.Node = connect.Node
|
||||||
card.ProfileRevision = connect.ProfileRevision
|
card.ProfileRevision = connect.ProfileRevision
|
||||||
|
card.Status = APP_CARDPENDING
|
||||||
card.NotifiedProfile = connect.ProfileRevision
|
card.NotifiedProfile = connect.ProfileRevision
|
||||||
card.NotifiedContent = connect.ContentRevision
|
card.NotifiedContent = connect.ContentRevision
|
||||||
card.NotifiedView = connect.ViewRevision
|
card.NotifiedView = connect.ViewRevision
|
||||||
card.Status = APP_CARDPENDING
|
|
||||||
card.DataRevision = 1
|
|
||||||
card.OutToken = connect.Token
|
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.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 {
|
} else {
|
||||||
|
|
||||||
@ -105,26 +152,42 @@ func SetOpenMessage(w http.ResponseWriter, r *http.Request) {
|
|||||||
card.DataRevision += 1
|
card.DataRevision += 1
|
||||||
card.OutToken = connect.Token
|
card.OutToken = connect.Token
|
||||||
|
|
||||||
}
|
// save contact card
|
||||||
|
err = store.DB.Transaction(func(tx *gorm.DB) error {
|
||||||
// save contact card
|
if res := tx.Save(&card).Error; res != nil {
|
||||||
err = store.DB.Transaction(func(tx *gorm.DB) error {
|
return res
|
||||||
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{
|
status := &ContactStatus{
|
||||||
Token: card.InToken,
|
Token: slot.Card.InToken,
|
||||||
Status: card.Status,
|
Status: slot.Card.Status,
|
||||||
}
|
}
|
||||||
SetStatus(&account)
|
SetStatus(&account)
|
||||||
WriteResponse(w, &status)
|
WriteResponse(w, &status)
|
||||||
|
@ -4,35 +4,40 @@ import (
|
|||||||
"databag/internal/store"
|
"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
|
// populate group id list
|
||||||
var groups []string;
|
var groups []string;
|
||||||
for _, group := range card.Groups {
|
for _, group := range slot.Card.Groups {
|
||||||
groups = append(groups, group.GroupId)
|
groups = append(groups, group.GroupId)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Card{
|
return &Card{
|
||||||
CardId: card.CardId,
|
CardId: slot.CardSlotId,
|
||||||
NotifiedProfile: card.NotifiedProfile,
|
CardData: &CardData {
|
||||||
NotifiedContent: card.NotifiedContent,
|
NotifiedProfile: slot.Card.NotifiedProfile,
|
||||||
NotifiedView: card.NotifiedView,
|
NotifiedContent: slot.Card.NotifiedContent,
|
||||||
CardProfile: &CardProfile{
|
NotifiedView: slot.Card.NotifiedView,
|
||||||
Guid: card.Guid,
|
CardProfile: &CardProfile{
|
||||||
Handle: card.Username,
|
Guid: slot.Card.Guid,
|
||||||
Name: card.Name,
|
Handle: slot.Card.Username,
|
||||||
Description: card.Description,
|
Name: slot.Card.Name,
|
||||||
Location: card.Location,
|
Description: slot.Card.Description,
|
||||||
Revision: card.ProfileRevision,
|
Location: slot.Card.Location,
|
||||||
ImageSet: card.Image != "",
|
Revision: slot.Card.ProfileRevision,
|
||||||
Version: card.Version,
|
ImageSet: slot.Card.Image != "",
|
||||||
Node: card.Node,
|
Version: slot.Card.Version,
|
||||||
},
|
Node: slot.Card.Node,
|
||||||
CardData: &CardData {
|
},
|
||||||
Revision: card.DataRevision,
|
Status: slot.Card.Status,
|
||||||
Status: card.Status,
|
Notes: slot.Card.Notes,
|
||||||
Notes: card.Notes,
|
Token: slot.Card.OutToken,
|
||||||
Token: card.OutToken,
|
|
||||||
Groups: groups,
|
Groups: groups,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -55,35 +60,34 @@ func getArticleModel(slot *store.ArticleSlot, contact bool, shared bool) *Articl
|
|||||||
return &Article{
|
return &Article{
|
||||||
ArticleId: slot.ArticleSlotId,
|
ArticleId: slot.ArticleSlotId,
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
|
||||||
var groups []string;
|
var groups []string;
|
||||||
if !contact {
|
if !contact {
|
||||||
for _, group := range slot.Article.Groups {
|
for _, group := range slot.Article.Groups {
|
||||||
groups = append(groups, group.GroupId)
|
groups = append(groups, group.GroupId)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var labels []string;
|
var labels []string;
|
||||||
for _, label := range slot.Article.Labels {
|
for _, label := range slot.Article.Labels {
|
||||||
labels = append(labels, label.LabelId)
|
labels = append(labels, label.LabelId)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Article{
|
return &Article{
|
||||||
ArticleId: slot.ArticleSlotId,
|
ArticleId: slot.ArticleSlotId,
|
||||||
ArticleData: &ArticleData{
|
ArticleData: &ArticleData{
|
||||||
DataType: slot.Article.DataType,
|
DataType: slot.Article.DataType,
|
||||||
Data: slot.Article.Data,
|
Data: slot.Article.Data,
|
||||||
Status: slot.Article.Status,
|
Status: slot.Article.Status,
|
||||||
Labels: labels,
|
Labels: labels,
|
||||||
Groups: groups,
|
Groups: groups,
|
||||||
TagCount: slot.Article.TagCount,
|
TagCount: slot.Article.TagCount,
|
||||||
Created: slot.Article.Created,
|
Created: slot.Article.Created,
|
||||||
Updated: slot.Article.Updated,
|
Updated: slot.Article.Updated,
|
||||||
TagUpdated: slot.Article.TagUpdated,
|
TagUpdated: slot.Article.TagUpdated,
|
||||||
TagRevision: slot.Article.TagRevision,
|
TagRevision: slot.Article.TagRevision,
|
||||||
},
|
},
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,15 +83,15 @@ type Asset struct {
|
|||||||
|
|
||||||
type Card struct {
|
type Card struct {
|
||||||
CardId string `json:"cardId"`
|
CardId string `json:"cardId"`
|
||||||
|
CardData *CardData `json:"cardData"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CardData struct {
|
||||||
CardProfile *CardProfile `json:"cardProfile"`
|
CardProfile *CardProfile `json:"cardProfile"`
|
||||||
CardData *CardData `json:"cardData"`
|
CardData *CardData `json:"cardData"`
|
||||||
NotifiedProfile int64 `json:"notifiedProfile"`
|
NotifiedProfile int64 `json:"notifiedProfile"`
|
||||||
NotifiedContent int64 `json:"notifiedContent"`
|
NotifiedContent int64 `json:"notifiedContent"`
|
||||||
NotifiedView int64 `json:"notifiedView"`
|
NotifiedView int64 `json:"notifiedView"`
|
||||||
}
|
|
||||||
|
|
||||||
type CardData struct {
|
|
||||||
Revision int64 `json:"revision,omitempty"`
|
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
Notes string `json:"notes,omitempty"`
|
Notes string `json:"notes,omitempty"`
|
||||||
Token string `json:"token,omitempty"`
|
Token string `json:"token,omitempty"`
|
||||||
|
@ -10,6 +10,7 @@ func AutoMigrate(db *gorm.DB) {
|
|||||||
db.AutoMigrate(&AccountToken{});
|
db.AutoMigrate(&AccountToken{});
|
||||||
db.AutoMigrate(&Group{});
|
db.AutoMigrate(&Group{});
|
||||||
db.AutoMigrate(&Label{});
|
db.AutoMigrate(&Label{});
|
||||||
|
db.AutoMigrate(&CardSlot{});
|
||||||
db.AutoMigrate(&Card{});
|
db.AutoMigrate(&Card{});
|
||||||
db.AutoMigrate(&Asset{});
|
db.AutoMigrate(&Asset{});
|
||||||
db.AutoMigrate(&ArticleSlot{});
|
db.AutoMigrate(&ArticleSlot{});
|
||||||
@ -135,10 +136,19 @@ type LabelData struct {
|
|||||||
Data string
|
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 {
|
type Card struct {
|
||||||
ID uint `gorm:"primaryKey;not null;unique;autoIncrement"`
|
ID uint `gorm:"primaryKey;not null;unique;autoIncrement"`
|
||||||
CardId string `gorm:"not null;index:card,unique"`
|
AccountID string `gorm:"not null;index:cardguid,unique"`
|
||||||
AccountID string `gorm:"not null;index:card,unique"`
|
|
||||||
Guid string `gorm:"not null;index:cardguid,unique"`
|
Guid string `gorm:"not null;index:cardguid,unique"`
|
||||||
Username string
|
Username string
|
||||||
Name string
|
Name string
|
||||||
|
@ -300,7 +300,7 @@ func GetCardToken(account string, cardId string) (token string, err error) {
|
|||||||
err = errors.New("card not connected")
|
err = errors.New("card not connected")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
token = card.CardProfile.Guid + "." + card.CardData.Token
|
token = card.CardData.CardProfile.Guid + "." + card.CardData.Token
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,6 @@ func TestGroupContact(t *testing.T) {
|
|||||||
var cardRevision int64
|
var cardRevision int64
|
||||||
var revision Revision
|
var revision Revision
|
||||||
var vars map[string]string
|
var vars map[string]string
|
||||||
var cardData CardData
|
|
||||||
var contactRevision int64
|
var contactRevision int64
|
||||||
var card Card
|
var card Card
|
||||||
var contactViewRevision int64
|
var contactViewRevision int64
|
||||||
@ -62,18 +61,18 @@ func TestGroupContact(t *testing.T) {
|
|||||||
SetBearerAuth(r, b)
|
SetBearerAuth(r, b)
|
||||||
GetCard(w, r)
|
GetCard(w, r)
|
||||||
assert.NoError(t, ReadResponse(w, &card))
|
assert.NoError(t, ReadResponse(w, &card))
|
||||||
contactViewRevision = card.NotifiedView
|
contactViewRevision = card.CardData.NotifiedView
|
||||||
|
|
||||||
// set contact group
|
// set contact group
|
||||||
r, w, _ = NewRequest("PUT", "/contact/cards/{cardId}/groups/{groupId}", nil)
|
r, w, _ = NewRequest("PUT", "/contact/cards/{cardId}/groups/{groupId}", nil)
|
||||||
vars = make(map[string]string)
|
vars = make(map[string]string)
|
||||||
vars["groupId"] = group.GroupId
|
vars["groupId"] = group.GroupId
|
||||||
vars["cardId"] = aCard
|
vars["cardId"] = aCard
|
||||||
r = mux.SetURLVars(r, vars)
|
r = mux.SetURLVars(r, vars)
|
||||||
SetBearerAuth(r, a)
|
SetBearerAuth(r, a)
|
||||||
SetCardGroup(w, r)
|
SetCardGroup(w, r)
|
||||||
assert.NoError(t, ReadResponse(w, &cardData))
|
assert.NoError(t, ReadResponse(w, &card))
|
||||||
assert.Equal(t, 1, len(cardData.Groups))
|
assert.Equal(t, 1, len(card.CardData.Groups))
|
||||||
|
|
||||||
// get contact revision
|
// get contact revision
|
||||||
r, w, _ = NewRequest("GET", "/contact/cards/{cardId}", nil)
|
r, w, _ = NewRequest("GET", "/contact/cards/{cardId}", nil)
|
||||||
@ -102,8 +101,8 @@ func TestGroupContact(t *testing.T) {
|
|||||||
SetBearerAuth(r, b)
|
SetBearerAuth(r, b)
|
||||||
GetCard(w, r)
|
GetCard(w, r)
|
||||||
assert.NoError(t, ReadResponse(w, &card))
|
assert.NoError(t, ReadResponse(w, &card))
|
||||||
assert.NotEqual(t, contactViewRevision, card.NotifiedView)
|
assert.NotEqual(t, contactViewRevision, card.CardData.NotifiedView)
|
||||||
contactViewRevision = card.NotifiedView
|
contactViewRevision = card.CardData.NotifiedView
|
||||||
|
|
||||||
// show group view
|
// show group view
|
||||||
r, w, _ = NewRequest("GET", "/share/groups", nil)
|
r, w, _ = NewRequest("GET", "/share/groups", nil)
|
||||||
@ -166,7 +165,7 @@ func TestGroupContact(t *testing.T) {
|
|||||||
SetBearerAuth(r, b)
|
SetBearerAuth(r, b)
|
||||||
GetCard(w, r)
|
GetCard(w, r)
|
||||||
assert.NoError(t, ReadResponse(w, &card))
|
assert.NoError(t, ReadResponse(w, &card))
|
||||||
assert.NotEqual(t, contactViewRevision, card.NotifiedView)
|
assert.NotEqual(t, contactViewRevision, card.CardData.NotifiedView)
|
||||||
|
|
||||||
// show group view
|
// show group view
|
||||||
r, w, _ = NewRequest("GET", "/share/groups", nil)
|
r, w, _ = NewRequest("GET", "/share/groups", nil)
|
||||||
|
@ -26,7 +26,7 @@ func TestProfileNotification(t *testing.T) {
|
|||||||
GetCards(w, r)
|
GetCards(w, r)
|
||||||
assert.NoError(t, ReadResponse(w, &cards))
|
assert.NoError(t, ReadResponse(w, &cards))
|
||||||
assert.Equal(t, len(cards), 1)
|
assert.Equal(t, len(cards), 1)
|
||||||
profileRevision := cards[0].NotifiedProfile
|
profileRevision := cards[0].CardData.NotifiedProfile
|
||||||
|
|
||||||
// app connects websocket
|
// app connects websocket
|
||||||
ws, err = StatusConnection(a, &revision);
|
ws, err = StatusConnection(a, &revision);
|
||||||
@ -55,5 +55,5 @@ func TestProfileNotification(t *testing.T) {
|
|||||||
GetCards(w, r)
|
GetCards(w, r)
|
||||||
assert.NoError(t, ReadResponse(w, &cards))
|
assert.NoError(t, ReadResponse(w, &cards))
|
||||||
assert.Equal(t, len(cards), 1)
|
assert.Equal(t, len(cards), 1)
|
||||||
assert.NotEqual(t, profileRevision, cards[0].NotifiedProfile)
|
assert.NotEqual(t, profileRevision, cards[0].CardData.NotifiedProfile)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user