diff --git a/net/server/internal/api_addCard.go b/net/server/internal/api_addCard.go
index 60616c32..36b14ee0 100644
--- a/net/server/internal/api_addCard.go
+++ b/net/server/internal/api_addCard.go
@@ -97,6 +97,10 @@ func AddCard(w http.ResponseWriter, r *http.Request) {
card.Node = identity.Node
card.ProfileRevision = identity.Revision
}
+ if card.Status == APP_CARDPENDING {
+ card.Status = APP_CARDCONFIRMED
+ }
+ card.DetailRevision = account.CardRevision + 1
// save contact card
err = store.DB.Transaction(func(tx *gorm.DB) error {
diff --git a/net/server/internal/api_getOpenMessage.go b/net/server/internal/api_getOpenMessage.go
index 3c344687..a53b56d4 100644
--- a/net/server/internal/api_getOpenMessage.go
+++ b/net/server/internal/api_getOpenMessage.go
@@ -10,7 +10,7 @@ import (
func GetOpenMessage(w http.ResponseWriter, r *http.Request) {
- account, code, res := BearerAppToken(r, true);
+ account, code, res := ParamAgentToken(r, true);
if res != nil {
ErrResponse(w, code, res)
return
diff --git a/net/server/internal/api_setCardStatus.go b/net/server/internal/api_setCardStatus.go
index 9b5fcc1b..1a37852a 100644
--- a/net/server/internal/api_setCardStatus.go
+++ b/net/server/internal/api_setCardStatus.go
@@ -14,7 +14,7 @@ import (
func SetCardStatus(w http.ResponseWriter, r *http.Request) {
var res error
- account, code, err := BearerAppToken(r, false);
+ account, code, err := ParamAgentToken(r, false);
if err != nil {
ErrResponse(w, code, err)
return
diff --git a/net/server/internal/api_setOpenMessage.go b/net/server/internal/api_setOpenMessage.go
index 3c597f11..9c95d4e6 100644
--- a/net/server/internal/api_setOpenMessage.go
+++ b/net/server/internal/api_setOpenMessage.go
@@ -44,7 +44,7 @@ func SetOpenMessage(w http.ResponseWriter, r *http.Request) {
// see if card exists
slot := &store.CardSlot{}
card := &store.Card{}
- if err := store.DB.Where("account_id = ? AND guid = ?", account.Guid, guid).First(card).Error; err != nil {
+ if err := store.DB.Preload("CardSlot").Where("account_id = ? AND guid = ?", account.Guid, guid).First(card).Error; err != nil {
if !errors.Is(err, gorm.ErrRecordNotFound) {
ErrResponse(w, http.StatusInternalServerError, err)
return
@@ -74,54 +74,28 @@ func SetOpenMessage(w http.ResponseWriter, r *http.Request) {
card.InToken = hex.EncodeToString(data)
card.AccountID = account.Guid
- // create new card or update existing
- if err = store.DB.Preload("Card").Where("account_id = ? AND card_id = 0", account.ID).First(slot).Error; err != nil {
- if !errors.Is(err, gorm.ErrRecordNotFound) {
- ErrResponse(w, http.StatusInternalServerError, err)
- return
+ // create slot
+ err = store.DB.Transaction(func(tx *gorm.DB) error {
+ if res := tx.Save(card).Error; res != nil {
+ return res
}
- err = store.DB.Transaction(func(tx *gorm.DB) error {
- if res := tx.Save(card).Error; res != nil {
- return res
- }
- slot.CardSlotId = uuid.New().String()
- slot.AccountID = account.ID
- slot.Revision = account.CardRevision + 1
- slot.CardID = card.ID
- slot.Card = card
- if res := tx.Save(slot).Error; res != nil {
- return res
- }
- if res := tx.Model(&account).Update("card_revision", account.CardRevision + 1).Error; res != nil {
- return res
- }
- return nil
- })
- if err != nil {
- ErrResponse(w, http.StatusInternalServerError, err)
- return
+ slot.CardSlotId = uuid.New().String()
+ slot.AccountID = account.ID
+ slot.Revision = account.CardRevision + 1
+ slot.CardID = card.ID
+ slot.Card = card
+ if res := tx.Save(slot).Error; res != nil {
+ return res
}
- } else {
- err = store.DB.Transaction(func(tx *gorm.DB) error {
- if res := tx.Save(card).Error; res != nil {
- return res
- }
- slot.Revision = account.CardRevision + 1
- slot.CardID = card.ID
- if res := tx.Save(slot).Error; res != nil {
- return res
- }
- if res := tx.Model(&account).Update("card_revision", account.CardRevision + 1).Error; res != nil {
- return res
- }
- return nil
- })
- if err != nil {
- ErrResponse(w, http.StatusInternalServerError, err)
- return
+ if res := tx.Model(&account).Update("card_revision", account.CardRevision + 1).Error; res != nil {
+ return res
}
+ return nil
+ })
+ if err != nil {
+ ErrResponse(w, http.StatusInternalServerError, err)
+ return
}
-
} else {
// update profile if revision changed
@@ -160,20 +134,8 @@ func SetOpenMessage(w http.ResponseWriter, r *http.Request) {
if res := tx.Save(&card).Error; res != nil {
return res
}
- if res := tx.Preload("Card").Where("account_id = ? AND card_id = ?", account.ID, card.ID).First(&slot).Error; res != nil {
- if !errors.Is(res, gorm.ErrRecordNotFound) {
- return nil
- }
- slot = &store.CardSlot{
- CardSlotId: uuid.New().String(),
- AccountID: account.ID,
- Revision: account.CardRevision + 1,
- CardID: card.ID,
- Card: card,
- }
- } else {
- slot.Revision = account.CardRevision + 1
- }
+ slot = &card.CardSlot
+ slot.Revision = account.CardRevision + 1
if res := tx.Preload("Card").Save(slot).Error; res != nil {
return res
}
@@ -189,9 +151,9 @@ func SetOpenMessage(w http.ResponseWriter, r *http.Request) {
}
status := &ContactStatus{
- Token: slot.Card.InToken,
- Status: slot.Card.Status,
- ViewRevision: slot.Card.ViewRevision,
+ Token: card.InToken,
+ Status: card.Status,
+ ViewRevision: card.ViewRevision,
ChannelRevision: account.ChannelRevision,
ProfileRevision: account.ProfileRevision,
ArticleRevision: account.ArticleRevision,
diff --git a/net/server/internal/main_test.go b/net/server/internal/main_test.go
index 37b9ffb9..792a00d5 100644
--- a/net/server/internal/main_test.go
+++ b/net/server/internal/main_test.go
@@ -54,7 +54,7 @@ func TestMain(m *testing.M) {
}
// config server
- config := NodeConfig{Domain: "example.com", AccountLimit: 1024, OpenAccess: true, AccountStorage: 4096}
+ config := NodeConfig{Domain: "databag.coredb.org", AccountLimit: 1024, OpenAccess: true, AccountStorage: 4096}
r, w, _ = NewRequest("PUT", "/admin/config", &config)
SetBasicAuth(r, "admin:pass")
SetNodeConfig(w, r)
@@ -70,7 +70,7 @@ func TestMain(m *testing.M) {
if ReadResponse(w, &check) != nil {
panic("failed to get node config")
}
- if check.Domain != "example.com" {
+ if check.Domain != "databag.coredb.org" {
panic("failed to set config domain");
}
if check.AccountLimit != 1024 {
diff --git a/net/server/internal/testUtil.go b/net/server/internal/testUtil.go
index 965b9ed5..1991a663 100644
--- a/net/server/internal/testUtil.go
+++ b/net/server/internal/testUtil.go
@@ -521,22 +521,20 @@ func OpenTestCard(account string, cardId string) (err error) {
var contactStatus ContactStatus
// set to connecting state
- if r, w, err = NewRequest("PUT", "/contact/cards/{cardId}/status", APP_CARDCONNECTING); err != nil {
+ if r, w, err = NewRequest("PUT", "/contact/cards/{cardId}/status?agent=" + account, APP_CARDCONNECTING); err != nil {
return
}
r = mux.SetURLVars(r, vars)
- SetBearerAuth(r, account)
SetCardStatus(w, r)
if err = ReadResponse(w, &card); err != nil {
return
}
// get open message
- if r, w, err = NewRequest("GET", "/contact/cards/{cardId}/openMessage", nil); err != nil {
+ if r, w, err = NewRequest("GET", "/contact/cards/{cardId}/openMessage?agent=" + account, nil); err != nil {
return
}
r = mux.SetURLVars(r, vars)
- SetBearerAuth(r, account)
GetOpenMessage(w, r)
if err = ReadResponse(w, &msg); err != nil {
return
@@ -557,11 +555,10 @@ func OpenTestCard(account string, cardId string) (err error) {
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 + "&" + article + "&" + channel + "&" + profile, APP_CARDCONNECTED); err != nil {
+ if r, w, err = NewRequest("PUT", "/contact/cards/{cardId}/status?agent=" + account + "&token=" + contactStatus.Token + "&" + view + "&" + article + "&" + channel + "&" + profile, APP_CARDCONNECTED); err != nil {
return
}
r = mux.SetURLVars(r, vars)
- SetBearerAuth(r, account)
SetCardStatus(w, r)
if err = ReadResponse(w, &card); err != nil {
return
@@ -605,7 +602,7 @@ func AddTestAccount(username string) (guid string, token string, err error) {
app := AppData{
Name: "Appy",
Description: "A test app",
- Url: "http://app.example.com",
+ Url: "http://app.coredb.org",
};
var claim Claim
var msg DataMessage
diff --git a/net/web/src/Api/getCardOpenMessage.js b/net/web/src/Api/getCardOpenMessage.js
new file mode 100644
index 00000000..130a6d89
--- /dev/null
+++ b/net/web/src/Api/getCardOpenMessage.js
@@ -0,0 +1,8 @@
+import { checkResponse, fetchWithTimeout } from './fetchUtil';
+
+export async function getCardOpenMessage(token, cardId) {
+ let message = await fetchWithTimeout(`/contact/cards/${cardId}/openMessage?agent=${token}`, { method: 'GET' });
+ checkResponse(message);
+ return await message.json();
+}
+
diff --git a/net/web/src/Api/setCardOpenMessage.js b/net/web/src/Api/setCardOpenMessage.js
new file mode 100644
index 00000000..b9e39884
--- /dev/null
+++ b/net/web/src/Api/setCardOpenMessage.js
@@ -0,0 +1,8 @@
+import { checkResponse, fetchWithTimeout } from './fetchUtil';
+
+export async function setCardOpenMessage(server, message) {
+ let status = await fetchWithTimeout(`https://${server}/contact/openMessage`, { method: 'PUT', body: JSON.stringify(message) });
+ checkResponse(status);
+ return await status.json();
+}
+
diff --git a/net/web/src/Api/setCardStatus.js b/net/web/src/Api/setCardStatus.js
new file mode 100644
index 00000000..843bda2b
--- /dev/null
+++ b/net/web/src/Api/setCardStatus.js
@@ -0,0 +1,20 @@
+import { checkResponse, fetchWithTimeout } from './fetchUtil';
+
+export async function setCardConnecting(token, cardId) {
+ let card = await fetchWithTimeout(`/contact/cards/${cardId}/status?agent=${token}`, { method: 'PUT', body: JSON.stringify('connecting') } );
+ checkResponse(card);
+ return await card.json();
+}
+
+export async function setCardConnected(token, cardId, access, view, article, channel, profile) {
+ let card = await fetchWithTimeout(`/contact/cards/${cardId}/status?agent=${token}&token=${access}&viewRevision=${view}&articleRevision=${article}&channelRevision=${channel}&profileRevision=${profile}`, { method: 'PUT', body: JSON.stringify('connected') } );
+ checkResponse(card);
+ return await card.json();
+}
+
+export async function setCardConfirmed(token, cardId) {
+ let card = await fetchWithTimeout(`/contact/cards/${cardId}/status?agent=${token}`, { method: 'PUT', body: JSON.stringify('confirmed') } );
+ checkResponse(card);
+ return await card.json();
+}
+
diff --git a/net/web/src/User/Contact/Contact.jsx b/net/web/src/User/Contact/Contact.jsx
index 70e42f3f..087df8ef 100644
--- a/net/web/src/User/Contact/Contact.jsx
+++ b/net/web/src/User/Contact/Contact.jsx
@@ -74,6 +74,13 @@ export function Contact() {
return <>>
}
+ const Confirm = () => {
+ if (state.showButtons.confirm) {
+ return actions.confirm()}>Save Contact
+ }
+ return <>>
+ }
+
const SaveRequest = () => {
if (state.showButtons.saveRequest) {
return Save & Request
@@ -83,7 +90,7 @@ export function Contact() {
const Connect = () => {
if (state.showButtons.connect) {
- return Connect
+ return actions.connect()}>Connect
}
return <>>
}
@@ -110,6 +117,7 @@ export function Contact() {
+
diff --git a/net/web/src/User/Contact/Contact.styled.js b/net/web/src/User/Contact/Contact.styled.js
index 506a67d0..f849ff4b 100644
--- a/net/web/src/User/Contact/Contact.styled.js
+++ b/net/web/src/User/Contact/Contact.styled.js
@@ -64,6 +64,7 @@ export const ContactWrapper = styled.div`
display: flex;
flex-direction: row;
margin-right: 32px;
+ align-items: center;
}
.profile {
diff --git a/net/web/src/User/Contact/useContact.hook.js b/net/web/src/User/Contact/useContact.hook.js
index bace5684..8e55d9a1 100644
--- a/net/web/src/User/Contact/useContact.hook.js
+++ b/net/web/src/User/Contact/useContact.hook.js
@@ -4,6 +4,9 @@ import { useNavigate, useLocation, useParams } from "react-router-dom";
import { getListingMessage } from '../../Api/getListingMessage';
import { addCard } from '../../Api/addCard';
import { removeCard } from '../../Api/removeCard';
+import { setCardConnecting, setCardConnected, setCardConfirmed } from '../../Api/setCardStatus';
+import { getCardOpenMessage } from '../../Api/getCardOpenMessage';
+import { setCardOpenMessage } from '../../Api/setCardOpenMessage';
export function useContact() {
@@ -46,7 +49,34 @@ export function useContact() {
updateState({ busy: false });
}
},
- connect: () => {
+ confirm: async () => {
+ if (!state.busy) {
+ updateState({ busy: true });
+ try {
+ await setCardConfirmed(app.state.token, state.cardId);
+ }
+ catch (err) {
+ window.alert(err);
+ }
+ updateState({ busy: false });
+ }
+ },
+ connect: async () => {
+ if (!state.busy) {
+ updateState({ busy: true });
+ try {
+ await setCardConnecting(app.state.token, state.cardId);
+ let message = await getCardOpenMessage(app.state.token, state.cardId);
+ let contact = await setCardOpenMessage(state.node, message);
+ if (contact.status === 'connected') {
+ await setCardConnected(app.state.token, state.cardId, contact.token, contact.viewRevision, contact.articleRevision, contact.channelRevision, contact.profileRevision);
+ }
+ }
+ catch (err) {
+ window.alert(err);
+ }
+ updateState({ busy: false });
+ }
},
disconnect: () => {
},
@@ -100,11 +130,11 @@ export function useContact() {
updateState({ showButtons: { cancel: true, remove: true }});
}
if (status === 'pending') {
- updateState({ status: 'requested' });
- updateState({ showButtons: { ignore: true, save: true, saveAccept: true }});
+ updateState({ status: 'pending' });
+ updateState({ showButtons: { ignore: true, confirm: true, saveAccept: true }});
}
if (status === 'confirmed') {
- updateState({ status: 'disconnected' });
+ updateState({ status: 'confirmed' });
updateState({ showButtons: { remove: true, connect: true }});
}
if (status === 'requested') {
diff --git a/net/web/src/User/SideBar/SideBar.styled.js b/net/web/src/User/SideBar/SideBar.styled.js
index 0696630a..d4d8f788 100644
--- a/net/web/src/User/SideBar/SideBar.styled.js
+++ b/net/web/src/User/SideBar/SideBar.styled.js
@@ -1,10 +1,10 @@
import styled from 'styled-components';
export const SideBarWrapper = styled.div`
- width: 30%;
+ width: 20%;
height: 100%;
max-width: 300px;
- min-width: 200px;
+ min-width: 260px;
border-right: 1px solid #8fbea7;
background-color: #8fbea7;
`;