mirror of
https://github.com/mautrix/telegram.git
synced 2026-05-17 07:25:46 +03:00
provisioning: implement legacy QR endpoint
Signed-off-by: Sumner Evans <sumner.evans@automattic.com>
This commit is contained in:
@@ -17,11 +17,13 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"sync"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/rs/zerolog"
|
||||
"go.mau.fi/util/exhttp"
|
||||
"maunium.net/go/mautrix/bridgev2"
|
||||
@@ -62,6 +64,92 @@ type legacyLogin struct {
|
||||
var inflightLegacyLoginsLock sync.RWMutex
|
||||
var inflightLegacyLogins = map[id.UserID]*legacyLogin{}
|
||||
|
||||
var upgrader = websocket.Upgrader{
|
||||
CheckOrigin: func(r *http.Request) bool {
|
||||
return true
|
||||
},
|
||||
Subprotocols: []string{"net.maunium.telegram.login"},
|
||||
}
|
||||
|
||||
func legacyProvLoginQR(w http.ResponseWriter, r *http.Request) {
|
||||
log := zerolog.Ctx(r.Context()).With().Str("prov_method", "qr_login").Logger()
|
||||
ctx := log.WithContext(r.Context())
|
||||
|
||||
user := m.Matrix.Provisioning.GetUser(r)
|
||||
resp := response{Username: user.MXID}
|
||||
|
||||
var err error
|
||||
var loginProcess bridgev2.LoginProcess
|
||||
var nextStep *bridgev2.LoginStep
|
||||
if loginProcess, err = c.CreateLogin(ctx, user, connector.LoginFlowIDQR); err != nil {
|
||||
exhttp.WriteJSONResponse(w, http.StatusInternalServerError, resp.WithError("create_login_failed", fmt.Sprintf("Failed to create a QR login process: %s", err.Error())))
|
||||
} else if nextStep, err = loginProcess.Start(ctx); err != nil {
|
||||
exhttp.WriteJSONResponse(w, http.StatusInternalServerError, resp.WithError("start_login_failed", fmt.Sprintf("Failed to start login process: %s", err.Error())))
|
||||
} else if nextStep.StepID != connector.LoginStepIDShowQR {
|
||||
exhttp.WriteJSONResponse(w, http.StatusInternalServerError, resp.WithError("unexpected_step", fmt.Sprintf("Unexpected first step %s", nextStep.StepID)))
|
||||
}
|
||||
|
||||
ws, err := upgrader.Upgrade(w, r, nil)
|
||||
if err != nil {
|
||||
log.Err(err).Msg("Failed to upgrade connection to websocket")
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
err := ws.Close()
|
||||
if err != nil {
|
||||
log.Debug().Err(err).Msg("Error closing websocket")
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
// Read everything so SetCloseHandler() works
|
||||
for {
|
||||
_, _, err = ws.ReadMessage()
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
}()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ws.SetCloseHandler(func(code int, text string) error {
|
||||
log.Debug().Int("close_code", code).Msg("Login websocket closed, cancelling login")
|
||||
cancel()
|
||||
return nil
|
||||
})
|
||||
|
||||
for {
|
||||
switch nextStep.StepID {
|
||||
case connector.LoginStepIDShowQR:
|
||||
nextStep, err = loginProcess.(bridgev2.LoginProcessDisplayAndWait).Wait(ctx)
|
||||
if err != nil {
|
||||
ws.WriteJSON(map[string]any{
|
||||
"success": false,
|
||||
"error": "qr_login_failed",
|
||||
"message": fmt.Sprintf("Failed to login using QR code: %s", err),
|
||||
})
|
||||
return
|
||||
}
|
||||
ws.WriteJSON(map[string]any{"code": nextStep.DisplayAndWaitParams.Data})
|
||||
case connector.LoginStepIDComplete:
|
||||
ws.WriteJSON(map[string]any{"success": true})
|
||||
return
|
||||
case connector.LoginStepIDPassword:
|
||||
inflightLegacyLoginsLock.Lock()
|
||||
inflightLegacyLogins[user.MXID] = &legacyLogin{Process: loginProcess, NextStep: nextStep}
|
||||
inflightLegacyLoginsLock.Unlock()
|
||||
ws.WriteJSON(map[string]any{"success": false, "error": "password-needed"})
|
||||
return
|
||||
default:
|
||||
ws.WriteJSON(map[string]any{
|
||||
"success": false,
|
||||
"error": "unexpected_step",
|
||||
"message": fmt.Sprintf("Unexpected step in QR code login process %s", nextStep.StepID),
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func legacyProvLoginRequestCode(w http.ResponseWriter, r *http.Request) {
|
||||
log := zerolog.Ctx(r.Context()).With().Str("prov_step", "request_code").Logger()
|
||||
ctx := log.WithContext(r.Context())
|
||||
|
||||
@@ -19,6 +19,8 @@ package main
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"go.mau.fi/util/dbutil/litestream"
|
||||
"maunium.net/go/mautrix/bridgev2/bridgeconfig"
|
||||
@@ -60,7 +62,20 @@ func main() {
|
||||
versionWithoutCommit := m.Version
|
||||
m.PostStart = func() {
|
||||
if m.Matrix.Provisioning != nil {
|
||||
// m.Matrix.Provisioning.Router.HandleFunc("/v1/user/{userID}/login/qr", legacyProvLoginQR)
|
||||
m.Matrix.Provisioning.GetAuthFromRequest = func(r *http.Request) string {
|
||||
if !strings.HasSuffix(r.URL.Path, "/login/qr") {
|
||||
return ""
|
||||
}
|
||||
authParts := strings.Split(r.Header.Get("Sec-WebSocket-Protocol"), ",")
|
||||
for _, part := range authParts {
|
||||
part = strings.TrimSpace(part)
|
||||
if strings.HasPrefix(part, "net.maunium.telegram.auth-") {
|
||||
return strings.TrimPrefix(part, "net.maunium.telegram.auth-")
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
m.Matrix.Provisioning.Router.HandleFunc("/v1/user/{userID}/login/qr", legacyProvLoginQR)
|
||||
m.Matrix.Provisioning.Router.HandleFunc("/v1/user/{userID}/login/request_code", legacyProvLoginRequestCode)
|
||||
m.Matrix.Provisioning.Router.HandleFunc("/v1/user/{userID}/login/send_code", legacyProvLoginSendCode)
|
||||
m.Matrix.Provisioning.Router.HandleFunc("/v1/user/{userID}/login/send_password", legacyProvLoginSendPassword)
|
||||
|
||||
4
go.mod
4
go.mod
@@ -3,6 +3,7 @@ module go.mau.fi/mautrix-telegram
|
||||
go 1.22
|
||||
|
||||
require (
|
||||
github.com/gorilla/websocket v1.5.3
|
||||
github.com/gotd/td v0.105.0
|
||||
github.com/rs/zerolog v1.33.0
|
||||
github.com/stretchr/testify v1.9.0
|
||||
@@ -11,7 +12,7 @@ require (
|
||||
go.uber.org/zap v1.27.0
|
||||
golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa
|
||||
golang.org/x/net v0.28.0
|
||||
maunium.net/go/mautrix v0.20.1-0.20240827134950-e3eb2953ddda
|
||||
maunium.net/go/mautrix v0.20.1-0.20240827221252-892e5cf01fc8
|
||||
)
|
||||
|
||||
require (
|
||||
@@ -23,7 +24,6 @@ require (
|
||||
github.com/go-faster/jx v1.1.0 // indirect
|
||||
github.com/go-faster/xor v1.0.0 // indirect
|
||||
github.com/gorilla/mux v1.8.1 // indirect
|
||||
github.com/gorilla/websocket v1.5.3 // indirect
|
||||
github.com/gotd/ige v0.2.2 // indirect
|
||||
github.com/gotd/neo v0.1.5 // indirect
|
||||
github.com/klauspost/compress v1.17.9 // indirect
|
||||
|
||||
4
go.sum
4
go.sum
@@ -116,8 +116,8 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M=
|
||||
maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA=
|
||||
maunium.net/go/mautrix v0.20.1-0.20240827134950-e3eb2953ddda h1:3n7LQS2LQFW4uNUeECEUNWCCCaNTygk0CGSE+CZtEqo=
|
||||
maunium.net/go/mautrix v0.20.1-0.20240827134950-e3eb2953ddda/go.mod h1:7hh/Hx5W9lUcqL0hkSw52kMyY+6nMUPTtdDN0qVEXwI=
|
||||
maunium.net/go/mautrix v0.20.1-0.20240827221252-892e5cf01fc8 h1:k+HkbFrExb508ofb+Snz+yGa1/GQ6WKqyGzGYXSzT3A=
|
||||
maunium.net/go/mautrix v0.20.1-0.20240827221252-892e5cf01fc8/go.mod h1:7hh/Hx5W9lUcqL0hkSw52kMyY+6nMUPTtdDN0qVEXwI=
|
||||
nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0=
|
||||
nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c=
|
||||
rsc.io/qr v0.2.0 h1:6vBLea5/NRMVTz8V66gipeLycZMl/+UlFmk8DvqQ6WY=
|
||||
|
||||
Reference in New Issue
Block a user