Update dependencies (#1841)

This commit is contained in:
Wim 2022-06-11 23:07:42 +02:00 committed by GitHub
parent 3819062574
commit 8751fb4bb1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
188 changed files with 5608 additions and 1334 deletions

40
go.mod
View File

@ -12,7 +12,7 @@ require (
github.com/davecgh/go-spew v1.1.1 github.com/davecgh/go-spew v1.1.1
github.com/fsnotify/fsnotify v1.5.4 github.com/fsnotify/fsnotify v1.5.4
github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1
github.com/gomarkdown/markdown v0.0.0-20220509074759-a57bf950ab8c github.com/gomarkdown/markdown v0.0.0-20220603122033-8f3b341fef32
github.com/google/gops v0.3.23 github.com/google/gops v0.3.23
github.com/gorilla/schema v1.2.0 github.com/gorilla/schema v1.2.0
github.com/gorilla/websocket v1.5.0 github.com/gorilla/websocket v1.5.0
@ -30,7 +30,7 @@ require (
github.com/matterbridge/logrus-prefixed-formatter v0.5.3-0.20200523233437-d971309a77ba github.com/matterbridge/logrus-prefixed-formatter v0.5.3-0.20200523233437-d971309a77ba
github.com/matterbridge/matterclient v0.0.0-20220430213656-07aca2731bc9 github.com/matterbridge/matterclient v0.0.0-20220430213656-07aca2731bc9
github.com/mattermost/mattermost-server/v5 v5.39.3 github.com/mattermost/mattermost-server/v5 v5.39.3
github.com/mattermost/mattermost-server/v6 v6.6.1 github.com/mattermost/mattermost-server/v6 v6.7.0
github.com/mattn/godown v0.0.1 github.com/mattn/godown v0.0.1
github.com/mdp/qrterminal v1.0.1 github.com/mdp/qrterminal v1.0.1
github.com/nelsonken/gomf v0.0.0-20190423072027-c65cc0469e94 github.com/nelsonken/gomf v0.0.0-20190423072027-c65cc0469e94
@ -41,21 +41,21 @@ require (
github.com/shazow/ssh-chat v1.10.1 github.com/shazow/ssh-chat v1.10.1
github.com/sirupsen/logrus v1.8.1 github.com/sirupsen/logrus v1.8.1
github.com/slack-go/slack v0.10.3 github.com/slack-go/slack v0.10.3
github.com/spf13/viper v1.11.0 github.com/spf13/viper v1.12.0
github.com/stretchr/testify v1.7.1 github.com/stretchr/testify v1.7.1
github.com/vincent-petithory/dataurl v1.0.0 github.com/vincent-petithory/dataurl v1.0.0
github.com/writeas/go-strip-markdown v2.0.1+incompatible github.com/writeas/go-strip-markdown v2.0.1+incompatible
github.com/yaegashi/msgraph.go v0.1.4 github.com/yaegashi/msgraph.go v0.1.4
github.com/zfjagann/golang-ring v0.0.0-20220330170733-19bcea1b6289 github.com/zfjagann/golang-ring v0.0.0-20220330170733-19bcea1b6289
go.mau.fi/whatsmeow v0.0.0-20220504135614-f1f2a9d231fb go.mau.fi/whatsmeow v0.0.0-20220601182603-a8d86cf1812c
golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9 golang.org/x/image v0.0.0-20220601225756-64ec528b34cd
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 golang.org/x/oauth2 v0.0.0-20220524215830-622c5d57e401
golang.org/x/text v0.3.7 golang.org/x/text v0.3.7
gomod.garykim.dev/nc-talk v0.3.0 gomod.garykim.dev/nc-talk v0.3.0
google.golang.org/protobuf v1.28.0 google.golang.org/protobuf v1.28.0
gopkg.in/olahol/melody.v1 v1.0.0-20170518105555-d52139073376 gopkg.in/olahol/melody.v1 v1.0.0-20170518105555-d52139073376
layeh.com/gumble v0.0.0-20200818122324-146f9205029b layeh.com/gumble v0.0.0-20200818122324-146f9205029b
modernc.org/sqlite v1.17.2 modernc.org/sqlite v1.17.3
) )
require ( require (
@ -81,7 +81,7 @@ require (
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
github.com/kettek/apng v0.0.0-20191108220231-414630eed80f // indirect github.com/kettek/apng v0.0.0-20191108220231-414630eed80f // indirect
github.com/klauspost/compress v1.15.1 // indirect github.com/klauspost/compress v1.15.1 // indirect
github.com/klauspost/cpuid/v2 v2.0.11 // indirect github.com/klauspost/cpuid/v2 v2.0.12 // indirect
github.com/labstack/gommon v0.3.1 // indirect github.com/labstack/gommon v0.3.1 // indirect
github.com/magiconair/properties v1.8.6 // indirect github.com/magiconair/properties v1.8.6 // indirect
github.com/mattermost/go-i18n v1.11.1-0.20211013152124-5c415071e404 // indirect github.com/mattermost/go-i18n v1.11.1-0.20211013152124-5c415071e404 // indirect
@ -93,10 +93,10 @@ require (
github.com/mattn/go-runewidth v0.0.13 // indirect github.com/mattn/go-runewidth v0.0.13 // indirect
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
github.com/minio/md5-simd v1.1.2 // indirect github.com/minio/md5-simd v1.1.2 // indirect
github.com/minio/minio-go/v7 v7.0.23 // indirect github.com/minio/minio-go/v7 v7.0.24 // indirect
github.com/minio/sha256-simd v1.0.0 // indirect github.com/minio/sha256-simd v1.0.0 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/mapstructure v1.4.3 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/monaco-io/request v1.0.5 // indirect github.com/monaco-io/request v1.0.5 // indirect
@ -104,8 +104,8 @@ require (
github.com/mrexodia/wray v0.0.0-20160318003008-78a2c1f284ff // indirect github.com/mrexodia/wray v0.0.0-20160318003008-78a2c1f284ff // indirect
github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect
github.com/pborman/uuid v1.2.1 // indirect github.com/pborman/uuid v1.2.1 // indirect
github.com/pelletier/go-toml v1.9.4 // indirect github.com/pelletier/go-toml v1.9.5 // indirect
github.com/pelletier/go-toml/v2 v2.0.0-beta.8 // indirect github.com/pelletier/go-toml/v2 v2.0.1 // indirect
github.com/philhofer/fwd v1.1.1 // indirect github.com/philhofer/fwd v1.1.1 // indirect
github.com/pkg/errors v0.9.1 // indirect github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect
@ -117,10 +117,10 @@ require (
github.com/sizeofint/webpanimation v0.0.0-20210809145948-1d2b32119882 // indirect github.com/sizeofint/webpanimation v0.0.0-20210809145948-1d2b32119882 // indirect
github.com/skip2/go-qrcode v0.0.0-20190110000554-dc11ecdae0a9 // indirect github.com/skip2/go-qrcode v0.0.0-20190110000554-dc11ecdae0a9 // indirect
github.com/spf13/afero v1.8.2 // indirect github.com/spf13/afero v1.8.2 // indirect
github.com/spf13/cast v1.4.1 // indirect github.com/spf13/cast v1.5.0 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/pflag v1.0.5 // indirect
github.com/subosito/gotenv v1.2.0 // indirect github.com/subosito/gotenv v1.3.0 // indirect
github.com/tinylib/msgp v1.1.6 // indirect github.com/tinylib/msgp v1.1.6 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasttemplate v1.2.1 // indirect github.com/valyala/fasttemplate v1.2.1 // indirect
@ -134,18 +134,18 @@ require (
go.uber.org/multierr v1.7.0 // indirect go.uber.org/multierr v1.7.0 // indirect
go.uber.org/zap v1.17.0 // indirect go.uber.org/zap v1.17.0 // indirect
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 // indirect golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 // indirect
golang.org/x/mod v0.5.1 // indirect golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect
golang.org/x/net v0.0.0-20220412020605-290c469a71a5 // indirect golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2 // indirect
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324 // indirect golang.org/x/time v0.0.0-20201208040808-7e3f01d25324 // indirect
golang.org/x/tools v0.1.9 // indirect golang.org/x/tools v0.1.10 // indirect
golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f // indirect golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df // indirect
google.golang.org/appengine v1.6.7 // indirect google.golang.org/appengine v1.6.7 // indirect
gopkg.in/ini.v1 v1.66.4 // indirect gopkg.in/ini.v1 v1.66.4 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect gopkg.in/yaml.v3 v3.0.0 // indirect
lukechampine.com/uint128 v1.1.1 // indirect lukechampine.com/uint128 v1.1.1 // indirect
modernc.org/cc/v3 v3.36.0 // indirect modernc.org/cc/v3 v3.36.0 // indirect
modernc.org/ccgo/v3 v3.16.6 // indirect modernc.org/ccgo/v3 v3.16.6 // indirect

189
go.sum
View File

@ -34,7 +34,6 @@ cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aD
cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI=
cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4=
cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc=
cloud.google.com/go v0.98.0/go.mod h1:ua6Ush4NALrHk5QXDWnjvZHN93OuF0HfuEPq9I1X0cM=
cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA=
cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
@ -46,6 +45,8 @@ cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM7
cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow=
cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM=
cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M=
cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s=
cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
@ -216,7 +217,7 @@ github.com/aws/aws-sdk-go v1.17.7/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN
github.com/aws/aws-sdk-go v1.19.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.19.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.20.6/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.20.6/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.38.67/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/aws/aws-sdk-go v1.38.67/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
github.com/aws/aws-sdk-go v1.43.6/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.43.31/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
github.com/aws/aws-sdk-go-v2 v1.8.0/go.mod h1:xEFuWz+3TYdlPRuo+CqATbeDWIWyaT5uAPwPaWtgse0= github.com/aws/aws-sdk-go-v2 v1.8.0/go.mod h1:xEFuWz+3TYdlPRuo+CqATbeDWIWyaT5uAPwPaWtgse0=
github.com/aws/aws-sdk-go-v2 v1.9.2/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4= github.com/aws/aws-sdk-go-v2 v1.9.2/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4=
github.com/aws/aws-sdk-go-v2/config v1.6.0/go.mod h1:TNtBVmka80lRPk5+S9ZqVfFszOQAGJJ9KbT3EM3CHNU= github.com/aws/aws-sdk-go-v2/config v1.6.0/go.mod h1:TNtBVmka80lRPk5+S9ZqVfFszOQAGJJ9KbT3EM3CHNU=
@ -255,7 +256,7 @@ github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kB
github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k= github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k=
github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA= github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA=
github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
github.com/bits-and-blooms/bitset v1.2.1/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= github.com/bits-and-blooms/bitset v1.2.2/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
github.com/bkaradzic/go-lz4 v1.0.0/go.mod h1:0YdlkowM3VswSROI7qDxhRvJ3sLhlFrRRwjwegp5jy4= github.com/bkaradzic/go-lz4 v1.0.0/go.mod h1:0YdlkowM3VswSROI7qDxhRvJ3sLhlFrRRwjwegp5jy4=
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM=
@ -263,15 +264,19 @@ github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnweb
github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/blevesearch/bleve v1.0.14/go.mod h1:e/LJTr+E7EaoVdkQZTfoz7dt4KoDNvDbLb8MSKuNTLQ= github.com/blevesearch/bleve v1.0.14/go.mod h1:e/LJTr+E7EaoVdkQZTfoz7dt4KoDNvDbLb8MSKuNTLQ=
github.com/blevesearch/bleve/v2 v2.3.1/go.mod h1:kAJuWn2L1TNSUyxtPJD4AGma2/PgMSm7GBlx61F9OBs= github.com/blevesearch/bleve/v2 v2.3.2/go.mod h1:96+xE5pZUOsr3Y4vHzV1cBC837xZCpwLlX0hrrxnvIg=
github.com/blevesearch/bleve_index_api v1.0.1/go.mod h1:fiwKS0xLEm+gBRgv5mumf0dhgFr2mDgZah1pqv1c1M4= github.com/blevesearch/bleve_index_api v1.0.1/go.mod h1:fiwKS0xLEm+gBRgv5mumf0dhgFr2mDgZah1pqv1c1M4=
github.com/blevesearch/blevex v1.0.0/go.mod h1:2rNVqoG2BZI8t1/P1awgTKnGlx5MP9ZbtEciQaNhswc= github.com/blevesearch/blevex v1.0.0/go.mod h1:2rNVqoG2BZI8t1/P1awgTKnGlx5MP9ZbtEciQaNhswc=
github.com/blevesearch/cld2 v0.0.0-20200327141045-8b5f551d37f5/go.mod h1:PN0QNTLs9+j1bKy3d/GB/59wsNBFC4sWLWG3k69lWbc= github.com/blevesearch/cld2 v0.0.0-20200327141045-8b5f551d37f5/go.mod h1:PN0QNTLs9+j1bKy3d/GB/59wsNBFC4sWLWG3k69lWbc=
github.com/blevesearch/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:9eJDeqxJ3E7WnLebQUlPD7ZjSce7AnDb9vjGmMCbD0A=
github.com/blevesearch/go-porterstemmer v1.0.3/go.mod h1:angGc5Ht+k2xhJdZi511LtmxuEf0OVpvUUNrwmM1P7M= github.com/blevesearch/go-porterstemmer v1.0.3/go.mod h1:angGc5Ht+k2xhJdZi511LtmxuEf0OVpvUUNrwmM1P7M=
github.com/blevesearch/goleveldb v1.0.1/go.mod h1:WrU8ltZbIp0wAoig/MHbrPCXSOLpe79nz5lv5nqfYrQ=
github.com/blevesearch/gtreap v0.1.1/go.mod h1:QaQyDRAT51sotthUWAH4Sj08awFSSWzgYICSZ3w0tYk=
github.com/blevesearch/mmap-go v1.0.2/go.mod h1:ol2qBqYaOUsGdm7aRMRrYGgPvnwLe6Y+7LMvAB5IbSA= github.com/blevesearch/mmap-go v1.0.2/go.mod h1:ol2qBqYaOUsGdm7aRMRrYGgPvnwLe6Y+7LMvAB5IbSA=
github.com/blevesearch/mmap-go v1.0.3/go.mod h1:pYvKl/grLQrBxuaRYgoTssa4rVujYYeenDp++2E+yvs= github.com/blevesearch/mmap-go v1.0.3/go.mod h1:pYvKl/grLQrBxuaRYgoTssa4rVujYYeenDp++2E+yvs=
github.com/blevesearch/scorch_segment_api/v2 v2.1.0/go.mod h1:uch7xyyO/Alxkuxa+CGs79vw0QY8BENSBjg6Mw5L5DE= github.com/blevesearch/scorch_segment_api/v2 v2.1.0/go.mod h1:uch7xyyO/Alxkuxa+CGs79vw0QY8BENSBjg6Mw5L5DE=
github.com/blevesearch/segment v0.9.0/go.mod h1:9PfHYUdQCgHktBgvtUOF4x+pc4/l8rdH0u5spnW85UQ= github.com/blevesearch/segment v0.9.0/go.mod h1:9PfHYUdQCgHktBgvtUOF4x+pc4/l8rdH0u5spnW85UQ=
github.com/blevesearch/snowball v0.6.1/go.mod h1:ZF0IBg5vgpeoUhnMza2v0A/z8m1cWPlwhke08LpNusg=
github.com/blevesearch/snowballstem v0.9.0/go.mod h1:PivSj3JMc8WuaFkTSRDW2SlrulNWPl4ABg1tC/hlgLs= github.com/blevesearch/snowballstem v0.9.0/go.mod h1:PivSj3JMc8WuaFkTSRDW2SlrulNWPl4ABg1tC/hlgLs=
github.com/blevesearch/upsidedown_store_api v1.0.1/go.mod h1:MQDVGpHZrpe3Uy26zJBf/a8h0FZY6xJbthIMm8myH2Q= github.com/blevesearch/upsidedown_store_api v1.0.1/go.mod h1:MQDVGpHZrpe3Uy26zJBf/a8h0FZY6xJbthIMm8myH2Q=
github.com/blevesearch/vellum v1.0.7/go.mod h1:doBZpmRhwTsASB4QdUZANlJvqVAUdUyX0ZK7QJCTeBE= github.com/blevesearch/vellum v1.0.7/go.mod h1:doBZpmRhwTsASB4QdUZANlJvqVAUdUyX0ZK7QJCTeBE=
@ -299,7 +304,6 @@ github.com/bwmarrin/discordgo v0.25.0/go.mod h1:NJZpH+1AfhIcyQsPeuBKsUtYrRnjkyu0
github.com/cenkalti/backoff/v4 v4.0.2/go.mod h1:eEew/i+1Q6OrCDZh3WiXYv3+nJwBASZ8Bog/87DQnVg= github.com/cenkalti/backoff/v4 v4.0.2/go.mod h1:eEew/i+1Q6OrCDZh3WiXYv3+nJwBASZ8Bog/87DQnVg=
github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
@ -326,7 +330,6 @@ github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWH
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
github.com/cockroachdb/cockroach-go v0.0.0-20190925194419-606b3d062051/go.mod h1:XGLbWH/ujMcbPbhZq52Nv6UrCghb1yGn//133kEsvDk= github.com/cockroachdb/cockroach-go v0.0.0-20190925194419-606b3d062051/go.mod h1:XGLbWH/ujMcbPbhZq52Nv6UrCghb1yGn//133kEsvDk=
github.com/cockroachdb/cockroach-go/v2 v2.1.1/go.mod h1:7NtUnP6eK+l6k483WSYNrq3Kb23bWV10IRV1TyeSpwM= github.com/cockroachdb/cockroach-go/v2 v2.1.1/go.mod h1:7NtUnP6eK+l6k483WSYNrq3Kb23bWV10IRV1TyeSpwM=
@ -520,9 +523,8 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
github.com/envoyproxy/go-control-plane v0.10.1/go.mod h1:AY7fTTXNdv/aJ2O5jwpxAPOWUZ7hQAEvzN5Pf27BkQQ= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws=
github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw=
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64= github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64=
@ -547,6 +549,8 @@ github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHqu
github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk=
github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY=
github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
@ -560,12 +564,14 @@ github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYis
github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc=
github.com/getsentry/sentry-go v0.11.0/go.mod h1:KBQIxiZAetw62Cj8Ri964vAEWVdgfaUCn30Q3bCvANo= github.com/getsentry/sentry-go v0.11.0/go.mod h1:KBQIxiZAetw62Cj8Ri964vAEWVdgfaUCn30Q3bCvANo=
github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c= github.com/getsentry/sentry-go v0.13.0/go.mod h1:EOsfu5ZdvKPfeHYV6pTVQnsjfp30+XA7//UooKNumH0=
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gigawattio/window v0.0.0-20180317192513-0f5467e35573/go.mod h1:eBvb3i++NHDH4Ugo9qCvMw8t0mTSctaEa5blJbWcNxs= github.com/gigawattio/window v0.0.0-20180317192513-0f5467e35573/go.mod h1:eBvb3i++NHDH4Ugo9qCvMw8t0mTSctaEa5blJbWcNxs=
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM=
github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U=
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
github.com/glycerine/go-unsnap-stream v0.0.0-20181221182339-f9677308dec2/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE= github.com/glycerine/go-unsnap-stream v0.0.0-20181221182339-f9677308dec2/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24= github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24=
@ -585,10 +591,12 @@ github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3I
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
github.com/go-latex/latex v0.0.0-20210118124228-b3d85cf34e07/go.mod h1:CO1AlKB2CSIqUrmQPqA0gdRIlnLEY0gK5JGjh37zN5U= github.com/go-latex/latex v0.0.0-20210118124228-b3d85cf34e07/go.mod h1:CO1AlKB2CSIqUrmQPqA0gdRIlnLEY0gK5JGjh37zN5U=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8=
@ -601,9 +609,13 @@ github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL9
github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
github.com/go-redis/redis/v8 v8.0.0/go.mod h1:isLoQT/NFSP7V67lyvM9GmdvLdyZ7pEhsXvvyQtnQTo= github.com/go-redis/redis/v8 v8.0.0/go.mod h1:isLoQT/NFSP7V67lyvM9GmdvLdyZ7pEhsXvvyQtnQTo=
github.com/go-redis/redis/v8 v8.10.0/go.mod h1:vXLTvigok0VtUX0znvbcEW1SOt4OA9CU1ZfnOtKOaiM= github.com/go-redis/redis/v8 v8.10.0/go.mod h1:vXLTvigok0VtUX0znvbcEW1SOt4OA9CU1ZfnOtKOaiM=
github.com/go-redis/redis/v8 v8.11.4/go.mod h1:2Z2wHZXdQpCDXEGzqMockDpNyYvi2l4Pxt6RJr792+w= github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
github.com/go-resty/resty/v2 v2.0.0/go.mod h1:dZGr0i9PLlaaTD4H/hoZIDjQ+r6xq8mgbRzHZf7f2J8= github.com/go-resty/resty/v2 v2.0.0/go.mod h1:dZGr0i9PLlaaTD4H/hoZIDjQ+r6xq8mgbRzHZf7f2J8=
github.com/go-resty/resty/v2 v2.3.0/go.mod h1:UpN9CgLZNsv4e9XG50UU8xdI0F43UQ4HmxLBDwaroHU= github.com/go-resty/resty/v2 v2.3.0/go.mod h1:UpN9CgLZNsv4e9XG50UU8xdI0F43UQ4HmxLBDwaroHU=
github.com/go-resty/resty/v2 v2.6.0/go.mod h1:PwvJS6hvaPkjtjNg9ph+VrSD92bi5Zq73w/BIH7cC3Q= github.com/go-resty/resty/v2 v2.6.0/go.mod h1:PwvJS6hvaPkjtjNg9ph+VrSD92bi5Zq73w/BIH7cC3Q=
@ -711,8 +723,8 @@ github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW
github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/gomarkdown/markdown v0.0.0-20220509074759-a57bf950ab8c h1:yGxnjZegu9T/94575b5UGf2uDDYN3elzreWYpkhw2f4= github.com/gomarkdown/markdown v0.0.0-20220603122033-8f3b341fef32 h1:QxcGJpbMJw6tHRtrHKJiL11LdX1SXDfV1f4t4mJl3QI=
github.com/gomarkdown/markdown v0.0.0-20220509074759-a57bf950ab8c/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= github.com/gomarkdown/markdown v0.0.0-20220603122033-8f3b341fef32/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA=
github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
@ -732,8 +744,9 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
github.com/google/go-github/v35 v35.2.0/go.mod h1:s0515YVTI+IMrDoy9Y4pHt9ShGpzHvHO8rZ7L7acgvs= github.com/google/go-github/v35 v35.2.0/go.mod h1:s0515YVTI+IMrDoy9Y4pHt9ShGpzHvHO8rZ7L7acgvs=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
@ -757,6 +770,7 @@ github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLe
github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210715191844-86eeefc3e471/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210715191844-86eeefc3e471/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
@ -776,6 +790,7 @@ github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pf
github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM=
github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM=
github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM=
github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c=
github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg=
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
github.com/gopackage/ddp v0.0.3 h1:fd0DxScoiS+ogq22ktey6DjDSDybtJPAn69geMpUtFc= github.com/gopackage/ddp v0.0.3 h1:fd0DxScoiS+ogq22ktey6DjDSDybtJPAn69geMpUtFc=
@ -803,6 +818,7 @@ github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/ad
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/graph-gophers/dataloader/v6 v6.0.0/go.mod h1:J15OZSnOoZgMkijpbZcwCmglIDYqlUiTEE1xLPbyqZM=
github.com/graph-gophers/graphql-go v1.3.0 h1:Eb9x/q6MFpCLz7jBCiP/WTxjSDrYLR1QY41SORZyNJ0= github.com/graph-gophers/graphql-go v1.3.0 h1:Eb9x/q6MFpCLz7jBCiP/WTxjSDrYLR1QY41SORZyNJ0=
github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
@ -823,7 +839,6 @@ github.com/hako/durafmt v0.0.0-20210608085754-5c1018a4e16b/go.mod h1:VzxiSdG6j1p
github.com/harmony-development/shibshib v0.0.0-20220101224523-c98059d09cfa h1:0EefSRfsNrdEwmoGVz4+cMG8++5M2XhvJ1tTRmmrJu8= github.com/harmony-development/shibshib v0.0.0-20220101224523-c98059d09cfa h1:0EefSRfsNrdEwmoGVz4+cMG8++5M2XhvJ1tTRmmrJu8=
github.com/harmony-development/shibshib v0.0.0-20220101224523-c98059d09cfa/go.mod h1:+KEOMb29OC2kRa5BajwNM2NEjHTbQA/Z3gKYARLHREI= github.com/harmony-development/shibshib v0.0.0-20220101224523-c98059d09cfa/go.mod h1:+KEOMb29OC2kRa5BajwNM2NEjHTbQA/Z3gKYARLHREI=
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
github.com/hashicorp/consul/api v1.11.0/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M=
github.com/hashicorp/consul/api v1.12.0/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= github.com/hashicorp/consul/api v1.12.0/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0=
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms=
@ -837,8 +852,6 @@ github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/S
github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
github.com/hashicorp/go-hclog v0.16.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-hclog v0.16.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
github.com/hashicorp/go-hclog v1.0.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
github.com/hashicorp/go-hclog v1.1.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
github.com/hashicorp/go-hclog v1.2.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-hclog v1.2.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-immutable-radix v1.3.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
@ -870,15 +883,12 @@ github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY=
github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc=
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
github.com/hashicorp/memberlist v0.2.4/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= github.com/hashicorp/memberlist v0.2.4/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
github.com/hashicorp/memberlist v0.3.1/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= github.com/hashicorp/memberlist v0.3.1/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk=
github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4=
github.com/hashicorp/serf v0.9.7/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= github.com/hashicorp/serf v0.9.7/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4=
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
@ -886,7 +896,6 @@ github.com/hashicorp/yamux v0.0.0-20210316155119-a95892c5f864/go.mod h1:CtWFDAQg
github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
github.com/howeyc/gopass v0.0.0-20190910152052-7cb4b85ec19c/go.mod h1:lADxMC39cJJqL93Duh1xhAs4I2Zs8mKS89XWXFGp9cs= github.com/howeyc/gopass v0.0.0-20190910152052-7cb4b85ec19c/go.mod h1:lADxMC39cJJqL93Duh1xhAs4I2Zs8mKS89XWXFGp9cs=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/icrowley/fake v0.0.0-20180203215853-4178557ae428/go.mod h1:uhpZMVGznybq1itEKXj6RYw9I71qK4kH+OGMjRC4KEo= github.com/icrowley/fake v0.0.0-20180203215853-4178557ae428/go.mod h1:uhpZMVGznybq1itEKXj6RYw9I71qK4kH+OGMjRC4KEo=
@ -970,6 +979,7 @@ github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqx
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/jonboulle/clockwork v0.2.0/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= github.com/jonboulle/clockwork v0.2.0/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
github.com/jonboulle/clockwork v0.2.3/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/jpillora/backoff v0.0.0-20180909062703-3050d21c67d7/go.mod h1:2iMrUgbbvHEiQClaW2NsSzMyGHqN+rDFqY705q49KG0= github.com/jpillora/backoff v0.0.0-20180909062703-3050d21c67d7/go.mod h1:2iMrUgbbvHEiQClaW2NsSzMyGHqN+rDFqY705q49KG0=
github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
@ -1022,7 +1032,6 @@ github.com/klauspost/compress v1.13.1/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8
github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
github.com/klauspost/compress v1.13.5/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.13.5/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/klauspost/compress v1.14.4/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/klauspost/compress v1.15.1 h1:y9FcTHGyrebwfP0ZZqFiaxTaiDnUrGkJkI+f583BL1A= github.com/klauspost/compress v1.15.1 h1:y9FcTHGyrebwfP0ZZqFiaxTaiDnUrGkJkI+f583BL1A=
github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
@ -1033,8 +1042,8 @@ github.com/klauspost/cpuid v1.3.1/go.mod h1:bYW4mA6ZgKPob1/Dlai2LviZJO7KGI3uoWLd
github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.0.6/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.6/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.0.11 h1:i2lw1Pm7Yi/4O6XCSyJWqEHI2MDw2FzUK6o/D21xn2A= github.com/klauspost/cpuid/v2 v2.0.12 h1:p9dKCg8i4gmOxtv35DvrYoWqYzQrvEVdjQ762Y0OqZE=
github.com/klauspost/cpuid/v2 v2.0.11/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c=
github.com/klauspost/pgzip v1.2.4/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/klauspost/pgzip v1.2.4/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
github.com/kljensen/snowball v0.6.0/go.mod h1:27N7E8fVU5H68RlUmnWwZCfxgt4POBJfENGMvNRhldw= github.com/kljensen/snowball v0.6.0/go.mod h1:27N7E8fVU5H68RlUmnWwZCfxgt4POBJfENGMvNRhldw=
@ -1068,6 +1077,8 @@ github.com/labstack/gommon v0.3.1/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o= github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o=
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw= github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw=
github.com/ledongthuc/pdf v0.0.0-20210621053716-e28cb8259002/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs= github.com/ledongthuc/pdf v0.0.0-20210621053716-e28cb8259002/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs=
github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/levigross/exp-html v0.0.0-20120902181939-8df60c69a8f5/go.mod h1:QMe2wuKJ0o7zIVE8AqiT8rd8epmm6WDIZ2wyuBqYPzM= github.com/levigross/exp-html v0.0.0-20120902181939-8df60c69a8f5/go.mod h1:QMe2wuKJ0o7zIVE8AqiT8rd8epmm6WDIZ2wyuBqYPzM=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
@ -1080,7 +1091,6 @@ github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lrstanley/girc v0.0.0-20220507183218-96757fe3d2a2 h1:iqJKGIChW2+aPIpnofEZAKgCNwG2tqytB2a1rJS6B6w= github.com/lrstanley/girc v0.0.0-20220507183218-96757fe3d2a2 h1:iqJKGIChW2+aPIpnofEZAKgCNwG2tqytB2a1rJS6B6w=
github.com/lrstanley/girc v0.0.0-20220507183218-96757fe3d2a2/go.mod h1:lgrnhcF8bg/Bd5HA5DOb4Z+uGqUqGnp4skr+J2GwVgI= github.com/lrstanley/girc v0.0.0-20220507183218-96757fe3d2a2/go.mod h1:lgrnhcF8bg/Bd5HA5DOb4Z+uGqUqGnp4skr+J2GwVgI=
github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
@ -1125,8 +1135,8 @@ github.com/mattermost/logr/v2 v2.0.15/go.mod h1:mpPp935r5dIkFDo2y9Q87cQWhFR/4xXp
github.com/mattermost/mattermost-server/v5 v5.39.3 h1:A5z/NlR4Xcwxx5UnlaNgUGP5hgj4KOV/CwpFg3OtlvQ= github.com/mattermost/mattermost-server/v5 v5.39.3 h1:A5z/NlR4Xcwxx5UnlaNgUGP5hgj4KOV/CwpFg3OtlvQ=
github.com/mattermost/mattermost-server/v5 v5.39.3/go.mod h1:MDmVSmsSsqwNkuZ7rQ0osuXVCzrR1IUqGR7I0QU91sY= github.com/mattermost/mattermost-server/v5 v5.39.3/go.mod h1:MDmVSmsSsqwNkuZ7rQ0osuXVCzrR1IUqGR7I0QU91sY=
github.com/mattermost/mattermost-server/v6 v6.0.0/go.mod h1:+S8CsNEPv1FOl1usaPBQ6Gu9+Sm1Cc9YdU/Qh1YMGVI= github.com/mattermost/mattermost-server/v6 v6.0.0/go.mod h1:+S8CsNEPv1FOl1usaPBQ6Gu9+Sm1Cc9YdU/Qh1YMGVI=
github.com/mattermost/mattermost-server/v6 v6.6.1 h1:jza7N9OMqFe+z7s9LZeSj1M4E/2DOV/llIUpi9VWg2U= github.com/mattermost/mattermost-server/v6 v6.7.0 h1:DqNZFuzXU4rtAzmmrpk6wXYI06GzfN+TsGqWf9mwlXc=
github.com/mattermost/mattermost-server/v6 v6.6.1/go.mod h1:oR6UCRo+SEvnfN2FEOdzHs1UljrskyCKU8tWeKlxgMo= github.com/mattermost/mattermost-server/v6 v6.7.0/go.mod h1:b/iDf7Jn2Pd2jWGzaznoVNT811JZpemdmNGP7M/a7Ao=
github.com/mattermost/morph v0.0.0-20220401091636-39f834798da8/go.mod h1:jxM3g1bx+k2Thz7jofcHguBS8TZn5Pc+o5MGmORObhw= github.com/mattermost/morph v0.0.0-20220401091636-39f834798da8/go.mod h1:jxM3g1bx+k2Thz7jofcHguBS8TZn5Pc+o5MGmORObhw=
github.com/mattermost/rsc v0.0.0-20160330161541-bbaefb05eaa0/go.mod h1:nV5bfVpT//+B1RPD2JvRnxbkLmJEYXmRaaVl15fsXjs= github.com/mattermost/rsc v0.0.0-20160330161541-bbaefb05eaa0/go.mod h1:nV5bfVpT//+B1RPD2JvRnxbkLmJEYXmRaaVl15fsXjs=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
@ -1188,14 +1198,14 @@ github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3N
github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4=
github.com/miekg/dns v1.1.46/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= github.com/miekg/dns v1.1.48/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
github.com/minio/md5-simd v1.1.0/go.mod h1:XpBqgZULrMYD3R+M28PcmP0CkI7PEMzB3U77ZrKZ0Gw= github.com/minio/md5-simd v1.1.0/go.mod h1:XpBqgZULrMYD3R+M28PcmP0CkI7PEMzB3U77ZrKZ0Gw=
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34= github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM= github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
github.com/minio/minio-go/v7 v7.0.11/go.mod h1:WoyW+ySKAKjY98B9+7ZbI8z8S3jaxaisdcvj9TGlazA= github.com/minio/minio-go/v7 v7.0.11/go.mod h1:WoyW+ySKAKjY98B9+7ZbI8z8S3jaxaisdcvj9TGlazA=
github.com/minio/minio-go/v7 v7.0.23 h1:NleyGQvAn9VQMU+YHVrgV4CX+EPtxPt/78lHOOTncy4= github.com/minio/minio-go/v7 v7.0.24 h1:HPlHiET6L5gIgrHRaw1xFo1OaN4bEP/082asWh3WJtI=
github.com/minio/minio-go/v7 v7.0.23/go.mod h1:ei5JjmxwHaMrgsMrn4U/+Nmg+d8MKS1U2DAn1ou4+Do= github.com/minio/minio-go/v7 v7.0.24/go.mod h1:x81+AX5gHSfCSqw7jxRKHvxUXMlE5uKX0Vb75Xk5yYg=
github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM=
github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g=
github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM=
@ -1219,8 +1229,9 @@ github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:F
github.com/mitchellh/mapstructure v0.0.0-20180220230111-00c29f56e238/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v0.0.0-20180220230111-00c29f56e238/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGgCcyj8cs=
github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A= github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A=
github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc=
github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
@ -1270,7 +1281,7 @@ github.com/neo4j/neo4j-go-driver v1.8.1-0.20200803113522-b626aa943eba/go.mod h1:
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
github.com/ngdinhtoan/glide-cleanup v0.2.0/go.mod h1:UQzsmiDOb8YV3nOsCxK/c9zPpCZVNoHScRE3EO9pVMM= github.com/ngdinhtoan/glide-cleanup v0.2.0/go.mod h1:UQzsmiDOb8YV3nOsCxK/c9zPpCZVNoHScRE3EO9pVMM=
github.com/nwaples/rardecode v1.1.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0= github.com/nwaples/rardecode v1.1.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0=
github.com/nwaples/rardecode v1.1.2/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0= github.com/nwaples/rardecode v1.1.3/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
@ -1295,8 +1306,10 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108
github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0= github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0=
github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
github.com/onsi/ginkgo v1.15.0/go.mod h1:hF8qUzuuC8DJGygJH3726JnCZX4MYbRB8yFfISqnKUg= github.com/onsi/ginkgo v1.15.0/go.mod h1:hF8qUzuuC8DJGygJH3726JnCZX4MYbRB8yFfISqnKUg=
github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
@ -1308,8 +1321,9 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y
github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc=
github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48= github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48=
github.com/onsi/gomega v1.16.0 h1:6gjqkI8iiRHMvdccRJM8rVKjCWk6ZIm6FTm3ddIe4/c= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs=
github.com/oov/psd v0.0.0-20210618170533-9fb823ddb631/go.mod h1:GHI1bnmAcbp96z6LNfBJvtrjxhaXGkbsk967utPlvL8= github.com/oov/psd v0.0.0-20210618170533-9fb823ddb631/go.mod h1:GHI1bnmAcbp96z6LNfBJvtrjxhaXGkbsk967utPlvL8=
github.com/oov/psd v0.0.0-20220121172623-5db5eafcecbb/go.mod h1:GHI1bnmAcbp96z6LNfBJvtrjxhaXGkbsk967utPlvL8= github.com/oov/psd v0.0.0-20220121172623-5db5eafcecbb/go.mod h1:GHI1bnmAcbp96z6LNfBJvtrjxhaXGkbsk967utPlvL8=
github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
@ -1349,6 +1363,7 @@ github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT9
github.com/otiai10/mint v1.3.2/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= github.com/otiai10/mint v1.3.2/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
github.com/paulrosania/go-charset v0.0.0-20190326053356-55c9d7a5834c h1:P6XGcuPTigoHf4TSu+3D/7QOQ1MbL6alNwrGhcW7sKw= github.com/paulrosania/go-charset v0.0.0-20190326053356-55c9d7a5834c h1:P6XGcuPTigoHf4TSu+3D/7QOQ1MbL6alNwrGhcW7sKw=
github.com/paulrosania/go-charset v0.0.0-20190326053356-55c9d7a5834c/go.mod h1:YnNlZP7l4MhyGQ4CBRwv6ohZTPrUJJZtEv4ZgADkbs4= github.com/paulrosania/go-charset v0.0.0-20190326053356-55c9d7a5834c/go.mod h1:YnNlZP7l4MhyGQ4CBRwv6ohZTPrUJJZtEv4ZgADkbs4=
github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw= github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw=
@ -1357,10 +1372,11 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9
github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE=
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM=
github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/pelletier/go-toml/v2 v2.0.0-beta.8 h1:dy81yyLYJDwMTifq24Oi/IslOslRrDSb3jwDggjz3Z0= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
github.com/pelletier/go-toml/v2 v2.0.0-beta.8/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/pelletier/go-toml/v2 v2.0.1 h1:8e3L2cCQzLFi2CR4g7vGFuFxX7Jl1kKX8gW+iV0GUKU=
github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo=
github.com/peterbourgon/diskv v0.0.0-20171120014656-2973218375c3/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/peterbourgon/diskv v0.0.0-20171120014656-2973218375c3/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
@ -1401,6 +1417,7 @@ github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3O
github.com/prometheus/client_golang v1.4.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.4.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
@ -1419,6 +1436,7 @@ github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8b
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
github.com/prometheus/common v0.33.0/go.mod h1:gB3sOl7P0TvJabZpLY5uQMpUqRCPPCyRLCZYc7JZTNE=
github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
@ -1471,7 +1489,7 @@ github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThC
github.com/rudderlabs/analytics-go v3.3.1+incompatible/go.mod h1:LF8/ty9kUX4PTY3l5c97K3nZZaX5Hwsvt+NBaRL/f30= github.com/rudderlabs/analytics-go v3.3.1+incompatible/go.mod h1:LF8/ty9kUX4PTY3l5c97K3nZZaX5Hwsvt+NBaRL/f30=
github.com/rudderlabs/analytics-go v3.3.2+incompatible/go.mod h1:LF8/ty9kUX4PTY3l5c97K3nZZaX5Hwsvt+NBaRL/f30= github.com/rudderlabs/analytics-go v3.3.2+incompatible/go.mod h1:LF8/ty9kUX4PTY3l5c97K3nZZaX5Hwsvt+NBaRL/f30=
github.com/russellhaering/goxmldsig v1.1.0/go.mod h1:QK8GhXPB3+AfuCrfo0oRISa9NfzeCpWmxeGnqEpDF9o= github.com/russellhaering/goxmldsig v1.1.0/go.mod h1:QK8GhXPB3+AfuCrfo0oRISa9NfzeCpWmxeGnqEpDF9o=
github.com/russellhaering/goxmldsig v1.1.1/go.mod h1:gM4MDENBQf7M+V824SGfyIUVFWydB7n0KkEubVJl+Tw= github.com/russellhaering/goxmldsig v1.2.0/go.mod h1:gM4MDENBQf7M+V824SGfyIUVFWydB7n0KkEubVJl+Tw=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww= github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww=
github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY= github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY=
@ -1482,8 +1500,7 @@ github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4= github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4=
github.com/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig= github.com/sagikazarmark/crypt v0.6.0/go.mod h1:U8+INwJo3nBv1m6A/8OBXAq7Jnpspk5AxSgDyEQcea8=
github.com/sagikazarmark/crypt v0.5.0/go.mod h1:l+nzl7KWh51rpzp2h7t4MZWyiEWdhNpOAnclKvg+mdA=
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca h1:NugYot0LIVPxTvN8n+Kvkn6TrbMyxQiuvKdEwFdR9vI= github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca h1:NugYot0LIVPxTvN8n+Kvkn6TrbMyxQiuvKdEwFdR9vI=
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU= github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU=
github.com/satori/go.uuid v0.0.0-20180103174451-36e9d2ebbde5/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/satori/go.uuid v0.0.0-20180103174451-36e9d2ebbde5/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
@ -1563,21 +1580,20 @@ github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4=
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo= github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo=
github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo= github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA= github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk=
github.com/spf13/cobra v1.3.0/go.mod h1:BrRVncBjOJa/eUcVVm9CE+oC6as8k+VYr4NY7WCi9V4= github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
@ -1591,9 +1607,8 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns=
github.com/spf13/viper v1.10.0/go.mod h1:SoyBPwAtKDzypXNDFKN5kzH7ppppbGZtls1UpIy5AsM= github.com/spf13/viper v1.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ=
github.com/spf13/viper v1.11.0 h1:7OX/1FS6n7jHD1zGrZTM7WtY13ZELRyosK4k93oPr44= github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI=
github.com/spf13/viper v1.11.0/go.mod h1:djo0X/bA5+tYVoCn+C7cAYJGcVn/qYLFTG8gdUsX7Zk=
github.com/splitio/go-client/v6 v6.1.0/go.mod h1:CEGAEFT99Fwb32ZIRcnZoXTMXddtB6IIpTmt3RP8mnM= github.com/splitio/go-client/v6 v6.1.0/go.mod h1:CEGAEFT99Fwb32ZIRcnZoXTMXddtB6IIpTmt3RP8mnM=
github.com/splitio/go-split-commons/v3 v3.1.0/go.mod h1:29NCy20oAS4ZMy4qkwTd6277eieVDonx4V/aeDU/wUQ= github.com/splitio/go-split-commons/v3 v3.1.0/go.mod h1:29NCy20oAS4ZMy4qkwTd6277eieVDonx4V/aeDU/wUQ=
github.com/splitio/go-toolkit/v4 v4.2.0/go.mod h1:EdIHN0yzB1GTXDYQc0KdKvnjkO/jfUM2YqHVYfhD3Wo= github.com/splitio/go-toolkit/v4 v4.2.0/go.mod h1:EdIHN0yzB1GTXDYQc0KdKvnjkO/jfUM2YqHVYfhD3Wo=
@ -1616,8 +1631,9 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/subosito/gotenv v1.3.0 h1:mjC+YW8QpAdXibNi+vNWgzmgBH4+5l5dCXv8cNysBLI=
github.com/subosito/gotenv v1.3.0/go.mod h1:YzJjq/33h7nrwdY+iHMhEOEEbW0ovIz0tB6t6PwAXzs=
github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
@ -1735,7 +1751,7 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.3.8/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.3.8/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.7/go.mod h1:rmuwmfZ0+bvzB24eSC//bk1R1Zp3hM0OXYv/G2LIilg= github.com/yuin/goldmark v1.4.11/go.mod h1:rmuwmfZ0+bvzB24eSC//bk1R1Zp3hM0OXYv/G2LIilg=
github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs=
github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA=
github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg=
@ -1750,18 +1766,16 @@ go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=
go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg= go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg=
go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
go.etcd.io/etcd/api/v3 v3.5.1/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= go.etcd.io/etcd/api/v3 v3.5.4/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A=
go.etcd.io/etcd/api/v3 v3.5.2/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A=
go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
go.etcd.io/etcd/client/pkg/v3 v3.5.1/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= go.etcd.io/etcd/client/pkg/v3 v3.5.4/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
go.etcd.io/etcd/client/pkg/v3 v3.5.2/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=
go.etcd.io/etcd/client/v2 v2.305.1/go.mod h1:pMEacxZW7o8pg4CrFE7pquyCJJzZvkvdD2RibOCCCGs= go.etcd.io/etcd/client/v2 v2.305.4/go.mod h1:Ud+VUwIi9/uQHOMA+4ekToJ12lTxlv0zB/+DHwTGEbU=
go.etcd.io/etcd/client/v2 v2.305.2/go.mod h1:2D7ZejHVMIfog1221iLSYlQRzrtECw3kz4I4VAQm3qI= go.etcd.io/etcd/client/v3 v3.5.4/go.mod h1:ZaRkVgBZC+L+dLCjTcF1hRXpgZXQPOvnA/Ak/gq3kiY=
go.mau.fi/libsignal v0.0.0-20220425070825-c40c839ee6a0 h1:3IQF2bgAyibdo77hTejwuJe4jlypj9QaE4xCQuxrThM= go.mau.fi/libsignal v0.0.0-20220425070825-c40c839ee6a0 h1:3IQF2bgAyibdo77hTejwuJe4jlypj9QaE4xCQuxrThM=
go.mau.fi/libsignal v0.0.0-20220425070825-c40c839ee6a0/go.mod h1:kBOXTvYyDG/q1Ihgvd4J6WenGPh7wtEGvPKF6vmf5ak= go.mau.fi/libsignal v0.0.0-20220425070825-c40c839ee6a0/go.mod h1:kBOXTvYyDG/q1Ihgvd4J6WenGPh7wtEGvPKF6vmf5ak=
go.mau.fi/whatsmeow v0.0.0-20220504135614-f1f2a9d231fb h1:xI4HiJwBMmztBXFzjKWt7Ea8xmOO7LyYCYV0/ROU7kY= go.mau.fi/whatsmeow v0.0.0-20220601182603-a8d86cf1812c h1:2pn4sUljgVcFrPl1wyFOA0Qvg8726yzwyC1+qVdPkjM=
go.mau.fi/whatsmeow v0.0.0-20220504135614-f1f2a9d231fb/go.mod h1:iUBgOLNaqShLrR17u0kIiRptIGFH+nbT1tRhaWBEX/c= go.mau.fi/whatsmeow v0.0.0-20220601182603-a8d86cf1812c/go.mod h1:iUBgOLNaqShLrR17u0kIiRptIGFH+nbT1tRhaWBEX/c=
go.mongodb.org/mongo-driver v1.1.0/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.0/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
go.mongodb.org/mongo-driver v1.7.0/go.mod h1:Q4oFMbo1+MSNqICAdYMlC/zSTrwCogR4R8NzkI+yfU8= go.mongodb.org/mongo-driver v1.7.0/go.mod h1:Q4oFMbo1+MSNqICAdYMlC/zSTrwCogR4R8NzkI+yfU8=
go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk= go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk=
@ -1843,7 +1857,7 @@ golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5y
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 h1:kUhD7nTDoI3fVd9G4ORWrbV5NY0liEs/Jg2pv5f+bBA= golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 h1:kUhD7nTDoI3fVd9G4ORWrbV5NY0liEs/Jg2pv5f+bBA=
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@ -1873,9 +1887,9 @@ golang.org/x/image v0.0.0-20200618115811-c13761719519/go.mod h1:FeLwcggjj3mMvU+o
golang.org/x/image v0.0.0-20201208152932-35266b937fa6/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20201208152932-35266b937fa6/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20210216034530-4410531fe030/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20210216034530-4410531fe030/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20210622092929-e6eecd499c2c/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= golang.org/x/image v0.0.0-20210622092929-e6eecd499c2c/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= golang.org/x/image v0.0.0-20220321031419-a8550c1d254a/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9 h1:LRtI4W37N+KFebI/qV0OFiLUv4GLOWeEW5hn/KEJvxE= golang.org/x/image v0.0.0-20220601225756-64ec528b34cd h1:9NbNcTg//wfC5JskFW4Z3sqwVnjmJKHxLAol1bW2qgw=
golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= golang.org/x/image v0.0.0-20220601225756-64ec528b34cd/go.mod h1:doUCurBvlfPMKfmIpRIywoHmhN3VyhnoFDbvIEWF4hY=
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20181217174547-8f45f776aaf1/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181217174547-8f45f776aaf1/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@ -1902,9 +1916,8 @@ golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hM
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 h1:kQgndtyPBW/JIYERgdxfwMYh3AVStj88WQTlNDi2a+o=
golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -1987,8 +2000,11 @@ golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qx
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220412020605-290c469a71a5 h1:bRb386wvrE+oBNdF1d/Xh9mQrfQ4ecYhW5qJ5GvTGT4= golang.org/x/net v0.0.0-20220403103023-749bd193bc2b/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2 h1:NWy5+hlRbC7HK+PmcXVUmW1IMyFce7to56IUvhUFm7Y=
golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/oauth2 v0.0.0-20180227000427-d7d64896b5ff/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180227000427-d7d64896b5ff/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@ -2014,8 +2030,9 @@ golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 h1:OSnWWcOd/CtWQC2cYSBgbTSJv3ciqd8r54ySIW2y3RE=
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
golang.org/x/oauth2 v0.0.0-20220524215830-622c5d57e401 h1:zwrSfklXn0gxyLRX/aR+q6cgHbV/ItVyzbPlbA+dkAw=
golang.org/x/oauth2 v0.0.0-20220524215830-622c5d57e401/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -2029,6 +2046,7 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220513210516-0976fa681c29/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180224232135-f6cff0780e54/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180224232135-f6cff0780e54/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -2148,7 +2166,6 @@ golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210818153620-00dd8d7831e7/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210818153620-00dd8d7831e7/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210902050250-f475640dd07b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210902050250-f475640dd07b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@ -2159,17 +2176,18 @@ golang.org/x/sys v0.0.0-20211013075003-97ac67df715c/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220224120231-95c6836cb0e7/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad h1:ntjMns5wyP/fN65tdBD4g8J5w8n015+iIIs9rtjXkY0= golang.org/x/sys v0.0.0-20220403205710-6acee93ad0eb/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
@ -2280,16 +2298,17 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.9 h1:j9KsMiaP1c3B0OTQGth0/k+miLGTgLsAFUCrF2vLcF8= golang.org/x/tools v0.1.10 h1:QjFRCZxdOhBJ/UNgnBZLbNV13DlbnK0quyivTnXJM20=
golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f h1:GGU+dLjvlC3qDwqYgL6UgRmHXhOOgns0bZu2Ty5mm6U=
golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df h1:5Pf6pFKu98ODmgnpvkJ3kFUOQGGLIzLIkbzUHp47618=
golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
gomod.garykim.dev/nc-talk v0.3.0 h1:MZxLc/gX2/+bdOw4xt6pi+qQFUQld1woGfw1hEJ0fbM= gomod.garykim.dev/nc-talk v0.3.0 h1:MZxLc/gX2/+bdOw4xt6pi+qQFUQld1woGfw1hEJ0fbM=
gomod.garykim.dev/nc-talk v0.3.0/go.mod h1:q/Adot/H7iqi+H4lANopV7/xcMf+sX3AZXUXqiITwok= gomod.garykim.dev/nc-talk v0.3.0/go.mod h1:q/Adot/H7iqi+H4lANopV7/xcMf+sX3AZXUXqiITwok=
gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
@ -2336,12 +2355,14 @@ google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqiv
google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI=
google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU= google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU=
google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I=
google.golang.org/api v0.62.0/go.mod h1:dKmwPCydfsad4qCH08MSdgWjfHOyfpd4VtDGgRFdavw=
google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo=
google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g=
google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA=
google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8=
google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs=
google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA=
google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw=
google.golang.org/api v0.81.0/go.mod h1:FA6Mb/bZxj706H2j+j2d6mHEEaHBmbbWnkfvmorOCko=
google.golang.org/appengine v1.0.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.0.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@ -2434,8 +2455,6 @@ google.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ6
google.golang.org/genproto v0.0.0-20211013025323-ce878158c4d4/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211013025323-ce878158c4d4/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20211028162531-8db9c33dc351/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211028162531-8db9c33dc351/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20211203200212-54befc351ae9/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
@ -2446,7 +2465,14 @@ google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2
google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E=
google.golang.org/genproto v0.0.0-20220401170504-314d38edb7de/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
@ -2484,9 +2510,10 @@ google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnD
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k= google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k=
google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
@ -2524,7 +2551,6 @@ gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.57.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.57.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.66.4 h1:SsAcf+mM7mRZo2nJNGt8mZCjG8ZRaNGMURJw7BsIST4= gopkg.in/ini.v1 v1.66.4 h1:SsAcf+mM7mRZo2nJNGt8mZCjG8ZRaNGMURJw7BsIST4=
gopkg.in/ini.v1 v1.66.4/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.66.4/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/mail.v2 v2.3.1/go.mod h1:htwXN1Qh09vZJ1NVKxQqHPBaCBbzKhp5GzuJEA4VJWw= gopkg.in/mail.v2 v2.3.1/go.mod h1:htwXN1Qh09vZJ1NVKxQqHPBaCBbzKhp5GzuJEA4VJWw=
@ -2556,8 +2582,9 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0 h1:hjy8E9ON/egN1tAYqKb61G10WtihqetD4sz2H+8nIeA=
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gorm.io/driver/postgres v1.0.8/go.mod h1:4eOzrI1MUfm6ObJU/UcmbXyiHSs8jSwH95G5P5dxcAg= gorm.io/driver/postgres v1.0.8/go.mod h1:4eOzrI1MUfm6ObJU/UcmbXyiHSs8jSwH95G5P5dxcAg=
gorm.io/gorm v1.20.12/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= gorm.io/gorm v1.20.12/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw=
gorm.io/gorm v1.21.4/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= gorm.io/gorm v1.21.4/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw=
@ -2741,8 +2768,8 @@ modernc.org/ql v1.0.0/go.mod h1:xGVyrLIatPcO2C1JvI/Co8c0sr6y91HKFNy4pt9JXEY=
modernc.org/sortutil v1.1.0/go.mod h1:ZyL98OQHJgH9IEfN71VsamvJgrtRX9Dj2gX+vH86L1k= modernc.org/sortutil v1.1.0/go.mod h1:ZyL98OQHJgH9IEfN71VsamvJgrtRX9Dj2gX+vH86L1k=
modernc.org/sqlite v1.10.6/go.mod h1:Z9FEjUtZP4qFEg6/SiADg9XCER7aYy9a/j7Pg9P7CPs= modernc.org/sqlite v1.10.6/go.mod h1:Z9FEjUtZP4qFEg6/SiADg9XCER7aYy9a/j7Pg9P7CPs=
modernc.org/sqlite v1.14.3/go.mod h1:xMpicS1i2MJ4C8+Ap0vYBqTwYfpFvdnPE6brbFOtV2Y= modernc.org/sqlite v1.14.3/go.mod h1:xMpicS1i2MJ4C8+Ap0vYBqTwYfpFvdnPE6brbFOtV2Y=
modernc.org/sqlite v1.17.2 h1:TjmF36Wi5QcPYqRoAacV1cAyJ7xB/CD0ExpVUEMebnw= modernc.org/sqlite v1.17.3 h1:iE+coC5g17LtByDYDWKpR6m2Z9022YrSh3bumwOnIrI=
modernc.org/sqlite v1.17.2/go.mod h1:GOQmuiXd6pTTes1Fi2s9apiCcD/wbKQtBZ0Nw6/etjM= modernc.org/sqlite v1.17.3/go.mod h1:10hPVYar9C0kfXuTWGz8s0XtB8uAGymUy51ZzStYe3k=
modernc.org/strutil v1.1.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs= modernc.org/strutil v1.1.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs=
modernc.org/strutil v1.1.1 h1:xv+J1BXY3Opl2ALrBwyfEikFAj8pmqcpnfmuwUwcozs= modernc.org/strutil v1.1.1 h1:xv+J1BXY3Opl2ALrBwyfEikFAj8pmqcpnfmuwUwcozs=
modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw= modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw=

View File

@ -1,3 +1,4 @@
//go:build gofuzz
// +build gofuzz // +build gofuzz
package markdown package markdown

View File

@ -11,6 +11,7 @@ import (
"strings" "strings"
"github.com/gomarkdown/markdown/ast" "github.com/gomarkdown/markdown/ast"
"github.com/gomarkdown/markdown/internal/valid"
"github.com/gomarkdown/markdown/parser" "github.com/gomarkdown/markdown/parser"
) )
@ -211,70 +212,6 @@ func NewRenderer(opts RendererOptions) *Renderer {
} }
} }
func isHTMLTag(tag []byte, tagname string) bool {
found, _ := findHTMLTagPos(tag, tagname)
return found
}
// Look for a character, but ignore it when it's in any kind of quotes, it
// might be JavaScript
func skipUntilCharIgnoreQuotes(html []byte, start int, char byte) int {
inSingleQuote := false
inDoubleQuote := false
inGraveQuote := false
i := start
for i < len(html) {
switch {
case html[i] == char && !inSingleQuote && !inDoubleQuote && !inGraveQuote:
return i
case html[i] == '\'':
inSingleQuote = !inSingleQuote
case html[i] == '"':
inDoubleQuote = !inDoubleQuote
case html[i] == '`':
inGraveQuote = !inGraveQuote
}
i++
}
return start
}
func findHTMLTagPos(tag []byte, tagname string) (bool, int) {
i := 0
if i < len(tag) && tag[0] != '<' {
return false, -1
}
i++
i = skipSpace(tag, i)
if i < len(tag) && tag[i] == '/' {
i++
}
i = skipSpace(tag, i)
j := 0
for ; i < len(tag); i, j = i+1, j+1 {
if j >= len(tagname) {
break
}
if strings.ToLower(string(tag[i]))[0] != tagname[j] {
return false, -1
}
}
if i == len(tag) {
return false, -1
}
rightAngle := skipUntilCharIgnoreQuotes(tag, i, '>')
if rightAngle >= i {
return true, rightAngle
}
return false, -1
}
func isRelativeLink(link []byte) (yes bool) { func isRelativeLink(link []byte) (yes bool) {
// a tag begin with '#' // a tag begin with '#'
if link[0] == '#' { if link[0] == '#' {
@ -351,14 +288,6 @@ func needSkipLink(flags Flags, dest []byte) bool {
return flags&Safelink != 0 && !isSafeLink(dest) && !isMailto(dest) return flags&Safelink != 0 && !isSafeLink(dest) && !isMailto(dest)
} }
func isSmartypantable(node ast.Node) bool {
switch node.GetParent().(type) {
case *ast.Link, *ast.CodeBlock, *ast.Code:
return false
}
return true
}
func appendLanguageAttr(attrs []string, info []byte) []string { func appendLanguageAttr(attrs []string, info []byte) []string {
if len(info) == 0 { if len(info) == 0 {
return attrs return attrs
@ -1297,21 +1226,8 @@ func isListItemTerm(node ast.Node) bool {
return ok && data.ListFlags&ast.ListTypeTerm != 0 return ok && data.ListFlags&ast.ListTypeTerm != 0
} }
// TODO: move to internal package
func skipSpace(data []byte, i int) int {
n := len(data)
for i < n && isSpace(data[i]) {
i++
}
return i
}
// TODO: move to internal package
var validUris = [][]byte{[]byte("http://"), []byte("https://"), []byte("ftp://"), []byte("mailto://")}
var validPaths = [][]byte{[]byte("/"), []byte("./"), []byte("../")}
func isSafeLink(link []byte) bool { func isSafeLink(link []byte) bool {
for _, path := range validPaths { for _, path := range valid.Paths {
if len(link) >= len(path) && bytes.Equal(link[:len(path)], path) { if len(link) >= len(path) && bytes.Equal(link[:len(path)], path) {
if len(link) == len(path) { if len(link) == len(path) {
return true return true
@ -1321,7 +1237,7 @@ func isSafeLink(link []byte) bool {
} }
} }
for _, prefix := range validUris { for _, prefix := range valid.URIs {
// TODO: handle unicode here // TODO: handle unicode here
// case-insensitive prefix test // case-insensitive prefix test
if len(link) > len(prefix) && bytes.Equal(bytes.ToLower(link[:len(prefix)]), prefix) && isAlnum(link[len(prefix)]) { if len(link) > len(prefix) && bytes.Equal(bytes.ToLower(link[:len(prefix)]), prefix) && isAlnum(link[len(prefix)]) {

View File

@ -0,0 +1,14 @@
package valid
var URIs = [][]byte{
[]byte("http://"),
[]byte("https://"),
[]byte("ftp://"),
[]byte("mailto:"),
}
var Paths = [][]byte{
[]byte("/"),
[]byte("./"),
[]byte("../"),
}

View File

@ -24,8 +24,8 @@ const (
) )
var ( var (
reBackslashOrAmp = regexp.MustCompile("[\\&]") reBackslashOrAmp = regexp.MustCompile(`[\&]`)
reEntityOrEscapedChar = regexp.MustCompile("(?i)\\\\" + escapable + "|" + charEntity) reEntityOrEscapedChar = regexp.MustCompile(`(?i)\\` + escapable + "|" + charEntity)
// blockTags is a set of tags that are recognized as HTML block tags. // blockTags is a set of tags that are recognized as HTML block tags.
// Any of these can be included in markdown text without special escaping. // Any of these can be included in markdown text without special escaping.

View File

@ -6,6 +6,7 @@ import (
"strconv" "strconv"
"github.com/gomarkdown/markdown/ast" "github.com/gomarkdown/markdown/ast"
"github.com/gomarkdown/markdown/internal/valid"
) )
// Parsing of inline elements // Parsing of inline elements
@ -994,12 +995,9 @@ func isEndOfLink(char byte) bool {
return isSpace(char) || char == '<' return isSpace(char) || char == '<'
} }
var validUris = [][]byte{[]byte("http://"), []byte("https://"), []byte("ftp://"), []byte("mailto://")}
var validPaths = [][]byte{[]byte("/"), []byte("./"), []byte("../")}
func isSafeLink(link []byte) bool { func isSafeLink(link []byte) bool {
nLink := len(link) nLink := len(link)
for _, path := range validPaths { for _, path := range valid.Paths {
nPath := len(path) nPath := len(path)
linkPrefix := link[:nPath] linkPrefix := link[:nPath]
if nLink >= nPath && bytes.Equal(linkPrefix, path) { if nLink >= nPath && bytes.Equal(linkPrefix, path) {
@ -1011,7 +1009,7 @@ func isSafeLink(link []byte) bool {
} }
} }
for _, prefix := range validUris { for _, prefix := range valid.URIs {
// TODO: handle unicode here // TODO: handle unicode here
// case-insensitive prefix test // case-insensitive prefix test
nPrefix := len(prefix) nPrefix := len(prefix)
@ -1119,7 +1117,7 @@ func isMailtoAutoLink(data []byte) int {
nb++ nb++
case '-', '.', '_': case '-', '.', '_':
break // no-op but not defult
case '>': case '>':
if nb == 1 { if nb == 1 {

View File

@ -8,7 +8,6 @@ import (
"fmt" "fmt"
"strconv" "strconv"
"strings" "strings"
"unicode/utf8"
"github.com/gomarkdown/markdown/ast" "github.com/gomarkdown/markdown/ast"
) )
@ -720,6 +719,7 @@ func isAlnum(c byte) bool {
// TODO: this is not used // TODO: this is not used
// Replace tab characters with spaces, aligning to the next TAB_SIZE column. // Replace tab characters with spaces, aligning to the next TAB_SIZE column.
// always ends output with a newline // always ends output with a newline
/*
func expandTabs(out *bytes.Buffer, line []byte, tabSize int) { func expandTabs(out *bytes.Buffer, line []byte, tabSize int) {
// first, check for common cases: no tabs, or only tabs at beginning of line // first, check for common cases: no tabs, or only tabs at beginning of line
i, prefix := 0, 0 i, prefix := 0, 0
@ -775,6 +775,7 @@ func expandTabs(out *bytes.Buffer, line []byte, tabSize int) {
i++ i++
} }
} }
*/
// Find if a line counts as indented or not. // Find if a line counts as indented or not.
// Returns number of characters the indent is (0 = not indented). // Returns number of characters the indent is (0 = not indented).

View File

@ -27,7 +27,7 @@ const (
ChannelGroupMinUsers = 3 ChannelGroupMinUsers = 3
DefaultChannelName = "town-square" DefaultChannelName = "town-square"
ChannelDisplayNameMaxRunes = 64 ChannelDisplayNameMaxRunes = 64
ChannelNameMinLength = 2 ChannelNameMinLength = 1
ChannelNameMaxLength = 64 ChannelNameMaxLength = 64
ChannelHeaderMaxRunes = 1024 ChannelHeaderMaxRunes = 1024
ChannelPurposeMaxRunes = 250 ChannelPurposeMaxRunes = 250
@ -216,7 +216,7 @@ func (o *Channel) IsValid() *AppError {
} }
if !IsValidChannelIdentifier(o.Name) { if !IsValidChannelIdentifier(o.Name) {
return NewAppError("Channel.IsValid", "model.channel.is_valid.2_or_more.app_error", nil, "id="+o.Id, http.StatusBadRequest) return NewAppError("Channel.IsValid", "model.channel.is_valid.1_or_more.app_error", nil, "id="+o.Id, http.StatusBadRequest)
} }
if !(o.Type == ChannelTypeOpen || o.Type == ChannelTypePrivate || o.Type == ChannelTypeDirect || o.Type == ChannelTypeGroup) { if !(o.Type == ChannelTypeOpen || o.Type == ChannelTypePrivate || o.Type == ChannelTypeDirect || o.Type == ChannelTypeGroup) {

View File

@ -8,4 +8,17 @@ type ChannelStats struct {
MemberCount int64 `json:"member_count"` MemberCount int64 `json:"member_count"`
GuestCount int64 `json:"guest_count"` GuestCount int64 `json:"guest_count"`
PinnedPostCount int64 `json:"pinnedpost_count"` PinnedPostCount int64 `json:"pinnedpost_count"`
FilesCount int64 `json:"files_count"`
}
func (o *ChannelStats) MemberCount_() float64 {
return float64(o.MemberCount)
}
func (o *ChannelStats) GuestCount_() float64 {
return float64(o.GuestCount)
}
func (o *ChannelStats) PinnedPostCount_() float64 {
return float64(o.PinnedPostCount)
} }

View File

@ -2638,6 +2638,30 @@ func (c *Client4) InviteGuestsToTeam(teamId string, userEmails []string, channel
// InviteUsersToTeam invite users by email to the team. // InviteUsersToTeam invite users by email to the team.
func (c *Client4) InviteUsersToTeamGracefully(teamId string, userEmails []string) ([]*EmailInviteWithError, *Response, error) { func (c *Client4) InviteUsersToTeamGracefully(teamId string, userEmails []string) ([]*EmailInviteWithError, *Response, error) {
r, err := c.DoAPIPost(c.teamRoute(teamId)+"/invite/email?graceful="+c.boolString(true), ArrayToJSON(userEmails)) r, err := c.DoAPIPost(c.teamRoute(teamId)+"/invite/email?graceful="+c.boolString(true), ArrayToJSON(userEmails))
if err != nil {
return nil, BuildResponse(r), err
}
defer closeBody(r)
var list []*EmailInviteWithError
if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil {
return nil, nil, NewAppError("InviteUsersToTeamGracefully", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError)
}
return list, BuildResponse(r), nil
}
// InviteUsersToTeam invite users by email to the team.
func (c *Client4) InviteUsersToTeamAndChannelsGracefully(teamId string, userEmails []string, channelIds []string, message string) ([]*EmailInviteWithError, *Response, error) {
memberInvite := MemberInvite{
Emails: userEmails,
ChannelIds: channelIds,
Message: message,
}
buf, err := json.Marshal(memberInvite)
if err != nil {
return nil, nil, NewAppError("InviteMembersToTeamAndChannels", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError)
}
r, err := c.DoAPIPostBytes(c.teamRoute(teamId)+"/invite/email?graceful="+c.boolString(true), buf)
if err != nil { if err != nil {
return nil, BuildResponse(r), err return nil, BuildResponse(r), err
} }
@ -3748,6 +3772,49 @@ func (c *Client4) GetPostThread(postId string, etag string, collapsedThreads boo
return &list, BuildResponse(r), nil return &list, BuildResponse(r), nil
} }
// GetPostThreadWithOpts gets a post with all the other posts in the same thread.
func (c *Client4) GetPostThreadWithOpts(postID string, etag string, opts GetPostsOptions) (*PostList, *Response, error) {
urlVal := c.postRoute(postID) + "/thread"
values := url.Values{}
if opts.CollapsedThreads {
values.Set("collapsedThreads", "true")
}
if opts.CollapsedThreadsExtended {
values.Set("collapsedThreadsExtended", "true")
}
if opts.SkipFetchThreads {
values.Set("skipFetchThreads", "true")
}
if opts.PerPage != 0 {
values.Set("perPage", strconv.Itoa(opts.PerPage))
}
if opts.FromPost != "" {
values.Set("fromPost", opts.FromPost)
}
if opts.FromCreateAt != 0 {
values.Set("fromCreateAt", strconv.FormatInt(opts.FromCreateAt, 10))
}
if opts.Direction != "" {
values.Set("direction", opts.Direction)
}
urlVal += "?" + values.Encode()
r, err := c.DoAPIGet(urlVal, etag)
if err != nil {
return nil, BuildResponse(r), err
}
defer closeBody(r)
var list PostList
if r.StatusCode == http.StatusNotModified {
return &list, BuildResponse(r), nil
}
if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil {
return nil, nil, NewAppError("GetPostThread", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError)
}
return &list, BuildResponse(r), nil
}
// GetPostsForChannel gets a page of posts with an array for ordering for a channel. // GetPostsForChannel gets a page of posts with an array for ordering for a channel.
func (c *Client4) GetPostsForChannel(channelId string, page, perPage int, etag string, collapsedThreads bool) (*PostList, *Response, error) { func (c *Client4) GetPostsForChannel(channelId string, page, perPage int, etag string, collapsedThreads bool) (*PostList, *Response, error) {
query := fmt.Sprintf("?page=%v&per_page=%v", page, perPage) query := fmt.Sprintf("?page=%v&per_page=%v", page, perPage)
@ -6429,6 +6496,39 @@ func (c *Client4) GetBulkReactions(postIds []string) (map[string][]*Reaction, *R
return reactions, BuildResponse(r), nil return reactions, BuildResponse(r), nil
} }
func (c *Client4) GetTopReactionsForTeamSince(teamId string, timeRange string, page int, perPage int) (*TopReactionList, *Response, error) {
query := fmt.Sprintf("?time_range=%v&page=%v&per_page=%v", timeRange, page, perPage)
r, err := c.DoAPIGet(c.teamRoute(teamId)+"/top/reactions"+query, "")
if err != nil {
return nil, BuildResponse(r), err
}
defer closeBody(r)
var topReactions *TopReactionList
if jsonErr := json.NewDecoder(r.Body).Decode(&topReactions); jsonErr != nil {
return nil, nil, NewAppError("GetTopReactionsForTeamSince", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError)
}
return topReactions, BuildResponse(r), nil
}
func (c *Client4) GetTopReactionsForUserSince(teamId string, timeRange string, page int, perPage int) (*TopReactionList, *Response, error) {
query := fmt.Sprintf("?time_range=%v&page=%v&per_page=%v", timeRange, page, perPage)
if teamId != "" {
query += fmt.Sprintf("&team_id=%v", teamId)
}
r, err := c.DoAPIGet(c.usersRoute()+"/me/top/reactions"+query, "")
if err != nil {
return nil, BuildResponse(r), err
}
defer closeBody(r)
var topReactions *TopReactionList
if jsonErr := json.NewDecoder(r.Body).Decode(&topReactions); jsonErr != nil {
return nil, nil, NewAppError("GetTopReactionsForUserSince", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError)
}
return topReactions, BuildResponse(r), nil
}
// Timezone Section // Timezone Section
// GetSupportedTimezone returns a page of supported timezones on the system. // GetSupportedTimezone returns a page of supported timezones on the system.
@ -7658,18 +7758,6 @@ func (c *Client4) GetSubscription() (*Subscription, *Response, error) {
return subscription, BuildResponse(r), nil return subscription, BuildResponse(r), nil
} }
func (c *Client4) GetSubscriptionStats() (*SubscriptionStats, *Response, error) {
r, err := c.DoAPIGet(c.cloudRoute()+"/subscription/stats", "")
if err != nil {
return nil, BuildResponse(r), err
}
defer closeBody(r)
var stats *SubscriptionStats
json.NewDecoder(r.Body).Decode(&stats)
return stats, BuildResponse(r), nil
}
func (c *Client4) GetInvoicesForSubscription() ([]*Invoice, *Response, error) { func (c *Client4) GetInvoicesForSubscription() ([]*Invoice, *Response, error) {
r, err := c.DoAPIGet(c.cloudRoute()+"/subscription/invoices", "") r, err := c.DoAPIGet(c.cloudRoute()+"/subscription/invoices", "")
if err != nil { if err != nil {
@ -7782,6 +7870,12 @@ func (c *Client4) GetUserThreads(userId, teamId string, options GetUserThreadsOp
if options.Unread { if options.Unread {
v.Set("unread", "true") v.Set("unread", "true")
} }
if options.ThreadsOnly {
v.Set("threadsOnly", "true")
}
if options.TotalsOnly {
v.Set("totalsOnly", "true")
}
url := c.userThreadsRoute(userId, teamId) url := c.userThreadsRoute(userId, teamId)
if len(v) > 0 { if len(v) > 0 {
url += "?" + v.Encode() url += "?" + v.Encode()
@ -7826,6 +7920,18 @@ func (c *Client4) UpdateThreadsReadForUser(userId, teamId string) (*Response, er
return BuildResponse(r), nil return BuildResponse(r), nil
} }
func (c *Client4) SetThreadUnreadByPostId(userId, teamId, threadId, postId string) (*ThreadResponse, *Response, error) {
r, err := c.DoAPIPost(fmt.Sprintf("%s/set_unread/%s", c.userThreadRoute(userId, teamId, threadId), postId), "")
if err != nil {
return nil, BuildResponse(r), err
}
defer closeBody(r)
var thread ThreadResponse
json.NewDecoder(r.Body).Decode(&thread)
return &thread, BuildResponse(r), nil
}
func (c *Client4) UpdateThreadReadForUser(userId, teamId, threadId string, timestamp int64) (*ThreadResponse, *Response, error) { func (c *Client4) UpdateThreadReadForUser(userId, teamId, threadId string, timestamp int64) (*ThreadResponse, *Response, error) {
r, err := c.DoAPIPut(fmt.Sprintf("%s/read/%d", c.userThreadRoute(userId, teamId, threadId), timestamp), "") r, err := c.DoAPIPut(fmt.Sprintf("%s/read/%d", c.userThreadRoute(userId, teamId, threadId), timestamp), "")
if err != nil { if err != nil {
@ -7854,26 +7960,6 @@ func (c *Client4) UpdateThreadFollowForUser(userId, teamId, threadId string, sta
return BuildResponse(r), nil return BuildResponse(r), nil
} }
func (c *Client4) SendAdminUpgradeRequestEmail() (*Response, error) {
r, err := c.DoAPIPost(c.cloudRoute()+"/subscription/limitreached/invite", "")
if err != nil {
return BuildResponse(r), err
}
defer closeBody(r)
return BuildResponse(r), nil
}
func (c *Client4) SendAdminUpgradeRequestEmailOnJoin() (*Response, error) {
r, err := c.DoAPIPost(c.cloudRoute()+"/subscription/limitreached/join", "")
if err != nil {
return BuildResponse(r), err
}
defer closeBody(r)
return BuildResponse(r), nil
}
func (c *Client4) GetAllSharedChannels(teamID string, page, perPage int) ([]*SharedChannel, *Response, error) { func (c *Client4) GetAllSharedChannels(teamID string, page, perPage int) ([]*SharedChannel, *Response, error) {
url := fmt.Sprintf("%s/%s?page=%d&per_page=%d", c.sharedChannelsRoute(), teamID, page, perPage) url := fmt.Sprintf("%s/%s?page=%d&per_page=%d", c.sharedChannelsRoute(), teamID, page, perPage)
r, err := c.DoAPIGet(url, "") r, err := c.DoAPIGet(url, "")

View File

@ -11,8 +11,6 @@ const (
EventTypeSendAdminWelcomeEmail = "send-admin-welcome-email" EventTypeSendAdminWelcomeEmail = "send-admin-welcome-email"
EventTypeTrialWillEnd = "trial-will-end" EventTypeTrialWillEnd = "trial-will-end"
EventTypeTrialEnded = "trial-ended" EventTypeTrialEnded = "trial-ended"
JoinLimitation = "join"
InviteLimitation = "invite"
) )
var MockCWS string var MockCWS string
@ -180,12 +178,6 @@ type FailedPayment struct {
type CloudWorkspaceOwner struct { type CloudWorkspaceOwner struct {
UserName string `json:"username"` UserName string `json:"username"`
} }
type SubscriptionStats struct {
RemainingSeats int `json:"remaining_seats"`
IsPaidTier string `json:"is_paid_tier"`
IsFreeTrial string `json:"is_free_trial"`
}
type SubscriptionChange struct { type SubscriptionChange struct {
ProductID string `json:"product_id"` ProductID string `json:"product_id"`
} }

View File

@ -26,6 +26,7 @@ const (
ClusterEventInvalidateCacheForWebhooks ClusterEvent = "inv_webhooks" ClusterEventInvalidateCacheForWebhooks ClusterEvent = "inv_webhooks"
ClusterEventInvalidateCacheForEmojisById ClusterEvent = "inv_emojis_by_id" ClusterEventInvalidateCacheForEmojisById ClusterEvent = "inv_emojis_by_id"
ClusterEventInvalidateCacheForEmojisIdByName ClusterEvent = "inv_emojis_id_by_name" ClusterEventInvalidateCacheForEmojisIdByName ClusterEvent = "inv_emojis_id_by_name"
ClusterEventInvalidateCacheForChannelFileCount ClusterEvent = "inv_channel_file_count"
ClusterEventInvalidateCacheForChannelPinnedpostsCounts ClusterEvent = "inv_channel_pinnedposts_counts" ClusterEventInvalidateCacheForChannelPinnedpostsCounts ClusterEvent = "inv_channel_pinnedposts_counts"
ClusterEventInvalidateCacheForChannelMemberCounts ClusterEvent = "inv_channel_member_counts" ClusterEventInvalidateCacheForChannelMemberCounts ClusterEvent = "inv_channel_member_counts"
ClusterEventInvalidateCacheForLastPosts ClusterEvent = "inv_last_posts" ClusterEventInvalidateCacheForLastPosts ClusterEvent = "inv_last_posts"

View File

@ -184,24 +184,24 @@ const (
TeamSettingsDefaultTeamText = "default" TeamSettingsDefaultTeamText = "default"
ElasticsearchSettingsDefaultConnectionURL = "http://localhost:9200" ElasticsearchSettingsDefaultConnectionURL = "http://localhost:9200"
ElasticsearchSettingsDefaultUsername = "elastic" ElasticsearchSettingsDefaultUsername = "elastic"
ElasticsearchSettingsDefaultPassword = "changeme" ElasticsearchSettingsDefaultPassword = "changeme"
ElasticsearchSettingsDefaultPostIndexReplicas = 1 ElasticsearchSettingsDefaultPostIndexReplicas = 1
ElasticsearchSettingsDefaultPostIndexShards = 1 ElasticsearchSettingsDefaultPostIndexShards = 1
ElasticsearchSettingsDefaultChannelIndexReplicas = 1 ElasticsearchSettingsDefaultChannelIndexReplicas = 1
ElasticsearchSettingsDefaultChannelIndexShards = 1 ElasticsearchSettingsDefaultChannelIndexShards = 1
ElasticsearchSettingsDefaultUserIndexReplicas = 1 ElasticsearchSettingsDefaultUserIndexReplicas = 1
ElasticsearchSettingsDefaultUserIndexShards = 1 ElasticsearchSettingsDefaultUserIndexShards = 1
ElasticsearchSettingsDefaultAggregatePostsAfterDays = 365 ElasticsearchSettingsDefaultAggregatePostsAfterDays = 365
ElasticsearchSettingsDefaultPostsAggregatorJobStartTime = "03:00" ElasticsearchSettingsDefaultPostsAggregatorJobStartTime = "03:00"
ElasticsearchSettingsDefaultIndexPrefix = "" ElasticsearchSettingsDefaultIndexPrefix = ""
ElasticsearchSettingsDefaultLiveIndexingBatchSize = 1 ElasticsearchSettingsDefaultLiveIndexingBatchSize = 1
ElasticsearchSettingsDefaultBulkIndexingTimeWindowSeconds = 3600 ElasticsearchSettingsDefaultRequestTimeoutSeconds = 30
ElasticsearchSettingsDefaultRequestTimeoutSeconds = 30 ElasticsearchSettingsDefaultBatchSize = 10000
BleveSettingsDefaultIndexDir = "" BleveSettingsDefaultIndexDir = ""
BleveSettingsDefaultBulkIndexingTimeWindowSeconds = 3600 BleveSettingsDefaultBatchSize = 10000
DataRetentionSettingsDefaultMessageRetentionDays = 365 DataRetentionSettingsDefaultMessageRetentionDays = 365
DataRetentionSettingsDefaultFileRetentionDays = 365 DataRetentionSettingsDefaultFileRetentionDays = 365
@ -275,15 +275,16 @@ var ServerTLSSupportedCiphers = map[string]uint16{
} }
type ServiceSettings struct { type ServiceSettings struct {
SiteURL *string `access:"environment_web_server,authentication_saml,write_restrictable"` SiteURL *string `access:"environment_web_server,authentication_saml,write_restrictable"`
WebsocketURL *string `access:"write_restrictable,cloud_restrictable"` WebsocketURL *string `access:"write_restrictable,cloud_restrictable"`
LicenseFileLocation *string `access:"write_restrictable,cloud_restrictable"` // telemetry: none LicenseFileLocation *string `access:"write_restrictable,cloud_restrictable"` // telemetry: none
ListenAddress *string `access:"environment_web_server,write_restrictable,cloud_restrictable"` // telemetry: none ListenAddress *string `access:"environment_web_server,write_restrictable,cloud_restrictable"` // telemetry: none
ConnectionSecurity *string `access:"environment_web_server,write_restrictable,cloud_restrictable"` ConnectionSecurity *string `access:"environment_web_server,write_restrictable,cloud_restrictable"`
TLSCertFile *string `access:"environment_web_server,write_restrictable,cloud_restrictable"` TLSCertFile *string `access:"environment_web_server,write_restrictable,cloud_restrictable"`
TLSKeyFile *string `access:"environment_web_server,write_restrictable,cloud_restrictable"` TLSKeyFile *string `access:"environment_web_server,write_restrictable,cloud_restrictable"`
TLSMinVer *string `access:"write_restrictable,cloud_restrictable"` // telemetry: none TLSMinVer *string `access:"write_restrictable,cloud_restrictable"` // telemetry: none
TLSStrictTransport *bool `access:"write_restrictable,cloud_restrictable"` TLSStrictTransport *bool `access:"write_restrictable,cloud_restrictable"`
// In seconds.
TLSStrictTransportMaxAge *int64 `access:"write_restrictable,cloud_restrictable"` // telemetry: none TLSStrictTransportMaxAge *int64 `access:"write_restrictable,cloud_restrictable"` // telemetry: none
TLSOverwriteCiphers []string `access:"write_restrictable,cloud_restrictable"` // telemetry: none TLSOverwriteCiphers []string `access:"write_restrictable,cloud_restrictable"` // telemetry: none
UseLetsEncrypt *bool `access:"environment_web_server,write_restrictable,cloud_restrictable"` UseLetsEncrypt *bool `access:"environment_web_server,write_restrictable,cloud_restrictable"`
@ -904,7 +905,6 @@ type ExperimentalSettings struct {
LinkMetadataTimeoutMilliseconds *int64 `access:"experimental_features,write_restrictable,cloud_restrictable"` LinkMetadataTimeoutMilliseconds *int64 `access:"experimental_features,write_restrictable,cloud_restrictable"`
RestrictSystemAdmin *bool `access:"experimental_features,write_restrictable"` RestrictSystemAdmin *bool `access:"experimental_features,write_restrictable"`
UseNewSAMLLibrary *bool `access:"experimental_features,cloud_restrictable"` UseNewSAMLLibrary *bool `access:"experimental_features,cloud_restrictable"`
CloudUserLimit *int64 `access:"experimental_features,write_restrictable"`
CloudBilling *bool `access:"experimental_features,write_restrictable"` CloudBilling *bool `access:"experimental_features,write_restrictable"`
EnableSharedChannels *bool `access:"experimental_features"` EnableSharedChannels *bool `access:"experimental_features"`
EnableRemoteClusterService *bool `access:"experimental_features"` EnableRemoteClusterService *bool `access:"experimental_features"`
@ -931,11 +931,6 @@ func (s *ExperimentalSettings) SetDefaults() {
s.RestrictSystemAdmin = NewBool(false) s.RestrictSystemAdmin = NewBool(false)
} }
if s.CloudUserLimit == nil {
// User limit 0 is treated as no limit
s.CloudUserLimit = NewInt64(0)
}
if s.CloudBilling == nil { if s.CloudBilling == nil {
s.CloudBilling = NewBool(false) s.CloudBilling = NewBool(false)
} }
@ -1541,6 +1536,7 @@ type EmailSettings struct {
LoginButtonColor *string `access:"experimental_features"` LoginButtonColor *string `access:"experimental_features"`
LoginButtonBorderColor *string `access:"experimental_features"` LoginButtonBorderColor *string `access:"experimental_features"`
LoginButtonTextColor *string `access:"experimental_features"` LoginButtonTextColor *string `access:"experimental_features"`
EnableInactivityEmail *bool
} }
func (s *EmailSettings) SetDefaults(isUpdate bool) { func (s *EmailSettings) SetDefaults(isUpdate bool) {
@ -1683,6 +1679,10 @@ func (s *EmailSettings) SetDefaults(isUpdate bool) {
if s.LoginButtonTextColor == nil { if s.LoginButtonTextColor == nil {
s.LoginButtonTextColor = NewString("#2389D7") s.LoginButtonTextColor = NewString("#2389D7")
} }
if s.EnableInactivityEmail == nil {
s.EnableInactivityEmail = NewBool(true)
}
} }
type RateLimitSettings struct { type RateLimitSettings struct {
@ -1885,17 +1885,18 @@ func (s *ThemeSettings) SetDefaults() {
} }
type TeamSettings struct { type TeamSettings struct {
SiteName *string `access:"site_customization"` SiteName *string `access:"site_customization"`
MaxUsersPerTeam *int `access:"site_users_and_teams"` MaxUsersPerTeam *int `access:"site_users_and_teams"`
EnableUserCreation *bool `access:"authentication_signup"` EnableUserCreation *bool `access:"authentication_signup"`
EnableOpenServer *bool `access:"authentication_signup"` EnableOpenServer *bool `access:"authentication_signup"`
EnableUserDeactivation *bool `access:"experimental_features"` EnableUserDeactivation *bool `access:"experimental_features"`
RestrictCreationToDomains *string `access:"authentication_signup"` // telemetry: none RestrictCreationToDomains *string `access:"authentication_signup"` // telemetry: none
EnableCustomUserStatuses *bool `access:"site_users_and_teams"` EnableCustomUserStatuses *bool `access:"site_users_and_teams"`
EnableCustomBrand *bool `access:"site_customization"` EnableCustomBrand *bool `access:"site_customization"`
CustomBrandText *string `access:"site_customization"` CustomBrandText *string `access:"site_customization"`
CustomDescriptionText *string `access:"site_customization"` CustomDescriptionText *string `access:"site_customization"`
RestrictDirectMessage *string `access:"site_users_and_teams"` RestrictDirectMessage *string `access:"site_users_and_teams"`
// In seconds.
UserStatusAwayTimeout *int64 `access:"experimental_features"` UserStatusAwayTimeout *int64 `access:"experimental_features"`
MaxChannelsPerTeam *int64 `access:"site_users_and_teams"` MaxChannelsPerTeam *int64 `access:"site_users_and_teams"`
MaxNotificationsPerChannel *int64 `access:"environment_push_notification_server"` MaxNotificationsPerChannel *int64 `access:"environment_push_notification_server"`
@ -2475,7 +2476,8 @@ type ElasticsearchSettings struct {
PostsAggregatorJobStartTime *string `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"` // telemetry: none PostsAggregatorJobStartTime *string `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"` // telemetry: none
IndexPrefix *string `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"` IndexPrefix *string `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"`
LiveIndexingBatchSize *int `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"` LiveIndexingBatchSize *int `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"`
BulkIndexingTimeWindowSeconds *int `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"` BulkIndexingTimeWindowSeconds *int `json:",omitempty"` // telemetry: none
BatchSize *int `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"`
RequestTimeoutSeconds *int `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"` RequestTimeoutSeconds *int `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"`
SkipTLSVerification *bool `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"` SkipTLSVerification *bool `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"`
Trace *string `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"` Trace *string `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"`
@ -2550,8 +2552,8 @@ func (s *ElasticsearchSettings) SetDefaults() {
s.LiveIndexingBatchSize = NewInt(ElasticsearchSettingsDefaultLiveIndexingBatchSize) s.LiveIndexingBatchSize = NewInt(ElasticsearchSettingsDefaultLiveIndexingBatchSize)
} }
if s.BulkIndexingTimeWindowSeconds == nil { if s.BatchSize == nil {
s.BulkIndexingTimeWindowSeconds = NewInt(ElasticsearchSettingsDefaultBulkIndexingTimeWindowSeconds) s.BatchSize = NewInt(ElasticsearchSettingsDefaultBatchSize)
} }
if s.RequestTimeoutSeconds == nil { if s.RequestTimeoutSeconds == nil {
@ -2572,7 +2574,8 @@ type BleveSettings struct {
EnableIndexing *bool `access:"experimental_bleve"` EnableIndexing *bool `access:"experimental_bleve"`
EnableSearching *bool `access:"experimental_bleve"` EnableSearching *bool `access:"experimental_bleve"`
EnableAutocomplete *bool `access:"experimental_bleve"` EnableAutocomplete *bool `access:"experimental_bleve"`
BulkIndexingTimeWindowSeconds *int `access:"experimental_bleve"` BulkIndexingTimeWindowSeconds *int `json:",omitempty"` // telemetry: none
BatchSize *int `access:"experimental_bleve"`
} }
func (bs *BleveSettings) SetDefaults() { func (bs *BleveSettings) SetDefaults() {
@ -2592,8 +2595,8 @@ func (bs *BleveSettings) SetDefaults() {
bs.EnableAutocomplete = NewBool(false) bs.EnableAutocomplete = NewBool(false)
} }
if bs.BulkIndexingTimeWindowSeconds == nil { if bs.BatchSize == nil {
bs.BulkIndexingTimeWindowSeconds = NewInt(BleveSettingsDefaultBulkIndexingTimeWindowSeconds) bs.BatchSize = NewInt(BleveSettingsDefaultBatchSize)
} }
} }
@ -2643,9 +2646,10 @@ func (s *DataRetentionSettings) SetDefaults() {
} }
type JobSettings struct { type JobSettings struct {
RunJobs *bool `access:"write_restrictable,cloud_restrictable"` // telemetry: none RunJobs *bool `access:"write_restrictable,cloud_restrictable"` // telemetry: none
RunScheduler *bool `access:"write_restrictable,cloud_restrictable"` // telemetry: none RunScheduler *bool `access:"write_restrictable,cloud_restrictable"` // telemetry: none
CleanupJobsThresholdDays *int `access:"write_restrictable,cloud_restrictable"` CleanupJobsThresholdDays *int `access:"write_restrictable,cloud_restrictable"`
CleanupConfigThresholdDays *int `access:"write_restrictable,cloud_restrictable"`
} }
func (s *JobSettings) SetDefaults() { func (s *JobSettings) SetDefaults() {
@ -2660,6 +2664,10 @@ func (s *JobSettings) SetDefaults() {
if s.CleanupJobsThresholdDays == nil { if s.CleanupJobsThresholdDays == nil {
s.CleanupJobsThresholdDays = NewInt(-1) s.CleanupJobsThresholdDays = NewInt(-1)
} }
if s.CleanupConfigThresholdDays == nil {
s.CleanupConfigThresholdDays = NewInt(-1)
}
} }
type CloudSettings struct { type CloudSettings struct {
@ -3564,13 +3572,13 @@ func (s *ServiceSettings) isValid() *AppError {
if *s.SiteURL != "" { if *s.SiteURL != "" {
if _, err := url.ParseRequestURI(*s.SiteURL); err != nil { if _, err := url.ParseRequestURI(*s.SiteURL); err != nil {
return NewAppError("Config.IsValid", "model.config.is_valid.site_url.app_error", nil, "", http.StatusBadRequest) return NewAppError("Config.IsValid", "model.config.is_valid.site_url.app_error", nil, err.Error(), http.StatusBadRequest)
} }
} }
if *s.WebsocketURL != "" { if *s.WebsocketURL != "" {
if _, err := url.ParseRequestURI(*s.WebsocketURL); err != nil { if _, err := url.ParseRequestURI(*s.WebsocketURL); err != nil {
return NewAppError("Config.IsValid", "model.config.is_valid.websocket_url.app_error", nil, "", http.StatusBadRequest) return NewAppError("Config.IsValid", "model.config.is_valid.websocket_url.app_error", nil, err.Error(), http.StatusBadRequest)
} }
} }
@ -3632,8 +3640,9 @@ func (s *ElasticsearchSettings) isValid() *AppError {
return NewAppError("Config.IsValid", "model.config.is_valid.elastic_search.live_indexing_batch_size.app_error", nil, "", http.StatusBadRequest) return NewAppError("Config.IsValid", "model.config.is_valid.elastic_search.live_indexing_batch_size.app_error", nil, "", http.StatusBadRequest)
} }
if *s.BulkIndexingTimeWindowSeconds < 1 { minBatchSize := 1
return NewAppError("Config.IsValid", "model.config.is_valid.elastic_search.bulk_indexing_time_window_seconds.app_error", nil, "", http.StatusBadRequest) if *s.BatchSize < minBatchSize {
return NewAppError("Config.IsValid", "model.config.is_valid.elastic_search.bulk_indexing_batch_size.app_error", map[string]interface{}{"BatchSize": minBatchSize}, "", http.StatusBadRequest)
} }
if *s.RequestTimeoutSeconds < 1 { if *s.RequestTimeoutSeconds < 1 {
@ -3656,8 +3665,9 @@ func (bs *BleveSettings) isValid() *AppError {
return NewAppError("Config.IsValid", "model.config.is_valid.bleve_search.enable_autocomplete.app_error", nil, "", http.StatusBadRequest) return NewAppError("Config.IsValid", "model.config.is_valid.bleve_search.enable_autocomplete.app_error", nil, "", http.StatusBadRequest)
} }
} }
if *bs.BulkIndexingTimeWindowSeconds < 1 { minBatchSize := 1
return NewAppError("Config.IsValid", "model.config.is_valid.bleve_search.bulk_indexing_time_window_seconds.app_error", nil, "", http.StatusBadRequest) if *bs.BatchSize < minBatchSize {
return NewAppError("Config.IsValid", "model.config.is_valid.bleve_search.bulk_indexing_batch_size.app_error", map[string]interface{}{"BatchSize": minBatchSize}, "", http.StatusBadRequest)
} }
return nil return nil

View File

@ -13,9 +13,9 @@ type GlobalRetentionPolicy struct {
} }
type RetentionPolicy struct { type RetentionPolicy struct {
ID string `db:"Id" json:"id"` ID string `db:"Id" json:"id"`
DisplayName string `json:"display_name"` DisplayName string `json:"display_name"`
PostDuration *int64 `json:"post_duration"` PostDurationDays *int64 `db:"PostDuration" json:"post_duration"`
} }
type RetentionPolicyWithTeamAndChannelIDs struct { type RetentionPolicyWithTeamAndChannelIDs struct {
@ -46,8 +46,8 @@ type RetentionPolicyWithTeamAndChannelCountsList struct {
} }
type RetentionPolicyForTeam struct { type RetentionPolicyForTeam struct {
TeamID string `db:"Id" json:"team_id"` TeamID string `db:"Id" json:"team_id"`
PostDuration int64 `json:"post_duration"` PostDurationDays int64 `db:"PostDuration" json:"post_duration"`
} }
type RetentionPolicyForTeamList struct { type RetentionPolicyForTeamList struct {
@ -56,8 +56,8 @@ type RetentionPolicyForTeamList struct {
} }
type RetentionPolicyForChannel struct { type RetentionPolicyForChannel struct {
ChannelID string `db:"Id" json:"channel_id"` ChannelID string `db:"Id" json:"channel_id"`
PostDuration int64 `json:"post_duration"` PostDurationDays int64 `db:"PostDuration" json:"post_duration"`
} }
type RetentionPolicyForChannelList struct { type RetentionPolicyForChannelList struct {

View File

@ -16,9 +16,6 @@ type FeatureFlags struct {
// all other values as false. // all other values as false.
TestBoolFeature bool TestBoolFeature bool
// Toggle on and off scheduled jobs for cloud user limit emails see MM-29999
CloudDelinquentEmailJobsEnabled bool
// Toggle on and off support for Collapsed Threads // Toggle on and off support for Collapsed Threads
CollapsedThreads bool CollapsedThreads bool
@ -38,18 +35,12 @@ type FeatureFlags struct {
PermalinkPreviews bool PermalinkPreviews bool
// Determine whether when a user gets created, they'll have noisy notifications e.g. Send desktop notifications for all activity
NewAccountNoisy bool
// Enable Calls plugin support in the mobile app // Enable Calls plugin support in the mobile app
CallsMobile bool CallsMobile bool
// A dash separated list for feature flags to turn on for Boards // A dash separated list for feature flags to turn on for Boards
BoardsFeatureFlags string BoardsFeatureFlags string
// A/B test for the add members to channel button, possible values = ("top", "bottom")
AddMembersToChannel string
// Enable Create First Channel // Enable Create First Channel
GuidedChannelCreation bool GuidedChannelCreation bool
@ -70,12 +61,15 @@ type FeatureFlags struct {
// Enable GraphQL feature // Enable GraphQL feature
GraphQL bool GraphQL bool
InsightsEnabled bool
CommandPalette bool
} }
func (f *FeatureFlags) SetDefaults() { func (f *FeatureFlags) SetDefaults() {
f.TestFeature = "off" f.TestFeature = "off"
f.TestBoolFeature = false f.TestBoolFeature = false
f.CloudDelinquentEmailJobsEnabled = false
f.CollapsedThreads = true f.CollapsedThreads = true
f.EnableRemoteClusterService = false f.EnableRemoteClusterService = false
f.AppsEnabled = true f.AppsEnabled = true
@ -83,10 +77,8 @@ func (f *FeatureFlags) SetDefaults() {
f.PluginApps = "" f.PluginApps = ""
f.PluginFocalboard = "" f.PluginFocalboard = ""
f.PermalinkPreviews = true f.PermalinkPreviews = true
f.NewAccountNoisy = false
f.CallsMobile = false f.CallsMobile = false
f.BoardsFeatureFlags = "" f.BoardsFeatureFlags = ""
f.AddMembersToChannel = "top"
f.GuidedChannelCreation = false f.GuidedChannelCreation = false
f.InviteToTeam = "none" f.InviteToTeam = "none"
f.CustomGroups = true f.CustomGroups = true
@ -95,6 +87,8 @@ func (f *FeatureFlags) SetDefaults() {
f.EnableInactivityCheckJob = true f.EnableInactivityCheckJob = true
f.UseCaseOnboarding = true f.UseCaseOnboarding = true
f.GraphQL = false f.GraphQL = false
f.InsightsEnabled = false
f.CommandPalette = false
} }
func (f *FeatureFlags) Plugins() map[string]string { func (f *FeatureFlags) Plugins() map[string]string {
rFFVal := reflect.ValueOf(f).Elem() rFFVal := reflect.ValueOf(f).Elem()

View File

@ -0,0 +1,76 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
package model
import (
"net/http"
"time"
)
const (
TimeRangeToday string = "today"
TimeRange7Day string = "7_day"
TimeRange28Day string = "28_day"
)
type InsightsOpts struct {
StartUnixMilli int64
Page int
PerPage int
}
type InsightsListData struct {
HasNext bool `json:"has_next"`
}
type InsightsData struct {
Rank int `json:"rank"`
}
type TopReactionList struct {
InsightsListData
Items []*TopReaction `json:"items"`
}
type TopReaction struct {
InsightsData
EmojiName string `json:"emoji_name"`
Count int64 `json:"count"`
}
// GetStartUnixMilliForTimeRange gets the unix start time in milliseconds from the given time range.
// Time range can be one of: "1_day", "7_day", or "28_day".
func GetStartUnixMilliForTimeRange(timeRange string) (int64, *AppError) {
now := time.Now()
_, offset := now.Zone()
switch timeRange {
case TimeRangeToday:
return GetStartOfDayMillis(now, offset), nil
case TimeRange7Day:
return GetStartOfDayMillis(now.Add(time.Hour*time.Duration(-168)), offset), nil
case TimeRange28Day:
return GetStartOfDayMillis(now.Add(time.Hour*time.Duration(-672)), offset), nil
}
return GetStartOfDayMillis(now, offset), NewAppError("Insights.IsValidRequest", "model.insights.time_range.app_error", nil, "", http.StatusBadRequest)
}
// GetTopReactionListWithRankAndPagination adds a rank to each item in the given list of TopReaction and checks if there is
// another page that can be fetched based on the given limit and offset. The given list of TopReaction is assumed to be
// sorted by Count. Returns a TopReactionList.
func GetTopReactionListWithRankAndPagination(reactions []*TopReaction, limit int, offset int) *TopReactionList {
// Add pagination support
var hasNext bool
if (limit != 0) && (len(reactions) == limit+1) {
hasNext = true
reactions = reactions[:len(reactions)-1]
}
// Assign rank to each reaction
for i, reaction := range reactions {
reaction.Rank = offset + i + 1
}
return &TopReactionList{InsightsListData: InsightsListData{HasNext: hasNext}, Items: reactions}
}

View File

@ -11,9 +11,12 @@ import (
) )
const ( const (
DayInSeconds = 24 * 60 * 60
DayInMilliseconds = DayInSeconds * 1000
ExpiredLicenseError = "api.license.add_license.expired.app_error" ExpiredLicenseError = "api.license.add_license.expired.app_error"
InvalidLicenseError = "api.license.add_license.invalid.app_error" InvalidLicenseError = "api.license.add_license.invalid.app_error"
LicenseGracePeriod = 1000 * 60 * 60 * 24 * 10 //10 days LicenseGracePeriod = DayInMilliseconds * 10 //10 days
LicenseRenewalLink = "https://mattermost.com/renew/" LicenseRenewalLink = "https://mattermost.com/renew/"
LicenseShortSkuE10 = "E10" LicenseShortSkuE10 = "E10"
@ -307,7 +310,7 @@ func (l *License) HasEnterpriseMarketplacePlugins() bool {
// NewTestLicense returns a license that expires in the future and has the given features. // NewTestLicense returns a license that expires in the future and has the given features.
func NewTestLicense(features ...string) *License { func NewTestLicense(features ...string) *License {
ret := &License{ ret := &License{
ExpiresAt: GetMillis() + 90*24*60*60*1000, ExpiresAt: GetMillis() + 90*DayInMilliseconds,
Customer: &Customer{}, Customer: &Customer{},
Features: &Features{}, Features: &Features{},
} }

View File

@ -0,0 +1,49 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
package model
import (
"encoding/json"
"net/http"
)
type MemberInvite struct {
Emails []string `json:"emails"`
ChannelIds []string `json:"channelIds,omitempty"`
Message string `json:"message"`
}
// IsValid validates that the invitation info is loaded correctly and with the correct structure
func (i *MemberInvite) IsValid() *AppError {
if len(i.Emails) == 0 {
return NewAppError("MemberInvite.IsValid", "model.member.is_valid.emails.app_error", nil, "", http.StatusBadRequest)
}
if len(i.ChannelIds) > 0 {
for _, channel := range i.ChannelIds {
if len(channel) != 26 {
return NewAppError("MemberInvite.IsValid", "model.member.is_valid.channel.app_error", nil, "channel="+channel, http.StatusBadRequest)
}
}
}
return nil
}
func (i *MemberInvite) UnmarshalJSON(b []byte) error {
var emails []string
if err := json.Unmarshal(b, &emails); err == nil {
*i = MemberInvite{}
i.Emails = emails
return nil
}
type TempMemberInvite MemberInvite
var o2 TempMemberInvite
if err := json.Unmarshal(b, &o2); err != nil {
return err
}
*i = MemberInvite(o2)
return nil
}

View File

@ -8,10 +8,12 @@ type Permalink struct {
} }
type PreviewPost struct { type PreviewPost struct {
PostID string `json:"post_id"` PostID string `json:"post_id"`
Post *Post `json:"post"` Post *Post `json:"post"`
TeamName string `json:"team_name"` TeamName string `json:"team_name"`
ChannelDisplayName string `json:"channel_display_name"` ChannelDisplayName string `json:"channel_display_name"`
ChannelType ChannelType `json:"channel_type"`
ChannelID string `json:"channel_id"`
} }
func NewPreviewPost(post *Post, team *Team, channel *Channel) *PreviewPost { func NewPreviewPost(post *Post, team *Team, channel *Channel) *PreviewPost {
@ -23,5 +25,7 @@ func NewPreviewPost(post *Post, team *Team, channel *Channel) *PreviewPost {
Post: post, Post: post,
TeamName: team.Name, TeamName: team.Name,
ChannelDisplayName: channel.DisplayName, ChannelDisplayName: channel.DisplayName,
ChannelType: channel.Type,
ChannelID: channel.Id,
} }
} }

View File

@ -263,6 +263,9 @@ type GetPostsOptions struct {
SkipFetchThreads bool SkipFetchThreads bool
CollapsedThreads bool CollapsedThreads bool
CollapsedThreadsExtended bool CollapsedThreadsExtended bool
FromPost string // PostId after which to send the items
FromCreateAt int64 // CreateAt after which to send the items
Direction string // Only accepts up|down. Indicates the order in which to send the items.
} }
func (o *Post) Etag() string { func (o *Post) Etag() string {

View File

@ -14,6 +14,8 @@ type PostList struct {
Posts map[string]*Post `json:"posts"` Posts map[string]*Post `json:"posts"`
NextPostId string `json:"next_post_id"` NextPostId string `json:"next_post_id"`
PrevPostId string `json:"prev_post_id"` PrevPostId string `json:"prev_post_id"`
// HasNext indicates whether there are more items to be fetched or not.
HasNext bool `json:"has_next"`
} }
func NewPostList() *PostList { func NewPostList() *PostList {
@ -39,6 +41,7 @@ func (o *PostList) Clone() *PostList {
Posts: postsCopy, Posts: postsCopy,
NextPostId: o.NextPostId, NextPostId: o.NextPostId,
PrevPostId: o.PrevPostId, PrevPostId: o.PrevPostId,
HasNext: o.HasNext,
} }
} }

View File

@ -51,7 +51,7 @@ func (sc *SharedChannel) IsValid() *AppError {
} }
if !IsValidChannelIdentifier(sc.ShareName) { if !IsValidChannelIdentifier(sc.ShareName) {
return NewAppError("SharedChannel.IsValid", "model.channel.is_valid.2_or_more.app_error", nil, "id="+sc.ChannelId, http.StatusBadRequest) return NewAppError("SharedChannel.IsValid", "model.channel.is_valid.1_or_more.app_error", nil, "id="+sc.ChannelId, http.StatusBadRequest)
} }
if utf8.RuneCountInString(sc.ShareHeader) > ChannelHeaderMaxRunes { if utf8.RuneCountInString(sc.ShareHeader) > ChannelHeaderMaxRunes {

View File

@ -12,7 +12,6 @@ const (
SystemRanUnitTests = "RanUnitTests" SystemRanUnitTests = "RanUnitTests"
SystemLastSecurityTime = "LastSecurityTime" SystemLastSecurityTime = "LastSecurityTime"
SystemActiveLicenseId = "ActiveLicenseId" SystemActiveLicenseId = "ActiveLicenseId"
SystemLicenseRenewalToken = "LicenseRenewalToken"
SystemLastComplianceTime = "LastComplianceTime" SystemLastComplianceTime = "LastComplianceTime"
SystemAsymmetricSigningKeyKey = "AsymmetricSigningKey" SystemAsymmetricSigningKeyKey = "AsymmetricSigningKey"
SystemPostActionCookieSecretKey = "PostActionCookieSecret" SystemPostActionCookieSecretKey = "PostActionCookieSecret"
@ -34,9 +33,6 @@ const (
SystemFirstAdminSetupComplete = "FirstAdminSetupComplete" SystemFirstAdminSetupComplete = "FirstAdminSetupComplete"
AwsMeteringReportInterval = 1 AwsMeteringReportInterval = 1
AwsMeteringDimensionUsageHrs = "UsageHrs" AwsMeteringDimensionUsageHrs = "UsageHrs"
UserLimitOverageCycleEndDate = "UserLimitOverageCycleEndDate"
OverUserLimitForgivenCount = "OverUserLimitForgivenCount"
OverUserLimitLastEmailSent = "OverUserLimitLastEmailSent"
) )
const ( const (

View File

@ -252,6 +252,12 @@ func (o *Team) IsGroupConstrained() bool {
return o.GroupConstrained != nil && *o.GroupConstrained return o.GroupConstrained != nil && *o.GroupConstrained
} }
// ShallowCopy returns a shallow copy of team.
func (o *Team) ShallowCopy() *Team {
c := *o
return &c
}
// The following are some GraphQL methods necessary to return the // The following are some GraphQL methods necessary to return the
// data in float64 type. The spec doesn't support 64 bit integers, // data in float64 type. The spec doesn't support 64 bit integers,
// so we have to pass the data in float64. The _ at the end is // so we have to pass the data in float64. The _ at the end is

View File

@ -67,6 +67,9 @@ type GetUserThreadsOpts struct {
// TotalsOnly will not fetch any threads and just fetch the total counts // TotalsOnly will not fetch any threads and just fetch the total counts
TotalsOnly bool TotalsOnly bool
// ThreadsOnly will fetch threads but not calculate totals and will return 0
ThreadsOnly bool
// TeamOnly will only fetch threads and unreads for the specified team and excludes DMs/GMs // TeamOnly will only fetch threads and unreads for the specified team and excludes DMs/GMs
TeamOnly bool TeamOnly bool
} }

View File

@ -33,6 +33,7 @@ const (
UppercaseLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" UppercaseLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
NUMBERS = "0123456789" NUMBERS = "0123456789"
SYMBOLS = " !\"\\#$%&'()*+,-./:;<=>?@[]^_`|~" SYMBOLS = " !\"\\#$%&'()*+,-./:;<=>?@[]^_`|~"
BinaryParamKey = "MM_BINARY_PARAMETERS"
) )
type StringInterface map[string]interface{} type StringInterface map[string]interface{}
@ -124,12 +125,19 @@ func (m *StringMap) Scan(value interface{}) error {
// Value converts StringMap to database value // Value converts StringMap to database value
func (m StringMap) Value() (driver.Value, error) { func (m StringMap) Value() (driver.Value, error) {
j, err := json.Marshal(m) ok := m[BinaryParamKey]
delete(m, BinaryParamKey)
buf, err := json.Marshal(m)
if err != nil { if err != nil {
return nil, err return nil, err
} }
// non utf8 characters are not supported https://mattermost.atlassian.net/browse/MM-41066 if ok == "true" {
return string(j), err return append([]byte{0x01}, buf...), nil
} else if ok == "false" {
return buf, nil
}
// Key wasn't found. We fall back to the default case.
return string(buf), nil
} }
func (StringMap) ImplementsGraphQLType(name string) bool { func (StringMap) ImplementsGraphQLType(name string) bool {
@ -502,21 +510,13 @@ var reservedName = []string{
} }
func IsValidChannelIdentifier(s string) bool { func IsValidChannelIdentifier(s string) bool {
return validSimpleAlphaNum.MatchString(s) && len(s) >= ChannelNameMinLength
if !IsValidAlphaNumHyphenUnderscore(s, true) {
return false
}
if len(s) < ChannelNameMinLength {
return false
}
return true
} }
var ( var (
validAlphaNum = regexp.MustCompile(`^[a-z0-9]+([a-z\-0-9]+|(__)?)[a-z0-9]+$`) validAlphaNum = regexp.MustCompile(`^[a-z0-9]+([a-z\-0-9]+|(__)?)[a-z0-9]+$`)
validAlphaNumHyphenUnderscore = regexp.MustCompile(`^[a-z0-9]+([a-z\-\_0-9]+|(__)?)[a-z0-9]+$`) validAlphaNumHyphenUnderscore = regexp.MustCompile(`^[a-z0-9]+([a-z\-\_0-9]+|(__)?)[a-z0-9]+$`)
validSimpleAlphaNum = regexp.MustCompile(`^[a-z0-9]+([a-z\-\_0-9]+|(__)?)[a-z0-9]*$`)
validSimpleAlphaNumHyphenUnderscore = regexp.MustCompile(`^[a-zA-Z0-9\-_]+$`) validSimpleAlphaNumHyphenUnderscore = regexp.MustCompile(`^[a-zA-Z0-9\-_]+$`)
validSimpleAlphaNumHyphenUnderscorePlus = regexp.MustCompile(`^[a-zA-Z0-9+_-]+$`) validSimpleAlphaNumHyphenUnderscorePlus = regexp.MustCompile(`^[a-zA-Z0-9+_-]+$`)
) )

View File

@ -13,7 +13,7 @@ import (
// It should be maintained in chronological order with most current // It should be maintained in chronological order with most current
// release at the front of the list. // release at the front of the list.
var versions = []string{ var versions = []string{
"6.6.1", "6.7.0",
"6.6.0", "6.6.0",
"6.5.0", "6.5.0",
"6.4.0", "6.4.0",

View File

@ -297,7 +297,7 @@ func (b *S3FileBackend) MoveFile(oldPath, newPath string) error {
} }
if _, err := b.client.CopyObject(context.Background(), dstOpts, srcOpts); err != nil { if _, err := b.client.CopyObject(context.Background(), dstOpts, srcOpts); err != nil {
return errors.Wrapf(err, "unable to copy the file to %s to the new destionation", newPath) return errors.Wrapf(err, "unable to copy the file to %s to the new destination", newPath)
} }
if err := b.client.RemoveObject(context.Background(), b.bucket, oldPath, s3.RemoveObjectOptions{}); err != nil { if err := b.client.RemoveObject(context.Background(), b.bucket, oldPath, s3.RemoveObjectOptions{}); err != nil {

View File

@ -9,7 +9,7 @@ checks: lint vet test examples functional-test
lint: lint:
@mkdir -p ${GOPATH}/bin @mkdir -p ${GOPATH}/bin
@echo "Installing golangci-lint" && curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(GOPATH)/bin v1.40.1 @echo "Installing golangci-lint" && curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(GOPATH)/bin v1.45.2
@echo "Running $@ check" @echo "Running $@ check"
@GO111MODULE=on ${GOPATH}/bin/golangci-lint cache clean @GO111MODULE=on ${GOPATH}/bin/golangci-lint cache clean
@GO111MODULE=on ${GOPATH}/bin/golangci-lint run --timeout=5m --config ./.golangci.yml @GO111MODULE=on ${GOPATH}/bin/golangci-lint run --timeout=5m --config ./.golangci.yml

View File

@ -103,7 +103,6 @@ func (c *Client) getBucketNotification(ctx context.Context, bucketName string) (
return notification.Configuration{}, err return notification.Configuration{}, err
} }
return processBucketNotificationResponse(bucketName, resp) return processBucketNotificationResponse(bucketName, resp)
} }
// processes the GetNotification http response from the server. // processes the GetNotification http response from the server.
@ -207,7 +206,7 @@ func (c *Client) ListenBucketNotification(ctx context.Context, bucketName, prefi
// Use a higher buffer to support unexpected // Use a higher buffer to support unexpected
// caching done by proxies // caching done by proxies
bio.Buffer(notificationEventBuffer, notificationCapacity) bio.Buffer(notificationEventBuffer, notificationCapacity)
var json = jsoniter.ConfigCompatibleWithStandardLibrary json := jsoniter.ConfigCompatibleWithStandardLibrary
// Unmarshal each line, returns marshaled values. // Unmarshal each line, returns marshaled values.
for bio.Scan() { for bio.Scan() {

View File

@ -202,8 +202,8 @@ func (opts CopySrcOptions) validate() (err error) {
// Low level implementation of CopyObject API, supports only upto 5GiB worth of copy. // Low level implementation of CopyObject API, supports only upto 5GiB worth of copy.
func (c *Client) copyObjectDo(ctx context.Context, srcBucket, srcObject, destBucket, destObject string, func (c *Client) copyObjectDo(ctx context.Context, srcBucket, srcObject, destBucket, destObject string,
metadata map[string]string, srcOpts CopySrcOptions, dstOpts PutObjectOptions) (ObjectInfo, error) { metadata map[string]string, srcOpts CopySrcOptions, dstOpts PutObjectOptions,
) (ObjectInfo, error) {
// Build headers. // Build headers.
headers := make(http.Header) headers := make(http.Header)
@ -285,8 +285,8 @@ func (c *Client) copyObjectDo(ctx context.Context, srcBucket, srcObject, destBuc
} }
func (c *Client) copyObjectPartDo(ctx context.Context, srcBucket, srcObject, destBucket, destObject string, uploadID string, func (c *Client) copyObjectPartDo(ctx context.Context, srcBucket, srcObject, destBucket, destObject string, uploadID string,
partID int, startOffset int64, length int64, metadata map[string]string) (p CompletePart, err error) { partID int, startOffset int64, length int64, metadata map[string]string,
) (p CompletePart, err error) {
headers := make(http.Header) headers := make(http.Header)
// Set source // Set source
@ -338,8 +338,8 @@ func (c *Client) copyObjectPartDo(ctx context.Context, srcBucket, srcObject, des
// upload via an upload-part-copy request // upload via an upload-part-copy request
// https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadUploadPartCopy.html // https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadUploadPartCopy.html
func (c *Client) uploadPartCopy(ctx context.Context, bucket, object, uploadID string, partNumber int, func (c *Client) uploadPartCopy(ctx context.Context, bucket, object, uploadID string, partNumber int,
headers http.Header) (p CompletePart, err error) { headers http.Header,
) (p CompletePart, err error) {
// Build query parameters // Build query parameters
urlValues := make(url.Values) urlValues := make(url.Values)
urlValues.Set("partNumber", strconv.Itoa(partNumber)) urlValues.Set("partNumber", strconv.Itoa(partNumber))
@ -492,7 +492,7 @@ func (c *Client) ComposeObject(ctx context.Context, dst CopyDestOptions, srcs ..
objParts := []CompletePart{} objParts := []CompletePart{}
partIndex := 1 partIndex := 1
for i, src := range srcs { for i, src := range srcs {
var h = make(http.Header) h := make(http.Header)
src.Marshal(h) src.Marshal(h)
if dst.Encryption != nil && dst.Encryption.Type() == encrypt.SSEC { if dst.Encryption != nil && dst.Encryption.Type() == encrypt.SSEC {
dst.Encryption.Marshal(h) dst.Encryption.Marshal(h)

View File

@ -57,7 +57,7 @@ func (c *Client) FGetObject(ctx context.Context, bucketName, objectName, filePat
objectDir, _ := filepath.Split(filePath) objectDir, _ := filepath.Split(filePath)
if objectDir != "" { if objectDir != "" {
// Create any missing top level directories. // Create any missing top level directories.
if err := os.MkdirAll(objectDir, 0700); err != nil { if err := os.MkdirAll(objectDir, 0o700); err != nil {
return err return err
} }
} }
@ -72,7 +72,7 @@ func (c *Client) FGetObject(ctx context.Context, bucketName, objectName, filePat
filePartPath := filePath + objectStat.ETag + ".part.minio" filePartPath := filePath + objectStat.ETag + ".part.minio"
// If exists, open in append mode. If not create it as a part file. // If exists, open in append mode. If not create it as a part file.
filePart, err := os.OpenFile(filePartPath, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0600) filePart, err := os.OpenFile(filePartPath, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0o600)
if err != nil { if err != nil {
return err return err
} }

View File

@ -774,7 +774,6 @@ func (c *Client) listIncompleteUploads(ctx context.Context, bucketName, objectPr
}(objectMultipartStatCh) }(objectMultipartStatCh)
// return. // return.
return objectMultipartStatCh return objectMultipartStatCh
} }
// listMultipartUploadsQuery - (List Multipart Uploads). // listMultipartUploadsQuery - (List Multipart Uploads).

View File

@ -38,7 +38,8 @@ import (
) )
func (c *Client) putObjectMultipart(ctx context.Context, bucketName, objectName string, reader io.Reader, size int64, func (c *Client) putObjectMultipart(ctx context.Context, bucketName, objectName string, reader io.Reader, size int64,
opts PutObjectOptions) (info UploadInfo, err error) { opts PutObjectOptions,
) (info UploadInfo, err error) {
info, err = c.putObjectMultipartNoStream(ctx, bucketName, objectName, reader, opts) info, err = c.putObjectMultipartNoStream(ctx, bucketName, objectName, reader, opts)
if err != nil { if err != nil {
errResp := ToErrorResponse(err) errResp := ToErrorResponse(err)
@ -240,7 +241,8 @@ func (c *Client) initiateMultipartUpload(ctx context.Context, bucketName, object
// uploadPart - Uploads a part in a multipart upload. // uploadPart - Uploads a part in a multipart upload.
func (c *Client) uploadPart(ctx context.Context, bucketName, objectName, uploadID string, reader io.Reader, func (c *Client) uploadPart(ctx context.Context, bucketName, objectName, uploadID string, reader io.Reader,
partNumber int, md5Base64, sha256Hex string, size int64, sse encrypt.ServerSide) (ObjectPart, error) { partNumber int, md5Base64, sha256Hex string, size int64, sse encrypt.ServerSide,
) (ObjectPart, error) {
// Input validation. // Input validation.
if err := s3utils.CheckValidBucketName(bucketName); err != nil { if err := s3utils.CheckValidBucketName(bucketName); err != nil {
return ObjectPart{}, err return ObjectPart{}, err
@ -311,7 +313,8 @@ func (c *Client) uploadPart(ctx context.Context, bucketName, objectName, uploadI
// completeMultipartUpload - Completes a multipart upload by assembling previously uploaded parts. // completeMultipartUpload - Completes a multipart upload by assembling previously uploaded parts.
func (c *Client) completeMultipartUpload(ctx context.Context, bucketName, objectName, uploadID string, func (c *Client) completeMultipartUpload(ctx context.Context, bucketName, objectName, uploadID string,
complete completeMultipartUpload, opts PutObjectOptions) (UploadInfo, error) { complete completeMultipartUpload, opts PutObjectOptions,
) (UploadInfo, error) {
// Input validation. // Input validation.
if err := s3utils.CheckValidBucketName(bucketName); err != nil { if err := s3utils.CheckValidBucketName(bucketName); err != nil {
return UploadInfo{}, err return UploadInfo{}, err
@ -392,5 +395,4 @@ func (c *Client) completeMultipartUpload(ctx context.Context, bucketName, object
Expiration: expTime, Expiration: expTime,
ExpirationRuleID: ruleID, ExpirationRuleID: ruleID,
}, nil }, nil
} }

View File

@ -42,8 +42,8 @@ import (
// - Any reader which has a method 'ReadAt()' // - Any reader which has a method 'ReadAt()'
// //
func (c *Client) putObjectMultipartStream(ctx context.Context, bucketName, objectName string, func (c *Client) putObjectMultipartStream(ctx context.Context, bucketName, objectName string,
reader io.Reader, size int64, opts PutObjectOptions) (info UploadInfo, err error) { reader io.Reader, size int64, opts PutObjectOptions,
) (info UploadInfo, err error) {
if !isObject(reader) && isReadAt(reader) && !opts.SendContentMd5 { if !isObject(reader) && isReadAt(reader) && !opts.SendContentMd5 {
// Verify if the reader implements ReadAt and it is not a *minio.Object then we will use parallel uploader. // Verify if the reader implements ReadAt and it is not a *minio.Object then we will use parallel uploader.
info, err = c.putObjectMultipartStreamFromReadAt(ctx, bucketName, objectName, reader.(io.ReaderAt), size, opts) info, err = c.putObjectMultipartStreamFromReadAt(ctx, bucketName, objectName, reader.(io.ReaderAt), size, opts)
@ -91,7 +91,8 @@ type uploadPartReq struct {
// cleaned automatically when the caller i.e http client closes the // cleaned automatically when the caller i.e http client closes the
// stream after uploading all the contents successfully. // stream after uploading all the contents successfully.
func (c *Client) putObjectMultipartStreamFromReadAt(ctx context.Context, bucketName, objectName string, func (c *Client) putObjectMultipartStreamFromReadAt(ctx context.Context, bucketName, objectName string,
reader io.ReaderAt, size int64, opts PutObjectOptions) (info UploadInfo, err error) { reader io.ReaderAt, size int64, opts PutObjectOptions,
) (info UploadInfo, err error) {
// Input validation. // Input validation.
if err = s3utils.CheckValidBucketName(bucketName); err != nil { if err = s3utils.CheckValidBucketName(bucketName); err != nil {
return UploadInfo{}, err return UploadInfo{}, err
@ -147,7 +148,7 @@ func (c *Client) putObjectMultipartStreamFromReadAt(ctx context.Context, bucketN
} }
close(uploadPartsCh) close(uploadPartsCh)
var partsBuf = make([][]byte, opts.getNumThreads()) partsBuf := make([][]byte, opts.getNumThreads())
for i := range partsBuf { for i := range partsBuf {
partsBuf[i] = make([]byte, 0, partSize) partsBuf[i] = make([]byte, 0, partSize)
} }
@ -171,7 +172,7 @@ func (c *Client) putObjectMultipartStreamFromReadAt(ctx context.Context, bucketN
} }
n, rerr := readFull(io.NewSectionReader(reader, readOffset, partSize), partsBuf[w-1][:partSize]) n, rerr := readFull(io.NewSectionReader(reader, readOffset, partSize), partsBuf[w-1][:partSize])
if rerr != nil && rerr != io.ErrUnexpectedEOF && err != io.EOF { if rerr != nil && rerr != io.ErrUnexpectedEOF && rerr != io.EOF {
uploadedPartsCh <- uploadedPartRes{ uploadedPartsCh <- uploadedPartRes{
Error: rerr, Error: rerr,
} }
@ -241,7 +242,8 @@ func (c *Client) putObjectMultipartStreamFromReadAt(ctx context.Context, bucketN
} }
func (c *Client) putObjectMultipartStreamOptionalChecksum(ctx context.Context, bucketName, objectName string, func (c *Client) putObjectMultipartStreamOptionalChecksum(ctx context.Context, bucketName, objectName string,
reader io.Reader, size int64, opts PutObjectOptions) (info UploadInfo, err error) { reader io.Reader, size int64, opts PutObjectOptions,
) (info UploadInfo, err error) {
// Input validation. // Input validation.
if err = s3utils.CheckValidBucketName(bucketName); err != nil { if err = s3utils.CheckValidBucketName(bucketName); err != nil {
return UploadInfo{}, err return UploadInfo{}, err

View File

@ -229,7 +229,8 @@ func (a completedParts) Less(i, j int) bool { return a[i].PartNumber < a[j].Part
// //
// NOTE: Upon errors during upload multipart operation is entirely aborted. // NOTE: Upon errors during upload multipart operation is entirely aborted.
func (c *Client) PutObject(ctx context.Context, bucketName, objectName string, reader io.Reader, objectSize int64, func (c *Client) PutObject(ctx context.Context, bucketName, objectName string, reader io.Reader, objectSize int64,
opts PutObjectOptions) (info UploadInfo, err error) { opts PutObjectOptions,
) (info UploadInfo, err error) {
if objectSize < 0 && opts.DisableMultipart { if objectSize < 0 && opts.DisableMultipart {
return UploadInfo{}, errors.New("object size must be provided with disable multipart upload") return UploadInfo{}, errors.New("object size must be provided with disable multipart upload")
} }

View File

@ -133,7 +133,7 @@ func (c Client) PutObjectsSnowball(ctx context.Context, bucketName string, opts
return f, st.Size(), nil return f, st.Size(), nil
} }
} }
var flush = func() error { return nil } flush := func() error { return nil }
if !opts.Compress { if !opts.Compress {
if !opts.InMemory { if !opts.InMemory {
// Insert buffer for writes. // Insert buffer for writes.

View File

@ -519,7 +519,7 @@ func (s *SelectResults) start(pipeWriter *io.PipeWriter) {
go func() { go func() {
for { for {
var prelude preludeInfo var prelude preludeInfo
var headers = make(http.Header) headers := make(http.Header)
var err error var err error
// Create CRC code // Create CRC code
@ -624,7 +624,7 @@ func (p preludeInfo) PayloadLen() int64 {
// the struct, // the struct,
func processPrelude(prelude io.Reader, crc hash.Hash32) (preludeInfo, error) { func processPrelude(prelude io.Reader, crc hash.Hash32) (preludeInfo, error) {
var err error var err error
var pInfo = preludeInfo{} pInfo := preludeInfo{}
// reads total length of the message (first 4 bytes) // reads total length of the message (first 4 bytes)
pInfo.totalLen, err = extractUint32(prelude) pInfo.totalLen, err = extractUint32(prelude)
@ -752,7 +752,6 @@ func checkCRC(r io.Reader, expect uint32) error {
if msgCRC != expect { if msgCRC != expect {
return fmt.Errorf("Checksum Mismatch, MessageCRC of 0x%X does not equal expected CRC of 0x%X", msgCRC, expect) return fmt.Errorf("Checksum Mismatch, MessageCRC of 0x%X does not equal expected CRC of 0x%X", msgCRC, expect)
} }
return nil return nil
} }

View File

@ -111,7 +111,7 @@ type Options struct {
// Global constants. // Global constants.
const ( const (
libraryName = "minio-go" libraryName = "minio-go"
libraryVersion = "v7.0.23" libraryVersion = "v7.0.24"
) )
// User Agent should always following the below style. // User Agent should always following the below style.
@ -537,7 +537,7 @@ func (c *Client) executeMethod(ctx context.Context, method string, metadata requ
var retryable bool // Indicates if request can be retried. var retryable bool // Indicates if request can be retried.
var bodySeeker io.Seeker // Extracted seeker from io.Reader. var bodySeeker io.Seeker // Extracted seeker from io.Reader.
var reqRetry = MaxRetry // Indicates how many times we can retry the request reqRetry := MaxRetry // Indicates how many times we can retry the request
if metadata.contentBody != nil { if metadata.contentBody != nil {
// Check if body is seekable then it is retryable. // Check if body is seekable then it is retryable.

View File

@ -181,6 +181,9 @@ func (c *Client) getBucketLocationRequest(ctx context.Context, bucketName string
if h, p, err := net.SplitHostPort(targetURL.Host); err == nil { if h, p, err := net.SplitHostPort(targetURL.Host); err == nil {
if targetURL.Scheme == "http" && p == "80" || targetURL.Scheme == "https" && p == "443" { if targetURL.Scheme == "http" && p == "80" || targetURL.Scheme == "https" && p == "443" {
targetURL.Host = h targetURL.Host = h
if ip := net.ParseIP(h); ip != nil && ip.To16() != nil {
targetURL.Host = "[" + h + "]"
}
} }
} }

View File

@ -63,8 +63,8 @@ func (c Core) CopyObject(ctx context.Context, sourceBucket, sourceObject, destBu
// CopyObjectPart - creates a part in a multipart upload by copying (a // CopyObjectPart - creates a part in a multipart upload by copying (a
// part of) an existing object. // part of) an existing object.
func (c Core) CopyObjectPart(ctx context.Context, srcBucket, srcObject, destBucket, destObject string, uploadID string, func (c Core) CopyObjectPart(ctx context.Context, srcBucket, srcObject, destBucket, destObject string, uploadID string,
partID int, startOffset, length int64, metadata map[string]string) (p CompletePart, err error) { partID int, startOffset, length int64, metadata map[string]string,
) (p CompletePart, err error) {
return c.copyObjectPartDo(ctx, srcBucket, srcObject, destBucket, destObject, uploadID, return c.copyObjectPartDo(ctx, srcBucket, srcObject, destBucket, destObject, uploadID,
partID, startOffset, length, metadata) partID, startOffset, length, metadata)
} }

View File

@ -61,6 +61,7 @@ const (
letterIdxMask = 1<<letterIdxBits - 1 // All 1-bits, as many as letterIdxBits letterIdxMask = 1<<letterIdxBits - 1 // All 1-bits, as many as letterIdxBits
letterIdxMax = 63 / letterIdxBits // # of letter indices fitting in 63 bits letterIdxMax = 63 / letterIdxBits // # of letter indices fitting in 63 bits
) )
const ( const (
serverEndpoint = "SERVER_ENDPOINT" serverEndpoint = "SERVER_ENDPOINT"
accessKey = "ACCESS_KEY" accessKey = "ACCESS_KEY"
@ -69,8 +70,7 @@ const (
enableKMS = "ENABLE_KMS" enableKMS = "ENABLE_KMS"
) )
type mintJSONFormatter struct { type mintJSONFormatter struct{}
}
func (f *mintJSONFormatter) Format(entry *log.Entry) ([]byte, error) { func (f *mintJSONFormatter) Format(entry *log.Entry) ([]byte, error) {
data := make(log.Fields, len(entry.Data)) data := make(log.Fields, len(entry.Data))
@ -84,7 +84,7 @@ func (f *mintJSONFormatter) Format(entry *log.Entry) ([]byte, error) {
data[k] = v data[k] = v
} }
} }
var json = jsoniter.ConfigCompatibleWithStandardLibrary json := jsoniter.ConfigCompatibleWithStandardLibrary
serialized, err := json.Marshal(data) serialized, err := json.Marshal(data)
if err != nil { if err != nil {
return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err) return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err)
@ -168,11 +168,15 @@ func failureLog(testName string, function string, args map[string]interface{}, s
var fields log.Fields var fields log.Fields
// log with the fields as per mint // log with the fields as per mint
if err != nil { if err != nil {
fields = log.Fields{"name": "minio-go: " + testName, "function": function, "args": args, fields = log.Fields{
"duration": duration.Nanoseconds() / 1000000, "status": "FAIL", "alert": alert, "message": message, "error": err} "name": "minio-go: " + testName, "function": function, "args": args,
"duration": duration.Nanoseconds() / 1000000, "status": "FAIL", "alert": alert, "message": message, "error": err,
}
} else { } else {
fields = log.Fields{"name": "minio-go: " + testName, "function": function, "args": args, fields = log.Fields{
"duration": duration.Nanoseconds() / 1000000, "status": "FAIL", "alert": alert, "message": message} "name": "minio-go: " + testName, "function": function, "args": args,
"duration": duration.Nanoseconds() / 1000000, "status": "FAIL", "alert": alert, "message": message,
}
} }
return log.WithFields(cleanEmptyEntries(fields)) return log.WithFields(cleanEmptyEntries(fields))
} }
@ -182,8 +186,10 @@ func ignoredLog(testName string, function string, args map[string]interface{}, s
// calculate the test case duration // calculate the test case duration
duration := time.Since(startTime) duration := time.Since(startTime)
// log with the fields as per mint // log with the fields as per mint
fields := log.Fields{"name": "minio-go: " + testName, "function": function, "args": args, fields := log.Fields{
"duration": duration.Nanoseconds() / 1000000, "status": "NA", "alert": strings.Split(alert, " ")[0] + " is NotImplemented"} "name": "minio-go: " + testName, "function": function, "args": args,
"duration": duration.Nanoseconds() / 1000000, "status": "NA", "alert": strings.Split(alert, " ")[0] + " is NotImplemented",
}
return log.WithFields(cleanEmptyEntries(fields)) return log.WithFields(cleanEmptyEntries(fields))
} }
@ -632,7 +638,7 @@ func testPutObjectReadAt() {
defer cleanupBucket(bucketName, c) defer cleanupBucket(bucketName, c)
bufSize := dataFileMap["datafile-129-MB"] bufSize := dataFileMap["datafile-129-MB"]
var reader = getDataReader("datafile-129-MB") reader := getDataReader("datafile-129-MB")
defer reader.Close() defer reader.Close()
// Save the data // Save the data
@ -738,7 +744,7 @@ func testListObjectVersions() {
args["objectName"] = objectName args["objectName"] = objectName
bufSize := dataFileMap["datafile-10-kB"] bufSize := dataFileMap["datafile-10-kB"]
var reader = getDataReader("datafile-10-kB") reader := getDataReader("datafile-10-kB")
_, err = c.PutObject(context.Background(), bucketName, objectName, reader, int64(bufSize), minio.PutObjectOptions{}) _, err = c.PutObject(context.Background(), bucketName, objectName, reader, int64(bufSize), minio.PutObjectOptions{})
if err != nil { if err != nil {
@ -857,7 +863,7 @@ func testStatObjectWithVersioning() {
args["objectName"] = objectName args["objectName"] = objectName
bufSize := dataFileMap["datafile-10-kB"] bufSize := dataFileMap["datafile-10-kB"]
var reader = getDataReader("datafile-10-kB") reader := getDataReader("datafile-10-kB")
_, err = c.PutObject(context.Background(), bucketName, objectName, reader, int64(bufSize), minio.PutObjectOptions{}) _, err = c.PutObject(context.Background(), bucketName, objectName, reader, int64(bufSize), minio.PutObjectOptions{})
if err != nil { if err != nil {
@ -975,7 +981,7 @@ func testGetObjectWithVersioning() {
// Save the contents of datafiles to check with GetObject() reader output later // Save the contents of datafiles to check with GetObject() reader output later
var buffers [][]byte var buffers [][]byte
var testFiles = []string{"datafile-1-b", "datafile-10-kB"} testFiles := []string{"datafile-1-b", "datafile-10-kB"}
for _, testFile := range testFiles { for _, testFile := range testFiles {
r := getDataReader(testFile) r := getDataReader(testFile)
@ -1117,7 +1123,7 @@ func testPutObjectWithVersioning() {
// Save the data concurrently. // Save the data concurrently.
var wg sync.WaitGroup var wg sync.WaitGroup
wg.Add(n) wg.Add(n)
var buffers = make([][]byte, n) buffers := make([][]byte, n)
var errs [n]error var errs [n]error
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
r := newRandomReader(int64((1<<20)*i+i), int64(i)) r := newRandomReader(int64((1<<20)*i+i), int64(i))
@ -1258,7 +1264,7 @@ func testCopyObjectWithVersioning() {
objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "") objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "")
args["objectName"] = objectName args["objectName"] = objectName
var testFiles = []string{"datafile-1-b", "datafile-10-kB"} testFiles := []string{"datafile-1-b", "datafile-10-kB"}
for _, testFile := range testFiles { for _, testFile := range testFiles {
r := getDataReader(testFile) r := getDataReader(testFile)
buf, err := ioutil.ReadAll(r) buf, err := ioutil.ReadAll(r)
@ -1395,7 +1401,7 @@ func testConcurrentCopyObjectWithVersioning() {
objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "") objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "")
args["objectName"] = objectName args["objectName"] = objectName
var testFiles = []string{"datafile-10-kB"} testFiles := []string{"datafile-10-kB"}
for _, testFile := range testFiles { for _, testFile := range testFiles {
r := getDataReader(testFile) r := getDataReader(testFile)
buf, err := ioutil.ReadAll(r) buf, err := ioutil.ReadAll(r)
@ -1556,7 +1562,7 @@ func testComposeObjectWithVersioning() {
args["objectName"] = objectName args["objectName"] = objectName
// var testFiles = []string{"datafile-5-MB", "datafile-10-kB"} // var testFiles = []string{"datafile-5-MB", "datafile-10-kB"}
var testFiles = []string{"datafile-5-MB", "datafile-10-kB"} testFiles := []string{"datafile-5-MB", "datafile-10-kB"}
var testFilesBytes [][]byte var testFilesBytes [][]byte
for _, testFile := range testFiles { for _, testFile := range testFiles {
@ -2036,7 +2042,7 @@ func testPutObjectWithMetadata() {
defer cleanupBucket(bucketName, c) defer cleanupBucket(bucketName, c)
bufSize := dataFileMap["datafile-129-MB"] bufSize := dataFileMap["datafile-129-MB"]
var reader = getDataReader("datafile-129-MB") reader := getDataReader("datafile-129-MB")
defer reader.Close() defer reader.Close()
// Save the data // Save the data
@ -2052,7 +2058,8 @@ func testPutObjectWithMetadata() {
} }
_, err = c.PutObject(context.Background(), bucketName, objectName, reader, int64(bufSize), minio.PutObjectOptions{ _, err = c.PutObject(context.Background(), bucketName, objectName, reader, int64(bufSize), minio.PutObjectOptions{
ContentType: customContentType}) ContentType: customContentType,
})
if err != nil { if err != nil {
logError(testName, function, args, startTime, "", "PutObject failed", err) logError(testName, function, args, startTime, "", "PutObject failed", err)
return return
@ -2282,7 +2289,7 @@ func testGetObjectSeekEnd() {
// Generate 33K of data. // Generate 33K of data.
bufSize := dataFileMap["datafile-33-kB"] bufSize := dataFileMap["datafile-33-kB"]
var reader = getDataReader("datafile-33-kB") reader := getDataReader("datafile-33-kB")
defer reader.Close() defer reader.Close()
// Save the data // Save the data
@ -2404,7 +2411,7 @@ func testGetObjectClosedTwice() {
// Generate 33K of data. // Generate 33K of data.
bufSize := dataFileMap["datafile-33-kB"] bufSize := dataFileMap["datafile-33-kB"]
var reader = getDataReader("datafile-33-kB") reader := getDataReader("datafile-33-kB")
defer reader.Close() defer reader.Close()
// Save the data // Save the data
@ -2807,7 +2814,7 @@ func testFPutObjectMultipart() {
defer cleanupBucket(bucketName, c) defer cleanupBucket(bucketName, c)
// Upload 4 parts to utilize all 3 'workers' in multipart and still have a part to upload. // Upload 4 parts to utilize all 3 'workers' in multipart and still have a part to upload.
var fileName = getMintDataDirFilePath("datafile-129-MB") fileName := getMintDataDirFilePath("datafile-129-MB")
if fileName == "" { if fileName == "" {
// Make a temp file with minPartSize bytes of data. // Make a temp file with minPartSize bytes of data.
file, err := ioutil.TempFile(os.TempDir(), "FPutObjectTest") file, err := ioutil.TempFile(os.TempDir(), "FPutObjectTest")
@ -2916,7 +2923,7 @@ func testFPutObject() {
// Upload 3 parts worth of data to use all 3 of multiparts 'workers' and have an extra part. // Upload 3 parts worth of data to use all 3 of multiparts 'workers' and have an extra part.
// Use different data in part for multipart tests to check parts are uploaded in correct order. // Use different data in part for multipart tests to check parts are uploaded in correct order.
var fName = getMintDataDirFilePath("datafile-129-MB") fName := getMintDataDirFilePath("datafile-129-MB")
if fName == "" { if fName == "" {
// Make a temp file with minPartSize bytes of data. // Make a temp file with minPartSize bytes of data.
file, err := ioutil.TempFile(os.TempDir(), "FPutObjectTest") file, err := ioutil.TempFile(os.TempDir(), "FPutObjectTest")
@ -3082,7 +3089,7 @@ func testFPutObjectContext() {
// Upload 1 parts worth of data to use multipart upload. // Upload 1 parts worth of data to use multipart upload.
// Use different data in part for multipart tests to check parts are uploaded in correct order. // Use different data in part for multipart tests to check parts are uploaded in correct order.
var fName = getMintDataDirFilePath("datafile-1-MB") fName := getMintDataDirFilePath("datafile-1-MB")
if fName == "" { if fName == "" {
// Make a temp file with 1 MiB bytes of data. // Make a temp file with 1 MiB bytes of data.
file, err := ioutil.TempFile(os.TempDir(), "FPutObjectContextTest") file, err := ioutil.TempFile(os.TempDir(), "FPutObjectContextTest")
@ -3134,7 +3141,6 @@ func testFPutObjectContext() {
} }
successLogger(testName, function, args, startTime).Info() successLogger(testName, function, args, startTime).Info()
} }
// Tests FPutObject request when context cancels after timeout // Tests FPutObject request when context cancels after timeout
@ -3183,7 +3189,7 @@ func testFPutObjectContextV2() {
// Upload 1 parts worth of data to use multipart upload. // Upload 1 parts worth of data to use multipart upload.
// Use different data in part for multipart tests to check parts are uploaded in correct order. // Use different data in part for multipart tests to check parts are uploaded in correct order.
var fName = getMintDataDirFilePath("datafile-1-MB") fName := getMintDataDirFilePath("datafile-1-MB")
if fName == "" { if fName == "" {
// Make a temp file with 1 MiB bytes of data. // Make a temp file with 1 MiB bytes of data.
file, err := ioutil.TempFile(os.TempDir(), "FPutObjectContextTest") file, err := ioutil.TempFile(os.TempDir(), "FPutObjectContextTest")
@ -3237,7 +3243,6 @@ func testFPutObjectContextV2() {
} }
successLogger(testName, function, args, startTime).Info() successLogger(testName, function, args, startTime).Info()
} }
// Test validates putObject with context to see if request cancellation is honored. // Test validates putObject with context to see if request cancellation is honored.
@ -3283,7 +3288,7 @@ func testPutObjectContext() {
defer cleanupBucket(bucketName, c) defer cleanupBucket(bucketName, c)
bufSize := dataFileMap["datafile-33-kB"] bufSize := dataFileMap["datafile-33-kB"]
var reader = getDataReader("datafile-33-kB") reader := getDataReader("datafile-33-kB")
defer reader.Close() defer reader.Close()
objectName := fmt.Sprintf("test-file-%v", rand.Uint32()) objectName := fmt.Sprintf("test-file-%v", rand.Uint32())
args["objectName"] = objectName args["objectName"] = objectName
@ -3312,7 +3317,6 @@ func testPutObjectContext() {
} }
successLogger(testName, function, args, startTime).Info() successLogger(testName, function, args, startTime).Info()
} }
// Tests get object with s3zip extensions. // Tests get object with s3zip extensions.
@ -3428,7 +3432,7 @@ func testGetObjectS3Zip() {
lOpts.Prefix = objectName + "/" lOpts.Prefix = objectName + "/"
lOpts.Recursive = true lOpts.Recursive = true
list := c.ListObjects(context.Background(), bucketName, lOpts) list := c.ListObjects(context.Background(), bucketName, lOpts)
var listed = map[string]minio.ObjectInfo{} listed := map[string]minio.ObjectInfo{}
for item := range list { for item := range list {
if item.Err != nil { if item.Err != nil {
break break
@ -3547,7 +3551,7 @@ func testGetObjectReadSeekFunctional() {
// Generate 33K of data. // Generate 33K of data.
bufSize := dataFileMap["datafile-33-kB"] bufSize := dataFileMap["datafile-33-kB"]
var reader = getDataReader("datafile-33-kB") reader := getDataReader("datafile-33-kB")
defer reader.Close() defer reader.Close()
objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "") objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "")
@ -3710,7 +3714,7 @@ func testGetObjectReadAtFunctional() {
// Generate 33K of data. // Generate 33K of data.
bufSize := dataFileMap["datafile-33-kB"] bufSize := dataFileMap["datafile-33-kB"]
var reader = getDataReader("datafile-33-kB") reader := getDataReader("datafile-33-kB")
defer reader.Close() defer reader.Close()
objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "") objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "")
@ -3887,7 +3891,7 @@ func testGetObjectReadAtWhenEOFWasReached() {
// Generate 33K of data. // Generate 33K of data.
bufSize := dataFileMap["datafile-33-kB"] bufSize := dataFileMap["datafile-33-kB"]
var reader = getDataReader("datafile-33-kB") reader := getDataReader("datafile-33-kB")
defer reader.Close() defer reader.Close()
objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "") objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "")
@ -4004,7 +4008,7 @@ func testPresignedPostPolicy() {
defer cleanupBucket(bucketName, c) defer cleanupBucket(bucketName, c)
// Generate 33K of data. // Generate 33K of data.
var reader = getDataReader("datafile-33-kB") reader := getDataReader("datafile-33-kB")
defer reader.Close() defer reader.Close()
objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "") objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "")
@ -4081,7 +4085,7 @@ func testPresignedPostPolicy() {
} }
// Get a 33KB file to upload and test if set post policy works // Get a 33KB file to upload and test if set post policy works
var filePath = getMintDataDirFilePath("datafile-33-kB") filePath := getMintDataDirFilePath("datafile-33-kB")
if filePath == "" { if filePath == "" {
// Make a temp file with 33 KB data. // Make a temp file with 33 KB data.
file, err := ioutil.TempFile(os.TempDir(), "PresignedPostPolicyTest") file, err := ioutil.TempFile(os.TempDir(), "PresignedPostPolicyTest")
@ -4228,7 +4232,7 @@ func testCopyObject() {
// Generate 33K of data. // Generate 33K of data.
bufSize := dataFileMap["datafile-33-kB"] bufSize := dataFileMap["datafile-33-kB"]
var reader = getDataReader("datafile-33-kB") reader := getDataReader("datafile-33-kB")
// Save the data // Save the data
objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "") objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "")
@ -4421,7 +4425,7 @@ func testSSECEncryptedGetObjectReadSeekFunctional() {
// Generate 129MiB of data. // Generate 129MiB of data.
bufSize := dataFileMap["datafile-129-MB"] bufSize := dataFileMap["datafile-129-MB"]
var reader = getDataReader("datafile-129-MB") reader := getDataReader("datafile-129-MB")
defer reader.Close() defer reader.Close()
objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "") objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "")
@ -4603,7 +4607,7 @@ func testSSES3EncryptedGetObjectReadSeekFunctional() {
// Generate 129MiB of data. // Generate 129MiB of data.
bufSize := dataFileMap["datafile-129-MB"] bufSize := dataFileMap["datafile-129-MB"]
var reader = getDataReader("datafile-129-MB") reader := getDataReader("datafile-129-MB")
defer reader.Close() defer reader.Close()
objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "") objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "")
@ -4777,7 +4781,7 @@ func testSSECEncryptedGetObjectReadAtFunctional() {
// Generate 129MiB of data. // Generate 129MiB of data.
bufSize := dataFileMap["datafile-129-MB"] bufSize := dataFileMap["datafile-129-MB"]
var reader = getDataReader("datafile-129-MB") reader := getDataReader("datafile-129-MB")
defer reader.Close() defer reader.Close()
objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "") objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "")
@ -4960,7 +4964,7 @@ func testSSES3EncryptedGetObjectReadAtFunctional() {
// Generate 129MiB of data. // Generate 129MiB of data.
bufSize := dataFileMap["datafile-129-MB"] bufSize := dataFileMap["datafile-129-MB"]
var reader = getDataReader("datafile-129-MB") reader := getDataReader("datafile-129-MB")
defer reader.Close() defer reader.Close()
objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "") objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "")
@ -5972,7 +5976,6 @@ func testFunctional() {
"objectName": objectName, "objectName": objectName,
} }
newReader, err := c.GetObject(context.Background(), bucketName, objectName, minio.GetObjectOptions{}) newReader, err := c.GetObject(context.Background(), bucketName, objectName, minio.GetObjectOptions{})
if err != nil { if err != nil {
logError(testName, function, args, startTime, "", "GetObject failed", err) logError(testName, function, args, startTime, "", "GetObject failed", err)
return return
@ -6025,7 +6028,6 @@ func testFunctional() {
"expires": 3600 * time.Second, "expires": 3600 * time.Second,
} }
presignedHeadURL, err := c.PresignedHeadObject(context.Background(), bucketName, objectName, 3600*time.Second, nil) presignedHeadURL, err := c.PresignedHeadObject(context.Background(), bucketName, objectName, 3600*time.Second, nil)
if err != nil { if err != nil {
logError(testName, function, args, startTime, "", "PresignedHeadObject failed", err) logError(testName, function, args, startTime, "", "PresignedHeadObject failed", err)
return return
@ -6089,7 +6091,6 @@ func testFunctional() {
"expires": 3600 * time.Second, "expires": 3600 * time.Second,
} }
presignedGetURL, err := c.PresignedGetObject(context.Background(), bucketName, objectName, 3600*time.Second, nil) presignedGetURL, err := c.PresignedGetObject(context.Background(), bucketName, objectName, 3600*time.Second, nil)
if err != nil { if err != nil {
logError(testName, function, args, startTime, "", "PresignedGetObject failed", err) logError(testName, function, args, startTime, "", "PresignedGetObject failed", err)
return return
@ -6189,7 +6190,6 @@ func testFunctional() {
"expires": 3600 * time.Second, "expires": 3600 * time.Second,
} }
presignedPutURL, err := c.PresignedPutObject(context.Background(), bucketName, objectName+"-presigned", 3600*time.Second) presignedPutURL, err := c.PresignedPutObject(context.Background(), bucketName, objectName+"-presigned", 3600*time.Second)
if err != nil { if err != nil {
logError(testName, function, args, startTime, "", "PresignedPutObject failed", err) logError(testName, function, args, startTime, "", "PresignedPutObject failed", err)
return return
@ -6513,7 +6513,7 @@ func testPutObjectUploadSeekedObject() {
// Seek back to the beginning of the file. // Seek back to the beginning of the file.
tempfile.Seek(0, 0) tempfile.Seek(0, 0)
} }
var length = 100 * humanize.KiByte length := 100 * humanize.KiByte
objectName := fmt.Sprintf("test-file-%v", rand.Uint32()) objectName := fmt.Sprintf("test-file-%v", rand.Uint32())
args["objectName"] = objectName args["objectName"] = objectName
@ -6670,7 +6670,7 @@ func testGetObjectClosedTwiceV2() {
// Generate 33K of data. // Generate 33K of data.
bufSize := dataFileMap["datafile-33-kB"] bufSize := dataFileMap["datafile-33-kB"]
var reader = getDataReader("datafile-33-kB") reader := getDataReader("datafile-33-kB")
defer reader.Close() defer reader.Close()
// Save the data // Save the data
@ -6982,7 +6982,7 @@ func testGetObjectReadSeekFunctionalV2() {
// Generate 33K of data. // Generate 33K of data.
bufSize := dataFileMap["datafile-33-kB"] bufSize := dataFileMap["datafile-33-kB"]
var reader = getDataReader("datafile-33-kB") reader := getDataReader("datafile-33-kB")
defer reader.Close() defer reader.Close()
objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "") objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "")
@ -7136,7 +7136,7 @@ func testGetObjectReadAtFunctionalV2() {
// Generate 33K of data. // Generate 33K of data.
bufSize := dataFileMap["datafile-33-kB"] bufSize := dataFileMap["datafile-33-kB"]
var reader = getDataReader("datafile-33-kB") reader := getDataReader("datafile-33-kB")
defer reader.Close() defer reader.Close()
objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "") objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "")
@ -7303,7 +7303,7 @@ func testCopyObjectV2() {
// Generate 33K of data. // Generate 33K of data.
bufSize := dataFileMap["datafile-33-kB"] bufSize := dataFileMap["datafile-33-kB"]
var reader = getDataReader("datafile-33-kB") reader := getDataReader("datafile-33-kB")
defer reader.Close() defer reader.Close()
// Save the data // Save the data
@ -7412,7 +7412,6 @@ func testComposeObjectErrorCasesWrapper(c *minio.Client) {
// Make a new bucket in 'us-east-1' (source bucket). // Make a new bucket in 'us-east-1' (source bucket).
err := c.MakeBucket(context.Background(), bucketName, minio.MakeBucketOptions{Region: "us-east-1"}) err := c.MakeBucket(context.Background(), bucketName, minio.MakeBucketOptions{Region: "us-east-1"})
if err != nil { if err != nil {
logError(testName, function, args, startTime, "", "MakeBucket failed", err) logError(testName, function, args, startTime, "", "MakeBucket failed", err)
return return
@ -9935,6 +9934,7 @@ func testSSES3EncryptedToSSES3CopyObjectPart() {
// Do not need to remove destBucketName its same as bucketName. // Do not need to remove destBucketName its same as bucketName.
} }
func testUserMetadataCopying() { func testUserMetadataCopying() {
// initialize logging params // initialize logging params
startTime := time.Now() startTime := time.Now()
@ -10432,7 +10432,7 @@ func testPutObjectNoLengthV2() {
args["objectName"] = objectName args["objectName"] = objectName
bufSize := dataFileMap["datafile-129-MB"] bufSize := dataFileMap["datafile-129-MB"]
var reader = getDataReader("datafile-129-MB") reader := getDataReader("datafile-129-MB")
defer reader.Close() defer reader.Close()
args["size"] = bufSize args["size"] = bufSize
@ -11162,7 +11162,7 @@ func testGetObjectContext() {
defer cleanupBucket(bucketName, c) defer cleanupBucket(bucketName, c)
bufSize := dataFileMap["datafile-33-kB"] bufSize := dataFileMap["datafile-33-kB"]
var reader = getDataReader("datafile-33-kB") reader := getDataReader("datafile-33-kB")
defer reader.Close() defer reader.Close()
// Save the data // Save the data
objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "") objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "")
@ -11216,7 +11216,6 @@ func testGetObjectContext() {
} }
successLogger(testName, function, args, startTime).Info() successLogger(testName, function, args, startTime).Info()
} }
// Test get object with FGetObject with a user provided context // Test get object with FGetObject with a user provided context
@ -11265,7 +11264,7 @@ func testFGetObjectContext() {
defer cleanupBucket(bucketName, c) defer cleanupBucket(bucketName, c)
bufSize := dataFileMap["datafile-1-MB"] bufSize := dataFileMap["datafile-1-MB"]
var reader = getDataReader("datafile-1-MB") reader := getDataReader("datafile-1-MB")
defer reader.Close() defer reader.Close()
// Save the data // Save the data
objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "") objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "")
@ -11304,7 +11303,6 @@ func testFGetObjectContext() {
} }
successLogger(testName, function, args, startTime).Info() successLogger(testName, function, args, startTime).Info()
} }
// Test get object with GetObject with a user provided context // Test get object with GetObject with a user provided context
@ -11354,7 +11352,7 @@ func testGetObjectRanges() {
defer cleanupBucket(bucketName, c) defer cleanupBucket(bucketName, c)
bufSize := dataFileMap["datafile-129-MB"] bufSize := dataFileMap["datafile-129-MB"]
var reader = getDataReader("datafile-129-MB") reader := getDataReader("datafile-129-MB")
defer reader.Close() defer reader.Close()
// Save the data // Save the data
objectName := randString(60, rng, "") objectName := randString(60, rng, "")
@ -11463,7 +11461,7 @@ func testGetObjectACLContext() {
defer cleanupBucket(bucketName, c) defer cleanupBucket(bucketName, c)
bufSize := dataFileMap["datafile-1-MB"] bufSize := dataFileMap["datafile-1-MB"]
var reader = getDataReader("datafile-1-MB") reader := getDataReader("datafile-1-MB")
defer reader.Close() defer reader.Close()
// Save the data // Save the data
objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "") objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "")
@ -11525,7 +11523,7 @@ func testGetObjectACLContext() {
} }
bufSize = dataFileMap["datafile-1-MB"] bufSize = dataFileMap["datafile-1-MB"]
var reader2 = getDataReader("datafile-1-MB") reader2 := getDataReader("datafile-1-MB")
defer reader2.Close() defer reader2.Close()
// Save the data // Save the data
objectName = randString(60, rand.NewSource(time.Now().UnixNano()), "") objectName = randString(60, rand.NewSource(time.Now().UnixNano()), "")
@ -11635,7 +11633,7 @@ func testPutObjectContextV2() {
} }
defer cleanupBucket(bucketName, c) defer cleanupBucket(bucketName, c)
bufSize := dataFileMap["datatfile-33-kB"] bufSize := dataFileMap["datatfile-33-kB"]
var reader = getDataReader("datafile-33-kB") reader := getDataReader("datafile-33-kB")
defer reader.Close() defer reader.Close()
objectName := fmt.Sprintf("test-file-%v", rand.Uint32()) objectName := fmt.Sprintf("test-file-%v", rand.Uint32())
@ -11665,7 +11663,6 @@ func testPutObjectContextV2() {
} }
successLogger(testName, function, args, startTime).Info() successLogger(testName, function, args, startTime).Info()
} }
// Test get object with GetObject with custom context // Test get object with GetObject with custom context
@ -11713,7 +11710,7 @@ func testGetObjectContextV2() {
defer cleanupBucket(bucketName, c) defer cleanupBucket(bucketName, c)
bufSize := dataFileMap["datafile-33-kB"] bufSize := dataFileMap["datafile-33-kB"]
var reader = getDataReader("datafile-33-kB") reader := getDataReader("datafile-33-kB")
defer reader.Close() defer reader.Close()
// Save the data // Save the data
objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "") objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "")
@ -11765,7 +11762,6 @@ func testGetObjectContextV2() {
} }
successLogger(testName, function, args, startTime).Info() successLogger(testName, function, args, startTime).Info()
} }
// Test get object with FGetObject with custom context // Test get object with FGetObject with custom context
@ -11814,7 +11810,7 @@ func testFGetObjectContextV2() {
defer cleanupBucket(bucketName, c) defer cleanupBucket(bucketName, c)
bufSize := dataFileMap["datatfile-1-MB"] bufSize := dataFileMap["datatfile-1-MB"]
var reader = getDataReader("datafile-1-MB") reader := getDataReader("datafile-1-MB")
defer reader.Close() defer reader.Close()
// Save the data // Save the data
objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "") objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "")
@ -11855,7 +11851,6 @@ func testFGetObjectContextV2() {
} }
successLogger(testName, function, args, startTime).Info() successLogger(testName, function, args, startTime).Info()
} }
// Test list object v1 and V2 // Test list object v1 and V2
@ -11915,7 +11910,7 @@ func testListObjects() {
for i, object := range testObjects { for i, object := range testObjects {
bufSize := dataFileMap["datafile-33-kB"] bufSize := dataFileMap["datafile-33-kB"]
var reader = getDataReader("datafile-33-kB") reader := getDataReader("datafile-33-kB")
defer reader.Close() defer reader.Close()
_, err = c.PutObject(context.Background(), bucketName, object.name, reader, int64(bufSize), _, err = c.PutObject(context.Background(), bucketName, object.name, reader, int64(bufSize),
minio.PutObjectOptions{ContentType: "binary/octet-stream", StorageClass: object.storageClass}) minio.PutObjectOptions{ContentType: "binary/octet-stream", StorageClass: object.storageClass})
@ -12003,7 +11998,7 @@ func testRemoveObjects() {
} }
bufSize := dataFileMap["datafile-129-MB"] bufSize := dataFileMap["datafile-129-MB"]
var reader = getDataReader("datafile-129-MB") reader := getDataReader("datafile-129-MB")
defer reader.Close() defer reader.Close()
_, err = c.PutObject(context.Background(), bucketName, objectName, reader, int64(bufSize), minio.PutObjectOptions{}) _, err = c.PutObject(context.Background(), bucketName, objectName, reader, int64(bufSize), minio.PutObjectOptions{})

View File

@ -122,7 +122,7 @@ type config struct {
// returned if it fails to read from the file. // returned if it fails to read from the file.
func loadAlias(filename, alias string) (hostConfig, error) { func loadAlias(filename, alias string) (hostConfig, error) {
cfg := &config{} cfg := &config{}
var json = jsoniter.ConfigCompatibleWithStandardLibrary json := jsoniter.ConfigCompatibleWithStandardLibrary
configBytes, err := ioutil.ReadFile(filename) configBytes, err := ioutil.ReadFile(filename)
if err != nil { if err != nil {

View File

@ -19,6 +19,7 @@ package credentials
import ( import (
"bufio" "bufio"
"context"
"errors" "errors"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
@ -254,7 +255,10 @@ func getEcsTaskCredentials(client *http.Client, endpoint string, token string) (
} }
func fetchIMDSToken(client *http.Client, endpoint string) (string, error) { func fetchIMDSToken(client *http.Client, endpoint string) (string, error) {
req, err := http.NewRequest(http.MethodPut, endpoint+tokenPath, nil) ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
req, err := http.NewRequestWithContext(ctx, http.MethodPut, endpoint+tokenPath, nil)
if err != nil { if err != nil {
return "", err return "", err
} }

View File

@ -105,8 +105,8 @@ func NewSTSClientGrants(stsEndpoint string, getClientGrantsTokenExpiry func() (*
} }
func getClientGrantsCredentials(clnt *http.Client, endpoint string, func getClientGrantsCredentials(clnt *http.Client, endpoint string,
getClientGrantsTokenExpiry func() (*ClientGrantsToken, error)) (AssumeRoleWithClientGrantsResponse, error) { getClientGrantsTokenExpiry func() (*ClientGrantsToken, error),
) (AssumeRoleWithClientGrantsResponse, error) {
accessToken, err := getClientGrantsTokenExpiry() accessToken, err := getClientGrantsTokenExpiry()
if err != nil { if err != nil {
return AssumeRoleWithClientGrantsResponse{}, err return AssumeRoleWithClientGrantsResponse{}, err
@ -138,7 +138,6 @@ func getClientGrantsCredentials(clnt *http.Client, endpoint string,
buf, err := ioutil.ReadAll(resp.Body) buf, err := ioutil.ReadAll(resp.Body)
if err != nil { if err != nil {
return AssumeRoleWithClientGrantsResponse{}, err return AssumeRoleWithClientGrantsResponse{}, err
} }
_, err = xmlDecodeAndBody(bytes.NewReader(buf), &errResp) _, err = xmlDecodeAndBody(bytes.NewReader(buf), &errResp)
if err != nil { if err != nil {

View File

@ -174,7 +174,6 @@ func (k *LDAPIdentity) Retrieve() (value Value, err error) {
buf, err := ioutil.ReadAll(resp.Body) buf, err := ioutil.ReadAll(resp.Body)
if err != nil { if err != nil {
return value, err return value, err
} }
_, err = xmlDecodeAndBody(bytes.NewReader(buf), &errResp) _, err = xmlDecodeAndBody(bytes.NewReader(buf), &errResp)
if err != nil { if err != nil {

View File

@ -94,7 +94,7 @@ func NewSTSCertificateIdentity(endpoint string, certificate tls.Certificate, opt
if _, err := url.Parse(endpoint); err != nil { if _, err := url.Parse(endpoint); err != nil {
return nil, err return nil, err
} }
var identity = &STSCertificateIdentity{ identity := &STSCertificateIdentity{
STSEndpoint: endpoint, STSEndpoint: endpoint,
Client: http.Client{ Client: http.Client{
Transport: &http.Transport{ Transport: &http.Transport{
@ -127,7 +127,7 @@ func (i *STSCertificateIdentity) Retrieve() (Value, error) {
if err != nil { if err != nil {
return Value{}, err return Value{}, err
} }
var livetime = i.S3CredentialLivetime livetime := i.S3CredentialLivetime
if livetime == 0 { if livetime == 0 {
livetime = 1 * time.Hour livetime = 1 * time.Hour
} }
@ -155,7 +155,6 @@ func (i *STSCertificateIdentity) Retrieve() (Value, error) {
buf, err := ioutil.ReadAll(resp.Body) buf, err := ioutil.ReadAll(resp.Body)
if err != nil { if err != nil {
return Value{}, err return Value{}, err
} }
_, err = xmlDecodeAndBody(bytes.NewReader(buf), &errResp) _, err = xmlDecodeAndBody(bytes.NewReader(buf), &errResp)
if err != nil { if err != nil {

View File

@ -107,7 +107,8 @@ func NewSTSWebIdentity(stsEndpoint string, getWebIDTokenExpiry func() (*WebIdent
} }
func getWebIdentityCredentials(clnt *http.Client, endpoint, roleARN, roleSessionName string, func getWebIdentityCredentials(clnt *http.Client, endpoint, roleARN, roleSessionName string,
getWebIDTokenExpiry func() (*WebIdentityToken, error)) (AssumeRoleWithWebIdentityResponse, error) { getWebIDTokenExpiry func() (*WebIdentityToken, error),
) (AssumeRoleWithWebIdentityResponse, error) {
idToken, err := getWebIDTokenExpiry() idToken, err := getWebIDTokenExpiry()
if err != nil { if err != nil {
return AssumeRoleWithWebIdentityResponse{}, err return AssumeRoleWithWebIdentityResponse{}, err
@ -156,7 +157,6 @@ func getWebIdentityCredentials(clnt *http.Client, endpoint, roleARN, roleSession
buf, err := ioutil.ReadAll(resp.Body) buf, err := ioutil.ReadAll(resp.Body)
if err != nil { if err != nil {
return AssumeRoleWithWebIdentityResponse{}, err return AssumeRoleWithWebIdentityResponse{}, err
} }
_, err = xmlDecodeAndBody(bytes.NewReader(buf), &errResp) _, err = xmlDecodeAndBody(bytes.NewReader(buf), &errResp)
if err != nil { if err != nil {

View File

@ -101,7 +101,7 @@ func NewSSEKMS(keyID string, context interface{}) (ServerSide, error) {
if context == nil { if context == nil {
return kms{key: keyID, hasContext: false}, nil return kms{key: keyID, hasContext: false}, nil
} }
var json = jsoniter.ConfigCompatibleWithStandardLibrary json := jsoniter.ConfigCompatibleWithStandardLibrary
serializedContext, err := json.Marshal(context) serializedContext, err := json.Marshal(context)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -78,11 +78,13 @@ type Arn struct {
// NewArn creates new ARN based on the given partition, service, region, account id and resource // NewArn creates new ARN based on the given partition, service, region, account id and resource
func NewArn(partition, service, region, accountID, resource string) Arn { func NewArn(partition, service, region, accountID, resource string) Arn {
return Arn{Partition: partition, return Arn{
Partition: partition,
Service: service, Service: service,
Region: region, Region: region,
AccountID: accountID, AccountID: accountID,
Resource: resource} Resource: resource,
}
} }
// String returns the string format of the ARN // String returns the string format of the ARN

View File

@ -432,7 +432,6 @@ func (c *Config) RemoveRule(opts Options) error {
} }
c.Rules = newRules c.Rules = newRules
return nil return nil
} }
// Rule - a rule for replication configuration. // Rule - a rule for replication configuration.

View File

@ -114,8 +114,8 @@ func buildChunkHeader(chunkLen int64, signature string) []byte {
// buildChunkSignature - returns chunk signature for a given chunk and previous signature. // buildChunkSignature - returns chunk signature for a given chunk and previous signature.
func buildChunkSignature(chunkData []byte, reqTime time.Time, region, func buildChunkSignature(chunkData []byte, reqTime time.Time, region,
previousSignature, secretAccessKey string) string { previousSignature, secretAccessKey string,
) string {
chunkStringToSign := buildChunkStringToSign(reqTime, region, chunkStringToSign := buildChunkStringToSign(reqTime, region,
previousSignature, chunkData) previousSignature, chunkData)
signingKey := getSigningKey(secretAccessKey, region, reqTime, ServiceTypeS3) signingKey := getSigningKey(secretAccessKey, region, reqTime, ServiceTypeS3)
@ -200,8 +200,8 @@ func (s *StreamingReader) setStreamingAuthHeader(req *http.Request) {
// StreamingSignV4 - provides chunked upload signatureV4 support by // StreamingSignV4 - provides chunked upload signatureV4 support by
// implementing io.Reader. // implementing io.Reader.
func StreamingSignV4(req *http.Request, accessKeyID, secretAccessKey, sessionToken, func StreamingSignV4(req *http.Request, accessKeyID, secretAccessKey, sessionToken,
region string, dataLen int64, reqTime time.Time) *http.Request { region string, dataLen int64, reqTime time.Time,
) *http.Request {
// Set headers needed for streaming signature. // Set headers needed for streaming signature.
prepareStreamingRequest(req, sessionToken, dataLen, reqTime) prepareStreamingRequest(req, sessionToken, dataLen, reqTime)

View File

@ -110,6 +110,7 @@ func isS3CodeRetryable(s3Code string) (ok bool) {
// List of HTTP status codes which are retryable. // List of HTTP status codes which are retryable.
var retryableHTTPStatusCodes = map[int]struct{}{ var retryableHTTPStatusCodes = map[int]struct{}{
429: {}, // http.StatusTooManyRequests is not part of the Go 1.5 library, yet 429: {}, // http.StatusTooManyRequests is not part of the Go 1.5 library, yet
499: {}, // client closed request, retry. A non-standard status code introduced by nginx.
http.StatusInternalServerError: {}, http.StatusInternalServerError: {},
http.StatusBadGateway: {}, http.StatusBadGateway: {},
http.StatusServiceUnavailable: {}, http.StatusServiceUnavailable: {},

View File

@ -105,21 +105,6 @@ func sumMD5Base64(data []byte) string {
// getEndpointURL - construct a new endpoint. // getEndpointURL - construct a new endpoint.
func getEndpointURL(endpoint string, secure bool) (*url.URL, error) { func getEndpointURL(endpoint string, secure bool) (*url.URL, error) {
if strings.Contains(endpoint, ":") {
host, _, err := net.SplitHostPort(endpoint)
if err != nil {
return nil, err
}
if !s3utils.IsValidIP(host) && !s3utils.IsValidDomain(host) {
msg := "Endpoint: " + endpoint + " does not follow ip address or domain name standards."
return nil, errInvalidArgument(msg)
}
} else {
if !s3utils.IsValidIP(endpoint) && !s3utils.IsValidDomain(endpoint) {
msg := "Endpoint: " + endpoint + " does not follow ip address or domain name standards."
return nil, errInvalidArgument(msg)
}
}
// If secure is false, use 'http' scheme. // If secure is false, use 'http' scheme.
scheme := "https" scheme := "https"
if !secure { if !secure {
@ -176,12 +161,18 @@ func isValidEndpointURL(endpointURL url.URL) error {
if endpointURL.Path != "/" && endpointURL.Path != "" { if endpointURL.Path != "/" && endpointURL.Path != "" {
return errInvalidArgument("Endpoint url cannot have fully qualified paths.") return errInvalidArgument("Endpoint url cannot have fully qualified paths.")
} }
if strings.Contains(endpointURL.Host, ".s3.amazonaws.com") { host := endpointURL.Hostname()
if !s3utils.IsValidIP(host) && !s3utils.IsValidDomain(host) {
msg := "Endpoint: " + endpointURL.Host + " does not follow ip address or domain name standards."
return errInvalidArgument(msg)
}
if strings.Contains(host, ".s3.amazonaws.com") {
if !s3utils.IsAmazonEndpoint(endpointURL) { if !s3utils.IsAmazonEndpoint(endpointURL) {
return errInvalidArgument("Amazon S3 endpoint should be 's3.amazonaws.com'.") return errInvalidArgument("Amazon S3 endpoint should be 's3.amazonaws.com'.")
} }
} }
if strings.Contains(endpointURL.Host, ".googleapis.com") { if strings.Contains(host, ".googleapis.com") {
if !s3utils.IsGoogleEndpoint(endpointURL) { if !s3utils.IsGoogleEndpoint(endpointURL) {
return errInvalidArgument("Google Cloud Storage endpoint should be 'storage.googleapis.com'.") return errInvalidArgument("Google Cloud Storage endpoint should be 'storage.googleapis.com'.")
} }
@ -513,8 +504,10 @@ func isAmzHeader(headerKey string) bool {
return strings.HasPrefix(key, "x-amz-meta-") || strings.HasPrefix(key, "x-amz-grant-") || key == "x-amz-acl" || isSSEHeader(headerKey) return strings.HasPrefix(key, "x-amz-meta-") || strings.HasPrefix(key, "x-amz-grant-") || key == "x-amz-acl" || isSSEHeader(headerKey)
} }
var md5Pool = sync.Pool{New: func() interface{} { return md5.New() }} var (
var sha256Pool = sync.Pool{New: func() interface{} { return sha256.New() }} md5Pool = sync.Pool{New: func() interface{} { return md5.New() }}
sha256Pool = sync.Pool{New: func() interface{} { return sha256.New() }}
)
func newMd5Hasher() md5simd.Hasher { func newMd5Hasher() md5simd.Hasher {
return hashWrapper{Hash: md5Pool.Get().(hash.Hash), isMD5: true} return hashWrapper{Hash: md5Pool.Get().(hash.Hash), isMD5: true}

View File

@ -1,3 +1,16 @@
## 1.5.0
* New option `IgnoreUntaggedFields` to ignore decoding to any fields
without `mapstructure` (or the configured tag name) set [GH-277]
* New option `ErrorUnset` which makes it an error if any fields
in a target struct are not set by the decoding process. [GH-225]
* New function `OrComposeDecodeHookFunc` to help compose decode hooks. [GH-240]
* Decoding to slice from array no longer crashes [GH-265]
* Decode nested struct pointers to map [GH-271]
* Fix issue where `,squash` was ignored if `Squash` option was set. [GH-280]
* Fix issue where fields with `,omitempty` would sometimes decode
into a map with an empty string key [GH-281]
## 1.4.3 ## 1.4.3
* Fix cases where `json.Number` didn't decode properly [GH-261] * Fix cases where `json.Number` didn't decode properly [GH-261]

View File

@ -77,6 +77,28 @@ func ComposeDecodeHookFunc(fs ...DecodeHookFunc) DecodeHookFunc {
} }
} }
// OrComposeDecodeHookFunc executes all input hook functions until one of them returns no error. In that case its value is returned.
// If all hooks return an error, OrComposeDecodeHookFunc returns an error concatenating all error messages.
func OrComposeDecodeHookFunc(ff ...DecodeHookFunc) DecodeHookFunc {
return func(a, b reflect.Value) (interface{}, error) {
var allErrs string
var out interface{}
var err error
for _, f := range ff {
out, err = DecodeHookExec(f, a, b)
if err != nil {
allErrs += err.Error() + "\n"
continue
}
return out, nil
}
return nil, errors.New(allErrs)
}
}
// StringToSliceHookFunc returns a DecodeHookFunc that converts // StringToSliceHookFunc returns a DecodeHookFunc that converts
// string to []string by splitting on the given sep. // string to []string by splitting on the given sep.
func StringToSliceHookFunc(sep string) DecodeHookFunc { func StringToSliceHookFunc(sep string) DecodeHookFunc {

View File

@ -122,7 +122,7 @@
// field value is zero and a numeric type, the field is empty, and it won't // field value is zero and a numeric type, the field is empty, and it won't
// be encoded into the destination type. // be encoded into the destination type.
// //
// type Source { // type Source struct {
// Age int `mapstructure:",omitempty"` // Age int `mapstructure:",omitempty"`
// } // }
// //
@ -215,6 +215,12 @@ type DecoderConfig struct {
// (extra keys). // (extra keys).
ErrorUnused bool ErrorUnused bool
// If ErrorUnset is true, then it is an error for there to exist
// fields in the result that were not set in the decoding process
// (extra fields). This only applies to decoding to a struct. This
// will affect all nested structs as well.
ErrorUnset bool
// ZeroFields, if set to true, will zero fields before writing them. // ZeroFields, if set to true, will zero fields before writing them.
// For example, a map will be emptied before decoded values are put in // For example, a map will be emptied before decoded values are put in
// it. If this is false, a map will be merged. // it. If this is false, a map will be merged.
@ -259,6 +265,10 @@ type DecoderConfig struct {
// defaults to "mapstructure" // defaults to "mapstructure"
TagName string TagName string
// IgnoreUntaggedFields ignores all struct fields without explicit
// TagName, comparable to `mapstructure:"-"` as default behaviour.
IgnoreUntaggedFields bool
// MatchName is the function used to match the map key to the struct // MatchName is the function used to match the map key to the struct
// field name or tag. Defaults to `strings.EqualFold`. This can be used // field name or tag. Defaults to `strings.EqualFold`. This can be used
// to implement case-sensitive tag values, support snake casing, etc. // to implement case-sensitive tag values, support snake casing, etc.
@ -284,6 +294,11 @@ type Metadata struct {
// Unused is a slice of keys that were found in the raw value but // Unused is a slice of keys that were found in the raw value but
// weren't decoded since there was no matching field in the result interface // weren't decoded since there was no matching field in the result interface
Unused []string Unused []string
// Unset is a slice of field names that were found in the result interface
// but weren't set in the decoding process since there was no matching value
// in the input
Unset []string
} }
// Decode takes an input structure and uses reflection to translate it to // Decode takes an input structure and uses reflection to translate it to
@ -375,6 +390,10 @@ func NewDecoder(config *DecoderConfig) (*Decoder, error) {
if config.Metadata.Unused == nil { if config.Metadata.Unused == nil {
config.Metadata.Unused = make([]string, 0) config.Metadata.Unused = make([]string, 0)
} }
if config.Metadata.Unset == nil {
config.Metadata.Unset = make([]string, 0)
}
} }
if config.TagName == "" { if config.TagName == "" {
@ -906,9 +925,15 @@ func (d *Decoder) decodeMapFromStruct(name string, dataVal reflect.Value, val re
tagValue := f.Tag.Get(d.config.TagName) tagValue := f.Tag.Get(d.config.TagName)
keyName := f.Name keyName := f.Name
if tagValue == "" && d.config.IgnoreUntaggedFields {
continue
}
// If Squash is set in the config, we squash the field down. // If Squash is set in the config, we squash the field down.
squash := d.config.Squash && v.Kind() == reflect.Struct && f.Anonymous squash := d.config.Squash && v.Kind() == reflect.Struct && f.Anonymous
v = dereferencePtrToStructIfNeeded(v, d.config.TagName)
// Determine the name of the key in the map // Determine the name of the key in the map
if index := strings.Index(tagValue, ","); index != -1 { if index := strings.Index(tagValue, ","); index != -1 {
if tagValue[:index] == "-" { if tagValue[:index] == "-" {
@ -920,7 +945,7 @@ func (d *Decoder) decodeMapFromStruct(name string, dataVal reflect.Value, val re
} }
// If "squash" is specified in the tag, we squash the field down. // If "squash" is specified in the tag, we squash the field down.
squash = !squash && strings.Index(tagValue[index+1:], "squash") != -1 squash = squash || strings.Index(tagValue[index+1:], "squash") != -1
if squash { if squash {
// When squashing, the embedded type can be a pointer to a struct. // When squashing, the embedded type can be a pointer to a struct.
if v.Kind() == reflect.Ptr && v.Elem().Kind() == reflect.Struct { if v.Kind() == reflect.Ptr && v.Elem().Kind() == reflect.Struct {
@ -932,7 +957,9 @@ func (d *Decoder) decodeMapFromStruct(name string, dataVal reflect.Value, val re
return fmt.Errorf("cannot squash non-struct type '%s'", v.Type()) return fmt.Errorf("cannot squash non-struct type '%s'", v.Type())
} }
} }
keyName = tagValue[:index] if keyNameTagValue := tagValue[:index]; keyNameTagValue != "" {
keyName = keyNameTagValue
}
} else if len(tagValue) > 0 { } else if len(tagValue) > 0 {
if tagValue == "-" { if tagValue == "-" {
continue continue
@ -1088,7 +1115,7 @@ func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value)
} }
// If the input value is nil, then don't allocate since empty != nil // If the input value is nil, then don't allocate since empty != nil
if dataVal.IsNil() { if dataValKind != reflect.Array && dataVal.IsNil() {
return nil return nil
} }
@ -1250,6 +1277,7 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
dataValKeysUnused[dataValKey.Interface()] = struct{}{} dataValKeysUnused[dataValKey.Interface()] = struct{}{}
} }
targetValKeysUnused := make(map[interface{}]struct{})
errors := make([]string, 0) errors := make([]string, 0)
// This slice will keep track of all the structs we'll be decoding. // This slice will keep track of all the structs we'll be decoding.
@ -1354,7 +1382,8 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
if !rawMapVal.IsValid() { if !rawMapVal.IsValid() {
// There was no matching key in the map for the value in // There was no matching key in the map for the value in
// the struct. Just ignore. // the struct. Remember it for potential errors and metadata.
targetValKeysUnused[fieldName] = struct{}{}
continue continue
} }
} }
@ -1414,6 +1443,17 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
errors = appendErrors(errors, err) errors = appendErrors(errors, err)
} }
if d.config.ErrorUnset && len(targetValKeysUnused) > 0 {
keys := make([]string, 0, len(targetValKeysUnused))
for rawKey := range targetValKeysUnused {
keys = append(keys, rawKey.(string))
}
sort.Strings(keys)
err := fmt.Errorf("'%s' has unset fields: %s", name, strings.Join(keys, ", "))
errors = appendErrors(errors, err)
}
if len(errors) > 0 { if len(errors) > 0 {
return &Error{errors} return &Error{errors}
} }
@ -1428,6 +1468,14 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
d.config.Metadata.Unused = append(d.config.Metadata.Unused, key) d.config.Metadata.Unused = append(d.config.Metadata.Unused, key)
} }
for rawKey := range targetValKeysUnused {
key := rawKey.(string)
if name != "" {
key = name + "." + key
}
d.config.Metadata.Unset = append(d.config.Metadata.Unset, key)
}
} }
return nil return nil
@ -1465,3 +1513,28 @@ func getKind(val reflect.Value) reflect.Kind {
return kind return kind
} }
} }
func isStructTypeConvertibleToMap(typ reflect.Type, checkMapstructureTags bool, tagName string) bool {
for i := 0; i < typ.NumField(); i++ {
f := typ.Field(i)
if f.PkgPath == "" && !checkMapstructureTags { // check for unexported fields
return true
}
if checkMapstructureTags && f.Tag.Get(tagName) != "" { // check for mapstructure tags inside
return true
}
}
return false
}
func dereferencePtrToStructIfNeeded(v reflect.Value, tagName string) reflect.Value {
if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct {
return v
}
deref := v.Elem()
derefT := deref.Type()
if isStructTypeConvertibleToMap(derefT, true, tagName) {
return deref
}
return v
}

View File

@ -25,9 +25,9 @@ and [much faster][v2-bench]. If you only need reading and writing TOML documents
(majority of cases), those features are implemented and the API unlikely to (majority of cases), those features are implemented and the API unlikely to
change. change.
The remaining features (Document structure editing and tooling) will be added The remaining features will be added shortly. While pull-requests are welcome on
shortly. While pull-requests are welcome on v1, no active development is v1, no active development is expected on it. When v2.0.0 is released, v1 will be
expected on it. When v2.0.0 is released, v1 will be deprecated. deprecated.
👉 [go-toml v2][v2] 👉 [go-toml v2][v2]

19
vendor/github.com/pelletier/go-toml/SECURITY.md generated vendored Normal file
View File

@ -0,0 +1,19 @@
# Security Policy
## Supported Versions
Use this section to tell people about which versions of your project are
currently being supported with security updates.
| Version | Supported |
| ---------- | ------------------ |
| Latest 2.x | :white_check_mark: |
| All 1.x | :x: |
| All 0.x | :x: |
## Reporting a Vulnerability
Email a vulnerability report to `security@pelletier.codes`. Make sure to include
as many details as possible to reproduce the vulnerability. This is a
side-project: I will try to get back to you as quickly as possible, time
permitting in my personal life. Providing a working patch helps very much!

View File

@ -1113,7 +1113,7 @@ func (d *Decoder) valueFromToml(mtype reflect.Type, tval interface{}, mval1 *ref
return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v", tval, tval, mtype.String()) return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v", tval, tval, mtype.String())
} }
if val.Convert(reflect.TypeOf(int(1))).Int() < 0 { if val.Type().Kind() != reflect.Uint64 && val.Convert(reflect.TypeOf(int(1))).Int() < 0 {
return reflect.ValueOf(nil), fmt.Errorf("%v(%T) is negative so does not fit in %v", tval, tval, mtype.String()) return reflect.ValueOf(nil), fmt.Errorf("%v(%T) is negative so does not fit in %v", tval, tval, mtype.String())
} }
if reflect.Indirect(reflect.New(mtype)).OverflowUint(val.Convert(reflect.TypeOf(uint64(0))).Uint()) { if reflect.Indirect(reflect.New(mtype)).OverflowUint(val.Convert(reflect.TypeOf(uint64(0))).Uint()) {

View File

@ -293,42 +293,41 @@ func (p *tomlParser) parseRvalue() interface{} {
return math.NaN() return math.NaN()
case tokenInteger: case tokenInteger:
cleanedVal := cleanupNumberToken(tok.val) cleanedVal := cleanupNumberToken(tok.val)
var err error base := 10
var val int64 s := cleanedVal
checkInvalidUnderscore := numberContainsInvalidUnderscore
if len(cleanedVal) >= 3 && cleanedVal[0] == '0' { if len(cleanedVal) >= 3 && cleanedVal[0] == '0' {
switch cleanedVal[1] { switch cleanedVal[1] {
case 'x': case 'x':
err = hexNumberContainsInvalidUnderscore(tok.val) checkInvalidUnderscore = hexNumberContainsInvalidUnderscore
if err != nil { base = 16
p.raiseError(tok, "%s", err)
}
val, err = strconv.ParseInt(cleanedVal[2:], 16, 64)
case 'o': case 'o':
err = numberContainsInvalidUnderscore(tok.val) base = 8
if err != nil {
p.raiseError(tok, "%s", err)
}
val, err = strconv.ParseInt(cleanedVal[2:], 8, 64)
case 'b': case 'b':
err = numberContainsInvalidUnderscore(tok.val) base = 2
if err != nil {
p.raiseError(tok, "%s", err)
}
val, err = strconv.ParseInt(cleanedVal[2:], 2, 64)
default: default:
panic("invalid base") // the lexer should catch this first panic("invalid base") // the lexer should catch this first
} }
} else { s = cleanedVal[2:]
err = numberContainsInvalidUnderscore(tok.val)
if err != nil {
p.raiseError(tok, "%s", err)
}
val, err = strconv.ParseInt(cleanedVal, 10, 64)
} }
err := checkInvalidUnderscore(tok.val)
if err != nil { if err != nil {
p.raiseError(tok, "%s", err) p.raiseError(tok, "%s", err)
} }
return val
var val interface{}
val, err = strconv.ParseInt(s, base, 64)
if err == nil {
return val
}
if s[0] != '-' {
if val, err = strconv.ParseUint(s, base, 64); err == nil {
return val
}
}
p.raiseError(tok, "%s", err)
case tokenFloat: case tokenFloat:
err := numberContainsInvalidUnderscore(tok.val) err := numberContainsInvalidUnderscore(tok.val)
if err != nil { if err != nil {

View File

@ -471,7 +471,7 @@ func LoadBytes(b []byte) (tree *Tree, err error) {
if _, ok := r.(runtime.Error); ok { if _, ok := r.(runtime.Error); ok {
panic(r) panic(r)
} }
err = errors.New(r.(string)) err = fmt.Errorf("%s", r)
} }
}() }()

View File

@ -1,6 +1,6 @@
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2013 - 2021 Thomas Pelletier, Eric Anderton Copyright (c) 2013 - 2022 Thomas Pelletier, Eric Anderton
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -4,17 +4,6 @@ Go library for the [TOML](https://toml.io/en/) format.
This library supports [TOML v1.0.0](https://toml.io/en/v1.0.0). This library supports [TOML v1.0.0](https://toml.io/en/v1.0.0).
## Development status
This is the upcoming major version of go-toml. It is currently in active
development. As of release v2.0.0-beta.1, the library has reached feature parity
with v1, and fixes a lot known bugs and performance issues along the way.
If you do not need the advanced document editing features of v1, you are
encouraged to try out this version.
[👉 Roadmap for v2](https://github.com/pelletier/go-toml/discussions/506)
[🐞 Bug Reports](https://github.com/pelletier/go-toml/issues) [🐞 Bug Reports](https://github.com/pelletier/go-toml/issues)
[💬 Anything else](https://github.com/pelletier/go-toml/discussions) [💬 Anything else](https://github.com/pelletier/go-toml/discussions)
@ -49,7 +38,7 @@ operations should not be shockingly slow. See [benchmarks](#benchmarks).
### Strict mode ### Strict mode
`Decoder` can be set to "strict mode", which makes it error when some parts of `Decoder` can be set to "strict mode", which makes it error when some parts of
the TOML document was not prevent in the target structure. This is a great way the TOML document was not present in the target structure. This is a great way
to check for typos. [See example in the documentation][strict]. to check for typos. [See example in the documentation][strict].
[strict]: https://pkg.go.dev/github.com/pelletier/go-toml/v2#example-Decoder.DisallowUnknownFields [strict]: https://pkg.go.dev/github.com/pelletier/go-toml/v2#example-Decoder.DisallowUnknownFields
@ -551,6 +540,13 @@ complete solutions exist out there.
[query]: https://github.com/pelletier/go-toml/tree/f99d6bbca119636aeafcf351ee52b3d202782627/query [query]: https://github.com/pelletier/go-toml/tree/f99d6bbca119636aeafcf351ee52b3d202782627/query
[dasel]: https://github.com/TomWright/dasel [dasel]: https://github.com/TomWright/dasel
## Versioning
Go-toml follows [Semantic Versioning](http://semver.org/). The supported version
of [TOML](https://github.com/toml-lang/toml) is indicated at the beginning of
this document. The last two major versions of Go are supported
(see [Go Release Policy](https://golang.org/doc/devel/release.html#policy)).
## License ## License
The MIT License (MIT). Read [LICENSE](LICENSE). The MIT License (MIT). Read [LICENSE](LICENSE).

View File

@ -128,7 +128,8 @@ func (enc *Encoder) SetIndentTables(indent bool) *Encoder {
// //
// In addition to the "toml" tag struct tag, a "comment" tag can be used to emit // In addition to the "toml" tag struct tag, a "comment" tag can be used to emit
// a TOML comment before the value being annotated. Comments are ignored inside // a TOML comment before the value being annotated. Comments are ignored inside
// inline tables. // inline tables. For array tables, the comment is only present before the first
// element of the array.
func (enc *Encoder) Encode(v interface{}) error { func (enc *Encoder) Encode(v interface{}) error {
var ( var (
b []byte b []byte
@ -652,10 +653,19 @@ func (enc *Encoder) encodeStruct(b []byte, ctx encoderCtx, v reflect.Value) ([]b
} }
func (enc *Encoder) encodeComment(indent int, comment string, b []byte) []byte { func (enc *Encoder) encodeComment(indent int, comment string, b []byte) []byte {
if comment != "" { for len(comment) > 0 {
var line string
idx := strings.IndexByte(comment, '\n')
if idx >= 0 {
line = comment[:idx]
comment = comment[idx+1:]
} else {
line = comment
comment = ""
}
b = enc.indent(indent, b) b = enc.indent(indent, b)
b = append(b, "# "...) b = append(b, "# "...)
b = append(b, comment...) b = append(b, line...)
b = append(b, '\n') b = append(b, '\n')
} }
return b return b
@ -881,6 +891,8 @@ func (enc *Encoder) encodeSliceAsArrayTable(b []byte, ctx encoderCtx, v reflect.
scratch = append(scratch, "]]\n"...) scratch = append(scratch, "]]\n"...)
ctx.skipTableHeader = true ctx.skipTableHeader = true
b = enc.encodeComment(ctx.indent, ctx.options.comment, b)
for i := 0; i < v.Len(); i++ { for i := 0; i < v.Len(); i++ {
b = append(b, scratch...) b = append(b, scratch...)

View File

@ -866,12 +866,27 @@ func (d *decoder) unmarshalFloat(value *ast.Node, v reflect.Value) error {
return nil return nil
} }
func (d *decoder) unmarshalInteger(value *ast.Node, v reflect.Value) error { const (
const ( maxInt = int64(^uint(0) >> 1)
maxInt = int64(^uint(0) >> 1) minInt = -maxInt - 1
minInt = -maxInt - 1 )
)
// Maximum value of uint for decoding. Currently the decoder parses the integer
// into an int64. As a result, on architectures where uint is 64 bits, the
// effective maximum uint we can decode is the maximum of int64. On
// architectures where uint is 32 bits, the maximum value we can decode is
// lower: the maximum of uint32. I didn't find a way to figure out this value at
// compile time, so it is computed during initialization.
var maxUint int64 = math.MaxInt64
func init() {
m := uint64(^uint(0))
if m < uint64(maxUint) {
maxUint = int64(m)
}
}
func (d *decoder) unmarshalInteger(value *ast.Node, v reflect.Value) error {
i, err := parseInteger(value.Data) i, err := parseInteger(value.Data)
if err != nil { if err != nil {
return err return err
@ -932,7 +947,7 @@ func (d *decoder) unmarshalInteger(value *ast.Node, v reflect.Value) error {
r = reflect.ValueOf(uint8(i)) r = reflect.ValueOf(uint8(i))
case reflect.Uint: case reflect.Uint:
if i < 0 { if i < 0 || i > maxUint {
return fmt.Errorf("toml: negative number %d does not fit in an uint", i) return fmt.Errorf("toml: negative number %d does not fit in an uint", i)
} }
@ -1167,11 +1182,6 @@ func forEachField(t reflect.Type, path []int, do func(name string, path []int))
fieldPath := append(path, i) fieldPath := append(path, i)
fieldPath = fieldPath[:len(fieldPath):len(fieldPath)] fieldPath = fieldPath[:len(fieldPath):len(fieldPath)]
if f.Anonymous {
forEachField(f.Type, fieldPath, do)
continue
}
name := f.Tag.Get("toml") name := f.Tag.Get("toml")
if name == "-" { if name == "-" {
continue continue
@ -1180,6 +1190,12 @@ func forEachField(t reflect.Type, path []int, do func(name string, path []int))
if i := strings.IndexByte(name, ','); i >= 0 { if i := strings.IndexByte(name, ','); i >= 0 {
name = name[:i] name = name[:i]
} }
if f.Anonymous && name == "" {
forEachField(f.Type, fieldPath, do)
continue
}
if name == "" { if name == "" {
name = f.Name name = f.Name
} }

327
vendor/github.com/spf13/cast/caste.go generated vendored
View File

@ -34,6 +34,12 @@ func ToTimeInDefaultLocationE(i interface{}, location *time.Location) (tim time.
return v, nil return v, nil
case string: case string:
return StringToDateInDefaultLocation(v, location) return StringToDateInDefaultLocation(v, location)
case json.Number:
s, err1 := ToInt64E(v)
if err1 != nil {
return time.Time{}, fmt.Errorf("unable to cast %#v of type %T to Time", i, i)
}
return time.Unix(s, 0), nil
case int: case int:
return time.Unix(int64(v), 0), nil return time.Unix(int64(v), 0), nil
case int64: case int64:
@ -71,6 +77,11 @@ func ToDurationE(i interface{}) (d time.Duration, err error) {
d, err = time.ParseDuration(s + "ns") d, err = time.ParseDuration(s + "ns")
} }
return return
case json.Number:
var v float64
v, err = s.Float64()
d = time.Duration(v)
return
default: default:
err = fmt.Errorf("unable to cast %#v of type %T to Duration", i, i) err = fmt.Errorf("unable to cast %#v of type %T to Duration", i, i)
return return
@ -93,6 +104,12 @@ func ToBoolE(i interface{}) (bool, error) {
return false, nil return false, nil
case string: case string:
return strconv.ParseBool(i.(string)) return strconv.ParseBool(i.(string))
case json.Number:
v, err := ToInt64E(b)
if err == nil {
return v != 0, nil
}
return false, fmt.Errorf("unable to cast %#v of type %T to bool", i, i)
default: default:
return false, fmt.Errorf("unable to cast %#v of type %T to bool", i, i) return false, fmt.Errorf("unable to cast %#v of type %T to bool", i, i)
} }
@ -102,13 +119,16 @@ func ToBoolE(i interface{}) (bool, error) {
func ToFloat64E(i interface{}) (float64, error) { func ToFloat64E(i interface{}) (float64, error) {
i = indirect(i) i = indirect(i)
intv, ok := toInt(i)
if ok {
return float64(intv), nil
}
switch s := i.(type) { switch s := i.(type) {
case float64: case float64:
return s, nil return s, nil
case float32: case float32:
return float64(s), nil return float64(s), nil
case int:
return float64(s), nil
case int64: case int64:
return float64(s), nil return float64(s), nil
case int32: case int32:
@ -133,11 +153,19 @@ func ToFloat64E(i interface{}) (float64, error) {
return v, nil return v, nil
} }
return 0, fmt.Errorf("unable to cast %#v of type %T to float64", i, i) return 0, fmt.Errorf("unable to cast %#v of type %T to float64", i, i)
case json.Number:
v, err := s.Float64()
if err == nil {
return v, nil
}
return 0, fmt.Errorf("unable to cast %#v of type %T to float64", i, i)
case bool: case bool:
if s { if s {
return 1, nil return 1, nil
} }
return 0, nil return 0, nil
case nil:
return 0, nil
default: default:
return 0, fmt.Errorf("unable to cast %#v of type %T to float64", i, i) return 0, fmt.Errorf("unable to cast %#v of type %T to float64", i, i)
} }
@ -147,13 +175,16 @@ func ToFloat64E(i interface{}) (float64, error) {
func ToFloat32E(i interface{}) (float32, error) { func ToFloat32E(i interface{}) (float32, error) {
i = indirect(i) i = indirect(i)
intv, ok := toInt(i)
if ok {
return float32(intv), nil
}
switch s := i.(type) { switch s := i.(type) {
case float64: case float64:
return float32(s), nil return float32(s), nil
case float32: case float32:
return s, nil return s, nil
case int:
return float32(s), nil
case int64: case int64:
return float32(s), nil return float32(s), nil
case int32: case int32:
@ -178,11 +209,19 @@ func ToFloat32E(i interface{}) (float32, error) {
return float32(v), nil return float32(v), nil
} }
return 0, fmt.Errorf("unable to cast %#v of type %T to float32", i, i) return 0, fmt.Errorf("unable to cast %#v of type %T to float32", i, i)
case json.Number:
v, err := s.Float64()
if err == nil {
return float32(v), nil
}
return 0, fmt.Errorf("unable to cast %#v of type %T to float32", i, i)
case bool: case bool:
if s { if s {
return 1, nil return 1, nil
} }
return 0, nil return 0, nil
case nil:
return 0, nil
default: default:
return 0, fmt.Errorf("unable to cast %#v of type %T to float32", i, i) return 0, fmt.Errorf("unable to cast %#v of type %T to float32", i, i)
} }
@ -192,9 +231,12 @@ func ToFloat32E(i interface{}) (float32, error) {
func ToInt64E(i interface{}) (int64, error) { func ToInt64E(i interface{}) (int64, error) {
i = indirect(i) i = indirect(i)
intv, ok := toInt(i)
if ok {
return int64(intv), nil
}
switch s := i.(type) { switch s := i.(type) {
case int:
return int64(s), nil
case int64: case int64:
return s, nil return s, nil
case int32: case int32:
@ -218,11 +260,13 @@ func ToInt64E(i interface{}) (int64, error) {
case float32: case float32:
return int64(s), nil return int64(s), nil
case string: case string:
v, err := strconv.ParseInt(s, 0, 0) v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
if err == nil { if err == nil {
return v, nil return v, nil
} }
return 0, fmt.Errorf("unable to cast %#v of type %T to int64", i, i) return 0, fmt.Errorf("unable to cast %#v of type %T to int64", i, i)
case json.Number:
return ToInt64E(string(s))
case bool: case bool:
if s { if s {
return 1, nil return 1, nil
@ -239,9 +283,12 @@ func ToInt64E(i interface{}) (int64, error) {
func ToInt32E(i interface{}) (int32, error) { func ToInt32E(i interface{}) (int32, error) {
i = indirect(i) i = indirect(i)
intv, ok := toInt(i)
if ok {
return int32(intv), nil
}
switch s := i.(type) { switch s := i.(type) {
case int:
return int32(s), nil
case int64: case int64:
return int32(s), nil return int32(s), nil
case int32: case int32:
@ -265,11 +312,13 @@ func ToInt32E(i interface{}) (int32, error) {
case float32: case float32:
return int32(s), nil return int32(s), nil
case string: case string:
v, err := strconv.ParseInt(s, 0, 0) v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
if err == nil { if err == nil {
return int32(v), nil return int32(v), nil
} }
return 0, fmt.Errorf("unable to cast %#v of type %T to int32", i, i) return 0, fmt.Errorf("unable to cast %#v of type %T to int32", i, i)
case json.Number:
return ToInt32E(string(s))
case bool: case bool:
if s { if s {
return 1, nil return 1, nil
@ -286,9 +335,12 @@ func ToInt32E(i interface{}) (int32, error) {
func ToInt16E(i interface{}) (int16, error) { func ToInt16E(i interface{}) (int16, error) {
i = indirect(i) i = indirect(i)
intv, ok := toInt(i)
if ok {
return int16(intv), nil
}
switch s := i.(type) { switch s := i.(type) {
case int:
return int16(s), nil
case int64: case int64:
return int16(s), nil return int16(s), nil
case int32: case int32:
@ -312,11 +364,13 @@ func ToInt16E(i interface{}) (int16, error) {
case float32: case float32:
return int16(s), nil return int16(s), nil
case string: case string:
v, err := strconv.ParseInt(s, 0, 0) v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
if err == nil { if err == nil {
return int16(v), nil return int16(v), nil
} }
return 0, fmt.Errorf("unable to cast %#v of type %T to int16", i, i) return 0, fmt.Errorf("unable to cast %#v of type %T to int16", i, i)
case json.Number:
return ToInt16E(string(s))
case bool: case bool:
if s { if s {
return 1, nil return 1, nil
@ -333,9 +387,12 @@ func ToInt16E(i interface{}) (int16, error) {
func ToInt8E(i interface{}) (int8, error) { func ToInt8E(i interface{}) (int8, error) {
i = indirect(i) i = indirect(i)
intv, ok := toInt(i)
if ok {
return int8(intv), nil
}
switch s := i.(type) { switch s := i.(type) {
case int:
return int8(s), nil
case int64: case int64:
return int8(s), nil return int8(s), nil
case int32: case int32:
@ -359,11 +416,13 @@ func ToInt8E(i interface{}) (int8, error) {
case float32: case float32:
return int8(s), nil return int8(s), nil
case string: case string:
v, err := strconv.ParseInt(s, 0, 0) v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
if err == nil { if err == nil {
return int8(v), nil return int8(v), nil
} }
return 0, fmt.Errorf("unable to cast %#v of type %T to int8", i, i) return 0, fmt.Errorf("unable to cast %#v of type %T to int8", i, i)
case json.Number:
return ToInt8E(string(s))
case bool: case bool:
if s { if s {
return 1, nil return 1, nil
@ -380,9 +439,12 @@ func ToInt8E(i interface{}) (int8, error) {
func ToIntE(i interface{}) (int, error) { func ToIntE(i interface{}) (int, error) {
i = indirect(i) i = indirect(i)
intv, ok := toInt(i)
if ok {
return intv, nil
}
switch s := i.(type) { switch s := i.(type) {
case int:
return s, nil
case int64: case int64:
return int(s), nil return int(s), nil
case int32: case int32:
@ -406,11 +468,13 @@ func ToIntE(i interface{}) (int, error) {
case float32: case float32:
return int(s), nil return int(s), nil
case string: case string:
v, err := strconv.ParseInt(s, 0, 0) v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
if err == nil { if err == nil {
return int(v), nil return int(v), nil
} }
return 0, fmt.Errorf("unable to cast %#v of type %T to int", i, i) return 0, fmt.Errorf("unable to cast %#v of type %T to int64", i, i)
case json.Number:
return ToIntE(string(s))
case bool: case bool:
if s { if s {
return 1, nil return 1, nil
@ -427,18 +491,26 @@ func ToIntE(i interface{}) (int, error) {
func ToUintE(i interface{}) (uint, error) { func ToUintE(i interface{}) (uint, error) {
i = indirect(i) i = indirect(i)
switch s := i.(type) { intv, ok := toInt(i)
case string: if ok {
v, err := strconv.ParseUint(s, 0, 0) if intv < 0 {
if err == nil {
return uint(v), nil
}
return 0, fmt.Errorf("unable to cast %#v to uint: %s", i, err)
case int:
if s < 0 {
return 0, errNegativeNotAllowed return 0, errNegativeNotAllowed
} }
return uint(s), nil return uint(intv), nil
}
switch s := i.(type) {
case string:
v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
if err == nil {
if v < 0 {
return 0, errNegativeNotAllowed
}
return uint(v), nil
}
return 0, fmt.Errorf("unable to cast %#v of type %T to uint", i, i)
case json.Number:
return ToUintE(string(s))
case int64: case int64:
if s < 0 { if s < 0 {
return 0, errNegativeNotAllowed return 0, errNegativeNotAllowed
@ -495,18 +567,26 @@ func ToUintE(i interface{}) (uint, error) {
func ToUint64E(i interface{}) (uint64, error) { func ToUint64E(i interface{}) (uint64, error) {
i = indirect(i) i = indirect(i)
switch s := i.(type) { intv, ok := toInt(i)
case string: if ok {
v, err := strconv.ParseUint(s, 0, 64) if intv < 0 {
if err == nil {
return v, nil
}
return 0, fmt.Errorf("unable to cast %#v to uint64: %s", i, err)
case int:
if s < 0 {
return 0, errNegativeNotAllowed return 0, errNegativeNotAllowed
} }
return uint64(s), nil return uint64(intv), nil
}
switch s := i.(type) {
case string:
v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
if err == nil {
if v < 0 {
return 0, errNegativeNotAllowed
}
return uint64(v), nil
}
return 0, fmt.Errorf("unable to cast %#v of type %T to uint64", i, i)
case json.Number:
return ToUint64E(string(s))
case int64: case int64:
if s < 0 { if s < 0 {
return 0, errNegativeNotAllowed return 0, errNegativeNotAllowed
@ -563,18 +643,26 @@ func ToUint64E(i interface{}) (uint64, error) {
func ToUint32E(i interface{}) (uint32, error) { func ToUint32E(i interface{}) (uint32, error) {
i = indirect(i) i = indirect(i)
switch s := i.(type) { intv, ok := toInt(i)
case string: if ok {
v, err := strconv.ParseUint(s, 0, 32) if intv < 0 {
if err == nil {
return uint32(v), nil
}
return 0, fmt.Errorf("unable to cast %#v to uint32: %s", i, err)
case int:
if s < 0 {
return 0, errNegativeNotAllowed return 0, errNegativeNotAllowed
} }
return uint32(s), nil return uint32(intv), nil
}
switch s := i.(type) {
case string:
v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
if err == nil {
if v < 0 {
return 0, errNegativeNotAllowed
}
return uint32(v), nil
}
return 0, fmt.Errorf("unable to cast %#v of type %T to uint32", i, i)
case json.Number:
return ToUint32E(string(s))
case int64: case int64:
if s < 0 { if s < 0 {
return 0, errNegativeNotAllowed return 0, errNegativeNotAllowed
@ -631,18 +719,26 @@ func ToUint32E(i interface{}) (uint32, error) {
func ToUint16E(i interface{}) (uint16, error) { func ToUint16E(i interface{}) (uint16, error) {
i = indirect(i) i = indirect(i)
switch s := i.(type) { intv, ok := toInt(i)
case string: if ok {
v, err := strconv.ParseUint(s, 0, 16) if intv < 0 {
if err == nil {
return uint16(v), nil
}
return 0, fmt.Errorf("unable to cast %#v to uint16: %s", i, err)
case int:
if s < 0 {
return 0, errNegativeNotAllowed return 0, errNegativeNotAllowed
} }
return uint16(s), nil return uint16(intv), nil
}
switch s := i.(type) {
case string:
v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
if err == nil {
if v < 0 {
return 0, errNegativeNotAllowed
}
return uint16(v), nil
}
return 0, fmt.Errorf("unable to cast %#v of type %T to uint16", i, i)
case json.Number:
return ToUint16E(string(s))
case int64: case int64:
if s < 0 { if s < 0 {
return 0, errNegativeNotAllowed return 0, errNegativeNotAllowed
@ -699,18 +795,26 @@ func ToUint16E(i interface{}) (uint16, error) {
func ToUint8E(i interface{}) (uint8, error) { func ToUint8E(i interface{}) (uint8, error) {
i = indirect(i) i = indirect(i)
switch s := i.(type) { intv, ok := toInt(i)
case string: if ok {
v, err := strconv.ParseUint(s, 0, 8) if intv < 0 {
if err == nil {
return uint8(v), nil
}
return 0, fmt.Errorf("unable to cast %#v to uint8: %s", i, err)
case int:
if s < 0 {
return 0, errNegativeNotAllowed return 0, errNegativeNotAllowed
} }
return uint8(s), nil return uint8(intv), nil
}
switch s := i.(type) {
case string:
v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
if err == nil {
if v < 0 {
return 0, errNegativeNotAllowed
}
return uint8(v), nil
}
return 0, fmt.Errorf("unable to cast %#v of type %T to uint8", i, i)
case json.Number:
return ToUint8E(string(s))
case int64: case int64:
if s < 0 { if s < 0 {
return 0, errNegativeNotAllowed return 0, errNegativeNotAllowed
@ -835,6 +939,8 @@ func ToStringE(i interface{}) (string, error) {
return strconv.FormatUint(uint64(s), 10), nil return strconv.FormatUint(uint64(s), 10), nil
case uint8: case uint8:
return strconv.FormatUint(uint64(s), 10), nil return strconv.FormatUint(uint64(s), 10), nil
case json.Number:
return s.String(), nil
case []byte: case []byte:
return string(s), nil return string(s), nil
case template.HTML: case template.HTML:
@ -1279,30 +1385,30 @@ func (f timeFormat) hasTimezone() bool {
var ( var (
timeFormats = []timeFormat{ timeFormats = []timeFormat{
timeFormat{time.RFC3339, timeFormatNumericTimezone}, {time.RFC3339, timeFormatNumericTimezone},
timeFormat{"2006-01-02T15:04:05", timeFormatNoTimezone}, // iso8601 without timezone {"2006-01-02T15:04:05", timeFormatNoTimezone}, // iso8601 without timezone
timeFormat{time.RFC1123Z, timeFormatNumericTimezone}, {time.RFC1123Z, timeFormatNumericTimezone},
timeFormat{time.RFC1123, timeFormatNamedTimezone}, {time.RFC1123, timeFormatNamedTimezone},
timeFormat{time.RFC822Z, timeFormatNumericTimezone}, {time.RFC822Z, timeFormatNumericTimezone},
timeFormat{time.RFC822, timeFormatNamedTimezone}, {time.RFC822, timeFormatNamedTimezone},
timeFormat{time.RFC850, timeFormatNamedTimezone}, {time.RFC850, timeFormatNamedTimezone},
timeFormat{"2006-01-02 15:04:05.999999999 -0700 MST", timeFormatNumericAndNamedTimezone}, // Time.String() {"2006-01-02 15:04:05.999999999 -0700 MST", timeFormatNumericAndNamedTimezone}, // Time.String()
timeFormat{"2006-01-02T15:04:05-0700", timeFormatNumericTimezone}, // RFC3339 without timezone hh:mm colon {"2006-01-02T15:04:05-0700", timeFormatNumericTimezone}, // RFC3339 without timezone hh:mm colon
timeFormat{"2006-01-02 15:04:05Z0700", timeFormatNumericTimezone}, // RFC3339 without T or timezone hh:mm colon {"2006-01-02 15:04:05Z0700", timeFormatNumericTimezone}, // RFC3339 without T or timezone hh:mm colon
timeFormat{"2006-01-02 15:04:05", timeFormatNoTimezone}, {"2006-01-02 15:04:05", timeFormatNoTimezone},
timeFormat{time.ANSIC, timeFormatNoTimezone}, {time.ANSIC, timeFormatNoTimezone},
timeFormat{time.UnixDate, timeFormatNamedTimezone}, {time.UnixDate, timeFormatNamedTimezone},
timeFormat{time.RubyDate, timeFormatNumericTimezone}, {time.RubyDate, timeFormatNumericTimezone},
timeFormat{"2006-01-02 15:04:05Z07:00", timeFormatNumericTimezone}, {"2006-01-02 15:04:05Z07:00", timeFormatNumericTimezone},
timeFormat{"2006-01-02", timeFormatNoTimezone}, {"2006-01-02", timeFormatNoTimezone},
timeFormat{"02 Jan 2006", timeFormatNoTimezone}, {"02 Jan 2006", timeFormatNoTimezone},
timeFormat{"2006-01-02 15:04:05 -07:00", timeFormatNumericTimezone}, {"2006-01-02 15:04:05 -07:00", timeFormatNumericTimezone},
timeFormat{"2006-01-02 15:04:05 -0700", timeFormatNumericTimezone}, {"2006-01-02 15:04:05 -0700", timeFormatNumericTimezone},
timeFormat{time.Kitchen, timeFormatTimeOnly}, {time.Kitchen, timeFormatTimeOnly},
timeFormat{time.Stamp, timeFormatTimeOnly}, {time.Stamp, timeFormatTimeOnly},
timeFormat{time.StampMilli, timeFormatTimeOnly}, {time.StampMilli, timeFormatTimeOnly},
timeFormat{time.StampMicro, timeFormatTimeOnly}, {time.StampMicro, timeFormatTimeOnly},
timeFormat{time.StampNano, timeFormatTimeOnly}, {time.StampNano, timeFormatTimeOnly},
} }
) )
@ -1335,3 +1441,36 @@ func jsonStringToObject(s string, v interface{}) error {
data := []byte(s) data := []byte(s)
return json.Unmarshal(data, v) return json.Unmarshal(data, v)
} }
// toInt returns the int value of v if v or v's underlying type
// is an int.
// Note that this will return false for int64 etc. types.
func toInt(v interface{}) (int, bool) {
switch v := v.(type) {
case int:
return v, true
case time.Weekday:
return int(v), true
case time.Month:
return int(v), true
default:
return 0, false
}
}
func trimZeroDecimal(s string) string {
var foundZero bool
for i := len(s); i > 0; i-- {
switch s[i-1] {
case '.':
if foundZero {
return s[:i-1]
}
case '0':
foundZero = true
default:
return s
}
}
return s
}

View File

@ -11,5 +11,5 @@ trim_trailing_whitespace = true
[*.go] [*.go]
indent_style = tab indent_style = tab
[{Makefile, *.mk}] [{Makefile,*.mk}]
indent_style = tab indent_style = tab

View File

@ -1,5 +1,5 @@
//go:build !viper_toml2 //go:build viper_toml1
// +build !viper_toml2 // +build viper_toml1
package toml package toml

View File

@ -1,5 +1,5 @@
//go:build viper_toml2 //go:build !viper_toml1
// +build viper_toml2 // +build !viper_toml1
package toml package toml

View File

@ -1,5 +1,5 @@
//go:build !viper_yaml3 //go:build viper_yaml2
// +build !viper_yaml3 // +build viper_yaml2
package yaml package yaml

View File

@ -1,5 +1,5 @@
//go:build viper_yaml3 //go:build !viper_yaml2
// +build viper_yaml3 // +build !viper_yaml2
package yaml package yaml

View File

@ -1197,6 +1197,17 @@ func (v *Viper) BindEnv(input ...string) error {
return nil return nil
} }
// MustBindEnv wraps BindEnv in a panic.
// If there is an error binding an environment variable, MustBindEnv will
// panic.
func MustBindEnv(input ...string) { v.MustBindEnv(input...) }
func (v *Viper) MustBindEnv(input ...string) {
if err := v.BindEnv(input...); err != nil {
panic(fmt.Sprintf("error while binding environment variable: %v", err))
}
}
// Given a key, find the value. // Given a key, find the value.
// //
// Viper will check to see if an alias exists first. // Viper will check to see if an alias exists first.
@ -1798,8 +1809,13 @@ func mergeMaps(
tsv, ok := sv.(map[interface{}]interface{}) tsv, ok := sv.(map[interface{}]interface{})
if !ok { if !ok {
v.logger.Error( v.logger.Error(
"Could not cast sv to map[interface{}]interface{}; key=%s, st=%v, tt=%v, sv=%v, tv=%v", "Could not cast sv to map[interface{}]interface{}",
sk, svType, tvType, sv, tv) "key", sk,
"st", svType,
"tt", tvType,
"sv", sv,
"tv", tv,
)
continue continue
} }
@ -1811,8 +1827,13 @@ func mergeMaps(
tsv, ok := sv.(map[string]interface{}) tsv, ok := sv.(map[string]interface{})
if !ok { if !ok {
v.logger.Error( v.logger.Error(
"Could not cast sv to map[string]interface{}; key=%s, st=%v, tt=%v, sv=%v, tv=%v", "Could not cast sv to map[string]interface{}",
sk, svType, tvType, sv, tv) "key", sk,
"st", svType,
"tt", tvType,
"sv", sv,
"tv", tv,
)
continue continue
} }
mergeMaps(tsv, ttv, nil) mergeMaps(tsv, ttv, nil)

View File

@ -1,10 +0,0 @@
language: go
go:
- 1.x
os:
- linux
- osx
script:
- go test -test.v -coverprofile=coverage.out -covermode=count
after_success:
- bash <(curl -s https://codecov.io/bash)

View File

@ -1,5 +1,16 @@
# Changelog # Changelog
## [1.3.0] - 2022-05-23
### Added
- Support = within double-quoted strings
- Add support for multiline values
### Changed
- `OverLoad` prefer environment variables over local variables
## [1.2.0] - 2019-08-03 ## [1.2.0] - 2019-08-03
### Added ### Added

View File

@ -1,12 +1,11 @@
# gotenv # gotenv
[![Build Status](https://travis-ci.org/subosito/gotenv.svg?branch=master)](https://travis-ci.org/subosito/gotenv) [![Build Status](https://github.com/subosito/gotenv/workflows/Go%20workflow/badge.svg)](https://github.com/subosito/gotenv/actions)
[![Build status](https://ci.appveyor.com/api/projects/status/wb2e075xkfl0m0v2/branch/master?svg=true)](https://ci.appveyor.com/project/subosito/gotenv/branch/master)
[![Coverage Status](https://badgen.net/codecov/c/github/subosito/gotenv)](https://codecov.io/gh/subosito/gotenv) [![Coverage Status](https://badgen.net/codecov/c/github/subosito/gotenv)](https://codecov.io/gh/subosito/gotenv)
[![Go Report Card](https://goreportcard.com/badge/github.com/subosito/gotenv)](https://goreportcard.com/report/github.com/subosito/gotenv) [![Go Report Card](https://goreportcard.com/badge/github.com/subosito/gotenv)](https://goreportcard.com/report/github.com/subosito/gotenv)
[![GoDoc](https://godoc.org/github.com/subosito/gotenv?status.svg)](https://godoc.org/github.com/subosito/gotenv) [![GoDoc](https://godoc.org/github.com/subosito/gotenv?status.svg)](https://godoc.org/github.com/subosito/gotenv)
Load environment variables dynamically in Go. Load environment variables from `.env` or `io.Reader` in Go.
## Usage ## Usage
@ -120,7 +119,7 @@ Just in case you want to parse environment variables from any `io.Reader`, goten
pairs := gotenv.Parse(strings.NewReader("FOO=test\nBAR=$FOO")) pairs := gotenv.Parse(strings.NewReader("FOO=test\nBAR=$FOO"))
// gotenv.Env{"FOO": "test", "BAR": "test"} // gotenv.Env{"FOO": "test", "BAR": "test"}
err, pairs = gotenv.StrictParse(strings.NewReader(`FOO="bar"`)) pairs, err := gotenv.StrictParse(strings.NewReader(`FOO="bar"`))
// gotenv.Env{"FOO": "bar"} // gotenv.Env{"FOO": "bar"}
``` ```

View File

@ -1,9 +0,0 @@
build: off
clone_folder: c:\gopath\src\github.com\subosito\gotenv
environment:
GOPATH: c:\gopath
stack: go 1.10
before_test:
- go get -t
test_script:
- go test -v -cover -race

View File

@ -16,6 +16,9 @@ const (
// Pattern for detecting valid variable within a value // Pattern for detecting valid variable within a value
variablePattern = `(\\)?(\$)(\{?([A-Z0-9_]+)?\}?)` variablePattern = `(\\)?(\$)(\{?([A-Z0-9_]+)?\}?)`
// Byte order mark character
bom = "\xef\xbb\xbf"
) )
// Env holds key/value pair of valid environment variable // Env holds key/value pair of valid environment variable
@ -84,7 +87,7 @@ func loadenv(override bool, filenames ...string) error {
// parse and set :) // parse and set :)
func parset(r io.Reader, override bool) error { func parset(r io.Reader, override bool) error {
env, err := StrictParse(r) env, err := strictParse(r, override)
if err != nil { if err != nil {
return err return err
} }
@ -110,7 +113,7 @@ func setenv(key, val string, override bool) {
// It expands the value of a variable from the environment variable but does not set the value to the environment itself. // It expands the value of a variable from the environment variable but does not set the value to the environment itself.
// This function is skipping any invalid lines and only processing the valid one. // This function is skipping any invalid lines and only processing the valid one.
func Parse(r io.Reader) Env { func Parse(r io.Reader) Env {
env, _ := StrictParse(r) env, _ := strictParse(r, false)
return env return env
} }
@ -118,22 +121,59 @@ func Parse(r io.Reader) Env {
// It expands the value of a variable from the environment variable but does not set the value to the environment itself. // It expands the value of a variable from the environment variable but does not set the value to the environment itself.
// This function is returning an error if there are any invalid lines. // This function is returning an error if there are any invalid lines.
func StrictParse(r io.Reader) (Env, error) { func StrictParse(r io.Reader) (Env, error) {
return strictParse(r, false)
}
func strictParse(r io.Reader, override bool) (Env, error) {
env := make(Env) env := make(Env)
scanner := bufio.NewScanner(r) scanner := bufio.NewScanner(r)
i := 1 firstLine := true
bom := string([]byte{239, 187, 191})
for scanner.Scan() { for scanner.Scan() {
line := scanner.Text() line := strings.TrimSpace(scanner.Text())
if i == 1 { if firstLine {
line = strings.TrimPrefix(line, bom) line = strings.TrimPrefix(line, bom)
firstLine = false
} }
i++ if line == "" || line[0] == '#' {
continue
}
err := parseLine(line, env) quote := ""
idx := strings.Index(line, "=")
if idx == -1 {
idx = strings.Index(line, ":")
}
if idx > 0 && idx < len(line)-1 {
val := strings.TrimSpace(line[idx+1:])
if val[0] == '"' || val[0] == '\'' {
quote = val[:1]
idx = strings.LastIndex(strings.TrimSpace(val[1:]), quote)
if idx >= 0 && val[idx] != '\\' {
quote = ""
}
}
}
for quote != "" && scanner.Scan() {
l := scanner.Text()
line += "\n" + l
idx := strings.LastIndex(l, quote)
if idx > 0 && l[idx-1] == '\\' {
continue
}
if idx >= 0 {
quote = ""
}
}
if quote != "" {
return env, fmt.Errorf("missing quotes")
}
err := parseLine(line, env, override)
if err != nil { if err != nil {
return env, err return env, err
} }
@ -142,9 +182,14 @@ func StrictParse(r io.Reader) (Env, error) {
return env, nil return env, nil
} }
func parseLine(s string, env Env) error { var (
rl := regexp.MustCompile(linePattern) lineRgx = regexp.MustCompile(linePattern)
rm := rl.FindStringSubmatch(s) unescapeRgx = regexp.MustCompile(`\\([^$])`)
varRgx = regexp.MustCompile(variablePattern)
)
func parseLine(s string, env Env, override bool) error {
rm := lineRgx.FindStringSubmatch(s)
if len(rm) == 0 { if len(rm) == 0 {
return checkFormat(s, env) return checkFormat(s, env)
@ -153,35 +198,36 @@ func parseLine(s string, env Env) error {
key := rm[1] key := rm[1]
val := rm[2] val := rm[2]
// trim whitespace
val = strings.TrimSpace(val)
// determine if string has quote prefix // determine if string has quote prefix
hdq := strings.HasPrefix(val, `"`) hdq := strings.HasPrefix(val, `"`)
// determine if string has single quote prefix // determine if string has single quote prefix
hsq := strings.HasPrefix(val, `'`) hsq := strings.HasPrefix(val, `'`)
// trim whitespace
val = strings.Trim(val, " ")
// remove quotes '' or "" // remove quotes '' or ""
rq := regexp.MustCompile(`\A(['"])(.*)(['"])\z`) if l := len(val); (hsq || hdq) && l >= 2 {
val = rq.ReplaceAllString(val, "$2") val = val[1 : l-1]
}
if hdq { if hdq {
val = strings.Replace(val, `\n`, "\n", -1) val = strings.ReplaceAll(val, `\n`, "\n")
val = strings.Replace(val, `\r`, "\r", -1) val = strings.ReplaceAll(val, `\r`, "\r")
// Unescape all characters except $ so variables can be escaped properly // Unescape all characters except $ so variables can be escaped properly
re := regexp.MustCompile(`\\([^$])`) val = unescapeRgx.ReplaceAllString(val, "$1")
val = re.ReplaceAllString(val, "$1")
} }
rv := regexp.MustCompile(variablePattern)
fv := func(s string) string { fv := func(s string) string {
return varReplacement(s, hsq, env) return varReplacement(s, hsq, env, override)
} }
val = rv.ReplaceAllStringFunc(val, fv) if !hsq {
val = parseVal(val, env) val = varRgx.ReplaceAllStringFunc(val, fv)
val = parseVal(val, env, hdq, override)
}
env[key] = val env[key] = val
return nil return nil
@ -201,7 +247,9 @@ func parseExport(st string, env Env) error {
return nil return nil
} }
func varReplacement(s string, hsq bool, env Env) string { var varNameRgx = regexp.MustCompile(`(\$)(\{?([A-Z0-9_]+)\}?)`)
func varReplacement(s string, hsq bool, env Env, override bool) string {
if strings.HasPrefix(s, "\\") { if strings.HasPrefix(s, "\\") {
return strings.TrimPrefix(s, "\\") return strings.TrimPrefix(s, "\\")
} }
@ -210,9 +258,7 @@ func varReplacement(s string, hsq bool, env Env) string {
return s return s
} }
sn := `(\$)(\{?([A-Z0-9_]+)\}?)` mn := varNameRgx.FindStringSubmatch(s)
rn := regexp.MustCompile(sn)
mn := rn.FindStringSubmatch(s)
if len(mn) == 0 { if len(mn) == 0 {
return s return s
@ -220,6 +266,10 @@ func varReplacement(s string, hsq bool, env Env) string {
v := mn[3] v := mn[3]
if replace, ok := os.LookupEnv(v); ok && !override {
return replace
}
replace, ok := env[v] replace, ok := env[v]
if !ok { if !ok {
replace = os.Getenv(v) replace = os.Getenv(v)
@ -242,21 +292,14 @@ func checkFormat(s string, env Env) error {
return fmt.Errorf("line `%s` doesn't match format", s) return fmt.Errorf("line `%s` doesn't match format", s)
} }
func parseVal(val string, env Env) string { func parseVal(val string, env Env, ignoreNewlines bool, override bool) string {
if strings.Contains(val, "=") { if strings.Contains(val, "=") && !ignoreNewlines {
if !(val == "\n" || val == "\r") { kv := strings.Split(val, "\r")
kv := strings.Split(val, "\n")
if len(kv) == 1 { if len(kv) > 1 {
kv = strings.Split(val, "\r") val = kv[0]
} for _, l := range kv[1:] {
_ = parseLine(l, env, override)
if len(kv) > 1 {
val = kv[0]
for i := 1; i < len(kv); i++ {
parseLine(kv[i], env)
}
} }
} }
} }

View File

@ -6,6 +6,12 @@ whatsmeow is a Go library for the WhatsApp web multidevice API.
## Discussion ## Discussion
Matrix room: [#whatsmeow:maunium.net](https://matrix.to/#/#whatsmeow:maunium.net) Matrix room: [#whatsmeow:maunium.net](https://matrix.to/#/#whatsmeow:maunium.net)
For questions about the WhatsApp protocol (like how to send a specific type of
message), you can also use the [WhatsApp protocol Q&A] section on GitHub
discussions.
[WhatsApp protocol Q&A]: https://github.com/tulir/whatsmeow/discussions/categories/whatsapp-protocol-q-a
## Usage ## Usage
The [godoc](https://pkg.go.dev/go.mau.fi/whatsmeow) includes docs for all methods and event types. The [godoc](https://pkg.go.dev/go.mau.fi/whatsmeow) includes docs for all methods and event types.
There's also a [simple example](https://godocs.io/go.mau.fi/whatsmeow#example-package) at the top. There's also a [simple example](https://godocs.io/go.mau.fi/whatsmeow#example-package) at the top.
@ -23,9 +29,10 @@ Most core features are already present:
* Sending and receiving delivery and read receipts * Sending and receiving delivery and read receipts
* Reading app state (contact list, chat pin/mute status, etc) * Reading app state (contact list, chat pin/mute status, etc)
* Sending and handling retry receipts if message decryption fails * Sending and handling retry receipts if message decryption fails
* Sending status messages (experimental, may not work for large contact lists)
Things that are not yet implemented: Things that are not yet implemented:
* Writing app state (contact list, chat pin/mute status, etc) * Writing app state (contact list, chat pin/mute status, etc)
* Sending status messages or broadcast list messages (this is not supported on WhatsApp web either) * Sending broadcast list messages (this is not supported on WhatsApp web either)
* Calls * Calls

View File

@ -7,6 +7,8 @@
package whatsmeow package whatsmeow
import ( import (
"encoding/hex"
"errors"
"fmt" "fmt"
"time" "time"
@ -53,6 +55,9 @@ func (cli *Client) FetchAppState(name appstate.WAPatchName, fullSync, onlyIfNotS
mutations, newState, err := cli.appStateProc.DecodePatches(patches, state, true) mutations, newState, err := cli.appStateProc.DecodePatches(patches, state, true)
if err != nil { if err != nil {
if errors.Is(err, appstate.ErrKeyNotFound) {
go cli.requestMissingAppStateKeys(patches)
}
return fmt.Errorf("failed to decode app state %s patches: %w", name, err) return fmt.Errorf("failed to decode app state %s patches: %w", name, err)
} }
wasFullSync := state.Version == 0 && patches.Snapshot != nil wasFullSync := state.Version == 0 && patches.Snapshot != nil
@ -228,3 +233,42 @@ func (cli *Client) fetchAppStatePatches(name appstate.WAPatchName, fromVersion u
} }
return appstate.ParsePatchList(resp, cli.downloadExternalAppStateBlob) return appstate.ParsePatchList(resp, cli.downloadExternalAppStateBlob)
} }
func (cli *Client) requestMissingAppStateKeys(patches *appstate.PatchList) {
cli.appStateKeyRequestsLock.Lock()
rawKeyIDs := cli.appStateProc.GetMissingKeyIDs(patches)
filteredKeyIDs := make([][]byte, 0, len(rawKeyIDs))
now := time.Now()
for _, keyID := range rawKeyIDs {
stringKeyID := hex.EncodeToString(keyID)
lastRequestTime := cli.appStateKeyRequests[stringKeyID]
if lastRequestTime.IsZero() || lastRequestTime.Add(24*time.Hour).Before(now) {
cli.appStateKeyRequests[stringKeyID] = now
filteredKeyIDs = append(filteredKeyIDs, keyID)
}
}
cli.appStateKeyRequestsLock.Unlock()
cli.requestAppStateKeys(filteredKeyIDs)
}
func (cli *Client) requestAppStateKeys(rawKeyIDs [][]byte) {
keyIDs := make([]*waProto.AppStateSyncKeyId, len(rawKeyIDs))
debugKeyIDs := make([]string, len(rawKeyIDs))
for i, keyID := range rawKeyIDs {
keyIDs[i] = &waProto.AppStateSyncKeyId{KeyId: keyID}
debugKeyIDs[i] = hex.EncodeToString(keyID)
}
msg := &waProto.Message{
ProtocolMessage: &waProto.ProtocolMessage{
Type: waProto.ProtocolMessage_APP_STATE_SYNC_KEY_REQUEST.Enum(),
AppStateSyncKeyRequest: &waProto.AppStateSyncKeyRequest{
KeyIds: keyIDs,
},
},
}
cli.Log.Infof("Sending key request for app state keys %+v", debugKeyIDs)
_, err := cli.SendMessage(cli.Store.ID.ToNonAD(), "", msg)
if err != nil {
cli.Log.Warnf("Failed to send app state key request: %v", err)
}
}

View File

@ -83,3 +83,36 @@ func (proc *Processor) getAppStateKey(keyID []byte) (keys ExpandedAppStateKeys,
} }
return return
} }
func (proc *Processor) GetMissingKeyIDs(pl *PatchList) [][]byte {
cache := make(map[string]bool)
var missingKeys [][]byte
checkMissing := func(keyID []byte) {
if keyID == nil {
return
}
stringKeyID := base64.RawStdEncoding.EncodeToString(keyID)
_, alreadyAdded := cache[stringKeyID]
if !alreadyAdded {
keyData, err := proc.Store.AppStateKeys.GetAppStateSyncKey(keyID)
if err != nil {
proc.Log.Warnf("Error fetching key %X while checking if it's missing: %v", keyID, err)
}
missing := keyData == nil && err == nil
cache[stringKeyID] = missing
if missing {
missingKeys = append(missingKeys, keyID)
}
}
}
if pl.Snapshot != nil {
checkMissing(pl.Snapshot.GetKeyId().GetId())
for _, record := range pl.Snapshot.GetRecords() {
checkMissing(record.GetKeyId().GetId())
}
}
for _, patch := range pl.Patches {
checkMissing(patch.GetKeyId().GetId())
}
return missingKeys
}

View File

@ -9,6 +9,7 @@ package binary
import ( import (
"fmt" "fmt"
"strconv" "strconv"
"time"
"go.mau.fi/whatsmeow/types" "go.mau.fi/whatsmeow/types"
) )
@ -112,6 +113,16 @@ func (au *AttrUtility) GetBool(key string, require bool) (bool, bool) {
} }
} }
func (au *AttrUtility) GetUnixTime(key string, require bool) (time.Time, bool) {
if intVal, ok := au.GetInt64(key, require); !ok {
return time.Time{}, false
} else if intVal == 0 {
return time.Time{}, true
} else {
return time.Unix(intVal, 0), true
}
}
// OptionalString returns the string under the given key. // OptionalString returns the string under the given key.
func (au *AttrUtility) OptionalString(key string) string { func (au *AttrUtility) OptionalString(key string) string {
strVal, _ := au.GetString(key, false) strVal, _ := au.GetString(key, false)
@ -155,6 +166,16 @@ func (au *AttrUtility) Bool(key string) bool {
return val return val
} }
func (au *AttrUtility) OptionalUnixTime(key string) time.Time {
val, _ := au.GetUnixTime(key, false)
return val
}
func (au *AttrUtility) UnixTime(key string) time.Time {
val, _ := au.GetUnixTime(key, true)
return val
}
// OK returns true if there are no errors. // OK returns true if there are no errors.
func (au *AttrUtility) OK() bool { func (au *AttrUtility) OK() bool {
return len(au.Errors) == 0 return len(au.Errors) == 0

View File

@ -2739,7 +2739,7 @@ func (x *DNSSource_DNSSourceDNSResolutionMethod) UnmarshalJSON(b []byte) error {
// Deprecated: Use DNSSource_DNSSourceDNSResolutionMethod.Descriptor instead. // Deprecated: Use DNSSource_DNSSourceDNSResolutionMethod.Descriptor instead.
func (DNSSource_DNSSourceDNSResolutionMethod) EnumDescriptor() ([]byte, []int) { func (DNSSource_DNSSourceDNSResolutionMethod) EnumDescriptor() ([]byte, []int) {
return file_binary_proto_def_proto_rawDescGZIP(), []int{182, 0} return file_binary_proto_def_proto_rawDescGZIP(), []int{183, 0}
} }
type WebMessageInfo_WebMessageInfoStatus int32 type WebMessageInfo_WebMessageInfoStatus int32
@ -10131,7 +10131,6 @@ type ContextInfo struct {
ActionLink *ActionLink `protobuf:"bytes,33,opt,name=actionLink" json:"actionLink,omitempty"` ActionLink *ActionLink `protobuf:"bytes,33,opt,name=actionLink" json:"actionLink,omitempty"`
GroupSubject *string `protobuf:"bytes,34,opt,name=groupSubject" json:"groupSubject,omitempty"` GroupSubject *string `protobuf:"bytes,34,opt,name=groupSubject" json:"groupSubject,omitempty"`
ParentGroupJid *string `protobuf:"bytes,35,opt,name=parentGroupJid" json:"parentGroupJid,omitempty"` ParentGroupJid *string `protobuf:"bytes,35,opt,name=parentGroupJid" json:"parentGroupJid,omitempty"`
MessageSecret []byte `protobuf:"bytes,36,opt,name=messageSecret" json:"messageSecret,omitempty"`
} }
func (x *ContextInfo) Reset() { func (x *ContextInfo) Reset() {
@ -10327,13 +10326,6 @@ func (x *ContextInfo) GetParentGroupJid() string {
return "" return ""
} }
func (x *ContextInfo) GetMessageSecret() []byte {
if x != nil {
return x.MessageSecret
}
return nil
}
type ExternalAdReplyInfo struct { type ExternalAdReplyInfo struct {
state protoimpl.MessageState state protoimpl.MessageState
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
@ -11577,6 +11569,7 @@ type MessageContextInfo struct {
DeviceListMetadata *DeviceListMetadata `protobuf:"bytes,1,opt,name=deviceListMetadata" json:"deviceListMetadata,omitempty"` DeviceListMetadata *DeviceListMetadata `protobuf:"bytes,1,opt,name=deviceListMetadata" json:"deviceListMetadata,omitempty"`
DeviceListMetadataVersion *int32 `protobuf:"varint,2,opt,name=deviceListMetadataVersion" json:"deviceListMetadataVersion,omitempty"` DeviceListMetadataVersion *int32 `protobuf:"varint,2,opt,name=deviceListMetadataVersion" json:"deviceListMetadataVersion,omitempty"`
MessageSecret []byte `protobuf:"bytes,3,opt,name=messageSecret" json:"messageSecret,omitempty"`
} }
func (x *MessageContextInfo) Reset() { func (x *MessageContextInfo) Reset() {
@ -11625,6 +11618,13 @@ func (x *MessageContextInfo) GetDeviceListMetadataVersion() int32 {
return 0 return 0
} }
func (x *MessageContextInfo) GetMessageSecret() []byte {
if x != nil {
return x.MessageSecret
}
return nil
}
type VideoMessage struct { type VideoMessage struct {
state protoimpl.MessageState state protoimpl.MessageState
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
@ -13220,6 +13220,8 @@ type GlobalSettings struct {
AutoDownloadRoaming *AutoDownloadSettings `protobuf:"bytes,6,opt,name=autoDownloadRoaming" json:"autoDownloadRoaming,omitempty"` AutoDownloadRoaming *AutoDownloadSettings `protobuf:"bytes,6,opt,name=autoDownloadRoaming" json:"autoDownloadRoaming,omitempty"`
ShowIndividualNotificationsPreview *bool `protobuf:"varint,7,opt,name=showIndividualNotificationsPreview" json:"showIndividualNotificationsPreview,omitempty"` ShowIndividualNotificationsPreview *bool `protobuf:"varint,7,opt,name=showIndividualNotificationsPreview" json:"showIndividualNotificationsPreview,omitempty"`
ShowGroupNotificationsPreview *bool `protobuf:"varint,8,opt,name=showGroupNotificationsPreview" json:"showGroupNotificationsPreview,omitempty"` ShowGroupNotificationsPreview *bool `protobuf:"varint,8,opt,name=showGroupNotificationsPreview" json:"showGroupNotificationsPreview,omitempty"`
DisappearingModeDuration *int32 `protobuf:"varint,9,opt,name=disappearingModeDuration" json:"disappearingModeDuration,omitempty"`
DisappearingModeTimestamp *int64 `protobuf:"varint,10,opt,name=disappearingModeTimestamp" json:"disappearingModeTimestamp,omitempty"`
} }
func (x *GlobalSettings) Reset() { func (x *GlobalSettings) Reset() {
@ -13310,6 +13312,20 @@ func (x *GlobalSettings) GetShowGroupNotificationsPreview() bool {
return false return false
} }
func (x *GlobalSettings) GetDisappearingModeDuration() int32 {
if x != nil && x.DisappearingModeDuration != nil {
return *x.DisappearingModeDuration
}
return 0
}
func (x *GlobalSettings) GetDisappearingModeTimestamp() int64 {
if x != nil && x.DisappearingModeTimestamp != nil {
return *x.DisappearingModeTimestamp
}
return 0
}
type Conversation struct { type Conversation struct {
state protoimpl.MessageState state protoimpl.MessageState
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
@ -17690,7 +17706,7 @@ type ClientPayload struct {
DnsSource *DNSSource `protobuf:"bytes,15,opt,name=dnsSource" json:"dnsSource,omitempty"` DnsSource *DNSSource `protobuf:"bytes,15,opt,name=dnsSource" json:"dnsSource,omitempty"`
ConnectAttemptCount *uint32 `protobuf:"varint,16,opt,name=connectAttemptCount" json:"connectAttemptCount,omitempty"` ConnectAttemptCount *uint32 `protobuf:"varint,16,opt,name=connectAttemptCount" json:"connectAttemptCount,omitempty"`
Device *uint32 `protobuf:"varint,18,opt,name=device" json:"device,omitempty"` Device *uint32 `protobuf:"varint,18,opt,name=device" json:"device,omitempty"`
RegData *CompanionRegData `protobuf:"bytes,19,opt,name=regData" json:"regData,omitempty"` DevicePairingData *DevicePairingRegistrationData `protobuf:"bytes,19,opt,name=devicePairingData" json:"devicePairingData,omitempty"`
Product *ClientPayload_ClientPayloadProduct `protobuf:"varint,20,opt,name=product,enum=proto.ClientPayload_ClientPayloadProduct" json:"product,omitempty"` Product *ClientPayload_ClientPayloadProduct `protobuf:"varint,20,opt,name=product,enum=proto.ClientPayload_ClientPayloadProduct" json:"product,omitempty"`
FbCat []byte `protobuf:"bytes,21,opt,name=fbCat" json:"fbCat,omitempty"` FbCat []byte `protobuf:"bytes,21,opt,name=fbCat" json:"fbCat,omitempty"`
FbUserAgent []byte `protobuf:"bytes,22,opt,name=fbUserAgent" json:"fbUserAgent,omitempty"` FbUserAgent []byte `protobuf:"bytes,22,opt,name=fbUserAgent" json:"fbUserAgent,omitempty"`
@ -17825,9 +17841,9 @@ func (x *ClientPayload) GetDevice() uint32 {
return 0 return 0
} }
func (x *ClientPayload) GetRegData() *CompanionRegData { func (x *ClientPayload) GetDevicePairingData() *DevicePairingRegistrationData {
if x != nil { if x != nil {
return x.RegData return x.DevicePairingData
} }
return nil return nil
} }
@ -18236,6 +18252,109 @@ func (x *UserAgent) GetDeviceBoard() string {
return "" return ""
} }
type DevicePairingRegistrationData struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
ERegid []byte `protobuf:"bytes,1,opt,name=eRegid" json:"eRegid,omitempty"`
EKeytype []byte `protobuf:"bytes,2,opt,name=eKeytype" json:"eKeytype,omitempty"`
EIdent []byte `protobuf:"bytes,3,opt,name=eIdent" json:"eIdent,omitempty"`
ESkeyId []byte `protobuf:"bytes,4,opt,name=eSkeyId" json:"eSkeyId,omitempty"`
ESkeyVal []byte `protobuf:"bytes,5,opt,name=eSkeyVal" json:"eSkeyVal,omitempty"`
ESkeySig []byte `protobuf:"bytes,6,opt,name=eSkeySig" json:"eSkeySig,omitempty"`
BuildHash []byte `protobuf:"bytes,7,opt,name=buildHash" json:"buildHash,omitempty"`
DeviceProps []byte `protobuf:"bytes,8,opt,name=deviceProps" json:"deviceProps,omitempty"`
}
func (x *DevicePairingRegistrationData) Reset() {
*x = DevicePairingRegistrationData{}
if protoimpl.UnsafeEnabled {
mi := &file_binary_proto_def_proto_msgTypes[182]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *DevicePairingRegistrationData) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*DevicePairingRegistrationData) ProtoMessage() {}
func (x *DevicePairingRegistrationData) ProtoReflect() protoreflect.Message {
mi := &file_binary_proto_def_proto_msgTypes[182]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use DevicePairingRegistrationData.ProtoReflect.Descriptor instead.
func (*DevicePairingRegistrationData) Descriptor() ([]byte, []int) {
return file_binary_proto_def_proto_rawDescGZIP(), []int{182}
}
func (x *DevicePairingRegistrationData) GetERegid() []byte {
if x != nil {
return x.ERegid
}
return nil
}
func (x *DevicePairingRegistrationData) GetEKeytype() []byte {
if x != nil {
return x.EKeytype
}
return nil
}
func (x *DevicePairingRegistrationData) GetEIdent() []byte {
if x != nil {
return x.EIdent
}
return nil
}
func (x *DevicePairingRegistrationData) GetESkeyId() []byte {
if x != nil {
return x.ESkeyId
}
return nil
}
func (x *DevicePairingRegistrationData) GetESkeyVal() []byte {
if x != nil {
return x.ESkeyVal
}
return nil
}
func (x *DevicePairingRegistrationData) GetESkeySig() []byte {
if x != nil {
return x.ESkeySig
}
return nil
}
func (x *DevicePairingRegistrationData) GetBuildHash() []byte {
if x != nil {
return x.BuildHash
}
return nil
}
func (x *DevicePairingRegistrationData) GetDeviceProps() []byte {
if x != nil {
return x.DeviceProps
}
return nil
}
type DNSSource struct { type DNSSource struct {
state protoimpl.MessageState state protoimpl.MessageState
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
@ -18248,7 +18367,7 @@ type DNSSource struct {
func (x *DNSSource) Reset() { func (x *DNSSource) Reset() {
*x = DNSSource{} *x = DNSSource{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_binary_proto_def_proto_msgTypes[182] mi := &file_binary_proto_def_proto_msgTypes[183]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -18261,7 +18380,7 @@ func (x *DNSSource) String() string {
func (*DNSSource) ProtoMessage() {} func (*DNSSource) ProtoMessage() {}
func (x *DNSSource) ProtoReflect() protoreflect.Message { func (x *DNSSource) ProtoReflect() protoreflect.Message {
mi := &file_binary_proto_def_proto_msgTypes[182] mi := &file_binary_proto_def_proto_msgTypes[183]
if protoimpl.UnsafeEnabled && x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -18274,7 +18393,7 @@ func (x *DNSSource) ProtoReflect() protoreflect.Message {
// Deprecated: Use DNSSource.ProtoReflect.Descriptor instead. // Deprecated: Use DNSSource.ProtoReflect.Descriptor instead.
func (*DNSSource) Descriptor() ([]byte, []int) { func (*DNSSource) Descriptor() ([]byte, []int) {
return file_binary_proto_def_proto_rawDescGZIP(), []int{182} return file_binary_proto_def_proto_rawDescGZIP(), []int{183}
} }
func (x *DNSSource) GetDnsMethod() DNSSource_DNSSourceDNSResolutionMethod { func (x *DNSSource) GetDnsMethod() DNSSource_DNSSourceDNSResolutionMethod {
@ -18291,109 +18410,6 @@ func (x *DNSSource) GetAppCached() bool {
return false return false
} }
type CompanionRegData struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
ERegid []byte `protobuf:"bytes,1,opt,name=eRegid" json:"eRegid,omitempty"`
EKeytype []byte `protobuf:"bytes,2,opt,name=eKeytype" json:"eKeytype,omitempty"`
EIdent []byte `protobuf:"bytes,3,opt,name=eIdent" json:"eIdent,omitempty"`
ESkeyId []byte `protobuf:"bytes,4,opt,name=eSkeyId" json:"eSkeyId,omitempty"`
ESkeyVal []byte `protobuf:"bytes,5,opt,name=eSkeyVal" json:"eSkeyVal,omitempty"`
ESkeySig []byte `protobuf:"bytes,6,opt,name=eSkeySig" json:"eSkeySig,omitempty"`
BuildHash []byte `protobuf:"bytes,7,opt,name=buildHash" json:"buildHash,omitempty"`
CompanionProps []byte `protobuf:"bytes,8,opt,name=companionProps" json:"companionProps,omitempty"`
}
func (x *CompanionRegData) Reset() {
*x = CompanionRegData{}
if protoimpl.UnsafeEnabled {
mi := &file_binary_proto_def_proto_msgTypes[183]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *CompanionRegData) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CompanionRegData) ProtoMessage() {}
func (x *CompanionRegData) ProtoReflect() protoreflect.Message {
mi := &file_binary_proto_def_proto_msgTypes[183]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CompanionRegData.ProtoReflect.Descriptor instead.
func (*CompanionRegData) Descriptor() ([]byte, []int) {
return file_binary_proto_def_proto_rawDescGZIP(), []int{183}
}
func (x *CompanionRegData) GetERegid() []byte {
if x != nil {
return x.ERegid
}
return nil
}
func (x *CompanionRegData) GetEKeytype() []byte {
if x != nil {
return x.EKeytype
}
return nil
}
func (x *CompanionRegData) GetEIdent() []byte {
if x != nil {
return x.EIdent
}
return nil
}
func (x *CompanionRegData) GetESkeyId() []byte {
if x != nil {
return x.ESkeyId
}
return nil
}
func (x *CompanionRegData) GetESkeyVal() []byte {
if x != nil {
return x.ESkeyVal
}
return nil
}
func (x *CompanionRegData) GetESkeySig() []byte {
if x != nil {
return x.ESkeySig
}
return nil
}
func (x *CompanionRegData) GetBuildHash() []byte {
if x != nil {
return x.BuildHash
}
return nil
}
func (x *CompanionRegData) GetCompanionProps() []byte {
if x != nil {
return x.CompanionProps
}
return nil
}
type WebNotificationsInfo struct { type WebNotificationsInfo struct {
state protoimpl.MessageState state protoimpl.MessageState
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
@ -20122,8 +20138,8 @@ var file_binary_proto_def_proto_goTypes = []interface{}{
(*WebInfo)(nil), // 229: proto.WebInfo (*WebInfo)(nil), // 229: proto.WebInfo
(*WebdPayload)(nil), // 230: proto.WebdPayload (*WebdPayload)(nil), // 230: proto.WebdPayload
(*UserAgent)(nil), // 231: proto.UserAgent (*UserAgent)(nil), // 231: proto.UserAgent
(*DNSSource)(nil), // 232: proto.DNSSource (*DevicePairingRegistrationData)(nil), // 232: proto.DevicePairingRegistrationData
(*CompanionRegData)(nil), // 233: proto.CompanionRegData (*DNSSource)(nil), // 233: proto.DNSSource
(*WebNotificationsInfo)(nil), // 234: proto.WebNotificationsInfo (*WebNotificationsInfo)(nil), // 234: proto.WebNotificationsInfo
(*WebMessageInfo)(nil), // 235: proto.WebMessageInfo (*WebMessageInfo)(nil), // 235: proto.WebMessageInfo
(*WebFeatures)(nil), // 236: proto.WebFeatures (*WebFeatures)(nil), // 236: proto.WebFeatures
@ -20417,8 +20433,8 @@ var file_binary_proto_def_proto_depIdxs = []int32{
229, // 276: proto.ClientPayload.webInfo:type_name -> proto.WebInfo 229, // 276: proto.ClientPayload.webInfo:type_name -> proto.WebInfo
35, // 277: proto.ClientPayload.connectType:type_name -> proto.ClientPayload.ClientPayloadConnectType 35, // 277: proto.ClientPayload.connectType:type_name -> proto.ClientPayload.ClientPayloadConnectType
36, // 278: proto.ClientPayload.connectReason:type_name -> proto.ClientPayload.ClientPayloadConnectReason 36, // 278: proto.ClientPayload.connectReason:type_name -> proto.ClientPayload.ClientPayloadConnectReason
232, // 279: proto.ClientPayload.dnsSource:type_name -> proto.DNSSource 233, // 279: proto.ClientPayload.dnsSource:type_name -> proto.DNSSource
233, // 280: proto.ClientPayload.regData:type_name -> proto.CompanionRegData 232, // 280: proto.ClientPayload.devicePairingData:type_name -> proto.DevicePairingRegistrationData
37, // 281: proto.ClientPayload.product:type_name -> proto.ClientPayload.ClientPayloadProduct 37, // 281: proto.ClientPayload.product:type_name -> proto.ClientPayload.ClientPayloadProduct
38, // 282: proto.ClientPayload.iosAppExtension:type_name -> proto.ClientPayload.ClientPayloadIOSAppExtension 38, // 282: proto.ClientPayload.iosAppExtension:type_name -> proto.ClientPayload.ClientPayloadIOSAppExtension
230, // 283: proto.WebInfo.webdPayload:type_name -> proto.WebdPayload 230, // 283: proto.WebInfo.webdPayload:type_name -> proto.WebdPayload
@ -22698,7 +22714,7 @@ func file_binary_proto_def_proto_init() {
} }
} }
file_binary_proto_def_proto_msgTypes[182].Exporter = func(v interface{}, i int) interface{} { file_binary_proto_def_proto_msgTypes[182].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*DNSSource); i { switch v := v.(*DevicePairingRegistrationData); i {
case 0: case 0:
return &v.state return &v.state
case 1: case 1:
@ -22710,7 +22726,7 @@ func file_binary_proto_def_proto_init() {
} }
} }
file_binary_proto_def_proto_msgTypes[183].Exporter = func(v interface{}, i int) interface{} { file_binary_proto_def_proto_msgTypes[183].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CompanionRegData); i { switch v := v.(*DNSSource); i {
case 0: case 0:
return &v.state return &v.state
case 1: case 1:

View File

@ -781,7 +781,6 @@ message ContextInfo {
optional ActionLink actionLink = 33; optional ActionLink actionLink = 33;
optional string groupSubject = 34; optional string groupSubject = 34;
optional string parentGroupJid = 35; optional string parentGroupJid = 35;
optional bytes messageSecret = 36;
} }
message ExternalAdReplyInfo { message ExternalAdReplyInfo {
@ -932,6 +931,7 @@ message Message {
message MessageContextInfo { message MessageContextInfo {
optional DeviceListMetadata deviceListMetadata = 1; optional DeviceListMetadata deviceListMetadata = 1;
optional int32 deviceListMetadataVersion = 2; optional int32 deviceListMetadataVersion = 2;
optional bytes messageSecret = 3;
} }
message VideoMessage { message VideoMessage {
@ -1123,6 +1123,8 @@ message GlobalSettings {
optional AutoDownloadSettings autoDownloadRoaming = 6; optional AutoDownloadSettings autoDownloadRoaming = 6;
optional bool showIndividualNotificationsPreview = 7; optional bool showIndividualNotificationsPreview = 7;
optional bool showGroupNotificationsPreview = 8; optional bool showGroupNotificationsPreview = 8;
optional int32 disappearingModeDuration = 9;
optional int64 disappearingModeTimestamp = 10;
} }
message Conversation { message Conversation {
@ -1633,7 +1635,7 @@ message ClientPayload {
optional DNSSource dnsSource = 15; optional DNSSource dnsSource = 15;
optional uint32 connectAttemptCount = 16; optional uint32 connectAttemptCount = 16;
optional uint32 device = 18; optional uint32 device = 18;
optional CompanionRegData regData = 19; optional DevicePairingRegistrationData devicePairingData = 19;
enum ClientPayloadProduct { enum ClientPayloadProduct {
WHATSAPP = 0; WHATSAPP = 0;
MESSENGER = 1; MESSENGER = 1;
@ -1744,6 +1746,17 @@ message UserAgent {
// optional uint32 quinary = 5; // optional uint32 quinary = 5;
//} //}
message DevicePairingRegistrationData {
optional bytes eRegid = 1;
optional bytes eKeytype = 2;
optional bytes eIdent = 3;
optional bytes eSkeyId = 4;
optional bytes eSkeyVal = 5;
optional bytes eSkeySig = 6;
optional bytes buildHash = 7;
optional bytes deviceProps = 8;
}
message DNSSource { message DNSSource {
enum DNSSourceDNSResolutionMethod { enum DNSSourceDNSResolutionMethod {
SYSTEM = 0; SYSTEM = 0;
@ -1756,17 +1769,6 @@ message DNSSource {
optional bool appCached = 16; optional bool appCached = 16;
} }
message CompanionRegData {
optional bytes eRegid = 1;
optional bytes eKeytype = 2;
optional bytes eIdent = 3;
optional bytes eSkeyId = 4;
optional bytes eSkeyVal = 5;
optional bytes eSkeySig = 6;
optional bytes buildHash = 7;
optional bytes companionProps = 8;
}
message WebNotificationsInfo { message WebNotificationsInfo {
optional uint64 timestamp = 2; optional uint64 timestamp = 2;
optional uint32 unreadChats = 3; optional uint32 unreadChats = 3;

138
vendor/go.mau.fi/whatsmeow/broadcast.go vendored Normal file
View File

@ -0,0 +1,138 @@
// Copyright (c) 2022 Tulir Asokan
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package whatsmeow
import (
"errors"
"fmt"
waBinary "go.mau.fi/whatsmeow/binary"
"go.mau.fi/whatsmeow/types"
)
func (cli *Client) getBroadcastListParticipants(jid types.JID) ([]types.JID, error) {
var list []types.JID
var err error
if jid == types.StatusBroadcastJID {
list, err = cli.getStatusBroadcastRecipients()
} else {
return nil, ErrBroadcastListUnsupported
}
if err != nil {
return nil, err
}
var hasSelf bool
for _, participant := range list {
if participant.User == cli.Store.ID.User {
hasSelf = true
break
}
}
if !hasSelf {
list = append(list, cli.Store.ID.ToNonAD())
}
return list, nil
}
func (cli *Client) getStatusBroadcastRecipients() ([]types.JID, error) {
statusPrivacyOptions, err := cli.GetStatusPrivacy()
if err != nil {
return nil, fmt.Errorf("failed to get status privacy: %w", err)
}
statusPrivacy := statusPrivacyOptions[0]
if statusPrivacy.Type == types.StatusPrivacyTypeWhitelist {
// Whitelist mode, just return the list
return statusPrivacy.List, nil
}
// Blacklist or all contacts mode. Find all contacts from database, then filter them appropriately.
contacts, err := cli.Store.Contacts.GetAllContacts()
if err != nil {
return nil, fmt.Errorf("failed to get contact list from db: %w", err)
}
blacklist := make(map[types.JID]struct{})
if statusPrivacy.Type == types.StatusPrivacyTypeBlacklist {
for _, jid := range statusPrivacy.List {
blacklist[jid] = struct{}{}
}
}
var contactsArray []types.JID
for jid, contact := range contacts {
_, isBlacklisted := blacklist[jid]
if isBlacklisted {
continue
}
// TODO should there be a better way to separate contacts and found push names in the db?
if len(contact.FullName) > 0 {
contactsArray = append(contactsArray, jid)
}
}
return contactsArray, nil
}
var DefaultStatusPrivacy = []types.StatusPrivacy{{
Type: types.StatusPrivacyTypeContacts,
IsDefault: true,
}}
// GetStatusPrivacy gets the user's status privacy settings (who to send status broadcasts to).
//
// There can be multiple different stored settings, the first one is always the default.
func (cli *Client) GetStatusPrivacy() ([]types.StatusPrivacy, error) {
resp, err := cli.sendIQ(infoQuery{
Namespace: "status",
Type: iqGet,
To: types.ServerJID,
Content: []waBinary.Node{{
Tag: "privacy",
}},
})
if err != nil {
if errors.Is(err, ErrIQNotFound) {
return DefaultStatusPrivacy, nil
}
return nil, err
}
privacyLists := resp.GetChildByTag("privacy")
var outputs []types.StatusPrivacy
for _, list := range privacyLists.GetChildren() {
if list.Tag != "list" {
continue
}
ag := list.AttrGetter()
var out types.StatusPrivacy
out.IsDefault = ag.OptionalBool("default")
out.Type = types.StatusPrivacyType(ag.String("type"))
children := list.GetChildren()
if len(children) > 0 {
out.List = make([]types.JID, 0, len(children))
for _, child := range children {
jid, ok := child.Attrs["jid"].(types.JID)
if child.Tag == "user" && ok {
out.List = append(out.List, jid)
}
}
}
outputs = append(outputs, out)
if out.IsDefault {
// Move default to always be first in the list
outputs[len(outputs)-1] = outputs[0]
outputs[0] = out
}
if len(ag.Errors) > 0 {
return nil, ag.Error()
}
}
if len(outputs) == 0 {
return DefaultStatusPrivacy, nil
}
return outputs, nil
}

View File

@ -7,8 +7,6 @@
package whatsmeow package whatsmeow
import ( import (
"time"
waBinary "go.mau.fi/whatsmeow/binary" waBinary "go.mau.fi/whatsmeow/binary"
"go.mau.fi/whatsmeow/types" "go.mau.fi/whatsmeow/types"
"go.mau.fi/whatsmeow/types/events" "go.mau.fi/whatsmeow/types/events"
@ -26,7 +24,7 @@ func (cli *Client) handleCallEvent(node *waBinary.Node) {
cag := child.AttrGetter() cag := child.AttrGetter()
basicMeta := types.BasicCallMeta{ basicMeta := types.BasicCallMeta{
From: ag.JID("from"), From: ag.JID("from"),
Timestamp: time.Unix(ag.Int64("t"), 0), Timestamp: ag.UnixTime("t"),
CallCreator: cag.JID("call-creator"), CallCreator: cag.JID("call-creator"),
CallID: cag.String("call-id"), CallID: cag.String("call-id"),
} }

View File

@ -10,7 +10,6 @@ package whatsmeow
import ( import (
"context" "context"
"crypto/rand" "crypto/rand"
"encoding/base64"
"encoding/hex" "encoding/hex"
"errors" "errors"
"fmt" "fmt"
@ -52,6 +51,7 @@ type Client struct {
socket *socket.NoiseSocket socket *socket.NoiseSocket
socketLock sync.RWMutex socketLock sync.RWMutex
socketWait chan struct{}
isLoggedIn uint32 isLoggedIn uint32
expectedDisconnectVal uint32 expectedDisconnectVal uint32
@ -88,6 +88,11 @@ type Client struct {
messageRetries map[string]int messageRetries map[string]int
messageRetriesLock sync.Mutex messageRetriesLock sync.Mutex
appStateKeyRequests map[string]time.Time
appStateKeyRequestsLock sync.RWMutex
messageSendLock sync.Mutex
privacySettingsCache atomic.Value privacySettingsCache atomic.Value
groupParticipantsCache map[types.JID][]types.JID groupParticipantsCache map[types.JID][]types.JID
@ -99,22 +104,21 @@ type Client struct {
recentMessagesList [recentMessagesSize]recentMessageKey recentMessagesList [recentMessagesSize]recentMessageKey
recentMessagesPtr int recentMessagesPtr int
recentMessagesLock sync.RWMutex recentMessagesLock sync.RWMutex
sessionRecreateHistory map[types.JID]time.Time
sessionRecreateHistoryLock sync.Mutex
// GetMessageForRetry is used to find the source message for handling retry receipts // GetMessageForRetry is used to find the source message for handling retry receipts
// when the message is not found in the recently sent message cache. // when the message is not found in the recently sent message cache.
GetMessageForRetry func(to types.JID, id types.MessageID) *waProto.Message GetMessageForRetry func(requester, to types.JID, id types.MessageID) *waProto.Message
// PreRetryCallback is called before a retry receipt is accepted. // PreRetryCallback is called before a retry receipt is accepted.
// If it returns false, the accepting will be cancelled and the retry receipt will be ignored. // If it returns false, the accepting will be cancelled and the retry receipt will be ignored.
PreRetryCallback func(receipt *events.Receipt, retryCount int, msg *waProto.Message) bool PreRetryCallback func(receipt *events.Receipt, id types.MessageID, retryCount int, msg *waProto.Message) bool
// Should untrusted identity errors be handled automatically? If true, the stored identity and existing signal // Should untrusted identity errors be handled automatically? If true, the stored identity and existing signal
// sessions will be removed on untrusted identity errors, and an events.IdentityChange will be dispatched. // sessions will be removed on untrusted identity errors, and an events.IdentityChange will be dispatched.
// If false, decrypting a message from untrusted devices will fail. // If false, decrypting a message from untrusted devices will fail.
AutoTrustIdentity bool AutoTrustIdentity bool
DebugDecodeBeforeSend bool
OneMessageAtATime bool
messageSendLock sync.Mutex
uniqueID string uniqueID string
idCounter uint32 idCounter uint32
@ -162,14 +166,17 @@ func NewClient(deviceStore *store.Device, log waLog.Logger) *Client {
messageRetries: make(map[string]int), messageRetries: make(map[string]int),
handlerQueue: make(chan *waBinary.Node, handlerQueueSize), handlerQueue: make(chan *waBinary.Node, handlerQueueSize),
appStateProc: appstate.NewProcessor(deviceStore, log.Sub("AppState")), appStateProc: appstate.NewProcessor(deviceStore, log.Sub("AppState")),
socketWait: make(chan struct{}),
historySyncNotifications: make(chan *waProto.HistorySyncNotification, 32), historySyncNotifications: make(chan *waProto.HistorySyncNotification, 32),
groupParticipantsCache: make(map[types.JID][]types.JID), groupParticipantsCache: make(map[types.JID][]types.JID),
userDevicesCache: make(map[types.JID][]types.JID), userDevicesCache: make(map[types.JID][]types.JID),
recentMessagesMap: make(map[recentMessageKey]*waProto.Message, recentMessagesSize), recentMessagesMap: make(map[recentMessageKey]*waProto.Message, recentMessagesSize),
GetMessageForRetry: func(to types.JID, id types.MessageID) *waProto.Message { return nil }, sessionRecreateHistory: make(map[types.JID]time.Time),
GetMessageForRetry: func(requester, to types.JID, id types.MessageID) *waProto.Message { return nil },
appStateKeyRequests: make(map[string]time.Time),
EnableAutoReconnect: true, EnableAutoReconnect: true,
AutoTrustIdentity: true, AutoTrustIdentity: true,
@ -226,6 +233,37 @@ func (cli *Client) SetProxy(proxy socket.Proxy) {
cli.http.Transport.(*http.Transport).Proxy = proxy cli.http.Transport.(*http.Transport).Proxy = proxy
} }
func (cli *Client) getSocketWaitChan() <-chan struct{} {
cli.socketLock.RLock()
ch := cli.socketWait
cli.socketLock.RUnlock()
return ch
}
func (cli *Client) closeSocketWaitChan() {
cli.socketLock.Lock()
close(cli.socketWait)
cli.socketWait = make(chan struct{})
cli.socketLock.Unlock()
}
func (cli *Client) WaitForConnection(timeout time.Duration) bool {
timeoutChan := time.After(timeout)
cli.socketLock.RLock()
for cli.socket == nil || !cli.socket.IsConnected() || !cli.IsLoggedIn() {
ch := cli.socketWait
cli.socketLock.RUnlock()
select {
case <-ch:
case <-timeoutChan:
return false
}
cli.socketLock.RLock()
}
cli.socketLock.RUnlock()
return true
}
// Connect connects the client to the WhatsApp web websocket. After connection, it will either // Connect connects the client to the WhatsApp web websocket. After connection, it will either
// authenticate if there's data in the device store, or emit a QREvent to set up a new link. // authenticate if there's data in the device store, or emit a QREvent to set up a new link.
func (cli *Client) Connect() error { func (cli *Client) Connect() error {
@ -322,6 +360,9 @@ func (cli *Client) IsConnected() bool {
} }
// Disconnect disconnects from the WhatsApp web websocket. // Disconnect disconnects from the WhatsApp web websocket.
//
// This will not emit any events, the Disconnected event is only used when the
// connection is closed by the server or a network error.
func (cli *Client) Disconnect() { func (cli *Client) Disconnect() {
if cli.socket == nil { if cli.socket == nil {
return return
@ -336,6 +377,7 @@ func (cli *Client) unlockedDisconnect() {
if cli.socket != nil { if cli.socket != nil {
cli.socket.Stop(true) cli.socket.Stop(true)
cli.socket = nil cli.socket = nil
cli.clearResponseWaiters(xmlStreamEndNode)
} }
} }
@ -343,6 +385,9 @@ func (cli *Client) unlockedDisconnect() {
// //
// If the logout request fails, the disconnection and local data deletion will not happen either. // If the logout request fails, the disconnection and local data deletion will not happen either.
// If an error is returned, but you want to force disconnect/clear data, call Client.Disconnect() and Client.Store.Delete() manually. // If an error is returned, but you want to force disconnect/clear data, call Client.Disconnect() and Client.Store.Delete() manually.
//
// Note that this will not emit any events. The LoggedOut event is only used for external logouts
// (triggered by the user from the main device or by WhatsApp servers).
func (cli *Client) Logout() error { func (cli *Client) Logout() error {
if cli.Store.ID == nil { if cli.Store.ID == nil {
return ErrNotLoggedIn return ErrNotLoggedIn
@ -491,7 +536,7 @@ func (cli *Client) handlerQueueLoop(ctx context.Context) {
} }
} }
func (cli *Client) sendNodeDebug(node waBinary.Node) ([]byte, error) { func (cli *Client) sendNodeAndGetData(node waBinary.Node) ([]byte, error) {
cli.socketLock.RLock() cli.socketLock.RLock()
sock := cli.socket sock := cli.socket
cli.socketLock.RUnlock() cli.socketLock.RUnlock()
@ -503,22 +548,13 @@ func (cli *Client) sendNodeDebug(node waBinary.Node) ([]byte, error) {
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to marshal node: %w", err) return nil, fmt.Errorf("failed to marshal node: %w", err)
} }
if cli.DebugDecodeBeforeSend {
var decoded *waBinary.Node
decoded, err = waBinary.Unmarshal(payload[1:])
if err != nil {
cli.Log.Infof("Malformed payload: %s", base64.URLEncoding.EncodeToString(payload))
return nil, fmt.Errorf("failed to decode the binary we just produced: %w", err)
}
node = *decoded
}
cli.sendLog.Debugf("%s", node.XMLString()) cli.sendLog.Debugf("%s", node.XMLString())
return payload, sock.SendFrame(payload) return payload, sock.SendFrame(payload)
} }
func (cli *Client) sendNode(node waBinary.Node) error { func (cli *Client) sendNode(node waBinary.Node) error {
_, err := cli.sendNodeDebug(node) _, err := cli.sendNodeAndGetData(node)
return err return err
} }
@ -535,3 +571,45 @@ func (cli *Client) dispatchEvent(evt interface{}) {
handler.fn(evt) handler.fn(evt)
} }
} }
// ParseWebMessage parses a WebMessageInfo object into *events.Message to match what real-time messages have.
//
// The chat JID can be found in the Conversation data:
// chatJID, err := types.ParseJID(conv.GetId())
// for _, historyMsg := range conv.GetMessages() {
// evt, err := cli.ParseWebMessage(chatJID, historyMsg.GetMessage())
// yourNormalEventHandler(evt)
// }
func (cli *Client) ParseWebMessage(chatJID types.JID, webMsg *waProto.WebMessageInfo) (*events.Message, error) {
info := types.MessageInfo{
MessageSource: types.MessageSource{
Chat: chatJID,
IsFromMe: webMsg.GetKey().GetFromMe(),
IsGroup: chatJID.Server == types.GroupServer,
},
ID: webMsg.GetKey().GetId(),
PushName: webMsg.GetPushName(),
Timestamp: time.Unix(int64(webMsg.GetMessageTimestamp()), 0),
}
var err error
if info.IsFromMe {
info.Sender = cli.Store.ID.ToNonAD()
} else if chatJID.Server == types.DefaultUserServer {
info.Sender = chatJID
} else if webMsg.GetParticipant() != "" {
info.Sender, err = types.ParseJID(webMsg.GetParticipant())
} else if webMsg.GetKey().GetParticipant() != "" {
info.Sender, err = types.ParseJID(webMsg.GetKey().GetParticipant())
} else {
return nil, fmt.Errorf("couldn't find sender of message %s", info.ID)
}
if err != nil {
return nil, fmt.Errorf("failed to parse sender of message %s: %v", info.ID, err)
}
evt := &events.Message{
RawMessage: webMsg.GetMessage(),
Info: info,
}
evt.UnwrapRaw()
return evt, nil
}

View File

@ -89,11 +89,7 @@ func (cli *Client) handleConnectFailure(node *waBinary.Node) {
} }
} else if reason == events.ConnectFailureTempBanned { } else if reason == events.ConnectFailureTempBanned {
cli.Log.Warnf("Temporary ban connect failure: %s", node.XMLString()) cli.Log.Warnf("Temporary ban connect failure: %s", node.XMLString())
expiryTimeUnix := ag.Int64("expire") expiryTime := ag.UnixTime("expire")
var expiryTime time.Time
if expiryTimeUnix > 0 {
expiryTime = time.Unix(expiryTimeUnix, 0)
}
go cli.dispatchEvent(&events.TemporaryBan{ go cli.dispatchEvent(&events.TemporaryBan{
Code: events.TempBanReason(ag.Int("code")), Code: events.TempBanReason(ag.Int("code")),
Expire: expiryTime, Expire: expiryTime,
@ -130,6 +126,7 @@ func (cli *Client) handleConnectSuccess(node *waBinary.Node) {
cli.Log.Warnf("Failed to send post-connect passive IQ: %v", err) cli.Log.Warnf("Failed to send post-connect passive IQ: %v", err)
} }
cli.dispatchEvent(&events.Connected{}) cli.dispatchEvent(&events.Connected{})
cli.closeSocketWaitChan()
}() }()
} }

View File

@ -13,6 +13,7 @@ import (
"fmt" "fmt"
"io" "io"
"net/http" "net/http"
"strings"
"google.golang.org/protobuf/proto" "google.golang.org/protobuf/proto"
"google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
@ -183,11 +184,20 @@ func (cli *Client) Download(msg DownloadableMessage) ([]byte, error) {
return nil, fmt.Errorf("%w '%s'", ErrUnknownMediaType, string(msg.ProtoReflect().Descriptor().Name())) return nil, fmt.Errorf("%w '%s'", ErrUnknownMediaType, string(msg.ProtoReflect().Descriptor().Name()))
} }
urlable, ok := msg.(downloadableMessageWithURL) urlable, ok := msg.(downloadableMessageWithURL)
if ok && len(urlable.GetUrl()) > 0 { var url string
var isWebWhatsappNetURL bool
if ok {
url = urlable.GetUrl()
isWebWhatsappNetURL = strings.HasPrefix(urlable.GetUrl(), "https://web.whatsapp.net")
}
if len(url) > 0 && !isWebWhatsappNetURL {
return cli.downloadAndDecrypt(urlable.GetUrl(), msg.GetMediaKey(), mediaType, getSize(msg), msg.GetFileEncSha256(), msg.GetFileSha256()) return cli.downloadAndDecrypt(urlable.GetUrl(), msg.GetMediaKey(), mediaType, getSize(msg), msg.GetFileEncSha256(), msg.GetFileSha256())
} else if len(msg.GetDirectPath()) > 0 { } else if len(msg.GetDirectPath()) > 0 {
return cli.DownloadMediaWithPath(msg.GetDirectPath(), msg.GetFileEncSha256(), msg.GetFileSha256(), msg.GetMediaKey(), getSize(msg), mediaType, mediaTypeToMMSType[mediaType]) return cli.DownloadMediaWithPath(msg.GetDirectPath(), msg.GetFileEncSha256(), msg.GetFileSha256(), msg.GetMediaKey(), getSize(msg), mediaType, mediaTypeToMMSType[mediaType])
} else { } else {
if isWebWhatsappNetURL {
cli.Log.Warnf("Got a media message with a web.whatsapp.net URL (%s) and no direct path", url)
}
return nil, ErrNoURLPresent return nil, ErrNoURLPresent
} }
} }

View File

@ -50,11 +50,13 @@ var (
ErrMediaNotAvailableOnPhone = errors.New("media no longer available on phone") ErrMediaNotAvailableOnPhone = errors.New("media no longer available on phone")
// ErrUnknownMediaRetryError is returned by DecryptMediaRetryNotification if the given event contains an unknown error code. // ErrUnknownMediaRetryError is returned by DecryptMediaRetryNotification if the given event contains an unknown error code.
ErrUnknownMediaRetryError = errors.New("unknown media retry error") ErrUnknownMediaRetryError = errors.New("unknown media retry error")
// ErrInvalidDisappearingTimer is returned by SetDisappearingTimer if the given timer is not one of the allowed values.
ErrInvalidDisappearingTimer = errors.New("invalid disappearing timer provided")
) )
// Some errors that Client.SendMessage can return // Some errors that Client.SendMessage can return
var ( var (
ErrBroadcastListUnsupported = errors.New("sending to broadcast lists is not yet supported") ErrBroadcastListUnsupported = errors.New("sending to non-status broadcast lists is not yet supported")
ErrUnknownServer = errors.New("can't send message to unknown server") ErrUnknownServer = errors.New("can't send message to unknown server")
ErrRecipientADJID = errors.New("message recipient must be normal (non-AD) JID") ErrRecipientADJID = errors.New("message recipient must be normal (non-AD) JID")
) )
@ -104,6 +106,7 @@ type IQError struct {
// Common errors returned by info queries for use with errors.Is // Common errors returned by info queries for use with errors.Is
var ( var (
ErrIQBadRequest error = &IQError{Code: 400, Text: "bad-request"}
ErrIQNotAuthorized error = &IQError{Code: 401, Text: "not-authorized"} ErrIQNotAuthorized error = &IQError{Code: 401, Text: "not-authorized"}
ErrIQForbidden error = &IQError{Code: 403, Text: "forbidden"} ErrIQForbidden error = &IQError{Code: 403, Text: "forbidden"}
ErrIQNotFound error = &IQError{Code: 404, Text: "item-not-found"} ErrIQNotFound error = &IQError{Code: 404, Text: "item-not-found"}

View File

@ -10,7 +10,6 @@ import (
"errors" "errors"
"fmt" "fmt"
"strings" "strings"
"time"
waBinary "go.mau.fi/whatsmeow/binary" waBinary "go.mau.fi/whatsmeow/binary"
"go.mau.fi/whatsmeow/types" "go.mau.fi/whatsmeow/types"
@ -397,10 +396,10 @@ func (cli *Client) parseGroupNode(groupNode *waBinary.Node) (*types.GroupInfo, e
group.OwnerJID = ag.OptionalJIDOrEmpty("creator") group.OwnerJID = ag.OptionalJIDOrEmpty("creator")
group.Name = ag.String("subject") group.Name = ag.String("subject")
group.NameSetAt = time.Unix(ag.Int64("s_t"), 0) group.NameSetAt = ag.UnixTime("s_t")
group.NameSetBy = ag.OptionalJIDOrEmpty("s_o") group.NameSetBy = ag.OptionalJIDOrEmpty("s_o")
group.GroupCreated = time.Unix(ag.Int64("creation"), 0) group.GroupCreated = ag.UnixTime("creation")
group.AnnounceVersionID = ag.OptionalString("a_v_id") group.AnnounceVersionID = ag.OptionalString("a_v_id")
group.ParticipantVersionID = ag.OptionalString("p_v_id") group.ParticipantVersionID = ag.OptionalString("p_v_id")
@ -423,7 +422,7 @@ func (cli *Client) parseGroupNode(groupNode *waBinary.Node) (*types.GroupInfo, e
group.Topic = string(topicBytes) group.Topic = string(topicBytes)
group.TopicID = childAG.String("id") group.TopicID = childAG.String("id")
group.TopicSetBy = childAG.OptionalJIDOrEmpty("participant") group.TopicSetBy = childAG.OptionalJIDOrEmpty("participant")
group.TopicSetAt = time.Unix(childAG.Int64("t"), 0) group.TopicSetAt = childAG.UnixTime("t")
} }
case "announcement": case "announcement":
group.IsAnnounce = true group.IsAnnounce = true
@ -477,7 +476,7 @@ func (cli *Client) parseGroupChange(node *waBinary.Node) (*events.GroupInfo, err
evt.JID = ag.JID("from") evt.JID = ag.JID("from")
evt.Notify = ag.OptionalString("notify") evt.Notify = ag.OptionalString("notify")
evt.Sender = ag.OptionalJID("participant") evt.Sender = ag.OptionalJID("participant")
evt.Timestamp = time.Unix(ag.Int64("t"), 0) evt.Timestamp = ag.UnixTime("t")
if !ag.OK() { if !ag.OK() {
return nil, fmt.Errorf("group change doesn't contain required attributes: %w", ag.Error()) return nil, fmt.Errorf("group change doesn't contain required attributes: %w", ag.Error())
} }
@ -505,7 +504,7 @@ func (cli *Client) parseGroupChange(node *waBinary.Node) (*events.GroupInfo, err
case "subject": case "subject":
evt.Name = &types.GroupName{ evt.Name = &types.GroupName{
Name: cag.String("subject"), Name: cag.String("subject"),
NameSetAt: time.Unix(cag.Int64("s_t"), 0), NameSetAt: cag.UnixTime("s_t"),
NameSetBy: cag.OptionalJIDOrEmpty("s_o"), NameSetBy: cag.OptionalJIDOrEmpty("s_o"),
} }
case "description": case "description":

View File

@ -53,3 +53,11 @@ func (int *DangerousInternalClient) RefreshMediaConn(force bool) (*MediaConn, er
func (int *DangerousInternalClient) GetServerPreKeyCount() (int, error) { func (int *DangerousInternalClient) GetServerPreKeyCount() (int, error) {
return int.c.getServerPreKeyCount() return int.c.getServerPreKeyCount()
} }
func (int *DangerousInternalClient) RequestAppStateKeys(keyIDs [][]byte) {
int.c.requestAppStateKeys(keyIDs)
}
func (int *DangerousInternalClient) SendRetryReceipt(node *waBinary.Node, forceIncludeIdentity bool) {
int.c.sendRetryReceipt(node, forceIncludeIdentity)
}

View File

@ -13,6 +13,7 @@ import (
waBinary "go.mau.fi/whatsmeow/binary" waBinary "go.mau.fi/whatsmeow/binary"
"go.mau.fi/whatsmeow/types" "go.mau.fi/whatsmeow/types"
"go.mau.fi/whatsmeow/types/events"
) )
var ( var (
@ -25,12 +26,27 @@ var (
) )
func (cli *Client) keepAliveLoop(ctx context.Context) { func (cli *Client) keepAliveLoop(ctx context.Context) {
var lastSuccess time.Time
var errorCount int
for { for {
interval := rand.Int63n(KeepAliveIntervalMax.Milliseconds()-KeepAliveIntervalMin.Milliseconds()) + KeepAliveIntervalMin.Milliseconds() interval := rand.Int63n(KeepAliveIntervalMax.Milliseconds()-KeepAliveIntervalMin.Milliseconds()) + KeepAliveIntervalMin.Milliseconds()
select { select {
case <-time.After(time.Duration(interval) * time.Millisecond): case <-time.After(time.Duration(interval) * time.Millisecond):
if !cli.sendKeepAlive(ctx) { isSuccess, shouldContinue := cli.sendKeepAlive(ctx)
if !shouldContinue {
return return
} else if !isSuccess {
errorCount++
go cli.dispatchEvent(&events.KeepAliveTimeout{
ErrorCount: errorCount,
LastSuccess: lastSuccess,
})
} else {
if errorCount > 0 {
errorCount = 0
go cli.dispatchEvent(&events.KeepAliveRestored{})
}
lastSuccess = time.Now()
} }
case <-ctx.Done(): case <-ctx.Done():
return return
@ -38,7 +54,7 @@ func (cli *Client) keepAliveLoop(ctx context.Context) {
} }
} }
func (cli *Client) sendKeepAlive(ctx context.Context) bool { func (cli *Client) sendKeepAlive(ctx context.Context) (isSuccess, shouldContinue bool) {
respCh, err := cli.sendIQAsync(infoQuery{ respCh, err := cli.sendIQAsync(infoQuery{
Namespace: "w:p", Namespace: "w:p",
Type: "get", Type: "get",
@ -47,16 +63,16 @@ func (cli *Client) sendKeepAlive(ctx context.Context) bool {
}) })
if err != nil { if err != nil {
cli.Log.Warnf("Failed to send keepalive: %v", err) cli.Log.Warnf("Failed to send keepalive: %v", err)
return true return false, true
} }
select { select {
case <-respCh: case <-respCh:
// All good // All good
return true, true
case <-time.After(KeepAliveResponseDeadline): case <-time.After(KeepAliveResponseDeadline):
// TODO disconnect websocket?
cli.Log.Warnf("Keepalive timed out") cli.Log.Warnf("Keepalive timed out")
return false, true
case <-ctx.Done(): case <-ctx.Done():
return false return false, false
} }
return true
} }

View File

@ -11,7 +11,6 @@ import (
"crypto/cipher" "crypto/cipher"
"crypto/rand" "crypto/rand"
"fmt" "fmt"
"time"
"google.golang.org/protobuf/proto" "google.golang.org/protobuf/proto"
@ -64,8 +63,38 @@ func encryptMediaRetryReceipt(messageID types.MessageID, mediaKey []byte) (ciphe
// SendMediaRetryReceipt sends a request to the phone to re-upload the media in a message. // SendMediaRetryReceipt sends a request to the phone to re-upload the media in a message.
// //
// This is mostly relevant when handling history syncs and getting a 404 or 410 error downloading media.
// Rough example on how to use it (will not work out of the box, you must adjust it depending on what you need exactly):
//
// var mediaRetryCache map[types.MessageID]*waProto.ImageMessage
//
// evt, err := cli.ParseWebMessage(chatJID, historyMsg.GetMessage())
// imageMsg := evt.Message.GetImageMessage() // replace this with the part of the message you want to download
// data, err := cli.Download(imageMsg)
// if errors.Is(err, whatsmeow.ErrMediaDownloadFailedWith404) || errors.Is(err, whatsmeow.ErrMediaDownloadFailedWith410) {
// err = cli.SendMediaRetryReceipt(&evt.Info, imageMsg.GetMediaKey())
// // You need to store the event data somewhere as it's necessary for handling the retry response.
// mediaRetryCache[evt.Info.ID] = imageMsg
// }
//
// The response will come as an *events.MediaRetry. The response will then have to be decrypted // The response will come as an *events.MediaRetry. The response will then have to be decrypted
// using DecryptMediaRetryNotification and the same media key passed here. // using DecryptMediaRetryNotification and the same media key passed here. If the media retry was successful,
// the decrypted notification should contain an updated DirectPath, which can be used to download the file.
//
// func eventHandler(rawEvt interface{}) {
// switch evt := rawEvt.(type) {
// case *events.MediaRetry:
// imageMsg := mediaRetryCache[evt.MessageID]
// retryData, err := whatsmeow.DecryptMediaRetryNotification(evt, imageMsg.GetMediaKey())
// if err != nil || retryData.GetResult != waProto.MediaRetryNotification_SUCCESS {
// return
// }
// // Use the new path to download the attachment
// imageMsg.DirectPath = retryData.DirectPath
// data, err := cli.Download(imageMsg)
// // Alternatively, you can use cli.DownloadMediaWithPath and provide the individual fields manually.
// }
// }
func (cli *Client) SendMediaRetryReceipt(message *types.MessageInfo, mediaKey []byte) error { func (cli *Client) SendMediaRetryReceipt(message *types.MessageInfo, mediaKey []byte) error {
ciphertext, iv, err := encryptMediaRetryReceipt(message.ID, mediaKey) ciphertext, iv, err := encryptMediaRetryReceipt(message.ID, mediaKey)
if err != nil { if err != nil {
@ -104,6 +133,7 @@ func (cli *Client) SendMediaRetryReceipt(message *types.MessageInfo, mediaKey []
} }
// DecryptMediaRetryNotification decrypts a media retry notification using the media key. // DecryptMediaRetryNotification decrypts a media retry notification using the media key.
// See Client.SendMediaRetryReceipt for more info on how to use this.
func DecryptMediaRetryNotification(evt *events.MediaRetry, mediaKey []byte) (*waProto.MediaRetryNotification, error) { func DecryptMediaRetryNotification(evt *events.MediaRetry, mediaKey []byte) (*waProto.MediaRetryNotification, error) {
var notif waProto.MediaRetryNotification var notif waProto.MediaRetryNotification
var plaintext []byte var plaintext []byte
@ -126,7 +156,7 @@ func DecryptMediaRetryNotification(evt *events.MediaRetry, mediaKey []byte) (*wa
func parseMediaRetryNotification(node *waBinary.Node) (*events.MediaRetry, error) { func parseMediaRetryNotification(node *waBinary.Node) (*events.MediaRetry, error) {
ag := node.AttrGetter() ag := node.AttrGetter()
var evt events.MediaRetry var evt events.MediaRetry
evt.Timestamp = time.Unix(ag.Int64("t"), 0) evt.Timestamp = ag.UnixTime("t")
evt.MessageID = types.MessageID(ag.String("id")) evt.MessageID = types.MessageID(ag.String("id"))
if !ag.OK() { if !ag.OK() {
return nil, ag.Error() return nil, ag.Error()

View File

@ -10,11 +10,11 @@ import (
"bytes" "bytes"
"compress/zlib" "compress/zlib"
"crypto/rand" "crypto/rand"
"encoding/hex"
"errors" "errors"
"fmt" "fmt"
"io" "io"
"runtime/debug" "runtime/debug"
"strconv"
"sync/atomic" "sync/atomic"
"time" "time"
@ -48,67 +48,50 @@ func (cli *Client) handleEncryptedMessage(node *waBinary.Node) {
} }
func (cli *Client) parseMessageSource(node *waBinary.Node) (source types.MessageSource, err error) { func (cli *Client) parseMessageSource(node *waBinary.Node) (source types.MessageSource, err error) {
from, ok := node.Attrs["from"].(types.JID) ag := node.AttrGetter()
if !ok { from := ag.JID("from")
err = fmt.Errorf("didn't find valid `from` attribute in message") if from.Server == types.GroupServer || from.Server == types.BroadcastServer {
} else if from.Server == types.GroupServer || from.Server == types.BroadcastServer {
source.IsGroup = true source.IsGroup = true
source.Chat = from source.Chat = from
sender, ok := node.Attrs["participant"].(types.JID) source.Sender = ag.JID("participant")
if !ok { if source.Sender.User == cli.Store.ID.User {
err = fmt.Errorf("didn't find valid `participant` attribute in group message") source.IsFromMe = true
} else {
source.Sender = sender
if source.Sender.User == cli.Store.ID.User {
source.IsFromMe = true
}
} }
if from.Server == types.BroadcastServer { if from.Server == types.BroadcastServer {
recipient, ok := node.Attrs["recipient"].(types.JID) source.BroadcastListOwner = ag.OptionalJIDOrEmpty("recipient")
if ok {
source.BroadcastListOwner = recipient
}
} }
} else if from.User == cli.Store.ID.User { } else if from.User == cli.Store.ID.User {
source.IsFromMe = true source.IsFromMe = true
source.Sender = from source.Sender = from
recipient, ok := node.Attrs["recipient"].(types.JID) recipient := ag.OptionalJID("recipient")
if !ok { if recipient != nil {
source.Chat = from.ToNonAD() source.Chat = *recipient
} else { } else {
source.Chat = recipient source.Chat = from.ToNonAD()
} }
} else { } else {
source.Chat = from.ToNonAD() source.Chat = from.ToNonAD()
source.Sender = from source.Sender = from
} }
err = ag.Error()
return return
} }
func (cli *Client) parseMessageInfo(node *waBinary.Node) (*types.MessageInfo, error) { func (cli *Client) parseMessageInfo(node *waBinary.Node) (*types.MessageInfo, error) {
var info types.MessageInfo var info types.MessageInfo
var err error var err error
var ok bool
info.MessageSource, err = cli.parseMessageSource(node) info.MessageSource, err = cli.parseMessageSource(node)
if err != nil { if err != nil {
return nil, err return nil, err
} }
info.ID, ok = node.Attrs["id"].(string) ag := node.AttrGetter()
if !ok { info.ID = types.MessageID(ag.String("id"))
return nil, fmt.Errorf("didn't find valid `id` attribute in message") info.Timestamp = ag.UnixTime("t")
info.PushName = ag.OptionalString("notify")
info.Category = ag.OptionalString("category")
if !ag.OK() {
return nil, ag.Error()
} }
ts, ok := node.Attrs["t"].(string)
if !ok {
return nil, fmt.Errorf("didn't find valid `t` (timestamp) attribute in message")
}
tsInt, err := strconv.ParseInt(ts, 10, 64)
if err != nil {
return nil, fmt.Errorf("didn't find valid `t` (timestamp) attribute in message: %w", err)
}
info.Timestamp = time.Unix(tsInt, 0)
info.PushName, _ = node.Attrs["notify"].(string)
info.Category, _ = node.Attrs["category"].(string)
for _, child := range node.GetChildren() { for _, child := range node.GetChildren() {
if child.Tag == "multicast" { if child.Tag == "multicast" {
@ -132,6 +115,7 @@ func (cli *Client) decryptMessages(info *types.MessageInfo, node *waBinary.Node)
children := node.GetChildren() children := node.GetChildren()
cli.Log.Debugf("Decrypting %d messages from %s", len(children), info.SourceString()) cli.Log.Debugf("Decrypting %d messages from %s", len(children), info.SourceString())
handled := false handled := false
containsDirectMsg := false
for _, child := range children { for _, child := range children {
if child.Tag != "enc" { if child.Tag != "enc" {
continue continue
@ -144,6 +128,7 @@ func (cli *Client) decryptMessages(info *types.MessageInfo, node *waBinary.Node)
var err error var err error
if encType == "pkmsg" || encType == "msg" { if encType == "pkmsg" || encType == "msg" {
decrypted, err = cli.decryptDM(&child, info.Sender, encType == "pkmsg") decrypted, err = cli.decryptDM(&child, info.Sender, encType == "pkmsg")
containsDirectMsg = true
} else if info.IsGroup && encType == "skmsg" { } else if info.IsGroup && encType == "skmsg" {
decrypted, err = cli.decryptGroupMsg(&child, info.Sender, info.Chat) decrypted, err = cli.decryptGroupMsg(&child, info.Sender, info.Chat)
} else { } else {
@ -152,8 +137,9 @@ func (cli *Client) decryptMessages(info *types.MessageInfo, node *waBinary.Node)
} }
if err != nil { if err != nil {
cli.Log.Warnf("Error decrypting message from %s: %v", info.SourceString(), err) cli.Log.Warnf("Error decrypting message from %s: %v", info.SourceString(), err)
go cli.sendRetryReceipt(node, false) isUnavailable := encType == "skmsg" && !containsDirectMsg && errors.Is(err, signalerror.ErrNoSenderKeyForUser)
cli.dispatchEvent(&events.UndecryptableMessage{Info: *info, IsUnavailable: false}) go cli.sendRetryReceipt(node, isUnavailable)
cli.dispatchEvent(&events.UndecryptableMessage{Info: *info, IsUnavailable: isUnavailable})
return return
} }
@ -317,27 +303,35 @@ func (cli *Client) handleHistorySyncNotification(notif *waProto.HistorySyncNotif
} }
func (cli *Client) handleAppStateSyncKeyShare(keys *waProto.AppStateSyncKeyShare) { func (cli *Client) handleAppStateSyncKeyShare(keys *waProto.AppStateSyncKeyShare) {
onlyResyncIfNotSynced := true
cli.Log.Debugf("Got %d new app state keys", len(keys.GetKeys())) cli.Log.Debugf("Got %d new app state keys", len(keys.GetKeys()))
cli.appStateKeyRequestsLock.RLock()
for _, key := range keys.GetKeys() { for _, key := range keys.GetKeys() {
marshaledFingerprint, err := proto.Marshal(key.GetKeyData().GetFingerprint()) marshaledFingerprint, err := proto.Marshal(key.GetKeyData().GetFingerprint())
if err != nil { if err != nil {
cli.Log.Errorf("Failed to marshal fingerprint of app state sync key %X", key.GetKeyId().GetKeyId()) cli.Log.Errorf("Failed to marshal fingerprint of app state sync key %X", key.GetKeyId().GetKeyId())
continue continue
} }
_, isReRequest := cli.appStateKeyRequests[hex.EncodeToString(key.GetKeyId().GetKeyId())]
if isReRequest {
onlyResyncIfNotSynced = false
}
err = cli.Store.AppStateKeys.PutAppStateSyncKey(key.GetKeyId().GetKeyId(), store.AppStateSyncKey{ err = cli.Store.AppStateKeys.PutAppStateSyncKey(key.GetKeyId().GetKeyId(), store.AppStateSyncKey{
Data: key.GetKeyData().GetKeyData(), Data: key.GetKeyData().GetKeyData(),
Fingerprint: marshaledFingerprint, Fingerprint: marshaledFingerprint,
Timestamp: key.GetKeyData().GetTimestamp(), Timestamp: key.GetKeyData().GetTimestamp(),
}) })
if err != nil { if err != nil {
cli.Log.Errorf("Failed to store app state sync key %X", key.GetKeyId().GetKeyId()) cli.Log.Errorf("Failed to store app state sync key %X: %v", key.GetKeyId().GetKeyId(), err)
continue continue
} }
cli.Log.Debugf("Received app state sync key %X", key.GetKeyId().GetKeyId()) cli.Log.Debugf("Received app state sync key %X", key.GetKeyId().GetKeyId())
} }
cli.appStateKeyRequestsLock.RUnlock()
for _, name := range appstate.AllPatchNames { for _, name := range appstate.AllPatchNames {
err := cli.FetchAppState(name, false, true) err := cli.FetchAppState(name, false, onlyResyncIfNotSynced)
if err != nil { if err != nil {
cli.Log.Errorf("Failed to do initial fetch of app state %s: %v", name, err) cli.Log.Errorf("Failed to do initial fetch of app state %s: %v", name, err)
} }
@ -364,18 +358,11 @@ func (cli *Client) handleProtocolMessage(info *types.MessageInfo, msg *waProto.M
} }
} }
func (cli *Client) handleDecryptedMessage(info *types.MessageInfo, msg *waProto.Message) { func (cli *Client) processProtocolParts(info *types.MessageInfo, msg *waProto.Message) {
evt := &events.Message{Info: *info, RawMessage: msg} // Hopefully sender key distribution messages and protocol messages can't be inside ephemeral messages
// First unwrap device sent messages
if msg.GetDeviceSentMessage().GetMessage() != nil { if msg.GetDeviceSentMessage().GetMessage() != nil {
msg = msg.GetDeviceSentMessage().GetMessage() msg = msg.GetDeviceSentMessage().GetMessage()
evt.Info.DeviceSentMeta = &types.DeviceSentMeta{
DestinationJID: msg.GetDeviceSentMessage().GetDestinationJid(),
Phash: msg.GetDeviceSentMessage().GetPhash(),
}
} }
if msg.GetSenderKeyDistributionMessage() != nil { if msg.GetSenderKeyDistributionMessage() != nil {
if !info.IsGroup { if !info.IsGroup {
cli.Log.Warnf("Got sender key distribution message in non-group chat from", info.Sender) cli.Log.Warnf("Got sender key distribution message in non-group chat from", info.Sender)
@ -387,19 +374,12 @@ func (cli *Client) handleDecryptedMessage(info *types.MessageInfo, msg *waProto.
cli.handleProtocolMessage(info, msg) cli.handleProtocolMessage(info, msg)
} }
// Unwrap ephemeral and view-once messages }
// Hopefully sender key distribution messages and protocol messages can't be inside ephemeral messages
if msg.GetEphemeralMessage().GetMessage() != nil {
msg = msg.GetEphemeralMessage().GetMessage()
evt.IsEphemeral = true
}
if msg.GetViewOnceMessage().GetMessage() != nil {
msg = msg.GetViewOnceMessage().GetMessage()
evt.IsViewOnce = true
}
evt.Message = msg
cli.dispatchEvent(evt) func (cli *Client) handleDecryptedMessage(info *types.MessageInfo, msg *waProto.Message) {
cli.processProtocolParts(info, msg)
evt := &events.Message{Info: *info, RawMessage: msg}
cli.dispatchEvent(evt.UnwrapRaw())
} }
func (cli *Client) sendProtocolMessageReceipt(id, msgType string) { func (cli *Client) sendProtocolMessageReceipt(id, msgType string) {

View File

@ -8,7 +8,6 @@ package whatsmeow
import ( import (
"errors" "errors"
"time"
"go.mau.fi/whatsmeow/appstate" "go.mau.fi/whatsmeow/appstate"
waBinary "go.mau.fi/whatsmeow/binary" waBinary "go.mau.fi/whatsmeow/binary"
@ -40,7 +39,7 @@ func (cli *Client) handleEncryptNotification(node *waBinary.Node) {
if err != nil { if err != nil {
cli.Log.Warnf("Failed to delete all sessions of %s from store after identity change: %v", from, err) cli.Log.Warnf("Failed to delete all sessions of %s from store after identity change: %v", from, err)
} }
ts := time.Unix(node.AttrGetter().Int64("t"), 0) ts := node.AttrGetter().UnixTime("t")
cli.dispatchEvent(&events.IdentityChange{JID: from, Timestamp: ts}) cli.dispatchEvent(&events.IdentityChange{JID: from, Timestamp: ts})
} else { } else {
cli.Log.Debugf("Got unknown encryption notification from server: %s", node.XMLString()) cli.Log.Debugf("Got unknown encryption notification from server: %s", node.XMLString())
@ -65,7 +64,7 @@ func (cli *Client) handleAppStateNotification(node *waBinary.Node) {
} }
func (cli *Client) handlePictureNotification(node *waBinary.Node) { func (cli *Client) handlePictureNotification(node *waBinary.Node) {
ts := time.Unix(node.AttrGetter().Int64("t"), 0) ts := node.AttrGetter().UnixTime("t")
for _, child := range node.GetChildren() { for _, child := range node.GetChildren() {
ag := child.AttrGetter() ag := child.AttrGetter()
var evt events.Picture var evt events.Picture

View File

@ -138,13 +138,13 @@ func (cli *Client) handlePair(deviceIdentityBytes []byte, reqID, businessName, p
return fmt.Errorf("failed to parse device identity details in pair success message: %w", err) return fmt.Errorf("failed to parse device identity details in pair success message: %w", err)
} }
cli.Store.Account = proto.Clone(&deviceIdentity).(*waProto.ADVSignedDeviceIdentity)
mainDeviceJID := jid mainDeviceJID := jid
mainDeviceJID.Device = 0 mainDeviceJID.Device = 0
mainDeviceIdentity := *(*[32]byte)(deviceIdentity.AccountSignatureKey) mainDeviceIdentity := *(*[32]byte)(deviceIdentity.AccountSignatureKey)
deviceIdentity.AccountSignatureKey = nil deviceIdentity.AccountSignatureKey = nil
cli.Store.Account = proto.Clone(&deviceIdentity).(*waProto.ADVSignedDeviceIdentity)
selfSignedDeviceIdentity, err := proto.Marshal(&deviceIdentity) selfSignedDeviceIdentity, err := proto.Marshal(&deviceIdentity)
if err != nil { if err != nil {
cli.sendIQError(reqID, 500, "internal-error") cli.sendIQError(reqID, 500, "internal-error")

Some files were not shown because too many files have changed in this diff Show More