- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
package main
import (
"io"
"fmt"
"log"
"bytes"
"strings"
"net/http"
"net/http/httputil"
"net/url"
)
func UpdateResponse(r *http.Response) error {
for k, v := range r.Header {
newValue := strings.Replace(v[0], "umnico.com", "umnico.*****.ru", -1)
r.Header[k][0] = newValue
}
b, err := io.ReadAll(r.Body)
if(err == nil) {
bodyText := strings.Replace(string(b), "://umnico.com", "://umnico.*****.ru", -1);
if(strings.Contains(bodyText, "</head><body>")) {
injectedStyle := `<style>
.nav-menu.hidden, .widget__preview-container--tech-support {
display: none !important;
}
</style>`
bodyText = strings.Replace(bodyText, "</head><body>", injectedStyle + "</head><body>", -1);
}
if(strings.Contains(bodyText, "</body></html>")) {
injectedScript := `<script>
fetch('/api/user').then((response) => {
return response.json().then((data) => {
//alert(data.user.id);
if(data.user.id != 12345) {
const style = document.createElement('style');
style.textContent = '.im__chat-buttons{display:none!important;}';
document.head.appendChild(style);
}
return true;
}).catch((err) => {
console.log(err);
})
});
var currentDialogId = 0;
function checkDialogControls() {
if(location.pathname.indexOf('app/deals/inbox/details/') > 0 || location.pathname.indexOf('app/deals/active/details/') > 0) {
if(location.pathname.indexOf('app/deals/active/details/') > 0) {
var dialogId = location.pathname.split('app/deals/active/details/')[1];
} else {
var dialogId = location.pathname.split('app/deals/inbox/details/')[1];
}
var chatIndicator = document.querySelector('.im-aside-section.im-aside-section__toolbox');
if(chatIndicator != null) {
var injectedControls = document.querySelector('.im-aside-section.injected-controls');
if(injectedControls == null) {
chatIndicator.insertAdjacentHTML('afterend', '<div class="im-aside-section injected-controls"><div><button type="button" class="button" style="width:100%;" onclick="window.parent.postMessage(\'openBookingModalByUmnicoId('+dialogId+')\', \'*\');">Оформить бронь</button></div><div style="margin-top:5px;"><button type="button" class="button button_attention" style="width:100%;" onclick="window.parent.postMessage(\'openLeadTaskModalByUmnicoId('+dialogId+')\', \'*\');">Задача</button></div></div>');
} else {
if(currentDialogId != dialogId) {
injectedControls.remove();
}
}
currentDialogId = parseInt(dialogId);
}
}
}
setInterval(checkDialogControls, 100);
</script>`
bodyText = strings.Replace(bodyText, "</body></html>", injectedScript + "</body></html>", -1);
}
if(strings.Contains(bodyText, "window.location.hostname != \"localhost\"")) {
bodyText = strings.Replace(bodyText, "window.location.hostname != \"localhost\"", "window.location.hostname != \"localhost\" && window.location.hostname != \"umnico.*****.ru\"", -1);
}
buf := bytes.NewBufferString(bodyText)
r.Body = io.NopCloser(buf)
r.Header["Content-Length"] = []string{fmt.Sprint(buf.Len())}
}
return nil
}
func main() {
target, err := url.Parse("https://umnico.com:443")
if err != nil {
log.Fatal(err)
}
proxy := httputil.NewSingleHostReverseProxy(target)
proxy.ModifyResponse = UpdateResponse
http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
req.Host = req.URL.Host
proxy.ServeHTTP(w, req)
})
err = http.ListenAndServe("127.0.0.1:8803", nil)
if err != nil {
panic(err)
}
}
Мой код для проксирования одного из SaaS-сервисов, с целью встраивания в интерфейс последнего кастомных кнопок. Взглянул спустя пару месяцев и ужаснулся.