You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

183 lines
3.8 KiB
Go

package core
import (
"encoding/binary"
"errors"
"fmt"
"os"
"github.com/hugot/go-deltachat/deltachat"
"github.com/mdp/qrterminal"
)
func DcClientFromConfig(
databasePath string,
logger deltachat.Logger,
config map[string]string,
) *deltachat.Client {
client := deltachat.NewClient(logger)
// Handler for info logs from libdeltachat
client.On(deltachat.DC_EVENT_INFO, func(c *deltachat.Context, e *deltachat.Event) {
info, _ := e.Data2.String()
logger.Println(*info)
})
client.Open(databasePath)
for key, value := range config {
client.SetConfig(key, value)
}
// TODO: Make this configurable for users
client.SetConfig(
"server_flags",
fmt.Sprintf(
"%d",
deltachat.DC_LP_AUTH_NORMAL|
deltachat.DC_LP_IMAP_SOCKET_SSL|
deltachat.DC_LP_SMTP_SOCKET_STARTTLS,
),
)
client.Configure()
return client
}
// Note: this manipulates the BridgeContext.
func BootstrapDcClientFromConfig(config Config, ctx *BridgeContext) (*deltachat.Client, error) {
dcClient := DcClientFromConfig(
config.App.DataFolder+"/deltachat.db",
ctx.Logger(),
config.Deltachat,
)
DCCtx := dcClient.Context()
ctx.Logger().Println("Waiting for deltachat client to be configured")
for !DCCtx.IsConfigured() {
}
userName := "user"
dcUserID := DCCtx.CreateContact(&userName, &config.App.UserAddress)
var (
userChatID uint32
err error
)
if config.App.VerifiedGroups {
// Send a message in a 1:1 chat first, this will let the user's client know that the
// crypto setup has changed if it has
DCCtx.SendTextMessage(
DCCtx.CreateChatByContactID(dcUserID),
"Hi, Whapp-Deltachat is initializing",
)
userChatIDRaw := ctx.DB.Get([]byte("user-chat-id"))
// The verified group chat that is used as 1:1 between whappDC and the user is
// created here if verified groups are enabled.
if userChatIDRaw == nil {
userChatID, err = AddUserAsVerifiedContact(dcUserID, dcClient, ctx.Logger())
if err != nil {
return nil, err
}
} else {
userChatID = binary.LittleEndian.Uint32(userChatIDRaw)
}
userChatIDbs := make([]byte, 4)
binary.LittleEndian.PutUint32(userChatIDbs, userChatID)
err = ctx.DB.Put([]byte("user-chat-id"), userChatIDbs)
} else {
userChatID = DCCtx.CreateChatByContactID(dcUserID)
}
ctx.DCUserID = dcUserID
ctx.DCUserChatID = userChatID
ctx.DCContext = DCCtx
ctx.DCClient = dcClient
return dcClient, err
}
// Add a user as verified contact to the deltachat context. This is necessary to be able
// to create verified groups.
func AddUserAsVerifiedContact(
dcUserID uint32,
client *deltachat.Client,
logger deltachat.Logger,
) (uint32, error) {
confirmChan := make(chan bool)
client.On(
deltachat.DC_EVENT_SECUREJOIN_INVITER_PROGRESS,
func(c *deltachat.Context, e *deltachat.Event) {
contactIDInt, err := e.Data1.Int()
if err != nil {
logger.Println(err)
confirmChan <- false
return
}
contactID := uint32(*contactIDInt)
if contactID != dcUserID {
logger.Println(
fmt.Sprintf(
"Unexpected contact ID encountered for securejoin progress: %v",
contactID,
),
)
return
}
progress, err := e.Data2.Int()
if err != nil {
logger.Println(err)
confirmChan <- false
return
}
if *progress == 1000 {
confirmChan <- true
}
},
)
ctx := client.Context()
chatID := ctx.CreateGroupChat(true, "Whapp-DC ***status***")
fmt.Println("Scan this qr code with your DC client:")
qrterminal.Generate(
ctx.GetSecurejoinQR(chatID),
qrterminal.L,
os.Stdout,
)
success := <-confirmChan
if !success {
errorString := "Contact Verification process failed"
fmt.Fprintln(os.Stderr, errorString)
return chatID, errors.New(errorString)
}
successString := "Securejoin verification completed"
fmt.Println(successString)
logger.Println(successString)
return chatID, nil
}