Update dependencies (#1841)
This commit is contained in:
parent
3819062574
commit
8751fb4bb1
40
go.mod
40
go.mod
|
@ -12,7 +12,7 @@ require (
|
|||
github.com/davecgh/go-spew v1.1.1
|
||||
github.com/fsnotify/fsnotify v1.5.4
|
||||
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/gorilla/schema v1.2.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/matterclient v0.0.0-20220430213656-07aca2731bc9
|
||||
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/mdp/qrterminal v1.0.1
|
||||
github.com/nelsonken/gomf v0.0.0-20190423072027-c65cc0469e94
|
||||
|
@ -41,21 +41,21 @@ require (
|
|||
github.com/shazow/ssh-chat v1.10.1
|
||||
github.com/sirupsen/logrus v1.8.1
|
||||
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/vincent-petithory/dataurl v1.0.0
|
||||
github.com/writeas/go-strip-markdown v2.0.1+incompatible
|
||||
github.com/yaegashi/msgraph.go v0.1.4
|
||||
github.com/zfjagann/golang-ring v0.0.0-20220330170733-19bcea1b6289
|
||||
go.mau.fi/whatsmeow v0.0.0-20220504135614-f1f2a9d231fb
|
||||
golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9
|
||||
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5
|
||||
go.mau.fi/whatsmeow v0.0.0-20220601182603-a8d86cf1812c
|
||||
golang.org/x/image v0.0.0-20220601225756-64ec528b34cd
|
||||
golang.org/x/oauth2 v0.0.0-20220524215830-622c5d57e401
|
||||
golang.org/x/text v0.3.7
|
||||
gomod.garykim.dev/nc-talk v0.3.0
|
||||
google.golang.org/protobuf v1.28.0
|
||||
gopkg.in/olahol/melody.v1 v1.0.0-20170518105555-d52139073376
|
||||
layeh.com/gumble v0.0.0-20200818122324-146f9205029b
|
||||
modernc.org/sqlite v1.17.2
|
||||
modernc.org/sqlite v1.17.3
|
||||
)
|
||||
|
||||
require (
|
||||
|
@ -81,7 +81,7 @@ require (
|
|||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||
github.com/kettek/apng v0.0.0-20191108220231-414630eed80f // 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/magiconair/properties v1.8.6 // 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/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // 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/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/reflect2 v1.0.2 // 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/opentracing/opentracing-go v1.2.0 // indirect
|
||||
github.com/pborman/uuid v1.2.1 // indirect
|
||||
github.com/pelletier/go-toml v1.9.4 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.0-beta.8 // indirect
|
||||
github.com/pelletier/go-toml v1.9.5 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.1 // indirect
|
||||
github.com/philhofer/fwd v1.1.1 // indirect
|
||||
github.com/pkg/errors v0.9.1 // 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/skip2/go-qrcode v0.0.0-20190110000554-dc11ecdae0a9 // 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/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/valyala/bytebufferpool v1.0.0 // 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/zap v1.17.0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 // indirect
|
||||
golang.org/x/mod v0.5.1 // indirect
|
||||
golang.org/x/net v0.0.0-20220412020605-290c469a71a5 // indirect
|
||||
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect
|
||||
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect
|
||||
golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2 // indirect
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
|
||||
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324 // indirect
|
||||
golang.org/x/tools v0.1.9 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f // indirect
|
||||
golang.org/x/tools v0.1.10 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
gopkg.in/ini.v1 v1.66.4 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.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
|
||||
modernc.org/cc/v3 v3.36.0 // indirect
|
||||
modernc.org/ccgo/v3 v3.16.6 // indirect
|
||||
|
|
189
go.sum
189
go.sum
|
@ -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.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4=
|
||||
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.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A=
|
||||
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 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.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.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
||||
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.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.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.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=
|
||||
|
@ -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-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.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/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=
|
||||
|
@ -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/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||
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/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/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/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.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/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/upsidedown_store_api v1.0.1/go.mod h1:MQDVGpHZrpe3Uy26zJBf/a8h0FZY6xJbthIMm8myH2Q=
|
||||
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/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.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
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.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-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-20211130200136-a8f946100490/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
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/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.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.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.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/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=
|
||||
|
@ -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/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY=
|
||||
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.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
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/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.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 v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
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.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.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U=
|
||||
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/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.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.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
|
||||
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.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.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.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
||||
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/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-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.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.3.0/go.mod h1:UpN9CgLZNsv4e9XG50UU8xdI0F43UQ4HmxLBDwaroHU=
|
||||
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.3/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-20220509074759-a57bf950ab8c/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA=
|
||||
github.com/gomarkdown/markdown v0.0.0-20220603122033-8f3b341fef32 h1:QxcGJpbMJw6tHRtrHKJiL11LdX1SXDfV1f4t4mJl3QI=
|
||||
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 v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
|
||||
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.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.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.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/v35 v35.2.0/go.mod h1:s0515YVTI+IMrDoy9Y4pHt9ShGpzHvHO8rZ7L7acgvs=
|
||||
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-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-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-20210609004039-a478d1d731e9/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.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.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c=
|
||||
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/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.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||
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/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc=
|
||||
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/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.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/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
||||
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.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 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-immutable-radix v1.0.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/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.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY=
|
||||
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.2.2/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.1/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
|
||||
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.7/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4=
|
||||
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/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/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-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
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.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.3/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
|
||||
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 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.5/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/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
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.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.11 h1:i2lw1Pm7Yi/4O6XCSyJWqEHI2MDw2FzUK6o/D21xn2A=
|
||||
github.com/klauspost/cpuid/v2 v2.0.11/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c=
|
||||
github.com/klauspost/cpuid/v2 v2.0.12 h1:p9dKCg8i4gmOxtv35DvrYoWqYzQrvEVdjQ762Y0OqZE=
|
||||
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.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
||||
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/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-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/lib/pq v1.0.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/go.mod h1:lgrnhcF8bg/Bd5HA5DOb4Z+uGqUqGnp4skr+J2GwVgI=
|
||||
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.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
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/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.6.1 h1:jza7N9OMqFe+z7s9LZeSj1M4E/2DOV/llIUpi9VWg2U=
|
||||
github.com/mattermost/mattermost-server/v6 v6.6.1/go.mod h1:oR6UCRo+SEvnfN2FEOdzHs1UljrskyCKU8tWeKlxgMo=
|
||||
github.com/mattermost/mattermost-server/v6 v6.7.0 h1:DqNZFuzXU4rtAzmmrpk6wXYI06GzfN+TsGqWf9mwlXc=
|
||||
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/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=
|
||||
|
@ -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.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.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/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/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.23 h1:NleyGQvAn9VQMU+YHVrgV4CX+EPtxPt/78lHOOTncy4=
|
||||
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 h1:HPlHiET6L5gIgrHRaw1xFo1OaN4bEP/082asWh3WJtI=
|
||||
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 v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g=
|
||||
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 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.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGgCcyj8cs=
|
||||
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/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=
|
||||
|
@ -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/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.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.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||
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.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
|
||||
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.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-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
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.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc=
|
||||
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.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
||||
github.com/onsi/gomega v1.17.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-20220121172623-5db5eafcecbb/go.mod h1:GHI1bnmAcbp96z6LNfBJvtrjxhaXGkbsk967utPlvL8=
|
||||
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/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/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/go.mod h1:YnNlZP7l4MhyGQ4CBRwv6ohZTPrUJJZtEv4ZgADkbs4=
|
||||
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.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.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM=
|
||||
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/v2 v2.0.0-beta.8/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo=
|
||||
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
|
||||
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 v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||
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.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.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
|
||||
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-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.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.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-20180725123919-05ee40e3a273/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.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.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.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww=
|
||||
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 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/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig=
|
||||
github.com/sagikazarmark/crypt v0.5.0/go.mod h1:l+nzl7KWh51rpzp2h7t4MZWyiEWdhNpOAnclKvg+mdA=
|
||||
github.com/sagikazarmark/crypt v0.6.0/go.mod h1:U8+INwJo3nBv1m6A/8OBXAq7Jnpspk5AxSgDyEQcea8=
|
||||
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/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/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.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4=
|
||||
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/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo=
|
||||
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.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA=
|
||||
github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
|
||||
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.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
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.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.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.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
|
||||
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.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
|
||||
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.11.0 h1:7OX/1FS6n7jHD1zGrZTM7WtY13ZELRyosK4k93oPr44=
|
||||
github.com/spf13/viper v1.11.0/go.mod h1:djo0X/bA5+tYVoCn+C7cAYJGcVn/qYLFTG8gdUsX7Zk=
|
||||
github.com/spf13/viper v1.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ=
|
||||
github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI=
|
||||
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-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.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
|
||||
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.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-20180916011248-d98352740cb2/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.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.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/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=
|
||||
|
@ -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/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.1/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
|
||||
go.etcd.io/etcd/api/v3 v3.5.2/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A=
|
||||
go.etcd.io/etcd/api/v3 v3.5.4/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.1/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/pkg/v3 v3.5.4/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.1/go.mod h1:pMEacxZW7o8pg4CrFE7pquyCJJzZvkvdD2RibOCCCGs=
|
||||
go.etcd.io/etcd/client/v2 v2.305.2/go.mod h1:2D7ZejHVMIfog1221iLSYlQRzrtECw3kz4I4VAQm3qI=
|
||||
go.etcd.io/etcd/client/v2 v2.305.4/go.mod h1:Ud+VUwIi9/uQHOMA+4ekToJ12lTxlv0zB/+DHwTGEbU=
|
||||
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/go.mod h1:kBOXTvYyDG/q1Ihgvd4J6WenGPh7wtEGvPKF6vmf5ak=
|
||||
go.mau.fi/whatsmeow v0.0.0-20220504135614-f1f2a9d231fb h1:xI4HiJwBMmztBXFzjKWt7Ea8xmOO7LyYCYV0/ROU7kY=
|
||||
go.mau.fi/whatsmeow v0.0.0-20220504135614-f1f2a9d231fb/go.mod h1:iUBgOLNaqShLrR17u0kIiRptIGFH+nbT1tRhaWBEX/c=
|
||||
go.mau.fi/whatsmeow v0.0.0-20220601182603-a8d86cf1812c h1:2pn4sUljgVcFrPl1wyFOA0Qvg8726yzwyC1+qVdPkjM=
|
||||
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.7.0/go.mod h1:Q4oFMbo1+MSNqICAdYMlC/zSTrwCogR4R8NzkI+yfU8=
|
||||
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-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-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/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
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-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-20211028202545-6944b10bf410/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-20220413100746-70e8d0d3baa9/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-20220601225756-64ec528b34cd h1:9NbNcTg//wfC5JskFW4Z3sqwVnjmJKHxLAol1bW2qgw=
|
||||
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-20181026193005-c67002cb31c3/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.1/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.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38=
|
||||
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 h1:kQgndtyPBW/JIYERgdxfwMYh3AVStj88WQTlNDi2a+o=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
|
||||
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-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-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-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-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-20180821212333-d2e6202438be/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-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-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-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/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=
|
||||
|
@ -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-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-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-20180823144017-11551d06cbcc/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-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-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-20210823070655-63515b42dcdf/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-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-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-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-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-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-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-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-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
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.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.9 h1:j9KsMiaP1c3B0OTQGth0/k+miLGTgLsAFUCrF2vLcF8=
|
||||
golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
|
||||
golang.org/x/tools v0.1.10 h1:QjFRCZxdOhBJ/UNgnBZLbNV13DlbnK0quyivTnXJM20=
|
||||
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-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-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-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-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/go.mod h1:q/Adot/H7iqi+H4lANopV7/xcMf+sX3AZXUXqiITwok=
|
||||
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.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU=
|
||||
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.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.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8=
|
||||
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.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
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-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-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-20211208223120-3a66f561d7aa/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-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-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-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 v1.8.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.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
|
||||
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.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/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=
|
||||
|
@ -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.57.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/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
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-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-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 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/gorm v1.20.12/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/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.17.2 h1:TjmF36Wi5QcPYqRoAacV1cAyJ7xB/CD0ExpVUEMebnw=
|
||||
modernc.org/sqlite v1.17.2/go.mod h1:GOQmuiXd6pTTes1Fi2s9apiCcD/wbKQtBZ0Nw6/etjM=
|
||||
modernc.org/sqlite v1.17.3 h1:iE+coC5g17LtByDYDWKpR6m2Z9022YrSh3bumwOnIrI=
|
||||
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.1 h1:xv+J1BXY3Opl2ALrBwyfEikFAj8pmqcpnfmuwUwcozs=
|
||||
modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw=
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package markdown
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/gomarkdown/markdown/ast"
|
||||
"github.com/gomarkdown/markdown/internal/valid"
|
||||
"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) {
|
||||
// a tag begin with '#'
|
||||
if link[0] == '#' {
|
||||
|
@ -351,14 +288,6 @@ func needSkipLink(flags Flags, dest []byte) bool {
|
|||
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 {
|
||||
if len(info) == 0 {
|
||||
return attrs
|
||||
|
@ -1297,21 +1226,8 @@ func isListItemTerm(node ast.Node) bool {
|
|||
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 {
|
||||
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) {
|
||||
return true
|
||||
|
@ -1321,7 +1237,7 @@ func isSafeLink(link []byte) bool {
|
|||
}
|
||||
}
|
||||
|
||||
for _, prefix := range validUris {
|
||||
for _, prefix := range valid.URIs {
|
||||
// TODO: handle unicode here
|
||||
// case-insensitive prefix test
|
||||
if len(link) > len(prefix) && bytes.Equal(bytes.ToLower(link[:len(prefix)]), prefix) && isAlnum(link[len(prefix)]) {
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
package valid
|
||||
|
||||
var URIs = [][]byte{
|
||||
[]byte("http://"),
|
||||
[]byte("https://"),
|
||||
[]byte("ftp://"),
|
||||
[]byte("mailto:"),
|
||||
}
|
||||
|
||||
var Paths = [][]byte{
|
||||
[]byte("/"),
|
||||
[]byte("./"),
|
||||
[]byte("../"),
|
||||
}
|
|
@ -24,8 +24,8 @@ const (
|
|||
)
|
||||
|
||||
var (
|
||||
reBackslashOrAmp = regexp.MustCompile("[\\&]")
|
||||
reEntityOrEscapedChar = regexp.MustCompile("(?i)\\\\" + escapable + "|" + charEntity)
|
||||
reBackslashOrAmp = regexp.MustCompile(`[\&]`)
|
||||
reEntityOrEscapedChar = regexp.MustCompile(`(?i)\\` + escapable + "|" + charEntity)
|
||||
|
||||
// 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.
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"strconv"
|
||||
|
||||
"github.com/gomarkdown/markdown/ast"
|
||||
"github.com/gomarkdown/markdown/internal/valid"
|
||||
)
|
||||
|
||||
// Parsing of inline elements
|
||||
|
@ -994,12 +995,9 @@ func isEndOfLink(char byte) bool {
|
|||
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 {
|
||||
nLink := len(link)
|
||||
for _, path := range validPaths {
|
||||
for _, path := range valid.Paths {
|
||||
nPath := len(path)
|
||||
linkPrefix := link[:nPath]
|
||||
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
|
||||
// case-insensitive prefix test
|
||||
nPrefix := len(prefix)
|
||||
|
@ -1119,7 +1117,7 @@ func isMailtoAutoLink(data []byte) int {
|
|||
nb++
|
||||
|
||||
case '-', '.', '_':
|
||||
break
|
||||
// no-op but not defult
|
||||
|
||||
case '>':
|
||||
if nb == 1 {
|
||||
|
|
|
@ -8,7 +8,6 @@ import (
|
|||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/gomarkdown/markdown/ast"
|
||||
)
|
||||
|
@ -720,6 +719,7 @@ func isAlnum(c byte) bool {
|
|||
// TODO: this is not used
|
||||
// Replace tab characters with spaces, aligning to the next TAB_SIZE column.
|
||||
// always ends output with a newline
|
||||
/*
|
||||
func expandTabs(out *bytes.Buffer, line []byte, tabSize int) {
|
||||
// first, check for common cases: no tabs, or only tabs at beginning of line
|
||||
i, prefix := 0, 0
|
||||
|
@ -775,6 +775,7 @@ func expandTabs(out *bytes.Buffer, line []byte, tabSize int) {
|
|||
i++
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// Find if a line counts as indented or not.
|
||||
// Returns number of characters the indent is (0 = not indented).
|
||||
|
|
|
@ -27,7 +27,7 @@ const (
|
|||
ChannelGroupMinUsers = 3
|
||||
DefaultChannelName = "town-square"
|
||||
ChannelDisplayNameMaxRunes = 64
|
||||
ChannelNameMinLength = 2
|
||||
ChannelNameMinLength = 1
|
||||
ChannelNameMaxLength = 64
|
||||
ChannelHeaderMaxRunes = 1024
|
||||
ChannelPurposeMaxRunes = 250
|
||||
|
@ -216,7 +216,7 @@ func (o *Channel) IsValid() *AppError {
|
|||
}
|
||||
|
||||
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) {
|
||||
|
|
|
@ -8,4 +8,17 @@ type ChannelStats struct {
|
|||
MemberCount int64 `json:"member_count"`
|
||||
GuestCount int64 `json:"guest_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)
|
||||
}
|
||||
|
|
|
@ -2638,6 +2638,30 @@ func (c *Client4) InviteGuestsToTeam(teamId string, userEmails []string, channel
|
|||
// InviteUsersToTeam invite users by email to the team.
|
||||
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))
|
||||
|
||||
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 {
|
||||
return nil, BuildResponse(r), err
|
||||
}
|
||||
|
@ -3748,6 +3772,49 @@ func (c *Client4) GetPostThread(postId string, etag string, collapsedThreads boo
|
|||
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.
|
||||
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)
|
||||
|
@ -6429,6 +6496,39 @@ func (c *Client4) GetBulkReactions(postIds []string) (map[string][]*Reaction, *R
|
|||
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
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
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) {
|
||||
r, err := c.DoAPIGet(c.cloudRoute()+"/subscription/invoices", "")
|
||||
if err != nil {
|
||||
|
@ -7782,6 +7870,12 @@ func (c *Client4) GetUserThreads(userId, teamId string, options GetUserThreadsOp
|
|||
if options.Unread {
|
||||
v.Set("unread", "true")
|
||||
}
|
||||
if options.ThreadsOnly {
|
||||
v.Set("threadsOnly", "true")
|
||||
}
|
||||
if options.TotalsOnly {
|
||||
v.Set("totalsOnly", "true")
|
||||
}
|
||||
url := c.userThreadsRoute(userId, teamId)
|
||||
if len(v) > 0 {
|
||||
url += "?" + v.Encode()
|
||||
|
@ -7826,6 +7920,18 @@ func (c *Client4) UpdateThreadsReadForUser(userId, teamId string) (*Response, er
|
|||
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) {
|
||||
r, err := c.DoAPIPut(fmt.Sprintf("%s/read/%d", c.userThreadRoute(userId, teamId, threadId), timestamp), "")
|
||||
if err != nil {
|
||||
|
@ -7854,26 +7960,6 @@ func (c *Client4) UpdateThreadFollowForUser(userId, teamId, threadId string, sta
|
|||
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) {
|
||||
url := fmt.Sprintf("%s/%s?page=%d&per_page=%d", c.sharedChannelsRoute(), teamID, page, perPage)
|
||||
r, err := c.DoAPIGet(url, "")
|
||||
|
|
|
@ -11,8 +11,6 @@ const (
|
|||
EventTypeSendAdminWelcomeEmail = "send-admin-welcome-email"
|
||||
EventTypeTrialWillEnd = "trial-will-end"
|
||||
EventTypeTrialEnded = "trial-ended"
|
||||
JoinLimitation = "join"
|
||||
InviteLimitation = "invite"
|
||||
)
|
||||
|
||||
var MockCWS string
|
||||
|
@ -180,12 +178,6 @@ type FailedPayment struct {
|
|||
type CloudWorkspaceOwner struct {
|
||||
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 {
|
||||
ProductID string `json:"product_id"`
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ const (
|
|||
ClusterEventInvalidateCacheForWebhooks ClusterEvent = "inv_webhooks"
|
||||
ClusterEventInvalidateCacheForEmojisById ClusterEvent = "inv_emojis_by_id"
|
||||
ClusterEventInvalidateCacheForEmojisIdByName ClusterEvent = "inv_emojis_id_by_name"
|
||||
ClusterEventInvalidateCacheForChannelFileCount ClusterEvent = "inv_channel_file_count"
|
||||
ClusterEventInvalidateCacheForChannelPinnedpostsCounts ClusterEvent = "inv_channel_pinnedposts_counts"
|
||||
ClusterEventInvalidateCacheForChannelMemberCounts ClusterEvent = "inv_channel_member_counts"
|
||||
ClusterEventInvalidateCacheForLastPosts ClusterEvent = "inv_last_posts"
|
||||
|
|
|
@ -197,11 +197,11 @@ const (
|
|||
ElasticsearchSettingsDefaultPostsAggregatorJobStartTime = "03:00"
|
||||
ElasticsearchSettingsDefaultIndexPrefix = ""
|
||||
ElasticsearchSettingsDefaultLiveIndexingBatchSize = 1
|
||||
ElasticsearchSettingsDefaultBulkIndexingTimeWindowSeconds = 3600
|
||||
ElasticsearchSettingsDefaultRequestTimeoutSeconds = 30
|
||||
ElasticsearchSettingsDefaultBatchSize = 10000
|
||||
|
||||
BleveSettingsDefaultIndexDir = ""
|
||||
BleveSettingsDefaultBulkIndexingTimeWindowSeconds = 3600
|
||||
BleveSettingsDefaultBatchSize = 10000
|
||||
|
||||
DataRetentionSettingsDefaultMessageRetentionDays = 365
|
||||
DataRetentionSettingsDefaultFileRetentionDays = 365
|
||||
|
@ -284,6 +284,7 @@ type ServiceSettings struct {
|
|||
TLSKeyFile *string `access:"environment_web_server,write_restrictable,cloud_restrictable"`
|
||||
TLSMinVer *string `access:"write_restrictable,cloud_restrictable"` // telemetry: none
|
||||
TLSStrictTransport *bool `access:"write_restrictable,cloud_restrictable"`
|
||||
// In seconds.
|
||||
TLSStrictTransportMaxAge *int64 `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"`
|
||||
|
@ -904,7 +905,6 @@ type ExperimentalSettings struct {
|
|||
LinkMetadataTimeoutMilliseconds *int64 `access:"experimental_features,write_restrictable,cloud_restrictable"`
|
||||
RestrictSystemAdmin *bool `access:"experimental_features,write_restrictable"`
|
||||
UseNewSAMLLibrary *bool `access:"experimental_features,cloud_restrictable"`
|
||||
CloudUserLimit *int64 `access:"experimental_features,write_restrictable"`
|
||||
CloudBilling *bool `access:"experimental_features,write_restrictable"`
|
||||
EnableSharedChannels *bool `access:"experimental_features"`
|
||||
EnableRemoteClusterService *bool `access:"experimental_features"`
|
||||
|
@ -931,11 +931,6 @@ func (s *ExperimentalSettings) SetDefaults() {
|
|||
s.RestrictSystemAdmin = NewBool(false)
|
||||
}
|
||||
|
||||
if s.CloudUserLimit == nil {
|
||||
// User limit 0 is treated as no limit
|
||||
s.CloudUserLimit = NewInt64(0)
|
||||
}
|
||||
|
||||
if s.CloudBilling == nil {
|
||||
s.CloudBilling = NewBool(false)
|
||||
}
|
||||
|
@ -1541,6 +1536,7 @@ type EmailSettings struct {
|
|||
LoginButtonColor *string `access:"experimental_features"`
|
||||
LoginButtonBorderColor *string `access:"experimental_features"`
|
||||
LoginButtonTextColor *string `access:"experimental_features"`
|
||||
EnableInactivityEmail *bool
|
||||
}
|
||||
|
||||
func (s *EmailSettings) SetDefaults(isUpdate bool) {
|
||||
|
@ -1683,6 +1679,10 @@ func (s *EmailSettings) SetDefaults(isUpdate bool) {
|
|||
if s.LoginButtonTextColor == nil {
|
||||
s.LoginButtonTextColor = NewString("#2389D7")
|
||||
}
|
||||
|
||||
if s.EnableInactivityEmail == nil {
|
||||
s.EnableInactivityEmail = NewBool(true)
|
||||
}
|
||||
}
|
||||
|
||||
type RateLimitSettings struct {
|
||||
|
@ -1896,6 +1896,7 @@ type TeamSettings struct {
|
|||
CustomBrandText *string `access:"site_customization"`
|
||||
CustomDescriptionText *string `access:"site_customization"`
|
||||
RestrictDirectMessage *string `access:"site_users_and_teams"`
|
||||
// In seconds.
|
||||
UserStatusAwayTimeout *int64 `access:"experimental_features"`
|
||||
MaxChannelsPerTeam *int64 `access:"site_users_and_teams"`
|
||||
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
|
||||
IndexPrefix *string `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"`
|
||||
SkipTLSVerification *bool `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)
|
||||
}
|
||||
|
||||
if s.BulkIndexingTimeWindowSeconds == nil {
|
||||
s.BulkIndexingTimeWindowSeconds = NewInt(ElasticsearchSettingsDefaultBulkIndexingTimeWindowSeconds)
|
||||
if s.BatchSize == nil {
|
||||
s.BatchSize = NewInt(ElasticsearchSettingsDefaultBatchSize)
|
||||
}
|
||||
|
||||
if s.RequestTimeoutSeconds == nil {
|
||||
|
@ -2572,7 +2574,8 @@ type BleveSettings struct {
|
|||
EnableIndexing *bool `access:"experimental_bleve"`
|
||||
EnableSearching *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() {
|
||||
|
@ -2592,8 +2595,8 @@ func (bs *BleveSettings) SetDefaults() {
|
|||
bs.EnableAutocomplete = NewBool(false)
|
||||
}
|
||||
|
||||
if bs.BulkIndexingTimeWindowSeconds == nil {
|
||||
bs.BulkIndexingTimeWindowSeconds = NewInt(BleveSettingsDefaultBulkIndexingTimeWindowSeconds)
|
||||
if bs.BatchSize == nil {
|
||||
bs.BatchSize = NewInt(BleveSettingsDefaultBatchSize)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2646,6 +2649,7 @@ type JobSettings struct {
|
|||
RunJobs *bool `access:"write_restrictable,cloud_restrictable"` // telemetry: none
|
||||
RunScheduler *bool `access:"write_restrictable,cloud_restrictable"` // telemetry: none
|
||||
CleanupJobsThresholdDays *int `access:"write_restrictable,cloud_restrictable"`
|
||||
CleanupConfigThresholdDays *int `access:"write_restrictable,cloud_restrictable"`
|
||||
}
|
||||
|
||||
func (s *JobSettings) SetDefaults() {
|
||||
|
@ -2660,6 +2664,10 @@ func (s *JobSettings) SetDefaults() {
|
|||
if s.CleanupJobsThresholdDays == nil {
|
||||
s.CleanupJobsThresholdDays = NewInt(-1)
|
||||
}
|
||||
|
||||
if s.CleanupConfigThresholdDays == nil {
|
||||
s.CleanupConfigThresholdDays = NewInt(-1)
|
||||
}
|
||||
}
|
||||
|
||||
type CloudSettings struct {
|
||||
|
@ -3564,13 +3572,13 @@ func (s *ServiceSettings) isValid() *AppError {
|
|||
|
||||
if *s.SiteURL != "" {
|
||||
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 _, 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)
|
||||
}
|
||||
|
||||
if *s.BulkIndexingTimeWindowSeconds < 1 {
|
||||
return NewAppError("Config.IsValid", "model.config.is_valid.elastic_search.bulk_indexing_time_window_seconds.app_error", nil, "", http.StatusBadRequest)
|
||||
minBatchSize := 1
|
||||
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 {
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
if *bs.BulkIndexingTimeWindowSeconds < 1 {
|
||||
return NewAppError("Config.IsValid", "model.config.is_valid.bleve_search.bulk_indexing_time_window_seconds.app_error", nil, "", http.StatusBadRequest)
|
||||
minBatchSize := 1
|
||||
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
|
||||
|
|
6
vendor/github.com/mattermost/mattermost-server/v6/model/data_retention_policy.go
generated
vendored
6
vendor/github.com/mattermost/mattermost-server/v6/model/data_retention_policy.go
generated
vendored
|
@ -15,7 +15,7 @@ type GlobalRetentionPolicy struct {
|
|||
type RetentionPolicy struct {
|
||||
ID string `db:"Id" json:"id"`
|
||||
DisplayName string `json:"display_name"`
|
||||
PostDuration *int64 `json:"post_duration"`
|
||||
PostDurationDays *int64 `db:"PostDuration" json:"post_duration"`
|
||||
}
|
||||
|
||||
type RetentionPolicyWithTeamAndChannelIDs struct {
|
||||
|
@ -47,7 +47,7 @@ type RetentionPolicyWithTeamAndChannelCountsList struct {
|
|||
|
||||
type RetentionPolicyForTeam struct {
|
||||
TeamID string `db:"Id" json:"team_id"`
|
||||
PostDuration int64 `json:"post_duration"`
|
||||
PostDurationDays int64 `db:"PostDuration" json:"post_duration"`
|
||||
}
|
||||
|
||||
type RetentionPolicyForTeamList struct {
|
||||
|
@ -57,7 +57,7 @@ type RetentionPolicyForTeamList struct {
|
|||
|
||||
type RetentionPolicyForChannel struct {
|
||||
ChannelID string `db:"Id" json:"channel_id"`
|
||||
PostDuration int64 `json:"post_duration"`
|
||||
PostDurationDays int64 `db:"PostDuration" json:"post_duration"`
|
||||
}
|
||||
|
||||
type RetentionPolicyForChannelList struct {
|
||||
|
|
|
@ -16,9 +16,6 @@ type FeatureFlags struct {
|
|||
// all other values as false.
|
||||
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
|
||||
CollapsedThreads bool
|
||||
|
||||
|
@ -38,18 +35,12 @@ type FeatureFlags struct {
|
|||
|
||||
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
|
||||
CallsMobile bool
|
||||
|
||||
// A dash separated list for feature flags to turn on for Boards
|
||||
BoardsFeatureFlags string
|
||||
|
||||
// A/B test for the add members to channel button, possible values = ("top", "bottom")
|
||||
AddMembersToChannel string
|
||||
|
||||
// Enable Create First Channel
|
||||
GuidedChannelCreation bool
|
||||
|
||||
|
@ -70,12 +61,15 @@ type FeatureFlags struct {
|
|||
|
||||
// Enable GraphQL feature
|
||||
GraphQL bool
|
||||
|
||||
InsightsEnabled bool
|
||||
|
||||
CommandPalette bool
|
||||
}
|
||||
|
||||
func (f *FeatureFlags) SetDefaults() {
|
||||
f.TestFeature = "off"
|
||||
f.TestBoolFeature = false
|
||||
f.CloudDelinquentEmailJobsEnabled = false
|
||||
f.CollapsedThreads = true
|
||||
f.EnableRemoteClusterService = false
|
||||
f.AppsEnabled = true
|
||||
|
@ -83,10 +77,8 @@ func (f *FeatureFlags) SetDefaults() {
|
|||
f.PluginApps = ""
|
||||
f.PluginFocalboard = ""
|
||||
f.PermalinkPreviews = true
|
||||
f.NewAccountNoisy = false
|
||||
f.CallsMobile = false
|
||||
f.BoardsFeatureFlags = ""
|
||||
f.AddMembersToChannel = "top"
|
||||
f.GuidedChannelCreation = false
|
||||
f.InviteToTeam = "none"
|
||||
f.CustomGroups = true
|
||||
|
@ -95,6 +87,8 @@ func (f *FeatureFlags) SetDefaults() {
|
|||
f.EnableInactivityCheckJob = true
|
||||
f.UseCaseOnboarding = true
|
||||
f.GraphQL = false
|
||||
f.InsightsEnabled = false
|
||||
f.CommandPalette = false
|
||||
}
|
||||
func (f *FeatureFlags) Plugins() map[string]string {
|
||||
rFFVal := reflect.ValueOf(f).Elem()
|
||||
|
|
76
vendor/github.com/mattermost/mattermost-server/v6/model/insights.go
generated
vendored
Normal file
76
vendor/github.com/mattermost/mattermost-server/v6/model/insights.go
generated
vendored
Normal 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}
|
||||
}
|
|
@ -11,9 +11,12 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
DayInSeconds = 24 * 60 * 60
|
||||
DayInMilliseconds = DayInSeconds * 1000
|
||||
|
||||
ExpiredLicenseError = "api.license.add_license.expired.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/"
|
||||
|
||||
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.
|
||||
func NewTestLicense(features ...string) *License {
|
||||
ret := &License{
|
||||
ExpiresAt: GetMillis() + 90*24*60*60*1000,
|
||||
ExpiresAt: GetMillis() + 90*DayInMilliseconds,
|
||||
Customer: &Customer{},
|
||||
Features: &Features{},
|
||||
}
|
||||
|
|
49
vendor/github.com/mattermost/mattermost-server/v6/model/member_invite.go
generated
vendored
Normal file
49
vendor/github.com/mattermost/mattermost-server/v6/model/member_invite.go
generated
vendored
Normal 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
|
||||
}
|
|
@ -12,6 +12,8 @@ type PreviewPost struct {
|
|||
Post *Post `json:"post"`
|
||||
TeamName string `json:"team_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 {
|
||||
|
@ -23,5 +25,7 @@ func NewPreviewPost(post *Post, team *Team, channel *Channel) *PreviewPost {
|
|||
Post: post,
|
||||
TeamName: team.Name,
|
||||
ChannelDisplayName: channel.DisplayName,
|
||||
ChannelType: channel.Type,
|
||||
ChannelID: channel.Id,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -263,6 +263,9 @@ type GetPostsOptions struct {
|
|||
SkipFetchThreads bool
|
||||
CollapsedThreads 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 {
|
||||
|
|
|
@ -14,6 +14,8 @@ type PostList struct {
|
|||
Posts map[string]*Post `json:"posts"`
|
||||
NextPostId string `json:"next_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 {
|
||||
|
@ -39,6 +41,7 @@ func (o *PostList) Clone() *PostList {
|
|||
Posts: postsCopy,
|
||||
NextPostId: o.NextPostId,
|
||||
PrevPostId: o.PrevPostId,
|
||||
HasNext: o.HasNext,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ func (sc *SharedChannel) IsValid() *AppError {
|
|||
}
|
||||
|
||||
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 {
|
||||
|
|
|
@ -12,7 +12,6 @@ const (
|
|||
SystemRanUnitTests = "RanUnitTests"
|
||||
SystemLastSecurityTime = "LastSecurityTime"
|
||||
SystemActiveLicenseId = "ActiveLicenseId"
|
||||
SystemLicenseRenewalToken = "LicenseRenewalToken"
|
||||
SystemLastComplianceTime = "LastComplianceTime"
|
||||
SystemAsymmetricSigningKeyKey = "AsymmetricSigningKey"
|
||||
SystemPostActionCookieSecretKey = "PostActionCookieSecret"
|
||||
|
@ -34,9 +33,6 @@ const (
|
|||
SystemFirstAdminSetupComplete = "FirstAdminSetupComplete"
|
||||
AwsMeteringReportInterval = 1
|
||||
AwsMeteringDimensionUsageHrs = "UsageHrs"
|
||||
UserLimitOverageCycleEndDate = "UserLimitOverageCycleEndDate"
|
||||
OverUserLimitForgivenCount = "OverUserLimitForgivenCount"
|
||||
OverUserLimitLastEmailSent = "OverUserLimitLastEmailSent"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
|
@ -252,6 +252,12 @@ func (o *Team) IsGroupConstrained() bool {
|
|||
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
|
||||
// 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
|
||||
|
|
|
@ -67,6 +67,9 @@ type GetUserThreadsOpts struct {
|
|||
// TotalsOnly will not fetch any threads and just fetch the total counts
|
||||
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 bool
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ const (
|
|||
UppercaseLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
NUMBERS = "0123456789"
|
||||
SYMBOLS = " !\"\\#$%&'()*+,-./:;<=>?@[]^_`|~"
|
||||
BinaryParamKey = "MM_BINARY_PARAMETERS"
|
||||
)
|
||||
|
||||
type StringInterface map[string]interface{}
|
||||
|
@ -124,12 +125,19 @@ func (m *StringMap) Scan(value interface{}) error {
|
|||
|
||||
// Value converts StringMap to database value
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
// non utf8 characters are not supported https://mattermost.atlassian.net/browse/MM-41066
|
||||
return string(j), err
|
||||
if ok == "true" {
|
||||
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 {
|
||||
|
@ -502,21 +510,13 @@ var reservedName = []string{
|
|||
}
|
||||
|
||||
func IsValidChannelIdentifier(s string) bool {
|
||||
|
||||
if !IsValidAlphaNumHyphenUnderscore(s, true) {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(s) < ChannelNameMinLength {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
return validSimpleAlphaNum.MatchString(s) && len(s) >= ChannelNameMinLength
|
||||
}
|
||||
|
||||
var (
|
||||
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]+$`)
|
||||
validSimpleAlphaNum = regexp.MustCompile(`^[a-z0-9]+([a-z\-\_0-9]+|(__)?)[a-z0-9]*$`)
|
||||
validSimpleAlphaNumHyphenUnderscore = regexp.MustCompile(`^[a-zA-Z0-9\-_]+$`)
|
||||
validSimpleAlphaNumHyphenUnderscorePlus = regexp.MustCompile(`^[a-zA-Z0-9+_-]+$`)
|
||||
)
|
||||
|
|
|
@ -13,7 +13,7 @@ import (
|
|||
// It should be maintained in chronological order with most current
|
||||
// release at the front of the list.
|
||||
var versions = []string{
|
||||
"6.6.1",
|
||||
"6.7.0",
|
||||
"6.6.0",
|
||||
"6.5.0",
|
||||
"6.4.0",
|
||||
|
|
|
@ -297,7 +297,7 @@ func (b *S3FileBackend) MoveFile(oldPath, newPath string) error {
|
|||
}
|
||||
|
||||
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 {
|
||||
|
|
|
@ -9,7 +9,7 @@ checks: lint vet test examples functional-test
|
|||
|
||||
lint:
|
||||
@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"
|
||||
@GO111MODULE=on ${GOPATH}/bin/golangci-lint cache clean
|
||||
@GO111MODULE=on ${GOPATH}/bin/golangci-lint run --timeout=5m --config ./.golangci.yml
|
||||
|
|
|
@ -103,7 +103,6 @@ func (c *Client) getBucketNotification(ctx context.Context, bucketName string) (
|
|||
return notification.Configuration{}, err
|
||||
}
|
||||
return processBucketNotificationResponse(bucketName, resp)
|
||||
|
||||
}
|
||||
|
||||
// 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
|
||||
// caching done by proxies
|
||||
bio.Buffer(notificationEventBuffer, notificationCapacity)
|
||||
var json = jsoniter.ConfigCompatibleWithStandardLibrary
|
||||
json := jsoniter.ConfigCompatibleWithStandardLibrary
|
||||
|
||||
// Unmarshal each line, returns marshaled values.
|
||||
for bio.Scan() {
|
||||
|
|
|
@ -202,8 +202,8 @@ func (opts CopySrcOptions) validate() (err error) {
|
|||
|
||||
// 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,
|
||||
metadata map[string]string, srcOpts CopySrcOptions, dstOpts PutObjectOptions) (ObjectInfo, error) {
|
||||
|
||||
metadata map[string]string, srcOpts CopySrcOptions, dstOpts PutObjectOptions,
|
||||
) (ObjectInfo, error) {
|
||||
// Build headers.
|
||||
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,
|
||||
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)
|
||||
|
||||
// Set source
|
||||
|
@ -338,8 +338,8 @@ func (c *Client) copyObjectPartDo(ctx context.Context, srcBucket, srcObject, des
|
|||
// upload via an upload-part-copy request
|
||||
// https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadUploadPartCopy.html
|
||||
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
|
||||
urlValues := make(url.Values)
|
||||
urlValues.Set("partNumber", strconv.Itoa(partNumber))
|
||||
|
@ -492,7 +492,7 @@ func (c *Client) ComposeObject(ctx context.Context, dst CopyDestOptions, srcs ..
|
|||
objParts := []CompletePart{}
|
||||
partIndex := 1
|
||||
for i, src := range srcs {
|
||||
var h = make(http.Header)
|
||||
h := make(http.Header)
|
||||
src.Marshal(h)
|
||||
if dst.Encryption != nil && dst.Encryption.Type() == encrypt.SSEC {
|
||||
dst.Encryption.Marshal(h)
|
||||
|
|
|
@ -57,7 +57,7 @@ func (c *Client) FGetObject(ctx context.Context, bucketName, objectName, filePat
|
|||
objectDir, _ := filepath.Split(filePath)
|
||||
if objectDir != "" {
|
||||
// Create any missing top level directories.
|
||||
if err := os.MkdirAll(objectDir, 0700); err != nil {
|
||||
if err := os.MkdirAll(objectDir, 0o700); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ func (c *Client) FGetObject(ctx context.Context, bucketName, objectName, filePat
|
|||
filePartPath := filePath + objectStat.ETag + ".part.minio"
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -774,7 +774,6 @@ func (c *Client) listIncompleteUploads(ctx context.Context, bucketName, objectPr
|
|||
}(objectMultipartStatCh)
|
||||
// return.
|
||||
return objectMultipartStatCh
|
||||
|
||||
}
|
||||
|
||||
// listMultipartUploadsQuery - (List Multipart Uploads).
|
||||
|
|
|
@ -38,7 +38,8 @@ import (
|
|||
)
|
||||
|
||||
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)
|
||||
if err != nil {
|
||||
errResp := ToErrorResponse(err)
|
||||
|
@ -240,7 +241,8 @@ func (c *Client) initiateMultipartUpload(ctx context.Context, bucketName, object
|
|||
|
||||
// uploadPart - Uploads a part in a multipart upload.
|
||||
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.
|
||||
if err := s3utils.CheckValidBucketName(bucketName); err != nil {
|
||||
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.
|
||||
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.
|
||||
if err := s3utils.CheckValidBucketName(bucketName); err != nil {
|
||||
return UploadInfo{}, err
|
||||
|
@ -392,5 +395,4 @@ func (c *Client) completeMultipartUpload(ctx context.Context, bucketName, object
|
|||
Expiration: expTime,
|
||||
ExpirationRuleID: ruleID,
|
||||
}, nil
|
||||
|
||||
}
|
||||
|
|
|
@ -42,8 +42,8 @@ import (
|
|||
// - Any reader which has a method 'ReadAt()'
|
||||
//
|
||||
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 {
|
||||
// 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)
|
||||
|
@ -91,7 +91,8 @@ type uploadPartReq struct {
|
|||
// cleaned automatically when the caller i.e http client closes the
|
||||
// stream after uploading all the contents successfully.
|
||||
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.
|
||||
if err = s3utils.CheckValidBucketName(bucketName); err != nil {
|
||||
return UploadInfo{}, err
|
||||
|
@ -147,7 +148,7 @@ func (c *Client) putObjectMultipartStreamFromReadAt(ctx context.Context, bucketN
|
|||
}
|
||||
close(uploadPartsCh)
|
||||
|
||||
var partsBuf = make([][]byte, opts.getNumThreads())
|
||||
partsBuf := make([][]byte, opts.getNumThreads())
|
||||
for i := range partsBuf {
|
||||
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])
|
||||
if rerr != nil && rerr != io.ErrUnexpectedEOF && err != io.EOF {
|
||||
if rerr != nil && rerr != io.ErrUnexpectedEOF && rerr != io.EOF {
|
||||
uploadedPartsCh <- uploadedPartRes{
|
||||
Error: rerr,
|
||||
}
|
||||
|
@ -241,7 +242,8 @@ func (c *Client) putObjectMultipartStreamFromReadAt(ctx context.Context, bucketN
|
|||
}
|
||||
|
||||
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.
|
||||
if err = s3utils.CheckValidBucketName(bucketName); err != nil {
|
||||
return UploadInfo{}, err
|
||||
|
|
|
@ -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.
|
||||
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 {
|
||||
return UploadInfo{}, errors.New("object size must be provided with disable multipart upload")
|
||||
}
|
||||
|
|
|
@ -133,7 +133,7 @@ func (c Client) PutObjectsSnowball(ctx context.Context, bucketName string, opts
|
|||
return f, st.Size(), nil
|
||||
}
|
||||
}
|
||||
var flush = func() error { return nil }
|
||||
flush := func() error { return nil }
|
||||
if !opts.Compress {
|
||||
if !opts.InMemory {
|
||||
// Insert buffer for writes.
|
||||
|
|
|
@ -519,7 +519,7 @@ func (s *SelectResults) start(pipeWriter *io.PipeWriter) {
|
|||
go func() {
|
||||
for {
|
||||
var prelude preludeInfo
|
||||
var headers = make(http.Header)
|
||||
headers := make(http.Header)
|
||||
var err error
|
||||
|
||||
// Create CRC code
|
||||
|
@ -624,7 +624,7 @@ func (p preludeInfo) PayloadLen() int64 {
|
|||
// the struct,
|
||||
func processPrelude(prelude io.Reader, crc hash.Hash32) (preludeInfo, error) {
|
||||
var err error
|
||||
var pInfo = preludeInfo{}
|
||||
pInfo := preludeInfo{}
|
||||
|
||||
// reads total length of the message (first 4 bytes)
|
||||
pInfo.totalLen, err = extractUint32(prelude)
|
||||
|
@ -752,7 +752,6 @@ func checkCRC(r io.Reader, expect uint32) error {
|
|||
|
||||
if msgCRC != expect {
|
||||
return fmt.Errorf("Checksum Mismatch, MessageCRC of 0x%X does not equal expected CRC of 0x%X", msgCRC, expect)
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -111,7 +111,7 @@ type Options struct {
|
|||
// Global constants.
|
||||
const (
|
||||
libraryName = "minio-go"
|
||||
libraryVersion = "v7.0.23"
|
||||
libraryVersion = "v7.0.24"
|
||||
)
|
||||
|
||||
// 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 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 {
|
||||
// Check if body is seekable then it is retryable.
|
||||
|
|
|
@ -181,6 +181,9 @@ func (c *Client) getBucketLocationRequest(ctx context.Context, bucketName string
|
|||
if h, p, err := net.SplitHostPort(targetURL.Host); err == nil {
|
||||
if targetURL.Scheme == "http" && p == "80" || targetURL.Scheme == "https" && p == "443" {
|
||||
targetURL.Host = h
|
||||
if ip := net.ParseIP(h); ip != nil && ip.To16() != nil {
|
||||
targetURL.Host = "[" + h + "]"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
// part of) an existing object.
|
||||
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,
|
||||
partID, startOffset, length, metadata)
|
||||
}
|
||||
|
|
|
@ -61,6 +61,7 @@ const (
|
|||
letterIdxMask = 1<<letterIdxBits - 1 // All 1-bits, as many as letterIdxBits
|
||||
letterIdxMax = 63 / letterIdxBits // # of letter indices fitting in 63 bits
|
||||
)
|
||||
|
||||
const (
|
||||
serverEndpoint = "SERVER_ENDPOINT"
|
||||
accessKey = "ACCESS_KEY"
|
||||
|
@ -69,8 +70,7 @@ const (
|
|||
enableKMS = "ENABLE_KMS"
|
||||
)
|
||||
|
||||
type mintJSONFormatter struct {
|
||||
}
|
||||
type mintJSONFormatter struct{}
|
||||
|
||||
func (f *mintJSONFormatter) Format(entry *log.Entry) ([]byte, error) {
|
||||
data := make(log.Fields, len(entry.Data))
|
||||
|
@ -84,7 +84,7 @@ func (f *mintJSONFormatter) Format(entry *log.Entry) ([]byte, error) {
|
|||
data[k] = v
|
||||
}
|
||||
}
|
||||
var json = jsoniter.ConfigCompatibleWithStandardLibrary
|
||||
json := jsoniter.ConfigCompatibleWithStandardLibrary
|
||||
serialized, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
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
|
||||
// log with the fields as per mint
|
||||
if err != nil {
|
||||
fields = log.Fields{"name": "minio-go: " + testName, "function": function, "args": args,
|
||||
"duration": duration.Nanoseconds() / 1000000, "status": "FAIL", "alert": alert, "message": message, "error": err}
|
||||
fields = log.Fields{
|
||||
"name": "minio-go: " + testName, "function": function, "args": args,
|
||||
"duration": duration.Nanoseconds() / 1000000, "status": "FAIL", "alert": alert, "message": message, "error": err,
|
||||
}
|
||||
} else {
|
||||
fields = log.Fields{"name": "minio-go: " + testName, "function": function, "args": args,
|
||||
"duration": duration.Nanoseconds() / 1000000, "status": "FAIL", "alert": alert, "message": message}
|
||||
fields = log.Fields{
|
||||
"name": "minio-go: " + testName, "function": function, "args": args,
|
||||
"duration": duration.Nanoseconds() / 1000000, "status": "FAIL", "alert": alert, "message": message,
|
||||
}
|
||||
}
|
||||
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
|
||||
duration := time.Since(startTime)
|
||||
// log with the fields as per mint
|
||||
fields := log.Fields{"name": "minio-go: " + testName, "function": function, "args": args,
|
||||
"duration": duration.Nanoseconds() / 1000000, "status": "NA", "alert": strings.Split(alert, " ")[0] + " is NotImplemented"}
|
||||
fields := log.Fields{
|
||||
"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))
|
||||
}
|
||||
|
||||
|
@ -632,7 +638,7 @@ func testPutObjectReadAt() {
|
|||
defer cleanupBucket(bucketName, c)
|
||||
|
||||
bufSize := dataFileMap["datafile-129-MB"]
|
||||
var reader = getDataReader("datafile-129-MB")
|
||||
reader := getDataReader("datafile-129-MB")
|
||||
defer reader.Close()
|
||||
|
||||
// Save the data
|
||||
|
@ -738,7 +744,7 @@ func testListObjectVersions() {
|
|||
args["objectName"] = objectName
|
||||
|
||||
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{})
|
||||
if err != nil {
|
||||
|
@ -857,7 +863,7 @@ func testStatObjectWithVersioning() {
|
|||
args["objectName"] = objectName
|
||||
|
||||
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{})
|
||||
if err != nil {
|
||||
|
@ -975,7 +981,7 @@ func testGetObjectWithVersioning() {
|
|||
|
||||
// Save the contents of datafiles to check with GetObject() reader output later
|
||||
var buffers [][]byte
|
||||
var testFiles = []string{"datafile-1-b", "datafile-10-kB"}
|
||||
testFiles := []string{"datafile-1-b", "datafile-10-kB"}
|
||||
|
||||
for _, testFile := range testFiles {
|
||||
r := getDataReader(testFile)
|
||||
|
@ -1117,7 +1123,7 @@ func testPutObjectWithVersioning() {
|
|||
// Save the data concurrently.
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(n)
|
||||
var buffers = make([][]byte, n)
|
||||
buffers := make([][]byte, n)
|
||||
var errs [n]error
|
||||
for i := 0; i < n; i++ {
|
||||
r := newRandomReader(int64((1<<20)*i+i), int64(i))
|
||||
|
@ -1258,7 +1264,7 @@ func testCopyObjectWithVersioning() {
|
|||
objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "")
|
||||
args["objectName"] = objectName
|
||||
|
||||
var testFiles = []string{"datafile-1-b", "datafile-10-kB"}
|
||||
testFiles := []string{"datafile-1-b", "datafile-10-kB"}
|
||||
for _, testFile := range testFiles {
|
||||
r := getDataReader(testFile)
|
||||
buf, err := ioutil.ReadAll(r)
|
||||
|
@ -1395,7 +1401,7 @@ func testConcurrentCopyObjectWithVersioning() {
|
|||
objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "")
|
||||
args["objectName"] = objectName
|
||||
|
||||
var testFiles = []string{"datafile-10-kB"}
|
||||
testFiles := []string{"datafile-10-kB"}
|
||||
for _, testFile := range testFiles {
|
||||
r := getDataReader(testFile)
|
||||
buf, err := ioutil.ReadAll(r)
|
||||
|
@ -1556,7 +1562,7 @@ func testComposeObjectWithVersioning() {
|
|||
args["objectName"] = objectName
|
||||
|
||||
// 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
|
||||
|
||||
for _, testFile := range testFiles {
|
||||
|
@ -2036,7 +2042,7 @@ func testPutObjectWithMetadata() {
|
|||
defer cleanupBucket(bucketName, c)
|
||||
|
||||
bufSize := dataFileMap["datafile-129-MB"]
|
||||
var reader = getDataReader("datafile-129-MB")
|
||||
reader := getDataReader("datafile-129-MB")
|
||||
defer reader.Close()
|
||||
|
||||
// Save the data
|
||||
|
@ -2052,7 +2058,8 @@ func testPutObjectWithMetadata() {
|
|||
}
|
||||
|
||||
_, err = c.PutObject(context.Background(), bucketName, objectName, reader, int64(bufSize), minio.PutObjectOptions{
|
||||
ContentType: customContentType})
|
||||
ContentType: customContentType,
|
||||
})
|
||||
if err != nil {
|
||||
logError(testName, function, args, startTime, "", "PutObject failed", err)
|
||||
return
|
||||
|
@ -2282,7 +2289,7 @@ func testGetObjectSeekEnd() {
|
|||
|
||||
// Generate 33K of data.
|
||||
bufSize := dataFileMap["datafile-33-kB"]
|
||||
var reader = getDataReader("datafile-33-kB")
|
||||
reader := getDataReader("datafile-33-kB")
|
||||
defer reader.Close()
|
||||
|
||||
// Save the data
|
||||
|
@ -2404,7 +2411,7 @@ func testGetObjectClosedTwice() {
|
|||
|
||||
// Generate 33K of data.
|
||||
bufSize := dataFileMap["datafile-33-kB"]
|
||||
var reader = getDataReader("datafile-33-kB")
|
||||
reader := getDataReader("datafile-33-kB")
|
||||
defer reader.Close()
|
||||
|
||||
// Save the data
|
||||
|
@ -2807,7 +2814,7 @@ func testFPutObjectMultipart() {
|
|||
defer cleanupBucket(bucketName, c)
|
||||
|
||||
// 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 == "" {
|
||||
// Make a temp file with minPartSize bytes of data.
|
||||
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.
|
||||
// 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 == "" {
|
||||
// Make a temp file with minPartSize bytes of data.
|
||||
file, err := ioutil.TempFile(os.TempDir(), "FPutObjectTest")
|
||||
|
@ -3082,7 +3089,7 @@ func testFPutObjectContext() {
|
|||
|
||||
// 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.
|
||||
var fName = getMintDataDirFilePath("datafile-1-MB")
|
||||
fName := getMintDataDirFilePath("datafile-1-MB")
|
||||
if fName == "" {
|
||||
// Make a temp file with 1 MiB bytes of data.
|
||||
file, err := ioutil.TempFile(os.TempDir(), "FPutObjectContextTest")
|
||||
|
@ -3134,7 +3141,6 @@ func testFPutObjectContext() {
|
|||
}
|
||||
|
||||
successLogger(testName, function, args, startTime).Info()
|
||||
|
||||
}
|
||||
|
||||
// Tests FPutObject request when context cancels after timeout
|
||||
|
@ -3183,7 +3189,7 @@ func testFPutObjectContextV2() {
|
|||
|
||||
// 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.
|
||||
var fName = getMintDataDirFilePath("datafile-1-MB")
|
||||
fName := getMintDataDirFilePath("datafile-1-MB")
|
||||
if fName == "" {
|
||||
// Make a temp file with 1 MiB bytes of data.
|
||||
file, err := ioutil.TempFile(os.TempDir(), "FPutObjectContextTest")
|
||||
|
@ -3237,7 +3243,6 @@ func testFPutObjectContextV2() {
|
|||
}
|
||||
|
||||
successLogger(testName, function, args, startTime).Info()
|
||||
|
||||
}
|
||||
|
||||
// Test validates putObject with context to see if request cancellation is honored.
|
||||
|
@ -3283,7 +3288,7 @@ func testPutObjectContext() {
|
|||
defer cleanupBucket(bucketName, c)
|
||||
|
||||
bufSize := dataFileMap["datafile-33-kB"]
|
||||
var reader = getDataReader("datafile-33-kB")
|
||||
reader := getDataReader("datafile-33-kB")
|
||||
defer reader.Close()
|
||||
objectName := fmt.Sprintf("test-file-%v", rand.Uint32())
|
||||
args["objectName"] = objectName
|
||||
|
@ -3312,7 +3317,6 @@ func testPutObjectContext() {
|
|||
}
|
||||
|
||||
successLogger(testName, function, args, startTime).Info()
|
||||
|
||||
}
|
||||
|
||||
// Tests get object with s3zip extensions.
|
||||
|
@ -3428,7 +3432,7 @@ func testGetObjectS3Zip() {
|
|||
lOpts.Prefix = objectName + "/"
|
||||
lOpts.Recursive = true
|
||||
list := c.ListObjects(context.Background(), bucketName, lOpts)
|
||||
var listed = map[string]minio.ObjectInfo{}
|
||||
listed := map[string]minio.ObjectInfo{}
|
||||
for item := range list {
|
||||
if item.Err != nil {
|
||||
break
|
||||
|
@ -3547,7 +3551,7 @@ func testGetObjectReadSeekFunctional() {
|
|||
|
||||
// Generate 33K of data.
|
||||
bufSize := dataFileMap["datafile-33-kB"]
|
||||
var reader = getDataReader("datafile-33-kB")
|
||||
reader := getDataReader("datafile-33-kB")
|
||||
defer reader.Close()
|
||||
|
||||
objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "")
|
||||
|
@ -3710,7 +3714,7 @@ func testGetObjectReadAtFunctional() {
|
|||
|
||||
// Generate 33K of data.
|
||||
bufSize := dataFileMap["datafile-33-kB"]
|
||||
var reader = getDataReader("datafile-33-kB")
|
||||
reader := getDataReader("datafile-33-kB")
|
||||
defer reader.Close()
|
||||
|
||||
objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "")
|
||||
|
@ -3887,7 +3891,7 @@ func testGetObjectReadAtWhenEOFWasReached() {
|
|||
|
||||
// Generate 33K of data.
|
||||
bufSize := dataFileMap["datafile-33-kB"]
|
||||
var reader = getDataReader("datafile-33-kB")
|
||||
reader := getDataReader("datafile-33-kB")
|
||||
defer reader.Close()
|
||||
|
||||
objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "")
|
||||
|
@ -4004,7 +4008,7 @@ func testPresignedPostPolicy() {
|
|||
defer cleanupBucket(bucketName, c)
|
||||
|
||||
// Generate 33K of data.
|
||||
var reader = getDataReader("datafile-33-kB")
|
||||
reader := getDataReader("datafile-33-kB")
|
||||
defer reader.Close()
|
||||
|
||||
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
|
||||
var filePath = getMintDataDirFilePath("datafile-33-kB")
|
||||
filePath := getMintDataDirFilePath("datafile-33-kB")
|
||||
if filePath == "" {
|
||||
// Make a temp file with 33 KB data.
|
||||
file, err := ioutil.TempFile(os.TempDir(), "PresignedPostPolicyTest")
|
||||
|
@ -4228,7 +4232,7 @@ func testCopyObject() {
|
|||
|
||||
// Generate 33K of data.
|
||||
bufSize := dataFileMap["datafile-33-kB"]
|
||||
var reader = getDataReader("datafile-33-kB")
|
||||
reader := getDataReader("datafile-33-kB")
|
||||
|
||||
// Save the data
|
||||
objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "")
|
||||
|
@ -4421,7 +4425,7 @@ func testSSECEncryptedGetObjectReadSeekFunctional() {
|
|||
|
||||
// Generate 129MiB of data.
|
||||
bufSize := dataFileMap["datafile-129-MB"]
|
||||
var reader = getDataReader("datafile-129-MB")
|
||||
reader := getDataReader("datafile-129-MB")
|
||||
defer reader.Close()
|
||||
|
||||
objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "")
|
||||
|
@ -4603,7 +4607,7 @@ func testSSES3EncryptedGetObjectReadSeekFunctional() {
|
|||
|
||||
// Generate 129MiB of data.
|
||||
bufSize := dataFileMap["datafile-129-MB"]
|
||||
var reader = getDataReader("datafile-129-MB")
|
||||
reader := getDataReader("datafile-129-MB")
|
||||
defer reader.Close()
|
||||
|
||||
objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "")
|
||||
|
@ -4777,7 +4781,7 @@ func testSSECEncryptedGetObjectReadAtFunctional() {
|
|||
|
||||
// Generate 129MiB of data.
|
||||
bufSize := dataFileMap["datafile-129-MB"]
|
||||
var reader = getDataReader("datafile-129-MB")
|
||||
reader := getDataReader("datafile-129-MB")
|
||||
defer reader.Close()
|
||||
|
||||
objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "")
|
||||
|
@ -4960,7 +4964,7 @@ func testSSES3EncryptedGetObjectReadAtFunctional() {
|
|||
|
||||
// Generate 129MiB of data.
|
||||
bufSize := dataFileMap["datafile-129-MB"]
|
||||
var reader = getDataReader("datafile-129-MB")
|
||||
reader := getDataReader("datafile-129-MB")
|
||||
defer reader.Close()
|
||||
|
||||
objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "")
|
||||
|
@ -5972,7 +5976,6 @@ func testFunctional() {
|
|||
"objectName": objectName,
|
||||
}
|
||||
newReader, err := c.GetObject(context.Background(), bucketName, objectName, minio.GetObjectOptions{})
|
||||
|
||||
if err != nil {
|
||||
logError(testName, function, args, startTime, "", "GetObject failed", err)
|
||||
return
|
||||
|
@ -6025,7 +6028,6 @@ func testFunctional() {
|
|||
"expires": 3600 * time.Second,
|
||||
}
|
||||
presignedHeadURL, err := c.PresignedHeadObject(context.Background(), bucketName, objectName, 3600*time.Second, nil)
|
||||
|
||||
if err != nil {
|
||||
logError(testName, function, args, startTime, "", "PresignedHeadObject failed", err)
|
||||
return
|
||||
|
@ -6089,7 +6091,6 @@ func testFunctional() {
|
|||
"expires": 3600 * time.Second,
|
||||
}
|
||||
presignedGetURL, err := c.PresignedGetObject(context.Background(), bucketName, objectName, 3600*time.Second, nil)
|
||||
|
||||
if err != nil {
|
||||
logError(testName, function, args, startTime, "", "PresignedGetObject failed", err)
|
||||
return
|
||||
|
@ -6189,7 +6190,6 @@ func testFunctional() {
|
|||
"expires": 3600 * time.Second,
|
||||
}
|
||||
presignedPutURL, err := c.PresignedPutObject(context.Background(), bucketName, objectName+"-presigned", 3600*time.Second)
|
||||
|
||||
if err != nil {
|
||||
logError(testName, function, args, startTime, "", "PresignedPutObject failed", err)
|
||||
return
|
||||
|
@ -6513,7 +6513,7 @@ func testPutObjectUploadSeekedObject() {
|
|||
// Seek back to the beginning of the file.
|
||||
tempfile.Seek(0, 0)
|
||||
}
|
||||
var length = 100 * humanize.KiByte
|
||||
length := 100 * humanize.KiByte
|
||||
objectName := fmt.Sprintf("test-file-%v", rand.Uint32())
|
||||
args["objectName"] = objectName
|
||||
|
||||
|
@ -6670,7 +6670,7 @@ func testGetObjectClosedTwiceV2() {
|
|||
|
||||
// Generate 33K of data.
|
||||
bufSize := dataFileMap["datafile-33-kB"]
|
||||
var reader = getDataReader("datafile-33-kB")
|
||||
reader := getDataReader("datafile-33-kB")
|
||||
defer reader.Close()
|
||||
|
||||
// Save the data
|
||||
|
@ -6982,7 +6982,7 @@ func testGetObjectReadSeekFunctionalV2() {
|
|||
|
||||
// Generate 33K of data.
|
||||
bufSize := dataFileMap["datafile-33-kB"]
|
||||
var reader = getDataReader("datafile-33-kB")
|
||||
reader := getDataReader("datafile-33-kB")
|
||||
defer reader.Close()
|
||||
|
||||
objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "")
|
||||
|
@ -7136,7 +7136,7 @@ func testGetObjectReadAtFunctionalV2() {
|
|||
|
||||
// Generate 33K of data.
|
||||
bufSize := dataFileMap["datafile-33-kB"]
|
||||
var reader = getDataReader("datafile-33-kB")
|
||||
reader := getDataReader("datafile-33-kB")
|
||||
defer reader.Close()
|
||||
|
||||
objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "")
|
||||
|
@ -7303,7 +7303,7 @@ func testCopyObjectV2() {
|
|||
|
||||
// Generate 33K of data.
|
||||
bufSize := dataFileMap["datafile-33-kB"]
|
||||
var reader = getDataReader("datafile-33-kB")
|
||||
reader := getDataReader("datafile-33-kB")
|
||||
defer reader.Close()
|
||||
|
||||
// Save the data
|
||||
|
@ -7412,7 +7412,6 @@ func testComposeObjectErrorCasesWrapper(c *minio.Client) {
|
|||
|
||||
// Make a new bucket in 'us-east-1' (source bucket).
|
||||
err := c.MakeBucket(context.Background(), bucketName, minio.MakeBucketOptions{Region: "us-east-1"})
|
||||
|
||||
if err != nil {
|
||||
logError(testName, function, args, startTime, "", "MakeBucket failed", err)
|
||||
return
|
||||
|
@ -9935,6 +9934,7 @@ func testSSES3EncryptedToSSES3CopyObjectPart() {
|
|||
|
||||
// Do not need to remove destBucketName its same as bucketName.
|
||||
}
|
||||
|
||||
func testUserMetadataCopying() {
|
||||
// initialize logging params
|
||||
startTime := time.Now()
|
||||
|
@ -10432,7 +10432,7 @@ func testPutObjectNoLengthV2() {
|
|||
args["objectName"] = objectName
|
||||
|
||||
bufSize := dataFileMap["datafile-129-MB"]
|
||||
var reader = getDataReader("datafile-129-MB")
|
||||
reader := getDataReader("datafile-129-MB")
|
||||
defer reader.Close()
|
||||
args["size"] = bufSize
|
||||
|
||||
|
@ -11162,7 +11162,7 @@ func testGetObjectContext() {
|
|||
defer cleanupBucket(bucketName, c)
|
||||
|
||||
bufSize := dataFileMap["datafile-33-kB"]
|
||||
var reader = getDataReader("datafile-33-kB")
|
||||
reader := getDataReader("datafile-33-kB")
|
||||
defer reader.Close()
|
||||
// Save the data
|
||||
objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "")
|
||||
|
@ -11216,7 +11216,6 @@ func testGetObjectContext() {
|
|||
}
|
||||
|
||||
successLogger(testName, function, args, startTime).Info()
|
||||
|
||||
}
|
||||
|
||||
// Test get object with FGetObject with a user provided context
|
||||
|
@ -11265,7 +11264,7 @@ func testFGetObjectContext() {
|
|||
defer cleanupBucket(bucketName, c)
|
||||
|
||||
bufSize := dataFileMap["datafile-1-MB"]
|
||||
var reader = getDataReader("datafile-1-MB")
|
||||
reader := getDataReader("datafile-1-MB")
|
||||
defer reader.Close()
|
||||
// Save the data
|
||||
objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "")
|
||||
|
@ -11304,7 +11303,6 @@ func testFGetObjectContext() {
|
|||
}
|
||||
|
||||
successLogger(testName, function, args, startTime).Info()
|
||||
|
||||
}
|
||||
|
||||
// Test get object with GetObject with a user provided context
|
||||
|
@ -11354,7 +11352,7 @@ func testGetObjectRanges() {
|
|||
defer cleanupBucket(bucketName, c)
|
||||
|
||||
bufSize := dataFileMap["datafile-129-MB"]
|
||||
var reader = getDataReader("datafile-129-MB")
|
||||
reader := getDataReader("datafile-129-MB")
|
||||
defer reader.Close()
|
||||
// Save the data
|
||||
objectName := randString(60, rng, "")
|
||||
|
@ -11463,7 +11461,7 @@ func testGetObjectACLContext() {
|
|||
defer cleanupBucket(bucketName, c)
|
||||
|
||||
bufSize := dataFileMap["datafile-1-MB"]
|
||||
var reader = getDataReader("datafile-1-MB")
|
||||
reader := getDataReader("datafile-1-MB")
|
||||
defer reader.Close()
|
||||
// Save the data
|
||||
objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "")
|
||||
|
@ -11525,7 +11523,7 @@ func testGetObjectACLContext() {
|
|||
}
|
||||
|
||||
bufSize = dataFileMap["datafile-1-MB"]
|
||||
var reader2 = getDataReader("datafile-1-MB")
|
||||
reader2 := getDataReader("datafile-1-MB")
|
||||
defer reader2.Close()
|
||||
// Save the data
|
||||
objectName = randString(60, rand.NewSource(time.Now().UnixNano()), "")
|
||||
|
@ -11635,7 +11633,7 @@ func testPutObjectContextV2() {
|
|||
}
|
||||
defer cleanupBucket(bucketName, c)
|
||||
bufSize := dataFileMap["datatfile-33-kB"]
|
||||
var reader = getDataReader("datafile-33-kB")
|
||||
reader := getDataReader("datafile-33-kB")
|
||||
defer reader.Close()
|
||||
|
||||
objectName := fmt.Sprintf("test-file-%v", rand.Uint32())
|
||||
|
@ -11665,7 +11663,6 @@ func testPutObjectContextV2() {
|
|||
}
|
||||
|
||||
successLogger(testName, function, args, startTime).Info()
|
||||
|
||||
}
|
||||
|
||||
// Test get object with GetObject with custom context
|
||||
|
@ -11713,7 +11710,7 @@ func testGetObjectContextV2() {
|
|||
defer cleanupBucket(bucketName, c)
|
||||
|
||||
bufSize := dataFileMap["datafile-33-kB"]
|
||||
var reader = getDataReader("datafile-33-kB")
|
||||
reader := getDataReader("datafile-33-kB")
|
||||
defer reader.Close()
|
||||
// Save the data
|
||||
objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "")
|
||||
|
@ -11765,7 +11762,6 @@ func testGetObjectContextV2() {
|
|||
}
|
||||
|
||||
successLogger(testName, function, args, startTime).Info()
|
||||
|
||||
}
|
||||
|
||||
// Test get object with FGetObject with custom context
|
||||
|
@ -11814,7 +11810,7 @@ func testFGetObjectContextV2() {
|
|||
defer cleanupBucket(bucketName, c)
|
||||
|
||||
bufSize := dataFileMap["datatfile-1-MB"]
|
||||
var reader = getDataReader("datafile-1-MB")
|
||||
reader := getDataReader("datafile-1-MB")
|
||||
defer reader.Close()
|
||||
// Save the data
|
||||
objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "")
|
||||
|
@ -11855,7 +11851,6 @@ func testFGetObjectContextV2() {
|
|||
}
|
||||
|
||||
successLogger(testName, function, args, startTime).Info()
|
||||
|
||||
}
|
||||
|
||||
// Test list object v1 and V2
|
||||
|
@ -11915,7 +11910,7 @@ func testListObjects() {
|
|||
|
||||
for i, object := range testObjects {
|
||||
bufSize := dataFileMap["datafile-33-kB"]
|
||||
var reader = getDataReader("datafile-33-kB")
|
||||
reader := getDataReader("datafile-33-kB")
|
||||
defer reader.Close()
|
||||
_, err = c.PutObject(context.Background(), bucketName, object.name, reader, int64(bufSize),
|
||||
minio.PutObjectOptions{ContentType: "binary/octet-stream", StorageClass: object.storageClass})
|
||||
|
@ -12003,7 +11998,7 @@ func testRemoveObjects() {
|
|||
}
|
||||
|
||||
bufSize := dataFileMap["datafile-129-MB"]
|
||||
var reader = getDataReader("datafile-129-MB")
|
||||
reader := getDataReader("datafile-129-MB")
|
||||
defer reader.Close()
|
||||
|
||||
_, err = c.PutObject(context.Background(), bucketName, objectName, reader, int64(bufSize), minio.PutObjectOptions{})
|
||||
|
|
|
@ -122,7 +122,7 @@ type config struct {
|
|||
// returned if it fails to read from the file.
|
||||
func loadAlias(filename, alias string) (hostConfig, error) {
|
||||
cfg := &config{}
|
||||
var json = jsoniter.ConfigCompatibleWithStandardLibrary
|
||||
json := jsoniter.ConfigCompatibleWithStandardLibrary
|
||||
|
||||
configBytes, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
|
|
|
@ -19,6 +19,7 @@ package credentials
|
|||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
|
@ -254,7 +255,10 @@ func getEcsTaskCredentials(client *http.Client, endpoint string, token string) (
|
|||
}
|
||||
|
||||
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 {
|
||||
return "", err
|
||||
}
|
||||
|
|
|
@ -105,8 +105,8 @@ func NewSTSClientGrants(stsEndpoint string, getClientGrantsTokenExpiry func() (*
|
|||
}
|
||||
|
||||
func getClientGrantsCredentials(clnt *http.Client, endpoint string,
|
||||
getClientGrantsTokenExpiry func() (*ClientGrantsToken, error)) (AssumeRoleWithClientGrantsResponse, error) {
|
||||
|
||||
getClientGrantsTokenExpiry func() (*ClientGrantsToken, error),
|
||||
) (AssumeRoleWithClientGrantsResponse, error) {
|
||||
accessToken, err := getClientGrantsTokenExpiry()
|
||||
if err != nil {
|
||||
return AssumeRoleWithClientGrantsResponse{}, err
|
||||
|
@ -138,7 +138,6 @@ func getClientGrantsCredentials(clnt *http.Client, endpoint string,
|
|||
buf, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return AssumeRoleWithClientGrantsResponse{}, err
|
||||
|
||||
}
|
||||
_, err = xmlDecodeAndBody(bytes.NewReader(buf), &errResp)
|
||||
if err != nil {
|
||||
|
|
|
@ -174,7 +174,6 @@ func (k *LDAPIdentity) Retrieve() (value Value, err error) {
|
|||
buf, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return value, err
|
||||
|
||||
}
|
||||
_, err = xmlDecodeAndBody(bytes.NewReader(buf), &errResp)
|
||||
if err != nil {
|
||||
|
|
|
@ -94,7 +94,7 @@ func NewSTSCertificateIdentity(endpoint string, certificate tls.Certificate, opt
|
|||
if _, err := url.Parse(endpoint); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var identity = &STSCertificateIdentity{
|
||||
identity := &STSCertificateIdentity{
|
||||
STSEndpoint: endpoint,
|
||||
Client: http.Client{
|
||||
Transport: &http.Transport{
|
||||
|
@ -127,7 +127,7 @@ func (i *STSCertificateIdentity) Retrieve() (Value, error) {
|
|||
if err != nil {
|
||||
return Value{}, err
|
||||
}
|
||||
var livetime = i.S3CredentialLivetime
|
||||
livetime := i.S3CredentialLivetime
|
||||
if livetime == 0 {
|
||||
livetime = 1 * time.Hour
|
||||
}
|
||||
|
@ -155,7 +155,6 @@ func (i *STSCertificateIdentity) Retrieve() (Value, error) {
|
|||
buf, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return Value{}, err
|
||||
|
||||
}
|
||||
_, err = xmlDecodeAndBody(bytes.NewReader(buf), &errResp)
|
||||
if err != nil {
|
||||
|
|
|
@ -107,7 +107,8 @@ func NewSTSWebIdentity(stsEndpoint string, getWebIDTokenExpiry func() (*WebIdent
|
|||
}
|
||||
|
||||
func getWebIdentityCredentials(clnt *http.Client, endpoint, roleARN, roleSessionName string,
|
||||
getWebIDTokenExpiry func() (*WebIdentityToken, error)) (AssumeRoleWithWebIdentityResponse, error) {
|
||||
getWebIDTokenExpiry func() (*WebIdentityToken, error),
|
||||
) (AssumeRoleWithWebIdentityResponse, error) {
|
||||
idToken, err := getWebIDTokenExpiry()
|
||||
if err != nil {
|
||||
return AssumeRoleWithWebIdentityResponse{}, err
|
||||
|
@ -156,7 +157,6 @@ func getWebIdentityCredentials(clnt *http.Client, endpoint, roleARN, roleSession
|
|||
buf, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return AssumeRoleWithWebIdentityResponse{}, err
|
||||
|
||||
}
|
||||
_, err = xmlDecodeAndBody(bytes.NewReader(buf), &errResp)
|
||||
if err != nil {
|
||||
|
|
|
@ -101,7 +101,7 @@ func NewSSEKMS(keyID string, context interface{}) (ServerSide, error) {
|
|||
if context == nil {
|
||||
return kms{key: keyID, hasContext: false}, nil
|
||||
}
|
||||
var json = jsoniter.ConfigCompatibleWithStandardLibrary
|
||||
json := jsoniter.ConfigCompatibleWithStandardLibrary
|
||||
serializedContext, err := json.Marshal(context)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -78,11 +78,13 @@ type Arn struct {
|
|||
|
||||
// NewArn creates new ARN based on the given partition, service, region, account id and resource
|
||||
func NewArn(partition, service, region, accountID, resource string) Arn {
|
||||
return Arn{Partition: partition,
|
||||
return Arn{
|
||||
Partition: partition,
|
||||
Service: service,
|
||||
Region: region,
|
||||
AccountID: accountID,
|
||||
Resource: resource}
|
||||
Resource: resource,
|
||||
}
|
||||
}
|
||||
|
||||
// String returns the string format of the ARN
|
||||
|
|
|
@ -432,7 +432,6 @@ func (c *Config) RemoveRule(opts Options) error {
|
|||
}
|
||||
c.Rules = newRules
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
// Rule - a rule for replication configuration.
|
||||
|
|
|
@ -114,8 +114,8 @@ func buildChunkHeader(chunkLen int64, signature string) []byte {
|
|||
|
||||
// buildChunkSignature - returns chunk signature for a given chunk and previous signature.
|
||||
func buildChunkSignature(chunkData []byte, reqTime time.Time, region,
|
||||
previousSignature, secretAccessKey string) string {
|
||||
|
||||
previousSignature, secretAccessKey string,
|
||||
) string {
|
||||
chunkStringToSign := buildChunkStringToSign(reqTime, region,
|
||||
previousSignature, chunkData)
|
||||
signingKey := getSigningKey(secretAccessKey, region, reqTime, ServiceTypeS3)
|
||||
|
@ -200,8 +200,8 @@ func (s *StreamingReader) setStreamingAuthHeader(req *http.Request) {
|
|||
// StreamingSignV4 - provides chunked upload signatureV4 support by
|
||||
// implementing io.Reader.
|
||||
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.
|
||||
prepareStreamingRequest(req, sessionToken, dataLen, reqTime)
|
||||
|
||||
|
|
|
@ -110,6 +110,7 @@ func isS3CodeRetryable(s3Code string) (ok bool) {
|
|||
// List of HTTP status codes which are retryable.
|
||||
var retryableHTTPStatusCodes = map[int]struct{}{
|
||||
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.StatusBadGateway: {},
|
||||
http.StatusServiceUnavailable: {},
|
||||
|
|
|
@ -105,21 +105,6 @@ func sumMD5Base64(data []byte) string {
|
|||
|
||||
// getEndpointURL - construct a new endpoint.
|
||||
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.
|
||||
scheme := "https"
|
||||
if !secure {
|
||||
|
@ -176,12 +161,18 @@ func isValidEndpointURL(endpointURL url.URL) error {
|
|||
if endpointURL.Path != "/" && endpointURL.Path != "" {
|
||||
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) {
|
||||
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) {
|
||||
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)
|
||||
}
|
||||
|
||||
var md5Pool = sync.Pool{New: func() interface{} { return md5.New() }}
|
||||
var sha256Pool = sync.Pool{New: func() interface{} { return sha256.New() }}
|
||||
var (
|
||||
md5Pool = sync.Pool{New: func() interface{} { return md5.New() }}
|
||||
sha256Pool = sync.Pool{New: func() interface{} { return sha256.New() }}
|
||||
)
|
||||
|
||||
func newMd5Hasher() md5simd.Hasher {
|
||||
return hashWrapper{Hash: md5Pool.Get().(hash.Hash), isMD5: true}
|
||||
|
|
|
@ -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
|
||||
|
||||
* Fix cases where `json.Number` didn't decode properly [GH-261]
|
||||
|
|
|
@ -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
|
||||
// string to []string by splitting on the given sep.
|
||||
func StringToSliceHookFunc(sep string) DecodeHookFunc {
|
||||
|
|
|
@ -122,7 +122,7 @@
|
|||
// field value is zero and a numeric type, the field is empty, and it won't
|
||||
// be encoded into the destination type.
|
||||
//
|
||||
// type Source {
|
||||
// type Source struct {
|
||||
// Age int `mapstructure:",omitempty"`
|
||||
// }
|
||||
//
|
||||
|
@ -215,6 +215,12 @@ type DecoderConfig struct {
|
|||
// (extra keys).
|
||||
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.
|
||||
// For example, a map will be emptied before decoded values are put in
|
||||
// it. If this is false, a map will be merged.
|
||||
|
@ -259,6 +265,10 @@ type DecoderConfig struct {
|
|||
// defaults to "mapstructure"
|
||||
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
|
||||
// field name or tag. Defaults to `strings.EqualFold`. This can be used
|
||||
// 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
|
||||
// weren't decoded since there was no matching field in the result interface
|
||||
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
|
||||
|
@ -375,6 +390,10 @@ func NewDecoder(config *DecoderConfig) (*Decoder, error) {
|
|||
if config.Metadata.Unused == nil {
|
||||
config.Metadata.Unused = make([]string, 0)
|
||||
}
|
||||
|
||||
if config.Metadata.Unset == nil {
|
||||
config.Metadata.Unset = make([]string, 0)
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
keyName := f.Name
|
||||
|
||||
if tagValue == "" && d.config.IgnoreUntaggedFields {
|
||||
continue
|
||||
}
|
||||
|
||||
// If Squash is set in the config, we squash the field down.
|
||||
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
|
||||
if index := strings.Index(tagValue, ","); index != -1 {
|
||||
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.
|
||||
squash = !squash && strings.Index(tagValue[index+1:], "squash") != -1
|
||||
squash = squash || strings.Index(tagValue[index+1:], "squash") != -1
|
||||
if squash {
|
||||
// When squashing, the embedded type can be a pointer to a 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())
|
||||
}
|
||||
}
|
||||
keyName = tagValue[:index]
|
||||
if keyNameTagValue := tagValue[:index]; keyNameTagValue != "" {
|
||||
keyName = keyNameTagValue
|
||||
}
|
||||
} else if len(tagValue) > 0 {
|
||||
if tagValue == "-" {
|
||||
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 dataVal.IsNil() {
|
||||
if dataValKind != reflect.Array && dataVal.IsNil() {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -1250,6 +1277,7 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
|
|||
dataValKeysUnused[dataValKey.Interface()] = struct{}{}
|
||||
}
|
||||
|
||||
targetValKeysUnused := make(map[interface{}]struct{})
|
||||
errors := make([]string, 0)
|
||||
|
||||
// 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() {
|
||||
// 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
|
||||
}
|
||||
}
|
||||
|
@ -1414,6 +1443,17 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
|
|||
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 {
|
||||
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)
|
||||
}
|
||||
for rawKey := range targetValKeysUnused {
|
||||
key := rawKey.(string)
|
||||
if name != "" {
|
||||
key = name + "." + key
|
||||
}
|
||||
|
||||
d.config.Metadata.Unset = append(d.config.Metadata.Unset, key)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -1465,3 +1513,28 @@ func getKind(val reflect.Value) reflect.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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
change.
|
||||
|
||||
The remaining features (Document structure editing and tooling) will be added
|
||||
shortly. While pull-requests are welcome on v1, no active development is
|
||||
expected on it. When v2.0.0 is released, v1 will be deprecated.
|
||||
The remaining features will be added shortly. While pull-requests are welcome on
|
||||
v1, no active development is expected on it. When v2.0.0 is released, v1 will be
|
||||
deprecated.
|
||||
|
||||
👉 [go-toml v2][v2]
|
||||
|
||||
|
|
|
@ -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!
|
|
@ -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())
|
||||
}
|
||||
|
||||
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())
|
||||
}
|
||||
if reflect.Indirect(reflect.New(mtype)).OverflowUint(val.Convert(reflect.TypeOf(uint64(0))).Uint()) {
|
||||
|
|
|
@ -293,42 +293,41 @@ func (p *tomlParser) parseRvalue() interface{} {
|
|||
return math.NaN()
|
||||
case tokenInteger:
|
||||
cleanedVal := cleanupNumberToken(tok.val)
|
||||
var err error
|
||||
var val int64
|
||||
base := 10
|
||||
s := cleanedVal
|
||||
checkInvalidUnderscore := numberContainsInvalidUnderscore
|
||||
if len(cleanedVal) >= 3 && cleanedVal[0] == '0' {
|
||||
switch cleanedVal[1] {
|
||||
case 'x':
|
||||
err = hexNumberContainsInvalidUnderscore(tok.val)
|
||||
if err != nil {
|
||||
p.raiseError(tok, "%s", err)
|
||||
}
|
||||
val, err = strconv.ParseInt(cleanedVal[2:], 16, 64)
|
||||
checkInvalidUnderscore = hexNumberContainsInvalidUnderscore
|
||||
base = 16
|
||||
case 'o':
|
||||
err = numberContainsInvalidUnderscore(tok.val)
|
||||
if err != nil {
|
||||
p.raiseError(tok, "%s", err)
|
||||
}
|
||||
val, err = strconv.ParseInt(cleanedVal[2:], 8, 64)
|
||||
base = 8
|
||||
case 'b':
|
||||
err = numberContainsInvalidUnderscore(tok.val)
|
||||
if err != nil {
|
||||
p.raiseError(tok, "%s", err)
|
||||
}
|
||||
val, err = strconv.ParseInt(cleanedVal[2:], 2, 64)
|
||||
base = 2
|
||||
default:
|
||||
panic("invalid base") // the lexer should catch this first
|
||||
}
|
||||
} else {
|
||||
err = numberContainsInvalidUnderscore(tok.val)
|
||||
if err != nil {
|
||||
p.raiseError(tok, "%s", err)
|
||||
}
|
||||
val, err = strconv.ParseInt(cleanedVal, 10, 64)
|
||||
}
|
||||
s = cleanedVal[2:]
|
||||
}
|
||||
|
||||
err := checkInvalidUnderscore(tok.val)
|
||||
if err != nil {
|
||||
p.raiseError(tok, "%s", err)
|
||||
}
|
||||
|
||||
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:
|
||||
err := numberContainsInvalidUnderscore(tok.val)
|
||||
if err != nil {
|
||||
|
|
|
@ -471,7 +471,7 @@ func LoadBytes(b []byte) (tree *Tree, err error) {
|
|||
if _, ok := r.(runtime.Error); ok {
|
||||
panic(r)
|
||||
}
|
||||
err = errors.New(r.(string))
|
||||
err = fmt.Errorf("%s", r)
|
||||
}
|
||||
}()
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
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
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
@ -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).
|
||||
|
||||
## 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)
|
||||
|
||||
[💬 Anything else](https://github.com/pelletier/go-toml/discussions)
|
||||
|
@ -49,7 +38,7 @@ operations should not be shockingly slow. See [benchmarks](#benchmarks).
|
|||
### Strict mode
|
||||
|
||||
`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].
|
||||
|
||||
[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
|
||||
[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
|
||||
|
||||
The MIT License (MIT). Read [LICENSE](LICENSE).
|
||||
|
|
|
@ -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
|
||||
// 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 {
|
||||
var (
|
||||
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 {
|
||||
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 = append(b, "# "...)
|
||||
b = append(b, comment...)
|
||||
b = append(b, line...)
|
||||
b = append(b, '\n')
|
||||
}
|
||||
return b
|
||||
|
@ -881,6 +891,8 @@ func (enc *Encoder) encodeSliceAsArrayTable(b []byte, ctx encoderCtx, v reflect.
|
|||
scratch = append(scratch, "]]\n"...)
|
||||
ctx.skipTableHeader = true
|
||||
|
||||
b = enc.encodeComment(ctx.indent, ctx.options.comment, b)
|
||||
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
b = append(b, scratch...)
|
||||
|
||||
|
|
|
@ -866,12 +866,27 @@ func (d *decoder) unmarshalFloat(value *ast.Node, v reflect.Value) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (d *decoder) unmarshalInteger(value *ast.Node, v reflect.Value) error {
|
||||
const (
|
||||
maxInt = int64(^uint(0) >> 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)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -932,7 +947,7 @@ func (d *decoder) unmarshalInteger(value *ast.Node, v reflect.Value) error {
|
|||
|
||||
r = reflect.ValueOf(uint8(i))
|
||||
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)
|
||||
}
|
||||
|
||||
|
@ -1167,11 +1182,6 @@ func forEachField(t reflect.Type, path []int, do func(name string, path []int))
|
|||
fieldPath := append(path, i)
|
||||
fieldPath = fieldPath[:len(fieldPath):len(fieldPath)]
|
||||
|
||||
if f.Anonymous {
|
||||
forEachField(f.Type, fieldPath, do)
|
||||
continue
|
||||
}
|
||||
|
||||
name := f.Tag.Get("toml")
|
||||
if name == "-" {
|
||||
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 {
|
||||
name = name[:i]
|
||||
}
|
||||
|
||||
if f.Anonymous && name == "" {
|
||||
forEachField(f.Type, fieldPath, do)
|
||||
continue
|
||||
}
|
||||
|
||||
if name == "" {
|
||||
name = f.Name
|
||||
}
|
||||
|
|
|
@ -34,6 +34,12 @@ func ToTimeInDefaultLocationE(i interface{}, location *time.Location) (tim time.
|
|||
return v, nil
|
||||
case string:
|
||||
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:
|
||||
return time.Unix(int64(v), 0), nil
|
||||
case int64:
|
||||
|
@ -71,6 +77,11 @@ func ToDurationE(i interface{}) (d time.Duration, err error) {
|
|||
d, err = time.ParseDuration(s + "ns")
|
||||
}
|
||||
return
|
||||
case json.Number:
|
||||
var v float64
|
||||
v, err = s.Float64()
|
||||
d = time.Duration(v)
|
||||
return
|
||||
default:
|
||||
err = fmt.Errorf("unable to cast %#v of type %T to Duration", i, i)
|
||||
return
|
||||
|
@ -93,6 +104,12 @@ func ToBoolE(i interface{}) (bool, error) {
|
|||
return false, nil
|
||||
case 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:
|
||||
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) {
|
||||
i = indirect(i)
|
||||
|
||||
intv, ok := toInt(i)
|
||||
if ok {
|
||||
return float64(intv), nil
|
||||
}
|
||||
|
||||
switch s := i.(type) {
|
||||
case float64:
|
||||
return s, nil
|
||||
case float32:
|
||||
return float64(s), nil
|
||||
case int:
|
||||
return float64(s), nil
|
||||
case int64:
|
||||
return float64(s), nil
|
||||
case int32:
|
||||
|
@ -133,11 +153,19 @@ func ToFloat64E(i interface{}) (float64, error) {
|
|||
return v, nil
|
||||
}
|
||||
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:
|
||||
if s {
|
||||
return 1, nil
|
||||
}
|
||||
return 0, nil
|
||||
case nil:
|
||||
return 0, nil
|
||||
default:
|
||||
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) {
|
||||
i = indirect(i)
|
||||
|
||||
intv, ok := toInt(i)
|
||||
if ok {
|
||||
return float32(intv), nil
|
||||
}
|
||||
|
||||
switch s := i.(type) {
|
||||
case float64:
|
||||
return float32(s), nil
|
||||
case float32:
|
||||
return s, nil
|
||||
case int:
|
||||
return float32(s), nil
|
||||
case int64:
|
||||
return float32(s), nil
|
||||
case int32:
|
||||
|
@ -178,11 +209,19 @@ func ToFloat32E(i interface{}) (float32, error) {
|
|||
return float32(v), nil
|
||||
}
|
||||
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:
|
||||
if s {
|
||||
return 1, nil
|
||||
}
|
||||
return 0, nil
|
||||
case nil:
|
||||
return 0, nil
|
||||
default:
|
||||
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) {
|
||||
i = indirect(i)
|
||||
|
||||
intv, ok := toInt(i)
|
||||
if ok {
|
||||
return int64(intv), nil
|
||||
}
|
||||
|
||||
switch s := i.(type) {
|
||||
case int:
|
||||
return int64(s), nil
|
||||
case int64:
|
||||
return s, nil
|
||||
case int32:
|
||||
|
@ -218,11 +260,13 @@ func ToInt64E(i interface{}) (int64, error) {
|
|||
case float32:
|
||||
return int64(s), nil
|
||||
case string:
|
||||
v, err := strconv.ParseInt(s, 0, 0)
|
||||
v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
|
||||
if err == nil {
|
||||
return v, nil
|
||||
}
|
||||
return 0, fmt.Errorf("unable to cast %#v of type %T to int64", i, i)
|
||||
case json.Number:
|
||||
return ToInt64E(string(s))
|
||||
case bool:
|
||||
if s {
|
||||
return 1, nil
|
||||
|
@ -239,9 +283,12 @@ func ToInt64E(i interface{}) (int64, error) {
|
|||
func ToInt32E(i interface{}) (int32, error) {
|
||||
i = indirect(i)
|
||||
|
||||
intv, ok := toInt(i)
|
||||
if ok {
|
||||
return int32(intv), nil
|
||||
}
|
||||
|
||||
switch s := i.(type) {
|
||||
case int:
|
||||
return int32(s), nil
|
||||
case int64:
|
||||
return int32(s), nil
|
||||
case int32:
|
||||
|
@ -265,11 +312,13 @@ func ToInt32E(i interface{}) (int32, error) {
|
|||
case float32:
|
||||
return int32(s), nil
|
||||
case string:
|
||||
v, err := strconv.ParseInt(s, 0, 0)
|
||||
v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
|
||||
if err == nil {
|
||||
return int32(v), nil
|
||||
}
|
||||
return 0, fmt.Errorf("unable to cast %#v of type %T to int32", i, i)
|
||||
case json.Number:
|
||||
return ToInt32E(string(s))
|
||||
case bool:
|
||||
if s {
|
||||
return 1, nil
|
||||
|
@ -286,9 +335,12 @@ func ToInt32E(i interface{}) (int32, error) {
|
|||
func ToInt16E(i interface{}) (int16, error) {
|
||||
i = indirect(i)
|
||||
|
||||
intv, ok := toInt(i)
|
||||
if ok {
|
||||
return int16(intv), nil
|
||||
}
|
||||
|
||||
switch s := i.(type) {
|
||||
case int:
|
||||
return int16(s), nil
|
||||
case int64:
|
||||
return int16(s), nil
|
||||
case int32:
|
||||
|
@ -312,11 +364,13 @@ func ToInt16E(i interface{}) (int16, error) {
|
|||
case float32:
|
||||
return int16(s), nil
|
||||
case string:
|
||||
v, err := strconv.ParseInt(s, 0, 0)
|
||||
v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
|
||||
if err == nil {
|
||||
return int16(v), nil
|
||||
}
|
||||
return 0, fmt.Errorf("unable to cast %#v of type %T to int16", i, i)
|
||||
case json.Number:
|
||||
return ToInt16E(string(s))
|
||||
case bool:
|
||||
if s {
|
||||
return 1, nil
|
||||
|
@ -333,9 +387,12 @@ func ToInt16E(i interface{}) (int16, error) {
|
|||
func ToInt8E(i interface{}) (int8, error) {
|
||||
i = indirect(i)
|
||||
|
||||
intv, ok := toInt(i)
|
||||
if ok {
|
||||
return int8(intv), nil
|
||||
}
|
||||
|
||||
switch s := i.(type) {
|
||||
case int:
|
||||
return int8(s), nil
|
||||
case int64:
|
||||
return int8(s), nil
|
||||
case int32:
|
||||
|
@ -359,11 +416,13 @@ func ToInt8E(i interface{}) (int8, error) {
|
|||
case float32:
|
||||
return int8(s), nil
|
||||
case string:
|
||||
v, err := strconv.ParseInt(s, 0, 0)
|
||||
v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
|
||||
if err == nil {
|
||||
return int8(v), nil
|
||||
}
|
||||
return 0, fmt.Errorf("unable to cast %#v of type %T to int8", i, i)
|
||||
case json.Number:
|
||||
return ToInt8E(string(s))
|
||||
case bool:
|
||||
if s {
|
||||
return 1, nil
|
||||
|
@ -380,9 +439,12 @@ func ToInt8E(i interface{}) (int8, error) {
|
|||
func ToIntE(i interface{}) (int, error) {
|
||||
i = indirect(i)
|
||||
|
||||
intv, ok := toInt(i)
|
||||
if ok {
|
||||
return intv, nil
|
||||
}
|
||||
|
||||
switch s := i.(type) {
|
||||
case int:
|
||||
return s, nil
|
||||
case int64:
|
||||
return int(s), nil
|
||||
case int32:
|
||||
|
@ -406,11 +468,13 @@ func ToIntE(i interface{}) (int, error) {
|
|||
case float32:
|
||||
return int(s), nil
|
||||
case string:
|
||||
v, err := strconv.ParseInt(s, 0, 0)
|
||||
v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
|
||||
if err == 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:
|
||||
if s {
|
||||
return 1, nil
|
||||
|
@ -427,18 +491,26 @@ func ToIntE(i interface{}) (int, error) {
|
|||
func ToUintE(i interface{}) (uint, error) {
|
||||
i = indirect(i)
|
||||
|
||||
switch s := i.(type) {
|
||||
case string:
|
||||
v, err := strconv.ParseUint(s, 0, 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 {
|
||||
intv, ok := toInt(i)
|
||||
if ok {
|
||||
if intv < 0 {
|
||||
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:
|
||||
if s < 0 {
|
||||
return 0, errNegativeNotAllowed
|
||||
|
@ -495,18 +567,26 @@ func ToUintE(i interface{}) (uint, error) {
|
|||
func ToUint64E(i interface{}) (uint64, error) {
|
||||
i = indirect(i)
|
||||
|
||||
switch s := i.(type) {
|
||||
case string:
|
||||
v, err := strconv.ParseUint(s, 0, 64)
|
||||
if err == nil {
|
||||
return v, nil
|
||||
}
|
||||
return 0, fmt.Errorf("unable to cast %#v to uint64: %s", i, err)
|
||||
case int:
|
||||
if s < 0 {
|
||||
intv, ok := toInt(i)
|
||||
if ok {
|
||||
if intv < 0 {
|
||||
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:
|
||||
if s < 0 {
|
||||
return 0, errNegativeNotAllowed
|
||||
|
@ -563,18 +643,26 @@ func ToUint64E(i interface{}) (uint64, error) {
|
|||
func ToUint32E(i interface{}) (uint32, error) {
|
||||
i = indirect(i)
|
||||
|
||||
switch s := i.(type) {
|
||||
case string:
|
||||
v, err := strconv.ParseUint(s, 0, 32)
|
||||
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 {
|
||||
intv, ok := toInt(i)
|
||||
if ok {
|
||||
if intv < 0 {
|
||||
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:
|
||||
if s < 0 {
|
||||
return 0, errNegativeNotAllowed
|
||||
|
@ -631,18 +719,26 @@ func ToUint32E(i interface{}) (uint32, error) {
|
|||
func ToUint16E(i interface{}) (uint16, error) {
|
||||
i = indirect(i)
|
||||
|
||||
switch s := i.(type) {
|
||||
case string:
|
||||
v, err := strconv.ParseUint(s, 0, 16)
|
||||
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 {
|
||||
intv, ok := toInt(i)
|
||||
if ok {
|
||||
if intv < 0 {
|
||||
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:
|
||||
if s < 0 {
|
||||
return 0, errNegativeNotAllowed
|
||||
|
@ -699,18 +795,26 @@ func ToUint16E(i interface{}) (uint16, error) {
|
|||
func ToUint8E(i interface{}) (uint8, error) {
|
||||
i = indirect(i)
|
||||
|
||||
switch s := i.(type) {
|
||||
case string:
|
||||
v, err := strconv.ParseUint(s, 0, 8)
|
||||
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 {
|
||||
intv, ok := toInt(i)
|
||||
if ok {
|
||||
if intv < 0 {
|
||||
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:
|
||||
if s < 0 {
|
||||
return 0, errNegativeNotAllowed
|
||||
|
@ -835,6 +939,8 @@ func ToStringE(i interface{}) (string, error) {
|
|||
return strconv.FormatUint(uint64(s), 10), nil
|
||||
case uint8:
|
||||
return strconv.FormatUint(uint64(s), 10), nil
|
||||
case json.Number:
|
||||
return s.String(), nil
|
||||
case []byte:
|
||||
return string(s), nil
|
||||
case template.HTML:
|
||||
|
@ -1279,30 +1385,30 @@ func (f timeFormat) hasTimezone() bool {
|
|||
|
||||
var (
|
||||
timeFormats = []timeFormat{
|
||||
timeFormat{time.RFC3339, timeFormatNumericTimezone},
|
||||
timeFormat{"2006-01-02T15:04:05", timeFormatNoTimezone}, // iso8601 without timezone
|
||||
timeFormat{time.RFC1123Z, timeFormatNumericTimezone},
|
||||
timeFormat{time.RFC1123, timeFormatNamedTimezone},
|
||||
timeFormat{time.RFC822Z, timeFormatNumericTimezone},
|
||||
timeFormat{time.RFC822, timeFormatNamedTimezone},
|
||||
timeFormat{time.RFC850, timeFormatNamedTimezone},
|
||||
timeFormat{"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
|
||||
timeFormat{"2006-01-02 15:04:05Z0700", timeFormatNumericTimezone}, // RFC3339 without T or timezone hh:mm colon
|
||||
timeFormat{"2006-01-02 15:04:05", timeFormatNoTimezone},
|
||||
timeFormat{time.ANSIC, timeFormatNoTimezone},
|
||||
timeFormat{time.UnixDate, timeFormatNamedTimezone},
|
||||
timeFormat{time.RubyDate, timeFormatNumericTimezone},
|
||||
timeFormat{"2006-01-02 15:04:05Z07:00", timeFormatNumericTimezone},
|
||||
timeFormat{"2006-01-02", timeFormatNoTimezone},
|
||||
timeFormat{"02 Jan 2006", timeFormatNoTimezone},
|
||||
timeFormat{"2006-01-02 15:04:05 -07:00", timeFormatNumericTimezone},
|
||||
timeFormat{"2006-01-02 15:04:05 -0700", timeFormatNumericTimezone},
|
||||
timeFormat{time.Kitchen, timeFormatTimeOnly},
|
||||
timeFormat{time.Stamp, timeFormatTimeOnly},
|
||||
timeFormat{time.StampMilli, timeFormatTimeOnly},
|
||||
timeFormat{time.StampMicro, timeFormatTimeOnly},
|
||||
timeFormat{time.StampNano, timeFormatTimeOnly},
|
||||
{time.RFC3339, timeFormatNumericTimezone},
|
||||
{"2006-01-02T15:04:05", timeFormatNoTimezone}, // iso8601 without timezone
|
||||
{time.RFC1123Z, timeFormatNumericTimezone},
|
||||
{time.RFC1123, timeFormatNamedTimezone},
|
||||
{time.RFC822Z, timeFormatNumericTimezone},
|
||||
{time.RFC822, timeFormatNamedTimezone},
|
||||
{time.RFC850, timeFormatNamedTimezone},
|
||||
{"2006-01-02 15:04:05.999999999 -0700 MST", timeFormatNumericAndNamedTimezone}, // Time.String()
|
||||
{"2006-01-02T15:04:05-0700", timeFormatNumericTimezone}, // RFC3339 without timezone hh:mm colon
|
||||
{"2006-01-02 15:04:05Z0700", timeFormatNumericTimezone}, // RFC3339 without T or timezone hh:mm colon
|
||||
{"2006-01-02 15:04:05", timeFormatNoTimezone},
|
||||
{time.ANSIC, timeFormatNoTimezone},
|
||||
{time.UnixDate, timeFormatNamedTimezone},
|
||||
{time.RubyDate, timeFormatNumericTimezone},
|
||||
{"2006-01-02 15:04:05Z07:00", timeFormatNumericTimezone},
|
||||
{"2006-01-02", timeFormatNoTimezone},
|
||||
{"02 Jan 2006", timeFormatNoTimezone},
|
||||
{"2006-01-02 15:04:05 -07:00", timeFormatNumericTimezone},
|
||||
{"2006-01-02 15:04:05 -0700", timeFormatNumericTimezone},
|
||||
{time.Kitchen, timeFormatTimeOnly},
|
||||
{time.Stamp, timeFormatTimeOnly},
|
||||
{time.StampMilli, timeFormatTimeOnly},
|
||||
{time.StampMicro, timeFormatTimeOnly},
|
||||
{time.StampNano, timeFormatTimeOnly},
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -1335,3 +1441,36 @@ func jsonStringToObject(s string, v interface{}) error {
|
|||
data := []byte(s)
|
||||
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
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//go:build !viper_toml2
|
||||
// +build !viper_toml2
|
||||
//go:build viper_toml1
|
||||
// +build viper_toml1
|
||||
|
||||
package toml
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//go:build viper_toml2
|
||||
// +build viper_toml2
|
||||
//go:build !viper_toml1
|
||||
// +build !viper_toml1
|
||||
|
||||
package toml
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//go:build !viper_yaml3
|
||||
// +build !viper_yaml3
|
||||
//go:build viper_yaml2
|
||||
// +build viper_yaml2
|
||||
|
||||
package yaml
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//go:build viper_yaml3
|
||||
// +build viper_yaml3
|
||||
//go:build !viper_yaml2
|
||||
// +build !viper_yaml2
|
||||
|
||||
package yaml
|
||||
|
||||
|
|
|
@ -1197,6 +1197,17 @@ func (v *Viper) BindEnv(input ...string) error {
|
|||
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.
|
||||
//
|
||||
// Viper will check to see if an alias exists first.
|
||||
|
@ -1798,8 +1809,13 @@ func mergeMaps(
|
|||
tsv, ok := sv.(map[interface{}]interface{})
|
||||
if !ok {
|
||||
v.logger.Error(
|
||||
"Could not cast sv to map[interface{}]interface{}; key=%s, st=%v, tt=%v, sv=%v, tv=%v",
|
||||
sk, svType, tvType, sv, tv)
|
||||
"Could not cast sv to map[interface{}]interface{}",
|
||||
"key", sk,
|
||||
"st", svType,
|
||||
"tt", tvType,
|
||||
"sv", sv,
|
||||
"tv", tv,
|
||||
)
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -1811,8 +1827,13 @@ func mergeMaps(
|
|||
tsv, ok := sv.(map[string]interface{})
|
||||
if !ok {
|
||||
v.logger.Error(
|
||||
"Could not cast sv to map[string]interface{}; key=%s, st=%v, tt=%v, sv=%v, tv=%v",
|
||||
sk, svType, tvType, sv, tv)
|
||||
"Could not cast sv to map[string]interface{}",
|
||||
"key", sk,
|
||||
"st", svType,
|
||||
"tt", tvType,
|
||||
"sv", sv,
|
||||
"tv", tv,
|
||||
)
|
||||
continue
|
||||
}
|
||||
mergeMaps(tsv, ttv, nil)
|
||||
|
|
|
@ -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)
|
|
@ -1,5 +1,16 @@
|
|||
# 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
|
||||
|
||||
### Added
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
# gotenv
|
||||
|
||||
[![Build Status](https://travis-ci.org/subosito/gotenv.svg?branch=master)](https://travis-ci.org/subosito/gotenv)
|
||||
[![Build status](https://ci.appveyor.com/api/projects/status/wb2e075xkfl0m0v2/branch/master?svg=true)](https://ci.appveyor.com/project/subosito/gotenv/branch/master)
|
||||
[![Build Status](https://github.com/subosito/gotenv/workflows/Go%20workflow/badge.svg)](https://github.com/subosito/gotenv/actions)
|
||||
[![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)
|
||||
[![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
|
||||
|
||||
|
@ -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"))
|
||||
// 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"}
|
||||
```
|
||||
|
||||
|
|
|
@ -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
|
|
@ -16,6 +16,9 @@ const (
|
|||
|
||||
// Pattern for detecting valid variable within a value
|
||||
variablePattern = `(\\)?(\$)(\{?([A-Z0-9_]+)?\}?)`
|
||||
|
||||
// Byte order mark character
|
||||
bom = "\xef\xbb\xbf"
|
||||
)
|
||||
|
||||
// Env holds key/value pair of valid environment variable
|
||||
|
@ -84,7 +87,7 @@ func loadenv(override bool, filenames ...string) error {
|
|||
|
||||
// parse and set :)
|
||||
func parset(r io.Reader, override bool) error {
|
||||
env, err := StrictParse(r)
|
||||
env, err := strictParse(r, override)
|
||||
if err != nil {
|
||||
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.
|
||||
// This function is skipping any invalid lines and only processing the valid one.
|
||||
func Parse(r io.Reader) Env {
|
||||
env, _ := StrictParse(r)
|
||||
env, _ := strictParse(r, false)
|
||||
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.
|
||||
// This function is returning an error if there are any invalid lines.
|
||||
func StrictParse(r io.Reader) (Env, error) {
|
||||
return strictParse(r, false)
|
||||
}
|
||||
|
||||
func strictParse(r io.Reader, override bool) (Env, error) {
|
||||
env := make(Env)
|
||||
scanner := bufio.NewScanner(r)
|
||||
|
||||
i := 1
|
||||
bom := string([]byte{239, 187, 191})
|
||||
firstLine := true
|
||||
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
line := strings.TrimSpace(scanner.Text())
|
||||
|
||||
if i == 1 {
|
||||
if firstLine {
|
||||
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 {
|
||||
return env, err
|
||||
}
|
||||
|
@ -142,9 +182,14 @@ func StrictParse(r io.Reader) (Env, error) {
|
|||
return env, nil
|
||||
}
|
||||
|
||||
func parseLine(s string, env Env) error {
|
||||
rl := regexp.MustCompile(linePattern)
|
||||
rm := rl.FindStringSubmatch(s)
|
||||
var (
|
||||
lineRgx = regexp.MustCompile(linePattern)
|
||||
unescapeRgx = regexp.MustCompile(`\\([^$])`)
|
||||
varRgx = regexp.MustCompile(variablePattern)
|
||||
)
|
||||
|
||||
func parseLine(s string, env Env, override bool) error {
|
||||
rm := lineRgx.FindStringSubmatch(s)
|
||||
|
||||
if len(rm) == 0 {
|
||||
return checkFormat(s, env)
|
||||
|
@ -153,35 +198,36 @@ func parseLine(s string, env Env) error {
|
|||
key := rm[1]
|
||||
val := rm[2]
|
||||
|
||||
// trim whitespace
|
||||
val = strings.TrimSpace(val)
|
||||
|
||||
// determine if string has quote prefix
|
||||
hdq := strings.HasPrefix(val, `"`)
|
||||
|
||||
// determine if string has single quote prefix
|
||||
hsq := strings.HasPrefix(val, `'`)
|
||||
|
||||
// trim whitespace
|
||||
val = strings.Trim(val, " ")
|
||||
|
||||
// remove quotes '' or ""
|
||||
rq := regexp.MustCompile(`\A(['"])(.*)(['"])\z`)
|
||||
val = rq.ReplaceAllString(val, "$2")
|
||||
if l := len(val); (hsq || hdq) && l >= 2 {
|
||||
val = val[1 : l-1]
|
||||
}
|
||||
|
||||
if hdq {
|
||||
val = strings.Replace(val, `\n`, "\n", -1)
|
||||
val = strings.Replace(val, `\r`, "\r", -1)
|
||||
val = strings.ReplaceAll(val, `\n`, "\n")
|
||||
val = strings.ReplaceAll(val, `\r`, "\r")
|
||||
|
||||
// Unescape all characters except $ so variables can be escaped properly
|
||||
re := regexp.MustCompile(`\\([^$])`)
|
||||
val = re.ReplaceAllString(val, "$1")
|
||||
val = unescapeRgx.ReplaceAllString(val, "$1")
|
||||
}
|
||||
|
||||
rv := regexp.MustCompile(variablePattern)
|
||||
fv := func(s string) string {
|
||||
return varReplacement(s, hsq, env)
|
||||
return varReplacement(s, hsq, env, override)
|
||||
}
|
||||
|
||||
val = rv.ReplaceAllStringFunc(val, fv)
|
||||
val = parseVal(val, env)
|
||||
if !hsq {
|
||||
val = varRgx.ReplaceAllStringFunc(val, fv)
|
||||
val = parseVal(val, env, hdq, override)
|
||||
}
|
||||
|
||||
env[key] = val
|
||||
return nil
|
||||
|
@ -201,7 +247,9 @@ func parseExport(st string, env Env) error {
|
|||
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, "\\") {
|
||||
return strings.TrimPrefix(s, "\\")
|
||||
}
|
||||
|
@ -210,9 +258,7 @@ func varReplacement(s string, hsq bool, env Env) string {
|
|||
return s
|
||||
}
|
||||
|
||||
sn := `(\$)(\{?([A-Z0-9_]+)\}?)`
|
||||
rn := regexp.MustCompile(sn)
|
||||
mn := rn.FindStringSubmatch(s)
|
||||
mn := varNameRgx.FindStringSubmatch(s)
|
||||
|
||||
if len(mn) == 0 {
|
||||
return s
|
||||
|
@ -220,6 +266,10 @@ func varReplacement(s string, hsq bool, env Env) string {
|
|||
|
||||
v := mn[3]
|
||||
|
||||
if replace, ok := os.LookupEnv(v); ok && !override {
|
||||
return replace
|
||||
}
|
||||
|
||||
replace, ok := env[v]
|
||||
if !ok {
|
||||
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)
|
||||
}
|
||||
|
||||
func parseVal(val string, env Env) string {
|
||||
if strings.Contains(val, "=") {
|
||||
if !(val == "\n" || val == "\r") {
|
||||
kv := strings.Split(val, "\n")
|
||||
|
||||
if len(kv) == 1 {
|
||||
kv = strings.Split(val, "\r")
|
||||
}
|
||||
func parseVal(val string, env Env, ignoreNewlines bool, override bool) string {
|
||||
if strings.Contains(val, "=") && !ignoreNewlines {
|
||||
kv := strings.Split(val, "\r")
|
||||
|
||||
if len(kv) > 1 {
|
||||
val = kv[0]
|
||||
|
||||
for i := 1; i < len(kv); i++ {
|
||||
parseLine(kv[i], env)
|
||||
}
|
||||
for _, l := range kv[1:] {
|
||||
_ = parseLine(l, env, override)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,12 @@ whatsmeow is a Go library for the WhatsApp web multidevice API.
|
|||
## Discussion
|
||||
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
|
||||
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.
|
||||
|
@ -23,9 +29,10 @@ Most core features are already present:
|
|||
* Sending and receiving delivery and read receipts
|
||||
* Reading app state (contact list, chat pin/mute status, etc)
|
||||
* 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:
|
||||
|
||||
* 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
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
package whatsmeow
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
|
@ -53,6 +55,9 @@ func (cli *Client) FetchAppState(name appstate.WAPatchName, fullSync, onlyIfNotS
|
|||
|
||||
mutations, newState, err := cli.appStateProc.DecodePatches(patches, state, true)
|
||||
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)
|
||||
}
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,3 +83,36 @@ func (proc *Processor) getAppStateKey(keyID []byte) (keys ExpandedAppStateKeys,
|
|||
}
|
||||
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
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ package binary
|
|||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"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.
|
||||
func (au *AttrUtility) OptionalString(key string) string {
|
||||
strVal, _ := au.GetString(key, false)
|
||||
|
@ -155,6 +166,16 @@ func (au *AttrUtility) Bool(key string) bool {
|
|||
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.
|
||||
func (au *AttrUtility) OK() bool {
|
||||
return len(au.Errors) == 0
|
||||
|
|
|
@ -2739,7 +2739,7 @@ func (x *DNSSource_DNSSourceDNSResolutionMethod) UnmarshalJSON(b []byte) error {
|
|||
|
||||
// Deprecated: Use DNSSource_DNSSourceDNSResolutionMethod.Descriptor instead.
|
||||
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
|
||||
|
@ -10131,7 +10131,6 @@ type ContextInfo struct {
|
|||
ActionLink *ActionLink `protobuf:"bytes,33,opt,name=actionLink" json:"actionLink,omitempty"`
|
||||
GroupSubject *string `protobuf:"bytes,34,opt,name=groupSubject" json:"groupSubject,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() {
|
||||
|
@ -10327,13 +10326,6 @@ func (x *ContextInfo) GetParentGroupJid() string {
|
|||
return ""
|
||||
}
|
||||
|
||||
func (x *ContextInfo) GetMessageSecret() []byte {
|
||||
if x != nil {
|
||||
return x.MessageSecret
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ExternalAdReplyInfo struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
|
@ -11577,6 +11569,7 @@ type MessageContextInfo struct {
|
|||
|
||||
DeviceListMetadata *DeviceListMetadata `protobuf:"bytes,1,opt,name=deviceListMetadata" json:"deviceListMetadata,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() {
|
||||
|
@ -11625,6 +11618,13 @@ func (x *MessageContextInfo) GetDeviceListMetadataVersion() int32 {
|
|||
return 0
|
||||
}
|
||||
|
||||
func (x *MessageContextInfo) GetMessageSecret() []byte {
|
||||
if x != nil {
|
||||
return x.MessageSecret
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type VideoMessage struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
|
@ -13220,6 +13220,8 @@ type GlobalSettings struct {
|
|||
AutoDownloadRoaming *AutoDownloadSettings `protobuf:"bytes,6,opt,name=autoDownloadRoaming" json:"autoDownloadRoaming,omitempty"`
|
||||
ShowIndividualNotificationsPreview *bool `protobuf:"varint,7,opt,name=showIndividualNotificationsPreview" json:"showIndividualNotificationsPreview,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() {
|
||||
|
@ -13310,6 +13312,20 @@ func (x *GlobalSettings) GetShowGroupNotificationsPreview() bool {
|
|||
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 {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
|
@ -17690,7 +17706,7 @@ type ClientPayload struct {
|
|||
DnsSource *DNSSource `protobuf:"bytes,15,opt,name=dnsSource" json:"dnsSource,omitempty"`
|
||||
ConnectAttemptCount *uint32 `protobuf:"varint,16,opt,name=connectAttemptCount" json:"connectAttemptCount,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"`
|
||||
FbCat []byte `protobuf:"bytes,21,opt,name=fbCat" json:"fbCat,omitempty"`
|
||||
FbUserAgent []byte `protobuf:"bytes,22,opt,name=fbUserAgent" json:"fbUserAgent,omitempty"`
|
||||
|
@ -17825,9 +17841,9 @@ func (x *ClientPayload) GetDevice() uint32 {
|
|||
return 0
|
||||
}
|
||||
|
||||
func (x *ClientPayload) GetRegData() *CompanionRegData {
|
||||
func (x *ClientPayload) GetDevicePairingData() *DevicePairingRegistrationData {
|
||||
if x != nil {
|
||||
return x.RegData
|
||||
return x.DevicePairingData
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -18236,6 +18252,109 @@ func (x *UserAgent) GetDeviceBoard() string {
|
|||
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 {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
|
@ -18248,7 +18367,7 @@ type DNSSource struct {
|
|||
func (x *DNSSource) Reset() {
|
||||
*x = DNSSource{}
|
||||
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.StoreMessageInfo(mi)
|
||||
}
|
||||
|
@ -18261,7 +18380,7 @@ func (x *DNSSource) String() string {
|
|||
func (*DNSSource) ProtoMessage() {}
|
||||
|
||||
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 {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
|
@ -18274,7 +18393,7 @@ func (x *DNSSource) ProtoReflect() protoreflect.Message {
|
|||
|
||||
// Deprecated: Use DNSSource.ProtoReflect.Descriptor instead.
|
||||
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 {
|
||||
|
@ -18291,109 +18410,6 @@ func (x *DNSSource) GetAppCached() bool {
|
|||
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 {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
|
@ -20122,8 +20138,8 @@ var file_binary_proto_def_proto_goTypes = []interface{}{
|
|||
(*WebInfo)(nil), // 229: proto.WebInfo
|
||||
(*WebdPayload)(nil), // 230: proto.WebdPayload
|
||||
(*UserAgent)(nil), // 231: proto.UserAgent
|
||||
(*DNSSource)(nil), // 232: proto.DNSSource
|
||||
(*CompanionRegData)(nil), // 233: proto.CompanionRegData
|
||||
(*DevicePairingRegistrationData)(nil), // 232: proto.DevicePairingRegistrationData
|
||||
(*DNSSource)(nil), // 233: proto.DNSSource
|
||||
(*WebNotificationsInfo)(nil), // 234: proto.WebNotificationsInfo
|
||||
(*WebMessageInfo)(nil), // 235: proto.WebMessageInfo
|
||||
(*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
|
||||
35, // 277: proto.ClientPayload.connectType:type_name -> proto.ClientPayload.ClientPayloadConnectType
|
||||
36, // 278: proto.ClientPayload.connectReason:type_name -> proto.ClientPayload.ClientPayloadConnectReason
|
||||
232, // 279: proto.ClientPayload.dnsSource:type_name -> proto.DNSSource
|
||||
233, // 280: proto.ClientPayload.regData:type_name -> proto.CompanionRegData
|
||||
233, // 279: proto.ClientPayload.dnsSource:type_name -> proto.DNSSource
|
||||
232, // 280: proto.ClientPayload.devicePairingData:type_name -> proto.DevicePairingRegistrationData
|
||||
37, // 281: proto.ClientPayload.product:type_name -> proto.ClientPayload.ClientPayloadProduct
|
||||
38, // 282: proto.ClientPayload.iosAppExtension:type_name -> proto.ClientPayload.ClientPayloadIOSAppExtension
|
||||
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{} {
|
||||
switch v := v.(*DNSSource); i {
|
||||
switch v := v.(*DevicePairingRegistrationData); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
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{} {
|
||||
switch v := v.(*CompanionRegData); i {
|
||||
switch v := v.(*DNSSource); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
|
|
Binary file not shown.
|
@ -781,7 +781,6 @@ message ContextInfo {
|
|||
optional ActionLink actionLink = 33;
|
||||
optional string groupSubject = 34;
|
||||
optional string parentGroupJid = 35;
|
||||
optional bytes messageSecret = 36;
|
||||
}
|
||||
|
||||
message ExternalAdReplyInfo {
|
||||
|
@ -932,6 +931,7 @@ message Message {
|
|||
message MessageContextInfo {
|
||||
optional DeviceListMetadata deviceListMetadata = 1;
|
||||
optional int32 deviceListMetadataVersion = 2;
|
||||
optional bytes messageSecret = 3;
|
||||
}
|
||||
|
||||
message VideoMessage {
|
||||
|
@ -1123,6 +1123,8 @@ message GlobalSettings {
|
|||
optional AutoDownloadSettings autoDownloadRoaming = 6;
|
||||
optional bool showIndividualNotificationsPreview = 7;
|
||||
optional bool showGroupNotificationsPreview = 8;
|
||||
optional int32 disappearingModeDuration = 9;
|
||||
optional int64 disappearingModeTimestamp = 10;
|
||||
}
|
||||
|
||||
message Conversation {
|
||||
|
@ -1633,7 +1635,7 @@ message ClientPayload {
|
|||
optional DNSSource dnsSource = 15;
|
||||
optional uint32 connectAttemptCount = 16;
|
||||
optional uint32 device = 18;
|
||||
optional CompanionRegData regData = 19;
|
||||
optional DevicePairingRegistrationData devicePairingData = 19;
|
||||
enum ClientPayloadProduct {
|
||||
WHATSAPP = 0;
|
||||
MESSENGER = 1;
|
||||
|
@ -1744,6 +1746,17 @@ message UserAgent {
|
|||
// 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 {
|
||||
enum DNSSourceDNSResolutionMethod {
|
||||
SYSTEM = 0;
|
||||
|
@ -1756,17 +1769,6 @@ message DNSSource {
|
|||
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 {
|
||||
optional uint64 timestamp = 2;
|
||||
optional uint32 unreadChats = 3;
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -7,8 +7,6 @@
|
|||
package whatsmeow
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
waBinary "go.mau.fi/whatsmeow/binary"
|
||||
"go.mau.fi/whatsmeow/types"
|
||||
"go.mau.fi/whatsmeow/types/events"
|
||||
|
@ -26,7 +24,7 @@ func (cli *Client) handleCallEvent(node *waBinary.Node) {
|
|||
cag := child.AttrGetter()
|
||||
basicMeta := types.BasicCallMeta{
|
||||
From: ag.JID("from"),
|
||||
Timestamp: time.Unix(ag.Int64("t"), 0),
|
||||
Timestamp: ag.UnixTime("t"),
|
||||
CallCreator: cag.JID("call-creator"),
|
||||
CallID: cag.String("call-id"),
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ package whatsmeow
|
|||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
@ -52,6 +51,7 @@ type Client struct {
|
|||
|
||||
socket *socket.NoiseSocket
|
||||
socketLock sync.RWMutex
|
||||
socketWait chan struct{}
|
||||
|
||||
isLoggedIn uint32
|
||||
expectedDisconnectVal uint32
|
||||
|
@ -88,6 +88,11 @@ type Client struct {
|
|||
messageRetries map[string]int
|
||||
messageRetriesLock sync.Mutex
|
||||
|
||||
appStateKeyRequests map[string]time.Time
|
||||
appStateKeyRequestsLock sync.RWMutex
|
||||
|
||||
messageSendLock sync.Mutex
|
||||
|
||||
privacySettingsCache atomic.Value
|
||||
|
||||
groupParticipantsCache map[types.JID][]types.JID
|
||||
|
@ -99,22 +104,21 @@ type Client struct {
|
|||
recentMessagesList [recentMessagesSize]recentMessageKey
|
||||
recentMessagesPtr int
|
||||
recentMessagesLock sync.RWMutex
|
||||
|
||||
sessionRecreateHistory map[types.JID]time.Time
|
||||
sessionRecreateHistoryLock sync.Mutex
|
||||
// GetMessageForRetry is used to find the source message for handling retry receipts
|
||||
// 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.
|
||||
// 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
|
||||
// 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.
|
||||
AutoTrustIdentity bool
|
||||
|
||||
DebugDecodeBeforeSend bool
|
||||
OneMessageAtATime bool
|
||||
messageSendLock sync.Mutex
|
||||
|
||||
uniqueID string
|
||||
idCounter uint32
|
||||
|
||||
|
@ -162,6 +166,7 @@ func NewClient(deviceStore *store.Device, log waLog.Logger) *Client {
|
|||
messageRetries: make(map[string]int),
|
||||
handlerQueue: make(chan *waBinary.Node, handlerQueueSize),
|
||||
appStateProc: appstate.NewProcessor(deviceStore, log.Sub("AppState")),
|
||||
socketWait: make(chan struct{}),
|
||||
|
||||
historySyncNotifications: make(chan *waProto.HistorySyncNotification, 32),
|
||||
|
||||
|
@ -169,7 +174,9 @@ func NewClient(deviceStore *store.Device, log waLog.Logger) *Client {
|
|||
userDevicesCache: make(map[types.JID][]types.JID),
|
||||
|
||||
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,
|
||||
AutoTrustIdentity: true,
|
||||
|
@ -226,6 +233,37 @@ func (cli *Client) SetProxy(proxy socket.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
|
||||
// authenticate if there's data in the device store, or emit a QREvent to set up a new link.
|
||||
func (cli *Client) Connect() error {
|
||||
|
@ -322,6 +360,9 @@ func (cli *Client) IsConnected() bool {
|
|||
}
|
||||
|
||||
// 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() {
|
||||
if cli.socket == nil {
|
||||
return
|
||||
|
@ -336,6 +377,7 @@ func (cli *Client) unlockedDisconnect() {
|
|||
if cli.socket != nil {
|
||||
cli.socket.Stop(true)
|
||||
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 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 {
|
||||
if cli.Store.ID == nil {
|
||||
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()
|
||||
sock := cli.socket
|
||||
cli.socketLock.RUnlock()
|
||||
|
@ -503,22 +548,13 @@ func (cli *Client) sendNodeDebug(node waBinary.Node) ([]byte, error) {
|
|||
if err != nil {
|
||||
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())
|
||||
return payload, sock.SendFrame(payload)
|
||||
}
|
||||
|
||||
func (cli *Client) sendNode(node waBinary.Node) error {
|
||||
_, err := cli.sendNodeDebug(node)
|
||||
_, err := cli.sendNodeAndGetData(node)
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -535,3 +571,45 @@ func (cli *Client) dispatchEvent(evt interface{}) {
|
|||
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
|
||||
}
|
||||
|
|
|
@ -89,11 +89,7 @@ func (cli *Client) handleConnectFailure(node *waBinary.Node) {
|
|||
}
|
||||
} else if reason == events.ConnectFailureTempBanned {
|
||||
cli.Log.Warnf("Temporary ban connect failure: %s", node.XMLString())
|
||||
expiryTimeUnix := ag.Int64("expire")
|
||||
var expiryTime time.Time
|
||||
if expiryTimeUnix > 0 {
|
||||
expiryTime = time.Unix(expiryTimeUnix, 0)
|
||||
}
|
||||
expiryTime := ag.UnixTime("expire")
|
||||
go cli.dispatchEvent(&events.TemporaryBan{
|
||||
Code: events.TempBanReason(ag.Int("code")),
|
||||
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.dispatchEvent(&events.Connected{})
|
||||
cli.closeSocketWaitChan()
|
||||
}()
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"google.golang.org/protobuf/proto"
|
||||
"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()))
|
||||
}
|
||||
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())
|
||||
} else if len(msg.GetDirectPath()) > 0 {
|
||||
return cli.DownloadMediaWithPath(msg.GetDirectPath(), msg.GetFileEncSha256(), msg.GetFileSha256(), msg.GetMediaKey(), getSize(msg), mediaType, mediaTypeToMMSType[mediaType])
|
||||
} 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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,11 +50,13 @@ var (
|
|||
ErrMediaNotAvailableOnPhone = errors.New("media no longer available on phone")
|
||||
// ErrUnknownMediaRetryError is returned by DecryptMediaRetryNotification if the given event contains an unknown error code.
|
||||
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
|
||||
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")
|
||||
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
|
||||
var (
|
||||
ErrIQBadRequest error = &IQError{Code: 400, Text: "bad-request"}
|
||||
ErrIQNotAuthorized error = &IQError{Code: 401, Text: "not-authorized"}
|
||||
ErrIQForbidden error = &IQError{Code: 403, Text: "forbidden"}
|
||||
ErrIQNotFound error = &IQError{Code: 404, Text: "item-not-found"}
|
||||
|
|
|
@ -10,7 +10,6 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
waBinary "go.mau.fi/whatsmeow/binary"
|
||||
"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.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.GroupCreated = time.Unix(ag.Int64("creation"), 0)
|
||||
group.GroupCreated = ag.UnixTime("creation")
|
||||
|
||||
group.AnnounceVersionID = ag.OptionalString("a_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.TopicID = childAG.String("id")
|
||||
group.TopicSetBy = childAG.OptionalJIDOrEmpty("participant")
|
||||
group.TopicSetAt = time.Unix(childAG.Int64("t"), 0)
|
||||
group.TopicSetAt = childAG.UnixTime("t")
|
||||
}
|
||||
case "announcement":
|
||||
group.IsAnnounce = true
|
||||
|
@ -477,7 +476,7 @@ func (cli *Client) parseGroupChange(node *waBinary.Node) (*events.GroupInfo, err
|
|||
evt.JID = ag.JID("from")
|
||||
evt.Notify = ag.OptionalString("notify")
|
||||
evt.Sender = ag.OptionalJID("participant")
|
||||
evt.Timestamp = time.Unix(ag.Int64("t"), 0)
|
||||
evt.Timestamp = ag.UnixTime("t")
|
||||
if !ag.OK() {
|
||||
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":
|
||||
evt.Name = &types.GroupName{
|
||||
Name: cag.String("subject"),
|
||||
NameSetAt: time.Unix(cag.Int64("s_t"), 0),
|
||||
NameSetAt: cag.UnixTime("s_t"),
|
||||
NameSetBy: cag.OptionalJIDOrEmpty("s_o"),
|
||||
}
|
||||
case "description":
|
||||
|
|
|
@ -53,3 +53,11 @@ func (int *DangerousInternalClient) RefreshMediaConn(force bool) (*MediaConn, er
|
|||
func (int *DangerousInternalClient) GetServerPreKeyCount() (int, error) {
|
||||
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)
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
|
||||
waBinary "go.mau.fi/whatsmeow/binary"
|
||||
"go.mau.fi/whatsmeow/types"
|
||||
"go.mau.fi/whatsmeow/types/events"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -25,12 +26,27 @@ var (
|
|||
)
|
||||
|
||||
func (cli *Client) keepAliveLoop(ctx context.Context) {
|
||||
var lastSuccess time.Time
|
||||
var errorCount int
|
||||
for {
|
||||
interval := rand.Int63n(KeepAliveIntervalMax.Milliseconds()-KeepAliveIntervalMin.Milliseconds()) + KeepAliveIntervalMin.Milliseconds()
|
||||
select {
|
||||
case <-time.After(time.Duration(interval) * time.Millisecond):
|
||||
if !cli.sendKeepAlive(ctx) {
|
||||
isSuccess, shouldContinue := cli.sendKeepAlive(ctx)
|
||||
if !shouldContinue {
|
||||
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():
|
||||
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{
|
||||
Namespace: "w:p",
|
||||
Type: "get",
|
||||
|
@ -47,16 +63,16 @@ func (cli *Client) sendKeepAlive(ctx context.Context) bool {
|
|||
})
|
||||
if err != nil {
|
||||
cli.Log.Warnf("Failed to send keepalive: %v", err)
|
||||
return true
|
||||
return false, true
|
||||
}
|
||||
select {
|
||||
case <-respCh:
|
||||
// All good
|
||||
return true, true
|
||||
case <-time.After(KeepAliveResponseDeadline):
|
||||
// TODO disconnect websocket?
|
||||
cli.Log.Warnf("Keepalive timed out")
|
||||
return false, true
|
||||
case <-ctx.Done():
|
||||
return false
|
||||
return false, false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@ import (
|
|||
"crypto/cipher"
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"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.
|
||||
//
|
||||
// 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
|
||||
// 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 {
|
||||
ciphertext, iv, err := encryptMediaRetryReceipt(message.ID, mediaKey)
|
||||
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.
|
||||
// See Client.SendMediaRetryReceipt for more info on how to use this.
|
||||
func DecryptMediaRetryNotification(evt *events.MediaRetry, mediaKey []byte) (*waProto.MediaRetryNotification, error) {
|
||||
var notif waProto.MediaRetryNotification
|
||||
var plaintext []byte
|
||||
|
@ -126,7 +156,7 @@ func DecryptMediaRetryNotification(evt *events.MediaRetry, mediaKey []byte) (*wa
|
|||
func parseMediaRetryNotification(node *waBinary.Node) (*events.MediaRetry, error) {
|
||||
ag := node.AttrGetter()
|
||||
var evt events.MediaRetry
|
||||
evt.Timestamp = time.Unix(ag.Int64("t"), 0)
|
||||
evt.Timestamp = ag.UnixTime("t")
|
||||
evt.MessageID = types.MessageID(ag.String("id"))
|
||||
if !ag.OK() {
|
||||
return nil, ag.Error()
|
||||
|
|
|
@ -10,11 +10,11 @@ import (
|
|||
"bytes"
|
||||
"compress/zlib"
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"runtime/debug"
|
||||
"strconv"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
|
@ -48,67 +48,50 @@ func (cli *Client) handleEncryptedMessage(node *waBinary.Node) {
|
|||
}
|
||||
|
||||
func (cli *Client) parseMessageSource(node *waBinary.Node) (source types.MessageSource, err error) {
|
||||
from, ok := node.Attrs["from"].(types.JID)
|
||||
if !ok {
|
||||
err = fmt.Errorf("didn't find valid `from` attribute in message")
|
||||
} else if from.Server == types.GroupServer || from.Server == types.BroadcastServer {
|
||||
ag := node.AttrGetter()
|
||||
from := ag.JID("from")
|
||||
if from.Server == types.GroupServer || from.Server == types.BroadcastServer {
|
||||
source.IsGroup = true
|
||||
source.Chat = from
|
||||
sender, ok := node.Attrs["participant"].(types.JID)
|
||||
if !ok {
|
||||
err = fmt.Errorf("didn't find valid `participant` attribute in group message")
|
||||
} else {
|
||||
source.Sender = sender
|
||||
source.Sender = ag.JID("participant")
|
||||
if source.Sender.User == cli.Store.ID.User {
|
||||
source.IsFromMe = true
|
||||
}
|
||||
}
|
||||
if from.Server == types.BroadcastServer {
|
||||
recipient, ok := node.Attrs["recipient"].(types.JID)
|
||||
if ok {
|
||||
source.BroadcastListOwner = recipient
|
||||
}
|
||||
source.BroadcastListOwner = ag.OptionalJIDOrEmpty("recipient")
|
||||
}
|
||||
} else if from.User == cli.Store.ID.User {
|
||||
source.IsFromMe = true
|
||||
source.Sender = from
|
||||
recipient, ok := node.Attrs["recipient"].(types.JID)
|
||||
if !ok {
|
||||
source.Chat = from.ToNonAD()
|
||||
recipient := ag.OptionalJID("recipient")
|
||||
if recipient != nil {
|
||||
source.Chat = *recipient
|
||||
} else {
|
||||
source.Chat = recipient
|
||||
source.Chat = from.ToNonAD()
|
||||
}
|
||||
} else {
|
||||
source.Chat = from.ToNonAD()
|
||||
source.Sender = from
|
||||
}
|
||||
err = ag.Error()
|
||||
return
|
||||
}
|
||||
|
||||
func (cli *Client) parseMessageInfo(node *waBinary.Node) (*types.MessageInfo, error) {
|
||||
var info types.MessageInfo
|
||||
var err error
|
||||
var ok bool
|
||||
info.MessageSource, err = cli.parseMessageSource(node)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
info.ID, ok = node.Attrs["id"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("didn't find valid `id` attribute in message")
|
||||
ag := node.AttrGetter()
|
||||
info.ID = types.MessageID(ag.String("id"))
|
||||
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() {
|
||||
if child.Tag == "multicast" {
|
||||
|
@ -132,6 +115,7 @@ func (cli *Client) decryptMessages(info *types.MessageInfo, node *waBinary.Node)
|
|||
children := node.GetChildren()
|
||||
cli.Log.Debugf("Decrypting %d messages from %s", len(children), info.SourceString())
|
||||
handled := false
|
||||
containsDirectMsg := false
|
||||
for _, child := range children {
|
||||
if child.Tag != "enc" {
|
||||
continue
|
||||
|
@ -144,6 +128,7 @@ func (cli *Client) decryptMessages(info *types.MessageInfo, node *waBinary.Node)
|
|||
var err error
|
||||
if encType == "pkmsg" || encType == "msg" {
|
||||
decrypted, err = cli.decryptDM(&child, info.Sender, encType == "pkmsg")
|
||||
containsDirectMsg = true
|
||||
} else if info.IsGroup && encType == "skmsg" {
|
||||
decrypted, err = cli.decryptGroupMsg(&child, info.Sender, info.Chat)
|
||||
} else {
|
||||
|
@ -152,8 +137,9 @@ func (cli *Client) decryptMessages(info *types.MessageInfo, node *waBinary.Node)
|
|||
}
|
||||
if err != nil {
|
||||
cli.Log.Warnf("Error decrypting message from %s: %v", info.SourceString(), err)
|
||||
go cli.sendRetryReceipt(node, false)
|
||||
cli.dispatchEvent(&events.UndecryptableMessage{Info: *info, IsUnavailable: false})
|
||||
isUnavailable := encType == "skmsg" && !containsDirectMsg && errors.Is(err, signalerror.ErrNoSenderKeyForUser)
|
||||
go cli.sendRetryReceipt(node, isUnavailable)
|
||||
cli.dispatchEvent(&events.UndecryptableMessage{Info: *info, IsUnavailable: isUnavailable})
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -317,27 +303,35 @@ func (cli *Client) handleHistorySyncNotification(notif *waProto.HistorySyncNotif
|
|||
}
|
||||
|
||||
func (cli *Client) handleAppStateSyncKeyShare(keys *waProto.AppStateSyncKeyShare) {
|
||||
onlyResyncIfNotSynced := true
|
||||
|
||||
cli.Log.Debugf("Got %d new app state keys", len(keys.GetKeys()))
|
||||
cli.appStateKeyRequestsLock.RLock()
|
||||
for _, key := range keys.GetKeys() {
|
||||
marshaledFingerprint, err := proto.Marshal(key.GetKeyData().GetFingerprint())
|
||||
if err != nil {
|
||||
cli.Log.Errorf("Failed to marshal fingerprint of app state sync key %X", key.GetKeyId().GetKeyId())
|
||||
continue
|
||||
}
|
||||
_, isReRequest := cli.appStateKeyRequests[hex.EncodeToString(key.GetKeyId().GetKeyId())]
|
||||
if isReRequest {
|
||||
onlyResyncIfNotSynced = false
|
||||
}
|
||||
err = cli.Store.AppStateKeys.PutAppStateSyncKey(key.GetKeyId().GetKeyId(), store.AppStateSyncKey{
|
||||
Data: key.GetKeyData().GetKeyData(),
|
||||
Fingerprint: marshaledFingerprint,
|
||||
Timestamp: key.GetKeyData().GetTimestamp(),
|
||||
})
|
||||
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
|
||||
}
|
||||
cli.Log.Debugf("Received app state sync key %X", key.GetKeyId().GetKeyId())
|
||||
}
|
||||
cli.appStateKeyRequestsLock.RUnlock()
|
||||
|
||||
for _, name := range appstate.AllPatchNames {
|
||||
err := cli.FetchAppState(name, false, true)
|
||||
err := cli.FetchAppState(name, false, onlyResyncIfNotSynced)
|
||||
if err != nil {
|
||||
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) {
|
||||
evt := &events.Message{Info: *info, RawMessage: msg}
|
||||
|
||||
// First unwrap device sent messages
|
||||
func (cli *Client) processProtocolParts(info *types.MessageInfo, msg *waProto.Message) {
|
||||
// Hopefully sender key distribution messages and protocol messages can't be inside ephemeral messages
|
||||
if msg.GetDeviceSentMessage().GetMessage() != nil {
|
||||
msg = msg.GetDeviceSentMessage().GetMessage()
|
||||
evt.Info.DeviceSentMeta = &types.DeviceSentMeta{
|
||||
DestinationJID: msg.GetDeviceSentMessage().GetDestinationJid(),
|
||||
Phash: msg.GetDeviceSentMessage().GetPhash(),
|
||||
}
|
||||
}
|
||||
|
||||
if msg.GetSenderKeyDistributionMessage() != nil {
|
||||
if !info.IsGroup {
|
||||
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)
|
||||
}
|
||||
|
||||
// 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) {
|
||||
|
|
|
@ -8,7 +8,6 @@ package whatsmeow
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"go.mau.fi/whatsmeow/appstate"
|
||||
waBinary "go.mau.fi/whatsmeow/binary"
|
||||
|
@ -40,7 +39,7 @@ func (cli *Client) handleEncryptNotification(node *waBinary.Node) {
|
|||
if err != nil {
|
||||
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})
|
||||
} else {
|
||||
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) {
|
||||
ts := time.Unix(node.AttrGetter().Int64("t"), 0)
|
||||
ts := node.AttrGetter().UnixTime("t")
|
||||
for _, child := range node.GetChildren() {
|
||||
ag := child.AttrGetter()
|
||||
var evt events.Picture
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
cli.Store.Account = proto.Clone(&deviceIdentity).(*waProto.ADVSignedDeviceIdentity)
|
||||
|
||||
mainDeviceJID := jid
|
||||
mainDeviceJID.Device = 0
|
||||
mainDeviceIdentity := *(*[32]byte)(deviceIdentity.AccountSignatureKey)
|
||||
deviceIdentity.AccountSignatureKey = nil
|
||||
|
||||
cli.Store.Account = proto.Clone(&deviceIdentity).(*waProto.ADVSignedDeviceIdentity)
|
||||
|
||||
selfSignedDeviceIdentity, err := proto.Marshal(&deviceIdentity)
|
||||
if err != nil {
|
||||
cli.sendIQError(reqID, 500, "internal-error")
|
||||
|
|
|
@ -8,7 +8,6 @@ package whatsmeow
|
|||
|
||||
import (
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
waBinary "go.mau.fi/whatsmeow/binary"
|
||||
"go.mau.fi/whatsmeow/types"
|
||||
|
@ -48,7 +47,7 @@ func (cli *Client) handlePresence(node *waBinary.Node) {
|
|||
}
|
||||
lastSeen := ag.OptionalString("last")
|
||||
if lastSeen != "" && lastSeen != "deny" {
|
||||
evt.LastSeen = time.Unix(ag.Int64("last"), 0)
|
||||
evt.LastSeen = ag.UnixTime("last")
|
||||
}
|
||||
if !ag.OK() {
|
||||
cli.Log.Warnf("Error parsing presence event: %+v", ag.Errors)
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue