package main
import (
"crypto/rand"
"encoding/base64"
"encoding/json"
"fmt"
"unicode"
log "github.com/sirupsen/logrus"
"golang.org/x/crypto/nacl/secretbox"
. "git.deuxfleurs.fr/Deuxfleurs/easybridge/connector"
)
const EASYBRIDGE_SYSTEM_PROTOCOL string = "✯◡✯"
func ezbrMxId() string {
return fmt.Sprintf("@%s:%s", registration.SenderLocalpart, config.MatrixDomain)
}
func ezbrSystemRoom(user_mx_id string) (string, error) {
mx_room_id, err := dbGetMxPmRoom(EASYBRIDGE_SYSTEM_PROTOCOL, UserID("Easybridge"), ezbrMxId(), user_mx_id, "easybridge")
if err != nil {
return "", err
}
widget_kv_key := "ezbr_widget_on:" + mx_room_id
if config.WebURL != "" && dbKvTestAndSet(widget_kv_key, "yes") {
widget := map[string]interface{}{
"type": "m.easybridge",
"url": config.WebURL,
"name": "Easybridge account configuration dashboard",
}
err = mx.PutStateAs(mx_room_id, "im.vector.modular.widgets", "ezbr_widget", widget, ezbrMxId())
if err != nil {
dbKvPut(widget_kv_key, "")
}
}
return mx_room_id, nil
}
func ezbrSystemSend(user_mx_id string, msg string) {
mx_room_id, err := ezbrSystemRoom(user_mx_id)
if err == nil {
err = mx.SendMessageAs(mx_room_id, "m.text", msg, ezbrMxId())
}
if err != nil {
log.Warnf("(%s) %s", user_mx_id, msg)
}
}
func ezbrSystemSendf(user_mx_id string, format string, args ...interface{}) {
ezbrSystemSend(user_mx_id, fmt.Sprintf(format, args...))
}
// ----
func roomAlias(protocol string, id RoomID) string {
return fmt.Sprintf("_ezbr__%s__%s", safeStringForId(string(id)), protocol)
}
func userMxId(protocol string, id UserID) string {
return fmt.Sprintf("_ezbr__%s__%s", safeStringForId(string(id)), protocol)
}
func safeStringForId(in string) string {
id2 := ""
for _, c := range in {
if c == '@' {
id2 += "__"
} else if c == ':' {
id2 += "_"
} else if unicode.IsDigit(c) || unicode.IsLetter(c) || c == '.' || c == '-' || c == '_' {
id2 += string(c)
}
}
return id2
}
// ---- Encoding and encryption of account config
func encryptAccountConfig(config map[string]string, key *[32]byte) string {
bytes, err := json.Marshal(config)
if err != nil {
log.Fatal(err)
}
var nonce [24]byte
_, err = rand.Read(nonce[:])
if err != nil {
log.Fatal(err)
}
crypto := secretbox.Seal([]byte{}, bytes, &nonce, key)
all := append(nonce[:], crypto...)
return base64.StdEncoding.EncodeToString(all)
}
func decryptAccountConfig(data string, key *[32]byte) (map[string]string, error) {
bytes, err := base64.StdEncoding.DecodeString(data)
if err != nil {
return nil, err
}
var nonce [24]byte
copy(nonce[:], bytes[:24])
decoded, ok := secretbox.Open([]byte{}, bytes[24:], &nonce, key)
if !ok {
return nil, fmt.Errorf("Invalid key")
}
var config map[string]string
err = json.Unmarshal(decoded, &config)
return config, err
}