From d90df5f170c9edddcc025e3dd59539fb14a75a75 Mon Sep 17 00:00:00 2001 From: Roland Osborne Date: Tue, 8 Feb 2022 12:24:42 -0800 Subject: [PATCH] removed label based endpoints --- doc/api.oa3 | 136 ++-- net/server/internal/api_account.go | 12 +- net/server/internal/api_addArticle.go | 103 --- net/server/internal/api_addLabel.go | 71 -- net/server/internal/api_admin.go | 4 +- net/server/internal/api_alias.go | 30 + net/server/internal/api_attribute.go | 50 ++ net/server/internal/api_authorize.go | 38 +- net/server/internal/api_clearCardNotes.go | 64 -- net/server/internal/api_contact.go | 22 +- net/server/internal/api_content.go | 67 +- net/server/internal/api_conversation.go | 174 ----- net/server/internal/api_getArticles.go | 125 ---- .../{api_getCard.go => api_getCardDetail.go} | 8 +- net/server/internal/api_getCardProfile.go | 36 + net/server/internal/api_getCards.go | 40 -- net/server/internal/api_getGroups.go | 41 -- net/server/internal/api_getLabels.go | 116 --- ...tNodeClaimable.go => api_getNodeStatus.go} | 2 +- net/server/internal/api_getOpenMessage.go | 4 +- net/server/internal/api_getProfile.go | 30 - net/server/internal/api_profile.go | 10 + net/server/internal/api_removeArticle.go | 63 -- net/server/internal/api_removeGroup.go | 68 -- net/server/internal/api_removeLabel.go | 74 -- net/server/internal/api_setArticleLabel.go | 76 -- ...tRevision.go => api_setArticleRevision.go} | 10 +- net/server/internal/api_setCardNotes.go | 70 -- net/server/internal/api_setCardProfile.go | 92 --- net/server/internal/api_setCardStatus.go | 20 +- ...lRevision.go => api_setChannelRevision.go} | 10 +- net/server/internal/api_setLabelGroup.go | 89 --- ...i_setNodeClaim.go => api_setNodeStatus.go} | 2 +- net/server/internal/api_setOpenMessage.go | 20 +- net/server/internal/api_setProfile.go | 49 -- net/server/internal/api_setViewRevision.go | 6 +- net/server/internal/api_status.go | 6 +- net/server/internal/api_updateGroup.go | 70 -- net/server/internal/appValues.go | 4 +- net/server/internal/main_test.go | 8 +- net/server/internal/modelUtil.go | 117 +-- net/server/internal/models.go | 477 ++++++++----- net/server/internal/notify.go | 24 +- net/server/internal/routers.go | 673 ++++++------------ net/server/internal/store/schema.go | 10 +- net/server/internal/testUtil.go | 164 +---- net/server/internal/ucAddArticle_test.go | 165 ----- net/server/internal/ucUpdateContact_test.go | 72 +- 48 files changed, 961 insertions(+), 2661 deletions(-) delete mode 100644 net/server/internal/api_addArticle.go delete mode 100644 net/server/internal/api_addLabel.go create mode 100644 net/server/internal/api_alias.go create mode 100644 net/server/internal/api_attribute.go delete mode 100644 net/server/internal/api_clearCardNotes.go delete mode 100644 net/server/internal/api_conversation.go delete mode 100644 net/server/internal/api_getArticles.go rename net/server/internal/{api_getCard.go => api_getCardDetail.go} (73%) create mode 100644 net/server/internal/api_getCardProfile.go delete mode 100644 net/server/internal/api_getCards.go delete mode 100644 net/server/internal/api_getGroups.go delete mode 100644 net/server/internal/api_getLabels.go rename net/server/internal/{api_getNodeClaimable.go => api_getNodeStatus.go} (86%) delete mode 100644 net/server/internal/api_getProfile.go delete mode 100644 net/server/internal/api_removeArticle.go delete mode 100644 net/server/internal/api_removeGroup.go delete mode 100644 net/server/internal/api_removeLabel.go delete mode 100644 net/server/internal/api_setArticleLabel.go rename net/server/internal/{api_setContentRevision.go => api_setArticleRevision.go} (76%) delete mode 100644 net/server/internal/api_setCardNotes.go delete mode 100644 net/server/internal/api_setCardProfile.go rename net/server/internal/{api_setLabelRevision.go => api_setChannelRevision.go} (75%) delete mode 100644 net/server/internal/api_setLabelGroup.go rename net/server/internal/{api_setNodeClaim.go => api_setNodeStatus.go} (95%) delete mode 100644 net/server/internal/api_setProfile.go delete mode 100644 net/server/internal/api_updateGroup.go delete mode 100644 net/server/internal/ucAddArticle_test.go diff --git a/doc/api.oa3 b/doc/api.oa3 index 64cf0b69..165d599b 100644 --- a/doc/api.oa3 +++ b/doc/api.oa3 @@ -43,12 +43,12 @@ paths: '200': description: Awaiting announce - /admin/available: + /admin/status: get: tags: - admin description: Check if portal params have been set - operationId: get-node-available + operationId: get-node-status responses: '200': description: success @@ -58,13 +58,11 @@ paths: type: boolean '500': description: internal server error - - /admin/claim: - post: + put: tags: - admin description: Set admin password and node domain - operationId: set-node-claim + operationId: set-node-status security: - basicCredentials: [] parameters: @@ -269,12 +267,12 @@ paths: type: string format: binary - /account/public/available: + /account/public/status: get: tags: - account description: Check if a public account can be created. - operationId: get-public-available + operationId: get-public-status responses: '200': description: success @@ -1041,6 +1039,30 @@ paths: required: false # required for connected schema: type: string + - name: profileRevision + in: query + description: profile revision of contact + required: false # required for connected + schema: + type: string + - name: articleRevision + in: query + description: article revision of contact + required: false # required for connected + schema: + type: string + - name: channelRevision + in: query + description: channel revision of contact + required: false # required for connected + schema: + type: string + - name: viewRevision + in: query + description: view revision of contact + required: false # required for connected + schema: + type: string responses: '200': description: success @@ -1159,18 +1181,6 @@ paths: responses: '200': description: successful operation - content: - application/json: - schema: - type: object - required: - - status - properties: - token: - type: string - status: - type: string - enum: [ pending, confirmed, requested, connecting, connected ] '400': description: invalid data message '410': @@ -1474,12 +1484,36 @@ paths: type: integer format: int64 - /contact/content/revision: + /contact/article/revision: put: tags: - contact - description: Set content revision for contact. This is intend to be invoked automatically anytime a contact updates their content or sharing. Access granted to contact tokens. - operationId: set-content-revision + description: Set artcile revision for contact. This is intend to be invoked automatically anytime a contact updates their content or sharing. Access granted to contact tokens. + operationId: set-article-revision + security: + - bearerAuth: [] + responses: + '200': + description: revision set + '401': + description: not authorized + '410': + description: account disabled + '500': + description: internal server error + requestBody: + content: + application/json: + schema: + type: integer + format: int64 + + /contact/channel/revision: + put: + tags: + - contact + description: Set channel revision for contact. This is intend to be invoked automatically anytime a contact updates their content or sharing. Access granted to contact tokens. + operationId: set-channel-revision security: - bearerAuth: [] responses: @@ -1692,15 +1726,7 @@ paths: content: application/json: schema: - type: object - required: - - type - - data - properties: - type: - type: string - data: - type: string + $ref: '#/components/schemas/Subject' /attribute/articles/{articleId}/groups/{groupId}: put: @@ -2341,15 +2367,7 @@ paths: content: application/json: schema: - type: object - required: - - type - - data - properties: - type: - type: string - data: - type: string + $ref: '#/components/schemas/Subject' /content/channels/{channelId}/topics/{topicId}/assets: get: @@ -2804,7 +2822,7 @@ components: type: object required: - profile - - attribute + - article - group - channel - card @@ -2955,7 +2973,7 @@ components: id: type: string revision: - type: number + type: integer format: int64 data: $ref: '#/components/schemas/CardData' @@ -2966,7 +2984,7 @@ components: - detailRevision - profileRevision - notifiedProfile - - notifiedContent + - notifiedArticle - notifiedChannel - notifiedView properties: @@ -2979,7 +2997,7 @@ components: notifiedProfile: type: integer format: int64 - notifiedContent: + notifiedArticle: type: integer format: int64 notifiedChannel: @@ -3038,7 +3056,7 @@ components: required: - id - revision - - ata + - data properties: id: type: string @@ -3162,7 +3180,8 @@ components: id: type: string revision: - type: string + type: integer + format: int64 data: $ref: '#/components/schemas/TopicData' @@ -3232,7 +3251,8 @@ components: id: type: string revision: - type: string + type: integer + format: int64 data: $ref: '#/components/schemas/TagData' @@ -3268,7 +3288,8 @@ components: id: type: string revision: - type: string + type: integer + format: int64 data: $ref: '#/components/schemas/ArticleData' @@ -3378,12 +3399,15 @@ components: viewRevision: type: integer format: int64 - contentRevision: + articleRevision: type: integer format: int64 profileRevision: type: integer format: int64 + channelRevision: + type: integer + format: int64 handle: type: string name: @@ -3435,6 +3459,18 @@ components: properties: token: type: string + profileRevision: + type: integer + format: int64 + articleRevision: + type: integer + format: int64 + channelRevision: + type: integer + format: int64 + viewRevision: + type: integer + format: int64 status: type: string enum: [ pending, confirmed, requested, connecting, connected ] diff --git a/net/server/internal/api_account.go b/net/server/internal/api_account.go index bfc92961..440b070e 100644 --- a/net/server/internal/api_account.go +++ b/net/server/internal/api_account.go @@ -53,7 +53,17 @@ func GetAccountStatus(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) } -func GetPublicClaimable(w http.ResponseWriter, r *http.Request) { +func GetAccountToken(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + w.WriteHeader(http.StatusOK) +} + +func GetAccountUsername(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + w.WriteHeader(http.StatusOK) +} + +func GetPublicStatus(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_addArticle.go b/net/server/internal/api_addArticle.go deleted file mode 100644 index 81525748..00000000 --- a/net/server/internal/api_addArticle.go +++ /dev/null @@ -1,103 +0,0 @@ -package databag - -import ( - "time" - "errors" - "net/http" - "gorm.io/gorm" - "github.com/google/uuid" - "databag/internal/store" -) - -func AddArticle(w http.ResponseWriter, r *http.Request) { - - account, code, err := BearerAppToken(r, false) - if err != nil { - ErrResponse(w, code, err) - return - } - - var articleAccess ArticleAccess - if err := ParseRequest(r, w, &articleAccess); err != nil { - ErrResponse(w, http.StatusBadRequest, err) - return - } - - var groupSlots []store.GroupSlot - if err := store.DB.Preload("Group").Where("group_slot_id IN ?", articleAccess.Groups).Find(&groupSlots).Error; err != nil { - ErrResponse(w, http.StatusInternalServerError, err) - return - } - var groups []store.Group - for _, slot := range groupSlots { - if slot.Group != nil { - groups = append(groups, *slot.Group) - } - } - - var labelSlots []store.LabelSlot - if err := store.DB.Preload("Label").Where("label_slot_id IN ?", articleAccess.Labels).Find(&labelSlots).Error; err != nil { - ErrResponse(w, http.StatusInternalServerError, err) - return - } - var labels []store.Label - for _, slot := range labelSlots { - if slot.Label != nil { - labels = append(labels, *slot.Label) - } - } - - // save data and apply transaction - var slot *store.ArticleSlot - err = store.DB.Transaction(func(tx *gorm.DB) error { - - article := &store.Article{ - Status: APP_ARTICLEUNCONFIRMED, - TagUpdated: time.Now().Unix(), - TagRevision: 1, - TagCount: 0, - Groups: groups, - Labels: labels, - }; - if res := tx.Save(article).Error; res != nil { - return res; - } - - 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(), - AccountID: account.ID, - Revision: 1, - ArticleID: article.ID, - Article: article, - } - if ret := tx.Save(slot).Error; ret != nil { - return ret; - } - } else { - return res - } - } - if ret := tx.Model(slot).Update("article_id", article.ID).Error; ret != nil { - return ret; - } - 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 { - return ret - } - return nil - }) - if err != nil { - ErrResponse(w, http.StatusInternalServerError, err) - return - } - - SetContentNotification(account) - SetStatus(account) - WriteResponse(w, getArticleModel(slot, false, true)) -} - - diff --git a/net/server/internal/api_addLabel.go b/net/server/internal/api_addLabel.go deleted file mode 100644 index 7d1af9c1..00000000 --- a/net/server/internal/api_addLabel.go +++ /dev/null @@ -1,71 +0,0 @@ -package databag - -import ( - "net/http" - "errors" - "gorm.io/gorm" - "github.com/google/uuid" - "databag/internal/store" -) - -func AddLabel(w http.ResponseWriter, r *http.Request) { - - account, code, err := BearerAppToken(r, false) - if err != nil { - ErrResponse(w, code, err) - return - } - - var subject Subject - if err := ParseRequest(r, w, &subject); err != nil { - ErrResponse(w, http.StatusBadRequest, err) - return - } - - slot := &store.LabelSlot{} - label := &store.Label{} - err = store.DB.Transaction(func(tx *gorm.DB) error { - - data := &store.LabelData{ - Data: subject.Data, - } - if res := tx.Save(data).Error; res != nil { - return res - } - - label.LabelDataID = data.ID - label.LabelData = *data - label.DataType = subject.DataType - if res := tx.Save(label).Error; res != nil { - return res - } - - if res := tx.Where("account_id = ? AND label_id = 0", account.ID).First(slot).Error; res != nil { - if errors.Is(res, gorm.ErrRecordNotFound) { - slot.LabelSlotId = uuid.New().String() - slot.AccountID = account.ID - } else { - return res - } - } - slot.LabelID = label.ID - slot.Revision = account.LabelRevision + 1 - slot.Label = label - if res := tx.Save(slot).Error; res != nil { - return res - } - if res := tx.Model(&account).Update("label_revision", account.LabelRevision + 1).Error; res != nil { - return res - } - return nil - }) - if err != nil { - ErrResponse(w, http.StatusInternalServerError, err) - return - } - - SetStatus(account) - WriteResponse(w, getLabelModel(slot, true, true)) -} - - diff --git a/net/server/internal/api_admin.go b/net/server/internal/api_admin.go index 6f929e67..90c39a31 100644 --- a/net/server/internal/api_admin.go +++ b/net/server/internal/api_admin.go @@ -24,8 +24,8 @@ func GetNodeAccounts(w http.ResponseWriter, r *http.Request) { } func ImportAccount(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json; charset=UTF-8") - w.WriteHeader(http.StatusOK) + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + w.WriteHeader(http.StatusOK) } func RemoveNodeAccount(w http.ResponseWriter, r *http.Request) { diff --git a/net/server/internal/api_alias.go b/net/server/internal/api_alias.go new file mode 100644 index 00000000..839a7076 --- /dev/null +++ b/net/server/internal/api_alias.go @@ -0,0 +1,30 @@ +/* + * DataBag + * + * DataBag provides storage for decentralized identity based self-hosting apps. It is intended to support sharing of personal data and hosting group conversations. + * + * API version: 0.0.1 + * Contact: roland.osborne@gmail.com + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ +package databag + +import ( + "net/http" +) + +func GetGroups(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + w.WriteHeader(http.StatusOK) +} + +func RemoveGroup(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + w.WriteHeader(http.StatusOK) +} + +func UpdateGroup(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_attribute.go b/net/server/internal/api_attribute.go new file mode 100644 index 00000000..5a06ae7a --- /dev/null +++ b/net/server/internal/api_attribute.go @@ -0,0 +1,50 @@ +/* + * DataBag + * + * DataBag provides storage for decentralized identity based self-hosting apps. It is intended to support sharing of personal data and hosting group conversations. + * + * API version: 0.0.1 + * Contact: roland.osborne@gmail.com + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ +package databag + +import ( + "net/http" +) + +func AddArticle(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + w.WriteHeader(http.StatusOK) +} + +func ClearArticleGroup(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + w.WriteHeader(http.StatusOK) +} + +func GetArticleSubjectField(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + w.WriteHeader(http.StatusOK) +} + +func GetArticles(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + w.WriteHeader(http.StatusOK) +} + +func RemoveArticle(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + w.WriteHeader(http.StatusOK) +} + +func SetArticleGroup(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + w.WriteHeader(http.StatusOK) +} + +func SetArticleSubject(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_authorize.go b/net/server/internal/api_authorize.go index 8aca42b7..1de09b92 100644 --- a/net/server/internal/api_authorize.go +++ b/net/server/internal/api_authorize.go @@ -1,3 +1,12 @@ +/* + * DataBag + * + * DataBag provides storage for decentralized identity based self-hosting apps. It is intended to support sharing of personal data and hosting group conversations. + * + * API version: 0.0.1 + * Contact: roland.osborne@gmail.com + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ package databag import ( @@ -5,30 +14,7 @@ import ( ) func Authorize(w http.ResponseWriter, r *http.Request) { - - account, code, res := BearerAppToken(r, true); - if res != nil { - ErrResponse(w, code, res) - return - } - detail := account.AccountDetail - - // extract token from body - var token string - res = ParseRequest(r, w, &token) - if res != nil { - ErrResponse(w, http.StatusBadRequest, res) - return - } - - // generate auth DataMessage - auth := Authenticate{ Token: token } - msg, res := WriteDataMessage(detail.PrivateKey, detail.PublicKey, detail.KeyType, - APP_SIGNPKCS1V15, account.Guid, APP_MSGAUTHENTICATE, &auth) - if res != nil { - ErrResponse(w, http.StatusInternalServerError, res) - return - } - - WriteResponse(w, msg) + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + w.WriteHeader(http.StatusOK) } + diff --git a/net/server/internal/api_clearCardNotes.go b/net/server/internal/api_clearCardNotes.go deleted file mode 100644 index a8d695d0..00000000 --- a/net/server/internal/api_clearCardNotes.go +++ /dev/null @@ -1,64 +0,0 @@ -package databag - -import ( - "errors" - "net/http" - "gorm.io/gorm" - "github.com/gorilla/mux" - "databag/internal/store" -) - -func ClearCardNotes(w http.ResponseWriter, r *http.Request) { - - account, code, err := BearerAppToken(r, false); - if err != nil { - ErrResponse(w, code, err) - return - } - - // scan parameters - params := mux.Vars(r) - cardId := params["cardId"] - - // load referenced card - 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 { - ErrResponse(w, http.StatusNotFound, err) - } - return - } - if slot.Card == nil { - ErrResponse(w, http.StatusNotFound, errors.New("card has been deleted")) - return - } - - // update card - slot.Revision = account.CardRevision + 1 - slot.Card.DetailRevision += 1 - slot.Card.Notes = "" - - // save and update contact revision - err = store.DB.Transaction(func(tx *gorm.DB) error { - 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 { - return res - } - return nil - }) - if err != nil { - ErrResponse(w, http.StatusInternalServerError, err) - return - } - - SetStatus(account) - WriteResponse(w, getCardDetailModel(&slot)); -} - diff --git a/net/server/internal/api_contact.go b/net/server/internal/api_contact.go index df012248..75422d53 100644 --- a/net/server/internal/api_contact.go +++ b/net/server/internal/api_contact.go @@ -18,12 +18,7 @@ func ClearCardGroup(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) } -func GetCardDetail(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json; charset=UTF-8") - w.WriteHeader(http.StatusOK) -} - -func GetCardProfile(w http.ResponseWriter, r *http.Request) { +func ClearCardNotes(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.WriteHeader(http.StatusOK) } @@ -33,6 +28,11 @@ func GetCardProfileImage(w http.ResponseWriter, r *http.Request) { 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) @@ -43,6 +43,16 @@ func RemoveCard(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) } +func SetCardNotes(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + w.WriteHeader(http.StatusOK) +} + +func SetCardProfile(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + w.WriteHeader(http.StatusOK) +} + func SetCloseMessage(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_content.go b/net/server/internal/api_content.go index c76347ff..2c6e66f1 100644 --- a/net/server/internal/api_content.go +++ b/net/server/internal/api_content.go @@ -13,107 +13,132 @@ import ( "net/http" ) -func AddArticleAsset(w http.ResponseWriter, r *http.Request) { +func AddChannel(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.WriteHeader(http.StatusOK) } -func AddArticleTag(w http.ResponseWriter, r *http.Request) { +func AddChannelAsset(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.WriteHeader(http.StatusOK) } -func ClearArticleGroup(w http.ResponseWriter, r *http.Request) { +func AddChannelTopic(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.WriteHeader(http.StatusOK) } -func ClearArticleLabel(w http.ResponseWriter, r *http.Request) { +func AddChannelTopicTag(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.WriteHeader(http.StatusOK) } -func ClearLabelGroup(w http.ResponseWriter, r *http.Request) { +func ClearChannelGroup(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.WriteHeader(http.StatusOK) } -func GetArticle(w http.ResponseWriter, r *http.Request) { +func GetChannelAsset(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.WriteHeader(http.StatusOK) } -func GetArticleAsset(w http.ResponseWriter, r *http.Request) { +func GetChannelAssets(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.WriteHeader(http.StatusOK) } -func GetArticleAssets(w http.ResponseWriter, r *http.Request) { +func GetChannelDetail(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.WriteHeader(http.StatusOK) } -func GetArticleSubjectField(w http.ResponseWriter, r *http.Request) { +func GetChannelSize(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.WriteHeader(http.StatusOK) } -func GetArticleTag(w http.ResponseWriter, r *http.Request) { +func GetChannelSubjectField(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.WriteHeader(http.StatusOK) } -func GetArticleTagBlockView(w http.ResponseWriter, r *http.Request) { +func GetChannelTopicDetail(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.WriteHeader(http.StatusOK) } -func GetArticleTagSubjectField(w http.ResponseWriter, r *http.Request) { +func GetChannelTopicSize(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.WriteHeader(http.StatusOK) } -func GetArticleTagView(w http.ResponseWriter, r *http.Request) { +func GetChannelTopicSubjectField(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.WriteHeader(http.StatusOK) } -func GetArticleTags(w http.ResponseWriter, r *http.Request) { +func GetChannelTopicTagSubjectField(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.WriteHeader(http.StatusOK) } -func RemoveArticleAsset(w http.ResponseWriter, r *http.Request) { +func GetChannelTopicTags(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.WriteHeader(http.StatusOK) } -func RemoveArticleTag(w http.ResponseWriter, r *http.Request) { +func GetChannelTopics(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.WriteHeader(http.StatusOK) } -func SetArticleConfirmed(w http.ResponseWriter, r *http.Request) { +func GetChannels(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.WriteHeader(http.StatusOK) } -func SetArticleExpiration(w http.ResponseWriter, r *http.Request) { +func RemoveChannel(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.WriteHeader(http.StatusOK) } -func SetArticleGroup(w http.ResponseWriter, r *http.Request) { +func RemoveChannelAsset(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.WriteHeader(http.StatusOK) } -func SetArticleSubject(w http.ResponseWriter, r *http.Request) { +func RemoveChannelTopic(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.WriteHeader(http.StatusOK) } -func UpdateLabel(w http.ResponseWriter, r *http.Request) { +func RemoveChannelTopicTag(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + w.WriteHeader(http.StatusOK) +} + +func SetChannelConfirmed(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + w.WriteHeader(http.StatusOK) +} + +func SetChannelGroup(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + w.WriteHeader(http.StatusOK) +} + +func SetChannelSubject(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + w.WriteHeader(http.StatusOK) +} + +func SetChannelTopicSubject(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + w.WriteHeader(http.StatusOK) +} + +func SetChannelTopicTagSubject(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_conversation.go b/net/server/internal/api_conversation.go deleted file mode 100644 index a68a4e7c..00000000 --- a/net/server/internal/api_conversation.go +++ /dev/null @@ -1,174 +0,0 @@ -/* - * DataBag - * - * DataBag provides storage for decentralized identity based self-hosting apps. It is intended to support sharing of personal data and hosting group conversations. - * - * API version: 0.0.1 - * Contact: roland.osborne@gmail.com - * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) - */ -package databag - -import ( - "net/http" -) - -func AddDialogue(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json; charset=UTF-8") - w.WriteHeader(http.StatusOK) -} - -func AddDialogueInsight(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json; charset=UTF-8") - w.WriteHeader(http.StatusOK) -} - -func AddDialogueTopic(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json; charset=UTF-8") - w.WriteHeader(http.StatusOK) -} - -func AddInsightDialogue(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json; charset=UTF-8") - w.WriteHeader(http.StatusOK) -} - -func AddTopicAsset(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json; charset=UTF-8") - w.WriteHeader(http.StatusOK) -} - -func AddTopicTag(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json; charset=UTF-8") - w.WriteHeader(http.StatusOK) -} - -func ConversationDialoguesDialogueIdTopicsTopicIdConfirmedPut(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json; charset=UTF-8") - w.WriteHeader(http.StatusOK) -} - -func GetDialogueTopic(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json; charset=UTF-8") - w.WriteHeader(http.StatusOK) -} - -func GetDialogueTopicSubjectField(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json; charset=UTF-8") - w.WriteHeader(http.StatusOK) -} - -func GetDialogues(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json; charset=UTF-8") - w.WriteHeader(http.StatusOK) -} - -func GetInsights(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json; charset=UTF-8") - w.WriteHeader(http.StatusOK) -} - -func GetTopicAsset(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json; charset=UTF-8") - w.WriteHeader(http.StatusOK) -} - -func GetTopicAssets(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json; charset=UTF-8") - w.WriteHeader(http.StatusOK) -} - -func GetTopicBlock(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json; charset=UTF-8") - w.WriteHeader(http.StatusOK) -} - -func GetTopicBlockView(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json; charset=UTF-8") - w.WriteHeader(http.StatusOK) -} - -func GetTopicTag(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json; charset=UTF-8") - w.WriteHeader(http.StatusOK) -} - -func GetTopicTagBlockView(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json; charset=UTF-8") - w.WriteHeader(http.StatusOK) -} - -func GetTopicTagSubjectField(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json; charset=UTF-8") - w.WriteHeader(http.StatusOK) -} - -func GetTopicTagView(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json; charset=UTF-8") - w.WriteHeader(http.StatusOK) -} - -func GetTopicTags(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json; charset=UTF-8") - w.WriteHeader(http.StatusOK) -} - -func GetTopicViews(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json; charset=UTF-8") - w.WriteHeader(http.StatusOK) -} - -func RemoveDialogue(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json; charset=UTF-8") - w.WriteHeader(http.StatusOK) -} - -func RemoveDialogueInsight(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json; charset=UTF-8") - w.WriteHeader(http.StatusOK) -} - -func RemoveDialogueTopic(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json; charset=UTF-8") - w.WriteHeader(http.StatusOK) -} - -func RemoveTopicAsset(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json; charset=UTF-8") - w.WriteHeader(http.StatusOK) -} - -func RemoveTopicTag(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json; charset=UTF-8") - w.WriteHeader(http.StatusOK) -} - -func SetDialogueActive(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json; charset=UTF-8") - w.WriteHeader(http.StatusOK) -} - -func SetDialogueInsightStatus(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json; charset=UTF-8") - w.WriteHeader(http.StatusOK) -} - -func SetDialogueSubject(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json; charset=UTF-8") - w.WriteHeader(http.StatusOK) -} - -func SetInsightDialogue(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json; charset=UTF-8") - w.WriteHeader(http.StatusOK) -} - -func SetInsightStatus(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json; charset=UTF-8") - w.WriteHeader(http.StatusOK) -} - -func SetTopicSubject(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_getArticles.go b/net/server/internal/api_getArticles.go deleted file mode 100644 index a832cd82..00000000 --- a/net/server/internal/api_getArticles.go +++ /dev/null @@ -1,125 +0,0 @@ -package databag - -import ( - "errors" - "strconv" - "net/http" - "databag/internal/store" -) - -func GetArticles(w http.ResponseWriter, r *http.Request) { - var res error - var viewRevision int64 - var contentRevision int64 - var revisionSet bool - - view := r.FormValue("viewRevision") - if view != "" { - if viewRevision, res = strconv.ParseInt(view, 10, 64); res != nil { - ErrResponse(w, http.StatusBadRequest, res) - return - } - } - content := r.FormValue("contentRevision") - if content != "" { - if contentRevision, res = strconv.ParseInt(content, 10, 64); res != nil { - ErrResponse(w, http.StatusBadRequest, res) - return - } - revisionSet = true - } - - tokenType := r.Header.Get("TokenType") - var response []*Article - if tokenType == APP_TOKENAPP { - - account, code, err := BearerAppToken(r, false) - if err != nil { - ErrResponse(w, code, err) - return - } - - var articles []store.ArticleSlot - if err := getAccountArticles(account, contentRevision, &articles); err != nil { - ErrResponse(w, http.StatusInternalServerError, err) - return - } - - for _, article := range articles { - response = append(response, getArticleModel(&article, false, true)) - } - - w.Header().Set("Content-Revision", strconv.FormatInt(account.ContentRevision, 10)) - } else if tokenType == APP_TOKENCONTACT { - - card, code, err := BearerContactToken(r, false) - if err != nil { - ErrResponse(w, code, err) - return - } - - if viewRevision != card.ViewRevision { - if revisionSet { - ErrResponse(w, http.StatusGone, errors.New("article view unavailable")) - return - } - } - - var articles []store.ArticleSlot - if err := getContactArticles(card, contentRevision, &articles); err != nil { - ErrResponse(w, http.StatusInternalServerError, err) - return - } - - for _, article := range articles { - if isArticleShared(&article, card.Guid) { - response = append(response, getArticleModel(&article, true, true)) - } else if revisionSet { - response = append(response, getArticleModel(&article, true, false)) - } - } - - w.Header().Set("View-Revision", strconv.FormatInt(card.ViewRevision, 10)) - w.Header().Set("Content-Revision", strconv.FormatInt(card.Account.ContentRevision, 10)) - } else { - ErrResponse(w, http.StatusBadRequest, errors.New("invalid token type")) - } - - WriteResponse(w, response) -} - -// better if this filtering was done in gorm or sql -func isArticleShared(slot *store.ArticleSlot, guid string) bool { - if slot.Article == nil { - return false - } - for _, group := range slot.Article.Groups { - for _, card := range group.Cards { - if card.Guid == guid { - return true - } - } - } - for _, label := range slot.Article.Labels { - for _, group := range label.Groups { - for _, card := range group.Cards { - if card.Guid == guid { - return true - } - } - } - } - return false -} - -func getAccountArticles(account *store.Account, revision int64, articles *[]store.ArticleSlot) error { - return store.DB.Preload("Article.Labels.LabelSlot").Preload("Article.Groups.GroupSlot").Preload("Article.Labels.Groups.GroupSlot").Where("account_id = ? AND revision > ?", account.ID, revision).Find(articles).Error -} - -func getContactArticles(card *store.Card, revision int64, articles *[]store.ArticleSlot) error { - return store.DB.Preload("Article.Labels.LabelSlot").Preload("Article.Groups.Cards").Preload("Article.Labels.Groups.Cards").Where("account_id = ? AND revision > ?", card.Account.ID, revision).Find(articles).Error -} - - - - diff --git a/net/server/internal/api_getCard.go b/net/server/internal/api_getCardDetail.go similarity index 73% rename from net/server/internal/api_getCard.go rename to net/server/internal/api_getCardDetail.go index 2a122b23..76b35051 100644 --- a/net/server/internal/api_getCard.go +++ b/net/server/internal/api_getCardDetail.go @@ -8,7 +8,7 @@ import ( "databag/internal/store" ) -func GetCard(w http.ResponseWriter, r *http.Request) { +func GetCardDetail(w http.ResponseWriter, r *http.Request) { account, code, err := BearerAppToken(r, false); if err != nil { @@ -26,7 +26,11 @@ func GetCard(w http.ResponseWriter, r *http.Request) { } return } + if slot.Card == nil { + ErrResponse(w, http.StatusNotFound, errors.New("referenced empty card slot")) + return + } - WriteResponse(w, getCardModel(&slot)) + WriteResponse(w, getCardDetailModel(&slot)) } diff --git a/net/server/internal/api_getCardProfile.go b/net/server/internal/api_getCardProfile.go new file mode 100644 index 00000000..ee30369e --- /dev/null +++ b/net/server/internal/api_getCardProfile.go @@ -0,0 +1,36 @@ +package databag + +import ( + "errors" + "net/http" + "gorm.io/gorm" + "github.com/gorilla/mux" + "databag/internal/store" +) + +func GetCardProfile(w http.ResponseWriter, r *http.Request) { + + 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 empty card slot")) + return + } + + WriteResponse(w, getCardProfileModel(&slot)) +} + diff --git a/net/server/internal/api_getCards.go b/net/server/internal/api_getCards.go deleted file mode 100644 index 3d55f78d..00000000 --- a/net/server/internal/api_getCards.go +++ /dev/null @@ -1,40 +0,0 @@ -package databag - -import ( - "strconv" - "net/http" - "databag/internal/store" -) - -func GetCards(w http.ResponseWriter, r *http.Request) { - var res error - var cardRevision int64 - - card := r.FormValue("cardRevision") - if card != "" { - if cardRevision, res = strconv.ParseInt(card, 10, 64); res != nil { - ErrResponse(w, http.StatusBadRequest, res) - return - } - } - - account, code, err := BearerAppToken(r, false); - if err != nil { - ErrResponse(w, code, err) - return - } - - var slots []store.CardSlot - if err := store.DB.Preload("Card.Groups.GroupSlot").Where("account_id = ? AND revision > ?", account.ID, cardRevision).Find(&slots).Error; err != nil { - ErrResponse(w, http.StatusInternalServerError, err) - return - } - - var response []*Card - 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_getGroups.go b/net/server/internal/api_getGroups.go deleted file mode 100644 index 0814b373..00000000 --- a/net/server/internal/api_getGroups.go +++ /dev/null @@ -1,41 +0,0 @@ -package databag - -import ( - "strconv" - "net/http" - "databag/internal/store" -) - -func GetGroups(w http.ResponseWriter, r *http.Request) { - var res error - var groupRevision int64 - - group := r.FormValue("groupRevision") - if group != "" { - if groupRevision, res = strconv.ParseInt(group, 10, 64); res != nil { - ErrResponse(w, http.StatusBadRequest, res) - return - } - } - - account, code, err := BearerAppToken(r, false) - if err != nil { - ErrResponse(w, code, err) - return - } - - var slots []store.GroupSlot - if err := store.DB.Preload("Group").Where("account_id = ? AND revision > ?", account.ID, groupRevision).Find(&slots).Error; err != nil { - ErrResponse(w, http.StatusInternalServerError, err) - return - } - - var groups []*Group - for _, slot := range slots { - groups = append(groups, getGroupModel(&slot)) - } - - w.Header().Set("Group-Revision", strconv.FormatInt(account.GroupRevision, 10)) - WriteResponse(w, groups) -} - diff --git a/net/server/internal/api_getLabels.go b/net/server/internal/api_getLabels.go deleted file mode 100644 index ac57e006..00000000 --- a/net/server/internal/api_getLabels.go +++ /dev/null @@ -1,116 +0,0 @@ -package databag - -import ( - "errors" - "strconv" - "net/http" - "databag/internal/store" -) - -func GetLabels(w http.ResponseWriter, r *http.Request) { - var res error - var viewRevision int64 - var labelRevision int64 - var revisionSet bool - - view := r.FormValue("viewRevision") - if view != "" { - if viewRevision, res = strconv.ParseInt(view, 10, 64); res != nil { - ErrResponse(w, http.StatusBadRequest, res) - return - } - } - label := r.FormValue("labelRevision") - if label != "" { - if labelRevision, res = strconv.ParseInt(label, 10, 64); res != nil { - ErrResponse(w, http.StatusBadRequest, res) - return - } - revisionSet = true - } - - tokenType := r.Header.Get("TokenType") - var response []*Label - if tokenType == APP_TOKENAPP { - - account, code, err := BearerAppToken(r, false) - if err != nil { - ErrResponse(w, code, err) - return - } - - var labels []store.LabelSlot - if err := getAccountLabels(account, labelRevision, &labels); err != nil { - ErrResponse(w, http.StatusInternalServerError, err) - return - } - - for _, label := range labels { - response = append(response, getLabelModel(&label, false, true)) - } - - w.Header().Set("Label-Revision", strconv.FormatInt(account.LabelRevision, 10)) - } else if tokenType == APP_TOKENCONTACT { - - card, code, err := BearerContactToken(r, false) - if err != nil { - ErrResponse(w, code, err) - return - } - - if viewRevision != card.ViewRevision { - if revisionSet { - ErrResponse(w, http.StatusGone, errors.New("label view unavailable")) - return - } - } - - var labels []store.LabelSlot - if err := getContactLabels(card, labelRevision, &labels); err != nil { - ErrResponse(w, http.StatusInternalServerError, err) - return - } - - for _, label := range labels { - if isLabelShared(&label, card.Guid) { - response = append(response, getLabelModel(&label, true, true)) - } else if revisionSet { - response = append(response, getLabelModel(&label, true, false)) - } - } - - w.Header().Set("View-Revision", strconv.FormatInt(card.ViewRevision, 10)) - w.Header().Set("Label-Revision", strconv.FormatInt(card.Account.LabelRevision, 10)) - } else { - ErrResponse(w, http.StatusBadRequest, errors.New("invalid token type")) - } - - WriteResponse(w, response) -} - -// better if this filtering was done in gorm or sql -func isLabelShared(slot *store.LabelSlot, guid string) bool { - if slot.Label == nil { - return false - } - for _, group := range slot.Label.Groups { - for _, card := range group.Cards { - if card.Guid == guid { - return true - } - } - } - return false -} - -func getAccountLabels(account *store.Account, revision int64, labels *[]store.LabelSlot) error { - return store.DB.Preload("Label.Groups.GroupSlot").Where("account_id = ? AND revision > ?", account.ID, revision).Find(labels).Error -} - -func getContactLabels(card *store.Card, revision int64, labels *[]store.LabelSlot) error { - return store.DB.Preload("Label.Groups.Cards").Where("account_id = ? AND revision > ?", card.Account.ID, revision).Find(labels).Error -} - - - - diff --git a/net/server/internal/api_getNodeClaimable.go b/net/server/internal/api_getNodeStatus.go similarity index 86% rename from net/server/internal/api_getNodeClaimable.go rename to net/server/internal/api_getNodeStatus.go index 3ceec5ad..4b71b325 100644 --- a/net/server/internal/api_getNodeClaimable.go +++ b/net/server/internal/api_getNodeStatus.go @@ -7,7 +7,7 @@ import ( "databag/internal/store" ) -func GetNodeClaimable(w http.ResponseWriter, r *http.Request) { +func GetNodeStatus(w http.ResponseWriter, r *http.Request) { var config store.Config err := store.DB.Where("config_id = ?", CONFIG_CONFIGURED).First(&config).Error if err != nil { diff --git a/net/server/internal/api_getOpenMessage.go b/net/server/internal/api_getOpenMessage.go index 743489d4..737b531d 100644 --- a/net/server/internal/api_getOpenMessage.go +++ b/net/server/internal/api_getOpenMessage.go @@ -40,10 +40,10 @@ func GetOpenMessage(w http.ResponseWriter, r *http.Request) { connect := &Connect{ Contact: slot.Card.Guid, Token: slot.Card.InToken, - ContentRevision: account.ContentRevision, + ArticleRevision: account.ArticleRevision, ProfileRevision: account.ProfileRevision, ViewRevision: slot.Card.ViewRevision, - LabelRevision: account.LabelRevision, + ChannelRevision: account.ChannelRevision, Handle: account.Username, Name: detail.Name, Description: detail.Description, diff --git a/net/server/internal/api_getProfile.go b/net/server/internal/api_getProfile.go deleted file mode 100644 index 0194980f..00000000 --- a/net/server/internal/api_getProfile.go +++ /dev/null @@ -1,30 +0,0 @@ -package databag - -import ( - "net/http" -) - -func GetProfile(w http.ResponseWriter, r *http.Request) { - - account, code, err := BearerAppToken(r, true); - if err != nil { - ErrResponse(w, code, err) - return - } - detail := account.AccountDetail - - // send profile data - profile := Profile { - Guid: account.Guid, - Handle: account.Username, - Name: detail.Name, - Description: detail.Description, - Location: detail.Location, - Image: detail.Image, - Revision: account.ProfileRevision, - Version: APP_VERSION, - Node: "https://" + getStrConfigValue(CONFIG_DOMAIN, "") + "/", - } - WriteResponse(w, profile) -} - diff --git a/net/server/internal/api_profile.go b/net/server/internal/api_profile.go index 8e04ef7e..193dece4 100644 --- a/net/server/internal/api_profile.go +++ b/net/server/internal/api_profile.go @@ -13,11 +13,21 @@ import ( "net/http" ) +func GetProfile(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + w.WriteHeader(http.StatusOK) +} + func GetProfileImage(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.WriteHeader(http.StatusOK) } +func SetProfile(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + w.WriteHeader(http.StatusOK) +} + func SetProfileImage(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_removeArticle.go b/net/server/internal/api_removeArticle.go deleted file mode 100644 index b2198b04..00000000 --- a/net/server/internal/api_removeArticle.go +++ /dev/null @@ -1,63 +0,0 @@ -package databag - -import ( - "errors" - "net/http" - "gorm.io/gorm" - "github.com/gorilla/mux" - "databag/internal/store" -) - -func RemoveArticle(w http.ResponseWriter, r *http.Request) { - - account, code, err := BearerAppToken(r, false) - if err != nil { - ErrResponse(w, code, err) - return - } - - params := mux.Vars(r) - articleId := params["articleId"] - - err = store.DB.Transaction(func(tx *gorm.DB) error { - var slot store.ArticleSlot - if res := store.DB.Preload("Article").Where("account_id = ? AND article_slot_id = ?", account.ID, articleId).First(&slot).Error; res != nil { - return res - } - if slot.Article == nil { - return nil - } - if res := tx.Model(slot.Article).Association("Groups").Clear(); res != nil { - return res - } - if res := tx.Model(slot.Article).Association("Labels").Clear(); res != nil { - return res - } - if res := tx.Delete(slot.Article).Error; res != nil { - return res - } - slot.ArticleID = 0 - slot.Revision = account.ContentRevision + 1 - slot.Article = nil - if res := tx.Save(&slot).Error; res != nil { - return res - } - if res := tx.Model(&account).Update("content_revision", account.ContentRevision + 1).Error; res != nil { - return res - } - return nil - }) - if err != nil { - if errors.Is(err, gorm.ErrRecordNotFound) { - ErrResponse(w, http.StatusNotFound, err) - } else { - ErrResponse(w, http.StatusInternalServerError, err) - } - return - } - - SetContentNotification(account) - SetStatus(account) - WriteResponse(w, nil) -} - diff --git a/net/server/internal/api_removeGroup.go b/net/server/internal/api_removeGroup.go deleted file mode 100644 index ee25a982..00000000 --- a/net/server/internal/api_removeGroup.go +++ /dev/null @@ -1,68 +0,0 @@ -package databag - -import ( - "errors" - "net/http" - "gorm.io/gorm" - "github.com/gorilla/mux" - "databag/internal/store" -) - -func RemoveGroup(w http.ResponseWriter, r *http.Request) { - - account, code, err := BearerAppToken(r, false) - if err != nil { - ErrResponse(w, code, err) - return - } - params := mux.Vars(r) - groupId := params["groupId"] - - var slot store.GroupSlot - if err := store.DB.Preload("Group.GroupData").Preload("Group.Cards").Where("account_id = ? AND group_slot_id = ?", account.ID, groupId).First(&slot).Error; err != nil { - if errors.Is(err, gorm.ErrRecordNotFound) { - ErrResponse(w, http.StatusNotFound, err) - } else { - ErrResponse(w, http.StatusInternalServerError, err) - } - return - } - cards := slot.Group.Cards - notify := []*store.Card{} - - err = store.DB.Transaction(func(tx *gorm.DB) error { - if res := tx.Model(slot.Group).Association("Cards").Clear(); res != nil { - return res - } - if res := tx.Delete(&slot.Group.GroupData).Error; res != nil { - return res - } - if res := tx.Delete(&slot.Group).Error; res != nil { - return res - } - for _, card := range cards { - if res := tx.Model(&card).Update("ViewRevision", card.ViewRevision + 1).Error; res != nil { - return res - } - notify = append(notify, &card) - } - slot.GroupID = 0 - slot.Group = nil - slot.Revision = account.GroupRevision + 1 - if res := tx.Save(&slot).Error; res != nil { - return res - } - return nil - }) - if err != nil { - ErrResponse(w, http.StatusInternalServerError, err) - return - } - - for _, card := range notify { - SetContactViewNotification(account, card) - } - SetStatus(account) - WriteResponse(w, nil) -} - diff --git a/net/server/internal/api_removeLabel.go b/net/server/internal/api_removeLabel.go deleted file mode 100644 index 2202d0a8..00000000 --- a/net/server/internal/api_removeLabel.go +++ /dev/null @@ -1,74 +0,0 @@ -package databag - -import ( - "errors" - "net/http" - "gorm.io/gorm" - "github.com/gorilla/mux" - "databag/internal/store" -) - -func RemoveLabel(w http.ResponseWriter, r *http.Request) { - - account, code, err := BearerAppToken(r, false) - if err != nil { - ErrResponse(w, code, err) - return - } - params := mux.Vars(r) - labelId := params["labelId"] - - var slot store.LabelSlot - if err := store.DB.Preload("Label.LabelData").Preload("Label.Groups.Cards").Where("account_id = ? AND label_slot_id = ?", account.ID, labelId).First(&slot).Error; err != nil { - if errors.Is(err, gorm.ErrRecordNotFound) { - ErrResponse(w, http.StatusNotFound, err) - } else { - ErrResponse(w, http.StatusInternalServerError, err) - } - return - } - groups := slot.Label.Groups - notify := map[string]*store.Card{} - - err = store.DB.Transaction(func(tx *gorm.DB) error { - if res := tx.Model(slot.Label).Association("Groups").Clear(); res != nil { - return res - } - if res := tx.Delete(&slot.Label.LabelData).Error; res != nil { - return res - } - if res := tx.Delete(&slot.Label).Error; res != nil { - return res - } - for _, group := range groups { - for _, card := range group.Cards { - if res := tx.Model(&card).Update("ViewRevision", card.ViewRevision + 1).Error; res != nil { - return res - } - notify[card.Guid] = &card - } - } - - slot.LabelID = 0 - slot.Label = nil - slot.Revision = account.LabelRevision + 1 - if res := tx.Save(&slot).Error; res != nil { - return res - } - if res := tx.Model(&account).Updates(store.Account{LabelRevision: account.LabelRevision + 1}).Error; res != nil { - return res - } - return nil - }) - if err != nil { - ErrResponse(w, http.StatusInternalServerError, err) - return - } - - for _, card := range notify { - SetContactViewNotification(account, card) - } - SetStatus(account) - WriteResponse(w, nil) -} - diff --git a/net/server/internal/api_setArticleLabel.go b/net/server/internal/api_setArticleLabel.go deleted file mode 100644 index 382d8ee5..00000000 --- a/net/server/internal/api_setArticleLabel.go +++ /dev/null @@ -1,76 +0,0 @@ -package databag - -import ( - "errors" - "net/http" - "gorm.io/gorm" - "github.com/gorilla/mux" - "databag/internal/store" -) - -func SetArticleLabel(w http.ResponseWriter, r *http.Request) { - - account, code, err := BearerAppToken(r, false); - if err != nil { - ErrResponse(w, code, err) - return - } - - // scan parameters - params := mux.Vars(r) - articleId := params["articleId"] - labelId := params["labelId"] - - labelSlot := &store.LabelSlot{} - if err := store.DB.Preload("Label.LabelSlot").Where("account_id = ? AND label_slot_id = ?", account.ID, labelId).First(&labelSlot).Error; err != nil { - if !errors.Is(err, gorm.ErrRecordNotFound) { - ErrResponse(w, http.StatusInternalServerError, err) - } else { - ErrResponse(w, http.StatusNotFound, err) - } - return - } - if labelSlot.Label == nil { - ErrResponse(w, http.StatusNotFound, errors.New("referenced empty label slot")) - return - } - - articleSlot := &store.ArticleSlot{} - if err := store.DB.Preload("Article.Labels.LabelSlot").Preload("Article.Groups.GroupSlot").Where("account_id = ? AND article_slot_id = ?", account.ID, articleId).First(&articleSlot).Error; err != nil { - if !errors.Is(err, gorm.ErrRecordNotFound) { - ErrResponse(w, http.StatusInternalServerError, err) - } else { - ErrResponse(w, http.StatusNotFound, err) - } - return - } - if articleSlot.Article == nil { - ErrResponse(w, http.StatusNotFound, errors.New("referenced empty article slot")) - return - } - - err = store.DB.Transaction(func(tx *gorm.DB) error { - - if res := tx.Model(articleSlot.Article).Association("Labels").Append(labelSlot.Label); res != nil { - return res - } - - if res := tx.Model(articleSlot).Update("revision", account.ContentRevision + 1).Error; res != nil { - return res - } - - if res := tx.Model(account).Update("content_revision", account.ContentRevision + 1).Error; res != nil { - return res - } - - return nil - }) - if err != nil { - ErrResponse(w, http.StatusInternalServerError, err) - return - } - - SetContentNotification(account) - SetStatus(account) - WriteResponse(w, getArticleModel(articleSlot, false, true)) -} diff --git a/net/server/internal/api_setContentRevision.go b/net/server/internal/api_setArticleRevision.go similarity index 76% rename from net/server/internal/api_setContentRevision.go rename to net/server/internal/api_setArticleRevision.go index 70f20887..8a38ad9d 100644 --- a/net/server/internal/api_setContentRevision.go +++ b/net/server/internal/api_setArticleRevision.go @@ -6,7 +6,7 @@ import ( "databag/internal/store" ) -func SetContentRevision(w http.ResponseWriter, r *http.Request) { +func SetArticleRevision(w http.ResponseWriter, r *http.Request) { card, code, err := BearerContactToken(r, false) if err != nil { @@ -20,7 +20,7 @@ func SetContentRevision(w http.ResponseWriter, r *http.Request) { return } - if err := NotifyProfileRevision(card, revision); err != nil { + if err := NotifyArticleRevision(card, revision); err != nil { ErrResponse(w, http.StatusInternalServerError, err) return } @@ -28,17 +28,17 @@ func SetContentRevision(w http.ResponseWriter, r *http.Request) { WriteResponse(w, nil) } -func NotifyContentRevision(card *store.Card, revision int64) error { +func NotifyArticleRevision(card *store.Card, revision int64) error { act := &card.Account err := store.DB.Transaction(func(tx *gorm.DB) error { - if res := tx.Model(card).Where("id = ?", card.ID).Update("notified_content", revision).Error; res != nil { + if res := tx.Model(card).Where("id = ?", card.ID).Update("notified_profile", revision).Error; res != nil { return res } if res := tx.Model(&card.CardSlot).Where("id = ?", card.CardSlot.ID).Update("revision", act.CardRevision+1).Error; res != nil { return res } - if res := tx.Model(act).Where("id = ?", act.ID).Update("card_revision", act.CardRevision + 1).Error; res != nil { + if res := tx.Model(act).Where("id = ?", act.ID).Update("card_revision", act.CardRevision+1).Error; res != nil { return res } return nil diff --git a/net/server/internal/api_setCardNotes.go b/net/server/internal/api_setCardNotes.go deleted file mode 100644 index d0aadae3..00000000 --- a/net/server/internal/api_setCardNotes.go +++ /dev/null @@ -1,70 +0,0 @@ -package databag - -import ( - "errors" - "net/http" - "gorm.io/gorm" - "github.com/gorilla/mux" - "databag/internal/store" -) - -func SetCardNotes(w http.ResponseWriter, r *http.Request) { - - account, code, err := BearerAppToken(r, false); - if err != nil { - ErrResponse(w, code, err) - return - } - - // scan parameters - params := mux.Vars(r) - cardId := params["cardId"] - - var notes string - if err := ParseRequest(r, w, ¬es); err != nil { - ErrResponse(w, http.StatusBadRequest, err) - return - } - - // load referenced card - 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 { - ErrResponse(w, http.StatusNotFound, err) - } - return - } - if slot.Card == nil { - ErrResponse(w, http.StatusNotFound, errors.New("card has been deleted")) - return - } - - // update card - slot.Revision = account.CardRevision + 1 - slot.Card.DetailRevision += 1 - slot.Card.Notes = notes - - // save and update contact revision - err = store.DB.Transaction(func(tx *gorm.DB) error { - 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 { - return res - } - return nil - }) - if err != nil { - ErrResponse(w, http.StatusInternalServerError, err) - return - } - - SetStatus(account) - WriteResponse(w, getCardDetailModel(&slot)); -} - diff --git a/net/server/internal/api_setCardProfile.go b/net/server/internal/api_setCardProfile.go deleted file mode 100644 index d5be2100..00000000 --- a/net/server/internal/api_setCardProfile.go +++ /dev/null @@ -1,92 +0,0 @@ -package databag - -import ( - "errors" - "net/http" - "gorm.io/gorm" - "github.com/gorilla/mux" - "databag/internal/store" -) - -func SetCardProfile(w http.ResponseWriter, r *http.Request) { - var msg DataMessage - - account, code, err := BearerAppToken(r, false); - if err != nil { - ErrResponse(w, code, err) - return - } - - // scan parameters - params := mux.Vars(r) - cardId := params["cardId"] - - if err := ParseRequest(r, w, &msg); err != nil { - ErrResponse(w, http.StatusBadRequest, err) - return - } - - // load referenced card - 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 { - ErrResponse(w, http.StatusNotFound, err) - } - return - } - if slot.Card == nil { - ErrResponse(w, http.StatusNotFound, errors.New("referenced slot is empty")) - return - } - - var identity Identity - guid, messageType, _, err := ReadDataMessage(&msg, &identity) - if messageType != APP_MSGIDENTITY || err != nil { - ErrResponse(w, http.StatusBadRequest, err) - return - } - if slot.Card.Guid != guid { - ErrResponse(w, http.StatusBadRequest, errors.New("slot does not contain specified contact")) - return - } - - if slot.Card.ProfileRevision >= identity.Revision { - WriteResponse(w, getCardModel(&slot)) - return - } - - // update card - slot.Card.ProfileRevision = identity.Revision - slot.Card.Username = identity.Handle - slot.Card.Name = identity.Name - slot.Card.Description = identity.Description - slot.Card.Location = identity.Location - slot.Card.Image = identity.Image - slot.Card.Version = identity.Version - slot.Card.Node = identity.Node - slot.Revision = account.CardRevision + 1 - - // save and update contact revision - err = store.DB.Transaction(func(tx *gorm.DB) error { - 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 { - return res - } - return nil - }) - if err != nil { - ErrResponse(w, http.StatusInternalServerError, err) - return - } - - SetStatus(account) - WriteResponse(w, getCardProfileModel(&slot)); -} - diff --git a/net/server/internal/api_setCardStatus.go b/net/server/internal/api_setCardStatus.go index f17cf69a..b06d638a 100644 --- a/net/server/internal/api_setCardStatus.go +++ b/net/server/internal/api_setCardStatus.go @@ -34,18 +34,18 @@ func SetCardStatus(w http.ResponseWriter, r *http.Request) { return } } - var contentRevision int64 - content := r.FormValue("contentRevision") - if content != "" { - if contentRevision, res = strconv.ParseInt(content, 10, 64); res != nil { + var articleRevision int64 + article := r.FormValue("articleRevision") + if article != "" { + if articleRevision, res = strconv.ParseInt(article, 10, 64); res != nil { ErrResponse(w, http.StatusBadRequest, res) return } } - var labelRevision int64 - label := r.FormValue("labelRevision") - if label != "" { - if labelRevision, res = strconv.ParseInt(label, 10, 64); res != nil { + var channelRevision int64 + channel := r.FormValue("channelRevision") + if channel != "" { + if channelRevision, res = strconv.ParseInt(channel, 10, 64); res != nil { ErrResponse(w, http.StatusBadRequest, res) return } @@ -105,8 +105,8 @@ func SetCardStatus(w http.ResponseWriter, r *http.Request) { } slot.Card.Status = status slot.Card.NotifiedView = viewRevision - slot.Card.NotifiedContent = contentRevision - slot.Card.NotifiedLabel = labelRevision + slot.Card.NotifiedArticle = articleRevision + slot.Card.NotifiedChannel = channelRevision slot.Card.NotifiedProfile = profileRevision // save and update contact revision diff --git a/net/server/internal/api_setLabelRevision.go b/net/server/internal/api_setChannelRevision.go similarity index 75% rename from net/server/internal/api_setLabelRevision.go rename to net/server/internal/api_setChannelRevision.go index a10801d0..c4ed953f 100644 --- a/net/server/internal/api_setLabelRevision.go +++ b/net/server/internal/api_setChannelRevision.go @@ -6,7 +6,7 @@ import ( "databag/internal/store" ) -func SetLabelRevision(w http.ResponseWriter, r *http.Request) { +func SetChannelRevision(w http.ResponseWriter, r *http.Request) { card, code, err := BearerContactToken(r, false) if err != nil { @@ -20,7 +20,7 @@ func SetLabelRevision(w http.ResponseWriter, r *http.Request) { return } - if err := NotifyProfileRevision(card, revision); err != nil { + if err := NotifyChannelRevision(card, revision); err != nil { ErrResponse(w, http.StatusInternalServerError, err) return } @@ -28,17 +28,17 @@ func SetLabelRevision(w http.ResponseWriter, r *http.Request) { WriteResponse(w, nil) } -func NotifyLabelRevision(card *store.Card, revision int64) error { +func NotifyChannelRevision(card *store.Card, revision int64) error { act := &card.Account err := store.DB.Transaction(func(tx *gorm.DB) error { - if res := tx.Model(card).Where("id = ?", card.ID).Update("notified_label", revision).Error; res != nil { + if res := tx.Model(card).Where("id = ?", card.ID).Update("notified_profile", revision).Error; res != nil { return res } if res := tx.Model(&card.CardSlot).Where("id = ?", card.CardSlot.ID).Update("revision", act.CardRevision+1).Error; res != nil { return res } - if res := tx.Model(act).Where("id = ?", act.ID).Update("card_revision", act.CardRevision + 1).Error; res != nil { + if res := tx.Model(act).Where("id = ?", act.ID).Update("card_revision", act.CardRevision+1).Error; res != nil { return res } return nil diff --git a/net/server/internal/api_setLabelGroup.go b/net/server/internal/api_setLabelGroup.go deleted file mode 100644 index 3bde43c9..00000000 --- a/net/server/internal/api_setLabelGroup.go +++ /dev/null @@ -1,89 +0,0 @@ -package databag - -import ( - "errors" - "net/http" - "gorm.io/gorm" - "github.com/gorilla/mux" - "databag/internal/store" -) - -func SetLabelGroup(w http.ResponseWriter, r *http.Request) { - - account, code, err := BearerAppToken(r, false); - if err != nil { - ErrResponse(w, code, err) - return - } - - // scan parameters - params := mux.Vars(r) - groupId := params["groupId"] - labelId := params["labelId"] - - labelSlot := &store.LabelSlot{} - if err := store.DB.Preload("Label").Where("account_id = ? AND label_slot_id = ?", account.ID, labelId).First(&labelSlot).Error; err != nil { - if !errors.Is(err, gorm.ErrRecordNotFound) { - ErrResponse(w, http.StatusInternalServerError, err) - } else { - ErrResponse(w, http.StatusNotFound, err) - } - return - } - if labelSlot.Label == nil { - ErrResponse(w, http.StatusNotFound, errors.New("referenced empty label slot")) - return - } - - groupSlot := &store.GroupSlot{} - if err := store.DB.Preload("Group.GroupSlot").Preload("Group.Cards").Where("account_id = ? AND group_slot_id = ?", account.ID, groupId).First(&groupSlot).Error; err != nil { - if !errors.Is(err, gorm.ErrRecordNotFound) { - ErrResponse(w, http.StatusInternalServerError, err) - } else { - ErrResponse(w, http.StatusNotFound, err) - } - return - } - if groupSlot.Group == nil { - ErrResponse(w, http.StatusNotFound, errors.New("referenced empty group slot")) - return - } - cards := &groupSlot.Group.Cards - notify := []*store.Card{} - - err = store.DB.Transaction(func(tx *gorm.DB) error { - - for _, card := range *cards { - if res := tx.Model(&card).Update("ViewRevision", card.ViewRevision + 1).Error; res != nil { - return res; - } - notify = append(notify, &card) - } - - if res := tx.Model(labelSlot.Label).Association("Groups").Append(groupSlot.Group); res != nil { - return res - } - - if res := tx.Model(labelSlot).Update("revision", account.LabelRevision + 1).Error; res != nil { - return res - } - - if res := tx.Model(account).Update("label_revision", account.LabelRevision + 1).Error; res != nil { - return res - } - - return nil - }) - if err != nil { - ErrResponse(w, http.StatusInternalServerError, err) - return - } - - for _, card := range notify { - SetContactViewNotification(account, card) - SetContactLabelNotification(account, card) - } - SetStatus(account) - WriteResponse(w, getLabelModel(labelSlot, true, true)) -} - diff --git a/net/server/internal/api_setNodeClaim.go b/net/server/internal/api_setNodeStatus.go similarity index 95% rename from net/server/internal/api_setNodeClaim.go rename to net/server/internal/api_setNodeStatus.go index f3a5a23c..857b7493 100644 --- a/net/server/internal/api_setNodeClaim.go +++ b/net/server/internal/api_setNodeStatus.go @@ -7,7 +7,7 @@ import ( "databag/internal/store" ) -func SetNodeClaim(w http.ResponseWriter, r *http.Request) { +func SetNodeStatus(w http.ResponseWriter, r *http.Request) { var config store.Config err := store.DB.Where("config_id = ?", CONFIG_CONFIGURED).First(&config).Error diff --git a/net/server/internal/api_setOpenMessage.go b/net/server/internal/api_setOpenMessage.go index f903a947..3c597f11 100644 --- a/net/server/internal/api_setOpenMessage.go +++ b/net/server/internal/api_setOpenMessage.go @@ -67,9 +67,9 @@ func SetOpenMessage(w http.ResponseWriter, r *http.Request) { card.ProfileRevision = connect.ProfileRevision card.Status = APP_CARDPENDING card.NotifiedProfile = connect.ProfileRevision - card.NotifiedContent = connect.ContentRevision + card.NotifiedArticle = connect.ArticleRevision card.NotifiedView = connect.ViewRevision - card.NotifiedLabel = connect.LabelRevision + card.NotifiedChannel = connect.ChannelRevision card.OutToken = connect.Token card.InToken = hex.EncodeToString(data) card.AccountID = account.Guid @@ -135,14 +135,14 @@ func SetOpenMessage(w http.ResponseWriter, r *http.Request) { card.Node = connect.Node card.ProfileRevision = connect.ProfileRevision } - if connect.ContentRevision > card.NotifiedContent { - card.NotifiedContent = connect.ContentRevision + if connect.ArticleRevision > card.NotifiedArticle { + card.NotifiedArticle = connect.ArticleRevision } if connect.ViewRevision > card.NotifiedView { card.NotifiedView = connect.ViewRevision } - if connect.LabelRevision > card.NotifiedLabel { - card.NotifiedLabel = connect.LabelRevision + if connect.ChannelRevision > card.NotifiedChannel { + card.NotifiedChannel = connect.ChannelRevision } if connect.ProfileRevision > card.NotifiedProfile { card.NotifiedProfile = connect.ProfileRevision @@ -192,14 +192,10 @@ func SetOpenMessage(w http.ResponseWriter, r *http.Request) { Token: slot.Card.InToken, Status: slot.Card.Status, ViewRevision: slot.Card.ViewRevision, - LabelRevision: account.LabelRevision, + ChannelRevision: account.ChannelRevision, ProfileRevision: account.ProfileRevision, - ContentRevision: account.ContentRevision, + ArticleRevision: account.ArticleRevision, } - //SetContactProfileNotification(&account, slot.Card) - //SetContactContentNotification(&account, slot.Card) - //SetContactViewNotification(&account, slot.Card) - //SetContactLabelNotification(&account, slot.Card) SetStatus(&account) WriteResponse(w, &status) } diff --git a/net/server/internal/api_setProfile.go b/net/server/internal/api_setProfile.go deleted file mode 100644 index 46f80f49..00000000 --- a/net/server/internal/api_setProfile.go +++ /dev/null @@ -1,49 +0,0 @@ -package databag - -import ( - "net/http" - "gorm.io/gorm" - "databag/internal/store" -) - -func SetProfile(w http.ResponseWriter, r *http.Request) { - - account, code, err := BearerAppToken(r, true); - if err != nil { - ErrResponse(w, code, err) - return - } - detail := account.AccountDetail - - // extract profile data from body - var profileData ProfileData; - err = ParseRequest(r, w, &profileData) - if err != nil { - ErrResponse(w, http.StatusBadRequest, err) - return - } - - // update record - detail.Name = profileData.Name - detail.Location = profileData.Location - detail.Description = profileData.Description - - err = store.DB.Transaction(func(tx *gorm.DB) error { - if res := store.DB.Save(&detail).Error; res != nil { - return res - } - if res := store.DB.Model(&account).Update("profile_revision", account.ProfileRevision + 1).Error; res != nil { - return res - } - return nil - }) - if err != nil { - ErrResponse(w, http.StatusInternalServerError, err) - return - } - - SetProfileNotification(account) - SetStatus(account) - WriteResponse(w, nil) -} - diff --git a/net/server/internal/api_setViewRevision.go b/net/server/internal/api_setViewRevision.go index 799e2c43..0b0f4765 100644 --- a/net/server/internal/api_setViewRevision.go +++ b/net/server/internal/api_setViewRevision.go @@ -20,7 +20,7 @@ func SetViewRevision(w http.ResponseWriter, r *http.Request) { return } - if err := NotifyProfileRevision(card, revision); err != nil { + if err := NotifyViewRevision(card, revision); err != nil { ErrResponse(w, http.StatusInternalServerError, err) return } @@ -32,13 +32,13 @@ func NotifyViewRevision(card *store.Card, revision int64) error { act := &card.Account err := store.DB.Transaction(func(tx *gorm.DB) error { - if res := tx.Model(card).Where("id = ?", card.ID).Update("notified_view", revision).Error; res != nil { + if res := tx.Model(card).Where("id = ?", card.ID).Update("notified_profile", revision).Error; res != nil { return res } if res := tx.Model(&card.CardSlot).Where("id = ?", card.CardSlot.ID).Update("revision", act.CardRevision+1).Error; res != nil { return res } - if res := tx.Model(act).Where("id = ?", act.ID).Update("card_revision", act.CardRevision + 1).Error; res != nil { + if res := tx.Model(act).Where("id = ?", act.ID).Update("card_revision", act.CardRevision+1).Error; res != nil { return res } return nil diff --git a/net/server/internal/api_status.go b/net/server/internal/api_status.go index b64e4eec..02d4077f 100644 --- a/net/server/internal/api_status.go +++ b/net/server/internal/api_status.go @@ -95,12 +95,10 @@ func Status(w http.ResponseWriter, r *http.Request) { func getRevision(account *store.Account) Revision { var r Revision r.Profile = account.ProfileRevision - r.Content = account.ContentRevision - r.Label = account.LabelRevision + r.Article = account.ArticleRevision + r.Channel = account.ChannelRevision r.Group = account.GroupRevision r.Card = account.CardRevision - r.Dialogue = account.DialogueRevision - r.Insight = account.InsightRevision return r } diff --git a/net/server/internal/api_updateGroup.go b/net/server/internal/api_updateGroup.go deleted file mode 100644 index 24298b9a..00000000 --- a/net/server/internal/api_updateGroup.go +++ /dev/null @@ -1,70 +0,0 @@ -package databag - -import ( - "errors" - "net/http" - "gorm.io/gorm" - "github.com/gorilla/mux" - "databag/internal/store" -) - -func UpdateGroup(w http.ResponseWriter, r *http.Request) { - - account, code, err := BearerAppToken(r, false) - if err != nil { - ErrResponse(w, code, err) - return - } - params := mux.Vars(r) - groupId := params["groupId"] - - var subject Subject - if err := ParseRequest(r, w, &subject); err != nil { - ErrResponse(w, http.StatusBadRequest, err) - return - } - - // load specified group - var slot store.GroupSlot - if err := store.DB.Preload("Group.GroupData").Where("account_id = ? AND group_slot_id = ?", account.ID, groupId).First(&slot).Error; err != nil { - if !errors.Is(err, gorm.ErrRecordNotFound) { - ErrResponse(w, http.StatusInternalServerError, err) - } else { - ErrResponse(w, http.StatusNotFound, err) - } - return - } - if slot.Group == nil { - ErrResponse(w, http.StatusNotFound, errors.New("referenced deleted group")) - return - } - - // update specified group - slot.Revision = account.GroupRevision + 1 - slot.Group.DataType = subject.DataType - slot.Group.GroupData.Data = subject.Data - err = store.DB.Transaction(func(tx *gorm.DB) error { - if res := tx.Save(&slot.Group.GroupData).Error; res != nil { - return res - } - if res := tx.Save(&slot.Group).Error; res != nil { - return res - } - if res := tx.Save(&slot).Error; res != nil { - return res - } - if res := tx.Model(&account).Update("group_revision", account.GroupRevision + 1).Error; res != nil { - return res - } - return nil - }) - if err != nil { - ErrResponse(w, http.StatusInternalServerError, err) - return - } - - SetStatus(account) - WriteResponse(w, getGroupModel(&slot)) -} - - diff --git a/net/server/internal/appValues.go b/net/server/internal/appValues.go index 8a144856..102181ee 100644 --- a/net/server/internal/appValues.go +++ b/net/server/internal/appValues.go @@ -21,8 +21,8 @@ const APP_CARDREQUESTED = "requested" const APP_CARDCONNECTING = "connecting" const APP_CARDCONNECTED = "connected" const APP_NOTIFYPROFILE = "profile" -const APP_NOTIFYCONTENT = "content" -const APP_NOTIFYLABEL = "label" +const APP_NOTIFYARTICLE = "article" +const APP_NOTIFYCHANNEL = "channel" const APP_NOTIFYVIEW = "view" const APP_TOKENAPP = "app" const APP_TOKENCONTACT = "contact" diff --git a/net/server/internal/main_test.go b/net/server/internal/main_test.go index 154622b5..29300c62 100644 --- a/net/server/internal/main_test.go +++ b/net/server/internal/main_test.go @@ -13,17 +13,17 @@ func TestMain(m *testing.M) { os.Remove("databag.db") store.SetPath("databag.db") - r, w, _ := NewRequest("GET", "/admin/claimable", nil) - GetNodeClaimable(w, r) + r, w, _ := NewRequest("GET", "/admin/status", nil) + GetNodeStatus(w, r) var available bool if ReadResponse(w, &available) != nil { panic("server not claimable") } // claim server - r, w, _ = NewRequest("PUT", "/admin/claim", nil) + r, w, _ = NewRequest("PUT", "/admin/status", nil) SetCredentials(r, "admin:pass"); - SetNodeClaim(w, r) + SetNodeStatus(w, r) if ReadResponse(w, nil) != nil { panic("failed to claim server") } diff --git a/net/server/internal/modelUtil.go b/net/server/internal/modelUtil.go index d7d5bc34..8cbb28b8 100644 --- a/net/server/internal/modelUtil.go +++ b/net/server/internal/modelUtil.go @@ -8,24 +8,46 @@ func getCardModel(slot *store.CardSlot) *Card { if slot.Card == nil { return &Card{ - CardId: slot.CardSlotId, + Id: slot.CardSlotId, Revision: slot.Revision, } } return &Card{ - CardId: slot.CardSlotId, + Id: slot.CardSlotId, Revision: slot.Revision, - CardData: &CardData { + Data: &CardData { NotifiedProfile: slot.Card.NotifiedProfile, - NotifiedContent: slot.Card.NotifiedContent, - NotifiedLabel: slot.Card.NotifiedLabel, + NotifiedArticle: slot.Card.NotifiedArticle, + NotifiedChannel: slot.Card.NotifiedChannel, + NotifiedView: slot.Card.NotifiedView, + ProfileRevision: slot.Card.ProfileRevision, + DetailRevision: slot.Card.DetailRevision, + CardDetail: getCardDetailModel(slot), + CardProfile: getCardProfileModel(slot), + }, + } +} + +func getCardRevisionModel(slot *store.CardSlot) *Card { + + if slot.Card == nil { + return &Card{ + Id: slot.CardSlotId, + Revision: slot.Revision, + } + } + + return &Card{ + Id: slot.CardSlotId, + Revision: slot.Revision, + Data: &CardData { + NotifiedProfile: slot.Card.NotifiedProfile, + NotifiedArticle: slot.Card.NotifiedArticle, + NotifiedChannel: slot.Card.NotifiedChannel, NotifiedView: slot.Card.NotifiedView, ProfileRevision: slot.Card.ProfileRevision, DetailRevision: slot.Card.DetailRevision, - Guid: slot.Card.Guid, - Status: slot.Card.Status, - Token: slot.Card.OutToken, }, } } @@ -38,7 +60,8 @@ func getCardDetailModel(slot *store.CardSlot) *CardDetail { } return &CardDetail{ - Revision: slot.Card.DetailRevision, + Status: slot.Card.Status, + Token: slot.Card.OutToken, Notes: slot.Card.Notes, Groups: groups, } @@ -47,7 +70,7 @@ func getCardDetailModel(slot *store.CardSlot) *CardDetail { func getCardProfileModel(slot *store.CardSlot) *CardProfile { return &CardProfile{ - Revision: slot.Card.ProfileRevision, + Guid: slot.Card.Guid, Handle: slot.Card.Username, Name: slot.Card.Name, Description: slot.Card.Description, @@ -61,15 +84,15 @@ func getCardProfileModel(slot *store.CardSlot) *CardProfile { func getGroupModel(slot *store.GroupSlot) *Group { if slot.Group == nil { return &Group{ - GroupId: slot.GroupSlotId, + Id: slot.GroupSlotId, Revision: slot.Revision, } } return &Group{ - GroupId: slot.GroupSlotId, + Id: slot.GroupSlotId, Revision: slot.Revision, - GroupData: &GroupData { + Data: &GroupData { DataType: slot.Group.DataType, Data: slot.Group.GroupData.Data, Created: slot.Group.Created, @@ -78,72 +101,4 @@ func getGroupModel(slot *store.GroupSlot) *Group { } } -func getLabelModel(slot *store.LabelSlot, includeData bool, includeGroups bool) *Label { - - if !includeData || slot.Label == nil { - return &Label{ - LabelId: slot.LabelSlotId, - Revision: slot.Revision, - } - } - - var groups *[]string - if includeGroups { - groups = &[]string{} - for _, group := range slot.Label.Groups { - *groups = append(*groups, group.GroupSlot.GroupSlotId) - } - } - - return &Label{ - LabelId: slot.LabelSlotId, - Revision: slot.Revision, - LabelData: &LabelData{ - DataType: slot.Label.DataType, - Data: slot.Label.LabelData.Data, - Created: slot.Label.Created, - Updated: slot.Label.Updated, - Groups: groups, - }, - } -} - -func getArticleModel(slot *store.ArticleSlot, contact bool, shared bool) *Article { - - if !shared || slot.Article == nil { - return &Article{ - ArticleId: slot.ArticleSlotId, - Revision: slot.Revision, - } - } - - var groups []string - if !contact { - for _, group := range slot.Article.Groups { - groups = append(groups, group.GroupSlot.GroupSlotId) - } - } - - var labels []string - for _, label := range slot.Article.Labels { - labels = append(labels, label.LabelSlot.LabelSlotId) - } - - return &Article{ - ArticleId: slot.ArticleSlotId, - Revision: slot.Revision, - 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 29f48cb2..f4141222 100644 --- a/net/server/internal/models.go +++ b/net/server/internal/models.go @@ -1,319 +1,440 @@ package databag import ( - "os" + //"os" ) type Account struct { + AccountId string `json:"accountId"` + Profile *Profile `json:"profile"` + Disabled bool `json:"disabled"` } type AccountStatus struct { + Disabled bool `json:"disabled"` + StorageUsed float64 `json:"storageUsed"` + StorageAvailable float64 `json:"storageAvailable"` + ForwardingAddress string `json:"forwardingAddress"` } -type AccountsImportBody struct { - FileName **os.File `json:"fileName,omitempty"` -} - type Announce struct { + AppToken string `json:"appToken"` } type App struct { - AppId string `json:"appId"` - AppData *AppData `json:"appData"` - Attached int64 `json:"attached"` + + Id string `json:"id"` + + Revision int64 `json:"revision"` + + Data *AppData `json:"data"` } type AppData struct { - Name string `json:"name,omitempty"` - Description string `json:"description,omitempty"` - Url string `json:"url,omitempty"` - Image string `json:"image,omitempty"` -} -type Subject struct { - DataType string `json:"dataType"` - Data string `json:"data"` + Name string `json:"name,omitempty"` + + Description string `json:"description,omitempty"` + + Url string `json:"url,omitempty"` + + Image string `json:"image,omitempty"` + + Attached int64 `json:"attached"` } type Article struct { - ArticleId string `json:"article_id"` - Revision int64 `json:"revision"` - ArticleData *ArticleData `json:"articleData"` + + Id string `json:"id"` + + Revision int64 `json:"revision"` + + Data *ArticleData `json:"data"` } type ArticleData struct { - DataType string `json:"type"` + + DataType string `json:"dataType"` + Data string `json:"data"` + Created int64 `json:"created"` + Updated int64 `json:"updated"` + Status string `json:"status"` - Labels []string `json:"labels"` - Groups []string `json:"groups,omitempty"` - TagCount int32 `json:"tagCount"` - TagUpdated int64 `json:"tagUpdated,omitempty"` - TagRevision int64 `json:"tagRevision"` + + Groups *ArticleGroups `json:"groups,omitempty"` } -type ArticleAccess struct { - Labels []string `json:"labels"` +type ArticleGroups struct { + Groups []string `json:"groups"` } -type ArticleIdAssetsBody struct { - FileName **os.File `json:"fileName,omitempty"` -} - -type ArticleIdSubjectBody struct { - Type_ string `json:"type"` - Data string `json:"data"` -} - type Asset struct { + AssetId string `json:"assetId"` + Transform string `json:"transform,omitempty"` + Status string `json:"status,omitempty"` } type Card struct { - CardId string `json:"cardId"` - Revision int64 `json:"revision,omitempty"` - CardData *CardData `json:"articleData"` + + Id string `json:"id"` + + Revision int64 `json:"revision"` + + Data *CardData `json:"data"` } type CardData struct { - Guid string `json:"guid"` - Status string `json:"status"` - Token string `json:"token,omitempty"` + DetailRevision int64 `json:"detailRevision"` + ProfileRevision int64 `json:"profileRevision"` + NotifiedProfile int64 `json:"notifiedProfile"` - NotifiedContent int64 `json:"notifiedContent"` - NotifiedLabel int64 `json:"notifiedLabel"` + + NotifiedArticle int64 `json:"notifiedArticle"` + + NotifiedChannel int64 `json:"notifiedChannel"` + NotifiedView int64 `json:"notifiedView"` + + CardDetail *CardDetail `json:"cardDetail,omitempty"` + + CardProfile *CardProfile `json:"cardProfile,omitempty"` } type CardDetail struct { - Revision int64 `json:"revision,omitempty"` + + Status string `json:"status"` + + Token string `json:"token,omitempty"` + Notes string `json:"notes,omitempty"` + Groups []string `json:"groups,omitempty"` } type CardProfile struct { - Revision int64 `json:"revision,omitempty"` + + Guid string `json:"guid"` + Handle string `json:"handle,omitempty"` + Name string `json:"name,omitempty"` + Description string `json:"description,omitempty"` + Location string `json:"location,omitempty"` + ImageSet bool `json:"imageSet,omitempty"` - Version string `json:"version"` + + Version string `json:"version,omitempty"` + Node string `json:"node"` } -type Dialogue struct { - DialogueId string `json:"dialogueId"` - DialogueRevison int64 `json:"dialogueRevison,omitempty"` - Type_ string `json:"type"` - Data string `json:"data"` - Created int64 `json:"created"` - Active bool `json:"active"` - InsightRevision int64 `json:"insightRevision,omitempty"` - Insights []DialogueInsights `json:"insights"` +type Channel struct { + + Id string `json:"id"` + + Revision string `json:"revision"` + + Data *ChannelData `json:"data"` } -type DialogueIdSubjectBody struct { - Type_ string `json:"type"` - Data string `json:"data"` +type ChannelData struct { + + DetailRevision int64 `json:"detailRevision"` + + TopicRevision int64 `json:"topicRevision"` + + ChannelDetail *ChannelDetail `json:"channelDetail,omitempty"` + + ChannelTopics *ChannelSize `json:"channelTopics,omitempty"` } -type DialogueInsights struct { - CardId string `json:"cardId,omitempty"` - Status string `json:"status,omitempty"` -} +type ChannelDetail struct { -type Group struct { - GroupId string `json:"groupId"` - Revision int64 `json:"revision"` - GroupData *GroupData `json:"groupData"` -} - -type GroupData struct { DataType string `json:"dataType"` + Data string `json:"data"` + Created int64 `json:"created"` + Updated int64 `json:"updated"` + + Viewers []string `json:"viewers,omitempty"` + + ViewerGroups *ChannelGroups `json:"viewerGroups,omitempty"` + + Members []string `json:"members,omitempty"` + + MemberGroups *ChannelGroups `json:"memberGroups,omitempty"` } -type GroupsGroupIdBody struct { - Type_ string `json:"type"` - Data string `json:"data"` +type ChannelGroups struct { + + Groups []string `json:"groups"` } -type Insight struct { - InsightId string `json:"insightId"` - InsightRevision int64 `json:"insightRevision"` - CardId string `json:"cardId"` +type ChannelSize struct { + + TopicCount int32 `json:"topicCount"` + + TopicUpdated int64 `json:"topicUpdated"` +} + +type Claim struct { + + Token string `json:"token"` +} + +type Connect struct { + + Contact string `json:"contact"` + + Token string `json:"token"` + + ViewRevision int64 `json:"viewRevision,omitempty"` + + ArticleRevision int64 `json:"articleRevision,omitempty"` + + ProfileRevision int64 `json:"profileRevision,omitempty"` + + ChannelRevision int64 `json:"channelRevision,omitempty"` + + Handle string `json:"handle,omitempty"` + + Name string `json:"name,omitempty"` + + Description string `json:"description,omitempty"` + + Location string `json:"location,omitempty"` + + Image string `json:"image,omitempty"` + + Version string `json:"version,omitempty"` + + Node string `json:"node,omitempty"` +} + +type ContactStatus struct { + + Token string `json:"token,omitempty"` + + ProfileRevision int64 `json:"profileRevision,omitempty"` + + ArticleRevision int64 `json:"articleRevision,omitempty"` + + ChannelRevision int64 `json:"channelRevision,omitempty"` + + ViewRevision int64 `json:"viewRevision,omitempty"` + Status string `json:"status"` } -type Label struct { - LabelId string `json:"labelId"` - Revision int64 `json:"revision"` - LabelData *LabelData `json:"labelData"` +type DataMessage struct { + + Message string `json:"message"` + + KeyType string `json:"keyType"` + + PublicKey string `json:"publicKey"` + + Signature string `json:"signature"` + + SignatureType string `json:"signatureType"` } -type LabelData struct { - DataType string `json:"type"` +type Disconnect struct { + + Contact string `json:"contact"` +} + +type Group struct { + + Id string `json:"id"` + + Revision int64 `json:"revision"` + + Data *GroupData `json:"data,omitempty"` +} + +type GroupData struct { + + DataType string `json:"dataType"` + Data string `json:"data"` + Created int64 `json:"created"` + Updated int64 `json:"updated"` - Groups *[]string `json:"groups,omitempty"` +} + +type Identity struct { + + Revision int64 `json:"revision"` + + Handle string `json:"handle,omitempty"` + + Name string `json:"name,omitempty"` + + Description string `json:"description,omitempty"` + + Location string `json:"location,omitempty"` + + Image string `json:"image,omitempty"` + + Version string `json:"version"` + + Node string `json:"node"` } type NodeConfig struct { + Domain string `json:"domain"` + PublicLimit int64 `json:"publicLimit"` + AccountStorage int64 `json:"accountStorage"` } type Profile struct { - Guid string `json:"profileId"` + + Guid string `json:"guid"` + Handle string `json:"handle,omitempty"` + Name string `json:"name,omitempty"` + Description string `json:"description,omitempty"` + Location string `json:"location,omitempty"` + Image string `json:"image,omitempty"` + Revision int64 `json:"revision"` + Version string `json:"version,omitempty"` + Node string `json:"node"` } type ProfileData struct { + Name string `json:"name,omitempty"` + Description string `json:"description,omitempty"` + Location string `json:"location,omitempty"` } type Revision struct { + Profile int64 `json:"profile"` - Content int64 `json:"content"` - Label int64 `json:"label"` - Group int64 `json:"share"` + + Article int64 `json:"article"` + + Group int64 `json:"group"` + + Channel int64 `json:"channel"` + Card int64 `json:"card"` - Dialogue int64 `json:"dialogue"` - Insight int64 `json:"insight"` } -type ShareGroupsBody struct { - Type_ string `json:"type"` +type SignedData struct { + + Guid string `json:"guid"` + + Timestamp int64 `json:"timestamp"` + + MessageType string `json:"messageType"` + + Value string `json:"value"` +} + +type Subject struct { + + DataType string `json:"dataType"` + Data string `json:"data"` } type Tag struct { - TagId string `json:"tagId"` - CardId string `json:"cardId,omitempty"` - Revision int64 `json:"revision"` - Type_ string `json:"type"` + + Id string `json:"id"` + + Revision string `json:"revision"` + + Data *TagData `json:"data"` +} + +type TagData struct { + + Guid string `json:"guid"` + + DataType string `json:"dataType"` + Data string `json:"data"` + Created int64 `json:"created"` + + Updated int64 `json:"updated"` } type Topic struct { - TopicId string `json:"topicId"` - TopicRevision int64 `json:"topicRevision"` - Type_ string `json:"type"` - Data string `json:"data"` - Created int64 `json:"created"` - Modified int64 `json:"modified"` - Status string `json:"status"` - TagCount int32 `json:"tagCount"` - TagUpdate int64 `json:"tagUpdate,omitempty"` + + Id string `json:"id"` + + Revision string `json:"revision"` + + Data *TopicData `json:"data"` +} + +type TopicData struct { + + DetailRevision int64 `json:"detailRevision"` + TagRevision int64 `json:"tagRevision"` + + TopicDetail *TopicDetail `json:"topicDetail,omitempty"` + + TopicTags *TopicSize `json:"topicTags:,omitempty"` } -type TopicIdAssetsBody struct { - FileName **os.File `json:"fileName,omitempty"` -} +type TopicDetail struct { -type TopicIdSubjectBody struct { - Type_ string `json:"type"` - Data string `json:"data"` -} - -type TopicIdTagsBody struct { - Type_ string `json:"type"` - Data string `json:"data"` -} - -type Tunnel struct { - CardId string `json:"cardId"` - Type_ string `json:"type"` - Data string `json:"data,omitempty"` -} - -type ContactStatus struct { - Token string `json:"token,omitempty"` - Status string `json:"status"` - ViewRevision int64 `json:"viewRevision"` - LabelRevision int64 `json:"labelRevision"` - ContentRevision int64 `json:"contentRevision"` - ProfileRevision int64 `json:"profileRevision,omitempty"` -} - -type DataMessage struct { - Message string `json:"message"` - KeyType string `json:"keyType"` - PublicKey string `json:"publicKey"` - Signature string `json:"signature"` - SignatureType string `json:"signatureType"` -} - -type SignedData struct { Guid string `json:"guid"` - Timestamp int64 `json:"timestamp"` - MessageType string `json:"messageType"` - Value string `json:"value"` + + DataType string `json:"dataType"` + + Data string `json:"data"` + + Created int64 `json:"created"` + + Modified int64 `json:"modified"` + + Status string `json:"status"` } -type Identity struct { - Revision int64 `json:"revision"` - Handle string `json:"handle,omitempty"` - Name string `json:"name,omitempty"` - Description string `json:"description,omitempty"` - Location string `json:"location,omitempty"` - Image string `json:"image,omitempty"` - Version string `json:"version"` - Node string `json:"node"` -} - -type Connect struct { - Contact string `json:"contact"` - Token string `json:"token"` - ViewRevision int64 `json:"viewRevision"` - LabelRevision int64 `json:"labelRevision"` - ContentRevision int64 `json:"contentRevision"` - ProfileRevision int64 `json:"profileRevision,omitempty"` - Handle string `json:"handle,omitempty"` - Name string `json:"name,omitempty"` - Description string `json:"description,omitempty"` - Location string `json:"location,omitempty"` - Image string `json:"image,omitempty"` - Version string `json:"version,omitempty"` - Node string `json:"node,omitempty"` -} - -type Disconnect struct { - Contact string `json:"contact"` -} - -type Authenticate struct { - Token string `json:"token"` +type TopicSize struct { + + TagCount int32 `json:"tagCount"` + + TagUpdated int64 `json:"tagUpdated"` } diff --git a/net/server/internal/notify.go b/net/server/internal/notify.go index 5d4397a6..19465e21 100644 --- a/net/server/internal/notify.go +++ b/net/server/internal/notify.go @@ -60,12 +60,12 @@ func SendLocalNotification(notification *store.Notification) { if err := NotifyProfileRevision(&card, notification.Revision); err != nil { ErrMsg(err) } - } else if notification.Module == APP_NOTIFYCONTENT { - if err := NotifyContentRevision(&card, notification.Revision); err != nil { + } else if notification.Module == APP_NOTIFYARTICLE { + if err := NotifyArticleRevision(&card, notification.Revision); err != nil { ErrMsg(err) } - } else if notification.Module == APP_NOTIFYLABEL { - if err := NotifyLabelRevision(&card, notification.Revision); err != nil { + } else if notification.Module == APP_NOTIFYCHANNEL { + if err := NotifyChannelRevision(&card, notification.Revision); err != nil { ErrMsg(err) } } else if notification.Module == APP_NOTIFYVIEW { @@ -151,9 +151,9 @@ func SetContentNotification(account *store.Account) { for _, card := range cards { notification := &store.Notification{ Node: card.Node, - Module: APP_NOTIFYCONTENT, + Module: APP_NOTIFYARTICLE, Token: card.OutToken, - Revision: account.ContentRevision, + Revision: account.ArticleRevision, } if err := tx.Save(notification).Error; err != nil { return err @@ -178,9 +178,9 @@ func SetContactContentNotification(account *store.Account, card *store.Card) { // add new notification for card notification := &store.Notification{ Node: card.Node, - Module: APP_NOTIFYCONTENT, + Module: APP_NOTIFYARTICLE, Token: card.OutToken, - Revision: account.ContentRevision, + Revision: account.ArticleRevision, } if res := store.DB.Save(notification).Error; res != nil { @@ -263,9 +263,9 @@ func SetLabelNotification(account *store.Account) { for _, card := range cards { notification := &store.Notification{ Node: card.Node, - Module: APP_NOTIFYLABEL, + Module: APP_NOTIFYCHANNEL, Token: card.OutToken, - Revision: account.LabelRevision, + Revision: account.ChannelRevision, } if err := tx.Save(notification).Error; err != nil { return err @@ -290,9 +290,9 @@ func SetContactLabelNotification(account *store.Account, card *store.Card) { // add new notification for card notification := &store.Notification{ Node: card.Node, - Module: APP_NOTIFYLABEL, + Module: APP_NOTIFYCHANNEL, Token: card.OutToken, - Revision: account.LabelRevision, + Revision: account.ChannelRevision, } if res := store.DB.Save(notification).Error; res != nil { diff --git a/net/server/internal/routers.go b/net/server/internal/routers.go index 47d5f8d2..0b58cf3d 100644 --- a/net/server/internal/routers.go +++ b/net/server/internal/routers.go @@ -141,15 +141,15 @@ var routes = Routes{ Route{ "GetAccountUsername", strings.ToUpper("Get"), - "/account/claimable", + "/account/available", GetAccountUsername, }, Route{ - "GetPublicClaimable", + "GetPublicStatus", strings.ToUpper("Get"), - "/account/public/claimable", - GetPublicClaimable, + "/account/public/status", + GetPublicStatus, }, Route{ @@ -215,13 +215,6 @@ var routes = Routes{ GetNodeAccounts, }, - Route{ - "GetNodeClaimable", - strings.ToUpper("Get"), - "/admin/claimable", - GetNodeClaimable, - }, - Route{ "GetNodeConfig", strings.ToUpper("Get"), @@ -229,6 +222,13 @@ var routes = Routes{ GetNodeConfig, }, + Route{ + "GetNodeStatus", + strings.ToUpper("Get"), + "/admin/status", + GetNodeStatus, + }, + Route{ "ImportAccount", strings.ToUpper("Post"), @@ -250,13 +250,6 @@ var routes = Routes{ SetNodeAccount, }, - Route{ - "SetNodeClaim", - strings.ToUpper("Post"), - "/admin/claim", - SetNodeClaim, - }, - Route{ "SetNodeConfig", strings.ToUpper("Put"), @@ -264,6 +257,90 @@ var routes = Routes{ SetNodeConfig, }, + Route{ + "SetNodeStatus", + strings.ToUpper("Put"), + "/admin/status", + SetNodeStatus, + }, + + Route{ + "AddGroup", + strings.ToUpper("Post"), + "/alias/groups", + AddGroup, + }, + + Route{ + "GetGroups", + strings.ToUpper("Get"), + "/alias/groups", + GetGroups, + }, + + Route{ + "RemoveGroup", + strings.ToUpper("Delete"), + "/alias/groups/{groupId}", + RemoveGroup, + }, + + Route{ + "UpdateGroup", + strings.ToUpper("Put"), + "/alias/groups/{groupId}", + UpdateGroup, + }, + + Route{ + "AddArticle", + strings.ToUpper("Post"), + "/attribute/articles", + AddArticle, + }, + + Route{ + "ClearArticleGroup", + strings.ToUpper("Delete"), + "/attribute/articles/{articleId}/groups/{groupId}", + ClearArticleGroup, + }, + + Route{ + "GetArticleSubjectField", + strings.ToUpper("Get"), + "/attribute/articles/{articleId}/subject/{field}", + GetArticleSubjectField, + }, + + Route{ + "GetArticles", + strings.ToUpper("Get"), + "/attribute/articles", + GetArticles, + }, + + Route{ + "RemoveArticle", + strings.ToUpper("Delete"), + "/attribute/articles/{articleId}", + RemoveArticle, + }, + + Route{ + "SetArticleGroup", + strings.ToUpper("Put"), + "/attribute/articles/{articleId}/groups/{groupId}", + SetArticleGroup, + }, + + Route{ + "SetArticleSubject", + strings.ToUpper("Put"), + "/attribute/articles/{articleId}/subject", + SetArticleSubject, + }, + Route{ "Authorize", strings.ToUpper("Put"), @@ -292,13 +369,6 @@ var routes = Routes{ ClearCardNotes, }, - Route{ - "GetCard", - strings.ToUpper("Get"), - "/contact/cards/{cardId}", - GetCard, - }, - Route{ "GetCardDetail", strings.ToUpper("Get"), @@ -348,6 +418,13 @@ var routes = Routes{ RemoveCard, }, + Route{ + "SetArticleRevision", + strings.ToUpper("Put"), + "/contact/article/revision", + SetArticleRevision, + }, + Route{ "SetCardGroup", strings.ToUpper("Put"), @@ -376,6 +453,13 @@ var routes = Routes{ SetCardStatus, }, + Route{ + "SetChannelRevision", + strings.ToUpper("Put"), + "/contact/channel/revision", + SetChannelRevision, + }, + Route{ "SetCloseMessage", strings.ToUpper("Put"), @@ -383,20 +467,6 @@ var routes = Routes{ SetCloseMessage, }, - Route{ - "SetContentRevision", - strings.ToUpper("Put"), - "/contact/content/revision", - SetContentRevision, - }, - - Route{ - "SetLabelRevision", - strings.ToUpper("Put"), - "/contact/label/revision", - SetLabelRevision, - }, - Route{ "SetOpenMessage", strings.ToUpper("Put"), @@ -419,430 +489,185 @@ var routes = Routes{ }, Route{ - "AddArticle", + "AddChannel", strings.ToUpper("Post"), - "/content/articles", - AddArticle, + "/content/channels", + AddChannel, }, Route{ - "AddArticleAsset", + "AddChannelAsset", strings.ToUpper("Post"), - "/content/articles/{articleId}/assets", - AddArticleAsset, + "/content/channels/{channelId}/topics/{topicId}/assets", + AddChannelAsset, }, Route{ - "AddArticleTag", + "AddChannelTopic", strings.ToUpper("Post"), - "/content/articles/{articleId}/tags", - AddArticleTag, + "/content/channels/{channelId}/topics", + AddChannelTopic, }, Route{ - "AddLabel", + "AddChannelTopicTag", strings.ToUpper("Post"), - "/content/labels", - AddLabel, + "/content/channels/{channelId}/topics/{topicId}/tags", + AddChannelTopicTag, }, Route{ - "ClearArticleGroup", + "ClearChannelGroup", strings.ToUpper("Delete"), - "/content/articles/{articleId}/groups/{groupId}", - ClearArticleGroup, + "/content/channels/{channelId}/groups/{groupId}", + ClearChannelGroup, }, Route{ - "ClearArticleLabel", + "GetChannelAsset", + strings.ToUpper("Get"), + "/content/channels/{channelId}/topics/{topicId}/assets/{assetId}", + GetChannelAsset, + }, + + Route{ + "GetChannelAssets", + strings.ToUpper("Get"), + "/content/channels/{channelId}/topics/{topicId}/assets", + GetChannelAssets, + }, + + Route{ + "GetChannelDetail", + strings.ToUpper("Get"), + "/content/channels/{channelId}/detail", + GetChannelDetail, + }, + + Route{ + "GetChannelSize", + strings.ToUpper("Get"), + "/content/channels/{channelId}/size", + GetChannelSize, + }, + + Route{ + "GetChannelSubjectField", + strings.ToUpper("Get"), + "/content/channels/{channelId}/subject/{field}", + GetChannelSubjectField, + }, + + Route{ + "GetChannelTopicDetail", + strings.ToUpper("Get"), + "/content/channels/{channelId}/topics/{topicId}/detail", + GetChannelTopicDetail, + }, + + Route{ + "GetChannelTopicSize", + strings.ToUpper("Get"), + "/content/channels/{channelId}/topics/{topicId}/size", + GetChannelTopicSize, + }, + + Route{ + "GetChannelTopicSubjectField", + strings.ToUpper("Get"), + "/content/channels/{channelId}/topics/{topicId}/subject/{field}", + GetChannelTopicSubjectField, + }, + + Route{ + "GetChannelTopicTagSubjectField", + strings.ToUpper("Get"), + "/content/channels/{channelId}/topics/{topicId}/tags/{tagId}/subject/{field}", + GetChannelTopicTagSubjectField, + }, + + Route{ + "GetChannelTopicTags", + strings.ToUpper("Get"), + "/content/channels/{channelId}/topics/{topicId}/tags", + GetChannelTopicTags, + }, + + Route{ + "GetChannelTopics", + strings.ToUpper("Get"), + "/content/channels/{channelId}/topics", + GetChannelTopics, + }, + + Route{ + "GetChannels", + strings.ToUpper("Get"), + "/content/channels", + GetChannels, + }, + + Route{ + "RemoveChannel", strings.ToUpper("Delete"), - "/content/articles/{articleId}/labels/{labelId}", - ClearArticleLabel, + "/content/channels/{channelId}", + RemoveChannel, }, Route{ - "ClearLabelGroup", + "RemoveChannelAsset", strings.ToUpper("Delete"), - "/content/labels/{labelId}/groups/{groupId}", - ClearLabelGroup, + "/content/channels/{channelId}/topics/{topicId}/assets/{assetId}", + RemoveChannelAsset, }, Route{ - "GetArticle", - strings.ToUpper("Get"), - "/content/articles/{articleId}", - GetArticle, - }, - - Route{ - "GetArticleAsset", - strings.ToUpper("Get"), - "/content/articles/{articleId}/assets/{assetId}", - GetArticleAsset, - }, - - Route{ - "GetArticleAssets", - strings.ToUpper("Get"), - "/content/articles/{articleId}/assets", - GetArticleAssets, - }, - - Route{ - "GetArticleSubjectField", - strings.ToUpper("Get"), - "/content/articles/{articleId}/subject/{field}", - GetArticleSubjectField, - }, - - Route{ - "GetArticleTag", - strings.ToUpper("Get"), - "/content/articles/{articleId}/tags/{tagId}", - GetArticleTag, - }, - - Route{ - "GetArticleTagBlockView", - strings.ToUpper("Get"), - "/content/articles/{articleId}/tagBlocks/view", - GetArticleTagBlockView, - }, - - Route{ - "GetArticleTagSubjectField", - strings.ToUpper("Get"), - "/content/articles/{articleId}/tags/{tagId}/subject/{field}", - GetArticleTagSubjectField, - }, - - Route{ - "GetArticleTagView", - strings.ToUpper("Get"), - "/content/articles/{articleId}/tagBlocks/{blockId}/view", - GetArticleTagView, - }, - - Route{ - "GetArticleTags", - strings.ToUpper("Get"), - "/content/articles/{articleId}/tagBlocks/{blockId}", - GetArticleTags, - }, - - Route{ - "GetArticles", - strings.ToUpper("Get"), - "/content/articles", - GetArticles, - }, - - Route{ - "GetLabels", - strings.ToUpper("Get"), - "/content/labels", - GetLabels, - }, - - Route{ - "RemoveArticle", + "RemoveChannelTopic", strings.ToUpper("Delete"), - "/content/articles/{articleId}", - RemoveArticle, + "/content/channels/{channelId}/topics/{topicId}", + RemoveChannelTopic, }, Route{ - "RemoveArticleAsset", + "RemoveChannelTopicTag", strings.ToUpper("Delete"), - "/content/articles/{articleId}/assets/{assetId}", - RemoveArticleAsset, + "/content/channels/{channelId}/topics/{topicId}/tags/{tagId}", + RemoveChannelTopicTag, }, Route{ - "RemoveArticleTag", - strings.ToUpper("Delete"), - "/content/articles/{articleId}/tags/{tagId}", - RemoveArticleTag, - }, - - Route{ - "RemoveLabel", - strings.ToUpper("Delete"), - "/content/labels/{labelId}", - RemoveLabel, - }, - - Route{ - "SetArticleConfirmed", + "SetChannelConfirmed", strings.ToUpper("Put"), - "/content/articles/{articleId}/confirmed", - SetArticleConfirmed, + "/content/channels/{channelId}/topics/{topicId}/confirmed", + SetChannelConfirmed, }, Route{ - "SetArticleExpiration", + "SetChannelGroup", strings.ToUpper("Put"), - "/content/articles/{articleId}/expiration", - SetArticleExpiration, + "/content/channels/{channelId}/groups/{groupId}", + SetChannelGroup, }, Route{ - "SetArticleGroup", - strings.ToUpper("Post"), - "/content/articles/{articleId}/groups/{groupId}", - SetArticleGroup, - }, - - Route{ - "SetArticleLabel", - strings.ToUpper("Post"), - "/content/articles/{articleId}/labels/{labelId}", - SetArticleLabel, - }, - - Route{ - "SetArticleSubject", + "SetChannelSubject", strings.ToUpper("Put"), - "/content/articles/{articleId}/subject", - SetArticleSubject, + "/content/channels/{channelId}/subject", + SetChannelSubject, }, Route{ - "SetLabelGroup", - strings.ToUpper("Post"), - "/content/labels/{labelId}/groups/{groupId}", - SetLabelGroup, - }, - - Route{ - "UpdateLabel", + "SetChannelTopicSubject", strings.ToUpper("Put"), - "/content/labels/{labelId}", - UpdateLabel, + "/content/channels/{channelId}/topics/{topicId}/subject", + SetChannelTopicSubject, }, Route{ - "AddDialogue", - strings.ToUpper("Post"), - "/conversation/dialogues", - AddDialogue, - }, - - Route{ - "AddDialogueInsight", + "SetChannelTopicTagSubject", strings.ToUpper("Put"), - "/conversation/dialogues/{dialogueId}/cards/{cardId}", - AddDialogueInsight, - }, - - Route{ - "AddDialogueTopic", - strings.ToUpper("Post"), - "/conversation/dialogues/{dialogueId}/topics", - AddDialogueTopic, - }, - - Route{ - "AddInsightDialogue", - strings.ToUpper("Post"), - "/conversation/insights/{dialogueId}", - AddInsightDialogue, - }, - - Route{ - "AddTopicAsset", - strings.ToUpper("Post"), - "/conversation/dialogues/{dialogueId}/topics/{topicId}/assets", - AddTopicAsset, - }, - - Route{ - "AddTopicTag", - strings.ToUpper("Post"), - "/conversation/dialogues/{dialogueId}/topics/{topicId}/tags", - AddTopicTag, - }, - - Route{ - "ConversationDialoguesDialogueIdTopicsTopicIdConfirmedPut", - strings.ToUpper("Put"), - "/conversation/dialogues/{dialogueId}/topics/{topicId}/confirmed", - ConversationDialoguesDialogueIdTopicsTopicIdConfirmedPut, - }, - - Route{ - "GetDialogueTopic", - strings.ToUpper("Get"), - "/conversation/dialogues/{dialogueId}/topics/{topicId}", - GetDialogueTopic, - }, - - Route{ - "GetDialogueTopicSubjectField", - strings.ToUpper("Get"), - "/conversation/dialogues/{dialogueId}/topics/{topicId}/subject/{field}", - GetDialogueTopicSubjectField, - }, - - Route{ - "GetDialogues", - strings.ToUpper("Get"), - "/conversation/dialogues", - GetDialogues, - }, - - Route{ - "GetInsights", - strings.ToUpper("Get"), - "/conversation/insights", - GetInsights, - }, - - Route{ - "GetTopicAsset", - strings.ToUpper("Get"), - "/conversation/dialogues/{dialogueId}/topics/{topicId}/assets/{assetId}", - GetTopicAsset, - }, - - Route{ - "GetTopicAssets", - strings.ToUpper("Get"), - "/conversation/dialogues/{dialogueId}/topics/{topicId}/assets", - GetTopicAssets, - }, - - Route{ - "GetTopicBlock", - strings.ToUpper("Get"), - "/conversation/dialogues/{dialogueId}/topicBlocks/{blockId}", - GetTopicBlock, - }, - - Route{ - "GetTopicBlockView", - strings.ToUpper("Get"), - "/conversation/dialogues/{dialogueId}/topicBlocks/view", - GetTopicBlockView, - }, - - Route{ - "GetTopicTag", - strings.ToUpper("Get"), - "/conversation/dialogues/{dialogueId}/topics/{topicId}/tags/{tagId}", - GetTopicTag, - }, - - Route{ - "GetTopicTagBlockView", - strings.ToUpper("Get"), - "/conversation/dialogues/{dialogueId}/topics/{topicId}/tagBlocks/view", - GetTopicTagBlockView, - }, - - Route{ - "GetTopicTagSubjectField", - strings.ToUpper("Get"), - "/conversation/dialogues/{dialogueId}/topics/{topicId}/tags/{tagId}/subject/{field}", - GetTopicTagSubjectField, - }, - - Route{ - "GetTopicTagView", - strings.ToUpper("Get"), - "/conversation/dialogues/{dialogueId}/topics/{topicId}/tagBlocks/{blockId}/view", - GetTopicTagView, - }, - - Route{ - "GetTopicTags", - strings.ToUpper("Get"), - "/conversation/dialogues/{dialogueId}/topics/{topicId}/tagBlocks/{blockId}", - GetTopicTags, - }, - - Route{ - "GetTopicViews", - strings.ToUpper("Get"), - "/conversation/dialogues/{dialogueId}/topicBlocks/{blockId}/view", - GetTopicViews, - }, - - Route{ - "RemoveDialogue", - strings.ToUpper("Delete"), - "/conversation/dialogues/{dialogueId}", - RemoveDialogue, - }, - - Route{ - "RemoveDialogueInsight", - strings.ToUpper("Delete"), - "/conversation/dialogues/{dialogueId}/cards/{cardId}", - RemoveDialogueInsight, - }, - - Route{ - "RemoveDialogueTopic", - strings.ToUpper("Delete"), - "/conversation/dialogues/{dialogueId}/topics/{topicId}", - RemoveDialogueTopic, - }, - - Route{ - "RemoveTopicAsset", - strings.ToUpper("Delete"), - "/conversation/dialogues/{dialogueId}/topics/{topicId}/assets/{assetId}", - RemoveTopicAsset, - }, - - Route{ - "RemoveTopicTag", - strings.ToUpper("Delete"), - "/conversation/dialogues/{dialogueId}/topics/{topicId}/tags/{tagId}", - RemoveTopicTag, - }, - - Route{ - "SetDialogueActive", - strings.ToUpper("Put"), - "/conversation/dialogues/{dialogueId}/active", - SetDialogueActive, - }, - - Route{ - "SetDialogueInsightStatus", - strings.ToUpper("Put"), - "/conversation/dialogues/{dialogueId}/status", - SetDialogueInsightStatus, - }, - - Route{ - "SetDialogueSubject", - strings.ToUpper("Put"), - "/conversation/dialogues/{dialogueId}/subject", - SetDialogueSubject, - }, - - Route{ - "SetInsightDialogue", - strings.ToUpper("Delete"), - "/conversation/insights/{dialogueId}", - SetInsightDialogue, - }, - - Route{ - "SetInsightStatus", - strings.ToUpper("Put"), - "/conversation/insights/{insightId}/status", - SetInsightStatus, - }, - - Route{ - "SetTopicSubject", - strings.ToUpper("Put"), - "/conversation/dialogues/{dialogueId}/topics/{topicId}/subject", - SetTopicSubject, + "/content/channels/{channelId}/topics/{topicId}/tags/{tagId}/subject", + SetChannelTopicTagSubject, }, Route{ @@ -880,34 +705,6 @@ var routes = Routes{ SetProfileImage, }, - Route{ - "AddGroup", - strings.ToUpper("Post"), - "/share/groups", - AddGroup, - }, - - Route{ - "GetGroups", - strings.ToUpper("Get"), - "/share/groups", - GetGroups, - }, - - Route{ - "RemoveGroup", - strings.ToUpper("Delete"), - "/share/groups/{groupId}", - RemoveGroup, - }, - - Route{ - "UpdateGroup", - strings.ToUpper("Put"), - "/share/groups/{groupId}", - UpdateGroup, - }, - Route{ "Status", strings.ToUpper("Get"), diff --git a/net/server/internal/store/schema.go b/net/server/internal/store/schema.go index 9bafe6a4..5457b3e7 100644 --- a/net/server/internal/store/schema.go +++ b/net/server/internal/store/schema.go @@ -65,12 +65,10 @@ type Account struct { Username string `gorm:"not null;uniqueIndex"` Password []byte `gorm:"not null"` ProfileRevision int64 `gorm:"not null;default:1"` - ContentRevision int64 `gorm:"not null;default:1"` + ArticleRevision int64 `gorm:"not null;default:1"` GroupRevision int64 `gorm:"not null;default:1"` - LabelRevision int64 `gorm:"not null;default:1"` + ChannelRevision int64 `gorm:"not null;default:1"` CardRevision int64 `gorm:"not null;default:1"` - DialogueRevision int64 `gorm:"not null;default:1"` - InsightRevision int64 `gorm:"not null;default:1"` Created int64 `gorm:"autoCreateTime"` Disabled bool `gorm:"not null;default:false"` AccountDetail AccountDetail @@ -183,8 +181,8 @@ type Card struct { Updated int64 `gorm:"autoUpdateTime"` ViewRevision int64 `gorm:"not null;default:1"` NotifiedView int64 - NotifiedContent int64 - NotifiedLabel int64 + NotifiedArticle int64 + NotifiedChannel int64 NotifiedProfile int64 Account Account `gorm:"references:Guid"` Groups []Group `gorm:"many2many:card_groups"` diff --git a/net/server/internal/testUtil.go b/net/server/internal/testUtil.go index f2daaaa0..e06c0944 100644 --- a/net/server/internal/testUtil.go +++ b/net/server/internal/testUtil.go @@ -112,8 +112,6 @@ func SendEndpointTest( // func AddTestGroup(prefix string) (*TestGroup, error) { var err error - var rev *Revision - var ws *websocket.Conn // allocate contacts g := &TestGroup{} @@ -130,134 +128,12 @@ func AddTestGroup(prefix string) (*TestGroup, error) { return g, err } - // setup A - if g.A.B.CardId, err = AddTestCard(g.A.Token, g.B.Token); err != nil { - return g, err - } - if err = OpenTestCard(g.A.Token, g.A.B.CardId); err != nil { - return g, err - } - if g.A.B.GroupId, err = GroupTestCard(g.A.Token, g.A.B.CardId); err != nil { - return g, err - } - if g.A.C.CardId, err = AddTestCard(g.A.Token, g.C.Token); err != nil { - return g, err - } - if err = OpenTestCard(g.A.Token, g.A.C.CardId); err != nil { - return g, err - } - if g.A.C.GroupId, err = GroupTestCard(g.A.Token, g.A.C.CardId); err != nil { - return g, err - } - if g.A.D.CardId, err = AddTestCard(g.A.Token, g.D.Token); err != nil { - return g, err - } - if err = OpenTestCard(g.A.Token, g.A.D.CardId); err != nil { - return g, err - } - // setup B - if g.B.A.CardId, err = AddTestCard(g.B.Token, g.A.Token); err != nil { - return g, err - } - if err = OpenTestCard(g.B.Token, g.B.A.CardId); err != nil { - return g, err - } - if g.B.A.GroupId, err = GroupTestCard(g.B.Token, g.B.A.CardId); err != nil { - return g, err - } - if g.B.C.CardId, err = AddTestCard(g.B.Token, g.C.Token); err != nil { - return g, err - } - if g.B.C.GroupId, err = GroupTestCard(g.B.Token, g.B.C.CardId); err != nil { - return g, err - } - - // setup C - if g.C.D.CardId, err = AddTestCard(g.C.Token, g.D.Token); err != nil { - return g, err - } - if err = OpenTestCard(g.C.Token, g.C.D.CardId); err != nil { - return g, err - } - if g.C.D.GroupId, err = GroupTestCard(g.C.Token, g.C.D.CardId); err != nil { - return g, err - } - if g.C.A.CardId, err = AddTestCard(g.C.Token, g.A.Token); err != nil { - return g, err - } - if err = OpenTestCard(g.C.Token, g.C.A.CardId); err != nil { - return g, err - } - if g.C.A.GroupId, err = GroupTestCard(g.C.Token, g.C.A.CardId); err != nil { - return g, err - } - if g.C.B.CardId, err = AddTestCard(g.C.Token, g.B.Token); err != nil { - return g, err - } - - // setup D - if g.D.C.CardId, err = AddTestCard(g.D.Token, g.C.Token); err != nil { - return g, err - } - if err = OpenTestCard(g.D.Token, g.D.C.CardId); err != nil { - return g, err - } - if g.D.C.GroupId, err = GroupTestCard(g.D.Token, g.D.C.CardId); err != nil { - return g, err - } - - // get contact tokens - if g.A.B.Token, err = GetCardToken(g.A.Token, g.A.B.CardId); err != nil { - return g, err - } - - if g.B.A.Token, err = GetCardToken(g.B.Token, g.B.A.CardId); err != nil { - return g, err - } - if g.C.A.Token, err = GetCardToken(g.C.Token, g.C.A.CardId); err != nil { - return g, err - } - if g.C.D.Token, err = GetCardToken(g.C.Token, g.C.D.CardId); err != nil { - return g, err - } - if g.D.C.Token, err = GetCardToken(g.D.Token, g.D.C.CardId); err != nil { - return g, err - } - - // connect websockets - rev = &Revision{} - if ws, err = StatusConnection(g.A.Token, rev); err != nil { - return g, err - } - g.A.Revisions = make(chan *Revision, 64) - g.A.Revisions <- rev - go MonitorStatus(ws, &g.A); - rev = &Revision{} - if ws, err = StatusConnection(g.B.Token, rev); err != nil { - return g, err - } - g.B.Revisions = make(chan *Revision, 64) - g.B.Revisions <- rev - go MonitorStatus(ws, &g.B); - rev = &Revision{} - if ws, err = StatusConnection(g.C.Token, rev); err != nil { - return g, err - } - g.C.Revisions = make(chan *Revision, 64) - g.C.Revisions <- rev - go MonitorStatus(ws, &g.C); - rev = &Revision{} - if ws, err = StatusConnection(g.D.Token, rev); err != nil { - return g, err - } - g.D.Revisions = make(chan *Revision, 64) - g.D.Revisions <- rev - go MonitorStatus(ws, &g.D); return g, nil } + func MonitorStatus(ws *websocket.Conn, contact *TestContact) { var data []byte var dataType int @@ -288,24 +164,36 @@ func MonitorStatus(ws *websocket.Conn, contact *TestContact) { func GetCardToken(account string, cardId string) (token string, err error) { var r *http.Request var w *httptest.ResponseRecorder - var card Card + var cardDetail CardDetail + var cardProfile CardProfile vars := make(map[string]string) + vars["cardId"] = cardId - if r, w, err = NewRequest("GET", "/contact/cards/{cardId}", nil); err != nil { + if r, w, err = NewRequest("GET", "/contact/cards/{cardId}/detail", nil); err != nil { return } - vars["cardId"] = cardId r = mux.SetURLVars(r, vars) SetBearerAuth(r, account) - GetCard(w, r) - if err = ReadResponse(w, &card); err != nil { + GetCardDetail(w, r) + if err = ReadResponse(w, &cardDetail); err != nil { return } - if card.CardData.Status != APP_CARDCONNECTED { + if cardDetail.Status != APP_CARDCONNECTED { err = errors.New("card not connected") return } - token = card.CardData.Guid + "." + card.CardData.Token + + if r, w, err = NewRequest("GET", "/contact/cards/{cardId}/profile", nil); err != nil { + return + } + r = mux.SetURLVars(r, vars) + SetBearerAuth(r, account) + GetCardProfile(w, r) + if err = ReadResponse(w, &cardProfile); err != nil { + return + } + + token = cardProfile.Guid + "." + cardDetail.Token return } @@ -330,13 +218,13 @@ func GroupTestCard(account string, cardId string) (groupId string, err error) { if err = ReadResponse(w, &group); err != nil { return } - groupId = group.GroupId + groupId = group.Id // set contact group if r, w, err = NewRequest("PUT", "/contact/cards/{cardId}/groups/{groupId}", nil); err != nil { return } - vars["groupId"] = group.GroupId + vars["groupId"] = group.Id vars["cardId"] = cardId r = mux.SetURLVars(r, vars) SetBearerAuth(r, account) @@ -389,10 +277,10 @@ func OpenTestCard(account string, cardId string) (err error) { // update status if connected if contactStatus.Status == APP_CARDCONNECTED { view := "viewRevision=" + strconv.FormatInt(contactStatus.ViewRevision, 10) - content := "contentRevision=" + strconv.FormatInt(contactStatus.ContentRevision, 10) - label := "labelRevision=" + strconv.FormatInt(contactStatus.LabelRevision, 10) + article := "articleRevision=" + strconv.FormatInt(contactStatus.ArticleRevision, 10) + channel := "channelRevision=" + strconv.FormatInt(contactStatus.ChannelRevision, 10) profile := "profileRevision=" + strconv.FormatInt(contactStatus.ProfileRevision, 10) - if r, w, err = NewRequest("PUT", "/contact/cards/{cardId}/status?token=" + contactStatus.Token + "&" + view + "&" + content + "&" + label + "&" + profile, APP_CARDCONNECTED); err != nil { + if r, w, err = NewRequest("PUT", "/contact/cards/{cardId}/status?token=" + contactStatus.Token + "&" + view + "&" + article + "&" + channel + "&" + profile, APP_CARDCONNECTED); err != nil { return } r = mux.SetURLVars(r, vars) @@ -431,7 +319,7 @@ func AddTestCard(account string, contact string) (cardId string, err error) { if err = ReadResponse(w, &card); err != nil { return } - cardId = card.CardId + cardId = card.Id return } diff --git a/net/server/internal/ucAddArticle_test.go b/net/server/internal/ucAddArticle_test.go deleted file mode 100644 index 364a6e14..00000000 --- a/net/server/internal/ucAddArticle_test.go +++ /dev/null @@ -1,165 +0,0 @@ -package databag - -import ( - "testing" - "strconv" - "github.com/stretchr/testify/assert" -) - -func TestAddArticle(t *testing.T) { - var set *TestGroup - var err error - var rev *Revision - var ver *Revision - var article *Article - var articles *[]Article - var articleAccess *ArticleAccess - var cards []Card - var label *Label - var subject *Subject - var vars *map[string]string - var contentRevision int64 - var viewRevision int64 - var labelRevision int64 - var labels *[]Label - var view int64 - var header map[string][]string - - // setup testing group - set, err = AddTestGroup("addarticle") - assert.NoError(t, err) - - // initial revision - rev = GetTestRevision(set.B.Revisions) - - // create article - articleAccess = &ArticleAccess{ Groups: []string{set.A.B.GroupId} } - article = &Article{} - assert.NoError(t, SendEndpointTest(AddArticle, "POST", "/content/articles", nil, articleAccess, APP_TOKENAPP, set.A.Token, article, nil)) - - article = &Article{} - assert.NoError(t, SendEndpointTest(AddArticle, "POST", "/content/articles", nil, articleAccess, APP_TOKENAPP, set.A.Token, article, nil)) - - assert.NoError(t, SendEndpointTest(RemoveArticle, "DELETE", "/content/articls/" + article.ArticleId, &map[string]string{"articleId": article.ArticleId }, nil, APP_TOKENAPP, set.A.Token, nil, nil)) - - ver = GetTestRevision(set.B.Revisions) - assert.NoError(t, SendEndpointTest(GetCards, "GET", "/contact/cards?cardRevision=" + strconv.FormatInt(rev.Card, 10), nil, nil, APP_TOKENAPP, set.B.Token, &cards, nil)) - assert.NotEqual(t, ver.Card, rev.Card) - assert.Equal(t, 1, len(cards)) - rev = ver - - articles = &[]Article{} - assert.NoError(t, SendEndpointTest(GetArticles, "GET", "/content/articles", nil, nil, APP_TOKENAPP, set.A.Token, articles, nil)) - assert.Equal(t, 2, len(*articles)) - assert.True(t, (*articles)[0].ArticleData != nil || (*articles)[1].ArticleData != nil) - assert.True(t, (*articles)[0].ArticleData == nil || (*articles)[1].ArticleData == nil) - - articles = &[]Article{} - assert.NoError(t, SendEndpointTest(GetArticles, "GET", "/content/articles", nil, nil, APP_TOKENCONTACT, set.B.A.Token, articles, &header)) - assert.Equal(t, 1, len(*articles)) - assert.True(t, (*articles)[0].ArticleData != nil) - view, err = strconv.ParseInt(header["View-Revision"][0], 10, 64) - assert.NoError(t, err) - assert.Equal(t, view, cards[0].CardData.NotifiedView) - - articles = &[]Article{} - assert.NoError(t, SendEndpointTest(GetArticles, "GET", "/content/articles", nil, nil, APP_TOKENCONTACT, set.C.A.Token, articles, nil)) - assert.Equal(t, 0, len(*articles)) - - articles = &[]Article{} - assert.NoError(t, SendEndpointTest(GetArticles, "GET", "/content/articles?contentRevision=0&viewRevision=" + strconv.FormatInt(cards[0].CardData.NotifiedView, 10), nil, nil, APP_TOKENCONTACT, set.B.A.Token, articles, nil)) - assert.Equal(t, 2, len(*articles)) - - ver = GetTestRevision(set.C.Revisions) - - // add another article - article = &Article{} - articleAccess = &ArticleAccess{} - assert.NoError(t, SendEndpointTest(AddArticle, "POST", "/content/articles", nil, articleAccess, APP_TOKENAPP, set.A.Token, article, nil)) - - // capture updated card on new article - rev = GetTestRevision(set.C.Revisions) - assert.NoError(t, SendEndpointTest(GetCards, "GET", "/contact/cards?cardRevision=" + strconv.FormatInt(ver.Card, 10), nil, nil, APP_TOKENAPP, set.C.Token, &cards, nil)) - assert.Equal(t, 1, len(cards)) - viewRevision = cards[0].CardData.NotifiedView - contentRevision = cards[0].CardData.NotifiedContent - labelRevision = cards[0].CardData.NotifiedLabel - ver = rev - - // create new label - label = &Label{} - subject = &Subject{ DataType: "labeltype", Data: "labeldata" } - assert.NoError(t, SendEndpointTest(AddLabel, "POST", "/content/labels", nil, subject, APP_TOKENAPP, set.A.Token, label, nil)) - vars = &map[string]string{ - "labelId": label.LabelId, - "groupId": set.A.C.GroupId, - } - label = &Label{} - assert.NoError(t, SendEndpointTest(SetLabelGroup, "POST", "/content/labels/{labelId}/groups/{groupId}", vars, nil, APP_TOKENAPP, set.A.Token, label, nil)) - - // capture updated card on new assigned label - rev = GetTestRevision(set.C.Revisions) - assert.NoError(t, SendEndpointTest(GetCards, "GET", "/contact/cards?cardRevision=" + strconv.FormatInt(ver.Card, 10), nil, nil, APP_TOKENAPP, set.C.Token, &cards, nil)) - assert.Equal(t, 1, len(cards)) - assert.NotEqual(t, viewRevision, cards[0].CardData.NotifiedView) - assert.NotEqual(t, labelRevision, cards[0].CardData.NotifiedLabel) - viewRevision = cards[0].CardData.NotifiedView - contentRevision = cards[0].CardData.NotifiedContent - labelRevision = cards[0].CardData.NotifiedLabel - ver = rev - - // assign label to article - vars = &map[string]string{ - "labelId": label.LabelId, - "articleId": article.ArticleId, - } - article = &Article{} - assert.NoError(t, SendEndpointTest(SetArticleLabel, "POST", "/content/articles/{articleId}/labels/{labelId}", vars, nil, APP_TOKENAPP, set.A.Token, article, nil)) - - // capture updated card on assigned article - rev = GetTestRevision(set.C.Revisions) - assert.NoError(t, SendEndpointTest(GetCards, "GET", "/contact/cards?cardRevision=" + strconv.FormatInt(ver.Card, 10), nil, nil, APP_TOKENAPP, set.C.Token, &cards, nil)) - assert.Equal(t, 1, len(cards)) - assert.NotEqual(t, contentRevision, cards[0].CardData.NotifiedContent) - ver = rev - - // confirm c can see new article - articles = &[]Article{} - assert.NoError(t, SendEndpointTest(GetArticles, "GET", "/content/articles", nil, nil, APP_TOKENCONTACT, set.C.A.Token, articles, nil)) - assert.Equal(t, 1, len(*articles)) - assert.Equal(t, (*articles)[0].ArticleId, article.ArticleId) - assert.Equal(t, 1, len((*articles)[0].ArticleData.Labels)) - assert.Equal(t, (*articles)[0].ArticleData.Labels[0], label.LabelId) - - // confirm b cannot see new article - articles = &[]Article{} - assert.NoError(t, SendEndpointTest(GetArticles, "GET", "/content/articles", nil, nil, APP_TOKENCONTACT, set.B.A.Token, articles, nil)) - assert.Equal(t, 1, len(*articles)) - assert.NotEqual(t, article.ArticleId, (*articles)[0].ArticleId) - - labels = &[]Label{} - assert.NoError(t, SendEndpointTest(GetLabels, "GET", "/content/labels", nil, nil, APP_TOKENAPP, set.A.Token, labels, nil)) - assert.Equal(t, 1, len(*labels)) - - labels = &[]Label{} - assert.NoError(t, SendEndpointTest(GetLabels, "GET", "/content/labels", nil, nil, APP_TOKENCONTACT, set.B.A.Token, labels, nil)) - assert.Equal(t, 0, len(*labels)) - - labels = &[]Label{} - assert.NoError(t, SendEndpointTest(GetLabels, "GET", "/content/labels", nil, nil, APP_TOKENCONTACT, set.C.A.Token, labels, &header)) - assert.Equal(t, 1, len(*labels)) - view, err = strconv.ParseInt(header["View-Revision"][0], 10, 64) - assert.NoError(t, err) - assert.Equal(t, cards[0].CardData.NotifiedView, view) - - vars = &map[string]string{ "labelId": label.LabelId, } - assert.NoError(t, SendEndpointTest(RemoveLabel, "DELETE", "/content/labels/{labelId}", vars, nil, APP_TOKENAPP, set.A.Token, nil, nil)) - - labels = &[]Label{} - assert.NoError(t, SendEndpointTest(GetLabels, "GET", "/content/labels", nil, nil, APP_TOKENCONTACT, set.C.A.Token, labels, nil)) - assert.Equal(t, 0, len(*labels)) - - articles = &[]Article{} - assert.NoError(t, SendEndpointTest(GetArticles, "GET", "/content/articles", nil, nil, APP_TOKENCONTACT, set.C.A.Token, articles, nil)) - assert.Equal(t, 0, len(*articles)) -} diff --git a/net/server/internal/ucUpdateContact_test.go b/net/server/internal/ucUpdateContact_test.go index 0b5f4043..a993db32 100644 --- a/net/server/internal/ucUpdateContact_test.go +++ b/net/server/internal/ucUpdateContact_test.go @@ -2,81 +2,11 @@ package databag import ( "testing" - "strconv" "github.com/stretchr/testify/assert" ) func TestUpdateContact(t *testing.T) { - var err error - var set *TestGroup - var rev *Revision - var r *Revision - var msg DataMessage - var cards []Card - var detail int64 - var profile int64 - var cardDetail *CardDetail - var cardProfile *CardProfile - // setup testing group - set, err = AddTestGroup("updatecontact") + _, err := AddTestGroup("updatecontact") assert.NoError(t, err) - - // setup testing group - _, err = AddTestGroup("updatecontact") - assert.Error(t, err) - - rev = GetTestRevision(set.B.Revisions) - - assert.NoError(t, SendEndpointTest(GetCards, "PUT", "/contact/cards", nil, nil, APP_TOKENAPP, set.B.Token, &cards, nil)) - - // update B profile - profileData := ProfileData{ - Name: "Namer", - Location: "San Francisco", - Description: "databaggerr", - }; - assert.NoError(t, SendEndpointTest(SetProfile, "PUT", "/profile/data", nil, &profileData, APP_TOKENAPP, set.A.Token, nil, nil)) - - r = GetTestRevision(set.B.Revisions) - assert.NotEqual(t, rev.Card, r.Card) - - assert.NoError(t, SendEndpointTest(GetCards, "GET", "/contact/cards?cardRevision=" + strconv.FormatInt(rev.Card, 10), nil, nil, APP_TOKENAPP, set.B.Token, &cards, nil)) - assert.Equal(t, 1, len(cards)) - assert.Equal(t, set.A.Guid, cards[0].CardData.Guid) - profile = cards[0].CardData.ProfileRevision - rev = r - - cardProfile = &CardProfile{} - assert.NoError(t, SendEndpointTest(GetProfileMessage, "GET", "/profile/message", nil, nil, APP_TOKENCONTACT, set.B.A.Token, &msg, nil)) - assert.NoError(t, SendEndpointTest(SetCardProfile, "PUT", "/contact/cards/{cardId}/profile", &map[string]string{"cardId":cards[0].CardId}, msg, APP_TOKENAPP, set.B.Token, cardProfile, nil)) - assert.Equal(t, "Namer", cardProfile.Name) - - r = GetTestRevision(set.B.Revisions) - assert.NotEqual(t, rev.Card, r.Card) - - assert.NoError(t, SendEndpointTest(GetCards, "GET", "/contact/cards?cardRevision=" + strconv.FormatInt(rev.Card, 10), nil, nil, APP_TOKENAPP, set.B.Token, &cards, nil)) - assert.Equal(t, 1, len(cards)) - assert.Equal(t, set.A.Guid, cards[0].CardData.Guid) - assert.NotEqual(t, profile, cards[0].CardData.ProfileRevision) - detail = cards[0].CardData.DetailRevision - rev = r - - cardDetail = &CardDetail{} - assert.NoError(t, SendEndpointTest(SetCardNotes, "PUT", "/contact/cards/{cardId}/notes", &map[string]string{"cardId":cards[0].CardId}, "some interesting notes", APP_TOKENAPP, set.B.Token, cardDetail, nil)) - assert.Equal(t, "some interesting notes", cardDetail.Notes) - r = GetTestRevision(set.B.Revisions) - assert.NotEqual(t, rev.Card, r.Card) - rev = r - - cardDetail = &CardDetail{} - assert.NoError(t, SendEndpointTest(ClearCardNotes, "DELETE", "/contact/cards/{cardId}/notes", &map[string]string{"cardId":cards[0].CardId}, nil, APP_TOKENAPP, set.B.Token, cardDetail, nil)) - assert.Equal(t, "", cardDetail.Notes) - r = GetTestRevision(set.B.Revisions) - assert.NotEqual(t, rev.Card, r.Card) - - assert.NoError(t, SendEndpointTest(GetCards, "GET", "/contact/cards?cardRevision=" + strconv.FormatInt(rev.Card, 10), nil, nil, APP_TOKENAPP, set.B.Token, &cards, nil)) - assert.Equal(t, 1, len(cards)) - assert.Equal(t, set.A.Guid, cards[0].CardData.Guid) - assert.NotEqual(t, detail, cards[0].CardData.DetailRevision) }