mirror of
https://github.com/mautrix/signal.git
synced 2026-11-09 15:49:17 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d451962ba2 |
||
|
|
c827c97adb |
||
|
|
c820321548 |
||
|
|
34b4187e07 |
||
|
|
a630835d70 |
5 changed files with 85 additions and 13 deletions
9
.github/workflows/go.yml
vendored
9
.github/workflows/go.yml
vendored
|
|
@ -30,16 +30,11 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
go install golang.org/x/tools/cmd/goimports@latest
|
go install golang.org/x/tools/cmd/goimports@latest
|
||||||
go install honnef.co/go/tools/cmd/staticcheck@latest
|
go install honnef.co/go/tools/cmd/staticcheck@latest
|
||||||
|
go install github.com/beeper/pre-commit-go/bridgelint@latest
|
||||||
export PATH="$HOME/go/bin:$PATH"
|
export PATH="$HOME/go/bin:$PATH"
|
||||||
|
|
||||||
- name: Cache pre-commit
|
|
||||||
uses: actions/cache@v6
|
|
||||||
with:
|
|
||||||
path: ~/.cache/pre-commit
|
|
||||||
key: pre-commit-go${{ matrix.go-version }}-${{ hashFiles('.pre-commit-config.yaml') }}
|
|
||||||
|
|
||||||
- name: Run pre-commit
|
- name: Run pre-commit
|
||||||
run: pipx run pre-commit run --all-files --show-diff-on-failure --color=always
|
uses: pre-commit/action@v3.0.1
|
||||||
|
|
||||||
test:
|
test:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
|
||||||
|
|
@ -27,4 +27,5 @@ repos:
|
||||||
- id: zerolog-ban-msgf
|
- id: zerolog-ban-msgf
|
||||||
- id: zerolog-use-stringer
|
- id: zerolog-use-stringer
|
||||||
- id: bridgelint
|
- id: bridgelint
|
||||||
|
language: system
|
||||||
verbose: true
|
verbose: true
|
||||||
|
|
|
||||||
|
|
@ -125,9 +125,10 @@ func (s *SignalClient) contactToUserInfo(ctx context.Context, contact *types.Rec
|
||||||
}
|
}
|
||||||
name := s.Main.Config.FormatDisplayname(contact, username)
|
name := s.Main.Config.FormatDisplayname(contact, username)
|
||||||
ui.Name = &name
|
ui.Name = &name
|
||||||
if s.Main.Config.UseContactAvatars && contact.ContactAvatar.Hash != "" {
|
contactAvatarID := networkid.AvatarID("hash:" + contact.ContactAvatar.Hash)
|
||||||
|
if s.Main.Config.UseContactAvatars && contact.ContactAvatar.Hash != "" && s.canUseContactAvatar(ctx, contact, contactAvatarID) {
|
||||||
ui.Avatar = &bridgev2.Avatar{
|
ui.Avatar = &bridgev2.Avatar{
|
||||||
ID: networkid.AvatarID("hash:" + contact.ContactAvatar.Hash),
|
ID: contactAvatarID,
|
||||||
Get: func(ctx context.Context) ([]byte, error) {
|
Get: func(ctx context.Context) ([]byte, error) {
|
||||||
if contact.ContactAvatar.Image == nil {
|
if contact.ContactAvatar.Image == nil {
|
||||||
return nil, fmt.Errorf("contact avatar not available")
|
return nil, fmt.Errorf("contact avatar not available")
|
||||||
|
|
@ -172,6 +173,20 @@ func (s *SignalClient) contactToUserInfo(ctx context.Context, contact *types.Rec
|
||||||
return ui, nil
|
return ui, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *SignalClient) canUseContactAvatar(ctx context.Context, contact *types.Recipient, avatarID networkid.AvatarID) bool {
|
||||||
|
if contact.ContactAvatar.Image != nil {
|
||||||
|
return true
|
||||||
|
} else if contact.ACI == uuid.Nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
ghost, err := s.Main.Bridge.GetExistingGhostByID(ctx, signalid.MakeUserID(contact.ACI))
|
||||||
|
if err != nil {
|
||||||
|
zerolog.Ctx(ctx).Err(err).Msg("Failed to get ghost to check contact avatar")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return ghost != nil && ghost.AvatarID == avatarID && ghost.AvatarMXC != "" && ghost.AvatarSet
|
||||||
|
}
|
||||||
|
|
||||||
func (s *SignalConnector) ValidateUserID(id networkid.UserID) bool {
|
func (s *SignalConnector) ValidateUserID(id networkid.UserID) bool {
|
||||||
_, err := signalid.ParseUserIDAsServiceID(id)
|
_, err := signalid.ParseUserIDAsServiceID(id)
|
||||||
return err == nil
|
return err == nil
|
||||||
|
|
@ -445,11 +460,15 @@ func (s *SignalClient) GetContactList(ctx context.Context) ([]*bridgev2.ResolveI
|
||||||
}
|
}
|
||||||
resp := make([]*bridgev2.ResolveIdentifierResponse, len(recipients))
|
resp := make([]*bridgev2.ResolveIdentifierResponse, len(recipients))
|
||||||
for i, recipient := range recipients {
|
for i, recipient := range recipients {
|
||||||
recipientResp := &bridgev2.ResolveIdentifierResponse{
|
if err = ctx.Err(); err != nil {
|
||||||
Chat: s.makeCreateDMResponse(ctx, recipient, nil),
|
return nil, err
|
||||||
}
|
}
|
||||||
|
recipientResp := &bridgev2.ResolveIdentifierResponse{}
|
||||||
var username string
|
var username string
|
||||||
if recipient.ACI != uuid.Nil {
|
if recipient.ACI != uuid.Nil {
|
||||||
|
recipientResp.Chat = &bridgev2.CreateChatResponse{
|
||||||
|
PortalKey: s.makeDMPortalKey(libsignalgo.NewACIServiceID(recipient.ACI)),
|
||||||
|
}
|
||||||
recipientResp.UserID = signalid.MakeUserID(recipient.ACI)
|
recipientResp.UserID = signalid.MakeUserID(recipient.ACI)
|
||||||
ghost, err := s.Main.Bridge.GetGhostByID(ctx, recipientResp.UserID)
|
ghost, err := s.Main.Bridge.GetGhostByID(ctx, recipientResp.UserID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -458,7 +477,11 @@ func (s *SignalClient) GetContactList(ctx context.Context) ([]*bridgev2.ResolveI
|
||||||
recipientResp.Ghost = ghost
|
recipientResp.Ghost = ghost
|
||||||
username = ghost.Metadata.(*signalid.GhostMetadata).Username
|
username = ghost.Metadata.(*signalid.GhostMetadata).Username
|
||||||
} else {
|
} else {
|
||||||
recipientResp.UserID = signalid.MakeUserIDFromServiceID(libsignalgo.NewPNIServiceID(recipient.PNI))
|
pniServiceID := libsignalgo.NewPNIServiceID(recipient.PNI)
|
||||||
|
recipientResp.Chat = &bridgev2.CreateChatResponse{
|
||||||
|
PortalKey: s.makeDMPortalKey(pniServiceID),
|
||||||
|
}
|
||||||
|
recipientResp.UserID = signalid.MakeUserIDFromServiceID(pniServiceID)
|
||||||
}
|
}
|
||||||
recipientResp.UserInfo, err = s.contactToUserInfo(ctx, recipient, username, false)
|
recipientResp.UserInfo, err = s.contactToUserInfo(ctx, recipient, username, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -502,6 +502,11 @@ func (mc *MessageConverter) convertAttachmentToMatrix(ctx context.Context, index
|
||||||
|
|
||||||
func (mc *MessageConverter) convertStickerToMatrix(ctx context.Context, sticker *signalpb.DataMessage_Sticker, attMap AttachmentMap) *bridgev2.ConvertedMessagePart {
|
func (mc *MessageConverter) convertStickerToMatrix(ctx context.Context, sticker *signalpb.DataMessage_Sticker, attMap AttachmentMap) *bridgev2.ConvertedMessagePart {
|
||||||
converted, err := mc.reuploadAttachment(ctx, sticker.GetData(), attMap)
|
converted, err := mc.reuploadAttachment(ctx, sticker.GetData(), attMap)
|
||||||
|
hasPack := len(sticker.GetPackId()) == PackIDLength && len(sticker.GetPackKey()) == PackKeyLength && !bytes.Equal(sticker.GetPackId(), zeroPackID)
|
||||||
|
if err != nil && hasPack && (errors.Is(err, signalmeow.ErrAttachmentNotFound) || errors.Is(err, ErrAttachmentNotInBackup) || errors.Is(err, ErrBackupNotSupported)) {
|
||||||
|
zerolog.Ctx(ctx).Debug().Err(err).Msg("Sticker attachment is unavailable, downloading it from the sticker pack")
|
||||||
|
converted, err = mc.reuploadStickerFromPack(ctx, sticker)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
zerolog.Ctx(ctx).Err(err).Msg("Failed to handle sticker")
|
zerolog.Ctx(ctx).Err(err).Msg("Failed to handle sticker")
|
||||||
return &bridgev2.ConvertedMessagePart{
|
return &bridgev2.ConvertedMessagePart{
|
||||||
|
|
@ -519,7 +524,7 @@ func (mc *MessageConverter) convertStickerToMatrix(ctx context.Context, sticker
|
||||||
converted.Content.Info.Height = 200
|
converted.Content.Info.Height = 200
|
||||||
}
|
}
|
||||||
converted.Content.Body = sticker.GetEmoji()
|
converted.Content.Body = sticker.GetEmoji()
|
||||||
if len(sticker.GetPackId()) == PackIDLength && len(sticker.GetPackKey()) == PackKeyLength && !bytes.Equal(sticker.GetPackId(), zeroPackID) {
|
if hasPack {
|
||||||
converted.Content.Info.BridgedSticker = &event.BridgedSticker{
|
converted.Content.Info.BridgedSticker = &event.BridgedSticker{
|
||||||
Network: StickerSourceID,
|
Network: StickerSourceID,
|
||||||
ID: strconv.FormatUint(uint64(sticker.GetStickerId()), 10),
|
ID: strconv.FormatUint(uint64(sticker.GetStickerId()), 10),
|
||||||
|
|
@ -532,6 +537,49 @@ func (mc *MessageConverter) convertStickerToMatrix(ctx context.Context, sticker
|
||||||
return converted
|
return converted
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (mc *MessageConverter) reuploadStickerFromPack(ctx context.Context, sticker *signalpb.DataMessage_Sticker) (*bridgev2.ConvertedMessagePart, error) {
|
||||||
|
att := sticker.GetData()
|
||||||
|
content := &event.MessageEventContent{
|
||||||
|
Body: att.GetFileName(),
|
||||||
|
Info: &event.FileInfo{
|
||||||
|
MimeType: att.GetContentType(),
|
||||||
|
Width: int(att.GetWidth()),
|
||||||
|
Height: int(att.GetHeight()),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if mc.DirectMedia {
|
||||||
|
mediaID, err := signalid.DirectMediaSticker{
|
||||||
|
PackID: sticker.GetPackId(),
|
||||||
|
PackKey: sticker.GetPackKey(),
|
||||||
|
StickerID: sticker.GetStickerId(),
|
||||||
|
}.AsMediaID()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
content.URL, content.File, err = mc.Bridge.GenerateContentURI(ctx, getPortal(ctx).MXID, mediaID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
data, err := signalmeow.DownloadStickerPackItem(ctx, sticker.GetPackId(), sticker.GetPackKey(), sticker.GetStickerId())
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to download sticker from pack: %w", err)
|
||||||
|
}
|
||||||
|
if content.Info.MimeType == "" {
|
||||||
|
content.Info.MimeType = http.DetectContentType(data)
|
||||||
|
}
|
||||||
|
content.Info.Size = len(data)
|
||||||
|
content.URL, content.File, err = getIntent(ctx).UploadMedia(ctx, getPortal(ctx).MXID, data, content.Body, content.Info.MimeType)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to upload sticker from pack: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &bridgev2.ConvertedMessagePart{
|
||||||
|
Type: event.EventMessage,
|
||||||
|
Content: content,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (mc *MessageConverter) downloadSignalLongText(ctx context.Context, att *signalpb.AttachmentPointer, attMap AttachmentMap) (*string, error) {
|
func (mc *MessageConverter) downloadSignalLongText(ctx context.Context, att *signalpb.AttachmentPointer, attMap AttachmentMap) (*string, error) {
|
||||||
data, err := mc.downloadAttachment(ctx, att, attMap, nil)
|
data, err := mc.downloadAttachment(ctx, att, attMap, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -319,6 +319,11 @@ func (s *SignalWebsocket) connectLoop(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Succssfully connected
|
// Succssfully connected
|
||||||
|
if resp != nil {
|
||||||
|
if alerts := resp.Header.Values("X-Signal-Alert"); len(alerts) > 0 {
|
||||||
|
log.Warn().Strs("alerts", alerts).Msg("Signal server sent alerts when opening websocket")
|
||||||
|
}
|
||||||
|
}
|
||||||
s.pushStatus(ctx, SignalWebsocketConnectionEventConnected, nil)
|
s.pushStatus(ctx, SignalWebsocketConnectionEventConnected, nil)
|
||||||
s.ws.Store(ws)
|
s.ws.Store(ws)
|
||||||
retrying = false
|
retrying = false
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue