Merge branch 'develop'
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details

This commit is contained in:
Maxim Lebedev 2023-03-16 23:57:31 +06:00
commit fbda134b7d
Signed by: toby3d
GPG Key ID: 1F14E25B7C119FC5
349 changed files with 155714 additions and 113033 deletions

View File

@ -7,7 +7,7 @@ srcdir = .
GO ?= go GO ?= go
GOFLAGS ?= -buildvcs=true GOFLAGS ?= -buildvcs=true
EXECUTABLE ?= indieauth EXECUTABLE ?= auth
#### End of system configuration section. #### #### End of system configuration section. ####
@ -17,11 +17,9 @@ all: main.go
$(GO) build -v $(GOFLAGS) -o $(EXECUTABLE) $(GO) build -v $(GOFLAGS) -o $(EXECUTABLE)
clean: ## Delete all files in the current directory that are normally created by building the program clean: ## Delete all files in the current directory that are normally created by building the program
-rm $(srcdir)/internal/testing/httptest/{cert,key}.pem
$(GO) clean $(GO) clean
check: ## Perform self-tests check: ## Perform self-tests
$(GO) generate $(srcdir)/internal/testing/httptest/...
$(GO) test -v -cover -failfast -short -shuffle=on $(GOFLAGS) $(srcdir)/... $(GO) test -v -cover -failfast -short -shuffle=on $(GOFLAGS) $(srcdir)/...
.PHONY: help .PHONY: help

View File

@ -1,83 +1,49 @@
--- ---
kind: pipeline kind: "pipeline"
type: docker type: "docker"
name: default name: "default"
environment: environment:
CGO_ENABLED: 0 CGO_ENABLED: 0
steps: steps:
- name: test - name: "test"
image: golang:latest image: "golang:1.20"
volumes: volumes:
- name: modules - name: "modules"
path: /go/pkg/mod path: "/go/pkg/mod"
commands: commands:
- make check - "make check"
- name: build - name: "build"
image: golang:latest image: "golang:1.20"
volumes: volumes:
- name: modules - name: "modules"
path: /go/pkg/mod path: "/go/pkg/mod"
commands: commands:
- make - "make"
depends_on: depends_on:
- test - "test"
- name: stop-service - name: "delivery"
image: appleboy/drone-ssh image: "drillster/drone-rsync"
settings: settings:
host: hosts:
from_secret: SSH_HOST from_secret: "SSH_HOST_IP"
username: root
key: key:
from_secret: SSH_PRIVATE_KEY from_secret: "SSH_PRIVATE_KEY"
source: "./auth"
target: "/etc/auth/auth"
prescript:
- "systemctl stop auth"
script: script:
- "systemctl stop indieauth" - "systemctl start auth"
depends_on: depends_on:
- build - build
when: when:
branch: branch:
- master - master
- name: delivery
image: appleboy/drone-scp
settings:
host:
from_secret: SSH_HOST
username: root
password: ""
key:
from_secret: SSH_PRIVATE_KEY
target: "/root/indieauth"
source:
- "indieauth"
overwrite: true
# NOTE(toby3d): Just run a previous version of the instance if it failed to deliver the current one.
failure: ignore
depends_on:
- stop-service
when:
branch:
- master
- name: start-service
image: appleboy/drone-ssh
settings:
host:
from_secret: SSH_HOST
username: root
key:
from_secret: SSH_PRIVATE_KEY
script:
- "systemctl start indieauth"
depends_on:
- delivery
when:
branch:
- master
volumes: volumes:
- name: modules - name: modules
temp: {} temp: {}

View File

@ -1,5 +1,5 @@
# [auth.toby3d.me](https://auth.toby3d.me/) [![Build Status](https://drone.toby3d.me/api/badges/toby3d/auth/status.svg)](https://drone.toby3d.me/toby3d/auth) # auth [![Build Status](https://drone.toby3d.me/api/badges/toby3d/auth/status.svg)](https://drone.toby3d.me/toby3d/auth)
> [IndieAuth](https://indieauth.net/source/) personal instance. > Personal [IndieAuth](https://indieauth.net/source/) server.
An attempt to implement my own server to authenticate and authorize third-party applications through [IndieWeb](https://indieweb.org/) sites on [Go](https://go.dev/). Based on the latest versions of the protocol standards and related batteries like [TicketAuth](https://indieweb.org/IndieAuth_Ticket_Auth) and [RelMeAuth](https://microformats.org/wiki/RelMeAuth). An attempt to implement my own server to authenticate and authorize third-party applications through [IndieWeb](https://indieweb.org/) sites on [Go](https://go.dev/). Based on the latest versions of the protocol standards and related batteries like [TicketAuth](https://indieweb.org/IndieAuth_Ticket_Auth) and [RelMeAuth](https://microformats.org/wiki/RelMeAuth).

44
go.mod
View File

@ -4,33 +4,33 @@ go 1.19
require ( require (
github.com/DATA-DOG/go-sqlmock v1.5.0 github.com/DATA-DOG/go-sqlmock v1.5.0
github.com/brianvoe/gofakeit/v6 v6.20.1 github.com/brianvoe/gofakeit/v6 v6.20.2
github.com/caarlos0/env/v6 v6.10.1 github.com/caarlos0/env/v7 v7.1.0
github.com/go-logfmt/logfmt v0.5.1 github.com/go-logfmt/logfmt v0.6.0
github.com/goccy/go-json v0.10.0 github.com/goccy/go-json v0.10.1
github.com/google/go-cmp v0.5.9 github.com/google/go-cmp v0.5.9
github.com/jmoiron/sqlx v1.3.5 github.com/jmoiron/sqlx v1.3.5
github.com/lestrrat-go/jwx/v2 v2.0.8 github.com/lestrrat-go/jwx/v2 v2.0.8
github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80 github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80
github.com/valyala/fasttemplate v1.2.2 github.com/valyala/fasttemplate v1.2.2
github.com/valyala/quicktemplate v1.7.0 github.com/valyala/quicktemplate v1.7.0
go.etcd.io/bbolt v1.3.6 go.etcd.io/bbolt v1.3.7
golang.org/x/exp v0.0.0-20230113213754-f9f960f08ad4 golang.org/x/exp v0.0.0-20230315142452-642cacee5cc0
golang.org/x/text v0.6.0 golang.org/x/text v0.8.0
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2
inet.af/netaddr v0.0.0-20220811202034-502d2d690317 inet.af/netaddr v0.0.0-20220811202034-502d2d690317
modernc.org/sqlite v1.20.2 modernc.org/sqlite v1.21.0
source.toby3d.me/toby3d/form v0.3.0 source.toby3d.me/toby3d/form v0.3.0
willnorris.com/go/microformats v1.1.1 willnorris.com/go/microformats v1.2.0
) )
require ( require (
github.com/andybalholm/brotli v1.0.4 // indirect github.com/andybalholm/brotli v1.0.5 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect github.com/dustin/go-humanize v1.0.1 // indirect
github.com/google/uuid v1.3.0 // indirect github.com/google/uuid v1.3.0 // indirect
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
github.com/klauspost/compress v1.15.14 // indirect github.com/klauspost/compress v1.16.3 // indirect
github.com/lestrrat-go/blackmagic v1.0.1 // indirect github.com/lestrrat-go/blackmagic v1.0.1 // indirect
github.com/lestrrat-go/httpcc v1.0.1 // indirect github.com/lestrrat-go/httpcc v1.0.1 // indirect
github.com/lestrrat-go/httprc v1.0.4 // indirect github.com/lestrrat-go/httprc v1.0.4 // indirect
@ -38,20 +38,20 @@ require (
github.com/lestrrat-go/option v1.0.1 // indirect github.com/lestrrat-go/option v1.0.1 // indirect
github.com/lib/pq v1.10.6 // indirect github.com/lib/pq v1.10.6 // indirect
github.com/mattn/go-isatty v0.0.17 // indirect github.com/mattn/go-isatty v0.0.17 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20220927061507-ef77025ab5aa // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasthttp v1.44.0 // indirect github.com/valyala/fasthttp v1.45.0 // indirect
go4.org/intern v0.0.0-20220617035311-6925f38cc365 // indirect go4.org/intern v0.0.0-20230205224052-192e9f60865c // indirect
go4.org/unsafe/assume-no-moving-gc v0.0.0-20220617031537-928513b29760 // indirect go4.org/unsafe/assume-no-moving-gc v0.0.0-20230221090011-e4bae7ad2296 // indirect
golang.org/x/crypto v0.5.0 // indirect golang.org/x/crypto v0.7.0 // indirect
golang.org/x/mod v0.7.0 // indirect golang.org/x/mod v0.9.0 // indirect
golang.org/x/net v0.5.0 // indirect golang.org/x/net v0.8.0 // indirect
golang.org/x/sys v0.4.0 // indirect golang.org/x/sys v0.6.0 // indirect
golang.org/x/tools v0.5.0 // indirect golang.org/x/tools v0.7.0 // indirect
lukechampine.com/uint128 v1.2.0 // indirect lukechampine.com/uint128 v1.3.0 // indirect
modernc.org/cc/v3 v3.40.0 // indirect modernc.org/cc/v3 v3.40.0 // indirect
modernc.org/ccgo/v3 v3.16.13 // indirect modernc.org/ccgo/v3 v3.16.13 // indirect
modernc.org/libc v1.22.2 // indirect modernc.org/libc v1.22.3 // indirect
modernc.org/mathutil v1.5.0 // indirect modernc.org/mathutil v1.5.0 // indirect
modernc.org/memory v1.5.0 // indirect modernc.org/memory v1.5.0 // indirect
modernc.org/opt v0.1.3 // indirect modernc.org/opt v0.1.3 // indirect

107
go.sum
View File

@ -1,15 +1,13 @@
github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
github.com/PuerkitoBio/goquery v1.5.0/go.mod h1:qD2PgZ9lccMbQlc7eEOjaeRlFQON7xY8kdmcsrnKqMg=
github.com/andybalholm/brotli v1.0.2/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= github.com/andybalholm/brotli v1.0.2/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
github.com/andybalholm/brotli v1.0.3/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/andybalholm/brotli v1.0.3/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= github.com/brianvoe/gofakeit/v6 v6.20.2 h1:FLloufuC7NcbHqDzVQ42CG9AKryS1gAGCRt8nQRsW+Y=
github.com/brianvoe/gofakeit/v6 v6.20.1 h1:8ihJ60OvPnPJ2W6wZR7M+TTeaZ9bml0z6oy4gvyJ/ek= github.com/brianvoe/gofakeit/v6 v6.20.2/go.mod h1:Ow6qC71xtwm79anlwKRlWZW6zVq9D2XHE4QSSMP/rU8=
github.com/brianvoe/gofakeit/v6 v6.20.1/go.mod h1:Ow6qC71xtwm79anlwKRlWZW6zVq9D2XHE4QSSMP/rU8= github.com/caarlos0/env/v7 v7.1.0 h1:9lzTF5amyQeWHZzuZeKlCb5FWSUxpG1js43mhbY8ozg=
github.com/caarlos0/env/v6 v6.10.1 h1:t1mPSxNpei6M5yAeu1qtRdPAK29Nbcf/n3G7x+b3/II= github.com/caarlos0/env/v7 v7.1.0/go.mod h1:LPPWniDUq4JaO6Q41vtlyikhMknqymCLBw0eX4dcH1E=
github.com/caarlos0/env/v6 v6.10.1/go.mod h1:hvp/ryKXKipEkcuYjs9mI4bBCg+UI0Yhgm5Zu0ddvwc=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@ -19,15 +17,14 @@ github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2U
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/dvyukov/go-fuzz v0.0.0-20210103155950-6a8e9d1f2415/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw= github.com/dvyukov/go-fuzz v0.0.0-20210103155950-6a8e9d1f2415/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw=
github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4=
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/goccy/go-json v0.10.0 h1:mXKd9Qw4NuzShiRlOXKews24ufknHO7gx30lsDyokKA= github.com/goccy/go-json v0.10.1 h1:lEs5Ob+oOG/Ze199njvzHbhn6p9T+h64F5hRj69iTTo=
github.com/goccy/go-json v0.10.0/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/goccy/go-json v0.10.1/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ= github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ=
@ -39,11 +36,9 @@ github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNU
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
github.com/klauspost/compress v1.13.5/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.13.5/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= github.com/klauspost/compress v1.16.3 h1:XuJt9zzcnaz6a16/OU53ZjWp/v7/42WcR5t2a0PcNQY=
github.com/klauspost/compress v1.15.14 h1:i7WCKDToww0wA+9qrUZ1xOjp218vfFo3nTU6UHp+gOc= github.com/klauspost/compress v1.16.3/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
github.com/klauspost/compress v1.15.14/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/lestrrat-go/blackmagic v1.0.1 h1:lS5Zts+5HIC/8og6cGHb0uCcNCa3OUt1ygh3Qz2Fe80= github.com/lestrrat-go/blackmagic v1.0.1 h1:lS5Zts+5HIC/8og6cGHb0uCcNCa3OUt1ygh3Qz2Fe80=
github.com/lestrrat-go/blackmagic v1.0.1/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU= github.com/lestrrat-go/blackmagic v1.0.1/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU=
github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE= github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE=
@ -63,12 +58,12 @@ github.com/lib/pq v1.10.6/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI= github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/remyoudompheng/bigfft v0.0.0-20220927061507-ef77025ab5aa h1:tEkEyxYeZ43TR55QU/hsIt9aRGBxbgGuz9CGykjvogY= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20220927061507-ef77025ab5aa/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
@ -82,79 +77,71 @@ github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80/go.mod h1:iFy
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.30.0/go.mod h1:2rsYD01CKFrjjsvFxx75KlEUNpWNBY9JWD3K/7o2Cus= github.com/valyala/fasthttp v1.30.0/go.mod h1:2rsYD01CKFrjjsvFxx75KlEUNpWNBY9JWD3K/7o2Cus=
github.com/valyala/fasthttp v1.44.0 h1:R+gLUhldIsfg1HokMuQjdQ5bh9nuXHPIfvkYUu9eR5Q= github.com/valyala/fasthttp v1.45.0 h1:zPkkzpIn8tdHZUrVa6PzYd0i5verqiPSkgTd3bSUcpA=
github.com/valyala/fasthttp v1.44.0/go.mod h1:f6VbjjoI3z1NDOZOv17o6RvtRSWxC77seBFc2uWtgiY= github.com/valyala/fasthttp v1.45.0/go.mod h1:k2zXd82h/7UZc3VOdJ2WaUqt1uZ/XpXAfE9i+HBC3lA=
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
github.com/valyala/quicktemplate v1.7.0 h1:LUPTJmlVcb46OOUY3IeD9DojFpAVbsG+5WFTcjMJzCM= github.com/valyala/quicktemplate v1.7.0 h1:LUPTJmlVcb46OOUY3IeD9DojFpAVbsG+5WFTcjMJzCM=
github.com/valyala/quicktemplate v1.7.0/go.mod h1:sqKJnoaOF88V07vkO+9FL8fb9uZg/VPSJnLYn+LmLk8= github.com/valyala/quicktemplate v1.7.0/go.mod h1:sqKJnoaOF88V07vkO+9FL8fb9uZg/VPSJnLYn+LmLk8=
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ=
go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw=
go4.org/intern v0.0.0-20211027215823-ae77deb06f29/go.mod h1:cS2ma+47FKrLPdXFpr7CuxiTW3eyJbWew4qx0qtQWDA= go4.org/intern v0.0.0-20211027215823-ae77deb06f29/go.mod h1:cS2ma+47FKrLPdXFpr7CuxiTW3eyJbWew4qx0qtQWDA=
go4.org/intern v0.0.0-20220617035311-6925f38cc365 h1:t9hFvR102YlOqU0fQn1wgwhNvSbHGBbbJxX9JKfU3l0= go4.org/intern v0.0.0-20230205224052-192e9f60865c h1:b8WZ7Ja8nKegYxfwDLLwT00ZKv4lXAQrw8LYPK+cHSI=
go4.org/intern v0.0.0-20220617035311-6925f38cc365/go.mod h1:WXRv3p7T6gzt0CcJm43AAKdKVZmcQbwwC7EwquU5BZU= go4.org/intern v0.0.0-20230205224052-192e9f60865c/go.mod h1:RJ0SVrOMpxLhgb5noIV+09zI1RsRlMsbUcSxpWHqbrE=
go4.org/unsafe/assume-no-moving-gc v0.0.0-20211027215541-db492cf91b37/go.mod h1:FftLjUGFEDu5k8lt0ddY+HcrH/qU/0qk+H8j9/nTl3E= go4.org/unsafe/assume-no-moving-gc v0.0.0-20211027215541-db492cf91b37/go.mod h1:FftLjUGFEDu5k8lt0ddY+HcrH/qU/0qk+H8j9/nTl3E=
go4.org/unsafe/assume-no-moving-gc v0.0.0-20220617031537-928513b29760 h1:FyBZqvoA/jbNzuAWLQE2kG820zMAkcilx6BMjGbL/E4=
go4.org/unsafe/assume-no-moving-gc v0.0.0-20220617031537-928513b29760/go.mod h1:FftLjUGFEDu5k8lt0ddY+HcrH/qU/0qk+H8j9/nTl3E= go4.org/unsafe/assume-no-moving-gc v0.0.0-20220617031537-928513b29760/go.mod h1:FftLjUGFEDu5k8lt0ddY+HcrH/qU/0qk+H8j9/nTl3E=
go4.org/unsafe/assume-no-moving-gc v0.0.0-20230204201903-c31fa085b70e/go.mod h1:FftLjUGFEDu5k8lt0ddY+HcrH/qU/0qk+H8j9/nTl3E=
go4.org/unsafe/assume-no-moving-gc v0.0.0-20230221090011-e4bae7ad2296 h1:QJ/xcIANMLApehfgPCHnfK1hZiaMmbaTVmPv7DAoTbo=
go4.org/unsafe/assume-no-moving-gc v0.0.0-20230221090011-e4bae7ad2296/go.mod h1:FftLjUGFEDu5k8lt0ddY+HcrH/qU/0qk+H8j9/nTl3E=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220427172511-eb4f295cb31f/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220427172511-eb4f295cb31f/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE= golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/exp v0.0.0-20230113213754-f9f960f08ad4 h1:CNkDRtCj8otM5CFz5jYvbr8ioXX8flVsLfDWEj0M5kk= golang.org/x/exp v0.0.0-20230315142452-642cacee5cc0 h1:pVgRXcIictcr+lBQIFeiwuwtDIs4eL21OuM9nyAADmo=
golang.org/x/exp v0.0.0-20230113213754-f9f960f08ad4/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/exp v0.0.0-20230315142452-642cacee5cc0/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA= golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs=
golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220906165146-f3363e06e74c/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.5.0 h1:+bSpV5HIeWkuvgaMfI3UmKRThoTA5ODJTUd8T17NO+4= golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4=
golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k= golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk=
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
@ -164,31 +151,31 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
inet.af/netaddr v0.0.0-20220811202034-502d2d690317 h1:U2fwK6P2EqmopP/hFLTOAjWTki0qgd4GMJn5X8wOleU= inet.af/netaddr v0.0.0-20220811202034-502d2d690317 h1:U2fwK6P2EqmopP/hFLTOAjWTki0qgd4GMJn5X8wOleU=
inet.af/netaddr v0.0.0-20220811202034-502d2d690317/go.mod h1:OIezDfdzOgFhuw4HuWapWq2e9l0H9tK4F1j+ETRtF3k= inet.af/netaddr v0.0.0-20220811202034-502d2d690317/go.mod h1:OIezDfdzOgFhuw4HuWapWq2e9l0H9tK4F1j+ETRtF3k=
lukechampine.com/uint128 v1.2.0 h1:mBi/5l91vocEN8otkC5bDLhi2KdCticRiwbdB0O+rjI= lukechampine.com/uint128 v1.3.0 h1:cDdUVfRwDUDovz610ABgFD17nXD4/uDgVHl2sC3+sbo=
lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= lukechampine.com/uint128 v1.3.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
modernc.org/cc/v3 v3.40.0 h1:P3g79IUS/93SYhtoeaHW+kRCIrYaxJ27MFPv+7kaTOw= modernc.org/cc/v3 v3.40.0 h1:P3g79IUS/93SYhtoeaHW+kRCIrYaxJ27MFPv+7kaTOw=
modernc.org/cc/v3 v3.40.0/go.mod h1:/bTg4dnWkSXowUO6ssQKnOV0yMVxDYNIsIrzqTFDGH0= modernc.org/cc/v3 v3.40.0/go.mod h1:/bTg4dnWkSXowUO6ssQKnOV0yMVxDYNIsIrzqTFDGH0=
modernc.org/ccgo/v3 v3.16.13 h1:Mkgdzl46i5F/CNR/Kj80Ri59hC8TKAhZrYSaqvkwzUw= modernc.org/ccgo/v3 v3.16.13 h1:Mkgdzl46i5F/CNR/Kj80Ri59hC8TKAhZrYSaqvkwzUw=
modernc.org/ccgo/v3 v3.16.13/go.mod h1:2Quk+5YgpImhPjv2Qsob1DnZ/4som1lJTodubIcoUkY= modernc.org/ccgo/v3 v3.16.13/go.mod h1:2Quk+5YgpImhPjv2Qsob1DnZ/4som1lJTodubIcoUkY=
modernc.org/ccorpus v1.11.6 h1:J16RXiiqiCgua6+ZvQot4yUuUy8zxgqbqEEUuGPlISk= modernc.org/ccorpus v1.11.6 h1:J16RXiiqiCgua6+ZvQot4yUuUy8zxgqbqEEUuGPlISk=
modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM= modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM=
modernc.org/libc v1.22.2 h1:4U7v51GyhlWqQmwCHj28Rdq2Yzwk55ovjFrdPjs8Hb0= modernc.org/libc v1.22.3 h1:D/g6O5ftAfavceqlLOFwaZuA5KYafKwmr30A6iSqoyY=
modernc.org/libc v1.22.2/go.mod h1:uvQavJ1pZ0hIoC/jfqNoMLURIMhKzINIWypNM17puug= modernc.org/libc v1.22.3/go.mod h1:MQrloYP209xa2zHome2a8HLiLm6k0UT8CoHpV74tOFw=
modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ= modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ=
modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
modernc.org/memory v1.5.0 h1:N+/8c5rE6EqugZwHii4IFsaJ7MUhoWX07J5tC/iI5Ds= modernc.org/memory v1.5.0 h1:N+/8c5rE6EqugZwHii4IFsaJ7MUhoWX07J5tC/iI5Ds=
modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4=
modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
modernc.org/sqlite v1.20.2 h1:9AaVzJH1Yf0u9iOZRjjuvqxLoGqybqVFbAUC5rvi9u8= modernc.org/sqlite v1.21.0 h1:4aP4MdUf15i3R3M2mx6Q90WHKz3nZLoz96zlB6tNdow=
modernc.org/sqlite v1.20.2/go.mod h1:zKcGyrICaxNTMEHSr1HQ2GUraP0j+845GYw37+EyT6A= modernc.org/sqlite v1.21.0/go.mod h1:XwQ0wZPIh1iKb5mkvCJ3szzbhk+tykC8ZWqTRTgYRwI=
modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY= modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY=
modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw= modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw=
modernc.org/tcl v1.15.0 h1:oY+JeD11qVVSgVvodMJsu7Edf8tr5E/7tuhF5cNYz34= modernc.org/tcl v1.15.1 h1:mOQwiEK4p7HruMZcwKTZPw/aqtGM4aY00uzWhlKKYws=
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
modernc.org/z v1.7.0 h1:xkDw/KepgEjeizO2sNco+hqYkU12taxQFqPEmgm1GWE= modernc.org/z v1.7.0 h1:xkDw/KepgEjeizO2sNco+hqYkU12taxQFqPEmgm1GWE=
source.toby3d.me/toby3d/form v0.3.0 h1:kI8apdFeVr+koqTTGVoIRiR5NMqjrhCJlajYlu+1bVw= source.toby3d.me/toby3d/form v0.3.0 h1:kI8apdFeVr+koqTTGVoIRiR5NMqjrhCJlajYlu+1bVw=
source.toby3d.me/toby3d/form v0.3.0/go.mod h1:drlHMC+j/gb5zsttCSwx8qcYsbaRW+wFfE8bK6y+oeY= source.toby3d.me/toby3d/form v0.3.0/go.mod h1:drlHMC+j/gb5zsttCSwx8qcYsbaRW+wFfE8bK6y+oeY=
willnorris.com/go/microformats v1.1.1 h1:h5tk2luq6KBIRcwMGdksxdeea4GGuWrRFie5460OAbo= willnorris.com/go/microformats v1.2.0 h1:73pzJCLJM69kYE5qsLI9OOC/7sImNVOzya9EQ0+1wmM=
willnorris.com/go/microformats v1.1.1/go.mod h1:kvVnWrkkEscVAIITCEoiTX66Hcyg59C7q0E49mb9TJ0= willnorris.com/go/microformats v1.2.0/go.mod h1:RrlwCSvib4qz+JICKiN7rON4phzQ3HAT7j6s4O2cZj4=

View File

@ -48,7 +48,7 @@ func NewHandler(opts NewHandlerOptions) *Handler {
func (h *Handler) Handler() http.Handler { func (h *Handler) Handler() http.Handler {
chain := middleware.Chain{ chain := middleware.Chain{
middleware.CSRFWithConfig(middleware.CSRFConfig{ middleware.CSRFWithConfig(middleware.CSRFConfig{
Skipper: func(w http.ResponseWriter, r *http.Request) bool { Skipper: func(_ http.ResponseWriter, r *http.Request) bool {
head, _ := urlutil.ShiftPath(r.URL.Path) head, _ := urlutil.ShiftPath(r.URL.Path)
return head == "" return head == ""
@ -65,7 +65,7 @@ func (h *Handler) Handler() http.Handler {
CookieHTTPOnly: true, CookieHTTPOnly: true,
}), }),
middleware.BasicAuthWithConfig(middleware.BasicAuthConfig{ middleware.BasicAuthWithConfig(middleware.BasicAuthConfig{
Skipper: func(w http.ResponseWriter, r *http.Request) bool { Skipper: func(_ http.ResponseWriter, r *http.Request) bool {
head, _ := urlutil.ShiftPath(r.URL.Path) head, _ := urlutil.ShiftPath(r.URL.Path)
return r.Method != http.MethodPost || return r.Method != http.MethodPost ||
@ -154,11 +154,8 @@ func (h *Handler) handleAuthorize(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
web.WriteTemplate(w, &web.ErrorPage{ web.WriteTemplate(w, &web.ErrorPage{
BaseOf: baseOf, BaseOf: baseOf,
Error: domain.NewError( Error: domain.NewError(domain.ErrorCodeInvalidClient, "requested redirect_uri is not"+
domain.ErrorCodeInvalidClient, " registered on client_id side", ""),
"requested redirect_uri is not registered on client_id side",
"",
),
}) })
return return

View File

@ -11,10 +11,6 @@ import (
type ( type (
AuthAuthorizationRequest struct { AuthAuthorizationRequest struct {
// Indicates to the authorization server that an authorization
// code should be returned as the response.
ResponseType domain.ResponseType `form:"response_type"` // code
// The client URL. // The client URL.
ClientID domain.ClientID `form:"client_id"` ClientID domain.ClientID `form:"client_id"`
@ -28,12 +24,9 @@ type (
// The hashing method used to calculate the code challenge. // The hashing method used to calculate the code challenge.
CodeChallengeMethod *domain.CodeChallengeMethod `form:"code_challenge_method,omitempty"` CodeChallengeMethod *domain.CodeChallengeMethod `form:"code_challenge_method,omitempty"`
// A space-separated list of scopes the client is requesting, // Indicates to the authorization server that an authorization
// e.g. "profile", or "profile create". If the client omits this // code should be returned as the response.
// value, the authorization server MUST NOT issue an access ResponseType domain.ResponseType `form:"response_type"` // code
// token for this authorization code. Only the user's profile
// URL may be returned without any scope requested.
Scope domain.Scopes `form:"scope,omitempty"`
// A parameter set by the client which will be included when the // A parameter set by the client which will be included when the
// user is redirected back to the client. This is used to // user is redirected back to the client. This is used to
@ -43,19 +36,26 @@ type (
// The code challenge as previously described. // The code challenge as previously described.
CodeChallenge string `form:"code_challenge,omitempty"` CodeChallenge string `form:"code_challenge,omitempty"`
// A space-separated list of scopes the client is requesting,
// e.g. "profile", or "profile create". If the client omits this
// value, the authorization server MUST NOT issue an access
// token for this authorization code. Only the user's profile
// URL may be returned without any scope requested.
Scope domain.Scopes `form:"scope,omitempty"`
} }
AuthVerifyRequest struct { AuthVerifyRequest struct {
ClientID domain.ClientID `form:"client_id"` ClientID domain.ClientID `form:"client_id"`
Me domain.Me `form:"me"` Me domain.Me `form:"me"`
RedirectURI domain.URL `form:"redirect_uri"` RedirectURI domain.URL `form:"redirect_uri"`
ResponseType domain.ResponseType `form:"response_type"`
CodeChallengeMethod *domain.CodeChallengeMethod `form:"code_challenge_method,omitempty"` CodeChallengeMethod *domain.CodeChallengeMethod `form:"code_challenge_method,omitempty"`
Scope domain.Scopes `form:"scope[],omitempty"` ResponseType domain.ResponseType `form:"response_type"`
Authorize string `form:"authorize"` Authorize string `form:"authorize"`
CodeChallenge string `form:"code_challenge,omitempty"` CodeChallenge string `form:"code_challenge,omitempty"`
State string `form:"state"` State string `form:"state"`
Provider string `form:"provider"` Provider string `form:"provider"`
Scope domain.Scopes `form:"scope[],omitempty"`
} }
AuthExchangeRequest struct { AuthExchangeRequest struct {

View File

@ -1,7 +1,5 @@
package common package common
const charsetUTF8 = "charset=UTF-8"
const ( const (
MIMEApplicationForm string = "application/x-www-form-urlencoded" MIMEApplicationForm string = "application/x-www-form-urlencoded"
MIMEApplicationJSON string = "application/json" MIMEApplicationJSON string = "application/json"
@ -10,6 +8,8 @@ const (
MIMETextHTMLCharsetUTF8 string = MIMETextHTML + "; " + charsetUTF8 MIMETextHTMLCharsetUTF8 string = MIMETextHTML + "; " + charsetUTF8
MIMETextPlain string = "text/plain" MIMETextPlain string = "text/plain"
MIMETextPlainCharsetUTF8 string = MIMETextPlain + "; " + charsetUTF8 MIMETextPlainCharsetUTF8 string = MIMETextPlain + "; " + charsetUTF8
charsetUTF8 = "charset=UTF-8"
) )
const ( const (

View File

@ -12,26 +12,26 @@ import (
// NOTE(toby3d): Encapsulate enums in structs for extra compile-time safety: // NOTE(toby3d): Encapsulate enums in structs for extra compile-time safety:
// https://threedots.tech/post/safer-enums-in-go/#struct-based-enums // https://threedots.tech/post/safer-enums-in-go/#struct-based-enums
type Action struct { type Action struct {
uid string action string
} }
//nolint:gochecknoglobals // structs cannot be constants //nolint:gochecknoglobals // structs cannot be constants
var ( var (
ActionUnd = Action{uid: ""} // "und" ActionUnd = Action{action: ""} // "und"
// ActionRevoke represent action for revoke token. // ActionRevoke represent action for revoke token.
ActionRevoke = Action{uid: "revoke"} // "revoke" ActionRevoke = Action{action: "revoke"} // "revoke"
// ActionTicket represent action for TicketAuth extension. // ActionTicket represent action for TicketAuth extension.
ActionTicket = Action{uid: "ticket"} // "ticket" ActionTicket = Action{action: "ticket"} // "ticket"
) )
var ErrActionSyntax error = NewError(ErrorCodeInvalidRequest, "unknown action method", "") var ErrActionSyntax error = NewError(ErrorCodeInvalidRequest, "unknown action method", "")
//nolint:gochecknoglobals //nolint:gochecknoglobals
var uidsActions = map[string]Action{ var uidsActions = map[string]Action{
ActionRevoke.uid: ActionRevoke, ActionRevoke.action: ActionRevoke,
ActionTicket.uid: ActionTicket, ActionTicket.action: ActionTicket,
} }
// ParseAction parse string identifier of action into struct enum. // ParseAction parse string identifier of action into struct enum.
@ -74,8 +74,8 @@ func (a *Action) UnmarshalJSON(v []byte) error {
// String returns string representation of action. // String returns string representation of action.
func (a Action) String() string { func (a Action) String() string {
if a.uid != "" { if a.action != "" {
return a.uid return a.action
} }
return common.Und return common.Und

View File

@ -1,6 +1,7 @@
package domain package domain
//nolint:gosec // support old clients //nolint:gosec // support old clients
import ( import (
"crypto/md5" "crypto/md5"
"crypto/sha1" "crypto/sha1"
@ -20,17 +21,17 @@ import (
// NOTE(toby3d): Encapsulate enums in structs for extra compile-time safety: // NOTE(toby3d): Encapsulate enums in structs for extra compile-time safety:
// https://threedots.tech/post/safer-enums-in-go/#struct-based-enums // https://threedots.tech/post/safer-enums-in-go/#struct-based-enums
type CodeChallengeMethod struct { type CodeChallengeMethod struct {
uid string codeChallengeMethod string
} }
//nolint:gochecknoglobals // structs cannot be constants //nolint:gochecknoglobals // structs cannot be constants
var ( var (
CodeChallengeMethodUnd = CodeChallengeMethod{uid: ""} // "und" CodeChallengeMethodUnd = CodeChallengeMethod{codeChallengeMethod: ""} // "und"
CodeChallengeMethodPLAIN = CodeChallengeMethod{uid: "plain"} // "PLAIN" CodeChallengeMethodPLAIN = CodeChallengeMethod{codeChallengeMethod: "plain"} // "PLAIN"
CodeChallengeMethodMD5 = CodeChallengeMethod{uid: "md5"} // "MD5" CodeChallengeMethodMD5 = CodeChallengeMethod{codeChallengeMethod: "md5"} // "MD5"
CodeChallengeMethodS1 = CodeChallengeMethod{uid: "s1"} // "S1" CodeChallengeMethodS1 = CodeChallengeMethod{codeChallengeMethod: "s1"} // "S1"
CodeChallengeMethodS256 = CodeChallengeMethod{uid: "s256"} // "S256" CodeChallengeMethodS256 = CodeChallengeMethod{codeChallengeMethod: "s256"} // "S256"
CodeChallengeMethodS512 = CodeChallengeMethod{uid: "s512"} // "S512" CodeChallengeMethodS512 = CodeChallengeMethod{codeChallengeMethod: "s512"} // "S512"
) )
var ErrCodeChallengeMethodUnknown error = NewError( var ErrCodeChallengeMethodUnknown error = NewError(
@ -41,11 +42,11 @@ var ErrCodeChallengeMethodUnknown error = NewError(
//nolint:gochecknoglobals // maps cannot be constants //nolint:gochecknoglobals // maps cannot be constants
var uidsMethods = map[string]CodeChallengeMethod{ var uidsMethods = map[string]CodeChallengeMethod{
CodeChallengeMethodMD5.uid: CodeChallengeMethodMD5, CodeChallengeMethodMD5.codeChallengeMethod: CodeChallengeMethodMD5,
CodeChallengeMethodPLAIN.uid: CodeChallengeMethodPLAIN, CodeChallengeMethodPLAIN.codeChallengeMethod: CodeChallengeMethodPLAIN,
CodeChallengeMethodS1.uid: CodeChallengeMethodS1, CodeChallengeMethodS1.codeChallengeMethod: CodeChallengeMethodS1,
CodeChallengeMethodS256.uid: CodeChallengeMethodS256, CodeChallengeMethodS256.codeChallengeMethod: CodeChallengeMethodS256,
CodeChallengeMethodS512.uid: CodeChallengeMethodS512, CodeChallengeMethodS512.codeChallengeMethod: CodeChallengeMethodS512,
} }
// ParseCodeChallengeMethod parse string identifier of code challenge method // ParseCodeChallengeMethod parse string identifier of code challenge method
@ -85,13 +86,13 @@ func (ccm *CodeChallengeMethod) UnmarshalJSON(v []byte) error {
} }
func (ccm CodeChallengeMethod) MarshalJSON() ([]byte, error) { func (ccm CodeChallengeMethod) MarshalJSON() ([]byte, error) {
return []byte(strconv.Quote(ccm.uid)), nil return []byte(strconv.Quote(ccm.codeChallengeMethod)), nil
} }
// String returns string representation of code challenge method. // String returns string representation of code challenge method.
func (ccm CodeChallengeMethod) String() string { func (ccm CodeChallengeMethod) String() string {
if ccm.uid != "" { if ccm.codeChallengeMethod != "" {
return strings.ToUpper(ccm.uid) return strings.ToUpper(ccm.codeChallengeMethod)
} }
return common.Und return common.Und

View File

@ -1,6 +1,7 @@
package domain_test package domain_test
//nolint:gosec // support old clients //nolint:gosec // support old clients
import ( import (
"crypto/md5" "crypto/md5"
"crypto/sha1" "crypto/sha1"

View File

@ -11,14 +11,14 @@ import (
type ( type (
Config struct { Config struct {
Code ConfigCode `envPrefix:"CODE_"`
Database ConfigDatabase `envPrefix:"DATABASE_"`
IndieAuth ConfigIndieAuth `envPrefix:"INDIEAUTH_"`
JWT ConfigJWT `envPrefix:"JWT_"`
Server ConfigServer `envPrefix:"SERVER_"` Server ConfigServer `envPrefix:"SERVER_"`
TicketAuth ConfigTicketAuth `envPrefix:"TICKETAUTH_"` Database ConfigDatabase `envPrefix:"DATABASE_"`
Name string `env:"NAME" envDefault:"IndieAuth"` Name string `env:"NAME" envDefault:"IndieAuth"`
RunMode string `env:"RUN_MODE" envDefault:"dev"` RunMode string `env:"RUN_MODE" envDefault:"dev"`
IndieAuth ConfigIndieAuth `envPrefix:"INDIEAUTH_"`
JWT ConfigJWT `envPrefix:"JWT_"`
Code ConfigCode `envPrefix:"CODE_"`
TicketAuth ConfigTicketAuth `envPrefix:"TICKETAUTH_"`
} }
ConfigServer struct { ConfigServer struct {
@ -45,10 +45,10 @@ type (
} }
ConfigJWT struct { ConfigJWT struct {
Expiry time.Duration `env:"EXPIRY" envDefault:"1h"` // 1h Algorithm string `env:"ALGORITHM" envDefault:"HS256"`
Algorithm string `env:"ALGORITHM" envDefault:"HS256"` // HS256
Secret string `env:"SECRET"` Secret string `env:"SECRET"`
NonceLength uint8 `env:"NONCE_LENGTH" envDefault:"22"` // 22 Expiry time.Duration `env:"EXPIRY" envDefault:"1h"`
NonceLength uint8 `env:"NONCE_LENGTH" envDefault:"22"`
} }
ConfigIndieAuth struct { ConfigIndieAuth struct {

View File

@ -15,6 +15,8 @@ type (
// Error describes the format of a typical IndieAuth error. // Error describes the format of a typical IndieAuth error.
//nolint:tagliatelle // RFC 6749 section 5.2 //nolint:tagliatelle // RFC 6749 section 5.2
Error struct { Error struct {
frame xerrors.Frame `json:"-"`
// A single error code. // A single error code.
Code ErrorCode `json:"error"` Code ErrorCode `json:"error"`
@ -31,25 +33,23 @@ type (
// authorization request. The exact value received from the // authorization request. The exact value received from the
// client. // client.
State string `json:"-"` State string `json:"-"`
frame xerrors.Frame `json:"-"`
} }
// ErrorCode represent error code described in RFC 6749. // ErrorCode represent error code described in RFC 6749.
ErrorCode struct { ErrorCode struct {
uid string errorCode string
} }
) )
var ( var (
// ErrorCodeUnd describes an unrecognized error code. // ErrorCodeUnd describes an unrecognized error code.
ErrorCodeUnd = ErrorCode{uid: ""} // "und" ErrorCodeUnd = ErrorCode{errorCode: ""} // "und"
// ErrorCodeAccessDenied describes the access_denied error code. // ErrorCodeAccessDenied describes the access_denied error code.
// //
// RFC 6749 section 4.1.2.1: The resource owner or authorization server // RFC 6749 section 4.1.2.1: The resource owner or authorization server
// denied the request. // denied the request.
ErrorCodeAccessDenied = ErrorCode{uid: "access_denied"} // "access_denied" ErrorCodeAccessDenied = ErrorCode{errorCode: "access_denied"} // "access_denied"
// ErrorCodeInvalidClient describes the invalid_client error code. // ErrorCodeInvalidClient describes the invalid_client error code.
// //
@ -65,7 +65,7 @@ var (
// HTTP 401 (Unauthorized) status code and include the // HTTP 401 (Unauthorized) status code and include the
// "WWW-Authenticate" response header field matching the authentication // "WWW-Authenticate" response header field matching the authentication
// scheme used by the client. // scheme used by the client.
ErrorCodeInvalidClient = ErrorCode{uid: "invalid_client"} // "invalid_client" ErrorCodeInvalidClient = ErrorCode{errorCode: "invalid_client"} // "invalid_client"
// ErrorCodeInvalidGrant describes the invalid_grant error code. // ErrorCodeInvalidGrant describes the invalid_grant error code.
// //
@ -73,7 +73,7 @@ var (
// authorization code, resource owner credentials) or refresh token is // authorization code, resource owner credentials) or refresh token is
// invalid, expired, revoked, does not match the redirection URI used in // invalid, expired, revoked, does not match the redirection URI used in
// the authorization request, or was issued to another client. // the authorization request, or was issued to another client.
ErrorCodeInvalidGrant = ErrorCode{uid: "invalid_grant"} // "invalid_grant" ErrorCodeInvalidGrant = ErrorCode{errorCode: "invalid_grant"} // "invalid_grant"
// ErrorCodeInvalidRequest describes the invalid_request error code. // ErrorCodeInvalidRequest describes the invalid_request error code.
// //
@ -88,7 +88,7 @@ var (
// repeats a parameter, includes multiple credentials, utilizes more // repeats a parameter, includes multiple credentials, utilizes more
// than one mechanism for authenticating the client, or is otherwise // than one mechanism for authenticating the client, or is otherwise
// malformed. // malformed.
ErrorCodeInvalidRequest = ErrorCode{uid: "invalid_request"} // "invalid_request" ErrorCodeInvalidRequest = ErrorCode{errorCode: "invalid_request"} // "invalid_request"
// ErrorCodeInvalidScope describes the invalid_scope error code. // ErrorCodeInvalidScope describes the invalid_scope error code.
// //
@ -97,7 +97,7 @@ var (
// //
// RFC 6749 section 5.2: The requested scope is invalid, unknown, // RFC 6749 section 5.2: The requested scope is invalid, unknown,
// malformed, or exceeds the scope granted by the resource owner. // malformed, or exceeds the scope granted by the resource owner.
ErrorCodeInvalidScope = ErrorCode{uid: "invalid_scope"} // "invalid_scope" ErrorCodeInvalidScope = ErrorCode{errorCode: "invalid_scope"} // "invalid_scope"
// ErrorCodeServerError describes the server_error error code. // ErrorCodeServerError describes the server_error error code.
// //
@ -105,7 +105,7 @@ var (
// unexpected condition that prevented it from fulfilling the request. // unexpected condition that prevented it from fulfilling the request.
// (This error code is needed because a 500 Internal Server Error HTTP // (This error code is needed because a 500 Internal Server Error HTTP
// status code cannot be returned to the client via an HTTP redirect.) // status code cannot be returned to the client via an HTTP redirect.)
ErrorCodeServerError = ErrorCode{uid: "server_error"} // "server_error" ErrorCodeServerError = ErrorCode{errorCode: "server_error"} // "server_error"
// ErrorCodeTemporarilyUnavailable describes the temporarily_unavailable error code. // ErrorCodeTemporarilyUnavailable describes the temporarily_unavailable error code.
// //
@ -114,7 +114,7 @@ var (
// maintenance of the server. (This error code is needed because a 503 // maintenance of the server. (This error code is needed because a 503
// Service Unavailable HTTP status code cannot be returned to the client // Service Unavailable HTTP status code cannot be returned to the client
// via an HTTP redirect.) // via an HTTP redirect.)
ErrorCodeTemporarilyUnavailable = ErrorCode{uid: "temporarily_unavailable"} // "temporarily_unavailable" ErrorCodeTemporarilyUnavailable = ErrorCode{errorCode: "temporarily_unavailable"} // "temporarily_unavailable"
// ErrorCodeUnauthorizedClient describes the unauthorized_client error code. // ErrorCodeUnauthorizedClient describes the unauthorized_client error code.
// //
@ -123,53 +123,53 @@ var (
// //
// RFC 6749 section 5.2: The authenticated client is not authorized to // RFC 6749 section 5.2: The authenticated client is not authorized to
// use this authorization grant type. // use this authorization grant type.
ErrorCodeUnauthorizedClient = ErrorCode{uid: "unauthorized_client"} // "unauthorized_client" ErrorCodeUnauthorizedClient = ErrorCode{errorCode: "unauthorized_client"} // "unauthorized_client"
// ErrorCodeUnsupportedGrantType describes the unsupported_grant_type error code. // ErrorCodeUnsupportedGrantType describes the unsupported_grant_type error code.
// //
// RFC 6749 section 5.2: The authorization grant type is not supported // RFC 6749 section 5.2: The authorization grant type is not supported
// by the authorization server. // by the authorization server.
ErrorCodeUnsupportedGrantType = ErrorCode{uid: "unsupported_grant_type"} // "unsupported_grant_type" ErrorCodeUnsupportedGrantType = ErrorCode{errorCode: "unsupported_grant_type"} // "unsupported_grant_type"
// ErrorCodeUnsupportedResponseType describes the unsupported_response_type error code. // ErrorCodeUnsupportedResponseType describes the unsupported_response_type error code.
// //
// RFC 6749 section 4.1.2.1: The authorization server does not support // RFC 6749 section 4.1.2.1: The authorization server does not support
// obtaining an authorization code using this method. // obtaining an authorization code using this method.
ErrorCodeUnsupportedResponseType = ErrorCode{uid: "unsupported_response_type"} // "unsupported_response_type" ErrorCodeUnsupportedResponseType = ErrorCode{errorCode: "unsupported_response_type"} // "unsupported_response_type"
// ErrorCodeInvalidToken describes the invalid_token error code. // ErrorCodeInvalidToken describes the invalid_token error code.
// //
// IndieAuth: The access token provided is expired, revoked, or invalid. // IndieAuth: The access token provided is expired, revoked, or invalid.
ErrorCodeInvalidToken = ErrorCode{uid: "invalid_token"} // "invalid_token" ErrorCodeInvalidToken = ErrorCode{errorCode: "invalid_token"} // "invalid_token"
// ErrorCodeInsufficientScope describes the insufficient_scope error code. // ErrorCodeInsufficientScope describes the insufficient_scope error code.
// //
// IndieAuth: The request requires higher privileges than provided. // IndieAuth: The request requires higher privileges than provided.
ErrorCodeInsufficientScope = ErrorCode{uid: "insufficient_scope"} // "insufficient_scope" ErrorCodeInsufficientScope = ErrorCode{errorCode: "insufficient_scope"} // "insufficient_scope"
) )
var ErrErrorCodeUnknown error = NewError(ErrorCodeInvalidRequest, "unknown error code", "") var ErrErrorCodeUnknown error = NewError(ErrorCodeInvalidRequest, "unknown error code", "")
//nolint:gochecknoglobals // maps cannot be constants //nolint:gochecknoglobals // maps cannot be constants
var uidsErrorCodes = map[string]ErrorCode{ var uidsErrorCodes = map[string]ErrorCode{
ErrorCodeAccessDenied.uid: ErrorCodeAccessDenied, ErrorCodeAccessDenied.errorCode: ErrorCodeAccessDenied,
ErrorCodeInsufficientScope.uid: ErrorCodeInsufficientScope, ErrorCodeInsufficientScope.errorCode: ErrorCodeInsufficientScope,
ErrorCodeInvalidClient.uid: ErrorCodeInvalidClient, ErrorCodeInvalidClient.errorCode: ErrorCodeInvalidClient,
ErrorCodeInvalidGrant.uid: ErrorCodeInvalidGrant, ErrorCodeInvalidGrant.errorCode: ErrorCodeInvalidGrant,
ErrorCodeInvalidRequest.uid: ErrorCodeInvalidRequest, ErrorCodeInvalidRequest.errorCode: ErrorCodeInvalidRequest,
ErrorCodeInvalidScope.uid: ErrorCodeInvalidScope, ErrorCodeInvalidScope.errorCode: ErrorCodeInvalidScope,
ErrorCodeInvalidToken.uid: ErrorCodeInvalidToken, ErrorCodeInvalidToken.errorCode: ErrorCodeInvalidToken,
ErrorCodeServerError.uid: ErrorCodeServerError, ErrorCodeServerError.errorCode: ErrorCodeServerError,
ErrorCodeTemporarilyUnavailable.uid: ErrorCodeTemporarilyUnavailable, ErrorCodeTemporarilyUnavailable.errorCode: ErrorCodeTemporarilyUnavailable,
ErrorCodeUnauthorizedClient.uid: ErrorCodeUnauthorizedClient, ErrorCodeUnauthorizedClient.errorCode: ErrorCodeUnauthorizedClient,
ErrorCodeUnsupportedGrantType.uid: ErrorCodeUnsupportedGrantType, ErrorCodeUnsupportedGrantType.errorCode: ErrorCodeUnsupportedGrantType,
ErrorCodeUnsupportedResponseType.uid: ErrorCodeUnsupportedResponseType, ErrorCodeUnsupportedResponseType.errorCode: ErrorCodeUnsupportedResponseType,
} }
// String returns a string representation of the error code. // String returns a string representation of the error code.
func (ec ErrorCode) String() string { func (ec ErrorCode) String() string {
if ec.uid != "" { if ec.errorCode != "" {
return ec.uid return ec.errorCode
} }
return common.Und return common.Und
@ -193,7 +193,7 @@ func (ec *ErrorCode) UnmarshalForm(v []byte) error {
// MarshalJSON encodes the error code into its string representation in JSON. // MarshalJSON encodes the error code into its string representation in JSON.
func (ec ErrorCode) MarshalJSON() ([]byte, error) { func (ec ErrorCode) MarshalJSON() ([]byte, error) {
return []byte(strconv.QuoteToASCII(ec.uid)), nil return []byte(strconv.QuoteToASCII(ec.errorCode)), nil
} }
// Error returns a string representation of the error, satisfying the error // Error returns a string representation of the error, satisfying the error
@ -231,6 +231,8 @@ func (e Error) SetReirectURI(u *url.URL) {
return return
} }
q := u.Query()
for key, val := range map[string]string{ for key, val := range map[string]string{
"error": e.Code.String(), "error": e.Code.String(),
"error_description": e.Description, "error_description": e.Description,
@ -241,8 +243,10 @@ func (e Error) SetReirectURI(u *url.URL) {
continue continue
} }
u.Query().Set(key, val) q.Set(key, val)
} }
u.RawQuery = q.Encode()
} }
// NewError creates a new Error with the stack pointing to the function call // NewError creates a new Error with the stack pointing to the function call

View File

@ -13,17 +13,17 @@ import (
// NOTE(toby3d): Encapsulate enums in structs for extra compile-time safety: // NOTE(toby3d): Encapsulate enums in structs for extra compile-time safety:
// https://threedots.tech/post/safer-enums-in-go/#struct-based-enums // https://threedots.tech/post/safer-enums-in-go/#struct-based-enums
type GrantType struct { type GrantType struct {
uid string grantType string
} }
//nolint:gochecknoglobals // structs cannot be constants //nolint:gochecknoglobals // structs cannot be constants
var ( var (
GrantTypeUnd = GrantType{uid: ""} // "und" GrantTypeUnd = GrantType{grantType: ""} // "und"
GrantTypeAuthorizationCode = GrantType{uid: "authorization_code"} // "authorization_code" GrantTypeAuthorizationCode = GrantType{grantType: "authorization_code"} // "authorization_code"
GrantTypeRefreshToken = GrantType{uid: "refresh_token"} // "refresh_token" GrantTypeRefreshToken = GrantType{grantType: "refresh_token"} // "refresh_token"
// TicketAuth extension. // TicketAuth extension.
GrantTypeTicket = GrantType{uid: "ticket"} GrantTypeTicket = GrantType{grantType: "ticket"}
) )
var ErrGrantTypeUnknown error = NewError( var ErrGrantTypeUnknown error = NewError(
@ -34,9 +34,9 @@ var ErrGrantTypeUnknown error = NewError(
//nolint:gochecknoglobals // maps cannot be constants //nolint:gochecknoglobals // maps cannot be constants
var uidsGrantTypes = map[string]GrantType{ var uidsGrantTypes = map[string]GrantType{
GrantTypeAuthorizationCode.uid: GrantTypeAuthorizationCode, GrantTypeAuthorizationCode.grantType: GrantTypeAuthorizationCode,
GrantTypeRefreshToken.uid: GrantTypeRefreshToken, GrantTypeRefreshToken.grantType: GrantTypeRefreshToken,
GrantTypeTicket.uid: GrantTypeTicket, GrantTypeTicket.grantType: GrantTypeTicket,
} }
// ParseGrantType parse grant_type value as GrantType struct enum. // ParseGrantType parse grant_type value as GrantType struct enum.
@ -78,13 +78,13 @@ func (gt *GrantType) UnmarshalJSON(v []byte) error {
} }
func (gt GrantType) MarshalJSON() ([]byte, error) { func (gt GrantType) MarshalJSON() ([]byte, error) {
return []byte(strconv.Quote(gt.uid)), nil return []byte(strconv.Quote(gt.grantType)), nil
} }
// String returns string representation of grant type. // String returns string representation of grant type.
func (gt GrantType) String() string { func (gt GrantType) String() string {
if gt.uid != "" { if gt.grantType != "" {
return gt.uid return gt.grantType
} }
return common.Und return common.Und

View File

@ -11,14 +11,14 @@ import (
// Me is a URL user identifier. // Me is a URL user identifier.
type Me struct { type Me struct {
id *url.URL me *url.URL
} }
// ParseMe parse string as me URL identifier. // ParseMe parse string as me URL identifier.
// //
//nolint:funlen,cyclop //nolint:funlen,cyclop
func ParseMe(raw string) (*Me, error) { func ParseMe(raw string) (*Me, error) {
id, err := url.Parse(raw) me, err := url.Parse(raw)
if err != nil { if err != nil {
return nil, NewError( return nil, NewError(
ErrorCodeInvalidRequest, ErrorCodeInvalidRequest,
@ -28,57 +28,57 @@ func ParseMe(raw string) (*Me, error) {
) )
} }
if id.Scheme != "http" && id.Scheme != "https" { if me.Scheme != "http" && me.Scheme != "https" {
return nil, NewError( return nil, NewError(
ErrorCodeInvalidRequest, ErrorCodeInvalidRequest,
"profile URL MUST have either an https or http scheme, got '"+id.Scheme+"'", "profile URL MUST have either an https or http scheme, got '"+me.Scheme+"'",
"https://indieauth.net/source/#user-profile-url", "https://indieauth.net/source/#user-profile-url",
"", "",
) )
} }
if id.Path == "" { if me.Path == "" {
id.Path = "/" me.Path = "/"
} }
if strings.Contains(id.Path, "/.") || strings.Contains(id.Path, "/..") { if strings.Contains(me.Path, "/.") || strings.Contains(me.Path, "/..") {
return nil, NewError( return nil, NewError(
ErrorCodeInvalidRequest, ErrorCodeInvalidRequest,
"profile URL MUST contain a path component (/ is a valid path), MUST NOT contain single-dot "+ "profile URL MUST contain a path component (/ is a valid path), MUST NOT contain single-dot "+
"or double-dot path segments, got '"+id.Path+"'", "or double-dot path segments, got '"+me.Path+"'",
"https://indieauth.net/source/#user-profile-url", "https://indieauth.net/source/#user-profile-url",
"", "",
) )
} }
if id.Fragment != "" { if me.Fragment != "" {
return nil, NewError( return nil, NewError(
ErrorCodeInvalidRequest, ErrorCodeInvalidRequest,
"profile URL MUST NOT contain a fragment component, got '"+id.Fragment+"'", "profile URL MUST NOT contain a fragment component, got '"+me.Fragment+"'",
"https://indieauth.net/source/#user-profile-url", "https://indieauth.net/source/#user-profile-url",
"", "",
) )
} }
if id.User != nil { if me.User != nil {
return nil, NewError( return nil, NewError(
ErrorCodeInvalidRequest, ErrorCodeInvalidRequest,
"profile URL MUST NOT contain a username or password component, got '"+id.User.String()+"'", "profile URL MUST NOT contain a username or password component, got '"+me.User.String()+"'",
"https://indieauth.net/source/#user-profile-url", "https://indieauth.net/source/#user-profile-url",
"", "",
) )
} }
if id.Host == "" { if<