feature complete app
This commit is contained in:
parent
383828512a
commit
eacce2113c
198
app/cli/main.go
198
app/cli/main.go
|
@ -1,33 +1,151 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
app2 "git.mascherari.press/cwtch/app"
|
app2 "git.mascherari.press/cwtch/app"
|
||||||
"os"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
"github.com/c-bata/go-prompt"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
var app app2.Application
|
||||||
|
|
||||||
|
|
||||||
|
func completer(d prompt.Document) []prompt.Suggest {
|
||||||
|
|
||||||
|
s := []prompt.Suggest{}
|
||||||
|
|
||||||
|
if d.FindStartOfPreviousWord() == 0 {
|
||||||
|
s := []prompt.Suggest{
|
||||||
|
{Text: "new-profile", Description: "create a new profile"},
|
||||||
|
{Text: "load-profile", Description: "load a new profile"},
|
||||||
|
{Text: "quit", Description: "quit cwtch"},
|
||||||
|
{Text: "servers", Description: "retrieve a list of servers and their connection status"},
|
||||||
|
{Text: "peers", Description: "retrieve a list of peers and their connection status"},
|
||||||
|
{Text: "contacts", Description: "retrieve a list of contacts"},
|
||||||
|
{Text: "groups", Description: "retrieve a list of groups"},
|
||||||
|
{Text: "send", Description: "send a message to a group"},
|
||||||
|
{Text: "timeline", Description: "read the timeline of a given group"},
|
||||||
|
{Text: "accept-invite", Description: "accept the invite of a group"},
|
||||||
|
{Text: "invite", Description: "invite a new contact"},
|
||||||
|
{Text: "invite-to-group", Description: "invite an existing contact to join an existing group"},
|
||||||
|
{Text: "new-group", Description: "create a new group"},
|
||||||
|
}
|
||||||
|
return prompt.FilterHasPrefix(s, d.GetWordBeforeCursor(), true)
|
||||||
|
}
|
||||||
|
|
||||||
|
w := d.CurrentLine()
|
||||||
|
if strings.HasPrefix(w, "send") || strings.HasPrefix(w, "timeline") {
|
||||||
|
s = []prompt.Suggest{}
|
||||||
|
groups := app.Peer.Profile.Groups
|
||||||
|
for _, group := range groups {
|
||||||
|
s = append(s, prompt.Suggest{Text: group.GroupID, Description: "Group owned by " + group.Owner + " on " + group.GroupServer})
|
||||||
|
}
|
||||||
|
return prompt.FilterHasPrefix(s, d.GetWordBeforeCursor(), true)
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.HasPrefix(w, "invite-to-group") {
|
||||||
|
|
||||||
|
if d.FindStartOfPreviousWordWithSpace() == 0 {
|
||||||
|
s = []prompt.Suggest{}
|
||||||
|
contacts := app.Peer.Profile.Contacts
|
||||||
|
for _, contact := range contacts {
|
||||||
|
s = append(s, prompt.Suggest{Text: contact.Onion, Description: contact.Name})
|
||||||
|
}
|
||||||
|
return prompt.FilterHasPrefix(s, d.GetWordBeforeCursor(), true)
|
||||||
|
} else {
|
||||||
|
s = []prompt.Suggest{}
|
||||||
|
groups := app.Peer.Profile.Groups
|
||||||
|
for _, group := range groups {
|
||||||
|
if group.Owner == "self" {
|
||||||
|
s = append(s, prompt.Suggest{Text: group.GroupID, Description: "Group owned by " + group.Owner + " on " + group.GroupServer})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return prompt.FilterHasPrefix(s, d.GetWordBeforeCursor(), true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.HasPrefix(w, "accept-invite") {
|
||||||
|
s = []prompt.Suggest{}
|
||||||
|
groups := app.Peer.Profile.Groups
|
||||||
|
for _, group := range groups {
|
||||||
|
if group.Accepted == false {
|
||||||
|
s = append(s, prompt.Suggest{Text: group.GroupID, Description: "Group owned by " + group.Owner + " on " + group.GroupServer})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return prompt.FilterHasPrefix(s, d.GetWordBeforeCursor(), true)
|
||||||
|
}
|
||||||
|
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
quit := false
|
cwtch :=
|
||||||
app := app2.Application{}
|
`
|
||||||
profilefile := ""
|
#, #'
|
||||||
for !quit {
|
@@@@@@:
|
||||||
reader := bufio.NewReader(os.Stdin)
|
@@@@@@.
|
||||||
|
@'@@+#' @@@@+
|
||||||
|
''''''@ #+@ :
|
||||||
|
@''''+;+' . '
|
||||||
|
@''@' :+' , ; ##, +'
|
||||||
|
,@@ ;' #'#@''. #''@''#
|
||||||
|
# ''''''#:,,#'''''@
|
||||||
|
: @''''@ :+'''@
|
||||||
|
' @;+'@ @'#
|
||||||
|
.:# '#..# '# @
|
||||||
|
@@@@@@
|
||||||
|
@@@@@@
|
||||||
|
'@@@@
|
||||||
|
@# . .
|
||||||
|
+++, #'@+'@
|
||||||
|
''', ''''''#
|
||||||
|
.#+# ''', @'''+,
|
||||||
|
@''# ''', .#@
|
||||||
|
:; '@''# .;. ''', ' : ;. ,
|
||||||
|
@+'''@ '+'+ @++ @+'@+''''+@ #+'''#: ''';#''+@ @@@@ @@@@@@@@@ :@@@@#
|
||||||
|
#''''''# +''. +'': +'''''''''+ @'''''''# '''+'''''@ @@@@ @@@@@@@@@@@@@@@@:
|
||||||
|
@'''@@'''@ @''# ,'''@ ''+ @@''+#+ :'''@@+''' ''''@@'''' @@@@ @@@@@@@@@@@@@@@@@
|
||||||
|
'''# @''# +''@ @'''# ;''@ +''+ @''@ ,+'', '''@ #'''. @@@@ @@@@ '@@@# @@@@
|
||||||
|
;''' @@; '''# #'@'' @''@ @''+ +''# .@@ ''', '''. @@@@ @@@ @@@ .@@@
|
||||||
|
@''# #'' ''#''#@''. #''# '''. '''. +'', @@@@ @@@ @@@ @@@
|
||||||
|
@''# @''@'' #'@+'+ #''# '''. ''', +'', +@@@.@@@ @@@@ @@@, @@@ ,@@@
|
||||||
|
;''+ @, +''@'# @'+''@ @''# +''; '+ ''', +'', @@@@@@@@# @@@@ @@@. .@@@ .@@@
|
||||||
|
'''# ++'+ ''''@ ,''''# #''' @''@ '@''+ ''', ''', @@@@@@@@: @@@@ @@@; .@@@' ;@@@
|
||||||
|
@'''@@'''@ #'''. +'''' ;'''#@ :'''#@+''+ ''', ''', @@@@@@# @@@@ @@@+ ,@@@. @@@@
|
||||||
|
#''''''# @''+ @''+ +'''' @'''''''# ''', ''', #@@@. @@@@ @@@+ @@@ @@@@
|
||||||
|
@+''+@ '++@ ;++@ '#''@ ##'''@: +++, +++, :@ @@@@ @@@' @@@ '@@@
|
||||||
|
:' ' '`
|
||||||
|
fmt.Printf("%v\n\n", cwtch)
|
||||||
|
|
||||||
|
quit := false
|
||||||
|
app = app2.Application{}
|
||||||
|
profilefile := ""
|
||||||
|
var history []string
|
||||||
|
for !quit {
|
||||||
profile := "unset"
|
profile := "unset"
|
||||||
if app.Peer != nil {
|
if app.Peer != nil {
|
||||||
profile = app.Peer.Profile.Name
|
profile = app.Peer.Profile.Name
|
||||||
}
|
}
|
||||||
fmt.Printf("cwtch [%v]> ", profile)
|
prmpt := fmt.Sprintf("cwtch [%v]> ", profile)
|
||||||
text, _ := reader.ReadString('\n')
|
|
||||||
commands := strings.Split(text[0:len(text)-1], " ")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
text := prompt.Input(prmpt, completer, prompt.OptionSuggestionBGColor(prompt.Purple),
|
||||||
|
prompt.OptionDescriptionBGColor(prompt.White),
|
||||||
|
prompt.OptionHistory(history))
|
||||||
|
|
||||||
|
commands := strings.Split(text[0:len(text)], " ")
|
||||||
|
history = append(history,text)
|
||||||
switch commands[0] {
|
switch commands[0] {
|
||||||
case "quit":
|
case "quit":
|
||||||
|
app.Peer.Save(profilefile)
|
||||||
quit = true
|
quit = true
|
||||||
case "newprofile":
|
case "new-profile":
|
||||||
if len(commands) == 3 {
|
if len(commands) == 3 {
|
||||||
err := app.NewProfile(commands[1], commands[2])
|
err := app.NewProfile(commands[1], commands[2])
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
@ -38,7 +156,7 @@ func main() {
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf("Error creating NewProfile, usage: newprofile [name] [filename]\n")
|
fmt.Printf("Error creating NewProfile, usage: newprofile [name] [filename]\n")
|
||||||
}
|
}
|
||||||
case "loadprofile":
|
case "load-profile":
|
||||||
if len(commands) == 2 {
|
if len(commands) == 2 {
|
||||||
err := app.SetProfile(commands[1])
|
err := app.SetProfile(commands[1])
|
||||||
profilefile = commands[1]
|
profilefile = commands[1]
|
||||||
|
@ -55,7 +173,7 @@ func main() {
|
||||||
if app.Peer != nil {
|
if app.Peer != nil {
|
||||||
fmt.Printf("Address cwtch:%v\n", app.Peer.Profile.Onion)
|
fmt.Printf("Address cwtch:%v\n", app.Peer.Profile.Onion)
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf("Profile needs to be set")
|
fmt.Printf("Profile needs to be set\n")
|
||||||
}
|
}
|
||||||
case "invite":
|
case "invite":
|
||||||
if len(commands) == 2 {
|
if len(commands) == 2 {
|
||||||
|
@ -69,33 +187,75 @@ func main() {
|
||||||
for p, s := range peers {
|
for p, s := range peers {
|
||||||
fmt.Printf("Name: %v Status: %v\n", p, s)
|
fmt.Printf("Name: %v Status: %v\n", p, s)
|
||||||
}
|
}
|
||||||
|
case "servers":
|
||||||
|
servers := app.Peer.GetServers()
|
||||||
|
for s, st := range servers {
|
||||||
|
fmt.Printf("Name: %v Status: %v\n", s, st)
|
||||||
|
}
|
||||||
case "contacts":
|
case "contacts":
|
||||||
for _, c := range app.Peer.Profile.Contacts {
|
for _, c := range app.Peer.Profile.Contacts {
|
||||||
fmt.Printf("Name: %v, Onion: %v, Trusted: %v\n", c.Name, c.Onion, c.Trusted)
|
fmt.Printf("Name: %v, Onion: %v, Trusted: %v\n", c.Name, c.Onion, c.Trusted)
|
||||||
}
|
}
|
||||||
case "groups":
|
case "groups":
|
||||||
for gid, g := range app.Peer.Profile.Groups {
|
for gid, g := range app.Peer.Profile.Groups {
|
||||||
fmt.Printf("Group Id: %v, Owner: %v\n", gid, g.Owner)
|
fmt.Printf("Group Id: %v, Owner: %v Accepted:%v \n", gid, g.Owner, g.Accepted)
|
||||||
}
|
}
|
||||||
case "invitetogroup":
|
case "accept-invite":
|
||||||
|
if len(commands) == 2 {
|
||||||
|
groupID:= commands[1]
|
||||||
|
err := app.Peer.AcceptInvite(groupID)
|
||||||
|
if err == nil {
|
||||||
|
fmt.Printf("Error: %v\n", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Printf("Error accepting invite, usage: accept-invite [groupid]\n")
|
||||||
|
}
|
||||||
|
case "invite-to-group":
|
||||||
if len(commands) == 3 {
|
if len(commands) == 3 {
|
||||||
fmt.Printf("Inviting %v to %v\n", commands[1], commands[2])
|
fmt.Printf("Inviting %v to %v\n", commands[1], commands[2])
|
||||||
err := app.Peer.InviteOnionToGroup(commands[1], commands[2])
|
err := app.Peer.InviteOnionToGroup(commands[1], commands[2])
|
||||||
if err == nil {
|
if err != nil {
|
||||||
fmt.Printf("Error: %v", err)
|
fmt.Printf("Error: %v\n", err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf("Error inviting peer to group, usage: invitetogroup [onion] [groupid]\n")
|
fmt.Printf("Error inviting peer to group, usage: invitetogroup [onion] [groupid]\n")
|
||||||
}
|
}
|
||||||
case "newgroup":
|
case "new-group":
|
||||||
if len(commands) == 2 {
|
if len(commands) == 2 {
|
||||||
fmt.Printf("Setting up a new group on server:%v\n", commands[1])
|
fmt.Printf("Setting up a new group on server:%v\n", commands[1])
|
||||||
id, _ := app.Peer.Profile.StartGroup(commands[1])
|
id, _ := app.Peer.Profile.StartGroup(commands[1])
|
||||||
fmt.Printf("New Group [%v] created for server %v", id, commands[1])
|
fmt.Printf("New Group [%v] created for server %v\n", id, commands[1])
|
||||||
app.Peer.Save(profilefile)
|
app.Peer.Save(profilefile)
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf("Error inviting peer, usage: newgroup [server]\n")
|
fmt.Printf("Error inviting peer, usage: newgroup [server]\n")
|
||||||
}
|
}
|
||||||
|
case "send":
|
||||||
|
if len(commands) > 2 {
|
||||||
|
message := strings.Join(commands[2:], " ")
|
||||||
|
err := app.Peer.SendMessageToGroup(commands[1], message)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error: %v\n", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Printf("Error sending message to group, usage: send [groupid] [message]\n")
|
||||||
|
}
|
||||||
|
case "timeline":
|
||||||
|
if len(commands) == 2 {
|
||||||
|
group := app.Peer.Profile.GetGroupByGroupId(commands[1])
|
||||||
|
if group == nil {
|
||||||
|
fmt.Printf("Error: group does not exist\n")
|
||||||
|
} else {
|
||||||
|
for _, m := range group.Timeline.Messages {
|
||||||
|
verified := "not-verified"
|
||||||
|
if m.Verified {
|
||||||
|
verified = "verified"
|
||||||
|
}
|
||||||
|
fmt.Printf("%v %v: %v [%s]\n", m.Timestamp, m.PeerID, m.Message, verified)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Printf("Error reading timeline from group, usage: timeline [groupid]\n")
|
||||||
|
}
|
||||||
case "save":
|
case "save":
|
||||||
app.Peer.Save(profilefile)
|
app.Peer.Save(profilefile)
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,6 +58,14 @@ func (t Timeline) Less(i, j int) bool {
|
||||||
|
|
||||||
func (t *Timeline) Insert(mi *Message) {
|
func (t *Timeline) Insert(mi *Message) {
|
||||||
t.lock.Lock()
|
t.lock.Lock()
|
||||||
|
|
||||||
|
for _,m := range t.Messages {
|
||||||
|
if compareSignatures(m.Signature, mi.Signature) {
|
||||||
|
t.lock.Unlock()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
t.Messages = append(t.Messages, *mi)
|
t.Messages = append(t.Messages, *mi)
|
||||||
sort.Sort(t)
|
sort.Sort(t)
|
||||||
t.lock.Unlock()
|
t.lock.Unlock()
|
||||||
|
|
|
@ -81,6 +81,12 @@ func (p *Profile) AddContact(onion string, profile PublicProfile) {
|
||||||
|
|
||||||
// VerifyMessage confirms the authenticity of a message given an onion, message and signature.
|
// VerifyMessage confirms the authenticity of a message given an onion, message and signature.
|
||||||
func (p *Profile) VerifyGroupMessage(onion string, groupID string, message string, timestamp int32, signature []byte) bool {
|
func (p *Profile) VerifyGroupMessage(onion string, groupID string, message string, timestamp int32, signature []byte) bool {
|
||||||
|
|
||||||
|
if onion == p.Onion {
|
||||||
|
m := message + groupID + strconv.Itoa(int(timestamp))
|
||||||
|
return ed25519.Verify(p.Ed25519PublicKey, []byte(m), signature)
|
||||||
|
}
|
||||||
|
|
||||||
contact, found := p.Contacts[onion]
|
contact, found := p.Contacts[onion]
|
||||||
if found {
|
if found {
|
||||||
m := message + groupID + strconv.Itoa(int(timestamp))
|
m := message + groupID + strconv.Itoa(int(timestamp))
|
||||||
|
|
|
@ -22,19 +22,28 @@ func NewConnectionsManager() *Manager {
|
||||||
|
|
||||||
func (m *Manager) ManagePeerConnection(host string, profile *model.Profile) {
|
func (m *Manager) ManagePeerConnection(host string, profile *model.Profile) {
|
||||||
m.lock.Lock()
|
m.lock.Lock()
|
||||||
|
|
||||||
|
|
||||||
|
_,exists := m.peerConnections[host]
|
||||||
|
if !exists {
|
||||||
ppc := NewPeerPeerConnection(host, profile)
|
ppc := NewPeerPeerConnection(host, profile)
|
||||||
go ppc.Run()
|
go ppc.Run()
|
||||||
m.peerConnections[host] = ppc
|
m.peerConnections[host] = ppc
|
||||||
|
}
|
||||||
m.lock.Unlock()
|
m.lock.Unlock()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Manager) ManageServerConnection(host string, handler func(string, *protocol.GroupMessage)) {
|
func (m *Manager) ManageServerConnection(host string, handler func(string, *protocol.GroupMessage)) {
|
||||||
m.lock.Lock()
|
m.lock.Lock()
|
||||||
|
|
||||||
|
_,exists := m.serverConnections[host]
|
||||||
|
if !exists {
|
||||||
psc := NewPeerServerConnection(host)
|
psc := NewPeerServerConnection(host)
|
||||||
go psc.Run()
|
go psc.Run()
|
||||||
psc.GroupMessageHandler = handler
|
psc.GroupMessageHandler = handler
|
||||||
m.serverConnections[host] = psc
|
m.serverConnections[host] = psc
|
||||||
|
}
|
||||||
m.lock.Unlock()
|
m.lock.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,6 +57,17 @@ func (m *Manager) GetPeers() map[string]ConnectionState {
|
||||||
return rm
|
return rm
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (m *Manager) GetServers() map[string]ConnectionState {
|
||||||
|
rm := make(map[string]ConnectionState)
|
||||||
|
m.lock.Lock()
|
||||||
|
for onion, psc := range m.serverConnections {
|
||||||
|
rm[onion] = psc.GetState()
|
||||||
|
}
|
||||||
|
m.lock.Unlock()
|
||||||
|
return rm
|
||||||
|
}
|
||||||
|
|
||||||
func (m *Manager) GetPeerPeerConnectionForOnion(host string) (ppc *PeerPeerConnection) {
|
func (m *Manager) GetPeerPeerConnectionForOnion(host string) (ppc *PeerPeerConnection) {
|
||||||
m.lock.Lock()
|
m.lock.Lock()
|
||||||
ppc = m.peerConnections[host]
|
ppc = m.peerConnections[host]
|
||||||
|
|
|
@ -46,6 +46,11 @@ func (cp *CwtchPeer) setup() {
|
||||||
cp.PeerWithOnion(onion)
|
cp.PeerWithOnion(onion)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _,group := range cp.Profile.Groups {
|
||||||
|
if group.Accepted || group.Owner == "self" {
|
||||||
|
cp.JoinServer(group.GroupServer)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCwtchPeer(name string) *CwtchPeer {
|
func NewCwtchPeer(name string) *CwtchPeer {
|
||||||
|
@ -87,6 +92,7 @@ func (cp *CwtchPeer) InviteOnionToGroup(onion string, groupid string) error {
|
||||||
ppc := cp.connectionsManager.GetPeerPeerConnectionForOnion(onion)
|
ppc := cp.connectionsManager.GetPeerPeerConnectionForOnion(onion)
|
||||||
fmt.Printf("Got connection for group: %v - Sending Invite\n", ppc)
|
fmt.Printf("Got connection for group: %v - Sending Invite\n", ppc)
|
||||||
ppc.SendGroupInvite(invite)
|
ppc.SendGroupInvite(invite)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
return errors.New("group id could not be found")
|
return errors.New("group id could not be found")
|
||||||
}
|
}
|
||||||
|
@ -99,20 +105,46 @@ func (cp *CwtchPeer) JoinServer(onion string) {
|
||||||
cp.connectionsManager.ManageServerConnection(onion, cp.ReceiveGroupMessage)
|
cp.connectionsManager.ManageServerConnection(onion, cp.ReceiveGroupMessage)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cp *CwtchPeer) SendMessageToGroup(groupid string, message string) {
|
func (cp *CwtchPeer) SendMessageToGroup(groupid string, message string) error {
|
||||||
group := cp.Profile.GetGroupByGroupId(groupid)
|
group := cp.Profile.GetGroupByGroupId(groupid)
|
||||||
|
if group == nil {
|
||||||
|
return errors.New("group does not exit")
|
||||||
|
}
|
||||||
psc := cp.connectionsManager.GetPeerServerConnectionForOnion(group.GroupServer)
|
psc := cp.connectionsManager.GetPeerServerConnectionForOnion(group.GroupServer)
|
||||||
ct := cp.Profile.EncryptMessageToGroup(message, groupid)
|
ct := cp.Profile.EncryptMessageToGroup(message, groupid)
|
||||||
gm := &protocol.GroupMessage{
|
gm := &protocol.GroupMessage{
|
||||||
Ciphertext: ct,
|
Ciphertext: ct,
|
||||||
}
|
}
|
||||||
psc.SendGroupMessage(gm)
|
psc.SendGroupMessage(gm)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cp *CwtchPeer) GetPeers() map[string]connections.ConnectionState {
|
func (cp *CwtchPeer) GetPeers() map[string]connections.ConnectionState {
|
||||||
return cp.connectionsManager.GetPeers()
|
return cp.connectionsManager.GetPeers()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cp *CwtchPeer) GetServers() map[string]connections.ConnectionState {
|
||||||
|
return cp.connectionsManager.GetServers()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cp *CwtchPeer) AcceptInvite(groupID string) error {
|
||||||
|
g := cp.Profile.GetGroupByGroupId(groupID)
|
||||||
|
if g == nil {
|
||||||
|
return errors.New("group invite does not exit")
|
||||||
|
}
|
||||||
|
g.Accepted = true
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cp *CwtchPeer) RejectInvite(groupID string) error {
|
||||||
|
g := cp.Profile.GetGroupByGroupId(groupID)
|
||||||
|
if g == nil {
|
||||||
|
return errors.New("group invite does not exit")
|
||||||
|
}
|
||||||
|
g.Accepted = false
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (cp *CwtchPeer) Listen() error {
|
func (cp *CwtchPeer) Listen() error {
|
||||||
cwtchpeer := new(application.RicochetApplication)
|
cwtchpeer := new(application.RicochetApplication)
|
||||||
l, err := application.SetupOnion("127.0.0.1:9051", "tcp4", "", cp.Profile.OnionPrivateKey, 9878)
|
l, err := application.SetupOnion("127.0.0.1:9051", "tcp4", "", cp.Profile.OnionPrivateKey, 9878)
|
||||||
|
|
Loading…
Reference in New Issue