mirror of
https://github.com/balzack/databag.git
synced 2025-02-11 19:19:16 +00:00
generate access from within server to avoid distributing api token
This commit is contained in:
parent
3e2b70c5ed
commit
3318048ce3
@ -40,6 +40,17 @@ func AddCall(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
iceService := getBoolConfigValue(CNFIceService, false);
|
||||||
|
iceURL := getStrConfigValue(CNFIceUrl, "")
|
||||||
|
iceUsername := getStrConfigValue(CNFIceUsername, "")
|
||||||
|
icePassword := getStrConfigValue(CNFIcePassword, "")
|
||||||
|
|
||||||
|
ice, err := getIce(iceService, iceURL, iceUsername, icePassword);
|
||||||
|
if err != nil || len(ice) == 0 {
|
||||||
|
ErrResponse(w, http.StatusServiceUnavailable, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// generate call params
|
// generate call params
|
||||||
callerBin, callerErr := securerandom.Bytes(APPTokenSize)
|
callerBin, callerErr := securerandom.Bytes(APPTokenSize)
|
||||||
if callerErr != nil {
|
if callerErr != nil {
|
||||||
@ -51,20 +62,11 @@ func AddCall(w http.ResponseWriter, r *http.Request) {
|
|||||||
ErrResponse(w, http.StatusInternalServerError, calleeErr)
|
ErrResponse(w, http.StatusInternalServerError, calleeErr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
//turnBin, turnErr := securerandom.Bytes(APPTokenSize)
|
|
||||||
//if turnErr != nil {
|
|
||||||
// ErrResponse(w, http.StatusInternalServerError, turnErr)
|
|
||||||
// return
|
|
||||||
//}
|
|
||||||
callId := uuid.New().String()
|
callId := uuid.New().String()
|
||||||
|
|
||||||
// allocate bridge
|
// allocate bridge
|
||||||
callerToken := hex.EncodeToString(callerBin);
|
callerToken := hex.EncodeToString(callerBin);
|
||||||
calleeToken := hex.EncodeToString(calleeBin);
|
calleeToken := hex.EncodeToString(calleeBin);
|
||||||
iceService := getBoolConfigValue(CNFIceService, false);
|
|
||||||
iceUrl := getStrConfigValue(CNFIceUrl, "")
|
|
||||||
iceUsername := getStrConfigValue(CNFIceUsername, "")
|
|
||||||
icePassword := getStrConfigValue(CNFIcePassword, "")
|
|
||||||
bridgeRelay.AddBridge(account.ID, callId, cardId, callerToken, calleeToken);
|
bridgeRelay.AddBridge(account.ID, callId, cardId, callerToken, calleeToken);
|
||||||
|
|
||||||
// create response
|
// create response
|
||||||
@ -73,10 +75,11 @@ func AddCall(w http.ResponseWriter, r *http.Request) {
|
|||||||
CardId: cardId,
|
CardId: cardId,
|
||||||
CallerToken: callerToken,
|
CallerToken: callerToken,
|
||||||
CalleeToken: calleeToken,
|
CalleeToken: calleeToken,
|
||||||
|
Ice: ice,
|
||||||
IceService: iceService,
|
IceService: iceService,
|
||||||
IceUrl: iceUrl,
|
IceURL: ice[len(ice)-1].URLs,
|
||||||
IceUsername: iceUsername,
|
IceUsername: ice[len(ice)-1].Username,
|
||||||
IcePassword: icePassword,
|
IcePassword: ice[len(ice)-1].Credential,
|
||||||
KeepAlive: BridgeKeepAlive,
|
KeepAlive: BridgeKeepAlive,
|
||||||
}
|
}
|
||||||
WriteResponse(w, call);
|
WriteResponse(w, call);
|
||||||
|
@ -26,7 +26,7 @@ func GetNodeConfig(w http.ResponseWriter, r *http.Request) {
|
|||||||
config.PushSupported = getBoolConfigValue(CNFPushSupported, true)
|
config.PushSupported = getBoolConfigValue(CNFPushSupported, true)
|
||||||
config.EnableIce = getBoolConfigValue(CNFEnableIce, false)
|
config.EnableIce = getBoolConfigValue(CNFEnableIce, false)
|
||||||
config.IceService = getBoolConfigValue(CNFIceService, false)
|
config.IceService = getBoolConfigValue(CNFIceService, false)
|
||||||
config.IceUrl = getStrConfigValue(CNFIceUrl, "")
|
config.IceURL = getStrConfigValue(CNFIceUrl, "")
|
||||||
config.IceUsername = getStrConfigValue(CNFIceUsername, "")
|
config.IceUsername = getStrConfigValue(CNFIceUsername, "")
|
||||||
config.IcePassword = getStrConfigValue(CNFIcePassword, "")
|
config.IcePassword = getStrConfigValue(CNFIcePassword, "")
|
||||||
config.EnableOpenAccess = getBoolConfigValue(CNFEnableOpenAccess, false);
|
config.EnableOpenAccess = getBoolConfigValue(CNFEnableOpenAccess, false);
|
||||||
|
@ -121,7 +121,7 @@ func SetNodeConfig(w http.ResponseWriter, r *http.Request) {
|
|||||||
if res := tx.Clauses(clause.OnConflict{
|
if res := tx.Clauses(clause.OnConflict{
|
||||||
Columns: []clause.Column{{Name: "config_id"}},
|
Columns: []clause.Column{{Name: "config_id"}},
|
||||||
DoUpdates: clause.AssignmentColumns([]string{"str_value"}),
|
DoUpdates: clause.AssignmentColumns([]string{"str_value"}),
|
||||||
}).Create(&store.Config{ConfigID: CNFIceUrl, StrValue: config.IceUrl}).Error; res != nil {
|
}).Create(&store.Config{ConfigID: CNFIceUrl, StrValue: config.IceURL}).Error; res != nil {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,7 +156,7 @@ func SetRing(card *store.Card, ring Ring) {
|
|||||||
phone.CallID = ring.CallID
|
phone.CallID = ring.CallID
|
||||||
phone.CalleeToken = ring.CalleeToken
|
phone.CalleeToken = ring.CalleeToken
|
||||||
phone.Ice = ring.Ice
|
phone.Ice = ring.Ice
|
||||||
phone.IceUrl = ring.IceUrl
|
phone.IceURL = ring.IceURL
|
||||||
phone.IceUsername = ring.IceUsername
|
phone.IceUsername = ring.IceUsername
|
||||||
phone.IcePassword = ring.IcePassword
|
phone.IcePassword = ring.IcePassword
|
||||||
phone.CardID = card.CardSlot.CardSlotID
|
phone.CardID = card.CardSlot.CardSlotID
|
||||||
|
47
net/server/internal/iceUtil.go
Normal file
47
net/server/internal/iceUtil.go
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
package databag
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
"errors"
|
||||||
|
"bytes"
|
||||||
|
)
|
||||||
|
|
||||||
|
func getIce(service bool, urls string, username string, credential string) ([]IceURL, error) {
|
||||||
|
|
||||||
|
if service {
|
||||||
|
gen := "https://rtc.live.cloudflare.com/v1/turn/keys/" + username + "/credentials/generate"
|
||||||
|
req, err := http.NewRequest(http.MethodPost, gen, bytes.NewBuffer([]byte("{\"ttl\": 86400}")))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
req.Header.Set("Content-Type", "application/json; charset=utf-8")
|
||||||
|
req.Header.Set("Authorization", "Bearer " + credential)
|
||||||
|
client := &http.Client{}
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil || resp == nil || resp.StatusCode != 201 {
|
||||||
|
return nil, errors.New("invalid ice service response")
|
||||||
|
}
|
||||||
|
|
||||||
|
var r IceService
|
||||||
|
err = json.NewDecoder(resp.Body).Decode(&r)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("invalid ice service response")
|
||||||
|
}
|
||||||
|
|
||||||
|
ice := []IceURL{}
|
||||||
|
for _, url := range r.Servers.URLs {
|
||||||
|
ice = append(ice, IceURL{ URLs: url, Username: r.Servers.Username, Credential: r.Servers.Credential });
|
||||||
|
}
|
||||||
|
return ice, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return []IceURL {
|
||||||
|
IceURL {
|
||||||
|
URLs: urls,
|
||||||
|
Username: username,
|
||||||
|
Credential: credential,
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
@ -377,7 +377,7 @@ type NodeConfig struct {
|
|||||||
|
|
||||||
IceService bool `json:"iceService"`
|
IceService bool `json:"iceService"`
|
||||||
|
|
||||||
IceUrl string `json:"iceUrl"`
|
IceURL string `json:"iceUrl"`
|
||||||
|
|
||||||
IceUsername string `json:"iceUsername"`
|
IceUsername string `json:"iceUsername"`
|
||||||
|
|
||||||
@ -460,9 +460,9 @@ type Phone struct {
|
|||||||
|
|
||||||
CalleeToken string `json:"calleeToken"`
|
CalleeToken string `json:"calleeToken"`
|
||||||
|
|
||||||
Ice []IceUrl `json:"ice,omitEmpty"`
|
Ice []IceURL `json:"ice,omitEmpty"`
|
||||||
|
|
||||||
IceUrl string `json:"iceUrl"`
|
IceURL string `json:"iceUrl"`
|
||||||
|
|
||||||
IceUsername string `json:"iceUsername"`
|
IceUsername string `json:"iceUsername"`
|
||||||
|
|
||||||
@ -569,14 +569,30 @@ type Call struct {
|
|||||||
|
|
||||||
IceService bool `json:"iceService"`
|
IceService bool `json:"iceService"`
|
||||||
|
|
||||||
IceUrl string `json:"iceUrl"`
|
Ice []IceURL `json:"ice,omitEmpty"`
|
||||||
|
|
||||||
|
IceURL string `json:"iceUrl"`
|
||||||
|
|
||||||
IceUsername string `json:"iceUsername"`
|
IceUsername string `json:"iceUsername"`
|
||||||
|
|
||||||
IcePassword string `json:"icePassword"`
|
IcePassword string `json:"icePassword"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type IceUrl struct {
|
type IceServers struct {
|
||||||
|
|
||||||
|
URLs []string `json:"urls"`
|
||||||
|
|
||||||
|
Username string `json:"username"`
|
||||||
|
|
||||||
|
Credential string `json:"credential"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type IceService struct {
|
||||||
|
|
||||||
|
Servers IceServers `json:"iceServers"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type IceURL struct {
|
||||||
|
|
||||||
URLs string `json:"urls"`
|
URLs string `json:"urls"`
|
||||||
|
|
||||||
@ -593,9 +609,9 @@ type Ring struct {
|
|||||||
|
|
||||||
Index int32 `json:"index"`
|
Index int32 `json:"index"`
|
||||||
|
|
||||||
Ice []IceUrl `json:"ice,omitEmpty"`
|
Ice []IceURL `json:"ice,omitEmpty"`
|
||||||
|
|
||||||
IceUrl string `json:"iceUrl"`
|
IceURL string `json:"iceUrl"`
|
||||||
|
|
||||||
IceUsername string `json:"iceUsername"`
|
IceUsername string `json:"iceUsername"`
|
||||||
|
|
||||||
|
@ -134,28 +134,6 @@ export function useRingContext() {
|
|||||||
processing.current = false;
|
processing.current = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const getIce = async (service, urls, username, credential) => {
|
|
||||||
if (!service) {
|
|
||||||
return [{ urls, username, credential }];
|
|
||||||
}
|
|
||||||
|
|
||||||
const params = await fetch(urls.replace('%%TURN_KEY_ID%%', username), {
|
|
||||||
method: 'POST',
|
|
||||||
body: '{"ttl": 86400}',
|
|
||||||
headers: new Headers({
|
|
||||||
'Authorization': `Bearer ${credential}`,
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
})
|
|
||||||
});
|
|
||||||
const server = await params.json();
|
|
||||||
const ice = [];
|
|
||||||
server.iceServers.urls.forEach(urls => {
|
|
||||||
const { username, credential } = server.iceServers;
|
|
||||||
ice.push({ urls, username, credential });
|
|
||||||
});
|
|
||||||
return ice;
|
|
||||||
}
|
|
||||||
|
|
||||||
const getAudioStream = async (audioId) => {
|
const getAudioStream = async (audioId) => {
|
||||||
try {
|
try {
|
||||||
if (audioId) {
|
if (audioId) {
|
||||||
@ -357,6 +335,8 @@ export function useRingContext() {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
accept: async (cardId, callId, contactNode, contactToken, calleeToken, ice, audioId) => {
|
accept: async (cardId, callId, contactNode, contactToken, calleeToken, ice, audioId) => {
|
||||||
|
console.log("ACCEPT", ice);
|
||||||
|
|
||||||
if (calling.current) {
|
if (calling.current) {
|
||||||
throw new Error("active session");
|
throw new Error("active session");
|
||||||
}
|
}
|
||||||
@ -409,7 +389,6 @@ export function useRingContext() {
|
|||||||
|
|
||||||
// create call
|
// create call
|
||||||
let call;
|
let call;
|
||||||
let ice;
|
|
||||||
try {
|
try {
|
||||||
call = await addCall(access.current, cardId);
|
call = await addCall(access.current, cardId);
|
||||||
}
|
}
|
||||||
@ -419,10 +398,9 @@ export function useRingContext() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let index = 0;
|
let index = 0;
|
||||||
const { id, keepAlive, callerToken, calleeToken, iceService, iceUrl, iceUsername, icePassword } = call;
|
const { id, keepAlive, callerToken, calleeToken, ice } = call;
|
||||||
try {
|
try {
|
||||||
ice = await getIce(iceService, iceUrl, iceUsername, icePassword);
|
const turn = ice[ice.length - 1]; //backwards compatibility
|
||||||
const turn = ice[ice.length - 1];
|
|
||||||
await addContactRing(contactNode, contactToken, { index, callId: id, calleeToken, ice, iceUrl: turn.urls, iceUsername: turn.username, icePassword: turn.credential });
|
await addContactRing(contactNode, contactToken, { index, callId: id, calleeToken, ice, iceUrl: turn.urls, iceUsername: turn.username, icePassword: turn.credential });
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
|
Loading…
Reference in New Issue
Block a user